@orangecheck/auth-client 2.33.1 → 2.33.3

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.mjs CHANGED
@@ -4,31 +4,6 @@ import { startRegistration, startAuthentication } from '@simplewebauthn/browser'
4
4
 
5
5
  // src/provider.tsx
6
6
 
7
- // src/types.ts
8
- var DISPLAY_IDENTITY_KINDS = ["did", "btc", "email", "nostr"];
9
- var DEFAULT_CONFIG = {
10
- authOrigin: "https://ochk.io",
11
- signInPath: "/signin",
12
- mePath: "/api/auth/me",
13
- logoutPath: "/api/auth/logout",
14
- multiAccount: true
15
- };
16
- function resolveConfig(cfg) {
17
- return { ...DEFAULT_CONFIG, ...cfg ?? {} };
18
- }
19
- function buildSignInUrl(cfg, returnTo) {
20
- const base = `${cfg.authOrigin}${cfg.signInPath}`;
21
- if (!returnTo) return base;
22
- const u = new URL(base);
23
- u.searchParams.set("return_to", returnTo);
24
- return u.toString();
25
- }
26
- function buildAddAccountUrl(cfg, returnTo) {
27
- const u = new URL(buildSignInUrl(cfg, returnTo));
28
- u.searchParams.set("add", "1");
29
- return u.toString();
30
- }
31
-
32
7
  // src/tab-session.ts
33
8
  var TAB_SESSION_HEADER = "x-oc-tab-session";
34
9
  var TAB_SESSION_STORAGE_KEY = "oc_tab_session";
@@ -200,6 +175,136 @@ async function consumeTabAccountHint(authOrigin) {
200
175
  }
201
176
  return null;
202
177
  }
178
+
179
+ // src/return-to.ts
180
+ var PREFIX = "oc:return-fragment:";
181
+ var HOLD_MS = 1e4;
182
+ var FRAGMENT_TTL_MS = 15 * 60 * 1e3;
183
+ function store() {
184
+ try {
185
+ return window.sessionStorage;
186
+ } catch {
187
+ return null;
188
+ }
189
+ }
190
+ function stripFragment(target) {
191
+ const cut = target.indexOf("#");
192
+ return cut < 0 ? target : target.slice(0, cut);
193
+ }
194
+ function keep(pathAndQuery, hash) {
195
+ if (hash.length < 2) return;
196
+ try {
197
+ store()?.setItem(PREFIX + pathAndQuery, JSON.stringify({ hash, at: Date.now() }));
198
+ } catch {
199
+ }
200
+ }
201
+ function withoutFragment(target) {
202
+ if (typeof window !== "undefined" && target.includes("#")) {
203
+ try {
204
+ const u = new URL(target, window.location.href);
205
+ if (u.origin === window.location.origin) keep(u.pathname + u.search, u.hash);
206
+ } catch {
207
+ }
208
+ }
209
+ return stripFragment(target);
210
+ }
211
+ function returnToHere() {
212
+ if (typeof window === "undefined") return "/";
213
+ const { pathname, search, hash } = window.location;
214
+ return withoutFragment(pathname + search + hash);
215
+ }
216
+ function keepFragmentOnReturnLinks() {
217
+ if (typeof document === "undefined") return () => {
218
+ };
219
+ const onClick = (e) => {
220
+ const { pathname, search, hash, href } = window.location;
221
+ if (hash.length < 2 || e.defaultPrevented) return;
222
+ const link = e.target?.closest?.("a[href]");
223
+ if (!link) return;
224
+ try {
225
+ const to = new URL(link.getAttribute("href") ?? "", href);
226
+ const back = to.searchParams.get("return_to");
227
+ if (!back) return;
228
+ const here = new URL(back, href);
229
+ if (here.origin === window.location.origin && here.pathname === pathname && here.search === search) {
230
+ keep(pathname + search, hash);
231
+ }
232
+ } catch {
233
+ }
234
+ };
235
+ document.addEventListener("click", onClick, true);
236
+ return () => document.removeEventListener("click", onClick, true);
237
+ }
238
+ function restoreReturnFragment() {
239
+ if (typeof window === "undefined") return false;
240
+ const s = store();
241
+ if (!s) return false;
242
+ const { pathname, search, hash } = window.location;
243
+ const key = PREFIX + pathname + search;
244
+ let raw;
245
+ try {
246
+ raw = s.getItem(key);
247
+ if (raw === null) return false;
248
+ s.removeItem(key);
249
+ } catch {
250
+ return false;
251
+ }
252
+ if (hash) return false;
253
+ try {
254
+ const kept = JSON.parse(raw);
255
+ if (typeof kept.hash !== "string" || !kept.hash.startsWith("#")) return false;
256
+ if (typeof kept.at !== "number" || Date.now() - kept.at > FRAGMENT_TTL_MS) return false;
257
+ const restored = pathname + search + kept.hash;
258
+ window.history.replaceState(window.history.state, "", restored);
259
+ holdFragment(pathname + search, kept.hash, restored);
260
+ return true;
261
+ } catch {
262
+ return false;
263
+ }
264
+ }
265
+ function holdFragment(pathAndQuery, hash, restored) {
266
+ const until = Date.now() + HOLD_MS;
267
+ const check = () => {
268
+ const l = window.location;
269
+ if (l.pathname + l.search !== pathAndQuery || l.hash === hash) {
270
+ if (l.pathname + l.search === pathAndQuery && Date.now() < until) {
271
+ window.setTimeout(check, 50);
272
+ }
273
+ return;
274
+ }
275
+ if (l.hash && l.hash !== TAB_ADOPT_HASH) return;
276
+ try {
277
+ window.history.replaceState(window.history.state, "", restored);
278
+ } catch {
279
+ }
280
+ };
281
+ window.setTimeout(check, 0);
282
+ }
283
+
284
+ // src/types.ts
285
+ var DISPLAY_IDENTITY_KINDS = ["did", "btc", "email", "nostr"];
286
+ var DEFAULT_CONFIG = {
287
+ authOrigin: "https://ochk.io",
288
+ signInPath: "/signin",
289
+ mePath: "/api/auth/me",
290
+ logoutPath: "/api/auth/logout",
291
+ multiAccount: true
292
+ };
293
+ function resolveConfig(cfg) {
294
+ return { ...DEFAULT_CONFIG, ...cfg ?? {} };
295
+ }
296
+ function buildSignInUrl(cfg, returnTo) {
297
+ const base = `${cfg.authOrigin}${cfg.signInPath}`;
298
+ if (!returnTo) return base;
299
+ const u = new URL(base);
300
+ u.searchParams.set("return_to", stripFragment(returnTo));
301
+ return u.toString();
302
+ }
303
+ function buildAddAccountUrl(cfg, returnTo) {
304
+ const u = new URL(buildSignInUrl(cfg, returnTo));
305
+ u.searchParams.set("add", "1");
306
+ return u.toString();
307
+ }
203
308
  var SessionContext = React4.createContext(null);
204
309
  function normalizeDisplayIdentity(raw, didOc) {
205
310
  const di = raw.display_identity ?? raw.displayIdentity;
@@ -259,6 +364,13 @@ function OcSessionProvider({
259
364
  defaultReturnTo
260
365
  }) {
261
366
  const cfg = React4.useMemo(() => resolveConfig(config), [config]);
367
+ React4.useState(() => {
368
+ if (typeof window !== "undefined") {
369
+ consumeTabAdoptMarker();
370
+ restoreReturnFragment();
371
+ }
372
+ return null;
373
+ });
262
374
  const [account, setAccount] = React4.useState(null);
263
375
  const [roster, setRoster] = React4.useState([]);
264
376
  const [status, setStatus] = React4.useState("loading");
@@ -353,6 +465,7 @@ function OcSessionProvider({
353
465
  cancelled = true;
354
466
  };
355
467
  }, [refresh, cfg.authOrigin, cfg.multiAccount]);
468
+ React4.useEffect(() => keepFragmentOnReturnLinks(), []);
356
469
  React4.useEffect(
357
470
  () => cfg.multiAccount ? installTabFetchInterceptor(cfg.authOrigin) : void 0,
358
471
  [cfg.authOrigin, cfg.multiAccount]
@@ -1153,7 +1266,7 @@ function redirectToSudo(args = {}) {
1153
1266
  }
1154
1267
  const cfg = resolveConfig(args.config);
1155
1268
  const url = new URL("/sudo", cfg.authOrigin);
1156
- const returnTo = args.returnTo ?? window.location.href;
1269
+ const returnTo = withoutFragment(args.returnTo ?? window.location.href);
1157
1270
  if (returnTo) url.searchParams.set("return_to", returnTo);
1158
1271
  if (args.purpose) url.searchParams.set("purpose", args.purpose);
1159
1272
  window.location.assign(url.toString());
@@ -2517,7 +2630,9 @@ function ProviderSignIn({
2517
2630
  }, [authOrigin, credentials, hidden]);
2518
2631
  if (hidden) return null;
2519
2632
  if (providers !== null && providers.length === 0) return null;
2520
- const providerReturnTo = returnTo.startsWith("/") ? origin ? `${origin}${returnTo}` : returnTo : returnTo;
2633
+ const providerReturnTo = stripFragment(
2634
+ returnTo.startsWith("/") ? origin ? `${origin}${returnTo}` : returnTo : returnTo
2635
+ );
2521
2636
  const line = { flex: 1, height: 1, background: "var(--border, #27272a)" };
2522
2637
  const BLOCK_GAP = 16;
2523
2638
  const BUTTON_GAP = 8;
@@ -3882,6 +3997,6 @@ function useStepUpAuth(opts) {
3882
3997
  return { status, error, stepUp, reset };
3883
3998
  }
3884
3999
 
3885
- export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, OcAccountChip, OcAccountPill, OcAddressInput, OcBond, OcLinkedIdentities, OcSessionProvider, OcSignIn, OcSignInButton, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, bondFloorsText, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcBond, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
4000
+ export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, FRAGMENT_TTL_MS, OcAccountChip, OcAccountPill, OcAddressInput, OcBond, OcLinkedIdentities, OcSessionProvider, OcSignIn, OcSignInButton, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, bondFloorsText, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcBond, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, keepFragmentOnReturnLinks, readTabSession, redirectToSudo, restoreReturnFragment, returnToHere, safeReturnTo, stripFragment, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, withoutFragment, writeTabSession };
3886
4001
  //# sourceMappingURL=index.mjs.map
3887
4002
  //# sourceMappingURL=index.mjs.map