@flytedesk/app-kit 3.2.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +130 -10
  2. package/dist/auth/client/httpClient.d.ts +79 -1
  3. package/dist/auth/client/httpClient.js +185 -16
  4. package/dist/auth/client/httpClient.js.map +1 -1
  5. package/dist/auth/client/index.d.ts +4 -4
  6. package/dist/auth/client/index.js +3 -3
  7. package/dist/auth/client/index.js.map +1 -1
  8. package/dist/auth/client/useAuthSession.d.ts +61 -13
  9. package/dist/auth/client/useAuthSession.js +185 -42
  10. package/dist/auth/client/useAuthSession.js.map +1 -1
  11. package/dist/auth/errors.d.ts +30 -7
  12. package/dist/auth/errors.js +38 -8
  13. package/dist/auth/errors.js.map +1 -1
  14. package/dist/auth/guards.d.ts +12 -0
  15. package/dist/auth/guards.js +24 -6
  16. package/dist/auth/guards.js.map +1 -1
  17. package/dist/auth/index.d.ts +4 -4
  18. package/dist/auth/index.js +2 -2
  19. package/dist/auth/index.js.map +1 -1
  20. package/dist/auth/oidc-client.js +12 -2
  21. package/dist/auth/oidc-client.js.map +1 -1
  22. package/dist/auth/plugin.d.ts +6 -0
  23. package/dist/auth/plugin.js +532 -304
  24. package/dist/auth/plugin.js.map +1 -1
  25. package/dist/auth/shared-types.d.ts +28 -1
  26. package/dist/auth/shared-types.js +35 -0
  27. package/dist/auth/shared-types.js.map +1 -1
  28. package/dist/auth/silentAuthPage.d.ts +20 -0
  29. package/dist/auth/silentAuthPage.js +75 -0
  30. package/dist/auth/silentAuthPage.js.map +1 -0
  31. package/dist/auth/testing/fake-idp.d.ts +35 -0
  32. package/dist/auth/testing/fake-idp.js +86 -2
  33. package/dist/auth/testing/fake-idp.js.map +1 -1
  34. package/dist/auth/testing/index.d.ts +3 -1
  35. package/dist/auth/testing/index.js +3 -1
  36. package/dist/auth/testing/index.js.map +1 -1
  37. package/dist/auth/testing/memory-store.d.ts +44 -0
  38. package/dist/auth/testing/memory-store.js +120 -0
  39. package/dist/auth/testing/memory-store.js.map +1 -0
  40. package/dist/auth/tokens.d.ts +24 -0
  41. package/dist/auth/tokens.js +31 -1
  42. package/dist/auth/tokens.js.map +1 -1
  43. package/dist/auth/types.d.ts +231 -96
  44. package/dist/auth/unavailable.d.ts +10 -0
  45. package/dist/auth/unavailable.js +11 -0
  46. package/dist/auth/unavailable.js.map +1 -0
  47. package/dist/bigquery/errors.d.ts +14 -3
  48. package/dist/bigquery/errors.js +54 -13
  49. package/dist/bigquery/errors.js.map +1 -1
  50. package/dist/bigquery/index.d.ts +5 -3
  51. package/dist/bigquery/index.js +4 -2
  52. package/dist/bigquery/index.js.map +1 -1
  53. package/dist/bigquery/query.d.ts +9 -2
  54. package/dist/bigquery/query.js +38 -16
  55. package/dist/bigquery/query.js.map +1 -1
  56. package/dist/bigquery/types.d.ts +45 -1
  57. package/dist/flags/plugin.js +4 -20
  58. package/dist/flags/plugin.js.map +1 -1
  59. package/dist/postgres/advisoryLock.d.ts +58 -0
  60. package/dist/postgres/advisoryLock.js +71 -0
  61. package/dist/postgres/advisoryLock.js.map +1 -0
  62. package/dist/postgres/index.d.ts +6 -0
  63. package/dist/postgres/index.js +7 -0
  64. package/dist/postgres/index.js.map +1 -0
  65. package/dist/profile/plugin.js +3 -20
  66. package/dist/profile/plugin.js.map +1 -1
  67. package/package.json +7 -2
  68. package/scripts/pending-release-count.mjs +0 -37
  69. package/scripts/release.sh +0 -126
  70. package/scripts/release.test.ts +0 -205
package/README.md CHANGED
@@ -13,6 +13,8 @@ Five subpath modules, one npm package:
13
13
  - `@flytedesk/app-kit/rate-limit` — request rate-limiting and quota enforcement.
14
14
  - `@flytedesk/app-kit/profile` — user profile and preferences management.
15
15
  - `@flytedesk/app-kit/flags` — feature flags and A/B testing.
16
+ - `@flytedesk/app-kit/postgres` — Postgres helpers shared by every app: transaction-scoped
17
+ advisory locks (`acquireAdvisoryLock`, `isAdvisoryLockTimeout`).
16
18
 
17
19
  Status: **bootstrapping.** Both modules are placeholders. See media-planner's published
18
20
  "Media Planner Backend" architecture doc for the full design (DEC-25 through DEC-34) and
@@ -36,22 +38,140 @@ every authenticated request to every consumer of this package. Sign-out still co
36
38
  locally (cookies cleared, refresh-token family revoked) even when the IdP-side
37
39
  revocation call itself times out.
38
40
 
41
+ **An outage is never a sign-out (4.0).** A session is revoked only on a verdict:
42
+ flytedesk-id refuses the session's token (a 401/403 from a resource endpoint, or
43
+ `invalid_grant` from `/token`), `onAuthorizeUser` returns `null`, or the IdP session
44
+ row is gone. Anything that merely prevents a decision — flytedesk-id down or timing
45
+ out, `/token` refusing THIS APP's credentials (`invalid_client`: a bad or rotated client
46
+ secret), a lock timeout, any `AuthStore` error, a *throwing* `onAuthorizeUser` — answers
47
+ **503** with nothing revoked, end to end:
48
+
49
+ - `POST {routePrefix}/refresh` answers 503 with the cookie untouched, so the same
50
+ cookie works again once the dependency recovers.
51
+ - Every authenticated request does too: `requireAuth`/`requirePermission`, `GET
52
+ {routePrefix}/me`, `GET {routePrefix}/apps` and the `@flytedesk/app-kit/flags` and
53
+ `@flytedesk/app-kit/profile` routes answer 503 (never the 401 that means "signed out")
54
+ when `request.authUnavailable` is set — all through one shared guard.
55
+ - `GET {routePrefix}/apps` is the app-switcher feed: once `requireAuth` has verified the
56
+ session, a failure of the feed itself (flytedesk-id's `/me/apps` or `/token`, or the
57
+ store) is **502 `apps_unavailable`**, not an auth 503 — the session is fine.
58
+ - The body is always `{ error, code }` with `code` one of `AUTH_UNAVAILABLE_CODES`:
59
+ `idp_unavailable`, `auth_store_unavailable` or `authorization_hook_failed`.
60
+ - The browser client raises `AuthUnavailableError` (an `ApiRequestError`) for it and
61
+ never runs the auth recovery; `onAuthUnavailable(listener)` announces it. The
62
+ automatic refresh treats only the plugin's 401 as "signed out": a network error, its
63
+ 10s deadline, a proxy's 502/504 or any other non-200 is an `AuthUnavailableError` too
64
+ (code `auth_unreachable`). `useAuthSession` keeps the session in
65
+ `status: "unavailable"` (with the last verified `user` — display-only, not a verified
66
+ identity — and `retryInMs`) and re-verifies by itself with jittered exponential
67
+ backoff (ceilings 1s, 2s, 4s, … capped at 30s, each delay drawn from the ceiling's
68
+ upper half) until the server answers — render it as "reconnecting", never as a
69
+ sign-in screen. A failing `/apps` never blocks the session: `apps` is `[]` and
70
+ `appsError` says why.
71
+
72
+ **Sign-out always clears the cookie (4.0).** `POST {routePrefix}/logout` clears the
73
+ refresh cookie in a `finally`, attempts each store step (revoke the family, look up and
74
+ delete the IdP session) independently, and answers `502 logout_store_failed` (logged)
75
+ if any step failed.
76
+
77
+ **Replays of ended families are not reuse (4.0).** A presented refresh token that was
78
+ *rotated* is a concurrent-tab race inside `refreshReuseGraceMs` and reuse outside it
79
+ (`reuse_detected`, family revoked). A token revoked for any other reason — its family
80
+ was signed out, rejected, or already revoked for reuse — answers 401 with the cookie
81
+ cleared, and is neither revoked again nor reported as reuse.
82
+
83
+ **The `AuthStore` contract (4.0).** Every method, and what it must guarantee, is
84
+ documented on `AuthStore` in `src/auth/types.ts`; the migration from 3.x is in
85
+ `CHANGELOG.md` under 4.0.0. The two guarantees that matter most:
86
+
87
+ - `withIdpSessionLock(sessionId, fn)` calls `fn(locked)` with a store bound to the
88
+ lock. A Postgres store takes the lock with `@flytedesk/app-kit/postgres`'s
89
+ `acquireAdvisoryLock` inside one interactive transaction and must run `locked`'s
90
+ queries on that same transaction. Using its pooled client instead needs a second
91
+ connection per lock holder, and a burst of stale-session refreshes the size of the
92
+ pool deadlocks it (3.x signed every one of those users out).
93
+ - `rotateRefreshToken(presentedId, successor, rotatedAt)` revokes the presented token
94
+ (reason `"rotated"`, only if still live) and inserts its successor in ONE transaction,
95
+ returning whether it won.
96
+ - ONE clock: every time the plugin compares (`expiresAt`, `revocation.at`) comes from the
97
+ app's clock — compared against the clock read at the request's start, and stamped from
98
+ it at the moment of the store write (`rotatedAt`, `revokedAt`). A store persists it
99
+ exactly as given and never stamps it with the database's `now()`. Multiple app
100
+ instances are assumed to run NTP-synced clocks.
101
+ - `rotateRefreshToken` and `revokeFamily` take the same per-family lock. Under READ
102
+ COMMITTED a family revocation cannot see a successor a concurrent rotation has not
103
+ committed yet, and without the lock that successor survives as a live token of a
104
+ signed-out family.
105
+
106
+ **Residual risk: a lost IdP refresh token.** flytedesk-id rotates its refresh token the
107
+ moment it answers a refresh; until the store's lock transaction commits, the plugin's
108
+ memory holds the only copy of the new one. If `updateIdpSession` or the commit fails in
109
+ that window, the next refresh of that session gets `invalid_grant` and the user has to
110
+ sign in again. The window can't be closed from this side (the IdP call can't join the
111
+ transaction); the plugin persists the new token before anything else that can fail,
112
+ `fn` never throws an IdP outcome (it returns it, and the plugin throws only once
113
+ `withIdpSessionLock` has resolved, so an unusable IdP answer never rolls the persisted
114
+ token back), and a store must not do more work in the transaction after `fn` returns. Details on
115
+ `AuthStore.withIdpSessionLock`.
116
+
117
+ `@flytedesk/app-kit/auth/testing` ships `MemoryAuthStore` (an in-memory store that
118
+ honours the whole contract) and `FakeIdp`, whose controls cover the negative paths:
119
+ `setForceSubjectMismatch`, `setForceInvalidClient`, an identity's `emailVerified: false`,
120
+ `setMyAppsFailureStatus`, `setForceRefreshFailure`, the `setHang*Ms` family, and
121
+ `refreshGrantCount`.
122
+
123
+ **The silent-resume page is hardened (4.0).** The `prompt=none` callback's postMessage
124
+ page carries only a fixed `SilentAuthDetailCode` (anything unknown becomes `"other"`),
125
+ serializes its payload so `<`, `>`, `&`, U+2028 and U+2029 can't escape the inline
126
+ script, and is served with
127
+ `Content-Security-Policy: default-src 'none'; script-src 'sha256-…'; frame-ancestors <postLoginRedirect origin>; base-uri 'none'`
128
+ plus `X-Content-Type-Options: nosniff`.
129
+
130
+ `onSignIn(profile, request, context)` receives `context.mode`: `"silent"` for a
131
+ hidden-iframe resume, `"interactive"` for a visible sign-in.
132
+
39
133
  **Residual risk in the refresh-token grace window (RFC 9700 §4.14.2).** `POST
40
134
  {routePrefix}/refresh` rotates the presented refresh token on every call and treats a
41
- second presentation of an already-rotated token as a legitimate concurrent-tab race
42
- (401, nothing revoked) rather than reuse, as long as it arrives within
43
- `refreshReuseGraceMs` (default 20s) of the rotation. This is deliberate — two browser
44
- tabs sharing one cookie jar can otherwise trip false-positive reuse detection — but it
45
- means that within that same window, an attacker who has obtained a copy of a
46
- not-yet-presented refresh token and wins the race against the legitimate browser is
47
- **indistinguishable from a same-device two-tab race**: both look like "a token was
48
- rotated, then its predecessor was presented again shortly after." A presentation
49
- **outside** the window, or of a token that was never rotated at all, is always treated
50
- as reuse and revokes the whole family. Consumers who need a tighter bound can lower
135
+ second presentation of the IMMEDIATELY previous token as a concurrent-tab race — or a
136
+ browser whose refresh response was lost and still holds the old cookie — rather than
137
+ reuse, as long as it arrives within `refreshReuseGraceMs` (default 20s) of the rotation.
138
+ Rotation is deterministic (an HMAC of the presented row's server-side id and the token,
139
+ under a key derived from `accessTokenSecret`), so such a presentation is answered with
140
+ the SAME successor the first one issued, when that successor is still the family's live
141
+ token, and nothing is revoked. Only one hop is honoured (as Auth0's reuse interval):
142
+ tabs share one cookie jar, so only an in-flight request can carry a stale token, and a
143
+ token two or more rotations back is reuse even inside the window. This is deliberate —
144
+ two browser tabs sharing one cookie jar can otherwise trip false-positive reuse
145
+ detection — but it means that within that same window, an attacker who has obtained a
146
+ copy of the immediately previous refresh token is **indistinguishable from a same-device
147
+ two-tab race or a lost response** — and, like them, is handed the family's live token.
148
+ Every such resume is logged at `warn` with the presenting client's IP and User-Agent
149
+ beside the ones the successor was issued to. A presentation **outside** the window, or
150
+ of an older token, is always treated as reuse and revokes the whole family. Consumers who need a tighter bound can lower
51
151
  `refreshReuseGraceMs`, trading some tolerance for slow concurrent-tab requests for a
52
152
  narrower attack window; it cannot be set to zero without reintroducing the false-positive
53
153
  two-tab problem this window exists to solve.
54
154
 
155
+ **Recovering from a leaked `accessTokenSecret` (4.0).** The secret signs access tokens and
156
+ keys refresh-token rotation (it must be at least 32 bytes; registration refuses anything
157
+ shorter). A refresh token's successor also depends on its row's server-side id, so a
158
+ leaked secret plus an old raw token does not let anyone compute a family's current token —
159
+ but anyone who has the secret can forge access tokens, and anyone holding a family's
160
+ CURRENT refresh token keeps it. Recover in two steps, together:
161
+
162
+ 1. **Rotate the secret** on every instance. Access tokens signed with the old one stop
163
+ verifying at once (the browser client refreshes transparently).
164
+ 2. **Revoke every refresh family**, so no refresh token issued before the rotation still
165
+ works: in your store, e.g. `UPDATE refresh_tokens SET revoked_at = $appNow,
166
+ revoked_reason = 'signed_out' WHERE revoked_at IS NULL` (with `$appNow` from the app's
167
+ clock). Every user signs in again.
168
+
169
+ **During a rolling secret change**, instances briefly disagree on the secret. A normal
170
+ refresh works on any instance, but an in-grace second presentation of a just-rotated
171
+ token (a lost response, a concurrent tab) that lands on an instance with the OTHER secret
172
+ cannot re-derive the successor and answers 401 — the client treats that browser as signed
173
+ out. Keep the change short, or drain traffic to one secret at a time.
174
+
55
175
  **Failed interactive sign-ins land back in the app, not on a raw JSON error page.**
56
176
  `signInUrl` (`FlytedeskAuthOptions`, required) is where `GET {routePrefix}/callback`
57
177
  redirects an INTERACTIVE (not `prompt=none`) sign-in failure — idp_error (including
@@ -10,7 +10,7 @@
10
10
  * future change here ever needs one, it belongs in the server (`../plugin.js`) or in a
11
11
  * new Node-only module instead.
12
12
  */
13
- import { type ApiErrorBody } from "../shared-types.js";
13
+ import { type ApiErrorBody, type AuthUnavailableCode } from "../shared-types.js";
14
14
  /** `expires_in`-free deadline for every call this client makes, unless a caller passes
15
15
  * its own `deadlineMs` — the same `AUTH_REQUEST_DEADLINE_MS` (`../shared-types.js`) the
16
16
  * server plugin's default `refreshReuseGraceMs` is sized around (2x this), so the two
@@ -26,6 +26,38 @@ export declare class ApiRequestError extends Error {
26
26
  body: ApiErrorBody & Record<string, unknown>;
27
27
  constructor(status: number, body: ApiErrorBody & Record<string, unknown>);
28
28
  }
29
+ /**
30
+ * The code an AuthUnavailableError carries when the automatic `POST {routePrefix}/refresh`
31
+ * produced no decision at all (AK-23, L-c): no response (a network error), no response
32
+ * within DEFAULT_REQUEST_DEADLINE_MS, or a response the plugin did not decide (an
33
+ * infrastructure 502/504, a 503 without an `AUTH_UNAVAILABLE_CODES` code — any status
34
+ * other than 200 or 401). `status` is the response's, or 0 when there was none.
35
+ */
36
+ export declare const AUTH_UNREACHABLE_CODE = "auth_unreachable";
37
+ /** Every `code` an AuthUnavailableError can carry: the server's own
38
+ * `AUTH_UNAVAILABLE_CODES`, or AUTH_UNREACHABLE_CODE when the refresh got no decision. */
39
+ export type AuthUnavailableErrorCode = AuthUnavailableCode | typeof AUTH_UNREACHABLE_CODE;
40
+ /**
41
+ * AK-23: the server could not DECIDE whether this session is still authorized —
42
+ * flytedesk-id or the app's AuthStore is down, or its authorization hook failed (a 503
43
+ * carrying one of `AUTH_UNAVAILABLE_CODES`) — or the automatic refresh reached no
44
+ * decision at all (`AUTH_UNREACHABLE_CODE`). Transient, and NOT a sign-out: the session
45
+ * (its refresh cookie) is intact and the same request can succeed once the dependency
46
+ * recovers. This client never runs the auth recovery for it; `useAuthSession` keeps the
47
+ * session and retries with backoff (its `"unavailable"` status). A subclass of
48
+ * ApiRequestError, so existing `instanceof ApiRequestError` handling still sees it.
49
+ */
50
+ export declare class AuthUnavailableError extends ApiRequestError {
51
+ code: AuthUnavailableErrorCode;
52
+ constructor(status: number, body: ApiErrorBody & Record<string, unknown> & {
53
+ code: AuthUnavailableErrorCode;
54
+ });
55
+ }
56
+ type AuthUnavailableListener = (error: AuthUnavailableError) => void;
57
+ /** Subscribes to every AuthUnavailableError this client raises (AK-23) — how a session
58
+ * layer learns that an ordinary request hit an outage, so it can show "reconnecting"
59
+ * instead of treating the user as signed out. Returns the unsubscribe function. */
60
+ export declare function onAuthUnavailable(listener: AuthUnavailableListener): () => void;
29
61
  /** A request that missed its deadline (see withDeadline). */
30
62
  export declare class RequestDeadlineError extends Error {
31
63
  constructor(what: string, ms: number);
@@ -52,6 +84,25 @@ export interface AuthRecovery {
52
84
  * invalidates its session state. Left entirely unset is fine — decodeWithAuthRetry
53
85
  * then just reports the second 401 as a failure, with no recovery attempt. */
54
86
  export declare function setAuthRecovery(recovery: AuthRecovery): () => void;
87
+ /**
88
+ * Runs — or joins, when one is already in flight — THE one `POST {routePrefix}/refresh`,
89
+ * and resolves the new access token (also stored via setAccessToken). Single-flighted and
90
+ * always deadline-bound: every caller that 401s, and useAuthSession's own loads, share
91
+ * this one refresh — the refresh cookie rotates on every call, so two concurrent
92
+ * refreshes presenting one cookie would race, and a refresh that never answered would
93
+ * stall them all.
94
+ *
95
+ * AK-23 (L-c): only the plugin's verdict signs anyone out. A 401 — the one answer the
96
+ * plugin gives a refresh it refuses — resolves `null` ("no new token"), which
97
+ * sendAndDecode treats as the session being gone. Every other outcome rejects with
98
+ * AuthUnavailableError, shared by every waiting caller, so no caller ever runs the auth
99
+ * recovery (the sign-out path) over an outage: the plugin's own 503 "could not decide",
100
+ * and an outcome that is no decision at all (AUTH_UNREACHABLE_CODE) — a network error,
101
+ * the deadline (the server's `/refresh` can legitimately outlast it: a contended
102
+ * session lock plus a slow flytedesk-id `/token` and authorization call), or a status
103
+ * the plugin never answers `/refresh` with, such as a proxy's 502/504.
104
+ */
105
+ export declare function refreshAccessToken(): Promise<string | null>;
55
106
  export interface RequestOptions {
56
107
  method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
57
108
  body?: unknown;
@@ -85,3 +136,30 @@ export declare function apiRequest<T>(path: string, options?: RequestOptions): P
85
136
  export declare function apiUpload<T>(path: string, formData: FormData, options?: {
86
137
  skipAuthRetry?: boolean;
87
138
  }): Promise<T>;
139
+ export interface ApiDownloadOptions {
140
+ query?: RequestOptions["query"];
141
+ /** Bounds the whole call exactly like RequestOptions.deadlineMs — first attempt, any
142
+ * refresh it waits on, the retry and the blob read. */
143
+ deadlineMs?: number;
144
+ /** An external abort signal (e.g. a component's cleanup) — aborts the in-flight
145
+ * fetch immediately, independent of deadlineMs. */
146
+ signal?: AbortSignal;
147
+ skipAuthRetry?: boolean;
148
+ }
149
+ export interface ApiDownloadResult {
150
+ blob: Blob;
151
+ /** Parsed from Content-Disposition (RFC 6266 / RFC 5987); undefined when the
152
+ * response carries neither a filename nor filename* directive. */
153
+ filename: string | undefined;
154
+ contentType: string;
155
+ }
156
+ /** Sibling to apiRequest for downloading a file through the SAME request pipeline:
157
+ * URL/query building, credentials, deadline, abort, and the 401 -> refresh ->
158
+ * retry-once dance (see sendWithAuthRetry) — but decodes the body as a Blob instead
159
+ * of JSON, and returns the filename Content-Disposition names for it. */
160
+ export declare function apiDownload(path: string, options?: ApiDownloadOptions): Promise<ApiDownloadResult>;
161
+ /** Triggers a browser "Save As" for an already-fetched blob (e.g. from apiDownload) —
162
+ * a transient off-DOM anchor is the standard way to do this without navigating away.
163
+ * No-op outside a browser (no `document`). */
164
+ export declare function saveBlob(blob: Blob, filename: string): void;
165
+ export {};
@@ -10,7 +10,7 @@
10
10
  * future change here ever needs one, it belongs in the server (`../plugin.js`) or in a
11
11
  * new Node-only module instead.
12
12
  */
13
- import { AUTH_REQUEST_DEADLINE_MS, AUTH_ROUTE_PREFIX, authRoutePath } from "../shared-types.js";
13
+ import { AUTH_REQUEST_DEADLINE_MS, AUTH_ROUTE_PREFIX, AUTH_UNAVAILABLE_CODES, authRoutePath, } from "../shared-types.js";
14
14
  /** `expires_in`-free deadline for every call this client makes, unless a caller passes
15
15
  * its own `deadlineMs` — the same `AUTH_REQUEST_DEADLINE_MS` (`../shared-types.js`) the
16
16
  * server plugin's default `refreshReuseGraceMs` is sized around (2x this), so the two
@@ -33,6 +33,60 @@ export class ApiRequestError extends Error {
33
33
  this.body = body;
34
34
  }
35
35
  }
36
+ /**
37
+ * The code an AuthUnavailableError carries when the automatic `POST {routePrefix}/refresh`
38
+ * produced no decision at all (AK-23, L-c): no response (a network error), no response
39
+ * within DEFAULT_REQUEST_DEADLINE_MS, or a response the plugin did not decide (an
40
+ * infrastructure 502/504, a 503 without an `AUTH_UNAVAILABLE_CODES` code — any status
41
+ * other than 200 or 401). `status` is the response's, or 0 when there was none.
42
+ */
43
+ export const AUTH_UNREACHABLE_CODE = "auth_unreachable";
44
+ /**
45
+ * AK-23: the server could not DECIDE whether this session is still authorized —
46
+ * flytedesk-id or the app's AuthStore is down, or its authorization hook failed (a 503
47
+ * carrying one of `AUTH_UNAVAILABLE_CODES`) — or the automatic refresh reached no
48
+ * decision at all (`AUTH_UNREACHABLE_CODE`). Transient, and NOT a sign-out: the session
49
+ * (its refresh cookie) is intact and the same request can succeed once the dependency
50
+ * recovers. This client never runs the auth recovery for it; `useAuthSession` keeps the
51
+ * session and retries with backoff (its `"unavailable"` status). A subclass of
52
+ * ApiRequestError, so existing `instanceof ApiRequestError` handling still sees it.
53
+ */
54
+ export class AuthUnavailableError extends ApiRequestError {
55
+ constructor(status, body) {
56
+ super(status, body);
57
+ this.name = "AuthUnavailableError";
58
+ }
59
+ }
60
+ function isAuthUnavailableCode(code) {
61
+ return AUTH_UNAVAILABLE_CODES.includes(code);
62
+ }
63
+ const authUnavailableListeners = new Set();
64
+ /** Subscribes to every AuthUnavailableError this client raises (AK-23) — how a session
65
+ * layer learns that an ordinary request hit an outage, so it can show "reconnecting"
66
+ * instead of treating the user as signed out. Returns the unsubscribe function. */
67
+ export function onAuthUnavailable(listener) {
68
+ authUnavailableListeners.add(listener);
69
+ return () => {
70
+ authUnavailableListeners.delete(listener);
71
+ };
72
+ }
73
+ function raiseAuthUnavailable(error) {
74
+ for (const listener of authUnavailableListeners)
75
+ listener(error);
76
+ return error;
77
+ }
78
+ /** The one mapping from an error response to the error this client throws: a
79
+ * "could not decide" 503 becomes AuthUnavailableError (and is announced), anything
80
+ * else an ApiRequestError. */
81
+ async function errorFromResponse(res) {
82
+ const body = (await res
83
+ .json()
84
+ .catch(() => ({ error: res.statusText, code: "unknown" })));
85
+ if (res.status === 503 && isAuthUnavailableCode(body.code)) {
86
+ return raiseAuthUnavailable(new AuthUnavailableError(503, { ...body, code: body.code }));
87
+ }
88
+ return new ApiRequestError(res.status, body);
89
+ }
36
90
  /** A request that missed its deadline (see withDeadline). */
37
91
  export class RequestDeadlineError extends Error {
38
92
  constructor(what, ms) {
@@ -76,8 +130,14 @@ export function setAuthRecovery(recovery) {
76
130
  * fetch, and any body read on it, is cancelled) and the returned promise rejects with
77
131
  * a RequestDeadlineError — the rejection does not depend on whatever `run` awaits
78
132
  * honouring the signal, so this settles no matter what. */
79
- async function withDeadline(what, ms, run) {
133
+ async function withDeadline(what, ms, run, externalSignal) {
80
134
  const controller = new AbortController();
135
+ if (externalSignal) {
136
+ if (externalSignal.aborted)
137
+ controller.abort(externalSignal.reason);
138
+ else
139
+ externalSignal.addEventListener("abort", () => controller.abort(externalSignal.reason), { once: true });
140
+ }
81
141
  let timer;
82
142
  const deadline = new Promise((_, reject) => {
83
143
  timer = setTimeout(() => {
@@ -93,11 +153,33 @@ async function withDeadline(what, ms, run) {
93
153
  clearTimeout(timer);
94
154
  }
95
155
  }
96
- /** Single-flighted, and always deadline-bound: every caller that 401s shares this one
97
- * refresh, so a refresh that never answered would stall all of them. Any failure — a
98
- * non-2xx, a network error, the deadline — resolves null ("no new token"), which
99
- * sendAndDecode treats exactly like a refused refresh. */
100
- async function refreshAccessToken() {
156
+ /** The AuthUnavailableError (announced to onAuthUnavailable listeners) for a refresh
157
+ * that reached no decision — see AUTH_UNREACHABLE_CODE. */
158
+ function refreshUnreachable(status, cause) {
159
+ return raiseAuthUnavailable(new AuthUnavailableError(status, {
160
+ error: `Sign-in could not be verified right now — ${cause}`,
161
+ code: AUTH_UNREACHABLE_CODE,
162
+ }));
163
+ }
164
+ /**
165
+ * Runs — or joins, when one is already in flight — THE one `POST {routePrefix}/refresh`,
166
+ * and resolves the new access token (also stored via setAccessToken). Single-flighted and
167
+ * always deadline-bound: every caller that 401s, and useAuthSession's own loads, share
168
+ * this one refresh — the refresh cookie rotates on every call, so two concurrent
169
+ * refreshes presenting one cookie would race, and a refresh that never answered would
170
+ * stall them all.
171
+ *
172
+ * AK-23 (L-c): only the plugin's verdict signs anyone out. A 401 — the one answer the
173
+ * plugin gives a refresh it refuses — resolves `null` ("no new token"), which
174
+ * sendAndDecode treats as the session being gone. Every other outcome rejects with
175
+ * AuthUnavailableError, shared by every waiting caller, so no caller ever runs the auth
176
+ * recovery (the sign-out path) over an outage: the plugin's own 503 "could not decide",
177
+ * and an outcome that is no decision at all (AUTH_UNREACHABLE_CODE) — a network error,
178
+ * the deadline (the server's `/refresh` can legitimately outlast it: a contended
179
+ * session lock plus a slow flytedesk-id `/token` and authorization call), or a status
180
+ * the plugin never answers `/refresh` with, such as a proxy's 502/504.
181
+ */
182
+ export async function refreshAccessToken() {
101
183
  if (!refreshPromise) {
102
184
  const refreshPath = authRoutePath(AUTH_ROUTE_PREFIX, "refresh");
103
185
  refreshPromise = withDeadline(`POST ${refreshPath}`, DEFAULT_REQUEST_DEADLINE_MS, async (signal) => {
@@ -106,13 +188,23 @@ async function refreshAccessToken() {
106
188
  credentials: "include",
107
189
  signal,
108
190
  });
109
- if (!res.ok)
191
+ if (res.status === 401)
110
192
  return null;
193
+ if (!res.ok) {
194
+ const error = await errorFromResponse(res);
195
+ if (error instanceof AuthUnavailableError)
196
+ throw error;
197
+ throw refreshUnreachable(res.status, `the server answered ${res.status}`);
198
+ }
111
199
  const body = (await res.json());
112
200
  setAccessToken(body.accessToken);
113
201
  return body.accessToken;
114
202
  })
115
- .catch(() => null)
203
+ .catch((err) => {
204
+ if (err instanceof AuthUnavailableError)
205
+ throw err;
206
+ throw refreshUnreachable(0, err instanceof RequestDeadlineError ? "no answer in time" : "the server could not be reached");
207
+ })
116
208
  .finally(() => {
117
209
  refreshPromise = null;
118
210
  });
@@ -154,12 +246,20 @@ async function sendAndDecode(label, doFetch, options) {
154
246
  return decodeWithAuthRetry(doFetch, options);
155
247
  return withDeadline(label, deadlineMs, (signal) => decodeWithAuthRetry(doFetch, options, signal));
156
248
  }
157
- async function decodeWithAuthRetry(doFetch, { skipAuthRetry, ownsAuthRecovery }, signal) {
249
+ /** The shared tail of every transport this client offers: fires `doFetch`,
250
+ * transparently retries once after a refresh on 401 (unless skipped), and once more
251
+ * after the shared auth recovery if that still 401s (see setAuthRecovery) — then
252
+ * throws the decoded error on any non-2xx. Returns the successful raw Response so
253
+ * each transport (JSON body, blob download) can decode it its own way; this is the
254
+ * ONE place the auth-retry dance lives, so it can't drift between them. */
255
+ async function sendWithAuthRetry(doFetch, { skipAuthRetry, ownsAuthRecovery }, signal) {
158
256
  // Who this request is being sent as — the only identity a recovery may replay it for.
159
257
  const recovery = authRecovery;
160
258
  const sentAs = recovery?.principal() ?? null;
161
259
  let res = await doFetch(signal);
162
260
  if (res.status === 401 && !skipAuthRetry) {
261
+ // Rejects with AuthUnavailableError on an outage (AK-23) — straight out of this
262
+ // call, past the recovery below: an outage is not a sign-out.
163
263
  const refreshed = await refreshAccessToken();
164
264
  // The shared refresh is not cancelled by this call's deadline (other callers may
165
265
  // still want it) — but a call that has already missed its deadline must not act on
@@ -186,12 +286,12 @@ async function decodeWithAuthRetry(doFetch, { skipAuthRetry, ownsAuthRecovery },
186
286
  signal?.throwIfAborted();
187
287
  }
188
288
  }
189
- if (!res.ok) {
190
- const errorBody = (await res
191
- .json()
192
- .catch(() => ({ error: res.statusText, code: "unknown" })));
193
- throw new ApiRequestError(res.status, errorBody);
194
- }
289
+ if (!res.ok)
290
+ throw await errorFromResponse(res);
291
+ return res;
292
+ }
293
+ async function decodeWithAuthRetry(doFetch, options, signal) {
294
+ const res = await sendWithAuthRetry(doFetch, options, signal);
195
295
  if (res.status === 204)
196
296
  return undefined;
197
297
  return (await res.json());
@@ -231,4 +331,73 @@ export async function apiUpload(path, formData, options = {}) {
231
331
  });
232
332
  return sendAndDecode(`POST ${path}`, doFetch, { skipAuthRetry });
233
333
  }
334
+ /** RFC 6266 filename from a `Content-Disposition` header, preferring the RFC 5987
335
+ * extended `filename*=charset'lang'value` form (percent-decoded) over the plain
336
+ * `filename="..."` form when both are present — the extended form is the one that can
337
+ * actually carry non-ASCII names. `undefined` when the header is absent or carries
338
+ * neither form. */
339
+ function parseContentDispositionFilename(header) {
340
+ if (!header)
341
+ return undefined;
342
+ const extended = /filename\*\s*=\s*([^;]+)/i.exec(header);
343
+ if (extended) {
344
+ // charset'lang'value — charset is always UTF-8 in practice and lang is usually
345
+ // empty; only the value is ever meaningful to decode.
346
+ const value = extended[1].trim().replace(/^"|"$/g, "");
347
+ const parts = value.split("'");
348
+ if (parts.length === 3) {
349
+ try {
350
+ return decodeURIComponent(parts[2]);
351
+ }
352
+ catch {
353
+ // Malformed percent-encoding — fall through to the plain form below.
354
+ }
355
+ }
356
+ }
357
+ const plain = /filename\s*=\s*"?([^";]+)"?/i.exec(header);
358
+ return plain ? plain[1] : undefined;
359
+ }
360
+ /** Sibling to apiRequest for downloading a file through the SAME request pipeline:
361
+ * URL/query building, credentials, deadline, abort, and the 401 -> refresh ->
362
+ * retry-once dance (see sendWithAuthRetry) — but decodes the body as a Blob instead
363
+ * of JSON, and returns the filename Content-Disposition names for it. */
364
+ export async function apiDownload(path, options = {}) {
365
+ const { query, deadlineMs, signal, skipAuthRetry } = options;
366
+ const doFetch = async (fetchSignal) => fetch(buildUrl(path, query), {
367
+ method: "GET",
368
+ credentials: "include",
369
+ headers: {
370
+ ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
371
+ },
372
+ signal: fetchSignal,
373
+ });
374
+ const decode = async (res) => {
375
+ const blob = await res.blob();
376
+ const contentType = res.headers.get("content-type")?.split(";")[0]?.trim() ?? "application/octet-stream";
377
+ const filename = parseContentDispositionFilename(res.headers.get("content-disposition"));
378
+ return { blob, filename, contentType };
379
+ };
380
+ const run = async (fetchSignal) => decode(await sendWithAuthRetry(doFetch, { skipAuthRetry }, fetchSignal));
381
+ if (deadlineMs === undefined)
382
+ return run(signal);
383
+ return withDeadline(`GET ${path}`, deadlineMs, run, signal);
384
+ }
385
+ /** Triggers a browser "Save As" for an already-fetched blob (e.g. from apiDownload) —
386
+ * a transient off-DOM anchor is the standard way to do this without navigating away.
387
+ * No-op outside a browser (no `document`). */
388
+ export function saveBlob(blob, filename) {
389
+ if (typeof document === "undefined")
390
+ return;
391
+ const urlStatics = URL;
392
+ const url = urlStatics.createObjectURL(blob);
393
+ try {
394
+ const anchor = document.createElement("a");
395
+ anchor.href = url;
396
+ anchor.download = filename;
397
+ anchor.click();
398
+ }
399
+ finally {
400
+ urlStatics.revokeObjectURL(url);
401
+ }
402
+ }
234
403
  //# sourceMappingURL=httpClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../../src/auth/client/httpClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../../src/auth/client/httpClient.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,9 @@
4
4
  * browser bundle. See httpClient.ts and useAuthSession.ts's own doc comments for what
5
5
  * was extracted from where and why (AK-16).
6
6
  */
7
- export { ApiRequestError, RequestDeadlineError, DEFAULT_REQUEST_DEADLINE_MS, configureApiClient, setAccessToken, getAccessToken, getBaseUrl, setAuthRecovery, apiRequest, apiUpload, type AuthRecovery, type RequestOptions, } from "./httpClient.js";
8
- export { useAuthSession, type AuthStatus, type AuthSessionState, type LoadingSessionState, type AuthenticatedSessionState, type UnauthenticatedSessionState, type ErrorSessionState, } from "./useAuthSession.js";
7
+ export { ApiRequestError, AuthUnavailableError, AUTH_UNREACHABLE_CODE, type AuthUnavailableErrorCode, RequestDeadlineError, onAuthUnavailable, DEFAULT_REQUEST_DEADLINE_MS, configureApiClient, setAccessToken, getAccessToken, getBaseUrl, setAuthRecovery, apiRequest, apiUpload, apiDownload, saveBlob, type AuthRecovery, type RequestOptions, type ApiDownloadOptions, type ApiDownloadResult, } from "./httpClient.js";
8
+ export { useAuthSession, unavailableRetryDelayMs, UNAVAILABLE_RETRY_BASE_MS, UNAVAILABLE_RETRY_MAX_MS, type AuthStatus, type AuthSessionState, type LoadingSessionState, type AuthenticatedSessionState, type UnauthenticatedSessionState, type UnavailableSessionState, type ErrorSessionState, } from "./useAuthSession.js";
9
9
  export { attemptSilentResume, type SilentResumeResult, type AttemptSilentResumeOptions, } from "./silentAuth.js";
10
10
  export { consumeSignInError } from "./signInError.js";
11
- export type { AppSwitcherEntry, AuthedUserDto, IdpRole, ApiErrorBody, SilentAuthMessage } from "../shared-types.js";
12
- export { AUTH_ROUTE_PREFIX, AUTH_ROUTE_SEGMENTS, authRoutePath, SIGNIN_ERROR_QUERY_PARAM, SIGNIN_ERROR_CODES, type AuthRouteSegment, type SignInErrorCode, } from "../shared-types.js";
11
+ export type { AppSwitcherEntry, AuthedUserDto, IdpRole, ApiErrorBody, AuthUnavailableCode, SilentAuthDetailCode, SilentAuthMessage, } from "../shared-types.js";
12
+ export { AUTH_ROUTE_PREFIX, AUTH_ROUTE_SEGMENTS, AUTH_UNAVAILABLE_CODES, authRoutePath, SILENT_AUTH_DETAIL_CODES, SIGNIN_ERROR_QUERY_PARAM, SIGNIN_ERROR_CODES, type AuthRouteSegment, type SignInErrorCode, } from "../shared-types.js";
@@ -4,9 +4,9 @@
4
4
  * browser bundle. See httpClient.ts and useAuthSession.ts's own doc comments for what
5
5
  * was extracted from where and why (AK-16).
6
6
  */
7
- export { ApiRequestError, RequestDeadlineError, DEFAULT_REQUEST_DEADLINE_MS, configureApiClient, setAccessToken, getAccessToken, getBaseUrl, setAuthRecovery, apiRequest, apiUpload, } from "./httpClient.js";
8
- export { useAuthSession, } from "./useAuthSession.js";
7
+ export { ApiRequestError, AuthUnavailableError, AUTH_UNREACHABLE_CODE, RequestDeadlineError, onAuthUnavailable, DEFAULT_REQUEST_DEADLINE_MS, configureApiClient, setAccessToken, getAccessToken, getBaseUrl, setAuthRecovery, apiRequest, apiUpload, apiDownload, saveBlob, } from "./httpClient.js";
8
+ export { useAuthSession, unavailableRetryDelayMs, UNAVAILABLE_RETRY_BASE_MS, UNAVAILABLE_RETRY_MAX_MS, } from "./useAuthSession.js";
9
9
  export { attemptSilentResume, } from "./silentAuth.js";
10
10
  export { consumeSignInError } from "./signInError.js";
11
- export { AUTH_ROUTE_PREFIX, AUTH_ROUTE_SEGMENTS, authRoutePath, SIGNIN_ERROR_QUERY_PARAM, SIGNIN_ERROR_CODES, } from "../shared-types.js";
11
+ export { AUTH_ROUTE_PREFIX, AUTH_ROUTE_SEGMENTS, AUTH_UNAVAILABLE_CODES, authRoutePath, SILENT_AUTH_DETAIL_CODES, SIGNIN_ERROR_QUERY_PARAM, SIGNIN_ERROR_CODES, } from "../shared-types.js";
12
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,UAAU,EACV,eAAe,EACf,UAAU,EACV,SAAS,GAGV,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,GAOf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,GAGpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACxB,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EAErB,oBAAoB,EACpB,iBAAiB,EACjB,2BAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,UAAU,EACV,eAAe,EACf,UAAU,EACV,SAAS,EACT,WAAW,EACX,QAAQ,GAKT,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,GAQzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,GAGpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAWtD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC"}