@boxyhq/saml-jackson 1.3.1 → 1.3.3

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.
@@ -108,6 +108,10 @@ export declare class OAuthController implements IOAuthController {
108
108
  * type: string
109
109
  * lastName:
110
110
  * type: string
111
+ * roles:
112
+ * type: array
113
+ * groups:
114
+ * type: array
111
115
  * raw:
112
116
  * type: object
113
117
  * requested:
@@ -100,11 +100,12 @@ class OAuthController {
100
100
  else if (this.opts.idpDiscoveryPath) {
101
101
  if (!isIdpFlow) {
102
102
  // redirect to IdP selection page
103
- const idpList = connections.map(({ idpMetadata, oidcProvider, clientID }) => {
103
+ const idpList = connections.map(({ idpMetadata, oidcProvider, clientID, name }) => {
104
104
  var _a;
105
105
  return JSON.stringify({
106
106
  provider: (_a = idpMetadata === null || idpMetadata === void 0 ? void 0 : idpMetadata.provider) !== null && _a !== void 0 ? _a : oidcProvider === null || oidcProvider === void 0 ? void 0 : oidcProvider.provider,
107
107
  clientID,
108
+ name,
108
109
  connectionIsSAML: idpMetadata && typeof idpMetadata === 'object',
109
110
  connectionIsOIDC: oidcProvider && typeof oidcProvider === 'object',
110
111
  });
@@ -381,7 +382,7 @@ class OAuthController {
381
382
  oidcCodeVerifier = openid_client_1.generators.codeVerifier();
382
383
  const code_challenge = openid_client_1.generators.codeChallenge(oidcCodeVerifier);
383
384
  ssoUrl = oidcClient.authorizationUrl({
384
- scope: [...requestedScopes, 'openid', 'email', 'profile']
385
+ scope: [...requestedScopes, 'openid', 'email', 'profile', 'groups']
385
386
  .filter((value, index, self) => self.indexOf(value) === index) // filter out duplicates
386
387
  .join(' '),
387
388
  code_challenge,
@@ -615,7 +616,7 @@ class OAuthController {
615
616
  });
616
617
  }
617
618
  extractOIDCUserProfile(tokenSet, oidcClient) {
618
- var _a, _b, _c;
619
+ var _a, _b, _c, _d, _e;
619
620
  return __awaiter(this, void 0, void 0, function* () {
620
621
  const profile = { claims: {} };
621
622
  const idTokenClaims = tokenSet.claims();
@@ -624,6 +625,8 @@ class OAuthController {
624
625
  profile.claims.email = (_a = idTokenClaims.email) !== null && _a !== void 0 ? _a : userinfo.email;
625
626
  profile.claims.firstName = (_b = idTokenClaims.given_name) !== null && _b !== void 0 ? _b : userinfo.given_name;
626
627
  profile.claims.lastName = (_c = idTokenClaims.family_name) !== null && _c !== void 0 ? _c : userinfo.family_name;
628
+ profile.claims.roles = (_d = idTokenClaims.roles) !== null && _d !== void 0 ? _d : userinfo.roles;
629
+ profile.claims.groups = (_e = idTokenClaims.groups) !== null && _e !== void 0 ? _e : userinfo.groups;
627
630
  profile.claims.raw = userinfo;
628
631
  return profile;
629
632
  });
@@ -867,7 +870,7 @@ class OAuthController {
867
870
  throw new error_1.JacksonError('JWT signing keys are not loaded', 500);
868
871
  }
869
872
  let claims = requestHasNonce ? { nonce: codeVal.requested.nonce } : {};
870
- claims = Object.assign(Object.assign({}, claims), { id: codeVal.profile.claims.id, email: codeVal.profile.claims.email, firstName: codeVal.profile.claims.firstName, lastName: codeVal.profile.claims.lastName });
873
+ claims = Object.assign(Object.assign({}, claims), { id: codeVal.profile.claims.id, email: codeVal.profile.claims.email, firstName: codeVal.profile.claims.firstName, lastName: codeVal.profile.claims.lastName, roles: codeVal.profile.claims.roles, groups: codeVal.profile.claims.groups });
871
874
  const signingKey = yield (0, utils_1.loadJWSPrivateKey)(jwtSigningKeys.private, jwsAlg);
872
875
  const id_token = yield new jose.SignJWT(claims)
873
876
  .setProtectedHeader({ alg: jwsAlg })
@@ -922,6 +925,10 @@ class OAuthController {
922
925
  * type: string
923
926
  * lastName:
924
927
  * type: string
928
+ * roles:
929
+ * type: array
930
+ * groups:
931
+ * type: array
925
932
  * raw:
926
933
  * type: object
927
934
  * requested:
@@ -34,16 +34,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
35
  const fs = __importStar(require("fs"));
36
36
  const path = __importStar(require("path"));
37
+ const url = __importStar(require("url"));
37
38
  const loadConnection = (preLoadedConnection) => __awaiter(void 0, void 0, void 0, function* () {
38
39
  if (preLoadedConnection.startsWith('./')) {
39
40
  preLoadedConnection = path.resolve(process.cwd(), preLoadedConnection);
40
41
  }
42
+ else {
43
+ preLoadedConnection = path.resolve(preLoadedConnection);
44
+ }
41
45
  const files = yield fs.promises.readdir(preLoadedConnection);
42
46
  const connections = [];
43
47
  for (const idx in files) {
44
48
  const file = files[idx];
45
49
  if (file.endsWith('.js')) {
46
- const { default: connection, } = yield Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ path.join(preLoadedConnection, file))));
50
+ const filePath = path.join(preLoadedConnection, file);
51
+ const fileUrl = preLoadedConnection.startsWith('/') ? filePath : url.pathToFileURL(filePath).toString();
52
+ const { default: connection, } = yield Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ fileUrl)));
47
53
  if (!('oidcDiscoveryUrl' in connection)) {
48
54
  const rawMetadata = yield fs.promises.readFile(path.join(preLoadedConnection, path.parse(file).name + '.xml'), 'utf8');
49
55
  connection.encodedRawMetadata = Buffer.from(rawMetadata, 'utf8').toString('base64');
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
- map: (claims: Record<"id" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" | "email" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" | "firstName" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" | "lastName" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", unknown>) => {
3
- raw: Record<"id" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" | "email" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" | "firstName" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" | "lastName" | "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", unknown>;
2
+ map: (claims: Record<string, unknown>) => {
3
+ raw: Record<string, unknown>;
4
4
  };
5
5
  };
6
6
  export default _default;
@@ -1,5 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const rolesAttribute = 'roles';
4
+ const rolesSchema = 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role';
5
+ const groupsAttribute = 'groups';
6
+ const groupsSchema = 'http://schemas.xmlsoap.org/claims/Group';
7
+ const arrayMapping = [
8
+ {
9
+ attribute: rolesAttribute,
10
+ schema: rolesSchema,
11
+ },
12
+ {
13
+ attribute: groupsAttribute,
14
+ schema: groupsSchema,
15
+ },
16
+ ];
3
17
  const mapping = [
4
18
  {
5
19
  attribute: 'id',
@@ -17,8 +31,17 @@ const mapping = [
17
31
  attribute: 'lastName',
18
32
  schema: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',
19
33
  },
34
+ ...arrayMapping,
20
35
  ];
21
36
  const map = (claims) => {
37
+ arrayMapping.forEach((m) => {
38
+ if (claims[m.attribute]) {
39
+ claims[m.attribute] = [].concat(claims[m.attribute]);
40
+ }
41
+ else if (claims[m.schema]) {
42
+ claims[m.schema] = [].concat(claims[m.schema]);
43
+ }
44
+ });
22
45
  const profile = {
23
46
  raw: claims,
24
47
  };
package/dist/typings.d.ts CHANGED
@@ -228,7 +228,10 @@ export interface Profile {
228
228
  email: string;
229
229
  firstName: string;
230
230
  lastName: string;
231
+ roles?: string[];
232
+ groups?: string[];
231
233
  requested: Record<string, string>;
234
+ raw: any;
232
235
  }
233
236
  export interface Index {
234
237
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boxyhq/saml-jackson",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "SAML Jackson library",
5
5
  "keywords": [
6
6
  "SAML 2.0"
@@ -38,13 +38,13 @@
38
38
  "statements": 70
39
39
  },
40
40
  "dependencies": {
41
- "@boxyhq/saml20": "1.0.7",
41
+ "@boxyhq/saml20": "1.0.11",
42
42
  "@opentelemetry/api": "1.0.4",
43
43
  "@opentelemetry/api-metrics": "0.27.0",
44
- "axios": "1.1.2",
45
- "jose": "4.10.0",
44
+ "axios": "1.1.3",
45
+ "jose": "4.10.3",
46
46
  "marked": "4.1.1",
47
- "mongodb": "4.10.0",
47
+ "mongodb": "4.11.0",
48
48
  "mysql2": "2.3.3",
49
49
  "openid-client": "5.1.10",
50
50
  "node-forge": "1.3.1",
@@ -57,14 +57,14 @@
57
57
  "xmlbuilder": "15.1.1"
58
58
  },
59
59
  "devDependencies": {
60
- "@faker-js/faker": "7.5.0",
61
- "@types/node": "18.8.3",
60
+ "@faker-js/faker": "7.6.0",
61
+ "@types/node": "18.11.5",
62
62
  "@types/sinon": "10.0.13",
63
63
  "@types/tap": "15.0.7",
64
64
  "@typescript-eslint/eslint-plugin": "5.40.0",
65
- "@typescript-eslint/parser": "5.38.1",
65
+ "@typescript-eslint/parser": "5.41.0",
66
66
  "cross-env": "7.0.3",
67
- "eslint": "8.25.0",
67
+ "eslint": "8.26.0",
68
68
  "eslint-config-prettier": "8.5.0",
69
69
  "prettier": "2.7.1",
70
70
  "sinon": "14.0.1",