samlesa 2.12.3 → 2.12.5
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.
- package/build/.idea/workspace.xml +13 -1
- package/build/index.js +54 -64
- package/build/index.js.map +1 -1
- package/build/src/api.js +24 -23
- package/build/src/api.js.map +1 -1
- package/build/src/binding-post.js +358 -368
- package/build/src/binding-post.js.map +1 -1
- package/build/src/binding-redirect.js +333 -332
- package/build/src/binding-redirect.js.map +1 -1
- package/build/src/binding-simplesign.js +222 -232
- package/build/src/binding-simplesign.js.map +1 -1
- package/build/src/entity-idp.js +130 -130
- package/build/src/entity-idp.js.map +1 -1
- package/build/src/entity-sp.js +96 -96
- package/build/src/entity-sp.js.map +1 -1
- package/build/src/entity.js +225 -235
- package/build/src/entity.js.map +1 -1
- package/build/src/extractor.js +385 -369
- package/build/src/extractor.js.map +1 -1
- package/build/src/flow.js +320 -319
- package/build/src/flow.js.map +1 -1
- package/build/src/libsaml.js +665 -641
- package/build/src/libsaml.js.map +1 -1
- package/build/src/metadata-idp.js +127 -127
- package/build/src/metadata-idp.js.map +1 -1
- package/build/src/metadata-sp.js +231 -231
- package/build/src/metadata-sp.js.map +1 -1
- package/build/src/metadata.js +166 -176
- package/build/src/metadata.js.map +1 -1
- package/build/src/types.js +11 -11
- package/build/src/urn.js +212 -212
- package/build/src/urn.js.map +1 -1
- package/build/src/utility.js +292 -248
- package/build/src/utility.js.map +1 -1
- package/build/src/validator.js +27 -26
- package/build/src/validator.js.map +1 -1
- package/package.json +8 -10
- package/src/api.ts +1 -1
- package/src/binding-redirect.ts +83 -64
- package/src/extractor.ts +23 -5
- package/src/libsaml.ts +95 -62
- package/src/utility.ts +147 -76
- package/types/index.d.ts +10 -10
- package/types/src/api.d.ts +13 -13
- package/types/src/binding-post.d.ts +46 -46
- package/types/src/binding-redirect.d.ts +52 -52
- package/types/src/binding-simplesign.d.ts +39 -39
- package/types/src/entity-idp.d.ts +42 -42
- package/types/src/entity-sp.d.ts +36 -36
- package/types/src/entity.d.ts +101 -99
- package/types/src/extractor.d.ts +25 -25
- package/types/src/flow.d.ts +6 -6
- package/types/src/libsaml.d.ts +200 -210
- package/types/src/metadata-idp.d.ts +24 -24
- package/types/src/metadata-sp.d.ts +36 -36
- package/types/src/metadata.d.ts +59 -57
- package/types/src/types.d.ts +129 -127
- package/types/src/urn.d.ts +194 -194
- package/types/src/utility.d.ts +134 -134
- package/types/src/validator.d.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/validator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/validator.ts"],"names":[],"mappings":";;;AAGA,SAAS,UAAU,CACjB,YAAgC,EAChC,eAAmC,EACnC,QAAwB,CAAC,CAAC,EAAE,CAAC,CAAC;IAG9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE;QACrC,kHAAkH;QAClH,OAAO,CAAC,IAAI,CAAC,2FAA2F,CAAC,CAAC;QAC1G,OAAO,IAAI,CAAC;KACb;IAED,IAAI,cAAc,GAAgB,IAAI,CAAC;IACvC,IAAI,iBAAiB,GAAgB,IAAI,CAAC;IAE1C,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,KAAK,CAAC;IAElD,IAAI,YAAY,IAAI,CAAC,eAAe,EAAE;QACpC,cAAc,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;QACxC,OAAO,CAAC,cAAc,GAAG,cAAc,IAAI,CAAC,GAAG,CAAC;KACjD;IACD,IAAI,CAAC,YAAY,IAAI,eAAe,EAAE;QACpC,iBAAiB,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;KACtD;IAED,cAAc,GAAG,IAAI,IAAI,CAAC,YAAa,CAAC,CAAC;IACzC,iBAAiB,GAAG,IAAI,IAAI,CAAC,eAAgB,CAAC,CAAC;IAE/C,OAAO,CACL,CAAC,cAAc,GAAG,cAAc,IAAI,CAAC,GAAG;QACxC,CAAC,GAAG,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAC9C,CAAC;AAEJ,CAAC;AAGC,gCAAU"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "samlesa",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.5",
|
|
4
4
|
"description": "High-level API for Single Sign On (SAML 2.0) 维护分支:修复原项目samlify的一些问题 ",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -32,17 +32,15 @@
|
|
|
32
32
|
},
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"xml-encryption": "^3.0
|
|
36
|
-
"@xmldom/xmldom": "^0.8
|
|
35
|
+
"xml-encryption": "^3.1.0",
|
|
36
|
+
"@xmldom/xmldom": "^0.9.8",
|
|
37
37
|
"camelcase": "^6.2.0",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"pako": "^1.0.10",
|
|
41
|
-
"uuid": "^10.0.0",
|
|
38
|
+
"pako": "^2.1.0",
|
|
39
|
+
"uuid": "^11.1.0",
|
|
42
40
|
"xml": "^1.0.1",
|
|
43
|
-
"xml-crypto": "^6.1.
|
|
41
|
+
"xml-crypto": "^6.1.2",
|
|
44
42
|
"xml-escape": "^1.1.0",
|
|
45
|
-
"xpath": "^0.0.
|
|
43
|
+
"xpath": "^0.0.34"
|
|
46
44
|
},
|
|
47
45
|
"devDependencies": {
|
|
48
46
|
"@ava/typescript": "^1.1.1",
|
|
@@ -50,8 +48,8 @@
|
|
|
50
48
|
"@types/node-forge": "^1.0.1",
|
|
51
49
|
"@types/node-rsa": "^1.1.1",
|
|
52
50
|
"@types/pako": "^1.0.1",
|
|
53
|
-
"@types/uuid": "^10.0.0",
|
|
54
51
|
"@types/xmldom": "^0.1.31",
|
|
52
|
+
"@types/xml-encryption": "1.2.4",
|
|
55
53
|
"ava": "^4.1.0",
|
|
56
54
|
"coveralls": "^3.1.1",
|
|
57
55
|
"nyc": "^17.1.0",
|
package/src/api.ts
CHANGED
package/src/binding-redirect.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file binding-redirect.ts
|
|
3
|
-
* @author tngan
|
|
4
|
-
* @desc Binding-level API, declare the functions using Redirect binding
|
|
5
|
-
*/
|
|
6
|
-
import utility, {
|
|
2
|
+
* @file binding-redirect.ts
|
|
3
|
+
* @author tngan
|
|
4
|
+
* @desc Binding-level API, declare the functions using Redirect binding
|
|
5
|
+
*/
|
|
6
|
+
import utility, {get} from './utility.js';
|
|
7
7
|
import libsaml from './libsaml.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
import {
|
|
8
|
+
import {BindingContext} from './entity.js';
|
|
9
|
+
import {IdentityProvider as Idp} from './entity-idp.js';
|
|
10
|
+
import {ServiceProvider as Sp} from './entity-sp.js';
|
|
11
|
+
|
|
12
|
+
import {wording, namespace} from './urn.js';
|
|
13
13
|
|
|
14
14
|
const binding = wording.binding;
|
|
15
15
|
const urlParams = wording.urlParams;
|
|
@@ -24,25 +24,26 @@ export interface BuildRedirectConfig {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* @private
|
|
28
|
-
* @desc Helper of generating URL param/value pair
|
|
29
|
-
* @param {string} param key
|
|
30
|
-
* @param {string} value value of key
|
|
31
|
-
* @param {boolean} first determine whether the param is the starting one in order to add query header '?'
|
|
32
|
-
* @return {string}
|
|
33
|
-
*/
|
|
27
|
+
* @private
|
|
28
|
+
* @desc Helper of generating URL param/value pair
|
|
29
|
+
* @param {string} param key
|
|
30
|
+
* @param {string} value value of key
|
|
31
|
+
* @param {boolean} first determine whether the param is the starting one in order to add query header '?'
|
|
32
|
+
* @return {string}
|
|
33
|
+
*/
|
|
34
34
|
function pvPair(param: string, value: string, first?: boolean): string {
|
|
35
35
|
return (first === true ? '?' : '&') + param + '=' + value;
|
|
36
36
|
}
|
|
37
|
+
|
|
37
38
|
/**
|
|
38
|
-
* @private
|
|
39
|
-
* @desc Refractored part of URL generation for login/logout request
|
|
40
|
-
* @param {string} type
|
|
41
|
-
* @param {boolean} isSigned
|
|
42
|
-
* @param {string} rawSamlRequest
|
|
43
|
-
* @param {object} entitySetting
|
|
44
|
-
* @return {string}
|
|
45
|
-
*/
|
|
39
|
+
* @private
|
|
40
|
+
* @desc Refractored part of URL generation for login/logout request
|
|
41
|
+
* @param {string} type
|
|
42
|
+
* @param {boolean} isSigned
|
|
43
|
+
* @param {string} rawSamlRequest
|
|
44
|
+
* @param {object} entitySetting
|
|
45
|
+
* @return {string}
|
|
46
|
+
*/
|
|
46
47
|
function buildRedirectURL(opts: BuildRedirectConfig) {
|
|
47
48
|
const {
|
|
48
49
|
baseUrl,
|
|
@@ -51,8 +52,14 @@ function buildRedirectURL(opts: BuildRedirectConfig) {
|
|
|
51
52
|
context,
|
|
52
53
|
entitySetting,
|
|
53
54
|
} = opts;
|
|
54
|
-
let {
|
|
55
|
-
|
|
55
|
+
let {relayState = ''} = opts;
|
|
56
|
+
let noParams = true
|
|
57
|
+
try {
|
|
58
|
+
noParams = new URL(baseUrl)?.searchParams?.size === 0
|
|
59
|
+
} catch {
|
|
60
|
+
noParams = true
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
const queryParam = libsaml.getQueryParamByType(type);
|
|
57
64
|
// In general, this xmlstring is required to do deflate -> base64 -> urlencode
|
|
58
65
|
const samlRequest = encodeURIComponent(utility.base64Encode(utility.deflateString(context)));
|
|
@@ -65,27 +72,31 @@ function buildRedirectURL(opts: BuildRedirectConfig) {
|
|
|
65
72
|
return baseUrl
|
|
66
73
|
+ pvPair(queryParam, octetString, noParams)
|
|
67
74
|
+ pvPair(urlParams.signature, encodeURIComponent(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
libsaml.constructMessageSignature(
|
|
76
|
+
queryParam + '=' + octetString,
|
|
77
|
+
entitySetting.privateKey,
|
|
78
|
+
entitySetting.privateKeyPass,
|
|
79
|
+
undefined,
|
|
80
|
+
entitySetting.requestSignatureAlgorithm
|
|
81
|
+
).toString()
|
|
82
|
+
)
|
|
76
83
|
);
|
|
77
84
|
}
|
|
78
85
|
return baseUrl + pvPair(queryParam, samlRequest + relayState, noParams);
|
|
79
86
|
}
|
|
87
|
+
|
|
80
88
|
/**
|
|
81
|
-
* @desc Redirect URL for login request
|
|
82
|
-
* @param {object} entity object includes both idp and sp
|
|
83
|
-
* @param {function} customTagReplacement used when developers have their own login response template
|
|
84
|
-
* @return {string} redirect URL
|
|
85
|
-
*/
|
|
86
|
-
function loginRequestRedirectURL(entity: {
|
|
89
|
+
* @desc Redirect URL for login request
|
|
90
|
+
* @param {object} entity object includes both idp and sp
|
|
91
|
+
* @param {function} customTagReplacement used when developers have their own login response template
|
|
92
|
+
* @return {string} redirect URL
|
|
93
|
+
*/
|
|
94
|
+
function loginRequestRedirectURL(entity: {
|
|
95
|
+
idp: Idp,
|
|
96
|
+
sp: Sp
|
|
97
|
+
}, customTagReplacement?: (template: string) => BindingContext): BindingContext {
|
|
87
98
|
|
|
88
|
-
const metadata: any = {
|
|
99
|
+
const metadata: any = {idp: entity.idp.entityMeta, sp: entity.sp.entityMeta};
|
|
89
100
|
const spSetting: any = entity.sp.entitySetting;
|
|
90
101
|
let id: string = '';
|
|
91
102
|
|
|
@@ -127,13 +138,13 @@ function loginRequestRedirectURL(entity: { idp: Idp, sp: Sp }, customTagReplacem
|
|
|
127
138
|
}
|
|
128
139
|
|
|
129
140
|
/**
|
|
130
|
-
* @desc Redirect URL for login response
|
|
131
|
-
* @param {object} requestInfo corresponding request, used to obtain the id
|
|
132
|
-
* @param {object} entity object includes both idp and sp
|
|
133
|
-
* @param {object} user current logged user (e.g. req.user)
|
|
134
|
-
* @param {String} relayState the relaystate sent by sp corresponding request
|
|
135
|
-
* @param {function} customTagReplacement used when developers have their own login response template
|
|
136
|
-
*/
|
|
141
|
+
* @desc Redirect URL for login response
|
|
142
|
+
* @param {object} requestInfo corresponding request, used to obtain the id
|
|
143
|
+
* @param {object} entity object includes both idp and sp
|
|
144
|
+
* @param {object} user current logged user (e.g. req.user)
|
|
145
|
+
* @param {String} relayState the relaystate sent by sp corresponding request
|
|
146
|
+
* @param {function} customTagReplacement used when developers have their own login response template
|
|
147
|
+
*/
|
|
137
148
|
function loginResponseRedirectURL(requestInfo: any, entity: any, user: any = {}, relayState?: string, customTagReplacement?: (template: string) => BindingContext): BindingContext {
|
|
138
149
|
const idpSetting = entity.idp.entitySetting;
|
|
139
150
|
const spSetting = entity.sp.entitySetting;
|
|
@@ -144,7 +155,11 @@ function loginResponseRedirectURL(requestInfo: any, entity: any, user: any = {},
|
|
|
144
155
|
|
|
145
156
|
let id: string = idpSetting.generateID();
|
|
146
157
|
if (metadata && metadata.idp && metadata.sp) {
|
|
147
|
-
const base = metadata.sp.getAssertionConsumerService(binding.redirect);
|
|
158
|
+
const base = metadata.sp.getAssertionConsumerService(binding.redirect) ?? 'https://signin.volcengine.com/saml/sso';
|
|
159
|
+
if(!base){
|
|
160
|
+
throw new Error('dont have a base url');
|
|
161
|
+
}
|
|
162
|
+
|
|
148
163
|
let rawSamlResponse: string;
|
|
149
164
|
//
|
|
150
165
|
const nameIDFormat = idpSetting.nameIDFormat;
|
|
@@ -186,7 +201,7 @@ function loginResponseRedirectURL(requestInfo: any, entity: any, user: any = {},
|
|
|
186
201
|
rawSamlResponse = libsaml.replaceTagsByValue(libsaml.defaultLoginResponseTemplate.context, tvalue);
|
|
187
202
|
}
|
|
188
203
|
|
|
189
|
-
const {
|
|
204
|
+
const {privateKey, privateKeyPass, requestSignatureAlgorithm: signatureAlgorithm} = idpSetting;
|
|
190
205
|
const config = {
|
|
191
206
|
privateKey,
|
|
192
207
|
privateKeyPass,
|
|
@@ -203,7 +218,10 @@ function loginResponseRedirectURL(requestInfo: any, entity: any, user: any = {},
|
|
|
203
218
|
referenceTagXPath: "/*[local-name(.)='Response']/*[local-name(.)='Assertion']",
|
|
204
219
|
signatureConfig: {
|
|
205
220
|
prefix: 'ds',
|
|
206
|
-
location: {
|
|
221
|
+
location: {
|
|
222
|
+
reference: "/*[local-name(.)='Response']/*[local-name(.)='Assertion']/*[local-name(.)='Issuer']",
|
|
223
|
+
action: 'after'
|
|
224
|
+
},
|
|
207
225
|
},
|
|
208
226
|
});
|
|
209
227
|
}
|
|
@@ -225,14 +243,14 @@ function loginResponseRedirectURL(requestInfo: any, entity: any, user: any = {},
|
|
|
225
243
|
}
|
|
226
244
|
|
|
227
245
|
/**
|
|
228
|
-
* @desc Redirect URL for logout request
|
|
229
|
-
* @param {object} user current logged user (e.g. req.user)
|
|
230
|
-
* @param {object} entity object includes both idp and sp
|
|
231
|
-
* @param {function} customTagReplacement used when developers have their own login response template
|
|
232
|
-
* @return {string} redirect URL
|
|
233
|
-
*/
|
|
246
|
+
* @desc Redirect URL for logout request
|
|
247
|
+
* @param {object} user current logged user (e.g. req.user)
|
|
248
|
+
* @param {object} entity object includes both idp and sp
|
|
249
|
+
* @param {function} customTagReplacement used when developers have their own login response template
|
|
250
|
+
* @return {string} redirect URL
|
|
251
|
+
*/
|
|
234
252
|
function logoutRequestRedirectURL(user, entity, relayState?: string, customTagReplacement?: (template: string, tags: object) => BindingContext): BindingContext {
|
|
235
|
-
const metadata = {
|
|
253
|
+
const metadata = {init: entity.init.entityMeta, target: entity.target.entityMeta};
|
|
236
254
|
const initSetting = entity.init.entitySetting;
|
|
237
255
|
let id: string = initSetting.generateID();
|
|
238
256
|
const nameIDFormat = initSetting.nameIDFormat;
|
|
@@ -272,12 +290,13 @@ function logoutRequestRedirectURL(user, entity, relayState?: string, customTagRe
|
|
|
272
290
|
}
|
|
273
291
|
throw new Error('ERR_GENERATE_REDIRECT_LOGOUT_REQUEST_MISSING_METADATA');
|
|
274
292
|
}
|
|
293
|
+
|
|
275
294
|
/**
|
|
276
|
-
* @desc Redirect URL for logout response
|
|
277
|
-
* @param {object} requescorresponding request, used to obtain the id
|
|
278
|
-
* @param {object} entity object includes both idp and sp
|
|
279
|
-
* @param {function} customTagReplacement used when developers have their own login response template
|
|
280
|
-
*/
|
|
295
|
+
* @desc Redirect URL for logout response
|
|
296
|
+
* @param {object} requescorresponding request, used to obtain the id
|
|
297
|
+
* @param {object} entity object includes both idp and sp
|
|
298
|
+
* @param {function} customTagReplacement used when developers have their own login response template
|
|
299
|
+
*/
|
|
281
300
|
function logoutResponseRedirectURL(requestInfo: any, entity: any, relayState?: string, customTagReplacement?: (template: string) => BindingContext): BindingContext {
|
|
282
301
|
const metadata = {
|
|
283
302
|
init: entity.init.entityMeta,
|
package/src/extractor.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { uniq, last, zipObject, notEmpty } from './utility.js';
|
|
|
3
3
|
import { getContext } from './api.js';
|
|
4
4
|
import camelCase from 'camelcase';
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
interface ExtractorField {
|
|
7
8
|
key: string;
|
|
8
9
|
localPath: string[] | string[][];
|
|
@@ -198,7 +199,7 @@ export const logoutResponseFields: ExtractorFields = [
|
|
|
198
199
|
|
|
199
200
|
export function extract(context: string, fields) {
|
|
200
201
|
const { dom } = getContext();
|
|
201
|
-
const rootDoc = dom.parseFromString(context);
|
|
202
|
+
const rootDoc = dom.parseFromString(context,'application/xml') as unknown as Node;
|
|
202
203
|
|
|
203
204
|
return fields.reduce((result: any, field) => {
|
|
204
205
|
// get essential fields
|
|
@@ -212,12 +213,12 @@ export function extract(context: string, fields) {
|
|
|
212
213
|
const attributePath = field.attributePath;
|
|
213
214
|
|
|
214
215
|
// set allowing overriding if there is a shortcut injected
|
|
215
|
-
let targetDoc = rootDoc;
|
|
216
|
+
let targetDoc = rootDoc ;
|
|
216
217
|
|
|
217
218
|
// if shortcut is used, then replace the doc
|
|
218
219
|
// it's a design for overriding the doc used during runtime
|
|
219
220
|
if (shortcut) {
|
|
220
|
-
targetDoc = dom.parseFromString(shortcut);
|
|
221
|
+
targetDoc = dom.parseFromString(shortcut,'application/xml') as unknown as Node;
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
// special case: multiple path
|
|
@@ -239,8 +240,10 @@ export function extract(context: string, fields) {
|
|
|
239
240
|
})
|
|
240
241
|
.join(' | ');
|
|
241
242
|
|
|
243
|
+
|
|
242
244
|
return {
|
|
243
245
|
...result,
|
|
246
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
244
247
|
[key]: uniq(select(multiXPaths, targetDoc).map((n: Node) => n.nodeValue).filter(notEmpty))
|
|
245
248
|
};
|
|
246
249
|
}
|
|
@@ -265,15 +268,18 @@ export function extract(context: string, fields) {
|
|
|
265
268
|
const fullLocalXPath = `${baseXPath}${indexPath}`;
|
|
266
269
|
const parentNodes = select(baseXPath, targetDoc);
|
|
267
270
|
// [uid, mail, edupersonaffiliation], ready for aggregate
|
|
271
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
268
272
|
const parentAttributes = select(fullLocalXPath, targetDoc).map((n: Attr) => n.value);
|
|
269
273
|
// [attribute, attributevalue]
|
|
270
274
|
const childXPath = buildAbsoluteXPath([last(localPath)].concat(attributePath));
|
|
271
275
|
const childAttributeXPath = buildAttributeXPath(attributes);
|
|
272
276
|
const fullChildXPath = `${childXPath}${childAttributeXPath}`;
|
|
273
277
|
// [ 'test', 'test@example.com', [ 'users', 'examplerole1' ] ]
|
|
278
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
274
279
|
const childAttributes = parentNodes.map(node => {
|
|
275
|
-
const nodeDoc = dom.parseFromString(node.toString());
|
|
280
|
+
const nodeDoc = dom.parseFromString(node.toString(),'application/xml') as unknown as Node;
|
|
276
281
|
if (attributes.length === 0) {
|
|
282
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
277
283
|
const childValues = select(fullChildXPath, nodeDoc).map((n: Node) => n.nodeValue);
|
|
278
284
|
if (childValues.length === 1) {
|
|
279
285
|
return childValues[0];
|
|
@@ -281,6 +287,7 @@ export function extract(context: string, fields) {
|
|
|
281
287
|
return childValues;
|
|
282
288
|
}
|
|
283
289
|
if (attributes.length > 0) {
|
|
290
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
284
291
|
const childValues = select(fullChildXPath, nodeDoc).map((n: Attr) => n.value);
|
|
285
292
|
if (childValues.length === 1) {
|
|
286
293
|
return childValues[0];
|
|
@@ -309,10 +316,14 @@ export function extract(context: string, fields) {
|
|
|
309
316
|
if (isEntire) {
|
|
310
317
|
const node = select(baseXPath, targetDoc);
|
|
311
318
|
let value: string | string[] | null = null;
|
|
319
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
312
320
|
if (node.length === 1) {
|
|
321
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
313
322
|
value = node[0].toString();
|
|
314
323
|
}
|
|
324
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
315
325
|
if (node.length > 1) {
|
|
326
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
316
327
|
value = node.map(n => n.toString());
|
|
317
328
|
}
|
|
318
329
|
return {
|
|
@@ -330,10 +341,12 @@ export function extract(context: string, fields) {
|
|
|
330
341
|
}
|
|
331
342
|
*/
|
|
332
343
|
if (attributes.length > 1) {
|
|
344
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
333
345
|
const baseNode = select(baseXPath, targetDoc).map(n => n.toString());
|
|
334
346
|
const childXPath = `${buildAbsoluteXPath([last(localPath)])}${attributeXPath}`;
|
|
335
347
|
const attributeValues = baseNode.map((node: string) => {
|
|
336
|
-
const nodeDoc = dom.parseFromString(node);
|
|
348
|
+
const nodeDoc = dom.parseFromString(node,'application/xml') as unknown as Node;
|
|
349
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
337
350
|
const values = select(childXPath, nodeDoc).reduce((r: any, n: Attr) => {
|
|
338
351
|
r[camelCase(n.name, {locale: 'en-us'})] = n.value;
|
|
339
352
|
return r;
|
|
@@ -355,6 +368,7 @@ export function extract(context: string, fields) {
|
|
|
355
368
|
*/
|
|
356
369
|
if (attributes.length === 1) {
|
|
357
370
|
const fullPath = `${baseXPath}${attributeXPath}`;
|
|
371
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
358
372
|
const attributeValues = select(fullPath, targetDoc).map((n: Attr) => n.value);
|
|
359
373
|
return {
|
|
360
374
|
...result,
|
|
@@ -372,11 +386,15 @@ export function extract(context: string, fields) {
|
|
|
372
386
|
if (attributes.length === 0) {
|
|
373
387
|
let attributeValue: SelectedValue[] | (string | null)[] | null = null;
|
|
374
388
|
const node = select(baseXPath, targetDoc);
|
|
389
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
375
390
|
if (node.length === 1) {
|
|
376
391
|
const fullPath = `string(${baseXPath}${attributeXPath})`;
|
|
392
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
377
393
|
attributeValue = select(fullPath, targetDoc);
|
|
378
394
|
}
|
|
395
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
379
396
|
if (node.length > 1) {
|
|
397
|
+
// @ts-expect-error misssing Node properties are not needed
|
|
380
398
|
attributeValue = node.filter((n: Node) => n.firstChild)
|
|
381
399
|
.map((n: Node) => n.firstChild!.nodeValue);
|
|
382
400
|
}
|