@boxyhq/saml-jackson 1.3.5 → 1.3.7

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,55 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.JacksonStore = void 0;
10
+ const typeorm_1 = require("typeorm");
11
+ let JacksonStore = class JacksonStore {
12
+ };
13
+ __decorate([
14
+ (0, typeorm_1.Column)({
15
+ primary: true,
16
+ type: 'varchar',
17
+ length: 1500,
18
+ })
19
+ ], JacksonStore.prototype, "key", void 0);
20
+ __decorate([
21
+ (0, typeorm_1.Column)({
22
+ type: 'text',
23
+ })
24
+ ], JacksonStore.prototype, "value", void 0);
25
+ __decorate([
26
+ (0, typeorm_1.Column)({
27
+ type: 'varchar',
28
+ length: 64,
29
+ nullable: true,
30
+ })
31
+ ], JacksonStore.prototype, "iv", void 0);
32
+ __decorate([
33
+ (0, typeorm_1.Column)({
34
+ type: 'varchar',
35
+ length: 64,
36
+ nullable: true,
37
+ })
38
+ ], JacksonStore.prototype, "tag", void 0);
39
+ __decorate([
40
+ (0, typeorm_1.Column)({
41
+ type: 'datetime',
42
+ default: () => 'CURRENT_TIMESTAMP',
43
+ nullable: false,
44
+ })
45
+ ], JacksonStore.prototype, "createdAt", void 0);
46
+ __decorate([
47
+ (0, typeorm_1.Column)({
48
+ type: 'datetime',
49
+ nullable: true,
50
+ })
51
+ ], JacksonStore.prototype, "modifiedAt", void 0);
52
+ JacksonStore = __decorate([
53
+ (0, typeorm_1.Entity)()
54
+ ], JacksonStore);
55
+ exports.JacksonStore = JacksonStore;
@@ -0,0 +1,4 @@
1
+ export declare class JacksonTTL {
2
+ key: string;
3
+ expiresAt: number;
4
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.JacksonTTL = void 0;
10
+ const typeorm_1 = require("typeorm");
11
+ let JacksonTTL = class JacksonTTL {
12
+ };
13
+ __decorate([
14
+ (0, typeorm_1.Column)({
15
+ primary: true,
16
+ type: 'varchar',
17
+ length: 1500,
18
+ })
19
+ ], JacksonTTL.prototype, "key", void 0);
20
+ __decorate([
21
+ (0, typeorm_1.Index)('_jackson_ttl_expires_at'),
22
+ (0, typeorm_1.Column)({
23
+ type: 'bigint',
24
+ })
25
+ ], JacksonTTL.prototype, "expiresAt", void 0);
26
+ JacksonTTL = __decorate([
27
+ (0, typeorm_1.Entity)()
28
+ ], JacksonTTL);
29
+ exports.JacksonTTL = JacksonTTL;
@@ -0,0 +1 @@
1
+ export declare const parseURL: (url?: string) => any;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseURL = void 0;
4
+ const parseURL = (url) => {
5
+ if (!url) {
6
+ throw new Error('URL is required');
7
+ }
8
+ const parts = url.split('://');
9
+ if (parts.length != 2) {
10
+ throw new Error('Invalid connection string');
11
+ }
12
+ //const scheme = parts[0];
13
+ const connectionString = parts[1];
14
+ const connParts = connectionString.split(';');
15
+ if (connParts.length == 0) {
16
+ throw new Error('Invalid connection string');
17
+ }
18
+ // sqlserver://[serverName[\instanceName][:portNumber]][;property=value[;property=value]]
19
+ const hostPort = connParts[0];
20
+ const hostPortParts = hostPort.split(':');
21
+ const host = hostPortParts[0];
22
+ const port = hostPortParts.length > 1 ? parseInt(hostPortParts[1], 10) : 1433;
23
+ const options = {};
24
+ connParts.slice(1).map((p) => {
25
+ const ps = p.split('=');
26
+ options[ps[0]] = ps[1];
27
+ });
28
+ const username = options.username || options.user;
29
+ const password = options.password || options.pass;
30
+ const database = options.database;
31
+ delete options.username;
32
+ delete options.user;
33
+ delete options.password;
34
+ delete options.pass;
35
+ delete options.database;
36
+ options.encrypt = Boolean(options.encrypt || false);
37
+ return {
38
+ host,
39
+ port,
40
+ database,
41
+ username,
42
+ password,
43
+ options,
44
+ };
45
+ };
46
+ exports.parseURL = parseURL;
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  require('reflect-metadata');
37
37
  const typeorm_1 = require("typeorm");
38
38
  const dbutils = __importStar(require("../utils"));
39
+ const mssql = __importStar(require("./mssql"));
39
40
  class Sql {
40
41
  constructor(options) {
41
42
  this.options = options;
@@ -45,15 +46,20 @@ class Sql {
45
46
  const sqlType = this.options.engine === 'planetscale' ? 'mysql' : this.options.type;
46
47
  while (true) {
47
48
  try {
48
- this.dataSource = new typeorm_1.DataSource({
49
+ const baseOpts = {
49
50
  type: sqlType,
50
- url: this.options.url,
51
51
  synchronize: this.options.engine !== 'planetscale',
52
52
  migrationsTableName: '_jackson_migrations',
53
53
  logging: ['error'],
54
54
  entities: [JacksonStore, JacksonIndex, JacksonTTL],
55
- ssl: this.options.ssl,
56
- });
55
+ };
56
+ if (sqlType === 'mssql') {
57
+ const mssqlOpts = mssql.parseURL(this.options.url);
58
+ this.dataSource = new typeorm_1.DataSource(Object.assign({ host: mssqlOpts.host, port: mssqlOpts.port, database: mssqlOpts.database, username: mssqlOpts.username, password: mssqlOpts.password, options: mssqlOpts.options }, baseOpts));
59
+ }
60
+ else {
61
+ this.dataSource = new typeorm_1.DataSource(Object.assign({ url: this.options.url, ssl: this.options.ssl }, baseOpts));
62
+ }
57
63
  yield this.dataSource.initialize();
58
64
  break;
59
65
  }
@@ -94,7 +100,7 @@ class Sql {
94
100
  this.timerId = setTimeout(this.ttlCleanup, this.options.ttl * 1000);
95
101
  }
96
102
  else {
97
- console.log('Warning: ttl cleanup not enabled, set both "ttl" and "cleanupLimit" options to enable it!');
103
+ console.warn('Warning: ttl cleanup not enabled, set both "ttl" and "cleanupLimit" options to enable it!');
98
104
  }
99
105
  return this;
100
106
  });
@@ -173,7 +179,7 @@ class Sql {
173
179
  // no ttl support for secondary indexes
174
180
  for (const idx of indexes || []) {
175
181
  const key = dbutils.keyForIndex(namespace, idx);
176
- const rec = yield this.indexRepository.findOneBy({
182
+ const rec = yield transactionalEntityManager.findOneBy(this.JacksonIndex, {
177
183
  key,
178
184
  storeKey: store.key,
179
185
  });
package/dist/index.js CHANGED
@@ -10,6 +10,18 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
13
25
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
26
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
27
  };
@@ -38,6 +50,7 @@ const logout_1 = require("./controller/logout");
38
50
  const directory_sync_1 = __importDefault(require("./directory-sync"));
39
51
  const oidc_discovery_1 = require("./controller/oidc-discovery");
40
52
  const sp_config_1 = require("./controller/sp-config");
53
+ const x509 = __importStar(require("./saml/x509"));
41
54
  const defaultOpts = (opts) => {
42
55
  const newOpts = Object.assign({}, opts);
43
56
  if (!newOpts.externalUrl) {
@@ -67,10 +80,13 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
67
80
  const codeStore = db.store('oauth:code', opts.db.ttl);
68
81
  const tokenStore = db.store('oauth:token', opts.db.ttl);
69
82
  const healthCheckStore = db.store('_health:check');
83
+ const certificateStore = db.store('x509:certificates');
70
84
  const connectionAPIController = new api_1.ConnectionAPIController({ connectionStore, opts });
71
85
  const adminController = new admin_1.AdminController({ connectionStore });
72
86
  const healthCheckController = new health_check_1.HealthCheckController({ healthCheckStore });
73
87
  yield healthCheckController.init();
88
+ // Create default certificate if it doesn't exist.
89
+ yield x509.init(certificateStore);
74
90
  const oauthController = new oauth_1.OAuthController({
75
91
  connectionStore,
76
92
  sessionStore,
@@ -85,7 +101,7 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
85
101
  });
86
102
  const directorySync = yield (0, directory_sync_1.default)({ db, opts });
87
103
  const oidcDiscoveryController = new oidc_discovery_1.OidcDiscoveryController({ opts });
88
- const spConfig = new sp_config_1.SPSAMLConfig(opts);
104
+ const spConfig = new sp_config_1.SPSAMLConfig(opts, x509.getDefaultCertificate);
89
105
  // write pre-loaded connections if present
90
106
  const preLoadedConnection = opts.preLoadedConnection || opts.preLoadedConfig;
91
107
  if (preLoadedConnection && preLoadedConnection.length > 0) {
@@ -97,11 +113,11 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
97
113
  else {
98
114
  yield connectionAPIController.createSAMLConnection(connection);
99
115
  }
100
- console.log(`loaded connection for tenant "${connection.tenant}" and product "${connection.product}"`);
116
+ console.info(`loaded connection for tenant "${connection.tenant}" and product "${connection.product}"`);
101
117
  }
102
118
  }
103
119
  const type = opts.db.engine === 'sql' && opts.db.type ? ' Type: ' + opts.db.type : '';
104
- console.log(`Using engine: ${opts.db.engine}.${type}`);
120
+ console.info(`Using engine: ${opts.db.engine}.${type}`);
105
121
  return {
106
122
  spConfig,
107
123
  apiController: connectionAPIController,
@@ -36,6 +36,7 @@ const fs = __importStar(require("fs"));
36
36
  const path = __importStar(require("path"));
37
37
  const url = __importStar(require("url"));
38
38
  const loadConnection = (preLoadedConnection) => __awaiter(void 0, void 0, void 0, function* () {
39
+ var _a;
39
40
  if (preLoadedConnection.startsWith('./')) {
40
41
  preLoadedConnection = path.resolve(process.cwd(), preLoadedConnection);
41
42
  }
@@ -49,7 +50,7 @@ const loadConnection = (preLoadedConnection) => __awaiter(void 0, void 0, void 0
49
50
  if (file.endsWith('.js')) {
50
51
  const filePath = path.join(preLoadedConnection, file);
51
52
  const fileUrl = preLoadedConnection.startsWith('/') ? filePath : url.pathToFileURL(filePath).toString();
52
- const { default: connection, } = yield Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ fileUrl)));
53
+ const { default: connection, } = yield (_a = fileUrl, Promise.resolve().then(() => __importStar(require(_a))));
53
54
  if (!('oidcDiscoveryUrl' in connection)) {
54
55
  const rawMetadata = yield fs.promises.readFile(path.join(preLoadedConnection, path.parse(file).name + '.xml'), 'utf8');
55
56
  connection.encodedRawMetadata = Buffer.from(rawMetadata, 'utf8').toString('base64');
@@ -1,7 +1,13 @@
1
- declare const _default: {
2
- generate: () => {
3
- publicKey: any;
4
- privateKey: any;
5
- };
1
+ import type { Storable } from '../typings';
2
+ export declare const init: (store: Storable) => Promise<{
3
+ publicKey: string;
4
+ privateKey: string;
5
+ }>;
6
+ export declare const generateCertificate: () => {
7
+ publicKey: any;
8
+ privateKey: any;
6
9
  };
7
- export default _default;
10
+ export declare const getDefaultCertificate: () => Promise<{
11
+ publicKey: string;
12
+ privateKey: string;
13
+ }>;
package/dist/saml/x509.js CHANGED
@@ -22,17 +22,38 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
25
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.getDefaultCertificate = exports.generateCertificate = exports.init = void 0;
26
39
  const forge = __importStar(require("node-forge"));
40
+ const crypto_1 = __importDefault(require("crypto"));
27
41
  const pki = forge.pki;
28
- const generate = () => {
42
+ let certificateStore;
43
+ let cachedCertificate;
44
+ const init = (store) => __awaiter(void 0, void 0, void 0, function* () {
45
+ certificateStore = store;
46
+ return yield (0, exports.getDefaultCertificate)();
47
+ });
48
+ exports.init = init;
49
+ const generateCertificate = () => {
29
50
  const today = new Date();
30
51
  const keys = pki.rsa.generateKeyPair(2048);
31
52
  const cert = pki.createCertificate();
32
53
  cert.publicKey = keys.publicKey;
33
54
  cert.serialNumber = '01';
34
55
  cert.validity.notBefore = new Date();
35
- cert.validity.notAfter = new Date(today.setFullYear(today.getFullYear() + 10));
56
+ cert.validity.notAfter = new Date(today.setFullYear(today.getFullYear() + 30));
36
57
  const attrs = [
37
58
  {
38
59
  name: 'commonName',
@@ -62,6 +83,26 @@ const generate = () => {
62
83
  privateKey: pki.privateKeyToPem(keys.privateKey),
63
84
  };
64
85
  };
65
- exports.default = {
66
- generate,
67
- };
86
+ exports.generateCertificate = generateCertificate;
87
+ const getDefaultCertificate = () => __awaiter(void 0, void 0, void 0, function* () {
88
+ if (cachedCertificate && !(yield isCertificateExpired(cachedCertificate.publicKey))) {
89
+ return cachedCertificate;
90
+ }
91
+ if (!certificateStore) {
92
+ throw new Error('Certificate store not initialized');
93
+ }
94
+ cachedCertificate = yield certificateStore.get('default');
95
+ // If certificate is expired let it drop through so it creates a new cert
96
+ if (cachedCertificate && !(yield isCertificateExpired(cachedCertificate.publicKey))) {
97
+ return cachedCertificate;
98
+ }
99
+ // If default certificate is not found or has expired, create one and store it.
100
+ cachedCertificate = (0, exports.generateCertificate)();
101
+ yield certificateStore.put('default', cachedCertificate);
102
+ return cachedCertificate;
103
+ });
104
+ exports.getDefaultCertificate = getDefaultCertificate;
105
+ const isCertificateExpired = (publicKey) => __awaiter(void 0, void 0, void 0, function* () {
106
+ const { validTo } = new crypto_1.default.X509Certificate(publicKey);
107
+ return !(validTo != 'Bad time value' && new Date(validTo) > new Date());
108
+ });
package/dist/typings.d.ts CHANGED
@@ -13,10 +13,12 @@ export interface SAMLSSOConnection extends SSOConnection {
13
13
  export interface SAMLSSOConnectionWithRawMetadata extends SAMLSSOConnection {
14
14
  rawMetadata: string;
15
15
  encodedRawMetadata?: never;
16
+ metadataUrl?: string;
16
17
  }
17
18
  export interface SAMLSSOConnectionWithEncodedMetadata extends SAMLSSOConnection {
18
19
  rawMetadata?: never;
19
20
  encodedRawMetadata: string;
21
+ metadataUrl?: string;
20
22
  }
21
23
  export interface OIDCSSOConnection extends SSOConnection {
22
24
  oidcDiscoveryUrl: string;
@@ -26,6 +28,7 @@ export interface OIDCSSOConnection extends SSOConnection {
26
28
  export interface SAMLSSORecord extends SAMLSSOConnection {
27
29
  clientID: string;
28
30
  clientSecret: string;
31
+ metadataUrl?: string;
29
32
  idpMetadata: {
30
33
  entityID: string;
31
34
  loginType?: string;
@@ -41,10 +44,6 @@ export interface SAMLSSORecord extends SAMLSSOConnection {
41
44
  thumbprint?: string;
42
45
  validTo?: string;
43
46
  };
44
- certs: {
45
- privateKey: string;
46
- publicKey: string;
47
- };
48
47
  }
49
48
  export interface OIDCSSORecord extends SSOConnection {
50
49
  clientID: string;
@@ -56,21 +55,21 @@ export interface OIDCSSORecord extends SSOConnection {
56
55
  clientSecret?: string;
57
56
  };
58
57
  }
59
- export declare type ConnectionType = 'saml' | 'oidc';
60
- declare type ClientIDQuery = {
58
+ export type ConnectionType = 'saml' | 'oidc';
59
+ type ClientIDQuery = {
61
60
  clientID: string;
62
61
  };
63
- declare type TenantQuery = {
62
+ type TenantQuery = {
64
63
  tenant: string;
65
64
  product: string;
66
65
  strategy?: ConnectionType;
67
66
  };
68
- export declare type GetConnectionsQuery = ClientIDQuery | TenantQuery;
69
- export declare type DelConnectionsQuery = (ClientIDQuery & {
67
+ export type GetConnectionsQuery = ClientIDQuery | TenantQuery;
68
+ export type DelConnectionsQuery = (ClientIDQuery & {
70
69
  clientSecret: string;
71
70
  }) | TenantQuery;
72
- export declare type GetConfigQuery = ClientIDQuery | Omit<TenantQuery, 'strategy'>;
73
- export declare type DelConfigQuery = (ClientIDQuery & {
71
+ export type GetConfigQuery = ClientIDQuery | Omit<TenantQuery, 'strategy'>;
72
+ export type DelConfigQuery = (ClientIDQuery & {
74
73
  clientSecret: string;
75
74
  }) | Omit<TenantQuery, 'strategy'>;
76
75
  export interface IConnectionAPIController {
@@ -181,7 +180,7 @@ export interface OAuthReqBodyWithResource extends OAuthReqBody {
181
180
  client_id: 'dummy';
182
181
  resource: string;
183
182
  }
184
- export declare type OAuthReq = OAuthReqBodyWithClientId | OAuthReqBodyWithTenantProduct | OAuthReqBodyWithAccessType | OAuthReqBodyWithResource;
183
+ export type OAuthReq = OAuthReqBodyWithClientId | OAuthReqBodyWithTenantProduct | OAuthReqBodyWithAccessType | OAuthReqBodyWithResource;
185
184
  export interface SAMLResponsePayload {
186
185
  SAMLResponse: string;
187
186
  RelayState: string;
@@ -199,7 +198,7 @@ interface OIDCAuthzResponseError {
199
198
  error: OAuthErrorHandlerParams['error'] | OIDCErrorCodes;
200
199
  error_description?: string;
201
200
  }
202
- export declare type OIDCAuthzResponsePayload = OIDCAuthzResponseSuccess | OIDCAuthzResponseError;
201
+ export type OIDCAuthzResponsePayload = OIDCAuthzResponseSuccess | OIDCAuthzResponseError;
203
202
  interface OAuthTokenReqBody {
204
203
  code: string;
205
204
  grant_type: 'authorization_code';
@@ -215,7 +214,7 @@ export interface OAuthTokenReqWithCredentials extends OAuthTokenReqBody {
215
214
  client_id: string;
216
215
  client_secret: string;
217
216
  }
218
- export declare type OAuthTokenReq = OAuthTokenReqWithCodeVerifier | OAuthTokenReqWithCredentials;
217
+ export type OAuthTokenReq = OAuthTokenReqWithCodeVerifier | OAuthTokenReqWithCredentials;
219
218
  export interface OAuthTokenRes {
220
219
  access_token: string;
221
220
  id_token?: string;
@@ -224,6 +223,7 @@ export interface OAuthTokenRes {
224
223
  }
225
224
  export interface Profile {
226
225
  id: string;
226
+ idHash: string;
227
227
  sub?: string;
228
228
  email: string;
229
229
  firstName: string;
@@ -259,9 +259,9 @@ export interface Encrypted {
259
259
  tag?: string;
260
260
  value: string;
261
261
  }
262
- export declare type EncryptionKey = any;
263
- export declare type DatabaseEngine = 'redis' | 'sql' | 'mongo' | 'mem' | 'planetscale';
264
- export declare type DatabaseType = 'postgres' | 'mysql' | 'mariadb';
262
+ export type EncryptionKey = any;
263
+ export type DatabaseEngine = 'redis' | 'sql' | 'mongo' | 'mem' | 'planetscale';
264
+ export type DatabaseType = 'postgres' | 'mysql' | 'mariadb' | 'mssql';
265
265
  export interface DatabaseOption {
266
266
  engine?: DatabaseEngine;
267
267
  url?: string;
@@ -314,10 +314,6 @@ interface Metadata {
314
314
  }
315
315
  export interface SAMLConnection {
316
316
  idpMetadata: Metadata;
317
- certs: {
318
- privateKey: string;
319
- publicKey: string;
320
- };
321
317
  defaultRedirectUrl: string;
322
318
  }
323
319
  export interface OAuthErrorHandlerParams {
@@ -326,20 +322,21 @@ export interface OAuthErrorHandlerParams {
326
322
  redirect_uri: string;
327
323
  state?: string;
328
324
  }
329
- export declare type OIDCErrorCodes = 'interaction_required' | 'login_required' | 'account_selection_required' | 'consent_required' | 'invalid_request_uri' | 'invalid_request_object' | 'request_not_supported' | 'request_uri_not_supported' | 'registration_not_supported';
325
+ export type OIDCErrorCodes = 'interaction_required' | 'login_required' | 'account_selection_required' | 'consent_required' | 'invalid_request_uri' | 'invalid_request_object' | 'request_not_supported' | 'request_uri_not_supported' | 'registration_not_supported';
330
326
  export interface ISPSAMLConfig {
331
- get(): {
327
+ get(): Promise<{
332
328
  acsUrl: string;
333
329
  entityId: string;
334
330
  response: string;
335
331
  assertionSignature: string;
336
332
  signatureAlgorithm: string;
337
- assertionEncryption: string;
338
- };
333
+ publicKey: string;
334
+ publicKeyString: string;
335
+ }>;
339
336
  toMarkdown(): string;
340
337
  toHTML(): string;
341
338
  }
342
- export declare type DirectorySyncEventType = 'user.created' | 'user.updated' | 'user.deleted' | 'group.created' | 'group.updated' | 'group.deleted' | 'group.user_added' | 'group.user_removed';
339
+ export type DirectorySyncEventType = 'user.created' | 'user.updated' | 'user.deleted' | 'group.created' | 'group.updated' | 'group.deleted' | 'group.user_added' | 'group.user_removed';
343
340
  export interface Base {
344
341
  store(type: 'groups' | 'members' | 'users'): Storable;
345
342
  setTenant(tenant: string): this;
@@ -432,7 +429,7 @@ export interface Groups extends Base {
432
429
  error: ApiError | null;
433
430
  }>;
434
431
  }
435
- export declare type User = {
432
+ export type User = {
436
433
  id: string;
437
434
  email: string;
438
435
  first_name: string;
@@ -440,7 +437,7 @@ export declare type User = {
440
437
  active: boolean;
441
438
  raw?: any;
442
439
  };
443
- export declare type Group = {
440
+ export type Group = {
444
441
  id: string;
445
442
  name: string;
446
443
  raw?: any;
@@ -452,9 +449,9 @@ export declare enum DirectorySyncProviders {
452
449
  'jumpcloud-scim-v2' = "JumpCloud v2.0",
453
450
  'generic-scim-v2' = "SCIM Generic v2.0"
454
451
  }
455
- export declare type DirectoryType = keyof typeof DirectorySyncProviders;
456
- export declare type HTTPMethod = 'POST' | 'PUT' | 'DELETE' | 'GET' | 'PATCH';
457
- export declare type Directory = {
452
+ export type DirectoryType = keyof typeof DirectorySyncProviders;
453
+ export type HTTPMethod = 'POST' | 'PUT' | 'DELETE' | 'GET' | 'PATCH';
454
+ export type Directory = {
458
455
  id: string;
459
456
  name: string;
460
457
  tenant: string;
@@ -471,7 +468,7 @@ export declare type Directory = {
471
468
  secret: string;
472
469
  };
473
470
  };
474
- export declare type DirectorySyncGroupMember = {
471
+ export type DirectorySyncGroupMember = {
475
472
  value: string;
476
473
  email?: string;
477
474
  };
@@ -544,7 +541,7 @@ export interface IWebhookEventsLogger extends Base {
544
541
  delete(id: string): Promise<void>;
545
542
  updateStatus(log: WebhookEventLog, statusCode: number): Promise<WebhookEventLog>;
546
543
  }
547
- export declare type DirectorySyncResponse = {
544
+ export type DirectorySyncResponse = {
548
545
  status: number;
549
546
  data?: any;
550
547
  };
@@ -567,7 +564,7 @@ export interface DirectorySyncRequest {
567
564
  filter?: string;
568
565
  };
569
566
  }
570
- export declare type DirectorySync = {
567
+ export type DirectorySync = {
571
568
  requests: DirectorySyncRequestHandler;
572
569
  directories: DirectoryConfig;
573
570
  groups: Groups;
@@ -0,0 +1,26 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class mssInitial1667949639424 implements MigrationInterface {
4
+ name = 'mssInitial1667949639424'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`CREATE TABLE "jackson_ttl" ("key" varchar(1500) NOT NULL, "expiresAt" bigint NOT NULL, CONSTRAINT "PK_7c9bcdfb4d82e873e19935ec806" PRIMARY KEY ("key"))`);
8
+ await queryRunner.query(`CREATE INDEX "_jackson_ttl_expires_at" ON "jackson_ttl" ("expiresAt") `);
9
+ await queryRunner.query(`CREATE TABLE "jackson_store" ("key" varchar(1500) NOT NULL, "value" text NOT NULL, "iv" varchar(64), "tag" varchar(64), "createdAt" datetime NOT NULL CONSTRAINT "DF_49022ed8c543adefc99ff762200" DEFAULT getdate(), "modifiedAt" datetime, CONSTRAINT "PK_87b6fc1475fbd1228d2f53c6f4a" PRIMARY KEY ("key"))`);
10
+ await queryRunner.query(`CREATE TABLE "jackson_index" ("id" int NOT NULL IDENTITY(1,1), "key" varchar(1500) NOT NULL, "storeKey" varchar(1500) NOT NULL, CONSTRAINT "PK_a95aa83f01e3c73e126856b7820" PRIMARY KEY ("id"))`);
11
+ await queryRunner.query(`CREATE INDEX "_jackson_index_key" ON "jackson_index" ("key") `);
12
+ await queryRunner.query(`CREATE INDEX "_jackson_index_key_store" ON "jackson_index" ("key", "storeKey") `);
13
+ await queryRunner.query(`ALTER TABLE "jackson_index" ADD CONSTRAINT "FK_937b040fb2592b4671cbde09e83" FOREIGN KEY ("storeKey") REFERENCES "jackson_store"("key") ON DELETE CASCADE ON UPDATE NO ACTION`);
14
+ }
15
+
16
+ public async down(queryRunner: QueryRunner): Promise<void> {
17
+ await queryRunner.query(`ALTER TABLE "jackson_index" DROP CONSTRAINT "FK_937b040fb2592b4671cbde09e83"`);
18
+ await queryRunner.query(`DROP INDEX "_jackson_index_key_store" ON "jackson_index"`);
19
+ await queryRunner.query(`DROP INDEX "_jackson_index_key" ON "jackson_index"`);
20
+ await queryRunner.query(`DROP TABLE "jackson_index"`);
21
+ await queryRunner.query(`DROP TABLE "jackson_store"`);
22
+ await queryRunner.query(`DROP INDEX "_jackson_ttl_expires_at" ON "jackson_ttl"`);
23
+ await queryRunner.query(`DROP TABLE "jackson_ttl"`);
24
+ }
25
+
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boxyhq/saml-jackson",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "SAML Jackson library",
5
5
  "keywords": [
6
6
  "SAML 2.0"
@@ -22,10 +22,12 @@
22
22
  "db:migration:generate:mysql": "cross-env DB_TYPE=mysql DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:generate -d typeorm.ts migration/mysql/ms_${MIGRATION_NAME}",
23
23
  "db:migration:generate:planetscale": "cross-env DB_ENGINE=planetscale DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:generate -d typeorm.ts migration/mysql/ms_${MIGRATION_NAME}",
24
24
  "db:migration:generate:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:generate -d typeorm.ts migration/mariadb/md_${MIGRATION_NAME}",
25
+ "db:migration:generate:mssql": "cross-env DB_TYPE=mssql DB_URL='sqlserver://localhost:1433;database=master;username=sa;password=123ABabc!' ts-node --transpile-only ./node_modules/typeorm/cli.js migration:generate -d typeorm.ts migration/mssql/mss_${MIGRATION_NAME}",
25
26
  "db:migration:run:postgres": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
26
27
  "db:migration:run:mysql": "cross-env DB_TYPE=mysql DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
27
28
  "db:migration:run:planetscale": "cross-env DB_SSL=true DB_ENGINE=planetscale DB_URL=${PLANETSCALE_URL} ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
28
29
  "db:migration:run:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
30
+ "db:migration:run:mssql": "cross-env DB_TYPE=mssql DB_URL='sqlserver://localhost:1433;database=master;username=sa;password=123ABabc!' ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
29
31
  "prepublishOnly": "npm run build",
30
32
  "test": "tap --ts --timeout=100 --coverage-map=map.js test/**/*.test.ts",
31
33
  "sort": "npx sort-package-json"
@@ -38,18 +40,19 @@
38
40
  "statements": 70
39
41
  },
40
42
  "dependencies": {
41
- "@boxyhq/saml20": "1.0.11",
43
+ "@boxyhq/saml20": "1.0.14",
42
44
  "@opentelemetry/api": "1.0.4",
43
45
  "@opentelemetry/api-metrics": "0.27.0",
44
46
  "axios": "1.1.3",
45
- "jose": "4.10.4",
46
- "marked": "4.2.2",
47
+ "jose": "4.11.0",
48
+ "marked": "4.2.3",
47
49
  "mongodb": "4.11.0",
50
+ "mssql": "9.0.1",
48
51
  "mysql2": "2.3.3",
49
- "openid-client": "5.2.1",
50
52
  "node-forge": "1.3.1",
53
+ "openid-client": "5.3.0",
51
54
  "pg": "8.8.0",
52
- "redis": "4.4.0",
55
+ "redis": "4.5.0",
53
56
  "reflect-metadata": "0.1.13",
54
57
  "ripemd160": "2.0.2",
55
58
  "typeorm": "0.3.10",
@@ -61,17 +64,17 @@
61
64
  "@types/node": "18.11.9",
62
65
  "@types/sinon": "10.0.13",
63
66
  "@types/tap": "15.0.7",
64
- "@typescript-eslint/eslint-plugin": "5.42.0",
65
- "@typescript-eslint/parser": "5.42.0",
67
+ "@typescript-eslint/eslint-plugin": "5.43.0",
68
+ "@typescript-eslint/parser": "5.42.1",
66
69
  "cross-env": "7.0.3",
67
- "eslint": "8.27.0",
70
+ "eslint": "8.28.0",
68
71
  "eslint-config-prettier": "8.5.0",
69
72
  "prettier": "2.7.1",
70
- "sinon": "14.0.1",
73
+ "sinon": "14.0.2",
71
74
  "tap": "16.3.0",
72
75
  "ts-node": "10.9.1",
73
76
  "tsconfig-paths": "4.1.0",
74
- "typescript": "4.8.4"
77
+ "typescript": "4.9.3"
75
78
  },
76
79
  "engines": {
77
80
  "node": ">=14.18.1 <=18.x"