@owlmeans/web-client 0.1.18-rc.13 → 0.1.18-rc.15

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 (58) hide show
  1. package/agent-meta/manifest.json +2 -2
  2. package/agent-meta/skills/web-client/SKILL.md +1 -1
  3. package/build/components/dispatcher/component.d.ts.map +1 -1
  4. package/build/components/dispatcher/component.js +46 -9
  5. package/build/components/dispatcher/component.js.map +1 -1
  6. package/build/i18n/auth-be.json +32 -0
  7. package/build/i18n/auth-de.json +32 -0
  8. package/build/i18n/auth-en.json +32 -0
  9. package/build/i18n/auth-es.json +32 -0
  10. package/build/i18n/auth-pl.json +32 -0
  11. package/build/i18n/auth-ru.json +32 -0
  12. package/build/i18n/auth-uk.json +32 -0
  13. package/build/login/index.d.ts +3 -0
  14. package/build/login/index.d.ts.map +1 -1
  15. package/build/login/index.js +3 -0
  16. package/build/login/index.js.map +1 -1
  17. package/build/login/pump.d.ts +20 -0
  18. package/build/login/pump.d.ts.map +1 -0
  19. package/build/login/pump.js +46 -0
  20. package/build/login/pump.js.map +1 -0
  21. package/build/login/redirect.d.ts.map +1 -1
  22. package/build/login/redirect.js +17 -1
  23. package/build/login/redirect.js.map +1 -1
  24. package/build/login/screen.d.ts +15 -0
  25. package/build/login/screen.d.ts.map +1 -0
  26. package/build/login/screen.js +97 -0
  27. package/build/login/screen.js.map +1 -0
  28. package/build/login/surrogate.d.ts.map +1 -1
  29. package/build/login/surrogate.js +109 -79
  30. package/build/login/surrogate.js.map +1 -1
  31. package/build/login/view.d.ts +26 -0
  32. package/build/login/view.d.ts.map +1 -0
  33. package/build/login/view.js +73 -0
  34. package/build/login/view.js.map +1 -0
  35. package/build/main.d.ts +9 -1
  36. package/build/main.d.ts.map +1 -1
  37. package/build/main.js +9 -1
  38. package/build/main.js.map +1 -1
  39. package/build/modules.d.ts.map +1 -1
  40. package/build/modules.js +11 -1
  41. package/build/modules.js.map +1 -1
  42. package/package.json +13 -13
  43. package/src/components/dispatcher/component.tsx +64 -8
  44. package/src/i18n/auth-be.json +32 -0
  45. package/src/i18n/auth-de.json +32 -0
  46. package/src/i18n/auth-en.json +32 -0
  47. package/src/i18n/auth-es.json +32 -0
  48. package/src/i18n/auth-pl.json +32 -0
  49. package/src/i18n/auth-ru.json +32 -0
  50. package/src/i18n/auth-uk.json +32 -0
  51. package/src/login/index.ts +3 -0
  52. package/src/login/pump.ts +53 -0
  53. package/src/login/redirect.ts +23 -2
  54. package/src/login/screen.tsx +119 -0
  55. package/src/login/surrogate.ts +136 -93
  56. package/src/login/view.tsx +94 -0
  57. package/src/main.tsx +11 -2
  58. package/src/modules.ts +12 -1
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/web-client",
4
- "version": "0.1.18-rc.12",
5
- "generatedAt": "2026-08-27T21:16:47.137Z",
4
+ "version": "0.1.18-rc.13",
5
+ "generatedAt": "2026-08-27T21:18:31.380Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/web-client
9
9
 
10
10
  **Layer:** Web (React)
11
- **Install:** `"@owlmeans/web-client": "^0.1.18-rc.12"` in `dependencies`
11
+ **Install:** `"@owlmeans/web-client": "^0.1.18-rc.13"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,UAAU,6FAmCrB,CAAA"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"AAUA,eAAO,MAAM,UAAU,6FAuFrB,CAAA"}
@@ -1,14 +1,27 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { DispatcherHOC } from '@owlmeans/client-auth';
3
- import { useEffect } from 'react';
3
+ import { useEffect, useState } from 'react';
4
4
  import { useI18nLib } from '@owlmeans/client-i18n';
5
5
  import { AUTH_QUERY } from '@owlmeans/auth';
6
+ import { FallbackLoginScreen, LoginIntent, LoginOutcome, ResumeAction, resumeAction, } from '@owlmeans/client-auth/login';
7
+ import { LoginSurrogateView, SurrogateStage } from '../../login/view.js';
6
8
  import { useContext } from '../../context.js';
7
- export const Dispatcher = DispatcherHOC(({ provideToken }) => {
9
+ export const Dispatcher = DispatcherHOC(({ provideToken, navigate }) => {
8
10
  const context = useContext();
9
11
  const [query] = context.router().useSearchParams();
10
12
  const t = useI18nLib('auth', 'dispatcher');
13
+ const tAuth = useI18nLib('auth');
14
+ // Read in the component body, not in the effect: `window.name` is set by `window.open` before
15
+ // this document loads and `sessionStorage` carries the marker across the provider round trip, so
16
+ // the answer is already correct at first paint — and a first paint that showed the application
17
+ // before an effect corrected it is the defect this exists to prevent.
18
+ const [env] = useState(() => context.login().env());
19
+ const [outcome, setOutcome] = useState(null);
20
+ // Nothing to return from and nobody signed in: offer the choice rather than starting a flow.
21
+ const [choose, setChoose] = useState(false);
11
22
  useEffect(() => {
23
+ // First statement of the effect on purpose: everything below can navigate this window away.
24
+ context.login().enter();
12
25
  const token = query.get(AUTH_QUERY);
13
26
  if (token != null) {
14
27
  const params = {};
@@ -18,15 +31,39 @@ export const Dispatcher = DispatcherHOC(({ provideToken }) => {
18
31
  }
19
32
  });
20
33
  provideToken({ token }, params);
34
+ return;
21
35
  }
22
- else {
23
- context.auth().authenticated().then(authzToken => {
24
- if (authzToken == null) {
25
- provideToken({ token: '' }, undefined);
26
- }
27
- });
28
- }
36
+ void context.auth().authenticated().then(async (authzToken) => {
37
+ if (authzToken == null || authzToken === '') {
38
+ setChoose(true);
39
+ return;
40
+ }
41
+ // A session already exists in THIS document. Whether it is useful here, or belongs to the
42
+ // window that opened this one, is the plugin's call — the dispatcher reads no environment.
43
+ const settled = await context.login().resume(authzToken);
44
+ switch (resumeAction(settled)) {
45
+ case ResumeAction.Stop:
46
+ return;
47
+ case ResumeAction.Render:
48
+ setOutcome(settled);
49
+ return;
50
+ default:
51
+ await navigate();
52
+ }
53
+ });
29
54
  }, []);
55
+ // A surrogate window never renders the application, whatever else is true. Checked ahead of
56
+ // every other return for exactly that reason.
57
+ if (env.surrogate) {
58
+ return _jsx(LoginSurrogateView, { intent: LoginIntent.Login, stage: outcome === LoginOutcome.Orphaned ? SurrogateStage.Orphaned
59
+ : outcome === LoginOutcome.Failed ? SurrogateStage.Failed
60
+ : outcome === LoginOutcome.Gesture ? SurrogateStage.Gesture
61
+ : SurrogateStage.Working, onAction: () => window.close(), translate: (key, defaultValue) => tAuth(key, { defaultValue }) });
62
+ }
63
+ if (choose) {
64
+ const Screen = context.login().screen() ?? FallbackLoginScreen;
65
+ return _jsx(Screen, { translate: (key, defaultValue) => tAuth(key, { defaultValue }) });
66
+ }
30
67
  return query.has(AUTH_QUERY) ? _jsx("div", { style: {
31
68
  width: '100%', // Makes the div occupy the full width
32
69
  display: 'flex', // Enables flexbox layout
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE;IAC3D,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,eAAe,EAAE,CAAA;IAElD,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAE1C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACnC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,MAAM,GAA2B,EAAE,CAAA;YACzC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC3B,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;oBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;gBACrB,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,CAAC,CAAA;QACjC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBAC/C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;oBACvB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,CAAC,CAAA;gBACxC,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,cAAK,KAAK,EAAE;YACzC,KAAK,EAAE,MAAM,EAAE,sCAAsC;YACrD,OAAO,EAAE,MAAM,EAAE,yBAAyB;YAC1C,cAAc,EAAE,QAAQ,EAAE,+BAA+B;YACzD,UAAU,EAAE,QAAQ,EAAE,yCAAyC;YAC/D,SAAS,EAAE,QAAQ,EAAE,8BAA8B;YACnD,UAAU,EAAE,MAAM,EAAE,6BAA6B;YACjD,aAAa,EAAE,MAAM,EAAE,6BAA6B;SACrD,YAAG,CAAC,CAAC,SAAS,CAAC,GAAO,CAAC,CAAC,CAAC,SAAS,CAAA;AACrC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/dispatcher/component.tsx"],"names":[],"mappings":"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"}
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Загрузка...",
4
4
  "error": "Не ўдалося прайсці аўтэнтыфікацыю: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Выконваем уваход…",
9
+ "gesture": {
10
+ "title": "Працягніце, каб увайсці.",
11
+ "action": "Увайсці"
12
+ },
13
+ "handing": "Гатова. Вяртаемся ў праграму…",
14
+ "orphaned": "Уваход выкананы. Можаце закрыць гэтае акно і вярнуцца ў праграму.",
15
+ "failed": "Не ўдалося завяршыць. Закрыйце гэтае акно і паспрабуйце зноў.",
16
+ "standalone": {
17
+ "title": "Гэтая старонка выкарыстоўваецца для ўваходу з іншага акна.",
18
+ "action": "Адкрыць праграму"
19
+ },
20
+ "close": "Закрыць"
21
+ },
22
+ "logout": {
23
+ "working": "Выконваем выхад…",
24
+ "gesture": {
25
+ "title": "Працягніце, каб выйсці.",
26
+ "action": "Выйсці"
27
+ },
28
+ "handing": "Выхад выкананы. Вяртаемся ў праграму…",
29
+ "orphaned": "Выхад выкананы. Можаце закрыць гэтае акно.",
30
+ "failed": "Выхад тут не завершаны. Можаце закрыць гэтае акно.",
31
+ "standalone": {
32
+ "title": "Гэтая старонка выкарыстоўваецца для выхаду з іншага акна.",
33
+ "action": "Адкрыць праграму"
34
+ },
35
+ "close": "Закрыць"
36
+ }
5
37
  }
6
38
  }
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Wird geladen...",
4
4
  "error": "Authentifizierung fehlgeschlagen: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Anmeldung läuft…",
9
+ "gesture": {
10
+ "title": "Fortfahren, um sich anzumelden.",
11
+ "action": "Anmelden"
12
+ },
13
+ "handing": "Fertig. Zurück zur Anwendung…",
14
+ "orphaned": "Angemeldet. Sie können dieses Fenster schließen und in der Anwendung fortfahren.",
15
+ "failed": "Das wurde nicht abgeschlossen. Schließen Sie dieses Fenster und versuchen Sie es erneut.",
16
+ "standalone": {
17
+ "title": "Diese Seite dient der Anmeldung aus einem anderen Fenster.",
18
+ "action": "Anwendung öffnen"
19
+ },
20
+ "close": "Schließen"
21
+ },
22
+ "logout": {
23
+ "working": "Abmeldung läuft…",
24
+ "gesture": {
25
+ "title": "Fortfahren, um sich abzumelden.",
26
+ "action": "Abmelden"
27
+ },
28
+ "handing": "Abgemeldet. Zurück zur Anwendung…",
29
+ "orphaned": "Abgemeldet. Sie können dieses Fenster schließen.",
30
+ "failed": "Die Abmeldung wurde hier nicht abgeschlossen. Sie können dieses Fenster schließen.",
31
+ "standalone": {
32
+ "title": "Diese Seite dient der Abmeldung aus einem anderen Fenster.",
33
+ "action": "Anwendung öffnen"
34
+ },
35
+ "close": "Schließen"
36
+ }
5
37
  }
6
38
  }
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Loading...",
4
4
  "error": "Authentication failed: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Signing you in…",
9
+ "gesture": {
10
+ "title": "Continue to sign in.",
11
+ "action": "Sign in"
12
+ },
13
+ "handing": "Done. Returning to the application…",
14
+ "orphaned": "Signed in. You can close this window and continue in the application.",
15
+ "failed": "That did not complete. You can close this window and try again.",
16
+ "standalone": {
17
+ "title": "This page is used to sign in from another window.",
18
+ "action": "Open the application"
19
+ },
20
+ "close": "Close"
21
+ },
22
+ "logout": {
23
+ "working": "Signing you out…",
24
+ "gesture": {
25
+ "title": "Continue to sign out.",
26
+ "action": "Sign out"
27
+ },
28
+ "handing": "Signed out. Returning to the application…",
29
+ "orphaned": "Signed out. You can close this window.",
30
+ "failed": "Sign-out did not complete here. You can close this window.",
31
+ "standalone": {
32
+ "title": "This page is used to sign out from another window.",
33
+ "action": "Open the application"
34
+ },
35
+ "close": "Close"
36
+ }
5
37
  }
6
38
  }
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Cargando...",
4
4
  "error": "Error de autenticación: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Iniciando sesión…",
9
+ "gesture": {
10
+ "title": "Continúa para iniciar sesión.",
11
+ "action": "Iniciar sesión"
12
+ },
13
+ "handing": "Listo. Volviendo a la aplicación…",
14
+ "orphaned": "Sesión iniciada. Puedes cerrar esta ventana y continuar en la aplicación.",
15
+ "failed": "No se completó. Cierra esta ventana e inténtalo de nuevo.",
16
+ "standalone": {
17
+ "title": "Esta página se usa para iniciar sesión desde otra ventana.",
18
+ "action": "Abrir la aplicación"
19
+ },
20
+ "close": "Cerrar"
21
+ },
22
+ "logout": {
23
+ "working": "Cerrando sesión…",
24
+ "gesture": {
25
+ "title": "Continúa para cerrar sesión.",
26
+ "action": "Cerrar sesión"
27
+ },
28
+ "handing": "Sesión cerrada. Volviendo a la aplicación…",
29
+ "orphaned": "Sesión cerrada. Puedes cerrar esta ventana.",
30
+ "failed": "El cierre de sesión no se completó aquí. Puedes cerrar esta ventana.",
31
+ "standalone": {
32
+ "title": "Esta página se usa para cerrar sesión desde otra ventana.",
33
+ "action": "Abrir la aplicación"
34
+ },
35
+ "close": "Cerrar"
36
+ }
5
37
  }
6
38
  }
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Ładowanie...",
4
4
  "error": "Uwierzytelnianie nie powiodło się: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Trwa logowanie…",
9
+ "gesture": {
10
+ "title": "Kontynuuj, aby się zalogować.",
11
+ "action": "Zaloguj się"
12
+ },
13
+ "handing": "Gotowe. Wracamy do aplikacji…",
14
+ "orphaned": "Zalogowano. Możesz zamknąć to okno i kontynuować w aplikacji.",
15
+ "failed": "Nie udało się ukończyć. Zamknij to okno i spróbuj ponownie.",
16
+ "standalone": {
17
+ "title": "Ta strona służy do logowania z innego okna.",
18
+ "action": "Otwórz aplikację"
19
+ },
20
+ "close": "Zamknij"
21
+ },
22
+ "logout": {
23
+ "working": "Trwa wylogowywanie…",
24
+ "gesture": {
25
+ "title": "Kontynuuj, aby się wylogować.",
26
+ "action": "Wyloguj się"
27
+ },
28
+ "handing": "Wylogowano. Wracamy do aplikacji…",
29
+ "orphaned": "Wylogowano. Możesz zamknąć to okno.",
30
+ "failed": "Wylogowanie nie zostało tu ukończone. Możesz zamknąć to okno.",
31
+ "standalone": {
32
+ "title": "Ta strona służy do wylogowania z innego okna.",
33
+ "action": "Otwórz aplikację"
34
+ },
35
+ "close": "Zamknij"
36
+ }
5
37
  }
6
38
  }
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Загрузка...",
4
4
  "error": "Не удалось выполнить аутентификацию: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Выполняем вход…",
9
+ "gesture": {
10
+ "title": "Продолжите, чтобы войти.",
11
+ "action": "Войти"
12
+ },
13
+ "handing": "Готово. Возвращаемся в приложение…",
14
+ "orphaned": "Вход выполнен. Можете закрыть это окно и вернуться в приложение.",
15
+ "failed": "Не удалось завершить. Закройте это окно и попробуйте снова.",
16
+ "standalone": {
17
+ "title": "Эта страница используется для входа из другого окна.",
18
+ "action": "Открыть приложение"
19
+ },
20
+ "close": "Закрыть"
21
+ },
22
+ "logout": {
23
+ "working": "Выполняем выход…",
24
+ "gesture": {
25
+ "title": "Продолжите, чтобы выйти.",
26
+ "action": "Выйти"
27
+ },
28
+ "handing": "Выход выполнен. Возвращаемся в приложение…",
29
+ "orphaned": "Выход выполнен. Можете закрыть это окно.",
30
+ "failed": "Выход здесь не завершён. Можете закрыть это окно.",
31
+ "standalone": {
32
+ "title": "Эта страница используется для выхода из другого окна.",
33
+ "action": "Открыть приложение"
34
+ },
35
+ "close": "Закрыть"
36
+ }
5
37
  }
6
38
  }
@@ -2,5 +2,37 @@
2
2
  "dispatcher": {
3
3
  "loading": "Завантаження...",
4
4
  "error": "Не вдалося пройти автентифікацію: {{error}}"
5
+ },
6
+ "surrogate": {
7
+ "login": {
8
+ "working": "Виконуємо вхід…",
9
+ "gesture": {
10
+ "title": "Продовжте, щоб увійти.",
11
+ "action": "Увійти"
12
+ },
13
+ "handing": "Готово. Повертаємось до застосунку…",
14
+ "orphaned": "Вхід виконано. Можете закрити це вікно й повернутися до застосунку.",
15
+ "failed": "Не вдалося завершити. Закрийте це вікно та спробуйте ще раз.",
16
+ "standalone": {
17
+ "title": "Ця сторінка використовується для входу з іншого вікна.",
18
+ "action": "Відкрити застосунок"
19
+ },
20
+ "close": "Закрити"
21
+ },
22
+ "logout": {
23
+ "working": "Виконуємо вихід…",
24
+ "gesture": {
25
+ "title": "Продовжте, щоб вийти.",
26
+ "action": "Вийти"
27
+ },
28
+ "handing": "Вихід виконано. Повертаємось до застосунку…",
29
+ "orphaned": "Вихід виконано. Можете закрити це вікно.",
30
+ "failed": "Вихід тут не завершено. Можете закрити це вікно.",
31
+ "standalone": {
32
+ "title": "Ця сторінка використовується для виходу з іншого вікна.",
33
+ "action": "Відкрити застосунок"
34
+ },
35
+ "close": "Закрити"
36
+ }
5
37
  }
6
38
  }
@@ -1,5 +1,8 @@
1
1
  export * from './consts.js';
2
+ export * from './pump.js';
2
3
  export * from './redirect.js';
3
4
  export * from './surrogate.js';
5
+ export * from './view.js';
6
+ export * from './screen.js';
4
7
  export * from './service.js';
5
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -1,5 +1,8 @@
1
1
  export * from './consts.js';
2
+ export * from './pump.js';
2
3
  export * from './redirect.js';
3
4
  export * from './surrogate.js';
5
+ export * from './view.js';
6
+ export * from './screen.js';
4
7
  export * from './service.js';
5
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { LoginOutcome } from '@owlmeans/client-auth/login';
2
+ /**
3
+ * Wait on a surrogate window until it says something, or goes away.
4
+ *
5
+ * Extracted so login and logout share one implementation rather than two that agree until one of
6
+ * them is changed. Every guard here was a real failure at some point:
7
+ *
8
+ * - the **origin pin** is not decoration — the message carries a bearer token, and a listener that
9
+ * accepted any origin would take one from any page that could reach this window;
10
+ * - the **`settled` latch** stops a second message, or a close racing a message, resolving twice;
11
+ * - the **`closed` poll** is the only exit when the user simply closes the window, because a window
12
+ * the user closes announces nothing at all;
13
+ * - the listener and the interval are removed on every path, including the ones that resolve.
14
+ */
15
+ export declare const awaitSurrogate: (surrogate: Window, messageType: string, onMessage: (data: {
16
+ type?: string;
17
+ token?: string;
18
+ ok?: boolean;
19
+ }) => Promise<LoginOutcome>) => Promise<LoginOutcome>;
20
+ //# sourceMappingURL=pump.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pump.d.ts","sourceRoot":"","sources":["../../src/login/pump.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAEhF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,cACd,MAAM,eACJ,MAAM,aACR,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC,YAAY,CAAC,KAC1F,OAAO,CAAC,YAAY,CAiCrB,CAAA"}
@@ -0,0 +1,46 @@
1
+ import { LOGIN_WATCH_INTERVAL, LoginOutcome } from '@owlmeans/client-auth/login';
2
+ /**
3
+ * Wait on a surrogate window until it says something, or goes away.
4
+ *
5
+ * Extracted so login and logout share one implementation rather than two that agree until one of
6
+ * them is changed. Every guard here was a real failure at some point:
7
+ *
8
+ * - the **origin pin** is not decoration — the message carries a bearer token, and a listener that
9
+ * accepted any origin would take one from any page that could reach this window;
10
+ * - the **`settled` latch** stops a second message, or a close racing a message, resolving twice;
11
+ * - the **`closed` poll** is the only exit when the user simply closes the window, because a window
12
+ * the user closes announces nothing at all;
13
+ * - the listener and the interval are removed on every path, including the ones that resolve.
14
+ */
15
+ export const awaitSurrogate = async (surrogate, messageType, onMessage) => await new Promise(resolve => {
16
+ let settled = false;
17
+ let watch;
18
+ const finish = (result) => {
19
+ if (settled) {
20
+ return;
21
+ }
22
+ settled = true;
23
+ window.removeEventListener('message', handler);
24
+ if (watch != null) {
25
+ clearInterval(watch);
26
+ }
27
+ resolve(result);
28
+ };
29
+ function handler(event) {
30
+ if (event.origin !== window.location.origin) {
31
+ return;
32
+ }
33
+ const data = event.data;
34
+ if (data?.type !== messageType) {
35
+ return;
36
+ }
37
+ void onMessage(data).then(finish).catch(() => finish(LoginOutcome.Failed));
38
+ }
39
+ window.addEventListener('message', handler);
40
+ watch = setInterval(() => {
41
+ if (surrogate.closed) {
42
+ finish(LoginOutcome.Failed);
43
+ }
44
+ }, LOGIN_WATCH_INTERVAL);
45
+ });
46
+ //# sourceMappingURL=pump.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pump.js","sourceRoot":"","sources":["../../src/login/pump.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,SAAiB,EACjB,WAAmB,EACnB,SAA2F,EACpE,EAAE,CAAC,MAAM,IAAI,OAAO,CAAe,OAAO,CAAC,EAAE;IACpE,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,KAAiD,CAAA;IAErD,MAAM,MAAM,GAAG,CAAC,MAAoB,EAAQ,EAAE;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAM;QACR,CAAC;QACD,OAAO,GAAG,IAAI,CAAA;QACd,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAC9C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,aAAa,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,CAAA;IACjB,CAAC,CAAA;IAED,SAAS,OAAO,CAAC,KAAmB;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC5C,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAA8D,CAAA;QACjF,IAAI,IAAI,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YAC/B,OAAM;QACR,CAAC;QACD,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAC3C,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QACvB,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC,EAAE,oBAAoB,CAAC,CAAA;AAC1B,CAAC,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../../src/login/redirect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAG9D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAO,WA2BzC,CAAA"}
1
+ {"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../../src/login/redirect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAG5E;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAAO,WAgDzC,CAAA"}
@@ -1,4 +1,4 @@
1
- import { LoginOutcome } from '@owlmeans/client-auth/login';
1
+ import { revokeToken, LoginOutcome } from '@owlmeans/client-auth/login';
2
2
  import { REDIRECT_LOGIN } from './consts.js';
3
3
  /**
4
4
  * The ordinary login flow: this document leaves for the identity provider and comes back.
@@ -27,5 +27,21 @@ export const makeRedirectLoginPlugin = () => ({
27
27
  },
28
28
  // Nothing to hand anywhere — the token was issued in the document that will use it.
29
29
  complete: async () => LoginOutcome.Passed,
30
+ // `resume` is deliberately NOT implemented. The host defaults to `Passed`, which is "keep the
31
+ // session you already have and carry on" — byte for byte what an ordinary tab has always done.
32
+ // Implementing it here would be the one way to regress every unframed application.
33
+ logout: (ctx, request) => revokeToken(ctx).then(async () => {
34
+ if (request.navigate != null) {
35
+ await request.navigate();
36
+ return LoginOutcome.Handled;
37
+ }
38
+ // A reload rather than a client-side navigation: `useOwlAuth` and its kin read through
39
+ // cached values, so the honest way to make a whole application forget a session is to
40
+ // rebuild it. This is what `useLogout` did inline before the mechanic became a plugin.
41
+ window.location.reload();
42
+ return LoginOutcome.Handled;
43
+ }),
44
+ // Nothing to tell anyone — the session was cleared in the document that owned it.
45
+ logoutComplete: async () => LoginOutcome.Passed,
30
46
  });
31
47
  //# sourceMappingURL=redirect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../../src/login/redirect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAgB,EAAE,CAAC,CAAC;IACzD,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;IAEjB,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC7B,yFAAyF;QACzF,8FAA8F;QAC9F,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC7B,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAA;YAExB,OAAO,YAAY,CAAC,OAAO,CAAA;QAC7B,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAA;QAElC,OAAO,YAAY,CAAC,UAAU,CAAA;IAChC,CAAC;IAED,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC7B,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAA;QAE1B,OAAO,YAAY,CAAC,UAAU,CAAA;IAChC,CAAC;IAED,oFAAoF;IACpF,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM;CAC1C,CAAC,CAAA"}
1
+ {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../../src/login/redirect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAgB,EAAE,CAAC,CAAC;IACzD,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;IAEjB,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC7B,yFAAyF;QACzF,8FAA8F;QAC9F,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC7B,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAA;YAExB,OAAO,YAAY,CAAC,OAAO,CAAA;QAC7B,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAA;QAElC,OAAO,YAAY,CAAC,UAAU,CAAA;IAChC,CAAC;IAED,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC7B,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAA;QAE1B,OAAO,YAAY,CAAC,UAAU,CAAA;IAChC,CAAC;IAED,oFAAoF;IACpF,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM;IAEzC,8FAA8F;IAC9F,+FAA+F;IAC/F,mFAAmF;IAEnF,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,GAAmB,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QACzE,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC7B,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAA;YAExB,OAAO,YAAY,CAAC,OAAO,CAAA;QAC7B,CAAC;QACD,uFAAuF;QACvF,sFAAsF;QACtF,uFAAuF;QACvF,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAA;QAExB,OAAO,YAAY,CAAC,OAAO,CAAA;IAC7B,CAAC,CAAC;IAEF,kFAAkF;IAClF,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM;CAChD,CAAC,CAAA"}
@@ -0,0 +1,15 @@
1
+ import type { FC } from 'react';
2
+ /**
3
+ * The login window an embedded application opens one level up.
4
+ *
5
+ * It is NOT wrapped in `DispatcherHOC`, and that is the point: the HOC's continuation navigates to
6
+ * `HOME` when it has nothing else to do, which is how a popup ended up rendering the whole
7
+ * application, with its navigation, inside itself. This screen has no continuation at all — it
8
+ * either hands something back and closes, or it says what it is waiting for.
9
+ *
10
+ * It also never runs the authorization machine. When there is already a session here, that is the
11
+ * answer, and it goes back to the opener immediately — no provider round trip, no PKCE exchange.
12
+ * When there is not, it forwards to the dispatcher (`next`), which owns that flow.
13
+ */
14
+ export declare const SurrogateScreen: FC;
15
+ //# sourceMappingURL=screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAU/B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,EA+F7B,CAAA"}