samlesa 2.12.3 → 2.12.6

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.

Potentially problematic release.


This version of samlesa might be problematic. Click here for more details.

Files changed (66) hide show
  1. package/build/index.js +54 -64
  2. package/build/index.js.map +1 -1
  3. package/build/src/api.js +24 -23
  4. package/build/src/api.js.map +1 -1
  5. package/build/src/binding-post.js +358 -368
  6. package/build/src/binding-post.js.map +1 -1
  7. package/build/src/binding-redirect.js +333 -332
  8. package/build/src/binding-redirect.js.map +1 -1
  9. package/build/src/binding-simplesign.js +222 -232
  10. package/build/src/binding-simplesign.js.map +1 -1
  11. package/build/src/entity-idp.js +132 -130
  12. package/build/src/entity-idp.js.map +1 -1
  13. package/build/src/entity-sp.js +96 -96
  14. package/build/src/entity-sp.js.map +1 -1
  15. package/build/src/entity.js +225 -235
  16. package/build/src/entity.js.map +1 -1
  17. package/build/src/extractor.js +369 -369
  18. package/build/src/extractor.js.map +1 -1
  19. package/build/src/flow.js +320 -319
  20. package/build/src/flow.js.map +1 -1
  21. package/build/src/libsaml.js +660 -641
  22. package/build/src/libsaml.js.map +1 -1
  23. package/build/src/metadata-idp.js +127 -127
  24. package/build/src/metadata-idp.js.map +1 -1
  25. package/build/src/metadata-sp.js +231 -231
  26. package/build/src/metadata-sp.js.map +1 -1
  27. package/build/src/metadata.js +166 -176
  28. package/build/src/metadata.js.map +1 -1
  29. package/build/src/types.js +11 -11
  30. package/build/src/urn.js +212 -212
  31. package/build/src/urn.js.map +1 -1
  32. package/build/src/utility.js +292 -248
  33. package/build/src/utility.js.map +1 -1
  34. package/build/src/validator.js +27 -26
  35. package/build/src/validator.js.map +1 -1
  36. package/index.d.ts +10 -10
  37. package/index.js +18 -18
  38. package/package.json +1 -5
  39. package/qodana.yaml +29 -29
  40. package/src/binding-post.ts +1 -1
  41. package/src/binding-redirect.ts +83 -64
  42. package/src/entity-idp.ts +26 -20
  43. package/src/libsaml.ts +79 -48
  44. package/src/utility.ts +147 -76
  45. package/types/index.d.ts +10 -10
  46. package/types/src/api.d.ts +13 -13
  47. package/types/src/binding-post.d.ts +46 -46
  48. package/types/src/binding-redirect.d.ts +52 -52
  49. package/types/src/binding-simplesign.d.ts +39 -39
  50. package/types/src/entity-idp.d.ts +35 -42
  51. package/types/src/entity-sp.d.ts +36 -36
  52. package/types/src/entity.d.ts +101 -99
  53. package/types/src/extractor.d.ts +25 -25
  54. package/types/src/flow.d.ts +6 -6
  55. package/types/src/libsaml.d.ts +200 -210
  56. package/types/src/metadata-idp.d.ts +24 -24
  57. package/types/src/metadata-sp.d.ts +36 -36
  58. package/types/src/metadata.d.ts +59 -57
  59. package/types/src/types.d.ts +129 -127
  60. package/types/src/urn.d.ts +194 -194
  61. package/types/src/utility.d.ts +134 -134
  62. package/types/src/validator.d.ts +3 -3
  63. package/.idea/compiler.xml +0 -6
  64. package/.idea/deployment.xml +0 -14
  65. package/.idea/jsLibraryMappings.xml +0 -6
  66. package/build/.idea/workspace.xml +0 -58
@@ -1,370 +1,370 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.logoutResponseFields = exports.logoutRequestFields = exports.loginResponseFields = exports.logoutResponseStatusFields = exports.loginResponseStatusFields = exports.loginRequestFields = void 0;
7
- exports.extract = extract;
8
- const xpath_1 = require("xpath");
9
- const utility_js_1 = require("./utility.js");
10
- const api_js_1 = require("./api.js");
11
- const camelcase_1 = __importDefault(require("camelcase"));
12
- function buildAbsoluteXPath(paths) {
13
- return paths.reduce((currentPath, name) => {
14
- let appendedPath = currentPath;
15
- const isWildcard = name.startsWith('~');
16
- if (isWildcard) {
17
- const pathName = name.replace('~', '');
18
- appendedPath = currentPath + `/*[contains(local-name(), '${pathName}')]`;
19
- }
20
- if (!isWildcard) {
21
- appendedPath = currentPath + `/*[local-name(.)='${name}']`;
22
- }
23
- return appendedPath;
24
- }, '');
25
- }
26
- function buildAttributeXPath(attributes) {
27
- if (attributes.length === 0) {
28
- return '/text()';
29
- }
30
- if (attributes.length === 1) {
31
- return `/@${attributes[0]}`;
32
- }
33
- const filters = attributes.map(attribute => `name()='${attribute}'`).join(' or ');
34
- return `/@*[${filters}]`;
35
- }
36
- exports.loginRequestFields = [
37
- {
38
- key: 'request',
39
- localPath: ['AuthnRequest'],
40
- attributes: ['ID', 'IssueInstant', 'Destination', 'AssertionConsumerServiceURL']
41
- },
42
- {
43
- key: 'issuer',
44
- localPath: ['AuthnRequest', 'Issuer'],
45
- attributes: []
46
- },
47
- {
48
- key: 'nameIDPolicy',
49
- localPath: ['AuthnRequest', 'NameIDPolicy'],
50
- attributes: ['Format', 'AllowCreate']
51
- },
52
- {
53
- key: 'authnContextClassRef',
54
- localPath: ['AuthnRequest', 'AuthnContextClassRef'],
55
- attributes: []
56
- },
57
- {
58
- key: 'signature',
59
- localPath: ['AuthnRequest', 'Signature'],
60
- attributes: [],
61
- context: true
62
- }
63
- ];
64
- // support two-tiers status code
65
- exports.loginResponseStatusFields = [
66
- {
67
- key: 'top',
68
- localPath: ['Response', 'Status', 'StatusCode'],
69
- attributes: ['Value'],
70
- },
71
- {
72
- key: 'second',
73
- localPath: ['Response', 'Status', 'StatusCode', 'StatusCode'],
74
- attributes: ['Value'],
75
- }
76
- ];
77
- // support two-tiers status code
78
- exports.logoutResponseStatusFields = [
79
- {
80
- key: 'top',
81
- localPath: ['LogoutResponse', 'Status', 'StatusCode'],
82
- attributes: ['Value']
83
- },
84
- {
85
- key: 'second',
86
- localPath: ['LogoutResponse', 'Status', 'StatusCode', 'StatusCode'],
87
- attributes: ['Value'],
88
- }
89
- ];
90
- const loginResponseFields = assertion => [
91
- {
92
- key: 'conditions',
93
- localPath: ['Assertion', 'Conditions'],
94
- attributes: ['NotBefore', 'NotOnOrAfter'],
95
- shortcut: assertion
96
- },
97
- {
98
- key: 'response',
99
- localPath: ['Response'],
100
- attributes: ['ID', 'IssueInstant', 'Destination', 'InResponseTo'],
101
- },
102
- {
103
- key: 'audience',
104
- localPath: ['Assertion', 'Conditions', 'AudienceRestriction', 'Audience'],
105
- attributes: [],
106
- shortcut: assertion
107
- },
108
- // {
109
- // key: 'issuer',
110
- // localPath: ['Response', 'Issuer'],
111
- // attributes: []
112
- // },
113
- {
114
- key: 'issuer',
115
- localPath: ['Assertion', 'Issuer'],
116
- attributes: [],
117
- shortcut: assertion
118
- },
119
- {
120
- key: 'nameID',
121
- localPath: ['Assertion', 'Subject', 'NameID'],
122
- attributes: [],
123
- shortcut: assertion
124
- },
125
- {
126
- key: 'sessionIndex',
127
- localPath: ['Assertion', 'AuthnStatement'],
128
- attributes: ['AuthnInstant', 'SessionNotOnOrAfter', 'SessionIndex'],
129
- shortcut: assertion
130
- },
131
- {
132
- key: 'attributes',
133
- localPath: ['Assertion', 'AttributeStatement', 'Attribute'],
134
- index: ['Name'],
135
- attributePath: ['AttributeValue'],
136
- attributes: [],
137
- shortcut: assertion
138
- }
139
- ];
140
- exports.loginResponseFields = loginResponseFields;
141
- exports.logoutRequestFields = [
142
- {
143
- key: 'request',
144
- localPath: ['LogoutRequest'],
145
- attributes: ['ID', 'IssueInstant', 'Destination']
146
- },
147
- {
148
- key: 'issuer',
149
- localPath: ['LogoutRequest', 'Issuer'],
150
- attributes: []
151
- },
152
- {
153
- key: 'nameID',
154
- localPath: ['LogoutRequest', 'NameID'],
155
- attributes: []
156
- },
157
- {
158
- key: 'sessionIndex',
159
- localPath: ['LogoutRequest', 'SessionIndex'],
160
- attributes: []
161
- },
162
- {
163
- key: 'signature',
164
- localPath: ['LogoutRequest', 'Signature'],
165
- attributes: [],
166
- context: true
167
- }
168
- ];
169
- exports.logoutResponseFields = [
170
- {
171
- key: 'response',
172
- localPath: ['LogoutResponse'],
173
- attributes: ['ID', 'Destination', 'InResponseTo']
174
- },
175
- {
176
- key: 'issuer',
177
- localPath: ['LogoutResponse', 'Issuer'],
178
- attributes: []
179
- },
180
- {
181
- key: 'signature',
182
- localPath: ['LogoutResponse', 'Signature'],
183
- attributes: [],
184
- context: true
185
- }
186
- ];
187
- function extract(context, fields) {
188
- const { dom } = (0, api_js_1.getContext)();
189
- const rootDoc = dom.parseFromString(context);
190
- return fields.reduce((result, field) => {
191
- // get essential fields
192
- const key = field.key;
193
- const localPath = field.localPath;
194
- const attributes = field.attributes;
195
- const isEntire = field.context;
196
- const shortcut = field.shortcut;
197
- // get optional fields
198
- const index = field.index;
199
- const attributePath = field.attributePath;
200
- // set allowing overriding if there is a shortcut injected
201
- let targetDoc = rootDoc;
202
- // if shortcut is used, then replace the doc
203
- // it's a design for overriding the doc used during runtime
204
- if (shortcut) {
205
- targetDoc = dom.parseFromString(shortcut);
206
- }
207
- // special case: multiple path
208
- /*
209
- {
210
- key: 'issuer',
211
- localPath: [
212
- ['Response', 'Issuer'],
213
- ['Response', 'Assertion', 'Issuer']
214
- ],
215
- attributes: []
216
- }
217
- */
218
- if (localPath.every(path => Array.isArray(path))) {
219
- const multiXPaths = localPath
220
- .map(path => {
221
- // not support attribute yet, so ignore it
222
- return `${buildAbsoluteXPath(path)}/text()`;
223
- })
224
- .join(' | ');
225
- return {
226
- ...result,
227
- [key]: (0, utility_js_1.uniq)((0, xpath_1.select)(multiXPaths, targetDoc).map((n) => n.nodeValue).filter(utility_js_1.notEmpty))
228
- };
229
- }
230
- // eo special case: multiple path
231
- const baseXPath = buildAbsoluteXPath(localPath);
232
- const attributeXPath = buildAttributeXPath(attributes);
233
- // special case: get attributes where some are in child, some are in parent
234
- /*
235
- {
236
- key: 'attributes',
237
- localPath: ['Response', 'Assertion', 'AttributeStatement', 'Attribute'],
238
- index: ['Name'],
239
- attributePath: ['AttributeValue'],
240
- attributes: []
241
- }
242
- */
243
- if (index && attributePath) {
244
- // find the index in localpath
245
- const indexPath = buildAttributeXPath(index);
246
- const fullLocalXPath = `${baseXPath}${indexPath}`;
247
- const parentNodes = (0, xpath_1.select)(baseXPath, targetDoc);
248
- // [uid, mail, edupersonaffiliation], ready for aggregate
249
- const parentAttributes = (0, xpath_1.select)(fullLocalXPath, targetDoc).map((n) => n.value);
250
- // [attribute, attributevalue]
251
- const childXPath = buildAbsoluteXPath([(0, utility_js_1.last)(localPath)].concat(attributePath));
252
- const childAttributeXPath = buildAttributeXPath(attributes);
253
- const fullChildXPath = `${childXPath}${childAttributeXPath}`;
254
- // [ 'test', 'test@example.com', [ 'users', 'examplerole1' ] ]
255
- const childAttributes = parentNodes.map(node => {
256
- const nodeDoc = dom.parseFromString(node.toString());
257
- if (attributes.length === 0) {
258
- const childValues = (0, xpath_1.select)(fullChildXPath, nodeDoc).map((n) => n.nodeValue);
259
- if (childValues.length === 1) {
260
- return childValues[0];
261
- }
262
- return childValues;
263
- }
264
- if (attributes.length > 0) {
265
- const childValues = (0, xpath_1.select)(fullChildXPath, nodeDoc).map((n) => n.value);
266
- if (childValues.length === 1) {
267
- return childValues[0];
268
- }
269
- return childValues;
270
- }
271
- return null;
272
- });
273
- // aggregation
274
- const obj = (0, utility_js_1.zipObject)(parentAttributes, childAttributes, false);
275
- return {
276
- ...result,
277
- [key]: obj
278
- };
279
- }
280
- // case: fetch entire content, only allow one existence
281
- /*
282
- {
283
- key: 'signature',
284
- localPath: ['AuthnRequest', 'Signature'],
285
- attributes: [],
286
- context: true
287
- }
288
- */
289
- if (isEntire) {
290
- const node = (0, xpath_1.select)(baseXPath, targetDoc);
291
- let value = null;
292
- if (node.length === 1) {
293
- value = node[0].toString();
294
- }
295
- if (node.length > 1) {
296
- value = node.map(n => n.toString());
297
- }
298
- return {
299
- ...result,
300
- [key]: value
301
- };
302
- }
303
- // case: multiple attribute
304
- /*
305
- {
306
- key: 'nameIDPolicy',
307
- localPath: ['AuthnRequest', 'NameIDPolicy'],
308
- attributes: ['Format', 'AllowCreate']
309
- }
310
- */
311
- if (attributes.length > 1) {
312
- const baseNode = (0, xpath_1.select)(baseXPath, targetDoc).map(n => n.toString());
313
- const childXPath = `${buildAbsoluteXPath([(0, utility_js_1.last)(localPath)])}${attributeXPath}`;
314
- const attributeValues = baseNode.map((node) => {
315
- const nodeDoc = dom.parseFromString(node);
316
- const values = (0, xpath_1.select)(childXPath, nodeDoc).reduce((r, n) => {
317
- r[(0, camelcase_1.default)(n.name, { locale: 'en-us' })] = n.value;
318
- return r;
319
- }, {});
320
- return values;
321
- });
322
- return {
323
- ...result,
324
- [key]: attributeValues.length === 1 ? attributeValues[0] : attributeValues
325
- };
326
- }
327
- // case: single attribute
328
- /*
329
- {
330
- key: 'statusCode',
331
- localPath: ['Response', 'Status', 'StatusCode'],
332
- attributes: ['Value'],
333
- }
334
- */
335
- if (attributes.length === 1) {
336
- const fullPath = `${baseXPath}${attributeXPath}`;
337
- const attributeValues = (0, xpath_1.select)(fullPath, targetDoc).map((n) => n.value);
338
- return {
339
- ...result,
340
- [key]: attributeValues[0]
341
- };
342
- }
343
- // case: zero attribute
344
- /*
345
- {
346
- key: 'issuer',
347
- localPath: ['AuthnRequest', 'Issuer'],
348
- attributes: []
349
- }
350
- */
351
- if (attributes.length === 0) {
352
- let attributeValue = null;
353
- const node = (0, xpath_1.select)(baseXPath, targetDoc);
354
- if (node.length === 1) {
355
- const fullPath = `string(${baseXPath}${attributeXPath})`;
356
- attributeValue = (0, xpath_1.select)(fullPath, targetDoc);
357
- }
358
- if (node.length > 1) {
359
- attributeValue = node.filter((n) => n.firstChild)
360
- .map((n) => n.firstChild.nodeValue);
361
- }
362
- return {
363
- ...result,
364
- [key]: attributeValue
365
- };
366
- }
367
- return result;
368
- }, {});
369
- }
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.extract = exports.logoutResponseFields = exports.logoutRequestFields = exports.loginResponseFields = exports.logoutResponseStatusFields = exports.loginResponseStatusFields = exports.loginRequestFields = void 0;
7
+ const xpath_1 = require("xpath");
8
+ const utility_js_1 = require("./utility.js");
9
+ const api_js_1 = require("./api.js");
10
+ const camelcase_1 = __importDefault(require("camelcase"));
11
+ function buildAbsoluteXPath(paths) {
12
+ return paths.reduce((currentPath, name) => {
13
+ let appendedPath = currentPath;
14
+ const isWildcard = name.startsWith('~');
15
+ if (isWildcard) {
16
+ const pathName = name.replace('~', '');
17
+ appendedPath = currentPath + `/*[contains(local-name(), '${pathName}')]`;
18
+ }
19
+ if (!isWildcard) {
20
+ appendedPath = currentPath + `/*[local-name(.)='${name}']`;
21
+ }
22
+ return appendedPath;
23
+ }, '');
24
+ }
25
+ function buildAttributeXPath(attributes) {
26
+ if (attributes.length === 0) {
27
+ return '/text()';
28
+ }
29
+ if (attributes.length === 1) {
30
+ return `/@${attributes[0]}`;
31
+ }
32
+ const filters = attributes.map(attribute => `name()='${attribute}'`).join(' or ');
33
+ return `/@*[${filters}]`;
34
+ }
35
+ exports.loginRequestFields = [
36
+ {
37
+ key: 'request',
38
+ localPath: ['AuthnRequest'],
39
+ attributes: ['ID', 'IssueInstant', 'Destination', 'AssertionConsumerServiceURL']
40
+ },
41
+ {
42
+ key: 'issuer',
43
+ localPath: ['AuthnRequest', 'Issuer'],
44
+ attributes: []
45
+ },
46
+ {
47
+ key: 'nameIDPolicy',
48
+ localPath: ['AuthnRequest', 'NameIDPolicy'],
49
+ attributes: ['Format', 'AllowCreate']
50
+ },
51
+ {
52
+ key: 'authnContextClassRef',
53
+ localPath: ['AuthnRequest', 'AuthnContextClassRef'],
54
+ attributes: []
55
+ },
56
+ {
57
+ key: 'signature',
58
+ localPath: ['AuthnRequest', 'Signature'],
59
+ attributes: [],
60
+ context: true
61
+ }
62
+ ];
63
+ // support two-tiers status code
64
+ exports.loginResponseStatusFields = [
65
+ {
66
+ key: 'top',
67
+ localPath: ['Response', 'Status', 'StatusCode'],
68
+ attributes: ['Value'],
69
+ },
70
+ {
71
+ key: 'second',
72
+ localPath: ['Response', 'Status', 'StatusCode', 'StatusCode'],
73
+ attributes: ['Value'],
74
+ }
75
+ ];
76
+ // support two-tiers status code
77
+ exports.logoutResponseStatusFields = [
78
+ {
79
+ key: 'top',
80
+ localPath: ['LogoutResponse', 'Status', 'StatusCode'],
81
+ attributes: ['Value']
82
+ },
83
+ {
84
+ key: 'second',
85
+ localPath: ['LogoutResponse', 'Status', 'StatusCode', 'StatusCode'],
86
+ attributes: ['Value'],
87
+ }
88
+ ];
89
+ const loginResponseFields = assertion => [
90
+ {
91
+ key: 'conditions',
92
+ localPath: ['Assertion', 'Conditions'],
93
+ attributes: ['NotBefore', 'NotOnOrAfter'],
94
+ shortcut: assertion
95
+ },
96
+ {
97
+ key: 'response',
98
+ localPath: ['Response'],
99
+ attributes: ['ID', 'IssueInstant', 'Destination', 'InResponseTo'],
100
+ },
101
+ {
102
+ key: 'audience',
103
+ localPath: ['Assertion', 'Conditions', 'AudienceRestriction', 'Audience'],
104
+ attributes: [],
105
+ shortcut: assertion
106
+ },
107
+ // {
108
+ // key: 'issuer',
109
+ // localPath: ['Response', 'Issuer'],
110
+ // attributes: []
111
+ // },
112
+ {
113
+ key: 'issuer',
114
+ localPath: ['Assertion', 'Issuer'],
115
+ attributes: [],
116
+ shortcut: assertion
117
+ },
118
+ {
119
+ key: 'nameID',
120
+ localPath: ['Assertion', 'Subject', 'NameID'],
121
+ attributes: [],
122
+ shortcut: assertion
123
+ },
124
+ {
125
+ key: 'sessionIndex',
126
+ localPath: ['Assertion', 'AuthnStatement'],
127
+ attributes: ['AuthnInstant', 'SessionNotOnOrAfter', 'SessionIndex'],
128
+ shortcut: assertion
129
+ },
130
+ {
131
+ key: 'attributes',
132
+ localPath: ['Assertion', 'AttributeStatement', 'Attribute'],
133
+ index: ['Name'],
134
+ attributePath: ['AttributeValue'],
135
+ attributes: [],
136
+ shortcut: assertion
137
+ }
138
+ ];
139
+ exports.loginResponseFields = loginResponseFields;
140
+ exports.logoutRequestFields = [
141
+ {
142
+ key: 'request',
143
+ localPath: ['LogoutRequest'],
144
+ attributes: ['ID', 'IssueInstant', 'Destination']
145
+ },
146
+ {
147
+ key: 'issuer',
148
+ localPath: ['LogoutRequest', 'Issuer'],
149
+ attributes: []
150
+ },
151
+ {
152
+ key: 'nameID',
153
+ localPath: ['LogoutRequest', 'NameID'],
154
+ attributes: []
155
+ },
156
+ {
157
+ key: 'sessionIndex',
158
+ localPath: ['LogoutRequest', 'SessionIndex'],
159
+ attributes: []
160
+ },
161
+ {
162
+ key: 'signature',
163
+ localPath: ['LogoutRequest', 'Signature'],
164
+ attributes: [],
165
+ context: true
166
+ }
167
+ ];
168
+ exports.logoutResponseFields = [
169
+ {
170
+ key: 'response',
171
+ localPath: ['LogoutResponse'],
172
+ attributes: ['ID', 'Destination', 'InResponseTo']
173
+ },
174
+ {
175
+ key: 'issuer',
176
+ localPath: ['LogoutResponse', 'Issuer'],
177
+ attributes: []
178
+ },
179
+ {
180
+ key: 'signature',
181
+ localPath: ['LogoutResponse', 'Signature'],
182
+ attributes: [],
183
+ context: true
184
+ }
185
+ ];
186
+ function extract(context, fields) {
187
+ const { dom } = (0, api_js_1.getContext)();
188
+ const rootDoc = dom.parseFromString(context);
189
+ return fields.reduce((result, field) => {
190
+ // get essential fields
191
+ const key = field.key;
192
+ const localPath = field.localPath;
193
+ const attributes = field.attributes;
194
+ const isEntire = field.context;
195
+ const shortcut = field.shortcut;
196
+ // get optional fields
197
+ const index = field.index;
198
+ const attributePath = field.attributePath;
199
+ // set allowing overriding if there is a shortcut injected
200
+ let targetDoc = rootDoc;
201
+ // if shortcut is used, then replace the doc
202
+ // it's a design for overriding the doc used during runtime
203
+ if (shortcut) {
204
+ targetDoc = dom.parseFromString(shortcut);
205
+ }
206
+ // special case: multiple path
207
+ /*
208
+ {
209
+ key: 'issuer',
210
+ localPath: [
211
+ ['Response', 'Issuer'],
212
+ ['Response', 'Assertion', 'Issuer']
213
+ ],
214
+ attributes: []
215
+ }
216
+ */
217
+ if (localPath.every(path => Array.isArray(path))) {
218
+ const multiXPaths = localPath
219
+ .map(path => {
220
+ // not support attribute yet, so ignore it
221
+ return `${buildAbsoluteXPath(path)}/text()`;
222
+ })
223
+ .join(' | ');
224
+ return {
225
+ ...result,
226
+ [key]: (0, utility_js_1.uniq)((0, xpath_1.select)(multiXPaths, targetDoc).map((n) => n.nodeValue).filter(utility_js_1.notEmpty))
227
+ };
228
+ }
229
+ // eo special case: multiple path
230
+ const baseXPath = buildAbsoluteXPath(localPath);
231
+ const attributeXPath = buildAttributeXPath(attributes);
232
+ // special case: get attributes where some are in child, some are in parent
233
+ /*
234
+ {
235
+ key: 'attributes',
236
+ localPath: ['Response', 'Assertion', 'AttributeStatement', 'Attribute'],
237
+ index: ['Name'],
238
+ attributePath: ['AttributeValue'],
239
+ attributes: []
240
+ }
241
+ */
242
+ if (index && attributePath) {
243
+ // find the index in localpath
244
+ const indexPath = buildAttributeXPath(index);
245
+ const fullLocalXPath = `${baseXPath}${indexPath}`;
246
+ const parentNodes = (0, xpath_1.select)(baseXPath, targetDoc);
247
+ // [uid, mail, edupersonaffiliation], ready for aggregate
248
+ const parentAttributes = (0, xpath_1.select)(fullLocalXPath, targetDoc).map((n) => n.value);
249
+ // [attribute, attributevalue]
250
+ const childXPath = buildAbsoluteXPath([(0, utility_js_1.last)(localPath)].concat(attributePath));
251
+ const childAttributeXPath = buildAttributeXPath(attributes);
252
+ const fullChildXPath = `${childXPath}${childAttributeXPath}`;
253
+ // [ 'test', 'test@example.com', [ 'users', 'examplerole1' ] ]
254
+ const childAttributes = parentNodes.map(node => {
255
+ const nodeDoc = dom.parseFromString(node.toString());
256
+ if (attributes.length === 0) {
257
+ const childValues = (0, xpath_1.select)(fullChildXPath, nodeDoc).map((n) => n.nodeValue);
258
+ if (childValues.length === 1) {
259
+ return childValues[0];
260
+ }
261
+ return childValues;
262
+ }
263
+ if (attributes.length > 0) {
264
+ const childValues = (0, xpath_1.select)(fullChildXPath, nodeDoc).map((n) => n.value);
265
+ if (childValues.length === 1) {
266
+ return childValues[0];
267
+ }
268
+ return childValues;
269
+ }
270
+ return null;
271
+ });
272
+ // aggregation
273
+ const obj = (0, utility_js_1.zipObject)(parentAttributes, childAttributes, false);
274
+ return {
275
+ ...result,
276
+ [key]: obj
277
+ };
278
+ }
279
+ // case: fetch entire content, only allow one existence
280
+ /*
281
+ {
282
+ key: 'signature',
283
+ localPath: ['AuthnRequest', 'Signature'],
284
+ attributes: [],
285
+ context: true
286
+ }
287
+ */
288
+ if (isEntire) {
289
+ const node = (0, xpath_1.select)(baseXPath, targetDoc);
290
+ let value = null;
291
+ if (node.length === 1) {
292
+ value = node[0].toString();
293
+ }
294
+ if (node.length > 1) {
295
+ value = node.map(n => n.toString());
296
+ }
297
+ return {
298
+ ...result,
299
+ [key]: value
300
+ };
301
+ }
302
+ // case: multiple attribute
303
+ /*
304
+ {
305
+ key: 'nameIDPolicy',
306
+ localPath: ['AuthnRequest', 'NameIDPolicy'],
307
+ attributes: ['Format', 'AllowCreate']
308
+ }
309
+ */
310
+ if (attributes.length > 1) {
311
+ const baseNode = (0, xpath_1.select)(baseXPath, targetDoc).map(n => n.toString());
312
+ const childXPath = `${buildAbsoluteXPath([(0, utility_js_1.last)(localPath)])}${attributeXPath}`;
313
+ const attributeValues = baseNode.map((node) => {
314
+ const nodeDoc = dom.parseFromString(node);
315
+ const values = (0, xpath_1.select)(childXPath, nodeDoc).reduce((r, n) => {
316
+ r[(0, camelcase_1.default)(n.name, { locale: 'en-us' })] = n.value;
317
+ return r;
318
+ }, {});
319
+ return values;
320
+ });
321
+ return {
322
+ ...result,
323
+ [key]: attributeValues.length === 1 ? attributeValues[0] : attributeValues
324
+ };
325
+ }
326
+ // case: single attribute
327
+ /*
328
+ {
329
+ key: 'statusCode',
330
+ localPath: ['Response', 'Status', 'StatusCode'],
331
+ attributes: ['Value'],
332
+ }
333
+ */
334
+ if (attributes.length === 1) {
335
+ const fullPath = `${baseXPath}${attributeXPath}`;
336
+ const attributeValues = (0, xpath_1.select)(fullPath, targetDoc).map((n) => n.value);
337
+ return {
338
+ ...result,
339
+ [key]: attributeValues[0]
340
+ };
341
+ }
342
+ // case: zero attribute
343
+ /*
344
+ {
345
+ key: 'issuer',
346
+ localPath: ['AuthnRequest', 'Issuer'],
347
+ attributes: []
348
+ }
349
+ */
350
+ if (attributes.length === 0) {
351
+ let attributeValue = null;
352
+ const node = (0, xpath_1.select)(baseXPath, targetDoc);
353
+ if (node.length === 1) {
354
+ const fullPath = `string(${baseXPath}${attributeXPath})`;
355
+ attributeValue = (0, xpath_1.select)(fullPath, targetDoc);
356
+ }
357
+ if (node.length > 1) {
358
+ attributeValue = node.filter((n) => n.firstChild)
359
+ .map((n) => n.firstChild.nodeValue);
360
+ }
361
+ return {
362
+ ...result,
363
+ [key]: attributeValue
364
+ };
365
+ }
366
+ return result;
367
+ }, {});
368
+ }
369
+ exports.extract = extract;
370
370
  //# sourceMappingURL=extractor.js.map