@civic/auth 0.0.1-beta.1 → 0.0.1-beta.11

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