@orangecheck/auth-client 2.33.0 → 2.33.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@orangecheck/auth-client`
2
2
 
3
- > **Full reference:** [docs.ochk.io/sdk/auth-client](https://docs.ochk.io/sdk/auth-client) — auto-generated from the TypeScript source on every release.
3
+ > **Full reference:** [ochk.io/docs/sdk/auth-client](https://ochk.io/docs/sdk/auth-client) — auto-generated from the TypeScript source on every release.
4
4
  > Hand-written prose below is the high-level overview; the docs site is the source of truth for every export, type, and signature.
5
5
 
6
6
 
@@ -16,8 +16,8 @@ Pairs with [`@orangecheck/auth-core`](../auth-core) on the server side.
16
16
  > OrangeCheck *be* your sign-in. If you already run your own login
17
17
  > (Google, Auth0, Clerk, NextAuth, …) and just want to add a `did:oc`
18
18
  > to your users, you don't need this package — see
19
- > [OrangeCheck Connect](https://docs.ochk.io/connect). Both pathways are
20
- > compared at [docs.ochk.io/integration](https://docs.ochk.io/integration).
19
+ > [OrangeCheck Connect](https://ochk.io/docs/connect). Both pathways are
20
+ > compared at [ochk.io/docs/integration](https://ochk.io/docs/integration).
21
21
 
22
22
  ## Install
23
23
 
package/dist/index.d.mts CHANGED
@@ -190,6 +190,13 @@ declare function fetchOcBond(opts?: {
190
190
  }): Promise<OcBondView | null>;
191
191
  declare function OcBond({ authOrigin, onChange, className, }: OcBondProps): React.ReactElement;
192
192
 
193
+ declare const FRAGMENT_TTL_MS: number;
194
+ declare function stripFragment(target: string): string;
195
+ declare function withoutFragment(target: string): string;
196
+ declare function returnToHere(): string;
197
+ declare function keepFragmentOnReturnLinks(): () => void;
198
+ declare function restoreReturnFragment(): boolean;
199
+
193
200
  declare const TAB_SESSION_HEADER = "x-oc-tab-session";
194
201
  declare const TAB_SESSION_STORAGE_KEY = "oc_tab_session";
195
202
  declare const TAB_ACCOUNT_HINT_KEY = "oc-as";
@@ -293,4 +300,4 @@ declare function isSudoAccountMismatch(body: {
293
300
  reason?: string;
294
301
  } | null | undefined): boolean;
295
302
 
296
- 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, OcBond, type OcBondProps, type OcBondView, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, 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, bondFloorsText, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcBond, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
303
+ export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, FRAGMENT_TTL_MS, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcBond, type OcBondProps, type OcBondView, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, 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, 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 };
package/dist/index.d.ts CHANGED
@@ -190,6 +190,13 @@ declare function fetchOcBond(opts?: {
190
190
  }): Promise<OcBondView | null>;
191
191
  declare function OcBond({ authOrigin, onChange, className, }: OcBondProps): React.ReactElement;
192
192
 
193
+ declare const FRAGMENT_TTL_MS: number;
194
+ declare function stripFragment(target: string): string;
195
+ declare function withoutFragment(target: string): string;
196
+ declare function returnToHere(): string;
197
+ declare function keepFragmentOnReturnLinks(): () => void;
198
+ declare function restoreReturnFragment(): boolean;
199
+
193
200
  declare const TAB_SESSION_HEADER = "x-oc-tab-session";
194
201
  declare const TAB_SESSION_STORAGE_KEY = "oc_tab_session";
195
202
  declare const TAB_ACCOUNT_HINT_KEY = "oc-as";
@@ -293,4 +300,4 @@ declare function isSudoAccountMismatch(body: {
293
300
  reason?: string;
294
301
  } | null | undefined): boolean;
295
302
 
296
- 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, OcBond, type OcBondProps, type OcBondView, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, 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, bondFloorsText, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, familyReturnTarget, fetchOcBond, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, isSudoAccountMismatch, readTabSession, redirectToSudo, safeReturnTo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
303
+ export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, FRAGMENT_TTL_MS, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, type OcAccountSummary, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcBond, type OcBondProps, type OcBondView, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, type OcSignOutScope, type OcTabSession, type RedirectToSudoArgs, SUDO_ACCOUNT_MISMATCH_MESSAGE, TAB_ACCOUNT_HINT_KEY, 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, 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 };
package/dist/index.js CHANGED
@@ -26,6 +26,90 @@ var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
26
26
 
27
27
  // src/provider.tsx
28
28
 
29
+ // src/return-to.ts
30
+ var PREFIX = "oc:return-fragment:";
31
+ var FRAGMENT_TTL_MS = 15 * 60 * 1e3;
32
+ function store() {
33
+ try {
34
+ return window.sessionStorage;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ function stripFragment(target) {
40
+ const cut = target.indexOf("#");
41
+ return cut < 0 ? target : target.slice(0, cut);
42
+ }
43
+ function keep(pathAndQuery, hash) {
44
+ if (hash.length < 2) return;
45
+ try {
46
+ store()?.setItem(PREFIX + pathAndQuery, JSON.stringify({ hash, at: Date.now() }));
47
+ } catch {
48
+ }
49
+ }
50
+ function withoutFragment(target) {
51
+ if (typeof window !== "undefined" && target.includes("#")) {
52
+ try {
53
+ const u = new URL(target, window.location.href);
54
+ if (u.origin === window.location.origin) keep(u.pathname + u.search, u.hash);
55
+ } catch {
56
+ }
57
+ }
58
+ return stripFragment(target);
59
+ }
60
+ function returnToHere() {
61
+ if (typeof window === "undefined") return "/";
62
+ const { pathname, search, hash } = window.location;
63
+ return withoutFragment(pathname + search + hash);
64
+ }
65
+ function keepFragmentOnReturnLinks() {
66
+ if (typeof document === "undefined") return () => {
67
+ };
68
+ const onClick = (e) => {
69
+ const { pathname, search, hash, href } = window.location;
70
+ if (hash.length < 2 || e.defaultPrevented) return;
71
+ const link = e.target?.closest?.("a[href]");
72
+ if (!link) return;
73
+ try {
74
+ const to = new URL(link.getAttribute("href") ?? "", href);
75
+ const back = to.searchParams.get("return_to");
76
+ if (!back) return;
77
+ const here = new URL(back, href);
78
+ if (here.origin === window.location.origin && here.pathname === pathname && here.search === search) {
79
+ keep(pathname + search, hash);
80
+ }
81
+ } catch {
82
+ }
83
+ };
84
+ document.addEventListener("click", onClick, true);
85
+ return () => document.removeEventListener("click", onClick, true);
86
+ }
87
+ function restoreReturnFragment() {
88
+ if (typeof window === "undefined") return false;
89
+ const s = store();
90
+ if (!s) return false;
91
+ const { pathname, search, hash } = window.location;
92
+ const key = PREFIX + pathname + search;
93
+ let raw;
94
+ try {
95
+ raw = s.getItem(key);
96
+ if (raw === null) return false;
97
+ s.removeItem(key);
98
+ } catch {
99
+ return false;
100
+ }
101
+ if (hash) return false;
102
+ try {
103
+ const kept = JSON.parse(raw);
104
+ if (typeof kept.hash !== "string" || !kept.hash.startsWith("#")) return false;
105
+ if (typeof kept.at !== "number" || Date.now() - kept.at > FRAGMENT_TTL_MS) return false;
106
+ window.history.replaceState(window.history.state, "", pathname + search + kept.hash);
107
+ return true;
108
+ } catch {
109
+ return false;
110
+ }
111
+ }
112
+
29
113
  // src/types.ts
30
114
  var DISPLAY_IDENTITY_KINDS = ["did", "btc", "email", "nostr"];
31
115
  var DEFAULT_CONFIG = {
@@ -42,7 +126,7 @@ function buildSignInUrl(cfg, returnTo) {
42
126
  const base = `${cfg.authOrigin}${cfg.signInPath}`;
43
127
  if (!returnTo) return base;
44
128
  const u = new URL(base);
45
- u.searchParams.set("return_to", returnTo);
129
+ u.searchParams.set("return_to", stripFragment(returnTo));
46
130
  return u.toString();
47
131
  }
48
132
  function buildAddAccountUrl(cfg, returnTo) {
@@ -281,6 +365,13 @@ function OcSessionProvider({
281
365
  defaultReturnTo
282
366
  }) {
283
367
  const cfg = React4__namespace.useMemo(() => resolveConfig(config), [config]);
368
+ React4__namespace.useState(() => {
369
+ if (typeof window !== "undefined") {
370
+ consumeTabAdoptMarker();
371
+ restoreReturnFragment();
372
+ }
373
+ return null;
374
+ });
284
375
  const [account, setAccount] = React4__namespace.useState(null);
285
376
  const [roster, setRoster] = React4__namespace.useState([]);
286
377
  const [status, setStatus] = React4__namespace.useState("loading");
@@ -375,6 +466,7 @@ function OcSessionProvider({
375
466
  cancelled = true;
376
467
  };
377
468
  }, [refresh, cfg.authOrigin, cfg.multiAccount]);
469
+ React4__namespace.useEffect(() => keepFragmentOnReturnLinks(), []);
378
470
  React4__namespace.useEffect(
379
471
  () => cfg.multiAccount ? installTabFetchInterceptor(cfg.authOrigin) : void 0,
380
472
  [cfg.authOrigin, cfg.multiAccount]
@@ -871,6 +963,10 @@ function OcAccountPill({
871
963
  }
872
964
  );
873
965
  }
966
+ function accountAddress(account) {
967
+ if (account?.primaryBtc) return account.primaryBtc;
968
+ return account?.displayIdentity?.kind === "btc" ? account.displayIdentity.value : null;
969
+ }
874
970
  function useOcAddressSuggestion(options) {
875
971
  const {
876
972
  value,
@@ -880,7 +976,7 @@ function useOcAddressSuggestion(options) {
880
976
  suggestionClassName
881
977
  } = options;
882
978
  const { status, account } = useOcSession();
883
- const sessionAddress = status === "authenticated" ? account?.primaryBtc ?? null : null;
979
+ const sessionAddress = status === "authenticated" ? accountAddress(account) : null;
884
980
  const [open, setOpen] = React4__namespace.useState(false);
885
981
  const [highlighted, setHighlighted] = React4__namespace.useState(false);
886
982
  const blurTimer = React4__namespace.useRef(null);
@@ -1012,7 +1108,7 @@ var OcAddressInput = React4__namespace.forwardRef(
1012
1108
  ...rest
1013
1109
  }, forwardedRef) {
1014
1110
  const { status, account } = useOcSession();
1015
- const sessionAddress = status === "authenticated" ? account?.primaryBtc ?? null : null;
1111
+ const sessionAddress = status === "authenticated" ? accountAddress(account) : null;
1016
1112
  const [open, setOpen] = React4__namespace.useState(false);
1017
1113
  const [highlighted, setHighlighted] = React4__namespace.useState(false);
1018
1114
  const innerRef = React4__namespace.useRef(null);
@@ -1171,7 +1267,7 @@ function redirectToSudo(args = {}) {
1171
1267
  }
1172
1268
  const cfg = resolveConfig(args.config);
1173
1269
  const url = new URL("/sudo", cfg.authOrigin);
1174
- const returnTo = args.returnTo ?? window.location.href;
1270
+ const returnTo = withoutFragment(args.returnTo ?? window.location.href);
1175
1271
  if (returnTo) url.searchParams.set("return_to", returnTo);
1176
1272
  if (args.purpose) url.searchParams.set("purpose", args.purpose);
1177
1273
  window.location.assign(url.toString());
@@ -2535,7 +2631,9 @@ function ProviderSignIn({
2535
2631
  }, [authOrigin, credentials, hidden]);
2536
2632
  if (hidden) return null;
2537
2633
  if (providers !== null && providers.length === 0) return null;
2538
- const providerReturnTo = returnTo.startsWith("/") ? origin ? `${origin}${returnTo}` : returnTo : returnTo;
2634
+ const providerReturnTo = stripFragment(
2635
+ returnTo.startsWith("/") ? origin ? `${origin}${returnTo}` : returnTo : returnTo
2636
+ );
2539
2637
  const line = { flex: 1, height: 1, background: "var(--border, #27272a)" };
2540
2638
  const BLOCK_GAP = 16;
2541
2639
  const BUTTON_GAP = 8;
@@ -3902,6 +4000,7 @@ function useStepUpAuth(opts) {
3902
4000
 
3903
4001
  exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
3904
4002
  exports.DISPLAY_IDENTITY_KINDS = DISPLAY_IDENTITY_KINDS;
4003
+ exports.FRAGMENT_TTL_MS = FRAGMENT_TTL_MS;
3905
4004
  exports.OcAccountChip = OcAccountChip;
3906
4005
  exports.OcAccountPill = OcAccountPill;
3907
4006
  exports.OcAddressInput = OcAddressInput;
@@ -3928,9 +4027,13 @@ exports.handleSudoRequired = handleSudoRequired;
3928
4027
  exports.installTabFetchInterceptor = installTabFetchInterceptor;
3929
4028
  exports.installTabLinkDecorator = installTabLinkDecorator;
3930
4029
  exports.isSudoAccountMismatch = isSudoAccountMismatch;
4030
+ exports.keepFragmentOnReturnLinks = keepFragmentOnReturnLinks;
3931
4031
  exports.readTabSession = readTabSession;
3932
4032
  exports.redirectToSudo = redirectToSudo;
4033
+ exports.restoreReturnFragment = restoreReturnFragment;
4034
+ exports.returnToHere = returnToHere;
3933
4035
  exports.safeReturnTo = safeReturnTo;
4036
+ exports.stripFragment = stripFragment;
3934
4037
  exports.tabSessionHeader = tabSessionHeader;
3935
4038
  exports.useOcAddressSuggestion = useOcAddressSuggestion;
3936
4039
  exports.useOcSession = useOcSession;
@@ -3938,6 +4041,7 @@ exports.useOptionalOcSession = useOptionalOcSession;
3938
4041
  exports.useStepUpAuth = useStepUpAuth;
3939
4042
  exports.useWebAuthnList = useWebAuthnList;
3940
4043
  exports.useWebAuthnRegister = useWebAuthnRegister;
4044
+ exports.withoutFragment = withoutFragment;
3941
4045
  exports.writeTabSession = writeTabSession;
3942
4046
  //# sourceMappingURL=index.js.map
3943
4047
  //# sourceMappingURL=index.js.map