@civic/auth 0.1.4-beta.0 → 0.1.4-beta.2

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 (283) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/README.md +10 -8
  3. package/dist/cjs/nextjs/GetUser.d.ts.map +1 -1
  4. package/dist/cjs/nextjs/GetUser.js +2 -13
  5. package/dist/cjs/nextjs/GetUser.js.map +1 -1
  6. package/dist/cjs/nextjs/hooks/useUserCookie.d.ts +4 -1
  7. package/dist/cjs/nextjs/hooks/useUserCookie.d.ts.map +1 -1
  8. package/dist/cjs/nextjs/hooks/useUserCookie.js +4 -5
  9. package/dist/cjs/nextjs/hooks/useUserCookie.js.map +1 -1
  10. package/dist/cjs/nextjs/providers/NextAuthProvider.js +2 -2
  11. package/dist/cjs/nextjs/providers/NextAuthProvider.js.map +1 -1
  12. package/dist/cjs/nextjs/routeHandler.js +2 -2
  13. package/dist/cjs/nextjs/routeHandler.js.map +1 -1
  14. package/dist/cjs/shared/components/CivicAuthIframe.js +1 -1
  15. package/dist/cjs/shared/components/CivicAuthIframe.js.map +1 -1
  16. package/dist/cjs/shared/lib/session.d.ts +1 -1
  17. package/dist/cjs/shared/lib/session.d.ts.map +1 -1
  18. package/dist/cjs/shared/lib/session.js +12 -1
  19. package/dist/cjs/shared/lib/session.js.map +1 -1
  20. package/dist/cjs/shared/lib/util.d.ts.map +1 -1
  21. package/dist/cjs/shared/lib/util.js +1 -0
  22. package/dist/cjs/shared/lib/util.js.map +1 -1
  23. package/dist/cjs/shared/providers/UserProvider.d.ts +5 -1
  24. package/dist/cjs/shared/providers/UserProvider.d.ts.map +1 -1
  25. package/dist/cjs/shared/providers/UserProvider.js +4 -2
  26. package/dist/cjs/shared/providers/UserProvider.js.map +1 -1
  27. package/dist/cjs/types.d.ts +4 -5
  28. package/dist/cjs/types.d.ts.map +1 -1
  29. package/dist/cjs/types.js +4 -0
  30. package/dist/cjs/types.js.map +1 -1
  31. package/dist/esm/nextjs/GetUser.d.ts.map +1 -1
  32. package/dist/esm/nextjs/GetUser.js +2 -13
  33. package/dist/esm/nextjs/GetUser.js.map +1 -1
  34. package/dist/esm/nextjs/hooks/useUserCookie.d.ts +4 -1
  35. package/dist/esm/nextjs/hooks/useUserCookie.d.ts.map +1 -1
  36. package/dist/esm/nextjs/hooks/useUserCookie.js +4 -5
  37. package/dist/esm/nextjs/hooks/useUserCookie.js.map +1 -1
  38. package/dist/esm/nextjs/providers/NextAuthProvider.js +2 -2
  39. package/dist/esm/nextjs/providers/NextAuthProvider.js.map +1 -1
  40. package/dist/esm/nextjs/routeHandler.js +2 -2
  41. package/dist/esm/nextjs/routeHandler.js.map +1 -1
  42. package/dist/esm/shared/components/CivicAuthIframe.js +1 -1
  43. package/dist/esm/shared/components/CivicAuthIframe.js.map +1 -1
  44. package/dist/esm/shared/lib/session.d.ts +1 -1
  45. package/dist/esm/shared/lib/session.d.ts.map +1 -1
  46. package/dist/esm/shared/lib/session.js +12 -1
  47. package/dist/esm/shared/lib/session.js.map +1 -1
  48. package/dist/esm/shared/lib/util.d.ts.map +1 -1
  49. package/dist/esm/shared/lib/util.js +1 -0
  50. package/dist/esm/shared/lib/util.js.map +1 -1
  51. package/dist/esm/shared/providers/UserProvider.d.ts +5 -1
  52. package/dist/esm/shared/providers/UserProvider.d.ts.map +1 -1
  53. package/dist/esm/shared/providers/UserProvider.js +4 -2
  54. package/dist/esm/shared/providers/UserProvider.js.map +1 -1
  55. package/dist/esm/types.d.ts +4 -5
  56. package/dist/esm/types.d.ts.map +1 -1
  57. package/dist/esm/types.js +3 -1
  58. package/dist/esm/types.js.map +1 -1
  59. package/dist/src/browser/storage.d.ts +9 -0
  60. package/dist/src/browser/storage.d.ts.map +1 -0
  61. package/dist/src/browser/storage.js +17 -0
  62. package/dist/src/browser/storage.js.map +1 -0
  63. package/dist/src/config.d.ts.map +1 -0
  64. package/dist/src/index.d.ts.map +1 -0
  65. package/dist/src/lib/cookies.d.ts +7 -0
  66. package/dist/src/lib/cookies.d.ts.map +1 -0
  67. package/dist/src/lib/cookies.js +25 -0
  68. package/dist/src/lib/cookies.js.map +1 -0
  69. package/dist/src/lib/jwt.d.ts.map +1 -0
  70. package/dist/src/lib/oauth.d.ts.map +1 -0
  71. package/dist/src/lib/postMessage.d.ts.map +1 -0
  72. package/dist/src/lib/postMessage.js +15 -0
  73. package/dist/src/lib/postMessage.js.map +1 -0
  74. package/dist/src/lib/windowUtil.d.ts.map +1 -0
  75. package/dist/src/lib/windowUtil.js +31 -0
  76. package/dist/src/lib/windowUtil.js.map +1 -0
  77. package/dist/src/nextjs/GetUser.d.ts.map +1 -0
  78. package/dist/src/nextjs/GetUser.js +7 -0
  79. package/dist/src/nextjs/GetUser.js.map +1 -0
  80. package/dist/src/nextjs/config.d.ts.map +1 -0
  81. package/dist/src/nextjs/config.js +173 -0
  82. package/dist/src/nextjs/config.js.map +1 -0
  83. package/dist/src/nextjs/cookies.d.ts.map +1 -0
  84. package/dist/src/nextjs/hooks/index.d.ts +2 -0
  85. package/dist/src/nextjs/hooks/index.d.ts.map +1 -0
  86. package/dist/src/nextjs/hooks/index.js +2 -0
  87. package/dist/src/nextjs/hooks/index.js.map +1 -0
  88. package/dist/src/nextjs/hooks/useRefresh.d.ts +4 -0
  89. package/dist/src/nextjs/hooks/useRefresh.d.ts.map +1 -0
  90. package/dist/src/nextjs/hooks/useRefresh.js +38 -0
  91. package/dist/src/nextjs/hooks/useRefresh.js.map +1 -0
  92. package/dist/src/nextjs/hooks/useTokenCookie.d.ts +3 -0
  93. package/dist/src/nextjs/hooks/useTokenCookie.d.ts.map +1 -0
  94. package/dist/src/nextjs/hooks/useTokenCookie.js +37 -0
  95. package/dist/src/nextjs/hooks/useTokenCookie.js.map +1 -0
  96. package/dist/src/nextjs/hooks/useUserCookie.d.ts +6 -0
  97. package/dist/src/nextjs/hooks/useUserCookie.d.ts.map +1 -1
  98. package/dist/src/nextjs/hooks/useUserCookie.js +4 -5
  99. package/dist/src/nextjs/hooks/useUserCookie.js.map +1 -1
  100. package/dist/src/nextjs/index.d.ts.map +1 -0
  101. package/dist/src/nextjs/middleware/index.d.ts.map +1 -0
  102. package/dist/src/nextjs/middleware.d.ts.map +1 -0
  103. package/dist/src/nextjs/providers/NextAuthProvider.d.ts +13 -0
  104. package/dist/src/nextjs/providers/NextAuthProvider.d.ts.map +1 -0
  105. package/dist/src/nextjs/providers/NextAuthProvider.js +79 -0
  106. package/dist/src/nextjs/providers/NextAuthProvider.js.map +1 -0
  107. package/dist/src/nextjs/routeHandler.d.ts.map +1 -0
  108. package/dist/src/nextjs/routeHandler.js +212 -0
  109. package/dist/src/nextjs/routeHandler.js.map +1 -0
  110. package/dist/src/nextjs/utils.d.ts.map +1 -0
  111. package/dist/src/reactjs/components/SignInButton.d.ts.map +1 -0
  112. package/dist/src/reactjs/components/SignOutButton.d.ts.map +1 -0
  113. package/dist/src/reactjs/components/UserButton.d.ts.map +1 -0
  114. package/dist/src/reactjs/components/UserButton.js +118 -0
  115. package/dist/src/reactjs/components/UserButton.js.map +1 -0
  116. package/dist/src/reactjs/components/index.d.ts.map +1 -0
  117. package/dist/src/reactjs/hooks/index.d.ts +6 -0
  118. package/dist/src/reactjs/hooks/index.d.ts.map +1 -0
  119. package/dist/src/reactjs/hooks/index.js +6 -0
  120. package/dist/src/reactjs/hooks/index.js.map +1 -0
  121. package/dist/src/reactjs/hooks/useAuth.d.ts.map +1 -0
  122. package/dist/src/reactjs/hooks/useRefresh.d.ts +4 -0
  123. package/dist/src/reactjs/hooks/useRefresh.d.ts.map +1 -0
  124. package/dist/src/reactjs/hooks/useRefresh.js +28 -0
  125. package/dist/src/reactjs/hooks/useRefresh.js.map +1 -0
  126. package/dist/src/reactjs/hooks/useUser.d.ts.map +1 -0
  127. package/dist/src/reactjs/index.d.ts.map +1 -0
  128. package/dist/src/reactjs/providers/index.d.ts.map +1 -0
  129. package/dist/src/server/ServerAuthenticationResolver.d.ts.map +1 -0
  130. package/dist/src/server/config.d.ts.map +1 -0
  131. package/dist/src/server/index.d.ts.map +1 -0
  132. package/dist/src/server/login.d.ts.map +1 -0
  133. package/dist/src/server/refresh.d.ts.map +1 -0
  134. package/dist/src/services/AuthenticationService.d.ts +90 -0
  135. package/dist/src/services/AuthenticationService.d.ts.map +1 -0
  136. package/dist/src/services/AuthenticationService.js +243 -0
  137. package/dist/src/services/AuthenticationService.js.map +1 -0
  138. package/dist/src/services/PKCE.d.ts.map +1 -0
  139. package/dist/src/services/types.d.ts.map +1 -0
  140. package/dist/src/shared/components/BlockDisplay.d.ts +7 -0
  141. package/dist/src/shared/components/BlockDisplay.d.ts.map +1 -0
  142. package/dist/src/shared/components/BlockDisplay.js +25 -0
  143. package/dist/src/shared/components/BlockDisplay.js.map +1 -0
  144. package/dist/src/shared/components/CivicAuthIframe.d.ts.map +1 -0
  145. package/dist/src/shared/components/CivicAuthIframe.js +9 -0
  146. package/dist/src/shared/components/CivicAuthIframe.js.map +1 -0
  147. package/dist/src/shared/components/CivicAuthIframeContainer.d.ts.map +1 -0
  148. package/dist/src/shared/components/CivicAuthIframeContainer.js +138 -0
  149. package/dist/src/shared/components/CivicAuthIframeContainer.js.map +1 -0
  150. package/dist/src/shared/components/IFrameAndLoading.d.ts +7 -0
  151. package/dist/src/shared/components/IFrameAndLoading.d.ts.map +1 -0
  152. package/dist/src/shared/components/IFrameAndLoading.js +22 -0
  153. package/dist/src/shared/components/IFrameAndLoading.js.map +1 -0
  154. package/dist/src/shared/hooks/index.d.ts +9 -0
  155. package/dist/src/shared/hooks/index.d.ts.map +1 -0
  156. package/dist/src/shared/hooks/index.js +9 -0
  157. package/dist/src/shared/hooks/index.js.map +1 -0
  158. package/dist/src/shared/hooks/useAuth.d.ts.map +1 -0
  159. package/dist/src/shared/hooks/useCivicAuthConfig.d.ts +3 -0
  160. package/dist/src/shared/hooks/useCivicAuthConfig.d.ts.map +1 -0
  161. package/dist/src/shared/hooks/useCivicAuthConfig.js +10 -0
  162. package/dist/src/shared/hooks/useCivicAuthConfig.js.map +1 -0
  163. package/dist/src/shared/hooks/useClientTokenExchangeSession.d.ts +3 -0
  164. package/dist/src/shared/hooks/useClientTokenExchangeSession.d.ts.map +1 -0
  165. package/dist/src/shared/hooks/useClientTokenExchangeSession.js +13 -0
  166. package/dist/src/shared/hooks/useClientTokenExchangeSession.js.map +1 -0
  167. package/dist/src/shared/hooks/useConfig.d.ts +3 -0
  168. package/dist/src/shared/hooks/useConfig.d.ts.map +1 -0
  169. package/dist/src/shared/hooks/useConfig.js +13 -0
  170. package/dist/src/shared/hooks/useConfig.js.map +1 -0
  171. package/dist/src/shared/hooks/useCurrentUrl.d.ts +3 -0
  172. package/dist/src/shared/hooks/useCurrentUrl.d.ts.map +1 -0
  173. package/dist/src/shared/hooks/useCurrentUrl.js +24 -0
  174. package/dist/src/shared/hooks/useCurrentUrl.js.map +1 -0
  175. package/dist/src/shared/hooks/useIframe.d.ts.map +1 -0
  176. package/dist/src/shared/hooks/useIsInIframe.d.ts +3 -0
  177. package/dist/src/shared/hooks/useIsInIframe.d.ts.map +1 -0
  178. package/dist/src/shared/hooks/useIsInIframe.js +14 -0
  179. package/dist/src/shared/hooks/useIsInIframe.js.map +1 -0
  180. package/dist/src/shared/hooks/useOAuthEndpoints.d.ts +4 -0
  181. package/dist/src/shared/hooks/useOAuthEndpoints.d.ts.map +1 -0
  182. package/dist/src/shared/hooks/useOAuthEndpoints.js +14 -0
  183. package/dist/src/shared/hooks/useOAuthEndpoints.js.map +1 -0
  184. package/dist/src/shared/hooks/useRefresh.d.ts +4 -0
  185. package/dist/src/shared/hooks/useRefresh.d.ts.map +1 -0
  186. package/dist/src/shared/hooks/useRefresh.js +38 -0
  187. package/dist/src/shared/hooks/useRefresh.js.map +1 -0
  188. package/dist/src/shared/hooks/useSession.d.ts +3 -0
  189. package/dist/src/shared/hooks/useSession.d.ts.map +1 -0
  190. package/dist/src/shared/hooks/useSignIn.d.ts +14 -0
  191. package/dist/src/shared/hooks/useSignIn.d.ts.map +1 -0
  192. package/dist/src/shared/hooks/useSignIn.js +71 -0
  193. package/dist/src/shared/hooks/useSignIn.js.map +1 -0
  194. package/dist/src/shared/hooks/useToken.d.ts.map +1 -0
  195. package/dist/src/shared/lib/GenericAuthenticationRefresher.d.ts +20 -0
  196. package/dist/src/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -0
  197. package/dist/src/shared/lib/GenericAuthenticationRefresher.js +73 -0
  198. package/dist/src/shared/lib/GenericAuthenticationRefresher.js.map +1 -0
  199. package/dist/src/shared/lib/UserSession.d.ts.map +1 -0
  200. package/dist/src/shared/lib/session.d.ts +3 -0
  201. package/dist/src/shared/lib/session.d.ts.map +1 -0
  202. package/dist/src/shared/lib/session.js +21 -0
  203. package/dist/src/shared/lib/session.js.map +1 -0
  204. package/dist/src/shared/lib/storage.d.ts.map +1 -0
  205. package/dist/src/shared/lib/types.d.ts +35 -0
  206. package/dist/src/shared/lib/types.d.ts.map +1 -0
  207. package/dist/src/shared/lib/types.js +18 -0
  208. package/dist/src/shared/lib/types.js.map +1 -0
  209. package/dist/src/shared/lib/util.d.ts.map +1 -0
  210. package/dist/src/shared/lib/util.js +133 -0
  211. package/dist/src/shared/lib/util.js.map +1 -0
  212. package/dist/src/shared/providers/AuthContext.d.ts.map +1 -0
  213. package/dist/src/shared/providers/AuthProvider.d.ts +21 -0
  214. package/dist/src/shared/providers/AuthProvider.d.ts.map +1 -0
  215. package/dist/src/shared/providers/AuthProvider.js +63 -0
  216. package/dist/src/shared/providers/AuthProvider.js.map +1 -0
  217. package/dist/src/shared/providers/CivicAuthConfigContext.d.ts +16 -0
  218. package/dist/src/shared/providers/CivicAuthConfigContext.d.ts.map +1 -0
  219. package/dist/src/shared/providers/CivicAuthConfigContext.js +43 -0
  220. package/dist/src/shared/providers/CivicAuthConfigContext.js.map +1 -0
  221. package/dist/src/shared/providers/CivicAuthProvider.d.ts.map +1 -0
  222. package/dist/src/shared/providers/CivicAuthProvider.js +32 -0
  223. package/dist/src/shared/providers/CivicAuthProvider.js.map +1 -0
  224. package/dist/src/shared/providers/ClientTokenExchangeSessionProvider.d.ts +17 -0
  225. package/dist/src/shared/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -0
  226. package/dist/src/shared/providers/ClientTokenExchangeSessionProvider.js +146 -0
  227. package/dist/src/shared/providers/ClientTokenExchangeSessionProvider.js.map +1 -0
  228. package/dist/src/shared/providers/ConfigProvider.d.ts +21 -0
  229. package/dist/src/shared/providers/ConfigProvider.d.ts.map +1 -0
  230. package/dist/src/shared/providers/ConfigProvider.js +19 -0
  231. package/dist/src/shared/providers/ConfigProvider.js.map +1 -0
  232. package/dist/src/shared/providers/IframeProvider.d.ts +19 -0
  233. package/dist/src/shared/providers/IframeProvider.d.ts.map +1 -0
  234. package/dist/src/shared/providers/IframeProvider.js +29 -0
  235. package/dist/src/shared/providers/IframeProvider.js.map +1 -0
  236. package/dist/src/shared/providers/SessionProvider.d.ts +19 -0
  237. package/dist/src/shared/providers/SessionProvider.d.ts.map +1 -0
  238. package/dist/src/shared/providers/SessionProvider.js +23 -0
  239. package/dist/src/shared/providers/SessionProvider.js.map +1 -0
  240. package/dist/src/shared/providers/TokenProvider.d.ts.map +1 -0
  241. package/dist/src/shared/providers/TokenProvider.js +42 -0
  242. package/dist/src/shared/providers/TokenProvider.js.map +1 -0
  243. package/dist/src/shared/providers/UserProvider.d.ts +20 -0
  244. package/dist/src/shared/providers/UserProvider.d.ts.map +1 -0
  245. package/dist/src/shared/providers/UserProvider.js +51 -0
  246. package/dist/src/shared/providers/UserProvider.js.map +1 -0
  247. package/dist/src/types.d.ts +146 -0
  248. package/dist/src/types.d.ts.map +1 -0
  249. package/dist/src/types.js +4 -0
  250. package/dist/src/types.js.map +1 -0
  251. package/dist/test/integration/sdk.test.d.ts.map +1 -0
  252. package/dist/test/integration/sdk.test.js +189 -0
  253. package/dist/test/integration/sdk.test.js.map +1 -0
  254. package/dist/test/unit/lib/oauth.test.d.ts.map +1 -0
  255. package/dist/test/unit/nextjs/NextAuthProvider.test.d.ts.map +1 -0
  256. package/dist/test/unit/nextjs/NextAuthProvider.test.js +31 -0
  257. package/dist/test/unit/nextjs/NextAuthProvider.test.js.map +1 -0
  258. package/dist/test/unit/nextjs/config.test.d.ts.map +1 -0
  259. package/dist/test/unit/nextjs/getUser.test.d.ts.map +1 -0
  260. package/dist/test/unit/nextjs/getUser.test.js +22 -0
  261. package/dist/test/unit/nextjs/getUser.test.js.map +1 -0
  262. package/dist/test/unit/nextjs/middleware.test.d.ts.map +1 -0
  263. package/dist/test/unit/nextjs/utils.test.d.ts.map +1 -0
  264. package/dist/test/unit/publicApi/apiSnapshot.test.d.ts.map +1 -0
  265. package/dist/test/unit/react/components/SignInButton.test.d.ts.map +1 -0
  266. package/dist/test/unit/react/components/SignOutButton.test.d.ts.map +1 -0
  267. package/dist/test/unit/server/login.test.d.ts.map +1 -0
  268. package/dist/test/unit/server/refresh.test.d.ts.map +1 -0
  269. package/dist/test/unit/server/session.test.d.ts.map +1 -0
  270. package/dist/test/unit/services/AuthenticationService.test.d.ts.map +1 -0
  271. package/dist/test/unit/services/AuthenticationService.test.js +121 -0
  272. package/dist/test/unit/services/AuthenticationService.test.js.map +1 -0
  273. package/dist/test/unit/services/ServerAuthenticationResolver.test.d.ts.map +1 -0
  274. package/dist/test/unit/shared/GenericAuthenticationRefresher.test.d.ts.map +1 -0
  275. package/dist/test/unit/shared/UserSession.test.d.ts.map +1 -0
  276. package/dist/test/unit/shared/components/CivicAuthIframeContainer.test.d.ts.map +1 -0
  277. package/dist/test/unit/shared/components/CivicAuthIframeContainer.test.js +122 -0
  278. package/dist/test/unit/shared/components/CivicAuthIframeContainer.test.js.map +1 -0
  279. package/dist/test/unit/shared/storage.test.d.ts.map +1 -0
  280. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  281. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  282. package/dist/tsconfig.tsbuildinfo +1 -1
  283. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToken.d.ts","sourceRoot":"","sources":["../../../../src/shared/hooks/useToken.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,QAAQ,sEAQb,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { AuthenticationRefresher } from "@/services/types.js";
2
+ import type { AuthStorage, Endpoints, OIDCTokenResponseBody } from "@/types.js";
3
+ import type { AuthConfig } from "@/server/config.js";
4
+ export declare class GenericAuthenticationRefresher implements AuthenticationRefresher {
5
+ private authConfig;
6
+ private storage;
7
+ private endpointOverrides?;
8
+ private oauth2client;
9
+ private endpoints;
10
+ private refreshTimeout;
11
+ private constructor();
12
+ get oauthServer(): string;
13
+ init(): Promise<this>;
14
+ static build(authConfig: AuthConfig, storage: AuthStorage, endpointOverrides?: Partial<Endpoints>): Promise<GenericAuthenticationRefresher>;
15
+ refreshTokens(): Promise<OIDCTokenResponseBody>;
16
+ private handleRefresh;
17
+ setupAutorefresh(): Promise<void>;
18
+ clearAutorefresh(): void;
19
+ }
20
+ //# sourceMappingURL=GenericAuthenticationRefresher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenericAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../../../src/shared/lib/GenericAuthenticationRefresher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAMhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,qBAAa,8BAA+B,YAAW,uBAAuB;IAM1E,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,iBAAiB,CAAC;IAP5B,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,cAAc,CAA6B;IAEnD,OAAO;IAMP,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;WAkBd,KAAK,CAChB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GACrC,OAAO,CAAC,8BAA8B,CAAC;IAWpC,aAAa;YAiBL,aAAa;IAWrB,gBAAgB;IAkBtB,gBAAgB;CAKjB"}
@@ -0,0 +1,73 @@
1
+ import { getEndpointsWithOverrides, retrieveTokens, storeTokens, } from "@/shared/lib/util.js";
2
+ import { OAuth2Client } from "oslo/oauth2";
3
+ import { DEFAULT_AUTH_SERVER } from "@/constants.js";
4
+ export class GenericAuthenticationRefresher {
5
+ authConfig;
6
+ storage;
7
+ endpointOverrides;
8
+ oauth2client;
9
+ endpoints;
10
+ refreshTimeout;
11
+ constructor(authConfig, storage, endpointOverrides) {
12
+ this.authConfig = authConfig;
13
+ this.storage = storage;
14
+ this.endpointOverrides = endpointOverrides;
15
+ }
16
+ get oauthServer() {
17
+ return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;
18
+ }
19
+ async init() {
20
+ // resolve oauth config
21
+ this.endpoints = await getEndpointsWithOverrides(this.oauthServer, this.endpointOverrides);
22
+ this.oauth2client = new OAuth2Client(this.authConfig.clientId, this.endpoints.auth, this.endpoints.token, {
23
+ redirectURI: this.authConfig.redirectUrl,
24
+ });
25
+ return this;
26
+ }
27
+ static async build(authConfig, storage, endpointOverrides) {
28
+ const refresher = new GenericAuthenticationRefresher(authConfig, storage, endpointOverrides);
29
+ await refresher.init();
30
+ return refresher;
31
+ }
32
+ async refreshTokens() {
33
+ if (!this.oauth2client)
34
+ await this.init();
35
+ const tokens = await retrieveTokens(this.storage);
36
+ if (!tokens?.refresh_token)
37
+ throw new Error("No refresh token available");
38
+ const oauth2Client = this.oauth2client;
39
+ const refreshedTokens = await oauth2Client.refreshAccessToken(tokens.refresh_token);
40
+ await storeTokens(this.storage, refreshedTokens);
41
+ return tokens;
42
+ }
43
+ async handleRefresh() {
44
+ try {
45
+ await this.refreshTokens();
46
+ await this.setupAutorefresh(); // Reset the timeout after successful refresh
47
+ console.log("Autorefreshed tokens");
48
+ }
49
+ catch (error) {
50
+ console.error("Failed to refresh tokens:", error);
51
+ }
52
+ }
53
+ async setupAutorefresh() {
54
+ // Clear any existing timeout
55
+ this.clearAutorefresh();
56
+ // get expires_in
57
+ const tokens = await retrieveTokens(this.storage);
58
+ const expires_in = tokens?.expires_in || 60;
59
+ // Calculate time until expiry (subtract 30 seconds as buffer)
60
+ const bufferTimeMs = 30 * 1000; // 30 seconds in milliseconds
61
+ const expiresInMs = expires_in * 1000; // Convert to milliseconds
62
+ const refreshTimeMs = Math.max(0, expiresInMs - bufferTimeMs);
63
+ this.refreshTimeout = setTimeout(() => {
64
+ this.handleRefresh();
65
+ }, refreshTimeMs);
66
+ }
67
+ clearAutorefresh() {
68
+ if (this.refreshTimeout) {
69
+ clearTimeout(this.refreshTimeout);
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=GenericAuthenticationRefresher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenericAuthenticationRefresher.js","sourceRoot":"","sources":["../../../../src/shared/lib/GenericAuthenticationRefresher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthenticationRefresher } from \"@/services/types.js\";\nimport type { AuthStorage, Endpoints, OIDCTokenResponseBody } from \"@/types.js\";\nimport {\n getEndpointsWithOverrides,\n retrieveTokens,\n storeTokens,\n} from \"@/shared/lib/util.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { DEFAULT_AUTH_SERVER } from \"@/constants.js\";\n\nexport class GenericAuthenticationRefresher implements AuthenticationRefresher {\n private oauth2client: OAuth2Client | undefined;\n private endpoints: Endpoints | undefined;\n private refreshTimeout: NodeJS.Timeout | undefined;\n\n private constructor(\n private authConfig: AuthConfig,\n private storage: AuthStorage,\n private endpointOverrides?: Partial<Endpoints>,\n ) {}\n\n get oauthServer(): string {\n return this.authConfig.oauthServer || DEFAULT_AUTH_SERVER;\n }\n\n async init(): Promise<this> {\n // resolve oauth config\n this.endpoints = await getEndpointsWithOverrides(\n this.oauthServer,\n this.endpointOverrides,\n );\n this.oauth2client = new OAuth2Client(\n this.authConfig.clientId,\n this.endpoints.auth,\n this.endpoints.token,\n {\n redirectURI: this.authConfig.redirectUrl,\n },\n );\n\n return this;\n }\n\n static async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n endpointOverrides?: Partial<Endpoints>,\n ): Promise<GenericAuthenticationRefresher> {\n const refresher = new GenericAuthenticationRefresher(\n authConfig,\n storage,\n endpointOverrides,\n );\n await refresher.init();\n\n return refresher;\n }\n\n async refreshTokens() {\n if (!this.oauth2client) await this.init();\n\n const tokens = await retrieveTokens(this.storage);\n if (!tokens?.refresh_token) throw new Error(\"No refresh token available\");\n\n const oauth2Client = this.oauth2client!;\n const refreshedTokens =\n await oauth2Client.refreshAccessToken<OIDCTokenResponseBody>(\n tokens.refresh_token,\n );\n\n await storeTokens(this.storage, refreshedTokens);\n\n return tokens;\n }\n\n private async handleRefresh() {\n try {\n await this.refreshTokens();\n await this.setupAutorefresh(); // Reset the timeout after successful refresh\n\n console.log(\"Autorefreshed tokens\");\n } catch (error) {\n console.error(\"Failed to refresh tokens:\", error);\n }\n }\n\n async setupAutorefresh() {\n // Clear any existing timeout\n this.clearAutorefresh();\n\n // get expires_in\n const tokens = await retrieveTokens(this.storage);\n const expires_in = tokens?.expires_in || 60;\n\n // Calculate time until expiry (subtract 30 seconds as buffer)\n const bufferTimeMs = 30 * 1000; // 30 seconds in milliseconds\n const expiresInMs = expires_in * 1000; // Convert to milliseconds\n const refreshTimeMs = Math.max(0, expiresInMs - bufferTimeMs);\n\n this.refreshTimeout = setTimeout(() => {\n this.handleRefresh();\n }, refreshTimeMs);\n }\n\n clearAutorefresh() {\n if (this.refreshTimeout) {\n clearTimeout(this.refreshTimeout);\n }\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/lib/UserSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAsB,IAAI,EAAE,MAAM,YAAY,CAAC;AAIxE,MAAM,WAAW,WAAW;IAC1B,GAAG,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC5B,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,qBAAa,kBAAmB,YAAW,WAAW;IACxC,QAAQ,CAAC,OAAO,EAAE,WAAW;gBAApB,OAAO,EAAE,WAAW;IAEnC,GAAG,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAK3B,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAO5C"}
@@ -0,0 +1,3 @@
1
+ import { type AuthStorage, type User } from "@/types.js";
2
+ export declare function getUser(storage: AuthStorage): Promise<User | null>;
3
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/shared/lib/session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,WAAW,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAcpE,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAQxE"}
@@ -0,0 +1,21 @@
1
+ import { retrieveTokens } from "@/shared/lib/util.js";
2
+ import { parseJWT } from "oslo/jwt";
3
+ import { tokenKeys } from "@/types.js";
4
+ // Function to omit keys from an object
5
+ const omitKeys = (keys, obj) => {
6
+ const result = { ...obj };
7
+ keys.forEach((key) => {
8
+ delete result[key];
9
+ });
10
+ return result;
11
+ };
12
+ export async function getUser(storage) {
13
+ const tokens = await retrieveTokens(storage);
14
+ if (!tokens)
15
+ return null;
16
+ const parsedToken = parseJWT(tokens.id_token)?.payload;
17
+ // Assumes all information is in the ID token
18
+ // remove the token keys from the user object to stop it getting too large
19
+ return parsedToken ? omitKeys(tokenKeys, parsedToken) : null;
20
+ }
21
+ //# sourceMappingURL=session.js.map
@@ -0,0 +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,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,SAAS,EAA+B,MAAM,YAAY,CAAC;AAEpE,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,KAAK,UAAU,OAAO,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAe,CAAC;IAC/D,6CAA6C;IAC7C,0EAA0E;IAC1E,OAAO,WAAW,CAAC,CAAC,CAAE,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC","sourcesContent":["import { retrieveTokens } from \"@/shared/lib/util.js\";\nimport { parseJWT } from \"oslo/jwt\";\nimport { tokenKeys, type AuthStorage, type User } from \"@/types.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\nexport async function getUser(storage: AuthStorage): Promise<User | null> {\n const tokens = await retrieveTokens(storage);\n if (!tokens) return null;\n\n const parsedToken = parseJWT(tokens.id_token)?.payload as User;\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 parsedToken ? (omitKeys(tokenKeys, parsedToken) as User) : null;\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../src/shared/lib/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEhF,KAAK,cAAc,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,GAAG,IAAI,WAAW,CAAC;IACnB,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IACtC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IACtC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAChD,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,uBAAuB,QAAU,CAAC;AAE/C,8BAAsB,aAAc,YAAW,WAAW;IACxD,SAAS,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IAC1C,SAAS,aAAa,QAAQ,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAanE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CACxD"}
@@ -0,0 +1,35 @@
1
+ import type { Endpoints } from "@/types.js";
2
+ export declare enum OAuthTokens {
3
+ ID_TOKEN = "id_token",
4
+ ACCESS_TOKEN = "access_token",
5
+ REFRESH_TOKEN = "refresh_token",
6
+ EXPIRES_IN = "expires_in",
7
+ TIMESTAMP = "timestamp"
8
+ }
9
+ export declare enum CodeVerifier {
10
+ COOKIE_NAME = "code_verifier",
11
+ APP_URL = "app_url"
12
+ }
13
+ export declare enum UserStorage {
14
+ USER = "user"
15
+ }
16
+ export interface CookieConfig {
17
+ secure?: boolean;
18
+ sameSite?: "strict" | "lax" | "none";
19
+ domain?: string;
20
+ path?: string;
21
+ maxAge?: number;
22
+ httpOnly?: boolean;
23
+ }
24
+ export type TokensCookieConfig = Record<OAuthTokens | CodeVerifier, CookieConfig>;
25
+ export type CivicAuthConfig = null | {
26
+ clientId: string;
27
+ redirectUrl: string;
28
+ oauthServer: string;
29
+ endpoints: Endpoints;
30
+ scopes: string[];
31
+ nonce?: string;
32
+ challengeUrl?: string;
33
+ logoutUrl?: string;
34
+ };
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +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,WAAW;IACrB,QAAQ,aAAa;IACrB,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,UAAU,eAAe;IACzB,SAAS,cAAc;CACxB;AAED,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;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACrC,WAAW,GAAG,YAAY,EAC1B,YAAY,CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,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,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC"}
@@ -0,0 +1,18 @@
1
+ export var OAuthTokens;
2
+ (function (OAuthTokens) {
3
+ OAuthTokens["ID_TOKEN"] = "id_token";
4
+ OAuthTokens["ACCESS_TOKEN"] = "access_token";
5
+ OAuthTokens["REFRESH_TOKEN"] = "refresh_token";
6
+ OAuthTokens["EXPIRES_IN"] = "expires_in";
7
+ OAuthTokens["TIMESTAMP"] = "timestamp";
8
+ })(OAuthTokens || (OAuthTokens = {}));
9
+ export var CodeVerifier;
10
+ (function (CodeVerifier) {
11
+ CodeVerifier["COOKIE_NAME"] = "code_verifier";
12
+ CodeVerifier["APP_URL"] = "app_url";
13
+ })(CodeVerifier || (CodeVerifier = {}));
14
+ export var UserStorage;
15
+ (function (UserStorage) {
16
+ UserStorage["USER"] = "user";
17
+ })(UserStorage || (UserStorage = {}));
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/shared/lib/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,4CAA6B,CAAA;IAC7B,8CAA+B,CAAA;IAC/B,wCAAyB,CAAA;IACzB,sCAAuB,CAAA;AACzB,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAED,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 OAuthTokens {\n ID_TOKEN = \"id_token\",\n ACCESS_TOKEN = \"access_token\",\n REFRESH_TOKEN = \"refresh_token\",\n EXPIRES_IN = \"expires_in\",\n TIMESTAMP = \"timestamp\",\n}\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}\n\nexport type TokensCookieConfig = Record<\n OAuthTokens | CodeVerifier,\n CookieConfig\n>;\n\nexport type CivicAuthConfig = null | {\n clientId: string;\n redirectUrl: string;\n oauthServer: string;\n endpoints: Endpoints;\n scopes: string[];\n nonce?: string;\n challengeUrl?: string;\n logoutUrl?: string;\n};\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../src/shared/lib/util.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EAET,qBAAqB,EACrB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGtE;;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,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,YAAY,EAAE,YAAY,CAAC;CAC5B,GAAG,OAAO,CAAC,GAAG,CAAC,CAIf;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,kCAoBrB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,qBAAqB,iBAY9B;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,iBAKrD;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,WAAW,iBAInD;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAgBvC;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CA2BvB"}
@@ -0,0 +1,133 @@
1
+ import { OAuthTokens } from "./types.js";
2
+ import { OAuth2Client } from "oslo/oauth2";
3
+ import { getIssuerVariations, getOauthEndpoints } from "@/lib/oauth.js";
4
+ import * as jose from "jose";
5
+ import { withoutUndefined } from "@/utils.js";
6
+ import { GenericUserSession } from "@/shared/lib/UserSession.js";
7
+ /**
8
+ * Given a PKCE code verifier, derive the code challenge using SHA
9
+ */
10
+ export async function deriveCodeChallenge(codeVerifier, method = "S256") {
11
+ if (method === "Plain") {
12
+ console.warn("Using insecure plain code challenge method");
13
+ return codeVerifier;
14
+ }
15
+ const encoder = new TextEncoder();
16
+ const data = encoder.encode(codeVerifier);
17
+ const digest = await crypto.subtle.digest("SHA-256", data);
18
+ return btoa(String.fromCharCode(...new Uint8Array(digest)))
19
+ .replace(/\+/g, "-")
20
+ .replace(/\//g, "_")
21
+ .replace(/=+$/, "");
22
+ }
23
+ export async function getEndpointsWithOverrides(oauthServer, endpointOverrides = {}) {
24
+ const endpoints = await getOauthEndpoints(oauthServer);
25
+ return {
26
+ ...endpoints,
27
+ ...endpointOverrides,
28
+ };
29
+ }
30
+ export async function generateOauthLoginUrl(config) {
31
+ const endpoints = await getEndpointsWithOverrides(config.oauthServer, config.endpointOverrides);
32
+ const oauth2Client = buildOauth2Client(config.clientId, config.redirectUrl, endpoints);
33
+ const challenge = await config.pkceConsumer.getCodeChallenge();
34
+ const oAuthUrl = await oauth2Client.createAuthorizationURL({
35
+ state: config.state,
36
+ scopes: config.scopes,
37
+ });
38
+ // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source
39
+ // It only allows passing in a code verifier which it then hashes itself.
40
+ oAuthUrl.searchParams.append("code_challenge", challenge);
41
+ oAuthUrl.searchParams.append("code_challenge_method", "S256");
42
+ if (config.nonce) {
43
+ // nonce isn't supported by oslo, so we add it manually
44
+ oAuthUrl.searchParams.append("nonce", config.nonce);
45
+ }
46
+ // Required by the auth server for offline_access scope
47
+ oAuthUrl.searchParams.append("prompt", "consent");
48
+ return oAuthUrl;
49
+ }
50
+ export async function generateOauthLogoutUrl(config) {
51
+ // TODO TECH-676: Implement logout
52
+ console.log("generateOauthLogoutUrl not implemented", config);
53
+ return new URL("http://localhost");
54
+ }
55
+ export function buildOauth2Client(clientId, redirectUri, endpoints) {
56
+ return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {
57
+ redirectURI: redirectUri,
58
+ });
59
+ }
60
+ export async function exchangeTokens(code, state, pkceProducer, oauth2Client, oauthServer, endpoints) {
61
+ const codeVerifier = await pkceProducer.getCodeVerifier();
62
+ if (!codeVerifier)
63
+ throw new Error("Code verifier not found in state");
64
+ const tokens = await oauth2Client.validateAuthorizationCode(code, {
65
+ codeVerifier,
66
+ });
67
+ // Validate relevant tokens
68
+ try {
69
+ await validateOauth2Tokens(tokens, endpoints, oauth2Client, oauthServer);
70
+ }
71
+ catch (error) {
72
+ console.error("tokenExchange error", { error, tokens });
73
+ throw new Error(`OIDC tokens validation failed: ${error.message}`);
74
+ }
75
+ return tokens;
76
+ }
77
+ export async function storeTokens(storage, tokens) {
78
+ // store tokens in storage ( TODO we should probably store them against the state to allow multiple logins )
79
+ await storage.set(OAuthTokens.ID_TOKEN, tokens.id_token);
80
+ await storage.set(OAuthTokens.ACCESS_TOKEN, tokens.access_token);
81
+ if (tokens.refresh_token) {
82
+ await storage.set(OAuthTokens.REFRESH_TOKEN, tokens.refresh_token);
83
+ }
84
+ if (tokens.expires_in) {
85
+ await storage.set(OAuthTokens.EXPIRES_IN, tokens.expires_in.toString());
86
+ await storage.set(OAuthTokens.TIMESTAMP, new Date().getTime().toString());
87
+ }
88
+ }
89
+ export async function clearTokens(storage) {
90
+ const clearOAuthPromises = Object.values(OAuthTokens).map(async (key) => {
91
+ await storage.set(key, "");
92
+ });
93
+ await Promise.all([...clearOAuthPromises]);
94
+ }
95
+ export async function clearUser(storage) {
96
+ const userSession = new GenericUserSession(storage);
97
+ console.log("clearUser");
98
+ await userSession.set(null);
99
+ }
100
+ export async function retrieveTokens(storage) {
101
+ const idToken = await storage.get(OAuthTokens.ID_TOKEN);
102
+ const accessToken = await storage.get(OAuthTokens.ACCESS_TOKEN);
103
+ const refreshToken = await storage.get(OAuthTokens.REFRESH_TOKEN);
104
+ const expiresIn = await storage.get(OAuthTokens.EXPIRES_IN);
105
+ const timestamp = await storage.get(OAuthTokens.TIMESTAMP);
106
+ if (!idToken || !accessToken)
107
+ return null;
108
+ return {
109
+ id_token: idToken,
110
+ access_token: accessToken,
111
+ refresh_token: refreshToken ?? undefined,
112
+ expires_in: expiresIn ? parseInt(expiresIn, 10) : undefined, // Convert string to number
113
+ timestamp: timestamp ? parseInt(timestamp, 10) : undefined, // Convert string to number
114
+ };
115
+ }
116
+ export async function validateOauth2Tokens(tokens, endpoints, oauth2Client, issuer) {
117
+ const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));
118
+ // validate the ID token
119
+ const idTokenResponse = await jose.jwtVerify(tokens.id_token, JWKS, {
120
+ issuer: getIssuerVariations(issuer),
121
+ audience: oauth2Client.clientId,
122
+ });
123
+ // validate the access token
124
+ const accessTokenResponse = await jose.jwtVerify(tokens.access_token, JWKS, {
125
+ issuer: getIssuerVariations(issuer),
126
+ });
127
+ return withoutUndefined({
128
+ id_token: idTokenResponse.payload,
129
+ access_token: accessTokenResponse.payload,
130
+ refresh_token: tokens.refresh_token,
131
+ });
132
+ }
133
+ //# sourceMappingURL=util.js.map
@@ -0,0 +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 JWTPayload,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport { OAuthTokens } 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\";\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 scopes: string[];\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n // TODO TECH-676: Implement logout\n console.log(\"generateOauthLogoutUrl not implemented\", config);\n return new URL(\"http://localhost\");\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(tokens, endpoints, oauth2Client, oauthServer);\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 async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // store tokens in storage ( TODO we should probably store them against the state to allow multiple logins )\n await storage.set(OAuthTokens.ID_TOKEN, tokens.id_token);\n await storage.set(OAuthTokens.ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token) {\n await storage.set(OAuthTokens.REFRESH_TOKEN, tokens.refresh_token);\n }\n if (tokens.expires_in) {\n await storage.set(OAuthTokens.EXPIRES_IN, tokens.expires_in.toString());\n await storage.set(OAuthTokens.TIMESTAMP, new Date().getTime().toString());\n }\n}\n\nexport async function clearTokens(storage: AuthStorage) {\n const clearOAuthPromises = Object.values(OAuthTokens).map(async (key) => {\n await storage.set(key, \"\");\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n console.log(\"clearUser\");\n await userSession.set(null);\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<OIDCTokenResponseBody | null> {\n const idToken = await storage.get(OAuthTokens.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokens.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokens.REFRESH_TOKEN);\n const expiresIn = await storage.get(OAuthTokens.EXPIRES_IN);\n const timestamp = await storage.get(OAuthTokens.TIMESTAMP);\n\n if (!idToken || !accessToken) return null;\n\n return {\n id_token: idToken,\n access_token: accessToken,\n refresh_token: refreshToken ?? undefined,\n expires_in: expiresIn ? parseInt(expiresIn, 10) : undefined, // Convert string to number\n timestamp: timestamp ? parseInt(timestamp, 10) : undefined, // Convert string to number\n };\n}\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n endpoints: Endpoints,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));\n\n // validate the ID token\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n JWKS,\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 JWKS,\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"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/AuthContext.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AACF,eAAO,MAAM,WAAW,iDAA8C,CAAC"}
@@ -0,0 +1,21 @@
1
+ import React, { type ReactNode } from "react";
2
+ import type { Config, SessionData } from "@/types.js";
3
+ import type { PKCEConsumer } from "@/services/types.js";
4
+ export type IframeMode = "embedded" | "modal";
5
+ export type AuthProviderProps = {
6
+ children: ReactNode;
7
+ clientId: string;
8
+ nonce?: string;
9
+ onSignIn?: (error?: Error) => void;
10
+ onSignOut?: () => Promise<void>;
11
+ iframeMode?: IframeMode;
12
+ config?: Config;
13
+ redirectUrl?: string;
14
+ };
15
+ export type InternalAuthProviderProps = AuthProviderProps & {
16
+ sessionData?: SessionData;
17
+ pkceConsumer?: PKCEConsumer;
18
+ };
19
+ declare const AuthProvider: ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode, }: InternalAuthProviderProps) => React.JSX.Element;
20
+ export { AuthProvider };
21
+ //# sourceMappingURL=AuthProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/AuthProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAgC,MAAM,OAAO,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAkBxD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAC9C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,QAAA,MAAM,YAAY,iEAMf,yBAAyB,sBA6D3B,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,63 @@
1
+ "use client";
2
+ import React, { useEffect, useMemo, useState } from "react";
3
+ import { AuthContext } from "@/shared/providers/AuthContext.js";
4
+ import { useSignIn } from "@/shared/hooks/useSignIn.js";
5
+ import { useIframe } from "@/shared/hooks/useIframe.js";
6
+ import { useCivicAuthConfig } from "@/shared/hooks/useCivicAuthConfig.js";
7
+ import { useSession } from "@/shared/hooks/useSession.js";
8
+ import { IFrameAndLoading } from "@/shared/components/IFrameAndLoading.js";
9
+ // Global this object setup
10
+ let globalThisObject;
11
+ if (typeof window !== "undefined") {
12
+ globalThisObject = window;
13
+ }
14
+ else if (typeof global !== "undefined") {
15
+ globalThisObject = global;
16
+ }
17
+ else {
18
+ globalThisObject = Function("return this")();
19
+ }
20
+ globalThisObject.globalThis = globalThisObject;
21
+ const AuthProvider = ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode = "modal", }) => {
22
+ const authConfig = useCivicAuthConfig();
23
+ const { redirectUrl } = authConfig || {};
24
+ const { iframeRef } = useIframe();
25
+ const { signIn, signOut } = useSignIn({
26
+ preSignOut: onSignOut,
27
+ pkceConsumer,
28
+ });
29
+ const [localSessionData, setLocalSessionData] = useState();
30
+ const { data: session, error: tokenExchangeError, isLoading: tokenExchangeInProgress, } = useSession();
31
+ useEffect(() => {
32
+ if (session) {
33
+ setLocalSessionData(session);
34
+ if (session.authenticated) {
35
+ onSignIn?.();
36
+ }
37
+ }
38
+ }, [onSignIn, session]);
39
+ const isAuthenticated = useMemo(() => {
40
+ return !!localSessionData?.idToken;
41
+ }, [localSessionData]);
42
+ useEffect(() => {
43
+ if (iframeMode === "embedded" &&
44
+ redirectUrl &&
45
+ !isAuthenticated &&
46
+ iframeRef?.current) {
47
+ signIn("iframe");
48
+ }
49
+ }, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]);
50
+ const isLoading = tokenExchangeInProgress || !authConfig;
51
+ const value = useMemo(() => ({
52
+ isLoading,
53
+ error: tokenExchangeError,
54
+ signOut,
55
+ isAuthenticated,
56
+ signIn,
57
+ }), [isLoading, tokenExchangeError, isAuthenticated, signIn, signOut]);
58
+ return (React.createElement(AuthContext.Provider, { value: value },
59
+ React.createElement(IFrameAndLoading, { error: tokenExchangeError, isLoading: isLoading }),
60
+ children));
61
+ };
62
+ export { AuthProvider };
63
+ //# sourceMappingURL=AuthProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../../../../src/shared/providers/AuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport React, { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport type { Config, SessionData } from \"@/types.js\";\nimport { AuthContext } from \"@/shared/providers/AuthContext.js\";\nimport type { PKCEConsumer } from \"@/services/types.js\";\nimport { useSignIn } from \"@/shared/hooks/useSignIn.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport { useSession } from \"@/shared/hooks/useSession.js\";\nimport { IFrameAndLoading } from \"@/shared/components/IFrameAndLoading.js\";\n\n// Global this object setup\nlet globalThisObject;\nif (typeof window !== \"undefined\") {\n globalThisObject = window;\n} else if (typeof global !== \"undefined\") {\n globalThisObject = global;\n} else {\n globalThisObject = Function(\"return this\")();\n}\nglobalThisObject.globalThis = globalThisObject;\n\nexport type IframeMode = \"embedded\" | \"modal\";\nexport type AuthProviderProps = {\n children: ReactNode;\n clientId: string;\n nonce?: string;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => Promise<void>;\n iframeMode?: IframeMode;\n config?: Config;\n redirectUrl?: string;\n};\n\nexport type InternalAuthProviderProps = AuthProviderProps & {\n sessionData?: SessionData;\n pkceConsumer?: PKCEConsumer;\n};\n\nconst AuthProvider = ({\n children,\n onSignIn,\n onSignOut,\n pkceConsumer,\n iframeMode = \"modal\",\n}: InternalAuthProviderProps) => {\n const authConfig = useCivicAuthConfig();\n const { redirectUrl } = authConfig || {};\n const { iframeRef } = useIframe();\n\n const { signIn, signOut } = useSignIn({\n preSignOut: onSignOut,\n pkceConsumer,\n });\n\n const [localSessionData, setLocalSessionData] =\n useState<SessionData | null>();\n\n const {\n data: session,\n error: tokenExchangeError,\n isLoading: tokenExchangeInProgress,\n } = useSession();\n\n useEffect(() => {\n if (session) {\n setLocalSessionData(session);\n if (session.authenticated) {\n onSignIn?.();\n }\n }\n }, [onSignIn, session]);\n\n const isAuthenticated = useMemo(() => {\n return !!localSessionData?.idToken;\n }, [localSessionData]);\n\n useEffect(() => {\n if (\n iframeMode === \"embedded\" &&\n redirectUrl &&\n !isAuthenticated &&\n iframeRef?.current\n ) {\n signIn(\"iframe\");\n }\n }, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]);\n\n const isLoading = tokenExchangeInProgress || !authConfig;\n const value = useMemo(\n () => ({\n isLoading,\n error: tokenExchangeError as Error | null,\n signOut,\n isAuthenticated,\n signIn,\n }),\n [isLoading, tokenExchangeError, isAuthenticated, signIn, signOut],\n );\n\n return (\n <AuthContext.Provider value={value}>\n <IFrameAndLoading error={tokenExchangeError} isLoading={isLoading} />\n {children}\n </AuthContext.Provider>\n );\n};\n\nexport { AuthProvider };\n"]}
@@ -0,0 +1,16 @@
1
+ import React, { type ReactNode } from "react";
2
+ import type { CivicAuthConfig } from "../lib/types.js";
3
+ type CivicAuthConfigContextType = {
4
+ children: ReactNode;
5
+ oauthServer?: string;
6
+ clientId: string;
7
+ scopes?: string[];
8
+ redirectUrl?: string;
9
+ nonce?: string;
10
+ challengeUrl?: string;
11
+ logoutUrl?: string;
12
+ };
13
+ declare const CivicAuthConfigContext: React.Context<CivicAuthConfig>;
14
+ declare const CivicAuthConfigProvider: ({ children, oauthServer, clientId, redirectUrl: inputRedirectUrl, nonce, challengeUrl, logoutUrl, scopes, }: CivicAuthConfigContextType) => React.JSX.Element;
15
+ export { CivicAuthConfigProvider, CivicAuthConfigContext };
16
+ //# sourceMappingURL=CivicAuthConfigContext.d.ts.map
@@ -0,0 +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,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,sBAAsB,gCAAgD,CAAC;AAE7E,QAAA,MAAM,uBAAuB,gHAS1B,0BAA0B,sBA0C5B,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { DEFAULT_AUTH_SERVER, DEFAULT_SCOPES } from "@/constants.js";
3
+ import React, { createContext, useMemo } from "react";
4
+ import { useOAuthEndpoints } from "@/shared/hooks/useOAuthEndpoints.js";
5
+ import { useCurrentUrl } from "@/shared/hooks/useCurrentUrl.js";
6
+ const defaultConfig = null;
7
+ // Context for exposing Config specifically to the TokenProvider
8
+ const CivicAuthConfigContext = createContext(defaultConfig);
9
+ const CivicAuthConfigProvider = ({ children, oauthServer, clientId, redirectUrl: inputRedirectUrl, nonce, challengeUrl, logoutUrl, scopes, }) => {
10
+ const currentUrl = useCurrentUrl();
11
+ const redirectUrl = useMemo(() => {
12
+ const useUrl = inputRedirectUrl || currentUrl;
13
+ if (useUrl) {
14
+ return `${useUrl.split("?")[0]}`;
15
+ }
16
+ return "";
17
+ }, [currentUrl, inputRedirectUrl]);
18
+ const endpoints = useOAuthEndpoints(oauthServer);
19
+ const value = useMemo(() => endpoints
20
+ ? {
21
+ clientId,
22
+ redirectUrl,
23
+ oauthServer: oauthServer || DEFAULT_AUTH_SERVER,
24
+ endpoints,
25
+ nonce,
26
+ challengeUrl,
27
+ logoutUrl,
28
+ scopes: scopes || DEFAULT_SCOPES,
29
+ }
30
+ : null, [
31
+ clientId,
32
+ redirectUrl,
33
+ oauthServer,
34
+ endpoints,
35
+ nonce,
36
+ challengeUrl,
37
+ logoutUrl,
38
+ scopes,
39
+ ]);
40
+ return (React.createElement(CivicAuthConfigContext.Provider, { value: value }, children));
41
+ };
42
+ export { CivicAuthConfigProvider, CivicAuthConfigContext };
43
+ //# sourceMappingURL=CivicAuthConfigContext.js.map
@@ -0,0 +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;AAY5C,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,SAAS,EACT,MAAM,GACqB,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,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,SAAS;YACT,MAAM,EAAE,MAAM,IAAI,cAAc;SACjC;QACH,CAAC,CAAC,IAAI,EACV;QACE,QAAQ;QACR,WAAW;QACX,WAAW;QACX,SAAS;QACT,KAAK;QACL,YAAY;QACZ,SAAS;QACT,MAAM;KACP,CACF,CAAC;IACF,OAAO,CACL,oBAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IAC1C,QAAQ,CACuB,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 nonce?: string;\n challengeUrl?: string;\n logoutUrl?: 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 logoutUrl,\n scopes,\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 value = useMemo(\n () =>\n endpoints\n ? {\n clientId,\n redirectUrl,\n oauthServer: oauthServer || DEFAULT_AUTH_SERVER,\n endpoints,\n nonce,\n challengeUrl,\n logoutUrl,\n scopes: scopes || DEFAULT_SCOPES,\n }\n : null,\n [\n clientId,\n redirectUrl,\n oauthServer,\n endpoints,\n nonce,\n challengeUrl,\n logoutUrl,\n scopes,\n ],\n );\n return (\n <CivicAuthConfigContext.Provider value={value}>\n {children}\n </CivicAuthConfigContext.Provider>\n );\n};\n\nexport { CivicAuthConfigProvider, CivicAuthConfigContext };\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CivicAuthProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oCAAoC,CAAC;AAY5C,KAAK,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAkCtE,QAAA,MAAM,iBAAiB,2BAA4B,sBAAsB,sBAexE,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import React from "react";
3
+ import { AuthProvider, } from "@/shared/providers/AuthProvider.js";
4
+ import { BrowserPublicClientPKCEProducer } from "@/services/PKCE.js";
5
+ import { UserProvider } from "@/shared/providers/UserProvider.js";
6
+ import { LocalStorageAdapter } from "@/browser/storage.js";
7
+ import { CivicAuthConfigProvider } from "@/shared/providers/CivicAuthConfigContext.js";
8
+ import { IframeProvider } from "@/shared/providers/IframeProvider.js";
9
+ import { ClientTokenExchangeSessionProvider } from "@/shared/providers/ClientTokenExchangeSessionProvider.js";
10
+ import { SessionProvider } from "@/shared/providers/SessionProvider.js";
11
+ import { useClientTokenExchangeSession } from "@/shared/hooks/useClientTokenExchangeSession.js";
12
+ import { TokenProvider } from "@/shared/providers/TokenProvider.js";
13
+ import { useAuth } from "@/shared/hooks/useAuth.js";
14
+ const WrapperUserProvider = ({ children }) => {
15
+ const { signIn, signOut } = useAuth();
16
+ return (React.createElement(UserProvider, { storage: new LocalStorageAdapter(), signIn: signIn, signOut: signOut }, children));
17
+ };
18
+ const WrapperSessionAuthProvider = ({ children, ...props }) => {
19
+ const sessionData = useClientTokenExchangeSession();
20
+ return (React.createElement(SessionProvider, { ...sessionData },
21
+ React.createElement(IframeProvider, { iframeMode: props.iframeMode },
22
+ React.createElement(AuthProvider, { ...props, pkceConsumer: new BrowserPublicClientPKCEProducer() },
23
+ React.createElement(TokenProvider, null,
24
+ React.createElement(WrapperUserProvider, null, children))))));
25
+ };
26
+ const CivicAuthProvider = ({ children, ...props }) => {
27
+ return (React.createElement(CivicAuthConfigProvider, { oauthServer: props?.config?.oauthServer, clientId: props?.clientId, redirectUrl: props?.redirectUrl, nonce: props?.nonce },
28
+ React.createElement(ClientTokenExchangeSessionProvider, null,
29
+ React.createElement(WrapperSessionAuthProvider, { ...props }, children))));
30
+ };
31
+ export { CivicAuthProvider };
32
+ //# sourceMappingURL=CivicAuthProvider.js.map