Added user profile page, prepped for TOTP 2fa

This commit is contained in:
2026-07-16 22:13:54 +02:00
parent 63deb02d39
commit c8f47768a3
11 changed files with 850 additions and 15 deletions
+93
View File
@@ -3,8 +3,10 @@ import {
deleteGroup,
fetchGroups,
fetchHealth,
fetchSecurity,
fetchStatus,
getApiBaseUrl,
saveSecurity,
upsertGroup,
} from './client'
@@ -209,3 +211,94 @@ describe('deleteGroup', () => {
)
})
})
describe('fetchSecurity', () => {
afterEach(() => {
vi.restoreAllMocks()
})
it('returns parsed security payload', async () => {
const security = {
idle_timeout_minutes: 30,
session_lifetime_hours: 24,
reauth_sensitive_actions: false,
reauth_grace_minutes: 15,
totp_enabled: false,
}
const fetchMock = vi.fn().mockResolvedValue({
ok: true,
json: async () => ({ security }),
})
const payload = await fetchSecurity(fetchMock)
expect(fetchMock).toHaveBeenCalledWith(
'http://localhost:8080/api/v1/security',
)
expect(payload.security).toEqual(security)
})
it('throws when the response is not ok', async () => {
const fetchMock = vi.fn().mockResolvedValue({
ok: false,
status: 503,
json: async () => ({}),
})
await expect(fetchSecurity(fetchMock)).rejects.toThrow(
'security fetch failed: 503',
)
})
})
describe('saveSecurity', () => {
afterEach(() => {
vi.restoreAllMocks()
})
it('sends JSON body and returns parsed security', async () => {
const security = {
idle_timeout_minutes: 45,
session_lifetime_hours: 12,
reauth_sensitive_actions: true,
reauth_grace_minutes: 0,
totp_enabled: true,
}
const fetchMock = vi.fn().mockResolvedValue({
ok: true,
json: async () => ({ security }),
})
await saveSecurity(security, fetchMock)
expect(fetchMock).toHaveBeenCalledWith(
'http://localhost:8080/api/v1/security',
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ security }),
},
)
})
it('throws when the response is not ok', async () => {
const fetchMock = vi.fn().mockResolvedValue({
ok: false,
status: 400,
json: async () => ({}),
})
await expect(
saveSecurity(
{
idle_timeout_minutes: 0,
session_lifetime_hours: 24,
reauth_sensitive_actions: false,
reauth_grace_minutes: 15,
totp_enabled: false,
},
fetchMock,
),
).rejects.toThrow('security save failed: 400')
})
})