@digipair/skill-keycloak 0.89.0 → 0.91.0-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/.swcrc +28 -0
- package/README.md +7 -0
- package/eslint.config.mjs +22 -0
- package/package.json +22 -8
- package/rollup.config.cjs +28 -0
- package/src/handlebars.d.ts +1 -0
- package/src/jsdom.d.ts +1 -0
- package/src/lib/skill-keycloak.spec.ts +7 -0
- package/src/lib/skill-keycloak.ts +531 -0
- package/tsconfig.json +13 -0
- package/tsconfig.lib.json +19 -0
- package/index.cjs.d.ts +0 -1
- package/index.cjs.js +0 -16850
- package/index.esm.js +0 -44880
- package/libs/skill-keycloak/src/lib/skill-keycloak.d.ts +0 -4
- /package/{index.d.ts → src/index.d.ts} +0 -0
- /package/{libs/skill-keycloak/src/index.d.ts → src/index.ts} +0 -0
- /package/{schema.fr.json → src/schema.fr.json} +0 -0
- /package/{schema.json → src/schema.json} +0 -0
package/.swcrc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"jsc": {
|
3
|
+
"target": "es2017",
|
4
|
+
"parser": {
|
5
|
+
"syntax": "typescript",
|
6
|
+
"decorators": true,
|
7
|
+
"dynamicImport": true
|
8
|
+
},
|
9
|
+
"transform": {
|
10
|
+
"decoratorMetadata": true,
|
11
|
+
"legacyDecorator": true
|
12
|
+
},
|
13
|
+
"keepClassNames": true,
|
14
|
+
"externalHelpers": true,
|
15
|
+
"loose": true
|
16
|
+
},
|
17
|
+
"module": {
|
18
|
+
"type": "es6"
|
19
|
+
},
|
20
|
+
"sourceMaps": true,
|
21
|
+
"exclude": [
|
22
|
+
"jest.config.ts",
|
23
|
+
".*\\.spec.tsx?$",
|
24
|
+
".*\\.test.tsx?$",
|
25
|
+
"./src/jest-setup.ts$",
|
26
|
+
"./**/jest-setup.ts$"
|
27
|
+
]
|
28
|
+
}
|
package/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
import baseConfig from '../../eslint.config.mjs';
|
2
|
+
|
3
|
+
export default [
|
4
|
+
...baseConfig,
|
5
|
+
{
|
6
|
+
files: ['**/*.json'],
|
7
|
+
rules: {
|
8
|
+
'@nx/dependency-checks': [
|
9
|
+
'error',
|
10
|
+
{
|
11
|
+
ignoredFiles: [
|
12
|
+
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
13
|
+
'{projectRoot}/rollup.config.{js,ts,mjs,mts,cjs,cts}',
|
14
|
+
],
|
15
|
+
},
|
16
|
+
],
|
17
|
+
},
|
18
|
+
languageOptions: {
|
19
|
+
parser: await import('jsonc-eslint-parser'),
|
20
|
+
},
|
21
|
+
},
|
22
|
+
];
|
package/package.json
CHANGED
@@ -1,14 +1,28 @@
|
|
1
1
|
{
|
2
2
|
"name": "@digipair/skill-keycloak",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.91.0-0",
|
4
|
+
"type": "module",
|
5
|
+
"main": "dist/libs/skill-keycloak/index.cjs.js",
|
6
|
+
"module": "dist/libs/skill-keycloak/index.esm.js",
|
7
|
+
"types": "dist/libs/skill-keycloak/index.esm.d.ts",
|
8
|
+
"exports": {
|
9
|
+
"./package.json": "./libs/skill-keycloak/package.json",
|
10
|
+
".": {
|
11
|
+
"development": "./dist/libs/skill-keycloak/src/index.ts",
|
12
|
+
"types": "./dist/libs/skill-keycloak/index.esm.d.ts",
|
13
|
+
"import": "./dist/libs/skill-keycloak/index.esm.js",
|
14
|
+
"default": "./dist/libs/skill-keycloak/index.cjs.js"
|
15
|
+
}
|
16
|
+
},
|
4
17
|
"keywords": [
|
5
18
|
"digipair",
|
6
|
-
"
|
7
|
-
"
|
19
|
+
"util",
|
20
|
+
"service"
|
8
21
|
],
|
9
|
-
"
|
10
|
-
"
|
22
|
+
"nx": {
|
23
|
+
"name": "skill-keycloak"
|
11
24
|
},
|
12
|
-
"
|
13
|
-
|
14
|
-
}
|
25
|
+
"dependencies": {
|
26
|
+
"@digipair/engine": "0.91.0-0"
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
const { withNx } = require('@nx/rollup/with-nx');
|
2
|
+
|
3
|
+
module.exports = withNx(
|
4
|
+
{
|
5
|
+
main: 'libs/skill-keycloak/src/index.ts',
|
6
|
+
outputPath: 'dist/libs/skill-keycloak',
|
7
|
+
tsConfig: 'libs/skill-keycloak/tsconfig.lib.json',
|
8
|
+
compiler: 'swc',
|
9
|
+
format: ['esm', "cjs"],
|
10
|
+
assets: [
|
11
|
+
{
|
12
|
+
input: 'libs/skill-keycloak/',
|
13
|
+
glob: 'package.json',
|
14
|
+
output: '.'
|
15
|
+
},
|
16
|
+
{
|
17
|
+
input: 'libs/skill-keycloak/src/',
|
18
|
+
glob: '*.json',
|
19
|
+
output: '.'
|
20
|
+
}
|
21
|
+
]
|
22
|
+
},
|
23
|
+
{
|
24
|
+
// Provide additional rollup configuration here. See: https://rollupjs.org/configuration-options
|
25
|
+
// e.g.
|
26
|
+
// output: { sourcemap: true },
|
27
|
+
}
|
28
|
+
);
|
@@ -0,0 +1 @@
|
|
1
|
+
declare module 'handlebars/dist/handlebars.min.js';
|
package/src/jsdom.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
declare module 'jsdom';
|
@@ -0,0 +1,531 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
+
import { PinsSettings, executePinsList, generateElementFromPins } from '@digipair/engine';
|
3
|
+
import * as jwt from 'jsonwebtoken';
|
4
|
+
import { JSDOM } from 'jsdom';
|
5
|
+
import { readFile } from 'fs/promises';
|
6
|
+
import { lookup } from 'mime-types';
|
7
|
+
|
8
|
+
class KeycloakService {
|
9
|
+
private filteredWebPinsSettings(item: any, path: string): any {
|
10
|
+
if (Array.isArray(item)) {
|
11
|
+
return item.map((subItem: any, subIndex: number) =>
|
12
|
+
this.filteredWebPinsSettings(subItem, `${path}[${subIndex}]`),
|
13
|
+
);
|
14
|
+
}
|
15
|
+
|
16
|
+
if (typeof item !== 'object' || item === null) {
|
17
|
+
return item;
|
18
|
+
}
|
19
|
+
|
20
|
+
if (item.library === '@digipair/skill-keycloak' && item.element === 'executeFactory') {
|
21
|
+
return {
|
22
|
+
library: item.library,
|
23
|
+
element: item.element,
|
24
|
+
properties: {
|
25
|
+
path,
|
26
|
+
},
|
27
|
+
};
|
28
|
+
}
|
29
|
+
|
30
|
+
const result = {} as any;
|
31
|
+
Object.entries(item).forEach(([key, value]) => {
|
32
|
+
result[key] = this.filteredWebPinsSettings(value, `${path}.${key}`);
|
33
|
+
});
|
34
|
+
|
35
|
+
return result;
|
36
|
+
}
|
37
|
+
|
38
|
+
private findFactoryPinsSettings(path: string, item: PinsSettings[]): PinsSettings {
|
39
|
+
const pinsSettings = path.split('.').reduce(
|
40
|
+
(acc: any, key: string) => {
|
41
|
+
if (key.indexOf('[') !== -1) {
|
42
|
+
const index = parseInt((key.match(/\d+/) as any[])[0]);
|
43
|
+
return acc[key.split('[')[0]][index];
|
44
|
+
}
|
45
|
+
|
46
|
+
return acc[key];
|
47
|
+
},
|
48
|
+
{ [path.split('[')[0]]: item },
|
49
|
+
);
|
50
|
+
|
51
|
+
return pinsSettings;
|
52
|
+
}
|
53
|
+
|
54
|
+
private async decodedToken(url: string, realm: string, token: string, signal: AbortSignal) {
|
55
|
+
const response = await fetch(`${url}/realms/${realm}/protocol/openid-connect/certs`, {
|
56
|
+
signal,
|
57
|
+
});
|
58
|
+
const infos = await response.json();
|
59
|
+
const publicKey = `-----BEGIN CERTIFICATE-----\n${
|
60
|
+
infos.keys.find(({ alg }: { alg: string; x5c: string }) => alg === 'RS256').x5c[0]
|
61
|
+
}\n-----END CERTIFICATE-----`;
|
62
|
+
const decodedtoken = jwt.verify(token, publicKey, { algorithms: ['RS256'] }) as any;
|
63
|
+
|
64
|
+
return decodedtoken;
|
65
|
+
}
|
66
|
+
|
67
|
+
private prepareBrowserPinsSettings(name: string, pinsSettings: PinsSettings[]): PinsSettings[] {
|
68
|
+
const preparedPinsSettings = pinsSettings.map((item: PinsSettings, index: number) =>
|
69
|
+
this.filteredWebPinsSettings(item, `${name}[${index}]`),
|
70
|
+
) as PinsSettings[];
|
71
|
+
|
72
|
+
return preparedPinsSettings;
|
73
|
+
}
|
74
|
+
|
75
|
+
private mergeConttext(context: any, newContext: any) {
|
76
|
+
const output = { ...context };
|
77
|
+
|
78
|
+
for (const key in newContext) {
|
79
|
+
if (Object.prototype.hasOwnProperty.call(newContext, key)) {
|
80
|
+
if (
|
81
|
+
key !== 'protected' &&
|
82
|
+
typeof newContext[key] === 'object' &&
|
83
|
+
newContext[key] !== null &&
|
84
|
+
!Array.isArray(newContext[key]) &&
|
85
|
+
Object.prototype.hasOwnProperty.call(context, key)
|
86
|
+
) {
|
87
|
+
output[key] = { ...context[key], ...newContext[key] };
|
88
|
+
} else if (typeof newContext[key] !== 'undefined') {
|
89
|
+
output[key] = newContext[key];
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
return output;
|
95
|
+
}
|
96
|
+
|
97
|
+
private async pins2html(pins: PinsSettings[], context: any): Promise<string> {
|
98
|
+
const dom = new JSDOM();
|
99
|
+
const element = dom.window.document.createElement('section');
|
100
|
+
|
101
|
+
await this.generateElementsFromPins(
|
102
|
+
pins,
|
103
|
+
element,
|
104
|
+
{
|
105
|
+
config: {
|
106
|
+
VERSIONS: context.config.VERSIONS || {},
|
107
|
+
},
|
108
|
+
variables: context.variables || {},
|
109
|
+
request: context.request || {},
|
110
|
+
},
|
111
|
+
dom.window.document,
|
112
|
+
);
|
113
|
+
|
114
|
+
return element.innerHTML;
|
115
|
+
}
|
116
|
+
|
117
|
+
private async generateElementsFromPins(
|
118
|
+
pinsList: PinsSettings[],
|
119
|
+
parent: Element,
|
120
|
+
context: any,
|
121
|
+
document: Document,
|
122
|
+
): Promise<void> {
|
123
|
+
for (let i = 0; i < pinsList.length; i++) {
|
124
|
+
const item = pinsList[i];
|
125
|
+
await generateElementFromPins(item, parent, context, document, { import: false });
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
private skillKeycloak = `(() => {
|
130
|
+
class KeycloakService {
|
131
|
+
async authentification() {
|
132
|
+
const keycloak = await this._keycloakPromise;
|
133
|
+
|
134
|
+
if (this.isLogged) {
|
135
|
+
await keycloak.updateToken(60000);
|
136
|
+
}
|
137
|
+
|
138
|
+
return keycloak;
|
139
|
+
}
|
140
|
+
|
141
|
+
async initialize(url, realm, clientId) {
|
142
|
+
this._keycloakPromise = (async () => {
|
143
|
+
const keycloak = new Keycloak({
|
144
|
+
url,
|
145
|
+
realm,
|
146
|
+
clientId,
|
147
|
+
});
|
148
|
+
|
149
|
+
this.isLogged = false;
|
150
|
+
try {
|
151
|
+
this.isLogged = await keycloak.init({
|
152
|
+
onLoad: 'check-sso',
|
153
|
+
silentCheckSsoRedirectUri: window.location.origin + '/public/silent-check-sso.html',
|
154
|
+
});
|
155
|
+
} catch (error) {
|
156
|
+
console.error('keycloak error', error);
|
157
|
+
}
|
158
|
+
|
159
|
+
return keycloak;
|
160
|
+
})();
|
161
|
+
|
162
|
+
await this.authentification();
|
163
|
+
}
|
164
|
+
|
165
|
+
async token() {
|
166
|
+
const authentification = await this.authentification();
|
167
|
+
return authentification.token;
|
168
|
+
}
|
169
|
+
|
170
|
+
async logout(_params, _pinsSettingsList, _context) {
|
171
|
+
const authentification = await this.authentification();
|
172
|
+
authentification.logout();
|
173
|
+
}
|
174
|
+
|
175
|
+
async login(_params, _pinsSettingsList, _context) {
|
176
|
+
const authentification = await this.authentification();
|
177
|
+
await authentification.login();
|
178
|
+
}
|
179
|
+
}
|
180
|
+
const keycloakService = new KeycloakService();
|
181
|
+
return keycloakService;
|
182
|
+
})()`;
|
183
|
+
|
184
|
+
async page(params: any, _pinsSettingsList: PinsSettings[], context: any): Promise<any> {
|
185
|
+
const {
|
186
|
+
body,
|
187
|
+
head,
|
188
|
+
ssr = false,
|
189
|
+
styleHtml = '',
|
190
|
+
styleBody = '',
|
191
|
+
url = context.privates.KEYCLOAK_URL,
|
192
|
+
realm = context.privates.KEYCLOAK_REALM,
|
193
|
+
clientId = context.privates.KEYCLOAK_CLIENTID,
|
194
|
+
factoryInitialize = [],
|
195
|
+
browserInitialize = [],
|
196
|
+
browserLoad = [],
|
197
|
+
confirmBeforeUnload = 'false',
|
198
|
+
logged = [],
|
199
|
+
unlogged = [],
|
200
|
+
factoryUrl = context.privates.FACTORY_URL ||
|
201
|
+
process.env['FACTORY_URL'] ||
|
202
|
+
'https://factory.digipair.ai',
|
203
|
+
} = params;
|
204
|
+
const engineVersion = context.config.VERSIONS['@digipair/engine'] || 'latest';
|
205
|
+
const preparedData = {} as { [key: string]: PinsSettings };
|
206
|
+
|
207
|
+
if (context.request.params[0] === '__digipair_www__') {
|
208
|
+
let result: any;
|
209
|
+
|
210
|
+
try {
|
211
|
+
const fileUrl = context.protected.req.path.split('__digipair_www__/')[1];
|
212
|
+
|
213
|
+
if (!fileUrl) {
|
214
|
+
context.protected.res.status(404);
|
215
|
+
return { status: 'not found' };
|
216
|
+
}
|
217
|
+
|
218
|
+
const regex = /^(.*?[^@]+)@(.*?[^\/]+)\/(.*?.+)$/;
|
219
|
+
const match = fileUrl.match(regex);
|
220
|
+
|
221
|
+
if (!match) {
|
222
|
+
context.protected.res.status(404);
|
223
|
+
return { status: 'not found' };
|
224
|
+
}
|
225
|
+
|
226
|
+
const library = match[1];
|
227
|
+
if (
|
228
|
+
library !== '@digipair/engine' &&
|
229
|
+
!context.config.VERSIONS[library] &&
|
230
|
+
!context.config.WEB_VERSIONS[library]
|
231
|
+
) {
|
232
|
+
context.protected.res.status(404);
|
233
|
+
return { status: 'not found' };
|
234
|
+
}
|
235
|
+
|
236
|
+
if (context.config.VERSIONS[library]) {
|
237
|
+
const infos = require(`${library}/package.json`);
|
238
|
+
if (!(infos.keywords?.indexOf('digipair') >= 0 && infos.keywords?.indexOf('web') >= 0)) {
|
239
|
+
context.protected.res.status(404);
|
240
|
+
return { status: 'not found' };
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
const path = match[3];
|
245
|
+
let filePath = require.resolve(`${library}/${path}`);
|
246
|
+
|
247
|
+
const mimeType = lookup(filePath) || 'application/octet-stream';
|
248
|
+
context.protected.res.setHeader('Content-Type', mimeType);
|
249
|
+
|
250
|
+
result = await readFile(filePath, 'utf8');
|
251
|
+
} catch (error) {
|
252
|
+
context.protected.res.status(404);
|
253
|
+
result = { status: 'not found' };
|
254
|
+
}
|
255
|
+
|
256
|
+
return result;
|
257
|
+
}
|
258
|
+
|
259
|
+
if (
|
260
|
+
context.request.method === 'POST' &&
|
261
|
+
context.request.body?.type === 'DIGIPAIR_EXECUTE_FACTORY'
|
262
|
+
) {
|
263
|
+
const param = context.request.body.params.path.split('[')[0];
|
264
|
+
const pinsSettings = this.findFactoryPinsSettings(
|
265
|
+
context.request.body.params.path,
|
266
|
+
params[param],
|
267
|
+
);
|
268
|
+
const pinsSettingsList = pinsSettings.properties?.['execute'] || [];
|
269
|
+
const token =
|
270
|
+
/^Bearer /g.test(context.request.headers.authorization) &&
|
271
|
+
context.request.headers.authorization?.replace(/^Bearer /g, '');
|
272
|
+
|
273
|
+
if (token) {
|
274
|
+
context.keycloak = {
|
275
|
+
isLogged: true,
|
276
|
+
decodedToken: await this.decodedToken(
|
277
|
+
url,
|
278
|
+
realm,
|
279
|
+
context.request.headers.authorization.replace(/^Bearer /, ''),
|
280
|
+
context.protected?.signal,
|
281
|
+
),
|
282
|
+
};
|
283
|
+
} else {
|
284
|
+
context.keycloak = {
|
285
|
+
isLogged: false,
|
286
|
+
};
|
287
|
+
}
|
288
|
+
|
289
|
+
if (
|
290
|
+
(typeof pinsSettings.properties?.['secured'] === 'undefined' ||
|
291
|
+
pinsSettings.properties?.['secured']) &&
|
292
|
+
!context.keycloak.decodedToken
|
293
|
+
) {
|
294
|
+
throw new Error('Unauthorized');
|
295
|
+
}
|
296
|
+
|
297
|
+
return JSON.stringify(
|
298
|
+
await executePinsList(
|
299
|
+
pinsSettingsList,
|
300
|
+
this.mergeConttext(context.request.body.context, context),
|
301
|
+
`${context.request.body.params.path}.execute`
|
302
|
+
),
|
303
|
+
);
|
304
|
+
}
|
305
|
+
|
306
|
+
const path = context.protected.req.path.replace(/\/$/g, '');
|
307
|
+
const baseUrl =
|
308
|
+
(context.request.headers['x-forwarded-proto'] ?? context.protected.req.protocol) +
|
309
|
+
'://' +
|
310
|
+
context.request.headers.host +
|
311
|
+
(context.request.params.length <= 0 || context.request.params[0] === ''
|
312
|
+
? path
|
313
|
+
: path.substring(0, path.length - context.request.params.join('/').length - 1)) +
|
314
|
+
'/__digipair_www__';
|
315
|
+
|
316
|
+
await executePinsList(factoryInitialize, context, `${context.__PATH__}.factoryInitialize`);
|
317
|
+
|
318
|
+
const html = `
|
319
|
+
<!DOCTYPE html>
|
320
|
+
<html style="${styleHtml}">
|
321
|
+
<head>
|
322
|
+
${
|
323
|
+
head
|
324
|
+
? await this.pins2html(head, context)
|
325
|
+
: `
|
326
|
+
<meta charset="UTF-8" />
|
327
|
+
<title>Digipair</title>
|
328
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
329
|
+
<link rel="icon" type="image/x-icon" href="https://res.cloudinary.com/do87nxq3l/image/upload/fl_preserve_transparency/v1717769492/logo-digipair_oyvvxz.png?_s=public-apps">
|
330
|
+
`
|
331
|
+
}
|
332
|
+
</head>
|
333
|
+
<body style="${styleBody}">
|
334
|
+
<script type="module">
|
335
|
+
import '${url}/js/keycloak.js';
|
336
|
+
import { config, executePinsList, generateElementFromPins, applyTemplate } from '${baseUrl}/@digipair/engine@${engineVersion}/index.esm.js';
|
337
|
+
|
338
|
+
const serverUrl = '${factoryUrl}';
|
339
|
+
const keycloakService = ${this.skillKeycloak};
|
340
|
+
|
341
|
+
const originalFetch = window.fetch;
|
342
|
+
window.fetch = async (url, options) => {
|
343
|
+
if (typeof(url) !== 'string' || !url.includes(serverUrl)) {
|
344
|
+
return originalFetch(url, options);
|
345
|
+
}
|
346
|
+
|
347
|
+
return originalFetch(url, {
|
348
|
+
...options,
|
349
|
+
headers: {
|
350
|
+
...options.headers,
|
351
|
+
'Content-Type': 'application/json',
|
352
|
+
'Authorization': keycloakService.isLogged ? 'Bearer ' + await keycloakService.token() : undefined,
|
353
|
+
},
|
354
|
+
});
|
355
|
+
};
|
356
|
+
|
357
|
+
const skillWeb = {
|
358
|
+
executeFactory: async (params, pinsSettingsList, context) => {
|
359
|
+
const result = await fetch(window.location, {
|
360
|
+
headers: {
|
361
|
+
'Content-Type': 'application/json',
|
362
|
+
'Authorization': keycloakService.isLogged ? 'Bearer ' + await keycloakService.token() : undefined,
|
363
|
+
},
|
364
|
+
body: JSON.stringify({ type: 'DIGIPAIR_EXECUTE_FACTORY', params, pinsSettingsList, context }),
|
365
|
+
method: 'POST',
|
366
|
+
});
|
367
|
+
|
368
|
+
return await result.json();
|
369
|
+
},
|
370
|
+
|
371
|
+
logout: (params, pinsSettingsList, context) =>
|
372
|
+
keycloakService.logout(),
|
373
|
+
|
374
|
+
login: (params, pinsSettingsList, context) =>
|
375
|
+
keycloakService.login(),
|
376
|
+
};
|
377
|
+
|
378
|
+
config.set('LIBRARIES', { '@digipair/skill-keycloak': skillWeb });
|
379
|
+
config.set('BASE_URL', '${baseUrl}');
|
380
|
+
|
381
|
+
// Keycloak initialization
|
382
|
+
await keycloakService.initialize(
|
383
|
+
${JSON.stringify(url)},
|
384
|
+
${JSON.stringify(realm)},
|
385
|
+
${JSON.stringify(clientId)});
|
386
|
+
|
387
|
+
const context = {
|
388
|
+
config: {
|
389
|
+
VERSIONS: ${JSON.stringify(context.config.VERSIONS || {})},
|
390
|
+
},
|
391
|
+
variables: ${JSON.stringify(context.variables || {})},
|
392
|
+
request: ${JSON.stringify(context.request || {})},
|
393
|
+
keycloak: { isLogged: keycloakService.isLogged },
|
394
|
+
__PATH__: '${context.__PATH__}',
|
395
|
+
};
|
396
|
+
|
397
|
+
if (keycloakService.isLogged) {
|
398
|
+
await executePinsList(${JSON.stringify(
|
399
|
+
this.prepareBrowserPinsSettings('logged', logged),
|
400
|
+
)}, context, context.__PATH__ + '.logged');
|
401
|
+
} else {
|
402
|
+
await executePinsList(${JSON.stringify(
|
403
|
+
this.prepareBrowserPinsSettings('unlogged', unlogged),
|
404
|
+
)}, context, context.__PATH__ + '.unlogged');
|
405
|
+
}
|
406
|
+
|
407
|
+
// Pins initialization
|
408
|
+
await executePinsList(${JSON.stringify(
|
409
|
+
this.prepareBrowserPinsSettings('browserInitialize', browserInitialize),
|
410
|
+
)}, context, context.__PATH__ + '.browserInitialize');
|
411
|
+
|
412
|
+
const pinsList = ${JSON.stringify(this.prepareBrowserPinsSettings('body', body))};
|
413
|
+
document.querySelectorAll('body > [data-digipair-pins]').forEach((element) => element.remove()); // Remove SSR elements
|
414
|
+
for (let i = 0; i < pinsList.length; i++) {
|
415
|
+
const item = pinsList[i];
|
416
|
+
await generateElementFromPins(item, document.body, { ...context, data: ${JSON.stringify(
|
417
|
+
preparedData,
|
418
|
+
)} });
|
419
|
+
}
|
420
|
+
|
421
|
+
setTimeout(async () => {
|
422
|
+
await executePinsList(${JSON.stringify(
|
423
|
+
this.prepareBrowserPinsSettings('browserLoad', browserLoad),
|
424
|
+
)}, context, context.__PATH__ + '.browserLoad');
|
425
|
+
}, 1);
|
426
|
+
|
427
|
+
window.addEventListener('beforeunload', (event) => {
|
428
|
+
const showConfirmationMessage = applyTemplate('EVALUATE:' + ${JSON.stringify(confirmBeforeUnload)}, context);
|
429
|
+
|
430
|
+
if (showConfirmationMessage) {
|
431
|
+
event.preventDefault();
|
432
|
+
event.returnValue = '';
|
433
|
+
}
|
434
|
+
});
|
435
|
+
</script>
|
436
|
+
|
437
|
+
${ssr ? await this.pins2html(body, context) : ''}
|
438
|
+
</body>
|
439
|
+
</html>
|
440
|
+
`;
|
441
|
+
|
442
|
+
return html;
|
443
|
+
}
|
444
|
+
|
445
|
+
async service(params: any, _pinsSettingsList: PinsSettings[], context: any): Promise<any> {
|
446
|
+
const {
|
447
|
+
execute,
|
448
|
+
secured = true,
|
449
|
+
url = context.privates.KEYCLOAK_URL,
|
450
|
+
realm = context.privates.KEYCLOAK_REALM,
|
451
|
+
} = params;
|
452
|
+
const token =
|
453
|
+
/^Bearer /g.test(context.request.headers.authorization) &&
|
454
|
+
context.request.headers.authorization?.replace(/^Bearer /g, '');
|
455
|
+
|
456
|
+
if (token) {
|
457
|
+
context.keycloak = {
|
458
|
+
isLogged: true,
|
459
|
+
decodedToken: await this.decodedToken(
|
460
|
+
url,
|
461
|
+
realm,
|
462
|
+
context.request.headers.authorization.replace(/^Bearer /, ''),
|
463
|
+
context.protected?.signal,
|
464
|
+
),
|
465
|
+
};
|
466
|
+
} else {
|
467
|
+
context.keycloak = {
|
468
|
+
isLogged: false,
|
469
|
+
};
|
470
|
+
}
|
471
|
+
|
472
|
+
if (secured && !context.keycloak.decodedToken) {
|
473
|
+
throw new Error('Unauthorized');
|
474
|
+
}
|
475
|
+
|
476
|
+
return await executePinsList(execute, context, `${context.__PATH__}.execute`);
|
477
|
+
}
|
478
|
+
|
479
|
+
async boost(params: any, _pinsSettingsList: PinsSettings[], context: any) {
|
480
|
+
if (context.request.method && context.request.method !== 'POST') {
|
481
|
+
return { error: 'Method not allowed' };
|
482
|
+
}
|
483
|
+
|
484
|
+
const {
|
485
|
+
steps,
|
486
|
+
secured = true,
|
487
|
+
url = context.privates.KEYCLOAK_URL,
|
488
|
+
realm = context.privates.KEYCLOAK_REALM,
|
489
|
+
} = params;
|
490
|
+
const token =
|
491
|
+
/^Bearer /g.test(context.request.headers.authorization) &&
|
492
|
+
context.request.headers.authorization?.replace(/^Bearer /g, '');
|
493
|
+
|
494
|
+
if (token) {
|
495
|
+
context.keycloak = {
|
496
|
+
isLogged: true,
|
497
|
+
decodedToken: await this.decodedToken(
|
498
|
+
url,
|
499
|
+
realm,
|
500
|
+
context.request.headers.authorization.replace(/^Bearer /, ''),
|
501
|
+
context.protected?.signal,
|
502
|
+
),
|
503
|
+
};
|
504
|
+
} else {
|
505
|
+
context.keycloak = {
|
506
|
+
isLogged: false,
|
507
|
+
};
|
508
|
+
}
|
509
|
+
|
510
|
+
if (secured && !context.keycloak.decodedToken) {
|
511
|
+
throw new Error('Unauthorized');
|
512
|
+
}
|
513
|
+
|
514
|
+
const step = context.request.body.step
|
515
|
+
? steps.findIndex(({ name }: any) => name === context.request.body.step)
|
516
|
+
: 0;
|
517
|
+
const execute = steps[step]?.execute || [];
|
518
|
+
|
519
|
+
const result = await executePinsList(execute, { ...context, boost: { steps } }, `${context.__PATH__}.execute`);
|
520
|
+
return result;
|
521
|
+
}
|
522
|
+
}
|
523
|
+
|
524
|
+
export const page = (params: any, pinsSettingsList: PinsSettings[], context: any) =>
|
525
|
+
new KeycloakService().page(params, pinsSettingsList, context);
|
526
|
+
|
527
|
+
export const service = (params: any, pinsSettingsList: PinsSettings[], context: any) =>
|
528
|
+
new KeycloakService().service(params, pinsSettingsList, context);
|
529
|
+
|
530
|
+
export const boost = (params: any, pinsSettingsList: PinsSettings[], context: any) =>
|
531
|
+
new KeycloakService().boost(params, pinsSettingsList, context);
|