@civic/auth 0.4.5 → 0.4.6

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 (73) hide show
  1. package/dist/nextjs/cookies.d.ts.map +1 -1
  2. package/dist/nextjs/cookies.js +2 -4
  3. package/dist/nextjs/cookies.js.map +1 -1
  4. package/dist/nextjs/hooks/useRefresh.d.ts +1 -2
  5. package/dist/nextjs/hooks/useRefresh.d.ts.map +1 -1
  6. package/dist/nextjs/hooks/useRefresh.js +3 -1
  7. package/dist/nextjs/hooks/useRefresh.js.map +1 -1
  8. package/dist/nextjs/index.js +1 -1
  9. package/dist/nextjs/index.js.map +1 -1
  10. package/dist/nextjs/middleware.d.ts +3 -2
  11. package/dist/nextjs/middleware.d.ts.map +1 -1
  12. package/dist/nextjs/middleware.js +16 -6
  13. package/dist/nextjs/middleware.js.map +1 -1
  14. package/dist/nextjs/providers/NextAuthProvider.js +1 -1
  15. package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
  16. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  17. package/dist/nextjs/routeHandler.js +29 -8
  18. package/dist/nextjs/routeHandler.js.map +1 -1
  19. package/dist/reactjs/providers/AuthProvider.d.ts +1 -1
  20. package/dist/reactjs/providers/AuthProvider.d.ts.map +1 -1
  21. package/dist/reactjs/providers/AuthProvider.js +4 -26
  22. package/dist/reactjs/providers/AuthProvider.js.map +1 -1
  23. package/dist/reactjs/providers/CivicAuthProvider.d.ts.map +1 -1
  24. package/dist/reactjs/providers/CivicAuthProvider.js +2 -2
  25. package/dist/reactjs/providers/CivicAuthProvider.js.map +1 -1
  26. package/dist/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts +1 -1
  27. package/dist/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -1
  28. package/dist/reactjs/providers/ClientTokenExchangeSessionProvider.js +50 -14
  29. package/dist/reactjs/providers/ClientTokenExchangeSessionProvider.js.map +1 -1
  30. package/dist/server/ServerAuthenticationResolver.d.ts +7 -1
  31. package/dist/server/ServerAuthenticationResolver.d.ts.map +1 -1
  32. package/dist/server/ServerAuthenticationResolver.js +66 -4
  33. package/dist/server/ServerAuthenticationResolver.js.map +1 -1
  34. package/dist/services/AuthenticationService.d.ts +2 -0
  35. package/dist/services/AuthenticationService.d.ts.map +1 -1
  36. package/dist/services/AuthenticationService.js +78 -13
  37. package/dist/services/AuthenticationService.js.map +1 -1
  38. package/dist/services/types.d.ts +2 -1
  39. package/dist/services/types.d.ts.map +1 -1
  40. package/dist/services/types.js.map +1 -1
  41. package/dist/shared/hooks/index.d.ts +1 -0
  42. package/dist/shared/hooks/index.d.ts.map +1 -1
  43. package/dist/shared/hooks/index.js +1 -0
  44. package/dist/shared/hooks/index.js.map +1 -1
  45. package/dist/shared/hooks/useSignIn.d.ts +1 -1
  46. package/dist/shared/hooks/useSignIn.d.ts.map +1 -1
  47. package/dist/shared/hooks/useSignIn.js +3 -1
  48. package/dist/shared/hooks/useSignIn.js.map +1 -1
  49. package/dist/shared/lib/AuthenticationRefresherImpl.d.ts.map +1 -1
  50. package/dist/shared/lib/AuthenticationRefresherImpl.js +25 -11
  51. package/dist/shared/lib/AuthenticationRefresherImpl.js.map +1 -1
  52. package/dist/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
  53. package/dist/shared/lib/GenericAuthenticationRefresher.js +13 -2
  54. package/dist/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
  55. package/dist/shared/lib/session.d.ts +5 -0
  56. package/dist/shared/lib/session.d.ts.map +1 -1
  57. package/dist/shared/lib/session.js +11 -2
  58. package/dist/shared/lib/session.js.map +1 -1
  59. package/dist/shared/lib/types.d.ts +2 -1
  60. package/dist/shared/lib/types.d.ts.map +1 -1
  61. package/dist/shared/lib/types.js.map +1 -1
  62. package/dist/shared/lib/util.d.ts +18 -1
  63. package/dist/shared/lib/util.d.ts.map +1 -1
  64. package/dist/shared/lib/util.js +53 -24
  65. package/dist/shared/lib/util.js.map +1 -1
  66. package/dist/shared/providers/CivicAuthConfigContext.d.ts +3 -1
  67. package/dist/shared/providers/CivicAuthConfigContext.d.ts.map +1 -1
  68. package/dist/shared/providers/CivicAuthConfigContext.js +3 -1
  69. package/dist/shared/providers/CivicAuthConfigContext.js.map +1 -1
  70. package/dist/shared/version.d.ts +1 -1
  71. package/dist/shared/version.js +1 -1
  72. package/dist/shared/version.js.map +1 -1
  73. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { retrieveTokens } from "../../shared/lib/util.js";
1
+ import { clearAuthServerSession, clearTokens, clearUser, retrieveTokens, } from "../../shared/lib/util.js";
2
2
  import { decodeJwt } from "jose";
3
3
  import { tokenKeys, } from "../../types.js";
4
4
  import { JWT_PAYLOAD_KNOWN_CLAIM_KEYS } from "../../constants.js";
@@ -16,7 +16,7 @@ const parseJWTToType = (jwt) => {
16
16
  };
17
17
  export async function getUser(storage) {
18
18
  const tokens = await retrieveTokens(storage);
19
- if (!tokens)
19
+ if (!tokens || !tokens.id_token)
20
20
  return null;
21
21
  const parsedToken = parseJWTToType(tokens.id_token);
22
22
  // it might be preferable to throw here
@@ -41,4 +41,13 @@ export async function getTokens(storage) {
41
41
  refreshToken: storageData.refresh_token,
42
42
  };
43
43
  }
44
+ /**
45
+ * Use the provided storage to clear all authentication cookies
46
+ * @param storage
47
+ */
48
+ export const clearAuthCookies = async (storage) => {
49
+ await clearTokens(storage);
50
+ await clearUser(storage);
51
+ await clearAuthServerSession(storage);
52
+ };
44
53
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAmB,MAAM,MAAM,CAAC;AAClD,OAAO,EACL,SAAS,GAMV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAE9D,uCAAuC;AACvC,MAAM,QAAQ,GAAG,CACf,IAAS,EACT,GAAM,EACM,EAAE;IACd,MAAM,MAAM,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,GAAW,EACK,EAAE;IAClB,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,WAA6B,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,WAAW,GAAG,cAAc,CAAI,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvD,uCAAuC;IACvC,IAAI,CAAC,WAAW,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAElC,qCAAqC;IACrC,MAAM,6BAA6B,GAAG;QACpC,GAAI,WAAiB;QACrB,EAAE,EAAE,WAAW,CAAC,GAAG;KACpB,CAAC;IAEF,6CAA6C;IAC7C,0EAA0E;IAC1E,OAAO,QAAQ,CACb,CAAC,GAAG,4BAA4B,EAAE,GAAG,SAAS,CAAC,EAC/C,6BAA6B,CACnB,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAoB;IAEpB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,QAAQ;QAC7B,WAAW,EAAE,WAAW,CAAC,YAAY;QACrC,YAAY,EAAE,WAAW,CAAC,aAAa;KACxC,CAAC;AACJ,CAAC","sourcesContent":["import { retrieveTokens } from \"@/shared/lib/util.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport {\n tokenKeys,\n type AuthStorage,\n type OAuthTokens,\n type User,\n type EmptyObject,\n type UnknownObject,\n} from \"@/types.js\";\nimport { JWT_PAYLOAD_KNOWN_CLAIM_KEYS } from \"@/constants.js\";\n\n// Function to omit keys from an object\nconst omitKeys = <K extends keyof T, T extends Record<string, unknown>>(\n keys: K[],\n obj: T,\n): Omit<T, K> => {\n const result = { ...obj };\n keys.forEach((key) => {\n delete result[key];\n });\n return result;\n};\n\nconst parseJWTToType = <T extends UnknownObject = EmptyObject>(\n jwt: string,\n): JWTPayload & T => {\n const parseResult = decodeJwt(jwt);\n return parseResult as JWTPayload & T;\n};\n\nexport async function getUser<T extends UnknownObject = EmptyObject>(\n storage: AuthStorage,\n): Promise<User<T> | null> {\n const tokens = await retrieveTokens(storage);\n if (!tokens) return null;\n\n const parsedToken = parseJWTToType<T>(tokens.id_token);\n // it might be preferable to throw here\n if (!parsedToken.sub) return null;\n\n // set the user ID from the token sub\n const userWithAdditionalTokenFields = {\n ...(parsedToken as T),\n id: parsedToken.sub,\n };\n\n // Assumes all information is in the ID token\n // remove the token keys from the user object to stop it getting too large\n return omitKeys(\n [...JWT_PAYLOAD_KNOWN_CLAIM_KEYS, ...tokenKeys],\n userWithAdditionalTokenFields,\n ) as User<T>;\n}\n\nexport async function getTokens(\n storage: AuthStorage,\n): Promise<OAuthTokens | null> {\n const storageData = await retrieveTokens(storage);\n if (!storageData) return null;\n\n return {\n idToken: storageData.id_token,\n accessToken: storageData.access_token,\n refreshToken: storageData.refresh_token,\n };\n}\n"]}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,WAAW,EACX,SAAS,EACT,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAmB,MAAM,MAAM,CAAC;AAClD,OAAO,EACL,SAAS,GAMV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAE9D,uCAAuC;AACvC,MAAM,QAAQ,GAAG,CACf,IAAS,EACT,GAAM,EACM,EAAE;IACd,MAAM,MAAM,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,GAAW,EACK,EAAE;IAClB,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,WAA6B,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE7C,MAAM,WAAW,GAAG,cAAc,CAAI,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvD,uCAAuC;IACvC,IAAI,CAAC,WAAW,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAElC,qCAAqC;IACrC,MAAM,6BAA6B,GAAG;QACpC,GAAI,WAAiB;QACrB,EAAE,EAAE,WAAW,CAAC,GAAG;KACpB,CAAC;IAEF,6CAA6C;IAC7C,0EAA0E;IAC1E,OAAO,QAAQ,CACb,CAAC,GAAG,4BAA4B,EAAE,GAAG,SAAS,CAAC,EAC/C,6BAA6B,CACnB,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAoB;IAEpB,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO;QACL,OAAO,EAAE,WAAW,CAAC,QAAQ;QAC7B,WAAW,EAAE,WAAW,CAAC,YAAY;QACrC,YAAY,EAAE,WAAW,CAAC,aAAa;KACxC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,OAAoB,EAAE,EAAE;IAC7D,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3B,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import {\n clearAuthServerSession,\n clearTokens,\n clearUser,\n retrieveTokens,\n} from \"@/shared/lib/util.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport {\n tokenKeys,\n type AuthStorage,\n type OAuthTokens,\n type User,\n type EmptyObject,\n type UnknownObject,\n} from \"@/types.js\";\nimport { JWT_PAYLOAD_KNOWN_CLAIM_KEYS } from \"@/constants.js\";\n\n// Function to omit keys from an object\nconst omitKeys = <K extends keyof T, T extends Record<string, unknown>>(\n keys: K[],\n obj: T,\n): Omit<T, K> => {\n const result = { ...obj };\n keys.forEach((key) => {\n delete result[key];\n });\n return result;\n};\n\nconst parseJWTToType = <T extends UnknownObject = EmptyObject>(\n jwt: string,\n): JWTPayload & T => {\n const parseResult = decodeJwt(jwt);\n return parseResult as JWTPayload & T;\n};\n\nexport async function getUser<T extends UnknownObject = EmptyObject>(\n storage: AuthStorage,\n): Promise<User<T> | null> {\n const tokens = await retrieveTokens(storage);\n if (!tokens || !tokens.id_token) return null;\n\n const parsedToken = parseJWTToType<T>(tokens.id_token);\n // it might be preferable to throw here\n if (!parsedToken.sub) return null;\n\n // set the user ID from the token sub\n const userWithAdditionalTokenFields = {\n ...(parsedToken as T),\n id: parsedToken.sub,\n };\n\n // Assumes all information is in the ID token\n // remove the token keys from the user object to stop it getting too large\n return omitKeys(\n [...JWT_PAYLOAD_KNOWN_CLAIM_KEYS, ...tokenKeys],\n userWithAdditionalTokenFields,\n ) as User<T>;\n}\n\nexport async function getTokens(\n storage: AuthStorage,\n): Promise<OAuthTokens | null> {\n const storageData = await retrieveTokens(storage);\n if (!storageData) return null;\n\n return {\n idToken: storageData.id_token,\n accessToken: storageData.access_token,\n refreshToken: storageData.refresh_token,\n };\n}\n\n/**\n * Use the provided storage to clear all authentication cookies\n * @param storage\n */\nexport const clearAuthCookies = async (storage: AuthStorage) => {\n await clearTokens(storage);\n await clearUser(storage);\n await clearAuthServerSession(storage);\n};\n"]}
@@ -1,4 +1,4 @@
1
- import type { Endpoints } from "../../types.js";
1
+ import type { DisplayMode, Endpoints } from "../../types.js";
2
2
  export declare enum OAuthTokenTypes {
3
3
  ID_TOKEN = "id_token",
4
4
  ACCESS_TOKEN = "access_token",
@@ -35,5 +35,6 @@ export type CivicAuthConfig = null | {
35
35
  challengeUrl?: string;
36
36
  refreshUrl?: string;
37
37
  logoutUrl?: string;
38
+ displayMode?: DisplayMode;
38
39
  };
39
40
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,oBAAY,eAAe;IACzB,QAAQ,aAAa;IACrB,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,uBAAuB,4BAA4B;CACpD;AAED,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAE5D,oBAAY,YAAY;IACtB,WAAW,kBAAkB;IAC7B,OAAO,YAAY;CACpB;AACD,oBAAY,WAAW;IACrB,IAAI,SAAS;CACd;AACD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,YAAY,GAAG,WAAW,CAAC;AAErE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACrC,eAAe,GAAG,YAAY,EAC9B,YAAY,CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzD,oBAAY,eAAe;IACzB,QAAQ,aAAa;IACrB,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,uBAAuB,4BAA4B;CACpD;AAED,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAE5D,oBAAY,YAAY;IACtB,WAAW,kBAAkB;IAC7B,OAAO,YAAY;CACpB;AACD,oBAAY,WAAW;IACrB,IAAI,SAAS;CACd;AACD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,YAAY,GAAG,WAAW,CAAC;AAErE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACrC,eAAe,GAAG,YAAY,EAC9B,YAAY,CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/shared/lib/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,wCAAqB,CAAA;IACrB,gDAA6B,CAAA;IAC7B,kDAA+B,CAAA;IAC/B,sEAAmD,CAAA;AACrD,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAC;AAE5D,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6CAA6B,CAAA;IAC7B,mCAAmB,CAAA;AACrB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AACD,MAAM,CAAN,IAAY,WAEX;AAFD,WAAY,WAAW;IACrB,4BAAa,CAAA;AACf,CAAC,EAFW,WAAW,KAAX,WAAW,QAEtB","sourcesContent":["import type { Endpoints } from \"@/types.js\";\n\nexport enum OAuthTokenTypes {\n ID_TOKEN = \"id_token\",\n ACCESS_TOKEN = \"access_token\",\n REFRESH_TOKEN = \"refresh_token\",\n ACCESS_TOKEN_EXPIRES_AT = \"access_token_expires_at\",\n}\n\nexport const AUTH_SERVER_SESSION = \"_session\";\nexport const AUTH_SERVER_LEGACY_SESSION = \"_session.legacy\";\n\nexport enum CodeVerifier {\n COOKIE_NAME = \"code_verifier\",\n APP_URL = \"app_url\",\n}\nexport enum UserStorage {\n USER = \"user\",\n}\nexport interface CookieConfig {\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n domain?: string;\n path?: string;\n maxAge?: number;\n httpOnly?: boolean;\n}\nexport type KeySetter = OAuthTokenTypes | CodeVerifier | UserStorage;\n\nexport type TokensCookieConfig = Record<\n OAuthTokenTypes | CodeVerifier,\n CookieConfig\n>;\n\nexport type CivicAuthConfig = null | {\n clientId: string;\n redirectUrl: string;\n logoutRedirectUrl: string;\n oauthServer: string;\n endpoints: Endpoints;\n scopes: string[];\n nonce?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n logoutUrl?: string;\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/shared/lib/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,wCAAqB,CAAA;IACrB,gDAA6B,CAAA;IAC7B,kDAA+B,CAAA;IAC/B,sEAAmD,CAAA;AACrD,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAC;AAE5D,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6CAA6B,CAAA;IAC7B,mCAAmB,CAAA;AACrB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AACD,MAAM,CAAN,IAAY,WAEX;AAFD,WAAY,WAAW;IACrB,4BAAa,CAAA;AACf,CAAC,EAFW,WAAW,KAAX,WAAW,QAEtB","sourcesContent":["import type { DisplayMode, Endpoints } from \"@/types.js\";\n\nexport enum OAuthTokenTypes {\n ID_TOKEN = \"id_token\",\n ACCESS_TOKEN = \"access_token\",\n REFRESH_TOKEN = \"refresh_token\",\n ACCESS_TOKEN_EXPIRES_AT = \"access_token_expires_at\",\n}\n\nexport const AUTH_SERVER_SESSION = \"_session\";\nexport const AUTH_SERVER_LEGACY_SESSION = \"_session.legacy\";\n\nexport enum CodeVerifier {\n COOKIE_NAME = \"code_verifier\",\n APP_URL = \"app_url\",\n}\nexport enum UserStorage {\n USER = \"user\",\n}\nexport interface CookieConfig {\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n domain?: string;\n path?: string;\n maxAge?: number;\n httpOnly?: boolean;\n}\nexport type KeySetter = OAuthTokenTypes | CodeVerifier | UserStorage;\n\nexport type TokensCookieConfig = Record<\n OAuthTokenTypes | CodeVerifier,\n CookieConfig\n>;\n\nexport type CivicAuthConfig = null | {\n clientId: string;\n redirectUrl: string;\n logoutRedirectUrl: string;\n oauthServer: string;\n endpoints: Endpoints;\n scopes: string[];\n nonce?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n logoutUrl?: string;\n displayMode?: DisplayMode;\n};\n"]}
@@ -27,14 +27,31 @@ export declare function generateOauthLogoutUrl(config: {
27
27
  }): Promise<URL>;
28
28
  export declare function buildOauth2Client(clientId: string, redirectUri: string, endpoints: Endpoints): OAuth2Client;
29
29
  export declare function exchangeTokens(code: string, state: string, pkceProducer: PKCEProducer, oauth2Client: OAuth2Client, oauthServer: string, endpoints: Endpoints): Promise<OIDCTokenResponseBody>;
30
+ /**
31
+ * Calculates the maxAge values for access and refresh token cookies
32
+ * based on the TTL values in the access token
33
+ *
34
+ * maxAge needs to be in seconds from now until expiration
35
+ *
36
+ * @param tokens OIDC tokens response containing the access token
37
+ * @returns Object with accessTokenMaxAge and refreshTokenMaxAge in seconds
38
+ */
39
+ export declare const getCookiesMaxAge: (tokens: OIDCTokenResponseBody) => {
40
+ accessTokenMaxAge: number;
41
+ refreshTokenMaxAge: number;
42
+ };
30
43
  export declare const getAccessTokenExpiresAt: (tokens: OIDCTokenResponseBody) => number;
31
44
  export declare function setAccessTokenExpiresAt(storage: AuthStorage | CookieStorage, tokens: OIDCTokenResponseBody): Promise<void>;
32
45
  export declare function storeTokens(storage: AuthStorage, tokens: OIDCTokenResponseBody): Promise<void>;
46
+ /**
47
+ * Stores tokens in server-side cookies with appropriate expiration times
48
+ * Uses TTL values from the tokens to set cookie maxAge values
49
+ */
33
50
  export declare function storeServerTokens(storage: AuthStorage | CookieStorage, tokens: OIDCTokenResponseBody): Promise<void>;
34
51
  export declare function clearTokens(storage: AuthStorage): Promise<void>;
35
52
  export declare function clearAuthServerSession(storage: AuthStorage): Promise<void>;
36
53
  export declare function clearUser(storage: AuthStorage): Promise<void>;
37
- export declare function retrieveTokens(storage: AuthStorage): Promise<OIDCTokenResponseBody | null>;
54
+ export declare function retrieveTokens(storage: AuthStorage): Promise<Partial<OIDCTokenResponseBody> | null>;
38
55
  export declare function retrieveAccessTokenExpiresAt(storage: AuthStorage): Promise<number>;
39
56
  export declare function validateOauth2Tokens(tokens: OIDCTokenResponseBody, jwksEndpoint: string, oauth2Client: OAuth2Client, issuer: string): Promise<ParsedTokens>;
40
57
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,YAAY,EACb,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAOlD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,GAAE,OAAO,GAAG,MAAe,GAChC,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,EACnB,iBAAiB,GAAE,OAAO,CAAC,SAAS,CAAM,GACzC,OAAO,CAAC,SAAS,CAAC,CAMpB;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,GAAG,CAAC,CA2Bf;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;CACxC,GAAG,OAAO,CAAC,GAAG,CAAC,CAcf;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,GACnB,YAAY,CAId;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,kCAyBrB;AAED,eAAO,MAAM,uBAAuB,GAClC,QAAQ,qBAAqB,KAC5B,MAUF,CAAC;AACF,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,WAAW,GAAG,aAAa,EACpC,MAAM,EAAE,qBAAqB,iBAQ9B;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,qBAAqB,iBAQ9B;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,GAAG,aAAa,EACpC,MAAM,EAAE,qBAAqB,iBA4C9B;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,iBAWrD;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,WAAW,iBAGhE;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,iBAGnD;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAkBvC;AAED,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAMD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,EAC7B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CA+BvB"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@ import { withoutUndefined } from "../../utils.js";
6
6
  import { GenericUserSession } from "../../shared/lib/UserSession.js";
7
7
  import { decodeJwt } from "jose";
8
8
  import { AUTOREFRESH_TIMEOUT_NAME, LOGOUT_STATE, REFRESH_IN_PROGRESS, } from "../../constants.js";
9
+ import { loggers } from "../../lib/logger.js";
10
+ const logger = loggers.services.validation;
9
11
  /**
10
12
  * Given a PKCE code verifier, derive the code challenge using SHA
11
13
  */
@@ -80,6 +82,29 @@ export async function exchangeTokens(code, state, pkceProducer, oauth2Client, oa
80
82
  }
81
83
  return tokens;
82
84
  }
85
+ /**
86
+ * Calculates the maxAge values for access and refresh token cookies
87
+ * based on the TTL values in the access token
88
+ *
89
+ * maxAge needs to be in seconds from now until expiration
90
+ *
91
+ * @param tokens OIDC tokens response containing the access token
92
+ * @returns Object with accessTokenMaxAge and refreshTokenMaxAge in seconds
93
+ */
94
+ export const getCookiesMaxAge = (tokens) => {
95
+ const parsedAccessToken = decodeJwt(tokens.access_token);
96
+ // Get TTL values from the token or use defaults
97
+ const accessTokenTTL = Number(parsedAccessToken?.accessTokenTTL) || 60 * 60; // 1 hour default
98
+ const refreshTokenTTL = Number(parsedAccessToken?.refreshTokenTTL) || 60 * 60 * 24 * 30; // 30 days default
99
+ // Calculate maxAge as TTL values directly (they represent seconds from now)
100
+ // This is correct because TTL values represent the lifetime of the token
101
+ const accessTokenMaxAge = accessTokenTTL;
102
+ const refreshTokenMaxAge = refreshTokenTTL;
103
+ return {
104
+ accessTokenMaxAge,
105
+ refreshTokenMaxAge,
106
+ };
107
+ };
83
108
  export const getAccessTokenExpiresAt = (tokens) => {
84
109
  const parsedAccessToken = decodeJwt(tokens.access_token);
85
110
  if (parsedAccessToken?.exp || false) {
@@ -106,37 +131,43 @@ export async function storeTokens(storage, tokens) {
106
131
  }
107
132
  await setAccessTokenExpiresAt(storage, tokens);
108
133
  }
134
+ /**
135
+ * Stores tokens in server-side cookies with appropriate expiration times
136
+ * Uses TTL values from the tokens to set cookie maxAge values
137
+ */
109
138
  export async function storeServerTokens(storage, tokens) {
110
139
  const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);
111
140
  const cookieStorage = storage;
112
141
  const now = Math.floor(Date.now() / 1000);
113
- const accessTokenMaxAge = accessTokenExpiresAt && accessTokenExpiresAt - now;
114
- const cookiesOverride = {
115
- ...(accessTokenMaxAge ? { maxAge: accessTokenMaxAge } : {}),
142
+ // Get maxAge values based on token TTLs
143
+ const { refreshTokenMaxAge, accessTokenMaxAge } = getCookiesMaxAge(tokens);
144
+ // Apply maxAge to cookie options
145
+ const accessTokenCookieOptions = {
146
+ maxAge: accessTokenMaxAge,
116
147
  };
117
- // the refresh token must be longer-lived than the access token max age to allow time for automatic refresh
118
- // as it's not a JWT, we derive it from the access token max age and add a margin
119
- const refreshTokenMaxAge = accessTokenMaxAge && accessTokenMaxAge + 5 * 60;
120
- const refreshCookiesOverride = {
121
- ...(refreshTokenMaxAge ? { maxAge: refreshTokenMaxAge } : {}),
148
+ const refreshTokenCookieOptions = {
149
+ maxAge: refreshTokenMaxAge,
122
150
  };
123
- console.log("storeServerTokens overrides", {
124
- cookiesOverride,
125
- refreshCookiesOverride,
126
- now,
127
- accessTokenMaxAge,
128
- accessTokenExpiresAt,
129
- });
151
+ // Set ID token with expiry based on the exp claim
130
152
  const idTokenExpiry = decodeJwt(tokens.id_token)?.exp;
131
- const idTokenMaxAge = idTokenExpiry && idTokenExpiry - now;
153
+ const idTokenMaxAge = idTokenExpiry ? idTokenExpiry - now : accessTokenMaxAge;
132
154
  await cookieStorage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token, {
133
- ...(idTokenMaxAge ? { maxAge: idTokenMaxAge } : {}),
155
+ maxAge: idTokenMaxAge,
134
156
  });
135
- await cookieStorage.set(OAuthTokenTypes.ACCESS_TOKEN, tokens.access_token, cookiesOverride);
157
+ // Set access token
158
+ await cookieStorage.set(OAuthTokenTypes.ACCESS_TOKEN, tokens.access_token, accessTokenCookieOptions);
159
+ // Set refresh token if present
136
160
  if (tokens.refresh_token) {
137
- await cookieStorage.set(OAuthTokenTypes.REFRESH_TOKEN, tokens.refresh_token, refreshCookiesOverride);
161
+ await cookieStorage.set(OAuthTokenTypes.REFRESH_TOKEN, tokens.refresh_token, refreshTokenCookieOptions);
138
162
  }
139
- await storage.set(OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT, accessTokenExpiresAt.toString(), cookiesOverride);
163
+ // Store the access token expiration timestamp
164
+ await storage.set(OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT, accessTokenExpiresAt.toString(), accessTokenCookieOptions);
165
+ logger.debug("storeServerTokens", {
166
+ accessTokenExpiresAt,
167
+ refreshTokenMaxAge,
168
+ accessTokenMaxAge,
169
+ idTokenMaxAge,
170
+ });
140
171
  }
141
172
  export async function clearTokens(storage) {
142
173
  // clear all local storage keys related to OAuth and CivicAuth SDK
@@ -163,11 +194,9 @@ export async function retrieveTokens(storage) {
163
194
  const accessToken = await storage.get(OAuthTokenTypes.ACCESS_TOKEN);
164
195
  const refreshToken = await storage.get(OAuthTokenTypes.REFRESH_TOKEN);
165
196
  const accessTokenExpiresAt = await storage.get(OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT);
166
- if (!idToken || !accessToken)
167
- return null;
168
197
  return {
169
- id_token: idToken,
170
- access_token: accessToken,
198
+ id_token: idToken ?? undefined,
199
+ access_token: accessToken ?? undefined,
171
200
  refresh_token: refreshToken ?? undefined,
172
201
  access_token_expires_at: accessTokenExpiresAt !== null
173
202
  ? parseInt(accessTokenExpiresAt, 10)
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport {\n AUTH_SERVER_LEGACY_SESSION,\n AUTH_SERVER_SESSION,\n OAuthTokenTypes,\n} from \"./types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport type { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport type { CookieStorage } from \"./storage.js\";\nimport {\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n REFRESH_IN_PROGRESS,\n} from \"@/constants.js\";\n\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n): Promise<Endpoints> {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n const challenge = await config.pkceConsumer.getCodeChallenge();\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n redirectUrl: string;\n idToken: string;\n state: string;\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const endSessionUrl = new URL(endpoints.endsession);\n endSessionUrl.searchParams.append(\"client_id\", config.clientId);\n endSessionUrl.searchParams.append(\"id_token_hint\", config.idToken);\n endSessionUrl.searchParams.append(\"state\", config.state);\n endSessionUrl.searchParams.append(\n \"post_logout_redirect_uri\",\n config.redirectUrl,\n );\n return endSessionUrl;\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n) {\n const codeVerifier = await pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in state\");\n\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(code, {\n codeVerifier,\n });\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(\n tokens,\n endpoints.jwks,\n oauth2Client,\n oauthServer,\n );\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n return tokens;\n}\n\nexport const getAccessTokenExpiresAt = (\n tokens: OIDCTokenResponseBody,\n): number => {\n const parsedAccessToken = decodeJwt(tokens.access_token);\n if (parsedAccessToken?.exp || false) {\n return parsedAccessToken.exp;\n } else if (tokens.expires_in) {\n const now = Math.floor(new Date().getTime() / 1000);\n return now + tokens.expires_in;\n } else {\n throw new Error(\"Cannot determine access token expiry!\");\n }\n};\nexport async function setAccessTokenExpiresAt(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // try to extract absolute expiry time from access token but fallback to calculation if not possible\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n await storage.set(\n OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n );\n}\n\nexport async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n await storage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token);\n await storage.set(OAuthTokenTypes.ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token) {\n await storage.set(OAuthTokenTypes.REFRESH_TOKEN, tokens.refresh_token);\n }\n await setAccessTokenExpiresAt(storage, tokens);\n}\n\nexport async function storeServerTokens(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n const cookieStorage = storage as CookieStorage;\n const now = Math.floor(Date.now() / 1000);\n const accessTokenMaxAge = accessTokenExpiresAt && accessTokenExpiresAt - now;\n const cookiesOverride = {\n ...(accessTokenMaxAge ? { maxAge: accessTokenMaxAge } : {}),\n };\n // the refresh token must be longer-lived than the access token max age to allow time for automatic refresh\n // as it's not a JWT, we derive it from the access token max age and add a margin\n const refreshTokenMaxAge = accessTokenMaxAge && accessTokenMaxAge + 5 * 60;\n const refreshCookiesOverride = {\n ...(refreshTokenMaxAge ? { maxAge: refreshTokenMaxAge } : {}),\n };\n console.log(\"storeServerTokens overrides\", {\n cookiesOverride,\n refreshCookiesOverride,\n now,\n accessTokenMaxAge,\n accessTokenExpiresAt,\n });\n const idTokenExpiry = decodeJwt(tokens.id_token)?.exp;\n const idTokenMaxAge = idTokenExpiry && idTokenExpiry - now;\n await cookieStorage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token, {\n ...(idTokenMaxAge ? { maxAge: idTokenMaxAge } : {}),\n });\n await cookieStorage.set(\n OAuthTokenTypes.ACCESS_TOKEN,\n tokens.access_token,\n cookiesOverride,\n );\n if (tokens.refresh_token) {\n await cookieStorage.set(\n OAuthTokenTypes.REFRESH_TOKEN,\n tokens.refresh_token,\n refreshCookiesOverride,\n );\n }\n await storage.set(\n OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n cookiesOverride,\n );\n}\n\nexport async function clearTokens(storage: AuthStorage) {\n // clear all local storage keys related to OAuth and CivicAuth SDK\n const clearOAuthPromises = [\n ...Object.values(OAuthTokenTypes),\n REFRESH_IN_PROGRESS,\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n ].map(async (key) => {\n await storage.delete(key);\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearAuthServerSession(storage: AuthStorage) {\n await storage.delete(AUTH_SERVER_SESSION);\n await storage.delete(AUTH_SERVER_LEGACY_SESSION);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n await userSession.clear();\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<OIDCTokenResponseBody | null> {\n const idToken = await storage.get(OAuthTokenTypes.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokenTypes.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokenTypes.REFRESH_TOKEN);\n const accessTokenExpiresAt = await storage.get(\n OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT,\n );\n if (!idToken || !accessToken) return null;\n\n return {\n id_token: idToken,\n access_token: accessToken,\n refresh_token: refreshToken ?? undefined,\n access_token_expires_at:\n accessTokenExpiresAt !== null\n ? parseInt(accessTokenExpiresAt, 10)\n : undefined, // Convert string to number\n };\n}\n\nexport async function retrieveAccessTokenExpiresAt(\n storage: AuthStorage,\n): Promise<number> {\n return Number(await storage.get(OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT));\n}\n\n// Single JWKS instance that persists for the lifetime of the SDK session\nlet cachedJWKS: ReturnType<typeof jose.createRemoteJWKSet> | null = null;\nlet cachedJwksUrl: string | null = null;\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n jwksEndpoint: string,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n // Only create a new JWKS instance if one doesn't exist yet\n if (!cachedJWKS || cachedJwksUrl !== jwksEndpoint) {\n cachedJWKS = jose.createRemoteJWKSet(new URL(jwksEndpoint));\n cachedJwksUrl = jwksEndpoint;\n }\n\n // validate the ID token\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenResponse.payload,\n refresh_token: tokens.refresh_token,\n });\n}\n"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/shared/lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport {\n AUTH_SERVER_LEGACY_SESSION,\n AUTH_SERVER_SESSION,\n OAuthTokenTypes,\n} from \"./types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport type { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport type { CookieStorage } from \"./storage.js\";\nimport {\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n REFRESH_IN_PROGRESS,\n} from \"@/constants.js\";\nimport { loggers } from \"@/lib/logger.js\";\n\nconst logger = loggers.services.validation;\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n): Promise<Endpoints> {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n const challenge = await config.pkceConsumer.getCodeChallenge();\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n redirectUrl: string;\n idToken: string;\n state: string;\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const endSessionUrl = new URL(endpoints.endsession);\n endSessionUrl.searchParams.append(\"client_id\", config.clientId);\n endSessionUrl.searchParams.append(\"id_token_hint\", config.idToken);\n endSessionUrl.searchParams.append(\"state\", config.state);\n endSessionUrl.searchParams.append(\n \"post_logout_redirect_uri\",\n config.redirectUrl,\n );\n return endSessionUrl;\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n) {\n const codeVerifier = await pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in state\");\n\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(code, {\n codeVerifier,\n });\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(\n tokens,\n endpoints.jwks,\n oauth2Client,\n oauthServer,\n );\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n return tokens;\n}\n/**\n * Calculates the maxAge values for access and refresh token cookies\n * based on the TTL values in the access token\n *\n * maxAge needs to be in seconds from now until expiration\n *\n * @param tokens OIDC tokens response containing the access token\n * @returns Object with accessTokenMaxAge and refreshTokenMaxAge in seconds\n */\nexport const getCookiesMaxAge = (\n tokens: OIDCTokenResponseBody,\n): { accessTokenMaxAge: number; refreshTokenMaxAge: number } => {\n const parsedAccessToken = decodeJwt(tokens.access_token);\n\n // Get TTL values from the token or use defaults\n const accessTokenTTL = Number(parsedAccessToken?.accessTokenTTL) || 60 * 60; // 1 hour default\n const refreshTokenTTL =\n Number(parsedAccessToken?.refreshTokenTTL) || 60 * 60 * 24 * 30; // 30 days default\n\n // Calculate maxAge as TTL values directly (they represent seconds from now)\n // This is correct because TTL values represent the lifetime of the token\n const accessTokenMaxAge = accessTokenTTL;\n const refreshTokenMaxAge = refreshTokenTTL;\n\n return {\n accessTokenMaxAge,\n refreshTokenMaxAge,\n };\n};\nexport const getAccessTokenExpiresAt = (\n tokens: OIDCTokenResponseBody,\n): number => {\n const parsedAccessToken = decodeJwt(tokens.access_token);\n if (parsedAccessToken?.exp || false) {\n return parsedAccessToken.exp;\n } else if (tokens.expires_in) {\n const now = Math.floor(new Date().getTime() / 1000);\n return now + tokens.expires_in;\n } else {\n throw new Error(\"Cannot determine access token expiry!\");\n }\n};\nexport async function setAccessTokenExpiresAt(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // try to extract absolute expiry time from access token but fallback to calculation if not possible\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n await storage.set(\n OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n );\n}\n\nexport async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n await storage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token);\n await storage.set(OAuthTokenTypes.ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token) {\n await storage.set(OAuthTokenTypes.REFRESH_TOKEN, tokens.refresh_token);\n }\n await setAccessTokenExpiresAt(storage, tokens);\n}\n\n/**\n * Stores tokens in server-side cookies with appropriate expiration times\n * Uses TTL values from the tokens to set cookie maxAge values\n */\nexport async function storeServerTokens(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n const cookieStorage = storage as CookieStorage;\n const now = Math.floor(Date.now() / 1000);\n\n // Get maxAge values based on token TTLs\n const { refreshTokenMaxAge, accessTokenMaxAge } = getCookiesMaxAge(tokens);\n\n // Apply maxAge to cookie options\n const accessTokenCookieOptions = {\n maxAge: accessTokenMaxAge,\n };\n\n const refreshTokenCookieOptions = {\n maxAge: refreshTokenMaxAge,\n };\n\n // Set ID token with expiry based on the exp claim\n const idTokenExpiry = decodeJwt(tokens.id_token)?.exp;\n const idTokenMaxAge = idTokenExpiry ? idTokenExpiry - now : accessTokenMaxAge;\n\n await cookieStorage.set(OAuthTokenTypes.ID_TOKEN, tokens.id_token, {\n maxAge: idTokenMaxAge,\n });\n\n // Set access token\n await cookieStorage.set(\n OAuthTokenTypes.ACCESS_TOKEN,\n tokens.access_token,\n accessTokenCookieOptions,\n );\n\n // Set refresh token if present\n if (tokens.refresh_token) {\n await cookieStorage.set(\n OAuthTokenTypes.REFRESH_TOKEN,\n tokens.refresh_token,\n refreshTokenCookieOptions,\n );\n }\n\n // Store the access token expiration timestamp\n await storage.set(\n OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n accessTokenCookieOptions,\n );\n logger.debug(\"storeServerTokens\", {\n accessTokenExpiresAt,\n refreshTokenMaxAge,\n accessTokenMaxAge,\n idTokenMaxAge,\n });\n}\n\nexport async function clearTokens(storage: AuthStorage) {\n // clear all local storage keys related to OAuth and CivicAuth SDK\n const clearOAuthPromises = [\n ...Object.values(OAuthTokenTypes),\n REFRESH_IN_PROGRESS,\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n ].map(async (key) => {\n await storage.delete(key);\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearAuthServerSession(storage: AuthStorage) {\n await storage.delete(AUTH_SERVER_SESSION);\n await storage.delete(AUTH_SERVER_LEGACY_SESSION);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n await userSession.clear();\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<Partial<OIDCTokenResponseBody> | null> {\n const idToken = await storage.get(OAuthTokenTypes.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokenTypes.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokenTypes.REFRESH_TOKEN);\n const accessTokenExpiresAt = await storage.get(\n OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT,\n );\n\n return {\n id_token: idToken ?? undefined,\n access_token: accessToken ?? undefined,\n refresh_token: refreshToken ?? undefined,\n access_token_expires_at:\n accessTokenExpiresAt !== null\n ? parseInt(accessTokenExpiresAt, 10)\n : undefined, // Convert string to number\n };\n}\n\nexport async function retrieveAccessTokenExpiresAt(\n storage: AuthStorage,\n): Promise<number> {\n return Number(await storage.get(OAuthTokenTypes.ACCESS_TOKEN_EXPIRES_AT));\n}\n\n// Single JWKS instance that persists for the lifetime of the SDK session\nlet cachedJWKS: ReturnType<typeof jose.createRemoteJWKSet> | null = null;\nlet cachedJwksUrl: string | null = null;\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n jwksEndpoint: string,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n // Only create a new JWKS instance if one doesn't exist yet\n if (!cachedJWKS || cachedJwksUrl !== jwksEndpoint) {\n cachedJWKS = jose.createRemoteJWKSet(new URL(jwksEndpoint));\n cachedJwksUrl = jwksEndpoint;\n }\n\n // validate the ID token\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n cachedJWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenResponse.payload,\n refresh_token: tokens.refresh_token,\n });\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import React, { type ReactNode } from "react";
2
2
  import type { CivicAuthConfig } from "../lib/types.js";
3
+ import type { DisplayMode } from "../../types.js";
3
4
  type CivicAuthConfigContextType = {
4
5
  children: ReactNode;
5
6
  oauthServer?: string;
@@ -12,8 +13,9 @@ type CivicAuthConfigContextType = {
12
13
  refreshUrl?: string;
13
14
  logoutUrl?: string;
14
15
  logoutCallbackUrl?: string;
16
+ displayMode?: DisplayMode;
15
17
  };
16
18
  declare const CivicAuthConfigContext: React.Context<CivicAuthConfig>;
17
- declare const CivicAuthConfigProvider: ({ children, oauthServer, clientId, redirectUrl: inputRedirectUrl, nonce, challengeUrl, refreshUrl, logoutUrl, scopes, logoutRedirectUrl: inputLogoutRedirectUrl, }: CivicAuthConfigContextType) => import("@emotion/react/jsx-runtime").JSX.Element;
19
+ declare const CivicAuthConfigProvider: ({ children, oauthServer, clientId, redirectUrl: inputRedirectUrl, nonce, challengeUrl, refreshUrl, logoutUrl, scopes, logoutRedirectUrl: inputLogoutRedirectUrl, displayMode, }: CivicAuthConfigContextType) => import("@emotion/react/jsx-runtime").JSX.Element;
18
20
  export { CivicAuthConfigProvider, CivicAuthConfigContext };
19
21
  //# sourceMappingURL=CivicAuthConfigContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CivicAuthConfigContext.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/CivicAuthConfigContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAA0B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIvD,KAAK,0BAA0B,GAAG;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,QAAA,MAAM,sBAAsB,gCAAgD,CAAC;AAE7E,QAAA,MAAM,uBAAuB,GAAI,oKAW9B,0BAA0B,qDAsD5B,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"CivicAuthConfigContext.d.ts","sourceRoot":"","sources":["../../../src/shared/providers/CivicAuthConfigContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAA0B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C,KAAK,0BAA0B,GAAG;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,QAAA,MAAM,sBAAsB,gCAAgD,CAAC;AAE7E,QAAA,MAAM,uBAAuB,GAAI,iLAY9B,0BAA0B,qDAwD5B,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,CAAC"}
@@ -7,7 +7,7 @@ import { useCurrentUrl } from "../../shared/hooks/useCurrentUrl.js";
7
7
  const defaultConfig = null;
8
8
  // Context for exposing Config specifically to the TokenProvider
9
9
  const CivicAuthConfigContext = createContext(defaultConfig);
10
- const CivicAuthConfigProvider = ({ children, oauthServer, clientId, redirectUrl: inputRedirectUrl, nonce, challengeUrl, refreshUrl, logoutUrl, scopes, logoutRedirectUrl: inputLogoutRedirectUrl, }) => {
10
+ const CivicAuthConfigProvider = ({ children, oauthServer, clientId, redirectUrl: inputRedirectUrl, nonce, challengeUrl, refreshUrl, logoutUrl, scopes, logoutRedirectUrl: inputLogoutRedirectUrl, displayMode = "iframe", }) => {
11
11
  const currentUrl = useCurrentUrl();
12
12
  const redirectUrl = useMemo(() => {
13
13
  const useUrl = inputRedirectUrl || currentUrl;
@@ -36,6 +36,7 @@ const CivicAuthConfigProvider = ({ children, oauthServer, clientId, redirectUrl:
36
36
  logoutUrl,
37
37
  scopes: scopes || DEFAULT_SCOPES,
38
38
  logoutRedirectUrl,
39
+ displayMode,
39
40
  }
40
41
  : null, [
41
42
  clientId,
@@ -48,6 +49,7 @@ const CivicAuthConfigProvider = ({ children, oauthServer, clientId, redirectUrl:
48
49
  logoutUrl,
49
50
  scopes,
50
51
  logoutRedirectUrl,
52
+ displayMode,
51
53
  ]);
52
54
  return (_jsx(CivicAuthConfigContext.Provider, { value: value, children: children }));
53
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CivicAuthConfigContext.js","sourceRoot":"","sources":["../../../src/shared/providers/CivicAuthConfigContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAGhE,MAAM,aAAa,GAAoB,IAAI,CAAC;AAe5C,gEAAgE;AAChE,MAAM,sBAAsB,GAAG,aAAa,CAAkB,aAAa,CAAC,CAAC;AAE7E,MAAM,uBAAuB,GAAG,CAAC,EAC/B,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EAAE,gBAAgB,EAC7B,KAAK,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,MAAM,EACN,iBAAiB,EAAE,sBAAsB,GACd,EAAE,EAAE;IAC/B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,MAAM,MAAM,GAAG,gBAAgB,IAAI,UAAU,CAAC;QAC9C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEjD,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,sBAAsB,IAAI,UAAU,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAEzC,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CACH,SAAS;QACP,CAAC,CAAC;YACE,QAAQ;YACR,WAAW;YACX,WAAW,EAAE,WAAW,IAAI,mBAAmB;YAC/C,SAAS;YACT,KAAK;YACL,YAAY;YACZ,UAAU;YACV,SAAS;YACT,MAAM,EAAE,MAAM,IAAI,cAAc;YAChC,iBAAiB;SAClB;QACH,CAAC,CAAC,IAAI,EACV;QACE,QAAQ;QACR,WAAW;QACX,WAAW;QACX,SAAS;QACT,KAAK;QACL,YAAY;QACZ,UAAU;QACV,SAAS;QACT,MAAM;QACN,iBAAiB;KAClB,CACF,CAAC;IACF,OAAO,CACL,KAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAC1C,QAAQ,GACuB,CACnC,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,CAAC","sourcesContent":["\"use client\";\nimport { DEFAULT_AUTH_SERVER, DEFAULT_SCOPES } from \"@/constants.js\";\nimport React, { createContext, useMemo, type ReactNode } from \"react\";\nimport { useOAuthEndpoints } from \"@/shared/hooks/useOAuthEndpoints.js\";\nimport { useCurrentUrl } from \"@/shared/hooks/useCurrentUrl.js\";\nimport type { CivicAuthConfig } from \"../lib/types.js\";\n\nconst defaultConfig: CivicAuthConfig = null;\n\ntype CivicAuthConfigContextType = {\n children: ReactNode;\n oauthServer?: string;\n clientId: string;\n scopes?: string[];\n redirectUrl?: string;\n logoutRedirectUrl?: string;\n nonce?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n};\n// Context for exposing Config specifically to the TokenProvider\nconst CivicAuthConfigContext = createContext<CivicAuthConfig>(defaultConfig);\n\nconst CivicAuthConfigProvider = ({\n children,\n oauthServer,\n clientId,\n redirectUrl: inputRedirectUrl,\n nonce,\n challengeUrl,\n refreshUrl,\n logoutUrl,\n scopes,\n logoutRedirectUrl: inputLogoutRedirectUrl,\n}: CivicAuthConfigContextType) => {\n const currentUrl = useCurrentUrl();\n\n const redirectUrl = useMemo(() => {\n const useUrl = inputRedirectUrl || currentUrl;\n if (useUrl) {\n return `${useUrl.split(\"?\")[0]}`;\n }\n return \"\";\n }, [currentUrl, inputRedirectUrl]);\n const endpoints = useOAuthEndpoints(oauthServer);\n\n const logoutRedirectUrl = useMemo(() => {\n const useUrl = inputLogoutRedirectUrl || currentUrl;\n if (useUrl) {\n return `${useUrl.split(\"?\")[0]}`;\n }\n return \"\";\n }, [currentUrl, inputLogoutRedirectUrl]);\n\n const value = useMemo(\n () =>\n endpoints\n ? {\n clientId,\n redirectUrl,\n oauthServer: oauthServer || DEFAULT_AUTH_SERVER,\n endpoints,\n nonce,\n challengeUrl,\n refreshUrl,\n logoutUrl,\n scopes: scopes || DEFAULT_SCOPES,\n logoutRedirectUrl,\n }\n : null,\n [\n clientId,\n redirectUrl,\n oauthServer,\n endpoints,\n nonce,\n challengeUrl,\n refreshUrl,\n logoutUrl,\n scopes,\n logoutRedirectUrl,\n ],\n );\n return (\n <CivicAuthConfigContext.Provider value={value}>\n {children}\n </CivicAuthConfigContext.Provider>\n );\n};\n\nexport { CivicAuthConfigProvider, CivicAuthConfigContext };\n"]}
1
+ {"version":3,"file":"CivicAuthConfigContext.js","sourceRoot":"","sources":["../../../src/shared/providers/CivicAuthConfigContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIhE,MAAM,aAAa,GAAoB,IAAI,CAAC;AAgB5C,gEAAgE;AAChE,MAAM,sBAAsB,GAAG,aAAa,CAAkB,aAAa,CAAC,CAAC;AAE7E,MAAM,uBAAuB,GAAG,CAAC,EAC/B,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EAAE,gBAAgB,EAC7B,KAAK,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,MAAM,EACN,iBAAiB,EAAE,sBAAsB,EACzC,WAAW,GAAG,QAAQ,GACK,EAAE,EAAE;IAC/B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,MAAM,MAAM,GAAG,gBAAgB,IAAI,UAAU,CAAC;QAC9C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEjD,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,sBAAsB,IAAI,UAAU,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAEzC,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CACH,SAAS;QACP,CAAC,CAAC;YACE,QAAQ;YACR,WAAW;YACX,WAAW,EAAE,WAAW,IAAI,mBAAmB;YAC/C,SAAS;YACT,KAAK;YACL,YAAY;YACZ,UAAU;YACV,SAAS;YACT,MAAM,EAAE,MAAM,IAAI,cAAc;YAChC,iBAAiB;YACjB,WAAW;SACZ;QACH,CAAC,CAAC,IAAI,EACV;QACE,QAAQ;QACR,WAAW;QACX,WAAW;QACX,SAAS;QACT,KAAK;QACL,YAAY;QACZ,UAAU;QACV,SAAS;QACT,MAAM;QACN,iBAAiB;QACjB,WAAW;KACZ,CACF,CAAC;IACF,OAAO,CACL,KAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAC1C,QAAQ,GACuB,CACnC,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,CAAC","sourcesContent":["\"use client\";\nimport { DEFAULT_AUTH_SERVER, DEFAULT_SCOPES } from \"@/constants.js\";\nimport React, { createContext, useMemo, type ReactNode } from \"react\";\nimport { useOAuthEndpoints } from \"@/shared/hooks/useOAuthEndpoints.js\";\nimport { useCurrentUrl } from \"@/shared/hooks/useCurrentUrl.js\";\nimport type { CivicAuthConfig } from \"../lib/types.js\";\nimport type { DisplayMode } from \"@/types.js\";\n\nconst defaultConfig: CivicAuthConfig = null;\n\ntype CivicAuthConfigContextType = {\n children: ReactNode;\n oauthServer?: string;\n clientId: string;\n scopes?: string[];\n redirectUrl?: string;\n logoutRedirectUrl?: string;\n nonce?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n logoutUrl?: string;\n logoutCallbackUrl?: string;\n displayMode?: DisplayMode;\n};\n// Context for exposing Config specifically to the TokenProvider\nconst CivicAuthConfigContext = createContext<CivicAuthConfig>(defaultConfig);\n\nconst CivicAuthConfigProvider = ({\n children,\n oauthServer,\n clientId,\n redirectUrl: inputRedirectUrl,\n nonce,\n challengeUrl,\n refreshUrl,\n logoutUrl,\n scopes,\n logoutRedirectUrl: inputLogoutRedirectUrl,\n displayMode = \"iframe\",\n}: CivicAuthConfigContextType) => {\n const currentUrl = useCurrentUrl();\n\n const redirectUrl = useMemo(() => {\n const useUrl = inputRedirectUrl || currentUrl;\n if (useUrl) {\n return `${useUrl.split(\"?\")[0]}`;\n }\n return \"\";\n }, [currentUrl, inputRedirectUrl]);\n const endpoints = useOAuthEndpoints(oauthServer);\n\n const logoutRedirectUrl = useMemo(() => {\n const useUrl = inputLogoutRedirectUrl || currentUrl;\n if (useUrl) {\n return `${useUrl.split(\"?\")[0]}`;\n }\n return \"\";\n }, [currentUrl, inputLogoutRedirectUrl]);\n\n const value = useMemo(\n () =>\n endpoints\n ? {\n clientId,\n redirectUrl,\n oauthServer: oauthServer || DEFAULT_AUTH_SERVER,\n endpoints,\n nonce,\n challengeUrl,\n refreshUrl,\n logoutUrl,\n scopes: scopes || DEFAULT_SCOPES,\n logoutRedirectUrl,\n displayMode,\n }\n : null,\n [\n clientId,\n redirectUrl,\n oauthServer,\n endpoints,\n nonce,\n challengeUrl,\n refreshUrl,\n logoutUrl,\n scopes,\n logoutRedirectUrl,\n displayMode,\n ],\n );\n return (\n <CivicAuthConfigContext.Provider value={value}>\n {children}\n </CivicAuthConfigContext.Provider>\n );\n};\n\nexport { CivicAuthConfigProvider, CivicAuthConfigContext };\n"]}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "@civic/auth:0.4.5";
1
+ export declare const VERSION = "@civic/auth:0.4.6";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // This is an auto-generated file. Do not edit.
2
- export const VERSION = "@civic/auth:0.4.5";
2
+ export const VERSION = "@civic/auth:0.4.6";
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,CAAC,MAAM,OAAO,GAAG,mBAAmB,CAAC","sourcesContent":["// This is an auto-generated file. Do not edit.\n\nexport const VERSION = \"@civic/auth:0.4.5\";\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/shared/version.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,CAAC,MAAM,OAAO,GAAG,mBAAmB,CAAC","sourcesContent":["// This is an auto-generated file. Do not edit.\n\nexport const VERSION = \"@civic/auth:0.4.6\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civic/auth",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -93,7 +93,7 @@
93
93
  "scripts": {
94
94
  "prebuild": "pnpm generate-version",
95
95
  "build": "tsc -p tsconfig.build.json --noEmit false $(if [ \"$WATCH_MODE\" = \"true\" ]; then echo \"--watch\"; fi) && tsc-alias -p tsconfig.build.json",
96
- "dev": "WATCH_MODE=true pnpm build",
96
+ "dev": "if [ \"$WATCH_MODE\" = \"true\" ]; then pnpm build; else echo \"WATCH_MODE is not set to true. Skipping build.\"; fi",
97
97
  "pretest": "pnpm generate-version",
98
98
  "test": "vitest",
99
99
  "lint": "eslint \"src/**/*.ts*\" \"test/**/*.ts*\" --max-warnings 0",