@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 +23 -0
- package/frontend/ipc.d.ts +19 -0
- package/frontend/ipc.js +79 -0
- package/package.json +1 -1
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.
|
|
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",
|