-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.ts
More file actions
42 lines (39 loc) · 1.36 KB
/
Copy pathapi.ts
File metadata and controls
42 lines (39 loc) · 1.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* Typed client for `GET /me` (ADR-0024). Sends the **ID token**, not the access token, as the
* bearer: `lambda_handlers/me.py` reads `email` from the verified claims, and Cognito's access
* token doesn't carry `email` by default — only the ID token does. This is a documented
* assumption, not something verified against a live deployment (ADR-0030's consequences); if
* `HttpUserPoolAuthorizer` turns out to reject ID tokens in practice, this is the one line that
* needs to change.
*/
import type { StoredSession } from './session';
export interface MeResponse {
readonly userId: string;
readonly email: string;
readonly created: boolean;
readonly plan: string;
readonly status: string;
readonly forcedDryRun: boolean;
}
export class ApiError extends Error {
constructor(
message: string,
public readonly status: number,
) {
super(message);
}
}
export async function fetchMe(
apiBaseUrl: string,
session: StoredSession,
fetchImpl: typeof fetch = fetch,
): Promise<MeResponse> {
const response = await fetchImpl(`${apiBaseUrl}/me`, {
headers: { Authorization: `Bearer ${session.idToken}` },
});
if (!response.ok) {
const text = await response.text().catch(() => '');
throw new ApiError(`GET /me failed (${response.status}): ${text.slice(0, 300)}`, response.status);
}
return (await response.json()) as MeResponse;
}