@ic-reactor/react 3.12.5 → 4.0.0-beta.1
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 +236 -423
- package/dist/index.d.ts +259 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +470 -17
- package/dist/index.js.map +1 -1
- package/llms.txt +82 -54
- package/package.json +12 -28
- package/src/index.tsx +611 -0
- package/dist/auth/authentication-manager.d.ts +0 -123
- package/dist/auth/authentication-manager.d.ts.map +0 -1
- package/dist/auth/authentication-manager.js +0 -767
- package/dist/auth/authentication-manager.js.map +0 -1
- package/dist/auth/constants.d.ts +0 -24
- package/dist/auth/constants.d.ts.map +0 -1
- package/dist/auth/constants.js +0 -24
- package/dist/auth/constants.js.map +0 -1
- package/dist/auth/createIdentityAttributeHooks.d.ts +0 -14
- package/dist/auth/createIdentityAttributeHooks.d.ts.map +0 -1
- package/dist/auth/createIdentityAttributeHooks.js +0 -106
- package/dist/auth/createIdentityAttributeHooks.js.map +0 -1
- package/dist/auth/identity-attributes-manager.d.ts +0 -26
- package/dist/auth/identity-attributes-manager.d.ts.map +0 -1
- package/dist/auth/identity-attributes-manager.js +0 -107
- package/dist/auth/identity-attributes-manager.js.map +0 -1
- package/dist/auth/identity-attributes.d.ts +0 -19
- package/dist/auth/identity-attributes.d.ts.map +0 -1
- package/dist/auth/identity-attributes.js +0 -170
- package/dist/auth/identity-attributes.js.map +0 -1
- package/dist/auth/index.d.ts +0 -8
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -8
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/local-ii-probe.d.ts +0 -46
- package/dist/auth/local-ii-probe.d.ts.map +0 -1
- package/dist/auth/local-ii-probe.js +0 -102
- package/dist/auth/local-ii-probe.js.map +0 -1
- package/dist/auth/types.d.ts +0 -179
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -2
- package/dist/auth/types.js.map +0 -1
- package/dist/createActorHooks.d.ts +0 -52
- package/dist/createActorHooks.d.ts.map +0 -1
- package/dist/createActorHooks.js +0 -17
- package/dist/createActorHooks.js.map +0 -1
- package/dist/createInfiniteQuery.d.ts +0 -144
- package/dist/createInfiniteQuery.d.ts.map +0 -1
- package/dist/createInfiniteQuery.js +0 -174
- package/dist/createInfiniteQuery.js.map +0 -1
- package/dist/createMutation.d.ts +0 -30
- package/dist/createMutation.d.ts.map +0 -1
- package/dist/createMutation.js +0 -192
- package/dist/createMutation.js.map +0 -1
- package/dist/createQuery.d.ts +0 -30
- package/dist/createQuery.d.ts.map +0 -1
- package/dist/createQuery.js +0 -117
- package/dist/createQuery.js.map +0 -1
- package/dist/createSuspenseInfiniteQuery.d.ts +0 -147
- package/dist/createSuspenseInfiniteQuery.d.ts.map +0 -1
- package/dist/createSuspenseInfiniteQuery.js +0 -177
- package/dist/createSuspenseInfiniteQuery.js.map +0 -1
- package/dist/createSuspenseQuery.d.ts +0 -25
- package/dist/createSuspenseQuery.d.ts.map +0 -1
- package/dist/createSuspenseQuery.js +0 -111
- package/dist/createSuspenseQuery.js.map +0 -1
- package/dist/defineReactor.d.ts +0 -125
- package/dist/defineReactor.d.ts.map +0 -1
- package/dist/defineReactor.js +0 -180
- package/dist/defineReactor.js.map +0 -1
- package/dist/hooks/createAuthHooks.d.ts +0 -43
- package/dist/hooks/createAuthHooks.d.ts.map +0 -1
- package/dist/hooks/createAuthHooks.js +0 -131
- package/dist/hooks/createAuthHooks.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -21
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -24
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/useActorInfiniteQuery.d.ts +0 -39
- package/dist/hooks/useActorInfiniteQuery.d.ts.map +0 -1
- package/dist/hooks/useActorInfiniteQuery.js +0 -56
- package/dist/hooks/useActorInfiniteQuery.js.map +0 -1
- package/dist/hooks/useActorMethod.d.ts +0 -115
- package/dist/hooks/useActorMethod.d.ts.map +0 -1
- package/dist/hooks/useActorMethod.js +0 -250
- package/dist/hooks/useActorMethod.js.map +0 -1
- package/dist/hooks/useActorMutation.d.ts +0 -48
- package/dist/hooks/useActorMutation.d.ts.map +0 -1
- package/dist/hooks/useActorMutation.js +0 -69
- package/dist/hooks/useActorMutation.js.map +0 -1
- package/dist/hooks/useActorQuery.d.ts +0 -32
- package/dist/hooks/useActorQuery.d.ts.map +0 -1
- package/dist/hooks/useActorQuery.js +0 -46
- package/dist/hooks/useActorQuery.js.map +0 -1
- package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts +0 -39
- package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts.map +0 -1
- package/dist/hooks/useActorSuspenseInfiniteQuery.js +0 -56
- package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +0 -1
- package/dist/hooks/useActorSuspenseQuery.d.ts +0 -32
- package/dist/hooks/useActorSuspenseQuery.d.ts.map +0 -1
- package/dist/hooks/useActorSuspenseQuery.js +0 -47
- package/dist/hooks/useActorSuspenseQuery.js.map +0 -1
- package/dist/types.d.ts +0 -270
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -51
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -105
- package/dist/utils.js.map +0 -1
- package/dist/validation.d.ts +0 -131
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -125
- package/dist/validation.js.map +0 -1
- package/src/auth/authentication-manager.ts +0 -860
- package/src/auth/constants.ts +0 -32
- package/src/auth/createIdentityAttributeHooks.ts +0 -143
- package/src/auth/identity-attributes-manager.ts +0 -131
- package/src/auth/identity-attributes.ts +0 -270
- package/src/auth/index.ts +0 -7
- package/src/auth/local-ii-probe.ts +0 -147
- package/src/auth/types.ts +0 -200
- package/src/createActorHooks.ts +0 -220
- package/src/createInfiniteQuery.ts +0 -578
- package/src/createMutation.ts +0 -341
- package/src/createQuery.ts +0 -237
- package/src/createSuspenseInfiniteQuery.ts +0 -601
- package/src/createSuspenseQuery.ts +0 -234
- package/src/defineReactor.ts +0 -324
- package/src/hooks/createAuthHooks.ts +0 -189
- package/src/hooks/index.ts +0 -103
- package/src/hooks/useActorInfiniteQuery.ts +0 -205
- package/src/hooks/useActorMethod.ts +0 -507
- package/src/hooks/useActorMutation.ts +0 -205
- package/src/hooks/useActorQuery.ts +0 -124
- package/src/hooks/useActorSuspenseInfiniteQuery.ts +0 -205
- package/src/hooks/useActorSuspenseQuery.ts +0 -132
- package/src/index.ts +0 -23
- package/src/types.ts +0 -499
- package/src/utils.ts +0 -121
- package/src/validation.ts +0 -202
|
@@ -1,767 +0,0 @@
|
|
|
1
|
-
import { AnonymousIdentity } from "@icp-sdk/core/agent";
|
|
2
|
-
import { isDev } from "@ic-reactor/core";
|
|
3
|
-
import { Principal } from "@icp-sdk/core/principal";
|
|
4
|
-
import { safeGetCanisterEnv } from "@icp-sdk/core/agent/canister-env";
|
|
5
|
-
import { probeLocalInternetIdentity, localInternetIdentityUnavailableError, } from "./local-ii-probe.js";
|
|
6
|
-
import { IC_INTERNET_IDENTITY_PROVIDER, INTERNET_IDENTITY_PROVIDER_ENV_KEY, LOCAL_INTERNET_IDENTITY_CANISTER_ID, localInternetIdentityProvider, } from "./constants.js";
|
|
7
|
-
/**
|
|
8
|
-
* Manages Internet Identity sign-in, session restoration, and authentication
|
|
9
|
-
* state for a {@link ClientManager}.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const authentication = new AuthenticationManager({ clientManager })
|
|
14
|
-
* const identity = await authentication.authenticate()
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export class AuthenticationManager {
|
|
18
|
-
/** The current authentication state. */
|
|
19
|
-
get authState() {
|
|
20
|
-
return this.authStateValue;
|
|
21
|
-
}
|
|
22
|
-
constructor({ clientManager, authClient, identityProvider, internetIdentityId, ...clientOptions }) {
|
|
23
|
-
Object.defineProperty(this, "authClient", {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
configurable: true,
|
|
26
|
-
writable: true,
|
|
27
|
-
value: void 0
|
|
28
|
-
});
|
|
29
|
-
Object.defineProperty(this, "authPromise", {
|
|
30
|
-
enumerable: true,
|
|
31
|
-
configurable: true,
|
|
32
|
-
writable: true,
|
|
33
|
-
value: void 0
|
|
34
|
-
});
|
|
35
|
-
Object.defineProperty(this, "authClientWasProvided", {
|
|
36
|
-
enumerable: true,
|
|
37
|
-
configurable: true,
|
|
38
|
-
writable: true,
|
|
39
|
-
value: false
|
|
40
|
-
});
|
|
41
|
-
Object.defineProperty(this, "authStateRevision", {
|
|
42
|
-
enumerable: true,
|
|
43
|
-
configurable: true,
|
|
44
|
-
writable: true,
|
|
45
|
-
value: 0
|
|
46
|
-
});
|
|
47
|
-
Object.defineProperty(this, "authStateSubscribers", {
|
|
48
|
-
enumerable: true,
|
|
49
|
-
configurable: true,
|
|
50
|
-
writable: true,
|
|
51
|
-
value: []
|
|
52
|
-
});
|
|
53
|
-
Object.defineProperty(this, "authClientConstructor", {
|
|
54
|
-
enumerable: true,
|
|
55
|
-
configurable: true,
|
|
56
|
-
writable: true,
|
|
57
|
-
value: void 0
|
|
58
|
-
});
|
|
59
|
-
Object.defineProperty(this, "authClientConstructorPromise", {
|
|
60
|
-
enumerable: true,
|
|
61
|
-
configurable: true,
|
|
62
|
-
writable: true,
|
|
63
|
-
value: void 0
|
|
64
|
-
});
|
|
65
|
-
Object.defineProperty(this, "authModuleMissing", {
|
|
66
|
-
enumerable: true,
|
|
67
|
-
configurable: true,
|
|
68
|
-
writable: true,
|
|
69
|
-
value: false
|
|
70
|
-
});
|
|
71
|
-
Object.defineProperty(this, "authClientOptions", {
|
|
72
|
-
enumerable: true,
|
|
73
|
-
configurable: true,
|
|
74
|
-
writable: true,
|
|
75
|
-
value: void 0
|
|
76
|
-
});
|
|
77
|
-
Object.defineProperty(this, "authStateValue", {
|
|
78
|
-
enumerable: true,
|
|
79
|
-
configurable: true,
|
|
80
|
-
writable: true,
|
|
81
|
-
value: {
|
|
82
|
-
identity: null,
|
|
83
|
-
isAuthenticating: false,
|
|
84
|
-
isAuthenticated: false,
|
|
85
|
-
error: undefined,
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
Object.defineProperty(this, "identityProvider", {
|
|
89
|
-
enumerable: true,
|
|
90
|
-
configurable: true,
|
|
91
|
-
writable: true,
|
|
92
|
-
value: void 0
|
|
93
|
-
});
|
|
94
|
-
Object.defineProperty(this, "internetIdentityId", {
|
|
95
|
-
enumerable: true,
|
|
96
|
-
configurable: true,
|
|
97
|
-
writable: true,
|
|
98
|
-
value: void 0
|
|
99
|
-
});
|
|
100
|
-
/**
|
|
101
|
-
* Which authorize path the locally deployed Internet Identity serves, once
|
|
102
|
-
* probed. `undefined` means not probed yet; `null` means it serves no sign-in
|
|
103
|
-
* UI and login should fail with an explanation rather than open a popup onto
|
|
104
|
-
* a gateway error page.
|
|
105
|
-
*/
|
|
106
|
-
Object.defineProperty(this, "localAuthorizePath", {
|
|
107
|
-
enumerable: true,
|
|
108
|
-
configurable: true,
|
|
109
|
-
writable: true,
|
|
110
|
-
value: void 0
|
|
111
|
-
});
|
|
112
|
-
Object.defineProperty(this, "defaultClientOptions", {
|
|
113
|
-
enumerable: true,
|
|
114
|
-
configurable: true,
|
|
115
|
-
writable: true,
|
|
116
|
-
value: void 0
|
|
117
|
-
});
|
|
118
|
-
Object.defineProperty(this, "clientManager", {
|
|
119
|
-
enumerable: true,
|
|
120
|
-
configurable: true,
|
|
121
|
-
writable: true,
|
|
122
|
-
value: void 0
|
|
123
|
-
});
|
|
124
|
-
Object.defineProperty(this, "authenticate", {
|
|
125
|
-
enumerable: true,
|
|
126
|
-
configurable: true,
|
|
127
|
-
writable: true,
|
|
128
|
-
value: async () => {
|
|
129
|
-
if (this.authState.isAuthenticated) {
|
|
130
|
-
// Returning on the cached flag alone meant a delegation that expired
|
|
131
|
-
// mid-session was never re-observed: the UI kept rendering a signed-in
|
|
132
|
-
// state while every update call failed, and only a reload recovered.
|
|
133
|
-
// Re-ask the client, which reads the cached expiry rather than hitting
|
|
134
|
-
// storage. A throw here is treated as "still valid" so a transient
|
|
135
|
-
// failure cannot sign anyone out.
|
|
136
|
-
if (!this.authClient) {
|
|
137
|
-
return this.authState.identity || undefined;
|
|
138
|
-
}
|
|
139
|
-
const stillValid = await Promise.resolve(this.authClient.isAuthenticated()).catch(() => true);
|
|
140
|
-
if (stillValid) {
|
|
141
|
-
return this.authState.identity || undefined;
|
|
142
|
-
}
|
|
143
|
-
// Expired. Re-deriving state from the client will not help: the v8
|
|
144
|
-
// client keeps handing out the lapsed delegation from getIdentity()
|
|
145
|
-
// until signOut() runs (only a fresh page load purges it), so the
|
|
146
|
-
// expired identity would go straight back on the agent and every
|
|
147
|
-
// refetch would be signed with it. End the session explicitly.
|
|
148
|
-
await this.expireSession();
|
|
149
|
-
return undefined;
|
|
150
|
-
}
|
|
151
|
-
if (this.authPromise) {
|
|
152
|
-
return this.authPromise;
|
|
153
|
-
}
|
|
154
|
-
if (this.authModuleMissing) {
|
|
155
|
-
return undefined;
|
|
156
|
-
}
|
|
157
|
-
this.authPromise = (async () => {
|
|
158
|
-
if (isDev() && typeof window !== "undefined") {
|
|
159
|
-
console.info(`%cic-reactor:%c Authenticating...`, "color: #3b82f6; font-weight: bold", "color: inherit", {
|
|
160
|
-
network: this.clientManager.network,
|
|
161
|
-
authClient: this.authClient ? "Shared Instance" : "Dynamic Import",
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
this.updateState({ isAuthenticating: true });
|
|
165
|
-
// Anything that changes auth state — a logout, notably — bumps this. If
|
|
166
|
-
// it moves while the awaits below are in flight, the result we are
|
|
167
|
-
// holding describes a session that has since ended, and installing it
|
|
168
|
-
// would put the signed-out user's delegation back on the agent.
|
|
169
|
-
const revision = this.authStateRevision;
|
|
170
|
-
try {
|
|
171
|
-
if (!this.authClient) {
|
|
172
|
-
const authClient = await this.initializeClient(this.resolveClientOptions());
|
|
173
|
-
if (!authClient) {
|
|
174
|
-
this.updateState({ isAuthenticating: false });
|
|
175
|
-
return undefined;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
const clientIdentity = await this.authClient.getIdentity();
|
|
179
|
-
const isAuthenticated = await this.authClient.isAuthenticated();
|
|
180
|
-
if (revision !== this.authStateRevision) {
|
|
181
|
-
// Superseded — leave whatever ran in the meantime in place.
|
|
182
|
-
return this.authState.identity || undefined;
|
|
183
|
-
}
|
|
184
|
-
// A client that says it is not authenticated but still hands out a
|
|
185
|
-
// non-anonymous identity is holding a delegation it will no longer
|
|
186
|
-
// vouch for (expired, mid-session). Nothing may be signed with it.
|
|
187
|
-
const identity = isAuthenticated || clientIdentity.getPrincipal().isAnonymous()
|
|
188
|
-
? clientIdentity
|
|
189
|
-
: new AnonymousIdentity();
|
|
190
|
-
// Restoring an anonymous session is the common first-load case; pushing
|
|
191
|
-
// it through updateAgent would invalidate the whole query cache on
|
|
192
|
-
// every mount for nothing. It is only skipped while the agent is
|
|
193
|
-
// anonymous too, so a lapsed delegation still gets replaced.
|
|
194
|
-
if (isAuthenticated ||
|
|
195
|
-
!identity.getPrincipal().isAnonymous() ||
|
|
196
|
-
!this.agentIsAnonymous()) {
|
|
197
|
-
this.clientManager.updateAgent(identity);
|
|
198
|
-
}
|
|
199
|
-
this.updateState({
|
|
200
|
-
identity,
|
|
201
|
-
isAuthenticated,
|
|
202
|
-
isAuthenticating: false,
|
|
203
|
-
});
|
|
204
|
-
return identity;
|
|
205
|
-
}
|
|
206
|
-
catch (error) {
|
|
207
|
-
this.updateState({ error: error, isAuthenticating: false });
|
|
208
|
-
console.error("Authentication failed:", error);
|
|
209
|
-
throw error;
|
|
210
|
-
}
|
|
211
|
-
finally {
|
|
212
|
-
this.authPromise = undefined;
|
|
213
|
-
}
|
|
214
|
-
})();
|
|
215
|
-
return this.authPromise;
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
Object.defineProperty(this, "login", {
|
|
219
|
-
enumerable: true,
|
|
220
|
-
configurable: true,
|
|
221
|
-
writable: true,
|
|
222
|
-
value: async (loginOptions) => {
|
|
223
|
-
let didCompleteSignIn = false;
|
|
224
|
-
try {
|
|
225
|
-
const authClientOptions = this.resolveClientOptions(loginOptions);
|
|
226
|
-
// Stays synchronous when `prepareClient()` has already loaded the auth
|
|
227
|
-
// module, so `signIn()` still runs inside the caller's click handler.
|
|
228
|
-
if (!this.ensurePreparedClient(authClientOptions)) {
|
|
229
|
-
await this.initializeClient(authClientOptions);
|
|
230
|
-
}
|
|
231
|
-
if (!this.authClient) {
|
|
232
|
-
await this.authenticate();
|
|
233
|
-
}
|
|
234
|
-
if (!this.authClient) {
|
|
235
|
-
throw new Error("Authentication module is missing or failed to initialize. To use login, install the optional auth peer: npm install @icp-sdk/auth. If it is already installed and your bundler could not resolve it, pass a pre-constructed client instead: new AuthenticationManager({ clientManager, authClient: new AuthClient(...) })");
|
|
236
|
-
}
|
|
237
|
-
this.updateState({ isAuthenticating: true, error: undefined });
|
|
238
|
-
const identity = await this.signInOrRecoverIdentity(getSignInOptions(loginOptions));
|
|
239
|
-
if (!this.clientManager.agentState.isInitialized) {
|
|
240
|
-
await this.clientManager.initializeAgent();
|
|
241
|
-
}
|
|
242
|
-
this.clientManager.updateAgent(identity);
|
|
243
|
-
this.updateState({
|
|
244
|
-
identity,
|
|
245
|
-
isAuthenticated: true,
|
|
246
|
-
isAuthenticating: false,
|
|
247
|
-
});
|
|
248
|
-
didCompleteSignIn = true;
|
|
249
|
-
try {
|
|
250
|
-
await loginOptions?.onSuccess?.();
|
|
251
|
-
}
|
|
252
|
-
catch (callbackError) {
|
|
253
|
-
this.updateState({ error: callbackError });
|
|
254
|
-
await loginOptions?.onError?.(callbackError.message);
|
|
255
|
-
throw callbackError;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
if (!didCompleteSignIn) {
|
|
260
|
-
await loginOptions?.onError?.(error.message);
|
|
261
|
-
this.updateState({
|
|
262
|
-
error: error,
|
|
263
|
-
isAuthenticating: false,
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
throw error;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
Object.defineProperty(this, "logout", {
|
|
271
|
-
enumerable: true,
|
|
272
|
-
configurable: true,
|
|
273
|
-
writable: true,
|
|
274
|
-
value: async (options) => {
|
|
275
|
-
if (!this.authClient) {
|
|
276
|
-
throw new Error("Authentication module is missing or failed to initialize. To use logout, install the optional auth peer: npm install @icp-sdk/auth. If it is already installed and your bundler could not resolve it, pass a pre-constructed client instead: new AuthenticationManager({ clientManager, authClient: new AuthClient(...) })");
|
|
277
|
-
}
|
|
278
|
-
this.updateState({ isAuthenticating: true, error: undefined });
|
|
279
|
-
try {
|
|
280
|
-
await this.authClient.signOut(options);
|
|
281
|
-
const identity = await this.authClient.getIdentity();
|
|
282
|
-
this.clientManager.updateAgent(identity);
|
|
283
|
-
this.updateState({
|
|
284
|
-
identity,
|
|
285
|
-
isAuthenticated: false,
|
|
286
|
-
isAuthenticating: false,
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
// Without this the manager was left with `isAuthenticating: true` and no
|
|
291
|
-
// recorded error, so a button disabled on `isAuthenticating` stayed stuck
|
|
292
|
-
// and nothing told the app why.
|
|
293
|
-
this.updateState({ error: error, isAuthenticating: false });
|
|
294
|
-
throw error;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
this.clientManager = clientManager;
|
|
299
|
-
const canisterEnv = typeof window !== "undefined" ? getAuthenticationCanisterEnv() : undefined;
|
|
300
|
-
this.identityProvider =
|
|
301
|
-
identityProvider ||
|
|
302
|
-
acceptEnvIdentityProvider(canisterEnv?.[INTERNET_IDENTITY_PROVIDER_ENV_KEY] ||
|
|
303
|
-
canisterEnv?.["PUBLIC_INTERNET_IDENTITY_PROVIDER"], clientManager);
|
|
304
|
-
// Same cookie, same decision. This one only ever reaches a local provider
|
|
305
|
-
// URL, but `allowEnvConfig: false` has to mean the cookie is not consulted
|
|
306
|
-
// rather than mostly not consulted.
|
|
307
|
-
this.internetIdentityId =
|
|
308
|
-
internetIdentityId ||
|
|
309
|
-
(clientManager.trustsEnvConfig
|
|
310
|
-
? acceptEnvCanisterId(canisterEnv?.["internet_identity"] ||
|
|
311
|
-
canisterEnv?.["PUBLIC_CANISTER_ID:internet_identity"] ||
|
|
312
|
-
canisterEnv?.["CANISTER_ID_INTERNET_IDENTITY"])
|
|
313
|
-
: undefined);
|
|
314
|
-
this.defaultClientOptions = clientOptions;
|
|
315
|
-
if (authClient) {
|
|
316
|
-
this.authClientWasProvided = true;
|
|
317
|
-
this.authClient = authClient;
|
|
318
|
-
this.syncStateFromClient(this.authStateRevision).catch((error) => {
|
|
319
|
-
this.updateState({ error: error, isAuthenticating: false });
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
else if (typeof window !== "undefined") {
|
|
323
|
-
this.loadAuthClientConstructor().catch(() => {
|
|
324
|
-
// Optional auth support is reported when an auth method is used.
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
/** @internal Used by IdentityAttributesManager. */
|
|
329
|
-
get client() {
|
|
330
|
-
return this.authClient;
|
|
331
|
-
}
|
|
332
|
-
subscribeAuthState(callback) {
|
|
333
|
-
this.authStateSubscribers.push(callback);
|
|
334
|
-
return () => {
|
|
335
|
-
this.authStateSubscribers = this.authStateSubscribers.filter((subscriber) => subscriber !== callback);
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Preloads the auth module and creates an AuthClient ahead of time.
|
|
340
|
-
*
|
|
341
|
-
* Call (and await) this before wiring up a login button: it makes
|
|
342
|
-
* {@link login} and {@link IdentityAttributesManager.request} able to open
|
|
343
|
-
* the identity provider synchronously inside the click handler, which is
|
|
344
|
-
* what browser popup blockers and the ICRC-29 transport require.
|
|
345
|
-
*/
|
|
346
|
-
async prepareClient(options) {
|
|
347
|
-
// Before resolving options, because resolving them is what picks the
|
|
348
|
-
// provider URL. This is the last async point before `login()` has to stay
|
|
349
|
-
// inside the user gesture, so the answer has to be cached by now.
|
|
350
|
-
await this.ensureLocalAuthorizePath();
|
|
351
|
-
const clientOptions = this.resolveClientOptions(options);
|
|
352
|
-
if (this.authClient && !this.shouldRecreateClient(clientOptions)) {
|
|
353
|
-
return this.authClient;
|
|
354
|
-
}
|
|
355
|
-
return this.initializeClient(clientOptions);
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Probe the local Internet Identity canister once, and remember what it
|
|
359
|
-
* serves.
|
|
360
|
-
*
|
|
361
|
-
* Only for the derived local provider: an explicitly configured
|
|
362
|
-
* `identityProvider` is the caller's business, and mainnet is fixed.
|
|
363
|
-
*/
|
|
364
|
-
async ensureLocalAuthorizePath() {
|
|
365
|
-
if (this.localAuthorizePath !== undefined)
|
|
366
|
-
return;
|
|
367
|
-
if (this.identityProvider)
|
|
368
|
-
return;
|
|
369
|
-
if (!this.clientManager.isLocal)
|
|
370
|
-
return;
|
|
371
|
-
const canisterId = this.internetIdentityId ?? LOCAL_INTERNET_IDENTITY_CANISTER_ID;
|
|
372
|
-
const { path, inconclusive } = await probeLocalInternetIdentity(this.clientManager.agent, canisterId);
|
|
373
|
-
// An inconclusive probe must not change behaviour: the canister may be
|
|
374
|
-
// fine and merely unreachable from here, and a diagnostic that blocks a
|
|
375
|
-
// working login is worse than the failure it explains.
|
|
376
|
-
this.localAuthorizePath = inconclusive ? "/authorize" : path;
|
|
377
|
-
if (path === "/#authorize" && !inconclusive) {
|
|
378
|
-
console.warn(`[ic-reactor] Internet Identity canister ${canisterId} serves its sign-in UI at ` +
|
|
379
|
-
`"/" rather than "/authorize" — using the legacy #authorize flow. This is a ` +
|
|
380
|
-
`pre-2026 build; newer ones through release-2026-03-16 serve /authorize directly.`);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Returns an AuthClient without awaiting, or `undefined` when the auth
|
|
385
|
-
* module has not been loaded yet.
|
|
386
|
-
*
|
|
387
|
-
* Callers that must stay inside a user gesture use this instead of
|
|
388
|
-
* `ensureClient`; awaiting anything before opening the identity
|
|
389
|
-
* provider window loses the gesture.
|
|
390
|
-
*/
|
|
391
|
-
getPreparedClient(options) {
|
|
392
|
-
return this.ensurePreparedClient(this.resolveClientOptions(options));
|
|
393
|
-
}
|
|
394
|
-
async initializeClient(options) {
|
|
395
|
-
const AuthClient = await this.loadAuthClientConstructor();
|
|
396
|
-
if (!AuthClient) {
|
|
397
|
-
return undefined;
|
|
398
|
-
}
|
|
399
|
-
this.authClient = new AuthClient(options);
|
|
400
|
-
this.authClientOptions = options;
|
|
401
|
-
return this.authClient;
|
|
402
|
-
}
|
|
403
|
-
/** @internal Used by IdentityAttributesManager. */
|
|
404
|
-
async signInOrRecoverIdentity(options) {
|
|
405
|
-
if (!this.authClient) {
|
|
406
|
-
throw new Error("Authentication module is missing or failed to initialize. To use login, install the optional auth peer: npm install @icp-sdk/auth. If it is already installed and your bundler could not resolve it, pass a pre-constructed client instead: new AuthenticationManager({ clientManager, authClient: new AuthClient(...) })");
|
|
407
|
-
}
|
|
408
|
-
try {
|
|
409
|
-
return await this.authClient.signIn(options);
|
|
410
|
-
}
|
|
411
|
-
catch (error) {
|
|
412
|
-
const identity = await Promise.resolve(this.authClient.getIdentity()).catch(() => null);
|
|
413
|
-
const isAuthenticated = await Promise.resolve(this.authClient.isAuthenticated()).catch(() => false);
|
|
414
|
-
if (identity && isAuthenticated) {
|
|
415
|
-
return identity;
|
|
416
|
-
}
|
|
417
|
-
throw error;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
ensurePreparedClient(options) {
|
|
421
|
-
if (this.authClient && !this.shouldRecreateClient(options)) {
|
|
422
|
-
return this.authClient;
|
|
423
|
-
}
|
|
424
|
-
const AuthClient = this.authClientConstructor;
|
|
425
|
-
if (!AuthClient || this.authClientWasProvided) {
|
|
426
|
-
return undefined;
|
|
427
|
-
}
|
|
428
|
-
this.authClient = new AuthClient(options);
|
|
429
|
-
this.authClientOptions = options;
|
|
430
|
-
return this.authClient;
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Only rebuild the client when the effective options actually changed.
|
|
434
|
-
*
|
|
435
|
-
* Recreating on every call would discard the client warmed up by
|
|
436
|
-
* `prepareClient()` and register a duplicate sign-out callback on the
|
|
437
|
-
* shared IdleManager singleton each time.
|
|
438
|
-
*/
|
|
439
|
-
shouldRecreateClient(options) {
|
|
440
|
-
if (this.authClientWasProvided) {
|
|
441
|
-
return false;
|
|
442
|
-
}
|
|
443
|
-
return !isSameAuthClientOptions(this.authClientOptions, options);
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Merges constructor-level defaults with per-call overrides and fills in the
|
|
447
|
-
* network-appropriate identity provider.
|
|
448
|
-
*/
|
|
449
|
-
resolveClientOptions(options) {
|
|
450
|
-
const merged = getAuthClientOptions({
|
|
451
|
-
...this.defaultClientOptions,
|
|
452
|
-
...options,
|
|
453
|
-
});
|
|
454
|
-
return {
|
|
455
|
-
...merged,
|
|
456
|
-
identityProvider: merged?.identityProvider ?? this.getDefaultIdentityProvider(),
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
/** Whether the shared agent currently signs as the anonymous principal. */
|
|
460
|
-
agentIsAnonymous() {
|
|
461
|
-
const installed = this.clientManager.identity;
|
|
462
|
-
return installed === undefined || installed.getPrincipal().isAnonymous();
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* End a session whose delegation has lapsed: ask the client to forget it,
|
|
466
|
-
* put the anonymous identity on the agent -- which also sweeps the previous
|
|
467
|
-
* user's caller-scoped cache entries and refetches the rest anonymously --
|
|
468
|
-
* and publish the signed-out state. `signOut` failing changes nothing here:
|
|
469
|
-
* the delegation is already unusable, and the agent must not keep it.
|
|
470
|
-
*/
|
|
471
|
-
async expireSession() {
|
|
472
|
-
try {
|
|
473
|
-
await this.authClient?.signOut();
|
|
474
|
-
}
|
|
475
|
-
catch {
|
|
476
|
-
// Nothing to keep; fall through to anonymous either way.
|
|
477
|
-
}
|
|
478
|
-
const identity = new AnonymousIdentity();
|
|
479
|
-
this.clientManager.updateAgent(identity);
|
|
480
|
-
this.updateState({
|
|
481
|
-
identity,
|
|
482
|
-
isAuthenticated: false,
|
|
483
|
-
isAuthenticating: false,
|
|
484
|
-
error: undefined,
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
async syncStateFromClient(revision = this.authStateRevision) {
|
|
488
|
-
if (!this.authClient) {
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
const identity = await this.authClient.getIdentity();
|
|
492
|
-
const isAuthenticated = await this.authClient.isAuthenticated();
|
|
493
|
-
if (revision !== this.authStateRevision) {
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
this.clientManager.updateAgent(identity);
|
|
497
|
-
this.updateState({
|
|
498
|
-
identity,
|
|
499
|
-
isAuthenticated,
|
|
500
|
-
isAuthenticating: false,
|
|
501
|
-
error: undefined,
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
/** @internal Used by IdentityAttributesManager. */
|
|
505
|
-
async ensureClient(options) {
|
|
506
|
-
const clientOptions = this.resolveClientOptions(options);
|
|
507
|
-
if (!this.ensurePreparedClient(clientOptions)) {
|
|
508
|
-
await this.initializeClient(clientOptions);
|
|
509
|
-
}
|
|
510
|
-
return this.authClient;
|
|
511
|
-
}
|
|
512
|
-
/** @internal Used by IdentityAttributesManager. */
|
|
513
|
-
async commitIdentity(identity, isAuthenticated) {
|
|
514
|
-
if (!this.clientManager.agentState.isInitialized) {
|
|
515
|
-
await this.clientManager.initializeAgent();
|
|
516
|
-
}
|
|
517
|
-
this.clientManager.updateAgent(identity);
|
|
518
|
-
this.updateState({ identity, isAuthenticated, isAuthenticating: false });
|
|
519
|
-
}
|
|
520
|
-
/** @internal Used by IdentityAttributesManager. */
|
|
521
|
-
setAuthenticating() {
|
|
522
|
-
this.updateState({ isAuthenticating: true, error: undefined });
|
|
523
|
-
}
|
|
524
|
-
/** @internal Used by IdentityAttributesManager. */
|
|
525
|
-
setAuthenticationError(error) {
|
|
526
|
-
this.updateState({ error, isAuthenticating: false });
|
|
527
|
-
}
|
|
528
|
-
getDefaultIdentityProvider() {
|
|
529
|
-
if (this.identityProvider) {
|
|
530
|
-
return this.identityProvider;
|
|
531
|
-
}
|
|
532
|
-
if (!this.clientManager.isLocal) {
|
|
533
|
-
return IC_INTERNET_IDENTITY_PROVIDER;
|
|
534
|
-
}
|
|
535
|
-
const canisterId = this.internetIdentityId ?? LOCAL_INTERNET_IDENTITY_CANISTER_ID;
|
|
536
|
-
// `null` is the probe's positive finding that this build serves no sign-in
|
|
537
|
-
// UI. Throwing here surfaces an actionable message where the caller can see
|
|
538
|
-
// it, instead of opening a popup onto the gateway's verification-error page
|
|
539
|
-
// and leaving the app waiting until the user closes it.
|
|
540
|
-
if (this.localAuthorizePath === null) {
|
|
541
|
-
throw localInternetIdentityUnavailableError(canisterId);
|
|
542
|
-
}
|
|
543
|
-
return localInternetIdentityProvider(Number(this.clientManager.agentHost?.port) || 4943, this.internetIdentityId, this.localAuthorizePath);
|
|
544
|
-
}
|
|
545
|
-
updateState(newState) {
|
|
546
|
-
if (isDev())
|
|
547
|
-
console.debug("[ic-reactor] Updating Auth State:", newState);
|
|
548
|
-
this.authStateRevision += 1;
|
|
549
|
-
this.authStateValue = { ...this.authStateValue, ...newState };
|
|
550
|
-
this.authStateSubscribers.forEach((subscriber) => subscriber(this.authStateValue));
|
|
551
|
-
}
|
|
552
|
-
async loadAuthClientConstructor() {
|
|
553
|
-
if (this.authClientConstructor) {
|
|
554
|
-
return this.authClientConstructor;
|
|
555
|
-
}
|
|
556
|
-
if (!this.authClientConstructorPromise) {
|
|
557
|
-
this.authClientConstructorPromise = importAuthClientModule()
|
|
558
|
-
.then((authModule) => {
|
|
559
|
-
const AuthClient = authModule.AuthClient;
|
|
560
|
-
if (!AuthClient) {
|
|
561
|
-
throw new Error("@icp-sdk/auth/client did not export AuthClient");
|
|
562
|
-
}
|
|
563
|
-
this.authClientConstructor = AuthClient;
|
|
564
|
-
return AuthClient;
|
|
565
|
-
})
|
|
566
|
-
.catch((error) => {
|
|
567
|
-
this.authModuleMissing = true;
|
|
568
|
-
this.authClientConstructorPromise = undefined;
|
|
569
|
-
if (error instanceof Error &&
|
|
570
|
-
error.message.includes("did not export AuthClient")) {
|
|
571
|
-
throw error;
|
|
572
|
-
}
|
|
573
|
-
return undefined;
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
return this.authClientConstructorPromise;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* Loads the optional `@icp-sdk/auth` peer.
|
|
581
|
-
*
|
|
582
|
-
* The `try` is load-bearing, not defensive. webpack flags a dynamic import
|
|
583
|
-
* that sits lexically inside a `try` block as an *optional* dependency
|
|
584
|
-
* (`ImportParserPlugin`: `dep.optional = Boolean(parser.scope.inTry)`), and
|
|
585
|
-
* `Compilation` reports an unresolvable optional dependency as a build
|
|
586
|
-
* *warning* instead of a fatal "Module not found" error, emitting a module
|
|
587
|
-
* that rejects at runtime. Without the `try`, every webpack-based toolchain
|
|
588
|
-
* (webpack, `next build --webpack`, Rspack) fails to build for consumers who
|
|
589
|
-
* never touch authentication, because npm/pnpm do not install optional peers.
|
|
590
|
-
* Do not hoist this import out of the `try`, and do not wrap it in a nested
|
|
591
|
-
* function — webpack resets `inTry` at every function boundary.
|
|
592
|
-
*
|
|
593
|
-
* The specifier must also stay a literal: a variable specifier (or
|
|
594
|
-
* `@vite-ignore`) makes bundlers skip this import entirely, so the bare
|
|
595
|
-
* specifier survives into the browser, where it cannot be resolved without an
|
|
596
|
-
* import map and every login path fails. A literal lets Vite/Rollup/webpack
|
|
597
|
-
* code-split the optional peer, and lets them tree-shake it away for apps that
|
|
598
|
-
* never reference this class.
|
|
599
|
-
*/
|
|
600
|
-
function importAuthClientModule() {
|
|
601
|
-
try {
|
|
602
|
-
return import("@icp-sdk/auth/client");
|
|
603
|
-
}
|
|
604
|
-
catch (error) {
|
|
605
|
-
// Native ESM without an import map (and bundlers that neither resolve nor
|
|
606
|
-
// stub the specifier) throw synchronously rather than rejecting.
|
|
607
|
-
return Promise.reject(error);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
function getAuthClientOptions(options) {
|
|
611
|
-
if (!options) {
|
|
612
|
-
return undefined;
|
|
613
|
-
}
|
|
614
|
-
return {
|
|
615
|
-
identityProvider: options.identityProvider,
|
|
616
|
-
windowOpenerFeatures: options.windowOpenerFeatures,
|
|
617
|
-
openIdProvider: getAuthClientOpenIdProvider(options.openIdProvider),
|
|
618
|
-
derivationOrigin: options.derivationOrigin,
|
|
619
|
-
storage: options.storage,
|
|
620
|
-
keyType: options.keyType,
|
|
621
|
-
idleOptions: options.idleOptions,
|
|
622
|
-
identity: options.identity,
|
|
623
|
-
transport: options.transport,
|
|
624
|
-
};
|
|
625
|
-
}
|
|
626
|
-
function getAuthClientOpenIdProvider(openIdProvider) {
|
|
627
|
-
return openIdProvider === "google" ||
|
|
628
|
-
openIdProvider === "apple" ||
|
|
629
|
-
openIdProvider === "microsoft"
|
|
630
|
-
? openIdProvider
|
|
631
|
-
: undefined;
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* Compares the options two AuthClients would be built from. Object-valued
|
|
635
|
-
* options (`storage`, `identity`, `idleOptions`) are compared by reference,
|
|
636
|
-
* which is what module-scoped configuration produces.
|
|
637
|
-
*/
|
|
638
|
-
function isSameAuthClientOptions(current, next) {
|
|
639
|
-
if (current === next) {
|
|
640
|
-
return true;
|
|
641
|
-
}
|
|
642
|
-
if (!current || !next) {
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
return (String(current.identityProvider ?? "") ===
|
|
646
|
-
String(next.identityProvider ?? "") &&
|
|
647
|
-
current.windowOpenerFeatures === next.windowOpenerFeatures &&
|
|
648
|
-
current.openIdProvider === next.openIdProvider &&
|
|
649
|
-
String(current.derivationOrigin ?? "") ===
|
|
650
|
-
String(next.derivationOrigin ?? "") &&
|
|
651
|
-
current.storage === next.storage &&
|
|
652
|
-
current.keyType === next.keyType &&
|
|
653
|
-
current.idleOptions === next.idleOptions &&
|
|
654
|
-
current.identity === next.identity &&
|
|
655
|
-
current.transport === next.transport);
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* Decides whether an Internet Identity provider carried by the `ic_env` cookie
|
|
659
|
-
* may be used.
|
|
660
|
-
*
|
|
661
|
-
* The cookie is written by the replica serving a local or testnet deployment,
|
|
662
|
-
* and it is only authoritative in that setting: cookies are not origin-isolated
|
|
663
|
-
* the way script-accessible storage is, so on a mainnet deployment the identity
|
|
664
|
-
* provider is configuration that belongs in code rather than something read
|
|
665
|
-
* back out of the environment at runtime. `AuthClient` treats `identityProvider`
|
|
666
|
-
* as trusted developer configuration and does not re-check it.
|
|
667
|
-
*
|
|
668
|
-
* This mirrors the root-key guard in `ClientManager` (see `packages/core`):
|
|
669
|
-
* both values arrive from the same cookie and get the same treatment — adopted
|
|
670
|
-
* off-mainnet, ignored on mainnet in favour of the pinned default.
|
|
671
|
-
*
|
|
672
|
-
* A provider on the app's own origin is always accepted: it is exactly as
|
|
673
|
-
* trustworthy as the page doing the asking. Callers that need a custom provider
|
|
674
|
-
* on mainnet pass `identityProvider` explicitly.
|
|
675
|
-
*/
|
|
676
|
-
function acceptEnvIdentityProvider(value, clientManager) {
|
|
677
|
-
if (!value)
|
|
678
|
-
return undefined;
|
|
679
|
-
const pageOrigin = typeof window !== "undefined" ? window.location?.origin : undefined;
|
|
680
|
-
let url;
|
|
681
|
-
try {
|
|
682
|
-
url = new URL(value, pageOrigin);
|
|
683
|
-
}
|
|
684
|
-
catch {
|
|
685
|
-
return undefined;
|
|
686
|
-
}
|
|
687
|
-
if (pageOrigin && url.origin === pageOrigin) {
|
|
688
|
-
return url.toString();
|
|
689
|
-
}
|
|
690
|
-
// Positive allowlist, not `!isMainnetHost(...)`.
|
|
691
|
-
//
|
|
692
|
-
// The old comment here claimed this defaulted to true for an unknown host so
|
|
693
|
-
// that "anything that looks like mainnet fails closed". It did not:
|
|
694
|
-
// isMainnetHost defaults to true only for `undefined`, and returns false for
|
|
695
|
-
// every unrecognised host — so a dapp on a custom domain accepted an identity
|
|
696
|
-
// provider chosen by a cookie, and the ic_env cookie is writable by any
|
|
697
|
-
// sibling subdomain. Redirecting the Internet Identity flow is as severe as
|
|
698
|
-
// substituting the root key, so both now use the same test.
|
|
699
|
-
//
|
|
700
|
-
// That test is the ClientManager's single resolved decision rather than a
|
|
701
|
-
// recomputed host test, which silently ignored a caller
|
|
702
|
-
// who had opted in: `allowEnvConfig: true` accepted the cookie's root key and
|
|
703
|
-
// then discarded its identity provider, from the same cookie, on the same
|
|
704
|
-
// host.
|
|
705
|
-
if (!clientManager.trustsEnvConfig) {
|
|
706
|
-
console.warn(`[ic-reactor] Ignoring the Internet Identity provider from the ic_env cookie ` +
|
|
707
|
-
`("${url.origin}") because this reactor does not target a local replica, where ` +
|
|
708
|
-
`the provider is taken from configuration rather than the environment. Pass ` +
|
|
709
|
-
`\`identityProvider\` to AuthenticationManager to use a custom provider.`);
|
|
710
|
-
return undefined;
|
|
711
|
-
}
|
|
712
|
-
return url.toString();
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Accepts an Internet Identity canister ID from `ic_env` only when it parses as
|
|
716
|
-
* a principal.
|
|
717
|
-
*
|
|
718
|
-
* The value is interpolated into a provider URL
|
|
719
|
-
* (`http://<id>.localhost:<port>/authorize`), so anything that is not a bare
|
|
720
|
-
* principal can change the shape of that URL rather than just its subdomain.
|
|
721
|
-
* Only reachable on local networks, since mainnet uses the pinned provider.
|
|
722
|
-
*/
|
|
723
|
-
function acceptEnvCanisterId(value) {
|
|
724
|
-
if (!value)
|
|
725
|
-
return undefined;
|
|
726
|
-
try {
|
|
727
|
-
return Principal.fromText(value).toText();
|
|
728
|
-
}
|
|
729
|
-
catch {
|
|
730
|
-
return undefined;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
function getAuthenticationCanisterEnv() {
|
|
734
|
-
const canisterEnv = safeGetCanisterEnv();
|
|
735
|
-
if (canisterEnv) {
|
|
736
|
-
return canisterEnv;
|
|
737
|
-
}
|
|
738
|
-
if (typeof document === "undefined") {
|
|
739
|
-
return undefined;
|
|
740
|
-
}
|
|
741
|
-
const cookie = document.cookie
|
|
742
|
-
.split(";")
|
|
743
|
-
.find((part) => part.trim().startsWith("ic_env="));
|
|
744
|
-
const encodedValue = cookie?.split("=").slice(1).join("=")?.trim();
|
|
745
|
-
if (!encodedValue) {
|
|
746
|
-
return undefined;
|
|
747
|
-
}
|
|
748
|
-
const env = Object.fromEntries(decodeURIComponent(encodedValue)
|
|
749
|
-
.split("&")
|
|
750
|
-
.map((entry) => {
|
|
751
|
-
const separatorIndex = entry.indexOf("=");
|
|
752
|
-
return separatorIndex === -1
|
|
753
|
-
? [entry, ""]
|
|
754
|
-
: [entry.slice(0, separatorIndex), entry.slice(separatorIndex + 1)];
|
|
755
|
-
}));
|
|
756
|
-
return Object.keys(env).length ? env : undefined;
|
|
757
|
-
}
|
|
758
|
-
function getSignInOptions(options) {
|
|
759
|
-
if (!options) {
|
|
760
|
-
return undefined;
|
|
761
|
-
}
|
|
762
|
-
return {
|
|
763
|
-
maxTimeToLive: options.maxTimeToLive,
|
|
764
|
-
targets: options.targets,
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
//# sourceMappingURL=authentication-manager.js.map
|