@orangecheck/auth-client 2.17.1 → 2.18.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/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +224 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +216 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -31,6 +31,7 @@ interface OcSessionState {
|
|
|
31
31
|
status: OcSessionStatus;
|
|
32
32
|
account: OcAccount | null;
|
|
33
33
|
roster: OcAccountSummary[];
|
|
34
|
+
tabPinned: boolean;
|
|
34
35
|
error: Error | null;
|
|
35
36
|
refresh: () => Promise<void>;
|
|
36
37
|
signOut: (opts?: {
|
|
@@ -152,6 +153,20 @@ interface OcLinkedIdentitiesProps {
|
|
|
152
153
|
}
|
|
153
154
|
declare function OcLinkedIdentities({ authOrigin, className, onChange, }: OcLinkedIdentitiesProps): React.ReactElement;
|
|
154
155
|
|
|
156
|
+
declare const TAB_SESSION_HEADER = "x-oc-tab-session";
|
|
157
|
+
declare const TAB_SESSION_STORAGE_KEY = "oc_tab_session";
|
|
158
|
+
declare const TAB_ADOPT_HASH = "#oc-adopt";
|
|
159
|
+
interface OcTabSession {
|
|
160
|
+
token: string;
|
|
161
|
+
didOc: string;
|
|
162
|
+
}
|
|
163
|
+
declare function readTabSession(): OcTabSession | null;
|
|
164
|
+
declare function writeTabSession(session: OcTabSession): void;
|
|
165
|
+
declare function clearTabSession(): void;
|
|
166
|
+
declare function tabSessionHeader(): Record<string, string>;
|
|
167
|
+
declare function installTabFetchInterceptor(authOrigin: string): () => void;
|
|
168
|
+
declare function consumeTabAdoptMarker(): boolean;
|
|
169
|
+
|
|
155
170
|
interface WebAuthnCredentialPublic {
|
|
156
171
|
id: string;
|
|
157
172
|
label: string;
|
|
@@ -234,4 +249,4 @@ declare function handleSudoRequired(body: {
|
|
|
234
249
|
returnTo?: string;
|
|
235
250
|
}): boolean;
|
|
236
251
|
|
|
237
|
-
export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type RedirectToSudoArgs, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, buildAddAccountUrl, buildSignInUrl, fetchOcLinkedIdentities, handleSudoRequired, redirectToSudo, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister };
|
|
252
|
+
export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAdoptMarker, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, readTabSession, redirectToSudo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ interface OcSessionState {
|
|
|
31
31
|
status: OcSessionStatus;
|
|
32
32
|
account: OcAccount | null;
|
|
33
33
|
roster: OcAccountSummary[];
|
|
34
|
+
tabPinned: boolean;
|
|
34
35
|
error: Error | null;
|
|
35
36
|
refresh: () => Promise<void>;
|
|
36
37
|
signOut: (opts?: {
|
|
@@ -152,6 +153,20 @@ interface OcLinkedIdentitiesProps {
|
|
|
152
153
|
}
|
|
153
154
|
declare function OcLinkedIdentities({ authOrigin, className, onChange, }: OcLinkedIdentitiesProps): React.ReactElement;
|
|
154
155
|
|
|
156
|
+
declare const TAB_SESSION_HEADER = "x-oc-tab-session";
|
|
157
|
+
declare const TAB_SESSION_STORAGE_KEY = "oc_tab_session";
|
|
158
|
+
declare const TAB_ADOPT_HASH = "#oc-adopt";
|
|
159
|
+
interface OcTabSession {
|
|
160
|
+
token: string;
|
|
161
|
+
didOc: string;
|
|
162
|
+
}
|
|
163
|
+
declare function readTabSession(): OcTabSession | null;
|
|
164
|
+
declare function writeTabSession(session: OcTabSession): void;
|
|
165
|
+
declare function clearTabSession(): void;
|
|
166
|
+
declare function tabSessionHeader(): Record<string, string>;
|
|
167
|
+
declare function installTabFetchInterceptor(authOrigin: string): () => void;
|
|
168
|
+
declare function consumeTabAdoptMarker(): boolean;
|
|
169
|
+
|
|
155
170
|
interface WebAuthnCredentialPublic {
|
|
156
171
|
id: string;
|
|
157
172
|
label: string;
|
|
@@ -234,4 +249,4 @@ declare function handleSudoRequired(body: {
|
|
|
234
249
|
returnTo?: string;
|
|
235
250
|
}): boolean;
|
|
236
251
|
|
|
237
|
-
export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type RedirectToSudoArgs, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, buildAddAccountUrl, buildSignInUrl, fetchOcLinkedIdentities, handleSudoRequired, redirectToSudo, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister };
|
|
252
|
+
export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, type UseOcAddressSuggestionOptions, type UseOcAddressSuggestionReturn, type UseStepUpAuthReturn, type UseWebAuthnListReturn, type UseWebAuthnRegisterReturn, type WebAuthnAssertionStatus, type WebAuthnCredentialPublic, type WebAuthnListStatus, type WebAuthnRegisterResult, type WebAuthnRegisterStatus, type WebAuthnRemoveResult, type WebAuthnRenameResult, type WebAuthnStepUpResult, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAdoptMarker, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, readTabSession, redirectToSudo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,91 @@ function buildAddAccountUrl(cfg, returnTo) {
|
|
|
49
49
|
u.searchParams.set("add", "1");
|
|
50
50
|
return u.toString();
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
// src/tab-session.ts
|
|
54
|
+
var TAB_SESSION_HEADER = "x-oc-tab-session";
|
|
55
|
+
var TAB_SESSION_STORAGE_KEY = "oc_tab_session";
|
|
56
|
+
var TAB_ADOPT_HASH = "#oc-adopt";
|
|
57
|
+
function readTabSession() {
|
|
58
|
+
if (typeof window === "undefined") return null;
|
|
59
|
+
try {
|
|
60
|
+
const raw = window.sessionStorage.getItem(TAB_SESSION_STORAGE_KEY);
|
|
61
|
+
if (!raw) return null;
|
|
62
|
+
const parsed = JSON.parse(raw);
|
|
63
|
+
if (typeof parsed.token !== "string" || parsed.token.length === 0) return null;
|
|
64
|
+
if (typeof parsed.didOc !== "string" || parsed.didOc.length === 0) return null;
|
|
65
|
+
return { token: parsed.token, didOc: parsed.didOc };
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function writeTabSession(session) {
|
|
71
|
+
if (typeof window === "undefined") return;
|
|
72
|
+
try {
|
|
73
|
+
window.sessionStorage.setItem(TAB_SESSION_STORAGE_KEY, JSON.stringify(session));
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function clearTabSession() {
|
|
78
|
+
if (typeof window === "undefined") return;
|
|
79
|
+
try {
|
|
80
|
+
window.sessionStorage.removeItem(TAB_SESSION_STORAGE_KEY);
|
|
81
|
+
} catch {
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function tabSessionHeader() {
|
|
85
|
+
const pin = readTabSession();
|
|
86
|
+
return pin ? { [TAB_SESSION_HEADER]: pin.token } : {};
|
|
87
|
+
}
|
|
88
|
+
function isPinnableUrl(url, authOrigin) {
|
|
89
|
+
if (typeof window === "undefined") return false;
|
|
90
|
+
try {
|
|
91
|
+
const u = new URL(url, window.location.href);
|
|
92
|
+
return u.origin === window.location.origin || u.origin === authOrigin;
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function installTabFetchInterceptor(authOrigin) {
|
|
98
|
+
if (typeof window === "undefined") return () => {
|
|
99
|
+
};
|
|
100
|
+
const original = window.fetch;
|
|
101
|
+
const wrapped = (input, init) => {
|
|
102
|
+
try {
|
|
103
|
+
const pin = readTabSession();
|
|
104
|
+
if (pin) {
|
|
105
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
106
|
+
if (isPinnableUrl(url, authOrigin)) {
|
|
107
|
+
const headers = new Headers(
|
|
108
|
+
init?.headers ?? (input instanceof Request ? input.headers : void 0)
|
|
109
|
+
);
|
|
110
|
+
if (!headers.has("authorization") && !headers.has(TAB_SESSION_HEADER)) {
|
|
111
|
+
headers.set(TAB_SESSION_HEADER, pin.token);
|
|
112
|
+
init = { ...init, headers };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
return original.call(window, input, init);
|
|
119
|
+
};
|
|
120
|
+
window.fetch = wrapped;
|
|
121
|
+
return () => {
|
|
122
|
+
if (window.fetch === wrapped) window.fetch = original;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function consumeTabAdoptMarker() {
|
|
126
|
+
if (typeof window === "undefined") return false;
|
|
127
|
+
if (!window.location.hash.includes(TAB_ADOPT_HASH.slice(1))) return false;
|
|
128
|
+
clearTabSession();
|
|
129
|
+
try {
|
|
130
|
+
const url = new URL(window.location.href);
|
|
131
|
+
url.hash = "";
|
|
132
|
+
window.history.replaceState(window.history.state, "", url.toString());
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
52
137
|
var SessionContext = React3__namespace.createContext(null);
|
|
53
138
|
function normalizeDisplayIdentity(raw, didOc) {
|
|
54
139
|
const di = raw.display_identity ?? raw.displayIdentity;
|
|
@@ -70,6 +155,20 @@ function normalizeRosterEntry(raw) {
|
|
|
70
155
|
lastSeenAt: raw.last_seen_at ?? raw.lastSeenAt ?? null
|
|
71
156
|
};
|
|
72
157
|
}
|
|
158
|
+
async function fetchHostRoster(cfg) {
|
|
159
|
+
try {
|
|
160
|
+
const res = await fetch(`${cfg.authOrigin}${cfg.mePath}`, {
|
|
161
|
+
method: "GET",
|
|
162
|
+
credentials: "include",
|
|
163
|
+
headers: { Accept: "application/json", ...tabSessionHeader() }
|
|
164
|
+
});
|
|
165
|
+
if (!res.ok) return [];
|
|
166
|
+
const body = await res.json();
|
|
167
|
+
return Array.isArray(body.roster) ? body.roster.map(normalizeRosterEntry).filter((r) => r !== null) : [];
|
|
168
|
+
} catch {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
73
172
|
function normalizeAccount(raw) {
|
|
74
173
|
if (!raw) return null;
|
|
75
174
|
const didOc = raw.did_oc ?? raw.didOc;
|
|
@@ -98,14 +197,50 @@ function OcSessionProvider({
|
|
|
98
197
|
const [roster, setRoster] = React3__namespace.useState([]);
|
|
99
198
|
const [status, setStatus] = React3__namespace.useState("loading");
|
|
100
199
|
const [error, setError] = React3__namespace.useState(null);
|
|
200
|
+
const [tabPinned, setTabPinned] = React3__namespace.useState(false);
|
|
201
|
+
const pinInFlightRef = React3__namespace.useRef(false);
|
|
202
|
+
const pinThisTab = React3__namespace.useCallback(
|
|
203
|
+
async (didOc) => {
|
|
204
|
+
if (pinInFlightRef.current || readTabSession()) return;
|
|
205
|
+
pinInFlightRef.current = true;
|
|
206
|
+
try {
|
|
207
|
+
const res = await fetch(`${cfg.authOrigin}/api/auth/tab`, {
|
|
208
|
+
method: "POST",
|
|
209
|
+
credentials: "include",
|
|
210
|
+
headers: { Accept: "application/json" }
|
|
211
|
+
});
|
|
212
|
+
if (!res.ok) return;
|
|
213
|
+
const body = await res.json();
|
|
214
|
+
if (body.ok && typeof body.token === "string" && body.account?.did_oc === didOc) {
|
|
215
|
+
writeTabSession({ token: body.token, didOc });
|
|
216
|
+
setTabPinned(true);
|
|
217
|
+
}
|
|
218
|
+
} catch {
|
|
219
|
+
} finally {
|
|
220
|
+
pinInFlightRef.current = false;
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
[cfg.authOrigin]
|
|
224
|
+
);
|
|
101
225
|
const refresh = React3__namespace.useCallback(async () => {
|
|
102
226
|
if (typeof window === "undefined") return;
|
|
103
227
|
try {
|
|
104
|
-
|
|
228
|
+
let pin = readTabSession();
|
|
229
|
+
let res = await fetch(cfg.mePath, {
|
|
105
230
|
method: "GET",
|
|
106
231
|
credentials: "include",
|
|
107
|
-
headers: { Accept: "application/json" }
|
|
232
|
+
headers: { Accept: "application/json", ...tabSessionHeader() }
|
|
108
233
|
});
|
|
234
|
+
if (res.status === 401 && pin) {
|
|
235
|
+
clearTabSession();
|
|
236
|
+
pin = null;
|
|
237
|
+
setTabPinned(false);
|
|
238
|
+
res = await fetch(cfg.mePath, {
|
|
239
|
+
method: "GET",
|
|
240
|
+
credentials: "include",
|
|
241
|
+
headers: { Accept: "application/json" }
|
|
242
|
+
});
|
|
243
|
+
}
|
|
109
244
|
if (res.status === 401) {
|
|
110
245
|
setAccount(null);
|
|
111
246
|
setRoster([]);
|
|
@@ -120,19 +255,32 @@ function OcSessionProvider({
|
|
|
120
255
|
}
|
|
121
256
|
const body = await res.json();
|
|
122
257
|
const acct = normalizeAccount(body.account);
|
|
258
|
+
if (acct && pin && acct.didOc !== pin.didOc) {
|
|
259
|
+
clearTabSession();
|
|
260
|
+
pin = null;
|
|
261
|
+
}
|
|
262
|
+
setTabPinned(pin !== null);
|
|
123
263
|
const rosterEntries = Array.isArray(body.roster) ? body.roster.map(normalizeRosterEntry).filter((r) => r !== null) : [];
|
|
124
264
|
setAccount(acct);
|
|
125
265
|
setRoster(rosterEntries);
|
|
126
266
|
setStatus(acct ? "authenticated" : "anonymous");
|
|
127
267
|
setError(null);
|
|
268
|
+
if (acct && !pin) void pinThisTab(acct.didOc);
|
|
269
|
+
const currentOrigin = typeof window !== "undefined" ? window.location.origin : null;
|
|
270
|
+
if (acct && rosterEntries.length === 0 && currentOrigin !== null && !cfg.authOrigin.startsWith(currentOrigin)) {
|
|
271
|
+
const peers = await fetchHostRoster(cfg);
|
|
272
|
+
if (peers.length > 0) setRoster(peers);
|
|
273
|
+
}
|
|
128
274
|
} catch (err) {
|
|
129
275
|
setStatus("error");
|
|
130
276
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
131
277
|
}
|
|
132
|
-
}, [cfg
|
|
278
|
+
}, [cfg, pinThisTab]);
|
|
133
279
|
React3__namespace.useEffect(() => {
|
|
280
|
+
consumeTabAdoptMarker();
|
|
134
281
|
void refresh();
|
|
135
282
|
}, [refresh]);
|
|
283
|
+
React3__namespace.useEffect(() => installTabFetchInterceptor(cfg.authOrigin), [cfg.authOrigin]);
|
|
136
284
|
const signOut = React3__namespace.useCallback(
|
|
137
285
|
async (opts) => {
|
|
138
286
|
const scope = opts?.scope ?? "all";
|
|
@@ -142,6 +290,10 @@ function OcSessionProvider({
|
|
|
142
290
|
const res = await fetch(url.toString(), {
|
|
143
291
|
method: "POST",
|
|
144
292
|
credentials: "include",
|
|
293
|
+
// Per-tab · carry the pin so scope='current' signs out
|
|
294
|
+
// the account THIS tab is operating as, not whichever
|
|
295
|
+
// account the shared cookie happens to point at.
|
|
296
|
+
headers: { ...tabSessionHeader() },
|
|
145
297
|
// `keepalive` lets the logout round-trip complete even if
|
|
146
298
|
// the caller hard-navigates away in the same tick (e.g.
|
|
147
299
|
// `<OcAccountMenu>` redirects home immediately on sign-out).
|
|
@@ -149,11 +301,15 @@ function OcSessionProvider({
|
|
|
149
301
|
// and the `.ochk.io` cookie may never get cleared.
|
|
150
302
|
keepalive: true
|
|
151
303
|
});
|
|
304
|
+
clearTabSession();
|
|
305
|
+
setTabPinned(false);
|
|
152
306
|
if (scope === "current" && res.ok) {
|
|
153
307
|
await refresh();
|
|
154
308
|
return;
|
|
155
309
|
}
|
|
156
310
|
} catch {
|
|
311
|
+
clearTabSession();
|
|
312
|
+
setTabPinned(false);
|
|
157
313
|
}
|
|
158
314
|
setAccount(null);
|
|
159
315
|
setRoster([]);
|
|
@@ -167,7 +323,7 @@ function OcSessionProvider({
|
|
|
167
323
|
const res = await fetch(`${cfg.authOrigin}/api/auth/switch`, {
|
|
168
324
|
method: "POST",
|
|
169
325
|
credentials: "include",
|
|
170
|
-
headers: { "Content-Type": "application/json" },
|
|
326
|
+
headers: { "Content-Type": "application/json", ...tabSessionHeader() },
|
|
171
327
|
body: JSON.stringify({ did_oc: didOc })
|
|
172
328
|
});
|
|
173
329
|
if (!res.ok) {
|
|
@@ -179,6 +335,14 @@ function OcSessionProvider({
|
|
|
179
335
|
}
|
|
180
336
|
throw new Error(`[@orangecheck/auth-client] switchAccount failed: ${reason}`);
|
|
181
337
|
}
|
|
338
|
+
try {
|
|
339
|
+
const body = await res.json();
|
|
340
|
+
if (typeof body.token === "string" && body.account?.did_oc) {
|
|
341
|
+
writeTabSession({ token: body.token, didOc: body.account.did_oc });
|
|
342
|
+
setTabPinned(true);
|
|
343
|
+
}
|
|
344
|
+
} catch {
|
|
345
|
+
}
|
|
182
346
|
await refresh();
|
|
183
347
|
},
|
|
184
348
|
[cfg.authOrigin, refresh]
|
|
@@ -196,7 +360,7 @@ function OcSessionProvider({
|
|
|
196
360
|
const res = await fetch(`${cfg.authOrigin}/api/auth/account`, {
|
|
197
361
|
method: "PATCH",
|
|
198
362
|
credentials: "include",
|
|
199
|
-
headers: { "Content-Type": "application/json" },
|
|
363
|
+
headers: { "Content-Type": "application/json", ...tabSessionHeader() },
|
|
200
364
|
body: JSON.stringify({ display_identity: kind })
|
|
201
365
|
});
|
|
202
366
|
if (!res.ok) {
|
|
@@ -208,6 +372,14 @@ function OcSessionProvider({
|
|
|
208
372
|
}
|
|
209
373
|
throw new Error(`[@orangecheck/auth-client] setDisplayIdentity failed: ${reason}`);
|
|
210
374
|
}
|
|
375
|
+
try {
|
|
376
|
+
const body = await res.json();
|
|
377
|
+
const pin = readTabSession();
|
|
378
|
+
if (pin && typeof body.token === "string" && body.account?.did_oc === pin.didOc) {
|
|
379
|
+
writeTabSession({ token: body.token, didOc: pin.didOc });
|
|
380
|
+
}
|
|
381
|
+
} catch {
|
|
382
|
+
}
|
|
211
383
|
await refresh();
|
|
212
384
|
},
|
|
213
385
|
[cfg.authOrigin, refresh]
|
|
@@ -218,6 +390,7 @@ function OcSessionProvider({
|
|
|
218
390
|
status,
|
|
219
391
|
account,
|
|
220
392
|
roster,
|
|
393
|
+
tabPinned,
|
|
221
394
|
error,
|
|
222
395
|
refresh,
|
|
223
396
|
signOut,
|
|
@@ -230,6 +403,7 @@ function OcSessionProvider({
|
|
|
230
403
|
status,
|
|
231
404
|
account,
|
|
232
405
|
roster,
|
|
406
|
+
tabPinned,
|
|
233
407
|
error,
|
|
234
408
|
refresh,
|
|
235
409
|
signOut,
|
|
@@ -1755,6 +1929,18 @@ function safeReturnTo(input) {
|
|
|
1755
1929
|
if (!candidate.startsWith("/") || candidate.startsWith("//")) return "/";
|
|
1756
1930
|
return candidate;
|
|
1757
1931
|
}
|
|
1932
|
+
function familyReturnTarget(input) {
|
|
1933
|
+
if (typeof input !== "string" || input.length === 0) return void 0;
|
|
1934
|
+
if (input.startsWith("/") && !input.startsWith("//")) return input;
|
|
1935
|
+
try {
|
|
1936
|
+
const u = new URL(input);
|
|
1937
|
+
if (u.protocol !== "https:") return void 0;
|
|
1938
|
+
const host = u.hostname.toLowerCase();
|
|
1939
|
+
if (host === "ochk.io" || host.endsWith(".ochk.io")) return u.toString();
|
|
1940
|
+
} catch {
|
|
1941
|
+
}
|
|
1942
|
+
return void 0;
|
|
1943
|
+
}
|
|
1758
1944
|
function hardNavigate(target) {
|
|
1759
1945
|
if (typeof window === "undefined") return;
|
|
1760
1946
|
window.location.assign(target);
|
|
@@ -1773,7 +1959,20 @@ function OcSignIn({
|
|
|
1773
1959
|
}) {
|
|
1774
1960
|
const walletEnabled = paths?.wallet ?? true;
|
|
1775
1961
|
const emailEnabled = paths?.email ?? true;
|
|
1776
|
-
const
|
|
1962
|
+
const [resolvedReturn, setResolvedReturn] = React3__namespace.useState(
|
|
1963
|
+
() => familyReturnTarget(returnTo) ?? safeReturnTo(returnTo)
|
|
1964
|
+
);
|
|
1965
|
+
React3__namespace.useEffect(() => {
|
|
1966
|
+
const fromProp = familyReturnTarget(returnTo);
|
|
1967
|
+
if (fromProp) {
|
|
1968
|
+
setResolvedReturn(fromProp);
|
|
1969
|
+
return;
|
|
1970
|
+
}
|
|
1971
|
+
if (typeof window === "undefined") return;
|
|
1972
|
+
const q = new URLSearchParams(window.location.search);
|
|
1973
|
+
const fromQuery = familyReturnTarget(q.get("return_to")) ?? familyReturnTarget(q.get("next"));
|
|
1974
|
+
setResolvedReturn(fromQuery ?? "/");
|
|
1975
|
+
}, [returnTo]);
|
|
1777
1976
|
const [addMode, setAddMode] = React3__namespace.useState(Boolean(addProp));
|
|
1778
1977
|
React3__namespace.useEffect(() => {
|
|
1779
1978
|
if (typeof window === "undefined") return;
|
|
@@ -1797,18 +1996,20 @@ function OcSignIn({
|
|
|
1797
1996
|
async (account) => {
|
|
1798
1997
|
if (resolveReturnTo) {
|
|
1799
1998
|
try {
|
|
1800
|
-
|
|
1999
|
+
const resolved = familyReturnTarget(await resolveReturnTo(account));
|
|
2000
|
+
hardNavigate(resolved ?? resolvedReturn);
|
|
1801
2001
|
return;
|
|
1802
2002
|
} catch {
|
|
1803
2003
|
}
|
|
1804
2004
|
}
|
|
1805
|
-
hardNavigate(
|
|
2005
|
+
hardNavigate(resolvedReturn);
|
|
1806
2006
|
},
|
|
1807
|
-
[resolveReturnTo,
|
|
2007
|
+
[resolveReturnTo, resolvedReturn]
|
|
1808
2008
|
);
|
|
1809
2009
|
const handleSuccess = React3__namespace.useCallback(
|
|
1810
2010
|
async (account, token, via) => {
|
|
1811
2011
|
const proceed = () => {
|
|
2012
|
+
clearTabSession();
|
|
1812
2013
|
if (onSuccess) onSuccess(account, token);
|
|
1813
2014
|
else void navigate(account);
|
|
1814
2015
|
};
|
|
@@ -1973,7 +2174,7 @@ function OcSignIn({
|
|
|
1973
2174
|
}
|
|
1974
2175
|
)
|
|
1975
2176
|
] }),
|
|
1976
|
-
/* @__PURE__ */ jsxRuntime.jsx(ProviderSignIn, { authOrigin, returnTo:
|
|
2177
|
+
/* @__PURE__ */ jsxRuntime.jsx(ProviderSignIn, { authOrigin, returnTo: resolvedReturn, add: addMode }),
|
|
1977
2178
|
linkPrompt && /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-oc-signin-linkalso": "", style: linkAlsoStyle, children: [
|
|
1978
2179
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1979
2180
|
"input",
|
|
@@ -2043,7 +2244,8 @@ function ProviderIcon({ id }) {
|
|
|
2043
2244
|
}
|
|
2044
2245
|
function ProviderSignIn({
|
|
2045
2246
|
authOrigin,
|
|
2046
|
-
returnTo
|
|
2247
|
+
returnTo,
|
|
2248
|
+
add
|
|
2047
2249
|
}) {
|
|
2048
2250
|
const [providers, setProviders] = React3__namespace.useState([]);
|
|
2049
2251
|
const [origin, setOrigin] = React3__namespace.useState("");
|
|
@@ -2059,7 +2261,7 @@ function ProviderSignIn({
|
|
|
2059
2261
|
};
|
|
2060
2262
|
}, [authOrigin]);
|
|
2061
2263
|
if (providers.length === 0) return null;
|
|
2062
|
-
const providerReturnTo = origin ? `${origin}${returnTo}` : returnTo;
|
|
2264
|
+
const providerReturnTo = returnTo.startsWith("/") ? origin ? `${origin}${returnTo}` : returnTo : returnTo;
|
|
2063
2265
|
const line = { flex: 1, height: 1, background: "var(--border, #27272a)" };
|
|
2064
2266
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-oc-signin-providers": "", style: { marginTop: 20 }, children: [
|
|
2065
2267
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2088,7 +2290,7 @@ function ProviderSignIn({
|
|
|
2088
2290
|
{
|
|
2089
2291
|
href: `${authOrigin}/api/auth/${p.id}/start?return_to=${encodeURIComponent(
|
|
2090
2292
|
providerReturnTo
|
|
2091
|
-
)}`,
|
|
2293
|
+
)}${add ? "&add=1" : ""}`,
|
|
2092
2294
|
"data-oc-signin-provider": p.id,
|
|
2093
2295
|
style: {
|
|
2094
2296
|
display: "flex",
|
|
@@ -2778,16 +2980,25 @@ exports.OcLinkedIdentities = OcLinkedIdentities;
|
|
|
2778
2980
|
exports.OcSessionProvider = OcSessionProvider;
|
|
2779
2981
|
exports.OcSignIn = OcSignIn;
|
|
2780
2982
|
exports.OcSignInButton = OcSignInButton;
|
|
2983
|
+
exports.TAB_ADOPT_HASH = TAB_ADOPT_HASH;
|
|
2984
|
+
exports.TAB_SESSION_HEADER = TAB_SESSION_HEADER;
|
|
2985
|
+
exports.TAB_SESSION_STORAGE_KEY = TAB_SESSION_STORAGE_KEY;
|
|
2781
2986
|
exports.buildAddAccountUrl = buildAddAccountUrl;
|
|
2782
2987
|
exports.buildSignInUrl = buildSignInUrl;
|
|
2988
|
+
exports.clearTabSession = clearTabSession;
|
|
2989
|
+
exports.consumeTabAdoptMarker = consumeTabAdoptMarker;
|
|
2783
2990
|
exports.fetchOcLinkedIdentities = fetchOcLinkedIdentities;
|
|
2784
2991
|
exports.handleSudoRequired = handleSudoRequired;
|
|
2992
|
+
exports.installTabFetchInterceptor = installTabFetchInterceptor;
|
|
2993
|
+
exports.readTabSession = readTabSession;
|
|
2785
2994
|
exports.redirectToSudo = redirectToSudo;
|
|
2995
|
+
exports.tabSessionHeader = tabSessionHeader;
|
|
2786
2996
|
exports.useOcAddressSuggestion = useOcAddressSuggestion;
|
|
2787
2997
|
exports.useOcSession = useOcSession;
|
|
2788
2998
|
exports.useOptionalOcSession = useOptionalOcSession;
|
|
2789
2999
|
exports.useStepUpAuth = useStepUpAuth;
|
|
2790
3000
|
exports.useWebAuthnList = useWebAuthnList;
|
|
2791
3001
|
exports.useWebAuthnRegister = useWebAuthnRegister;
|
|
3002
|
+
exports.writeTabSession = writeTabSession;
|
|
2792
3003
|
//# sourceMappingURL=index.js.map
|
|
2793
3004
|
//# sourceMappingURL=index.js.map
|