@efa-one/sdk 1.17.0 → 1.18.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.
package/README.md CHANGED
@@ -61,6 +61,24 @@ import { initI18n, registerAppInfo, DevHeader } from '@efa-one/sdk/frontend';
61
61
  registerAppInfo({ appName: 'efa-chat', version: __APP_VERSION__ });
62
62
  ```
63
63
 
64
+ ```tsx
65
+ // Frontend — receive the login token from the kernel (inside a mount effect)
66
+ import { subscribeConvergeAuth } from '@efa-one/sdk/frontend';
67
+
68
+ useEffect(() => subscribeConvergeAuth({
69
+ onAuth: async ({ token, serviceKey, theme, language }) => {
70
+ try { await exchange(token, serviceKey); return true; } catch { return false; }
71
+ },
72
+ onTimeout: () => setError('No login received from the platform — reload the page.'),
73
+ }), []);
74
+ ```
75
+
76
+ The app asks for the token itself (`CONVERGE_AUTH_REQUEST`) as soon as its listener
77
+ is attached and repeats the request with backoff. Waiting passively for the kernel's
78
+ push is not enough: the push goes out in a fixed window after the tile opens, and an
79
+ app that needs longer to mount (cold cache, slow connection) would miss it and spin
80
+ forever.
81
+
64
82
  ```tsx
65
83
  // Frontend — a fully-featured list in a few lines
66
84
  import { DataTable, type ColumnDef } from '@efa-one/sdk/frontend/ui';
@@ -152,6 +170,11 @@ kernel without that endpoint, every authenticated request fails closed with
152
170
  Sessions issued by an older SDK are rejected once (401) and renewed on the next
153
171
  iframe load.
154
172
 
173
+ **1.18.0 — auth handshake on request.** `subscribeConvergeAuth` sends
174
+ `CONVERGE_AUTH_REQUEST` to the kernel. It works against any kernel: an older kernel
175
+ ignores the request and its fixed-window push reaches the app as before; a current
176
+ kernel answers the request directly. No rollout order.
177
+
155
178
  ## License
156
179
 
157
180
  [Apache-2.0](./LICENSE) — permissive with a patent grant, so customers and partners
package/frontend/ipc.d.ts CHANGED
@@ -24,3 +24,22 @@ export declare function navigateToApp(serviceKey: string, options?: {
24
24
  path?: string;
25
25
  }): void;
26
26
  export declare function notifyRouteChange(path: string): void;
27
+ export declare const CONVERGE_AUTH = "CONVERGE_AUTH";
28
+ export declare const CONVERGE_AUTH_REQUEST = "CONVERGE_AUTH_REQUEST";
29
+ export interface ConvergeAuthMessage<TTheme = unknown> {
30
+ type: typeof CONVERGE_AUTH;
31
+ token: string;
32
+ serviceKey?: string;
33
+ language?: string;
34
+ theme?: TTheme;
35
+ embed?: boolean;
36
+ }
37
+ export interface SubscribeConvergeAuthOptions<TTheme = unknown> {
38
+ onAuth: (message: ConvergeAuthMessage<TTheme>) => Promise<boolean>;
39
+ onTimeout?: () => void;
40
+ requestDelaysMs?: readonly number[];
41
+ timeoutMs?: number;
42
+ }
43
+ export declare const DEFAULT_AUTH_REQUEST_DELAYS_MS: readonly number[];
44
+ export declare const DEFAULT_AUTH_TIMEOUT_MS = 15000;
45
+ export declare function subscribeConvergeAuth<TTheme = unknown>(options: SubscribeConvergeAuthOptions<TTheme>): () => void;
package/frontend/ipc.js CHANGED
@@ -59,3 +59,82 @@ export function notifyRouteChange(path) {
59
59
  return;
60
60
  window.parent.postMessage({ type: 'CONVERGE_ROUTE_CHANGED', path }, getParentOrigin());
61
61
  }
62
+ export const CONVERGE_AUTH = 'CONVERGE_AUTH';
63
+ export const CONVERGE_AUTH_REQUEST = 'CONVERGE_AUTH_REQUEST';
64
+ export const DEFAULT_AUTH_REQUEST_DELAYS_MS = [0, 500, 1000, 2000, 4000, 8000];
65
+ export const DEFAULT_AUTH_TIMEOUT_MS = 15000;
66
+ function isAuthMessage(data) {
67
+ const d = data;
68
+ return !!d && d.type === CONVERGE_AUTH && typeof d.token === 'string' && d.token !== '';
69
+ }
70
+ export function subscribeConvergeAuth(options) {
71
+ if (!isEmbedded())
72
+ return () => { };
73
+ const delays = options.requestDelaysMs ?? DEFAULT_AUTH_REQUEST_DELAYS_MS;
74
+ const timeoutMs = options.timeoutMs ?? DEFAULT_AUTH_TIMEOUT_MS;
75
+ let active = true;
76
+ let received = false;
77
+ let authenticated = false;
78
+ let inFlight = false;
79
+ let queued = null;
80
+ const timers = [];
81
+ const clearTimers = () => {
82
+ timers.forEach((t) => clearTimeout(t));
83
+ timers.length = 0;
84
+ };
85
+ const start = (message) => {
86
+ inFlight = true;
87
+ options.onAuth(message).then((ok) => finish(ok), () => finish(false));
88
+ };
89
+ const finish = (ok) => {
90
+ inFlight = false;
91
+ if (!active)
92
+ return;
93
+ if (ok) {
94
+ authenticated = true;
95
+ queued = null;
96
+ clearTimers();
97
+ return;
98
+ }
99
+ const next = queued;
100
+ queued = null;
101
+ if (next)
102
+ start(next);
103
+ };
104
+ const handler = (event) => {
105
+ if (!isFromPlatformParent(event))
106
+ return;
107
+ if (!isAuthMessage(event.data))
108
+ return;
109
+ received = true;
110
+ if (authenticated)
111
+ return;
112
+ const message = event.data;
113
+ if (inFlight) {
114
+ queued = message;
115
+ return;
116
+ }
117
+ start(message);
118
+ };
119
+ const request = () => {
120
+ if (!active || received)
121
+ return;
122
+ window.parent.postMessage({ type: CONVERGE_AUTH_REQUEST }, getParentOrigin());
123
+ };
124
+ window.addEventListener('message', handler);
125
+ for (const ms of delays) {
126
+ if (ms <= 0)
127
+ request();
128
+ else
129
+ timers.push(setTimeout(request, ms));
130
+ }
131
+ timers.push(setTimeout(() => {
132
+ if (active && !received)
133
+ options.onTimeout?.();
134
+ }, timeoutMs));
135
+ return () => {
136
+ active = false;
137
+ clearTimers();
138
+ window.removeEventListener('message', handler);
139
+ };
140
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@efa-one/sdk",
3
- "version": "1.17.0",
3
+ "version": "1.18.0",
4
4
  "description": "Offizielles SDK für efa-one-Apps: Auth/Session, Service-Discovery, Gateway-Client, Audit/Reporting/Mail/Notifications, Permission- und Capability-Registrierung sowie das Frontend-IPC-/i18n-Toolkit.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",