samlify 2.12.0 → 2.13.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 +1 -1
- package/build/src/api.js +41 -3
- package/build/src/api.js.map +1 -1
- package/build/src/binding-post.js +236 -182
- package/build/src/binding-post.js.map +1 -1
- package/build/src/binding-redirect.js +303 -215
- package/build/src/binding-redirect.js.map +1 -1
- package/build/src/binding-simplesign.js +285 -137
- package/build/src/binding-simplesign.js.map +1 -1
- package/build/src/entity-idp.js +130 -47
- package/build/src/entity-idp.js.map +1 -1
- package/build/src/entity-sp.js +81 -39
- package/build/src/entity-sp.js.map +1 -1
- package/build/src/entity.js +100 -62
- package/build/src/entity.js.map +1 -1
- package/build/src/extractor.js +118 -151
- package/build/src/extractor.js.map +1 -1
- package/build/src/flow.js +100 -96
- package/build/src/flow.js.map +1 -1
- package/build/src/libsaml.js +315 -259
- package/build/src/libsaml.js.map +1 -1
- package/build/src/metadata-idp.js +60 -30
- package/build/src/metadata-idp.js.map +1 -1
- package/build/src/metadata-sp.js +51 -41
- package/build/src/metadata-sp.js.map +1 -1
- package/build/src/metadata.js +47 -43
- package/build/src/metadata.js.map +1 -1
- package/build/src/options.js +73 -0
- package/build/src/options.js.map +1 -0
- package/build/src/urn.js +28 -1
- package/build/src/urn.js.map +1 -1
- package/build/src/utility.js +140 -85
- package/build/src/utility.js.map +1 -1
- package/build/src/validator.js +27 -10
- package/build/src/validator.js.map +1 -1
- package/package.json +16 -5
- package/types/src/api.d.ts +33 -3
- package/types/src/binding-post.d.ts +67 -34
- package/types/src/binding-redirect.d.ts +58 -31
- package/types/src/binding-simplesign.d.ts +77 -21
- package/types/src/entity-idp.d.ts +40 -31
- package/types/src/entity-sp.d.ts +37 -27
- package/types/src/entity.d.ts +71 -77
- package/types/src/extractor.d.ts +31 -22
- package/types/src/flow.d.ts +24 -2
- package/types/src/libsaml.d.ts +172 -118
- package/types/src/metadata-idp.d.ts +27 -11
- package/types/src/metadata-sp.d.ts +29 -19
- package/types/src/metadata.d.ts +59 -34
- package/types/src/options.d.ts +37 -0
- package/types/src/types.d.ts +250 -24
- package/types/src/urn.d.ts +7 -0
- package/types/src/utility.d.ts +139 -90
- package/types/src/validator.d.ts +21 -0
- package/.circleci/config.yml +0 -98
- package/.editorconfig +0 -19
- package/.github/FUNDING.yml +0 -1
- package/.github/workflows/deploy-docs.yml +0 -56
- package/.pre-commit.sh +0 -15
- package/.snyk +0 -4
- package/Makefile +0 -25
- package/index.ts +0 -28
- package/samlify-2.11.0.tgz +0 -0
- package/src/api.ts +0 -48
- package/src/binding-post.ts +0 -336
- package/src/binding-redirect.ts +0 -335
- package/src/binding-simplesign.ts +0 -231
- package/src/entity-idp.ts +0 -145
- package/src/entity-sp.ts +0 -114
- package/src/entity.ts +0 -243
- package/src/extractor.ts +0 -399
- package/src/flow.ts +0 -469
- package/src/libsaml.ts +0 -779
- package/src/metadata-idp.ts +0 -146
- package/src/metadata-sp.ts +0 -203
- package/src/metadata.ts +0 -166
- package/src/types.ts +0 -127
- package/src/urn.ts +0 -210
- package/src/utility.ts +0 -259
- package/src/validator.ts +0 -44
- package/tsconfig.json +0 -41
- package/tslint.json +0 -35
- package/types.d.ts +0 -2
- package/vitest.config.ts +0 -12
package/build/src/utility.js
CHANGED
|
@@ -40,17 +40,22 @@ exports.notEmpty = notEmpty;
|
|
|
40
40
|
exports.escapeXPathValue = escapeXPathValue;
|
|
41
41
|
exports.camelCase = camelCase;
|
|
42
42
|
/**
|
|
43
|
-
* @file utility.ts
|
|
44
|
-
* @author tngan
|
|
45
|
-
* @desc
|
|
46
|
-
*/
|
|
43
|
+
* @file utility.ts
|
|
44
|
+
* @author tngan
|
|
45
|
+
* @desc Common helpers (encoding, compression, certificate / key handling).
|
|
46
|
+
*/
|
|
47
47
|
var crypto_1 = require("crypto");
|
|
48
48
|
var zlib_1 = require("zlib");
|
|
49
49
|
var BASE64_STR = 'base64';
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
51
|
+
* Build an object by zipping two parallel arrays of keys and values.
|
|
52
|
+
* When `skipDuplicated` is false, colliding keys are aggregated into arrays
|
|
53
|
+
* so duplicate keys do not clobber earlier values.
|
|
54
|
+
*
|
|
55
|
+
* @param arr1 key array
|
|
56
|
+
* @param arr2 value array (same index as keys)
|
|
57
|
+
* @param skipDuplicated when true (default) later writes overwrite earlier ones
|
|
58
|
+
* @returns object composed from key/value pairs
|
|
54
59
|
*/
|
|
55
60
|
function zipObject(arr1, arr2, skipDuplicated) {
|
|
56
61
|
if (skipDuplicated === void 0) { skipDuplicated = true; }
|
|
@@ -59,7 +64,6 @@ function zipObject(arr1, arr2, skipDuplicated) {
|
|
|
59
64
|
res[l] = arr2[i];
|
|
60
65
|
return res;
|
|
61
66
|
}
|
|
62
|
-
// if key exists, aggregate with array in order to get rid of duplicate key
|
|
63
67
|
if (res[l] !== undefined) {
|
|
64
68
|
res[l] = Array.isArray(res[l])
|
|
65
69
|
? res[l].concat(arr2[i])
|
|
@@ -71,9 +75,10 @@ function zipObject(arr1, arr2, skipDuplicated) {
|
|
|
71
75
|
}, {});
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* @param input
|
|
78
|
+
* Recursively flatten a nested array into a single-level array.
|
|
79
|
+
*
|
|
80
|
+
* @param input nested array input
|
|
81
|
+
* @returns flattened array
|
|
77
82
|
*/
|
|
78
83
|
function flattenDeep(input) {
|
|
79
84
|
return Array.isArray(input)
|
|
@@ -81,144 +86,168 @@ function flattenDeep(input) {
|
|
|
81
86
|
: [input];
|
|
82
87
|
}
|
|
83
88
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* @param input
|
|
89
|
+
* Return the last element of an array.
|
|
90
|
+
*
|
|
91
|
+
* @param input source array
|
|
92
|
+
* @returns the final element, or undefined when the array is empty
|
|
87
93
|
*/
|
|
88
94
|
function last(input) {
|
|
89
95
|
return input.slice(-1)[0];
|
|
90
96
|
}
|
|
91
97
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* @param input
|
|
98
|
+
* Return a copy of a string array with duplicates removed.
|
|
99
|
+
*
|
|
100
|
+
* @param input array with possible duplicates
|
|
101
|
+
* @returns array in original order without duplicates
|
|
95
102
|
*/
|
|
96
103
|
function uniq(input) {
|
|
97
104
|
var set = new Set(input);
|
|
98
105
|
return __spreadArray([], __read(set), false);
|
|
99
106
|
}
|
|
100
107
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* @param
|
|
105
|
-
* @param
|
|
108
|
+
* Safely read a dotted path from an object, returning `defaultValue` when
|
|
109
|
+
* any segment is missing.
|
|
110
|
+
*
|
|
111
|
+
* @param obj source object
|
|
112
|
+
* @param path dotted path expression (e.g. "a.b.c")
|
|
113
|
+
* @param defaultValue fallback when the path does not resolve
|
|
114
|
+
* @returns resolved value or the default
|
|
106
115
|
*/
|
|
107
116
|
function get(obj, path, defaultValue) {
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
if (defaultValue === void 0) { defaultValue = null; }
|
|
118
|
+
return path
|
|
119
|
+
.split('.')
|
|
120
|
+
.reduce(function (a, c) {
|
|
121
|
+
if (a && typeof a === 'object' && c in a) {
|
|
122
|
+
var next = a[c];
|
|
123
|
+
return next !== null && next !== void 0 ? next : defaultValue;
|
|
124
|
+
}
|
|
125
|
+
return defaultValue;
|
|
126
|
+
}, obj);
|
|
110
127
|
}
|
|
111
128
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
129
|
+
* Type guard for strings.
|
|
130
|
+
*
|
|
131
|
+
* @param input value to test
|
|
132
|
+
* @returns true when the input is a string primitive
|
|
114
133
|
*/
|
|
115
134
|
function isString(input) {
|
|
116
135
|
return typeof input === 'string';
|
|
117
136
|
}
|
|
118
137
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* @
|
|
122
|
-
|
|
138
|
+
* Encode a string or byte array as base64.
|
|
139
|
+
*
|
|
140
|
+
* @param message plain text or raw bytes
|
|
141
|
+
* @returns base64 encoded string
|
|
142
|
+
*/
|
|
123
143
|
function base64Encode(message) {
|
|
124
144
|
return Buffer.from(message).toString(BASE64_STR);
|
|
125
145
|
}
|
|
126
146
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* @
|
|
131
|
-
|
|
147
|
+
* Decode a base64 message. Returns either the decoded string or the raw
|
|
148
|
+
* Buffer depending on `isBytes`.
|
|
149
|
+
*
|
|
150
|
+
* @param base64Message base64 encoded payload
|
|
151
|
+
* @param isBytes when true, return a Buffer instead of a string
|
|
152
|
+
* @returns decoded string or Buffer
|
|
153
|
+
*/
|
|
132
154
|
function base64Decode(base64Message, isBytes) {
|
|
133
155
|
var bytes = Buffer.from(base64Message, BASE64_STR);
|
|
134
156
|
return Boolean(isBytes) ? bytes : bytes.toString();
|
|
135
157
|
}
|
|
136
158
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* @
|
|
140
|
-
|
|
159
|
+
* Raw-deflate a UTF-8 string and return the compressed bytes.
|
|
160
|
+
*
|
|
161
|
+
* @param message plain text
|
|
162
|
+
* @returns compressed bytes as a number array
|
|
163
|
+
*/
|
|
141
164
|
function deflateString(message) {
|
|
142
165
|
var input = Buffer.from(message, 'utf8');
|
|
143
166
|
return Array.from((0, zlib_1.deflateRawSync)(input));
|
|
144
167
|
}
|
|
145
168
|
/**
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* @
|
|
149
|
-
|
|
169
|
+
* Raw-inflate a base64 string that was produced by {@link deflateString}.
|
|
170
|
+
*
|
|
171
|
+
* @param compressedString base64-encoded raw-deflate payload
|
|
172
|
+
* @returns decompressed UTF-8 string
|
|
173
|
+
*/
|
|
150
174
|
function inflateString(compressedString) {
|
|
151
175
|
var inputBuffer = Buffer.from(compressedString, BASE64_STR);
|
|
152
176
|
return (0, zlib_1.inflateRawSync)(inputBuffer).toString('utf8');
|
|
153
177
|
}
|
|
154
178
|
/**
|
|
155
|
-
*
|
|
156
|
-
|
|
157
|
-
* @param {string} String for header and tail
|
|
158
|
-
* @return {string} A formatted certificate string
|
|
159
|
-
*/
|
|
179
|
+
* Strip PEM header/footer, whitespace and newlines from a PEM payload.
|
|
180
|
+
*/
|
|
160
181
|
function _normalizeCerString(bin, format) {
|
|
161
|
-
return bin
|
|
182
|
+
return bin
|
|
183
|
+
.toString()
|
|
184
|
+
.replace(/\n/g, '')
|
|
185
|
+
.replace(/\r/g, '')
|
|
186
|
+
.replace("-----BEGIN ".concat(format, "-----"), '')
|
|
187
|
+
.replace("-----END ".concat(format, "-----"), '')
|
|
188
|
+
.replace(/ /g, '')
|
|
189
|
+
.replace(/\t/g, '');
|
|
162
190
|
}
|
|
163
191
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* @
|
|
167
|
-
|
|
192
|
+
* Normalise a PEM certificate string to its base64 body.
|
|
193
|
+
*
|
|
194
|
+
* @param certString PEM-encoded X.509 certificate
|
|
195
|
+
* @returns certificate body without headers/whitespace
|
|
196
|
+
*/
|
|
168
197
|
function normalizeCerString(certString) {
|
|
169
198
|
return _normalizeCerString(certString, 'CERTIFICATE');
|
|
170
199
|
}
|
|
171
200
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* @
|
|
175
|
-
|
|
201
|
+
* Normalise a PEM RSA private key string to its base64 body.
|
|
202
|
+
*
|
|
203
|
+
* @param pemString PEM-encoded RSA private key
|
|
204
|
+
* @returns key body without headers/whitespace
|
|
205
|
+
*/
|
|
176
206
|
function normalizePemString(pemString) {
|
|
177
207
|
return _normalizeCerString(pemString.toString(), 'RSA PRIVATE KEY');
|
|
178
208
|
}
|
|
179
209
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
|
|
210
|
+
* Reconstruct the full URL (protocol + host + path) from an Express-style
|
|
211
|
+
* HTTP request.
|
|
212
|
+
*
|
|
213
|
+
* @param req Express-compatible request object
|
|
214
|
+
* @returns absolute URL string
|
|
215
|
+
*/
|
|
184
216
|
function getFullURL(req) {
|
|
185
217
|
return "".concat(req.protocol, "://").concat(req.get('host')).concat(req.originalUrl);
|
|
186
218
|
}
|
|
187
219
|
/**
|
|
188
|
-
*
|
|
189
|
-
|
|
190
|
-
* @return {boolean}
|
|
191
|
-
*/
|
|
220
|
+
* Return `str` when it is truthy, otherwise the provided default.
|
|
221
|
+
*/
|
|
192
222
|
function parseString(str, defaultValue) {
|
|
193
223
|
if (defaultValue === void 0) { defaultValue = ''; }
|
|
194
224
|
return str || defaultValue;
|
|
195
225
|
}
|
|
196
226
|
/**
|
|
197
|
-
*
|
|
198
|
-
|
|
199
|
-
* @param {object} object applied to the default object
|
|
200
|
-
* @return {object} result object
|
|
201
|
-
*/
|
|
227
|
+
* Shallow-merge `obj2` on top of `obj1`, returning a new object.
|
|
228
|
+
*/
|
|
202
229
|
function applyDefault(obj1, obj2) {
|
|
203
230
|
return Object.assign({}, obj1, obj2);
|
|
204
231
|
}
|
|
205
232
|
/**
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* @
|
|
209
|
-
|
|
233
|
+
* Extract the SPKI PEM public key from a base64 X.509 certificate body.
|
|
234
|
+
*
|
|
235
|
+
* @param x509Certificate normalised certificate body (no PEM wrappers)
|
|
236
|
+
* @returns PEM-encoded public key
|
|
237
|
+
*/
|
|
210
238
|
function getPublicKeyPemFromCertificate(x509Certificate) {
|
|
211
239
|
var der = Buffer.from(x509Certificate, 'base64');
|
|
212
240
|
var cert = new crypto_1.X509Certificate(der);
|
|
213
241
|
return cert.publicKey.export({ type: 'spki', format: 'pem' });
|
|
214
242
|
}
|
|
215
243
|
/**
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* @param
|
|
219
|
-
* @
|
|
220
|
-
*
|
|
221
|
-
|
|
244
|
+
* Read a PEM private key, optionally decrypting it with a passphrase.
|
|
245
|
+
*
|
|
246
|
+
* @param keyString PEM key contents
|
|
247
|
+
* @param passphrase optional passphrase protecting the key
|
|
248
|
+
* @param isOutputString when true, always return a string
|
|
249
|
+
* @returns PEM key as string or Buffer
|
|
250
|
+
*/
|
|
222
251
|
function readPrivateKey(keyString, passphrase, isOutputString) {
|
|
223
252
|
if (isString(passphrase)) {
|
|
224
253
|
var key = (0, crypto_1.createPrivateKey)({ key: keyString, format: 'pem', passphrase: passphrase });
|
|
@@ -228,37 +257,63 @@ function readPrivateKey(keyString, passphrase, isOutputString) {
|
|
|
228
257
|
return keyString;
|
|
229
258
|
}
|
|
230
259
|
/**
|
|
231
|
-
*
|
|
232
|
-
|
|
260
|
+
* Coerce a value to a string when `isOutputString` is true, otherwise pass
|
|
261
|
+
* it through untouched.
|
|
262
|
+
*/
|
|
233
263
|
function convertToString(input, isOutputString) {
|
|
234
264
|
return Boolean(isOutputString) ? String(input) : input;
|
|
235
265
|
}
|
|
236
266
|
/**
|
|
237
|
-
*
|
|
267
|
+
* Check that the input is an array with at least one element.
|
|
268
|
+
*
|
|
269
|
+
* @param a candidate value
|
|
270
|
+
* @returns true when the argument is a non-empty array
|
|
238
271
|
*/
|
|
239
272
|
function isNonEmptyArray(a) {
|
|
240
273
|
return Array.isArray(a) && a.length > 0;
|
|
241
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Wrap a single value in an array, or return the array unchanged.
|
|
277
|
+
* An undefined input returns an empty array.
|
|
278
|
+
*
|
|
279
|
+
* @param a scalar, array, or undefined
|
|
280
|
+
* @returns array form of the input
|
|
281
|
+
*/
|
|
242
282
|
function castArrayOpt(a) {
|
|
243
283
|
if (a === undefined)
|
|
244
284
|
return [];
|
|
245
285
|
return Array.isArray(a) ? a : [a];
|
|
246
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Type guard removing `null` and `undefined` from a union.
|
|
289
|
+
*
|
|
290
|
+
* @param value value to narrow
|
|
291
|
+
* @returns true when the value is neither null nor undefined
|
|
292
|
+
*/
|
|
247
293
|
function notEmpty(value) {
|
|
248
294
|
return value !== null && value !== undefined;
|
|
249
295
|
}
|
|
250
296
|
/**
|
|
251
|
-
*
|
|
297
|
+
* Escape a string for safe use inside an XPath single-quoted string literal.
|
|
252
298
|
* Prevents XPath injection by splitting on single quotes and using concat().
|
|
299
|
+
*
|
|
300
|
+
* @param value raw string that may contain quotes
|
|
301
|
+
* @returns XPath-safe string expression
|
|
253
302
|
*/
|
|
254
303
|
function escapeXPathValue(value) {
|
|
255
304
|
if (!value.includes("'")) {
|
|
256
305
|
return "'" + value + "'";
|
|
257
306
|
}
|
|
258
|
-
// Use XPath concat() to safely handle strings containing single quotes
|
|
259
307
|
var parts = value.split("'").map(function (part) { return "'" + part + "'"; });
|
|
260
308
|
return 'concat(' + parts.join(",\"'\",") + ')';
|
|
261
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Convert a string to camelCase, splitting on whitespace, `-`, `_`, `.`,
|
|
312
|
+
* and inferred case boundaries.
|
|
313
|
+
*
|
|
314
|
+
* @param input source string
|
|
315
|
+
* @returns camelCased output
|
|
316
|
+
*/
|
|
262
317
|
function camelCase(input) {
|
|
263
318
|
var words = input
|
|
264
319
|
.replace(/([a-z\d])([A-Z])/g, '$1\0$2')
|
package/build/src/utility.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utility.js","sourceRoot":"","sources":["../../src/utility.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"utility.js","sourceRoot":"","sources":["../../src/utility.ts"],"names":[],"mappings":"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"}
|
package/build/src/validator.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file validator.ts
|
|
4
|
+
* @author tngan
|
|
5
|
+
* @desc Time-window validators for SAML `NotBefore` / `NotOnOrAfter` conditions.
|
|
6
|
+
*/
|
|
2
7
|
var __read = (this && this.__read) || function (o, n) {
|
|
3
8
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
4
9
|
if (!m) return o;
|
|
@@ -17,27 +22,39 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
17
22
|
};
|
|
18
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
24
|
exports.verifyTime = verifyTime;
|
|
25
|
+
/**
|
|
26
|
+
* Check whether the current clock falls within the provided SAML time
|
|
27
|
+
* window, applying a symmetric drift tolerance to both ends.
|
|
28
|
+
*
|
|
29
|
+
* Behaviour:
|
|
30
|
+
* - Both bounds missing: logs a warning and returns `true`.
|
|
31
|
+
* - Only `utcNotBefore` given: returns true when now is at or after it.
|
|
32
|
+
* - Only `utcNotOnOrAfter` given: returns true when now is strictly before it.
|
|
33
|
+
* - Both given: returns true only when both individual checks pass.
|
|
34
|
+
*
|
|
35
|
+
* @param utcNotBefore ISO-8601 lower bound (inclusive) or undefined
|
|
36
|
+
* @param utcNotOnOrAfter ISO-8601 upper bound (exclusive) or undefined
|
|
37
|
+
* @param drift tolerance applied to each bound, defaults to `[0, 0]`
|
|
38
|
+
* @returns whether the current time is within the configured window
|
|
39
|
+
*/
|
|
20
40
|
function verifyTime(utcNotBefore, utcNotOnOrAfter, drift) {
|
|
21
41
|
if (drift === void 0) { drift = [0, 0]; }
|
|
22
42
|
var now = new Date();
|
|
23
43
|
if (!utcNotBefore && !utcNotOnOrAfter) {
|
|
24
|
-
|
|
25
|
-
console.warn('You intend to have time validation however the document doesn\'t include the valid range.');
|
|
44
|
+
console.warn("You intend to have time validation however the document doesn't include the valid range.");
|
|
26
45
|
return true;
|
|
27
46
|
}
|
|
28
|
-
var notBeforeLocal = null;
|
|
29
|
-
var notOnOrAfterLocal = null;
|
|
30
47
|
var _a = __read(drift, 2), notBeforeDrift = _a[0], notOnOrAfterDrift = _a[1];
|
|
31
48
|
if (utcNotBefore && !utcNotOnOrAfter) {
|
|
32
|
-
|
|
33
|
-
return +
|
|
49
|
+
var notBeforeLocal_1 = new Date(utcNotBefore);
|
|
50
|
+
return +notBeforeLocal_1 + notBeforeDrift <= +now;
|
|
34
51
|
}
|
|
35
52
|
if (!utcNotBefore && utcNotOnOrAfter) {
|
|
36
|
-
|
|
37
|
-
return +now < +
|
|
53
|
+
var notOnOrAfterLocal_1 = new Date(utcNotOnOrAfter);
|
|
54
|
+
return +now < +notOnOrAfterLocal_1 + notOnOrAfterDrift;
|
|
38
55
|
}
|
|
39
|
-
notBeforeLocal = new Date(utcNotBefore);
|
|
40
|
-
notOnOrAfterLocal = new Date(utcNotOnOrAfter);
|
|
56
|
+
var notBeforeLocal = new Date(utcNotBefore);
|
|
57
|
+
var notOnOrAfterLocal = new Date(utcNotOnOrAfter);
|
|
41
58
|
return (+notBeforeLocal + notBeforeDrift <= +now &&
|
|
42
59
|
+now < +notOnOrAfterLocal + notOnOrAfterDrift);
|
|
43
60
|
}
|
|
@@ -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":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;AAoDM,gCAAU;AA/CnB;;;;;;;;;;;;;;GAcG;AACH,SAAS,UAAU,CACjB,YAAgC,EAChC,eAAmC,EACnC,KAA8B;IAA9B,sBAAA,EAAA,SAAyB,CAAC,EAAE,CAAC,CAAC;IAE9B,IAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,EAAE,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,0FAA0F,CAAC,CAAC;QACzG,OAAO,IAAI,CAAC;IACd,CAAC;IAEK,IAAA,KAAA,OAAsC,KAAK,IAAA,EAA1C,cAAc,QAAA,EAAE,iBAAiB,QAAS,CAAC;IAElD,IAAI,YAAY,IAAI,CAAC,eAAe,EAAE,CAAC;QACrC,IAAM,gBAAc,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9C,OAAO,CAAC,gBAAc,GAAG,cAAc,IAAI,CAAC,GAAG,CAAC;IAClD,CAAC;IACD,IAAI,CAAC,YAAY,IAAI,eAAe,EAAE,CAAC;QACrC,IAAM,mBAAiB,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,GAAG,CAAC,mBAAiB,GAAG,iBAAiB,CAAC;IACvD,CAAC;IAED,IAAM,cAAc,GAAG,IAAI,IAAI,CAAC,YAAa,CAAC,CAAC;IAC/C,IAAM,iBAAiB,GAAG,IAAI,IAAI,CAAC,eAAgB,CAAC,CAAC;IAErD,OAAO,CACL,CAAC,cAAc,GAAG,cAAc,IAAI,CAAC,GAAG;QACxC,CAAC,GAAG,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAC9C,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "samlify",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Node.js library for SAML SSO",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -11,14 +11,21 @@
|
|
|
11
11
|
"metadata"
|
|
12
12
|
],
|
|
13
13
|
"typings": "types/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"build",
|
|
16
|
+
"types",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
14
20
|
"scripts": {
|
|
15
|
-
"
|
|
21
|
+
"clean": "rm -rf build types",
|
|
22
|
+
"build": "yarn audit && rm -rf build && tsc",
|
|
16
23
|
"docs:dev": "vitepress dev docs",
|
|
17
24
|
"docs:build": "vitepress build docs",
|
|
18
25
|
"docs:preview": "vitepress preview docs",
|
|
19
26
|
"lint": "tslint -p .",
|
|
20
27
|
"lint:fix": "tslint -p . --fix",
|
|
21
|
-
"pretest": "
|
|
28
|
+
"pretest": "mkdir -p build/test && cp -a test/key test/misc build/test",
|
|
22
29
|
"test": "NODE_ENV=test vitest run",
|
|
23
30
|
"test:watch": "NODE_ENV=test vitest",
|
|
24
31
|
"coverage": "vitest run --coverage",
|
|
@@ -43,15 +50,19 @@
|
|
|
43
50
|
"xpath": "^0.0.34"
|
|
44
51
|
},
|
|
45
52
|
"resolutions": {
|
|
46
|
-
"brace-expansion": ">=1.1.12",
|
|
47
53
|
"diff": ">=4.0.4",
|
|
48
|
-
"esbuild": ">=0.25.0"
|
|
54
|
+
"esbuild": ">=0.25.0",
|
|
55
|
+
"vitest/vite": "^6.4.2",
|
|
56
|
+
"vitest/vite-node/vite": "^6.4.2",
|
|
57
|
+
"vitepress/vite": "^6.4.2",
|
|
58
|
+
"vitepress/@vitejs/plugin-vue/vite": "^6.4.2"
|
|
49
59
|
},
|
|
50
60
|
"devDependencies": {
|
|
51
61
|
"@authenio/samlify-xsd-schema-validator": "^1.0.5",
|
|
52
62
|
"@types/node": "^25.4.0",
|
|
53
63
|
"@types/node-rsa": "^1.1.4",
|
|
54
64
|
"@types/xmldom": "^0.1.34",
|
|
65
|
+
"@vitest/coverage-v8": "^3.2.0",
|
|
55
66
|
"timekeeper": "^2.3.1",
|
|
56
67
|
"ts-node": "^10.9.2",
|
|
57
68
|
"tslint": "^6.1.3",
|
package/types/src/api.d.ts
CHANGED
|
@@ -1,13 +1,43 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @file api.ts
|
|
3
|
+
* @author tngan
|
|
4
|
+
* @desc Global module configuration: XML schema validator and DOM parser.
|
|
5
|
+
*/
|
|
6
|
+
import { DOMParser as Dom, Options as DOMParserOptions } from '@xmldom/xmldom';
|
|
7
|
+
/** Module-wide runtime configuration. */
|
|
2
8
|
interface Context extends ValidatorContext, DOMParserContext {
|
|
3
9
|
}
|
|
10
|
+
/** Caller-supplied SAML XML schema validator. */
|
|
4
11
|
interface ValidatorContext {
|
|
5
|
-
validate?: (xml: string) => Promise<
|
|
12
|
+
validate?: (xml: string) => Promise<unknown>;
|
|
6
13
|
}
|
|
14
|
+
/** DOM parser used to decode SAML messages. */
|
|
7
15
|
interface DOMParserContext {
|
|
8
|
-
dom:
|
|
16
|
+
dom: Dom;
|
|
9
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Return the module-wide runtime context (DOM parser and validator).
|
|
20
|
+
*
|
|
21
|
+
* @returns shared context object
|
|
22
|
+
*/
|
|
10
23
|
export declare function getContext(): Context;
|
|
24
|
+
/**
|
|
25
|
+
* Register the caller-supplied SAML schema validator. Throws when the
|
|
26
|
+
* supplied value does not expose a `validate` callback.
|
|
27
|
+
*
|
|
28
|
+
* @param params object with a `validate(xml)` callback
|
|
29
|
+
*/
|
|
11
30
|
export declare function setSchemaValidator(params: ValidatorContext): void;
|
|
31
|
+
/**
|
|
32
|
+
* Replace the module-wide DOM parser with one configured by the caller.
|
|
33
|
+
*
|
|
34
|
+
* The XXE-safe error handlers are merged into the supplied options as a
|
|
35
|
+
* baseline so callers can override unrelated settings without
|
|
36
|
+
* accidentally disabling XXE protection (`saml-core §6.4`,
|
|
37
|
+
* `saml-sec-consider §6.3.1`). A caller can still opt out by passing
|
|
38
|
+
* its own `errorHandler`, but it must do so explicitly.
|
|
39
|
+
*
|
|
40
|
+
* @param options xmldom parser options
|
|
41
|
+
*/
|
|
12
42
|
export declare function setDOMParserOptions(options?: DOMParserOptions): void;
|
|
13
43
|
export {};
|