@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.
@@ -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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"}