feat(api): admin reset-password endpoint

This commit is contained in:
Bas van Rossem
2026-06-24 22:57:35 +02:00
parent 40977f8abd
commit 4b80898b0e
2 changed files with 88 additions and 1 deletions

View File

@@ -293,3 +293,65 @@ describe('deactivate / reactivate', () => {
).toBe(403);
});
});
describe('POST /api/admin/users/:id/password', () => {
async function signIn(app: Hono, email: string, password: string): Promise<number> {
const res = await app.request('/api/auth/sign-in/email', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ email, password }),
});
return res.status;
}
it('sets a new password: new works, old fails', async () => {
const app = createApp();
const adminTok = await authToken(app, 'pw-admin@example.com', 'admin');
await app.request('/api/admin/users', {
method: 'POST',
headers: bearer(adminTok),
body: JSON.stringify({
email: 'pw-target@example.com',
name: 'Pw',
password: 'old-wachtwoord-123',
role: 'worker',
}),
});
const id = await userIdByEmail('pw-target@example.com');
const res = await app.request(`/api/admin/users/${id}/password`, {
method: 'POST',
headers: bearer(adminTok),
body: JSON.stringify({ password: 'new-wachtwoord-456' }),
});
expect(res.status).toBe(200);
expect(await signIn(app, 'pw-target@example.com', 'new-wachtwoord-456')).toBe(200);
expect(await signIn(app, 'pw-target@example.com', 'old-wachtwoord-123')).not.toBe(200);
});
it('rejects a too-short password with 400 and 403s for a worker', async () => {
const app = createApp();
const adminTok = await authToken(app, 'pw-short-admin@example.com', 'admin');
await authToken(app, 'pw-worker@example.com');
const id = await userIdByEmail('pw-worker@example.com');
expect(
(
await app.request(`/api/admin/users/${id}/password`, {
method: 'POST',
headers: bearer(adminTok),
body: JSON.stringify({ password: 'short' }),
})
).status,
).toBe(400);
const workerTok = await authToken(app, 'pw-worker2@example.com');
expect(
(
await app.request(`/api/admin/users/${id}/password`, {
method: 'POST',
headers: bearer(workerTok),
body: JSON.stringify({ password: 'long-enough-123' }),
})
).status,
).toBe(403);
});
});