@bostonuniversity/shibboleth-sp 1.0.2
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 +87 -0
- package/dist/cjs/index.js +63195 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/esm/Config.js +25 -0
- package/dist/esm/Config.js.map +1 -0
- package/dist/esm/HandlerSp.js +229 -0
- package/dist/esm/HandlerSp.js.map +1 -0
- package/dist/esm/Http.js +83 -0
- package/dist/esm/Http.js.map +1 -0
- package/dist/esm/Jwt.js +186 -0
- package/dist/esm/Jwt.js.map +1 -0
- package/dist/esm/Keys.js +82 -0
- package/dist/esm/Keys.js.map +1 -0
- package/dist/esm/Saml.js +235 -0
- package/dist/esm/Saml.js.map +1 -0
- package/dist/esm/Utils.js +138 -0
- package/dist/esm/Utils.js.map +1 -0
- package/dist/esm/index.js +63177 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/types/Config.d.ts +28 -0
- package/dist/types/HandlerSp.d.ts +20 -0
- package/dist/types/Http.d.ts +72 -0
- package/dist/types/Jwt.d.ts +59 -0
- package/dist/types/Keys.d.ts +13 -0
- package/dist/types/Saml.d.ts +73 -0
- package/dist/types/Utils.d.ts +40 -0
- package/dist/types/index.d.ts +8 -0
- package/package.json +49 -0
package/dist/esm/Saml.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getFriendlySamlResponse = exports.SamlTools = void 0;
|
|
13
|
+
const saml2_js_1 = require("saml2-js");
|
|
14
|
+
const xmldom_1 = require("@xmldom/xmldom");
|
|
15
|
+
class SamlTools {
|
|
16
|
+
constructor(parms) {
|
|
17
|
+
const { entityId, entryPoint, logoutUrl, idpCert, cert, key } = parms;
|
|
18
|
+
this.sp_options = {
|
|
19
|
+
entity_id: entityId,
|
|
20
|
+
private_key: '',
|
|
21
|
+
certificate: '',
|
|
22
|
+
assert_endpoint: '',
|
|
23
|
+
force_authn: true,
|
|
24
|
+
sign_get_request: true,
|
|
25
|
+
allow_unencrypted_assertion: true,
|
|
26
|
+
notbefore_skew: 60
|
|
27
|
+
};
|
|
28
|
+
if (cert) {
|
|
29
|
+
this.sp_options.certificate = cert;
|
|
30
|
+
}
|
|
31
|
+
if (key) {
|
|
32
|
+
this.sp_options.private_key = key;
|
|
33
|
+
}
|
|
34
|
+
this.idp_options = {
|
|
35
|
+
sso_login_url: entryPoint,
|
|
36
|
+
sso_logout_url: logoutUrl,
|
|
37
|
+
sign_get_request: true,
|
|
38
|
+
allow_unencrypted_assertion: true,
|
|
39
|
+
force_authn: false,
|
|
40
|
+
certificates: [idpCert]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
setSpCertificate(cert) {
|
|
44
|
+
this.sp_options.certificate = cert;
|
|
45
|
+
}
|
|
46
|
+
setPrivateKey(key) {
|
|
47
|
+
this.sp_options.private_key = key;
|
|
48
|
+
}
|
|
49
|
+
setAssertUrl(assertEndpoint) {
|
|
50
|
+
this.sp_options.assert_endpoint = assertEndpoint;
|
|
51
|
+
}
|
|
52
|
+
getMetaData() {
|
|
53
|
+
return (new saml2_js_1.ServiceProvider(this.sp_options)).create_metadata();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The request indicates the user is not authenticated, and so needs to be redirected to a url for signin with the IDP.
|
|
57
|
+
*
|
|
58
|
+
* @see https://www.npmjs.com/package/saml2-js#create_login_request_urlidp-options-cb
|
|
59
|
+
* @param relay_state
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
62
|
+
createLoginRequestUrl(relay_state) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const sp = new saml2_js_1.ServiceProvider(this.sp_options);
|
|
66
|
+
const idp = new saml2_js_1.IdentityProvider(this.idp_options);
|
|
67
|
+
sp.create_login_request_url(idp, {
|
|
68
|
+
relay_state,
|
|
69
|
+
}, (err, login_url, request_id) => {
|
|
70
|
+
if (err) {
|
|
71
|
+
reject(err);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
resolve(login_url);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @returns The url to the IDP to logout.
|
|
82
|
+
*/
|
|
83
|
+
createLogoutRequestUrl() {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
const sp = new saml2_js_1.ServiceProvider(this.sp_options);
|
|
87
|
+
const idp = new saml2_js_1.IdentityProvider(this.idp_options);
|
|
88
|
+
sp.create_logout_request_url(idp, {}, (err, logout_url) => {
|
|
89
|
+
if (err) {
|
|
90
|
+
reject(err);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
resolve(logout_url);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The saml response could come from the IDP as either a querystring parameter (GET), or as a
|
|
101
|
+
* form data parameter (POST).
|
|
102
|
+
* @param request
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
getSamlResponseParameter(request) {
|
|
106
|
+
let samlResponseParm;
|
|
107
|
+
let xmlData;
|
|
108
|
+
let relayState;
|
|
109
|
+
try {
|
|
110
|
+
if (request.method === 'GET') {
|
|
111
|
+
// Check query string for SAMLResponse
|
|
112
|
+
const queryStringParams = request.querystring ? new URLSearchParams(request.querystring) : null;
|
|
113
|
+
const samlResponseFromQueryString = queryStringParams ? queryStringParams.get('SAMLResponse') : null;
|
|
114
|
+
relayState = queryStringParams ? queryStringParams.get('RelayState') || undefined : undefined;
|
|
115
|
+
if (samlResponseFromQueryString) {
|
|
116
|
+
samlResponseParm = samlResponseFromQueryString;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (request.method === 'POST') {
|
|
120
|
+
/**
|
|
121
|
+
* Check form data for SAMLResponse.
|
|
122
|
+
* ( If the redirect binding was used to initiate the authentication flow,
|
|
123
|
+
* shibboleth may nonetheless send the saml response as form data, perhaps because its size exceeds
|
|
124
|
+
* the limits of querystring parameters )
|
|
125
|
+
*/
|
|
126
|
+
const ctheader = request.headers['content-type'];
|
|
127
|
+
if (ctheader && ctheader[0].value === 'application/x-www-form-urlencoded') {
|
|
128
|
+
// 1) The body data will be base64 encoded, decode it:
|
|
129
|
+
const body = Buffer.from(request.body.data, 'base64').toString();
|
|
130
|
+
// 2) Get the "SAMLResponse" parameter from within the body, url-decoded:
|
|
131
|
+
const params = body ? new URLSearchParams(body) : null;
|
|
132
|
+
samlResponseParm = params ? params.get('SAMLResponse') : null;
|
|
133
|
+
samlResponseParm = samlResponseParm ? decodeURIComponent(samlResponseParm) : null;
|
|
134
|
+
relayState = params ? params.get('RelayState') || '' : '';
|
|
135
|
+
if (samlResponseParm) {
|
|
136
|
+
console.log('SAMLResponse parameter FOUND in request');
|
|
137
|
+
// 3) The "SAMLResponse" parameter will in turn be base64 encoded, decode it (you should find xml):
|
|
138
|
+
xmlData = samlResponseParm ? Buffer.from(samlResponseParm, 'base64').toString() : undefined;
|
|
139
|
+
// console.log(xmlData);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw new Error('SAMLResponse parameter NOT FOUND in request');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
console.log('Error getting SAMLResponse from request');
|
|
149
|
+
throw (e);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
samlResponseParm, xmlData, relayState
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The request has a SAMLResponse parameter and so indicates authentication has completed and a followup
|
|
157
|
+
* assert against the SAMLResponse parameter is next.
|
|
158
|
+
*
|
|
159
|
+
* @see https://www.npmjs.com/package/saml2-js#create_login_request_urlidp-options-cb
|
|
160
|
+
* @param requestUrl
|
|
161
|
+
* @returns
|
|
162
|
+
*/
|
|
163
|
+
sendAssert(request) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
return new Promise((resolve, reject) => {
|
|
166
|
+
const sp = new saml2_js_1.ServiceProvider(this.sp_options);
|
|
167
|
+
const idp = new saml2_js_1.IdentityProvider(this.idp_options);
|
|
168
|
+
const parm = this.getSamlResponseParameter(request);
|
|
169
|
+
const { samlResponseParm, xmlData, relayState } = parm;
|
|
170
|
+
const options = {
|
|
171
|
+
request_body: { SAMLResponse: samlResponseParm }
|
|
172
|
+
};
|
|
173
|
+
const callback = (err, saml_assert_response) => {
|
|
174
|
+
if (err) {
|
|
175
|
+
reject(err);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const friendlyResponse = getFriendlySamlResponse(xmlData, saml_assert_response);
|
|
179
|
+
resolve({
|
|
180
|
+
samlAssertResponse: friendlyResponse,
|
|
181
|
+
relayState: relayState || null
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
if (request.method === 'POST') {
|
|
186
|
+
sp.post_assert(idp, options, callback);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
sp.redirect_assert(idp, options, callback);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.SamlTools = SamlTools;
|
|
196
|
+
/**
|
|
197
|
+
* The saml assert response will have attributes that are missing the friendly names.
|
|
198
|
+
* These friendly names can still be found in the xml that was passed to the post_assert
|
|
199
|
+
* to get the response, and can be applied to that response to overwrite the "unfriendly" names.
|
|
200
|
+
* @param saml_assert_response
|
|
201
|
+
*/
|
|
202
|
+
function getFriendlySamlResponse(xmlData, response) {
|
|
203
|
+
var _a;
|
|
204
|
+
const xml = (new xmldom_1.DOMParser()).parseFromString(xmlData || '');
|
|
205
|
+
const xmlChoices = xml.getElementsByTagName('saml2:Attribute');
|
|
206
|
+
const friendlyAttributes = {};
|
|
207
|
+
const findFriendlyName = (unfriendlyName) => {
|
|
208
|
+
let item = null;
|
|
209
|
+
for (const itm in xmlChoices) {
|
|
210
|
+
if (!xmlChoices[itm].getAttribute)
|
|
211
|
+
continue;
|
|
212
|
+
if (xmlChoices[itm].getAttribute('Name') === unfriendlyName) {
|
|
213
|
+
return xmlChoices[itm].getAttribute('FriendlyName');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
};
|
|
218
|
+
if ((response === null || response === void 0 ? void 0 : response.user) && ((_a = response.user) === null || _a === void 0 ? void 0 : _a.attributes)) {
|
|
219
|
+
const { attributes } = response.user;
|
|
220
|
+
for (const a in attributes) {
|
|
221
|
+
var fn = findFriendlyName(a);
|
|
222
|
+
var val = attributes[a];
|
|
223
|
+
if (fn) {
|
|
224
|
+
friendlyAttributes[fn] = val;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
friendlyAttributes[a] = val;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
response.user.attributes = friendlyAttributes;
|
|
232
|
+
return response;
|
|
233
|
+
}
|
|
234
|
+
exports.getFriendlySamlResponse = getFriendlySamlResponse;
|
|
235
|
+
//# sourceMappingURL=Saml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Saml.js","sourceRoot":"","sources":["../../src/Saml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.safeStringify = exports.instanceOf = exports.debugLog = exports.findFirstFieldValue = exports.debugPrint = exports.ParameterTester = void 0;
|
|
4
|
+
const isBlank = (s) => {
|
|
5
|
+
return s === undefined || s === null || `${s}`.trim() == '';
|
|
6
|
+
};
|
|
7
|
+
const isNotBlank = (s) => !isBlank(s);
|
|
8
|
+
const anyBlank = (...a) => a.findIndex((s) => isBlank(s)) > -1;
|
|
9
|
+
const anyNotBlank = (...a) => a.findIndex((s) => isNotBlank(s)) > -1;
|
|
10
|
+
const allBlank = (...a) => !anyNotBlank(...a);
|
|
11
|
+
const noneBlank = (...a) => !anyBlank(...a);
|
|
12
|
+
const someBlankSomeNot = (...a) => anyBlank(...a) && anyNotBlank(...a);
|
|
13
|
+
exports.ParameterTester = {
|
|
14
|
+
isBlank, isNotBlank, anyBlank, anyNotBlank, allBlank, noneBlank, someBlankSomeNot
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Prints debug information to console when DEBUG environment variable is set to 'true'.
|
|
18
|
+
* @param value The debug message to print
|
|
19
|
+
*/
|
|
20
|
+
const debugPrint = (value) => {
|
|
21
|
+
var _a;
|
|
22
|
+
if (((_a = process.env) === null || _a === void 0 ? void 0 : _a.DEBUG) == 'true') {
|
|
23
|
+
console.log(`DEBUG: ${value}`);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.debugPrint = debugPrint;
|
|
27
|
+
/**
|
|
28
|
+
* Find the first field with a value in an object for the list of field names provided.
|
|
29
|
+
* The field is assumed to be an array, and the value is the first element of it.
|
|
30
|
+
* @param parentObj The object to search within
|
|
31
|
+
* @param names The field names to search for
|
|
32
|
+
* @returns The first non-empty field value found, or null if none found
|
|
33
|
+
*/
|
|
34
|
+
const findFirstFieldValue = (parentObj, ...names) => {
|
|
35
|
+
for (const name of names) {
|
|
36
|
+
if (parentObj[name] && parentObj[name].length > 0) {
|
|
37
|
+
if (parentObj[name][0]) {
|
|
38
|
+
return parentObj[name][0];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
44
|
+
exports.findFirstFieldValue = findFirstFieldValue;
|
|
45
|
+
/**
|
|
46
|
+
* Logs debug messages to console when DEBUG environment variable is set to 'true'.
|
|
47
|
+
* @param msg The message to log
|
|
48
|
+
*/
|
|
49
|
+
const debugLog = (msg) => {
|
|
50
|
+
var _a;
|
|
51
|
+
if (((_a = process.env) === null || _a === void 0 ? void 0 : _a.DEBUG) == 'true') {
|
|
52
|
+
console.log(msg);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.debugLog = debugLog;
|
|
56
|
+
/**
|
|
57
|
+
* Type guard function to check if a value is of a specific type based on field presence.
|
|
58
|
+
* @param value The value to check
|
|
59
|
+
* @param fieldName The field name that should exist on the type
|
|
60
|
+
* @returns True if the field exists on the value, indicating it's of type T
|
|
61
|
+
*/
|
|
62
|
+
const instanceOf = (value, fieldName) => fieldName in value;
|
|
63
|
+
exports.instanceOf = instanceOf;
|
|
64
|
+
const safeStringify = (obj, replacer, space) => {
|
|
65
|
+
// Handle array replacer by converting to a function
|
|
66
|
+
let replaceFn = null;
|
|
67
|
+
if (typeof replacer === 'function') {
|
|
68
|
+
replaceFn = replacer;
|
|
69
|
+
}
|
|
70
|
+
else if (Array.isArray(replacer)) {
|
|
71
|
+
const allowList = new Set(replacer.map(String));
|
|
72
|
+
replaceFn = (key, value) => (key === '' || allowList.has(key) ? value : undefined);
|
|
73
|
+
}
|
|
74
|
+
// Track visited objects to detect circular references
|
|
75
|
+
const visited = new WeakSet();
|
|
76
|
+
const _serialize = (value, key = '') => {
|
|
77
|
+
// Apply replacer function if provided
|
|
78
|
+
const replacedValue = replaceFn ? replaceFn(key, value) : value;
|
|
79
|
+
// Handle undefined and functions
|
|
80
|
+
if (replacedValue === undefined || typeof replacedValue === 'function') {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
// Handle null and non-objects
|
|
84
|
+
if (replacedValue === null || typeof replacedValue !== 'object') {
|
|
85
|
+
return JSON.stringify(replacedValue);
|
|
86
|
+
}
|
|
87
|
+
// Handle built-in objects
|
|
88
|
+
if (replacedValue instanceof Date) {
|
|
89
|
+
return JSON.stringify(replacedValue);
|
|
90
|
+
}
|
|
91
|
+
if (replacedValue instanceof RegExp) {
|
|
92
|
+
return JSON.stringify(replacedValue.toString());
|
|
93
|
+
}
|
|
94
|
+
if (replacedValue instanceof Map || replacedValue instanceof Set) {
|
|
95
|
+
return '{}';
|
|
96
|
+
}
|
|
97
|
+
// Handle circular references
|
|
98
|
+
if (visited.has(replacedValue)) {
|
|
99
|
+
return '"[Circular]"';
|
|
100
|
+
}
|
|
101
|
+
visited.add(replacedValue);
|
|
102
|
+
try {
|
|
103
|
+
// Process arrays
|
|
104
|
+
if (Array.isArray(replacedValue)) {
|
|
105
|
+
const items = replacedValue.map((item, i) => {
|
|
106
|
+
const serialized = _serialize(item, String(i));
|
|
107
|
+
return serialized === undefined ? 'null' : serialized;
|
|
108
|
+
});
|
|
109
|
+
return `[${items.join(',')}]`;
|
|
110
|
+
}
|
|
111
|
+
// Process objects
|
|
112
|
+
const entries = [];
|
|
113
|
+
for (const [k, v] of Object.entries(replacedValue)) {
|
|
114
|
+
const serialized = _serialize(v, k);
|
|
115
|
+
if (serialized !== undefined) {
|
|
116
|
+
entries.push(`${JSON.stringify(k)}:${serialized}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return `{${entries.join(',')}}`;
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
// Clean up visited set for recursive structures
|
|
123
|
+
visited.delete(replacedValue);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
const result = _serialize(obj);
|
|
128
|
+
if (space) {
|
|
129
|
+
return JSON.stringify(JSON.parse(result || 'null'), null, space);
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
catch (_a) {
|
|
134
|
+
return '{}';
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
exports.safeStringify = safeStringify;
|
|
138
|
+
//# sourceMappingURL=Utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../src/Utils.ts"],"names":[],"mappings":"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"}
|