@flytedesk/app-kit 5.0.0 → 7.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.
- package/README.md +184 -41
- package/dist/auth/client/authSession.d.ts +168 -0
- package/dist/auth/client/authSession.js +581 -0
- package/dist/auth/client/authSession.js.map +1 -0
- package/dist/auth/client/browserEnvironment.d.ts +22 -0
- package/dist/auth/client/browserEnvironment.js +87 -0
- package/dist/auth/client/browserEnvironment.js.map +1 -0
- package/dist/auth/client/httpClient.d.ts +22 -25
- package/dist/auth/client/httpClient.js +49 -51
- package/dist/auth/client/httpClient.js.map +1 -1
- package/dist/auth/client/index.d.ts +15 -8
- package/dist/auth/client/index.js +13 -7
- package/dist/auth/client/index.js.map +1 -1
- package/dist/auth/client/testing.d.ts +6 -0
- package/dist/auth/client/testing.js +20 -0
- package/dist/auth/client/testing.js.map +1 -0
- package/dist/auth/client/useAuthSession.d.ts +54 -91
- package/dist/auth/client/useAuthSession.js +65 -252
- package/dist/auth/client/useAuthSession.js.map +1 -1
- package/dist/auth/index.d.ts +3 -4
- package/dist/auth/index.js +1 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/oidc-client.d.ts +18 -4
- package/dist/auth/oidc-client.js +18 -1
- package/dist/auth/oidc-client.js.map +1 -1
- package/dist/auth/plugin.js +250 -211
- package/dist/auth/plugin.js.map +1 -1
- package/dist/auth/returnTarget.d.ts +30 -0
- package/dist/auth/returnTarget.js +48 -0
- package/dist/auth/returnTarget.js.map +1 -0
- package/dist/auth/shared-types.d.ts +18 -41
- package/dist/auth/shared-types.js +18 -45
- package/dist/auth/shared-types.js.map +1 -1
- package/dist/auth/testing/fake-idp.d.ts +38 -1
- package/dist/auth/testing/fake-idp.js +166 -27
- package/dist/auth/testing/fake-idp.js.map +1 -1
- package/dist/auth/types.d.ts +26 -29
- package/dist/bigquery/errors.d.ts +19 -0
- package/dist/bigquery/errors.js +41 -0
- package/dist/bigquery/errors.js.map +1 -1
- package/dist/bigquery/index.d.ts +2 -2
- package/dist/bigquery/index.js +1 -1
- package/dist/bigquery/index.js.map +1 -1
- package/dist/bigquery/query.js +14 -1
- package/dist/bigquery/query.js.map +1 -1
- package/dist/bigquery/schema.d.ts +5 -0
- package/dist/bigquery/schema.js +35 -0
- package/dist/bigquery/schema.js.map +1 -0
- package/dist/bigquery/types.d.ts +47 -2
- package/dist/chat/index.d.ts +52 -21
- package/dist/chat/index.js +50 -20
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/mcp/entry.d.ts +37 -0
- package/dist/chat/mcp/entry.js +135 -0
- package/dist/chat/mcp/entry.js.map +1 -0
- package/dist/cli/is-running-as-main.d.ts +1 -0
- package/dist/cli/is-running-as-main.js +54 -0
- package/dist/cli/is-running-as-main.js.map +1 -0
- package/dist/cli/sync-engine.d.ts +1 -32
- package/dist/cli/sync-engine.js +7 -45
- package/dist/cli/sync-engine.js.map +1 -1
- package/dist/flags/evaluate.d.ts +43 -0
- package/dist/flags/evaluate.js +64 -0
- package/dist/flags/evaluate.js.map +1 -0
- package/dist/flags/index.d.ts +22 -6
- package/dist/flags/index.js +21 -6
- package/dist/flags/index.js.map +1 -1
- package/dist/flags/plugin.js +73 -7
- package/dist/flags/plugin.js.map +1 -1
- package/dist/flags/types.d.ts +25 -0
- package/package.json +11 -4
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The flytedesk ID session lifecycle — the ONE owner of every sign-in and session
|
|
3
|
+
* decision a flytedesk ID app makes (AK-35, PLN-2 R-14; design: PLN-2 architecture
|
|
4
|
+
* "flytedesk ID session lifecycle"). An app never builds any of this itself: it renders
|
|
5
|
+
* its shell for a usable session and the design system's `SessionScreen` for the rest
|
|
6
|
+
* (`./useAuthSession.ts`'s `SessionBoundary`), and reads the session through
|
|
7
|
+
* `authSession` / `useAuthSession`.
|
|
8
|
+
*
|
|
9
|
+
* - Signed out: shows "signing in" and sends the browser through flytedesk ID with a
|
|
10
|
+
* top-level navigation, carrying the exact `path?query#hash` as the return target.
|
|
11
|
+
* Sign-in is only ever that navigation: it is the one request that can carry
|
|
12
|
+
* `prompt=consent`, which flytedesk ID requires before it issues a refresh token
|
|
13
|
+
* (see `../plugin.ts`'s `/login`).
|
|
14
|
+
* - Session lost mid-use (a refused refresh, `onSessionEnded`): "session expired", then
|
|
15
|
+
* the same automatic sign-in, back to the same URL.
|
|
16
|
+
* - Checked every 10 minutes while the tab is visible, and when it becomes visible or
|
|
17
|
+
* focused (at most once a minute).
|
|
18
|
+
* - An outage (`AuthUnavailableError`) is never a sign-out: "unavailable", retried with
|
|
19
|
+
* backoff (AK-23).
|
|
20
|
+
* - Sign-out ends this app's session and flytedesk ID's (RP-initiated logout), and never
|
|
21
|
+
* bounces straight back in (the server's signed-out marker forces `prompt=login`).
|
|
22
|
+
* - Cross-tab: only a visible tab navigates, and while one tab is signing in (a short
|
|
23
|
+
* claim) the others wait for its `signed-in` message.
|
|
24
|
+
* - Loop guard: a tab that arrives back still signed out within two minutes of starting
|
|
25
|
+
* a sign-in, or with `signin_error`, shows the sign-in-failed state with a manual
|
|
26
|
+
* retry — never another automatic redirect.
|
|
27
|
+
*
|
|
28
|
+
* Framework-agnostic and browser-safe (ZERO Node imports, like `./httpClient.ts`). Every
|
|
29
|
+
* browser API it touches comes through an `AuthSessionEnvironment`, so the state machine
|
|
30
|
+
* is tested with a scripted environment and the real one is `browserEnvironment()`.
|
|
31
|
+
*/
|
|
32
|
+
import { absoluteApiUrl, apiRequest, ApiRequestError, AuthUnavailableError, onAuthUnavailable, onSessionEnded, refreshAccessToken, setAccessToken, } from "./httpClient.js";
|
|
33
|
+
import { safeReturnTarget } from "../returnTarget.js";
|
|
34
|
+
import { AUTH_ROUTE_PREFIX, AUTH_REQUEST_DEADLINE_MS, authRoutePath, RETURN_TO_QUERY_PARAM, SIGNIN_ERROR_CODES, SIGNIN_ERROR_QUERY_PARAM, } from "../shared-types.js";
|
|
35
|
+
/** How often a visible, signed-in tab verifies its session. */
|
|
36
|
+
export const SESSION_CHECK_INTERVAL_MS = 10 * 60_000;
|
|
37
|
+
/** A tab becoming visible or focused re-checks at most this often. */
|
|
38
|
+
export const FOCUS_CHECK_MIN_INTERVAL_MS = 60_000;
|
|
39
|
+
/** A tab arriving back still signed out this soon after starting a sign-in is a loop. */
|
|
40
|
+
export const SIGN_IN_LOOP_WINDOW_MS = 2 * 60_000;
|
|
41
|
+
/** How long one tab's sign-in claim makes the other visible tabs wait for it — a round
|
|
42
|
+
* trip while flytedesk ID is still signed in. */
|
|
43
|
+
export const SIGN_IN_CLAIM_MS = 20_000;
|
|
44
|
+
/** A page still here this long after handing the browser to a top-level navigation was
|
|
45
|
+
* not navigated (the user cancelled it): it acts on its own behalf again. Well past a
|
|
46
|
+
* slow round trip, during which the old page legitimately stays up. */
|
|
47
|
+
export const NAVIGATION_STALL_MS = 60_000;
|
|
48
|
+
/** First delay before re-verifying a session the server could not verify (AK-23). */
|
|
49
|
+
export const UNAVAILABLE_RETRY_BASE_MS = 1_000;
|
|
50
|
+
/** The backoff's ceiling: an outage is retried every this-many ms at most. */
|
|
51
|
+
export const UNAVAILABLE_RETRY_MAX_MS = 30_000;
|
|
52
|
+
/** Storage keys and the BroadcastChannel name — one namespace, never an app's. */
|
|
53
|
+
export const SIGN_IN_ATTEMPT_KEY = "flytedesk-app-kit.auth.signInStartedAt";
|
|
54
|
+
export const SIGN_IN_CLAIM_KEY = "flytedesk-app-kit.auth.signInClaim";
|
|
55
|
+
export const SESSION_CHANNEL = "flytedesk-app-kit-session";
|
|
56
|
+
/**
|
|
57
|
+
* Jittered exponential backoff for the `"unavailable"` state's automatic retries: the
|
|
58
|
+
* ceiling doubles per attempt (1s, 2s, 4s, … capped at UNAVAILABLE_RETRY_MAX_MS) and the
|
|
59
|
+
* delay is drawn uniformly from its upper half ("equal jitter", AK-23 L-c) — so every
|
|
60
|
+
* tab that saw the same outage does not retry in the same instant when it ends.
|
|
61
|
+
*/
|
|
62
|
+
export function unavailableRetryDelayMs(attempt, random = Math.random) {
|
|
63
|
+
const ceiling = Math.min(UNAVAILABLE_RETRY_BASE_MS * 2 ** attempt, UNAVAILABLE_RETRY_MAX_MS);
|
|
64
|
+
return Math.round(ceiling / 2 + random() * (ceiling / 2));
|
|
65
|
+
}
|
|
66
|
+
/** The plain message each sign-in failure shows (AK-19's closed code set). */
|
|
67
|
+
export const SIGN_IN_ERROR_MESSAGES = {
|
|
68
|
+
expired: "Your sign-in took too long. Please try again.",
|
|
69
|
+
cancelled: "Sign-in was cancelled.",
|
|
70
|
+
other: "Sign-in didn't complete. Please try again.",
|
|
71
|
+
};
|
|
72
|
+
const STORAGE_BLOCKED_MESSAGE = "This browser is blocking this site's storage, so you can't be signed in automatically. Please try again.";
|
|
73
|
+
const ME_PATH = authRoutePath(AUTH_ROUTE_PREFIX, "me");
|
|
74
|
+
const APPS_PATH = authRoutePath(AUTH_ROUTE_PREFIX, "apps");
|
|
75
|
+
const LOGOUT_PATH = authRoutePath(AUTH_ROUTE_PREFIX, "logout");
|
|
76
|
+
const LOGIN_PATH = authRoutePath(AUTH_ROUTE_PREFIX, "login");
|
|
77
|
+
function isSignInErrorCode(value) {
|
|
78
|
+
return SIGNIN_ERROR_CODES.includes(value);
|
|
79
|
+
}
|
|
80
|
+
function asError(err) {
|
|
81
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
82
|
+
}
|
|
83
|
+
export function createAuthSession(env) {
|
|
84
|
+
let state = { status: "checking" };
|
|
85
|
+
const listeners = new Set();
|
|
86
|
+
let started = false;
|
|
87
|
+
let teardown = [];
|
|
88
|
+
let channel = null;
|
|
89
|
+
/** Which load may still change state: every fresh load and every sign-out bumps it, and
|
|
90
|
+
* a load that finds it moved on drops its answer. */
|
|
91
|
+
let epoch = 0;
|
|
92
|
+
let retryTimer = null;
|
|
93
|
+
let retryAttempt = 0;
|
|
94
|
+
let claimTimer = null;
|
|
95
|
+
let checkInFlight = null;
|
|
96
|
+
let lastCheckedAt = 0;
|
|
97
|
+
/** The `signin_error` this page arrived with (read once, then stripped from the URL). */
|
|
98
|
+
let arrivedSignInError = null;
|
|
99
|
+
/** The user last verified — kept through an outage, for display and identity checks. */
|
|
100
|
+
let lastUser = null;
|
|
101
|
+
let lastApps = [];
|
|
102
|
+
let lastAppsError = null;
|
|
103
|
+
/** Set once this page has handed the browser to a top-level navigation. Until the
|
|
104
|
+
* page goes (or comes back from the back/forward cache) nothing may act on its behalf:
|
|
105
|
+
* a focus event in that moment must not re-check and show a false sign-in failure. */
|
|
106
|
+
let navigating = false;
|
|
107
|
+
let navigationStallTimer = null;
|
|
108
|
+
/** Loads started and not yet settled — a stale load's late refresh token is dropped
|
|
109
|
+
* only when no newer load shares that refresh (see `load`). */
|
|
110
|
+
let loadsInFlight = 0;
|
|
111
|
+
function setState(next) {
|
|
112
|
+
state = next;
|
|
113
|
+
for (const listener of listeners)
|
|
114
|
+
listener();
|
|
115
|
+
}
|
|
116
|
+
function clearTimer(timer) {
|
|
117
|
+
if (timer !== null)
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
// ── Storage-backed guard and claim ────────────────────────────────────────────────
|
|
122
|
+
/** The loop guard's record: when this tab last started a sign-in. `blocked` when
|
|
123
|
+
* sessionStorage can't be read — the guard can't be kept, so the tab must not
|
|
124
|
+
* redirect automatically (fail closed). */
|
|
125
|
+
function readAttempt() {
|
|
126
|
+
try {
|
|
127
|
+
const raw = env.sessionStorage().getItem(SIGN_IN_ATTEMPT_KEY);
|
|
128
|
+
const startedAt = raw === null ? null : Number(raw);
|
|
129
|
+
return {
|
|
130
|
+
blocked: false,
|
|
131
|
+
startedAt: Number.isFinite(startedAt) ? startedAt : null,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return { blocked: true };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Records a sign-in start; false when sessionStorage refuses. */
|
|
139
|
+
function writeAttempt() {
|
|
140
|
+
try {
|
|
141
|
+
env.sessionStorage().setItem(SIGN_IN_ATTEMPT_KEY, String(Date.now()));
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function clearAttempt() {
|
|
149
|
+
try {
|
|
150
|
+
env.sessionStorage().removeItem(SIGN_IN_ATTEMPT_KEY);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Nothing was recorded that could be read back either.
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** When another tab claimed the sign-in, if that claim is still live. A blocked
|
|
157
|
+
* localStorage means no claim — a courtesy lost, never correctness (every attempt
|
|
158
|
+
* has its own server-side cookie). */
|
|
159
|
+
function liveClaimAt() {
|
|
160
|
+
try {
|
|
161
|
+
const at = Number(env.localStorage().getItem(SIGN_IN_CLAIM_KEY));
|
|
162
|
+
return Number.isFinite(at) && at > 0 && Date.now() - at < SIGN_IN_CLAIM_MS
|
|
163
|
+
? at
|
|
164
|
+
: null;
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function writeClaim() {
|
|
171
|
+
try {
|
|
172
|
+
env.localStorage().setItem(SIGN_IN_CLAIM_KEY, String(Date.now()));
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// See liveClaimAt.
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function releaseClaim() {
|
|
179
|
+
try {
|
|
180
|
+
env.localStorage().removeItem(SIGN_IN_CLAIM_KEY);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// See liveClaimAt.
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// ── URLs ──────────────────────────────────────────────────────────────────────────
|
|
187
|
+
function navigate(url) {
|
|
188
|
+
navigating = true;
|
|
189
|
+
navigationStallTimer = clearTimer(navigationStallTimer);
|
|
190
|
+
navigationStallTimer = setTimeout(() => {
|
|
191
|
+
navigationStallTimer = null;
|
|
192
|
+
navigating = false;
|
|
193
|
+
}, NAVIGATION_STALL_MS);
|
|
194
|
+
env.navigate(url);
|
|
195
|
+
}
|
|
196
|
+
/** `GET {api}{prefix}/login`, carrying this page's `path?query#hash` when it is a
|
|
197
|
+
* safe return target. */
|
|
198
|
+
function loginUrl() {
|
|
199
|
+
const here = new URL(env.href());
|
|
200
|
+
const target = safeReturnTarget(`${here.pathname}${here.search}${here.hash}`);
|
|
201
|
+
const url = new URL(absoluteApiUrl(LOGIN_PATH, new URL(env.href()).origin));
|
|
202
|
+
if (target !== null)
|
|
203
|
+
url.searchParams.set(RETURN_TO_QUERY_PARAM, target);
|
|
204
|
+
return url.toString();
|
|
205
|
+
}
|
|
206
|
+
/** Reads and strips `signin_error` from the URL this page arrived with. */
|
|
207
|
+
function consumeArrivedSignInError() {
|
|
208
|
+
const url = new URL(env.href());
|
|
209
|
+
const raw = url.searchParams.get(SIGNIN_ERROR_QUERY_PARAM);
|
|
210
|
+
if (raw === null)
|
|
211
|
+
return null;
|
|
212
|
+
url.searchParams.delete(SIGNIN_ERROR_QUERY_PARAM);
|
|
213
|
+
env.replaceUrl(url.toString());
|
|
214
|
+
return isSignInErrorCode(raw) ? raw : "other";
|
|
215
|
+
}
|
|
216
|
+
// ── Transitions ───────────────────────────────────────────────────────────────────
|
|
217
|
+
function signInFailed(message) {
|
|
218
|
+
releaseClaim();
|
|
219
|
+
setState({
|
|
220
|
+
status: "error",
|
|
221
|
+
kind: "sign-in-failed",
|
|
222
|
+
error: new Error(message),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function loadFailed(err) {
|
|
226
|
+
retryAttempt = 0;
|
|
227
|
+
setState({ status: "error", kind: "load-failed", error: asError(err) });
|
|
228
|
+
}
|
|
229
|
+
/** The server says this browser has no session. */
|
|
230
|
+
function signedOutVerdict(reason) {
|
|
231
|
+
retryTimer = clearTimer(retryTimer);
|
|
232
|
+
retryAttempt = 0;
|
|
233
|
+
setAccessToken(null);
|
|
234
|
+
if (arrivedSignInError !== null) {
|
|
235
|
+
signInFailed(SIGN_IN_ERROR_MESSAGES[arrivedSignInError]);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const attempt = readAttempt();
|
|
239
|
+
if (attempt.blocked) {
|
|
240
|
+
signInFailed(STORAGE_BLOCKED_MESSAGE);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (attempt.startedAt !== null &&
|
|
244
|
+
Date.now() - attempt.startedAt < SIGN_IN_LOOP_WINDOW_MS) {
|
|
245
|
+
// Back from flytedesk ID (or Back from its page) and still signed out: never loop.
|
|
246
|
+
signInFailed(SIGN_IN_ERROR_MESSAGES.other);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
setState({ status: "signing-in", reason });
|
|
250
|
+
proceedToSignIn();
|
|
251
|
+
}
|
|
252
|
+
/** Navigates to flytedesk ID when this tab may: it is visible and no other tab holds a
|
|
253
|
+
* live sign-in claim. Otherwise it waits (a hidden tab re-checks when it becomes
|
|
254
|
+
* visible; a claim-blocked tab retries when the claim expires or on `signed-in`). */
|
|
255
|
+
function proceedToSignIn() {
|
|
256
|
+
if (state.status !== "signing-in" || !env.isVisible())
|
|
257
|
+
return;
|
|
258
|
+
const claimedAt = liveClaimAt();
|
|
259
|
+
if (claimedAt !== null) {
|
|
260
|
+
claimTimer = clearTimer(claimTimer);
|
|
261
|
+
claimTimer = setTimeout(() => {
|
|
262
|
+
claimTimer = null;
|
|
263
|
+
proceedToSignIn();
|
|
264
|
+
}, SIGN_IN_CLAIM_MS - (Date.now() - claimedAt));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (!writeAttempt()) {
|
|
268
|
+
signInFailed(STORAGE_BLOCKED_MESSAGE);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
writeClaim();
|
|
272
|
+
navigate(loginUrl());
|
|
273
|
+
}
|
|
274
|
+
function enterAuthenticated(user, apps, appsError) {
|
|
275
|
+
retryTimer = clearTimer(retryTimer);
|
|
276
|
+
claimTimer = clearTimer(claimTimer);
|
|
277
|
+
retryAttempt = 0;
|
|
278
|
+
lastCheckedAt = Date.now();
|
|
279
|
+
const justSignedIn = (() => {
|
|
280
|
+
const attempt = readAttempt();
|
|
281
|
+
return !attempt.blocked && attempt.startedAt !== null;
|
|
282
|
+
})();
|
|
283
|
+
arrivedSignInError = null;
|
|
284
|
+
lastUser = user;
|
|
285
|
+
lastApps = apps;
|
|
286
|
+
lastAppsError = appsError;
|
|
287
|
+
setState({ status: "authenticated", user, apps, appsError });
|
|
288
|
+
if (justSignedIn) {
|
|
289
|
+
// This tab just completed a sign-in round trip: tell the tabs waiting on it.
|
|
290
|
+
clearAttempt();
|
|
291
|
+
releaseClaim();
|
|
292
|
+
channel?.post({ type: "signed-in", userId: user.id });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function scheduleRetry(err) {
|
|
296
|
+
if (retryTimer !== null)
|
|
297
|
+
return;
|
|
298
|
+
const retryInMs = unavailableRetryDelayMs(retryAttempt);
|
|
299
|
+
retryAttempt += 1;
|
|
300
|
+
setState({
|
|
301
|
+
status: "unavailable",
|
|
302
|
+
user: lastUser,
|
|
303
|
+
apps: lastApps,
|
|
304
|
+
appsError: lastAppsError,
|
|
305
|
+
error: err,
|
|
306
|
+
retryInMs,
|
|
307
|
+
});
|
|
308
|
+
retryTimer = setTimeout(() => {
|
|
309
|
+
retryTimer = null;
|
|
310
|
+
void load({ show: false });
|
|
311
|
+
}, retryInMs);
|
|
312
|
+
}
|
|
313
|
+
/** The switcher feed, non-blocking (AK-23, N2): a failure is `apps: []` plus the error,
|
|
314
|
+
* never a failed load and never a session verdict. */
|
|
315
|
+
async function loadApps() {
|
|
316
|
+
try {
|
|
317
|
+
const res = await apiRequest(APPS_PATH, {
|
|
318
|
+
skipAuthRetry: true,
|
|
319
|
+
deadlineMs: AUTH_REQUEST_DEADLINE_MS,
|
|
320
|
+
});
|
|
321
|
+
return { apps: res.apps, error: null };
|
|
322
|
+
}
|
|
323
|
+
catch (err) {
|
|
324
|
+
return { apps: [], error: asError(err) };
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Verifies the session from the refresh cookie: `POST /refresh` (the shared,
|
|
329
|
+
* single-flighted one), then `/me`, then `/apps`. `show` puts up the checking state
|
|
330
|
+
* first (a fresh load); a retry keeps showing what it was showing until it has an
|
|
331
|
+
* answer. A refresh 401, or `/me` 401 right after a good refresh, is the verdict.
|
|
332
|
+
*/
|
|
333
|
+
async function load({ show }) {
|
|
334
|
+
epoch += 1;
|
|
335
|
+
loadsInFlight += 1;
|
|
336
|
+
const mine = epoch;
|
|
337
|
+
const current = () => mine === epoch;
|
|
338
|
+
claimTimer = clearTimer(claimTimer);
|
|
339
|
+
if (show) {
|
|
340
|
+
retryTimer = clearTimer(retryTimer);
|
|
341
|
+
retryAttempt = 0;
|
|
342
|
+
setState({ status: "checking" });
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
const token = await refreshAccessToken();
|
|
346
|
+
if (!current()) {
|
|
347
|
+
// A newer decision owns the state. The shared refresh stored its token as it
|
|
348
|
+
// landed. When a newer LOAD is in flight it shares that same refresh and needs
|
|
349
|
+
// the token, so it is left alone. When none is, and the decision is that this tab
|
|
350
|
+
// holds no session (signed out elsewhere, signing out), the late token must not
|
|
351
|
+
// linger in memory.
|
|
352
|
+
const noSession = state.status !== "authenticated" && state.status !== "unavailable";
|
|
353
|
+
if (loadsInFlight === 1 && noSession)
|
|
354
|
+
setAccessToken(null);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (token === null) {
|
|
358
|
+
signedOutVerdict(lastUser === null ? "signed-out" : "expired");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const me = await apiRequest(ME_PATH, {
|
|
362
|
+
skipAuthRetry: true,
|
|
363
|
+
deadlineMs: AUTH_REQUEST_DEADLINE_MS,
|
|
364
|
+
});
|
|
365
|
+
if (!current())
|
|
366
|
+
return;
|
|
367
|
+
if (lastUser !== null && me.user.id !== lastUser.id) {
|
|
368
|
+
// Another tab signed this browser in as someone else: nothing this page holds in
|
|
369
|
+
// memory may be shown as the new user.
|
|
370
|
+
env.reload();
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const feed = await loadApps();
|
|
374
|
+
if (!current())
|
|
375
|
+
return;
|
|
376
|
+
enterAuthenticated(me.user, feed.apps, feed.error);
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
if (!current())
|
|
380
|
+
return;
|
|
381
|
+
if (err instanceof AuthUnavailableError) {
|
|
382
|
+
scheduleRetry(err);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (err instanceof ApiRequestError && err.status === 401) {
|
|
386
|
+
signedOutVerdict(lastUser === null ? "signed-out" : "expired");
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
loadFailed(err);
|
|
390
|
+
}
|
|
391
|
+
finally {
|
|
392
|
+
loadsInFlight -= 1;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
/** One cheap verification of a signed-in session — `GET /me` through the normal
|
|
396
|
+
* 401 -> refresh -> retry path, so a refused refresh ends the session through
|
|
397
|
+
* `onSessionEnded` and an outage becomes `unavailable` through `onAuthUnavailable`.
|
|
398
|
+
* Single-flighted per tab. A failure that is neither a verdict nor an outage (a 500)
|
|
399
|
+
* changes nothing: the next check tries again. */
|
|
400
|
+
function check() {
|
|
401
|
+
if (state.status !== "authenticated")
|
|
402
|
+
return Promise.resolve();
|
|
403
|
+
checkInFlight ??= (async () => {
|
|
404
|
+
const mine = epoch;
|
|
405
|
+
try {
|
|
406
|
+
const me = await apiRequest(ME_PATH, {
|
|
407
|
+
deadlineMs: AUTH_REQUEST_DEADLINE_MS,
|
|
408
|
+
});
|
|
409
|
+
if (mine !== epoch || state.status !== "authenticated")
|
|
410
|
+
return;
|
|
411
|
+
lastCheckedAt = Date.now();
|
|
412
|
+
if (me.user.id !== state.user.id) {
|
|
413
|
+
env.reload();
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
lastUser = me.user;
|
|
417
|
+
setState({ ...state, user: me.user });
|
|
418
|
+
}
|
|
419
|
+
catch (err) {
|
|
420
|
+
// A refused refresh (onSessionEnded) and an outage (onAuthUnavailable) have
|
|
421
|
+
// already moved the state. What is left to decide here: `/me` answering 401
|
|
422
|
+
// after a SUCCESSFUL refresh is the same verdict `load` treats it as.
|
|
423
|
+
const stillCurrent = mine === epoch && state.status === "authenticated";
|
|
424
|
+
if (stillCurrent &&
|
|
425
|
+
err instanceof ApiRequestError &&
|
|
426
|
+
!(err instanceof AuthUnavailableError) &&
|
|
427
|
+
err.status === 401) {
|
|
428
|
+
signedOutVerdict("expired");
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
finally {
|
|
432
|
+
checkInFlight = null;
|
|
433
|
+
}
|
|
434
|
+
})();
|
|
435
|
+
return checkInFlight;
|
|
436
|
+
}
|
|
437
|
+
// ── Events ────────────────────────────────────────────────────────────────────────
|
|
438
|
+
function onAttention() {
|
|
439
|
+
if (navigating)
|
|
440
|
+
return;
|
|
441
|
+
if (state.status === "signing-in") {
|
|
442
|
+
// Another tab may have signed in while this one waited: check before navigating.
|
|
443
|
+
void load({ show: false });
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (state.status === "authenticated" &&
|
|
447
|
+
Date.now() - lastCheckedAt >= FOCUS_CHECK_MIN_INTERVAL_MS) {
|
|
448
|
+
void check();
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function onMessage(message) {
|
|
452
|
+
if (navigating)
|
|
453
|
+
return;
|
|
454
|
+
if (message.type === "signed-in") {
|
|
455
|
+
if (state.status === "authenticated") {
|
|
456
|
+
if (state.user.id !== message.userId)
|
|
457
|
+
env.reload();
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (state.status !== "signing-out")
|
|
461
|
+
void load({ show: false });
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
// signed-out: another tab signed this browser out.
|
|
465
|
+
if (state.status === "signing-out")
|
|
466
|
+
return;
|
|
467
|
+
epoch += 1;
|
|
468
|
+
retryTimer = clearTimer(retryTimer);
|
|
469
|
+
setAccessToken(null);
|
|
470
|
+
lastUser = null;
|
|
471
|
+
setState({ status: "signing-in", reason: "signed-out" });
|
|
472
|
+
proceedToSignIn();
|
|
473
|
+
}
|
|
474
|
+
function start() {
|
|
475
|
+
if (started)
|
|
476
|
+
return;
|
|
477
|
+
started = true;
|
|
478
|
+
arrivedSignInError = consumeArrivedSignInError();
|
|
479
|
+
channel = env.openChannel(onMessage);
|
|
480
|
+
teardown = [
|
|
481
|
+
onSessionEnded(() => {
|
|
482
|
+
if (state.status !== "authenticated" && state.status !== "unavailable")
|
|
483
|
+
return;
|
|
484
|
+
epoch += 1;
|
|
485
|
+
signedOutVerdict("expired");
|
|
486
|
+
}),
|
|
487
|
+
onAuthUnavailable((err) => {
|
|
488
|
+
if (state.status === "authenticated")
|
|
489
|
+
scheduleRetry(err);
|
|
490
|
+
}),
|
|
491
|
+
env.onAttention(onAttention),
|
|
492
|
+
env.onRestore(() => {
|
|
493
|
+
navigating = false;
|
|
494
|
+
navigationStallTimer = clearTimer(navigationStallTimer);
|
|
495
|
+
void load({ show: true });
|
|
496
|
+
}),
|
|
497
|
+
(() => {
|
|
498
|
+
const timer = setInterval(() => {
|
|
499
|
+
if (env.isVisible())
|
|
500
|
+
void check();
|
|
501
|
+
}, SESSION_CHECK_INTERVAL_MS);
|
|
502
|
+
return () => clearInterval(timer);
|
|
503
|
+
})(),
|
|
504
|
+
];
|
|
505
|
+
void load({ show: true });
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
getSnapshot() {
|
|
509
|
+
return state;
|
|
510
|
+
},
|
|
511
|
+
subscribe(listener) {
|
|
512
|
+
listeners.add(listener);
|
|
513
|
+
start();
|
|
514
|
+
return () => {
|
|
515
|
+
listeners.delete(listener);
|
|
516
|
+
};
|
|
517
|
+
},
|
|
518
|
+
async signOut() {
|
|
519
|
+
if (state.status !== "authenticated" && state.status !== "unavailable") {
|
|
520
|
+
throw new Error(`Cannot sign out while ${state.status}`);
|
|
521
|
+
}
|
|
522
|
+
epoch += 1;
|
|
523
|
+
retryTimer = clearTimer(retryTimer);
|
|
524
|
+
setState({ status: "signing-out" });
|
|
525
|
+
let endSessionUrl;
|
|
526
|
+
try {
|
|
527
|
+
const res = await apiRequest(LOGOUT_PATH, {
|
|
528
|
+
method: "POST",
|
|
529
|
+
skipAuthRetry: true,
|
|
530
|
+
deadlineMs: AUTH_REQUEST_DEADLINE_MS,
|
|
531
|
+
});
|
|
532
|
+
endSessionUrl = res.endSessionUrl;
|
|
533
|
+
}
|
|
534
|
+
catch (err) {
|
|
535
|
+
const carried = err instanceof ApiRequestError ? err.body.endSessionUrl : undefined;
|
|
536
|
+
if (typeof carried !== "string") {
|
|
537
|
+
// The server did not end the session (or we can't tell): find out what it is.
|
|
538
|
+
void load({ show: false });
|
|
539
|
+
throw err;
|
|
540
|
+
}
|
|
541
|
+
// 502 logout_store_failed: the session is over anyway (its cookie is cleared).
|
|
542
|
+
endSessionUrl = carried;
|
|
543
|
+
}
|
|
544
|
+
setAccessToken(null);
|
|
545
|
+
lastUser = null;
|
|
546
|
+
channel?.post({ type: "signed-out" });
|
|
547
|
+
navigate(endSessionUrl);
|
|
548
|
+
},
|
|
549
|
+
retry() {
|
|
550
|
+
if (state.status !== "error")
|
|
551
|
+
return;
|
|
552
|
+
if (state.kind === "load-failed") {
|
|
553
|
+
void load({ show: true });
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
arrivedSignInError = null;
|
|
557
|
+
writeAttempt();
|
|
558
|
+
navigate(loginUrl());
|
|
559
|
+
},
|
|
560
|
+
async refreshUser() {
|
|
561
|
+
// A check already in flight may have read the user before the change being
|
|
562
|
+
// refreshed for: wait it out, then read again.
|
|
563
|
+
if (checkInFlight)
|
|
564
|
+
await checkInFlight;
|
|
565
|
+
await check();
|
|
566
|
+
},
|
|
567
|
+
stop() {
|
|
568
|
+
for (const undo of teardown)
|
|
569
|
+
undo();
|
|
570
|
+
teardown = [];
|
|
571
|
+
channel?.close();
|
|
572
|
+
channel = null;
|
|
573
|
+
retryTimer = clearTimer(retryTimer);
|
|
574
|
+
claimTimer = clearTimer(claimTimer);
|
|
575
|
+
navigationStallTimer = clearTimer(navigationStallTimer);
|
|
576
|
+
listeners.clear();
|
|
577
|
+
started = false;
|
|
578
|
+
},
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
//# sourceMappingURL=authSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authSession.js","sourceRoot":"","sources":["../../../src/auth/client/authSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The real browser behind `./authSession.ts`'s `AuthSessionEnvironment` (AK-35), and the
|
|
3
|
+
* one per-tab `authSession` every app reads. Browser-safe, ZERO Node imports.
|
|
4
|
+
*
|
|
5
|
+
* This package's tsconfig deliberately has no "DOM" lib (it is Node-first — see
|
|
6
|
+
* `./httpClient.ts`'s own `declare const window`), so the few browser globals used here
|
|
7
|
+
* are declared below with exactly the members this file touches. The declarations are
|
|
8
|
+
* erased at compile time and resolve to the real browser objects at runtime.
|
|
9
|
+
*/
|
|
10
|
+
import { type AuthSessionController, type AuthSessionEnvironment } from "./authSession.js";
|
|
11
|
+
export declare function browserEnvironment(): AuthSessionEnvironment;
|
|
12
|
+
/**
|
|
13
|
+
* THE session of this tab — one lifecycle, however many components or modules read it.
|
|
14
|
+
* Created on first use (never at import, so importing this module is safe during SSR or
|
|
15
|
+
* in a Node test). React code reads it through `useAuthSession()`; anything else (an
|
|
16
|
+
* API helper, a store outside React) through `authSession.getSnapshot()` and
|
|
17
|
+
* `authSession.subscribe()`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const authSession: Omit<AuthSessionController, "stop">;
|
|
20
|
+
/** Test seam (`@flytedesk/app-kit/auth/client/testing`): stops and forgets the tab's
|
|
21
|
+
* lifecycle, so the next use starts a fresh one. */
|
|
22
|
+
export declare function resetAuthSession(): void;
|