@hexclave/next 1.0.73 → 1.0.74

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 (141) hide show
  1. package/dist/{admin-app-impl-D867jXHk.d.ts → admin-app-impl-FZdANO62.d.ts} +10 -4
  2. package/dist/admin-app-impl-FZdANO62.d.ts.map +1 -0
  3. package/dist/clickmap/clickmap-core.d.ts +1 -1
  4. package/dist/clickmap/index.d.ts +1 -1
  5. package/dist/{client-app-B931IBrx.d.ts → client-app-BCT5p_70.d.ts} +11 -3
  6. package/dist/{client-app-B931IBrx.d.ts.map → client-app-BCT5p_70.d.ts.map} +1 -1
  7. package/dist/components/elements/sidebar-layout.js +1 -1
  8. package/dist/components/selected-team-switcher.d.ts +1 -1
  9. package/dist/components/team-icon.d.ts +1 -1
  10. package/dist/components/team-switcher.d.ts +1 -1
  11. package/dist/components-page/account-settings/payments/payments-page.d.ts +1 -1
  12. package/dist/components-page/account-settings/teams/leave-team-section.d.ts +1 -1
  13. package/dist/components-page/account-settings/teams/team-api-keys-section.d.ts +1 -1
  14. package/dist/components-page/account-settings/teams/team-display-name-section.d.ts +1 -1
  15. package/dist/components-page/account-settings/teams/team-member-invitation-section.d.ts +1 -1
  16. package/dist/components-page/account-settings/teams/team-member-list-section.d.ts +1 -1
  17. package/dist/components-page/account-settings/teams/team-page.d.ts +1 -1
  18. package/dist/components-page/account-settings/teams/team-profile-image-section.d.ts +1 -1
  19. package/dist/components-page/account-settings/teams/team-profile-user-section.d.ts +1 -1
  20. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  21. package/dist/components-page/hexclave-handler.d.ts +1 -1
  22. package/dist/components-page/oauth-callback.js +3 -18
  23. package/dist/components-page/oauth-callback.js.map +1 -1
  24. package/dist/dev-tool/dev-tool-core.d.ts +1 -1
  25. package/dist/dev-tool/index.d.ts +1 -1
  26. package/dist/esm/components/elements/sidebar-layout.js +1 -1
  27. package/dist/esm/components-page/oauth-callback.d.ts.map +1 -1
  28. package/dist/esm/components-page/oauth-callback.js +4 -19
  29. package/dist/esm/components-page/oauth-callback.js.map +1 -1
  30. package/dist/esm/lib/auth.d.ts.map +1 -1
  31. package/dist/esm/lib/auth.js +1 -1
  32. package/dist/esm/lib/auth.js.map +1 -1
  33. package/dist/esm/lib/auth.test.js +2 -2
  34. package/dist/esm/lib/auth.test.js.map +1 -1
  35. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +3 -0
  36. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  37. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.d.ts +1 -0
  38. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +102 -0
  39. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -0
  40. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +57 -1
  41. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  42. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +5 -2
  43. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  44. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +44 -12
  45. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  46. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  47. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +13 -1
  48. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -1
  49. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js +15 -1
  50. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -1
  51. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +25 -1
  52. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -1
  53. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts +1 -0
  54. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts.map +1 -1
  55. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.js +67 -12
  56. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.js.map +1 -1
  57. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.d.ts +1 -0
  58. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +87 -0
  59. package/dist/esm/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -0
  60. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts +9 -1
  61. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.d.ts.map +1 -1
  62. package/dist/esm/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  63. package/dist/esm/utils/url.js +10 -2
  64. package/dist/esm/utils/url.js.map +1 -1
  65. package/dist/esm/utils/url.test.d.ts +1 -0
  66. package/dist/esm/utils/url.test.js +28 -0
  67. package/dist/esm/utils/url.test.js.map +1 -0
  68. package/dist/{hexclave-provider-DkFUT3Fa.d.ts → hexclave-provider-BKxi3Vy-.d.ts} +2 -2
  69. package/dist/{hexclave-provider-DkFUT3Fa.d.ts.map → hexclave-provider-BKxi3Vy-.d.ts.map} +1 -1
  70. package/dist/{hooks-4PMrTtJr.d.ts → hooks-CUe5bc3s.d.ts} +2 -2
  71. package/dist/{hooks-4PMrTtJr.d.ts.map → hooks-CUe5bc3s.d.ts.map} +1 -1
  72. package/dist/{index-C9bAeWRr.d.ts → index-CvB7XacB.d.ts} +2 -2
  73. package/dist/{index-C9bAeWRr.d.ts.map → index-CvB7XacB.d.ts.map} +1 -1
  74. package/dist/index.d.ts +4 -4
  75. package/dist/lib/auth.d.ts.map +1 -1
  76. package/dist/lib/auth.js +1 -1
  77. package/dist/lib/auth.js.map +1 -1
  78. package/dist/lib/auth.test.js +2 -2
  79. package/dist/lib/auth.test.js.map +1 -1
  80. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +1 -1
  81. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.d.ts +1 -0
  82. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js +101 -0
  83. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.js.map +1 -0
  84. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js +57 -1
  85. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.js.map +1 -1
  86. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts +1 -1
  87. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +43 -11
  88. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  89. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  90. package/dist/lib/hexclave-app/apps/implementations/index.d.ts +1 -1
  91. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts +13 -1
  92. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.d.ts.map +1 -1
  93. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js +15 -0
  94. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.js.map +1 -1
  95. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js +24 -0
  96. package/dist/lib/hexclave-app/apps/implementations/redirect-back-state.test.js.map +1 -1
  97. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.d.ts +1 -1
  98. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.js +67 -12
  99. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.js.map +1 -1
  100. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.d.ts +1 -0
  101. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js +86 -0
  102. package/dist/lib/hexclave-app/apps/implementations/redirect-page-urls.test.js.map +1 -0
  103. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  104. package/dist/lib/hexclave-app/apps/index.d.ts +1 -1
  105. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +1 -1
  106. package/dist/lib/hexclave-app/apps/interfaces/client-app.d.ts +1 -1
  107. package/dist/lib/hexclave-app/apps/interfaces/client-app.js.map +1 -1
  108. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  109. package/dist/lib/hexclave-app/index.d.ts +1 -1
  110. package/dist/lib/hexclave-app/projects/index.d.ts +1 -1
  111. package/dist/lib/hexclave-app/teams/index.d.ts +1 -1
  112. package/dist/lib/hexclave-app/users/index.d.ts +1 -1
  113. package/dist/lib/hooks.d.ts +1 -1
  114. package/dist/oauth-callback-tCVTRbF2.d.ts.map +1 -1
  115. package/dist/providers/hexclave-context.d.ts +1 -1
  116. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  117. package/dist/providers/hexclave-provider.d.ts +1 -1
  118. package/dist/pushed-config-error-overlay/index.d.ts +1 -1
  119. package/dist/{redirect-page-urls-NUHUchgR.d.ts → redirect-page-urls-BEWG0AtP.d.ts} +2 -1
  120. package/dist/redirect-page-urls-BEWG0AtP.d.ts.map +1 -0
  121. package/dist/utils/url.js +10 -2
  122. package/dist/utils/url.js.map +1 -1
  123. package/dist/utils/url.test.d.ts +1 -0
  124. package/dist/utils/url.test.js +27 -0
  125. package/dist/utils/url.test.js.map +1 -0
  126. package/package.json +4 -4
  127. package/src/components-page/oauth-callback.tsx +0 -16
  128. package/src/lib/auth.test.ts +2 -2
  129. package/src/lib/auth.ts +3 -1
  130. package/src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts +126 -0
  131. package/src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts +75 -0
  132. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +73 -16
  133. package/src/lib/hexclave-app/apps/implementations/redirect-back-state.test.ts +29 -1
  134. package/src/lib/hexclave-app/apps/implementations/redirect-back-state.ts +17 -0
  135. package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.test.ts +119 -0
  136. package/src/lib/hexclave-app/apps/implementations/redirect-page-urls.ts +104 -12
  137. package/src/lib/hexclave-app/apps/interfaces/client-app.ts +12 -2
  138. package/src/utils/url.test.ts +54 -0
  139. package/src/utils/url.ts +12 -3
  140. package/dist/admin-app-impl-D867jXHk.d.ts.map +0 -1
  141. package/dist/redirect-page-urls-NUHUchgR.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-callback.js","names":[],"sources":["../../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownError } from \"@hexclave/shared\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@hexclave/ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { hexclaveAppInternalsSymbol } from \"../lib/hexclave-app/common\";\nimport { useTranslation } from \"../lib/translations\";\nimport { ErrorPage } from \"./error-page\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const app = useStackApp();\n const called = useRef(false);\n const [showRedirectLink, setShowRedirectLink] = useState(false);\n const [errorSearchParams, setErrorSearchParams] = useState<Record<string, string> | null>(null);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n try {\n // The startup handler in StackClientApp's constructor may have already consumed the\n // one-time OAuth params (code + state cookie) via a microtask that fires before this\n // macrotask-scheduled useEffect. Await its completion so we don't race: if it succeeds\n // it will redirect and this page tears down; if it fails we fall through below.\n await app[hexclaveAppInternalsSymbol].awaitPendingAuthResolutions();\n const hasRedirected = await app.callOAuthCallback();\n if (!hasRedirected) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n } catch (e) {\n if (KnownError.isKnownError(e)) {\n setErrorSearchParams({\n errorCode: e.errorCode,\n message: e.message,\n details: JSON.stringify(e.details ?? {}),\n });\n return;\n }\n captureError(\"<OAuthCallback />\", e);\n setErrorSearchParams({});\n }\n }), [app]);\n\n useEffect(() => {\n setTimeout(() => setShowRedirectLink(true), 3000);\n }, []);\n\n if (errorSearchParams != null) {\n return <ErrorPage searchParams={errorSearchParams} fullPage={fullPage} />;\n }\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n {showRedirectLink ? <p>{t('If you are not redirected automatically, ')}<StyledLink\n className=\"whitespace-nowrap\"\n href=\"#\"\n onClick={(e) => {\n e.preventDefault();\n runAsynchronously(app.redirectToHome());\n }}\n >{t(\"click here\")}</StyledLink></p> : null}\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,cAAc,EAAE,YAAoC;CAClE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,MAAM,YAAY;CACxB,MAAM,SAAS,OAAO,KAAK;CAC3B,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,KAAK;CAC9D,MAAM,CAAC,mBAAmB,wBAAwB,SAAwC,IAAI;CAE9F,gBAAgB,kBAAkB,YAAY;EAC5C,IAAI,OAAO,SAAS;EACpB,OAAO,UAAU;EACjB,IAAI;GAKF,MAAM,IAAI,2BAA2B,CAAC,4BAA4B;GAElE,IAAI,CAAC,MADuB,IAAI,kBAAkB,GAEhD,MAAM,IAAI,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;EAEvD,SAAS,GAAG;GACV,IAAI,WAAW,aAAa,CAAC,GAAG;IAC9B,qBAAqB;KACnB,WAAW,EAAE;KACb,SAAS,EAAE;KACX,SAAS,KAAK,UAAU,EAAE,WAAW,CAAC,CAAC;IACzC,CAAC;IACD;GACF;GACA,aAAa,qBAAqB,CAAC;GACnC,qBAAqB,CAAC,CAAC;EACzB;CACF,CAAC,GAAG,CAAC,GAAG,CAAC;CAET,gBAAgB;EACd,iBAAiB,oBAAoB,IAAI,GAAG,GAAI;CAClD,GAAG,CAAC,CAAC;CAEL,IAAI,qBAAqB,MACvB,OAAO,oBAAC,WAAD;EAAW,cAAc;EAA6B;CAAW,CAAA;CAG1E,OACE,oBAAC,eAAD;EACE,UAAU,YAAY;EACtB,oBAAmB;YAEnB,qBAAC,OAAD;GACE,WAAW,GACT,yFACA,WAAW,QAAQ,KACrB;aAJF,CAME,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,SAAD,EAAS,MAAM,GAAK,CAAA;GACjB,CAAA,GACJ,mBAAmB,qBAAC,KAAD,EAAA,UAAA,CAAI,EAAE,2CAA2C,GAAE,oBAAC,YAAD;IACrE,WAAU;IACV,MAAK;IACL,UAAU,MAAM;KACd,EAAE,eAAe;KACjB,kBAAkB,IAAI,eAAe,CAAC;IACxC;cACA,EAAE,YAAY;GAAc,CAAA,CAAI,EAAA,CAAA,IAAI,IACnC;;CACQ,CAAA;AAEnB"}
1
+ {"version":3,"file":"oauth-callback.js","names":[],"sources":["../../../src/components-page/oauth-callback.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownError } from \"@hexclave/shared\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { Spinner, cn } from \"@hexclave/ui\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { hexclaveAppInternalsSymbol } from \"../lib/hexclave-app/common\";\nimport { ErrorPage } from \"./error-page\";\n\nexport function OAuthCallback({ fullPage }: { fullPage?: boolean }) {\n const app = useStackApp();\n const called = useRef(false);\n const [errorSearchParams, setErrorSearchParams] = useState<Record<string, string> | null>(null);\n\n useEffect(() => runAsynchronously(async () => {\n if (called.current) return;\n called.current = true;\n try {\n // The startup handler in StackClientApp's constructor may have already consumed the\n // one-time OAuth params (code + state cookie) via a microtask that fires before this\n // macrotask-scheduled useEffect. Await its completion so we don't race: if it succeeds\n // it will redirect and this page tears down; if it fails we fall through below.\n await app[hexclaveAppInternalsSymbol].awaitPendingAuthResolutions();\n const hasRedirected = await app.callOAuthCallback();\n if (!hasRedirected) {\n await app.redirectToSignIn({ noRedirectBack: true });\n }\n } catch (e) {\n if (KnownError.isKnownError(e)) {\n setErrorSearchParams({\n errorCode: e.errorCode,\n message: e.message,\n details: JSON.stringify(e.details ?? {}),\n });\n return;\n }\n captureError(\"<OAuthCallback />\", e);\n setErrorSearchParams({});\n }\n }), [app]);\n\n if (errorSearchParams != null) {\n return <ErrorPage searchParams={errorSearchParams} fullPage={fullPage} />;\n }\n\n return (\n <MaybeFullPage\n fullPage={fullPage ?? false}\n containerClassName=\"flex items-center justify-center\"\n >\n <div\n className={cn(\n \"text-center justify-center items-center stack-scope flex flex-col gap-4 max-w-[380px]\",\n fullPage ? \"p-4\" : \"p-0\"\n )}\n >\n <div className=\"flex flex-col justify-center items-center gap-4\">\n <Spinner size={20} />\n </div>\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,SAAgB,cAAc,EAAE,YAAoC;CAClE,MAAM,MAAM,YAAY;CACxB,MAAM,SAAS,OAAO,KAAK;CAC3B,MAAM,CAAC,mBAAmB,wBAAwB,SAAwC,IAAI;CAE9F,gBAAgB,kBAAkB,YAAY;EAC5C,IAAI,OAAO,SAAS;EACpB,OAAO,UAAU;EACjB,IAAI;GAKF,MAAM,IAAI,2BAA2B,CAAC,4BAA4B;GAElE,IAAI,CAAC,MADuB,IAAI,kBAAkB,GAEhD,MAAM,IAAI,iBAAiB,EAAE,gBAAgB,KAAK,CAAC;EAEvD,SAAS,GAAG;GACV,IAAI,WAAW,aAAa,CAAC,GAAG;IAC9B,qBAAqB;KACnB,WAAW,EAAE;KACb,SAAS,EAAE;KACX,SAAS,KAAK,UAAU,EAAE,WAAW,CAAC,CAAC;IACzC,CAAC;IACD;GACF;GACA,aAAa,qBAAqB,CAAC;GACnC,qBAAqB,CAAC,CAAC;EACzB;CACF,CAAC,GAAG,CAAC,GAAG,CAAC;CAET,IAAI,qBAAqB,MACvB,OAAO,oBAAC,WAAD;EAAW,cAAc;EAA6B;CAAW,CAAA;CAG1E,OACE,oBAAC,eAAD;EACE,UAAU,YAAY;EACtB,oBAAmB;YAEnB,oBAAC,OAAD;GACE,WAAW,GACT,yFACA,WAAW,QAAQ,KACrB;aAEA,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,SAAD,EAAS,MAAM,GAAK,CAAA;GACjB,CAAA;EACF,CAAA;CACQ,CAAA;AAEnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/lib/auth.ts"],"mappings":";;;;iBAWsB,6BAAA,CACpB,KAAA,EAAO,uBAAA,EACP,OAAA;EACE,QAAA;EACA,WAAA;EACA,gBAAA;EACA,aAAA;AAAA,GAEF,OAAA,EAAS,eAAA,GACR,OAAA;AAAA,iBA4JmB,iBAAA,CACpB,KAAA,EAAO,uBAAA,EACP,WAAA,UACA,OAAA;EACE,+BAAA;AAAA,IACD,OAAA"}
1
+ {"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/lib/auth.ts"],"mappings":";;;;iBAWsB,6BAAA,CACpB,KAAA,EAAO,uBAAA,EACP,OAAA;EACE,QAAA;EACA,WAAA;EACA,gBAAA;EACA,aAAA;AAAA,GAEF,OAAA,EAAS,eAAA,GACR,OAAA;AAAA,iBA8JmB,iBAAA,CACpB,KAAA,EAAO,uBAAA,EACP,WAAA,UACA,OAAA;EACE,+BAAA;AAAA,IACD,OAAA"}
@@ -11,7 +11,7 @@ async function getNewOAuthProviderOrScopeUrl(iface, options, session) {
11
11
  provider: options.provider,
12
12
  redirectUrl: constructRedirectUrl(options.redirectUrl, "redirectUrl"),
13
13
  errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, "errorRedirectUrl"),
14
- afterCallbackRedirectUrl: constructRedirectUrl(window.location.href, "afterCallbackRedirectUrl"),
14
+ afterCallbackRedirectUrl: window.location.href,
15
15
  codeChallenge,
16
16
  state,
17
17
  type: "link",
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","names":[],"sources":["../../../src/lib/auth.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownError, KnownErrors, HexclaveClientInterface } from \"@hexclave/shared\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport { HexclaveAssertionError, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { deindent } from \"@hexclave/shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\nexport async function getNewOAuthProviderOrScopeUrl(\n iface: HexclaveClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n): Promise<string> {\n const { codeChallenge, state } = await saveVerifierAndState();\n return await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl, \"redirectUrl\"),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, \"errorRedirectUrl\"),\n afterCallbackRedirectUrl: constructRedirectUrl(window.location.href, \"afterCallbackRedirectUrl\"),\n codeChallenge,\n state,\n type: \"link\",\n session,\n providerScope: options.providerScope,\n });\n}\n\n/**\n * Checks if the current URL has the query parameters for an OAuth callback, and if so, removes them.\n *\n * Must be synchronous for the logic in callOAuthCallback to work without race conditions.\n */\ntype OAuthCallbackConsumptionResult =\n | {\n type: \"oauth-response\",\n originalUrl: URL,\n codeVerifier: string,\n state: string,\n }\n | {\n type: \"known-error\",\n error: KnownError,\n };\n\nconst oauthErrorParams = [\"error\", \"error_description\", \"errorCode\", \"message\", \"details\"] as const;\n\nfunction removeOAuthErrorParamsFromHistory(originalUrl: URL): void {\n const newUrl = new URL(originalUrl);\n for (const param of oauthErrorParams) {\n newUrl.searchParams.delete(param);\n }\n window.history.replaceState({}, \"\", newUrl.toString());\n}\n\nfunction getProviderOAuthErrorFromUrl(originalUrl: URL): KnownError | null {\n const providerError = originalUrl.searchParams.get(\"error\");\n const providerErrorDescription = originalUrl.searchParams.get(\"error_description\");\n if (providerError == null && providerErrorDescription == null) {\n return null;\n }\n\n switch (providerError) {\n case \"access_denied\":\n case \"consent_required\": {\n return new KnownErrors.OAuthProviderAccessDenied();\n }\n case \"server_error\":\n case \"temporarily_unavailable\":\n default: {\n return new KnownErrors.OAuthProviderTemporarilyUnavailable();\n }\n }\n}\n\nfunction consumeOAuthCallbackQueryParams(options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n}): OAuthCallbackConsumptionResult | null {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n const knownErrorCode = originalUrl.searchParams.get(\"errorCode\");\n const knownErrorMessage = originalUrl.searchParams.get(\"message\");\n if (knownErrorCode && knownErrorMessage) {\n const details = originalUrl.searchParams.get(\"details\");\n let detailsJson = {};\n if (details) {\n try {\n detailsJson = JSON.parse(details);\n } catch (error) {\n throw new HexclaveAssertionError(\"OAuth callback returned malformed known-error details\", {\n details,\n cause: error,\n });\n }\n }\n\n removeOAuthErrorParamsFromHistory(originalUrl);\n\n return {\n type: \"known-error\",\n error: KnownError.fromJson({\n code: knownErrorCode,\n message: knownErrorMessage,\n details: detailsJson,\n }),\n };\n }\n\n const providerOAuthError = getProviderOAuthErrorFromUrl(originalUrl);\n if (providerOAuthError != null && !requiredParams.every(param => originalUrl.searchParams.has(param))) {\n removeOAuthErrorParamsFromHistory(originalUrl);\n return {\n type: \"known-error\",\n error: providerOAuthError,\n };\n }\n\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\n if (!options?.dontWarnAboutMissingQueryParams) {\n console.warn(new Error(`Missing required query parameter on OAuth callback: ${param}. Maybe you opened or reloaded the oauth-callback page from your history?`));\n }\n return null;\n }\n }\n\n const expectedState = originalUrl.searchParams.get(\"state\") ?? throwErr(\"This should never happen; isn't state required above?\");\n const cookieResult = consumeVerifierAndStateCookie(expectedState);\n\n if (!cookieResult) {\n // If the state can't be found in the cookies, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\n console.warn(deindent`\n Hexclave found an outer OAuth callback state in the query parameters, but not in cookies.\n\n This could have multiple reasons:\n - The cookie expired, because the OAuth flow took too long.\n - The user's browser deleted the cookie, either manually or because of a very strict cookie policy.\n - The cookie was already consumed by this page, and the user already logged in.\n - You are using another OAuth client library with the same callback URL as Hexclave.\n - The user opened the OAuth callback page from their history.\n\n Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.\n `);\n return null;\n }\n\n\n const newUrl = new URL(originalUrl);\n for (const param of requiredParams) {\n newUrl.searchParams.delete(param);\n }\n\n // let's get rid of the authorization code in the history as we\n // don't redirect to `redirectUrl` if there's a validation error\n // (as the redirectUrl might be malicious!).\n //\n // We use history.replaceState instead of location.assign(...) to\n // prevent an unnecessary reload\n window.history.replaceState({}, \"\", newUrl.toString());\n\n return {\n type: \"oauth-response\",\n originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: HexclaveClientInterface,\n redirectUrl: string,\n options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n },\n) {\n // note: this part of the function (until the return) needs\n // to be synchronous, to prevent race conditions when\n // callOAuthCallback is called multiple times in parallel\n const consumed = consumeOAuthCallbackQueryParams(options);\n if (!consumed) return Result.ok(undefined);\n if (consumed.type === \"known-error\") {\n throw consumed.error;\n }\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback, and the only instance\n // of callOAuthCallback that's running)\n try {\n return Result.ok(await iface.callOAuthCallback({\n oauthParams: consumed.originalUrl.searchParams,\n redirectUri: constructRedirectUrl(redirectUrl, \"redirectUri\"),\n codeVerifier: consumed.codeVerifier,\n state: consumed.state,\n }));\n } catch (e) {\n if (KnownError.isKnownError(e)) {\n throw e;\n }\n throw new HexclaveAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","names":[],"sources":["../../../src/lib/auth.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { KnownError, KnownErrors, HexclaveClientInterface } from \"@hexclave/shared\";\nimport { InternalSession } from \"@hexclave/shared/dist/sessions\";\nimport { HexclaveAssertionError, throwErr } from \"@hexclave/shared/dist/utils/errors\";\nimport { Result } from \"@hexclave/shared/dist/utils/results\";\nimport { deindent } from \"@hexclave/shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\nexport async function getNewOAuthProviderOrScopeUrl(\n iface: HexclaveClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n): Promise<string> {\n const { codeChallenge, state } = await saveVerifierAndState();\n return await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl, \"redirectUrl\"),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl, \"errorRedirectUrl\"),\n // Unlike callback URLs, this is the final user-facing location and may legitimately use a\n // fragment for an account-settings tab. Preserve it exactly.\n afterCallbackRedirectUrl: window.location.href,\n codeChallenge,\n state,\n type: \"link\",\n session,\n providerScope: options.providerScope,\n });\n}\n\n/**\n * Checks if the current URL has the query parameters for an OAuth callback, and if so, removes them.\n *\n * Must be synchronous for the logic in callOAuthCallback to work without race conditions.\n */\ntype OAuthCallbackConsumptionResult =\n | {\n type: \"oauth-response\",\n originalUrl: URL,\n codeVerifier: string,\n state: string,\n }\n | {\n type: \"known-error\",\n error: KnownError,\n };\n\nconst oauthErrorParams = [\"error\", \"error_description\", \"errorCode\", \"message\", \"details\"] as const;\n\nfunction removeOAuthErrorParamsFromHistory(originalUrl: URL): void {\n const newUrl = new URL(originalUrl);\n for (const param of oauthErrorParams) {\n newUrl.searchParams.delete(param);\n }\n window.history.replaceState({}, \"\", newUrl.toString());\n}\n\nfunction getProviderOAuthErrorFromUrl(originalUrl: URL): KnownError | null {\n const providerError = originalUrl.searchParams.get(\"error\");\n const providerErrorDescription = originalUrl.searchParams.get(\"error_description\");\n if (providerError == null && providerErrorDescription == null) {\n return null;\n }\n\n switch (providerError) {\n case \"access_denied\":\n case \"consent_required\": {\n return new KnownErrors.OAuthProviderAccessDenied();\n }\n case \"server_error\":\n case \"temporarily_unavailable\":\n default: {\n return new KnownErrors.OAuthProviderTemporarilyUnavailable();\n }\n }\n}\n\nfunction consumeOAuthCallbackQueryParams(options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n}): OAuthCallbackConsumptionResult | null {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n const knownErrorCode = originalUrl.searchParams.get(\"errorCode\");\n const knownErrorMessage = originalUrl.searchParams.get(\"message\");\n if (knownErrorCode && knownErrorMessage) {\n const details = originalUrl.searchParams.get(\"details\");\n let detailsJson = {};\n if (details) {\n try {\n detailsJson = JSON.parse(details);\n } catch (error) {\n throw new HexclaveAssertionError(\"OAuth callback returned malformed known-error details\", {\n details,\n cause: error,\n });\n }\n }\n\n removeOAuthErrorParamsFromHistory(originalUrl);\n\n return {\n type: \"known-error\",\n error: KnownError.fromJson({\n code: knownErrorCode,\n message: knownErrorMessage,\n details: detailsJson,\n }),\n };\n }\n\n const providerOAuthError = getProviderOAuthErrorFromUrl(originalUrl);\n if (providerOAuthError != null && !requiredParams.every(param => originalUrl.searchParams.has(param))) {\n removeOAuthErrorParamsFromHistory(originalUrl);\n return {\n type: \"known-error\",\n error: providerOAuthError,\n };\n }\n\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\n if (!options?.dontWarnAboutMissingQueryParams) {\n console.warn(new Error(`Missing required query parameter on OAuth callback: ${param}. Maybe you opened or reloaded the oauth-callback page from your history?`));\n }\n return null;\n }\n }\n\n const expectedState = originalUrl.searchParams.get(\"state\") ?? throwErr(\"This should never happen; isn't state required above?\");\n const cookieResult = consumeVerifierAndStateCookie(expectedState);\n\n if (!cookieResult) {\n // If the state can't be found in the cookies, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\n console.warn(deindent`\n Hexclave found an outer OAuth callback state in the query parameters, but not in cookies.\n\n This could have multiple reasons:\n - The cookie expired, because the OAuth flow took too long.\n - The user's browser deleted the cookie, either manually or because of a very strict cookie policy.\n - The cookie was already consumed by this page, and the user already logged in.\n - You are using another OAuth client library with the same callback URL as Hexclave.\n - The user opened the OAuth callback page from their history.\n\n Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.\n `);\n return null;\n }\n\n\n const newUrl = new URL(originalUrl);\n for (const param of requiredParams) {\n newUrl.searchParams.delete(param);\n }\n\n // let's get rid of the authorization code in the history as we\n // don't redirect to `redirectUrl` if there's a validation error\n // (as the redirectUrl might be malicious!).\n //\n // We use history.replaceState instead of location.assign(...) to\n // prevent an unnecessary reload\n window.history.replaceState({}, \"\", newUrl.toString());\n\n return {\n type: \"oauth-response\",\n originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: HexclaveClientInterface,\n redirectUrl: string,\n options?: {\n dontWarnAboutMissingQueryParams?: boolean,\n },\n) {\n // note: this part of the function (until the return) needs\n // to be synchronous, to prevent race conditions when\n // callOAuthCallback is called multiple times in parallel\n const consumed = consumeOAuthCallbackQueryParams(options);\n if (!consumed) return Result.ok(undefined);\n if (consumed.type === \"known-error\") {\n throw consumed.error;\n }\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback, and the only instance\n // of callOAuthCallback that's running)\n try {\n return Result.ok(await iface.callOAuthCallback({\n oauthParams: consumed.originalUrl.searchParams,\n redirectUri: constructRedirectUrl(redirectUrl, \"redirectUri\"),\n codeVerifier: consumed.codeVerifier,\n state: consumed.state,\n }));\n } catch (e) {\n if (KnownError.isKnownError(e)) {\n throw e;\n }\n throw new HexclaveAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":"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"}
@@ -24,7 +24,7 @@ function createTestInterface() {
24
24
  }
25
25
  describe("getNewOAuthProviderOrScopeUrl", () => {
26
26
  it("returns the OAuth URL without performing navigation", async () => {
27
- window.history.replaceState({}, "", "/account?after_auth_return_to=%2Fsettings");
27
+ window.history.replaceState({}, "", "/account?after_auth_return_to=%2Fsettings#connected-accounts");
28
28
  const iface = createTestInterface();
29
29
  const location = await getNewOAuthProviderOrScopeUrl(iface, {
30
30
  provider: "github",
@@ -39,7 +39,7 @@ describe("getNewOAuthProviderOrScopeUrl", () => {
39
39
  expect(`${url.origin}${url.pathname}`).toBe("https://api.example.com/api/v1/auth/oauth/authorize/github");
40
40
  expect(Object.fromEntries(url.searchParams.entries())).toMatchInlineSnapshot(`
41
41
  {
42
- "after_callback_redirect_url": "http://localhost:3000/account?after_auth_return_to=%2Fsettings",
42
+ "after_callback_redirect_url": "http://localhost:3000/account?after_auth_return_to=%2Fsettings#connected-accounts",
43
43
  "client_id": "00000000-0000-4000-8000-000000000000",
44
44
  "client_secret": "pck_test",
45
45
  "code_challenge": "<stripped code challenge>",
@@ -1 +1 @@
1
- {"version":3,"file":"auth.test.js","names":[],"sources":["../../../src/lib/auth.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport { HexclaveClientInterface, KnownErrors } from \"@hexclave/shared\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from \"./auth\";\n\nvi.mock(\"./cookie\", async (importOriginal) => {\n const actual = await importOriginal<typeof import(\"./cookie\")>();\n return {\n ...actual,\n saveVerifierAndState: async () => ({\n codeChallenge: \"<stripped code challenge>\",\n state: \"<stripped state>\",\n }),\n };\n});\n\nfunction createTestInterface() {\n return new HexclaveClientInterface({\n clientVersion: \"test\",\n getBaseUrl: () => \"https://api.example.com\",\n getApiUrls: () => [\"https://api.example.com\"],\n extraRequestHeaders: {},\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"pck_test\",\n });\n}\n\ndescribe(\"getNewOAuthProviderOrScopeUrl\", () => {\n it(\"returns the OAuth URL without performing navigation\", async () => {\n window.history.replaceState({}, \"\", \"/account?after_auth_return_to=%2Fsettings\");\n\n const iface = createTestInterface();\n const session = iface.createSession({ refreshToken: null, accessToken: null });\n\n const location = await getNewOAuthProviderOrScopeUrl(\n iface,\n {\n provider: \"github\",\n redirectUrl: \"/handler/oauth-callback\",\n errorRedirectUrl: \"/handler/error\",\n providerScope: \"repo user\",\n },\n session,\n );\n\n const url = new URL(location);\n expect(`${url.origin}${url.pathname}`).toBe(\"https://api.example.com/api/v1/auth/oauth/authorize/github\");\n expect(Object.fromEntries(url.searchParams.entries())).toMatchInlineSnapshot(`\n {\n \"after_callback_redirect_url\": \"http://localhost:3000/account?after_auth_return_to=%2Fsettings\",\n \"client_id\": \"00000000-0000-4000-8000-000000000000\",\n \"client_secret\": \"pck_test\",\n \"code_challenge\": \"<stripped code challenge>\",\n \"code_challenge_method\": \"S256\",\n \"error_redirect_url\": \"http://localhost:3000/handler/error?after_auth_return_to=%2Fsettings\",\n \"grant_type\": \"authorization_code\",\n \"provider_scope\": \"repo user\",\n \"redirect_uri\": \"http://localhost:3000/handler/oauth-callback?after_auth_return_to=%2Fsettings\",\n \"response_type\": \"code\",\n \"scope\": \"legacy\",\n \"state\": \"<stripped state>\",\n \"type\": \"link\",\n }\n `);\n });\n});\n\ndescribe(\"callOAuthCallback\", () => {\n it(\"turns provider access denial callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=access_denied&error_description=User+cancelled\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderAccessDenied.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n\n it(\"turns generic provider error callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=server_error&error_description=Provider+failed\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderTemporarilyUnavailable.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n});\n"],"mappings":";;;;;AAUA,GAAG,KAAK,YAAY,OAAO,mBAAmB;CAE5C,OAAO;EACL,GAAG,MAFgB,eAA0C;EAG7D,sBAAsB,aAAa;GACjC,eAAe;GACf,OAAO;EACT;CACF;AACF,CAAC;AAED,SAAS,sBAAsB;CAC7B,OAAO,IAAI,wBAAwB;EACjC,eAAe;EACf,kBAAkB;EAClB,kBAAkB,CAAC,yBAAyB;EAC5C,qBAAqB,CAAC;EACtB,WAAW;EACX,sBAAsB;CACxB,CAAC;AACH;AAEA,SAAS,uCAAuC;CAC9C,GAAG,uDAAuD,YAAY;EACpE,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,2CAA2C;EAE/E,MAAM,QAAQ,oBAAoB;EAGlC,MAAM,WAAW,MAAM,8BACrB,OACA;GACE,UAAU;GACV,aAAa;GACb,kBAAkB;GAClB,eAAe;EACjB,GATc,MAAM,cAAc;GAAE,cAAc;GAAM,aAAa;EAAK,CAUpE,CACR;EAEA,MAAM,MAAM,IAAI,IAAI,QAAQ;EAC5B,OAAO,GAAG,IAAI,SAAS,IAAI,UAAU,CAAC,CAAC,KAAK,4DAA4D;EACxG,OAAO,OAAO,YAAY,IAAI,aAAa,QAAQ,CAAC,CAAC,CAAC,CAAC,sBAAsB;;;;;;;;;;;;;;;;KAgB5E;CACH,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B;CAClC,GAAG,mEAAmE,YAAY;EAChF,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8EAA8E;EAElH,MAAM,OAAO,kBAAkB,oBAAoB,GAAG,yBAAyB,CAAC,CAAC,CAC9E,QAAQ,WAAW,UAAmB,YAAY,0BAA0B,WAAW,KAAK,CAAC;EAChG,OAAO,OAAO,SAAS,IAAI,CAAC,CAAC,KAAK,8CAA8C;CAClF,CAAC;CAED,GAAG,mEAAmE,YAAY;EAChF,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8EAA8E;EAElH,MAAM,OAAO,kBAAkB,oBAAoB,GAAG,yBAAyB,CAAC,CAAC,CAC9E,QAAQ,WAAW,UAAmB,YAAY,oCAAoC,WAAW,KAAK,CAAC;EAC1G,OAAO,OAAO,SAAS,IAAI,CAAC,CAAC,KAAK,8CAA8C;CAClF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"auth.test.js","names":[],"sources":["../../../src/lib/auth.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// @vitest-environment jsdom\n\nimport { HexclaveClientInterface, KnownErrors } from \"@hexclave/shared\";\nimport { describe, expect, it, vi } from \"vitest\";\nimport { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from \"./auth\";\n\nvi.mock(\"./cookie\", async (importOriginal) => {\n const actual = await importOriginal<typeof import(\"./cookie\")>();\n return {\n ...actual,\n saveVerifierAndState: async () => ({\n codeChallenge: \"<stripped code challenge>\",\n state: \"<stripped state>\",\n }),\n };\n});\n\nfunction createTestInterface() {\n return new HexclaveClientInterface({\n clientVersion: \"test\",\n getBaseUrl: () => \"https://api.example.com\",\n getApiUrls: () => [\"https://api.example.com\"],\n extraRequestHeaders: {},\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"pck_test\",\n });\n}\n\ndescribe(\"getNewOAuthProviderOrScopeUrl\", () => {\n it(\"returns the OAuth URL without performing navigation\", async () => {\n window.history.replaceState({}, \"\", \"/account?after_auth_return_to=%2Fsettings#connected-accounts\");\n\n const iface = createTestInterface();\n const session = iface.createSession({ refreshToken: null, accessToken: null });\n\n const location = await getNewOAuthProviderOrScopeUrl(\n iface,\n {\n provider: \"github\",\n redirectUrl: \"/handler/oauth-callback\",\n errorRedirectUrl: \"/handler/error\",\n providerScope: \"repo user\",\n },\n session,\n );\n\n const url = new URL(location);\n expect(`${url.origin}${url.pathname}`).toBe(\"https://api.example.com/api/v1/auth/oauth/authorize/github\");\n expect(Object.fromEntries(url.searchParams.entries())).toMatchInlineSnapshot(`\n {\n \"after_callback_redirect_url\": \"http://localhost:3000/account?after_auth_return_to=%2Fsettings#connected-accounts\",\n \"client_id\": \"00000000-0000-4000-8000-000000000000\",\n \"client_secret\": \"pck_test\",\n \"code_challenge\": \"<stripped code challenge>\",\n \"code_challenge_method\": \"S256\",\n \"error_redirect_url\": \"http://localhost:3000/handler/error?after_auth_return_to=%2Fsettings\",\n \"grant_type\": \"authorization_code\",\n \"provider_scope\": \"repo user\",\n \"redirect_uri\": \"http://localhost:3000/handler/oauth-callback?after_auth_return_to=%2Fsettings\",\n \"response_type\": \"code\",\n \"scope\": \"legacy\",\n \"state\": \"<stripped state>\",\n \"type\": \"link\",\n }\n `);\n });\n});\n\ndescribe(\"callOAuthCallback\", () => {\n it(\"turns provider access denial callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=access_denied&error_description=User+cancelled\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderAccessDenied.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n\n it(\"turns generic provider error callback params into a known error\", async () => {\n window.history.replaceState({}, \"\", \"/handler/oauth-callback?error=server_error&error_description=Provider+failed\");\n\n await expect(callOAuthCallback(createTestInterface(), \"/handler/oauth-callback\"))\n .rejects.toSatisfy((error: unknown) => KnownErrors.OAuthProviderTemporarilyUnavailable.isInstance(error));\n expect(window.location.href).toBe(\"http://localhost:3000/handler/oauth-callback\");\n });\n});\n"],"mappings":";;;;;AAUA,GAAG,KAAK,YAAY,OAAO,mBAAmB;CAE5C,OAAO;EACL,GAAG,MAFgB,eAA0C;EAG7D,sBAAsB,aAAa;GACjC,eAAe;GACf,OAAO;EACT;CACF;AACF,CAAC;AAED,SAAS,sBAAsB;CAC7B,OAAO,IAAI,wBAAwB;EACjC,eAAe;EACf,kBAAkB;EAClB,kBAAkB,CAAC,yBAAyB;EAC5C,qBAAqB,CAAC;EACtB,WAAW;EACX,sBAAsB;CACxB,CAAC;AACH;AAEA,SAAS,uCAAuC;CAC9C,GAAG,uDAAuD,YAAY;EACpE,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8DAA8D;EAElG,MAAM,QAAQ,oBAAoB;EAGlC,MAAM,WAAW,MAAM,8BACrB,OACA;GACE,UAAU;GACV,aAAa;GACb,kBAAkB;GAClB,eAAe;EACjB,GATc,MAAM,cAAc;GAAE,cAAc;GAAM,aAAa;EAAK,CAUpE,CACR;EAEA,MAAM,MAAM,IAAI,IAAI,QAAQ;EAC5B,OAAO,GAAG,IAAI,SAAS,IAAI,UAAU,CAAC,CAAC,KAAK,4DAA4D;EACxG,OAAO,OAAO,YAAY,IAAI,aAAa,QAAQ,CAAC,CAAC,CAAC,CAAC,sBAAsB;;;;;;;;;;;;;;;;KAgB5E;CACH,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B;CAClC,GAAG,mEAAmE,YAAY;EAChF,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8EAA8E;EAElH,MAAM,OAAO,kBAAkB,oBAAoB,GAAG,yBAAyB,CAAC,CAAC,CAC9E,QAAQ,WAAW,UAAmB,YAAY,0BAA0B,WAAW,KAAK,CAAC;EAChG,OAAO,OAAO,SAAS,IAAI,CAAC,CAAC,KAAK,8CAA8C;CAClF,CAAC;CAED,GAAG,mEAAmE,YAAY;EAChF,OAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,8EAA8E;EAElH,MAAM,OAAO,kBAAkB,oBAAoB,GAAG,yBAAyB,CAAC,CAAC,CAC9E,QAAQ,WAAW,UAAmB,YAAY,oCAAoC,WAAW,KAAK,CAAC;EAC1G,OAAO,OAAO,SAAS,IAAI,CAAC,CAAC,KAAK,8CAA8C;CAClF,CAAC;AACH,CAAC"}
@@ -192,6 +192,7 @@ declare class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Pro
192
192
  inheritsFrom?: import("..").StackClientApp<any, any>;
193
193
  devTool?: boolean | "auto";
194
194
  noAutomaticPrefetch?: boolean;
195
+ automaticSideEffects?: boolean;
195
196
  analytics?: import("./session-replay").AnalyticsOptions;
196
197
  } & {
197
198
  tokenStore: import("../../common").TokenStoreInit<HasTokenStore>;
@@ -220,6 +221,7 @@ declare class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Pro
220
221
  inheritsFrom?: import("..").StackClientApp<any, any>;
221
222
  devTool?: boolean | "auto";
222
223
  noAutomaticPrefetch?: boolean;
224
+ automaticSideEffects?: boolean;
223
225
  analytics?: import("./session-replay").AnalyticsOptions;
224
226
  } & {
225
227
  tokenStore: import("../../common").TokenStoreInit<HasTokenStore>;
@@ -250,6 +252,7 @@ declare class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Pro
250
252
  } | undefined) => Promise<void>;
251
253
  getRedirectToHandlerUrl: (handlerName: keyof import("@hexclave/shared/dist/handler-urls-BHt3v8Ai").o, options?: import("../../common").RedirectToOptions) => Promise<string>;
252
254
  redirectToHandler: (handlerName: keyof import("@hexclave/shared/dist/handler-urls-BHt3v8Ai").o, options?: import("../../common").RedirectToOptions) => Promise<void>;
255
+ getRawAfterAuthReturnTo: () => string | null;
253
256
  refreshOwnedProjects: () => Promise<void>;
254
257
  signInWithTokens: (tokens: {
255
258
  accessToken: string;
@@ -1 +1 @@
1
- {"version":3,"file":"admin-app-impl.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/admin-app-impl.ts"],"mappings":"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"}
1
+ {"version":3,"file":"admin-app-impl.d.ts","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/admin-app-impl.ts"],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { hexclaveAppInternalsSymbol } from "../../common.js";
3
+ import { HexclaveClientApp } from "../interfaces/client-app.js";
4
+ //#region src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts
5
+ const baseOptions = {
6
+ baseUrl: "http://localhost:12345",
7
+ projectId: "00000000-0000-4000-8000-000000000000",
8
+ publishableClientKey: "stack-pk-test",
9
+ tokenStore: "memory",
10
+ redirectMethod: "none"
11
+ };
12
+ describe("HexclaveClientApp automatic side effects", () => {
13
+ it("does not inspect browser state when disabled", () => {
14
+ const previousWindow = Reflect.get(globalThis, "window");
15
+ const previousDocument = Reflect.get(globalThis, "document");
16
+ const hadPreviousWindow = Reflect.has(globalThis, "window");
17
+ const hadPreviousDocument = Reflect.has(globalThis, "document");
18
+ const browserGlobal = {};
19
+ Object.defineProperty(browserGlobal, "location", { get() {
20
+ throw new Error("Construction must not inspect the current URL when automatic side effects are disabled");
21
+ } });
22
+ Reflect.set(globalThis, "window", browserGlobal);
23
+ Object.defineProperty(globalThis, "document", {
24
+ configurable: true,
25
+ get() {
26
+ throw new Error("Construction must not access the document when automatic side effects are disabled");
27
+ }
28
+ });
29
+ try {
30
+ expect(() => new HexclaveClientApp({
31
+ ...baseOptions,
32
+ automaticSideEffects: false
33
+ })).not.toThrow();
34
+ } finally {
35
+ if (hadPreviousWindow) Reflect.set(globalThis, "window", previousWindow);
36
+ else Reflect.deleteProperty(globalThis, "window");
37
+ if (hadPreviousDocument) Object.defineProperty(globalThis, "document", {
38
+ configurable: true,
39
+ value: previousDocument,
40
+ writable: true
41
+ });
42
+ else Reflect.deleteProperty(globalThis, "document");
43
+ }
44
+ });
45
+ it("does not initialize automatic side effects when disabled", () => {
46
+ const methodName = "_initializeAutomaticSideEffects";
47
+ const originalInitializer = Reflect.get(HexclaveClientApp.prototype, methodName);
48
+ let initializationCalls = 0;
49
+ Reflect.set(HexclaveClientApp.prototype, methodName, () => {
50
+ initializationCalls += 1;
51
+ });
52
+ try {
53
+ new HexclaveClientApp({
54
+ ...baseOptions,
55
+ automaticSideEffects: false
56
+ });
57
+ expect(initializationCalls).toBe(0);
58
+ } finally {
59
+ Reflect.set(HexclaveClientApp.prototype, methodName, originalInitializer);
60
+ }
61
+ });
62
+ it.each([void 0, true])("retains automatic initialization when automaticSideEffects is %s", (automaticSideEffects) => {
63
+ const methodName = "_initializeAutomaticSideEffects";
64
+ const originalInitializer = Reflect.get(HexclaveClientApp.prototype, methodName);
65
+ let initializationCalls = 0;
66
+ Reflect.set(HexclaveClientApp.prototype, methodName, () => {
67
+ initializationCalls += 1;
68
+ });
69
+ try {
70
+ new HexclaveClientApp({
71
+ ...baseOptions,
72
+ automaticSideEffects
73
+ });
74
+ expect(initializationCalls).toBe(1);
75
+ } finally {
76
+ Reflect.set(HexclaveClientApp.prototype, methodName, originalInitializer);
77
+ }
78
+ });
79
+ it("preserves the option through serialization", () => {
80
+ expect(new HexclaveClientApp({
81
+ ...baseOptions,
82
+ automaticSideEffects: false
83
+ })[hexclaveAppInternalsSymbol].toClientJson().automaticSideEffects).toBe(false);
84
+ });
85
+ it("preserves stable identity when deserializing with automatic side effects disabled", () => {
86
+ const json = {
87
+ baseUrl: baseOptions.baseUrl,
88
+ projectId: baseOptions.projectId,
89
+ publishableClientKey: baseOptions.publishableClientKey,
90
+ tokenStore: null,
91
+ redirectMethod: baseOptions.redirectMethod,
92
+ automaticSideEffects: false,
93
+ uniqueIdentifier: "00000000-0000-4000-8000-000000000001"
94
+ };
95
+ const first = HexclaveClientApp[hexclaveAppInternalsSymbol].fromClientJson(json);
96
+ expect(HexclaveClientApp[hexclaveAppInternalsSymbol].fromClientJson(json)).toBe(first);
97
+ });
98
+ });
99
+ //#endregion
100
+ export {};
101
+
102
+ //# sourceMappingURL=client-app-impl.automatic-side-effects.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-app-impl.automatic-side-effects.test.js","names":[],"sources":["../../../../../../src/lib/hexclave-app/apps/implementations/client-app-impl.automatic-side-effects.test.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\nimport { describe, expect, it } from \"vitest\";\nimport { hexclaveAppInternalsSymbol } from \"../../common\";\nimport { HexclaveClientApp, HexclaveClientAppConstructorOptions, HexclaveClientAppJson } from \"../interfaces/client-app\";\n\nconst baseOptions = {\n baseUrl: \"http://localhost:12345\",\n projectId: \"00000000-0000-4000-8000-000000000000\",\n publishableClientKey: \"stack-pk-test\",\n tokenStore: \"memory\",\n redirectMethod: \"none\",\n} satisfies HexclaveClientAppConstructorOptions<true, string>;\n\ndescribe(\"HexclaveClientApp automatic side effects\", () => {\n it(\"does not inspect browser state when disabled\", () => {\n const previousWindow = Reflect.get(globalThis, \"window\");\n const previousDocument = Reflect.get(globalThis, \"document\");\n const hadPreviousWindow = Reflect.has(globalThis, \"window\");\n const hadPreviousDocument = Reflect.has(globalThis, \"document\");\n const browserGlobal = {};\n Object.defineProperty(browserGlobal, \"location\", {\n get() {\n throw new Error(\"Construction must not inspect the current URL when automatic side effects are disabled\");\n },\n });\n\n Reflect.set(globalThis, \"window\", browserGlobal);\n Object.defineProperty(globalThis, \"document\", {\n configurable: true,\n get() {\n throw new Error(\"Construction must not access the document when automatic side effects are disabled\");\n },\n });\n\n try {\n expect(() => new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects: false,\n })).not.toThrow();\n } finally {\n if (hadPreviousWindow) {\n Reflect.set(globalThis, \"window\", previousWindow);\n } else {\n Reflect.deleteProperty(globalThis, \"window\");\n }\n if (hadPreviousDocument) {\n Object.defineProperty(globalThis, \"document\", {\n configurable: true,\n value: previousDocument,\n writable: true,\n });\n } else {\n Reflect.deleteProperty(globalThis, \"document\");\n }\n }\n });\n\n it(\"does not initialize automatic side effects when disabled\", () => {\n const methodName = \"_initializeAutomaticSideEffects\";\n const originalInitializer = Reflect.get(HexclaveClientApp.prototype, methodName);\n let initializationCalls = 0;\n Reflect.set(HexclaveClientApp.prototype, methodName, () => {\n initializationCalls += 1;\n });\n\n try {\n new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects: false,\n });\n\n expect(initializationCalls).toBe(0);\n } finally {\n Reflect.set(HexclaveClientApp.prototype, methodName, originalInitializer);\n }\n });\n\n it.each([undefined, true])(\"retains automatic initialization when automaticSideEffects is %s\", (automaticSideEffects) => {\n const methodName = \"_initializeAutomaticSideEffects\";\n const originalInitializer = Reflect.get(HexclaveClientApp.prototype, methodName);\n let initializationCalls = 0;\n Reflect.set(HexclaveClientApp.prototype, methodName, () => {\n initializationCalls += 1;\n });\n\n try {\n new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects,\n });\n\n expect(initializationCalls).toBe(1);\n } finally {\n Reflect.set(HexclaveClientApp.prototype, methodName, originalInitializer);\n }\n });\n\n it(\"preserves the option through serialization\", () => {\n const app = new HexclaveClientApp({\n ...baseOptions,\n automaticSideEffects: false,\n });\n\n expect(app[hexclaveAppInternalsSymbol].toClientJson().automaticSideEffects).toBe(false);\n });\n\n it(\"preserves stable identity when deserializing with automatic side effects disabled\", () => {\n const json: HexclaveClientAppJson<false, string> = {\n baseUrl: baseOptions.baseUrl,\n projectId: baseOptions.projectId,\n publishableClientKey: baseOptions.publishableClientKey,\n tokenStore: null,\n redirectMethod: baseOptions.redirectMethod,\n automaticSideEffects: false,\n uniqueIdentifier: \"00000000-0000-4000-8000-000000000001\",\n };\n\n const first = HexclaveClientApp[hexclaveAppInternalsSymbol].fromClientJson(json);\n const second = HexclaveClientApp[hexclaveAppInternalsSymbol].fromClientJson(json);\n\n expect(second).toBe(first);\n });\n});\n"],"mappings":";;;;AAQA,MAAM,cAAc;CAClB,SAAS;CACT,WAAW;CACX,sBAAsB;CACtB,YAAY;CACZ,gBAAgB;AAClB;AAEA,SAAS,kDAAkD;CACzD,GAAG,sDAAsD;EACvD,MAAM,iBAAiB,QAAQ,IAAI,YAAY,QAAQ;EACvD,MAAM,mBAAmB,QAAQ,IAAI,YAAY,UAAU;EAC3D,MAAM,oBAAoB,QAAQ,IAAI,YAAY,QAAQ;EAC1D,MAAM,sBAAsB,QAAQ,IAAI,YAAY,UAAU;EAC9D,MAAM,gBAAgB,CAAC;EACvB,OAAO,eAAe,eAAe,YAAY,EAC/C,MAAM;GACJ,MAAM,IAAI,MAAM,wFAAwF;EAC1G,EACF,CAAC;EAED,QAAQ,IAAI,YAAY,UAAU,aAAa;EAC/C,OAAO,eAAe,YAAY,YAAY;GAC5C,cAAc;GACd,MAAM;IACJ,MAAM,IAAI,MAAM,oFAAoF;GACtG;EACF,CAAC;EAED,IAAI;GACF,aAAa,IAAI,kBAAkB;IACjC,GAAG;IACH,sBAAsB;GACxB,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ;EAClB,UAAU;GACR,IAAI,mBACF,QAAQ,IAAI,YAAY,UAAU,cAAc;QAEhD,QAAQ,eAAe,YAAY,QAAQ;GAE7C,IAAI,qBACF,OAAO,eAAe,YAAY,YAAY;IAC5C,cAAc;IACd,OAAO;IACP,UAAU;GACZ,CAAC;QAED,QAAQ,eAAe,YAAY,UAAU;EAEjD;CACF,CAAC;CAED,GAAG,kEAAkE;EACnE,MAAM,aAAa;EACnB,MAAM,sBAAsB,QAAQ,IAAI,kBAAkB,WAAW,UAAU;EAC/E,IAAI,sBAAsB;EAC1B,QAAQ,IAAI,kBAAkB,WAAW,kBAAkB;GACzD,uBAAuB;EACzB,CAAC;EAED,IAAI;GACF,IAAI,kBAAkB;IACpB,GAAG;IACH,sBAAsB;GACxB,CAAC;GAED,OAAO,mBAAmB,CAAC,CAAC,KAAK,CAAC;EACpC,UAAU;GACR,QAAQ,IAAI,kBAAkB,WAAW,YAAY,mBAAmB;EAC1E;CACF,CAAC;CAED,GAAG,KAAK,CAAC,KAAA,GAAW,IAAI,CAAC,CAAC,CAAC,qEAAqE,yBAAyB;EACvH,MAAM,aAAa;EACnB,MAAM,sBAAsB,QAAQ,IAAI,kBAAkB,WAAW,UAAU;EAC/E,IAAI,sBAAsB;EAC1B,QAAQ,IAAI,kBAAkB,WAAW,kBAAkB;GACzD,uBAAuB;EACzB,CAAC;EAED,IAAI;GACF,IAAI,kBAAkB;IACpB,GAAG;IACH;GACF,CAAC;GAED,OAAO,mBAAmB,CAAC,CAAC,KAAK,CAAC;EACpC,UAAU;GACR,QAAQ,IAAI,kBAAkB,WAAW,YAAY,mBAAmB;EAC1E;CACF,CAAC;CAED,GAAG,oDAAoD;EAMrD,OAAO,IALS,kBAAkB;GAChC,GAAG;GACH,sBAAsB;EACxB,CAES,CAAC,CAAC,2BAA2B,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,CAAC,KAAK,KAAK;CACxF,CAAC;CAED,GAAG,2FAA2F;EAC5F,MAAM,OAA6C;GACjD,SAAS,YAAY;GACrB,WAAW,YAAY;GACvB,sBAAsB,YAAY;GAClC,YAAY;GACZ,gBAAgB,YAAY;GAC5B,sBAAsB;GACtB,kBAAkB;EACpB;EAEA,MAAM,QAAQ,kBAAkB,2BAA2B,CAAC,eAAe,IAAI;EAG/E,OAFe,kBAAkB,2BAA2B,CAAC,eAAe,IAEhE,CAAC,CAAC,CAAC,KAAK,KAAK;CAC3B,CAAC;AACH,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import { describe, expect, it, vi } from "vitest";
2
2
  import { hexclaveAppInternalsSymbol } from "../../common.js";
3
+ import { StackClientApp } from "../interfaces/client-app.js";
3
4
  import { AccessToken } from "@hexclave/shared/dist/sessions";
4
5
  import { Store } from "@hexclave/shared/dist/utils/stores";
5
- import { StackClientApp } from "../interfaces/client-app.js";
6
+ import { planRedirectToHandler } from "./redirect-page-urls.js";
6
7
  //#region src/lib/hexclave-app/apps/implementations/client-app-impl.cross-domain.test.ts
7
8
  function createAccessTokenString(refreshTokenId) {
8
9
  const encode = (value) => Buffer.from(JSON.stringify(value)).toString("base64url");
@@ -51,6 +52,57 @@ function createMockDocument() {
51
52
  };
52
53
  }
53
54
  describe("StackClientApp cross-domain auth", () => {
55
+ it("keeps noRedirectBack same-domain redirects free of redirect-back state", async () => {
56
+ expect(await planRedirectToHandler({
57
+ handlerName: "signIn",
58
+ rawHandlerUrl: "/handler/sign-in",
59
+ noRedirectBack: true,
60
+ currentUrl: new URL("https://app.example.test/settings?tab=profile"),
61
+ localOAuthCallbackUrl: "/handler/oauth-callback",
62
+ rawHomeUrl: "/home",
63
+ getCrossDomainHandoffParams: async () => {
64
+ throw new Error("Same-domain redirects must not create cross-domain handoff parameters.");
65
+ }
66
+ })).toEqual({
67
+ type: "redirect",
68
+ url: "/handler/sign-in"
69
+ });
70
+ });
71
+ it("returns noRedirectBack cross-domain auth to the source app home", async () => {
72
+ const handoffState = "no-redirect-back-state";
73
+ const handoffCodeChallenge = "abcdefghijklmnopqrstuvwxyzABCDEFG_0123456789-._~";
74
+ const currentUrl = new URL("https://app.example.test/settings?tab=profile");
75
+ currentUrl.searchParams.set("hexclave_cross_domain_state", handoffState);
76
+ currentUrl.searchParams.set("hexclave_cross_domain_code_challenge", handoffCodeChallenge);
77
+ currentUrl.searchParams.set("hexclave_cross_domain_after_callback_redirect_url", "https://app.example.test/settings?tab=profile");
78
+ const redirectPlan = await planRedirectToHandler({
79
+ handlerName: "signIn",
80
+ rawHandlerUrl: "https://auth.example.test/handler/sign-in",
81
+ noRedirectBack: true,
82
+ currentUrl,
83
+ localOAuthCallbackUrl: "/handler/oauth-callback",
84
+ rawHomeUrl: "/home",
85
+ getCrossDomainHandoffParams: async () => {
86
+ throw new Error("Existing cross-domain handoff parameters must be reused.");
87
+ }
88
+ });
89
+ expect(redirectPlan.type).toBe("redirect");
90
+ if (redirectPlan.type !== "redirect") throw new Error("Expected noRedirectBack sign-in to produce a redirect URL.");
91
+ const hostedUrl = new URL(redirectPlan.url);
92
+ expect(hostedUrl.origin).toBe("https://auth.example.test");
93
+ expect(hostedUrl.pathname).toBe("/handler/sign-in");
94
+ expect(hostedUrl.searchParams.get("hexclave_cross_domain_after_callback_redirect_url")).toBe("https://app.example.test/home");
95
+ const rawSourceCallbackUrl = hostedUrl.searchParams.get("after_auth_return_to");
96
+ if (rawSourceCallbackUrl == null) throw new Error("Expected cross-domain noRedirectBack to include its internal source callback URL.");
97
+ const sourceCallbackUrl = new URL(rawSourceCallbackUrl);
98
+ expect(sourceCallbackUrl.origin).toBe("https://app.example.test");
99
+ expect(sourceCallbackUrl.pathname).toBe("/handler/oauth-callback");
100
+ expect(sourceCallbackUrl.searchParams.get("hexclave_cross_domain_auth")).toBe("1");
101
+ expect(sourceCallbackUrl.searchParams.get("hexclave_cross_domain_state")).toBe(handoffState);
102
+ expect(sourceCallbackUrl.searchParams.get("hexclave_cross_domain_code_challenge")).toBe(handoffCodeChallenge);
103
+ expect(sourceCallbackUrl.searchParams.get("hexclave_cross_domain_after_callback_redirect_url")).toBe("https://app.example.test/home");
104
+ expect(sourceCallbackUrl.toString()).not.toContain("/settings");
105
+ });
54
106
  it("exposes redirect-back-aware handler URLs for devtool previews", async () => {
55
107
  const previousWindow = Reflect.get(globalThis, "window");
56
108
  const hadPreviousWindow = Reflect.has(globalThis, "window");
@@ -384,6 +436,8 @@ describe("StackClientApp cross-domain auth", () => {
384
436
  callbackUrl.searchParams.set("errorCode", "SIGN_UP_REJECTED");
385
437
  callbackUrl.searchParams.set("message", "Your sign up was rejected by an administrator's sign-up rule.");
386
438
  callbackUrl.searchParams.set("details", JSON.stringify({ message: "Your sign up was rejected by an administrator's sign-up rule." }));
439
+ callbackUrl.searchParams.set("after_auth_return_to", "/dashboard");
440
+ callbackUrl.searchParams.set("after_callback_redirect_url", "https://customer.example.test/settings?tab=connected-accounts");
387
441
  let currentHref = callbackUrl.toString();
388
442
  let redirectedUrl = "";
389
443
  const redirectSpy = vi.spyOn(StackClientApp.prototype, "_redirectTo").mockImplementation(async (...args) => {
@@ -428,6 +482,8 @@ describe("StackClientApp cross-domain auth", () => {
428
482
  expect(errorUrl.pathname).toBe("/handler/error");
429
483
  expect(errorUrl.searchParams.get("errorCode")).toBe("SIGN_UP_REJECTED");
430
484
  expect(errorUrl.searchParams.get("message")).toBe("Your sign up was rejected by an administrator's sign-up rule.");
485
+ expect(errorUrl.searchParams.get("after_auth_return_to")).toBe("/dashboard");
486
+ expect(errorUrl.searchParams.get("after_callback_redirect_url")).toBe("https://customer.example.test/settings?tab=connected-accounts");
431
487
  expect(new URL(currentHref).searchParams.has("errorCode")).toBe(false);
432
488
  });
433
489
  it("uses direct sign-out instead of hosted sign-out redirects when code execution is available", async () => {