feat: establish auth listing and image vertical slices
Includes MFA-capable authentication, session and CSRF security, password recovery, listing lifecycle and ownership rules, inventory image metadata, local ImageStorage, migrations, tests, and implementation status documentation. Verification: npm test (62 passing) and integration suite (14 passing).
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import test from 'node:test';
|
||||
|
||||
import { createRedisConnection } from '../../src/infrastructure/redis/client.js';
|
||||
import { createRedisLoginRateLimiter } from '../../src/modules/auth/services/login-rate-limiter.js';
|
||||
|
||||
const redisUrl = process.env.TEST_REDIS_URL;
|
||||
|
||||
if (!redisUrl) {
|
||||
throw new Error('TEST_REDIS_URL is required to run integration tests.');
|
||||
}
|
||||
|
||||
test('shares login attempts across limiter instances', async () => {
|
||||
const redis = await createRedisConnection(redisUrl);
|
||||
const keyPrefix = `pokemon-inventory:test:auth:${randomUUID()}:`;
|
||||
|
||||
try {
|
||||
const firstLimiter = createRedisLoginRateLimiter({
|
||||
keyPrefix,
|
||||
maxAttempts: 2,
|
||||
redisClient: redis.client,
|
||||
});
|
||||
const secondLimiter = createRedisLoginRateLimiter({
|
||||
keyPrefix,
|
||||
maxAttempts: 2,
|
||||
redisClient: redis.client,
|
||||
});
|
||||
|
||||
assert.deepEqual(await firstLimiter.consume('198.51.100.8'), { allowed: true });
|
||||
assert.deepEqual(await secondLimiter.consume('198.51.100.8'), { allowed: true });
|
||||
|
||||
const blockedAttempt = await firstLimiter.consume('198.51.100.8');
|
||||
|
||||
assert.equal(blockedAttempt.allowed, false);
|
||||
assert.ok(blockedAttempt.retryAfterSeconds > 0);
|
||||
assert.deepEqual(await secondLimiter.consume('198.51.100.9'), { allowed: true });
|
||||
} finally {
|
||||
await redis.close();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user