fix(web): #295 align MachineKey wire field to server ({ apiKey }, not { key })

The server returns MachineKeyResponse(string ApiKey) -> JSON { apiKey }, but the
hand-written SPA MachineKey type declared { key } and ApiKeyScreen read result.key,
which would be undefined at runtime (blank key + empty copy). Mocked unit tests
passed against the wrong shape. Align the type, the screen, and both test mocks to
the real { apiKey } contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 21:50:24 +02:00
co-authored by Claude Opus 4.8
parent de9fc7e8cc
commit 3c1e694905
4 changed files with 9 additions and 6 deletions
+2 -2
View File
@@ -127,11 +127,11 @@ describe('auth endpoints', () => {
});
it('GET /api/auth/machine-key', async () => {
const fetchMock = vi.spyOn(window, 'fetch').mockResolvedValue(jsonResponse({ key: 'abc123' }));
const fetchMock = vi.spyOn(window, 'fetch').mockResolvedValue(jsonResponse({ apiKey: 'abc123' }));
const result = await getMachineKey();
expect(result).toEqual({ key: 'abc123' });
expect(result).toEqual({ apiKey: 'abc123' });
expect(fetchMock).toHaveBeenCalledWith('/api/auth/machine-key', expect.objectContaining({ method: 'GET' }));
});
});
+5 -2
View File
@@ -21,9 +21,12 @@ export interface AuthSession {
method: string | null;
}
/** `GET /api/auth/machine-key` — the server-generated machine API key (consumed by another slice). */
/**
* `GET /api/auth/machine-key` — the server-generated machine API key.
* The wire field is `apiKey` (server record `MachineKeyResponse(string ApiKey)`), not `key`.
*/
export interface MachineKey {
key: string;
apiKey: string;
}
const legacyApiKeyStorageKey = 'ctv-api-key';
+1 -1
View File
@@ -16,7 +16,7 @@ function installFetch(options: { machineKey?: string; passwordStatus?: number }
return vi.spyOn(window, 'fetch').mockImplementation((input: RequestInfo | URL) => {
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
if (url === '/api/auth/machine-key') {
return Promise.resolve(json({ key: machineKey }));
return Promise.resolve(json({ apiKey: machineKey }));
}
if (url === '/api/auth/password') {
if (passwordStatus >= 400) {
+1 -1
View File
@@ -67,7 +67,7 @@ function MachineKeyCard() {
if (!activeRef.current || seq !== seqRef.current) {
return;
}
setState({ status: 'success', key: result.key });
setState({ status: 'success', key: result.apiKey });
})
.catch((error: unknown) => {
if (!activeRef.current || seq !== seqRef.current) {