@civic/auth 0.0.1-beta.0 → 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.
Files changed (45) hide show
  1. package/README.md +36 -10
  2. package/dist/chunk-CRTRMMJ7.js +59 -0
  3. package/dist/chunk-CRTRMMJ7.js.map +1 -0
  4. package/dist/chunk-EAANLFR5.mjs +148 -0
  5. package/dist/chunk-EAANLFR5.mjs.map +1 -0
  6. package/dist/chunk-EGFTMH5S.mjs +214 -0
  7. package/dist/chunk-EGFTMH5S.mjs.map +1 -0
  8. package/dist/chunk-KCSGIIPA.js +214 -0
  9. package/dist/chunk-KCSGIIPA.js.map +1 -0
  10. package/dist/chunk-MVO4UZ2A.js +148 -0
  11. package/dist/chunk-MVO4UZ2A.js.map +1 -0
  12. package/dist/chunk-PMDIR5XE.mjs +502 -0
  13. package/dist/chunk-PMDIR5XE.mjs.map +1 -0
  14. package/dist/chunk-RGHW4PYM.mjs +59 -0
  15. package/dist/chunk-RGHW4PYM.mjs.map +1 -0
  16. package/dist/chunk-YNLXRD5L.js +502 -0
  17. package/dist/chunk-YNLXRD5L.js.map +1 -0
  18. package/dist/{index-yT0eVchS.d.mts → index-Bfi0hVMZ.d.mts} +14 -8
  19. package/dist/{index-yT0eVchS.d.ts → index-Bfi0hVMZ.d.ts} +14 -8
  20. package/dist/index.css +66 -66
  21. package/dist/index.css.map +1 -1
  22. package/dist/index.d.mts +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +1 -19
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +1 -1
  27. package/dist/nextjs.d.mts +220 -4
  28. package/dist/nextjs.d.ts +220 -4
  29. package/dist/nextjs.js +228 -104
  30. package/dist/nextjs.js.map +1 -1
  31. package/dist/nextjs.mjs +228 -82
  32. package/dist/nextjs.mjs.map +1 -1
  33. package/dist/react.d.mts +60 -24
  34. package/dist/react.d.ts +60 -24
  35. package/dist/react.js +759 -895
  36. package/dist/react.js.map +1 -1
  37. package/dist/react.mjs +726 -828
  38. package/dist/react.mjs.map +1 -1
  39. package/dist/server.d.mts +56 -0
  40. package/dist/server.d.ts +56 -0
  41. package/dist/server.js +20 -0
  42. package/dist/server.js.map +1 -0
  43. package/dist/server.mjs +20 -0
  44. package/dist/server.mjs.map +1 -0
  45. package/package.json +20 -6
package/dist/react.js CHANGED
@@ -1,106 +1,45 @@
1
- 'use client'
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __defProps = Object.defineProperties;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
8
- var __getOwnPropNames = Object.getOwnPropertyNames;
9
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
10
- var __getProtoOf = Object.getPrototypeOf;
11
- var __hasOwnProp = Object.prototype.hasOwnProperty;
12
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
13
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
- var __spreadValues = (a, b) => {
15
- for (var prop in b || (b = {}))
16
- if (__hasOwnProp.call(b, prop))
17
- __defNormalProp(a, prop, b[prop]);
18
- if (__getOwnPropSymbols)
19
- for (var prop of __getOwnPropSymbols(b)) {
20
- if (__propIsEnum.call(b, prop))
21
- __defNormalProp(a, prop, b[prop]);
22
- }
23
- return a;
24
- };
25
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
- var __objRest = (source, exclude) => {
27
- var target = {};
28
- for (var prop in source)
29
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
30
- target[prop] = source[prop];
31
- if (source != null && __getOwnPropSymbols)
32
- for (var prop of __getOwnPropSymbols(source)) {
33
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
34
- target[prop] = source[prop];
35
- }
36
- return target;
37
- };
38
- var __export = (target, all) => {
39
- for (var name in all)
40
- __defProp(target, name, { get: all[name], enumerable: true });
41
- };
42
- var __copyProps = (to, from, except, desc) => {
43
- if (from && typeof from === "object" || typeof from === "function") {
44
- for (let key of __getOwnPropNames(from))
45
- if (!__hasOwnProp.call(to, key) && key !== except)
46
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
47
- }
48
- return to;
49
- };
50
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
51
- // If the importer is in node compatibility mode or this is not an ESM
52
- // file that has been converted to a CommonJS file using a Babel-
53
- // compatible transform (i.e. "__esModule" has not been set), then set
54
- // "default" to the CommonJS "module.exports" for node compatibility.
55
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
56
- mod
57
- ));
58
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
59
- var __async = (__this, __arguments, generator) => {
60
- return new Promise((resolve, reject) => {
61
- var fulfilled = (value) => {
62
- try {
63
- step(generator.next(value));
64
- } catch (e) {
65
- reject(e);
66
- }
67
- };
68
- var rejected = (value) => {
69
- try {
70
- step(generator.throw(value));
71
- } catch (e) {
72
- reject(e);
73
- }
74
- };
75
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
76
- step((generator = generator.apply(__this, __arguments)).next());
77
- });
78
- };
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunkMVO4UZ2Ajs = require('./chunk-MVO4UZ2A.js');
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+ var _chunkYNLXRD5Ljs = require('./chunk-YNLXRD5L.js');
79
19
 
80
- // src/react/index.ts
81
- var react_exports = {};
82
- __export(react_exports, {
83
- CivicProvider: () => CivicProvider,
84
- UserButton: () => UserButton,
85
- useAuth: () => useAuth,
86
- useParams: () => useParams,
87
- useSession: () => useSession,
88
- useToken: () => useToken,
89
- useUser: () => useUser
90
- });
91
- module.exports = __toCommonJS(react_exports);
20
+
21
+
22
+
23
+
24
+ var _chunkCRTRMMJ7js = require('./chunk-CRTRMMJ7.js');
92
25
 
93
26
  // src/react/hooks/useUser.tsx
94
- var import_react10 = require("react");
27
+ var _react = require('react');
95
28
 
96
29
  // src/react/providers/UserProvider.tsx
97
- var import_react3 = require("react");
98
- var import_react_query = require("@tanstack/react-query");
30
+
31
+ var _reactquery = require('@tanstack/react-query');
32
+
33
+ // src/react/hooks/useAuth.tsx
34
+
35
+
36
+ // src/shared/AuthContext.tsx
37
+
38
+ var AuthContext = _react.createContext.call(void 0, null);
99
39
 
100
40
  // src/react/hooks/useAuth.tsx
101
- var import_react = require("react");
102
41
  var useAuth = () => {
103
- const context = (0, import_react.useContext)(AuthContext);
42
+ const context = _react.useContext.call(void 0, AuthContext);
104
43
  if (!context) {
105
44
  throw new Error("useAuth must be used within an AuthProvider");
106
45
  }
@@ -108,98 +47,90 @@ var useAuth = () => {
108
47
  };
109
48
 
110
49
  // src/react/hooks/useToken.tsx
111
- var import_react2 = require("react");
112
- var useToken = () => {
113
- const context = (0, import_react2.useContext)(TokenContext);
50
+
51
+
52
+ // src/react/providers/TokenProvider.tsx
53
+
54
+
55
+
56
+ // src/react/hooks/useSession.tsx
57
+
58
+
59
+ // src/react/providers/SessionProvider.tsx
60
+
61
+
62
+
63
+ var _jsxruntime = require('react/jsx-runtime');
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 = _react.createContext.call(void 0, defaultSession);
74
+ var SessionProvider = ({
75
+ children,
76
+ session,
77
+ iframeRef,
78
+ setAuthResponseUrl
79
+ }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
80
+ SessionContext.Provider,
81
+ {
82
+ value: _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, session || defaultSession), { iframeRef, setAuthResponseUrl }),
83
+ children
84
+ }
85
+ );
86
+
87
+ // src/react/hooks/useSession.tsx
88
+ var useSession = () => {
89
+ const context = _react.useContext.call(void 0, SessionContext);
114
90
  if (!context) {
115
- throw new Error("useToken must be used within a TokenProvider");
91
+ throw new Error("useSession must be used within an SessionProvider");
116
92
  }
117
93
  return context;
118
94
  };
119
95
 
120
- // src/react/providers/UserProvider.tsx
121
- var import_jwt = require("oslo/jwt");
122
- var import_jsx_runtime = require("react/jsx-runtime");
123
- var UserContext = (0, import_react3.createContext)(null);
124
- var UserProvider = ({
125
- children
126
- }) => {
127
- const { isLoading: authLoading, error: authError } = useAuth();
128
- const session = useSession();
129
- const { forwardedTokens, idToken, accessToken, refreshToken } = useToken();
130
- const { isAuthenticated, signIn, signOut } = useAuth();
131
- const fetchUser = () => __async(void 0, null, function* () {
132
- if (!(session == null ? void 0 : session.idToken)) {
133
- return null;
134
- }
135
- const parsedJWT = (0, import_jwt.parseJWT)(session.idToken);
136
- if (!parsedJWT) {
137
- return null;
138
- }
139
- const user2 = parsedJWT.payload;
140
- return __spreadProps(__spreadValues({}, user2), {
141
- forwardedTokens,
142
- idToken,
143
- accessToken,
144
- refreshToken
145
- });
146
- });
147
- const {
148
- data: user,
149
- isLoading: userLoading,
150
- error: userError,
151
- refetch
152
- } = (0, import_react_query.useQuery)({
153
- queryKey: ["user", session == null ? void 0 : session.accessToken],
154
- queryFn: fetchUser,
155
- enabled: !!(session == null ? void 0 : session.accessToken)
156
- // Only run the query if we have an access token
157
- });
158
- const isLoading = authLoading || userLoading;
159
- const error = authError || userError;
160
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
- UserContext.Provider,
96
+ // src/react/providers/TokenProvider.tsx
97
+ var _jwt = require('oslo/jwt');
98
+
99
+ // src/lib/jwt.ts
100
+ var convertForwardedTokenFormat = (inputTokens) => Object.fromEntries(
101
+ Object.entries(inputTokens).map(([source, tokens]) => [
102
+ source,
162
103
  {
163
- value: {
164
- user,
165
- isLoading,
166
- error,
167
- refetch,
168
- isAuthenticated,
169
- signIn,
170
- signOut
171
- },
172
- children
104
+ idToken: tokens == null ? void 0 : tokens.id_token,
105
+ accessToken: tokens == null ? void 0 : tokens.access_token,
106
+ refreshToken: tokens == null ? void 0 : tokens.refresh_token
173
107
  }
174
- );
175
- };
108
+ ])
109
+ );
176
110
 
177
111
  // src/react/providers/TokenProvider.tsx
178
- var import_react4 = require("react");
179
- var import_react_query2 = require("@tanstack/react-query");
180
- var import_jwt2 = require("oslo/jwt");
181
- var import_jsx_runtime2 = require("react/jsx-runtime");
182
- var TokenContext = (0, import_react4.createContext)(void 0);
112
+
113
+ var TokenContext = _react.createContext.call(void 0, void 0);
183
114
  var TokenProvider = ({ children }) => {
184
115
  const { isLoading, error: authError } = useAuth();
185
116
  const session = useSession();
186
- const queryClient2 = (0, import_react_query2.useQueryClient)();
187
- const refreshTokenMutation = (0, import_react_query2.useMutation)({
188
- mutationFn: () => __async(void 0, null, function* () {
117
+ const queryClient3 = _reactquery.useQueryClient.call(void 0, );
118
+ const refreshTokenMutation = _reactquery.useMutation.call(void 0, {
119
+ mutationFn: () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
189
120
  throw new Error("Method not implemented.");
190
121
  }),
191
122
  onSuccess: () => {
192
- queryClient2.invalidateQueries({ queryKey: ["session"] });
123
+ queryClient3.invalidateQueries({ queryKey: ["session"] });
193
124
  }
194
125
  });
195
- const decodeTokens = (0, import_react4.useMemo)(() => {
126
+ const decodeTokens = _react.useMemo.call(void 0, () => {
196
127
  if (!(session == null ? void 0 : session.idToken)) return null;
197
- const parsedJWT = (0, import_jwt2.parseJWT)(session.idToken);
128
+ const parsedJWT = _jwt.parseJWT.call(void 0, session.idToken);
198
129
  if (!parsedJWT) return null;
199
130
  const { forwardedTokens } = parsedJWT.payload;
200
- return forwardedTokens;
131
+ return forwardedTokens ? convertForwardedTokenFormat(forwardedTokens) : null;
201
132
  }, [session == null ? void 0 : session.idToken]);
202
- const value = (0, import_react4.useMemo)(
133
+ const value = _react.useMemo.call(void 0,
203
134
  () => ({
204
135
  accessToken: session.accessToken || null,
205
136
  idToken: session.idToken || null,
@@ -218,375 +149,96 @@ var TokenProvider = ({ children }) => {
218
149
  authError
219
150
  ]
220
151
  );
221
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TokenContext.Provider, { value, children });
152
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TokenContext.Provider, { value, children });
222
153
  };
223
154
 
224
- // src/react/providers/AuthProvider.tsx
225
- var import_react9 = require("react");
226
- var import_react_query3 = require("@tanstack/react-query");
227
-
228
- // src/services/UserInfoService.ts
229
- var UserInfoServiceImpl = class {
230
- constructor(endpoints) {
231
- this.endpoints = endpoints;
232
- }
233
- getUserInfo(accessToken) {
234
- return __async(this, null, function* () {
235
- return {
236
- id: "user123",
237
- name: "John Doe",
238
- email: "john@example.com",
239
- picture: "https://example.com/john.jpg",
240
- given_name: "John",
241
- family_name: "Doe",
242
- created_at: /* @__PURE__ */ new Date(),
243
- updated_at: /* @__PURE__ */ new Date(),
244
- country: "US",
245
- accessToken
246
- };
247
- });
155
+ // src/react/hooks/useToken.tsx
156
+ var useToken = () => {
157
+ const context = _react.useContext.call(void 0, TokenContext);
158
+ if (!context) {
159
+ throw new Error("useToken must be used within a TokenProvider");
248
160
  }
161
+ return context;
249
162
  };
250
163
 
251
- // src/services/SessionService.ts
252
- var import_oauth2 = require("oslo/oauth2");
253
- var jose = __toESM(require("jose"));
164
+ // src/react/providers/UserProvider.tsx
254
165
 
255
- // src/lib/oauth.ts
256
- var import_uuid = require("uuid");
257
- var getIssuerVariations = (issuer) => {
258
- const issuerWithoutSlash = issuer.endsWith("/") ? issuer.slice(0, issuer.length - 1) : issuer;
259
- const issuerWithSlash = `${issuerWithoutSlash}/`;
260
- return [issuerWithoutSlash, issuerWithSlash];
261
- };
262
- var addSlashIfNeeded = (url) => url.endsWith("/") ? url : `${url}/`;
263
- var getOauthEndpoints = (oauthServer) => __async(void 0, null, function* () {
264
- const openIdConfigResponse = yield fetch(
265
- `${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`
266
- );
267
- const openIdConfig = yield openIdConfigResponse.json();
268
- return {
269
- jwks: openIdConfig.jwks_uri,
270
- auth: openIdConfig.authorization_endpoint,
271
- token: openIdConfig.token_endpoint,
272
- userinfo: openIdConfig.userinfo_endpoint
273
- };
274
- });
275
- var generateState = (displayMode) => {
276
- const jsonString = JSON.stringify({
277
- uuid: (0, import_uuid.v4)(),
278
- displayMode
166
+ var UserContext = _react.createContext.call(void 0, 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 = () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
176
+ if (!accessToken) {
177
+ return null;
178
+ }
179
+ const userSession = new (0, _chunkYNLXRD5Ljs.GenericUserSession)(storage);
180
+ return userSession.get();
279
181
  });
280
- return Buffer.from(jsonString).toString("base64");
281
- };
282
- var displayModeFromState = (state, sessionDisplayMode) => {
283
- try {
284
- const jsonString = Buffer.from(state, "base64").toString();
285
- return JSON.parse(jsonString).displayMode;
286
- } catch (_e) {
287
- return sessionDisplayMode;
288
- }
289
- };
290
-
291
- // src/utils.ts
292
- var import_clsx = require("clsx");
293
- var import_tailwind_merge = require("tailwind-merge");
294
- var isPopupBlocked = () => {
295
- const popup = window.open("", "", "width=1,height=1");
296
- if (!popup) {
297
- return true;
298
- }
299
- try {
300
- if (typeof popup.closed === "undefined") {
301
- throw new Error("Popup is blocked");
182
+ const {
183
+ data: user,
184
+ isLoading: userLoading,
185
+ error: userError
186
+ } = _reactquery.useQuery.call(void 0, {
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__ */ _jsxruntime.jsx.call(void 0,
195
+ UserContext.Provider,
196
+ {
197
+ value: {
198
+ user: user != null ? user : null,
199
+ isLoading,
200
+ error,
201
+ signIn,
202
+ signOut
203
+ },
204
+ children
302
205
  }
303
- } catch (e) {
304
- return true;
305
- }
306
- popup.close();
307
- return false;
308
- };
309
- var cn = (...inputs) => {
310
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
206
+ );
311
207
  };
312
208
 
313
- // src/services/SessionService.ts
314
- var AuthSessionServiceImpl = class {
315
- constructor(clientId, redirectUrl, oauthServer, inputEndpoints) {
316
- this.clientId = clientId;
317
- this.redirectUrl = redirectUrl;
318
- this.oauthServer = oauthServer;
319
- this.codeVerifier = void 0;
320
- this.state = void 0;
321
- this.codeVerifier = (0, import_oauth2.generateCodeVerifier)();
322
- this._endpoints = inputEndpoints;
323
- }
324
- getUserInfoService() {
325
- return __async(this, null, function* () {
326
- if (this._userInfoService) {
327
- return this._userInfoService;
328
- }
329
- const endpoints = yield this.getEndpoints();
330
- this._userInfoService = new UserInfoServiceImpl(endpoints);
331
- return this._userInfoService;
332
- });
333
- }
334
- getEndpoints() {
335
- return __async(this, null, function* () {
336
- if (this._endpoints) {
337
- return this._endpoints;
338
- }
339
- this._endpoints = yield getOauthEndpoints(this.oauthServer);
340
- return this._endpoints;
341
- });
342
- }
343
- getOauth2Client() {
344
- return __async(this, null, function* () {
345
- if (this._oauth2Client) {
346
- return this._oauth2Client;
347
- }
348
- const endpoints = yield this.getEndpoints();
349
- this._oauth2Client = new import_oauth2.OAuth2Client(
350
- this.clientId,
351
- endpoints.auth,
352
- endpoints.token,
353
- // this
354
- { redirectURI: this.redirectUrl }
355
- );
356
- return this._oauth2Client;
357
- });
358
- }
359
- getSessionData() {
360
- return JSON.parse(
361
- localStorage.getItem(`civic-auth:${this.clientId}`) || "{}"
362
- );
363
- }
364
- updateSessionData(data) {
365
- localStorage.setItem(
366
- `civic-auth:${this.clientId}`,
367
- JSON.stringify(__spreadValues({}, data))
368
- );
369
- }
370
- getAuthorizationUrl(scopes, displayMode, nonce) {
371
- return __async(this, null, function* () {
372
- const state = generateState(displayMode);
373
- this.state = state;
374
- const existingSessionData = this.getSessionData();
375
- this.updateSessionData(__spreadProps(__spreadValues({}, existingSessionData), {
376
- codeVerifier: this.codeVerifier,
377
- displayMode
378
- }));
379
- const oauth2Client = yield this.getOauth2Client();
380
- const oAuthUrl = yield oauth2Client.createAuthorizationURL({
381
- state,
382
- codeVerifier: this.codeVerifier,
383
- codeChallengeMethod: "S256",
384
- scopes
385
- });
386
- if (nonce) {
387
- oAuthUrl.searchParams.append("nonce", nonce);
388
- }
389
- return oAuthUrl.toString();
390
- });
391
- }
392
- // TODO fix the Window reference
393
- loadAuthorizationUrl(authorizationURL, displayMode) {
394
- switch (displayMode) {
395
- case "iframe":
396
- break;
397
- case "redirect":
398
- window.location.href = authorizationURL;
399
- break;
400
- case "new_tab":
401
- window.open(authorizationURL, "_blank");
402
- break;
403
- case "custom_tab":
404
- break;
405
- }
406
- }
407
- init() {
408
- return __async(this, null, function* () {
409
- this.updateSessionData({ authenticated: false });
410
- });
411
- }
412
- determineDisplayMode(displayMode) {
413
- if (isPopupBlocked() && displayMode === "iframe") {
414
- displayMode = "redirect";
415
- }
416
- return displayMode;
417
- }
418
- signIn(displayMode, scopes, nonce) {
419
- return __async(this, null, function* () {
420
- const authorizationURL = yield this.getAuthorizationUrl(
421
- scopes,
422
- displayMode,
423
- nonce
424
- );
425
- this.loadAuthorizationUrl(authorizationURL, displayMode);
426
- });
427
- }
428
- tokenExchange(responseUrl) {
429
- return __async(this, null, function* () {
430
- let session = this.getSessionData();
431
- if (!session.authenticated) {
432
- const url = new URL(responseUrl);
433
- const authorizationCode = url.searchParams.get("code");
434
- const returnedState = url.searchParams.get("state");
435
- if (!authorizationCode || !returnedState) {
436
- throw new Error("Invalid authorization response");
437
- }
438
- const codeVerifier = this.getSessionData().codeVerifier;
439
- const oauth2Client = yield this.getOauth2Client();
440
- const tokens = yield oauth2Client.validateAuthorizationCode(
441
- authorizationCode,
442
- {
443
- codeVerifier
444
- }
445
- );
446
- try {
447
- yield this.validateTokens(tokens);
448
- } catch (error) {
449
- console.error("tokenExchange tokens", { error, tokens });
450
- throw new Error(
451
- `OIDC tokens validation failed: ${error.message}`
452
- );
453
- }
454
- const parsedDisplayMode = displayModeFromState(
455
- returnedState,
456
- session.displayMode
457
- );
458
- session = __spreadProps(__spreadValues({}, session), {
459
- displayMode: parsedDisplayMode,
460
- idToken: tokens.id_token,
461
- authenticated: true,
462
- state: returnedState,
463
- accessToken: tokens.access_token,
464
- refreshToken: tokens.refresh_token,
465
- expiresIn: tokens.expires_in
466
- });
467
- this.updateSessionData(session);
468
- }
469
- if (session.displayMode === "new_tab") {
470
- window.close();
471
- } else if (session.displayMode === "redirect") {
472
- }
473
- return session;
474
- });
475
- }
476
- refreshToken() {
477
- return __async(this, null, function* () {
478
- const sessionData = this.getSessionData();
479
- if (!sessionData.refreshToken) {
480
- throw new Error("No refresh token available");
481
- }
482
- const oauth2Client = yield this.getOauth2Client();
483
- const tokens = yield oauth2Client.refreshAccessToken(
484
- sessionData.refreshToken
485
- );
486
- const session = __spreadProps(__spreadValues({}, sessionData), {
487
- idToken: tokens.id_token,
488
- authenticated: true,
489
- accessToken: tokens.access_token,
490
- refreshToken: tokens.refresh_token,
491
- expiresIn: tokens.expires_in
492
- });
493
- this.updateSessionData(session);
494
- return session;
495
- });
496
- }
497
- getUserInfo() {
498
- return __async(this, null, function* () {
499
- const sessionData = this.getSessionData();
500
- if (!sessionData.accessToken) {
501
- throw new Error("No access token available");
502
- }
503
- const userInfoService = yield this.getUserInfoService();
504
- return userInfoService.getUserInfo(sessionData.accessToken);
505
- });
506
- }
507
- /**
508
- * Uses the jose library to validate a JWT token using the OAuth JWKS endpoint
509
- * @param {string} token
510
- * @returns {Promise<jose.JWTPayload>}
511
- * @throws {Error} if the token is invalid
512
- */
513
- validateTokens(tokens) {
514
- return __async(this, null, function* () {
515
- const endpoints = yield this.getEndpoints();
516
- const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));
517
- const returnPayload = {};
518
- console.log("issuer", getIssuerVariations(this.oauthServer));
519
- const idTokenResponse = yield jose.jwtVerify(tokens.id_token, JWKS, {
520
- issuer: getIssuerVariations(this.oauthServer),
521
- audience: this.clientId
522
- });
523
- returnPayload.idToken = idTokenResponse.payload;
524
- const accessTokenResponse = yield jose.jwtVerify(
525
- tokens.access_token,
526
- JWKS,
527
- {
528
- issuer: getIssuerVariations(this.oauthServer)
529
- }
530
- );
531
- returnPayload.accessToken = accessTokenResponse.payload;
532
- if (tokens.refresh_token) {
533
- const refreshResponse = yield jose.jwtVerify(tokens.refresh_token, JWKS, {
534
- issuer: getIssuerVariations(this.oauthServer)
535
- });
536
- returnPayload.refreshToken = refreshResponse.payload;
537
- }
538
- return returnPayload;
539
- });
540
- }
541
- validateExistingSession() {
542
- return __async(this, null, function* () {
543
- const sessionData = this.getSessionData();
544
- try {
545
- if (!sessionData.idToken || !sessionData.accessToken) {
546
- const unAuthenticatedSession = __spreadProps(__spreadValues({}, sessionData), { authenticated: false });
547
- this.updateSessionData(unAuthenticatedSession);
548
- return unAuthenticatedSession;
549
- }
550
- yield this.validateTokens({
551
- id_token: sessionData.idToken,
552
- access_token: sessionData.accessToken,
553
- refresh_token: sessionData.refreshToken
554
- });
555
- sessionData.authenticated = true;
556
- return sessionData;
557
- } catch (error) {
558
- console.warn("Failed to validate existing tokens", error);
559
- const unAuthenticatedSession = __spreadProps(__spreadValues({}, sessionData), { authenticated: false });
560
- this.updateSessionData(unAuthenticatedSession);
561
- return unAuthenticatedSession;
562
- }
563
- });
564
- }
565
- };
209
+ // src/shared/AuthProvider.tsx
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+ // src/react/components/CivicAuthIframeContainer.tsx
566
220
 
567
- // src/react/components/CivicAuthIframe.tsx
568
- var import_react5 = require("react");
569
221
 
570
222
  // src/react/components/LoadingIcon.tsx
571
- var import_jsx_runtime3 = require("react/jsx-runtime");
572
- var LoadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "status", children: [
573
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
223
+
224
+ var LoadingIcon = () => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { role: "status", children: [
225
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
574
226
  "svg",
575
227
  {
576
228
  "aria-hidden": "true",
577
- 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",
578
230
  viewBox: "0 0 100 101",
579
231
  fill: "none",
580
232
  xmlns: "http://www.w3.org/2000/svg",
581
233
  children: [
582
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
234
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
583
235
  "path",
584
236
  {
585
237
  d: "M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z",
586
238
  fill: "currentColor"
587
239
  }
588
240
  ),
589
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
241
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
590
242
  "path",
591
243
  {
592
244
  d: "M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z",
@@ -596,12 +248,12 @@ var LoadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { r
596
248
  ]
597
249
  }
598
250
  ),
599
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "sr-only", children: "Loading..." })
251
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "cac-sr-only", children: "Loading..." })
600
252
  ] });
601
253
 
602
- // src/react/components/CivicAuthIframe.tsx
603
- var import_jsx_runtime4 = require("react/jsx-runtime");
604
- var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
254
+ // src/react/components/CloseIcon.tsx
255
+
256
+ var CloseIcon = () => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
605
257
  "svg",
606
258
  {
607
259
  xmlns: "http://www.w3.org/2000/svg",
@@ -615,26 +267,90 @@ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
615
267
  strokeLinejoin: "round",
616
268
  className: "lucide lucide-x",
617
269
  children: [
618
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 6 6 18" }),
619
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m6 6 12 12" })
270
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M18 6 6 18" }),
271
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "m6 6 12 12" })
620
272
  ]
621
273
  }
622
274
  );
623
- var IFRAME_ID = "civic-auth-iframe";
624
- var CivicAuthIframe = ({
625
- authUrl,
626
- redirectUri,
627
- setAuthResponseUrl,
275
+
276
+ // src/react/components/CivicAuthIframe.tsx
277
+
278
+
279
+ var CivicAuthIframe = _react.forwardRef.call(void 0,
280
+ ({ onLoad }, ref) => {
281
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
282
+ "iframe",
283
+ {
284
+ id: _chunkYNLXRD5Ljs.IFRAME_ID,
285
+ ref,
286
+ className: "cac-h-96 cac-w-80 cac-border-none",
287
+ onLoad
288
+ }
289
+ );
290
+ }
291
+ );
292
+ CivicAuthIframe.displayName = "CivicAuthIframe";
293
+
294
+ // src/react/components/CivicAuthIframeContainer.tsx
295
+
296
+ function NoChrome({
297
+ children
298
+ }) {
299
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
300
+ }
301
+ function IframeChrome({
302
+ children,
628
303
  onClose
304
+ }) {
305
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
306
+ "div",
307
+ {
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",
309
+ onClick: onClose,
310
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
311
+ "div",
312
+ {
313
+ className: "cac-relative cac-rounded-3xl cac-bg-white cac-p-6 cac-shadow-lg",
314
+ onClick: (e) => e.stopPropagation(),
315
+ children: [
316
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
317
+ "button",
318
+ {
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",
320
+ onClick: onClose,
321
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
322
+ }
323
+ ),
324
+ children
325
+ ]
326
+ }
327
+ )
328
+ }
329
+ );
330
+ }
331
+ var CivicAuthIframeContainer = ({
332
+ onClose,
333
+ closeOnRedirect = true
629
334
  }) => {
630
- const iframeRef = (0, import_react5.useRef)(null);
631
- const [isLoading, setIsLoading] = (0, import_react5.useState)(true);
632
- const processIframeUrl = (0, import_react5.useCallback)(() => {
633
- if (iframeRef.current && iframeRef.current.contentWindow) {
335
+ var _a;
336
+ const [isLoading, setIsLoading] = _react.useState.call(void 0, true);
337
+ const { isLoading: isAuthLoading } = useAuth();
338
+ const config = useConfig();
339
+ const { serverTokenExchange } = config;
340
+ const { setAuthResponseUrl, iframeRef } = useSession();
341
+ const processIframeUrl = _react.useCallback.call(void 0, () => {
342
+ if (iframeRef && iframeRef.current && iframeRef.current.contentWindow) {
634
343
  try {
635
344
  const iframeUrl = iframeRef.current.contentWindow.location.href;
636
- if (iframeUrl.startsWith(redirectUri)) {
637
- setAuthResponseUrl(iframeUrl);
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();
638
354
  return true;
639
355
  }
640
356
  } catch (e) {
@@ -642,14 +358,24 @@ var CivicAuthIframe = ({
642
358
  }
643
359
  }
644
360
  return false;
645
- }, [redirectUri, setAuthResponseUrl]);
646
- const intervalId = (0, import_react5.useRef)();
647
- (0, import_react5.useEffect)(() => {
648
- const handleEscape = (event) => {
361
+ }, [
362
+ closeOnRedirect,
363
+ config.redirectUrl,
364
+ iframeRef,
365
+ onClose,
366
+ serverTokenExchange,
367
+ setAuthResponseUrl
368
+ ]);
369
+ const intervalId = _react.useRef.call(void 0, );
370
+ const handleEscape = _react.useCallback.call(void 0,
371
+ (event) => {
649
372
  if (event.key === "Escape") {
650
- onClose();
373
+ onClose == null ? void 0 : onClose();
651
374
  }
652
- };
375
+ },
376
+ [onClose]
377
+ );
378
+ _react.useEffect.call(void 0, () => {
653
379
  window.addEventListener("keydown", handleEscape);
654
380
  return () => window.removeEventListener("keydown", handleEscape);
655
381
  });
@@ -660,214 +386,51 @@ var CivicAuthIframe = ({
660
386
  clearInterval(intervalId.current);
661
387
  }
662
388
  };
663
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
664
- "div",
665
- {
666
- className: "absolute left-0 top-0 z-[9999] flex h-screen w-screen items-center justify-center bg-neutral-950 bg-opacity-50",
667
- onClick: onClose,
668
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
669
- "div",
670
- {
671
- className: "relative rounded-3xl bg-white p-6 shadow-lg",
672
- onClick: (e) => e.stopPropagation(),
673
- children: [
674
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
675
- "button",
676
- {
677
- className: "absolute right-4 top-4 flex cursor-pointer items-center justify-center border-none bg-transparent p-1 text-neutral-400",
678
- onClick: onClose,
679
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, {})
680
- }
681
- ),
682
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute inset-0 flex items-center justify-center rounded-3xl bg-neutral-100", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LoadingIcon, {}) }),
683
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
684
- "iframe",
685
- {
686
- id: IFRAME_ID,
687
- ref: iframeRef,
688
- src: authUrl,
689
- className: "h-48 w-80 border-none",
690
- onLoad: handleIframeLoad
691
- }
692
- )
693
- ]
694
- }
695
- )
696
- }
697
- );
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__ */ _jsxruntime.jsxs.call(void 0, WrapperComponent, { onClose, children: [
392
+ showLoadingIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "cac-absolute cac-inset-0 cac-flex cac-items-center cac-justify-center cac-rounded-3xl cac-bg-neutral-100", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LoadingIcon, {}) }),
393
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CivicAuthIframe, { ref: iframeRef, onLoad: handleIframeLoad })
394
+ ] });
698
395
  };
699
396
 
700
- // src/react/components/UserButton.tsx
701
- var import_react6 = require("react");
702
- var import_jsx_runtime5 = require("react/jsx-runtime");
703
- var ChevronDown = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
704
- "svg",
705
- {
706
- xmlns: "http://www.w3.org/2000/svg",
707
- width: "24",
708
- height: "24",
709
- viewBox: "0 0 24 24",
710
- fill: "none",
711
- stroke: "currentColor",
712
- strokeWidth: "2",
713
- strokeLinecap: "round",
714
- strokeLinejoin: "round",
715
- className: "lucide lucide-chevron-down",
716
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 9 6 6 6-6" })
717
- }
718
- );
719
- var ChevronUp = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
720
- "svg",
721
- {
722
- xmlns: "http://www.w3.org/2000/svg",
723
- width: "24",
724
- height: "24",
725
- viewBox: "0 0 24 24",
726
- fill: "none",
727
- stroke: "currentColor",
728
- strokeWidth: "2",
729
- strokeLinecap: "round",
730
- strokeLinejoin: "round",
731
- className: "lucide lucide-chevron-up",
732
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m18 15-6-6-6 6" })
733
- }
734
- );
735
- var UserButton = ({
736
- displayMode,
737
- className
738
- }) => {
739
- const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
740
- const { signIn, isAuthenticated, signOut } = useAuth();
741
- const { user } = useUser();
742
- (0, import_react6.useEffect)(() => {
743
- const handleEscape = (event) => {
744
- if (event.key === "Escape") {
745
- setIsOpen(false);
746
- }
747
- };
748
- if (isOpen) {
749
- window.addEventListener("keydown", handleEscape);
750
- }
751
- return () => {
752
- window.removeEventListener("keydown", handleEscape);
753
- };
754
- }, [isOpen]);
755
- (0, import_react6.useEffect)(() => {
756
- const handleClick = (event) => {
757
- const target = event.target;
758
- if (!target.closest("#civic-dropdown-container")) {
759
- setIsOpen(false);
760
- }
761
- };
762
- if (isOpen) {
763
- window.addEventListener("click", handleClick);
764
- }
765
- return () => {
766
- window.removeEventListener("click", handleClick);
767
- };
768
- }, [isOpen]);
769
- (0, import_react6.useEffect)(() => {
770
- if (!isAuthenticated) {
771
- setIsOpen(false);
772
- }
773
- }, [isAuthenticated]);
774
- if (isAuthenticated) {
775
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative", id: "civic-dropdown-container", children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
777
- "button",
778
- {
779
- className: cn(
780
- "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",
781
- className
782
- ),
783
- onClick: () => setIsOpen((isOpen2) => !isOpen2),
784
- children: [
785
- (user == null ? void 0 : user.picture) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "relative flex h-10 w-10 shrink-0 gap-2 overflow-hidden rounded-full", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
786
- "img",
787
- {
788
- className: "h-full w-full object-cover",
789
- src: user.picture,
790
- alt: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email)
791
- }
792
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", {}),
793
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email) }),
794
- isOpen ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronUp, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronDown, {})
795
- ]
796
- }
797
- ),
798
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
799
- "div",
800
- {
801
- className: isOpen ? "absolute right-0 mt-2 w-full rounded-lg bg-white py-2 text-neutral-500 shadow-xl" : "hidden",
802
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
803
- "button",
804
- {
805
- className: "block w-full px-4 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
806
- onClick: () => signOut(),
807
- children: "Logout"
808
- }
809
- ) }) })
810
- }
811
- )
812
- ] });
813
- }
814
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
815
- "button",
816
- {
817
- className: cn(
818
- "rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50",
819
- className
820
- ),
821
- onClick: () => signIn(displayMode),
822
- children: "Sign in"
823
- }
824
- );
825
- };
826
-
827
- // src/react/providers/ParamsProvider.tsx
828
- var import_react7 = require("react");
829
- var import_jsx_runtime6 = require("react/jsx-runtime");
830
- var ParamsContext = (0, import_react7.createContext)(null);
831
- var ParamsProvider = ({
832
- children,
833
- clientId,
834
- redirectUrl,
835
- config,
836
- nonce
837
- }) => {
838
- const value = {
839
- clientId,
840
- redirectUrl,
841
- config,
842
- nonce
843
- };
844
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ParamsContext.Provider, { value, children });
845
- };
846
-
847
- // src/react/providers/SessionProvider.tsx
848
- var import_react8 = require("react");
849
- var import_jsx_runtime7 = require("react/jsx-runtime");
850
- var defaultSession = {
851
- authenticated: false,
852
- idToken: void 0,
853
- accessToken: void 0,
854
- displayMode: "iframe"
855
- };
856
- var SessionContext = (0, import_react8.createContext)(defaultSession);
857
- var SessionProvider = ({ children, session }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SessionContext.Provider, { value: session || defaultSession, children });
858
-
859
- // src/constants.ts
860
- var DEFAULT_SCOPES = ["openid", "profile", "email", "forwardedTokens"];
861
-
862
397
  // src/config.ts
863
398
  var authConfig = {
864
399
  // TODO change this to the production URL once we're out of beta
865
400
  oauthServer: "https://auth-dev.civic.com/oauth/"
866
401
  };
867
402
 
868
- // src/react/providers/AuthProvider.tsx
869
- var import_jsx_runtime8 = require("react/jsx-runtime");
870
- var AuthContext = (0, import_react9.createContext)(null);
403
+ // src/react/providers/ConfigProvider.tsx
404
+
405
+
406
+ var defaultConfig = {
407
+ config: authConfig,
408
+ redirectUrl: "",
409
+ modalIframe: true,
410
+ serverTokenExchange: false
411
+ };
412
+ var ConfigContext = _react.createContext.call(void 0, defaultConfig);
413
+ var ConfigProvider = ({
414
+ children,
415
+ config,
416
+ redirectUrl,
417
+ modalIframe,
418
+ serverTokenExchange
419
+ }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
420
+ ConfigContext.Provider,
421
+ {
422
+ value: {
423
+ config,
424
+ redirectUrl,
425
+ modalIframe: !!modalIframe,
426
+ serverTokenExchange
427
+ },
428
+ children
429
+ }
430
+ );
431
+
432
+ // src/shared/AuthProvider.tsx
433
+
871
434
  var globalThisObject;
872
435
  if (typeof window !== "undefined") {
873
436
  globalThisObject = window;
@@ -877,78 +440,93 @@ if (typeof window !== "undefined") {
877
440
  globalThisObject = Function("return this")();
878
441
  }
879
442
  globalThisObject.globalThis = globalThisObject;
443
+ function BlockDisplay({ children }) {
444
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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__ */ _jsxruntime.jsx.call(void 0, "div", { className: "cac-absolute cac-inset-0 cac-flex cac-items-center cac-justify-center cac-bg-white", children }) });
445
+ }
880
446
  var AuthProvider = ({
881
447
  children,
882
448
  clientId,
883
449
  redirectUrl: inputRedirectUrl,
884
450
  config = authConfig,
885
- nonce,
886
451
  onSignIn,
887
- onSignOut
452
+ onSignOut,
453
+ pkceConsumer,
454
+ nonce,
455
+ modalIframe = true
888
456
  }) => {
889
- const [iframeUrl, setIframeUrl] = (0, import_react9.useState)(null);
890
- const [currentUrl, setCurrentUrl] = (0, import_react9.useState)(null);
891
- const [isInIframe, setIsInIframe] = (0, import_react9.useState)(false);
892
- const [authResponseUrl, setAuthResponseUrl] = (0, import_react9.useState)(null);
893
- const [tokenExchangeInProgress, setTokenExchangeInProgress] = (0, import_react9.useState)(false);
894
- const [tokenExchangeError, setTokenExchangeError] = (0, import_react9.useState)();
895
- const queryClient2 = (0, import_react_query3.useQueryClient)();
896
- (0, import_react9.useEffect)(() => {
897
- var _a, _b;
457
+ const [iframeUrl, setIframeUrl] = _react.useState.call(void 0, null);
458
+ const [currentUrl, setCurrentUrl] = _react.useState.call(void 0, null);
459
+ const [isInIframe, setIsInIframe] = _react.useState.call(void 0, false);
460
+ const [authResponseUrl, setAuthResponseUrl] = _react.useState.call(void 0, null);
461
+ const [tokenExchangeError, setTokenExchangeError] = _react.useState.call(void 0, );
462
+ const [displayMode, setDisplayMode] = _react.useState.call(void 0, "iframe");
463
+ const [browserAuthenticationInitiator, setBrowserAuthenticationInitiator] = _react.useState.call(void 0, );
464
+ const [showIFrame, setShowIFrame] = _react.useState.call(void 0, false);
465
+ const [isRedirecting, setIsRedirecting] = _react.useState.call(void 0, false);
466
+ const queryClient3 = _reactquery.useQueryClient.call(void 0, );
467
+ const iframeRef = _react.useRef.call(void 0, null);
468
+ const serverTokenExchange = pkceConsumer instanceof _chunkYNLXRD5Ljs.ConfidentialClientPKCEConsumer;
469
+ _react.useEffect.call(void 0, () => {
898
470
  if (typeof globalThis.window !== "undefined") {
899
471
  setCurrentUrl(globalThis.window.location.href);
900
- let isInIframeVal = false;
901
- try {
902
- if (((_b = (_a = globalThis.window) == null ? void 0 : _a.frameElement) == null ? void 0 : _b.id) === "civic-auth-iframe") {
903
- isInIframeVal = true;
904
- }
905
- } catch (_e) {
906
- isInIframeVal = false;
907
- }
908
- console.log("isInIframeVal", isInIframeVal);
472
+ const isInIframeVal = _chunkYNLXRD5Ljs.isWindowInIframe.call(void 0, globalThis.window);
909
473
  setIsInIframe(isInIframeVal);
910
474
  }
911
475
  }, []);
912
- const redirectUrl = (0, import_react9.useMemo)(
476
+ const redirectUrl = _react.useMemo.call(void 0,
913
477
  () => (inputRedirectUrl || currentUrl || "").split("?")[0],
914
478
  [currentUrl, inputRedirectUrl]
915
479
  );
916
- const authService = (0, import_react9.useMemo)(
917
- () => currentUrl ? new AuthSessionServiceImpl(
480
+ const [authService, setAuthService] = _react.useState.call(void 0, );
481
+ _react.useEffect.call(void 0, () => {
482
+ if (!currentUrl) return;
483
+ _chunkYNLXRD5Ljs.BrowserAuthenticationService.build({
918
484
  clientId,
919
485
  redirectUrl,
920
- config == null ? void 0 : config.oauthServer,
921
- config == null ? void 0 : config.endpoints
922
- ) : null,
923
- [currentUrl, clientId, redirectUrl, config]
924
- );
486
+ oauthServer: config.oauthServer,
487
+ scopes: _chunkYNLXRD5Ljs.DEFAULT_SCOPES,
488
+ displayMode
489
+ }).then(setAuthService);
490
+ }, [currentUrl, clientId, redirectUrl, config, displayMode]);
925
491
  const {
926
492
  data: session,
927
493
  isLoading,
928
494
  error
929
- } = (0, import_react_query3.useQuery)({
930
- queryKey: ["session"],
931
- queryFn: () => __async(void 0, null, function* () {
932
- const url = new URL(globalThis.window.location.href || "");
933
- console.log("AuthProvider useQuery", { isInIframe, url, authService });
495
+ } = _reactquery.useQuery.call(void 0, {
496
+ queryKey: [
497
+ "session",
498
+ authResponseUrl,
499
+ iframeUrl,
500
+ currentUrl,
501
+ isInIframe,
502
+ authService
503
+ ],
504
+ queryFn: () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
934
505
  if (!authService) {
935
506
  return { authenticated: false };
936
507
  }
937
- const existingSessionData = yield authService.validateExistingSession();
938
- if (existingSessionData.authenticated) {
939
- return existingSessionData;
940
- }
508
+ const url = new URL(
509
+ authResponseUrl ? authResponseUrl : globalThis.window.location.href || ""
510
+ );
941
511
  const code = url.searchParams.get("code");
942
- if (code && !isInIframe) {
512
+ const state = url.searchParams.get("state");
513
+ if (!serverTokenExchange && code && state && !isInIframe) {
943
514
  try {
944
- console.log("AuthProvider useQuery code", { isInIframe, code });
945
- setTokenExchangeInProgress(true);
946
- const newSession = yield authService.tokenExchange(
947
- globalThis.window.location.href
948
- );
949
- setTokenExchangeInProgress(false);
515
+ console.log("AuthProvider useQuery code", {
516
+ isInIframe,
517
+ code,
518
+ state
519
+ });
520
+ yield authService.tokenExchange(code, state);
521
+ const clientStorage = new (0, _chunkYNLXRD5Ljs.LocalStorageAdapter)();
522
+ const user = yield _chunkYNLXRD5Ljs.getUser.call(void 0, clientStorage);
523
+ if (!user) {
524
+ throw new Error("Failed to get user info");
525
+ }
526
+ const userSession = new (0, _chunkYNLXRD5Ljs.GenericUserSession)(clientStorage);
527
+ userSession.set(user);
950
528
  onSignIn == null ? void 0 : onSignIn();
951
- return newSession;
529
+ return authService.getSessionData();
952
530
  } catch (error2) {
953
531
  setTokenExchangeError(error2);
954
532
  onSignIn == null ? void 0 : onSignIn(
@@ -957,174 +535,460 @@ var AuthProvider = ({
957
535
  return { authenticated: false };
958
536
  }
959
537
  }
538
+ const existingSessionData = yield authService.validateExistingSession();
539
+ if (existingSessionData.authenticated) {
540
+ return existingSessionData;
541
+ }
960
542
  return existingSessionData;
961
- }),
962
- enabled: !!authService && !!currentUrl && !isInIframe
543
+ })
963
544
  });
964
- const signOutMutation = (0, import_react_query3.useMutation)({
965
- mutationFn: () => __async(void 0, null, function* () {
966
- authService == null ? void 0 : authService.updateSessionData({});
545
+ const signOutMutation = _reactquery.useMutation.call(void 0, {
546
+ mutationFn: () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
547
+ const authInitiator = getAuthInitiator();
548
+ authInitiator == null ? void 0 : authInitiator.signOut();
549
+ setIframeUrl(null);
550
+ setShowIFrame(false);
967
551
  setAuthResponseUrl(null);
968
552
  onSignOut == null ? void 0 : onSignOut();
969
553
  }),
970
554
  onSuccess: () => {
971
- queryClient2.setQueryData(["session"], null);
555
+ queryClient3.setQueryData(
556
+ [
557
+ "session",
558
+ authResponseUrl,
559
+ iframeUrl,
560
+ currentUrl,
561
+ isInIframe,
562
+ authService
563
+ ],
564
+ null
565
+ );
972
566
  }
973
567
  });
974
- const signIn = (0, import_react9.useCallback)(
975
- (overrideDisplayMode = "iframe") => __async(void 0, null, function* () {
976
- if (!authService) return;
977
- const url = yield authService.getAuthorizationUrl(
978
- // This is the default scope. We will eventually pull this from the partner dashboard
979
- DEFAULT_SCOPES,
980
- overrideDisplayMode,
568
+ const getAuthInitiator = _react.useCallback.call(void 0,
569
+ (overrideDisplayMode) => {
570
+ const useDisplayMode = overrideDisplayMode || displayMode;
571
+ if (!pkceConsumer) {
572
+ return null;
573
+ }
574
+ return browserAuthenticationInitiator || new (0, _chunkYNLXRD5Ljs.BrowserAuthenticationInitiator)({
575
+ pkceConsumer,
576
+ // generate and retrieve the challenge client-side
577
+ clientId,
578
+ redirectUrl,
579
+ state: _chunkYNLXRD5Ljs.generateState.call(void 0, useDisplayMode),
580
+ scopes: _chunkYNLXRD5Ljs.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,
981
585
  nonce
982
- );
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 = _react.useCallback.call(void 0,
600
+ (overrideDisplayMode = "iframe") => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
601
+ setDisplayMode(overrideDisplayMode);
602
+ const authInitiator = getAuthInitiator(overrideDisplayMode);
603
+ setBrowserAuthenticationInitiator(authInitiator);
983
604
  if (overrideDisplayMode === "iframe") {
984
- setIframeUrl(url);
985
- return;
605
+ setShowIFrame(true);
606
+ } else if (overrideDisplayMode === "redirect") {
607
+ setIsRedirecting(true);
986
608
  }
987
- authService.loadAuthorizationUrl(url, overrideDisplayMode);
609
+ authInitiator == null ? void 0 : authInitiator.signIn(iframeRef.current);
988
610
  }),
989
- [authService, nonce]
611
+ [getAuthInitiator]
990
612
  );
991
- const isAuthenticated = (0, import_react9.useMemo)(
613
+ const isAuthenticated = _react.useMemo.call(void 0,
992
614
  () => session ? session.authenticated : false,
993
615
  [session]
994
616
  );
995
- (0, import_react9.useEffect)(() => {
996
- if (!authService || !authResponseUrl) return;
997
- const url = new URL(authResponseUrl);
998
- const code = url.searchParams.get("code");
999
- console.log("AuthProvider useEffect code", {
1000
- isAuthenticated,
1001
- code,
1002
- tokenExchangeInProgress,
1003
- isInIframe
1004
- });
1005
- if (code && !isAuthenticated && !tokenExchangeInProgress && !isInIframe) {
1006
- try {
1007
- setTokenExchangeInProgress(true);
1008
- authService.tokenExchange(authResponseUrl).then((newSession) => {
1009
- queryClient2.setQueryData(["session"], newSession);
1010
- setIframeUrl(null);
1011
- onSignIn == null ? void 0 : onSignIn();
1012
- }).catch((error2) => {
1013
- setTokenExchangeError(error2);
1014
- }).finally(() => {
1015
- setTokenExchangeInProgress(false);
1016
- });
1017
- } catch (error2) {
1018
- setTokenExchangeInProgress(false);
1019
- onSignIn == null ? void 0 : onSignIn(
1020
- error2 instanceof Error ? error2 : new Error("Failed to sign in")
1021
- );
617
+ const {
618
+ data: autoSignIn,
619
+ isLoading: autoSignInLoading,
620
+ error: autoSignInError
621
+ } = _reactquery.useQuery.call(void 0, {
622
+ queryKey: ["autoSignIn", modalIframe, redirectUrl, isAuthenticated],
623
+ queryFn: () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
624
+ if (!modalIframe && redirectUrl && !isAuthenticated && iframeRef.current) {
625
+ signIn("iframe");
1022
626
  }
1023
- }
1024
- }, [
1025
- authService,
1026
- onSignIn,
1027
- queryClient2,
1028
- isAuthenticated,
1029
- authResponseUrl,
1030
- tokenExchangeInProgress,
1031
- isInIframe
1032
- ]);
1033
- const value = (0, import_react9.useMemo)(
627
+ return true;
628
+ }),
629
+ refetchOnWindowFocus: false
630
+ });
631
+ const value = _react.useMemo.call(void 0,
1034
632
  () => ({
1035
633
  isLoading,
1036
634
  error,
1037
- signOut: signOutMutation.mutate,
635
+ signOut: () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
636
+ yield signOutMutation.mutateAsync();
637
+ }),
1038
638
  isAuthenticated,
1039
639
  signIn
1040
640
  }),
1041
- [isLoading, error, signOutMutation.mutate, isAuthenticated, signIn]
641
+ [isLoading, error, signOutMutation, isAuthenticated, signIn]
1042
642
  );
1043
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1044
- AuthContext.Provider,
643
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AuthContext.Provider, { value, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
644
+ ConfigProvider,
1045
645
  {
1046
- value: __spreadProps(__spreadValues({}, value), {
1047
- signOut: () => __async(void 0, null, function* () {
1048
- yield signOutMutation.mutateAsync();
1049
- })
1050
- }),
1051
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1052
- ParamsProvider,
646
+ config,
647
+ redirectUrl,
648
+ modalIframe,
649
+ serverTokenExchange,
650
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
651
+ SessionProvider,
1053
652
  {
1054
- clientId,
1055
- redirectUrl,
1056
- config,
1057
- nonce,
1058
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SessionProvider, { session, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TokenProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(UserProvider, { children: [
1059
- !isInIframe && iframeUrl && !(session == null ? void 0 : session.authenticated) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1060
- CivicAuthIframe,
653
+ session,
654
+ setAuthResponseUrl,
655
+ iframeRef,
656
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TokenProvider, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, UserProvider, { storage: new (0, _chunkYNLXRD5Ljs.LocalStorageAdapter)(), children: [
657
+ modalIframe && !isInIframe && !(session == null ? void 0 : session.authenticated) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
658
+ "div",
1061
659
  {
1062
- authUrl: iframeUrl,
1063
- redirectUri: redirectUrl,
1064
- setAuthResponseUrl,
1065
- onClose: () => setIframeUrl(null)
660
+ style: showIFrame ? { display: "block" } : { display: "none" },
661
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
662
+ CivicAuthIframeContainer,
663
+ {
664
+ onClose: () => setShowIFrame(false)
665
+ }
666
+ )
1066
667
  }
1067
668
  ),
1068
- (tokenExchangeInProgress || tokenExchangeError || isLoading || isInIframe) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "absolute left-0 top-0 z-[9999] flex h-screen w-screen items-center justify-center bg-white", children: [
1069
- " ",
1070
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-white", children: tokenExchangeError ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1071
- "Error: ",
1072
- tokenExchangeError.message
1073
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LoadingIcon, {}) })
1074
- ] }),
669
+ modalIframe && (isInIframe || isRedirecting || isLoading) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BlockDisplay, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LoadingIcon, {}) }),
670
+ (tokenExchangeError || error) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BlockDisplay, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
671
+ "Error: ",
672
+ (tokenExchangeError || error).message
673
+ ] }) }),
1075
674
  children
1076
- ] }) }) })
675
+ ] }) })
1077
676
  }
1078
677
  )
1079
678
  }
1080
- );
679
+ ) });
1081
680
  };
1082
681
 
1083
- // src/react/providers/CivicProvider.tsx
1084
- var import_react_query4 = require("@tanstack/react-query");
1085
- var import_jsx_runtime9 = require("react/jsx-runtime");
1086
- var queryClient = new import_react_query4.QueryClient();
1087
- var CivicProvider = (_a) => {
1088
- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
1089
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_query4.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AuthProvider, __spreadProps(__spreadValues({}, props), { children })) });
682
+ // src/shared/CivicAuthProvider.tsx
683
+
684
+ require('@civic/auth/styles.css');
685
+
686
+ var queryClient = new (0, _reactquery.QueryClient)();
687
+ var CivicAuthProvider = (_a) => {
688
+ var _b = _a, { children } = _b, props = _chunkCRTRMMJ7js.__objRest.call(void 0, _b, ["children"]);
689
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactquery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
690
+ AuthProvider,
691
+ _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, props), {
692
+ pkceConsumer: new (0, _chunkYNLXRD5Ljs.BrowserPublicClientPKCEProducer)(),
693
+ children
694
+ })
695
+ ) });
1090
696
  };
1091
697
 
698
+ // src/react/providers/NextAuthProvider.tsx
699
+
700
+
701
+ // src/react/hooks/useUserCookie.ts
702
+
703
+ var _navigationjs = require('next/navigation.js');
704
+
705
+
706
+ // src/lib/cookies.ts
707
+ var getCookieValue = (key, window2) => {
708
+ const cookie = window2.document.cookie;
709
+ if (!cookie) return null;
710
+ const cookies = cookie.split(";");
711
+ for (const c of cookies) {
712
+ const [name, value] = c.trim().split("=");
713
+ if (value && name === key) {
714
+ try {
715
+ return JSON.parse(decodeURIComponent(value));
716
+ } catch (e) {
717
+ console.log("Error parsing cookie value", e);
718
+ return value;
719
+ }
720
+ }
721
+ }
722
+ return null;
723
+ };
724
+
725
+ // src/react/hooks/useUserCookie.ts
726
+ var getUserFromCookie = () => {
727
+ const userCookie = getCookieValue("user", globalThis.window);
728
+ return userCookie;
729
+ };
730
+ var useUserCookie = () => {
731
+ const hasRunRef = _react.useRef.call(void 0, false);
732
+ const router = _navigationjs.useRouter.call(void 0, );
733
+ const { data: user } = _reactquery.useQuery.call(void 0, {
734
+ queryKey: ["user"],
735
+ queryFn: () => getUserFromCookie(),
736
+ refetchInterval: 2e3,
737
+ refetchIntervalInBackground: true,
738
+ enabled: !hasRunRef.current,
739
+ refetchOnWindowFocus: true
740
+ });
741
+ _react.useEffect.call(void 0, () => {
742
+ if (user) {
743
+ if (!hasRunRef.current) {
744
+ hasRunRef.current = true;
745
+ router.refresh();
746
+ }
747
+ } else {
748
+ hasRunRef.current = false;
749
+ }
750
+ }, [user, router]);
751
+ return user;
752
+ };
753
+
754
+ // src/react/providers/NextAuthProvider.tsx
755
+
756
+
757
+
758
+ var queryClient2 = new (0, _reactquery.QueryClient)();
759
+ var defaultUserContext = { user: null };
760
+ var UserContext2 = _react.createContext.call(void 0, defaultUserContext);
761
+ var CivicNextAuthProvider = (_a) => {
762
+ var _b = _a, {
763
+ children
764
+ } = _b, props = _chunkCRTRMMJ7js.__objRest.call(void 0, _b, [
765
+ "children"
766
+ ]);
767
+ const user = useUserCookie();
768
+ const [redirectUrl, setRedirectUrl] = _react.useState.call(void 0, "");
769
+ const { clientId, oauthServer, callbackUrl, challengeUrl } = _chunkMVO4UZ2Ajs.resolveAuthConfig.call(void 0, );
770
+ _react.useEffect.call(void 0, () => {
771
+ if (typeof globalThis.window !== "undefined") {
772
+ const currentUrl = globalThis.window.location.href;
773
+ setRedirectUrl(_chunkMVO4UZ2Ajs.resolveCallbackUrl.call(void 0, _chunkMVO4UZ2Ajs.resolveAuthConfig.call(void 0, ), currentUrl));
774
+ }
775
+ }, [callbackUrl]);
776
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactquery.QueryClientProvider, { client: queryClient2, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
777
+ AuthProvider,
778
+ _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, props), {
779
+ redirectUrl,
780
+ config: { oauthServer },
781
+ clientId,
782
+ pkceConsumer: new (0, _chunkYNLXRD5Ljs.ConfidentialClientPKCEConsumer)(challengeUrl),
783
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UserContext2.Provider, { value: user, children })
784
+ })
785
+ ) });
786
+ };
787
+ var useNextUser = () => _react.useContext.call(void 0, UserContext2);
788
+
1092
789
  // src/react/hooks/useUser.tsx
1093
790
  var useUser = () => {
1094
- const context = (0, import_react10.useContext)(UserContext);
791
+ const context = _react.useContext.call(void 0, UserContext);
1095
792
  if (!context) {
1096
793
  throw new Error("useUser must be used within a UserProvider");
1097
794
  }
1098
795
  return context;
1099
796
  };
1100
797
 
1101
- // src/react/hooks/useParams.tsx
1102
- var import_react11 = require("react");
1103
- var useParams = () => {
1104
- const context = (0, import_react11.useContext)(ParamsContext);
798
+ // src/react/hooks/useConfig.tsx
799
+
800
+ var useConfig = () => {
801
+ const context = _react.useContext.call(void 0, ConfigContext);
1105
802
  if (!context) {
1106
- throw new Error("useParams must be used within an ParamsProvider");
803
+ throw new Error("useConfig must be used within an ConfigProvider");
1107
804
  }
1108
805
  return context;
1109
806
  };
1110
807
 
1111
- // src/react/hooks/useSession.tsx
1112
- var import_react12 = require("react");
1113
- var useSession = () => {
1114
- const context = (0, import_react12.useContext)(SessionContext);
1115
- if (!context) {
1116
- throw new Error("useSession must be used within an SessionProvider");
808
+ // src/react/components/UserButton.tsx
809
+
810
+
811
+ var ChevronDown = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
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__ */ _jsxruntime.jsx.call(void 0, "path", { d: "m6 9 6 6 6-6" })
1117
825
  }
1118
- return context;
826
+ );
827
+ var ChevronUp = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
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__ */ _jsxruntime.jsx.call(void 0, "path", { d: "m18 15-6-6-6 6" })
841
+ }
842
+ );
843
+ var UserButton = ({
844
+ displayMode,
845
+ className
846
+ }) => {
847
+ const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
848
+ const { signIn, isAuthenticated, signOut } = useAuth();
849
+ const { user } = useUser();
850
+ const handleClickOutside = _react.useCallback.call(void 0, (event) => {
851
+ const target = event.target;
852
+ if (!target.closest("#civic-dropdown-container")) {
853
+ setIsOpen(false);
854
+ }
855
+ }, []);
856
+ const handleSignOut = _react.useCallback.call(void 0, () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
857
+ yield signOut();
858
+ setIsOpen(false);
859
+ }), [signOut]);
860
+ const handleSignIn = _react.useCallback.call(void 0, () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
861
+ yield signIn(displayMode);
862
+ setIsOpen(false);
863
+ }), [signIn, displayMode]);
864
+ const handleEscape = _react.useCallback.call(void 0, (event) => {
865
+ if (event.key === "Escape") {
866
+ setIsOpen(false);
867
+ }
868
+ }, []);
869
+ _react.useEffect.call(void 0, () => {
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__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "cac-relative", id: "civic-dropdown-container", children: [
881
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
882
+ "button",
883
+ {
884
+ className: _chunkYNLXRD5Ljs.cn.call(void 0,
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__ */ _jsxruntime.jsx.call(void 0, "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__ */ _jsxruntime.jsx.call(void 0,
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__ */ _jsxruntime.jsx.call(void 0, "div", {}),
898
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: (user == null ? void 0 : user.name) || (user == null ? void 0 : user.email) }),
899
+ isOpen ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChevronUp, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChevronDown, {})
900
+ ]
901
+ }
902
+ ),
903
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
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__ */ _jsxruntime.jsx.call(void 0, "ul", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
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__ */ _jsxruntime.jsx.call(void 0,
920
+ "button",
921
+ {
922
+ "data-testid": "sign-in-button",
923
+ className: _chunkYNLXRD5Ljs.cn.call(void 0,
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
+ );
1119
931
  };
1120
- // Annotate the CommonJS export names for ESM import in node:
1121
- 0 && (module.exports = {
1122
- CivicProvider,
1123
- UserButton,
1124
- useAuth,
1125
- useParams,
1126
- useSession,
1127
- useToken,
1128
- useUser
1129
- });
932
+
933
+ // src/react/components/SignInButton.tsx
934
+
935
+ var SignInButton = ({
936
+ displayMode,
937
+ className
938
+ }) => {
939
+ const { signIn } = useAuth();
940
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
941
+ "button",
942
+ {
943
+ "data-testid": "sign-in-button",
944
+ className: _chunkYNLXRD5Ljs.cn.call(void 0,
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
+
956
+ var SignOutButton = ({ className }) => {
957
+ const { signOut } = useAuth();
958
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
959
+ "button",
960
+ {
961
+ className: _chunkYNLXRD5Ljs.cn.call(void 0,
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
+
973
+ var NextLogOut = ({ children }) => {
974
+ const config = _chunkMVO4UZ2Ajs.resolveAuthConfig.call(void 0, );
975
+ const logoutUrl = `${config.logoutUrl}`;
976
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "a", { href: logoutUrl, children });
977
+ };
978
+
979
+
980
+
981
+
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+ exports.CivicAuthIframeContainer = CivicAuthIframeContainer; exports.CivicAuthProvider = CivicAuthProvider; exports.CivicNextAuthProvider = CivicNextAuthProvider; exports.NextLogOut = NextLogOut; exports.SignInButton = SignInButton; exports.SignOutButton = SignOutButton; exports.UserButton = UserButton; exports.useAuth = useAuth; exports.useConfig = useConfig; exports.useNextUser = useNextUser; exports.useSession = useSession; exports.useToken = useToken; exports.useUser = useUser; exports.useUserCookie = useUserCookie;
1130
994
  //# sourceMappingURL=react.js.map