@civic/auth 0.0.1-beta.1 → 0.0.1-beta.10
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 +26 -0
- package/dist/chunk-CRTRMMJ7.js +59 -0
- package/dist/chunk-CRTRMMJ7.js.map +1 -0
- package/dist/chunk-EAANLFR5.mjs +148 -0
- package/dist/chunk-EAANLFR5.mjs.map +1 -0
- package/dist/chunk-EGFTMH5S.mjs +214 -0
- package/dist/chunk-EGFTMH5S.mjs.map +1 -0
- package/dist/chunk-KCSGIIPA.js +214 -0
- package/dist/chunk-KCSGIIPA.js.map +1 -0
- package/dist/chunk-MVO4UZ2A.js +148 -0
- package/dist/chunk-MVO4UZ2A.js.map +1 -0
- package/dist/chunk-PMDIR5XE.mjs +502 -0
- package/dist/chunk-PMDIR5XE.mjs.map +1 -0
- package/dist/chunk-RGHW4PYM.mjs +59 -0
- package/dist/chunk-RGHW4PYM.mjs.map +1 -0
- package/dist/chunk-YNLXRD5L.js +502 -0
- package/dist/chunk-YNLXRD5L.js.map +1 -0
- package/dist/{index-DFVNodC9.d.mts → index-Bfi0hVMZ.d.mts} +5 -13
- package/dist/{index-DFVNodC9.d.ts → index-Bfi0hVMZ.d.ts} +5 -13
- package/dist/index.css +63 -63
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/nextjs.d.mts +22 -37
- package/dist/nextjs.d.ts +22 -37
- package/dist/nextjs.js +166 -848
- package/dist/nextjs.js.map +1 -1
- package/dist/nextjs.mjs +162 -805
- package/dist/nextjs.mjs.map +1 -1
- package/dist/react.d.mts +42 -58
- package/dist/react.d.ts +42 -58
- package/dist/react.js +668 -1103
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +608 -1005
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +56 -0
- package/dist/server.d.ts +56 -0
- package/dist/server.js +20 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +20 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +28 -18
package/dist/react.mjs
CHANGED
|
@@ -1,65 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
target[prop] = source[prop];
|
|
26
|
-
if (source != null && __getOwnPropSymbols)
|
|
27
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
-
target[prop] = source[prop];
|
|
30
|
-
}
|
|
31
|
-
return target;
|
|
32
|
-
};
|
|
33
|
-
var __async = (__this, __arguments, generator) => {
|
|
34
|
-
return new Promise((resolve, reject) => {
|
|
35
|
-
var fulfilled = (value) => {
|
|
36
|
-
try {
|
|
37
|
-
step(generator.next(value));
|
|
38
|
-
} catch (e) {
|
|
39
|
-
reject(e);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
var rejected = (value) => {
|
|
43
|
-
try {
|
|
44
|
-
step(generator.throw(value));
|
|
45
|
-
} catch (e) {
|
|
46
|
-
reject(e);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
50
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
51
|
-
});
|
|
52
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
resolveAuthConfig,
|
|
3
|
+
resolveCallbackUrl
|
|
4
|
+
} from "./chunk-EAANLFR5.mjs";
|
|
5
|
+
import {
|
|
6
|
+
BrowserAuthenticationInitiator,
|
|
7
|
+
BrowserAuthenticationService,
|
|
8
|
+
BrowserPublicClientPKCEProducer,
|
|
9
|
+
ConfidentialClientPKCEConsumer,
|
|
10
|
+
DEFAULT_SCOPES,
|
|
11
|
+
GenericUserSession,
|
|
12
|
+
IFRAME_ID,
|
|
13
|
+
LocalStorageAdapter,
|
|
14
|
+
cn,
|
|
15
|
+
generateState,
|
|
16
|
+
getUser,
|
|
17
|
+
isWindowInIframe
|
|
18
|
+
} from "./chunk-PMDIR5XE.mjs";
|
|
19
|
+
import {
|
|
20
|
+
__async,
|
|
21
|
+
__objRest,
|
|
22
|
+
__spreadProps,
|
|
23
|
+
__spreadValues
|
|
24
|
+
} from "./chunk-RGHW4PYM.mjs";
|
|
53
25
|
|
|
54
26
|
// src/react/hooks/useUser.tsx
|
|
55
|
-
import { useContext as
|
|
27
|
+
import { useContext as useContext5 } from "react";
|
|
56
28
|
|
|
57
29
|
// src/react/providers/UserProvider.tsx
|
|
58
|
-
import { createContext } from "react";
|
|
30
|
+
import { createContext as createContext4 } from "react";
|
|
59
31
|
import { useQuery } from "@tanstack/react-query";
|
|
60
32
|
|
|
61
33
|
// src/react/hooks/useAuth.tsx
|
|
62
34
|
import { useContext } from "react";
|
|
35
|
+
|
|
36
|
+
// src/shared/AuthContext.tsx
|
|
37
|
+
import { createContext } from "react";
|
|
38
|
+
var AuthContext = createContext(null);
|
|
39
|
+
|
|
40
|
+
// src/react/hooks/useAuth.tsx
|
|
63
41
|
var useAuth = () => {
|
|
64
42
|
const context = useContext(AuthContext);
|
|
65
43
|
if (!context) {
|
|
@@ -69,71 +47,53 @@ var useAuth = () => {
|
|
|
69
47
|
};
|
|
70
48
|
|
|
71
49
|
// src/react/hooks/useToken.tsx
|
|
50
|
+
import { useContext as useContext3 } from "react";
|
|
51
|
+
|
|
52
|
+
// src/react/providers/TokenProvider.tsx
|
|
53
|
+
import { createContext as createContext3, useMemo } from "react";
|
|
54
|
+
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
55
|
+
|
|
56
|
+
// src/react/hooks/useSession.tsx
|
|
72
57
|
import { useContext as useContext2 } from "react";
|
|
73
|
-
var useToken = () => {
|
|
74
|
-
const context = useContext2(TokenContext);
|
|
75
|
-
if (!context) {
|
|
76
|
-
throw new Error("useToken must be used within a TokenProvider");
|
|
77
|
-
}
|
|
78
|
-
return context;
|
|
79
|
-
};
|
|
80
58
|
|
|
81
|
-
// src/react/providers/
|
|
59
|
+
// src/react/providers/SessionProvider.tsx
|
|
60
|
+
import {
|
|
61
|
+
createContext as createContext2
|
|
62
|
+
} from "react";
|
|
82
63
|
import { jsx } from "react/jsx-runtime";
|
|
83
|
-
var
|
|
84
|
-
|
|
64
|
+
var defaultSession = {
|
|
65
|
+
authenticated: false,
|
|
66
|
+
idToken: void 0,
|
|
67
|
+
accessToken: void 0,
|
|
68
|
+
displayMode: "iframe",
|
|
69
|
+
iframeRef: null,
|
|
70
|
+
setAuthResponseUrl: () => {
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var SessionContext = createContext2(defaultSession);
|
|
74
|
+
var SessionProvider = ({
|
|
85
75
|
children,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
refreshToken
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
const {
|
|
108
|
-
data: user,
|
|
109
|
-
isLoading: userLoading,
|
|
110
|
-
error: userError
|
|
111
|
-
} = useQuery({
|
|
112
|
-
queryKey: ["user", session == null ? void 0 : session.idToken],
|
|
113
|
-
queryFn: fetchUser,
|
|
114
|
-
enabled: !!(session == null ? void 0 : session.idToken)
|
|
115
|
-
// Only run the query if we have an access token
|
|
116
|
-
});
|
|
117
|
-
const isLoading = authLoading || userLoading;
|
|
118
|
-
const error = authError || userError;
|
|
119
|
-
return /* @__PURE__ */ jsx(
|
|
120
|
-
UserContext.Provider,
|
|
121
|
-
{
|
|
122
|
-
value: {
|
|
123
|
-
user: user != null ? user : null,
|
|
124
|
-
isLoading,
|
|
125
|
-
error,
|
|
126
|
-
signIn,
|
|
127
|
-
signOut
|
|
128
|
-
},
|
|
129
|
-
children
|
|
130
|
-
}
|
|
131
|
-
);
|
|
76
|
+
session,
|
|
77
|
+
iframeRef,
|
|
78
|
+
setAuthResponseUrl
|
|
79
|
+
}) => /* @__PURE__ */ jsx(
|
|
80
|
+
SessionContext.Provider,
|
|
81
|
+
{
|
|
82
|
+
value: __spreadProps(__spreadValues({}, session || defaultSession), { iframeRef, setAuthResponseUrl }),
|
|
83
|
+
children
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// src/react/hooks/useSession.tsx
|
|
88
|
+
var useSession = () => {
|
|
89
|
+
const context = useContext2(SessionContext);
|
|
90
|
+
if (!context) {
|
|
91
|
+
throw new Error("useSession must be used within an SessionProvider");
|
|
92
|
+
}
|
|
93
|
+
return context;
|
|
132
94
|
};
|
|
133
95
|
|
|
134
96
|
// src/react/providers/TokenProvider.tsx
|
|
135
|
-
import { createContext as createContext2, useMemo } from "react";
|
|
136
|
-
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
137
97
|
import { parseJWT } from "oslo/jwt";
|
|
138
98
|
|
|
139
99
|
// src/lib/jwt.ts
|
|
@@ -150,7 +110,7 @@ var convertForwardedTokenFormat = (inputTokens) => Object.fromEntries(
|
|
|
150
110
|
|
|
151
111
|
// src/react/providers/TokenProvider.tsx
|
|
152
112
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
153
|
-
var TokenContext =
|
|
113
|
+
var TokenContext = createContext3(void 0);
|
|
154
114
|
var TokenProvider = ({ children }) => {
|
|
155
115
|
const { isLoading, error: authError } = useAuth();
|
|
156
116
|
const session = useSession();
|
|
@@ -192,454 +152,71 @@ var TokenProvider = ({ children }) => {
|
|
|
192
152
|
return /* @__PURE__ */ jsx2(TokenContext.Provider, { value, children });
|
|
193
153
|
};
|
|
194
154
|
|
|
195
|
-
// src/
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
useMemo as useMemo2,
|
|
201
|
-
useCallback as useCallback3,
|
|
202
|
-
useRef as useRef2
|
|
203
|
-
} from "react";
|
|
204
|
-
import { useQuery as useQuery2, useMutation as useMutation2, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
205
|
-
|
|
206
|
-
// src/services/UserInfoService.ts
|
|
207
|
-
import { parseJWT as parseJWT2 } from "oslo/jwt";
|
|
208
|
-
var UserInfoServiceImpl = class {
|
|
209
|
-
constructor(endpoints) {
|
|
210
|
-
this.endpoints = endpoints;
|
|
211
|
-
}
|
|
212
|
-
extractUserFromIdToken(idToken) {
|
|
213
|
-
const parsedJWT = parseJWT2(idToken);
|
|
214
|
-
if (!parsedJWT) {
|
|
215
|
-
return null;
|
|
216
|
-
}
|
|
217
|
-
return parsedJWT.payload;
|
|
218
|
-
}
|
|
219
|
-
getUserInfo(accessToken, idToken) {
|
|
220
|
-
return __async(this, null, function* () {
|
|
221
|
-
if (idToken) {
|
|
222
|
-
return this.extractUserFromIdToken(idToken);
|
|
223
|
-
}
|
|
224
|
-
const userInfo = yield fetch(this.endpoints.userinfo, {
|
|
225
|
-
headers: { Authorization: `Bearer ${accessToken}` }
|
|
226
|
-
});
|
|
227
|
-
return userInfo.json();
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// src/services/SessionService.ts
|
|
233
|
-
import { OAuth2Client, generateCodeVerifier } from "oslo/oauth2";
|
|
234
|
-
import * as jose from "jose";
|
|
235
|
-
|
|
236
|
-
// src/lib/oauth.ts
|
|
237
|
-
import { v4 as uuid } from "uuid";
|
|
238
|
-
var getIssuerVariations = (issuer) => {
|
|
239
|
-
const issuerWithoutSlash = issuer.endsWith("/") ? issuer.slice(0, issuer.length - 1) : issuer;
|
|
240
|
-
const issuerWithSlash = `${issuerWithoutSlash}/`;
|
|
241
|
-
return [issuerWithoutSlash, issuerWithSlash];
|
|
242
|
-
};
|
|
243
|
-
var addSlashIfNeeded = (url) => url.endsWith("/") ? url : `${url}/`;
|
|
244
|
-
var getOauthEndpoints = (oauthServer) => __async(void 0, null, function* () {
|
|
245
|
-
const openIdConfigResponse = yield fetch(
|
|
246
|
-
`${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`
|
|
247
|
-
);
|
|
248
|
-
const openIdConfig = yield openIdConfigResponse.json();
|
|
249
|
-
return {
|
|
250
|
-
jwks: openIdConfig.jwks_uri,
|
|
251
|
-
auth: openIdConfig.authorization_endpoint,
|
|
252
|
-
token: openIdConfig.token_endpoint,
|
|
253
|
-
userinfo: openIdConfig.userinfo_endpoint
|
|
254
|
-
};
|
|
255
|
-
});
|
|
256
|
-
var generateState = (displayMode) => {
|
|
257
|
-
const jsonString = JSON.stringify({
|
|
258
|
-
uuid: uuid(),
|
|
259
|
-
displayMode
|
|
260
|
-
});
|
|
261
|
-
return btoa(jsonString);
|
|
262
|
-
};
|
|
263
|
-
var displayModeFromState = (state, sessionDisplayMode) => {
|
|
264
|
-
try {
|
|
265
|
-
const jsonString = btoa(state);
|
|
266
|
-
return JSON.parse(jsonString).displayMode;
|
|
267
|
-
} catch (e) {
|
|
268
|
-
console.error("Failed to parse displayMode from state:", e);
|
|
269
|
-
return sessionDisplayMode;
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
// src/utils.ts
|
|
274
|
-
import { clsx } from "clsx";
|
|
275
|
-
import { twMerge } from "tailwind-merge";
|
|
276
|
-
var isPopupBlocked = () => {
|
|
277
|
-
const popup = window.open("", "", "width=1,height=1");
|
|
278
|
-
if (!popup) {
|
|
279
|
-
return true;
|
|
280
|
-
}
|
|
281
|
-
try {
|
|
282
|
-
if (typeof popup.closed === "undefined") {
|
|
283
|
-
throw new Error("Popup is blocked");
|
|
284
|
-
}
|
|
285
|
-
} catch (e) {
|
|
286
|
-
return true;
|
|
155
|
+
// src/react/hooks/useToken.tsx
|
|
156
|
+
var useToken = () => {
|
|
157
|
+
const context = useContext3(TokenContext);
|
|
158
|
+
if (!context) {
|
|
159
|
+
throw new Error("useToken must be used within a TokenProvider");
|
|
287
160
|
}
|
|
288
|
-
|
|
289
|
-
return false;
|
|
290
|
-
};
|
|
291
|
-
var cn = (...inputs) => {
|
|
292
|
-
return twMerge(clsx(inputs));
|
|
161
|
+
return context;
|
|
293
162
|
};
|
|
294
163
|
|
|
295
|
-
// src/
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
getUserInfoService() {
|
|
311
|
-
return __async(this, null, function* () {
|
|
312
|
-
if (this.userInfoService) {
|
|
313
|
-
return this.userInfoService;
|
|
314
|
-
}
|
|
315
|
-
const endpoints = yield this.getEndpoints();
|
|
316
|
-
this.userInfoService = new UserInfoServiceImpl(endpoints);
|
|
317
|
-
return this.userInfoService;
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
getEndpoints() {
|
|
321
|
-
return __async(this, null, function* () {
|
|
322
|
-
var _a;
|
|
323
|
-
if ((_a = this.endpoints) == null ? void 0 : _a.auth) {
|
|
324
|
-
return this.endpoints;
|
|
325
|
-
}
|
|
326
|
-
const jwksEndpoints = yield getOauthEndpoints(this.oauthServer);
|
|
327
|
-
return this.endpoints ? __spreadValues(__spreadValues({}, this.endpoints), jwksEndpoints) : jwksEndpoints;
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
getOauth2Client() {
|
|
331
|
-
return __async(this, null, function* () {
|
|
332
|
-
if (this.oauth2Client) {
|
|
333
|
-
return this.oauth2Client;
|
|
334
|
-
}
|
|
335
|
-
const endpoints = yield this.getEndpoints();
|
|
336
|
-
this.oauth2Client = new OAuth2Client(
|
|
337
|
-
this.clientId,
|
|
338
|
-
endpoints.auth,
|
|
339
|
-
endpoints.token,
|
|
340
|
-
// this
|
|
341
|
-
{ redirectURI: this.redirectUrl }
|
|
342
|
-
);
|
|
343
|
-
return this.oauth2Client;
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
getSessionData() {
|
|
347
|
-
return JSON.parse(
|
|
348
|
-
localStorage.getItem(`civic-auth:${this.clientId}`) || "{}"
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
updateSessionData(data) {
|
|
352
|
-
localStorage.setItem(
|
|
353
|
-
`civic-auth:${this.clientId}`,
|
|
354
|
-
JSON.stringify(__spreadValues({}, data))
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
getUser() {
|
|
358
|
-
return JSON.parse(
|
|
359
|
-
localStorage.getItem(`civic-auth:${this.clientId}:user`) || "{}"
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
setUser(data) {
|
|
363
|
-
localStorage.setItem(
|
|
364
|
-
`civic-auth:${this.clientId}:user`,
|
|
365
|
-
JSON.stringify(data === null ? {} : data)
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
clearSessionData() {
|
|
369
|
-
localStorage.setItem(`civic-auth:${this.clientId}`, JSON.stringify({}));
|
|
370
|
-
}
|
|
371
|
-
getAuthorizationUrlWithChallenge(state, scopes) {
|
|
372
|
-
return __async(this, null, function* () {
|
|
373
|
-
var _a;
|
|
374
|
-
const oauth2Client = yield this.getOauth2Client();
|
|
375
|
-
if ((_a = this.endpoints) == null ? void 0 : _a.challenge) {
|
|
376
|
-
const challenge = yield fetch(this.endpoints.challenge).then(
|
|
377
|
-
(res) => res.json().then((data) => data.challenge)
|
|
378
|
-
);
|
|
379
|
-
const oAuthUrl2 = yield oauth2Client.createAuthorizationURL({
|
|
380
|
-
state,
|
|
381
|
-
scopes
|
|
382
|
-
});
|
|
383
|
-
oAuthUrl2.searchParams.append("code_challenge", challenge);
|
|
384
|
-
oAuthUrl2.searchParams.append("code_challenge_method", "S256");
|
|
385
|
-
return oAuthUrl2;
|
|
386
|
-
}
|
|
387
|
-
const oAuthUrl = yield oauth2Client.createAuthorizationURL({
|
|
388
|
-
state,
|
|
389
|
-
codeVerifier: this.codeVerifier,
|
|
390
|
-
codeChallengeMethod: "S256",
|
|
391
|
-
scopes
|
|
392
|
-
});
|
|
393
|
-
return oAuthUrl;
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
getAuthorizationUrl(scopes, displayMode, nonce) {
|
|
397
|
-
return __async(this, null, function* () {
|
|
398
|
-
const state = generateState(displayMode);
|
|
399
|
-
const existingSessionData = this.getSessionData();
|
|
400
|
-
this.updateSessionData(__spreadProps(__spreadValues({}, existingSessionData), {
|
|
401
|
-
codeVerifier: this.codeVerifier,
|
|
402
|
-
displayMode
|
|
403
|
-
}));
|
|
404
|
-
const oAuthUrl = yield this.getAuthorizationUrlWithChallenge(state, scopes);
|
|
405
|
-
if (nonce) {
|
|
406
|
-
oAuthUrl.searchParams.append("nonce", nonce);
|
|
407
|
-
}
|
|
408
|
-
oAuthUrl.searchParams.append("prompt", "consent");
|
|
409
|
-
return oAuthUrl.toString();
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
// TODO fix the Window reference
|
|
413
|
-
loadAuthorizationUrl(authorizationURL, displayMode) {
|
|
414
|
-
switch (displayMode) {
|
|
415
|
-
case "iframe":
|
|
416
|
-
break;
|
|
417
|
-
case "redirect":
|
|
418
|
-
window.location.href = authorizationURL;
|
|
419
|
-
break;
|
|
420
|
-
case "new_tab":
|
|
421
|
-
window.open(authorizationURL, "_blank");
|
|
422
|
-
break;
|
|
423
|
-
case "custom_tab":
|
|
424
|
-
break;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
init() {
|
|
428
|
-
return __async(this, null, function* () {
|
|
429
|
-
this.updateSessionData({ authenticated: false });
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
determineDisplayMode(displayMode) {
|
|
433
|
-
if (isPopupBlocked() && displayMode === "iframe") {
|
|
434
|
-
displayMode = "redirect";
|
|
435
|
-
}
|
|
436
|
-
return displayMode;
|
|
437
|
-
}
|
|
438
|
-
signIn(displayMode, scopes, nonce) {
|
|
439
|
-
return __async(this, null, function* () {
|
|
440
|
-
const authorizationURL = yield this.getAuthorizationUrl(
|
|
441
|
-
scopes,
|
|
442
|
-
displayMode,
|
|
443
|
-
nonce
|
|
444
|
-
);
|
|
445
|
-
this.loadAuthorizationUrl(authorizationURL, displayMode);
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
tokenExchange(responseUrl) {
|
|
449
|
-
return __async(this, null, function* () {
|
|
450
|
-
let session = this.getSessionData();
|
|
451
|
-
if (!session.authenticated) {
|
|
452
|
-
const url = new URL(responseUrl);
|
|
453
|
-
const authorizationCode = url.searchParams.get("code");
|
|
454
|
-
const returnedState = url.searchParams.get("state");
|
|
455
|
-
if (!authorizationCode || !returnedState) {
|
|
456
|
-
throw new Error("Invalid authorization response");
|
|
457
|
-
}
|
|
458
|
-
const codeVerifier = session.codeVerifier;
|
|
459
|
-
const oauth2Client = yield this.getOauth2Client();
|
|
460
|
-
const tokens = yield oauth2Client.validateAuthorizationCode(
|
|
461
|
-
authorizationCode,
|
|
462
|
-
{
|
|
463
|
-
codeVerifier
|
|
464
|
-
}
|
|
465
|
-
);
|
|
466
|
-
try {
|
|
467
|
-
yield this.validateTokens(tokens);
|
|
468
|
-
} catch (error) {
|
|
469
|
-
console.error("tokenExchange tokens", { error, tokens });
|
|
470
|
-
throw new Error(
|
|
471
|
-
`OIDC tokens validation failed: ${error.message}`
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
const parsedDisplayMode = displayModeFromState(
|
|
475
|
-
returnedState,
|
|
476
|
-
session.displayMode
|
|
477
|
-
);
|
|
478
|
-
session = __spreadProps(__spreadValues({}, session), {
|
|
479
|
-
displayMode: parsedDisplayMode,
|
|
480
|
-
idToken: tokens.id_token,
|
|
481
|
-
authenticated: true,
|
|
482
|
-
state: returnedState,
|
|
483
|
-
accessToken: tokens.access_token,
|
|
484
|
-
refreshToken: tokens.refresh_token,
|
|
485
|
-
timestamp: Date.now(),
|
|
486
|
-
expiresIn: tokens.expires_in
|
|
487
|
-
});
|
|
488
|
-
this.updateSessionData(session);
|
|
489
|
-
const user = yield (yield this.getUserInfoService()).getUserInfo(tokens.access_token, tokens.id_token || null);
|
|
490
|
-
this.setUser(user);
|
|
491
|
-
}
|
|
492
|
-
this.setupTokenRefresh(session);
|
|
493
|
-
if (session.displayMode === "new_tab") {
|
|
494
|
-
window.close();
|
|
495
|
-
} else if (session.displayMode === "redirect") {
|
|
496
|
-
}
|
|
497
|
-
return session;
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
setupTokenRefresh(session) {
|
|
501
|
-
if (this.refreshTokenTimeout) {
|
|
502
|
-
clearTimeout(this.refreshTokenTimeout);
|
|
164
|
+
// src/react/providers/UserProvider.tsx
|
|
165
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
166
|
+
var UserContext = createContext4(null);
|
|
167
|
+
var UserProvider = ({
|
|
168
|
+
children,
|
|
169
|
+
storage
|
|
170
|
+
}) => {
|
|
171
|
+
const { isLoading: authLoading, error: authError } = useAuth();
|
|
172
|
+
const session = useSession();
|
|
173
|
+
const { accessToken } = useToken();
|
|
174
|
+
const { signIn, signOut } = useAuth();
|
|
175
|
+
const fetchUser = () => __async(void 0, null, function* () {
|
|
176
|
+
if (!accessToken) {
|
|
177
|
+
return null;
|
|
503
178
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
179
|
+
const userSession = new GenericUserSession(storage);
|
|
180
|
+
return userSession.get();
|
|
181
|
+
});
|
|
182
|
+
const {
|
|
183
|
+
data: user,
|
|
184
|
+
isLoading: userLoading,
|
|
185
|
+
error: userError
|
|
186
|
+
} = useQuery({
|
|
187
|
+
queryKey: ["user", session == null ? void 0 : session.idToken],
|
|
188
|
+
queryFn: fetchUser,
|
|
189
|
+
enabled: !!(session == null ? void 0 : session.idToken)
|
|
190
|
+
// Only run the query if we have an access token
|
|
191
|
+
});
|
|
192
|
+
const isLoading = authLoading || userLoading;
|
|
193
|
+
const error = authError || userError;
|
|
194
|
+
return /* @__PURE__ */ jsx3(
|
|
195
|
+
UserContext.Provider,
|
|
196
|
+
{
|
|
197
|
+
value: {
|
|
198
|
+
user: user != null ? user : null,
|
|
199
|
+
isLoading,
|
|
200
|
+
error,
|
|
201
|
+
signIn,
|
|
202
|
+
signOut
|
|
203
|
+
},
|
|
204
|
+
children
|
|
516
205
|
}
|
|
517
|
-
|
|
518
|
-
refreshToken() {
|
|
519
|
-
return __async(this, null, function* () {
|
|
520
|
-
const sessionData = this.getSessionData();
|
|
521
|
-
if (!sessionData.refreshToken) {
|
|
522
|
-
throw new Error("No refresh token available");
|
|
523
|
-
}
|
|
524
|
-
const oauth2Client = yield this.getOauth2Client();
|
|
525
|
-
const tokens = yield oauth2Client.refreshAccessToken(
|
|
526
|
-
sessionData.refreshToken
|
|
527
|
-
);
|
|
528
|
-
const session = __spreadProps(__spreadValues({}, sessionData), {
|
|
529
|
-
idToken: tokens.id_token,
|
|
530
|
-
authenticated: true,
|
|
531
|
-
accessToken: tokens.access_token,
|
|
532
|
-
refreshToken: tokens.refresh_token,
|
|
533
|
-
timestamp: Date.now(),
|
|
534
|
-
expiresIn: tokens.expires_in
|
|
535
|
-
});
|
|
536
|
-
this.updateSessionData(session);
|
|
537
|
-
this.setupTokenRefresh(session);
|
|
538
|
-
return session;
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
getUserInfo() {
|
|
542
|
-
return __async(this, null, function* () {
|
|
543
|
-
const sessionData = this.getSessionData();
|
|
544
|
-
if (!sessionData.accessToken) {
|
|
545
|
-
throw new Error("No access token available");
|
|
546
|
-
}
|
|
547
|
-
const userInfoService = yield this.getUserInfoService();
|
|
548
|
-
return userInfoService.getUserInfo(
|
|
549
|
-
sessionData.accessToken,
|
|
550
|
-
sessionData.idToken || null
|
|
551
|
-
);
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
/**
|
|
555
|
-
* Uses the jose library to validate a JWT token using the OAuth JWKS endpoint
|
|
556
|
-
* @param {string} token
|
|
557
|
-
* @returns {Promise<jose.JWTPayload>}
|
|
558
|
-
* @throws {Error} if the token is invalid
|
|
559
|
-
*/
|
|
560
|
-
validateTokens(tokens) {
|
|
561
|
-
return __async(this, null, function* () {
|
|
562
|
-
const endpoints = yield this.getEndpoints();
|
|
563
|
-
const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));
|
|
564
|
-
const returnPayload = {};
|
|
565
|
-
console.log("issuer", getIssuerVariations(this.oauthServer));
|
|
566
|
-
const idTokenResponse = yield jose.jwtVerify(tokens.id_token, JWKS, {
|
|
567
|
-
issuer: getIssuerVariations(this.oauthServer),
|
|
568
|
-
audience: this.clientId
|
|
569
|
-
});
|
|
570
|
-
returnPayload.idToken = idTokenResponse.payload;
|
|
571
|
-
const accessTokenResponse = yield jose.jwtVerify(
|
|
572
|
-
tokens.access_token,
|
|
573
|
-
JWKS,
|
|
574
|
-
{
|
|
575
|
-
issuer: getIssuerVariations(this.oauthServer)
|
|
576
|
-
}
|
|
577
|
-
);
|
|
578
|
-
returnPayload.accessToken = accessTokenResponse.payload;
|
|
579
|
-
if (tokens.refresh_token) {
|
|
580
|
-
returnPayload.refreshToken = tokens.refresh_token;
|
|
581
|
-
}
|
|
582
|
-
return returnPayload;
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
validateExistingSession() {
|
|
586
|
-
return __async(this, null, function* () {
|
|
587
|
-
const sessionData = this.getSessionData();
|
|
588
|
-
try {
|
|
589
|
-
if (!sessionData.idToken || !sessionData.accessToken) {
|
|
590
|
-
const unAuthenticatedSession = __spreadProps(__spreadValues({}, sessionData), { authenticated: false });
|
|
591
|
-
this.updateSessionData(unAuthenticatedSession);
|
|
592
|
-
return unAuthenticatedSession;
|
|
593
|
-
}
|
|
594
|
-
yield this.validateTokens({
|
|
595
|
-
id_token: sessionData.idToken,
|
|
596
|
-
access_token: sessionData.accessToken,
|
|
597
|
-
refresh_token: sessionData.refreshToken
|
|
598
|
-
});
|
|
599
|
-
sessionData.authenticated = true;
|
|
600
|
-
return sessionData;
|
|
601
|
-
} catch (error) {
|
|
602
|
-
console.warn("Failed to validate existing tokens", error);
|
|
603
|
-
const unAuthenticatedSession = {
|
|
604
|
-
authenticated: false
|
|
605
|
-
};
|
|
606
|
-
this.updateSessionData(unAuthenticatedSession);
|
|
607
|
-
return unAuthenticatedSession;
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
|
-
}
|
|
206
|
+
);
|
|
611
207
|
};
|
|
612
208
|
|
|
613
|
-
// src/
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
// src/react/components/CivicAuthIframe.tsx
|
|
624
|
-
import { forwardRef } from "react";
|
|
625
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
626
|
-
var CivicAuthIframe = forwardRef(
|
|
627
|
-
({ authUrl, onLoad }, ref) => {
|
|
628
|
-
return /* @__PURE__ */ jsx3(
|
|
629
|
-
"iframe",
|
|
630
|
-
{
|
|
631
|
-
id: IFRAME_ID,
|
|
632
|
-
ref,
|
|
633
|
-
src: authUrl,
|
|
634
|
-
className: "h-96 w-80 border-none",
|
|
635
|
-
onLoad
|
|
636
|
-
}
|
|
637
|
-
);
|
|
638
|
-
}
|
|
639
|
-
);
|
|
640
|
-
CivicAuthIframe.displayName = "CivicAuthIframe";
|
|
209
|
+
// src/shared/AuthProvider.tsx
|
|
210
|
+
import {
|
|
211
|
+
useCallback as useCallback2,
|
|
212
|
+
useEffect as useEffect2,
|
|
213
|
+
useMemo as useMemo2,
|
|
214
|
+
useRef as useRef2,
|
|
215
|
+
useState as useState2
|
|
216
|
+
} from "react";
|
|
217
|
+
import { useMutation as useMutation2, useQuery as useQuery2, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
641
218
|
|
|
642
|
-
// src/react/components/
|
|
219
|
+
// src/react/components/CivicAuthIframeContainer.tsx
|
|
643
220
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
644
221
|
|
|
645
222
|
// src/react/components/LoadingIcon.tsx
|
|
@@ -649,7 +226,7 @@ var LoadingIcon = () => /* @__PURE__ */ jsxs("div", { role: "status", children:
|
|
|
649
226
|
"svg",
|
|
650
227
|
{
|
|
651
228
|
"aria-hidden": "true",
|
|
652
|
-
className: "inline h-8 w-8 animate-spin fill-neutral-600 text-neutral-200 dark:fill-neutral-300 dark:text-neutral-600",
|
|
229
|
+
className: "cac-inline cac-h-8 cac-w-8 cac-animate-spin cac-fill-neutral-600 cac-text-neutral-200 dark:cac-fill-neutral-300 dark:cac-text-neutral-600",
|
|
653
230
|
viewBox: "0 0 100 101",
|
|
654
231
|
fill: "none",
|
|
655
232
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -671,7 +248,7 @@ var LoadingIcon = () => /* @__PURE__ */ jsxs("div", { role: "status", children:
|
|
|
671
248
|
]
|
|
672
249
|
}
|
|
673
250
|
),
|
|
674
|
-
/* @__PURE__ */ jsx4("span", { className: "sr-only", children: "Loading..." })
|
|
251
|
+
/* @__PURE__ */ jsx4("span", { className: "cac-sr-only", children: "Loading..." })
|
|
675
252
|
] });
|
|
676
253
|
|
|
677
254
|
// src/react/components/CloseIcon.tsx
|
|
@@ -696,379 +273,126 @@ var CloseIcon = () => /* @__PURE__ */ jsxs2(
|
|
|
696
273
|
}
|
|
697
274
|
);
|
|
698
275
|
|
|
699
|
-
// src/react/components/
|
|
700
|
-
import {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
const processIframeUrl = useCallback(() => {
|
|
712
|
-
if (iframeRef.current && iframeRef.current.contentWindow) {
|
|
713
|
-
try {
|
|
714
|
-
const iframeUrl = iframeRef.current.contentWindow.location.href;
|
|
715
|
-
if (iframeUrl.startsWith(redirectUri)) {
|
|
716
|
-
setAuthResponseUrl(iframeUrl);
|
|
717
|
-
if (closeOnRedirect) onClose();
|
|
718
|
-
return true;
|
|
719
|
-
}
|
|
720
|
-
} catch (e) {
|
|
721
|
-
console.log("Waiting for redirect...");
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
return false;
|
|
725
|
-
}, [closeOnRedirect, iframeRef, onClose, redirectUri, setAuthResponseUrl]);
|
|
726
|
-
const intervalId = useRef();
|
|
727
|
-
const handleEscape = useCallback(
|
|
728
|
-
(event) => {
|
|
729
|
-
if (event.key === "Escape") {
|
|
730
|
-
onClose();
|
|
276
|
+
// src/react/components/CivicAuthIframe.tsx
|
|
277
|
+
import { forwardRef } from "react";
|
|
278
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
279
|
+
var CivicAuthIframe = forwardRef(
|
|
280
|
+
({ onLoad }, ref) => {
|
|
281
|
+
return /* @__PURE__ */ jsx6(
|
|
282
|
+
"iframe",
|
|
283
|
+
{
|
|
284
|
+
id: IFRAME_ID,
|
|
285
|
+
ref,
|
|
286
|
+
className: "cac-h-96 cac-w-80 cac-border-none",
|
|
287
|
+
onLoad
|
|
731
288
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
CivicAuthIframe.displayName = "CivicAuthIframe";
|
|
293
|
+
|
|
294
|
+
// src/react/components/CivicAuthIframeContainer.tsx
|
|
295
|
+
import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
296
|
+
function NoChrome({
|
|
297
|
+
children
|
|
298
|
+
}) {
|
|
299
|
+
return /* @__PURE__ */ jsx7(Fragment, { children });
|
|
300
|
+
}
|
|
301
|
+
function IframeChrome({
|
|
302
|
+
children,
|
|
303
|
+
onClose
|
|
304
|
+
}) {
|
|
305
|
+
return /* @__PURE__ */ jsx7(
|
|
747
306
|
"div",
|
|
748
307
|
{
|
|
749
|
-
className: "absolute left-0 top-0 z-50 flex h-screen w-screen items-center justify-center bg-neutral-950 bg-opacity-50",
|
|
308
|
+
className: "cac-absolute cac-left-0 cac-top-0 cac-z-50 cac-flex cac-h-screen cac-w-screen cac-items-center cac-justify-center cac-bg-neutral-950 cac-bg-opacity-50",
|
|
750
309
|
onClick: onClose,
|
|
751
310
|
children: /* @__PURE__ */ jsxs3(
|
|
752
311
|
"div",
|
|
753
312
|
{
|
|
754
|
-
className: "relative rounded-3xl bg-white p-6 shadow-lg",
|
|
313
|
+
className: "cac-relative cac-rounded-3xl cac-bg-white cac-p-6 cac-shadow-lg",
|
|
755
314
|
onClick: (e) => e.stopPropagation(),
|
|
756
315
|
children: [
|
|
757
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ jsx7(
|
|
758
317
|
"button",
|
|
759
318
|
{
|
|
760
|
-
className: "absolute right-4 top-4 flex cursor-pointer items-center justify-center border-none bg-transparent p-1 text-neutral-400",
|
|
319
|
+
className: "cac-absolute cac-right-4 cac-top-4 cac-flex cac-cursor-pointer cac-items-center cac-justify-center cac-border-none cac-bg-transparent cac-p-1 cac-text-neutral-400",
|
|
761
320
|
onClick: onClose,
|
|
762
|
-
children: /* @__PURE__ */
|
|
321
|
+
children: /* @__PURE__ */ jsx7(CloseIcon, {})
|
|
763
322
|
}
|
|
764
323
|
),
|
|
765
|
-
|
|
766
|
-
/* @__PURE__ */ jsx6(
|
|
767
|
-
CivicAuthIframe,
|
|
768
|
-
{
|
|
769
|
-
ref: iframeRef,
|
|
770
|
-
authUrl,
|
|
771
|
-
onLoad: handleIframeLoad
|
|
772
|
-
}
|
|
773
|
-
)
|
|
324
|
+
children
|
|
774
325
|
]
|
|
775
326
|
}
|
|
776
327
|
)
|
|
777
328
|
}
|
|
778
329
|
);
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
784
|
-
var ChevronDown = () => /* @__PURE__ */ jsx7(
|
|
785
|
-
"svg",
|
|
786
|
-
{
|
|
787
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
788
|
-
width: "24",
|
|
789
|
-
height: "24",
|
|
790
|
-
viewBox: "0 0 24 24",
|
|
791
|
-
fill: "none",
|
|
792
|
-
stroke: "currentColor",
|
|
793
|
-
strokeWidth: "2",
|
|
794
|
-
strokeLinecap: "round",
|
|
795
|
-
strokeLinejoin: "round",
|
|
796
|
-
className: "lucide lucide-chevron-down",
|
|
797
|
-
children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" })
|
|
798
|
-
}
|
|
799
|
-
);
|
|
800
|
-
var ChevronUp = () => /* @__PURE__ */ jsx7(
|
|
801
|
-
"svg",
|
|
802
|
-
{
|
|
803
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
804
|
-
width: "24",
|
|
805
|
-
height: "24",
|
|
806
|
-
viewBox: "0 0 24 24",
|
|
807
|
-
fill: "none",
|
|
808
|
-
stroke: "currentColor",
|
|
809
|
-
strokeWidth: "2",
|
|
810
|
-
strokeLinecap: "round",
|
|
811
|
-
strokeLinejoin: "round",
|
|
812
|
-
className: "lucide lucide-chevron-up",
|
|
813
|
-
children: /* @__PURE__ */ jsx7("path", { d: "m18 15-6-6-6 6" })
|
|
814
|
-
}
|
|
815
|
-
);
|
|
816
|
-
var UserButton = ({
|
|
817
|
-
displayMode,
|
|
818
|
-
className
|
|
330
|
+
}
|
|
331
|
+
var CivicAuthIframeContainer = ({
|
|
332
|
+
onClose,
|
|
333
|
+
closeOnRedirect = true
|
|
819
334
|
}) => {
|
|
820
|
-
|
|
821
|
-
const
|
|
822
|
-
const {
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
}
|
|
841
|
-
}, []);
|
|
842
|
-
useEffect2(() => {
|
|
843
|
-
if (isOpen) {
|
|
844
|
-
window.addEventListener("click", handleClickOutside);
|
|
845
|
-
window.addEventListener("keydown", handleEscape);
|
|
846
|
-
}
|
|
847
|
-
return () => {
|
|
848
|
-
window.removeEventListener("click", handleClickOutside);
|
|
849
|
-
window.removeEventListener("keydown", handleEscape);
|
|
850
|
-
};
|
|
851
|
-
}, [handleClickOutside, handleEscape, isOpen]);
|
|
852
|
-
if (isAuthenticated) {
|
|
853
|
-
return /* @__PURE__ */ jsxs4("div", { className: "relative", id: "civic-dropdown-container", children: [
|
|
854
|
-
/* @__PURE__ */ jsxs4(
|
|
855
|
-
"button",
|
|
856
|
-
{
|
|
857
|
-
className: cn(
|
|
858
|
-
"flex w-full items-center justify-between gap-2 rounded-full border border-neutral-500 px-3 py-2 text-neutral-500 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
|
|
859
|
-
className
|
|
860
|
-
),
|
|
861
|
-
onClick: () => setIsOpen((isOpen2) => !isOpen2),
|
|
862
|
-
children: [
|
|
863
|
-
(user == null ? void 0 : user.picture) ? /* @__PURE__ */ jsx7("span", { className: "relative flex h-10 w-10 shrink-0 gap-2 overflow-hidden rounded-full", children: /* @__PURE__ */ jsx7(
|
|
864
|
-
"img",
|
|
865
|
-
{
|
|
866
|
-
className: "h-full w-full object-cover",
|
|
867
|
-
src: user.picture,
|
|
868
|
-
alt: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email)
|
|
869
|
-
}
|
|
870
|
-
) }) : /* @__PURE__ */ jsx7("div", {}),
|
|
871
|
-
/* @__PURE__ */ jsx7("span", { children: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email) }),
|
|
872
|
-
isOpen ? /* @__PURE__ */ jsx7(ChevronUp, {}) : /* @__PURE__ */ jsx7(ChevronDown, {})
|
|
873
|
-
]
|
|
874
|
-
}
|
|
875
|
-
),
|
|
876
|
-
/* @__PURE__ */ jsx7(
|
|
877
|
-
"div",
|
|
878
|
-
{
|
|
879
|
-
className: isOpen ? "absolute right-0 mt-2 w-full rounded-lg bg-white py-2 text-neutral-500 shadow-xl" : "hidden",
|
|
880
|
-
children: /* @__PURE__ */ jsx7("ul", { children: /* @__PURE__ */ jsx7("li", { children: /* @__PURE__ */ jsx7(
|
|
881
|
-
"button",
|
|
882
|
-
{
|
|
883
|
-
className: "block w-full px-4 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
|
|
884
|
-
onClick: handleSignOut,
|
|
885
|
-
children: "Logout"
|
|
886
|
-
}
|
|
887
|
-
) }) })
|
|
335
|
+
var _a;
|
|
336
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
337
|
+
const { isLoading: isAuthLoading } = useAuth();
|
|
338
|
+
const config = useConfig();
|
|
339
|
+
const { serverTokenExchange } = config;
|
|
340
|
+
const { setAuthResponseUrl, iframeRef } = useSession();
|
|
341
|
+
const processIframeUrl = useCallback(() => {
|
|
342
|
+
if (iframeRef && iframeRef.current && iframeRef.current.contentWindow) {
|
|
343
|
+
try {
|
|
344
|
+
const iframeUrl = iframeRef.current.contentWindow.location.href;
|
|
345
|
+
if (iframeUrl.startsWith(config.redirectUrl)) {
|
|
346
|
+
if (serverTokenExchange) {
|
|
347
|
+
const params = new URL(iframeUrl).searchParams;
|
|
348
|
+
params.set("tokenExchange", "true");
|
|
349
|
+
fetch(`${config.redirectUrl}?${params.toString()}`);
|
|
350
|
+
} else {
|
|
351
|
+
setAuthResponseUrl(iframeUrl);
|
|
352
|
+
}
|
|
353
|
+
if (closeOnRedirect) onClose == null ? void 0 : onClose();
|
|
354
|
+
return true;
|
|
888
355
|
}
|
|
889
|
-
)
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
return /* @__PURE__ */ jsx7(
|
|
893
|
-
"button",
|
|
894
|
-
{
|
|
895
|
-
className: cn(
|
|
896
|
-
"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
|
|
897
|
-
className
|
|
898
|
-
),
|
|
899
|
-
onClick: handleSignIn,
|
|
900
|
-
children: "Sign in"
|
|
901
|
-
}
|
|
902
|
-
);
|
|
903
|
-
};
|
|
904
|
-
|
|
905
|
-
// src/react/components/SignInButton.tsx
|
|
906
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
907
|
-
var SignInButton = ({
|
|
908
|
-
displayMode,
|
|
909
|
-
className
|
|
910
|
-
}) => {
|
|
911
|
-
const { signIn } = useAuth();
|
|
912
|
-
return /* @__PURE__ */ jsx8(
|
|
913
|
-
"button",
|
|
914
|
-
{
|
|
915
|
-
className: cn(
|
|
916
|
-
"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
|
|
917
|
-
className
|
|
918
|
-
),
|
|
919
|
-
onClick: () => signIn(displayMode),
|
|
920
|
-
children: "Sign In"
|
|
921
|
-
}
|
|
922
|
-
);
|
|
923
|
-
};
|
|
924
|
-
|
|
925
|
-
// src/react/components/SignOutButton.tsx
|
|
926
|
-
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
927
|
-
var SignOutButton = ({ className }) => {
|
|
928
|
-
const { signOut } = useAuth();
|
|
929
|
-
return /* @__PURE__ */ jsx9(
|
|
930
|
-
"button",
|
|
931
|
-
{
|
|
932
|
-
className: cn(
|
|
933
|
-
"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
|
|
934
|
-
className
|
|
935
|
-
),
|
|
936
|
-
onClick: () => signOut(),
|
|
937
|
-
children: "Sign Out"
|
|
938
|
-
}
|
|
939
|
-
);
|
|
940
|
-
};
|
|
941
|
-
|
|
942
|
-
// src/lib/logger.ts
|
|
943
|
-
import debug from "debug";
|
|
944
|
-
var PACKAGE_NAME = "@civic/auth";
|
|
945
|
-
var DebugLogger = class {
|
|
946
|
-
constructor(namespace) {
|
|
947
|
-
this.debugLogger = debug(`${PACKAGE_NAME}:${namespace}:debug`);
|
|
948
|
-
this.infoLogger = debug(`${PACKAGE_NAME}:${namespace}:info`);
|
|
949
|
-
this.warnLogger = debug(`${PACKAGE_NAME}:${namespace}:warn`);
|
|
950
|
-
this.errorLogger = debug(`${PACKAGE_NAME}:${namespace}:error`);
|
|
951
|
-
this.debugLogger.color = "4";
|
|
952
|
-
this.infoLogger.color = "2";
|
|
953
|
-
this.warnLogger.color = "3";
|
|
954
|
-
this.errorLogger.color = "1";
|
|
955
|
-
}
|
|
956
|
-
debug(message, ...args) {
|
|
957
|
-
this.debugLogger(message, ...args);
|
|
958
|
-
}
|
|
959
|
-
info(message, ...args) {
|
|
960
|
-
this.infoLogger(message, ...args);
|
|
961
|
-
}
|
|
962
|
-
warn(message, ...args) {
|
|
963
|
-
this.warnLogger(message, ...args);
|
|
964
|
-
}
|
|
965
|
-
error(message, ...args) {
|
|
966
|
-
this.errorLogger(message, ...args);
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
var createLogger = (namespace) => new DebugLogger(namespace);
|
|
970
|
-
var loggers = {
|
|
971
|
-
// Next.js specific loggers
|
|
972
|
-
nextjs: {
|
|
973
|
-
routes: createLogger("api:routes"),
|
|
974
|
-
middleware: createLogger("api:middleware"),
|
|
975
|
-
handlers: {
|
|
976
|
-
auth: createLogger("api:handlers:auth")
|
|
356
|
+
} catch (e) {
|
|
357
|
+
console.log("Waiting for redirect...");
|
|
358
|
+
}
|
|
977
359
|
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
var logger = loggers.nextjs.handlers.auth;
|
|
994
|
-
var defaultAuthConfig = {
|
|
995
|
-
oauthServer: "https://auth-dev.civic.com/oauth",
|
|
996
|
-
callbackUrl: "/api/auth/callback",
|
|
997
|
-
challengeUrl: "/api/auth/challenge",
|
|
998
|
-
logoutUrl: "/api/auth/logout",
|
|
999
|
-
loginUrl: "/",
|
|
1000
|
-
include: ["/*"],
|
|
1001
|
-
exclude: [],
|
|
1002
|
-
cookies: {
|
|
1003
|
-
tokens: {
|
|
1004
|
-
sameSite: "strict",
|
|
1005
|
-
path: "/",
|
|
1006
|
-
maxAge: 60 * 60
|
|
1007
|
-
// 1 hour
|
|
360
|
+
return false;
|
|
361
|
+
}, [
|
|
362
|
+
closeOnRedirect,
|
|
363
|
+
config.redirectUrl,
|
|
364
|
+
iframeRef,
|
|
365
|
+
onClose,
|
|
366
|
+
serverTokenExchange,
|
|
367
|
+
setAuthResponseUrl
|
|
368
|
+
]);
|
|
369
|
+
const intervalId = useRef();
|
|
370
|
+
const handleEscape = useCallback(
|
|
371
|
+
(event) => {
|
|
372
|
+
if (event.key === "Escape") {
|
|
373
|
+
onClose == null ? void 0 : onClose();
|
|
374
|
+
}
|
|
1008
375
|
},
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
};
|
|
1017
|
-
var withoutUndefined = (obj) => {
|
|
1018
|
-
const result = {};
|
|
1019
|
-
for (const key in obj) {
|
|
1020
|
-
if (obj[key] !== void 0) {
|
|
1021
|
-
result[key] = obj[key];
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
return result;
|
|
1025
|
-
};
|
|
1026
|
-
var resolveAuthConfig = (config = {}) => {
|
|
1027
|
-
var _a, _b, _c, _d;
|
|
1028
|
-
const configFromEnv = withoutUndefined({
|
|
1029
|
-
clientId: process.env._civic_auth_client_id,
|
|
1030
|
-
oauthServer: process.env._civic_oauth_server,
|
|
1031
|
-
callbackUrl: process.env._civic_auth_callback_url,
|
|
1032
|
-
loginUrl: process.env._civic_auth_login_url,
|
|
1033
|
-
logoutUrl: process.env._civic_auth_logout_url,
|
|
1034
|
-
include: (_a = process.env._civic_auth_includes) == null ? void 0 : _a.split(","),
|
|
1035
|
-
exclude: (_b = process.env._civic_auth_excludes) == null ? void 0 : _b.split(","),
|
|
1036
|
-
cookies: process.env._civic_auth_cookie_config ? JSON.parse(process.env._civic_auth_cookie_config) : void 0
|
|
376
|
+
[onClose]
|
|
377
|
+
);
|
|
378
|
+
useEffect(() => {
|
|
379
|
+
window.addEventListener("keydown", handleEscape);
|
|
380
|
+
return () => window.removeEventListener("keydown", handleEscape);
|
|
1037
381
|
});
|
|
1038
|
-
const
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
382
|
+
const handleIframeLoad = () => {
|
|
383
|
+
setIsLoading(false);
|
|
384
|
+
console.log("handleIframeLoad");
|
|
385
|
+
if (processIframeUrl() && intervalId.current) {
|
|
386
|
+
clearInterval(intervalId.current);
|
|
1043
387
|
}
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
};
|
|
1052
|
-
|
|
1053
|
-
// src/react/components/NextLogOut.tsx
|
|
1054
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1055
|
-
var NextLogOut = ({ children }) => {
|
|
1056
|
-
const config = resolveAuthConfig();
|
|
1057
|
-
const logoutUrl = `${config.logoutUrl}`;
|
|
1058
|
-
return /* @__PURE__ */ jsx10("a", { href: logoutUrl, children });
|
|
1059
|
-
};
|
|
1060
|
-
|
|
1061
|
-
// src/react/providers/SessionProvider.tsx
|
|
1062
|
-
import { createContext as createContext3 } from "react";
|
|
1063
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1064
|
-
var defaultSession = {
|
|
1065
|
-
authenticated: false,
|
|
1066
|
-
idToken: void 0,
|
|
1067
|
-
accessToken: void 0,
|
|
1068
|
-
displayMode: "iframe"
|
|
388
|
+
};
|
|
389
|
+
const showLoadingIcon = isLoading || isAuthLoading || !((_a = iframeRef == null ? void 0 : iframeRef.current) == null ? void 0 : _a.getAttribute("src"));
|
|
390
|
+
const WrapperComponent = config.modalIframe ? IframeChrome : NoChrome;
|
|
391
|
+
return /* @__PURE__ */ jsxs3(WrapperComponent, { onClose, children: [
|
|
392
|
+
showLoadingIcon && /* @__PURE__ */ jsx7("div", { className: "cac-absolute cac-inset-0 cac-flex cac-items-center cac-justify-center cac-rounded-3xl cac-bg-neutral-100", children: /* @__PURE__ */ jsx7(LoadingIcon, {}) }),
|
|
393
|
+
/* @__PURE__ */ jsx7(CivicAuthIframe, { ref: iframeRef, onLoad: handleIframeLoad })
|
|
394
|
+
] });
|
|
1069
395
|
};
|
|
1070
|
-
var SessionContext = createContext3(defaultSession);
|
|
1071
|
-
var SessionProvider = ({ children, session }) => /* @__PURE__ */ jsx11(SessionContext.Provider, { value: session || defaultSession, children });
|
|
1072
396
|
|
|
1073
397
|
// src/config.ts
|
|
1074
398
|
var authConfig = {
|
|
@@ -1076,24 +400,37 @@ var authConfig = {
|
|
|
1076
400
|
oauthServer: "https://auth-dev.civic.com/oauth/"
|
|
1077
401
|
};
|
|
1078
402
|
|
|
1079
|
-
// src/
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
403
|
+
// src/react/providers/ConfigProvider.tsx
|
|
404
|
+
import { createContext as createContext5 } from "react";
|
|
405
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
406
|
+
var defaultConfig = {
|
|
407
|
+
config: authConfig,
|
|
408
|
+
redirectUrl: "",
|
|
409
|
+
modalIframe: true,
|
|
410
|
+
serverTokenExchange: false
|
|
411
|
+
};
|
|
412
|
+
var ConfigContext = createContext5(defaultConfig);
|
|
413
|
+
var ConfigProvider = ({
|
|
414
|
+
children,
|
|
415
|
+
config,
|
|
416
|
+
redirectUrl,
|
|
417
|
+
modalIframe,
|
|
418
|
+
serverTokenExchange
|
|
419
|
+
}) => /* @__PURE__ */ jsx8(
|
|
420
|
+
ConfigContext.Provider,
|
|
421
|
+
{
|
|
422
|
+
value: {
|
|
423
|
+
config,
|
|
424
|
+
redirectUrl,
|
|
425
|
+
modalIframe: !!modalIframe,
|
|
426
|
+
serverTokenExchange
|
|
427
|
+
},
|
|
428
|
+
children
|
|
1090
429
|
}
|
|
1091
|
-
|
|
1092
|
-
};
|
|
430
|
+
);
|
|
1093
431
|
|
|
1094
432
|
// src/shared/AuthProvider.tsx
|
|
1095
|
-
import { jsx as
|
|
1096
|
-
var AuthContext = createContext4(null);
|
|
433
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1097
434
|
var globalThisObject;
|
|
1098
435
|
if (typeof window !== "undefined") {
|
|
1099
436
|
globalThisObject = window;
|
|
@@ -1103,25 +440,33 @@ if (typeof window !== "undefined") {
|
|
|
1103
440
|
globalThisObject = Function("return this")();
|
|
1104
441
|
}
|
|
1105
442
|
globalThisObject.globalThis = globalThisObject;
|
|
443
|
+
function BlockDisplay({ children }) {
|
|
444
|
+
return /* @__PURE__ */ jsx9("div", { className: "cac-absolute cac-left-0 cac-top-0 cac-z-50 cac-flex cac-h-screen cac-w-screen cac-items-center cac-justify-center cac-bg-white", children: /* @__PURE__ */ jsx9("div", { className: "cac-absolute cac-inset-0 cac-flex cac-items-center cac-justify-center cac-bg-white", children }) });
|
|
445
|
+
}
|
|
1106
446
|
var AuthProvider = ({
|
|
1107
447
|
children,
|
|
1108
448
|
clientId,
|
|
1109
449
|
redirectUrl: inputRedirectUrl,
|
|
1110
450
|
config = authConfig,
|
|
1111
|
-
nonce,
|
|
1112
451
|
onSignIn,
|
|
1113
452
|
onSignOut,
|
|
1114
|
-
|
|
1115
|
-
|
|
453
|
+
pkceConsumer,
|
|
454
|
+
nonce,
|
|
455
|
+
modalIframe = true
|
|
1116
456
|
}) => {
|
|
1117
|
-
const [iframeUrl, setIframeUrl] =
|
|
1118
|
-
const [currentUrl, setCurrentUrl] =
|
|
1119
|
-
const [isInIframe, setIsInIframe] =
|
|
1120
|
-
const [authResponseUrl, setAuthResponseUrl] =
|
|
1121
|
-
const [tokenExchangeError, setTokenExchangeError] =
|
|
457
|
+
const [iframeUrl, setIframeUrl] = useState2(null);
|
|
458
|
+
const [currentUrl, setCurrentUrl] = useState2(null);
|
|
459
|
+
const [isInIframe, setIsInIframe] = useState2(false);
|
|
460
|
+
const [authResponseUrl, setAuthResponseUrl] = useState2(null);
|
|
461
|
+
const [tokenExchangeError, setTokenExchangeError] = useState2();
|
|
462
|
+
const [displayMode, setDisplayMode] = useState2("iframe");
|
|
463
|
+
const [browserAuthenticationInitiator, setBrowserAuthenticationInitiator] = useState2();
|
|
464
|
+
const [showIFrame, setShowIFrame] = useState2(false);
|
|
465
|
+
const [isRedirecting, setIsRedirecting] = useState2(false);
|
|
1122
466
|
const queryClient3 = useQueryClient2();
|
|
1123
467
|
const iframeRef = useRef2(null);
|
|
1124
|
-
|
|
468
|
+
const serverTokenExchange = pkceConsumer instanceof ConfidentialClientPKCEConsumer;
|
|
469
|
+
useEffect2(() => {
|
|
1125
470
|
if (typeof globalThis.window !== "undefined") {
|
|
1126
471
|
setCurrentUrl(globalThis.window.location.href);
|
|
1127
472
|
const isInIframeVal = isWindowInIframe(globalThis.window);
|
|
@@ -1132,26 +477,30 @@ var AuthProvider = ({
|
|
|
1132
477
|
() => (inputRedirectUrl || currentUrl || "").split("?")[0],
|
|
1133
478
|
[currentUrl, inputRedirectUrl]
|
|
1134
479
|
);
|
|
1135
|
-
const authService =
|
|
1136
|
-
|
|
480
|
+
const [authService, setAuthService] = useState2();
|
|
481
|
+
useEffect2(() => {
|
|
482
|
+
if (!currentUrl) return;
|
|
483
|
+
BrowserAuthenticationService.build({
|
|
1137
484
|
clientId,
|
|
1138
485
|
redirectUrl,
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
);
|
|
1144
|
-
const [userInfoService, setUserInfoService] = useState3();
|
|
1145
|
-
useEffect3(() => {
|
|
1146
|
-
if (!authService) return;
|
|
1147
|
-
authService.getUserInfoService().then(setUserInfoService);
|
|
1148
|
-
}, [authService]);
|
|
486
|
+
oauthServer: config.oauthServer,
|
|
487
|
+
scopes: DEFAULT_SCOPES,
|
|
488
|
+
displayMode
|
|
489
|
+
}).then(setAuthService);
|
|
490
|
+
}, [currentUrl, clientId, redirectUrl, config, displayMode]);
|
|
1149
491
|
const {
|
|
1150
492
|
data: session,
|
|
1151
493
|
isLoading,
|
|
1152
494
|
error
|
|
1153
495
|
} = useQuery2({
|
|
1154
|
-
queryKey: [
|
|
496
|
+
queryKey: [
|
|
497
|
+
"session",
|
|
498
|
+
authResponseUrl,
|
|
499
|
+
iframeUrl,
|
|
500
|
+
currentUrl,
|
|
501
|
+
isInIframe,
|
|
502
|
+
authService
|
|
503
|
+
],
|
|
1155
504
|
queryFn: () => __async(void 0, null, function* () {
|
|
1156
505
|
if (!authService) {
|
|
1157
506
|
return { authenticated: false };
|
|
@@ -1160,12 +509,24 @@ var AuthProvider = ({
|
|
|
1160
509
|
authResponseUrl ? authResponseUrl : globalThis.window.location.href || ""
|
|
1161
510
|
);
|
|
1162
511
|
const code = url.searchParams.get("code");
|
|
1163
|
-
|
|
512
|
+
const state = url.searchParams.get("state");
|
|
513
|
+
if (!serverTokenExchange && code && state && !isInIframe) {
|
|
1164
514
|
try {
|
|
1165
|
-
console.log("AuthProvider useQuery code", {
|
|
1166
|
-
|
|
515
|
+
console.log("AuthProvider useQuery code", {
|
|
516
|
+
isInIframe,
|
|
517
|
+
code,
|
|
518
|
+
state
|
|
519
|
+
});
|
|
520
|
+
yield authService.tokenExchange(code, state);
|
|
521
|
+
const clientStorage = new LocalStorageAdapter();
|
|
522
|
+
const user = yield getUser(clientStorage);
|
|
523
|
+
if (!user) {
|
|
524
|
+
throw new Error("Failed to get user info");
|
|
525
|
+
}
|
|
526
|
+
const userSession = new GenericUserSession(clientStorage);
|
|
527
|
+
userSession.set(user);
|
|
1167
528
|
onSignIn == null ? void 0 : onSignIn();
|
|
1168
|
-
return
|
|
529
|
+
return authService.getSessionData();
|
|
1169
530
|
} catch (error2) {
|
|
1170
531
|
setTokenExchangeError(error2);
|
|
1171
532
|
onSignIn == null ? void 0 : onSignIn(
|
|
@@ -1183,39 +544,90 @@ var AuthProvider = ({
|
|
|
1183
544
|
});
|
|
1184
545
|
const signOutMutation = useMutation2({
|
|
1185
546
|
mutationFn: () => __async(void 0, null, function* () {
|
|
1186
|
-
|
|
547
|
+
const authInitiator = getAuthInitiator();
|
|
548
|
+
authInitiator == null ? void 0 : authInitiator.signOut();
|
|
1187
549
|
setIframeUrl(null);
|
|
550
|
+
setShowIFrame(false);
|
|
1188
551
|
setAuthResponseUrl(null);
|
|
1189
552
|
onSignOut == null ? void 0 : onSignOut();
|
|
1190
553
|
}),
|
|
1191
554
|
onSuccess: () => {
|
|
1192
555
|
queryClient3.setQueryData(
|
|
1193
|
-
[
|
|
556
|
+
[
|
|
557
|
+
"session",
|
|
558
|
+
authResponseUrl,
|
|
559
|
+
iframeUrl,
|
|
560
|
+
currentUrl,
|
|
561
|
+
isInIframe,
|
|
562
|
+
authService
|
|
563
|
+
],
|
|
1194
564
|
null
|
|
1195
565
|
);
|
|
1196
566
|
}
|
|
1197
567
|
});
|
|
1198
|
-
const
|
|
1199
|
-
(overrideDisplayMode
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
568
|
+
const getAuthInitiator = useCallback2(
|
|
569
|
+
(overrideDisplayMode) => {
|
|
570
|
+
const useDisplayMode = overrideDisplayMode || displayMode;
|
|
571
|
+
if (!pkceConsumer) {
|
|
572
|
+
return null;
|
|
573
|
+
}
|
|
574
|
+
return browserAuthenticationInitiator || new BrowserAuthenticationInitiator({
|
|
575
|
+
pkceConsumer,
|
|
576
|
+
// generate and retrieve the challenge client-side
|
|
577
|
+
clientId,
|
|
578
|
+
redirectUrl,
|
|
579
|
+
state: generateState(useDisplayMode),
|
|
580
|
+
scopes: DEFAULT_SCOPES,
|
|
581
|
+
displayMode: useDisplayMode,
|
|
582
|
+
oauthServer: config.oauthServer,
|
|
583
|
+
// the endpoints to use for the login (if not obtained from the auth server
|
|
584
|
+
endpointOverrides: config.endpoints,
|
|
1205
585
|
nonce
|
|
1206
|
-
);
|
|
586
|
+
});
|
|
587
|
+
},
|
|
588
|
+
[
|
|
589
|
+
displayMode,
|
|
590
|
+
browserAuthenticationInitiator,
|
|
591
|
+
clientId,
|
|
592
|
+
redirectUrl,
|
|
593
|
+
config.oauthServer,
|
|
594
|
+
config.endpoints,
|
|
595
|
+
pkceConsumer,
|
|
596
|
+
nonce
|
|
597
|
+
]
|
|
598
|
+
);
|
|
599
|
+
const signIn = useCallback2(
|
|
600
|
+
(overrideDisplayMode = "iframe") => __async(void 0, null, function* () {
|
|
601
|
+
setDisplayMode(overrideDisplayMode);
|
|
602
|
+
const authInitiator = getAuthInitiator(overrideDisplayMode);
|
|
603
|
+
setBrowserAuthenticationInitiator(authInitiator);
|
|
1207
604
|
if (overrideDisplayMode === "iframe") {
|
|
1208
|
-
|
|
1209
|
-
|
|
605
|
+
setShowIFrame(true);
|
|
606
|
+
} else if (overrideDisplayMode === "redirect") {
|
|
607
|
+
setIsRedirecting(true);
|
|
1210
608
|
}
|
|
1211
|
-
|
|
609
|
+
authInitiator == null ? void 0 : authInitiator.signIn(iframeRef.current);
|
|
1212
610
|
}),
|
|
1213
|
-
[
|
|
611
|
+
[getAuthInitiator]
|
|
1214
612
|
);
|
|
1215
613
|
const isAuthenticated = useMemo2(
|
|
1216
614
|
() => session ? session.authenticated : false,
|
|
1217
615
|
[session]
|
|
1218
616
|
);
|
|
617
|
+
const {
|
|
618
|
+
data: autoSignIn,
|
|
619
|
+
isLoading: autoSignInLoading,
|
|
620
|
+
error: autoSignInError
|
|
621
|
+
} = useQuery2({
|
|
622
|
+
queryKey: ["autoSignIn", modalIframe, redirectUrl, isAuthenticated],
|
|
623
|
+
queryFn: () => __async(void 0, null, function* () {
|
|
624
|
+
if (!modalIframe && redirectUrl && !isAuthenticated && iframeRef.current) {
|
|
625
|
+
signIn("iframe");
|
|
626
|
+
}
|
|
627
|
+
return true;
|
|
628
|
+
}),
|
|
629
|
+
refetchOnWindowFocus: false
|
|
630
|
+
});
|
|
1219
631
|
const value = useMemo2(
|
|
1220
632
|
() => ({
|
|
1221
633
|
isLoading,
|
|
@@ -1228,41 +640,66 @@ var AuthProvider = ({
|
|
|
1228
640
|
}),
|
|
1229
641
|
[isLoading, error, signOutMutation, isAuthenticated, signIn]
|
|
1230
642
|
);
|
|
1231
|
-
return /* @__PURE__ */
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
643
|
+
return /* @__PURE__ */ jsx9(AuthContext.Provider, { value, children: /* @__PURE__ */ jsx9(
|
|
644
|
+
ConfigProvider,
|
|
645
|
+
{
|
|
646
|
+
config,
|
|
647
|
+
redirectUrl,
|
|
648
|
+
modalIframe,
|
|
649
|
+
serverTokenExchange,
|
|
650
|
+
children: /* @__PURE__ */ jsx9(
|
|
651
|
+
SessionProvider,
|
|
652
|
+
{
|
|
653
|
+
session,
|
|
654
|
+
setAuthResponseUrl,
|
|
655
|
+
iframeRef,
|
|
656
|
+
children: /* @__PURE__ */ jsx9(TokenProvider, { children: /* @__PURE__ */ jsxs4(UserProvider, { storage: new LocalStorageAdapter(), children: [
|
|
657
|
+
modalIframe && !isInIframe && !(session == null ? void 0 : session.authenticated) && /* @__PURE__ */ jsx9(
|
|
658
|
+
"div",
|
|
659
|
+
{
|
|
660
|
+
style: showIFrame ? { display: "block" } : { display: "none" },
|
|
661
|
+
children: /* @__PURE__ */ jsx9(
|
|
662
|
+
CivicAuthIframeContainer,
|
|
663
|
+
{
|
|
664
|
+
onClose: () => setShowIFrame(false)
|
|
665
|
+
}
|
|
666
|
+
)
|
|
667
|
+
}
|
|
668
|
+
),
|
|
669
|
+
modalIframe && (isInIframe || isRedirecting || isLoading) && /* @__PURE__ */ jsx9(BlockDisplay, { children: /* @__PURE__ */ jsx9(LoadingIcon, {}) }),
|
|
670
|
+
(tokenExchangeError || error) && /* @__PURE__ */ jsx9(BlockDisplay, { children: /* @__PURE__ */ jsxs4("div", { children: [
|
|
671
|
+
"Error: ",
|
|
672
|
+
(tokenExchangeError || error).message
|
|
673
|
+
] }) }),
|
|
674
|
+
children
|
|
675
|
+
] }) })
|
|
676
|
+
}
|
|
677
|
+
)
|
|
678
|
+
}
|
|
679
|
+
) });
|
|
1249
680
|
};
|
|
1250
681
|
|
|
1251
682
|
// src/shared/CivicAuthProvider.tsx
|
|
1252
683
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
1253
684
|
import "@civic/auth/styles.css";
|
|
1254
|
-
import { jsx as
|
|
685
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1255
686
|
var queryClient = new QueryClient();
|
|
1256
687
|
var CivicAuthProvider = (_a) => {
|
|
1257
688
|
var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
|
|
1258
|
-
return /* @__PURE__ */
|
|
689
|
+
return /* @__PURE__ */ jsx10(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx10(
|
|
690
|
+
AuthProvider,
|
|
691
|
+
__spreadProps(__spreadValues({}, props), {
|
|
692
|
+
pkceConsumer: new BrowserPublicClientPKCEProducer(),
|
|
693
|
+
children
|
|
694
|
+
})
|
|
695
|
+
) });
|
|
1259
696
|
};
|
|
1260
697
|
|
|
1261
698
|
// src/react/providers/NextAuthProvider.tsx
|
|
1262
|
-
import { createContext as
|
|
699
|
+
import { createContext as createContext6, useContext as useContext4, useEffect as useEffect4, useState as useState3 } from "react";
|
|
1263
700
|
|
|
1264
701
|
// src/react/hooks/useUserCookie.ts
|
|
1265
|
-
import { useEffect as
|
|
702
|
+
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
1266
703
|
import { useRouter } from "next/navigation.js";
|
|
1267
704
|
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
1268
705
|
|
|
@@ -1273,7 +710,7 @@ var getCookieValue = (key, window2) => {
|
|
|
1273
710
|
const cookies = cookie.split(";");
|
|
1274
711
|
for (const c of cookies) {
|
|
1275
712
|
const [name, value] = c.trim().split("=");
|
|
1276
|
-
if (name === key) {
|
|
713
|
+
if (value && name === key) {
|
|
1277
714
|
try {
|
|
1278
715
|
return JSON.parse(decodeURIComponent(value));
|
|
1279
716
|
} catch (e) {
|
|
@@ -1301,7 +738,7 @@ var useUserCookie = () => {
|
|
|
1301
738
|
enabled: !hasRunRef.current,
|
|
1302
739
|
refetchOnWindowFocus: true
|
|
1303
740
|
});
|
|
1304
|
-
|
|
741
|
+
useEffect3(() => {
|
|
1305
742
|
if (user) {
|
|
1306
743
|
if (!hasRunRef.current) {
|
|
1307
744
|
hasRunRef.current = true;
|
|
@@ -1316,10 +753,11 @@ var useUserCookie = () => {
|
|
|
1316
753
|
|
|
1317
754
|
// src/react/providers/NextAuthProvider.tsx
|
|
1318
755
|
import { QueryClient as QueryClient2, QueryClientProvider as QueryClientProvider2 } from "@tanstack/react-query";
|
|
1319
|
-
import
|
|
756
|
+
import "@civic/auth/styles.css";
|
|
757
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1320
758
|
var queryClient2 = new QueryClient2();
|
|
1321
759
|
var defaultUserContext = { user: null };
|
|
1322
|
-
var UserContext2 =
|
|
760
|
+
var UserContext2 = createContext6(defaultUserContext);
|
|
1323
761
|
var CivicNextAuthProvider = (_a) => {
|
|
1324
762
|
var _b = _a, {
|
|
1325
763
|
children
|
|
@@ -1327,54 +765,218 @@ var CivicNextAuthProvider = (_a) => {
|
|
|
1327
765
|
"children"
|
|
1328
766
|
]);
|
|
1329
767
|
const user = useUserCookie();
|
|
1330
|
-
const [redirectUrl, setRedirectUrl] =
|
|
768
|
+
const [redirectUrl, setRedirectUrl] = useState3("");
|
|
1331
769
|
const { clientId, oauthServer, callbackUrl, challengeUrl } = resolveAuthConfig();
|
|
1332
|
-
|
|
770
|
+
useEffect4(() => {
|
|
1333
771
|
if (typeof globalThis.window !== "undefined") {
|
|
1334
772
|
const currentUrl = globalThis.window.location.href;
|
|
1335
|
-
setRedirectUrl(
|
|
773
|
+
setRedirectUrl(resolveCallbackUrl(resolveAuthConfig(), currentUrl));
|
|
1336
774
|
}
|
|
1337
775
|
}, [callbackUrl]);
|
|
1338
|
-
|
|
1339
|
-
if (redirectUrl && clientId && oauthServer) {
|
|
1340
|
-
return new AuthSessionServiceImpl(clientId, redirectUrl, oauthServer, {
|
|
1341
|
-
challenge: challengeUrl
|
|
1342
|
-
});
|
|
1343
|
-
}
|
|
1344
|
-
return void 0;
|
|
1345
|
-
}, [redirectUrl, clientId, oauthServer, challengeUrl]);
|
|
1346
|
-
return /* @__PURE__ */ jsx14(QueryClientProvider2, { client: queryClient2, children: /* @__PURE__ */ jsx14(
|
|
776
|
+
return /* @__PURE__ */ jsx11(QueryClientProvider2, { client: queryClient2, children: /* @__PURE__ */ jsx11(
|
|
1347
777
|
AuthProvider,
|
|
1348
778
|
__spreadProps(__spreadValues({}, props), {
|
|
779
|
+
redirectUrl,
|
|
1349
780
|
config: { oauthServer },
|
|
1350
781
|
clientId,
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
children: /* @__PURE__ */ jsx14(UserContext2.Provider, { value: user, children })
|
|
782
|
+
pkceConsumer: new ConfidentialClientPKCEConsumer(challengeUrl),
|
|
783
|
+
children: /* @__PURE__ */ jsx11(UserContext2.Provider, { value: user, children })
|
|
1354
784
|
})
|
|
1355
785
|
) });
|
|
1356
786
|
};
|
|
1357
|
-
var useNextUser = () =>
|
|
787
|
+
var useNextUser = () => useContext4(UserContext2);
|
|
1358
788
|
|
|
1359
789
|
// src/react/hooks/useUser.tsx
|
|
1360
790
|
var useUser = () => {
|
|
1361
|
-
const context =
|
|
791
|
+
const context = useContext5(UserContext);
|
|
1362
792
|
if (!context) {
|
|
1363
793
|
throw new Error("useUser must be used within a UserProvider");
|
|
1364
794
|
}
|
|
1365
795
|
return context;
|
|
1366
796
|
};
|
|
1367
797
|
|
|
1368
|
-
// src/react/hooks/
|
|
1369
|
-
import { useContext as
|
|
1370
|
-
var
|
|
1371
|
-
const context =
|
|
798
|
+
// src/react/hooks/useConfig.tsx
|
|
799
|
+
import { useContext as useContext6 } from "react";
|
|
800
|
+
var useConfig = () => {
|
|
801
|
+
const context = useContext6(ConfigContext);
|
|
1372
802
|
if (!context) {
|
|
1373
|
-
throw new Error("
|
|
803
|
+
throw new Error("useConfig must be used within an ConfigProvider");
|
|
1374
804
|
}
|
|
1375
805
|
return context;
|
|
1376
806
|
};
|
|
807
|
+
|
|
808
|
+
// src/react/components/UserButton.tsx
|
|
809
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useState as useState4 } from "react";
|
|
810
|
+
import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
811
|
+
var ChevronDown = () => /* @__PURE__ */ jsx12(
|
|
812
|
+
"svg",
|
|
813
|
+
{
|
|
814
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
815
|
+
width: "24",
|
|
816
|
+
height: "24",
|
|
817
|
+
viewBox: "0 0 24 24",
|
|
818
|
+
fill: "none",
|
|
819
|
+
stroke: "currentColor",
|
|
820
|
+
strokeWidth: "2",
|
|
821
|
+
strokeLinecap: "round",
|
|
822
|
+
strokeLinejoin: "round",
|
|
823
|
+
className: "lucide lucide-chevron-down",
|
|
824
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" })
|
|
825
|
+
}
|
|
826
|
+
);
|
|
827
|
+
var ChevronUp = () => /* @__PURE__ */ jsx12(
|
|
828
|
+
"svg",
|
|
829
|
+
{
|
|
830
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
831
|
+
width: "24",
|
|
832
|
+
height: "24",
|
|
833
|
+
viewBox: "0 0 24 24",
|
|
834
|
+
fill: "none",
|
|
835
|
+
stroke: "currentColor",
|
|
836
|
+
strokeWidth: "2",
|
|
837
|
+
strokeLinecap: "round",
|
|
838
|
+
strokeLinejoin: "round",
|
|
839
|
+
className: "lucide lucide-chevron-up",
|
|
840
|
+
children: /* @__PURE__ */ jsx12("path", { d: "m18 15-6-6-6 6" })
|
|
841
|
+
}
|
|
842
|
+
);
|
|
843
|
+
var UserButton = ({
|
|
844
|
+
displayMode,
|
|
845
|
+
className
|
|
846
|
+
}) => {
|
|
847
|
+
const [isOpen, setIsOpen] = useState4(false);
|
|
848
|
+
const { signIn, isAuthenticated, signOut } = useAuth();
|
|
849
|
+
const { user } = useUser();
|
|
850
|
+
const handleClickOutside = useCallback3((event) => {
|
|
851
|
+
const target = event.target;
|
|
852
|
+
if (!target.closest("#civic-dropdown-container")) {
|
|
853
|
+
setIsOpen(false);
|
|
854
|
+
}
|
|
855
|
+
}, []);
|
|
856
|
+
const handleSignOut = useCallback3(() => __async(void 0, null, function* () {
|
|
857
|
+
yield signOut();
|
|
858
|
+
setIsOpen(false);
|
|
859
|
+
}), [signOut]);
|
|
860
|
+
const handleSignIn = useCallback3(() => __async(void 0, null, function* () {
|
|
861
|
+
yield signIn(displayMode);
|
|
862
|
+
setIsOpen(false);
|
|
863
|
+
}), [signIn, displayMode]);
|
|
864
|
+
const handleEscape = useCallback3((event) => {
|
|
865
|
+
if (event.key === "Escape") {
|
|
866
|
+
setIsOpen(false);
|
|
867
|
+
}
|
|
868
|
+
}, []);
|
|
869
|
+
useEffect5(() => {
|
|
870
|
+
if (isOpen) {
|
|
871
|
+
window.addEventListener("click", handleClickOutside);
|
|
872
|
+
window.addEventListener("keydown", handleEscape);
|
|
873
|
+
}
|
|
874
|
+
return () => {
|
|
875
|
+
window.removeEventListener("click", handleClickOutside);
|
|
876
|
+
window.removeEventListener("keydown", handleEscape);
|
|
877
|
+
};
|
|
878
|
+
}, [handleClickOutside, handleEscape, isOpen]);
|
|
879
|
+
if (isAuthenticated) {
|
|
880
|
+
return /* @__PURE__ */ jsxs5("div", { className: "cac-relative", id: "civic-dropdown-container", children: [
|
|
881
|
+
/* @__PURE__ */ jsxs5(
|
|
882
|
+
"button",
|
|
883
|
+
{
|
|
884
|
+
className: cn(
|
|
885
|
+
"cac-flex cac-w-full cac-items-center cac-justify-between cac-gap-2 cac-rounded-full cac-border cac-border-neutral-500 cac-px-3 cac-py-2 cac-text-neutral-500 cac-transition-colors hover:cac-bg-neutral-200 hover:cac-bg-opacity-50",
|
|
886
|
+
className
|
|
887
|
+
),
|
|
888
|
+
onClick: () => setIsOpen((isOpen2) => !isOpen2),
|
|
889
|
+
children: [
|
|
890
|
+
(user == null ? void 0 : user.picture) ? /* @__PURE__ */ jsx12("span", { className: "cac-relative cac-flex cac-h-10 cac-w-10 cac-shrink-0 cac-gap-2 cac-overflow-hidden cac-rounded-full", children: /* @__PURE__ */ jsx12(
|
|
891
|
+
"img",
|
|
892
|
+
{
|
|
893
|
+
className: "cac-h-full cac-w-full cac-object-cover",
|
|
894
|
+
src: user.picture,
|
|
895
|
+
alt: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email)
|
|
896
|
+
}
|
|
897
|
+
) }) : /* @__PURE__ */ jsx12("div", {}),
|
|
898
|
+
/* @__PURE__ */ jsx12("span", { children: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email) }),
|
|
899
|
+
isOpen ? /* @__PURE__ */ jsx12(ChevronUp, {}) : /* @__PURE__ */ jsx12(ChevronDown, {})
|
|
900
|
+
]
|
|
901
|
+
}
|
|
902
|
+
),
|
|
903
|
+
/* @__PURE__ */ jsx12(
|
|
904
|
+
"div",
|
|
905
|
+
{
|
|
906
|
+
className: isOpen ? "cac-absolute cac-right-0 cac-mt-2 cac-w-full cac-rounded-lg cac-bg-white cac-py-2 cac-text-neutral-500 cac-shadow-xl" : "cac-hidden",
|
|
907
|
+
children: /* @__PURE__ */ jsx12("ul", { children: /* @__PURE__ */ jsx12("li", { children: /* @__PURE__ */ jsx12(
|
|
908
|
+
"button",
|
|
909
|
+
{
|
|
910
|
+
className: "cac-block cac-w-full cac-px-4 cac-py-2 cac-transition-colors hover:cac-bg-neutral-200 hover:cac-bg-opacity-50",
|
|
911
|
+
onClick: handleSignOut,
|
|
912
|
+
children: "Logout"
|
|
913
|
+
}
|
|
914
|
+
) }) })
|
|
915
|
+
}
|
|
916
|
+
)
|
|
917
|
+
] });
|
|
918
|
+
}
|
|
919
|
+
return /* @__PURE__ */ jsx12(
|
|
920
|
+
"button",
|
|
921
|
+
{
|
|
922
|
+
"data-testid": "sign-in-button",
|
|
923
|
+
className: cn(
|
|
924
|
+
"cac-rounded-full cac-border cac-border-neutral-500 cac-px-3 cac-py-2 cac-transition-colors hover:cac-bg-neutral-200 hover:cac-bg-opacity-50",
|
|
925
|
+
className
|
|
926
|
+
),
|
|
927
|
+
onClick: handleSignIn,
|
|
928
|
+
children: "Sign in"
|
|
929
|
+
}
|
|
930
|
+
);
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
// src/react/components/SignInButton.tsx
|
|
934
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
935
|
+
var SignInButton = ({
|
|
936
|
+
displayMode,
|
|
937
|
+
className
|
|
938
|
+
}) => {
|
|
939
|
+
const { signIn } = useAuth();
|
|
940
|
+
return /* @__PURE__ */ jsx13(
|
|
941
|
+
"button",
|
|
942
|
+
{
|
|
943
|
+
"data-testid": "sign-in-button",
|
|
944
|
+
className: cn(
|
|
945
|
+
"cac-rounded-full cac-border cac-border-neutral-500 cac-px-3 cac-py-2 cac-transition-colors hover:cac-bg-neutral-200 hover:cac-bg-opacity-50",
|
|
946
|
+
className
|
|
947
|
+
),
|
|
948
|
+
onClick: () => signIn(displayMode),
|
|
949
|
+
children: "Sign In"
|
|
950
|
+
}
|
|
951
|
+
);
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
// src/react/components/SignOutButton.tsx
|
|
955
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
956
|
+
var SignOutButton = ({ className }) => {
|
|
957
|
+
const { signOut } = useAuth();
|
|
958
|
+
return /* @__PURE__ */ jsx14(
|
|
959
|
+
"button",
|
|
960
|
+
{
|
|
961
|
+
className: cn(
|
|
962
|
+
"cac-rounded-full cac-border cac-border-neutral-500 cac-px-3 cac-py-2 cac-transition-colors hover:cac-bg-neutral-200 hover:cac-bg-opacity-50",
|
|
963
|
+
className
|
|
964
|
+
),
|
|
965
|
+
onClick: () => signOut(),
|
|
966
|
+
children: "Sign Out"
|
|
967
|
+
}
|
|
968
|
+
);
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
// src/react/components/NextLogOut.tsx
|
|
972
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
973
|
+
var NextLogOut = ({ children }) => {
|
|
974
|
+
const config = resolveAuthConfig();
|
|
975
|
+
const logoutUrl = `${config.logoutUrl}`;
|
|
976
|
+
return /* @__PURE__ */ jsx15("a", { href: logoutUrl, children });
|
|
977
|
+
};
|
|
1377
978
|
export {
|
|
979
|
+
CivicAuthIframeContainer,
|
|
1378
980
|
CivicAuthProvider,
|
|
1379
981
|
CivicNextAuthProvider,
|
|
1380
982
|
NextLogOut,
|
|
@@ -1382,6 +984,7 @@ export {
|
|
|
1382
984
|
SignOutButton,
|
|
1383
985
|
UserButton,
|
|
1384
986
|
useAuth,
|
|
987
|
+
useConfig,
|
|
1385
988
|
useNextUser,
|
|
1386
989
|
useSession,
|
|
1387
990
|
useToken,
|