@strivacity/sdk-core 3.0.3 → 4.0.0-beta.0

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 (327) hide show
  1. package/README.md +1873 -340
  2. package/dist/assets/oidc.cjs +2 -0
  3. package/dist/assets/oidc.cjs.map +1 -0
  4. package/dist/assets/oidc.mjs +2 -0
  5. package/dist/assets/oidc.mjs.map +1 -0
  6. package/dist/assets/server.cjs +2 -0
  7. package/dist/assets/server.cjs.map +1 -0
  8. package/dist/assets/server.mjs +2 -0
  9. package/dist/assets/server.mjs.map +1 -0
  10. package/dist/flows/base.cjs +2 -0
  11. package/dist/flows/base.cjs.map +1 -0
  12. package/dist/flows/base.d.ts +26 -0
  13. package/dist/flows/base.mjs +2 -0
  14. package/dist/flows/base.mjs.map +1 -0
  15. package/dist/flows/embedded.cjs +2 -0
  16. package/dist/flows/embedded.cjs.map +1 -0
  17. package/dist/flows/embedded.d.ts +9 -0
  18. package/dist/flows/embedded.mjs +2 -0
  19. package/dist/flows/embedded.mjs.map +1 -0
  20. package/dist/flows/index.cjs +1 -0
  21. package/dist/flows/index.d.ts +5 -0
  22. package/dist/flows/index.mjs +1 -0
  23. package/dist/flows/native.cjs +2 -0
  24. package/dist/flows/native.cjs.map +1 -0
  25. package/dist/flows/native.d.ts +9 -0
  26. package/dist/flows/native.mjs +2 -0
  27. package/dist/flows/native.mjs.map +1 -0
  28. package/dist/flows/popup.cjs +2 -0
  29. package/dist/flows/popup.cjs.map +1 -0
  30. package/dist/flows/popup.d.ts +9 -0
  31. package/dist/flows/popup.mjs +2 -0
  32. package/dist/flows/popup.mjs.map +1 -0
  33. package/dist/flows/redirect.cjs +2 -0
  34. package/dist/flows/redirect.cjs.map +1 -0
  35. package/dist/flows/redirect.d.ts +9 -0
  36. package/dist/flows/redirect.mjs +2 -0
  37. package/dist/flows/redirect.mjs.map +1 -0
  38. package/dist/handlers/embedded.cjs +2 -0
  39. package/dist/handlers/embedded.cjs.map +1 -0
  40. package/dist/handlers/embedded.d.ts +37 -0
  41. package/dist/handlers/embedded.mjs +2 -0
  42. package/dist/handlers/embedded.mjs.map +1 -0
  43. package/dist/handlers/index.cjs +1 -0
  44. package/dist/handlers/index.d.ts +2 -0
  45. package/dist/handlers/index.mjs +1 -0
  46. package/dist/handlers/native.cjs +2 -0
  47. package/dist/handlers/native.cjs.map +1 -0
  48. package/dist/handlers/native.d.ts +56 -0
  49. package/dist/handlers/native.mjs +2 -0
  50. package/dist/handlers/native.mjs.map +1 -0
  51. package/dist/handlers/popup.cjs +2 -0
  52. package/dist/handlers/popup.cjs.map +1 -0
  53. package/dist/handlers/popup.d.ts +21 -0
  54. package/dist/handlers/popup.mjs +2 -0
  55. package/dist/handlers/popup.mjs.map +1 -0
  56. package/dist/handlers/redirect.cjs +2 -0
  57. package/dist/handlers/redirect.cjs.map +1 -0
  58. package/dist/handlers/redirect.d.ts +18 -0
  59. package/dist/handlers/redirect.mjs +2 -0
  60. package/dist/handlers/redirect.mjs.map +1 -0
  61. package/dist/index.cjs +2 -2
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.ts +16 -21
  64. package/dist/index.mjs +2 -2
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/server/base.cjs +2 -0
  67. package/dist/server/base.cjs.map +1 -0
  68. package/dist/server/base.d.ts +15 -0
  69. package/dist/server/base.mjs +2 -0
  70. package/dist/server/base.mjs.map +1 -0
  71. package/dist/server/index.cjs +1 -0
  72. package/dist/server/index.d.ts +1 -0
  73. package/dist/server/index.mjs +1 -0
  74. package/dist/storages/cache.cjs +2 -0
  75. package/dist/storages/cache.cjs.map +1 -0
  76. package/dist/storages/cache.d.ts +11 -0
  77. package/dist/storages/cache.mjs +2 -0
  78. package/dist/storages/cache.mjs.map +1 -0
  79. package/dist/storages/index.cjs +1 -0
  80. package/dist/storages/index.d.ts +7 -0
  81. package/dist/storages/index.mjs +1 -0
  82. package/dist/storages/indexeddb.cjs +2 -0
  83. package/dist/storages/indexeddb.cjs.map +1 -0
  84. package/dist/storages/indexeddb.d.ts +10 -0
  85. package/dist/storages/indexeddb.mjs +2 -0
  86. package/dist/storages/indexeddb.mjs.map +1 -0
  87. package/dist/storages/local.cjs +2 -0
  88. package/dist/storages/local.cjs.map +1 -0
  89. package/dist/storages/local.d.ts +7 -0
  90. package/dist/storages/local.mjs +2 -0
  91. package/dist/storages/local.mjs.map +1 -0
  92. package/dist/storages/memory.cjs +2 -0
  93. package/dist/storages/memory.cjs.map +1 -0
  94. package/dist/storages/memory.d.ts +8 -0
  95. package/dist/storages/memory.mjs +2 -0
  96. package/dist/storages/memory.mjs.map +1 -0
  97. package/dist/storages/server.cjs +1 -0
  98. package/dist/storages/server.d.ts +39 -0
  99. package/dist/storages/server.mjs +1 -0
  100. package/dist/storages/session.cjs +2 -0
  101. package/dist/storages/session.cjs.map +1 -0
  102. package/dist/storages/session.d.ts +7 -0
  103. package/dist/storages/session.mjs +2 -0
  104. package/dist/storages/session.mjs.map +1 -0
  105. package/dist/storages/worker.cjs +2 -0
  106. package/dist/storages/worker.cjs.map +1 -0
  107. package/dist/storages/worker.d.ts +46 -0
  108. package/dist/storages/worker.mjs +2 -0
  109. package/dist/storages/worker.mjs.map +1 -0
  110. package/dist/types/common.cjs +0 -0
  111. package/dist/types/common.d.ts +145 -0
  112. package/dist/types/common.mjs +0 -0
  113. package/dist/types/embedded.cjs +0 -0
  114. package/dist/types/embedded.d.ts +103 -0
  115. package/dist/types/embedded.mjs +0 -0
  116. package/dist/types/index.cjs +1 -0
  117. package/dist/types/index.d.ts +7 -0
  118. package/dist/types/index.mjs +1 -0
  119. package/dist/types/native.cjs +0 -0
  120. package/dist/types/native.d.ts +385 -0
  121. package/dist/types/native.mjs +0 -0
  122. package/dist/types/oidc.cjs +2 -0
  123. package/dist/types/oidc.cjs.map +1 -0
  124. package/dist/types/oidc.d.ts +768 -0
  125. package/dist/types/oidc.mjs +2 -0
  126. package/dist/types/oidc.mjs.map +1 -0
  127. package/dist/types/popup.cjs +0 -0
  128. package/dist/types/popup.d.ts +69 -0
  129. package/dist/types/popup.mjs +0 -0
  130. package/dist/types/redirect.cjs +0 -0
  131. package/dist/types/redirect.d.ts +21 -0
  132. package/dist/types/redirect.mjs +0 -0
  133. package/dist/types/server.cjs +0 -0
  134. package/dist/types/server.d.ts +200 -0
  135. package/dist/types/server.mjs +0 -0
  136. package/dist/utils/base64url.cjs +2 -0
  137. package/dist/utils/base64url.cjs.map +1 -0
  138. package/dist/utils/base64url.d.ts +14 -0
  139. package/dist/utils/base64url.mjs +2 -0
  140. package/dist/utils/base64url.mjs.map +1 -0
  141. package/dist/utils/common.cjs +2 -0
  142. package/dist/utils/common.cjs.map +1 -0
  143. package/dist/utils/common.d.ts +23 -0
  144. package/dist/utils/common.mjs +2 -0
  145. package/dist/utils/common.mjs.map +1 -0
  146. package/dist/utils/credentials.cjs +2 -2
  147. package/dist/utils/credentials.cjs.map +1 -1
  148. package/dist/utils/credentials.d.ts +19 -3
  149. package/dist/utils/credentials.mjs +2 -2
  150. package/dist/utils/credentials.mjs.map +1 -1
  151. package/dist/utils/crypto.cjs +2 -2
  152. package/dist/utils/crypto.cjs.map +1 -1
  153. package/dist/utils/crypto.d.ts +16 -26
  154. package/dist/utils/crypto.mjs +2 -2
  155. package/dist/utils/crypto.mjs.map +1 -1
  156. package/dist/utils/dom.cjs +2 -0
  157. package/dist/utils/dom.cjs.map +1 -0
  158. package/dist/utils/dom.d.ts +7 -0
  159. package/dist/utils/dom.mjs +2 -0
  160. package/dist/utils/dom.mjs.map +1 -0
  161. package/dist/utils/errors.cjs +2 -2
  162. package/dist/utils/errors.cjs.map +1 -1
  163. package/dist/utils/errors.d.ts +62 -1
  164. package/dist/utils/errors.mjs +2 -2
  165. package/dist/utils/errors.mjs.map +1 -1
  166. package/dist/utils/httpClient.cjs +2 -0
  167. package/dist/utils/httpClient.cjs.map +1 -0
  168. package/dist/utils/httpClient.d.ts +2 -0
  169. package/dist/utils/httpClient.mjs +2 -0
  170. package/dist/utils/httpClient.mjs.map +1 -0
  171. package/dist/utils/index.cjs +1 -0
  172. package/dist/utils/index.d.ts +12 -0
  173. package/dist/utils/index.mjs +1 -0
  174. package/dist/utils/logging.cjs +2 -0
  175. package/dist/utils/logging.cjs.map +1 -0
  176. package/dist/utils/logging.d.ts +2 -0
  177. package/dist/utils/logging.mjs +2 -0
  178. package/dist/utils/logging.mjs.map +1 -0
  179. package/dist/utils/oidc.cjs +1 -0
  180. package/dist/utils/oidc.d.ts +264 -0
  181. package/dist/utils/oidc.mjs +1 -0
  182. package/dist/utils/server.cjs +1 -0
  183. package/dist/utils/server.d.ts +72 -0
  184. package/dist/utils/server.mjs +1 -0
  185. package/dist/utils/session.cjs +2 -0
  186. package/dist/utils/session.cjs.map +1 -0
  187. package/dist/utils/session.d.ts +29 -0
  188. package/dist/utils/session.mjs +2 -0
  189. package/dist/utils/session.mjs.map +1 -0
  190. package/dist/utils/state.cjs +1 -0
  191. package/dist/utils/state.d.ts +23 -0
  192. package/dist/utils/state.mjs +1 -0
  193. package/package.json +53 -1
  194. package/testing/tests/flows/base.spec.ts +1030 -0
  195. package/testing/tests/flows/embedded.spec.ts +443 -0
  196. package/testing/tests/flows/index.spec.ts +8 -0
  197. package/testing/tests/flows/native.spec.ts +487 -0
  198. package/testing/tests/flows/popup.spec.ts +400 -0
  199. package/testing/tests/flows/redirect.spec.ts +369 -0
  200. package/testing/tests/handlers/embedded.spec.ts +199 -0
  201. package/testing/tests/handlers/index.spec.ts +8 -0
  202. package/testing/tests/handlers/native.spec.ts +283 -0
  203. package/testing/tests/handlers/popup.spec.ts +206 -0
  204. package/testing/tests/handlers/redirect.spec.ts +70 -0
  205. package/testing/tests/index.spec.ts +78 -0
  206. package/testing/tests/server/base.spec.ts +846 -0
  207. package/testing/tests/server/index.spec.ts +15 -0
  208. package/testing/tests/storages/cache.spec.ts +107 -0
  209. package/testing/tests/storages/index.spec.ts +22 -0
  210. package/testing/tests/storages/indexeddb.spec.ts +113 -0
  211. package/testing/tests/storages/local.spec.ts +46 -0
  212. package/testing/tests/storages/memory.spec.ts +51 -0
  213. package/testing/tests/storages/server.spec.ts +435 -0
  214. package/testing/tests/storages/session.spec.ts +46 -0
  215. package/testing/tests/storages/worker.spec.ts +106 -0
  216. package/testing/tests/utils/common.spec.ts +77 -0
  217. package/testing/tests/utils/credentials.spec.ts +195 -0
  218. package/testing/tests/utils/dom.spec.ts +37 -0
  219. package/testing/tests/utils/index.spec.ts +71 -0
  220. package/testing/tests/utils/logging.spec.ts +82 -0
  221. package/testing/tests/utils/oidc.spec.ts +744 -0
  222. package/testing/tests/utils/server.spec.ts +235 -0
  223. package/dist/flows/BaseFlow.cjs +0 -2
  224. package/dist/flows/BaseFlow.cjs.map +0 -1
  225. package/dist/flows/BaseFlow.d.ts +0 -191
  226. package/dist/flows/BaseFlow.mjs +0 -2
  227. package/dist/flows/BaseFlow.mjs.map +0 -1
  228. package/dist/flows/EmbeddedFlow.cjs +0 -2
  229. package/dist/flows/EmbeddedFlow.cjs.map +0 -1
  230. package/dist/flows/EmbeddedFlow.d.ts +0 -26
  231. package/dist/flows/EmbeddedFlow.mjs +0 -2
  232. package/dist/flows/EmbeddedFlow.mjs.map +0 -1
  233. package/dist/flows/NativeFlow.cjs +0 -2
  234. package/dist/flows/NativeFlow.cjs.map +0 -1
  235. package/dist/flows/NativeFlow.d.ts +0 -34
  236. package/dist/flows/NativeFlow.mjs +0 -2
  237. package/dist/flows/NativeFlow.mjs.map +0 -1
  238. package/dist/flows/PopupFlow.cjs +0 -2
  239. package/dist/flows/PopupFlow.cjs.map +0 -1
  240. package/dist/flows/PopupFlow.d.ts +0 -36
  241. package/dist/flows/PopupFlow.mjs +0 -2
  242. package/dist/flows/PopupFlow.mjs.map +0 -1
  243. package/dist/flows/RedirectFlow.cjs +0 -2
  244. package/dist/flows/RedirectFlow.cjs.map +0 -1
  245. package/dist/flows/RedirectFlow.d.ts +0 -38
  246. package/dist/flows/RedirectFlow.mjs +0 -2
  247. package/dist/flows/RedirectFlow.mjs.map +0 -1
  248. package/dist/handlers/BaseFlowHandler.cjs +0 -2
  249. package/dist/handlers/BaseFlowHandler.cjs.map +0 -1
  250. package/dist/handlers/BaseFlowHandler.d.ts +0 -61
  251. package/dist/handlers/BaseFlowHandler.mjs +0 -2
  252. package/dist/handlers/BaseFlowHandler.mjs.map +0 -1
  253. package/dist/handlers/EmbeddedFlowHandler.cjs +0 -2
  254. package/dist/handlers/EmbeddedFlowHandler.cjs.map +0 -1
  255. package/dist/handlers/EmbeddedFlowHandler.d.ts +0 -28
  256. package/dist/handlers/EmbeddedFlowHandler.mjs +0 -2
  257. package/dist/handlers/EmbeddedFlowHandler.mjs.map +0 -1
  258. package/dist/handlers/NativeFlowHandler.cjs +0 -2
  259. package/dist/handlers/NativeFlowHandler.cjs.map +0 -1
  260. package/dist/handlers/NativeFlowHandler.d.ts +0 -31
  261. package/dist/handlers/NativeFlowHandler.mjs +0 -2
  262. package/dist/handlers/NativeFlowHandler.mjs.map +0 -1
  263. package/dist/storages/LocalStorage.cjs +0 -2
  264. package/dist/storages/LocalStorage.cjs.map +0 -1
  265. package/dist/storages/LocalStorage.d.ts +0 -23
  266. package/dist/storages/LocalStorage.mjs +0 -2
  267. package/dist/storages/LocalStorage.mjs.map +0 -1
  268. package/dist/storages/SessionStorage.cjs +0 -2
  269. package/dist/storages/SessionStorage.cjs.map +0 -1
  270. package/dist/storages/SessionStorage.d.ts +0 -23
  271. package/dist/storages/SessionStorage.mjs +0 -2
  272. package/dist/storages/SessionStorage.mjs.map +0 -1
  273. package/dist/types.cjs +0 -2
  274. package/dist/types.cjs.map +0 -1
  275. package/dist/types.d.ts +0 -1263
  276. package/dist/types.mjs +0 -2
  277. package/dist/types.mjs.map +0 -1
  278. package/dist/utils/HttpClient.cjs +0 -2
  279. package/dist/utils/HttpClient.cjs.map +0 -1
  280. package/dist/utils/HttpClient.d.ts +0 -4
  281. package/dist/utils/HttpClient.mjs +0 -2
  282. package/dist/utils/HttpClient.mjs.map +0 -1
  283. package/dist/utils/Logging.cjs +0 -2
  284. package/dist/utils/Logging.cjs.map +0 -1
  285. package/dist/utils/Logging.d.ts +0 -8
  286. package/dist/utils/Logging.mjs +0 -2
  287. package/dist/utils/Logging.mjs.map +0 -1
  288. package/dist/utils/Metadata.cjs +0 -2
  289. package/dist/utils/Metadata.cjs.map +0 -1
  290. package/dist/utils/Metadata.d.ts +0 -98
  291. package/dist/utils/Metadata.mjs +0 -2
  292. package/dist/utils/Metadata.mjs.map +0 -1
  293. package/dist/utils/Session.cjs +0 -2
  294. package/dist/utils/Session.cjs.map +0 -1
  295. package/dist/utils/Session.d.ts +0 -82
  296. package/dist/utils/Session.mjs +0 -2
  297. package/dist/utils/Session.mjs.map +0 -1
  298. package/dist/utils/State.cjs +0 -2
  299. package/dist/utils/State.cjs.map +0 -1
  300. package/dist/utils/State.d.ts +0 -43
  301. package/dist/utils/State.mjs +0 -2
  302. package/dist/utils/State.mjs.map +0 -1
  303. package/dist/utils/base64Url.cjs +0 -2
  304. package/dist/utils/base64Url.cjs.map +0 -1
  305. package/dist/utils/base64Url.d.ts +0 -27
  306. package/dist/utils/base64Url.mjs +0 -2
  307. package/dist/utils/base64Url.mjs.map +0 -1
  308. package/dist/utils/date.cjs +0 -2
  309. package/dist/utils/date.cjs.map +0 -1
  310. package/dist/utils/date.d.ts +0 -6
  311. package/dist/utils/date.mjs +0 -2
  312. package/dist/utils/date.mjs.map +0 -1
  313. package/dist/utils/handlers.cjs +0 -2
  314. package/dist/utils/handlers.cjs.map +0 -1
  315. package/dist/utils/handlers.d.ts +0 -35
  316. package/dist/utils/handlers.mjs +0 -2
  317. package/dist/utils/handlers.mjs.map +0 -1
  318. package/dist/utils/jwt.cjs +0 -2
  319. package/dist/utils/jwt.cjs.map +0 -1
  320. package/dist/utils/jwt.d.ts +0 -34
  321. package/dist/utils/jwt.mjs +0 -2
  322. package/dist/utils/jwt.mjs.map +0 -1
  323. package/dist/utils/object.cjs +0 -2
  324. package/dist/utils/object.cjs.map +0 -1
  325. package/dist/utils/object.d.ts +0 -1
  326. package/dist/utils/object.mjs +0 -2
  327. package/dist/utils/object.mjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/errors.cjs");var t=null;function n(e){t&&!t.closed&&t.close(),t=null,e.forEach(e=>e()),e.clear()}async function r(r,i){let a=new Set;t&&n(a);let o={location:!1,toolbar:!1,height:640,...i?.popupWindowFeatures};if(o.width===void 0&&(o.width=[800,720,600,480].find(e=>e<=globalThis.window.outerWidth/1.618)??360),o.left=Math.max(0,Math.round(globalThis.window.screenX+(globalThis.window.outerWidth-o.width)/2)),o.height!==void 0&&(o.top=Math.max(0,Math.round(globalThis.window.screenY+(globalThis.window.outerHeight-o.height)/2))),t=globalThis.open(void 0,i?.popupWindowTarget??`_blank`,Object.entries(o).filter(([,e])=>e!==null).map(([e,t])=>`${e}=${typeof t==`boolean`?t?`yes`:`no`:t}`).join(`,`)),!t)throw new e.PopupBlockedError;t.focus(),typeof r==`function`?await r(t):t.location.replace(r);try{return await new Promise((n,r)=>{let o=e=>{(!i?.checkOrigin||e.origin===globalThis.location?.origin)&&e.source===t&&e.data&&n(e.data)},s=setInterval(()=>{t?.closed&&(clearInterval(s),r(new e.PopupClosedError))},500);globalThis.window.addEventListener(`message`,o),a.add(()=>globalThis.window.removeEventListener(`message`,o)),a.add(()=>clearInterval(s))})}finally{n(a)}}function i(e,t){let n=t===`fragment`?globalThis.window?.location.hash.replace(`#`,`?`):globalThis.window?.location.search,r={};for(let[e,t]of new URLSearchParams(n).entries()){if(e in r){r={error:`invalid_request`,error_description:`Duplicate parameter in popup callback: ${e}`};break}r[e]=t}return globalThis.window?.opener?.postMessage(r,`*`),new Promise(()=>void 0)}exports.popupCallbackHandler=i,exports.popupUrlHandler=r;
2
+ //# sourceMappingURL=popup.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popup.cjs","names":[],"sources":["../../src/handlers/popup.ts"],"sourcesContent":["import type { ResponseMode } from '../types/oidc';\nimport type { PopupParams, PopupWindowFeatures } from '../types/popup';\nimport { PopupBlockedError, PopupClosedError } from '../utils/errors';\n\nlet activePopup: WindowProxy | null = null;\n\n/**\n * Closes the currently active popup window and cleans up any associated resources.\n *\n * @param {Set<() => void>} disposables - A set of cleanup functions to be called when the popup is closed.\n */\nfunction closePopup(disposables: Set<() => void>): void {\n\tif (activePopup && !activePopup.closed) {\n\t\tactivePopup.close();\n\t}\n\n\tactivePopup = null;\n\tdisposables.forEach((d) => d());\n\tdisposables.clear();\n}\n\n/**\n * Opens a popup window to handle URL redirection and resolves with the data received from the popup.\n *\n * @param {string | URL | ((popupWindow: Window) => void | Promise<void>)} urlOrPopupHandler - The URL to open in the popup or a function that handles the popup window.\n * @param {PopupParams} [params] - Optional parameters for configuring the popup window, such as features and target.\n * @param {PopupWindowFeatures} [params.popupWindowFeatures] - Optional features for the popup window, such as width, height, and position.\n * @param {string} [params.popupWindowTarget] - Optional target for the popup window, such as '_blank' or a named window.\n * @param {boolean} [params.checkOrigin] - Optional flag to check the origin of the message received from the popup window.\n * @returns {Promise<Record<string, string>>} A promise that resolves with the data received from the popup window, or rejects if the popup is blocked or closed by the user.\n * @throws {Error} If the popup window is blocked or closed by the user.\n */\nexport async function popupUrlHandler(\n\turlOrPopupHandler: string | URL | ((popupWindow: Window) => void | Promise<void>),\n\tparams?: PopupParams,\n): Promise<Record<string, string>> {\n\tconst disposables = new Set<() => void>();\n\n\t// NOTE: Close any leftover popup from a previous call\n\tif (activePopup) {\n\t\tclosePopup(disposables);\n\t}\n\n\tconst features: PopupWindowFeatures = {\n\t\tlocation: false,\n\t\ttoolbar: false,\n\t\theight: 640,\n\t\t...params?.popupWindowFeatures,\n\t};\n\n\tif (features.width === undefined) {\n\t\tfeatures.width = [800, 720, 600, 480].find((w) => w <= globalThis.window.outerWidth / 1.618) ?? 360;\n\t}\n\n\tfeatures.left = Math.max(0, Math.round(globalThis.window.screenX + (globalThis.window.outerWidth - features.width) / 2));\n\n\tif (features.height !== undefined) {\n\t\tfeatures.top = Math.max(0, Math.round(globalThis.window.screenY + (globalThis.window.outerHeight - features.height) / 2));\n\t}\n\n\tactivePopup = globalThis.open(\n\t\tundefined,\n\t\tparams?.popupWindowTarget ?? '_blank',\n\t\tObject.entries(features)\n\t\t\t.filter(([, v]) => v !== null)\n\t\t\t.map(([k, v]) => `${k}=${typeof v !== 'boolean' ? v : v ? 'yes' : 'no'}`)\n\t\t\t.join(','),\n\t);\n\n\tif (!activePopup) {\n\t\tthrow new PopupBlockedError();\n\t}\n\n\tactivePopup.focus();\n\n\tif (typeof urlOrPopupHandler === 'function') {\n\t\tawait urlOrPopupHandler(activePopup);\n\t} else {\n\t\tactivePopup.location.replace(urlOrPopupHandler);\n\t}\n\n\ttry {\n\t\treturn await new Promise<Record<string, string>>((resolve, reject) => {\n\t\t\tconst listener = (event: MessageEvent<Record<string, string>>) => {\n\t\t\t\tconst sameOrigin = !params?.checkOrigin || event.origin === globalThis.location?.origin;\n\n\t\t\t\tif (sameOrigin && event.source === activePopup && event.data) {\n\t\t\t\t\tresolve(event.data);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst timer = setInterval(() => {\n\t\t\t\tif (activePopup?.closed) {\n\t\t\t\t\tclearInterval(timer);\n\t\t\t\t\treject(new PopupClosedError());\n\t\t\t\t}\n\t\t\t}, 500);\n\n\t\t\tglobalThis.window.addEventListener('message', listener);\n\t\t\tdisposables.add(() => globalThis.window.removeEventListener('message', listener));\n\t\t\tdisposables.add(() => clearInterval(timer));\n\t\t});\n\t} finally {\n\t\tclosePopup(disposables);\n\t}\n}\n\n/**\n * Handles the callback from a popup window, parsing the response parameters from the URL and posting them to the opener window.\n *\n * @param {string} [_url] - the URL is not used in this function, but it is kept for type compatibility.\n * @param {ResponseMode} responseMode The response mode, either 'query' or 'fragment'.\n */\nexport function popupCallbackHandler(_url?: string | URL, responseMode?: ResponseMode): Promise<void> {\n\tconst raw = responseMode === 'fragment' ? globalThis.window?.location.hash.replace('#', '?') : globalThis.window?.location.search;\n\tlet args: Record<string, string> = {};\n\n\tfor (const [key, value] of new URLSearchParams(raw).entries()) {\n\t\tif (key in args) {\n\t\t\targs = { error: 'invalid_request', error_description: `Duplicate parameter in popup callback: ${key}` };\n\t\t\tbreak;\n\t\t}\n\n\t\targs[key] = value;\n\t}\n\n\tglobalThis.window?.opener?.postMessage(args, '*');\n\n\t// NOTE: Stay suspended – the opener will close the popup after the token exchange\n\treturn new Promise(() => undefined);\n}\n"],"mappings":"0GAIA,IAAI,EAAkC,KAOtC,SAAS,EAAW,EAAoC,CACnD,GAAe,CAAC,EAAY,QAC/B,EAAY,MAAM,EAGnB,EAAc,KACd,EAAY,QAAS,GAAM,EAAE,CAAC,EAC9B,EAAY,MAAM,CACnB,CAaA,eAAsB,EACrB,EACA,EACkC,CAClC,IAAM,EAAc,IAAI,IAGpB,GACH,EAAW,CAAW,EAGvB,IAAM,EAAgC,CACrC,SAAU,GACV,QAAS,GACT,OAAQ,IACR,GAAG,GAAQ,mBACZ,EAqBA,GAnBI,EAAS,QAAU,IAAA,KACtB,EAAS,MAAQ,CAAC,IAAK,IAAK,IAAK,GAAG,CAAC,CAAC,KAAM,GAAM,GAAK,WAAW,OAAO,WAAa,KAAK,GAAK,KAGjG,EAAS,KAAO,KAAK,IAAI,EAAG,KAAK,MAAM,WAAW,OAAO,SAAW,WAAW,OAAO,WAAa,EAAS,OAAS,CAAC,CAAC,EAEnH,EAAS,SAAW,IAAA,KACvB,EAAS,IAAM,KAAK,IAAI,EAAG,KAAK,MAAM,WAAW,OAAO,SAAW,WAAW,OAAO,YAAc,EAAS,QAAU,CAAC,CAAC,GAGzH,EAAc,WAAW,KACxB,IAAA,GACA,GAAQ,mBAAqB,SAC7B,OAAO,QAAQ,CAAQ,CAAC,CACtB,QAAQ,EAAG,KAAO,IAAM,IAAI,CAAC,CAC7B,KAAK,CAAC,EAAG,KAAO,GAAG,EAAE,GAAG,OAAO,GAAM,UAAgB,EAAI,MAAQ,KAAhB,GAAsB,CAAC,CACxE,KAAK,GAAG,CACX,EAEI,CAAC,EACJ,MAAM,IAAI,EAAA,kBAGX,EAAY,MAAM,EAEd,OAAO,GAAsB,WAChC,MAAM,EAAkB,CAAW,EAEnC,EAAY,SAAS,QAAQ,CAAiB,EAG/C,GAAI,CACH,OAAO,MAAM,IAAI,SAAiC,EAAS,IAAW,CACrE,IAAM,EAAY,GAAgD,EAC9C,CAAC,GAAQ,aAAe,EAAM,SAAW,WAAW,UAAU,SAE/D,EAAM,SAAW,GAAe,EAAM,MACvD,EAAQ,EAAM,IAAI,CAEpB,EAEM,EAAQ,gBAAkB,CAC3B,GAAa,SAChB,cAAc,CAAK,EACnB,EAAO,IAAI,EAAA,gBAAkB,EAE/B,EAAG,GAAG,EAEN,WAAW,OAAO,iBAAiB,UAAW,CAAQ,EACtD,EAAY,QAAU,WAAW,OAAO,oBAAoB,UAAW,CAAQ,CAAC,EAChF,EAAY,QAAU,cAAc,CAAK,CAAC,CAC3C,CAAC,CACF,QAAU,CACT,EAAW,CAAW,CACvB,CACD,CAQA,SAAgB,EAAqB,EAAqB,EAA4C,CACrG,IAAM,EAAM,IAAiB,WAAa,WAAW,QAAQ,SAAS,KAAK,QAAQ,IAAK,GAAG,EAAI,WAAW,QAAQ,SAAS,OACvH,EAA+B,CAAC,EAEpC,IAAK,GAAM,CAAC,EAAK,KAAU,IAAI,gBAAgB,CAAG,CAAC,CAAC,QAAQ,EAAG,CAC9D,GAAI,KAAO,EAAM,CAChB,EAAO,CAAE,MAAO,kBAAmB,kBAAmB,0CAA0C,GAAM,EACtG,KACD,CAEA,EAAK,GAAO,CACb,CAKA,OAHA,WAAW,QAAQ,QAAQ,YAAY,EAAM,GAAG,EAGzC,IAAI,YAAc,IAAA,EAAS,CACnC"}
@@ -0,0 +1,21 @@
1
+ import { ResponseMode } from '../types/oidc';
2
+ import { PopupParams } from '../types/popup';
3
+ /**
4
+ * Opens a popup window to handle URL redirection and resolves with the data received from the popup.
5
+ *
6
+ * @param {string | URL | ((popupWindow: Window) => void | Promise<void>)} urlOrPopupHandler - The URL to open in the popup or a function that handles the popup window.
7
+ * @param {PopupParams} [params] - Optional parameters for configuring the popup window, such as features and target.
8
+ * @param {PopupWindowFeatures} [params.popupWindowFeatures] - Optional features for the popup window, such as width, height, and position.
9
+ * @param {string} [params.popupWindowTarget] - Optional target for the popup window, such as '_blank' or a named window.
10
+ * @param {boolean} [params.checkOrigin] - Optional flag to check the origin of the message received from the popup window.
11
+ * @returns {Promise<Record<string, string>>} A promise that resolves with the data received from the popup window, or rejects if the popup is blocked or closed by the user.
12
+ * @throws {Error} If the popup window is blocked or closed by the user.
13
+ */
14
+ export declare function popupUrlHandler(urlOrPopupHandler: string | URL | ((popupWindow: Window) => void | Promise<void>), params?: PopupParams): Promise<Record<string, string>>;
15
+ /**
16
+ * Handles the callback from a popup window, parsing the response parameters from the URL and posting them to the opener window.
17
+ *
18
+ * @param {string} [_url] - the URL is not used in this function, but it is kept for type compatibility.
19
+ * @param {ResponseMode} responseMode The response mode, either 'query' or 'fragment'.
20
+ */
21
+ export declare function popupCallbackHandler(_url?: string | URL, responseMode?: ResponseMode): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import{PopupBlockedError as e,PopupClosedError as t}from"../utils/errors.mjs";var n=null;function r(e){n&&!n.closed&&n.close(),n=null,e.forEach(e=>e()),e.clear()}async function i(i,a){let o=new Set;n&&r(o);let s={location:!1,toolbar:!1,height:640,...a?.popupWindowFeatures};if(s.width===void 0&&(s.width=[800,720,600,480].find(e=>e<=globalThis.window.outerWidth/1.618)??360),s.left=Math.max(0,Math.round(globalThis.window.screenX+(globalThis.window.outerWidth-s.width)/2)),s.height!==void 0&&(s.top=Math.max(0,Math.round(globalThis.window.screenY+(globalThis.window.outerHeight-s.height)/2))),n=globalThis.open(void 0,a?.popupWindowTarget??`_blank`,Object.entries(s).filter(([,e])=>e!==null).map(([e,t])=>`${e}=${typeof t==`boolean`?t?`yes`:`no`:t}`).join(`,`)),!n)throw new e;n.focus(),typeof i==`function`?await i(n):n.location.replace(i);try{return await new Promise((e,r)=>{let i=t=>{(!a?.checkOrigin||t.origin===globalThis.location?.origin)&&t.source===n&&t.data&&e(t.data)},s=setInterval(()=>{n?.closed&&(clearInterval(s),r(new t))},500);globalThis.window.addEventListener(`message`,i),o.add(()=>globalThis.window.removeEventListener(`message`,i)),o.add(()=>clearInterval(s))})}finally{r(o)}}function a(e,t){let n=t===`fragment`?globalThis.window?.location.hash.replace(`#`,`?`):globalThis.window?.location.search,r={};for(let[e,t]of new URLSearchParams(n).entries()){if(e in r){r={error:`invalid_request`,error_description:`Duplicate parameter in popup callback: ${e}`};break}r[e]=t}return globalThis.window?.opener?.postMessage(r,`*`),new Promise(()=>void 0)}export{a as popupCallbackHandler,i as popupUrlHandler};
2
+ //# sourceMappingURL=popup.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popup.mjs","names":[],"sources":["../../src/handlers/popup.ts"],"sourcesContent":["import type { ResponseMode } from '../types/oidc';\nimport type { PopupParams, PopupWindowFeatures } from '../types/popup';\nimport { PopupBlockedError, PopupClosedError } from '../utils/errors';\n\nlet activePopup: WindowProxy | null = null;\n\n/**\n * Closes the currently active popup window and cleans up any associated resources.\n *\n * @param {Set<() => void>} disposables - A set of cleanup functions to be called when the popup is closed.\n */\nfunction closePopup(disposables: Set<() => void>): void {\n\tif (activePopup && !activePopup.closed) {\n\t\tactivePopup.close();\n\t}\n\n\tactivePopup = null;\n\tdisposables.forEach((d) => d());\n\tdisposables.clear();\n}\n\n/**\n * Opens a popup window to handle URL redirection and resolves with the data received from the popup.\n *\n * @param {string | URL | ((popupWindow: Window) => void | Promise<void>)} urlOrPopupHandler - The URL to open in the popup or a function that handles the popup window.\n * @param {PopupParams} [params] - Optional parameters for configuring the popup window, such as features and target.\n * @param {PopupWindowFeatures} [params.popupWindowFeatures] - Optional features for the popup window, such as width, height, and position.\n * @param {string} [params.popupWindowTarget] - Optional target for the popup window, such as '_blank' or a named window.\n * @param {boolean} [params.checkOrigin] - Optional flag to check the origin of the message received from the popup window.\n * @returns {Promise<Record<string, string>>} A promise that resolves with the data received from the popup window, or rejects if the popup is blocked or closed by the user.\n * @throws {Error} If the popup window is blocked or closed by the user.\n */\nexport async function popupUrlHandler(\n\turlOrPopupHandler: string | URL | ((popupWindow: Window) => void | Promise<void>),\n\tparams?: PopupParams,\n): Promise<Record<string, string>> {\n\tconst disposables = new Set<() => void>();\n\n\t// NOTE: Close any leftover popup from a previous call\n\tif (activePopup) {\n\t\tclosePopup(disposables);\n\t}\n\n\tconst features: PopupWindowFeatures = {\n\t\tlocation: false,\n\t\ttoolbar: false,\n\t\theight: 640,\n\t\t...params?.popupWindowFeatures,\n\t};\n\n\tif (features.width === undefined) {\n\t\tfeatures.width = [800, 720, 600, 480].find((w) => w <= globalThis.window.outerWidth / 1.618) ?? 360;\n\t}\n\n\tfeatures.left = Math.max(0, Math.round(globalThis.window.screenX + (globalThis.window.outerWidth - features.width) / 2));\n\n\tif (features.height !== undefined) {\n\t\tfeatures.top = Math.max(0, Math.round(globalThis.window.screenY + (globalThis.window.outerHeight - features.height) / 2));\n\t}\n\n\tactivePopup = globalThis.open(\n\t\tundefined,\n\t\tparams?.popupWindowTarget ?? '_blank',\n\t\tObject.entries(features)\n\t\t\t.filter(([, v]) => v !== null)\n\t\t\t.map(([k, v]) => `${k}=${typeof v !== 'boolean' ? v : v ? 'yes' : 'no'}`)\n\t\t\t.join(','),\n\t);\n\n\tif (!activePopup) {\n\t\tthrow new PopupBlockedError();\n\t}\n\n\tactivePopup.focus();\n\n\tif (typeof urlOrPopupHandler === 'function') {\n\t\tawait urlOrPopupHandler(activePopup);\n\t} else {\n\t\tactivePopup.location.replace(urlOrPopupHandler);\n\t}\n\n\ttry {\n\t\treturn await new Promise<Record<string, string>>((resolve, reject) => {\n\t\t\tconst listener = (event: MessageEvent<Record<string, string>>) => {\n\t\t\t\tconst sameOrigin = !params?.checkOrigin || event.origin === globalThis.location?.origin;\n\n\t\t\t\tif (sameOrigin && event.source === activePopup && event.data) {\n\t\t\t\t\tresolve(event.data);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst timer = setInterval(() => {\n\t\t\t\tif (activePopup?.closed) {\n\t\t\t\t\tclearInterval(timer);\n\t\t\t\t\treject(new PopupClosedError());\n\t\t\t\t}\n\t\t\t}, 500);\n\n\t\t\tglobalThis.window.addEventListener('message', listener);\n\t\t\tdisposables.add(() => globalThis.window.removeEventListener('message', listener));\n\t\t\tdisposables.add(() => clearInterval(timer));\n\t\t});\n\t} finally {\n\t\tclosePopup(disposables);\n\t}\n}\n\n/**\n * Handles the callback from a popup window, parsing the response parameters from the URL and posting them to the opener window.\n *\n * @param {string} [_url] - the URL is not used in this function, but it is kept for type compatibility.\n * @param {ResponseMode} responseMode The response mode, either 'query' or 'fragment'.\n */\nexport function popupCallbackHandler(_url?: string | URL, responseMode?: ResponseMode): Promise<void> {\n\tconst raw = responseMode === 'fragment' ? globalThis.window?.location.hash.replace('#', '?') : globalThis.window?.location.search;\n\tlet args: Record<string, string> = {};\n\n\tfor (const [key, value] of new URLSearchParams(raw).entries()) {\n\t\tif (key in args) {\n\t\t\targs = { error: 'invalid_request', error_description: `Duplicate parameter in popup callback: ${key}` };\n\t\t\tbreak;\n\t\t}\n\n\t\targs[key] = value;\n\t}\n\n\tglobalThis.window?.opener?.postMessage(args, '*');\n\n\t// NOTE: Stay suspended – the opener will close the popup after the token exchange\n\treturn new Promise(() => undefined);\n}\n"],"mappings":"8EAIA,IAAI,EAAkC,KAOtC,SAAS,EAAW,EAAoC,CACnD,GAAe,CAAC,EAAY,QAC/B,EAAY,MAAM,EAGnB,EAAc,KACd,EAAY,QAAS,GAAM,EAAE,CAAC,EAC9B,EAAY,MAAM,CACnB,CAaA,eAAsB,EACrB,EACA,EACkC,CAClC,IAAM,EAAc,IAAI,IAGpB,GACH,EAAW,CAAW,EAGvB,IAAM,EAAgC,CACrC,SAAU,GACV,QAAS,GACT,OAAQ,IACR,GAAG,GAAQ,mBACZ,EAqBA,GAnBI,EAAS,QAAU,IAAA,KACtB,EAAS,MAAQ,CAAC,IAAK,IAAK,IAAK,GAAG,CAAC,CAAC,KAAM,GAAM,GAAK,WAAW,OAAO,WAAa,KAAK,GAAK,KAGjG,EAAS,KAAO,KAAK,IAAI,EAAG,KAAK,MAAM,WAAW,OAAO,SAAW,WAAW,OAAO,WAAa,EAAS,OAAS,CAAC,CAAC,EAEnH,EAAS,SAAW,IAAA,KACvB,EAAS,IAAM,KAAK,IAAI,EAAG,KAAK,MAAM,WAAW,OAAO,SAAW,WAAW,OAAO,YAAc,EAAS,QAAU,CAAC,CAAC,GAGzH,EAAc,WAAW,KACxB,IAAA,GACA,GAAQ,mBAAqB,SAC7B,OAAO,QAAQ,CAAQ,CAAC,CACtB,QAAQ,EAAG,KAAO,IAAM,IAAI,CAAC,CAC7B,KAAK,CAAC,EAAG,KAAO,GAAG,EAAE,GAAG,OAAO,GAAM,UAAgB,EAAI,MAAQ,KAAhB,GAAsB,CAAC,CACxE,KAAK,GAAG,CACX,EAEI,CAAC,EACJ,MAAM,IAAI,EAGX,EAAY,MAAM,EAEd,OAAO,GAAsB,WAChC,MAAM,EAAkB,CAAW,EAEnC,EAAY,SAAS,QAAQ,CAAiB,EAG/C,GAAI,CACH,OAAO,MAAM,IAAI,SAAiC,EAAS,IAAW,CACrE,IAAM,EAAY,GAAgD,EAC9C,CAAC,GAAQ,aAAe,EAAM,SAAW,WAAW,UAAU,SAE/D,EAAM,SAAW,GAAe,EAAM,MACvD,EAAQ,EAAM,IAAI,CAEpB,EAEM,EAAQ,gBAAkB,CAC3B,GAAa,SAChB,cAAc,CAAK,EACnB,EAAO,IAAI,CAAkB,EAE/B,EAAG,GAAG,EAEN,WAAW,OAAO,iBAAiB,UAAW,CAAQ,EACtD,EAAY,QAAU,WAAW,OAAO,oBAAoB,UAAW,CAAQ,CAAC,EAChF,EAAY,QAAU,cAAc,CAAK,CAAC,CAC3C,CAAC,CACF,QAAU,CACT,EAAW,CAAW,CACvB,CACD,CAQA,SAAgB,EAAqB,EAAqB,EAA4C,CACrG,IAAM,EAAM,IAAiB,WAAa,WAAW,QAAQ,SAAS,KAAK,QAAQ,IAAK,GAAG,EAAI,WAAW,QAAQ,SAAS,OACvH,EAA+B,CAAC,EAEpC,IAAK,GAAM,CAAC,EAAK,KAAU,IAAI,gBAAgB,CAAG,CAAC,CAAC,QAAQ,EAAG,CAC9D,GAAI,KAAO,EAAM,CAChB,EAAO,CAAE,MAAO,kBAAmB,kBAAmB,0CAA0C,GAAM,EACtG,KACD,CAEA,EAAK,GAAO,CACb,CAKA,OAHA,WAAW,QAAQ,QAAQ,YAAY,EAAM,GAAG,EAGzC,IAAI,YAAc,IAAA,EAAS,CACnC"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/errors.cjs");async function t(e,t){let n=t?.targetWindow===`top`?globalThis.window?.top:globalThis.window?.self,r=t?.locationMethod??`assign`;return e?(n&&n.location[r](e),Promise.resolve()):Promise.reject(Error(`No URL provided for redirection`))}function n(t=globalThis.window?.location.href,n){if(!t)return Promise.reject(Error(`No URL provided for redirect callback handling`));let r=new URL(t)[n===`fragment`?`hash`:`search`].slice(1),i={};for(let[t,n]of new URLSearchParams(r).entries()){if(t in i)return Promise.reject(new e.ProtocolError(`Duplicate parameter in redirect callback: ${t}`));i[t]=n}return Promise.resolve(i)}exports.redirectCallbackHandler=n,exports.redirectUrlHandler=t;
2
+ //# sourceMappingURL=redirect.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.cjs","names":[],"sources":["../../src/handlers/redirect.ts"],"sourcesContent":["import type { ResponseMode } from '../types/oidc';\nimport type { RedirectParams } from '../types/redirect';\nimport { ProtocolError } from '../utils/errors';\n\n/**\n * Handles URL redirection to a target window using a specified location method.\n *\n * @param {string | URL} url - The URL to redirect to.\n * @param {RedirectParams} [params] - Optional parameters for the redirection, including the target window and location method.\n * @returns {Promise<void>} A promise that resolves when the redirection occurs.\n */\nexport async function redirectUrlHandler(url?: string | URL, params?: RedirectParams): Promise<void> {\n\tconst targetWindow = params?.targetWindow === 'top' ? globalThis.window?.top : globalThis.window?.self;\n\tconst method = params?.locationMethod ?? 'assign';\n\n\tif (!url) {\n\t\treturn Promise.reject(new Error('No URL provided for redirection'));\n\t}\n\n\tif (targetWindow) {\n\t\ttargetWindow.location[method](url);\n\t}\n\n\treturn Promise.resolve();\n}\n\n/**\n * Handles the callback after a redirect and parses the response from the URL.\n *\n * @param {string | URL} [url=globalThis.window?.location.href] - The URL to parse, defaults to the current window location.\n * @param {ResponseMode} responseMode - The response mode, either 'query' or 'fragment'.\n * @returns {Promise<Record<string, string>>} A promise that resolves to the parsed response data.\n */\nexport function redirectCallbackHandler(\n\turl: string | URL | undefined = globalThis.window?.location.href,\n\tresponseMode?: ResponseMode,\n): Promise<Record<string, string>> {\n\tif (!url) {\n\t\treturn Promise.reject(new Error('No URL provided for redirect callback handling'));\n\t}\n\n\tconst raw = new URL(url)[responseMode === 'fragment' ? 'hash' : 'search'].slice(1);\n\tconst result: Record<string, string> = {};\n\n\tfor (const [key, value] of new URLSearchParams(raw).entries()) {\n\t\tif (key in result) {\n\t\t\treturn Promise.reject(new ProtocolError(`Duplicate parameter in redirect callback: ${key}`));\n\t\t}\n\n\t\tresult[key] = value;\n\t}\n\n\treturn Promise.resolve(result);\n}\n"],"mappings":"0GAWA,eAAsB,EAAmB,EAAoB,EAAwC,CACpG,IAAM,EAAe,GAAQ,eAAiB,MAAQ,WAAW,QAAQ,IAAM,WAAW,QAAQ,KAC5F,EAAS,GAAQ,gBAAkB,SAUzC,OARK,GAID,GACH,EAAa,SAAS,EAAO,CAAC,CAAG,EAG3B,QAAQ,QAAQ,GAPf,QAAQ,OAAW,MAAM,iCAAiC,CAAC,CAQpE,CASA,SAAgB,EACf,EAAgC,WAAW,QAAQ,SAAS,KAC5D,EACkC,CAClC,GAAI,CAAC,EACJ,OAAO,QAAQ,OAAW,MAAM,gDAAgD,CAAC,EAGlF,IAAM,EAAM,IAAI,IAAI,CAAG,CAAC,CAAC,IAAiB,WAAa,OAAS,SAAS,CAAC,MAAM,CAAC,EAC3E,EAAiC,CAAC,EAExC,IAAK,GAAM,CAAC,EAAK,KAAU,IAAI,gBAAgB,CAAG,CAAC,CAAC,QAAQ,EAAG,CAC9D,GAAI,KAAO,EACV,OAAO,QAAQ,OAAO,IAAI,EAAA,cAAc,6CAA6C,GAAK,CAAC,EAG5F,EAAO,GAAO,CACf,CAEA,OAAO,QAAQ,QAAQ,CAAM,CAC9B"}
@@ -0,0 +1,18 @@
1
+ import { ResponseMode } from '../types/oidc';
2
+ import { RedirectParams } from '../types/redirect';
3
+ /**
4
+ * Handles URL redirection to a target window using a specified location method.
5
+ *
6
+ * @param {string | URL} url - The URL to redirect to.
7
+ * @param {RedirectParams} [params] - Optional parameters for the redirection, including the target window and location method.
8
+ * @returns {Promise<void>} A promise that resolves when the redirection occurs.
9
+ */
10
+ export declare function redirectUrlHandler(url?: string | URL, params?: RedirectParams): Promise<void>;
11
+ /**
12
+ * Handles the callback after a redirect and parses the response from the URL.
13
+ *
14
+ * @param {string | URL} [url=globalThis.window?.location.href] - The URL to parse, defaults to the current window location.
15
+ * @param {ResponseMode} responseMode - The response mode, either 'query' or 'fragment'.
16
+ * @returns {Promise<Record<string, string>>} A promise that resolves to the parsed response data.
17
+ */
18
+ export declare function redirectCallbackHandler(url?: string | URL | undefined, responseMode?: ResponseMode): Promise<Record<string, string>>;
@@ -0,0 +1,2 @@
1
+ import{ProtocolError as e}from"../utils/errors.mjs";async function t(e,t){let n=t?.targetWindow===`top`?globalThis.window?.top:globalThis.window?.self,r=t?.locationMethod??`assign`;return e?(n&&n.location[r](e),Promise.resolve()):Promise.reject(Error(`No URL provided for redirection`))}function n(t=globalThis.window?.location.href,n){if(!t)return Promise.reject(Error(`No URL provided for redirect callback handling`));let r=new URL(t)[n===`fragment`?`hash`:`search`].slice(1),i={};for(let[t,n]of new URLSearchParams(r).entries()){if(t in i)return Promise.reject(new e(`Duplicate parameter in redirect callback: ${t}`));i[t]=n}return Promise.resolve(i)}export{n as redirectCallbackHandler,t as redirectUrlHandler};
2
+ //# sourceMappingURL=redirect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.mjs","names":[],"sources":["../../src/handlers/redirect.ts"],"sourcesContent":["import type { ResponseMode } from '../types/oidc';\nimport type { RedirectParams } from '../types/redirect';\nimport { ProtocolError } from '../utils/errors';\n\n/**\n * Handles URL redirection to a target window using a specified location method.\n *\n * @param {string | URL} url - The URL to redirect to.\n * @param {RedirectParams} [params] - Optional parameters for the redirection, including the target window and location method.\n * @returns {Promise<void>} A promise that resolves when the redirection occurs.\n */\nexport async function redirectUrlHandler(url?: string | URL, params?: RedirectParams): Promise<void> {\n\tconst targetWindow = params?.targetWindow === 'top' ? globalThis.window?.top : globalThis.window?.self;\n\tconst method = params?.locationMethod ?? 'assign';\n\n\tif (!url) {\n\t\treturn Promise.reject(new Error('No URL provided for redirection'));\n\t}\n\n\tif (targetWindow) {\n\t\ttargetWindow.location[method](url);\n\t}\n\n\treturn Promise.resolve();\n}\n\n/**\n * Handles the callback after a redirect and parses the response from the URL.\n *\n * @param {string | URL} [url=globalThis.window?.location.href] - The URL to parse, defaults to the current window location.\n * @param {ResponseMode} responseMode - The response mode, either 'query' or 'fragment'.\n * @returns {Promise<Record<string, string>>} A promise that resolves to the parsed response data.\n */\nexport function redirectCallbackHandler(\n\turl: string | URL | undefined = globalThis.window?.location.href,\n\tresponseMode?: ResponseMode,\n): Promise<Record<string, string>> {\n\tif (!url) {\n\t\treturn Promise.reject(new Error('No URL provided for redirect callback handling'));\n\t}\n\n\tconst raw = new URL(url)[responseMode === 'fragment' ? 'hash' : 'search'].slice(1);\n\tconst result: Record<string, string> = {};\n\n\tfor (const [key, value] of new URLSearchParams(raw).entries()) {\n\t\tif (key in result) {\n\t\t\treturn Promise.reject(new ProtocolError(`Duplicate parameter in redirect callback: ${key}`));\n\t\t}\n\n\t\tresult[key] = value;\n\t}\n\n\treturn Promise.resolve(result);\n}\n"],"mappings":"oDAWA,eAAsB,EAAmB,EAAoB,EAAwC,CACpG,IAAM,EAAe,GAAQ,eAAiB,MAAQ,WAAW,QAAQ,IAAM,WAAW,QAAQ,KAC5F,EAAS,GAAQ,gBAAkB,SAUzC,OARK,GAID,GACH,EAAa,SAAS,EAAO,CAAC,CAAG,EAG3B,QAAQ,QAAQ,GAPf,QAAQ,OAAW,MAAM,iCAAiC,CAAC,CAQpE,CASA,SAAgB,EACf,EAAgC,WAAW,QAAQ,SAAS,KAC5D,EACkC,CAClC,GAAI,CAAC,EACJ,OAAO,QAAQ,OAAW,MAAM,gDAAgD,CAAC,EAGlF,IAAM,EAAM,IAAI,IAAI,CAAG,CAAC,CAAC,IAAiB,WAAa,OAAS,SAAS,CAAC,MAAM,CAAC,EAC3E,EAAiC,CAAC,EAExC,IAAK,GAAM,CAAC,EAAK,KAAU,IAAI,gBAAgB,CAAG,CAAC,CAAC,QAAQ,EAAG,CAC9D,GAAI,KAAO,EACV,OAAO,QAAQ,OAAO,IAAI,EAAc,6CAA6C,GAAK,CAAC,EAG5F,EAAO,GAAO,CACf,CAEA,OAAO,QAAQ,QAAQ,CAAM,CAC9B"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./flows/BaseFlow.cjs"),w=require("./flows/RedirectFlow.cjs"),c=require("./flows/PopupFlow.cjs"),g=require("./flows/NativeFlow.cjs"),a=require("./flows/EmbeddedFlow.cjs"),d=require("./storages/LocalStorage.cjs"),q=require("./utils/HttpClient.cjs"),l=require("./utils/errors.cjs"),u=require("./types.cjs");require("./utils/jwt.cjs");require("./utils/base64Url.cjs");require("./utils/date.cjs");require("./utils/Metadata.cjs");require("./utils/Session.cjs");require("./utils/State.cjs");require("./utils/crypto.cjs");require("./utils/handlers.cjs");require("./handlers/NativeFlowHandler.cjs");require("./handlers/BaseFlowHandler.cjs");require("./handlers/EmbeddedFlowHandler.cjs");function F(e){const i=e.storage||d.LocalStorage,n=e.httpClient||q.HttpClient,o=new i,t=new n;let r;if(e.logging&&(r=new e.logging,t.logging=r),e.mode==="popup")return new c.PopupFlow(e,o,t,r);if(e.mode==="native")return new g.NativeFlow(e,o,t,r);if(e.mode==="embedded")return new a.EmbeddedFlow(e,o,t,r);if(e.mode==="custom"){if(!e.customFlow||!(e.customFlow.prototype instanceof s.BaseFlow))throw new Error("customFlow must extend BaseFlow");return new e.customFlow(e,o,t,r)}else return new w.RedirectFlow(e,o,t,r)}exports.FallbackError=l.FallbackError;exports.PopupBlockedError=l.PopupBlockedError;exports.PopupClosedError=l.PopupClosedError;exports.SDKHttpClient=u.SDKHttpClient;exports.SDKLogging=u.SDKLogging;exports.SDKStorage=u.SDKStorage;exports.initFlow=F;
2
- //# sourceMappingURL=index.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./utils/errors.cjs"),t=require("./flows/redirect.cjs"),n=require("./flows/popup.cjs"),r=require("./flows/embedded.cjs"),i=require("./flows/native.cjs");function a(a){if(typeof a.factory==`function`)return a.factory(a);if(a.mode===`redirect`)return t.createRedirectFlow(a);if(a.mode===`popup`)return n.createPopupFlow(a);if(a.mode===`embedded`)return r.createEmbeddedFlow(a);if(a.mode===`native`)return i.createNativeFlow(a);throw new e.UnsupportedFlowError}exports.initFlow=a;
2
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import type { SDKOptions } from './types';\nimport { BaseFlow } from './flows/BaseFlow';\nimport { RedirectFlow } from './flows/RedirectFlow';\nimport { PopupFlow } from './flows/PopupFlow';\nimport { NativeFlow } from './flows/NativeFlow';\nimport { EmbeddedFlow } from './flows/EmbeddedFlow';\nimport { LocalStorage } from './storages/LocalStorage';\nimport { HttpClient } from './utils/HttpClient';\n\nexport * from './utils/errors';\nexport type * from './types';\nexport { SDKStorage, SDKLogging, SDKHttpClient } from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @param {SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' }} options - The SDK options, including an optional mode. The default storage class is `LocalStorage`.\n * @returns {PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow} A new instance of either PopupFlow, RedirectFlow, NativeFlow or EmbeddedFlow based on the mode.\n */\nexport function initFlow(options: SDKOptions & { mode: 'popup' }): PopupFlow;\nexport function initFlow(options: SDKOptions & { mode: 'redirect' }): RedirectFlow;\nexport function initFlow(options: SDKOptions & { mode: 'native' }): NativeFlow;\nexport function initFlow(options: SDKOptions & { mode: 'embedded' }): EmbeddedFlow;\nexport function initFlow(options: SDKOptions & { mode: 'custom' }): EmbeddedFlow;\nexport function initFlow(\n\toptions: SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' | 'custom' },\n): PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow | typeof options.customFlow;\nexport function initFlow(\n\toptions: SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' | 'custom' },\n): PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow | typeof options.customFlow {\n\tconst StorageClass = options.storage || LocalStorage;\n\tconst HttpClientClass = options.httpClient || HttpClient;\n\n\tconst storage = new StorageClass();\n\tconst httpClient = new HttpClientClass();\n\tlet logging;\n\n\tif (options.logging) {\n\t\tlogging = new options.logging();\n\t\thttpClient.logging = logging;\n\t}\n\n\tif (options.mode === 'popup') {\n\t\treturn new PopupFlow(options, storage, httpClient, logging);\n\t} else if (options.mode === 'native') {\n\t\treturn new NativeFlow(options, storage, httpClient, logging);\n\t} else if (options.mode === 'embedded') {\n\t\treturn new EmbeddedFlow(options, storage, httpClient, logging);\n\t} else if (options.mode === 'custom') {\n\t\tif (!options.customFlow || !(options.customFlow.prototype instanceof BaseFlow)) {\n\t\t\tthrow new Error('customFlow must extend BaseFlow');\n\t\t}\n\n\t\treturn new options.customFlow(options, storage, httpClient, logging) as unknown as typeof options.customFlow;\n\t} else {\n\t\treturn new RedirectFlow(options, storage, httpClient, logging);\n\t}\n}\n"],"names":["initFlow","options","StorageClass","LocalStorage","HttpClientClass","HttpClient","storage","httpClient","logging","PopupFlow","NativeFlow","EmbeddedFlow","BaseFlow","RedirectFlow"],"mappings":"uwBA2BO,SAASA,EACfC,EACmF,CACnF,MAAMC,EAAeD,EAAQ,SAAWE,EAAAA,aAClCC,EAAkBH,EAAQ,YAAcI,EAAAA,WAExCC,EAAU,IAAIJ,EACdK,EAAa,IAAIH,EACvB,IAAII,EAOJ,GALIP,EAAQ,UACXO,EAAU,IAAIP,EAAQ,QACtBM,EAAW,QAAUC,GAGlBP,EAAQ,OAAS,QACpB,OAAO,IAAIQ,EAAAA,UAAUR,EAASK,EAASC,EAAYC,CAAO,EAC3D,GAAWP,EAAQ,OAAS,SAC3B,OAAO,IAAIS,EAAAA,WAAWT,EAASK,EAASC,EAAYC,CAAO,EAC5D,GAAWP,EAAQ,OAAS,WAC3B,OAAO,IAAIU,EAAAA,aAAaV,EAASK,EAASC,EAAYC,CAAO,EAC9D,GAAWP,EAAQ,OAAS,SAAU,CACrC,GAAI,CAACA,EAAQ,YAAc,EAAEA,EAAQ,WAAW,qBAAqBW,EAAAA,UACpE,MAAM,IAAI,MAAM,iCAAiC,EAGlD,OAAO,IAAIX,EAAQ,WAAWA,EAASK,EAASC,EAAYC,CAAO,CACpE,KACC,QAAO,IAAIK,EAAAA,aAAaZ,EAASK,EAASC,EAAYC,CAAO,CAE/D"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SDKInitConfig, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';\nimport { UnsupportedFlowError } from './utils/errors';\nimport { createRedirectFlow } from './flows/redirect';\nimport { createPopupFlow } from './flows/popup';\nimport { createEmbeddedFlow } from './flows/embedded';\nimport { createNativeFlow } from './flows/native';\n\nexport type * from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @template T - The type of the flow instance returned by the factory function.\n * @param {SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' }} options - The configuration options for the SDK.\n * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.\n * @throws {UnsupportedFlowError} If the specified mode is not supported.\n */\nexport function initFlow<T>(options: SDKInitConfig): T;\nexport function initFlow(options: SDKInitConfig & { mode: 'popup'; lazyLoad: true }): PopupFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'redirect'; lazyLoad: true }): RedirectFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'embedded'; lazyLoad: true }): EmbeddedFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'native'; lazyLoad: true }): NativeFlow;\nexport function initFlow(\n\toptions: SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' },\n): Promise<PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow> | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow | unknown {\n\tif (typeof options.factory === 'function') {\n\t\treturn options.factory(options);\n\t}\n\n\tif (options.mode === 'redirect') {\n\t\treturn createRedirectFlow(options);\n\t} else if (options.mode === 'popup') {\n\t\treturn createPopupFlow(options);\n\t} else if (options.mode === 'embedded') {\n\t\treturn createEmbeddedFlow(options);\n\t} else if (options.mode === 'native') {\n\t\treturn createNativeFlow(options);\n\t}\n\n\tthrow new UnsupportedFlowError();\n}\n"],"mappings":"4OAsBA,SAAgB,EACf,EACiI,CACjI,GAAI,OAAO,EAAQ,SAAY,WAC9B,OAAO,EAAQ,QAAQ,CAAO,EAG/B,GAAI,EAAQ,OAAS,WACpB,OAAO,EAAA,mBAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,QAC3B,OAAO,EAAA,gBAAgB,CAAO,EACxB,GAAI,EAAQ,OAAS,WAC3B,OAAO,EAAA,mBAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,SAC3B,OAAO,EAAA,iBAAiB,CAAO,EAGhC,MAAM,IAAI,EAAA,oBACX"}
package/dist/index.d.ts CHANGED
@@ -1,32 +1,27 @@
1
- import { SDKOptions } from './types';
2
- import { RedirectFlow } from './flows/RedirectFlow';
3
- import { PopupFlow } from './flows/PopupFlow';
4
- import { NativeFlow } from './flows/NativeFlow';
5
- import { EmbeddedFlow } from './flows/EmbeddedFlow';
6
- export * from './utils/errors';
1
+ import { SDKInitConfig, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';
7
2
  export type * from './types';
8
- export { SDKStorage, SDKLogging, SDKHttpClient } from './types';
9
3
  /**
10
4
  * Initializes an authentication flow based on the specified mode.
11
5
  *
12
- * @param {SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' }} options - The SDK options, including an optional mode. The default storage class is `LocalStorage`.
13
- * @returns {PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow} A new instance of either PopupFlow, RedirectFlow, NativeFlow or EmbeddedFlow based on the mode.
6
+ * @template T - The type of the flow instance returned by the factory function.
7
+ * @param {SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' }} options - The configuration options for the SDK.
8
+ * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.
9
+ * @throws {UnsupportedFlowError} If the specified mode is not supported.
14
10
  */
15
- export declare function initFlow(options: SDKOptions & {
11
+ export declare function initFlow<T>(options: SDKInitConfig): T;
12
+ export declare function initFlow(options: SDKInitConfig & {
16
13
  mode: 'popup';
14
+ lazyLoad: true;
17
15
  }): PopupFlow;
18
- export declare function initFlow(options: SDKOptions & {
16
+ export declare function initFlow(options: SDKInitConfig & {
19
17
  mode: 'redirect';
18
+ lazyLoad: true;
20
19
  }): RedirectFlow;
21
- export declare function initFlow(options: SDKOptions & {
22
- mode: 'native';
23
- }): NativeFlow;
24
- export declare function initFlow(options: SDKOptions & {
20
+ export declare function initFlow(options: SDKInitConfig & {
25
21
  mode: 'embedded';
22
+ lazyLoad: true;
26
23
  }): EmbeddedFlow;
27
- export declare function initFlow(options: SDKOptions & {
28
- mode: 'custom';
29
- }): EmbeddedFlow;
30
- export declare function initFlow(options: SDKOptions & {
31
- mode?: 'popup' | 'redirect' | 'native' | 'embedded' | 'custom';
32
- }): PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow | typeof options.customFlow;
24
+ export declare function initFlow(options: SDKInitConfig & {
25
+ mode: 'native';
26
+ lazyLoad: true;
27
+ }): NativeFlow;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{BaseFlow as i}from"./flows/BaseFlow.mjs";import{RedirectFlow as p}from"./flows/RedirectFlow.mjs";import{PopupFlow as w}from"./flows/PopupFlow.mjs";import{NativeFlow as g}from"./flows/NativeFlow.mjs";import{EmbeddedFlow as n}from"./flows/EmbeddedFlow.mjs";import{LocalStorage as f}from"./storages/LocalStorage.mjs";import{HttpClient as u}from"./utils/HttpClient.mjs";import{FallbackError as R,PopupBlockedError as j,PopupClosedError as q}from"./utils/errors.mjs";import{SDKHttpClient as A,SDKLogging as G,SDKStorage as I}from"./types.mjs";import"./utils/jwt.mjs";import"./utils/base64Url.mjs";import"./utils/date.mjs";import"./utils/Metadata.mjs";import"./utils/Session.mjs";import"./utils/State.mjs";import"./utils/crypto.mjs";import"./utils/handlers.mjs";import"./handlers/NativeFlowHandler.mjs";import"./handlers/BaseFlowHandler.mjs";import"./handlers/EmbeddedFlowHandler.mjs";function L(r){const m=r.storage||f,l=r.httpClient||u,o=new m,t=new l;let e;if(r.logging&&(e=new r.logging,t.logging=e),r.mode==="popup")return new w(r,o,t,e);if(r.mode==="native")return new g(r,o,t,e);if(r.mode==="embedded")return new n(r,o,t,e);if(r.mode==="custom"){if(!r.customFlow||!(r.customFlow.prototype instanceof i))throw new Error("customFlow must extend BaseFlow");return new r.customFlow(r,o,t,e)}else return new p(r,o,t,e)}export{R as FallbackError,j as PopupBlockedError,q as PopupClosedError,A as SDKHttpClient,G as SDKLogging,I as SDKStorage,L as initFlow};
2
- //# sourceMappingURL=index.mjs.map
1
+ import{UnsupportedFlowError as e}from"./utils/errors.mjs";import{createRedirectFlow as t}from"./flows/redirect.mjs";import{createPopupFlow as n}from"./flows/popup.mjs";import{createEmbeddedFlow as r}from"./flows/embedded.mjs";import{createNativeFlow as i}from"./flows/native.mjs";function a(a){if(typeof a.factory==`function`)return a.factory(a);if(a.mode===`redirect`)return t(a);if(a.mode===`popup`)return n(a);if(a.mode===`embedded`)return r(a);if(a.mode===`native`)return i(a);throw new e}export{a as initFlow};
2
+ //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import type { SDKOptions } from './types';\nimport { BaseFlow } from './flows/BaseFlow';\nimport { RedirectFlow } from './flows/RedirectFlow';\nimport { PopupFlow } from './flows/PopupFlow';\nimport { NativeFlow } from './flows/NativeFlow';\nimport { EmbeddedFlow } from './flows/EmbeddedFlow';\nimport { LocalStorage } from './storages/LocalStorage';\nimport { HttpClient } from './utils/HttpClient';\n\nexport * from './utils/errors';\nexport type * from './types';\nexport { SDKStorage, SDKLogging, SDKHttpClient } from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @param {SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' }} options - The SDK options, including an optional mode. The default storage class is `LocalStorage`.\n * @returns {PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow} A new instance of either PopupFlow, RedirectFlow, NativeFlow or EmbeddedFlow based on the mode.\n */\nexport function initFlow(options: SDKOptions & { mode: 'popup' }): PopupFlow;\nexport function initFlow(options: SDKOptions & { mode: 'redirect' }): RedirectFlow;\nexport function initFlow(options: SDKOptions & { mode: 'native' }): NativeFlow;\nexport function initFlow(options: SDKOptions & { mode: 'embedded' }): EmbeddedFlow;\nexport function initFlow(options: SDKOptions & { mode: 'custom' }): EmbeddedFlow;\nexport function initFlow(\n\toptions: SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' | 'custom' },\n): PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow | typeof options.customFlow;\nexport function initFlow(\n\toptions: SDKOptions & { mode?: 'popup' | 'redirect' | 'native' | 'embedded' | 'custom' },\n): PopupFlow | RedirectFlow | NativeFlow | EmbeddedFlow | typeof options.customFlow {\n\tconst StorageClass = options.storage || LocalStorage;\n\tconst HttpClientClass = options.httpClient || HttpClient;\n\n\tconst storage = new StorageClass();\n\tconst httpClient = new HttpClientClass();\n\tlet logging;\n\n\tif (options.logging) {\n\t\tlogging = new options.logging();\n\t\thttpClient.logging = logging;\n\t}\n\n\tif (options.mode === 'popup') {\n\t\treturn new PopupFlow(options, storage, httpClient, logging);\n\t} else if (options.mode === 'native') {\n\t\treturn new NativeFlow(options, storage, httpClient, logging);\n\t} else if (options.mode === 'embedded') {\n\t\treturn new EmbeddedFlow(options, storage, httpClient, logging);\n\t} else if (options.mode === 'custom') {\n\t\tif (!options.customFlow || !(options.customFlow.prototype instanceof BaseFlow)) {\n\t\t\tthrow new Error('customFlow must extend BaseFlow');\n\t\t}\n\n\t\treturn new options.customFlow(options, storage, httpClient, logging) as unknown as typeof options.customFlow;\n\t} else {\n\t\treturn new RedirectFlow(options, storage, httpClient, logging);\n\t}\n}\n"],"names":["initFlow","options","StorageClass","LocalStorage","HttpClientClass","HttpClient","storage","httpClient","logging","PopupFlow","NativeFlow","EmbeddedFlow","BaseFlow","RedirectFlow"],"mappings":"s3BA2BO,SAASA,EACfC,EACmF,CACnF,MAAMC,EAAeD,EAAQ,SAAWE,EAClCC,EAAkBH,EAAQ,YAAcI,EAExCC,EAAU,IAAIJ,EACdK,EAAa,IAAIH,EACvB,IAAII,EAOJ,GALIP,EAAQ,UACXO,EAAU,IAAIP,EAAQ,QACtBM,EAAW,QAAUC,GAGlBP,EAAQ,OAAS,QACpB,OAAO,IAAIQ,EAAUR,EAASK,EAASC,EAAYC,CAAO,EAC3D,GAAWP,EAAQ,OAAS,SAC3B,OAAO,IAAIS,EAAWT,EAASK,EAASC,EAAYC,CAAO,EAC5D,GAAWP,EAAQ,OAAS,WAC3B,OAAO,IAAIU,EAAaV,EAASK,EAASC,EAAYC,CAAO,EAC9D,GAAWP,EAAQ,OAAS,SAAU,CACrC,GAAI,CAACA,EAAQ,YAAc,EAAEA,EAAQ,WAAW,qBAAqBW,GACpE,MAAM,IAAI,MAAM,iCAAiC,EAGlD,OAAO,IAAIX,EAAQ,WAAWA,EAASK,EAASC,EAAYC,CAAO,CACpE,KACC,QAAO,IAAIK,EAAaZ,EAASK,EAASC,EAAYC,CAAO,CAE/D"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SDKInitConfig, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';\nimport { UnsupportedFlowError } from './utils/errors';\nimport { createRedirectFlow } from './flows/redirect';\nimport { createPopupFlow } from './flows/popup';\nimport { createEmbeddedFlow } from './flows/embedded';\nimport { createNativeFlow } from './flows/native';\n\nexport type * from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @template T - The type of the flow instance returned by the factory function.\n * @param {SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' }} options - The configuration options for the SDK.\n * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.\n * @throws {UnsupportedFlowError} If the specified mode is not supported.\n */\nexport function initFlow<T>(options: SDKInitConfig): T;\nexport function initFlow(options: SDKInitConfig & { mode: 'popup'; lazyLoad: true }): PopupFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'redirect'; lazyLoad: true }): RedirectFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'embedded'; lazyLoad: true }): EmbeddedFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'native'; lazyLoad: true }): NativeFlow;\nexport function initFlow(\n\toptions: SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' },\n): Promise<PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow> | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow | unknown {\n\tif (typeof options.factory === 'function') {\n\t\treturn options.factory(options);\n\t}\n\n\tif (options.mode === 'redirect') {\n\t\treturn createRedirectFlow(options);\n\t} else if (options.mode === 'popup') {\n\t\treturn createPopupFlow(options);\n\t} else if (options.mode === 'embedded') {\n\t\treturn createEmbeddedFlow(options);\n\t} else if (options.mode === 'native') {\n\t\treturn createNativeFlow(options);\n\t}\n\n\tthrow new UnsupportedFlowError();\n}\n"],"mappings":"wRAsBA,SAAgB,EACf,EACiI,CACjI,GAAI,OAAO,EAAQ,SAAY,WAC9B,OAAO,EAAQ,QAAQ,CAAO,EAG/B,GAAI,EAAQ,OAAS,WACpB,OAAO,EAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,QAC3B,OAAO,EAAgB,CAAO,EACxB,GAAI,EAAQ,OAAS,WAC3B,OAAO,EAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,SAC3B,OAAO,EAAiB,CAAO,EAGhC,MAAM,IAAI,CACX"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/errors.cjs"),t=require("../utils/common.cjs"),n=require("../utils/session.cjs"),r=require("../assets/oidc.cjs"),i=require("../assets/server.cjs");var a=`strivacity-session-v1`,o=3900,s=new Set([`transfer-encoding`,`connection`,`keep-alive`,`content-encoding`]),c=`sty.returnTo`,l=120;function u(a,o){let s=i.o(a,o),l=new Map;function u(){if(!s.issuer){let t=new e.ConfigurationError(`Missing option: issuer`);throw s.logging?.error(`Required option missing`,t),t}if(!s.clientId){let t=new e.ConfigurationError(`Missing option: clientId`);throw s.logging?.error(`Required option missing`,t),t}if(!s.redirectUri){let t=new e.ConfigurationError(`Missing option: redirectUri`);throw s.logging?.error(`Required option missing`,t),t}if(s.scopes&&!Array.isArray(s.scopes)){let t=new e.ConfigurationError(`Invalid option: scopes`);throw s.logging?.error(`Invalid option provided`,t),t}}async function d(e,t=302,n){return a.redirect?await a.redirect(e,t,n):new Response(null,{status:t,headers:{location:e.toString()}})}async function f(t,n,r){let i=new URL(`/error`,t);return n instanceof e.OidcError?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.error),n.errorDescription&&i.searchParams.set(`error_description`,n.errorDescription)):n instanceof Error&&`category`in n?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.name),i.searchParams.set(`error_description`,n.message)):(i.searchParams.set(`type`,`unknown`),i.searchParams.set(`error`,`unknown_error`),i.searchParams.set(`error_description`,n instanceof Error?n.message:`Unknown error`)),d(i,302,r)}async function p(e){return n.loadSession(await s.storage.get(s.storageTokenName,e))}async function m(e,t){await s.storage.set(s.storageTokenName,n.serializeSession(e),t)}async function h(e){await s.storage.delete(s.storageTokenName,e)}async function g(t){s.logging?.debug(`Attempting to refresh session`);let n=await p(t);if(!n)throw new e.ProtocolError(`No session available to refresh`);if(typeof n.refresh_token!=`string`)throw new e.ConfigurationError(`No refresh token available`);try{let e=await r.h({refreshToken:n.refresh_token,options:s,expectedSub:n.claims?.sub});return await m(e,t),s.logging?.debug(`Session refresh successful`),e}catch(e){throw await h(t),s.logging?.error(`Session refresh failed`,e),e}}async function _(e){let t=await p(e);if(t?.refresh_token?s.logging?.debug(`Attempting to revoke refresh token`):s.logging?.debug(`Attempting to revoke access token`),await h(e),!t?.access_token&&!t?.refresh_token){s.logging?.debug(`Revoke called without session`);return}let n=t.refresh_token?`refresh_token`:`access_token`,i=n===`refresh_token`?t.refresh_token:t.access_token;try{await r.g({tokenTypeHint:n,token:i,options:s}),n===`refresh_token`?s.logging?.info(`Refresh token successfully revoked`):s.logging?.info(`Access token successfully revoked`)}catch(e){throw s.logging?.error(`Token revocation failed`,e),e}}async function v(e){s.logging?.debug(`Attempting entry request`);let{searchParams:t}=new URL(e);try{let e=new URL(`/provider/flow/entry`,s.issuer),n=await r.o({url:e,params:t,sdkMode:s.mode===`embedded`?`web-embedded`:`web`,options:s});return s.logging?.debug(`Entry request successful - ${JSON.stringify(n)}`),n}catch(e){throw s.logging?.error(`Entry request failed`,e),e}}async function y(t,n){s.logging?.debug(`Exchanging authorization code for tokens`);try{let i=await r.a({params:t,options:s});if(!i.access_token)throw new e.ProtocolError(`Missing access_token`);return await m(i,n),s.logging?.debug(`Token exchange successful`),s.logging&&(s.logging.xEventId=void 0,s.logging.info(`Login successful`)),i}catch(e){throw s.logging?.error(`Token exchange failed`,e),e}}async function b(e,t){s.logging?.debug(`Attempting to logout`);let n=await p(t);if(await h(t),s.logging?.debug(`Logout initiated`),!n?.id_token)return s.logging?.debug(`Logout called without id token`),new URL(e);let i=await r.p(s);return r.n({url:i.end_session_endpoint,idToken:n.id_token,postLogoutRedirectUri:new URL(e).toString()})}async function x(t,n={}){let o=await a.toRequest(t),l=new URL(o.url),{returnTo:u,...d}=Object.fromEntries(l.searchParams),f=i.d(u,l.origin),p=await r.t({params:{...d,...n},options:s});if(u&&!f)throw new e.ProtocolError(`Invalid returnTo URL: ${u}. Expected a URL with the same origin as the request: ${l.origin}`);[`embedded`,`native`].includes(s.mode)&&d.sdk&&p.searchParams.set(`sdk`,d.sdk);let m=await s.httpClient.request(p,{method:`GET`,credentials:`include`,redirect:`manual`});return s.logging?.debug(`Attempting to redirect for login`),f&&i.l(t,i.u(c,f)),i.a(t,i.c(m))}async function S(e){return x(e,{prompt:`create`})}async function C(t){let n=await a.toRequest(t),o=new URL(n.url),l=Object.fromEntries(o.searchParams);try{let a=await s.stateStorage.get(`sty.${l.state}`);if(!a)throw new e.ProtocolError(`State not found or expired. Please try logging in again.`);await y(l,t);let u=r.x(a),f=i.s(n.headers.get(`cookie`))[`sty.returnTo`]??s.postLoginRedirectUri;return i.l(t,i.u(c,``,{expires:new Date(0)})),u.metadata?.display===`popup`?i.a(t,new Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();<\/script></body></html>`,{headers:{"content-type":`text/html; charset=utf-8`}})):i.a(t,await d(new URL(f,o.origin),302,t))}catch(e){return i.a(t,await f(o.origin,e,t))}}async function w(t){let n=await a.toRequest(t),r=new URL(n.url),o=r.origin,s=r.searchParams.get(`returnTo`),c=i.d(s,o);if(s&&!c)throw new e.ProtocolError(`Invalid returnTo URL: ${s}. Expected a URL with the same origin as the request: ${r.origin}`);try{return await g(t),c?i.a(t,await d(new URL(c,o),302,t)):i.a(t,new Response(null,{status:204}))}catch(e){return i.a(t,await f(o,e,t))}}async function T(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{return await _(e),i.a(e,await d(new URL(s.postLogoutRedirectUri,n),302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function E(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{let r=await v(t.url),a=new URL(s.loginUri,n);return a.searchParams.set(`session_id`,r.session_id),a.searchParams.set(`short_app_id`,r.short_app_id),a.searchParams.set(`language`,r.language),i.a(e,await d(a,302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function D(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{let t=await b(new URL(s.postLogoutRedirectUri,n),e);return i.a(e,await d(t,302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function O(e){if(typeof s.storage.deleteByLogoutToken!=`function`)return new Response(`Back-channel logout requires a storage with deleteByLogoutToken`,{status:501});let n=await a.toRequest(e),o;try{if((n.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`))o=(await n.formData()).get(`logout_token`);else return new Response(`Invalid content type: expected application/x-www-form-urlencoded`,{status:400})}catch{return new Response(`Failed to parse request body`,{status:400})}if(!o)return new Response(`Missing logout_token`,{status:400});let c=t.timestamp();for(let[e,t]of l)t<=c&&l.delete(e);if(l.has(o))return new Response(`Invalid logout_token: token already used`,{status:400});l.set(o,c+120);let u,d;try{d=await r.p(s),u=await r.y({token:o,jwksUri:d.jwks_uri,options:s})}catch(e){return new Response(`Invalid logout_token: ${e.message}`,{status:400})}if(u.iss!==d.issuer)return new Response(`Invalid logout_token: invalid iss claim`,{status:400});if(Array.isArray(u.aud)?!u.aud.includes(s.clientId):u.aud!==s.clientId)return new Response(`Invalid logout_token: invalid aud claim`,{status:400});if(typeof u.iat!=`number`||Math.abs(c-u.iat)>120)return new Response(`Invalid logout_token: invalid or stale iat claim`,{status:400});if(!u.jti)return new Response(`Invalid logout_token: missing jti claim`,{status:400});if(u.nonce!==void 0)return new Response(`Invalid logout_token: nonce claim must not be present`,{status:400});if(!u.events||!(`http://schemas.openid.net/event/backchannel-logout`in u.events))return new Response(`Invalid logout_token: missing ${i.t} in events`,{status:400});if(!u.sid&&!u.sub)return new Response(`Invalid logout_token: must contain sid or sub claim`,{status:400});let f={};u.sid&&(f.sid=u.sid),u.sub&&(f.sub=u.sub);try{await s.storage.deleteByLogoutToken(f)}catch(e){return new Response(`Failed to delete session: ${e.message}`,{status:500})}return new Response(null,{status:200})}async function k(e){let t=await a.toRequest(e),n=new URL(t.url);return t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/login`?x(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/register`?S(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/callback`?C(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/refresh`?w(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/revoke`?T(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/entry`?E(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/logout`?D(e):t.method===`POST`&&n.pathname===`${s.authUrlPrefix}/backchannel-logout`?O(e):null}return u(),{get options(){return s},getSession:p,updateSession:m,refreshSession:g,revokeSession:_,getEntrySession:v,completeLogin:y,logout:b,handleLogin:x,handleRegister:S,handleCallback:C,handleRefresh:w,handleRevoke:T,handleEntry:E,handleLogout:D,handleBackChannelLogout:O,handler:k}}exports.BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS=l,exports.COOKIE_CHUNK_SIZE=o,exports.COOKIE_CONTEXT=a,exports.DISALLOWED_PROXY_HEADERS=s,exports.RETURN_TO_COOKIE=c,exports.createBaseServerSDK=u;
2
+ //# sourceMappingURL=base.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.cjs","names":[],"sources":["../../src/server/base.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\nimport type { SessionData, LogoutTokenClaims } from '../types/oidc';\nimport type { BaseServerSDK, ServerAdapter, ServerStorage, ServerSDKInitConfig } from '../types/server';\nimport {\n\tbuildEndSessionUrl,\n\tbuildAuthorizationUrl,\n\trevokeToken,\n\trefreshToken,\n\texchangeCode,\n\tverifyJwt,\n\tfetchFlowEntry,\n\tgetDiscoveryDocument,\n} from '../utils/oidc';\nimport { loadSession, serializeSession } from '../utils/session';\nimport { parseState } from '../utils/state';\nimport { timestamp } from '../utils/common';\nimport { ConfigurationError, OidcError, ProtocolError, type FailureCategory } from '../utils/errors';\nimport {\n\tpushSetCookie,\n\tflushSetCookies,\n\tparseCookieHeader,\n\tserializeCookie,\n\tproxyResponse,\n\ttoSafeRedirect,\n\tgetServerSDKOptions,\n\tBACKCHANNEL_LOGOUT_EVENT,\n} from '../utils/server';\n\nexport const COOKIE_CONTEXT = 'strivacity-session-v1';\nexport const COOKIE_CHUNK_SIZE = 3900;\nexport const DISALLOWED_PROXY_HEADERS = new Set(['transfer-encoding', 'connection', 'keep-alive', 'content-encoding']);\nexport const RETURN_TO_COOKIE = 'sty.returnTo';\nexport const BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS = 120;\n\n/**\n * Creates the framework-agnostic Strivacity base server SDK.\n *\n * @param {ServerAdapter<TEvent>} adapter - The framework adapter converting `TEvent` to a standard `Request`.\n * @param {ServerSDKOptions<TEvent, Storage, StateStorage>} initConfig - The initial configuration for the server SDK.\n * @returns {BaseServerSDK<TEvent>} The initialized, framework-agnostic server SDK core.\n */\nexport function createBaseServerSDK<\n\tTEvent = unknown,\n\tStorage extends ServerStorage<TEvent> = ServerStorage<TEvent>,\n\tStateStorage extends SDKStorage = SDKStorage,\n>(adapter: ServerAdapter<TEvent>, initConfig: ServerSDKInitConfig<TEvent, Storage, StateStorage>): BaseServerSDK<TEvent> {\n\tconst options = getServerSDKOptions(adapter, initConfig);\n\tconst seenLogoutTokenIds = new Map<string, number>();\n\n\tfunction init() {\n\t\tif (!options.issuer) {\n\t\t\tconst error = new ConfigurationError('Missing option: issuer');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.clientId) {\n\t\t\tconst error = new ConfigurationError('Missing option: clientId');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.redirectUri) {\n\t\t\tconst error = new ConfigurationError('Missing option: redirectUri');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (options.scopes && !Array.isArray(options.scopes)) {\n\t\t\tconst error = new ConfigurationError('Invalid option: scopes');\n\t\t\toptions.logging?.error('Invalid option provided', error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function redirect(url: string | URL, status = 302, event?: TEvent): Promise<Response> {\n\t\tif (adapter.redirect) {\n\t\t\treturn await adapter.redirect(url, status, event);\n\t\t}\n\n\t\treturn new Response(null, { status, headers: { location: url.toString() } });\n\t}\n\n\tasync function errorRedirect(origin: string, error: unknown, event?: TEvent): Promise<Response> {\n\t\tconst url = new URL('/error', origin);\n\n\t\tif (error instanceof OidcError) {\n\t\t\turl.searchParams.set('type', error.category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.error);\n\t\t\tif (error.errorDescription) {\n\t\t\t\turl.searchParams.set('error_description', error.errorDescription);\n\t\t\t}\n\t\t} else if (error instanceof Error && 'category' in error) {\n\t\t\turl.searchParams.set('type', (error as { category: FailureCategory }).category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.name);\n\t\t\turl.searchParams.set('error_description', error.message);\n\t\t} else {\n\t\t\turl.searchParams.set('type', 'unknown');\n\t\t\turl.searchParams.set('error', 'unknown_error');\n\t\t\turl.searchParams.set('error_description', error instanceof Error ? error.message : 'Unknown error');\n\t\t}\n\n\t\treturn redirect(url, 302, event);\n\t}\n\n\tasync function getSession(event?: TEvent): Promise<SessionData | null> {\n\t\treturn loadSession(await options.storage.get(options.storageTokenName, event));\n\t}\n\n\tasync function updateSession(session: SessionData, event?: TEvent): Promise<void> {\n\t\tawait options.storage.set(options.storageTokenName, serializeSession(session), event);\n\t}\n\n\tasync function cleanupSession(event?: TEvent): Promise<void> {\n\t\tawait options.storage.delete(options.storageTokenName, event);\n\t}\n\n\tasync function refreshSession(event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Attempting to refresh session');\n\n\t\tconst currentSession = await getSession(event);\n\n\t\tif (!currentSession) {\n\t\t\tthrow new ProtocolError('No session available to refresh');\n\t\t}\n\n\t\tif (typeof currentSession.refresh_token !== 'string') {\n\t\t\tthrow new ConfigurationError('No refresh token available');\n\t\t}\n\n\t\ttry {\n\t\t\tconst newSession = await refreshToken({ refreshToken: currentSession.refresh_token, options, expectedSub: currentSession.claims?.sub });\n\t\t\tawait updateSession(newSession, event);\n\n\t\t\toptions.logging?.debug('Session refresh successful');\n\n\t\t\treturn newSession;\n\t\t} catch (error) {\n\t\t\tawait cleanupSession(event);\n\t\t\toptions.logging?.error('Session refresh failed', error as Error);\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function revokeSession(event?: TEvent): Promise<void> {\n\t\tconst currentSession = await getSession(event);\n\n\t\tif (currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Attempting to revoke refresh token');\n\t\t} else {\n\t\t\toptions.logging?.debug('Attempting to revoke access token');\n\t\t}\n\n\t\t// NOTE: Cleanup session before revocation\n\t\tawait cleanupSession(event);\n\n\t\tif (!currentSession?.access_token && !currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Revoke called without session');\n\t\t\treturn;\n\t\t}\n\n\t\tconst tokenTypeHint = currentSession.refresh_token ? 'refresh_token' : 'access_token';\n\t\tconst token = (tokenTypeHint === 'refresh_token' ? currentSession.refresh_token : currentSession.access_token)!;\n\n\t\ttry {\n\t\t\tawait revokeToken({ tokenTypeHint, token, options });\n\n\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\toptions.logging?.info('Refresh token successfully revoked');\n\t\t\t} else {\n\t\t\t\toptions.logging?.info('Access token successfully revoked');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token revocation failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function getEntrySession(entryUrl: string | URL): Promise<Record<string, string>> {\n\t\toptions.logging?.debug('Attempting entry request');\n\n\t\tconst { searchParams: params } = new URL(entryUrl);\n\n\t\ttry {\n\t\t\tconst url = new URL('/provider/flow/entry', options.issuer);\n\t\t\tconst data = await fetchFlowEntry({\n\t\t\t\turl,\n\t\t\t\tparams,\n\t\t\t\tsdkMode: options.mode === 'embedded' ? 'web-embedded' : 'web',\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\toptions.logging?.debug(`Entry request successful - ${JSON.stringify(data)}`);\n\n\t\t\treturn data;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Entry request failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function completeLogin(params: Record<string, string>, event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Exchanging authorization code for tokens');\n\n\t\ttry {\n\t\t\tconst session = await exchangeCode({ params, options });\n\n\t\t\tif (!session.access_token) {\n\t\t\t\tthrow new ProtocolError('Missing access_token');\n\t\t\t}\n\n\t\t\tawait updateSession(session, event);\n\n\t\t\toptions.logging?.debug('Token exchange successful');\n\n\t\t\tif (options.logging) {\n\t\t\t\toptions.logging.xEventId = undefined;\n\t\t\t\toptions.logging.info('Login successful');\n\t\t\t}\n\n\t\t\treturn session;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token exchange failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function logout(postLogoutRedirectUri: string | URL, event?: TEvent): Promise<URL> {\n\t\toptions.logging?.debug('Attempting to logout');\n\n\t\t// NOTE: Cleanup session before logout\n\t\tconst currentSession = await getSession(event);\n\t\tawait cleanupSession(event);\n\n\t\toptions.logging?.debug('Logout initiated');\n\n\t\tif (!currentSession?.id_token) {\n\t\t\toptions.logging?.debug('Logout called without id token');\n\t\t\treturn new URL(postLogoutRedirectUri);\n\t\t}\n\n\t\tconst metadata = await getDiscoveryDocument(options);\n\n\t\treturn buildEndSessionUrl({\n\t\t\turl: metadata.end_session_endpoint,\n\t\t\tidToken: currentSession.id_token,\n\t\t\tpostLogoutRedirectUri: new URL(postLogoutRedirectUri).toString(),\n\t\t});\n\t}\n\n\tasync function handleLogin(event: TEvent, extraParams: Record<string, unknown> = {}): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst { returnTo, ...params } = Object.fromEntries(requestUrl.searchParams);\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, requestUrl.origin);\n\t\tconst url = await buildAuthorizationUrl({ params: { ...params, ...extraParams }, options });\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\tif (['embedded', 'native'].includes(options.mode) && params.sdk) {\n\t\t\turl.searchParams.set('sdk', params.sdk);\n\t\t}\n\n\t\tconst startResponse = await options.httpClient.request<string>(url, {\n\t\t\tmethod: 'GET',\n\t\t\tcredentials: 'include',\n\t\t\tredirect: 'manual',\n\t\t});\n\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tif (safeReturnTo) {\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, safeReturnTo));\n\t\t}\n\n\t\treturn flushSetCookies(event, proxyResponse(startResponse));\n\t}\n\n\tasync function handleRegister(event: TEvent): Promise<Response> {\n\t\treturn handleLogin(event, { prompt: 'create' });\n\t}\n\n\tasync function handleCallback(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst params = Object.fromEntries(requestUrl.searchParams);\n\n\t\ttry {\n\t\t\tconst serializedState = await options.stateStorage.get(`sty.${params.state}`);\n\n\t\t\tif (!serializedState) {\n\t\t\t\tthrow new ProtocolError('State not found or expired. Please try logging in again.');\n\t\t\t}\n\n\t\t\tawait completeLogin(params, event);\n\n\t\t\tconst state = parseState(serializedState);\n\t\t\tconst returnTo = parseCookieHeader(request.headers.get('cookie'))[RETURN_TO_COOKIE] ?? options.postLoginRedirectUri;\n\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, '', { expires: new Date(0) }));\n\n\t\t\tif (state.metadata?.display === 'popup') {\n\t\t\t\t// NOTE: If the login was initiated from a popup, we return a HTML page that will close the popup and notify the opener window.\n\t\t\t\treturn flushSetCookies(\n\t\t\t\t\tevent,\n\t\t\t\t\tnew Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();</script></body></html>`, {\n\t\t\t\t\t\theaders: { 'content-type': 'text/html; charset=utf-8' },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(returnTo, requestUrl.origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(requestUrl.origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRefresh(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst origin = requestUrl.origin;\n\t\tconst returnTo = requestUrl.searchParams.get('returnTo');\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, origin);\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\ttry {\n\t\t\tawait refreshSession(event);\n\n\t\t\tif (safeReturnTo) {\n\t\t\t\treturn flushSetCookies(event, await redirect(new URL(safeReturnTo, origin), 302, event));\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, new Response(null, { status: 204 }));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRevoke(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tawait revokeSession(event);\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(options.postLogoutRedirectUri, origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleEntry(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst data = await getEntrySession(request.url);\n\t\t\tconst uri = new URL(options.loginUri, origin);\n\t\t\turi.searchParams.set('session_id', data.session_id);\n\t\t\turi.searchParams.set('short_app_id', data.short_app_id);\n\t\t\turi.searchParams.set('language', data.language);\n\n\t\t\treturn flushSetCookies(event, await redirect(uri, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleLogout(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst logoutUrl = await logout(new URL(options.postLogoutRedirectUri, origin), event);\n\t\t\treturn flushSetCookies(event, await redirect(logoutUrl, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleBackChannelLogout(event: TEvent): Promise<Response> {\n\t\tif (typeof options.storage.deleteByLogoutToken !== 'function') {\n\t\t\treturn new Response('Back-channel logout requires a storage with deleteByLogoutToken', { status: 501 });\n\t\t}\n\n\t\tconst request = await adapter.toRequest(event);\n\t\tlet logoutToken: string | null;\n\n\t\ttry {\n\t\t\tconst contentType = request.headers.get('content-type') ?? '';\n\n\t\t\tif (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\tconst body = await request.formData();\n\t\t\t\tlogoutToken = body.get('logout_token') as string | null;\n\t\t\t} else {\n\t\t\t\treturn new Response('Invalid content type: expected application/x-www-form-urlencoded', { status: 400 });\n\t\t\t}\n\t\t} catch {\n\t\t\treturn new Response('Failed to parse request body', { status: 400 });\n\t\t}\n\n\t\tif (!logoutToken) {\n\t\t\treturn new Response('Missing logout_token', { status: 400 });\n\t\t}\n\n\t\tconst now = timestamp();\n\n\t\tfor (const [token, expiresAt] of seenLogoutTokenIds) {\n\t\t\tif (expiresAt <= now) {\n\t\t\t\tseenLogoutTokenIds.delete(token);\n\t\t\t}\n\t\t}\n\n\t\tif (seenLogoutTokenIds.has(logoutToken)) {\n\t\t\treturn new Response('Invalid logout_token: token already used', { status: 400 });\n\t\t}\n\n\t\tseenLogoutTokenIds.set(logoutToken, now + BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS);\n\n\t\tlet claims;\n\t\tlet metadata;\n\n\t\ttry {\n\t\t\tmetadata = await getDiscoveryDocument(options);\n\t\t\tclaims = await verifyJwt<LogoutTokenClaims>({ token: logoutToken, jwksUri: metadata.jwks_uri, options });\n\t\t} catch (error) {\n\t\t\treturn new Response(`Invalid logout_token: ${error.message}`, { status: 400 });\n\t\t}\n\n\t\tif (claims.iss !== metadata.issuer) {\n\t\t\treturn new Response('Invalid logout_token: invalid iss claim', { status: 400 });\n\t\t}\n\n\t\tif (Array.isArray(claims.aud) ? !claims.aud.includes(options.clientId) : claims.aud !== options.clientId) {\n\t\t\treturn new Response('Invalid logout_token: invalid aud claim', { status: 400 });\n\t\t}\n\n\t\tif (typeof claims.iat !== 'number' || Math.abs(now - claims.iat) > BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS) {\n\t\t\treturn new Response('Invalid logout_token: invalid or stale iat claim', { status: 400 });\n\t\t}\n\n\t\tif (!claims.jti) {\n\t\t\treturn new Response('Invalid logout_token: missing jti claim', { status: 400 });\n\t\t}\n\n\t\tif (claims.nonce !== undefined) {\n\t\t\treturn new Response('Invalid logout_token: nonce claim must not be present', { status: 400 });\n\t\t}\n\n\t\tif (!claims.events || !(BACKCHANNEL_LOGOUT_EVENT in claims.events)) {\n\t\t\treturn new Response(`Invalid logout_token: missing ${BACKCHANNEL_LOGOUT_EVENT} in events`, { status: 400 });\n\t\t}\n\n\t\tif (!claims.sid && !claims.sub) {\n\t\t\treturn new Response('Invalid logout_token: must contain sid or sub claim', { status: 400 });\n\t\t}\n\n\t\tconst token: LogoutTokenClaims = {} as never;\n\n\t\tif (claims.sid) {\n\t\t\ttoken.sid = claims.sid;\n\t\t}\n\t\tif (claims.sub) {\n\t\t\ttoken.sub = claims.sub;\n\t\t}\n\n\t\ttry {\n\t\t\tawait options.storage.deleteByLogoutToken(token);\n\t\t} catch (error) {\n\t\t\treturn new Response(`Failed to delete session: ${error.message}`, { status: 500 });\n\t\t}\n\n\t\treturn new Response(null, { status: 200 });\n\t}\n\n\tasync function handler(event: TEvent): Promise<Response | null> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/login`) {\n\t\t\treturn handleLogin(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/register`) {\n\t\t\treturn handleRegister(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/callback`) {\n\t\t\treturn handleCallback(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/refresh`) {\n\t\t\treturn handleRefresh(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/revoke`) {\n\t\t\treturn handleRevoke(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/entry`) {\n\t\t\treturn handleEntry(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/logout`) {\n\t\t\treturn handleLogout(event);\n\t\t}\n\t\tif (request.method === 'POST' && requestUrl.pathname === `${options.authUrlPrefix}/backchannel-logout`) {\n\t\t\treturn handleBackChannelLogout(event);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// endregion\n\n\tinit();\n\n\treturn {\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tgetSession,\n\t\tupdateSession,\n\t\trefreshSession,\n\t\trevokeSession,\n\t\tgetEntrySession,\n\t\tcompleteLogin,\n\t\tlogout,\n\t\thandleLogin,\n\t\thandleRegister,\n\t\thandleCallback,\n\t\thandleRefresh,\n\t\thandleRevoke,\n\t\thandleEntry,\n\t\thandleLogout,\n\t\thandleBackChannelLogout,\n\t\thandler,\n\t};\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { SDKStorage } from '../types/common';
2
+ import { BaseServerSDK, ServerAdapter, ServerStorage, ServerSDKInitConfig } from '../types/server';
3
+ export declare const COOKIE_CONTEXT = "strivacity-session-v1";
4
+ export declare const COOKIE_CHUNK_SIZE = 3900;
5
+ export declare const DISALLOWED_PROXY_HEADERS: Set<string>;
6
+ export declare const RETURN_TO_COOKIE = "sty.returnTo";
7
+ export declare const BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS = 120;
8
+ /**
9
+ * Creates the framework-agnostic Strivacity base server SDK.
10
+ *
11
+ * @param {ServerAdapter<TEvent>} adapter - The framework adapter converting `TEvent` to a standard `Request`.
12
+ * @param {ServerSDKOptions<TEvent, Storage, StateStorage>} initConfig - The initial configuration for the server SDK.
13
+ * @returns {BaseServerSDK<TEvent>} The initialized, framework-agnostic server SDK core.
14
+ */
15
+ export declare function createBaseServerSDK<TEvent = unknown, Storage extends ServerStorage<TEvent> = ServerStorage<TEvent>, StateStorage extends SDKStorage = SDKStorage>(adapter: ServerAdapter<TEvent>, initConfig: ServerSDKInitConfig<TEvent, Storage, StateStorage>): BaseServerSDK<TEvent>;
@@ -0,0 +1,2 @@
1
+ import{ConfigurationError as e,OidcError as t,ProtocolError as n}from"../utils/errors.mjs";import{timestamp as r}from"../utils/common.mjs";import{loadSession as i,serializeSession as a}from"../utils/session.mjs";import{a as o,g as s,h as c,n as l,o as u,p as d,t as f,x as p,y as m}from"../assets/oidc.mjs";import{a as h,c as g,d as _,l as v,o as y,s as b,t as x,u as S}from"../assets/server.mjs";var C=`strivacity-session-v1`,w=3900,T=new Set([`transfer-encoding`,`connection`,`keep-alive`,`content-encoding`]),E=`sty.returnTo`,D=120;function O(C,w){let T=y(C,w),D=new Map;function O(){if(!T.issuer){let t=new e(`Missing option: issuer`);throw T.logging?.error(`Required option missing`,t),t}if(!T.clientId){let t=new e(`Missing option: clientId`);throw T.logging?.error(`Required option missing`,t),t}if(!T.redirectUri){let t=new e(`Missing option: redirectUri`);throw T.logging?.error(`Required option missing`,t),t}if(T.scopes&&!Array.isArray(T.scopes)){let t=new e(`Invalid option: scopes`);throw T.logging?.error(`Invalid option provided`,t),t}}async function k(e,t=302,n){return C.redirect?await C.redirect(e,t,n):new Response(null,{status:t,headers:{location:e.toString()}})}async function A(e,n,r){let i=new URL(`/error`,e);return n instanceof t?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.error),n.errorDescription&&i.searchParams.set(`error_description`,n.errorDescription)):n instanceof Error&&`category`in n?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.name),i.searchParams.set(`error_description`,n.message)):(i.searchParams.set(`type`,`unknown`),i.searchParams.set(`error`,`unknown_error`),i.searchParams.set(`error_description`,n instanceof Error?n.message:`Unknown error`)),k(i,302,r)}async function j(e){return i(await T.storage.get(T.storageTokenName,e))}async function M(e,t){await T.storage.set(T.storageTokenName,a(e),t)}async function N(e){await T.storage.delete(T.storageTokenName,e)}async function P(t){T.logging?.debug(`Attempting to refresh session`);let r=await j(t);if(!r)throw new n(`No session available to refresh`);if(typeof r.refresh_token!=`string`)throw new e(`No refresh token available`);try{let e=await c({refreshToken:r.refresh_token,options:T,expectedSub:r.claims?.sub});return await M(e,t),T.logging?.debug(`Session refresh successful`),e}catch(e){throw await N(t),T.logging?.error(`Session refresh failed`,e),e}}async function F(e){let t=await j(e);if(t?.refresh_token?T.logging?.debug(`Attempting to revoke refresh token`):T.logging?.debug(`Attempting to revoke access token`),await N(e),!t?.access_token&&!t?.refresh_token){T.logging?.debug(`Revoke called without session`);return}let n=t.refresh_token?`refresh_token`:`access_token`,r=n===`refresh_token`?t.refresh_token:t.access_token;try{await s({tokenTypeHint:n,token:r,options:T}),n===`refresh_token`?T.logging?.info(`Refresh token successfully revoked`):T.logging?.info(`Access token successfully revoked`)}catch(e){throw T.logging?.error(`Token revocation failed`,e),e}}async function I(e){T.logging?.debug(`Attempting entry request`);let{searchParams:t}=new URL(e);try{let e=new URL(`/provider/flow/entry`,T.issuer),n=await u({url:e,params:t,sdkMode:T.mode===`embedded`?`web-embedded`:`web`,options:T});return T.logging?.debug(`Entry request successful - ${JSON.stringify(n)}`),n}catch(e){throw T.logging?.error(`Entry request failed`,e),e}}async function L(e,t){T.logging?.debug(`Exchanging authorization code for tokens`);try{let r=await o({params:e,options:T});if(!r.access_token)throw new n(`Missing access_token`);return await M(r,t),T.logging?.debug(`Token exchange successful`),T.logging&&(T.logging.xEventId=void 0,T.logging.info(`Login successful`)),r}catch(e){throw T.logging?.error(`Token exchange failed`,e),e}}async function R(e,t){T.logging?.debug(`Attempting to logout`);let n=await j(t);if(await N(t),T.logging?.debug(`Logout initiated`),!n?.id_token)return T.logging?.debug(`Logout called without id token`),new URL(e);let r=await d(T);return l({url:r.end_session_endpoint,idToken:n.id_token,postLogoutRedirectUri:new URL(e).toString()})}async function z(e,t={}){let r=await C.toRequest(e),i=new URL(r.url),{returnTo:a,...o}=Object.fromEntries(i.searchParams),s=_(a,i.origin),c=await f({params:{...o,...t},options:T});if(a&&!s)throw new n(`Invalid returnTo URL: ${a}. Expected a URL with the same origin as the request: ${i.origin}`);[`embedded`,`native`].includes(T.mode)&&o.sdk&&c.searchParams.set(`sdk`,o.sdk);let l=await T.httpClient.request(c,{method:`GET`,credentials:`include`,redirect:`manual`});return T.logging?.debug(`Attempting to redirect for login`),s&&v(e,S(E,s)),h(e,g(l))}async function B(e){return z(e,{prompt:`create`})}async function V(e){let t=await C.toRequest(e),r=new URL(t.url),i=Object.fromEntries(r.searchParams);try{let a=await T.stateStorage.get(`sty.${i.state}`);if(!a)throw new n(`State not found or expired. Please try logging in again.`);await L(i,e);let o=p(a),s=b(t.headers.get(`cookie`))[`sty.returnTo`]??T.postLoginRedirectUri;return v(e,S(E,``,{expires:new Date(0)})),o.metadata?.display===`popup`?h(e,new Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();<\/script></body></html>`,{headers:{"content-type":`text/html; charset=utf-8`}})):h(e,await k(new URL(s,r.origin),302,e))}catch(t){return h(e,await A(r.origin,t,e))}}async function H(e){let t=await C.toRequest(e),r=new URL(t.url),i=r.origin,a=r.searchParams.get(`returnTo`),o=_(a,i);if(a&&!o)throw new n(`Invalid returnTo URL: ${a}. Expected a URL with the same origin as the request: ${r.origin}`);try{return await P(e),o?h(e,await k(new URL(o,i),302,e)):h(e,new Response(null,{status:204}))}catch(t){return h(e,await A(i,t,e))}}async function U(e){let t=await C.toRequest(e),n=new URL(t.url).origin;try{return await F(e),h(e,await k(new URL(T.postLogoutRedirectUri,n),302,e))}catch(t){return h(e,await A(n,t,e))}}async function W(e){let t=await C.toRequest(e),n=new URL(t.url).origin;try{let r=await I(t.url),i=new URL(T.loginUri,n);return i.searchParams.set(`session_id`,r.session_id),i.searchParams.set(`short_app_id`,r.short_app_id),i.searchParams.set(`language`,r.language),h(e,await k(i,302,e))}catch(t){return h(e,await A(n,t,e))}}async function G(e){let t=await C.toRequest(e),n=new URL(t.url).origin;try{let t=await R(new URL(T.postLogoutRedirectUri,n),e);return h(e,await k(t,302,e))}catch(t){return h(e,await A(n,t,e))}}async function K(e){if(typeof T.storage.deleteByLogoutToken!=`function`)return new Response(`Back-channel logout requires a storage with deleteByLogoutToken`,{status:501});let t=await C.toRequest(e),n;try{if((t.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`))n=(await t.formData()).get(`logout_token`);else return new Response(`Invalid content type: expected application/x-www-form-urlencoded`,{status:400})}catch{return new Response(`Failed to parse request body`,{status:400})}if(!n)return new Response(`Missing logout_token`,{status:400});let i=r();for(let[e,t]of D)t<=i&&D.delete(e);if(D.has(n))return new Response(`Invalid logout_token: token already used`,{status:400});D.set(n,i+120);let a,o;try{o=await d(T),a=await m({token:n,jwksUri:o.jwks_uri,options:T})}catch(e){return new Response(`Invalid logout_token: ${e.message}`,{status:400})}if(a.iss!==o.issuer)return new Response(`Invalid logout_token: invalid iss claim`,{status:400});if(Array.isArray(a.aud)?!a.aud.includes(T.clientId):a.aud!==T.clientId)return new Response(`Invalid logout_token: invalid aud claim`,{status:400});if(typeof a.iat!=`number`||Math.abs(i-a.iat)>120)return new Response(`Invalid logout_token: invalid or stale iat claim`,{status:400});if(!a.jti)return new Response(`Invalid logout_token: missing jti claim`,{status:400});if(a.nonce!==void 0)return new Response(`Invalid logout_token: nonce claim must not be present`,{status:400});if(!a.events||!(`http://schemas.openid.net/event/backchannel-logout`in a.events))return new Response(`Invalid logout_token: missing ${x} in events`,{status:400});if(!a.sid&&!a.sub)return new Response(`Invalid logout_token: must contain sid or sub claim`,{status:400});let s={};a.sid&&(s.sid=a.sid),a.sub&&(s.sub=a.sub);try{await T.storage.deleteByLogoutToken(s)}catch(e){return new Response(`Failed to delete session: ${e.message}`,{status:500})}return new Response(null,{status:200})}async function q(e){let t=await C.toRequest(e),n=new URL(t.url);return t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/login`?z(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/register`?B(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/callback`?V(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/refresh`?H(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/revoke`?U(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/entry`?W(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/logout`?G(e):t.method===`POST`&&n.pathname===`${T.authUrlPrefix}/backchannel-logout`?K(e):null}return O(),{get options(){return T},getSession:j,updateSession:M,refreshSession:P,revokeSession:F,getEntrySession:I,completeLogin:L,logout:R,handleLogin:z,handleRegister:B,handleCallback:V,handleRefresh:H,handleRevoke:U,handleEntry:W,handleLogout:G,handleBackChannelLogout:K,handler:q}}export{D as BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS,w as COOKIE_CHUNK_SIZE,C as COOKIE_CONTEXT,T as DISALLOWED_PROXY_HEADERS,E as RETURN_TO_COOKIE,O as createBaseServerSDK};
2
+ //# sourceMappingURL=base.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.mjs","names":[],"sources":["../../src/server/base.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\nimport type { SessionData, LogoutTokenClaims } from '../types/oidc';\nimport type { BaseServerSDK, ServerAdapter, ServerStorage, ServerSDKInitConfig } from '../types/server';\nimport {\n\tbuildEndSessionUrl,\n\tbuildAuthorizationUrl,\n\trevokeToken,\n\trefreshToken,\n\texchangeCode,\n\tverifyJwt,\n\tfetchFlowEntry,\n\tgetDiscoveryDocument,\n} from '../utils/oidc';\nimport { loadSession, serializeSession } from '../utils/session';\nimport { parseState } from '../utils/state';\nimport { timestamp } from '../utils/common';\nimport { ConfigurationError, OidcError, ProtocolError, type FailureCategory } from '../utils/errors';\nimport {\n\tpushSetCookie,\n\tflushSetCookies,\n\tparseCookieHeader,\n\tserializeCookie,\n\tproxyResponse,\n\ttoSafeRedirect,\n\tgetServerSDKOptions,\n\tBACKCHANNEL_LOGOUT_EVENT,\n} from '../utils/server';\n\nexport const COOKIE_CONTEXT = 'strivacity-session-v1';\nexport const COOKIE_CHUNK_SIZE = 3900;\nexport const DISALLOWED_PROXY_HEADERS = new Set(['transfer-encoding', 'connection', 'keep-alive', 'content-encoding']);\nexport const RETURN_TO_COOKIE = 'sty.returnTo';\nexport const BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS = 120;\n\n/**\n * Creates the framework-agnostic Strivacity base server SDK.\n *\n * @param {ServerAdapter<TEvent>} adapter - The framework adapter converting `TEvent` to a standard `Request`.\n * @param {ServerSDKOptions<TEvent, Storage, StateStorage>} initConfig - The initial configuration for the server SDK.\n * @returns {BaseServerSDK<TEvent>} The initialized, framework-agnostic server SDK core.\n */\nexport function createBaseServerSDK<\n\tTEvent = unknown,\n\tStorage extends ServerStorage<TEvent> = ServerStorage<TEvent>,\n\tStateStorage extends SDKStorage = SDKStorage,\n>(adapter: ServerAdapter<TEvent>, initConfig: ServerSDKInitConfig<TEvent, Storage, StateStorage>): BaseServerSDK<TEvent> {\n\tconst options = getServerSDKOptions(adapter, initConfig);\n\tconst seenLogoutTokenIds = new Map<string, number>();\n\n\tfunction init() {\n\t\tif (!options.issuer) {\n\t\t\tconst error = new ConfigurationError('Missing option: issuer');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.clientId) {\n\t\t\tconst error = new ConfigurationError('Missing option: clientId');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.redirectUri) {\n\t\t\tconst error = new ConfigurationError('Missing option: redirectUri');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (options.scopes && !Array.isArray(options.scopes)) {\n\t\t\tconst error = new ConfigurationError('Invalid option: scopes');\n\t\t\toptions.logging?.error('Invalid option provided', error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function redirect(url: string | URL, status = 302, event?: TEvent): Promise<Response> {\n\t\tif (adapter.redirect) {\n\t\t\treturn await adapter.redirect(url, status, event);\n\t\t}\n\n\t\treturn new Response(null, { status, headers: { location: url.toString() } });\n\t}\n\n\tasync function errorRedirect(origin: string, error: unknown, event?: TEvent): Promise<Response> {\n\t\tconst url = new URL('/error', origin);\n\n\t\tif (error instanceof OidcError) {\n\t\t\turl.searchParams.set('type', error.category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.error);\n\t\t\tif (error.errorDescription) {\n\t\t\t\turl.searchParams.set('error_description', error.errorDescription);\n\t\t\t}\n\t\t} else if (error instanceof Error && 'category' in error) {\n\t\t\turl.searchParams.set('type', (error as { category: FailureCategory }).category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.name);\n\t\t\turl.searchParams.set('error_description', error.message);\n\t\t} else {\n\t\t\turl.searchParams.set('type', 'unknown');\n\t\t\turl.searchParams.set('error', 'unknown_error');\n\t\t\turl.searchParams.set('error_description', error instanceof Error ? error.message : 'Unknown error');\n\t\t}\n\n\t\treturn redirect(url, 302, event);\n\t}\n\n\tasync function getSession(event?: TEvent): Promise<SessionData | null> {\n\t\treturn loadSession(await options.storage.get(options.storageTokenName, event));\n\t}\n\n\tasync function updateSession(session: SessionData, event?: TEvent): Promise<void> {\n\t\tawait options.storage.set(options.storageTokenName, serializeSession(session), event);\n\t}\n\n\tasync function cleanupSession(event?: TEvent): Promise<void> {\n\t\tawait options.storage.delete(options.storageTokenName, event);\n\t}\n\n\tasync function refreshSession(event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Attempting to refresh session');\n\n\t\tconst currentSession = await getSession(event);\n\n\t\tif (!currentSession) {\n\t\t\tthrow new ProtocolError('No session available to refresh');\n\t\t}\n\n\t\tif (typeof currentSession.refresh_token !== 'string') {\n\t\t\tthrow new ConfigurationError('No refresh token available');\n\t\t}\n\n\t\ttry {\n\t\t\tconst newSession = await refreshToken({ refreshToken: currentSession.refresh_token, options, expectedSub: currentSession.claims?.sub });\n\t\t\tawait updateSession(newSession, event);\n\n\t\t\toptions.logging?.debug('Session refresh successful');\n\n\t\t\treturn newSession;\n\t\t} catch (error) {\n\t\t\tawait cleanupSession(event);\n\t\t\toptions.logging?.error('Session refresh failed', error as Error);\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function revokeSession(event?: TEvent): Promise<void> {\n\t\tconst currentSession = await getSession(event);\n\n\t\tif (currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Attempting to revoke refresh token');\n\t\t} else {\n\t\t\toptions.logging?.debug('Attempting to revoke access token');\n\t\t}\n\n\t\t// NOTE: Cleanup session before revocation\n\t\tawait cleanupSession(event);\n\n\t\tif (!currentSession?.access_token && !currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Revoke called without session');\n\t\t\treturn;\n\t\t}\n\n\t\tconst tokenTypeHint = currentSession.refresh_token ? 'refresh_token' : 'access_token';\n\t\tconst token = (tokenTypeHint === 'refresh_token' ? currentSession.refresh_token : currentSession.access_token)!;\n\n\t\ttry {\n\t\t\tawait revokeToken({ tokenTypeHint, token, options });\n\n\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\toptions.logging?.info('Refresh token successfully revoked');\n\t\t\t} else {\n\t\t\t\toptions.logging?.info('Access token successfully revoked');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token revocation failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function getEntrySession(entryUrl: string | URL): Promise<Record<string, string>> {\n\t\toptions.logging?.debug('Attempting entry request');\n\n\t\tconst { searchParams: params } = new URL(entryUrl);\n\n\t\ttry {\n\t\t\tconst url = new URL('/provider/flow/entry', options.issuer);\n\t\t\tconst data = await fetchFlowEntry({\n\t\t\t\turl,\n\t\t\t\tparams,\n\t\t\t\tsdkMode: options.mode === 'embedded' ? 'web-embedded' : 'web',\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\toptions.logging?.debug(`Entry request successful - ${JSON.stringify(data)}`);\n\n\t\t\treturn data;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Entry request failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function completeLogin(params: Record<string, string>, event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Exchanging authorization code for tokens');\n\n\t\ttry {\n\t\t\tconst session = await exchangeCode({ params, options });\n\n\t\t\tif (!session.access_token) {\n\t\t\t\tthrow new ProtocolError('Missing access_token');\n\t\t\t}\n\n\t\t\tawait updateSession(session, event);\n\n\t\t\toptions.logging?.debug('Token exchange successful');\n\n\t\t\tif (options.logging) {\n\t\t\t\toptions.logging.xEventId = undefined;\n\t\t\t\toptions.logging.info('Login successful');\n\t\t\t}\n\n\t\t\treturn session;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token exchange failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function logout(postLogoutRedirectUri: string | URL, event?: TEvent): Promise<URL> {\n\t\toptions.logging?.debug('Attempting to logout');\n\n\t\t// NOTE: Cleanup session before logout\n\t\tconst currentSession = await getSession(event);\n\t\tawait cleanupSession(event);\n\n\t\toptions.logging?.debug('Logout initiated');\n\n\t\tif (!currentSession?.id_token) {\n\t\t\toptions.logging?.debug('Logout called without id token');\n\t\t\treturn new URL(postLogoutRedirectUri);\n\t\t}\n\n\t\tconst metadata = await getDiscoveryDocument(options);\n\n\t\treturn buildEndSessionUrl({\n\t\t\turl: metadata.end_session_endpoint,\n\t\t\tidToken: currentSession.id_token,\n\t\t\tpostLogoutRedirectUri: new URL(postLogoutRedirectUri).toString(),\n\t\t});\n\t}\n\n\tasync function handleLogin(event: TEvent, extraParams: Record<string, unknown> = {}): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst { returnTo, ...params } = Object.fromEntries(requestUrl.searchParams);\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, requestUrl.origin);\n\t\tconst url = await buildAuthorizationUrl({ params: { ...params, ...extraParams }, options });\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\tif (['embedded', 'native'].includes(options.mode) && params.sdk) {\n\t\t\turl.searchParams.set('sdk', params.sdk);\n\t\t}\n\n\t\tconst startResponse = await options.httpClient.request<string>(url, {\n\t\t\tmethod: 'GET',\n\t\t\tcredentials: 'include',\n\t\t\tredirect: 'manual',\n\t\t});\n\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tif (safeReturnTo) {\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, safeReturnTo));\n\t\t}\n\n\t\treturn flushSetCookies(event, proxyResponse(startResponse));\n\t}\n\n\tasync function handleRegister(event: TEvent): Promise<Response> {\n\t\treturn handleLogin(event, { prompt: 'create' });\n\t}\n\n\tasync function handleCallback(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst params = Object.fromEntries(requestUrl.searchParams);\n\n\t\ttry {\n\t\t\tconst serializedState = await options.stateStorage.get(`sty.${params.state}`);\n\n\t\t\tif (!serializedState) {\n\t\t\t\tthrow new ProtocolError('State not found or expired. Please try logging in again.');\n\t\t\t}\n\n\t\t\tawait completeLogin(params, event);\n\n\t\t\tconst state = parseState(serializedState);\n\t\t\tconst returnTo = parseCookieHeader(request.headers.get('cookie'))[RETURN_TO_COOKIE] ?? options.postLoginRedirectUri;\n\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, '', { expires: new Date(0) }));\n\n\t\t\tif (state.metadata?.display === 'popup') {\n\t\t\t\t// NOTE: If the login was initiated from a popup, we return a HTML page that will close the popup and notify the opener window.\n\t\t\t\treturn flushSetCookies(\n\t\t\t\t\tevent,\n\t\t\t\t\tnew Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();</script></body></html>`, {\n\t\t\t\t\t\theaders: { 'content-type': 'text/html; charset=utf-8' },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(returnTo, requestUrl.origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(requestUrl.origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRefresh(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst origin = requestUrl.origin;\n\t\tconst returnTo = requestUrl.searchParams.get('returnTo');\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, origin);\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\ttry {\n\t\t\tawait refreshSession(event);\n\n\t\t\tif (safeReturnTo) {\n\t\t\t\treturn flushSetCookies(event, await redirect(new URL(safeReturnTo, origin), 302, event));\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, new Response(null, { status: 204 }));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRevoke(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tawait revokeSession(event);\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(options.postLogoutRedirectUri, origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleEntry(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst data = await getEntrySession(request.url);\n\t\t\tconst uri = new URL(options.loginUri, origin);\n\t\t\turi.searchParams.set('session_id', data.session_id);\n\t\t\turi.searchParams.set('short_app_id', data.short_app_id);\n\t\t\turi.searchParams.set('language', data.language);\n\n\t\t\treturn flushSetCookies(event, await redirect(uri, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleLogout(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst logoutUrl = await logout(new URL(options.postLogoutRedirectUri, origin), event);\n\t\t\treturn flushSetCookies(event, await redirect(logoutUrl, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleBackChannelLogout(event: TEvent): Promise<Response> {\n\t\tif (typeof options.storage.deleteByLogoutToken !== 'function') {\n\t\t\treturn new Response('Back-channel logout requires a storage with deleteByLogoutToken', { status: 501 });\n\t\t}\n\n\t\tconst request = await adapter.toRequest(event);\n\t\tlet logoutToken: string | null;\n\n\t\ttry {\n\t\t\tconst contentType = request.headers.get('content-type') ?? '';\n\n\t\t\tif (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\tconst body = await request.formData();\n\t\t\t\tlogoutToken = body.get('logout_token') as string | null;\n\t\t\t} else {\n\t\t\t\treturn new Response('Invalid content type: expected application/x-www-form-urlencoded', { status: 400 });\n\t\t\t}\n\t\t} catch {\n\t\t\treturn new Response('Failed to parse request body', { status: 400 });\n\t\t}\n\n\t\tif (!logoutToken) {\n\t\t\treturn new Response('Missing logout_token', { status: 400 });\n\t\t}\n\n\t\tconst now = timestamp();\n\n\t\tfor (const [token, expiresAt] of seenLogoutTokenIds) {\n\t\t\tif (expiresAt <= now) {\n\t\t\t\tseenLogoutTokenIds.delete(token);\n\t\t\t}\n\t\t}\n\n\t\tif (seenLogoutTokenIds.has(logoutToken)) {\n\t\t\treturn new Response('Invalid logout_token: token already used', { status: 400 });\n\t\t}\n\n\t\tseenLogoutTokenIds.set(logoutToken, now + BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS);\n\n\t\tlet claims;\n\t\tlet metadata;\n\n\t\ttry {\n\t\t\tmetadata = await getDiscoveryDocument(options);\n\t\t\tclaims = await verifyJwt<LogoutTokenClaims>({ token: logoutToken, jwksUri: metadata.jwks_uri, options });\n\t\t} catch (error) {\n\t\t\treturn new Response(`Invalid logout_token: ${error.message}`, { status: 400 });\n\t\t}\n\n\t\tif (claims.iss !== metadata.issuer) {\n\t\t\treturn new Response('Invalid logout_token: invalid iss claim', { status: 400 });\n\t\t}\n\n\t\tif (Array.isArray(claims.aud) ? !claims.aud.includes(options.clientId) : claims.aud !== options.clientId) {\n\t\t\treturn new Response('Invalid logout_token: invalid aud claim', { status: 400 });\n\t\t}\n\n\t\tif (typeof claims.iat !== 'number' || Math.abs(now - claims.iat) > BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS) {\n\t\t\treturn new Response('Invalid logout_token: invalid or stale iat claim', { status: 400 });\n\t\t}\n\n\t\tif (!claims.jti) {\n\t\t\treturn new Response('Invalid logout_token: missing jti claim', { status: 400 });\n\t\t}\n\n\t\tif (claims.nonce !== undefined) {\n\t\t\treturn new Response('Invalid logout_token: nonce claim must not be present', { status: 400 });\n\t\t}\n\n\t\tif (!claims.events || !(BACKCHANNEL_LOGOUT_EVENT in claims.events)) {\n\t\t\treturn new Response(`Invalid logout_token: missing ${BACKCHANNEL_LOGOUT_EVENT} in events`, { status: 400 });\n\t\t}\n\n\t\tif (!claims.sid && !claims.sub) {\n\t\t\treturn new Response('Invalid logout_token: must contain sid or sub claim', { status: 400 });\n\t\t}\n\n\t\tconst token: LogoutTokenClaims = {} as never;\n\n\t\tif (claims.sid) {\n\t\t\ttoken.sid = claims.sid;\n\t\t}\n\t\tif (claims.sub) {\n\t\t\ttoken.sub = claims.sub;\n\t\t}\n\n\t\ttry {\n\t\t\tawait options.storage.deleteByLogoutToken(token);\n\t\t} catch (error) {\n\t\t\treturn new Response(`Failed to delete session: ${error.message}`, { status: 500 });\n\t\t}\n\n\t\treturn new Response(null, { status: 200 });\n\t}\n\n\tasync function handler(event: TEvent): Promise<Response | null> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/login`) {\n\t\t\treturn handleLogin(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/register`) {\n\t\t\treturn handleRegister(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/callback`) {\n\t\t\treturn handleCallback(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/refresh`) {\n\t\t\treturn handleRefresh(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/revoke`) {\n\t\t\treturn handleRevoke(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/entry`) {\n\t\t\treturn handleEntry(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/logout`) {\n\t\t\treturn handleLogout(event);\n\t\t}\n\t\tif (request.method === 'POST' && requestUrl.pathname === `${options.authUrlPrefix}/backchannel-logout`) {\n\t\t\treturn handleBackChannelLogout(event);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// endregion\n\n\tinit();\n\n\treturn {\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tgetSession,\n\t\tupdateSession,\n\t\trefreshSession,\n\t\trevokeSession,\n\t\tgetEntrySession,\n\t\tcompleteLogin,\n\t\tlogout,\n\t\thandleLogin,\n\t\thandleRegister,\n\t\thandleCallback,\n\t\thandleRefresh,\n\t\thandleRevoke,\n\t\thandleEntry,\n\t\thandleLogout,\n\t\thandleBackChannelLogout,\n\t\thandler,\n\t};\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./base.cjs");exports.BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS=e.BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS,exports.COOKIE_CHUNK_SIZE=e.COOKIE_CHUNK_SIZE,exports.COOKIE_CONTEXT=e.COOKIE_CONTEXT,exports.DISALLOWED_PROXY_HEADERS=e.DISALLOWED_PROXY_HEADERS,exports.RETURN_TO_COOKIE=e.RETURN_TO_COOKIE,exports.createBaseServerSDK=e.createBaseServerSDK;
@@ -0,0 +1 @@
1
+ export * from './base';
@@ -0,0 +1 @@
1
+ import{BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS as e,COOKIE_CHUNK_SIZE as t,COOKIE_CONTEXT as n,DISALLOWED_PROXY_HEADERS as r,RETURN_TO_COOKIE as i,createBaseServerSDK as a}from"./base.mjs";export{e as BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS,t as COOKIE_CHUNK_SIZE,n as COOKIE_CONTEXT,r as DISALLOWED_PROXY_HEADERS,i as RETURN_TO_COOKIE,a as createBaseServerSDK};
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`strivacity-sdk`,t=`https://sdk.strivacity/`;function n(n=e){function r(e){return t+encodeURIComponent(e)}async function i(){return globalThis.caches.open(n)}return{get:async e=>{let t=await(await i()).match(r(e));return t?t.text():null},set:async(e,t)=>{await(await i()).put(r(e),new Response(t,{status:200}))},delete:async e=>{await(await i()).delete(r(e))}}}exports.createCacheAPIStorage=n;
2
+ //# sourceMappingURL=cache.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.cjs","names":[],"sources":["../../src/storages/cache.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\n\nconst DEFAULT_CACHE_NAME = 'strivacity-sdk';\nconst DUMMY_BASE_URL = 'https://sdk.strivacity/';\n\n/**\n * Creates a storage adapter that uses the browser's `Cache` API (`caches`).\n * Works in both the main thread and in Service Workers.\n *\n * Values are stored as synthetic `Response` objects keyed by a fake URL derived from the storage key.\n *\n * @param {string} [cacheName='sdk-storage'] - The name of the cache bucket to use.\n * @returns {SDKStorage} An object implementing the SDKStorage interface.\n */\nexport function createCacheAPIStorage(cacheName = DEFAULT_CACHE_NAME): SDKStorage {\n\tfunction keyToUrl(key: string): string {\n\t\treturn DUMMY_BASE_URL + encodeURIComponent(key);\n\t}\n\n\tasync function getCache(): Promise<Cache> {\n\t\treturn globalThis.caches.open(cacheName);\n\t}\n\n\treturn {\n\t\tget: async (key) => {\n\t\t\tconst cache = await getCache();\n\t\t\tconst response = await cache.match(keyToUrl(key));\n\n\t\t\tif (!response) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn response.text();\n\t\t},\n\t\tset: async (key, value) => {\n\t\t\tconst cache = await getCache();\n\n\t\t\tawait cache.put(keyToUrl(key), new Response(value, { status: 200 }));\n\t\t},\n\t\tdelete: async (key) => {\n\t\t\tconst cache = await getCache();\n\n\t\t\tawait cache.delete(keyToUrl(key));\n\t\t},\n\t};\n}\n"],"mappings":"mEAEA,IAAM,EAAqB,iBACrB,EAAiB,0BAWvB,SAAgB,EAAsB,EAAY,EAAgC,CACjF,SAAS,EAAS,EAAqB,CACtC,OAAO,EAAiB,mBAAmB,CAAG,CAC/C,CAEA,eAAe,GAA2B,CACzC,OAAO,WAAW,OAAO,KAAK,CAAS,CACxC,CAEA,MAAO,CACN,IAAK,KAAO,IAAQ,CAEnB,IAAM,EAAW,MAAM,MADH,EAAS,EAAA,CACA,MAAM,EAAS,CAAG,CAAC,EAMhD,OAJK,EAIE,EAAS,KAAK,EAHb,IAIT,EACA,IAAK,MAAO,EAAK,IAAU,CAG1B,MAAM,MAFc,EAAS,EAAA,CAEjB,IAAI,EAAS,CAAG,EAAG,IAAI,SAAS,EAAO,CAAE,OAAQ,GAAI,CAAC,CAAC,CACpE,EACA,OAAQ,KAAO,IAAQ,CAGtB,MAAM,MAFc,EAAS,EAAA,CAEjB,OAAO,EAAS,CAAG,CAAC,CACjC,CACD,CACD"}
@@ -0,0 +1,11 @@
1
+ import { SDKStorage } from '../types/common';
2
+ /**
3
+ * Creates a storage adapter that uses the browser's `Cache` API (`caches`).
4
+ * Works in both the main thread and in Service Workers.
5
+ *
6
+ * Values are stored as synthetic `Response` objects keyed by a fake URL derived from the storage key.
7
+ *
8
+ * @param {string} [cacheName='sdk-storage'] - The name of the cache bucket to use.
9
+ * @returns {SDKStorage} An object implementing the SDKStorage interface.
10
+ */
11
+ export declare function createCacheAPIStorage(cacheName?: string): SDKStorage;
@@ -0,0 +1,2 @@
1
+ function e(e=`strivacity-sdk`){function t(e){return`https://sdk.strivacity/`+encodeURIComponent(e)}async function n(){return globalThis.caches.open(e)}return{get:async e=>{let r=await(await n()).match(t(e));return r?r.text():null},set:async(e,r)=>{await(await n()).put(t(e),new Response(r,{status:200}))},delete:async e=>{await(await n()).delete(t(e))}}}export{e as createCacheAPIStorage};
2
+ //# sourceMappingURL=cache.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.mjs","names":[],"sources":["../../src/storages/cache.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\n\nconst DEFAULT_CACHE_NAME = 'strivacity-sdk';\nconst DUMMY_BASE_URL = 'https://sdk.strivacity/';\n\n/**\n * Creates a storage adapter that uses the browser's `Cache` API (`caches`).\n * Works in both the main thread and in Service Workers.\n *\n * Values are stored as synthetic `Response` objects keyed by a fake URL derived from the storage key.\n *\n * @param {string} [cacheName='sdk-storage'] - The name of the cache bucket to use.\n * @returns {SDKStorage} An object implementing the SDKStorage interface.\n */\nexport function createCacheAPIStorage(cacheName = DEFAULT_CACHE_NAME): SDKStorage {\n\tfunction keyToUrl(key: string): string {\n\t\treturn DUMMY_BASE_URL + encodeURIComponent(key);\n\t}\n\n\tasync function getCache(): Promise<Cache> {\n\t\treturn globalThis.caches.open(cacheName);\n\t}\n\n\treturn {\n\t\tget: async (key) => {\n\t\t\tconst cache = await getCache();\n\t\t\tconst response = await cache.match(keyToUrl(key));\n\n\t\t\tif (!response) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn response.text();\n\t\t},\n\t\tset: async (key, value) => {\n\t\t\tconst cache = await getCache();\n\n\t\t\tawait cache.put(keyToUrl(key), new Response(value, { status: 200 }));\n\t\t},\n\t\tdelete: async (key) => {\n\t\t\tconst cache = await getCache();\n\n\t\t\tawait cache.delete(keyToUrl(key));\n\t\t},\n\t};\n}\n"],"mappings":"AAcA,SAAgB,EAAsB,EAAY,iBAAgC,CACjF,SAAS,EAAS,EAAqB,CACtC,MAAO,0BAAiB,mBAAmB,CAAG,CAC/C,CAEA,eAAe,GAA2B,CACzC,OAAO,WAAW,OAAO,KAAK,CAAS,CACxC,CAEA,MAAO,CACN,IAAK,KAAO,IAAQ,CAEnB,IAAM,EAAW,MAAM,MADH,EAAS,EAAA,CACA,MAAM,EAAS,CAAG,CAAC,EAMhD,OAJK,EAIE,EAAS,KAAK,EAHb,IAIT,EACA,IAAK,MAAO,EAAK,IAAU,CAG1B,MAAM,MAFc,EAAS,EAAA,CAEjB,IAAI,EAAS,CAAG,EAAG,IAAI,SAAS,EAAO,CAAE,OAAQ,GAAI,CAAC,CAAC,CACpE,EACA,OAAQ,KAAO,IAAQ,CAGtB,MAAM,MAFc,EAAS,EAAA,CAEjB,OAAO,EAAS,CAAG,CAAC,CACjC,CACD,CACD"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./local.cjs"),t=require("./session.cjs"),n=require("../assets/server.cjs"),r=require("./cache.cjs"),i=require("./indexeddb.cjs"),a=require("./memory.cjs"),o=require("./worker.cjs");exports.COOKIE_CHUNK_SIZE=n.f,exports.COOKIE_CONTEXT=n.p,exports.createCacheAPIStorage=r.createCacheAPIStorage,exports.createEncryptedCookieStorage=n.m,exports.createIndexedDBStorage=i.createIndexedDBStorage,exports.createLocalStorage=e.createLocalStorage,exports.createMemoryStorage=a.createMemoryStorage,exports.createServerMemoryStorage=n.h,exports.createServerStateStorage=n.g,exports.createSessionIdCookieStorage=n._,exports.createSessionStorage=t.createSessionStorage,exports.createWorkerStorage=o.createWorkerStorage,exports.handleWorkerStorageRequests=o.handleWorkerStorageRequests;
@@ -0,0 +1,7 @@
1
+ export * from './cache';
2
+ export * from './indexeddb';
3
+ export * from './local';
4
+ export * from './memory';
5
+ export * from './server';
6
+ export * from './session';
7
+ export * from './worker';
@@ -0,0 +1 @@
1
+ import{createLocalStorage as e}from"./local.mjs";import{createSessionStorage as t}from"./session.mjs";import{_ as n,f as r,g as i,h as a,m as o,p as s}from"../assets/server.mjs";import{createCacheAPIStorage as c}from"./cache.mjs";import{createIndexedDBStorage as l}from"./indexeddb.mjs";import{createMemoryStorage as u}from"./memory.mjs";import{createWorkerStorage as d,handleWorkerStorageRequests as f}from"./worker.mjs";export{r as COOKIE_CHUNK_SIZE,s as COOKIE_CONTEXT,c as createCacheAPIStorage,o as createEncryptedCookieStorage,l as createIndexedDBStorage,e as createLocalStorage,u as createMemoryStorage,a as createServerMemoryStorage,i as createServerStateStorage,n as createSessionIdCookieStorage,t as createSessionStorage,d as createWorkerStorage,f as handleWorkerStorageRequests};
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`sdk-storage`,t=`kv`,n=1;function r(e,t){return new Promise((r,i)=>{let a=indexedDB.open(e,n);a.onupgradeneeded=e=>{let n=e.target.result;n.objectStoreNames.contains(t)||n.createObjectStore(t)},a.onsuccess=e=>r(e.target.result),a.onerror=e=>i(e.target.error)})}function i(e,t,n){return e.transaction(t,n).objectStore(t)}function a(n=e,a=t){let o=null;function s(){return o||=r(n,a),o}return{get:async e=>{let t=await s();return new Promise((n,r)=>{let o=i(t,a,`readonly`).get(e);o.onsuccess=e=>n(e.target.result??null),o.onerror=e=>r(e.target.error)})},set:async(e,t)=>{let n=await s();return new Promise((r,o)=>{let s=i(n,a,`readwrite`).put(t,e);s.onsuccess=()=>r(),s.onerror=e=>o(e.target.error)})},delete:async e=>{let t=await s();return new Promise((n,r)=>{let o=i(t,a,`readwrite`).delete(e);o.onsuccess=()=>n(),o.onerror=e=>r(e.target.error)})}}}exports.createIndexedDBStorage=a;
2
+ //# sourceMappingURL=indexeddb.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexeddb.cjs","names":[],"sources":["../../src/storages/indexeddb.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\n\nconst DEFAULT_DB_NAME = 'sdk-storage';\nconst DEFAULT_STORE_NAME = 'kv';\nconst DB_VERSION = 1;\n\nfunction openDB(dbName: string, storeName: string): Promise<IDBDatabase> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst request = indexedDB.open(dbName, DB_VERSION);\n\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst db = (event.target as IDBOpenDBRequest).result;\n\n\t\t\tif (!db.objectStoreNames.contains(storeName)) {\n\t\t\t\tdb.createObjectStore(storeName);\n\t\t\t}\n\t\t};\n\n\t\trequest.onsuccess = (event) => resolve((event.target as IDBOpenDBRequest).result);\n\t\trequest.onerror = (event) => reject((event.target as IDBOpenDBRequest).error);\n\t});\n}\n\nfunction tx(db: IDBDatabase, storeName: string, mode: IDBTransactionMode): IDBObjectStore {\n\treturn db.transaction(storeName, mode).objectStore(storeName);\n}\n\n/**\n * Creates a storage adapter that uses the browser's `IndexedDB` API.\n * Works in both the main thread and in Service Workers.\n *\n * @param {string} [dbName='sdk-storage'] - The name of the IndexedDB database.\n * @param {string} [storeName='kv'] - The name of the object store within the database.\n * @returns {SDKStorage} An object implementing the SDKStorage interface.\n */\nexport function createIndexedDBStorage(dbName = DEFAULT_DB_NAME, storeName = DEFAULT_STORE_NAME): SDKStorage {\n\tlet dbPromise: Promise<IDBDatabase> | null = null;\n\n\tfunction getDB(): Promise<IDBDatabase> {\n\t\tif (!dbPromise) {\n\t\t\tdbPromise = openDB(dbName, storeName);\n\t\t}\n\n\t\treturn dbPromise;\n\t}\n\n\treturn {\n\t\tget: async (key) => {\n\t\t\tconst db = await getDB();\n\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst request = tx(db, storeName, 'readonly').get(key);\n\n\t\t\t\trequest.onsuccess = (event) => resolve((event.target as IDBRequest<string | undefined>).result ?? null);\n\t\t\t\trequest.onerror = (event) => reject((event.target as IDBRequest).error);\n\t\t\t});\n\t\t},\n\t\tset: async (key, value) => {\n\t\t\tconst db = await getDB();\n\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst request = tx(db, storeName, 'readwrite').put(value, key);\n\n\t\t\t\trequest.onsuccess = () => resolve();\n\t\t\t\trequest.onerror = (event) => reject((event.target as IDBRequest).error);\n\t\t\t});\n\t\t},\n\t\tdelete: async (key) => {\n\t\t\tconst db = await getDB();\n\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst request = tx(db, storeName, 'readwrite').delete(key);\n\n\t\t\t\trequest.onsuccess = () => resolve();\n\t\t\t\trequest.onerror = (event) => reject((event.target as IDBRequest).error);\n\t\t\t});\n\t\t},\n\t};\n}\n"],"mappings":"mEAEA,IAAM,EAAkB,cAClB,EAAqB,KACrB,EAAa,EAEnB,SAAS,EAAO,EAAgB,EAAyC,CACxE,OAAO,IAAI,SAAS,EAAS,IAAW,CACvC,IAAM,EAAU,UAAU,KAAK,EAAQ,CAAU,EAEjD,EAAQ,gBAAmB,GAAU,CACpC,IAAM,EAAM,EAAM,OAA4B,OAEzC,EAAG,iBAAiB,SAAS,CAAS,GAC1C,EAAG,kBAAkB,CAAS,CAEhC,EAEA,EAAQ,UAAa,GAAU,EAAS,EAAM,OAA4B,MAAM,EAChF,EAAQ,QAAW,GAAU,EAAQ,EAAM,OAA4B,KAAK,CAC7E,CAAC,CACF,CAEA,SAAS,EAAG,EAAiB,EAAmB,EAA0C,CACzF,OAAO,EAAG,YAAY,EAAW,CAAI,CAAC,CAAC,YAAY,CAAS,CAC7D,CAUA,SAAgB,EAAuB,EAAS,EAAiB,EAAY,EAAgC,CAC5G,IAAI,EAAyC,KAE7C,SAAS,GAA8B,CAKtC,MAJA,CACC,IAAY,EAAO,EAAQ,CAAS,EAG9B,CACR,CAEA,MAAO,CACN,IAAK,KAAO,IAAQ,CACnB,IAAM,EAAK,MAAM,EAAM,EAEvB,OAAO,IAAI,SAAS,EAAS,IAAW,CACvC,IAAM,EAAU,EAAG,EAAI,EAAW,UAAU,CAAC,CAAC,IAAI,CAAG,EAErD,EAAQ,UAAa,GAAU,EAAS,EAAM,OAA0C,QAAU,IAAI,EACtG,EAAQ,QAAW,GAAU,EAAQ,EAAM,OAAsB,KAAK,CACvE,CAAC,CACF,EACA,IAAK,MAAO,EAAK,IAAU,CAC1B,IAAM,EAAK,MAAM,EAAM,EAEvB,OAAO,IAAI,SAAS,EAAS,IAAW,CACvC,IAAM,EAAU,EAAG,EAAI,EAAW,WAAW,CAAC,CAAC,IAAI,EAAO,CAAG,EAE7D,EAAQ,cAAkB,EAAQ,EAClC,EAAQ,QAAW,GAAU,EAAQ,EAAM,OAAsB,KAAK,CACvE,CAAC,CACF,EACA,OAAQ,KAAO,IAAQ,CACtB,IAAM,EAAK,MAAM,EAAM,EAEvB,OAAO,IAAI,SAAS,EAAS,IAAW,CACvC,IAAM,EAAU,EAAG,EAAI,EAAW,WAAW,CAAC,CAAC,OAAO,CAAG,EAEzD,EAAQ,cAAkB,EAAQ,EAClC,EAAQ,QAAW,GAAU,EAAQ,EAAM,OAAsB,KAAK,CACvE,CAAC,CACF,CACD,CACD"}
@@ -0,0 +1,10 @@
1
+ import { SDKStorage } from '../types/common';
2
+ /**
3
+ * Creates a storage adapter that uses the browser's `IndexedDB` API.
4
+ * Works in both the main thread and in Service Workers.
5
+ *
6
+ * @param {string} [dbName='sdk-storage'] - The name of the IndexedDB database.
7
+ * @param {string} [storeName='kv'] - The name of the object store within the database.
8
+ * @returns {SDKStorage} An object implementing the SDKStorage interface.
9
+ */
10
+ export declare function createIndexedDBStorage(dbName?: string, storeName?: string): SDKStorage;
@@ -0,0 +1,2 @@
1
+ function e(e,t){return new Promise((n,r)=>{let i=indexedDB.open(e,1);i.onupgradeneeded=e=>{let n=e.target.result;n.objectStoreNames.contains(t)||n.createObjectStore(t)},i.onsuccess=e=>n(e.target.result),i.onerror=e=>r(e.target.error)})}function t(e,t,n){return e.transaction(t,n).objectStore(t)}function n(n=`sdk-storage`,r=`kv`){let i=null;function a(){return i||=e(n,r),i}return{get:async e=>{let n=await a();return new Promise((i,a)=>{let o=t(n,r,`readonly`).get(e);o.onsuccess=e=>i(e.target.result??null),o.onerror=e=>a(e.target.error)})},set:async(e,n)=>{let i=await a();return new Promise((a,o)=>{let s=t(i,r,`readwrite`).put(n,e);s.onsuccess=()=>a(),s.onerror=e=>o(e.target.error)})},delete:async e=>{let n=await a();return new Promise((i,a)=>{let o=t(n,r,`readwrite`).delete(e);o.onsuccess=()=>i(),o.onerror=e=>a(e.target.error)})}}}export{n as createIndexedDBStorage};
2
+ //# sourceMappingURL=indexeddb.mjs.map