@owlmeans/client-auth 0.1.18-rc.9 → 0.1.18

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 (255) hide show
  1. package/README.md +283 -37
  2. package/agent-meta/manifest.json +50 -4
  3. package/agent-meta/skills/client-auth/SKILL.md +84 -55
  4. package/agent-meta/skills/client-auth/parts/login.md +77 -0
  5. package/agent-meta/skills/client-auth/parts/manager.md +37 -0
  6. package/build/components/dispatcher/component.d.ts.map +1 -1
  7. package/build/components/dispatcher/component.js +26 -6
  8. package/build/components/dispatcher/component.js.map +1 -1
  9. package/build/components/dispatcher/types.local.d.ts +7 -0
  10. package/build/components/dispatcher/types.local.d.ts.map +1 -0
  11. package/build/components/dispatcher/types.local.js +2 -0
  12. package/build/components/dispatcher/types.local.js.map +1 -0
  13. package/build/entrypoints.d.ts +7 -0
  14. package/build/entrypoints.d.ts.map +1 -0
  15. package/build/entrypoints.js +7 -0
  16. package/build/entrypoints.js.map +1 -0
  17. package/build/helper.d.ts +2 -1
  18. package/build/helper.d.ts.map +1 -1
  19. package/build/helper.js +28 -5
  20. package/build/helper.js.map +1 -1
  21. package/build/index.d.ts +1 -1
  22. package/build/index.d.ts.map +1 -1
  23. package/build/index.js +1 -1
  24. package/build/index.js.map +1 -1
  25. package/build/login/adopt/types.d.ts +26 -0
  26. package/build/login/adopt/types.d.ts.map +1 -0
  27. package/build/login/adopt/types.js +2 -0
  28. package/build/login/adopt/types.js.map +1 -0
  29. package/build/login/adopt.d.ts +7 -12
  30. package/build/login/adopt.d.ts.map +1 -1
  31. package/build/login/adopt.js +15 -14
  32. package/build/login/adopt.js.map +1 -1
  33. package/build/login/consts.d.ts +89 -4
  34. package/build/login/consts.d.ts.map +1 -1
  35. package/build/login/consts.js +93 -5
  36. package/build/login/consts.js.map +1 -1
  37. package/build/login/consts.local.d.ts +16 -0
  38. package/build/login/consts.local.d.ts.map +1 -0
  39. package/build/login/consts.local.js +30 -0
  40. package/build/login/consts.local.js.map +1 -0
  41. package/build/login/credit/types.d.ts +7 -0
  42. package/build/login/credit/types.d.ts.map +1 -0
  43. package/build/login/credit/types.js +2 -0
  44. package/build/login/credit/types.js.map +1 -0
  45. package/build/login/credit.d.ts +19 -0
  46. package/build/login/credit.d.ts.map +1 -0
  47. package/build/login/credit.js +58 -0
  48. package/build/login/credit.js.map +1 -0
  49. package/build/login/env/types.d.ts +35 -0
  50. package/build/login/env/types.d.ts.map +1 -0
  51. package/build/login/env/types.js +2 -0
  52. package/build/login/env/types.js.map +1 -0
  53. package/build/login/env.d.ts +5 -29
  54. package/build/login/env.d.ts.map +1 -1
  55. package/build/login/env.js +63 -80
  56. package/build/login/env.js.map +1 -1
  57. package/build/login/flow.d.ts +20 -0
  58. package/build/login/flow.d.ts.map +1 -0
  59. package/build/login/flow.js +39 -0
  60. package/build/login/flow.js.map +1 -0
  61. package/build/login/hook.d.ts +30 -4
  62. package/build/login/hook.d.ts.map +1 -1
  63. package/build/login/hook.js +53 -18
  64. package/build/login/hook.js.map +1 -1
  65. package/build/login/i18n/be.json +41 -0
  66. package/build/login/i18n/de.json +41 -0
  67. package/build/login/i18n/en.json +41 -0
  68. package/build/login/i18n/es.json +41 -0
  69. package/build/login/i18n/fr.json +41 -0
  70. package/build/login/i18n/pl.json +41 -0
  71. package/build/login/i18n/ru.json +41 -0
  72. package/build/login/i18n/uk.json +41 -0
  73. package/build/login/i18n.d.ts +2 -0
  74. package/build/login/i18n.d.ts.map +1 -0
  75. package/build/login/i18n.js +27 -0
  76. package/build/login/i18n.js.map +1 -0
  77. package/build/login/index.d.ts +20 -0
  78. package/build/login/index.d.ts.map +1 -1
  79. package/build/login/index.js +11 -0
  80. package/build/login/index.js.map +1 -1
  81. package/build/login/land/types.d.ts +52 -0
  82. package/build/login/land/types.d.ts.map +1 -0
  83. package/build/login/land/types.js +2 -0
  84. package/build/login/land/types.js.map +1 -0
  85. package/build/login/land.d.ts +6 -0
  86. package/build/login/land.d.ts.map +1 -0
  87. package/build/login/land.js +122 -0
  88. package/build/login/land.js.map +1 -0
  89. package/build/login/methods/types.d.ts +30 -0
  90. package/build/login/methods/types.d.ts.map +1 -0
  91. package/build/login/methods/types.js +2 -0
  92. package/build/login/methods/types.js.map +1 -0
  93. package/build/login/methods.d.ts +7 -0
  94. package/build/login/methods.d.ts.map +1 -0
  95. package/build/login/methods.js +87 -0
  96. package/build/login/methods.js.map +1 -0
  97. package/build/login/resume/types.d.ts +24 -0
  98. package/build/login/resume/types.d.ts.map +1 -0
  99. package/build/login/resume/types.js +2 -0
  100. package/build/login/resume/types.js.map +1 -0
  101. package/build/login/resume.d.ts +9 -0
  102. package/build/login/resume.d.ts.map +1 -0
  103. package/build/login/resume.js +38 -0
  104. package/build/login/resume.js.map +1 -0
  105. package/build/login/screen.d.ts +17 -0
  106. package/build/login/screen.d.ts.map +1 -0
  107. package/build/login/screen.js +66 -0
  108. package/build/login/screen.js.map +1 -0
  109. package/build/login/service.d.ts +6 -5
  110. package/build/login/service.d.ts.map +1 -1
  111. package/build/login/service.js +141 -15
  112. package/build/login/service.js.map +1 -1
  113. package/build/login/start/types.d.ts +29 -0
  114. package/build/login/start/types.d.ts.map +1 -0
  115. package/build/login/start/types.js +2 -0
  116. package/build/login/start/types.js.map +1 -0
  117. package/build/login/start.d.ts +5 -0
  118. package/build/login/start.d.ts.map +1 -0
  119. package/build/login/start.js +36 -0
  120. package/build/login/start.js.map +1 -0
  121. package/build/login/surrogate/types.d.ts +9 -0
  122. package/build/login/surrogate/types.d.ts.map +1 -0
  123. package/build/login/surrogate/types.js +2 -0
  124. package/build/login/surrogate/types.js.map +1 -0
  125. package/build/login/surrogate.d.ts +13 -0
  126. package/build/login/surrogate.d.ts.map +1 -0
  127. package/build/login/surrogate.js +33 -0
  128. package/build/login/surrogate.js.map +1 -0
  129. package/build/login/terms/types.d.ts +112 -0
  130. package/build/login/terms/types.d.ts.map +1 -0
  131. package/build/login/terms/types.js +2 -0
  132. package/build/login/terms/types.js.map +1 -0
  133. package/build/login/terms-config.d.ts +65 -0
  134. package/build/login/terms-config.d.ts.map +1 -0
  135. package/build/login/terms-config.js +2 -0
  136. package/build/login/terms-config.js.map +1 -0
  137. package/build/login/terms.d.ts +21 -0
  138. package/build/login/terms.d.ts.map +1 -0
  139. package/build/login/terms.js +235 -0
  140. package/build/login/terms.js.map +1 -0
  141. package/build/login/types.d.ts +223 -16
  142. package/build/login/types.d.ts.map +1 -1
  143. package/build/login/types.js +1 -16
  144. package/build/login/types.js.map +1 -1
  145. package/build/manager/components/authentication/control.js +3 -3
  146. package/build/manager/components/authentication/control.js.map +1 -1
  147. package/build/manager/components/authentication/types.d.ts +2 -2
  148. package/build/manager/components/authentication/types.d.ts.map +1 -1
  149. package/build/manager/components/tunnel-consumer.js +2 -2
  150. package/build/manager/components/tunnel-consumer.js.map +1 -1
  151. package/build/manager/entrypoints.d.ts +11 -0
  152. package/build/manager/entrypoints.d.ts.map +1 -0
  153. package/build/manager/entrypoints.js +17 -0
  154. package/build/manager/entrypoints.js.map +1 -0
  155. package/build/manager/plugins/basic-ed25519.d.ts.map +1 -1
  156. package/build/manager/plugins/basic-ed25519.js +5 -0
  157. package/build/manager/plugins/basic-ed25519.js.map +1 -1
  158. package/build/manager/plugins/exports.d.ts +3 -0
  159. package/build/manager/plugins/exports.d.ts.map +1 -1
  160. package/build/manager/plugins/exports.js +2 -0
  161. package/build/manager/plugins/exports.js.map +1 -1
  162. package/build/manager/plugins/index.d.ts +2 -5
  163. package/build/manager/plugins/index.d.ts.map +1 -1
  164. package/build/manager/plugins/index.js +9 -1
  165. package/build/manager/plugins/index.js.map +1 -1
  166. package/build/manager/plugins/methods.d.ts +6 -0
  167. package/build/manager/plugins/methods.d.ts.map +1 -0
  168. package/build/manager/plugins/methods.js +65 -0
  169. package/build/manager/plugins/methods.js.map +1 -0
  170. package/build/manager/plugins/re-captcha.d.ts.map +1 -1
  171. package/build/manager/plugins/re-captcha.js +5 -0
  172. package/build/manager/plugins/re-captcha.js.map +1 -1
  173. package/build/manager/plugins/registry/types.d.ts +10 -0
  174. package/build/manager/plugins/registry/types.d.ts.map +1 -0
  175. package/build/manager/plugins/registry/types.js +2 -0
  176. package/build/manager/plugins/registry/types.js.map +1 -0
  177. package/build/manager/plugins/registry.d.ts +20 -0
  178. package/build/manager/plugins/registry.d.ts.map +1 -0
  179. package/build/manager/plugins/registry.js +23 -0
  180. package/build/manager/plugins/registry.js.map +1 -0
  181. package/build/manager/plugins/tunnel-consumer.d.ts.map +1 -1
  182. package/build/manager/plugins/tunnel-consumer.js +10 -3
  183. package/build/manager/plugins/tunnel-consumer.js.map +1 -1
  184. package/build/manager/plugins/types.d.ts +53 -0
  185. package/build/manager/plugins/types.d.ts.map +1 -1
  186. package/build/modules.d.ts.map +1 -1
  187. package/build/service.js +1 -1
  188. package/build/service.js.map +1 -1
  189. package/package.json +33 -30
  190. package/src/components/dispatcher/component.tsx +37 -14
  191. package/src/components/dispatcher/types.local.ts +7 -0
  192. package/src/entrypoints.ts +10 -0
  193. package/src/helper.ts +31 -5
  194. package/src/index.ts +1 -1
  195. package/src/login/adopt/types.ts +25 -0
  196. package/src/login/adopt.ts +21 -14
  197. package/src/login/consts.local.ts +34 -0
  198. package/src/login/consts.ts +105 -5
  199. package/src/login/credit/types.ts +6 -0
  200. package/src/login/credit.ts +69 -0
  201. package/src/login/env/types.ts +35 -0
  202. package/src/login/env.ts +60 -72
  203. package/src/login/flow.ts +44 -0
  204. package/src/login/hook.ts +58 -22
  205. package/src/login/i18n/be.json +41 -0
  206. package/src/login/i18n/de.json +41 -0
  207. package/src/login/i18n/en.json +41 -0
  208. package/src/login/i18n/es.json +41 -0
  209. package/src/login/i18n/fr.json +41 -0
  210. package/src/login/i18n/pl.json +41 -0
  211. package/src/login/i18n/ru.json +41 -0
  212. package/src/login/i18n/uk.json +41 -0
  213. package/src/login/i18n.ts +29 -0
  214. package/src/login/index.ts +21 -0
  215. package/src/login/land/types.ts +54 -0
  216. package/src/login/land.ts +149 -0
  217. package/src/login/methods/types.ts +32 -0
  218. package/src/login/methods.ts +109 -0
  219. package/src/login/resume/types.ts +24 -0
  220. package/src/login/resume.ts +45 -0
  221. package/src/login/screen.tsx +140 -0
  222. package/src/login/service.ts +181 -18
  223. package/src/login/start/types.ts +30 -0
  224. package/src/login/start.ts +44 -0
  225. package/src/login/surrogate/types.ts +9 -0
  226. package/src/login/surrogate.ts +37 -0
  227. package/src/login/terms/types.ts +126 -0
  228. package/src/login/terms-config.ts +55 -0
  229. package/src/login/terms.ts +315 -0
  230. package/src/login/types.ts +233 -17
  231. package/src/manager/README.md +37 -80
  232. package/src/manager/components/authentication/control.ts +3 -3
  233. package/src/manager/components/authentication/types.ts +2 -2
  234. package/src/manager/components/tunnel-consumer.tsx +2 -2
  235. package/src/manager/entrypoints.ts +18 -0
  236. package/src/manager/plugins/basic-ed25519.tsx +7 -0
  237. package/src/manager/plugins/exports.ts +3 -0
  238. package/src/manager/plugins/index.ts +11 -4
  239. package/src/manager/plugins/methods.ts +74 -0
  240. package/src/manager/plugins/re-captcha.tsx +7 -0
  241. package/src/manager/plugins/registry/types.ts +10 -0
  242. package/src/manager/plugins/registry.ts +33 -0
  243. package/src/manager/plugins/tunnel-consumer.tsx +12 -3
  244. package/src/manager/plugins/types.ts +54 -0
  245. package/src/service.ts +1 -1
  246. package/tests/context.ts +1 -2
  247. package/tests/i18n.spec.ts +68 -0
  248. package/tests/land.spec.ts +292 -0
  249. package/tests/login.spec.ts +332 -0
  250. package/tests/target.spec.ts +210 -0
  251. package/tests/terms-deferred.spec.ts +65 -0
  252. package/tests/terms.spec.ts +314 -0
  253. package/build/.gitkeep +0 -0
  254. package/src/manager/modules.ts +0 -18
  255. package/src/modules.ts +0 -13
@@ -2,17 +2,105 @@ export const DEFAULT_ALIAS = 'login-service';
2
2
  export const LOGIN_SERVICE = DEFAULT_ALIAS;
3
3
  /** Priority of a plugin that makes no claim about the environment. */
4
4
  export const DEFAULT_LOGIN_PRIORITY = 0;
5
+ /** Order given to a method that declares none. */
6
+ export const DEFAULT_METHOD_ORDER = 100;
5
7
  /**
6
- * Name given to the surrogate login window, and the marker it records about itself.
8
+ * Name given to the surrogate login window, the marker it records about itself, and the values the
9
+ * two documents exchange.
7
10
  *
8
- * These values are a wire protocol between two documents that may be running different builds —
9
- * an opener holding an older bundle and a surrogate freshly loaded, or the reverse. They are
10
- * therefore fixed, and must never be "tidied" to match a newer vocabulary.
11
+ * These are a wire protocol between two documents that may be running different builds — an opener
12
+ * holding an older bundle and a surrogate freshly loaded, or the reverse. They are therefore fixed,
13
+ * and must never be "tidied" to match a newer vocabulary. That applies to the query names and the
14
+ * message types added later just as much as to the original three.
11
15
  */
12
16
  export const LOGIN_SURROGATE_NAME = 'owlmeans-oidc-login';
13
17
  export const LOGIN_TOKEN_MESSAGE = 'owlmeans:oidc:popup-token';
18
+ export const LOGIN_LOGOUT_MESSAGE = 'owlmeans:oidc:popup-logout';
14
19
  export const LOGIN_SURROGATE_MARKER = '_owlmeans-oidc-popup';
15
- export const LOGIN_SURROGATE_FEATURES = 'popup=yes,width=520,height=760';
20
+ export const LOGIN_SURROGATE_WIDTH = 520;
21
+ export const LOGIN_SURROGATE_HEIGHT = 760;
22
+ /**
23
+ * @deprecated Never centered the window — it carried no `left`/`top`, so the surrogate always
24
+ * opened wherever the browser's own default popup placement put it. Superseded by
25
+ * `@owlmeans/web-client`'s `centeredPopupFeatures(LOGIN_SURROGATE_WIDTH, LOGIN_SURROGATE_HEIGHT)`,
26
+ * computed fresh per call since centering depends on where the browser window currently sits.
27
+ * Kept, unchanged, for the same reason as the rest of this block: an already-generated app may
28
+ * carry a copy of code that still imports it.
29
+ */
30
+ export const LOGIN_SURROGATE_FEATURES = `popup=yes,width=${LOGIN_SURROGATE_WIDTH},height=${LOGIN_SURROGATE_HEIGHT}`;
16
31
  /** How often a surrogate window is checked for having been closed by the user. */
17
32
  export const LOGIN_WATCH_INTERVAL = 500;
33
+ /** Carries WHY the surrogate window was opened across the window boundary. */
34
+ export const LOGIN_INTENT_QUERY = 'intent';
35
+ /**
36
+ * Carries the address the surrogate should run, so the flow parameters the opener's URL held are
37
+ * forwarded rather than discarded.
38
+ */
39
+ export const LOGIN_NEXT_QUERY = 'next';
40
+ /**
41
+ * Carries the method the user already chose, one window up.
42
+ *
43
+ * A surrogate acting on it is not an auto-redirect in the "never choose for the user" sense: the
44
+ * choice was made, by a person, in the document that opened this one.
45
+ */
46
+ export const LOGIN_METHOD_QUERY = 'method';
47
+ /** Where a browser records that it agreed to one exact set of legal documents. */
48
+ export const LOGIN_TERMS_STORAGE = '_owlmeans-login-terms';
49
+ /**
50
+ * Bound on a single step's `pending` check, or a landing hook's `landed` call.
51
+ *
52
+ * A step/hook that hangs must never HANG sign-in itself — both `continueLogin` and
53
+ * `landAfterLogin` treat a timeout exactly like a rejection, resolving within this budget either
54
+ * way. What that resolves TO is fail-open ("not pending") for an ordinary step, and fail-closed
55
+ * ("pending") for one that declared itself `required` — see `continueLogin`'s `onBroken`.
56
+ */
57
+ export const LOGIN_STEP_TIMEOUT = 5_000;
58
+ /** Where a browser records the last token a landing hook has already run for. */
59
+ export const LOGIN_LANDED_STORAGE = '_owlmeans-login-landed';
60
+ /** What a dispatcher does once `login().resume(...)` has answered. */
61
+ export var ResumeAction;
62
+ (function (ResumeAction) {
63
+ /** The plugin took it over — the browser is leaving, or the window is closing. */
64
+ ResumeAction["Stop"] = "stop";
65
+ /** Render the outcome to the user; there is nothing further to do automatically. */
66
+ ResumeAction["Render"] = "render";
67
+ /** Ordinary tab: keep the session and carry on to the application. */
68
+ ResumeAction["Navigate"] = "navigate";
69
+ })(ResumeAction || (ResumeAction = {}));
70
+ /** What a stage did, and therefore what the caller must do next. */
71
+ export var LoginOutcome;
72
+ (function (LoginOutcome) {
73
+ /** The plugin took the flow over and it is finished. The caller does nothing more. */
74
+ LoginOutcome["Handled"] = "handled";
75
+ /** The plugin did nothing — the caller carries on with its ordinary continuation. */
76
+ LoginOutcome["Passed"] = "passed";
77
+ /** The browser is leaving this document. The caller must not navigate or render. */
78
+ LoginOutcome["Redirected"] = "redirected";
79
+ /** Cannot proceed without a fresh user gesture — the caller renders a sign-in control. */
80
+ LoginOutcome["Gesture"] = "gesture";
81
+ /** Authenticated, but with no channel back to the window that started it. */
82
+ LoginOutcome["Orphaned"] = "orphaned";
83
+ /** The attempt ended with no token (the user closed the window, or the provider refused it). */
84
+ LoginOutcome["Failed"] = "failed";
85
+ /**
86
+ * A window this flow needed could not be opened at all — `window.open` returned `null`, which is
87
+ * the browser's own popup blocker, not a flow failure. Distinct from {@link Failed}: a caller
88
+ * with nowhere inline to render (a header "Log in"/"Log out" control, not the sign-in screen)
89
+ * needs to know specifically that a fresh click reopening the SAME control will not help, and
90
+ * that the browser is already showing its own blocked-popup affordance somewhere.
91
+ */
92
+ LoginOutcome["Blocked"] = "blocked";
93
+ })(LoginOutcome || (LoginOutcome = {}));
94
+ /** Why a surrogate window was opened. */
95
+ export var LoginIntent;
96
+ (function (LoginIntent) {
97
+ LoginIntent["Login"] = "login";
98
+ LoginIntent["Logout"] = "logout";
99
+ })(LoginIntent || (LoginIntent = {}));
100
+ /**
101
+ * How long a sign-in aimed at a screen (`LoginRequest.target`) keeps that screen parked: long
102
+ * enough for a sign-in with an emailed code, short enough that a tab abandoned mid-way never lands
103
+ * a later, unrelated sign-in on it.
104
+ */
105
+ export const LOGIN_TARGET_TTL = 30 * 60 * 1000;
18
106
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/login/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAA;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAA;AAE1C,sEAAsE;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAA;AAEvC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,qBAAqB,CAAA;AAEzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,2BAA2B,CAAA;AAE9D,MAAM,CAAC,MAAM,sBAAsB,GAAG,sBAAsB,CAAA;AAE5D,MAAM,CAAC,MAAM,wBAAwB,GAAG,gCAAgC,CAAA;AAExE,kFAAkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/login/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAA;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAA;AAE1C,sEAAsE;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAA;AAEvC,kDAAkD;AAClD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAEvC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,qBAAqB,CAAA;AAEzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,2BAA2B,CAAA;AAE9D,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAA4B,CAAA;AAEhE,MAAM,CAAC,MAAM,sBAAsB,GAAG,sBAAsB,CAAA;AAE5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AAExC,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAA;AAEzC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GACnC,mBAAmB,qBAAqB,WAAW,sBAAsB,EAAE,CAAA;AAE7E,kFAAkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAA;AAEvC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAA;AAE1C;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAA;AAE1C,kFAAkF;AAClF,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAA;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAEvC,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAA;AAE5D,sEAAsE;AACtE,MAAM,CAAN,IAAY,YAOX;AAPD,WAAY,YAAY;IACtB,kFAAkF;IAClF,6BAAa,CAAA;IACb,oFAAoF;IACpF,iCAAiB,CAAA;IACjB,sEAAsE;IACtE,qCAAqB,CAAA;AACvB,CAAC,EAPW,YAAY,KAAZ,YAAY,QAOvB;AAED,oEAAoE;AACpE,MAAM,CAAN,IAAY,YAqBX;AArBD,WAAY,YAAY;IACtB,sFAAsF;IACtF,mCAAmB,CAAA;IACnB,qFAAqF;IACrF,iCAAiB,CAAA;IACjB,oFAAoF;IACpF,yCAAyB,CAAA;IACzB,0FAA0F;IAC1F,mCAAmB,CAAA;IACnB,6EAA6E;IAC7E,qCAAqB,CAAA;IACrB,gGAAgG;IAChG,iCAAiB,CAAA;IACjB;;;;;;OAMG;IACH,mCAAmB,CAAA;AACrB,CAAC,EArBW,YAAY,KAAZ,YAAY,QAqBvB;AAED,yCAAyC;AACzC,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,8BAAe,CAAA;IACf,gCAAiB,CAAA;AACnB,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { LoginOutcome } from './consts.js';
2
+ import type { CSSProperties } from 'react';
3
+ /**
4
+ * The page the card sits in.
5
+ *
6
+ * It carries its own viewport height because this screen is rendered straight out of the
7
+ * dispatcher, into whatever the application happens to have around it — which is usually nothing
8
+ * with a height, so a percentage minimum would resolve to zero and leave the card at the top.
9
+ */
10
+ export declare const page: CSSProperties;
11
+ export declare const box: CSSProperties;
12
+ /** The same English fallback a document's `i18nKey` translates to when nothing else names it. */
13
+ export declare const DEFAULT_LABEL: Record<string, string>;
14
+ /** Outcomes after which nobody was signed in, so a screen parked for the landing must not wait. */
15
+ export declare const UNSIGNED_OUTCOMES: ReadonlySet<LoginOutcome>;
16
+ //# sourceMappingURL=consts.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../../src/login/consts.local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,EAAE,aAIlB,CAAA;AAGD,eAAO,MAAM,GAAG,EAAE,aAEjB,CAAA;AAED,iGAAiG;AACjG,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMhD,CAAA;AAED,mGAAmG;AACnG,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAEtD,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { LoginOutcome } from './consts.js';
2
+ /**
3
+ * The page the card sits in.
4
+ *
5
+ * It carries its own viewport height because this screen is rendered straight out of the
6
+ * dispatcher, into whatever the application happens to have around it — which is usually nothing
7
+ * with a height, so a percentage minimum would resolve to zero and leave the card at the top.
8
+ */
9
+ export const page = {
10
+ display: 'flex', alignItems: 'center', justifyContent: 'center',
11
+ minHeight: '100dvh', padding: '1rem',
12
+ fontFamily: 'system-ui, sans-serif', lineHeight: 1.5,
13
+ };
14
+ // Centred throughout, so the plain screen and the styled one read the same way.
15
+ export const box = {
16
+ width: '100%', maxWidth: '24rem', padding: '1.5rem', textAlign: 'center',
17
+ };
18
+ /** The same English fallback a document's `i18nKey` translates to when nothing else names it. */
19
+ export const DEFAULT_LABEL = {
20
+ terms: 'Terms & Conditions',
21
+ privacy: 'Privacy Policy',
22
+ cookies: 'Cookie Policy',
23
+ billing: 'Billing Terms',
24
+ product: '{{product}} Product Terms',
25
+ };
26
+ /** Outcomes after which nobody was signed in, so a screen parked for the landing must not wait. */
27
+ export const UNSIGNED_OUTCOMES = new Set([
28
+ LoginOutcome.Blocked, LoginOutcome.Failed, LoginOutcome.Gesture,
29
+ ]);
30
+ //# sourceMappingURL=consts.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../../src/login/consts.local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAkB;IACjC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ;IAC/D,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IACpC,UAAU,EAAE,uBAAuB,EAAE,UAAU,EAAE,GAAG;CACrD,CAAA;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,GAAG,GAAkB;IAChC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ;CACzE,CAAA;AAED,iGAAiG;AACjG,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,KAAK,EAAE,oBAAoB;IAC3B,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,eAAe;IACxB,OAAO,EAAE,eAAe;IACxB,OAAO,EAAE,2BAA2B;CACrC,CAAA;AAED,mGAAmG;AACnG,MAAM,CAAC,MAAM,iBAAiB,GAA8B,IAAI,GAAG,CAAe;IAChF,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,OAAO;CAChE,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ export interface ResolvedCredit {
2
+ /** Whether "Powered by OwlMeans" is rendered. */
3
+ poweredBy: boolean;
4
+ /** The product and organization line, already composed. Null when there is nothing to say. */
5
+ line: string | null;
6
+ }
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/login/credit/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB,8FAA8F;IAC9F,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/login/credit/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { BrandSettings, LoginCreditConfig } from '@owlmeans/config';
2
+ import type { ResolvedCredit } from './credit/types.js';
3
+ /**
4
+ * What the bottom of the sign-in screen says.
5
+ *
6
+ * It is a copyright notice, so it is composed as one: `© <year> <holder>`. That is the whole
7
+ * reason `copyright` defaults to on — the name on its own reads as a caption, and an application
8
+ * that means to assert a copyright would have had to write the mark and the year into a literal
9
+ * `line` to get one.
10
+ *
11
+ * The organization falls back to its slug because an organization record carries no readable name
12
+ * — so "no name" is the ordinary case, not an error, and a screen that rendered an empty line for
13
+ * it would be worse than one that renders the slug.
14
+ *
15
+ * `line` replaces everything when an app supplies it: a product with its own legal wording should
16
+ * not have to defeat a composition rule to use it.
17
+ */
18
+ export declare const resolveCredit: (cfg?: LoginCreditConfig, brand?: BrandSettings, service?: string) => ResolvedCredit;
19
+ //# sourceMappingURL=credit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit.d.ts","sourceRoot":"","sources":["../../src/login/credit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAuBvD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,aAAa,SAClB,iBAAiB,UAAU,aAAa,YAAY,MAAM,KAC/D,cA2BF,CAAA"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The years one notice covers.
3
+ *
4
+ * A range only while the first year is genuinely in the past — an app configured with the current
5
+ * year, or with a year a skewed clock puts in the future, still gets a well-formed notice rather
6
+ * than `© 2026–2026` or a range that runs backwards.
7
+ */
8
+ const years = (since, now) => since != null && since > 0 && since < now ? `${since}–${now}` : `${now}`;
9
+ /**
10
+ * A configured value that was actually SET.
11
+ *
12
+ * Empty is how a build-time default spells "unset", and this config is filled from environment
13
+ * variables a platform delivers — `BRANDING_ORGANIZATION: meta.brandingOrganization ?? ''` is the
14
+ * shape of every one of them. `??` does not fall through an empty string, so an undelivered
15
+ * organization used to win the fallback chain and compose a line ending in a bare dash.
16
+ */
17
+ const set = (value) => value != null && value.trim() !== '' ? value : null;
18
+ /**
19
+ * What the bottom of the sign-in screen says.
20
+ *
21
+ * It is a copyright notice, so it is composed as one: `© <year> <holder>`. That is the whole
22
+ * reason `copyright` defaults to on — the name on its own reads as a caption, and an application
23
+ * that means to assert a copyright would have had to write the mark and the year into a literal
24
+ * `line` to get one.
25
+ *
26
+ * The organization falls back to its slug because an organization record carries no readable name
27
+ * — so "no name" is the ordinary case, not an error, and a screen that rendered an empty line for
28
+ * it would be worse than one that renders the slug.
29
+ *
30
+ * `line` replaces everything when an app supplies it: a product with its own legal wording should
31
+ * not have to defeat a composition rule to use it.
32
+ */
33
+ export const resolveCredit = (cfg, brand, service) => {
34
+ const poweredBy = cfg?.poweredBy ?? true;
35
+ const literal = set(cfg?.line);
36
+ if (literal != null) {
37
+ return { poweredBy, line: literal };
38
+ }
39
+ const product = set(cfg?.product) ?? set(brand?.name) ?? set(service);
40
+ const organization = set(cfg?.organization) ?? set(brand?.organization)
41
+ ?? set(cfg?.entity) ?? set(brand?.entity);
42
+ // Whoever the notice names. A product with no organization behind it holds its own copyright,
43
+ // which is why this falls through to the product rather than dropping the notice.
44
+ const holder = set(cfg?.holder) ?? organization ?? product;
45
+ const wording = typeof cfg?.copyright === 'string' ? set(cfg.copyright) : null;
46
+ const notice = cfg?.copyright === false || holder == null
47
+ ? organization
48
+ : wording ?? `© ${years(cfg?.since, new Date().getFullYear())} ${holder}`;
49
+ // The product is named beside the notice only when it is not already the thing being claimed —
50
+ // "OwlMeans — © 2026 OwlMeans" says the name twice and neither time usefully.
51
+ return {
52
+ poweredBy,
53
+ line: product != null && notice != null && product !== holder
54
+ ? `${product} — ${notice}`
55
+ : notice ?? product,
56
+ };
57
+ };
58
+ //# sourceMappingURL=credit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credit.js","sourceRoot":"","sources":["../../src/login/credit.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,KAAK,GAAG,CAAC,KAAyB,EAAE,GAAW,EAAU,EAAE,CAC/D,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAA;AAE1E;;;;;;;GAOG;AACH,MAAM,GAAG,GAAG,CAAC,KAAqB,EAAiB,EAAE,CACnD,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;AAErD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,GAAuB,EAAE,KAAqB,EAAE,OAAgB,EAChD,EAAE;IAClB,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS,IAAI,IAAI,CAAA;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACrC,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;IACrE,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC;WAClE,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAE3C,8FAA8F;IAC9F,kFAAkF;IAClF,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,YAAY,IAAI,OAAO,CAAA;IAC1D,MAAM,OAAO,GAAG,OAAO,GAAG,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9E,MAAM,MAAM,GAAG,GAAG,EAAE,SAAS,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI;QACvD,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,OAAO,IAAI,KAAK,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,MAAM,EAAE,CAAA;IAE3E,+FAA+F;IAC/F,8EAA8E;IAC9E,OAAO;QACL,SAAS;QACT,IAAI,EAAE,OAAO,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,MAAM;YAC3D,CAAC,CAAC,GAAG,OAAO,MAAM,MAAM,EAAE;YAC1B,CAAC,CAAC,MAAM,IAAI,OAAO;KACtB,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,35 @@
1
+ import type { LoginEnv } from '../types.js';
2
+ /** What this browsing context is for a sign-in: framed, the surrogate window, opened by another. */
3
+ export interface LoginEnvHelper {
4
+ /**
5
+ * Whether this document is embedded in a frame.
6
+ *
7
+ * Reading `window.top` across origins throws, and that throw is itself the answer: a `top` that
8
+ * differs and a `top` that cannot be reached both mean "framed".
9
+ */
10
+ isEmbedded: () => boolean;
11
+ /**
12
+ * Record that this window is the surrogate login window, while that is still knowable.
13
+ *
14
+ * Must run on the surrogate's **first** load, before the flow navigates to the provider:
15
+ * `window.name` is the only evidence at that point, and browsers clear it as soon as a top-level
16
+ * context goes cross-origin — so by the time the provider redirects back, the name is gone and
17
+ * this window would look like an ordinary tab.
18
+ *
19
+ * Idempotent, and a no-op in every window that is not the surrogate.
20
+ */
21
+ markSurrogate: () => void;
22
+ /** Whether this document is the surrogate login window. */
23
+ isSurrogate: () => boolean;
24
+ /** Forget the surrogate marker — called once its token has been handed back. */
25
+ clearSurrogate: () => void;
26
+ /**
27
+ * Default login environment.
28
+ *
29
+ * The single source of environment truth for cascade selection — a plugin's `match` reads this
30
+ * and never probes `window` itself, so a non-DOM host can drive the same plugins by supplying its
31
+ * own descriptor.
32
+ */
33
+ defaultLoginEnv: () => LoginEnv;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/login/env/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,oGAAoG;AACpG,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,UAAU,EAAE,MAAM,OAAO,CAAA;IACzB;;;;;;;;;OASG;IACH,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,OAAO,CAAA;IAC1B,gFAAgF;IAChF,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;;;OAMG;IACH,eAAe,EAAE,MAAM,QAAQ,CAAA;CAChC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/login/env/types.ts"],"names":[],"mappings":""}
@@ -1,32 +1,8 @@
1
- import type { LoginEnv } from './types.js';
2
- /**
3
- * Whether this document is embedded in a frame.
4
- *
5
- * Reading `window.top` across origins throws, and that throw is itself the answer: a `top` that
6
- * differs and a `top` that cannot be reached both mean "framed".
7
- */
8
- export declare const isEmbedded: () => boolean;
9
- /**
10
- * Record that this window is the surrogate login window, while that is still knowable.
11
- *
12
- * Must run on the surrogate's **first** load, before the flow navigates to the provider:
13
- * `window.name` is the only evidence at that point, and browsers clear it as soon as a top-level
14
- * context goes cross-origin — so by the time the provider redirects back, the name is gone and
15
- * this window would look like an ordinary tab.
16
- *
17
- * Idempotent, and a no-op in every window that is not the surrogate.
18
- */
1
+ import type { LoginEnvHelper } from './env/types.js';
2
+ export declare const createLoginEnvHelper: () => LoginEnvHelper;
3
+ export declare const loginEnvHelper: LoginEnvHelper;
4
+ /** @deprecated compat:factory-refactor — use `loginEnvHelper.markSurrogate()` */
19
5
  export declare const markSurrogate: () => void;
20
- /** Whether this document is the surrogate login window. */
21
- export declare const isSurrogate: () => boolean;
22
- /** Forget the surrogate marker — called once its token has been handed back. */
6
+ /** @deprecated compat:factory-refactor — use `loginEnvHelper.clearSurrogate()` */
23
7
  export declare const clearSurrogate: () => void;
24
- /**
25
- * Default login environment.
26
- *
27
- * The single source of environment truth for cascade selection — a plugin's `match` reads this
28
- * and never probes `window` itself, so a non-DOM host can drive the same plugins by supplying its
29
- * own descriptor.
30
- */
31
- export declare const defaultLoginEnv: () => LoginEnv;
32
8
  //# sourceMappingURL=env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/login/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,UAAU,QAAO,OAM7B,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,QAAO,IAUhC,CAAA;AAED,2DAA2D;AAC3D,eAAO,MAAM,WAAW,QAAO,OAY9B,CAAA;AAED,gFAAgF;AAChF,eAAO,MAAM,cAAc,QAAO,IAOjC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,QAAO,QAclC,CAAA"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/login/env.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,eAAO,MAAM,oBAAoB,QAAO,cA6DvC,CAAA;AAED,eAAO,MAAM,cAAc,gBAAyB,CAAA;AAEpD,iFAAiF;AACjF,eAAO,MAAM,aAAa,QAAO,IAAsC,CAAA;AAEvE,kFAAkF;AAClF,eAAO,MAAM,cAAc,QAAO,IAAuC,CAAA"}
@@ -1,84 +1,67 @@
1
1
  import { LOGIN_SURROGATE_MARKER, LOGIN_SURROGATE_NAME } from './consts.js';
2
- /**
3
- * Whether this document is embedded in a frame.
4
- *
5
- * Reading `window.top` across origins throws, and that throw is itself the answer: a `top` that
6
- * differs and a `top` that cannot be reached both mean "framed".
7
- */
8
- export const isEmbedded = () => {
9
- try {
10
- return window.self !== window.top;
11
- }
12
- catch {
13
- return true;
14
- }
15
- };
16
- /**
17
- * Record that this window is the surrogate login window, while that is still knowable.
18
- *
19
- * Must run on the surrogate's **first** load, before the flow navigates to the provider:
20
- * `window.name` is the only evidence at that point, and browsers clear it as soon as a top-level
21
- * context goes cross-origin — so by the time the provider redirects back, the name is gone and
22
- * this window would look like an ordinary tab.
23
- *
24
- * Idempotent, and a no-op in every window that is not the surrogate.
25
- */
26
- export const markSurrogate = () => {
27
- if (typeof window === 'undefined' || window.name !== LOGIN_SURROGATE_NAME) {
28
- return;
29
- }
30
- try {
31
- window.sessionStorage.setItem(LOGIN_SURROGATE_MARKER, '1');
32
- }
33
- catch {
34
- // Storage can be unavailable (private modes, blocked cookies). The `window.name` check still
35
- // covers the case where nothing cross-origin happened in between.
36
- }
37
- };
38
- /** Whether this document is the surrogate login window. */
39
- export const isSurrogate = () => {
40
- if (typeof window === 'undefined') {
41
- return false;
42
- }
43
- if (window.name === LOGIN_SURROGATE_NAME) {
44
- return true;
45
- }
46
- try {
47
- return window.sessionStorage.getItem(LOGIN_SURROGATE_MARKER) === '1';
48
- }
49
- catch {
50
- return false;
51
- }
52
- };
53
- /** Forget the surrogate marker — called once its token has been handed back. */
54
- export const clearSurrogate = () => {
55
- if (typeof window === 'undefined') {
56
- return;
57
- }
58
- try {
59
- window.sessionStorage.removeItem(LOGIN_SURROGATE_MARKER);
60
- }
61
- catch { /* nothing to clean up if storage was never available */ }
62
- };
63
- /**
64
- * Default login environment.
65
- *
66
- * The single source of environment truth for cascade selection — a plugin's `match` reads this
67
- * and never probes `window` itself, so a non-DOM host can drive the same plugins by supplying its
68
- * own descriptor.
69
- */
70
- export const defaultLoginEnv = () => {
71
- const hasWindow = typeof window !== 'undefined';
72
- if (!hasWindow) {
73
- return { hasWindow, embedded: false, surrogate: false, hasOpener: false };
74
- }
75
- return {
76
- hasWindow,
77
- embedded: isEmbedded(),
78
- surrogate: isSurrogate(),
79
- // `Cross-Origin-Opener-Policy: same-origin` from the provider severs this permanently, which
80
- // is why it is observed rather than assumed from "we were opened by someone".
81
- hasOpener: window.opener != null,
2
+ export const createLoginEnvHelper = () => {
3
+ const isEmbedded = () => {
4
+ try {
5
+ return window.self !== window.top;
6
+ }
7
+ catch {
8
+ return true;
9
+ }
10
+ };
11
+ const markSurrogate = () => {
12
+ if (typeof window === 'undefined' || window.name !== LOGIN_SURROGATE_NAME) {
13
+ return;
14
+ }
15
+ try {
16
+ window.sessionStorage.setItem(LOGIN_SURROGATE_MARKER, '1');
17
+ }
18
+ catch {
19
+ // Storage can be unavailable (private modes, blocked cookies). The `window.name` check still
20
+ // covers the case where nothing cross-origin happened in between.
21
+ }
22
+ };
23
+ const isSurrogate = () => {
24
+ if (typeof window === 'undefined') {
25
+ return false;
26
+ }
27
+ if (window.name === LOGIN_SURROGATE_NAME) {
28
+ return true;
29
+ }
30
+ try {
31
+ return window.sessionStorage.getItem(LOGIN_SURROGATE_MARKER) === '1';
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ };
37
+ const clearSurrogate = () => {
38
+ if (typeof window === 'undefined') {
39
+ return;
40
+ }
41
+ try {
42
+ window.sessionStorage.removeItem(LOGIN_SURROGATE_MARKER);
43
+ }
44
+ catch { /* nothing to clean up if storage was never available */ }
45
+ };
46
+ const defaultLoginEnv = () => {
47
+ const hasWindow = typeof window !== 'undefined';
48
+ if (!hasWindow) {
49
+ return { hasWindow, embedded: false, surrogate: false, hasOpener: false };
50
+ }
51
+ return {
52
+ hasWindow,
53
+ embedded: isEmbedded(),
54
+ surrogate: isSurrogate(),
55
+ // `Cross-Origin-Opener-Policy: same-origin` from the provider severs this permanently, which
56
+ // is why it is observed rather than assumed from "we were opened by someone".
57
+ hasOpener: window.opener != null,
58
+ };
82
59
  };
60
+ return { isEmbedded, markSurrogate, isSurrogate, clearSurrogate, defaultLoginEnv };
83
61
  };
62
+ export const loginEnvHelper = createLoginEnvHelper();
63
+ /** @deprecated compat:factory-refactor — use `loginEnvHelper.markSurrogate()` */
64
+ export const markSurrogate = () => loginEnvHelper.markSurrogate();
65
+ /** @deprecated compat:factory-refactor — use `loginEnvHelper.clearSurrogate()` */
66
+ export const clearSurrogate = () => loginEnvHelper.clearSurrogate();
84
67
  //# sourceMappingURL=env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/login/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAG1E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAY,EAAE;IACtC,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAS,EAAE;IACtC,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;QAC1E,OAAM;IACR,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,6FAA6F;QAC7F,kEAAkE;IACpE,CAAC;AACH,CAAC,CAAA;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,GAAY,EAAE;IACvC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACzC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAA;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAS,EAAE;IACvC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAM;IACR,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAA;IAC1D,CAAC;IAAC,MAAM,CAAC,CAAC,wDAAwD,CAAC,CAAC;AACtE,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAa,EAAE;IAC5C,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAA;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;IAC3E,CAAC;IAED,OAAO;QACL,SAAS;QACT,QAAQ,EAAE,UAAU,EAAE;QACtB,SAAS,EAAE,WAAW,EAAE;QACxB,6FAA6F;QAC7F,8EAA8E;QAC9E,SAAS,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI;KACjC,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/login/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAI1E,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAmB,EAAE;IACvD,MAAM,UAAU,GAAG,GAAY,EAAE;QAC/B,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,CAAA;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC,CAAA;IAED,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YAC1E,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAA;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,6FAA6F;YAC7F,kEAAkE;QACpE,CAAC;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,GAAY,EAAE;QAChC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACzC,OAAO,IAAI,CAAA;QACb,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAA;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,GAAS,EAAE;QAChC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAA;QAC1D,CAAC;QAAC,MAAM,CAAC,CAAC,wDAAwD,CAAC,CAAC;IACtE,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,GAAa,EAAE;QACrC,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAA;QAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;QAC3E,CAAC;QAED,OAAO;YACL,SAAS;YACT,QAAQ,EAAE,UAAU,EAAE;YACtB,SAAS,EAAE,WAAW,EAAE;YACxB,6FAA6F;YAC7F,8EAA8E;YAC9E,SAAS,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI;SACjC,CAAA;IACH,CAAC,CAAA;IAED,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA;AACpF,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAA;AAEpD,iFAAiF;AACjF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAS,EAAE,CAAC,cAAc,CAAC,aAAa,EAAE,CAAA;AAEvE,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAS,EAAE,CAAC,cAAc,CAAC,cAAc,EAAE,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { FlowModel } from '@owlmeans/flow';
2
+ /**
3
+ * Bring a freshly booted standard OIDC flow to the step an authorization request can be made from.
4
+ *
5
+ * `stdOidcFlow` starts at `Dispatch`, but `OidcAuthService.authenticate` refuses any state that is
6
+ * not `Ephemeral` and returns null — so an application whose flow was only booted can ask for an
7
+ * authorization URL all day and be told nothing, forever. The dispatcher in this package has always
8
+ * done this transition inline; a relying party that replaces that dispatcher (`web-oidc-rp`,
9
+ * `mui-oidc-rp`) inherited the requirement without the code, which is what left a sign-in button
10
+ * that reported no error and did nothing at all.
11
+ *
12
+ * `Ephemeral` is the branch for an application that is its OWN authority — its flow configuration
13
+ * maps the auth service to a placeholder, which is exactly the generated-application case. An app
14
+ * federated with a real auth service keeps its target and is left alone.
15
+ *
16
+ * Idempotent, and safe to call on every attempt: a flow already past `Dispatch`, or one that is
17
+ * not the standard OIDC flow at all, is returned untouched.
18
+ */
19
+ export declare const enterOidcAuthorization: (model: FlowModel) => FlowModel;
20
+ //# sourceMappingURL=flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/login/flow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG/C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,sBAAsB,UAAW,SAAS,KAAG,SAsBzD,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { FLOW_PLACEHOLDER, OidcAuthStep, STD_OIDC_FLOW } from '@owlmeans/flow';
2
+ import { DEFAULT_ENTITY } from '../consts.js';
3
+ /**
4
+ * Bring a freshly booted standard OIDC flow to the step an authorization request can be made from.
5
+ *
6
+ * `stdOidcFlow` starts at `Dispatch`, but `OidcAuthService.authenticate` refuses any state that is
7
+ * not `Ephemeral` and returns null — so an application whose flow was only booted can ask for an
8
+ * authorization URL all day and be told nothing, forever. The dispatcher in this package has always
9
+ * done this transition inline; a relying party that replaces that dispatcher (`web-oidc-rp`,
10
+ * `mui-oidc-rp`) inherited the requirement without the code, which is what left a sign-in button
11
+ * that reported no error and did nothing at all.
12
+ *
13
+ * `Ephemeral` is the branch for an application that is its OWN authority — its flow configuration
14
+ * maps the auth service to a placeholder, which is exactly the generated-application case. An app
15
+ * federated with a real auth service keeps its target and is left alone.
16
+ *
17
+ * Idempotent, and safe to call on every attempt: a flow already past `Dispatch`, or one that is
18
+ * not the standard OIDC flow at all, is returned untouched.
19
+ */
20
+ export const enterOidcAuthorization = (model) => {
21
+ const state = model.state();
22
+ if (state.flow !== STD_OIDC_FLOW || state.step !== OidcAuthStep.Dispatch) {
23
+ return model;
24
+ }
25
+ const target = model.step().service;
26
+ if (state.service == null || state.service === '') {
27
+ model.target(target);
28
+ }
29
+ // The entity travels to this app's own backend, which resolves its default provider by `def`
30
+ // alone. It still has to BE there: the init endpoint rejects a body without one.
31
+ if (state.entityId == null) {
32
+ model.entity(DEFAULT_ENTITY);
33
+ }
34
+ if (target === FLOW_PLACEHOLDER) {
35
+ model.transit(OidcAuthStep.Ephemeral, true);
36
+ }
37
+ return model;
38
+ };
39
+ //# sourceMappingURL=flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/login/flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAE9E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAgB,EAAa,EAAE;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;IAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,QAAQ,EAAE,CAAC;QACzE,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAA;IACnC,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;QAClD,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACtB,CAAC;IAED,6FAA6F;IAC7F,iFAAiF;IACjF,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC3B,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}