@boxyhq/saml-jackson 1.3.5 → 1.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"