@orangecheck/auth-client 2.15.0 → 2.17.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 +7 -0
- package/dist/index.d.mts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +146 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,13 @@ sign-in button.
|
|
|
12
12
|
|
|
13
13
|
Pairs with [`@orangecheck/auth-core`](../auth-core) on the server side.
|
|
14
14
|
|
|
15
|
+
> **Which integration pathway is this?** This package is for letting
|
|
16
|
+
> OrangeCheck *be* your sign-in. If you already run your own login
|
|
17
|
+
> (Google, Auth0, Clerk, NextAuth, …) and just want to add a `did:oc`
|
|
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).
|
|
21
|
+
|
|
15
22
|
## Install
|
|
16
23
|
|
|
17
24
|
```bash
|
package/dist/index.d.mts
CHANGED
|
@@ -19,12 +19,25 @@ interface OcAccount {
|
|
|
19
19
|
displayIdentity: DisplayIdentity;
|
|
20
20
|
}
|
|
21
21
|
type OcSessionStatus = 'loading' | 'authenticated' | 'anonymous' | 'error';
|
|
22
|
+
interface OcAccountSummary {
|
|
23
|
+
didOc: string;
|
|
24
|
+
displayName: string | null;
|
|
25
|
+
primaryBtc: string | null;
|
|
26
|
+
displayIdentity: DisplayIdentity;
|
|
27
|
+
lastSeenAt: string | null;
|
|
28
|
+
}
|
|
29
|
+
type OcSignOutScope = 'all' | 'current';
|
|
22
30
|
interface OcSessionState {
|
|
23
31
|
status: OcSessionStatus;
|
|
24
32
|
account: OcAccount | null;
|
|
33
|
+
roster: OcAccountSummary[];
|
|
25
34
|
error: Error | null;
|
|
26
35
|
refresh: () => Promise<void>;
|
|
27
|
-
signOut: (
|
|
36
|
+
signOut: (opts?: {
|
|
37
|
+
scope?: OcSignOutScope;
|
|
38
|
+
}) => Promise<void>;
|
|
39
|
+
switchAccount: (didOc: string) => Promise<void>;
|
|
40
|
+
addAccountUrl: (returnTo?: string) => string;
|
|
28
41
|
setDisplayIdentity: (kind: DisplayIdentityKind) => Promise<void>;
|
|
29
42
|
signInUrl: string;
|
|
30
43
|
}
|
|
@@ -36,6 +49,7 @@ interface OcAuthConfig {
|
|
|
36
49
|
}
|
|
37
50
|
declare const DEFAULT_CONFIG: Required<OcAuthConfig>;
|
|
38
51
|
declare function buildSignInUrl(cfg: Required<OcAuthConfig>, returnTo?: string): string;
|
|
52
|
+
declare function buildAddAccountUrl(cfg: Required<OcAuthConfig>, returnTo?: string): string;
|
|
39
53
|
|
|
40
54
|
interface OcSessionProviderProps {
|
|
41
55
|
children: React.ReactNode;
|
|
@@ -115,9 +129,10 @@ interface OcSignInProps {
|
|
|
115
129
|
email?: boolean;
|
|
116
130
|
};
|
|
117
131
|
linkPrompt?: boolean;
|
|
132
|
+
add?: boolean;
|
|
118
133
|
className?: string;
|
|
119
134
|
}
|
|
120
|
-
declare function OcSignIn({ audience, returnTo, onSuccess, resolveReturnTo, linkPrompt, authOrigin, initialPath, paths, className, }: OcSignInProps): React.ReactElement;
|
|
135
|
+
declare function OcSignIn({ audience, returnTo, onSuccess, resolveReturnTo, linkPrompt, add: addProp, authOrigin, initialPath, paths, className, }: OcSignInProps): React.ReactElement;
|
|
121
136
|
|
|
122
137
|
interface OcLinkedIdentity {
|
|
123
138
|
id: string;
|
|
@@ -219,4 +234,4 @@ declare function handleSudoRequired(body: {
|
|
|
219
234
|
returnTo?: string;
|
|
220
235
|
}): boolean;
|
|
221
236
|
|
|
222
|
-
export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, 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, buildSignInUrl, fetchOcLinkedIdentities, handleSudoRequired, redirectToSudo, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -19,12 +19,25 @@ interface OcAccount {
|
|
|
19
19
|
displayIdentity: DisplayIdentity;
|
|
20
20
|
}
|
|
21
21
|
type OcSessionStatus = 'loading' | 'authenticated' | 'anonymous' | 'error';
|
|
22
|
+
interface OcAccountSummary {
|
|
23
|
+
didOc: string;
|
|
24
|
+
displayName: string | null;
|
|
25
|
+
primaryBtc: string | null;
|
|
26
|
+
displayIdentity: DisplayIdentity;
|
|
27
|
+
lastSeenAt: string | null;
|
|
28
|
+
}
|
|
29
|
+
type OcSignOutScope = 'all' | 'current';
|
|
22
30
|
interface OcSessionState {
|
|
23
31
|
status: OcSessionStatus;
|
|
24
32
|
account: OcAccount | null;
|
|
33
|
+
roster: OcAccountSummary[];
|
|
25
34
|
error: Error | null;
|
|
26
35
|
refresh: () => Promise<void>;
|
|
27
|
-
signOut: (
|
|
36
|
+
signOut: (opts?: {
|
|
37
|
+
scope?: OcSignOutScope;
|
|
38
|
+
}) => Promise<void>;
|
|
39
|
+
switchAccount: (didOc: string) => Promise<void>;
|
|
40
|
+
addAccountUrl: (returnTo?: string) => string;
|
|
28
41
|
setDisplayIdentity: (kind: DisplayIdentityKind) => Promise<void>;
|
|
29
42
|
signInUrl: string;
|
|
30
43
|
}
|
|
@@ -36,6 +49,7 @@ interface OcAuthConfig {
|
|
|
36
49
|
}
|
|
37
50
|
declare const DEFAULT_CONFIG: Required<OcAuthConfig>;
|
|
38
51
|
declare function buildSignInUrl(cfg: Required<OcAuthConfig>, returnTo?: string): string;
|
|
52
|
+
declare function buildAddAccountUrl(cfg: Required<OcAuthConfig>, returnTo?: string): string;
|
|
39
53
|
|
|
40
54
|
interface OcSessionProviderProps {
|
|
41
55
|
children: React.ReactNode;
|
|
@@ -115,9 +129,10 @@ interface OcSignInProps {
|
|
|
115
129
|
email?: boolean;
|
|
116
130
|
};
|
|
117
131
|
linkPrompt?: boolean;
|
|
132
|
+
add?: boolean;
|
|
118
133
|
className?: string;
|
|
119
134
|
}
|
|
120
|
-
declare function OcSignIn({ audience, returnTo, onSuccess, resolveReturnTo, linkPrompt, authOrigin, initialPath, paths, className, }: OcSignInProps): React.ReactElement;
|
|
135
|
+
declare function OcSignIn({ audience, returnTo, onSuccess, resolveReturnTo, linkPrompt, add: addProp, authOrigin, initialPath, paths, className, }: OcSignInProps): React.ReactElement;
|
|
121
136
|
|
|
122
137
|
interface OcLinkedIdentity {
|
|
123
138
|
id: string;
|
|
@@ -219,4 +234,4 @@ declare function handleSudoRequired(body: {
|
|
|
219
234
|
returnTo?: string;
|
|
220
235
|
}): boolean;
|
|
221
236
|
|
|
222
|
-
export { DEFAULT_CONFIG, DISPLAY_IDENTITY_KINDS, type DisplayIdentity, type DisplayIdentityKind, type OcAccount, OcAccountChip, type OcAccountChipProps, OcAccountPill, type OcAccountPillProps, OcAddressInput, type OcAddressInputProps, type OcAuthConfig, OcLinkedIdentities, type OcLinkedIdentitiesProps, type OcLinkedIdentity, OcSessionProvider, type OcSessionState, type OcSessionStatus, OcSignIn, OcSignInButton, type OcSignInButtonProps, type OcSignInProps, 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, buildSignInUrl, fetchOcLinkedIdentities, handleSudoRequired, redirectToSudo, useOcAddressSuggestion, useOcSession, useOptionalOcSession, useStepUpAuth, useWebAuthnList, useWebAuthnRegister };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,11 @@ function buildSignInUrl(cfg, returnTo) {
|
|
|
44
44
|
u.searchParams.set("return_to", returnTo);
|
|
45
45
|
return u.toString();
|
|
46
46
|
}
|
|
47
|
+
function buildAddAccountUrl(cfg, returnTo) {
|
|
48
|
+
const u = new URL(buildSignInUrl(cfg, returnTo));
|
|
49
|
+
u.searchParams.set("add", "1");
|
|
50
|
+
return u.toString();
|
|
51
|
+
}
|
|
47
52
|
var SessionContext = React3__namespace.createContext(null);
|
|
48
53
|
function normalizeDisplayIdentity(raw, didOc) {
|
|
49
54
|
const di = raw.display_identity ?? raw.displayIdentity;
|
|
@@ -52,6 +57,19 @@ function normalizeDisplayIdentity(raw, didOc) {
|
|
|
52
57
|
}
|
|
53
58
|
return { kind: "did", value: didOc };
|
|
54
59
|
}
|
|
60
|
+
function normalizeRosterEntry(raw) {
|
|
61
|
+
const didOc = raw.did_oc ?? raw.didOc;
|
|
62
|
+
if (!didOc) return null;
|
|
63
|
+
const di = raw.display_identity ?? raw.displayIdentity;
|
|
64
|
+
const displayIdentity = di && typeof di === "object" && typeof di.value === "string" && di.value.length > 0 && typeof di.kind === "string" && DISPLAY_IDENTITY_KINDS.includes(di.kind) ? { kind: di.kind, value: di.value } : { kind: "did", value: didOc };
|
|
65
|
+
return {
|
|
66
|
+
didOc,
|
|
67
|
+
displayName: raw.display_name ?? raw.displayName ?? null,
|
|
68
|
+
primaryBtc: raw.primary_btc ?? raw.primaryBtc ?? null,
|
|
69
|
+
displayIdentity,
|
|
70
|
+
lastSeenAt: raw.last_seen_at ?? raw.lastSeenAt ?? null
|
|
71
|
+
};
|
|
72
|
+
}
|
|
55
73
|
function normalizeAccount(raw) {
|
|
56
74
|
if (!raw) return null;
|
|
57
75
|
const didOc = raw.did_oc ?? raw.didOc;
|
|
@@ -77,6 +95,7 @@ function OcSessionProvider({
|
|
|
77
95
|
}) {
|
|
78
96
|
const cfg = React3__namespace.useMemo(() => resolveConfig(config), [config]);
|
|
79
97
|
const [account, setAccount] = React3__namespace.useState(null);
|
|
98
|
+
const [roster, setRoster] = React3__namespace.useState([]);
|
|
80
99
|
const [status, setStatus] = React3__namespace.useState("loading");
|
|
81
100
|
const [error, setError] = React3__namespace.useState(null);
|
|
82
101
|
const refresh = React3__namespace.useCallback(async () => {
|
|
@@ -89,6 +108,7 @@ function OcSessionProvider({
|
|
|
89
108
|
});
|
|
90
109
|
if (res.status === 401) {
|
|
91
110
|
setAccount(null);
|
|
111
|
+
setRoster([]);
|
|
92
112
|
setStatus("anonymous");
|
|
93
113
|
setError(null);
|
|
94
114
|
return;
|
|
@@ -100,7 +120,9 @@ function OcSessionProvider({
|
|
|
100
120
|
}
|
|
101
121
|
const body = await res.json();
|
|
102
122
|
const acct = normalizeAccount(body.account);
|
|
123
|
+
const rosterEntries = Array.isArray(body.roster) ? body.roster.map(normalizeRosterEntry).filter((r) => r !== null) : [];
|
|
103
124
|
setAccount(acct);
|
|
125
|
+
setRoster(rosterEntries);
|
|
104
126
|
setStatus(acct ? "authenticated" : "anonymous");
|
|
105
127
|
setError(null);
|
|
106
128
|
} catch (err) {
|
|
@@ -111,23 +133,63 @@ function OcSessionProvider({
|
|
|
111
133
|
React3__namespace.useEffect(() => {
|
|
112
134
|
void refresh();
|
|
113
135
|
}, [refresh]);
|
|
114
|
-
const signOut = React3__namespace.useCallback(
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
const signOut = React3__namespace.useCallback(
|
|
137
|
+
async (opts) => {
|
|
138
|
+
const scope = opts?.scope ?? "all";
|
|
139
|
+
try {
|
|
140
|
+
const url = new URL(`${cfg.authOrigin}${cfg.logoutPath}`);
|
|
141
|
+
if (scope === "current") url.searchParams.set("scope", "current");
|
|
142
|
+
const res = await fetch(url.toString(), {
|
|
143
|
+
method: "POST",
|
|
144
|
+
credentials: "include",
|
|
145
|
+
// `keepalive` lets the logout round-trip complete even if
|
|
146
|
+
// the caller hard-navigates away in the same tick (e.g.
|
|
147
|
+
// `<OcAccountMenu>` redirects home immediately on sign-out).
|
|
148
|
+
// Without it the in-flight request is cancelled on unload
|
|
149
|
+
// and the `.ochk.io` cookie may never get cleared.
|
|
150
|
+
keepalive: true
|
|
151
|
+
});
|
|
152
|
+
if (scope === "current" && res.ok) {
|
|
153
|
+
await refresh();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
setAccount(null);
|
|
159
|
+
setRoster([]);
|
|
160
|
+
setStatus("anonymous");
|
|
161
|
+
},
|
|
162
|
+
[cfg.authOrigin, cfg.logoutPath, refresh]
|
|
163
|
+
);
|
|
164
|
+
const switchAccount = React3__namespace.useCallback(
|
|
165
|
+
async (didOc) => {
|
|
166
|
+
if (typeof window === "undefined") return;
|
|
167
|
+
const res = await fetch(`${cfg.authOrigin}/api/auth/switch`, {
|
|
117
168
|
method: "POST",
|
|
118
169
|
credentials: "include",
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// `<OcAccountMenu>` redirects home immediately on sign-out).
|
|
122
|
-
// Without it the in-flight request is cancelled on unload
|
|
123
|
-
// and the `.ochk.io` cookie may never get cleared.
|
|
124
|
-
keepalive: true
|
|
170
|
+
headers: { "Content-Type": "application/json" },
|
|
171
|
+
body: JSON.stringify({ did_oc: didOc })
|
|
125
172
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
173
|
+
if (!res.ok) {
|
|
174
|
+
let reason = `http_${res.status}`;
|
|
175
|
+
try {
|
|
176
|
+
const body = await res.json();
|
|
177
|
+
if (body.reason) reason = body.reason;
|
|
178
|
+
} catch {
|
|
179
|
+
}
|
|
180
|
+
throw new Error(`[@orangecheck/auth-client] switchAccount failed: ${reason}`);
|
|
181
|
+
}
|
|
182
|
+
await refresh();
|
|
183
|
+
},
|
|
184
|
+
[cfg.authOrigin, refresh]
|
|
185
|
+
);
|
|
186
|
+
const addAccountUrl = React3__namespace.useCallback(
|
|
187
|
+
(returnTo) => {
|
|
188
|
+
const rt = returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0);
|
|
189
|
+
return buildAddAccountUrl(cfg, rt);
|
|
190
|
+
},
|
|
191
|
+
[cfg]
|
|
192
|
+
);
|
|
131
193
|
const setDisplayIdentity = React3__namespace.useCallback(
|
|
132
194
|
async (kind) => {
|
|
133
195
|
if (typeof window === "undefined") return;
|
|
@@ -155,13 +217,28 @@ function OcSessionProvider({
|
|
|
155
217
|
return {
|
|
156
218
|
status,
|
|
157
219
|
account,
|
|
220
|
+
roster,
|
|
158
221
|
error,
|
|
159
222
|
refresh,
|
|
160
223
|
signOut,
|
|
224
|
+
switchAccount,
|
|
225
|
+
addAccountUrl,
|
|
161
226
|
setDisplayIdentity,
|
|
162
227
|
signInUrl: buildSignInUrl(cfg, returnTo)
|
|
163
228
|
};
|
|
164
|
-
}, [
|
|
229
|
+
}, [
|
|
230
|
+
status,
|
|
231
|
+
account,
|
|
232
|
+
roster,
|
|
233
|
+
error,
|
|
234
|
+
refresh,
|
|
235
|
+
signOut,
|
|
236
|
+
switchAccount,
|
|
237
|
+
addAccountUrl,
|
|
238
|
+
setDisplayIdentity,
|
|
239
|
+
cfg,
|
|
240
|
+
defaultReturnTo
|
|
241
|
+
]);
|
|
165
242
|
return /* @__PURE__ */ jsxRuntime.jsx(SessionContext.Provider, { value, children });
|
|
166
243
|
}
|
|
167
244
|
function useOcSession() {
|
|
@@ -1688,6 +1765,7 @@ function OcSignIn({
|
|
|
1688
1765
|
onSuccess,
|
|
1689
1766
|
resolveReturnTo,
|
|
1690
1767
|
linkPrompt = true,
|
|
1768
|
+
add: addProp,
|
|
1691
1769
|
authOrigin = "https://ochk.io",
|
|
1692
1770
|
initialPath = "wallet",
|
|
1693
1771
|
paths,
|
|
@@ -1696,6 +1774,15 @@ function OcSignIn({
|
|
|
1696
1774
|
const walletEnabled = paths?.wallet ?? true;
|
|
1697
1775
|
const emailEnabled = paths?.email ?? true;
|
|
1698
1776
|
const safeReturn = safeReturnTo(returnTo);
|
|
1777
|
+
const [addMode, setAddMode] = React3__namespace.useState(Boolean(addProp));
|
|
1778
|
+
React3__namespace.useEffect(() => {
|
|
1779
|
+
if (typeof window === "undefined") return;
|
|
1780
|
+
if (addProp !== void 0) {
|
|
1781
|
+
setAddMode(Boolean(addProp));
|
|
1782
|
+
return;
|
|
1783
|
+
}
|
|
1784
|
+
setAddMode(new URLSearchParams(window.location.search).get("add") === "1");
|
|
1785
|
+
}, [addProp]);
|
|
1699
1786
|
const [path, setPath] = React3__namespace.useState(initialPath);
|
|
1700
1787
|
const [signedIn, setSignedIn] = React3__namespace.useState(null);
|
|
1701
1788
|
const [linkAlso, setLinkAlso] = React3__namespace.useState(false);
|
|
@@ -1838,6 +1925,7 @@ function OcSignIn({
|
|
|
1838
1925
|
{
|
|
1839
1926
|
authOrigin,
|
|
1840
1927
|
audience,
|
|
1928
|
+
add: addMode,
|
|
1841
1929
|
onSuccess: (a, t) => void handleSuccess(a, t, "wallet")
|
|
1842
1930
|
}
|
|
1843
1931
|
),
|
|
@@ -1845,6 +1933,7 @@ function OcSignIn({
|
|
|
1845
1933
|
EmailFlow,
|
|
1846
1934
|
{
|
|
1847
1935
|
authOrigin,
|
|
1936
|
+
add: addMode,
|
|
1848
1937
|
onSuccess: (a, t) => void handleSuccess(a, t, "email")
|
|
1849
1938
|
}
|
|
1850
1939
|
)
|
|
@@ -1900,6 +1989,23 @@ function SigninTab({
|
|
|
1900
1989
|
}
|
|
1901
1990
|
);
|
|
1902
1991
|
}
|
|
1992
|
+
function ProviderIcon({ id }) {
|
|
1993
|
+
const common = {
|
|
1994
|
+
width: 14,
|
|
1995
|
+
height: 14,
|
|
1996
|
+
viewBox: "0 0 24 24",
|
|
1997
|
+
fill: "currentColor",
|
|
1998
|
+
"aria-hidden": true,
|
|
1999
|
+
style: { flex: "0 0 auto" }
|
|
2000
|
+
};
|
|
2001
|
+
if (id === "google") {
|
|
2002
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { ...common, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z" }) });
|
|
2003
|
+
}
|
|
2004
|
+
if (id === "github") {
|
|
2005
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { ...common, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" }) });
|
|
2006
|
+
}
|
|
2007
|
+
return null;
|
|
2008
|
+
}
|
|
1903
2009
|
function ProviderSignIn({
|
|
1904
2010
|
authOrigin,
|
|
1905
2011
|
returnTo
|
|
@@ -1942,7 +2048,7 @@ function ProviderSignIn({
|
|
|
1942
2048
|
]
|
|
1943
2049
|
}
|
|
1944
2050
|
),
|
|
1945
|
-
providers.map((p, i) => /* @__PURE__ */ jsxRuntime.
|
|
2051
|
+
providers.map((p, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1946
2052
|
"a",
|
|
1947
2053
|
{
|
|
1948
2054
|
href: `${authOrigin}/api/auth/${p.id}/start?return_to=${encodeURIComponent(
|
|
@@ -1950,12 +2056,14 @@ function ProviderSignIn({
|
|
|
1950
2056
|
)}`,
|
|
1951
2057
|
"data-oc-signin-provider": p.id,
|
|
1952
2058
|
style: {
|
|
1953
|
-
display: "
|
|
2059
|
+
display: "flex",
|
|
2060
|
+
alignItems: "center",
|
|
2061
|
+
justifyContent: "center",
|
|
2062
|
+
gap: 10,
|
|
1954
2063
|
boxSizing: "border-box",
|
|
1955
2064
|
width: "100%",
|
|
1956
2065
|
marginTop: i === 0 ? 0 : 8,
|
|
1957
2066
|
padding: "0.6rem 0.875rem",
|
|
1958
|
-
textAlign: "center",
|
|
1959
2067
|
border: "1px solid var(--border, #27272a)",
|
|
1960
2068
|
borderRadius: 6,
|
|
1961
2069
|
background: "transparent",
|
|
@@ -1964,13 +2072,16 @@ function ProviderSignIn({
|
|
|
1964
2072
|
fontSize: 12,
|
|
1965
2073
|
textDecoration: "none"
|
|
1966
2074
|
},
|
|
1967
|
-
children:
|
|
2075
|
+
children: [
|
|
2076
|
+
/* @__PURE__ */ jsxRuntime.jsx(ProviderIcon, { id: p.id }),
|
|
2077
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: p.label })
|
|
2078
|
+
]
|
|
1968
2079
|
},
|
|
1969
2080
|
p.id
|
|
1970
2081
|
))
|
|
1971
2082
|
] });
|
|
1972
2083
|
}
|
|
1973
|
-
function WalletFlow({ authOrigin, audience, onSuccess }) {
|
|
2084
|
+
function WalletFlow({ authOrigin, audience, add, onSuccess }) {
|
|
1974
2085
|
const [address, setAddress] = React3__namespace.useState("");
|
|
1975
2086
|
const [error, setError] = React3__namespace.useState(null);
|
|
1976
2087
|
const [submitting, setSubmitting] = React3__namespace.useState(false);
|
|
@@ -2018,7 +2129,12 @@ function WalletFlow({ authOrigin, audience, onSuccess }) {
|
|
|
2018
2129
|
scheme: "bip322",
|
|
2019
2130
|
expectedNonce: challenge.nonce,
|
|
2020
2131
|
expectedAudience: audience,
|
|
2021
|
-
expectedPurpose: "login"
|
|
2132
|
+
expectedPurpose: "login",
|
|
2133
|
+
// Multi-account add-mode · the auth host preserves
|
|
2134
|
+
// the current roster_id when set, instead of minting
|
|
2135
|
+
// a fresh one. Hosts that haven't deployed the
|
|
2136
|
+
// multi-account migration silently ignore the field.
|
|
2137
|
+
...add ? { add: true } : {}
|
|
2022
2138
|
})
|
|
2023
2139
|
});
|
|
2024
2140
|
const json = await res.json();
|
|
@@ -2069,7 +2185,7 @@ function WalletFlow({ authOrigin, audience, onSuccess }) {
|
|
|
2069
2185
|
/* @__PURE__ */ jsxRuntime.jsx(Hint, { children: "Detection picks the first installed BIP-322-capable extension. Address is the one your wallet will sign for." })
|
|
2070
2186
|
] });
|
|
2071
2187
|
}
|
|
2072
|
-
function EmailFlow({ authOrigin, onSuccess }) {
|
|
2188
|
+
function EmailFlow({ authOrigin, add, onSuccess }) {
|
|
2073
2189
|
const [stage, setStage] = React3__namespace.useState("enter");
|
|
2074
2190
|
const [email, setEmail] = React3__namespace.useState("");
|
|
2075
2191
|
const [emailError, setEmailError] = React3__namespace.useState(null);
|
|
@@ -2120,7 +2236,13 @@ function EmailFlow({ authOrigin, onSuccess }) {
|
|
|
2120
2236
|
method: "POST",
|
|
2121
2237
|
credentials: "include",
|
|
2122
2238
|
headers: { "Content-Type": "application/json" },
|
|
2123
|
-
body: JSON.stringify({
|
|
2239
|
+
body: JSON.stringify({
|
|
2240
|
+
email,
|
|
2241
|
+
code,
|
|
2242
|
+
token,
|
|
2243
|
+
// Multi-account add-mode · see WalletFlow.
|
|
2244
|
+
...add ? { add: true } : {}
|
|
2245
|
+
})
|
|
2124
2246
|
});
|
|
2125
2247
|
const json = await res.json();
|
|
2126
2248
|
if (!res.ok || !("ok" in json) || !json.ok || !json.account) {
|
|
@@ -2621,6 +2743,7 @@ exports.OcLinkedIdentities = OcLinkedIdentities;
|
|
|
2621
2743
|
exports.OcSessionProvider = OcSessionProvider;
|
|
2622
2744
|
exports.OcSignIn = OcSignIn;
|
|
2623
2745
|
exports.OcSignInButton = OcSignInButton;
|
|
2746
|
+
exports.buildAddAccountUrl = buildAddAccountUrl;
|
|
2624
2747
|
exports.buildSignInUrl = buildSignInUrl;
|
|
2625
2748
|
exports.fetchOcLinkedIdentities = fetchOcLinkedIdentities;
|
|
2626
2749
|
exports.handleSudoRequired = handleSudoRequired;
|