@orangecheck/auth-client 2.19.0 → 2.21.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.mjs CHANGED
@@ -31,6 +31,7 @@ function buildAddAccountUrl(cfg, returnTo) {
31
31
  // src/tab-session.ts
32
32
  var TAB_SESSION_HEADER = "x-oc-tab-session";
33
33
  var TAB_SESSION_STORAGE_KEY = "oc_tab_session";
34
+ var TAB_ACCOUNT_HINT_KEY = "oc-as";
34
35
  var TAB_ADOPT_HASH = "#oc-adopt";
35
36
  function readTabSession() {
36
37
  if (typeof window === "undefined") return null;
@@ -112,6 +113,92 @@ function consumeTabAdoptMarker() {
112
113
  }
113
114
  return true;
114
115
  }
116
+ var OC_AS_HINT_RE = /^oc-as=(did:oc:[0-9a-f]{32})$/;
117
+ function familyApex(authOrigin) {
118
+ try {
119
+ return new URL(authOrigin).hostname.toLowerCase();
120
+ } catch {
121
+ return null;
122
+ }
123
+ }
124
+ function isFamilyUrl(u, authOrigin) {
125
+ if (u.protocol !== "http:" && u.protocol !== "https:") return false;
126
+ if (typeof window !== "undefined" && u.origin === window.location.origin) return true;
127
+ const apex = familyApex(authOrigin);
128
+ if (!apex) return false;
129
+ const host = u.hostname.toLowerCase();
130
+ return host === apex || host.endsWith(`.${apex}`);
131
+ }
132
+ function opensWithoutTabPin(e, anchor, dest) {
133
+ if (typeof window !== "undefined" && dest.origin !== window.location.origin) return true;
134
+ const target = (anchor.getAttribute("target") ?? "").toLowerCase();
135
+ return e.button === 1 || // middle-click
136
+ e.metaKey || e.ctrlKey || e.shiftKey || target === "_blank";
137
+ }
138
+ function installTabLinkDecorator(authOrigin) {
139
+ if (typeof window === "undefined" || typeof document === "undefined") return () => {
140
+ };
141
+ const onActivate = (e) => {
142
+ try {
143
+ const pin = readTabSession();
144
+ if (!pin) return;
145
+ const target = e.target;
146
+ if (!(target instanceof Element)) return;
147
+ const anchor = target.closest("a[href]");
148
+ if (!anchor || anchor.hasAttribute("download")) return;
149
+ const raw = anchor.getAttribute("href");
150
+ if (!raw || raw.includes(`${TAB_ACCOUNT_HINT_KEY}=`)) return;
151
+ let dest;
152
+ try {
153
+ dest = new URL(anchor.href);
154
+ } catch {
155
+ return;
156
+ }
157
+ if (dest.hash) return;
158
+ if (!isFamilyUrl(dest, authOrigin)) return;
159
+ if (!opensWithoutTabPin(e, anchor, dest)) return;
160
+ anchor.setAttribute("href", `${raw}#${TAB_ACCOUNT_HINT_KEY}=${pin.didOc}`);
161
+ } catch {
162
+ }
163
+ };
164
+ window.addEventListener("click", onActivate, true);
165
+ window.addEventListener("auxclick", onActivate, true);
166
+ return () => {
167
+ window.removeEventListener("click", onActivate, true);
168
+ window.removeEventListener("auxclick", onActivate, true);
169
+ };
170
+ }
171
+ async function consumeTabAccountHint(authOrigin) {
172
+ if (typeof window === "undefined") return null;
173
+ const frag = window.location.hash.replace(/^#/, "");
174
+ const m = OC_AS_HINT_RE.exec(frag);
175
+ if (!m) return null;
176
+ const did = m[1];
177
+ try {
178
+ const url = new URL(window.location.href);
179
+ url.hash = "";
180
+ window.history.replaceState(window.history.state, "", url.toString());
181
+ } catch {
182
+ }
183
+ const existing = readTabSession();
184
+ if (existing && existing.didOc === did) return did;
185
+ try {
186
+ const res = await fetch(`${authOrigin}/api/auth/tab`, {
187
+ method: "POST",
188
+ credentials: "include",
189
+ headers: { Accept: "application/json", "Content-Type": "application/json" },
190
+ body: JSON.stringify({ did_oc: did })
191
+ });
192
+ if (!res.ok) return null;
193
+ const body = await res.json();
194
+ if (body.ok && typeof body.token === "string" && body.account?.did_oc === did) {
195
+ writeTabSession({ token: body.token, didOc: did });
196
+ return did;
197
+ }
198
+ } catch {
199
+ }
200
+ return null;
201
+ }
115
202
  var SessionContext = React3.createContext(null);
116
203
  function normalizeDisplayIdentity(raw, didOc) {
117
204
  const di = raw.display_identity ?? raw.displayIdentity;
@@ -255,10 +342,18 @@ function OcSessionProvider({
255
342
  }
256
343
  }, [cfg, pinThisTab]);
257
344
  React3.useEffect(() => {
345
+ let cancelled = false;
258
346
  consumeTabAdoptMarker();
259
- void refresh();
260
- }, [refresh]);
347
+ void (async () => {
348
+ await consumeTabAccountHint(cfg.authOrigin);
349
+ if (!cancelled) void refresh();
350
+ })();
351
+ return () => {
352
+ cancelled = true;
353
+ };
354
+ }, [refresh, cfg.authOrigin]);
261
355
  React3.useEffect(() => installTabFetchInterceptor(cfg.authOrigin), [cfg.authOrigin]);
356
+ React3.useEffect(() => installTabLinkDecorator(cfg.authOrigin), [cfg.authOrigin]);
262
357
  const signOut = React3.useCallback(
263
358
  async (opts) => {
264
359
  const scope = opts?.scope ?? "all";
@@ -1932,7 +2027,7 @@ function OcSignIn({
1932
2027
  add: addProp,
1933
2028
  authOrigin = "https://ochk.io",
1934
2029
  initialPath,
1935
- providersFirst = false,
2030
+ providersFirst = true,
1936
2031
  paths,
1937
2032
  className
1938
2033
  }) {
@@ -2991,6 +3086,6 @@ function handleSudoRequired(body, args = {}) {
2991
3086
  return false;
2992
3087
  }
2993
3088
 
2994
- export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, OcAccountChip, OcAccountPill, OcAddressInput, OcLinkedIdentities, OcSessionProvider, OcSignIn, OcSignInButton, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAdoptMarker, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, readTabSession, redirectToSudo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
3089
+ export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, OcAccountChip, OcAccountPill, OcAddressInput, OcLinkedIdentities, OcSessionProvider, OcSignIn, OcSignInButton, TAB_ACCOUNT_HINT_KEY, TAB_ADOPT_HASH, TAB_SESSION_HEADER, TAB_SESSION_STORAGE_KEY, buildAddAccountUrl, buildSignInUrl, clearTabSession, consumeTabAccountHint, consumeTabAdoptMarker, fetchOcLinkedIdentities, handleSudoRequired, installTabFetchInterceptor, installTabLinkDecorator, readTabSession, redirectToSudo, tabSessionHeader, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister, writeTabSession };
2995
3090
  //# sourceMappingURL=index.mjs.map
2996
3091
  //# sourceMappingURL=index.mjs.map