|
1 | 1 | import { COOKIE_NAMES } from "~/src/utilities/cookieConfig"; |
2 | 2 |
|
| 3 | +/** |
| 4 | + * Cache of admin auth result per server instance so tests do not exceed the |
| 5 | + * auth rate limit (20 req/min). All tests share the same server; one sign-in |
| 6 | + * per run is enough. |
| 7 | + */ |
| 8 | +const adminAuthCache = new WeakMap< |
| 9 | + ServerWithAuthEnv, |
| 10 | + Promise<AdminAuthRestResult> |
| 11 | +>(); |
| 12 | + |
3 | 13 | /** |
4 | 14 | * Minimal server shape required for REST admin sign-in. |
5 | 15 | * Tests pass the same server instance from test/server.ts. |
@@ -42,38 +52,46 @@ export interface AdminAuthRestResult { |
42 | 52 | export async function getAdminAuthViaRest( |
43 | 53 | server: ServerWithAuthEnv, |
44 | 54 | ): Promise<AdminAuthRestResult> { |
45 | | - const response = await server.inject({ |
46 | | - method: "POST", |
47 | | - url: "/auth/signin", |
48 | | - payload: { |
49 | | - email: server.envConfig.API_ADMINISTRATOR_USER_EMAIL_ADDRESS, |
50 | | - password: server.envConfig.API_ADMINISTRATOR_USER_PASSWORD, |
51 | | - }, |
52 | | - }); |
| 55 | + const cached = adminAuthCache.get(server); |
| 56 | + if (cached) return cached; |
| 57 | + |
| 58 | + const promise = (async (): Promise<AdminAuthRestResult> => { |
| 59 | + const response = await server.inject({ |
| 60 | + method: "POST", |
| 61 | + url: "/auth/signin", |
| 62 | + payload: { |
| 63 | + email: server.envConfig.API_ADMINISTRATOR_USER_EMAIL_ADDRESS, |
| 64 | + password: server.envConfig.API_ADMINISTRATOR_USER_PASSWORD, |
| 65 | + }, |
| 66 | + }); |
53 | 67 |
|
54 | | - if (response.statusCode !== 200) { |
55 | | - throw new Error( |
56 | | - `REST admin sign-in failed: ${response.statusCode} ${response.body}`, |
| 68 | + if (response.statusCode !== 200) { |
| 69 | + throw new Error( |
| 70 | + `REST admin sign-in failed: ${response.statusCode} ${response.body}`, |
| 71 | + ); |
| 72 | + } |
| 73 | + |
| 74 | + const accessCookie = response.cookies.find( |
| 75 | + (c) => c.name === COOKIE_NAMES.ACCESS_TOKEN, |
57 | 76 | ); |
58 | | - } |
| 77 | + if (!accessCookie?.value) { |
| 78 | + throw new Error("REST admin sign-in did not set access token cookie"); |
| 79 | + } |
59 | 80 |
|
60 | | - const accessCookie = response.cookies.find( |
61 | | - (c) => c.name === COOKIE_NAMES.ACCESS_TOKEN, |
62 | | - ); |
63 | | - if (!accessCookie?.value) { |
64 | | - throw new Error("REST admin sign-in did not set access token cookie"); |
65 | | - } |
| 81 | + const refreshCookie = response.cookies.find( |
| 82 | + (c) => c.name === COOKIE_NAMES.REFRESH_TOKEN, |
| 83 | + ); |
| 84 | + if (!refreshCookie?.value) { |
| 85 | + throw new Error("REST admin sign-in did not set refresh token cookie"); |
| 86 | + } |
66 | 87 |
|
67 | | - const refreshCookie = response.cookies.find( |
68 | | - (c) => c.name === COOKIE_NAMES.REFRESH_TOKEN, |
69 | | - ); |
70 | | - if (!refreshCookie?.value) { |
71 | | - throw new Error("REST admin sign-in did not set refresh token cookie"); |
72 | | - } |
| 88 | + return { |
| 89 | + accessToken: accessCookie.value, |
| 90 | + cookies: [...response.cookies], |
| 91 | + refreshToken: refreshCookie.value, |
| 92 | + }; |
| 93 | + })(); |
73 | 94 |
|
74 | | - return { |
75 | | - accessToken: accessCookie.value, |
76 | | - cookies: [...response.cookies], |
77 | | - refreshToken: refreshCookie.value, |
78 | | - }; |
| 95 | + adminAuthCache.set(server, promise); |
| 96 | + return promise; |
79 | 97 | } |
0 commit comments