@civic/auth 0.10.0-beta.7 → 0.10.0-beta.9

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 (60) hide show
  1. package/dist/browser/storage.d.ts +1 -0
  2. package/dist/browser/storage.d.ts.map +1 -1
  3. package/dist/browser/storage.js +3 -0
  4. package/dist/browser/storage.js.map +1 -1
  5. package/dist/nextjs/config.d.ts +29 -0
  6. package/dist/nextjs/config.d.ts.map +1 -1
  7. package/dist/nextjs/config.js +53 -24
  8. package/dist/nextjs/config.js.map +1 -1
  9. package/dist/nextjs/cookies.d.ts.map +1 -1
  10. package/dist/nextjs/cookies.js +16 -1
  11. package/dist/nextjs/cookies.js.map +1 -1
  12. package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -1
  13. package/dist/nextjs/hooks/useInitialAuthConfig.js +17 -10
  14. package/dist/nextjs/hooks/useInitialAuthConfig.js.map +1 -1
  15. package/dist/nextjs/middleware.d.ts.map +1 -1
  16. package/dist/nextjs/middleware.js +17 -6
  17. package/dist/nextjs/middleware.js.map +1 -1
  18. package/dist/nextjs/providers/NextAuthProviderClient.js +1 -1
  19. package/dist/nextjs/providers/NextAuthProviderClient.js.map +1 -1
  20. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  21. package/dist/nextjs/routeHandler.js +4 -12
  22. package/dist/nextjs/routeHandler.js.map +1 -1
  23. package/dist/nextjs/utils.d.ts +3 -7
  24. package/dist/nextjs/utils.d.ts.map +1 -1
  25. package/dist/nextjs/utils.js +30 -26
  26. package/dist/nextjs/utils.js.map +1 -1
  27. package/dist/reactjs/core/GlobalAuthManager.d.ts +5 -2
  28. package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
  29. package/dist/reactjs/core/GlobalAuthManager.js +21 -6
  30. package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
  31. package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
  32. package/dist/reactjs/hooks/useUser.js +79 -127
  33. package/dist/reactjs/hooks/useUser.js.map +1 -1
  34. package/dist/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -1
  35. package/dist/shared/lib/BrowserAuthenticationRefresher.js +5 -0
  36. package/dist/shared/lib/BrowserAuthenticationRefresher.js.map +1 -1
  37. package/dist/shared/lib/UserSession.d.ts +4 -3
  38. package/dist/shared/lib/UserSession.d.ts.map +1 -1
  39. package/dist/shared/lib/UserSession.js +4 -0
  40. package/dist/shared/lib/UserSession.js.map +1 -1
  41. package/dist/shared/lib/cookieUtils.d.ts +6 -0
  42. package/dist/shared/lib/cookieUtils.d.ts.map +1 -0
  43. package/dist/shared/lib/cookieUtils.js +21 -0
  44. package/dist/shared/lib/cookieUtils.js.map +1 -0
  45. package/dist/shared/lib/session.d.ts.map +1 -1
  46. package/dist/shared/lib/session.js +6 -0
  47. package/dist/shared/lib/session.js.map +1 -1
  48. package/dist/shared/version.d.ts +1 -1
  49. package/dist/shared/version.js +1 -1
  50. package/dist/shared/version.js.map +1 -1
  51. package/dist/types.d.ts +3 -0
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/types.js.map +1 -1
  54. package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -1
  55. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +6 -2
  56. package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -1
  57. package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
  58. package/dist/vanillajs/auth/SessionManager.js +21 -14
  59. package/dist/vanillajs/auth/SessionManager.js.map +1 -1
  60. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalAuthManager.js","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EACL,SAAS,EACT,oBAAoB,EACpB,SAAS,GACV,MAAM,0BAA0B,CAAC;AASlC,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AAqDvF;;;GAGG;AACH,MAAM,iBAAiB;IACb,MAAM,CAAC,QAAQ,GAA6B,IAAI,CAAC;IACjD,IAAI,GAAqB,IAAI,CAAC;IAC9B,MAAM,GAAgC,IAAI,CAAC;IAC3C,MAAM,GAA4B,IAAI,CAAC;IACvC,SAAS,GAAG,IAAI,GAAG,EAAiB,CAAC;IACrC,SAAS,GAIb,EAAE,CAAC;IACC,qBAAqB,GAAyB,IAAI,CAAC;IAEnD,KAAK,GAAoB;QAC/B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE,iBAAiB;QAC7B,KAAK,EAAE,IAAI;QACX,WAAW,EAAE,SAAS;KACvB,CAAC;IAEF;QACE,oCAAoC;IACtC,CAAC;IAED,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;YAChC,iBAAiB,CAAC,QAAQ,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACvD,CAAC;QACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,MAAwB;QACvC,gEAAgE;QAChE,IACE,IAAI,CAAC,qBAAqB;YAC1B,IAAI,CAAC,MAAM;YACX,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EACzB,CAAC;YACD,OAAO,IAAI,CAAC,qBAAqB,CAAC;QACpC,CAAC;QAED,wCAAwC;QACxC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAClC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAED,8CAA8C;QAC9C,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;IAEO,kBAAkB,CAAC,GAAW,EAAE,MAAe;QACrD,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACvE,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAC;IAC7B,CAAC;IACD;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,MAAwB;QAClD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG;YACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,kBAAkB;SAC3D,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhD,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;YACzC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE3B,4CAA4C;YAC5C,MAAM,UAAU,GAAG;gBACjB,GAAG,MAAM;gBACT,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW;gBAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI;oBACvB,QAAQ;oBACR,SAAS;oBACT,OAAO;oBACP,gBAAgB;iBACjB;gBACD,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,QAAQ;gBAC3C,iBAAiB,EAAE,MAAM,CAAC,UAAU,IAAI,OAAO;gBAC/C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,kBAAkB,EAChB,MAAM,CAAC,kBAAkB,IAAI,4BAA4B;gBAC3D,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC;YAEF,8DAA8D;YAC9D,MAAM,UAAU,GAA0B,MAAM,CAAC,QAAQ;gBACvD,CAAC,CAAC;oBACE,iEAAiE;oBACjE,GAAG,UAAU;oBACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B;gBACH,CAAC,CAAC;oBACE,4DAA4D;oBAC5D,GAAG,UAAU;oBACb,QAAQ,EAAE,MAAM,CAAC,QAAS;oBAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC;YAEN,mCAAmC;YACnC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,UAAU,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;YAC9C,CAAC;YAED,yCAAyC;YACzC,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;gBAC7B,UAAU,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;YAC1D,CAAC;YAED,uCAAuC;YACvC,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;gBAC3B,UAAU,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;YACtD,CAAC;YAED,IAAI,CAAC,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAE/C,2BAA2B;YAC3B,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAE1D,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBACnC,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,eAAe,EAAE,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC,CAAC;gBAEjD,2FAA2F;YAC7F,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC;gBACZ,SAAS,EAAE,KAAK;gBAChB,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,8CAA8C;YAC9C,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAElC,MAAM,SAAS,GACb,KAAK,YAAY,KAAK;gBACpB,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC9C,IAAI,CAAC,QAAQ,CAAC;gBACZ,KAAK,EAAE,SAAS;gBAChB,UAAU,EAAE,OAAO;gBACnB,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YACH,MAAM,SAAS,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,QAAuB;QAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAEzD,qDAAqD;QACrD,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,QAAQ,CAAC;gBACZ,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,UAAU,EAAE,eAAe;gBAC3B,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;QACnC,CAAC;QAED,iDAAiD;QACjD,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAEnC,qDAAqD;QACrD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAErC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QAED,4CAA4C;QAC5C,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC;YACZ,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,iBAAiB;SAC9B,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,yBAAyB;QACvB,OAAO,IAAI,CAAC,IAAI,EAAE,yBAAyB,EAAE,IAAI,KAAK,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,OAAgB;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,IAAI,CAAC;IAChD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QAEvB,uCAAuC;QACvC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAE3B,oEAAoE;QACpE,IAAI,CAAC,QAAQ,CAAC;YACZ,UAAU,EAAE,iBAAiB;YAC7B,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,wDAAwD;QACxD,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,SAA2B;QAC9C,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC/B,OAAO,CACL,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ;YAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,KAAK,SAAS,CAAC,MAAM,EAAE,WAAW;YACjE,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW;YACjD,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK;YACrC,IAAI,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,aAAa;YACrD,IAAI,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,YAAY,CACpD,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,mBAAmB;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,GAAG,EAAE;YAC7C,IAAI,CAAC,QAAQ,CAAC;gBACZ,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,gBAAgB;gBAC5B,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,GAAG,EAAE;YAC9C,IAAI,CAAC,QAAQ,CAAC;gBACZ,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE,eAAe;gBAC3B,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,KAAwB,EAAE,EAAE;YACnE,MAAM,WAAW,GAAG,KAAK,EAAE,MAAM,IAAI,uBAAuB,CAAC;YAC7D,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC;gBACZ,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE,OAAO;gBACnB,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,GAAG,EAAE;YAC9C,IAAI,CAAC,QAAQ,CAAC;gBACZ,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,aAAa;gBACzB,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,GAAG,EAAE;YAC/C,IAAI,CAAC,QAAQ,CAAC;gBACZ,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE,iBAAiB;gBAC7B,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAClD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,SAAS,CAAC,UAAU,EACpB,CAAC,KAA0D,EAAE,EAAE;YAC7D,IAAI,CAAC,QAAQ,CAAC;gBACZ,UAAU,EAAE,gBAAgB,EAAE,iDAAiD;gBAC/E,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,6CAA6C;YAC7C,IAAI,KAAK,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;gBAC7C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACtD,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QAEvB,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACxC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;gBAC7B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;aAC3B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACtE,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,OAAiC;QAChD,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,OAAO;QACnB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC,4CAA4C;IACjF,CAAC;;AAGH,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["/**\n * GlobalAuthManager - Singleton Authentication State Manager\n *\n * This module provides a global singleton that manages authentication state across a React application\n * without requiring React Context providers or prop drilling. It acts as a centralized authentication\n * manager that wraps the CivicAuth vanilla JavaScript library and provides a React-friendly interface.\n *\n * Key Features:\n * - Singleton pattern ensures single auth instance across the entire app\n * - Eliminates need for React Context providers and reduces bundle size\n * - Manages authentication state (user, session, loading, errors)\n * - Handles sign-in/sign-out flows with event-driven updates\n * - Provides idempotent initialization (safe to call multiple times)\n * - Supports multiple React hooks subscribing to the same auth state\n * - Automatic session refresh and user data synchronization\n *\n * Usage:\n * - Initialize once in your app with authentication configuration\n * - Use React hooks (useCivicAuth, useAuth, etc.) to access auth state\n * - The manager handles all underlying CivicAuth SDK interactions\n * - State updates are automatically propagated to all subscribed components\n *\n * This design pattern is particularly useful for:\n * - Large applications with many components needing auth state\n * - Avoiding provider wrapper hell in React component trees\n * - Ensuring consistent auth state across disconnected component hierarchies\n * - Server-side rendering scenarios where providers might be problematic\n */\n\nimport {\n CivicAuth,\n AuthenticationEvents,\n AuthEvent,\n} from \"../../vanillajs/index.js\";\nimport type {\n User,\n Session,\n CivicAuthClientConfig,\n} from \"../../vanillajs/index.js\";\nimport type { FrameworkType } from \"../../types.js\";\nimport type { VanillaJSDisplayMode } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { LoggingConfig } from \"@/vanillajs/auth/types/AuthTypes.js\";\nimport { DEFAULT_AUTH_PROCESS_TIMEOUT } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { BackendEndpoints } from \"@/server/config.js\";\n\n// Event payload interfaces\ninterface SignInErrorEvent {\n detail: string;\n}\n\nexport interface GlobalAuthConfig {\n clientId?: string;\n redirectUrl?: string;\n loginUrl?: string;\n config?: {\n oauthServer?: string;\n };\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: \"modal\" | \"embedded\";\n nonce?: string;\n logoutRedirectUrl?: string;\n scopes?: string[];\n authProcessTimeout?: number;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n logging?: LoggingConfig;\n preloadIframe?: boolean;\n autoRedirect?: boolean;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n backendEndpoints?: BackendEndpoints;\n targetContainerElement?: HTMLElement | string;\n loginSuccessUrl?: string;\n}\n\nexport type AuthStatus =\n | \"authenticated\"\n | \"unauthenticated\"\n | \"authenticating\"\n | \"error\"\n | \"signing_out\";\n\nexport interface GlobalAuthState {\n user: User | null;\n session: Session | null;\n isLoading: boolean;\n authStatus: AuthStatus;\n error: Error | null;\n displayMode?: VanillaJSDisplayMode;\n isPreloaded?: boolean;\n}\n\ntype StateListener = (state: GlobalAuthState) => void;\n\n/**\n * Global singleton that manages CivicAuth instance for React hooks\n * Eliminates the need for React providers\n */\nclass GlobalAuthManager {\n private static instance: GlobalAuthManager | null = null;\n private auth: CivicAuth | null = null;\n private events: AuthenticationEvents | null = null;\n private config: GlobalAuthConfig | null = null;\n private listeners = new Set<StateListener>();\n private callbacks: {\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n } = {};\n private initializationPromise: Promise<void> | null = null;\n\n private state: GlobalAuthState = {\n user: null,\n session: null,\n isLoading: false,\n authStatus: \"unauthenticated\",\n error: null,\n displayMode: undefined,\n };\n\n private constructor() {\n // Private constructor for singleton\n }\n\n static getInstance(): GlobalAuthManager {\n if (!GlobalAuthManager.instance) {\n GlobalAuthManager.instance = new GlobalAuthManager();\n }\n return GlobalAuthManager.instance;\n }\n\n /**\n * Initialize auth with config (idempotent)\n * Returns the same promise for concurrent calls with same config\n */\n async initialize(config: GlobalAuthConfig): Promise<void> {\n // If we have a promise and same config, return existing promise\n if (\n this.initializationPromise &&\n this.config &&\n this.isSameConfig(config)\n ) {\n return this.initializationPromise;\n }\n\n // If different config, reset everything\n if (this.config && !this.isSameConfig(config)) {\n this.initializationPromise = null;\n await this.cleanup();\n }\n\n // Create new initialization promise if needed\n if (!this.initializationPromise) {\n this.initializationPromise = this._doInitialize(config);\n }\n\n return this.initializationPromise;\n }\n\n private defaultOnUrlChange(url: string, source?: string) {\n console.log(\"onUrlChange triggering window redirect\", { url, source });\n window.location.href = url;\n }\n /**\n * Private method that does the actual initialization work\n */\n private async _doInitialize(config: GlobalAuthConfig): Promise<void> {\n this.config = config;\n this.callbacks = {\n onSignIn: config.onSignIn,\n onSignOut: config.onSignOut,\n onUrlChange: config.onUrlChange || this.defaultOnUrlChange,\n };\n this.setState({ isLoading: true, error: null });\n\n try {\n this.events = new AuthenticationEvents();\n this.setupEventListeners();\n\n // Build base config common to both branches\n const baseConfig = {\n ...config,\n oauthServerBaseUrl: config.config?.oauthServer,\n scopes: config.scopes || [\n \"openid\",\n \"profile\",\n \"email\",\n \"offline_access\",\n ],\n displayMode: config.displayMode || \"iframe\",\n iframeDisplayMode: config.iframeMode || \"modal\",\n nonce: config.nonce,\n authProcessTimeout:\n config.authProcessTimeout || DEFAULT_AUTH_PROCESS_TIMEOUT,\n preloadIframe: config.preloadIframe,\n autoRedirect: config.autoRedirect,\n events: this.events,\n framework: config.framework,\n };\n\n // Build auth config based on discriminated union requirements\n const authConfig: CivicAuthClientConfig = config.loginUrl\n ? {\n // Backend integration mode: loginUrl required, clientId optional\n ...baseConfig,\n loginUrl: config.loginUrl,\n clientId: config.clientId,\n }\n : {\n // Standard OAuth mode: clientId required, loginUrl optional\n ...baseConfig,\n clientId: config.clientId!,\n loginUrl: config.loginUrl,\n };\n\n // Only add redirectUrl if provided\n if (config.redirectUrl) {\n authConfig.redirectUrl = config.redirectUrl;\n }\n\n // Only add logoutRedirectUrl if provided\n if (config.logoutRedirectUrl) {\n authConfig.logoutRedirectUrl = config.logoutRedirectUrl;\n }\n\n // Only add loginSuccessUrl if provided\n if (config.loginSuccessUrl) {\n authConfig.loginSuccessUrl = config.loginSuccessUrl;\n }\n\n this.auth = await CivicAuth.create(authConfig);\n\n // Check initial auth state\n const isAuthenticated = await this.auth.isAuthenticated();\n\n if (isAuthenticated) {\n await this.refreshUserAndSession();\n this.setState({ authStatus: \"authenticated\" });\n } else {\n this.setState({ authStatus: \"unauthenticated\" });\n\n // Note: Preloading is now handled automatically by CivicAuth based on config.preloadIframe\n }\n\n this.setState({\n isLoading: false,\n displayMode: config.displayMode,\n });\n } catch (error) {\n // Reset promise on error so it can be retried\n this.initializationPromise = null;\n\n const authError =\n error instanceof Error\n ? error\n : new Error(\"Auth initialization failed\");\n this.setState({\n error: authError,\n authStatus: \"error\",\n isLoading: false,\n });\n throw authError;\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: StateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Get current state\n */\n getState(): GlobalAuthState {\n return { ...this.state };\n }\n\n /**\n * Get current configuration\n * Returns the current config or null if not initialized\n */\n getConfig(): GlobalAuthConfig | null {\n return this.config ? { ...this.config } : null;\n }\n\n /**\n * Sign in\n */\n async signIn(): Promise<{ user: User }> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n const authResult = await this.auth.startAuthentication();\n\n // If authentication returned a user, use it directly\n if (authResult.user) {\n this.setState({\n user: authResult.user,\n authStatus: \"authenticated\",\n error: null,\n });\n return { user: authResult.user };\n }\n\n // Fallback: try to refresh user and session data\n await this.refreshUserAndSession();\n\n // Check the current state for the user after refresh\n const currentState = this.getState();\n\n if (!currentState.user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n // Return the user object from current state\n return { user: currentState.user };\n }\n\n /**\n * Sign out\n */\n async signOut(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n await this.auth.logout();\n this.setState({\n user: null,\n session: null,\n authStatus: \"unauthenticated\",\n });\n }\n\n /**\n * Check if authentication is preloaded and ready for instant sign-in\n * @returns True if an iframe is preloaded and ready\n */\n isAuthenticationPreloaded(): boolean {\n return this.auth?.isAuthenticationPreloaded() ?? false;\n }\n\n /**\n * Enable or disable iframe preloading\n */\n setPreloadEnabled(enabled: boolean): void {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n this.auth.setPreloadEnabled(enabled);\n }\n\n /**\n * Check if iframe preloading is enabled\n */\n getPreloadEnabled(): boolean {\n return this.auth?.getPreloadEnabled() ?? true;\n }\n\n /**\n * Reloads embedded authentication interface\n *\n * This method is specifically designed for embedded mode scenarios where the iframe\n * needs to be recreated after navigation or DOM changes. It delegates to the\n * underlying CivicAuth instance's reloadEmbedded method.\n *\n * @returns Promise that resolves when the embedded iframe is created\n * @throws {Error} If not in embedded mode or if auth is not initialized\n */\n async reloadEmbedded(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized. Call initialize() first.\");\n }\n\n return this.auth.reloadEmbedded();\n }\n\n /**\n * Reset authentication state when detected from back-forward cache (bfcache)\n * This fixes issues where sign-in button becomes unclickable after back navigation\n */\n resetOnBfcache(): void {\n if (!this.auth) return;\n\n // Reset internal CivicAuth state first\n this.auth.resetOnBfcache();\n\n // Reset auth state to unauthenticated to allow new sign-in attempts\n this.setState({\n authStatus: \"unauthenticated\",\n isLoading: false,\n error: null,\n user: null,\n session: null,\n });\n\n // Ensure iframe preloading state is refreshed if needed\n if (this.getPreloadEnabled()) {\n this.auth.setPreloadEnabled(true);\n }\n }\n\n /**\n * Check if config is the same (for idempotent initialization)\n */\n private isSameConfig(newConfig: GlobalAuthConfig): boolean {\n if (!this.config) return false;\n return (\n this.config.clientId === newConfig.clientId &&\n this.config.config?.oauthServer === newConfig.config?.oauthServer &&\n this.config.displayMode === newConfig.displayMode &&\n this.config.nonce === newConfig.nonce &&\n this.config.preloadIframe === newConfig.preloadIframe &&\n this.config.autoRedirect === newConfig.autoRedirect\n );\n }\n\n /**\n * Setup event listeners for auth state changes\n */\n private setupEventListeners(): void {\n if (!this.events) return;\n\n this.events.on(AuthEvent.SIGN_IN_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"authenticating\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_IN_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"authenticated\",\n error: null,\n });\n this.refreshUserAndSession();\n this.callbacks.onSignIn?.();\n });\n\n this.events.on(AuthEvent.SIGN_IN_ERROR, (event?: SignInErrorEvent) => {\n const errorDetail = event?.detail || \"Authentication failed\";\n const authError = new Error(errorDetail);\n this.setState({\n isLoading: false,\n authStatus: \"error\",\n error: authError,\n });\n this.callbacks.onSignIn?.(authError);\n });\n\n this.events.on(AuthEvent.SIGN_OUT_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"signing_out\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_OUT_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"unauthenticated\",\n user: null,\n session: null,\n error: null,\n });\n this.callbacks.onSignOut?.();\n });\n\n this.events.on(AuthEvent.USER_SESSION_CHANGED, () => {\n this.refreshUserAndSession();\n });\n\n this.events.on(\n AuthEvent.URL_CHANGE,\n (event?: { detail?: string; url?: string; source?: string }) => {\n this.setState({\n authStatus: \"authenticating\", // Keep as authenticating since we're redirecting\n error: null,\n });\n // Call custom URL change handler if provided\n if (event?.url && this.callbacks.onUrlChange) {\n this.callbacks.onUrlChange(event.url, event.source);\n }\n },\n );\n }\n\n /**\n * Refresh user and session data\n */\n private async refreshUserAndSession(): Promise<void> {\n if (!this.auth) return;\n\n try {\n const [session, user] = await Promise.all([\n this.auth.getCurrentSession(),\n this.auth.getCurrentUser(),\n ]);\n\n this.setState({ session, user });\n } catch (error) {\n const sessionError =\n error instanceof Error ? error : new Error(\"Failed to get session\");\n this.setState({ error: sessionError });\n }\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<GlobalAuthState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach((listener) => listener(this.state));\n }\n\n /**\n * Cleanup auth instance\n */\n private async cleanup(): Promise<void> {\n if (this.auth) {\n await this.auth.destroy();\n this.auth = null;\n }\n this.events = null;\n this.config = null;\n this.initializationPromise = null; // Reset promise for clean re-initialization\n }\n}\n\nexport { GlobalAuthManager };\n"]}
1
+ {"version":3,"file":"GlobalAuthManager.js","sourceRoot":"","sources":["../../../src/reactjs/core/GlobalAuthManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GlobalAuthManager - Singleton Authentication State Manager\n *\n * This module provides a global singleton that manages authentication state across a React application\n * without requiring React Context providers or prop drilling. It acts as a centralized authentication\n * manager that wraps the CivicAuth vanilla JavaScript library and provides a React-friendly interface.\n *\n * Key Features:\n * - Singleton pattern ensures single auth instance across the entire app\n * - Eliminates need for React Context providers and reduces bundle size\n * - Manages authentication state (user, session, loading, errors)\n * - Handles sign-in/sign-out flows with event-driven updates\n * - Provides idempotent initialization (safe to call multiple times)\n * - Supports multiple React hooks subscribing to the same auth state\n * - Automatic session refresh and user data synchronization\n *\n * Usage:\n * - Initialize once in your app with authentication configuration\n * - Use React hooks (useCivicAuth, useAuth, etc.) to access auth state\n * - The manager handles all underlying CivicAuth SDK interactions\n * - State updates are automatically propagated to all subscribed components\n *\n * This design pattern is particularly useful for:\n * - Large applications with many components needing auth state\n * - Avoiding provider wrapper hell in React component trees\n * - Ensuring consistent auth state across disconnected component hierarchies\n * - Server-side rendering scenarios where providers might be problematic\n */\n\nimport {\n CivicAuth,\n AuthenticationEvents,\n AuthEvent,\n} from \"../../vanillajs/index.js\";\nimport type {\n User,\n Session,\n CivicAuthClientConfig,\n} from \"../../vanillajs/index.js\";\nimport type { AuthStorage, FrameworkType } from \"../../types.js\";\nimport type { VanillaJSDisplayMode } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { LoggingConfig } from \"@/vanillajs/auth/types/AuthTypes.js\";\nimport { DEFAULT_AUTH_PROCESS_TIMEOUT } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { BackendEndpoints } from \"@/server/config.js\";\n\n// Event payload interfaces\ninterface SignInErrorEvent {\n detail: string;\n}\n\nexport interface GlobalAuthConfig {\n clientId?: string;\n redirectUrl?: string;\n loginUrl?: string;\n config?: {\n oauthServer?: string;\n };\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: \"modal\" | \"embedded\";\n nonce?: string;\n logoutRedirectUrl?: string;\n scopes?: string[];\n authProcessTimeout?: number;\n onRefresh?: (error?: Error) => void;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n logging?: LoggingConfig;\n preloadIframe?: boolean;\n autoRedirect?: boolean;\n /** Framework being used (for analytics) - internal use only */\n framework?: FrameworkType;\n backendEndpoints?: BackendEndpoints;\n targetContainerElement?: HTMLElement | string;\n loginSuccessUrl?: string;\n storage?: AuthStorage;\n initialUser?: User | null;\n}\n\nexport type AuthStatus =\n | \"authenticated\"\n | \"unauthenticated\"\n | \"authenticating\"\n | \"error\"\n | \"signing_out\";\n\nexport interface GlobalAuthState {\n user: User | null;\n session: Session | null;\n isLoading: boolean;\n authStatus: AuthStatus;\n error: Error | null;\n displayMode?: VanillaJSDisplayMode;\n isPreloaded?: boolean;\n}\n\ntype StateListener = (state: GlobalAuthState) => void;\n\n/**\n * Global singleton that manages CivicAuth instance for React hooks\n * Eliminates the need for React providers\n */\nclass GlobalAuthManager {\n private static instance: GlobalAuthManager | null = null;\n private auth: CivicAuth | null = null;\n private events: AuthenticationEvents | null = null;\n private config: GlobalAuthConfig | null = null;\n private listeners = new Set<StateListener>();\n private callbacks: {\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n onRefresh?: (error?: Error) => void;\n } = {};\n private initializationPromise: Promise<void> | null = null;\n\n private state: GlobalAuthState = {\n user: null,\n session: null,\n isLoading: false,\n authStatus: \"unauthenticated\",\n error: null,\n displayMode: undefined,\n };\n\n private constructor() {\n // Private constructor for singleton\n }\n\n static getInstance(): GlobalAuthManager {\n if (!GlobalAuthManager.instance) {\n GlobalAuthManager.instance = new GlobalAuthManager();\n }\n return GlobalAuthManager.instance;\n }\n\n /**\n * Initialize auth with config (idempotent)\n * Returns the same promise for concurrent calls with same config\n */\n async initialize(config: GlobalAuthConfig): Promise<void> {\n // If we have a promise and same config, return existing promise\n if (\n this.initializationPromise &&\n this.config &&\n this.isSameConfig(config)\n ) {\n return this.initializationPromise;\n }\n\n // If different config, reset everything\n if (this.config && !this.isSameConfig(config)) {\n this.initializationPromise = null;\n await this.cleanup();\n }\n\n // Create new initialization promise if needed\n if (!this.initializationPromise) {\n this.initializationPromise = this._doInitialize(config);\n }\n\n return this.initializationPromise;\n }\n\n private defaultOnUrlChange(url: string, source?: string) {\n console.log(\"onUrlChange triggering window redirect\", { url, source });\n window.location.href = url;\n }\n /**\n * Private method that does the actual initialization work\n */\n private async _doInitialize(config: GlobalAuthConfig): Promise<void> {\n this.config = config;\n this.callbacks = {\n onSignIn: config.onSignIn,\n onSignOut: config.onSignOut,\n onUrlChange: config.onUrlChange || this.defaultOnUrlChange,\n onRefresh: config.onRefresh,\n };\n this.setState({\n isLoading: true,\n error: null,\n ...(this.config.initialUser\n ? { user: this.config.initialUser, authStatus: \"authenticated\" }\n : {}), // Set initial user if provided\n });\n\n try {\n this.events = new AuthenticationEvents();\n this.setupEventListeners();\n\n // Build base config common to both branches\n const baseConfig = {\n ...config,\n oauthServerBaseUrl: config.config?.oauthServer,\n scopes: config.scopes || [\n \"openid\",\n \"profile\",\n \"email\",\n \"offline_access\",\n ],\n displayMode: config.displayMode || \"iframe\",\n iframeDisplayMode: config.iframeMode || \"modal\",\n nonce: config.nonce,\n authProcessTimeout:\n config.authProcessTimeout || DEFAULT_AUTH_PROCESS_TIMEOUT,\n preloadIframe: config.preloadIframe,\n autoRedirect: config.autoRedirect,\n events: this.events,\n framework: config.framework,\n };\n\n // Build auth config based on discriminated union requirements\n const authConfig: CivicAuthClientConfig = config.loginUrl\n ? {\n // Backend integration mode: loginUrl required, clientId optional\n ...baseConfig,\n loginUrl: config.loginUrl,\n clientId: config.clientId,\n }\n : {\n // Standard OAuth mode: clientId required, loginUrl optional\n ...baseConfig,\n clientId: config.clientId!,\n loginUrl: config.loginUrl,\n };\n\n // Only add redirectUrl if provided\n if (config.redirectUrl) {\n authConfig.redirectUrl = config.redirectUrl;\n }\n\n // Only add logoutRedirectUrl if provided\n if (config.logoutRedirectUrl) {\n authConfig.logoutRedirectUrl = config.logoutRedirectUrl;\n }\n\n // Only add loginSuccessUrl if provided\n if (config.loginSuccessUrl) {\n authConfig.loginSuccessUrl = config.loginSuccessUrl;\n }\n\n this.auth = await CivicAuth.create(authConfig);\n\n // Check initial auth state\n const isAuthenticated = await this.auth.isAuthenticated();\n\n if (isAuthenticated) {\n await this.updateUserAndSession();\n this.setState({ authStatus: \"authenticated\" });\n } else {\n this.setState({ authStatus: \"unauthenticated\" });\n\n // Note: Preloading is now handled automatically by CivicAuth based on config.preloadIframe\n }\n\n this.setState({\n isLoading: false,\n displayMode: config.displayMode,\n });\n } catch (error) {\n // Reset promise on error so it can be retried\n this.initializationPromise = null;\n\n const authError =\n error instanceof Error\n ? error\n : new Error(\"Auth initialization failed\");\n this.setState({\n error: authError,\n authStatus: \"error\",\n isLoading: false,\n });\n throw authError;\n }\n }\n\n /**\n * Subscribe to state changes\n */\n subscribe(listener: StateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Get current state\n */\n getState(): GlobalAuthState {\n return { ...this.state };\n }\n\n /**\n * Get current configuration\n * Returns the current config or null if not initialized\n */\n getConfig(): GlobalAuthConfig | null {\n return this.config ? { ...this.config } : null;\n }\n\n /**\n * Sign in\n */\n async signIn(): Promise<{ user: User }> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n const authResult = await this.auth.startAuthentication();\n\n // If authentication returned a user, use it directly\n if (authResult.user) {\n this.setState({\n user: authResult.user,\n authStatus: \"authenticated\",\n error: null,\n });\n return { user: authResult.user };\n }\n\n // Fallback: try to refresh user and session data\n await this.updateUserAndSession();\n\n // Check the current state for the user after refresh\n const currentState = this.getState();\n\n if (!currentState.user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n // Return the user object from current state\n return { user: currentState.user };\n }\n\n /**\n * Sign out\n */\n async signOut(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n\n await this.auth.logout();\n this.setState({\n user: null,\n session: null,\n authStatus: \"unauthenticated\",\n });\n }\n\n /**\n * Check if authentication is preloaded and ready for instant sign-in\n * @returns True if an iframe is preloaded and ready\n */\n isAuthenticationPreloaded(): boolean {\n return this.auth?.isAuthenticationPreloaded() ?? false;\n }\n\n /**\n * Enable or disable iframe preloading\n */\n setPreloadEnabled(enabled: boolean): void {\n if (!this.auth) {\n throw new Error(\"Auth not initialized\");\n }\n this.auth.setPreloadEnabled(enabled);\n }\n\n /**\n * Check if iframe preloading is enabled\n */\n getPreloadEnabled(): boolean {\n return this.auth?.getPreloadEnabled() ?? true;\n }\n\n /**\n * Reloads embedded authentication interface\n *\n * This method is specifically designed for embedded mode scenarios where the iframe\n * needs to be recreated after navigation or DOM changes. It delegates to the\n * underlying CivicAuth instance's reloadEmbedded method.\n *\n * @returns Promise that resolves when the embedded iframe is created\n * @throws {Error} If not in embedded mode or if auth is not initialized\n */\n async reloadEmbedded(): Promise<void> {\n if (!this.auth) {\n throw new Error(\"Auth not initialized. Call initialize() first.\");\n }\n\n return this.auth.reloadEmbedded();\n }\n\n /**\n * Reset authentication state when detected from back-forward cache (bfcache)\n * This fixes issues where sign-in button becomes unclickable after back navigation\n */\n resetOnBfcache(): void {\n if (!this.auth) return;\n\n // Reset internal CivicAuth state first\n this.auth.resetOnBfcache();\n\n // Reset auth state to unauthenticated to allow new sign-in attempts\n this.setState({\n authStatus: \"unauthenticated\",\n isLoading: false,\n error: null,\n user: null,\n session: null,\n });\n\n // Ensure iframe preloading state is refreshed if needed\n if (this.getPreloadEnabled()) {\n this.auth.setPreloadEnabled(true);\n }\n }\n\n /**\n * Check if config is the same (for idempotent initialization)\n */\n private isSameConfig(newConfig: GlobalAuthConfig): boolean {\n if (!this.config) return false;\n return (\n this.config.clientId === newConfig.clientId &&\n this.config.config?.oauthServer === newConfig.config?.oauthServer &&\n this.config.displayMode === newConfig.displayMode &&\n this.config.nonce === newConfig.nonce &&\n this.config.preloadIframe === newConfig.preloadIframe &&\n this.config.autoRedirect === newConfig.autoRedirect\n );\n }\n\n /**\n * Setup event listeners for auth state changes\n */\n private setupEventListeners(): void {\n if (!this.events) return;\n\n this.events.on(AuthEvent.SIGN_IN_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"authenticating\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.TOKEN_REFRESH_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"authenticated\",\n });\n this.updateUserAndSession();\n this.callbacks.onRefresh?.();\n });\n\n this.events.on(AuthEvent.SIGN_IN_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"authenticated\",\n error: null,\n });\n this.updateUserAndSession();\n this.callbacks.onSignIn?.();\n });\n\n this.events.on(AuthEvent.SIGN_IN_ERROR, (event?: SignInErrorEvent) => {\n const errorDetail = event?.detail || \"Authentication failed\";\n const authError = new Error(errorDetail);\n this.setState({\n isLoading: false,\n authStatus: \"error\",\n error: authError,\n });\n this.callbacks.onSignIn?.(authError);\n });\n\n this.events.on(AuthEvent.SIGN_OUT_STARTED, () => {\n this.setState({\n isLoading: true,\n authStatus: \"signing_out\",\n error: null,\n });\n });\n\n this.events.on(AuthEvent.SIGN_OUT_COMPLETE, () => {\n this.setState({\n isLoading: false,\n authStatus: \"unauthenticated\",\n user: null,\n session: null,\n error: null,\n });\n this.callbacks.onSignOut?.();\n });\n\n this.events.on(AuthEvent.USER_SESSION_CHANGED, () => {\n this.updateUserAndSession();\n });\n\n this.events.on(\n AuthEvent.URL_CHANGE,\n (event?: { detail?: string; url?: string; source?: string }) => {\n this.setState({\n authStatus: \"authenticating\", // Keep as authenticating since we're redirecting\n error: null,\n });\n // Call custom URL change handler if provided\n if (event?.url && this.callbacks.onUrlChange) {\n this.callbacks.onUrlChange(event.url, event.source);\n }\n },\n );\n }\n\n /**\n * Refresh user and session data\n */\n private async updateUserAndSession(): Promise<void> {\n if (!this.auth) return;\n\n try {\n const [session, user] = await Promise.all([\n this.auth.getCurrentSession(),\n this.auth.getCurrentUser(),\n ]);\n\n this.setState({ session, user });\n } catch (error) {\n const sessionError =\n error instanceof Error ? error : new Error(\"Failed to get session\");\n this.setState({ error: sessionError });\n }\n }\n\n /**\n * Update state and notify listeners\n */\n private setState(updates: Partial<GlobalAuthState>): void {\n this.state = { ...this.state, ...updates };\n this.listeners.forEach((listener) => listener(this.state));\n }\n\n /**\n * Cleanup auth instance\n */\n private async cleanup(): Promise<void> {\n if (this.auth) {\n await this.auth.destroy();\n this.auth = null;\n }\n this.events = null;\n this.config = null;\n this.initializationPromise = null; // Reset promise for clean re-initialization\n }\n}\n\nexport { GlobalAuthManager };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAQjD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB,EAAE,MAAM,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mCACvC,gBAAgB,KACxB,eAAe,CAAC,CAAC,CA0SnB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAYjD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB,EAAE,MAAM,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mCACvC,gBAAgB,KACxB,eAAe,CAAC,CAAC,CAuOnB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -38,19 +38,24 @@
38
38
  */
39
39
  "use client";
40
40
  import { useContext, useState, useEffect, useCallback, useMemo } from "react";
41
- import { UserContext } from "../../shared/providers/UserProvider.js";
42
41
  import { ServerUserContext } from "../../nextjs/providers/ServerUserContext.js";
43
42
  import { GlobalAuthManager, } from "../core/GlobalAuthManager.js";
44
43
  import { extractTokensFromSession } from "../../vanillajs/utils/auth-utils.js";
44
+ import { BrowserCookieStorage } from "../../shared/index.js";
45
+ import { GenericUserSession } from "../../shared/lib/UserSession.js";
46
+ import { LocalStorageAdapter } from "../../browser/storage.js";
47
+ import { useIsClient } from "usehooks-ts";
45
48
  const useUser = (config) => {
46
49
  // Always call context hooks unconditionally (rules of hooks)
47
- const sharedContext = useContext(UserContext);
48
50
  const serverAuthData = useContext(ServerUserContext);
49
- // State for global manager approach
50
- const [globalState, setGlobalState] = useState(null);
51
- // Determine which approach to use
52
- const hasProviderContext = sharedContext;
53
- const shouldUseGlobal = !hasProviderContext;
51
+ const { user: serverUser, tokens: serverTokens } = serverAuthData || {};
52
+ const isClient = useIsClient();
53
+ const localStorageAdapter = useMemo(() => (isClient ? new LocalStorageAdapter() : null), [isClient]);
54
+ const localUserStorage = useMemo(() => localStorageAdapter
55
+ ? new GenericUserSession(localStorageAdapter)
56
+ : null, [localStorageAdapter]);
57
+ const localStorageUserData = localUserStorage?.getSync() || null; // Get user from local storage if available
58
+ const initialUser = serverUser || localStorageUserData; // Get initial user from server context or local storage
54
59
  // Helper to merge config overrides with current manager config
55
60
  const createConfigWithOverrides = useCallback((overrides) => {
56
61
  const manager = GlobalAuthManager.getInstance();
@@ -85,33 +90,25 @@ const useUser = (config) => {
85
90
  ...(overrides.onSignIn && { onSignIn: overrides.onSignIn }),
86
91
  ...(overrides.onSignOut && { onSignOut: overrides.onSignOut }),
87
92
  ...(overrides.onUrlChange && { onUrlChange: overrides.onUrlChange }),
93
+ ...(currentConfig && serverAuthData
94
+ ? { storage: new BrowserCookieStorage() }
95
+ : localStorageAdapter), // Use cookie storage if server data present
96
+ ...(currentConfig && initialUser ? { initialUser } : {}), // Use server user as initial user if available
88
97
  };
89
- }, [config]);
90
- // Initialize global manager if no provider context
91
- useEffect(() => {
92
- if (!shouldUseGlobal)
93
- return;
98
+ }, [config, initialUser, serverAuthData, localStorageAdapter]);
99
+ // Global manager preloading functions
100
+ const globalIsAuthenticationPreloaded = useCallback(() => {
94
101
  const manager = GlobalAuthManager.getInstance();
95
- // If config is provided, initialize with it
96
- if (config) {
97
- const initializeAuth = async () => {
98
- try {
99
- await manager.initialize(config);
100
- }
101
- catch (error) {
102
- console.error("Failed to initialize auth:", error);
103
- }
104
- };
105
- initializeAuth();
106
- }
107
- // Subscribe to state changes
108
- const unsubscribe = manager.subscribe((newState) => {
109
- setGlobalState(newState);
110
- });
111
- // Get current state
112
- setGlobalState(manager.getState());
113
- return unsubscribe;
114
- }, [shouldUseGlobal, config]);
102
+ return manager.isAuthenticationPreloaded();
103
+ }, []);
104
+ const globalSetPreloadEnabled = useCallback((enabled) => {
105
+ const manager = GlobalAuthManager.getInstance();
106
+ manager.setPreloadEnabled(enabled);
107
+ }, []);
108
+ const globalGetPreloadEnabled = useCallback(() => {
109
+ const manager = GlobalAuthManager.getInstance();
110
+ return manager.getPreloadEnabled();
111
+ }, []);
115
112
  // Global manager sign in/out functions
116
113
  const globalSignIn = useCallback(async (signInConfig) => {
117
114
  const manager = GlobalAuthManager.getInstance();
@@ -137,81 +134,23 @@ const useUser = (config) => {
137
134
  }
138
135
  await manager.signOut();
139
136
  }, [createConfigWithOverrides]);
140
- // Global manager preloading functions
141
- const globalIsAuthenticationPreloaded = useCallback(() => {
142
- const manager = GlobalAuthManager.getInstance();
143
- return manager.isAuthenticationPreloaded();
144
- }, []);
145
- const globalSetPreloadEnabled = useCallback((enabled) => {
146
- const manager = GlobalAuthManager.getInstance();
147
- manager.setPreloadEnabled(enabled);
148
- }, []);
149
- const globalGetPreloadEnabled = useCallback(() => {
150
- const manager = GlobalAuthManager.getInstance();
151
- return manager.getPreloadEnabled();
152
- }, []);
153
- // Extract tokens from global state
154
- const globalTokens = useMemo(() => {
155
- return extractTokensFromSession(globalState?.session || null);
156
- }, [globalState?.session]);
157
- // Create wrapper functions for different signIn signatures
158
- const wrapSharedSignIn = useCallback(async (sharedConfig) => {
159
- if (sharedContext) {
160
- // Note: Shared context doesn't support config overrides yet
161
- // This is a limitation of the legacy provider system
162
- if (sharedConfig) {
163
- console.warn("Config overrides are not supported with legacy UserContext. Consider upgrading to GlobalAuthManager for full config override support.");
164
- }
165
- await sharedContext.signIn(); // This returns void
166
- // Get user from context after sign in
167
- if (sharedContext.user) {
168
- return { user: sharedContext.user };
169
- }
170
- // We don't return a user yet in nextjs until the next refactor
171
- return { user: null };
172
- }
173
- throw new Error("Shared context not available");
174
- }, [sharedContext]);
175
- // Shared context preloading stubs (not implemented for legacy context)
176
- const sharedIsAuthenticationPreloaded = useCallback(() => {
177
- return false; // Not available in shared context
178
- }, []);
179
- const sharedSetPreloadEnabled = useCallback((_enabled) => {
180
- console.warn("Preloading not available with legacy UserContext. Use GlobalAuthManager instead.", _enabled);
181
- }, []);
182
- const sharedGetPreloadEnabled = useCallback(() => {
183
- return false; // Not available in shared context
184
- }, []);
185
- // Create wrapper for sharedContext signOut with config support
186
- const wrapSharedSignOut = useCallback(async (sharedConfig) => {
187
- if (sharedContext) {
188
- // Note: Shared context doesn't support config overrides yet
189
- if (sharedConfig) {
190
- console.warn("Config overrides are not supported with legacy UserContext. Consider upgrading to GlobalAuthManager for full config override support.");
191
- }
192
- await sharedContext.signOut();
193
- }
194
- else {
195
- throw new Error("Shared context not available");
196
- }
197
- }, [sharedContext]);
198
- // ========================================================================
199
- // FALLBACK PRIORITY SYSTEM - Three authentication context approaches
200
- // ========================================================================
201
- // 0. NextJS ServerUserContext (HIGHEST PRIORITY - Fresh server data)
202
- // This ensures client components sync with server data after revalidation
203
- if (serverAuthData !== null) {
204
- const { user: serverUser, tokens: serverTokens } = serverAuthData;
205
- return {
206
- user: serverUser,
137
+ // Only set initial state if we have server data or local storage data
138
+ const initialState = initialUser
139
+ ? {
140
+ session: {
141
+ user: initialUser,
142
+ idToken: serverTokens?.idToken,
143
+ accessToken: serverTokens?.accessToken,
144
+ refreshToken: serverTokens?.refreshToken,
145
+ },
146
+ user: initialUser,
207
147
  idToken: serverTokens?.idToken || null,
208
148
  accessToken: serverTokens?.accessToken || null,
209
149
  refreshToken: serverTokens?.refreshToken || null,
210
- forwardedTokens: serverUser?.forwardedTokens,
150
+ forwardedTokens: serverUser
151
+ ?.forwardedTokens,
211
152
  isLoading: false, // Server data is immediately available
212
- authStatus: (serverUser
213
- ? "authenticated"
214
- : "unauthenticated"),
153
+ authStatus: "authenticated",
215
154
  error: null,
216
155
  signIn: globalSignIn,
217
156
  signOut: globalSignOut,
@@ -219,30 +158,43 @@ const useUser = (config) => {
219
158
  setPreloadEnabled: globalSetPreloadEnabled,
220
159
  getPreloadEnabled: globalGetPreloadEnabled,
221
160
  displayMode: config?.displayMode,
222
- };
223
- }
224
- // 1. DEPRECATED UserContext (ACTIVE - Used by NextJS)
225
- // Framework-agnostic shared context from UserProvider
226
- // Location: shared/providers/UserProvider.tsx
227
- // Usage: NextJS example uses CivicNextAuthProvider UserProvider → UserContext
228
- if (sharedContext) {
229
- return {
230
- user: sharedContext.user,
231
- idToken: sharedContext.idToken,
232
- accessToken: sharedContext.accessToken,
233
- refreshToken: undefined, // Not available in shared context
234
- forwardedTokens: sharedContext.forwardedTokens,
235
- isLoading: sharedContext.isLoading,
236
- authStatus: sharedContext.authStatus,
237
- error: sharedContext.error,
238
- signIn: wrapSharedSignIn,
239
- signOut: wrapSharedSignOut,
240
- isAuthenticationPreloaded: sharedIsAuthenticationPreloaded,
241
- setPreloadEnabled: sharedSetPreloadEnabled,
242
- getPreloadEnabled: sharedGetPreloadEnabled,
243
- displayMode: sharedContext.displayMode,
244
- };
245
- }
161
+ storage: config?.storage,
162
+ }
163
+ : null;
164
+ // State for global manager approach
165
+ const [globalState, setGlobalState] = useState(initialState);
166
+ // Initialize global manager if no provider context
167
+ useEffect(() => {
168
+ const manager = GlobalAuthManager.getInstance();
169
+ const mergedConfig = createConfigWithOverrides({});
170
+ // If config is provided, initialize with it
171
+ if (mergedConfig?.config) {
172
+ const initializeAuth = async () => {
173
+ try {
174
+ await manager.initialize(mergedConfig);
175
+ }
176
+ catch (error) {
177
+ console.error("Failed to initialize auth:", error);
178
+ }
179
+ };
180
+ initializeAuth();
181
+ }
182
+ // Subscribe to state changes
183
+ const unsubscribe = manager.subscribe((newState) => {
184
+ setGlobalState(newState);
185
+ });
186
+ const currentState = manager.getState();
187
+ // Get current state
188
+ if (manager.getConfig()) {
189
+ setGlobalState(currentState);
190
+ }
191
+ return unsubscribe;
192
+ // eslint-disable-next-line react-hooks/exhaustive-deps
193
+ }, [config]);
194
+ // Extract tokens from global state
195
+ const globalTokens = useMemo(() => {
196
+ return extractTokensFromSession(globalState?.session || null);
197
+ }, [globalState?.session]);
246
198
  // 2. GlobalAuthManager (MODERN - Provider-free approach)
247
199
  // Singleton-based state management, eliminates need for React providers
248
200
  // Location: reactjs/core/GlobalAuthManager.ts
@@ -1 +1 @@
1
- {"version":3,"file":"useUser.js","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * useUser Hook\n *\n * A comprehensive user session hook that provides full user data including profile information,\n * authentication tokens, and authentication state. Supports generic typing for custom user data.\n *\n * Use this hook when you:\n * - Need access to user profile information (user object)\n * - Need authentication tokens (JWT, access, refresh tokens)\n * - Are working with custom user data types\n * - Need comprehensive user session data\n * - Want backward compatibility with legacy UserContext\n *\n * This hook supports two authentication patterns with automatic fallback:\n * 1. Provider-based (legacy): Uses CivicAuthProvider or CivicNextAuthProvider\n * 2. Provider-free (modern): Direct configuration via useUser(config)\n *\n * Usage Examples:\n *\n * // With provider (existing approach - NextJS/React providers)\n * <CivicAuthProvider clientId=\"...\" config={{ oauthServer: \"...\" }}>\n * const { user, isLoading, signIn } = useUser();\n * </CivicAuthProvider>\n *\n * // Without provider (new approach) - direct configuration\n * const { user, authStatus, signOut } = useUser({\n * clientId: \"your-client-id\",\n * config: { oauthServer: \"https://auth.civic.com/oauth/\" },\n * displayMode: \"iframe\", // or \"redirect\", \"popup\", etc.\n * scopes: [\"openid\", \"profile\", \"email\"],\n * onSignIn: (error) => console.log(\"Sign in completed\", error),\n * onSignOut: () => console.log(\"Sign out completed\")\n * });\n *\n * // Generic typing for custom user data\n * interface CustomUser { customField: string; }\n * const { user } = useUser<CustomUser>(); // user will be User<CustomUser> | null\n */\n\"use client\";\nimport { useContext, useState, useEffect, useCallback, useMemo } from \"react\";\nimport { UserContext } from \"../../shared/providers/UserProvider.js\";\nimport { ServerUserContext } from \"../../nextjs/providers/ServerUserContext.js\";\nimport type { User, ForwardedTokens } from \"../../types.js\";\nimport type { AuthStatus } from \"../../types.js\";\nimport type { DisplayMode } from \"../../types.js\";\nimport {\n GlobalAuthManager,\n type GlobalAuthConfig,\n type GlobalAuthState,\n} from \"../core/GlobalAuthManager.js\";\nimport { extractTokensFromSession } from \"../../vanillajs/utils/auth-utils.js\";\nimport type { VanillaJSDisplayMode } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { IframeMode } from \"../../types.js\";\n\n// Type for server user data that may include forwardedTokens from session storage\ntype ServerUserWithTokens<\n T extends Record<string, unknown> = Record<string, never>,\n> = User<T> & { forwardedTokens?: ForwardedTokens };\n\n// Configuration type for signIn and signOut functions\nexport interface SignInConfig {\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: IframeMode;\n clientId?: string;\n redirectUrl?: string;\n logoutRedirectUrl?: string;\n targetContainerElement?: HTMLElement | string;\n scopes?: string[];\n authProcessTimeout?: number;\n preloadIframe?: boolean;\n autoRedirect?: boolean;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n}\n\nexport interface UserContextType<\n T extends Record<string, unknown> = Record<string, never>,\n> {\n user: User<T> | null;\n idToken?: string | null;\n accessToken?: string | null;\n refreshToken?: string | null;\n forwardedTokens?: ForwardedTokens;\n isLoading: boolean;\n authStatus: AuthStatus;\n error: Error | null;\n signIn: (config?: SignInConfig) => Promise<{ user: User<T> }>;\n signOut: (config?: SignInConfig) => Promise<void>;\n // Preloading methods\n isAuthenticationPreloaded: () => boolean;\n setPreloadEnabled: (enabled: boolean) => void;\n getPreloadEnabled: () => boolean;\n displayMode?: DisplayMode;\n}\n\nconst useUser = <T extends Record<string, unknown> = Record<string, never>>(\n config?: GlobalAuthConfig,\n): UserContextType<T> => {\n // Always call context hooks unconditionally (rules of hooks)\n const sharedContext = useContext(UserContext);\n const serverAuthData = useContext(ServerUserContext);\n\n // State for global manager approach\n const [globalState, setGlobalState] = useState<GlobalAuthState | null>(null);\n\n // Determine which approach to use\n const hasProviderContext = sharedContext;\n const shouldUseGlobal = !hasProviderContext;\n\n // Helper to merge config overrides with current manager config\n const createConfigWithOverrides = useCallback(\n (overrides: SignInConfig): GlobalAuthConfig => {\n const manager = GlobalAuthManager.getInstance();\n const currentConfig = manager.getConfig();\n\n // Use current config from manager, or fall back to initial config if manager not initialized\n const baseConfig = currentConfig || config || {};\n\n return {\n ...baseConfig, // Complete current config from GlobalAuthManager\n // Override specific properties while keeping the base config\n ...(overrides.displayMode && { displayMode: overrides.displayMode }),\n ...(overrides.iframeMode !== undefined && {\n iframeMode: overrides.iframeMode,\n }),\n ...(overrides.clientId && { clientId: overrides.clientId }),\n ...(overrides.redirectUrl && { redirectUrl: overrides.redirectUrl }),\n ...(overrides.logoutRedirectUrl && {\n logoutRedirectUrl: overrides.logoutRedirectUrl,\n }),\n ...(overrides.targetContainerElement && {\n targetContainerElement: overrides.targetContainerElement,\n }),\n ...(overrides.scopes && { scopes: overrides.scopes }),\n ...(overrides.authProcessTimeout && {\n authProcessTimeout: overrides.authProcessTimeout,\n }),\n ...(overrides.preloadIframe !== undefined && {\n preloadIframe: overrides.preloadIframe,\n }),\n ...(overrides.autoRedirect !== undefined && {\n autoRedirect: overrides.autoRedirect,\n }),\n ...(overrides.onSignIn && { onSignIn: overrides.onSignIn }),\n ...(overrides.onSignOut && { onSignOut: overrides.onSignOut }),\n ...(overrides.onUrlChange && { onUrlChange: overrides.onUrlChange }),\n };\n },\n [config],\n );\n\n // Initialize global manager if no provider context\n useEffect(() => {\n if (!shouldUseGlobal) return;\n\n const manager = GlobalAuthManager.getInstance();\n\n // If config is provided, initialize with it\n if (config) {\n const initializeAuth = async () => {\n try {\n await manager.initialize(config);\n } catch (error) {\n console.error(\"Failed to initialize auth:\", error);\n }\n };\n initializeAuth();\n }\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n setGlobalState(newState);\n });\n\n // Get current state\n setGlobalState(manager.getState());\n\n return unsubscribe;\n }, [shouldUseGlobal, config]);\n\n // Global manager sign in/out functions\n const globalSignIn = useCallback(\n async (signInConfig?: SignInConfig) => {\n const manager = GlobalAuthManager.getInstance();\n\n // If config is provided, reinitialize with merged config\n if (signInConfig) {\n const mergedConfig = createConfigWithOverrides(signInConfig);\n await manager.initialize(mergedConfig);\n }\n\n await manager.signIn();\n\n // Get the user after sign in\n const state = manager.getState();\n if (!state.user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n return { user: state.user as User<T> };\n },\n [createConfigWithOverrides],\n );\n\n const globalSignOut = useCallback(\n async (signOutConfig?: SignInConfig) => {\n const manager = GlobalAuthManager.getInstance();\n\n // If config is provided, reinitialize with merged config\n if (signOutConfig) {\n const mergedConfig = createConfigWithOverrides(signOutConfig);\n await manager.initialize(mergedConfig);\n }\n\n await manager.signOut();\n },\n [createConfigWithOverrides],\n );\n\n // Global manager preloading functions\n const globalIsAuthenticationPreloaded = useCallback(() => {\n const manager = GlobalAuthManager.getInstance();\n return manager.isAuthenticationPreloaded();\n }, []);\n\n const globalSetPreloadEnabled = useCallback((enabled: boolean) => {\n const manager = GlobalAuthManager.getInstance();\n manager.setPreloadEnabled(enabled);\n }, []);\n\n const globalGetPreloadEnabled = useCallback(() => {\n const manager = GlobalAuthManager.getInstance();\n return manager.getPreloadEnabled();\n }, []);\n\n // Extract tokens from global state\n const globalTokens = useMemo(() => {\n return extractTokensFromSession(globalState?.session || null);\n }, [globalState?.session]);\n\n // Create wrapper functions for different signIn signatures\n const wrapSharedSignIn = useCallback(\n async (sharedConfig?: SignInConfig): Promise<{ user: User<T> }> => {\n if (sharedContext) {\n // Note: Shared context doesn't support config overrides yet\n // This is a limitation of the legacy provider system\n if (sharedConfig) {\n console.warn(\n \"Config overrides are not supported with legacy UserContext. Consider upgrading to GlobalAuthManager for full config override support.\",\n );\n }\n\n await sharedContext.signIn(); // This returns void\n // Get user from context after sign in\n if (sharedContext.user) {\n return { user: sharedContext.user as User<T> };\n }\n\n // We don't return a user yet in nextjs until the next refactor\n return { user: null as unknown as User<T> };\n }\n throw new Error(\"Shared context not available\");\n },\n [sharedContext],\n );\n\n // Shared context preloading stubs (not implemented for legacy context)\n const sharedIsAuthenticationPreloaded = useCallback(() => {\n return false; // Not available in shared context\n }, []);\n\n const sharedSetPreloadEnabled = useCallback((_enabled: boolean) => {\n console.warn(\n \"Preloading not available with legacy UserContext. Use GlobalAuthManager instead.\",\n _enabled,\n );\n }, []);\n\n const sharedGetPreloadEnabled = useCallback(() => {\n return false; // Not available in shared context\n }, []);\n\n // Create wrapper for sharedContext signOut with config support\n const wrapSharedSignOut = useCallback(\n async (sharedConfig?: SignInConfig): Promise<void> => {\n if (sharedContext) {\n // Note: Shared context doesn't support config overrides yet\n if (sharedConfig) {\n console.warn(\n \"Config overrides are not supported with legacy UserContext. Consider upgrading to GlobalAuthManager for full config override support.\",\n );\n }\n\n await sharedContext.signOut();\n } else {\n throw new Error(\"Shared context not available\");\n }\n },\n [sharedContext],\n );\n\n // ========================================================================\n // FALLBACK PRIORITY SYSTEM - Three authentication context approaches\n // ========================================================================\n\n // 0. NextJS ServerUserContext (HIGHEST PRIORITY - Fresh server data)\n // This ensures client components sync with server data after revalidation\n if (serverAuthData !== null) {\n const { user: serverUser, tokens: serverTokens } = serverAuthData;\n\n return {\n user: serverUser as User<T> | null,\n idToken: serverTokens?.idToken || null,\n accessToken: serverTokens?.accessToken || null,\n refreshToken: serverTokens?.refreshToken || null,\n forwardedTokens: (serverUser as ServerUserWithTokens<T>)?.forwardedTokens,\n isLoading: false, // Server data is immediately available\n authStatus: (serverUser\n ? \"authenticated\"\n : \"unauthenticated\") as AuthStatus,\n error: null,\n signIn: globalSignIn,\n signOut: globalSignOut,\n isAuthenticationPreloaded: globalIsAuthenticationPreloaded,\n setPreloadEnabled: globalSetPreloadEnabled,\n getPreloadEnabled: globalGetPreloadEnabled,\n displayMode: config?.displayMode as DisplayMode,\n };\n }\n\n // 1. DEPRECATED UserContext (ACTIVE - Used by NextJS)\n // Framework-agnostic shared context from UserProvider\n // Location: shared/providers/UserProvider.tsx\n // Usage: NextJS example uses CivicNextAuthProvider → UserProvider → UserContext\n if (sharedContext) {\n return {\n user: sharedContext.user as User<T> | null,\n idToken: sharedContext.idToken,\n accessToken: sharedContext.accessToken,\n refreshToken: undefined, // Not available in shared context\n forwardedTokens: sharedContext.forwardedTokens,\n isLoading: sharedContext.isLoading,\n authStatus: sharedContext.authStatus,\n error: sharedContext.error,\n signIn: wrapSharedSignIn,\n signOut: wrapSharedSignOut,\n isAuthenticationPreloaded: sharedIsAuthenticationPreloaded,\n setPreloadEnabled: sharedSetPreloadEnabled,\n getPreloadEnabled: sharedGetPreloadEnabled,\n displayMode: sharedContext.displayMode,\n };\n }\n\n // 2. GlobalAuthManager (MODERN - Provider-free approach)\n // Singleton-based state management, eliminates need for React providers\n // Location: reactjs/core/GlobalAuthManager.ts\n // Usage: React example uses CivicAuthProvider → GlobalAuthManager internally\n // Can also be used directly: useUser({ clientId: \"...\", config: {...} })\n if (globalState) {\n return {\n user: globalState.user as User<T> | null,\n idToken: globalTokens.idToken,\n accessToken: globalTokens.accessToken,\n refreshToken: globalTokens.refreshToken,\n forwardedTokens: globalTokens.forwardedTokens,\n isLoading: globalState.isLoading,\n authStatus: globalState.authStatus as AuthStatus,\n error: globalState.error,\n signIn: globalSignIn,\n signOut: globalSignOut,\n isAuthenticationPreloaded: globalIsAuthenticationPreloaded,\n setPreloadEnabled: globalSetPreloadEnabled,\n getPreloadEnabled: globalGetPreloadEnabled,\n displayMode: globalState.displayMode as DisplayMode,\n };\n }\n\n // If no context and no global state, provide default loading state\n // This happens when CivicAuthProvider is present but GlobalAuthManager hasn't initialized yet\n return {\n user: null,\n idToken: null,\n accessToken: null,\n refreshToken: null,\n forwardedTokens: undefined,\n isLoading: true,\n authStatus: \"unauthenticated\" as AuthStatus,\n error: null,\n signIn: globalSignIn,\n signOut: globalSignOut,\n isAuthenticationPreloaded: globalIsAuthenticationPreloaded,\n setPreloadEnabled: globalSetPreloadEnabled,\n getPreloadEnabled: globalGetPreloadEnabled,\n displayMode: config?.displayMode as DisplayMode,\n };\n};\n\nexport { useUser };\n"]}
1
+ {"version":3,"file":"useUser.js","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * useUser Hook\n *\n * A comprehensive user session hook that provides full user data including profile information,\n * authentication tokens, and authentication state. Supports generic typing for custom user data.\n *\n * Use this hook when you:\n * - Need access to user profile information (user object)\n * - Need authentication tokens (JWT, access, refresh tokens)\n * - Are working with custom user data types\n * - Need comprehensive user session data\n * - Want backward compatibility with legacy UserContext\n *\n * This hook supports two authentication patterns with automatic fallback:\n * 1. Provider-based (legacy): Uses CivicAuthProvider or CivicNextAuthProvider\n * 2. Provider-free (modern): Direct configuration via useUser(config)\n *\n * Usage Examples:\n *\n * // With provider (existing approach - NextJS/React providers)\n * <CivicAuthProvider clientId=\"...\" config={{ oauthServer: \"...\" }}>\n * const { user, isLoading, signIn } = useUser();\n * </CivicAuthProvider>\n *\n * // Without provider (new approach) - direct configuration\n * const { user, authStatus, signOut } = useUser({\n * clientId: \"your-client-id\",\n * config: { oauthServer: \"https://auth.civic.com/oauth/\" },\n * displayMode: \"iframe\", // or \"redirect\", \"popup\", etc.\n * scopes: [\"openid\", \"profile\", \"email\"],\n * onSignIn: (error) => console.log(\"Sign in completed\", error),\n * onSignOut: () => console.log(\"Sign out completed\")\n * });\n *\n * // Generic typing for custom user data\n * interface CustomUser { customField: string; }\n * const { user } = useUser<CustomUser>(); // user will be User<CustomUser> | null\n */\n\"use client\";\nimport { useContext, useState, useEffect, useCallback, useMemo } from \"react\";\nimport { ServerUserContext } from \"../../nextjs/providers/ServerUserContext.js\";\nimport type { User, ForwardedTokens } from \"../../types.js\";\nimport type { AuthStatus } from \"../../types.js\";\nimport type { DisplayMode } from \"../../types.js\";\nimport {\n GlobalAuthManager,\n type GlobalAuthConfig,\n type GlobalAuthState,\n} from \"../core/GlobalAuthManager.js\";\nimport { extractTokensFromSession } from \"../../vanillajs/utils/auth-utils.js\";\nimport type { VanillaJSDisplayMode } from \"../../vanillajs/auth/types/AuthTypes.js\";\nimport type { IframeMode } from \"../../types.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport { useIsClient } from \"usehooks-ts\";\n\n// Type for server user data that may include forwardedTokens from session storage\ntype ServerUserWithTokens<\n T extends Record<string, unknown> = Record<string, never>,\n> = User<T> & { forwardedTokens?: ForwardedTokens };\n\n// Configuration type for signIn and signOut functions\nexport interface SignInConfig {\n displayMode?: VanillaJSDisplayMode;\n iframeMode?: IframeMode;\n clientId?: string;\n redirectUrl?: string;\n logoutRedirectUrl?: string;\n targetContainerElement?: HTMLElement | string;\n scopes?: string[];\n authProcessTimeout?: number;\n preloadIframe?: boolean;\n autoRedirect?: boolean;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => void;\n onUrlChange?: (url: string, source?: string) => void;\n}\n\nexport interface UserContextType<\n T extends Record<string, unknown> = Record<string, never>,\n> {\n user: User<T> | null;\n idToken?: string | null;\n accessToken?: string | null;\n refreshToken?: string | null;\n forwardedTokens?: ForwardedTokens;\n isLoading: boolean;\n authStatus: AuthStatus;\n error: Error | null;\n signIn: (config?: SignInConfig) => Promise<{ user: User<T> }>;\n signOut: (config?: SignInConfig) => Promise<void>;\n // Preloading methods\n isAuthenticationPreloaded: () => boolean;\n setPreloadEnabled: (enabled: boolean) => void;\n getPreloadEnabled: () => boolean;\n displayMode?: DisplayMode;\n}\n\nconst useUser = <T extends Record<string, unknown> = Record<string, never>>(\n config?: GlobalAuthConfig,\n): UserContextType<T> => {\n // Always call context hooks unconditionally (rules of hooks)\n const serverAuthData = useContext(ServerUserContext);\n const { user: serverUser, tokens: serverTokens } = serverAuthData || {};\n const isClient = useIsClient();\n const localStorageAdapter = useMemo(\n () => (isClient ? new LocalStorageAdapter() : null),\n [isClient],\n );\n const localUserStorage = useMemo(\n () =>\n localStorageAdapter\n ? new GenericUserSession<T>(localStorageAdapter)\n : null,\n [localStorageAdapter],\n );\n const localStorageUserData = localUserStorage?.getSync() || null; // Get user from local storage if available\n const initialUser = serverUser || localStorageUserData; // Get initial user from server context or local storage\n\n // Helper to merge config overrides with current manager config\n const createConfigWithOverrides = useCallback(\n (overrides: SignInConfig): GlobalAuthConfig => {\n const manager = GlobalAuthManager.getInstance();\n const currentConfig = manager.getConfig();\n\n // Use current config from manager, or fall back to initial config if manager not initialized\n const baseConfig = currentConfig || config || {};\n\n return {\n ...baseConfig, // Complete current config from GlobalAuthManager\n // Override specific properties while keeping the base config\n ...(overrides.displayMode && { displayMode: overrides.displayMode }),\n ...(overrides.iframeMode !== undefined && {\n iframeMode: overrides.iframeMode,\n }),\n ...(overrides.clientId && { clientId: overrides.clientId }),\n ...(overrides.redirectUrl && { redirectUrl: overrides.redirectUrl }),\n ...(overrides.logoutRedirectUrl && {\n logoutRedirectUrl: overrides.logoutRedirectUrl,\n }),\n ...(overrides.targetContainerElement && {\n targetContainerElement: overrides.targetContainerElement,\n }),\n ...(overrides.scopes && { scopes: overrides.scopes }),\n ...(overrides.authProcessTimeout && {\n authProcessTimeout: overrides.authProcessTimeout,\n }),\n ...(overrides.preloadIframe !== undefined && {\n preloadIframe: overrides.preloadIframe,\n }),\n ...(overrides.autoRedirect !== undefined && {\n autoRedirect: overrides.autoRedirect,\n }),\n ...(overrides.onSignIn && { onSignIn: overrides.onSignIn }),\n ...(overrides.onSignOut && { onSignOut: overrides.onSignOut }),\n ...(overrides.onUrlChange && { onUrlChange: overrides.onUrlChange }),\n ...(currentConfig && serverAuthData\n ? { storage: new BrowserCookieStorage() }\n : localStorageAdapter), // Use cookie storage if server data present\n ...(currentConfig && initialUser ? { initialUser } : {}), // Use server user as initial user if available\n };\n },\n [config, initialUser, serverAuthData, localStorageAdapter],\n );\n\n // Global manager preloading functions\n const globalIsAuthenticationPreloaded = useCallback(() => {\n const manager = GlobalAuthManager.getInstance();\n return manager.isAuthenticationPreloaded();\n }, []);\n\n const globalSetPreloadEnabled = useCallback((enabled: boolean) => {\n const manager = GlobalAuthManager.getInstance();\n manager.setPreloadEnabled(enabled);\n }, []);\n\n const globalGetPreloadEnabled = useCallback(() => {\n const manager = GlobalAuthManager.getInstance();\n return manager.getPreloadEnabled();\n }, []);\n\n // Global manager sign in/out functions\n const globalSignIn = useCallback(\n async (signInConfig?: SignInConfig) => {\n const manager = GlobalAuthManager.getInstance();\n\n // If config is provided, reinitialize with merged config\n if (signInConfig) {\n const mergedConfig = createConfigWithOverrides(signInConfig);\n await manager.initialize(mergedConfig);\n }\n\n await manager.signIn();\n\n // Get the user after sign in\n const state = manager.getState();\n if (!state.user) {\n throw new Error(\"Authentication succeeded but no user was returned\");\n }\n\n return { user: state.user as User<T> };\n },\n [createConfigWithOverrides],\n );\n\n const globalSignOut = useCallback(\n async (signOutConfig?: SignInConfig) => {\n const manager = GlobalAuthManager.getInstance();\n\n // If config is provided, reinitialize with merged config\n if (signOutConfig) {\n const mergedConfig = createConfigWithOverrides(signOutConfig);\n await manager.initialize(mergedConfig);\n }\n\n await manager.signOut();\n },\n [createConfigWithOverrides],\n );\n\n // Only set initial state if we have server data or local storage data\n const initialState = initialUser\n ? {\n session: {\n user: initialUser as User<T>,\n idToken: serverTokens?.idToken,\n accessToken: serverTokens?.accessToken,\n refreshToken: serverTokens?.refreshToken,\n },\n user: initialUser as User<T> | null,\n idToken: serverTokens?.idToken || null,\n accessToken: serverTokens?.accessToken || null,\n refreshToken: serverTokens?.refreshToken || null,\n forwardedTokens: (serverUser as ServerUserWithTokens<T>)\n ?.forwardedTokens,\n isLoading: false, // Server data is immediately available\n authStatus: \"authenticated\" as AuthStatus,\n error: null,\n signIn: globalSignIn,\n signOut: globalSignOut,\n isAuthenticationPreloaded: globalIsAuthenticationPreloaded,\n setPreloadEnabled: globalSetPreloadEnabled,\n getPreloadEnabled: globalGetPreloadEnabled,\n displayMode: config?.displayMode as DisplayMode,\n storage: config?.storage,\n }\n : null;\n\n // State for global manager approach\n const [globalState, setGlobalState] = useState<GlobalAuthState | null>(\n initialState,\n );\n\n // Initialize global manager if no provider context\n useEffect(() => {\n const manager = GlobalAuthManager.getInstance();\n const mergedConfig = createConfigWithOverrides({});\n // If config is provided, initialize with it\n if (mergedConfig?.config) {\n const initializeAuth = async () => {\n try {\n await manager.initialize(mergedConfig);\n } catch (error) {\n console.error(\"Failed to initialize auth:\", error);\n }\n };\n initializeAuth();\n }\n\n // Subscribe to state changes\n const unsubscribe = manager.subscribe((newState) => {\n setGlobalState(newState);\n });\n\n const currentState = manager.getState();\n // Get current state\n if (manager.getConfig()) {\n setGlobalState(currentState);\n }\n\n return unsubscribe;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [config]);\n\n // Extract tokens from global state\n const globalTokens = useMemo(() => {\n return extractTokensFromSession(globalState?.session || null);\n }, [globalState?.session]);\n\n // 2. GlobalAuthManager (MODERN - Provider-free approach)\n // Singleton-based state management, eliminates need for React providers\n // Location: reactjs/core/GlobalAuthManager.ts\n // Usage: React example uses CivicAuthProvider → GlobalAuthManager internally\n // Can also be used directly: useUser({ clientId: \"...\", config: {...} })\n if (globalState) {\n return {\n user: globalState.user as User<T> | null,\n idToken: globalTokens.idToken,\n accessToken: globalTokens.accessToken,\n refreshToken: globalTokens.refreshToken,\n forwardedTokens: globalTokens.forwardedTokens,\n isLoading: globalState.isLoading,\n authStatus: globalState.authStatus as AuthStatus,\n error: globalState.error,\n signIn: globalSignIn,\n signOut: globalSignOut,\n isAuthenticationPreloaded: globalIsAuthenticationPreloaded,\n setPreloadEnabled: globalSetPreloadEnabled,\n getPreloadEnabled: globalGetPreloadEnabled,\n displayMode: globalState.displayMode as DisplayMode,\n };\n }\n\n // If no context and no global state, provide default loading state\n // This happens when CivicAuthProvider is present but GlobalAuthManager hasn't initialized yet\n return {\n user: null,\n idToken: null,\n accessToken: null,\n refreshToken: null,\n forwardedTokens: undefined,\n isLoading: true,\n authStatus: \"unauthenticated\" as AuthStatus,\n error: null,\n signIn: globalSignIn,\n signOut: globalSignOut,\n isAuthenticationPreloaded: globalIsAuthenticationPreloaded,\n setPreloadEnabled: globalSetPreloadEnabled,\n getPreloadEnabled: globalGetPreloadEnabled,\n displayMode: config?.displayMode as DisplayMode,\n };\n};\n\nexport { useUser };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"BrowserAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/BrowserAuthenticationRefresher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACzC;AAED,qBAAa,8BAA+B,SAAQ,2BAA2B;IAC7E,OAAO,CAAC,qBAAqB,CAAC,CAAwB;WAChC,KAAK,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,qBAAqB,CAAC,EAAE,qBAAqB,GAC5C,OAAO,CAAC,8BAA8B,CAAC;IAa1C,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK;cAMlB,iBAAiB;IAsC3B,gBAAgB;IAmCtB,gBAAgB;CASjB"}
1
+ {"version":3,"file":"BrowserAuthenticationRefresher.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/BrowserAuthenticationRefresher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACzC;AAED,qBAAa,8BAA+B,SAAQ,2BAA2B;IAC7E,OAAO,CAAC,qBAAqB,CAAC,CAAwB;WAChC,KAAK,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,qBAAqB,CAAC,EAAE,qBAAqB,GAC5C,OAAO,CAAC,8BAA8B,CAAC;IAmB1C,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK;cAMlB,iBAAiB;IAsC3B,gBAAgB;IAmCtB,gBAAgB;CASjB"}
@@ -2,12 +2,17 @@ import { AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS } from "../../constants.j
2
2
  import { retrieveOidcSessionExpiredAtSeconds } from "../../shared/lib/util.js";
3
3
  import { AuthenticationRefresherImpl } from "./AuthenticationRefresherImpl.js";
4
4
  import { UserStorage } from "./types.js";
5
+ import { loggers } from "../../lib/logger.js";
5
6
  export class BrowserAuthenticationRefresher extends AuthenticationRefresherImpl {
6
7
  refreshEventCallbacks;
7
8
  static async build(authConfig, storage, onError, endpointOverrides, refreshEventCallbacks) {
8
9
  const refresher = new BrowserAuthenticationRefresher(authConfig, storage, onError, endpointOverrides);
9
10
  refresher.refreshEventCallbacks = refreshEventCallbacks;
10
11
  await refresher.init();
12
+ window.addEventListener("focus", () => {
13
+ loggers.react.components.debug("BrowserAuthenticationRefresher: Window focused, checking token refresh..");
14
+ refresher.setupAutorefresh();
15
+ });
11
16
  return refresher;
12
17
  }
13
18
  handleError(error) {
@@ -1 +1 @@
1
- {"version":3,"file":"BrowserAuthenticationRefresher.js","sourceRoot":"","sources":["../../../src/shared/lib/BrowserAuthenticationRefresher.ts"],"names":[],"mappings":"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","sourcesContent":["import { AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS } from \"@/constants.js\";\nimport { retrieveOidcSessionExpiredAtSeconds } from \"@/shared/lib/util.js\";\nimport { AuthenticationRefresherImpl } from \"./AuthenticationRefresherImpl.js\";\nimport type { AuthStorage, Endpoints } from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport { UserStorage } from \"./types.js\";\n\nexport interface RefreshEventCallbacks {\n onRefreshStarted?: () => void;\n onRefreshComplete?: () => void;\n onRefreshError?: (error: Error) => void;\n}\n\nexport class BrowserAuthenticationRefresher extends AuthenticationRefresherImpl {\n private refreshEventCallbacks?: RefreshEventCallbacks;\n static override async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n onError: (error: Error) => Promise<void>,\n endpointOverrides?: Partial<Endpoints>,\n refreshEventCallbacks?: RefreshEventCallbacks,\n ): Promise<BrowserAuthenticationRefresher> {\n const refresher = new BrowserAuthenticationRefresher(\n authConfig,\n storage,\n onError,\n endpointOverrides,\n );\n refresher.refreshEventCallbacks = refreshEventCallbacks;\n await refresher.init();\n\n return refresher;\n }\n\n protected handleError(error: Error) {\n console.error(\"BrowserAuthenticationRefresher: Error\", error);\n this.clearAutorefresh();\n this.onError(error);\n }\n\n protected async handleAutoRefresh() {\n try {\n const existingUser = await this.storage?.get(UserStorage.USER);\n if (!existingUser) {\n console.warn(\n \"BrowserAuthenticationRefresher: No user found, skipping refresh\",\n );\n this.clearAutorefresh();\n return;\n }\n // ensure only one refresh is in progress\n if (localStorage.getItem(REFRESH_IN_PROGRESS) !== \"true\") {\n localStorage.setItem(REFRESH_IN_PROGRESS, \"true\");\n\n // Call onRefreshStarted callback\n this.refreshEventCallbacks?.onRefreshStarted?.();\n\n await this.refreshTokens();\n\n // Call onRefreshComplete callback\n this.refreshEventCallbacks?.onRefreshComplete?.();\n\n await this.setupAutorefresh(); // Reset the timeout after successful refresh\n }\n } catch (error) {\n console.error(\n \"BrowserAuthenticationRefresher: Failed to refresh tokens:\",\n error,\n );\n\n // Call onRefreshError callback\n this.refreshEventCallbacks?.onRefreshError?.(error as Error);\n\n // TODO detect if refresh token has expired and if yes then logout\n this.handleError(error as Error);\n }\n }\n\n async setupAutorefresh() {\n // clear any existing state\n localStorage.removeItem(REFRESH_IN_PROGRESS);\n\n if (!this.storage) throw new Error(\"No storage available\");\n // Clear any existing timeout\n this.clearAutorefresh();\n\n // get expires_in\n const nowSeconds = Math.floor(Date.now() / 1000);\n const expiresAtSeconds = await retrieveOidcSessionExpiredAtSeconds(\n this.storage,\n );\n\n // If there's no expiration time, don't set up auto-refresh\n if (!expiresAtSeconds) {\n console.warn(\n \"BrowserAuthenticationRefresher: No OIDC_SESSION_EXPIRES_AT found, skipping auto-refresh setup\",\n );\n return;\n }\n\n // Calculate time until expiry (subtract 30 seconds as buffer)\n const bufferTime = 30; // 30 seconds\n const refreshTimeSeconds = Math.max(\n 0,\n expiresAtSeconds - bufferTime - nowSeconds,\n ); // handle case were token has expired in the past\n\n const refreshTimeout = setTimeout(() => {\n this.handleAutoRefresh();\n }, 1000 * refreshTimeSeconds);\n localStorage.setItem(AUTOREFRESH_TIMEOUT_NAME, refreshTimeout.toString());\n }\n\n clearAutorefresh() {\n // use local storage to store the timeout id so that if multiple instances\n // of the refresher are created they can all clear the same timeout\n const existingTimeout = localStorage.getItem(AUTOREFRESH_TIMEOUT_NAME);\n if (existingTimeout) {\n clearTimeout(Number(existingTimeout));\n localStorage.removeItem(AUTOREFRESH_TIMEOUT_NAME);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"BrowserAuthenticationRefresher.js","sourceRoot":"","sources":["../../../src/shared/lib/BrowserAuthenticationRefresher.ts"],"names":[],"mappings":"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","sourcesContent":["import { AUTOREFRESH_TIMEOUT_NAME, REFRESH_IN_PROGRESS } from \"@/constants.js\";\nimport { retrieveOidcSessionExpiredAtSeconds } from \"@/shared/lib/util.js\";\nimport { AuthenticationRefresherImpl } from \"./AuthenticationRefresherImpl.js\";\nimport type { AuthStorage, Endpoints } from \"@/types.js\";\nimport type { AuthConfig } from \"@/server/config.js\";\nimport { UserStorage } from \"./types.js\";\nimport { loggers } from \"@/lib/logger.js\";\n\nexport interface RefreshEventCallbacks {\n onRefreshStarted?: () => void;\n onRefreshComplete?: () => void;\n onRefreshError?: (error: Error) => void;\n}\n\nexport class BrowserAuthenticationRefresher extends AuthenticationRefresherImpl {\n private refreshEventCallbacks?: RefreshEventCallbacks;\n static override async build(\n authConfig: AuthConfig,\n storage: AuthStorage,\n onError: (error: Error) => Promise<void>,\n endpointOverrides?: Partial<Endpoints>,\n refreshEventCallbacks?: RefreshEventCallbacks,\n ): Promise<BrowserAuthenticationRefresher> {\n const refresher = new BrowserAuthenticationRefresher(\n authConfig,\n storage,\n onError,\n endpointOverrides,\n );\n refresher.refreshEventCallbacks = refreshEventCallbacks;\n await refresher.init();\n\n window.addEventListener(\"focus\", () => {\n loggers.react.components.debug(\n \"BrowserAuthenticationRefresher: Window focused, checking token refresh..\",\n );\n refresher.setupAutorefresh();\n });\n return refresher;\n }\n\n protected handleError(error: Error) {\n console.error(\"BrowserAuthenticationRefresher: Error\", error);\n this.clearAutorefresh();\n this.onError(error);\n }\n\n protected async handleAutoRefresh() {\n try {\n const existingUser = await this.storage?.get(UserStorage.USER);\n if (!existingUser) {\n console.warn(\n \"BrowserAuthenticationRefresher: No user found, skipping refresh\",\n );\n this.clearAutorefresh();\n return;\n }\n // ensure only one refresh is in progress\n if (localStorage.getItem(REFRESH_IN_PROGRESS) !== \"true\") {\n localStorage.setItem(REFRESH_IN_PROGRESS, \"true\");\n\n // Call onRefreshStarted callback\n this.refreshEventCallbacks?.onRefreshStarted?.();\n\n await this.refreshTokens();\n\n // Call onRefreshComplete callback\n this.refreshEventCallbacks?.onRefreshComplete?.();\n\n await this.setupAutorefresh(); // Reset the timeout after successful refresh\n }\n } catch (error) {\n console.error(\n \"BrowserAuthenticationRefresher: Failed to refresh tokens:\",\n error,\n );\n\n // Call onRefreshError callback\n this.refreshEventCallbacks?.onRefreshError?.(error as Error);\n\n // TODO detect if refresh token has expired and if yes then logout\n this.handleError(error as Error);\n }\n }\n\n async setupAutorefresh() {\n // clear any existing state\n localStorage.removeItem(REFRESH_IN_PROGRESS);\n\n if (!this.storage) throw new Error(\"No storage available\");\n // Clear any existing timeout\n this.clearAutorefresh();\n\n // get expires_in\n const nowSeconds = Math.floor(Date.now() / 1000);\n const expiresAtSeconds = await retrieveOidcSessionExpiredAtSeconds(\n this.storage,\n );\n\n // If there's no expiration time, don't set up auto-refresh\n if (!expiresAtSeconds) {\n console.warn(\n \"BrowserAuthenticationRefresher: No OIDC_SESSION_EXPIRES_AT found, skipping auto-refresh setup\",\n );\n return;\n }\n\n // Calculate time until expiry (subtract 30 seconds as buffer)\n const bufferTime = 30; // 30 seconds\n const refreshTimeSeconds = Math.max(\n 0,\n expiresAtSeconds - bufferTime - nowSeconds,\n ); // handle case were token has expired in the past\n\n const refreshTimeout = setTimeout(() => {\n this.handleAutoRefresh();\n }, 1000 * refreshTimeSeconds);\n localStorage.setItem(AUTOREFRESH_TIMEOUT_NAME, refreshTimeout.toString());\n }\n\n clearAutorefresh() {\n // use local storage to store the timeout id so that if multiple instances\n // of the refresher are created they can all clear the same timeout\n const existingTimeout = localStorage.getItem(AUTOREFRESH_TIMEOUT_NAME);\n if (existingTimeout) {\n clearTimeout(Number(existingTimeout));\n localStorage.removeItem(AUTOREFRESH_TIMEOUT_NAME);\n }\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { AuthStorage, ForwardedTokensJWT, UnknownObject, User } from "../../types.js";
1
+ import type { AuthStorage, ForwardedTokensJWT, SyncAuthStorage, UnknownObject, User } from "../../types.js";
2
2
  export interface UserSession<T extends UnknownObject> {
3
3
  get(): Promise<User<T> | null>;
4
4
  set(user: User<T> & {
@@ -6,8 +6,9 @@ export interface UserSession<T extends UnknownObject> {
6
6
  }): Promise<void>;
7
7
  }
8
8
  export declare class GenericUserSession<T extends UnknownObject> implements UserSession<T> {
9
- readonly storage: AuthStorage;
10
- constructor(storage: AuthStorage);
9
+ readonly storage: AuthStorage | SyncAuthStorage;
10
+ constructor(storage: AuthStorage | SyncAuthStorage);
11
+ getSync(): User<T> | null;
11
12
  get(): Promise<User<T> | null>;
12
13
  set(user: (User<T> & {
13
14
  forwardedTokens?: ForwardedTokensJWT;
@@ -1 +1 @@
1
- {"version":3,"file":"UserSession.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/UserSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,IAAI,EACL,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,aAAa;IAClD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/B,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG;QAAE,eAAe,CAAC,EAAE,kBAAkB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAED,qBAAa,kBAAkB,CAAC,CAAC,SAAS,aAAa,CACrD,YAAW,WAAW,CAAC,CAAC,CAAC;IAEb,QAAQ,CAAC,OAAO,EAAE,WAAW;gBAApB,OAAO,EAAE,WAAW;IAEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAK9B,GAAG,CACP,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;QAAE,eAAe,CAAC,EAAE,kBAAkB,CAAA;KAAE,CAAC,GAAG,IAAI,GAChE,OAAO,CAAC,IAAI,CAAC;IAQV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
1
+ {"version":3,"file":"UserSession.d.ts","sourceRoot":"","sources":["../../../src/shared/lib/UserSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,IAAI,EACL,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,aAAa;IAClD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/B,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG;QAAE,eAAe,CAAC,EAAE,kBAAkB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAED,qBAAa,kBAAkB,CAAC,CAAC,SAAS,aAAa,CACrD,YAAW,WAAW,CAAC,CAAC,CAAC;IAEb,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe;gBAAtC,OAAO,EAAE,WAAW,GAAG,eAAe;IAE3D,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;IAInB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAK9B,GAAG,CACP,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;QAAE,eAAe,CAAC,EAAE,kBAAkB,CAAA;KAAE,CAAC,GAAG,IAAI,GAChE,OAAO,CAAC,IAAI,CAAC;IAQV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -5,6 +5,10 @@ export class GenericUserSession {
5
5
  constructor(storage) {
6
6
  this.storage = storage;
7
7
  }
8
+ getSync() {
9
+ const user = this.storage.getSync(UserStorage.USER);
10
+ return user ? JSON.parse(user) : null;
11
+ }
8
12
  async get() {
9
13
  const user = await this.storage.get(UserStorage.USER);
10
14
  return user ? JSON.parse(user) : null;