@boxyhq/saml-jackson 1.3.4 → 1.3.6
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/controller/api.d.ts +0 -11
- package/dist/controller/api.js +0 -11
- package/dist/controller/connection/saml.js +0 -6
- package/dist/controller/logout.js +3 -1
- package/dist/controller/oauth.js +7 -25
- package/dist/controller/sp-config.d.ts +6 -5
- package/dist/controller/sp-config.js +29 -15
- package/dist/db/db.js +17 -5
- package/dist/db/redis.js +1 -1
- package/dist/db/sql/mssql/entity/JacksonIndex.d.ts +7 -0
- package/dist/db/sql/mssql/entity/JacksonIndex.js +41 -0
- package/dist/db/sql/mssql/entity/JacksonStore.d.ts +8 -0
- package/dist/db/sql/mssql/entity/JacksonStore.js +55 -0
- package/dist/db/sql/mssql/entity/JacksonTTL.d.ts +4 -0
- package/dist/db/sql/mssql/entity/JacksonTTL.js +29 -0
- package/dist/db/sql/mssql.d.ts +1 -0
- package/dist/db/sql/mssql.js +46 -0
- package/dist/db/sql/sql.js +12 -6
- package/dist/index.js +19 -3
- package/dist/saml/x509.d.ts +12 -6
- package/dist/saml/x509.js +46 -5
- package/dist/typings.d.ts +5 -12
- package/migration/mssql/1667949639424-mss_Initial.ts +26 -0
- package/package.json +13 -10
package/dist/controller/api.d.ts
CHANGED
@@ -31,10 +31,6 @@ export declare class ConnectionAPIController implements IConnectionAPIController
|
|
31
31
|
* "description": "SP for hoppscotch.io",
|
32
32
|
* "clientID": "Xq8AJt3yYAxmXizsCWmUBDRiVP1iTC8Y/otnvFIMitk",
|
33
33
|
* "clientSecret": "00e3e11a3426f97d8000000738300009130cd45419c5943",
|
34
|
-
* "certs": {
|
35
|
-
* "publicKey": "-----BEGIN CERTIFICATE-----.......-----END CERTIFICATE-----",
|
36
|
-
* "privateKey": "-----BEGIN PRIVATE KEY-----......-----END PRIVATE KEY-----"
|
37
|
-
* }
|
38
34
|
* }
|
39
35
|
* validationErrorsPost:
|
40
36
|
* description: Please provide rawMetadata or encodedRawMetadata | Please provide a defaultRedirectUrl | Please provide redirectUrl | redirectUrl is invalid | Exceeded maximum number of allowed redirect urls | defaultRedirectUrl is invalid | Please provide tenant | Please provide product | Please provide a friendly name | Description should not exceed 100 characters | Strategy: xxxx not supported | Please provide the clientId from OpenID Provider | Please provide the clientSecret from OpenID Provider | Please provide the discoveryUrl for the OpenID Provider
|
@@ -362,9 +358,6 @@ export declare class ConnectionAPIController implements IConnectionAPIController
|
|
362
358
|
* idpMetadata:
|
363
359
|
* type: object
|
364
360
|
* description: SAML IdP metadata
|
365
|
-
* certs:
|
366
|
-
* type: object
|
367
|
-
* description: Certs generated for SAML connection
|
368
361
|
* oidcProvider:
|
369
362
|
* type: object
|
370
363
|
* description: OIDC IdP metadata
|
@@ -435,10 +428,6 @@ export declare class ConnectionAPIController implements IConnectionAPIController
|
|
435
428
|
* "description": "SP for hoppscotch.io",
|
436
429
|
* "clientID": "Xq8AJt3yYAxmXizsCWmUBDRiVP1iTC8Y/otnvFIMitk",
|
437
430
|
* "clientSecret": "00e3e11a3426f97d8000000738300009130cd45419c5943",
|
438
|
-
* "certs": {
|
439
|
-
* "publicKey": "-----BEGIN CERTIFICATE-----.......-----END CERTIFICATE-----",
|
440
|
-
* "privateKey": "-----BEGIN PRIVATE KEY-----......-----END PRIVATE KEY-----"
|
441
|
-
* }
|
442
431
|
* }
|
443
432
|
* '400':
|
444
433
|
* $ref: '#/responses/400Get'
|
package/dist/controller/api.js
CHANGED
@@ -72,10 +72,6 @@ class ConnectionAPIController {
|
|
72
72
|
* "description": "SP for hoppscotch.io",
|
73
73
|
* "clientID": "Xq8AJt3yYAxmXizsCWmUBDRiVP1iTC8Y/otnvFIMitk",
|
74
74
|
* "clientSecret": "00e3e11a3426f97d8000000738300009130cd45419c5943",
|
75
|
-
* "certs": {
|
76
|
-
* "publicKey": "-----BEGIN CERTIFICATE-----.......-----END CERTIFICATE-----",
|
77
|
-
* "privateKey": "-----BEGIN PRIVATE KEY-----......-----END PRIVATE KEY-----"
|
78
|
-
* }
|
79
75
|
* }
|
80
76
|
* validationErrorsPost:
|
81
77
|
* description: Please provide rawMetadata or encodedRawMetadata | Please provide a defaultRedirectUrl | Please provide redirectUrl | redirectUrl is invalid | Exceeded maximum number of allowed redirect urls | defaultRedirectUrl is invalid | Please provide tenant | Please provide product | Please provide a friendly name | Description should not exceed 100 characters | Strategy: xxxx not supported | Please provide the clientId from OpenID Provider | Please provide the clientSecret from OpenID Provider | Please provide the discoveryUrl for the OpenID Provider
|
@@ -431,9 +427,6 @@ class ConnectionAPIController {
|
|
431
427
|
* idpMetadata:
|
432
428
|
* type: object
|
433
429
|
* description: SAML IdP metadata
|
434
|
-
* certs:
|
435
|
-
* type: object
|
436
|
-
* description: Certs generated for SAML connection
|
437
430
|
* oidcProvider:
|
438
431
|
* type: object
|
439
432
|
* description: OIDC IdP metadata
|
@@ -549,10 +542,6 @@ class ConnectionAPIController {
|
|
549
542
|
* "description": "SP for hoppscotch.io",
|
550
543
|
* "clientID": "Xq8AJt3yYAxmXizsCWmUBDRiVP1iTC8Y/otnvFIMitk",
|
551
544
|
* "clientSecret": "00e3e11a3426f97d8000000738300009130cd45419c5943",
|
552
|
-
* "certs": {
|
553
|
-
* "publicKey": "-----BEGIN CERTIFICATE-----.......-----END CERTIFICATE-----",
|
554
|
-
* "privateKey": "-----BEGIN PRIVATE KEY-----......-----END PRIVATE KEY-----"
|
555
|
-
* }
|
556
545
|
* }
|
557
546
|
* '400':
|
558
547
|
* $ref: '#/responses/400Get'
|
@@ -50,7 +50,6 @@ const crypto_1 = __importDefault(require("crypto"));
|
|
50
50
|
const dbutils = __importStar(require("../../db/utils"));
|
51
51
|
const utils_1 = require("../utils");
|
52
52
|
const saml20_1 = __importDefault(require("@boxyhq/saml20"));
|
53
|
-
const x509_1 = __importDefault(require("../../saml/x509"));
|
54
53
|
const error_1 = require("../error");
|
55
54
|
const saml = {
|
56
55
|
create: (body, connectionStore) => __awaiter(void 0, void 0, void 0, function* () {
|
@@ -86,12 +85,7 @@ const saml = {
|
|
86
85
|
}
|
87
86
|
idpMetadata.provider = providerName ? providerName : 'Unknown';
|
88
87
|
record.clientID = dbutils.keyDigest(dbutils.keyFromParts(tenant, product, idpMetadata.entityID));
|
89
|
-
const certs = yield x509_1.default.generate();
|
90
|
-
if (!certs) {
|
91
|
-
throw new error_1.JacksonError('Error generating x509 certs');
|
92
|
-
}
|
93
88
|
record.idpMetadata = idpMetadata;
|
94
|
-
record.certs = certs;
|
95
89
|
const exists = yield connectionStore.get(record.clientID);
|
96
90
|
if (exists) {
|
97
91
|
connectionClientSecret = exists.clientSecret;
|
@@ -46,6 +46,7 @@ const saml20_1 = __importDefault(require("@boxyhq/saml20"));
|
|
46
46
|
const error_1 = require("./error");
|
47
47
|
const redirect = __importStar(require("./oauth/redirect"));
|
48
48
|
const utils_1 = require("./utils");
|
49
|
+
const x509_1 = require("../saml/x509");
|
49
50
|
const deflateRawAsync = (0, util_1.promisify)(zlib_1.deflateRaw);
|
50
51
|
const relayStatePrefix = 'boxyhq_jackson_';
|
51
52
|
const logoutXPath = "/*[local-name(.)='LogoutRequest']";
|
@@ -72,7 +73,8 @@ class LogoutController {
|
|
72
73
|
if (!samlConnection) {
|
73
74
|
throw new error_1.JacksonError('SAML connection not found.', 403);
|
74
75
|
}
|
75
|
-
const { idpMetadata: { slo, provider },
|
76
|
+
const { idpMetadata: { slo, provider }, } = samlConnection;
|
77
|
+
const { privateKey, publicKey } = yield (0, x509_1.getDefaultCertificate)();
|
76
78
|
if ('redirectUrl' in slo === false && 'postUrl' in slo === false) {
|
77
79
|
throw new error_1.JacksonError(`${provider} doesn't support SLO or disabled by IdP.`, 400);
|
78
80
|
}
|
package/dist/controller/oauth.js
CHANGED
@@ -50,7 +50,7 @@ const allowed = __importStar(require("./oauth/allowed"));
|
|
50
50
|
const codeVerifier = __importStar(require("./oauth/code-verifier"));
|
51
51
|
const redirect = __importStar(require("./oauth/redirect"));
|
52
52
|
const utils_1 = require("./utils");
|
53
|
-
const x509_1 =
|
53
|
+
const x509_1 = require("../saml/x509");
|
54
54
|
const deflateRawAsync = (0, util_1.promisify)(zlib_1.deflateRaw);
|
55
55
|
const validateSAMLResponse = (rawResponse, validateOpts) => __awaiter(void 0, void 0, void 0, function* () {
|
56
56
|
const profile = yield saml20_1.default.validate(rawResponse, validateOpts);
|
@@ -312,27 +312,8 @@ class OAuthController {
|
|
312
312
|
}),
|
313
313
|
};
|
314
314
|
}
|
315
|
+
const cert = yield (0, x509_1.getDefaultCertificate)();
|
315
316
|
try {
|
316
|
-
const { validTo } = new crypto_1.default.X509Certificate(connection.certs.publicKey);
|
317
|
-
const isValidExpiry = validTo != 'Bad time value' && new Date(validTo) > new Date();
|
318
|
-
if (!isValidExpiry) {
|
319
|
-
const certs = yield x509_1.default.generate();
|
320
|
-
connection.certs = certs;
|
321
|
-
if (certs) {
|
322
|
-
yield this.connectionStore.put(connection.clientID, connection, {
|
323
|
-
// secondary index on entityID
|
324
|
-
name: utils_1.IndexNames.EntityID,
|
325
|
-
value: connection.idpMetadata.entityID,
|
326
|
-
}, {
|
327
|
-
// secondary index on tenant + product
|
328
|
-
name: utils_1.IndexNames.TenantProduct,
|
329
|
-
value: dbutils.keyFromParts(connection.tenant, connection.product),
|
330
|
-
});
|
331
|
-
}
|
332
|
-
else {
|
333
|
-
throw new Error('Error generating x509 certs');
|
334
|
-
}
|
335
|
-
}
|
336
317
|
// We will get undefined or Space delimited, case sensitive list of ASCII string values in prompt
|
337
318
|
// If login is one of the value in prompt we want to enable forceAuthn
|
338
319
|
// Else use the saml connection forceAuthn value
|
@@ -341,8 +322,8 @@ class OAuthController {
|
|
341
322
|
ssoUrl,
|
342
323
|
entityID: this.opts.samlAudience,
|
343
324
|
callbackUrl: this.opts.externalUrl + this.opts.samlPath,
|
344
|
-
signingKey:
|
345
|
-
publicKey:
|
325
|
+
signingKey: cert.privateKey,
|
326
|
+
publicKey: cert.publicKey,
|
346
327
|
forceAuthn: promptOptions.length > 0 ? true : !!connection.forceAuthn,
|
347
328
|
});
|
348
329
|
}
|
@@ -382,7 +363,7 @@ class OAuthController {
|
|
382
363
|
oidcCodeVerifier = openid_client_1.generators.codeVerifier();
|
383
364
|
const code_challenge = openid_client_1.generators.codeChallenge(oidcCodeVerifier);
|
384
365
|
ssoUrl = oidcClient.authorizationUrl({
|
385
|
-
scope: [...requestedScopes, 'openid', 'email', 'profile'
|
366
|
+
scope: [...requestedScopes, 'openid', 'email', 'profile']
|
386
367
|
.filter((value, index, self) => self.indexOf(value) === index) // filter out duplicates
|
387
368
|
.join(' '),
|
388
369
|
code_challenge,
|
@@ -544,10 +525,11 @@ class OAuthController {
|
|
544
525
|
if (!samlConnection) {
|
545
526
|
throw new error_1.JacksonError('SAML connection not found.', 403);
|
546
527
|
}
|
528
|
+
const { privateKey } = yield (0, x509_1.getDefaultCertificate)();
|
547
529
|
const validateOpts = {
|
548
530
|
thumbprint: samlConnection.idpMetadata.thumbprint,
|
549
531
|
audience: this.opts.samlAudience,
|
550
|
-
privateKey
|
532
|
+
privateKey,
|
551
533
|
};
|
552
534
|
if (session &&
|
553
535
|
session.redirect_uri &&
|
@@ -1,21 +1,22 @@
|
|
1
1
|
import type { JacksonOption } from '../typings';
|
2
2
|
export declare class SPSAMLConfig {
|
3
3
|
private opts;
|
4
|
-
|
4
|
+
private getDefaultCertificate;
|
5
|
+
constructor(opts: JacksonOption, getDefaultCertificate: any);
|
5
6
|
private get acsUrl();
|
6
7
|
private get entityId();
|
7
8
|
private get responseSigned();
|
8
9
|
private get assertionSignature();
|
9
10
|
private get signatureAlgorithm();
|
10
|
-
|
11
|
-
get(): {
|
11
|
+
get(): Promise<{
|
12
12
|
acsUrl: string;
|
13
13
|
entityId: string;
|
14
14
|
response: string;
|
15
15
|
assertionSignature: string;
|
16
16
|
signatureAlgorithm: string;
|
17
|
-
|
18
|
-
|
17
|
+
publicKey: string;
|
18
|
+
publicKeyString: string;
|
19
|
+
}>;
|
19
20
|
toMarkdown(): string;
|
20
21
|
toHTML(): string;
|
21
22
|
}
|
@@ -1,11 +1,25 @@
|
|
1
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
2
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
15
|
exports.SPSAMLConfig = void 0;
|
4
16
|
const marked_1 = require("marked");
|
17
|
+
const saml20_1 = __importDefault(require("@boxyhq/saml20"));
|
5
18
|
// Service Provider SAML Configuration
|
6
19
|
class SPSAMLConfig {
|
7
|
-
constructor(opts) {
|
20
|
+
constructor(opts, getDefaultCertificate) {
|
8
21
|
this.opts = opts;
|
22
|
+
this.getDefaultCertificate = getDefaultCertificate;
|
9
23
|
}
|
10
24
|
get acsUrl() {
|
11
25
|
return `${this.opts.externalUrl}${this.opts.samlPath}`;
|
@@ -22,18 +36,19 @@ class SPSAMLConfig {
|
|
22
36
|
get signatureAlgorithm() {
|
23
37
|
return 'RSA-SHA256';
|
24
38
|
}
|
25
|
-
get assertionEncryption() {
|
26
|
-
return 'Unencrypted';
|
27
|
-
}
|
28
39
|
get() {
|
29
|
-
return {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
41
|
+
const cert = yield this.getDefaultCertificate();
|
42
|
+
return {
|
43
|
+
acsUrl: this.acsUrl,
|
44
|
+
entityId: this.entityId,
|
45
|
+
response: this.responseSigned,
|
46
|
+
assertionSignature: this.assertionSignature,
|
47
|
+
signatureAlgorithm: this.signatureAlgorithm,
|
48
|
+
publicKey: cert.publicKey,
|
49
|
+
publicKeyString: saml20_1.default.stripCertHeaderAndFooter(cert.publicKey),
|
50
|
+
};
|
51
|
+
});
|
37
52
|
}
|
38
53
|
toMarkdown() {
|
39
54
|
return markdownTemplate
|
@@ -41,8 +56,7 @@ class SPSAMLConfig {
|
|
41
56
|
.replace('{{entityId}}', this.entityId)
|
42
57
|
.replace('{{responseSigned}}', this.responseSigned)
|
43
58
|
.replace('{{assertionSignature}}', this.assertionSignature)
|
44
|
-
.replace('{{signatureAlgorithm}}', this.signatureAlgorithm)
|
45
|
-
.replace('{{assertionEncryption}}', this.assertionEncryption);
|
59
|
+
.replace('{{signatureAlgorithm}}', this.signatureAlgorithm);
|
46
60
|
}
|
47
61
|
toHTML() {
|
48
62
|
return marked_1.marked.parse(this.toMarkdown());
|
@@ -70,5 +84,5 @@ Your Identity Provider (IdP) will ask for the following information while config
|
|
70
84
|
{{signatureAlgorithm}}
|
71
85
|
|
72
86
|
**Assertion Encryption** <br />
|
73
|
-
|
87
|
+
If you want to encrypt the assertion, you can download our [public certificate](/.well-known/saml.cer). Otherwise select the 'Unencrypted' option.
|
74
88
|
`;
|
package/dist/db/db.js
CHANGED
@@ -47,6 +47,9 @@ const JacksonTTL_1 = require("./sql/entity/JacksonTTL");
|
|
47
47
|
const JacksonStore_2 = require("./planetscale/entity/JacksonStore");
|
48
48
|
const JacksonIndex_2 = require("./planetscale/entity/JacksonIndex");
|
49
49
|
const JacksonTTL_2 = require("./planetscale/entity/JacksonTTL");
|
50
|
+
const JacksonStore_3 = require("./sql/mssql/entity/JacksonStore");
|
51
|
+
const JacksonIndex_3 = require("./sql/mssql/entity/JacksonIndex");
|
52
|
+
const JacksonTTL_3 = require("./sql/mssql/entity/JacksonTTL");
|
50
53
|
const decrypt = (res, encryptionKey) => {
|
51
54
|
if (res.iv && res.tag) {
|
52
55
|
return JSON.parse(encrypter.decrypt(res.value, res.iv, res.tag, encryptionKey));
|
@@ -113,11 +116,20 @@ exports.default = {
|
|
113
116
|
case 'redis':
|
114
117
|
return new DB(yield redis_1.default.new(options), encryptionKey);
|
115
118
|
case 'sql':
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
119
|
+
switch (options.type) {
|
120
|
+
case 'mssql':
|
121
|
+
return new DB(yield sql_1.default.new(options, {
|
122
|
+
JacksonStore: JacksonStore_3.JacksonStore,
|
123
|
+
JacksonIndex: JacksonIndex_3.JacksonIndex,
|
124
|
+
JacksonTTL: JacksonTTL_3.JacksonTTL,
|
125
|
+
}), encryptionKey);
|
126
|
+
default:
|
127
|
+
return new DB(yield sql_1.default.new(options, {
|
128
|
+
JacksonStore: JacksonStore_1.JacksonStore,
|
129
|
+
JacksonIndex: JacksonIndex_1.JacksonIndex,
|
130
|
+
JacksonTTL: JacksonTTL_1.JacksonTTL,
|
131
|
+
}), encryptionKey);
|
132
|
+
}
|
121
133
|
case 'planetscale':
|
122
134
|
return new DB(yield sql_1.default.new(options, {
|
123
135
|
JacksonStore: JacksonStore_2.JacksonStore,
|
package/dist/db/redis.js
CHANGED
@@ -54,7 +54,7 @@ class Redis {
|
|
54
54
|
};
|
55
55
|
}
|
56
56
|
this.client = redis.createClient(opts);
|
57
|
-
this.client.on('error', (err) => console.
|
57
|
+
this.client.on('error', (err) => console.info('Redis Client Error', err));
|
58
58
|
yield this.client.connect();
|
59
59
|
return this;
|
60
60
|
});
|
@@ -0,0 +1,41 @@
|
|
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.JacksonIndex = void 0;
|
10
|
+
const JacksonStore_1 = require("./JacksonStore");
|
11
|
+
const typeorm_1 = require("typeorm");
|
12
|
+
let JacksonIndex = class JacksonIndex {
|
13
|
+
};
|
14
|
+
__decorate([
|
15
|
+
(0, typeorm_1.PrimaryGeneratedColumn)()
|
16
|
+
], JacksonIndex.prototype, "id", void 0);
|
17
|
+
__decorate([
|
18
|
+
(0, typeorm_1.Index)('_jackson_index_key'),
|
19
|
+
(0, typeorm_1.Column)({
|
20
|
+
type: 'varchar',
|
21
|
+
length: 1500,
|
22
|
+
})
|
23
|
+
], JacksonIndex.prototype, "key", void 0);
|
24
|
+
__decorate([
|
25
|
+
(0, typeorm_1.Column)({
|
26
|
+
type: 'varchar',
|
27
|
+
length: 1500,
|
28
|
+
})
|
29
|
+
], JacksonIndex.prototype, "storeKey", void 0);
|
30
|
+
__decorate([
|
31
|
+
(0, typeorm_1.ManyToOne)(() => JacksonStore_1.JacksonStore, undefined, {
|
32
|
+
//inverseSide: 'in',
|
33
|
+
eager: true,
|
34
|
+
onDelete: 'CASCADE',
|
35
|
+
})
|
36
|
+
], JacksonIndex.prototype, "store", void 0);
|
37
|
+
JacksonIndex = __decorate([
|
38
|
+
(0, typeorm_1.Index)('_jackson_index_key_store', ['key', 'storeKey']),
|
39
|
+
(0, typeorm_1.Entity)()
|
40
|
+
], JacksonIndex);
|
41
|
+
exports.JacksonIndex = JacksonIndex;
|
@@ -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,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;
|
package/dist/db/sql/sql.js
CHANGED
@@ -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
|
-
|
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
|
-
|
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.
|
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
|
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.
|
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.
|
120
|
+
console.info(`Using engine: ${opts.db.engine}.${type}`);
|
105
121
|
return {
|
106
122
|
spConfig,
|
107
123
|
apiController: connectionAPIController,
|
package/dist/saml/x509.d.ts
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
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
|
-
|
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() +
|
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.
|
66
|
-
|
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
@@ -41,10 +41,6 @@ export interface SAMLSSORecord extends SAMLSSOConnection {
|
|
41
41
|
thumbprint?: string;
|
42
42
|
validTo?: string;
|
43
43
|
};
|
44
|
-
certs: {
|
45
|
-
privateKey: string;
|
46
|
-
publicKey: string;
|
47
|
-
};
|
48
44
|
}
|
49
45
|
export interface OIDCSSORecord extends SSOConnection {
|
50
46
|
clientID: string;
|
@@ -261,7 +257,7 @@ export interface Encrypted {
|
|
261
257
|
}
|
262
258
|
export declare type EncryptionKey = any;
|
263
259
|
export declare type DatabaseEngine = 'redis' | 'sql' | 'mongo' | 'mem' | 'planetscale';
|
264
|
-
export declare type DatabaseType = 'postgres' | 'mysql' | 'mariadb';
|
260
|
+
export declare type DatabaseType = 'postgres' | 'mysql' | 'mariadb' | 'mssql';
|
265
261
|
export interface DatabaseOption {
|
266
262
|
engine?: DatabaseEngine;
|
267
263
|
url?: string;
|
@@ -314,10 +310,6 @@ interface Metadata {
|
|
314
310
|
}
|
315
311
|
export interface SAMLConnection {
|
316
312
|
idpMetadata: Metadata;
|
317
|
-
certs: {
|
318
|
-
privateKey: string;
|
319
|
-
publicKey: string;
|
320
|
-
};
|
321
313
|
defaultRedirectUrl: string;
|
322
314
|
}
|
323
315
|
export interface OAuthErrorHandlerParams {
|
@@ -328,14 +320,15 @@ export interface OAuthErrorHandlerParams {
|
|
328
320
|
}
|
329
321
|
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';
|
330
322
|
export interface ISPSAMLConfig {
|
331
|
-
get(): {
|
323
|
+
get(): Promise<{
|
332
324
|
acsUrl: string;
|
333
325
|
entityId: string;
|
334
326
|
response: string;
|
335
327
|
assertionSignature: string;
|
336
328
|
signatureAlgorithm: string;
|
337
|
-
|
338
|
-
|
329
|
+
publicKey: string;
|
330
|
+
publicKeyString: string;
|
331
|
+
}>;
|
339
332
|
toMarkdown(): string;
|
340
333
|
toHTML(): string;
|
341
334
|
}
|
@@ -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.
|
3
|
+
"version": "1.3.6",
|
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"
|
@@ -42,14 +44,15 @@
|
|
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.
|
46
|
-
"marked": "4.
|
47
|
+
"jose": "4.10.4",
|
48
|
+
"marked": "4.2.2",
|
47
49
|
"mongodb": "4.11.0",
|
50
|
+
"mssql": "9.0.1",
|
48
51
|
"mysql2": "2.3.3",
|
49
|
-
"openid-client": "5.1.10",
|
50
52
|
"node-forge": "1.3.1",
|
53
|
+
"openid-client": "5.2.1",
|
51
54
|
"pg": "8.8.0",
|
52
|
-
"redis": "4.
|
55
|
+
"redis": "4.4.0",
|
53
56
|
"reflect-metadata": "0.1.13",
|
54
57
|
"ripemd160": "2.0.2",
|
55
58
|
"typeorm": "0.3.10",
|
@@ -58,13 +61,13 @@
|
|
58
61
|
},
|
59
62
|
"devDependencies": {
|
60
63
|
"@faker-js/faker": "7.6.0",
|
61
|
-
"@types/node": "18.11.
|
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.
|
65
|
-
"@typescript-eslint/parser": "5.
|
67
|
+
"@typescript-eslint/eslint-plugin": "5.42.0",
|
68
|
+
"@typescript-eslint/parser": "5.42.0",
|
66
69
|
"cross-env": "7.0.3",
|
67
|
-
"eslint": "8.
|
70
|
+
"eslint": "8.27.0",
|
68
71
|
"eslint-config-prettier": "8.5.0",
|
69
72
|
"prettier": "2.7.1",
|
70
73
|
"sinon": "14.0.1",
|
@@ -74,6 +77,6 @@
|
|
74
77
|
"typescript": "4.8.4"
|
75
78
|
},
|
76
79
|
"engines": {
|
77
|
-
"node": ">=14.18.1 <=
|
80
|
+
"node": ">=14.18.1 <=18.x"
|
78
81
|
}
|
79
82
|
}
|