feat(auth): implement Android refresh token handling and session management
- Added support for generating Android access tokens and managing refresh sessions in the auth endpoints. - Implemented new tests for login, logout, and refresh functionalities specific to Android clients. - Enhanced password reset logging with normalization and masking of email addresses. - Created a new diagnostics endpoint for password reset attempts, including filtering and summarizing logs. - Introduced a new utility for managing password reset logs with retention policies. - Added tests for password reset log utilities to ensure proper functionality and privacy compliance. - Updated WebAuthn configuration tests to validate origin handling for production and allowed origins.
This commit is contained in:
74
tests/password-reset-log.spec.ts
Normal file
74
tests/password-reset-log.spec.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const filesystem = vi.hoisted(() => ({
|
||||
mkdir: vi.fn(),
|
||||
appendFile: vi.fn(),
|
||||
readFile: vi.fn(),
|
||||
writeFile: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('fs/promises', () => ({
|
||||
default: filesystem
|
||||
}))
|
||||
|
||||
import {
|
||||
cleanupPasswordResetLogs,
|
||||
fingerprintResetEmail,
|
||||
maskResetEmail,
|
||||
normalizeResetEmail,
|
||||
writePasswordResetLog
|
||||
} from '../server/utils/password-reset-log.js'
|
||||
|
||||
describe('Password reset diagnostic log privacy helpers', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('normalisiert E-Mail-Adressen für Lookup und Korrelation', () => {
|
||||
expect(normalizeResetEmail(' User@Example.com ')).toBe('user@example.com')
|
||||
expect(fingerprintResetEmail(' User@Example.com ')).toBe(fingerprintResetEmail('user@example.com'))
|
||||
})
|
||||
|
||||
it('maskiert die E-Mail-Adresse für Diagnoseausgaben', () => {
|
||||
const masked = maskResetEmail('ag2608@googlemail.com')
|
||||
|
||||
expect(masked).toBe('ag***@go***.com')
|
||||
expect(masked).not.toContain('ag2608')
|
||||
expect(masked).not.toContain('googlemail')
|
||||
})
|
||||
|
||||
it('entfernt Diagnoseeinträge nach 72 Stunden', async () => {
|
||||
const now = Date.parse('2026-05-27T12:00:00.000Z')
|
||||
filesystem.readFile.mockResolvedValue([
|
||||
JSON.stringify({ ts: '2026-05-24T11:59:59.000Z', requestId: 'alt' }),
|
||||
JSON.stringify({ ts: '2026-05-24T12:00:00.000Z', requestId: 'neu' }),
|
||||
''
|
||||
].join('\n'))
|
||||
|
||||
const result = await cleanupPasswordResetLogs(now)
|
||||
|
||||
expect(result).toEqual({ retained: 1, removed: 1 })
|
||||
expect(filesystem.writeFile).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
`${JSON.stringify({ ts: '2026-05-24T12:00:00.000Z', requestId: 'neu' })}\n`,
|
||||
'utf8'
|
||||
)
|
||||
})
|
||||
|
||||
it('schreibt bereinigte Fehlerdetails ohne E-Mail oder Credentials', async () => {
|
||||
await writePasswordResetLog({
|
||||
requestId: 'r1',
|
||||
email: 'ag2608@googlemail.com',
|
||||
step: 'mail_send',
|
||||
status: 'failed',
|
||||
error: Object.assign(new Error('Versand an ag2608@googlemail.com fehlgeschlagen password=geheim'), { code: 'EAUTH' })
|
||||
})
|
||||
|
||||
const payload = filesystem.appendFile.mock.calls[0][1]
|
||||
expect(payload).toContain('"errorCode":"EAUTH"')
|
||||
expect(payload).toContain('ag***@go***.com')
|
||||
expect(payload).toContain('password=[redacted]')
|
||||
expect(payload).not.toContain('ag2608@googlemail.com')
|
||||
expect(payload).not.toContain('geheim')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user