@boxyhq/saml-jackson 1.0.4 → 1.0.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.
- package/dist/controller/oauth.js +13 -3
- package/dist/controller/utils.d.ts +1 -1
- package/dist/controller/utils.js +4 -3
- package/dist/db/db.js +17 -1
- package/dist/db/mongo.js +2 -1
- package/dist/db/planetscale/entity/JacksonIndex.d.ts +5 -0
- package/dist/db/planetscale/entity/JacksonIndex.js +34 -0
- package/dist/db/planetscale/entity/JacksonStore.d.ts +8 -0
- package/dist/db/planetscale/entity/JacksonStore.js +55 -0
- package/dist/db/planetscale/entity/JacksonTTL.d.ts +4 -0
- package/dist/db/planetscale/entity/JacksonTTL.js +29 -0
- package/dist/db/sql/sql.d.ts +9 -2
- package/dist/db/sql/sql.js +46 -26
- package/dist/typings.d.ts +4 -2
- package/migration/planetscale/1653746497237-ms_nocascade.ts +22 -0
- package/package.json +17 -14
package/dist/controller/oauth.js
CHANGED
@@ -50,7 +50,7 @@ const redirect = __importStar(require("./oauth/redirect"));
|
|
50
50
|
const utils_1 = require("./utils");
|
51
51
|
const deflateRawAsync = (0, util_1.promisify)(zlib_1.deflateRaw);
|
52
52
|
const validateResponse = (rawResponse, validateOpts) => __awaiter(void 0, void 0, void 0, function* () {
|
53
|
-
const profile = yield saml20_1.default.
|
53
|
+
const profile = yield saml20_1.default.validate(rawResponse, validateOpts);
|
54
54
|
if (profile && profile.claims) {
|
55
55
|
// we map claims to our attributes id, email, firstName, lastName where possible. We also map original claims to raw
|
56
56
|
profile.claims = claims_1.default.map(profile.claims);
|
@@ -237,6 +237,7 @@ class OAuthController {
|
|
237
237
|
error: 'unsupported_response_type',
|
238
238
|
error_description: 'Only Authorization Code grant is supported',
|
239
239
|
redirect_uri,
|
240
|
+
state,
|
240
241
|
}),
|
241
242
|
};
|
242
243
|
}
|
@@ -258,6 +259,7 @@ class OAuthController {
|
|
258
259
|
error: 'invalid_request',
|
259
260
|
error_description: 'SAML binding could not be retrieved',
|
260
261
|
redirect_uri,
|
262
|
+
state,
|
261
263
|
}),
|
262
264
|
};
|
263
265
|
}
|
@@ -323,12 +325,14 @@ class OAuthController {
|
|
323
325
|
error: 'server_error',
|
324
326
|
error_description: (0, utils_1.getErrorMessage)(err),
|
325
327
|
redirect_uri,
|
328
|
+
state,
|
326
329
|
}),
|
327
330
|
};
|
328
331
|
}
|
329
332
|
});
|
330
333
|
}
|
331
334
|
samlResponse(body) {
|
335
|
+
var _a, _b;
|
332
336
|
return __awaiter(this, void 0, void 0, function* () {
|
333
337
|
const { SAMLResponse, idp_hint } = body;
|
334
338
|
let RelayState = body.RelayState || ''; // RelayState will contain the sessionId from earlier quasi-oauth flow
|
@@ -339,10 +343,13 @@ class OAuthController {
|
|
339
343
|
}
|
340
344
|
RelayState = RelayState.replace(utils_1.relayStatePrefix, '');
|
341
345
|
const rawResponse = Buffer.from(SAMLResponse, 'base64').toString();
|
342
|
-
const
|
346
|
+
const issuer = saml20_1.default.parseIssuer(rawResponse);
|
347
|
+
if (!issuer) {
|
348
|
+
throw new error_1.JacksonError('Issuer not found.', 403);
|
349
|
+
}
|
343
350
|
const samlConfigs = yield this.configStore.getByIndex({
|
344
351
|
name: utils_1.IndexNames.EntityID,
|
345
|
-
value:
|
352
|
+
value: issuer,
|
346
353
|
});
|
347
354
|
if (!samlConfigs || samlConfigs.length === 0) {
|
348
355
|
throw new error_1.JacksonError('SAML configuration not found.', 403);
|
@@ -382,6 +389,7 @@ class OAuthController {
|
|
382
389
|
const validateOpts = {
|
383
390
|
thumbprint: samlConfig.idpMetadata.thumbprint,
|
384
391
|
audience: this.opts.samlAudience,
|
392
|
+
privateKey: samlConfig.certs.privateKey,
|
385
393
|
};
|
386
394
|
if (session && session.redirect_uri && !allowed.redirect(session.redirect_uri, samlConfig.redirectUrl)) {
|
387
395
|
throw new error_1.JacksonError('Redirect URL is not allowed.', 403);
|
@@ -401,6 +409,7 @@ class OAuthController {
|
|
401
409
|
error: 'access_denied',
|
402
410
|
error_description: (0, utils_1.getErrorMessage)(err),
|
403
411
|
redirect_uri,
|
412
|
+
state: (_a = session === null || session === void 0 ? void 0 : session.requested) === null || _a === void 0 ? void 0 : _a.state,
|
404
413
|
}),
|
405
414
|
};
|
406
415
|
}
|
@@ -425,6 +434,7 @@ class OAuthController {
|
|
425
434
|
error: 'server_error',
|
426
435
|
error_description: (0, utils_1.getErrorMessage)(err),
|
427
436
|
redirect_uri,
|
437
|
+
state: (_b = session === null || session === void 0 ? void 0 : session.requested) === null || _b === void 0 ? void 0 : _b.state,
|
428
438
|
}),
|
429
439
|
};
|
430
440
|
}
|
@@ -5,5 +5,5 @@ export declare enum IndexNames {
|
|
5
5
|
}
|
6
6
|
export declare const relayStatePrefix = "boxyhq_jackson_";
|
7
7
|
export declare const validateAbsoluteUrl: (url: any, message: any) => void;
|
8
|
-
export declare const OAuthErrorResponse: ({ error, error_description, redirect_uri }: OAuthErrorHandlerParams) => string;
|
8
|
+
export declare const OAuthErrorResponse: ({ error, error_description, redirect_uri, state, }: OAuthErrorHandlerParams) => string;
|
9
9
|
export declare function getErrorMessage(error: unknown): string;
|
package/dist/controller/utils.js
CHANGED
@@ -41,14 +41,15 @@ const validateAbsoluteUrl = (url, message) => {
|
|
41
41
|
}
|
42
42
|
};
|
43
43
|
exports.validateAbsoluteUrl = validateAbsoluteUrl;
|
44
|
-
const OAuthErrorResponse = ({ error, error_description, redirect_uri }) => {
|
45
|
-
return redirect.success(redirect_uri, { error, error_description });
|
44
|
+
const OAuthErrorResponse = ({ error, error_description, redirect_uri, state, }) => {
|
45
|
+
return redirect.success(redirect_uri, { error, error_description, state });
|
46
46
|
};
|
47
47
|
exports.OAuthErrorResponse = OAuthErrorResponse;
|
48
48
|
// https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript
|
49
49
|
function getErrorMessage(error) {
|
50
|
-
if (error instanceof Error)
|
50
|
+
if (error instanceof Error) {
|
51
51
|
return error.message;
|
52
|
+
}
|
52
53
|
return String(error);
|
53
54
|
}
|
54
55
|
exports.getErrorMessage = getErrorMessage;
|
package/dist/db/db.js
CHANGED
@@ -41,6 +41,12 @@ const mongo_1 = __importDefault(require("./mongo"));
|
|
41
41
|
const redis_1 = __importDefault(require("./redis"));
|
42
42
|
const sql_1 = __importDefault(require("./sql/sql"));
|
43
43
|
const store_1 = __importDefault(require("./store"));
|
44
|
+
const JacksonStore_1 = require("./sql/entity/JacksonStore");
|
45
|
+
const JacksonIndex_1 = require("./sql/entity/JacksonIndex");
|
46
|
+
const JacksonTTL_1 = require("./sql/entity/JacksonTTL");
|
47
|
+
const JacksonStore_2 = require("./planetscale/entity/JacksonStore");
|
48
|
+
const JacksonIndex_2 = require("./planetscale/entity/JacksonIndex");
|
49
|
+
const JacksonTTL_2 = require("./planetscale/entity/JacksonTTL");
|
44
50
|
const decrypt = (res, encryptionKey) => {
|
45
51
|
if (res.iv && res.tag) {
|
46
52
|
return JSON.parse(encrypter.decrypt(res.value, res.iv, res.tag, encryptionKey));
|
@@ -107,7 +113,17 @@ exports.default = {
|
|
107
113
|
case 'redis':
|
108
114
|
return new DB(yield redis_1.default.new(options), encryptionKey);
|
109
115
|
case 'sql':
|
110
|
-
return new DB(yield sql_1.default.new(options
|
116
|
+
return new DB(yield sql_1.default.new(options, {
|
117
|
+
JacksonStore: JacksonStore_1.JacksonStore,
|
118
|
+
JacksonIndex: JacksonIndex_1.JacksonIndex,
|
119
|
+
JacksonTTL: JacksonTTL_1.JacksonTTL,
|
120
|
+
}), encryptionKey);
|
121
|
+
case 'planetscale':
|
122
|
+
return new DB(yield sql_1.default.new(options, {
|
123
|
+
JacksonStore: JacksonStore_2.JacksonStore,
|
124
|
+
JacksonIndex: JacksonIndex_2.JacksonIndex,
|
125
|
+
JacksonTTL: JacksonTTL_2.JacksonTTL,
|
126
|
+
}), encryptionKey);
|
111
127
|
case 'mongo':
|
112
128
|
return new DB(yield mongo_1.default.new(options), encryptionKey);
|
113
129
|
case 'mem':
|
package/dist/db/mongo.js
CHANGED
@@ -67,8 +67,9 @@ class Mongo {
|
|
67
67
|
const docs = yield this.collection
|
68
68
|
.find({ _id: _namespaceMatch }, { sort: { createdAt: -1 }, skip: offset, limit: limit })
|
69
69
|
.toArray();
|
70
|
-
if (docs)
|
70
|
+
if (docs) {
|
71
71
|
return docs.map(({ value }) => value);
|
72
|
+
}
|
72
73
|
return [];
|
73
74
|
});
|
74
75
|
}
|
@@ -0,0 +1,34 @@
|
|
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 typeorm_1 = require("typeorm");
|
11
|
+
let JacksonIndex = class JacksonIndex {
|
12
|
+
};
|
13
|
+
__decorate([
|
14
|
+
(0, typeorm_1.PrimaryGeneratedColumn)()
|
15
|
+
], JacksonIndex.prototype, "id", void 0);
|
16
|
+
__decorate([
|
17
|
+
(0, typeorm_1.Index)('_jackson_index_key'),
|
18
|
+
(0, typeorm_1.Column)({
|
19
|
+
type: 'varchar',
|
20
|
+
length: 250,
|
21
|
+
})
|
22
|
+
], JacksonIndex.prototype, "key", void 0);
|
23
|
+
__decorate([
|
24
|
+
(0, typeorm_1.Index)('_jackson_index_store'),
|
25
|
+
(0, typeorm_1.Column)({
|
26
|
+
type: 'varchar',
|
27
|
+
length: 250,
|
28
|
+
})
|
29
|
+
], JacksonIndex.prototype, "storeKey", void 0);
|
30
|
+
JacksonIndex = __decorate([
|
31
|
+
(0, typeorm_1.Index)('_jackson_index_key_store', ['key', 'storeKey']),
|
32
|
+
(0, typeorm_1.Entity)()
|
33
|
+
], JacksonIndex);
|
34
|
+
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: 250,
|
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: 'timestamp',
|
42
|
+
default: () => 'CURRENT_TIMESTAMP',
|
43
|
+
nullable: false,
|
44
|
+
})
|
45
|
+
], JacksonStore.prototype, "createdAt", void 0);
|
46
|
+
__decorate([
|
47
|
+
(0, typeorm_1.Column)({
|
48
|
+
type: 'timestamp',
|
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: 250,
|
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;
|
package/dist/db/sql/sql.d.ts
CHANGED
@@ -7,8 +7,15 @@ declare class Sql implements DatabaseDriver {
|
|
7
7
|
private ttlRepository;
|
8
8
|
private ttlCleanup;
|
9
9
|
private timerId;
|
10
|
+
private JacksonStore;
|
11
|
+
private JacksonIndex;
|
12
|
+
private JacksonTTL;
|
10
13
|
constructor(options: DatabaseOption);
|
11
|
-
init(
|
14
|
+
init({ JacksonStore, JacksonIndex, JacksonTTL }: {
|
15
|
+
JacksonStore: any;
|
16
|
+
JacksonIndex: any;
|
17
|
+
JacksonTTL: any;
|
18
|
+
}): Promise<Sql>;
|
12
19
|
get(namespace: string, key: string): Promise<any>;
|
13
20
|
getAll(namespace: string, pageOffset: number, pageLimit: number): Promise<unknown[]>;
|
14
21
|
getByIndex(namespace: string, idx: Index): Promise<any>;
|
@@ -16,6 +23,6 @@ declare class Sql implements DatabaseDriver {
|
|
16
23
|
delete(namespace: string, key: string): Promise<any>;
|
17
24
|
}
|
18
25
|
declare const _default: {
|
19
|
-
new: (options: DatabaseOption) => Promise<Sql>;
|
26
|
+
new: (options: DatabaseOption, entities: any) => Promise<Sql>;
|
20
27
|
};
|
21
28
|
export default _default;
|
package/dist/db/sql/sql.js
CHANGED
@@ -36,25 +36,23 @@ 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 JacksonStore_1 = require("./entity/JacksonStore");
|
40
|
-
const JacksonIndex_1 = require("./entity/JacksonIndex");
|
41
|
-
const JacksonTTL_1 = require("./entity/JacksonTTL");
|
42
39
|
class Sql {
|
43
40
|
constructor(options) {
|
44
41
|
this.options = options;
|
45
42
|
}
|
46
|
-
init() {
|
43
|
+
init({ JacksonStore, JacksonIndex, JacksonTTL }) {
|
47
44
|
return __awaiter(this, void 0, void 0, function* () {
|
48
45
|
while (true) {
|
49
46
|
try {
|
50
47
|
this.dataSource = new typeorm_1.DataSource({
|
51
48
|
// name: this.options.type! + Math.floor(Math.random() * 100000),
|
52
|
-
type: this.options.type,
|
49
|
+
type: this.options.engine === 'planetscale' ? 'mysql' : this.options.type,
|
53
50
|
url: this.options.url,
|
54
|
-
synchronize:
|
51
|
+
synchronize: this.options.engine !== 'planetscale',
|
55
52
|
migrationsTableName: '_jackson_migrations',
|
56
53
|
logging: ['error'],
|
57
|
-
entities: [
|
54
|
+
entities: [JacksonStore, JacksonIndex, JacksonTTL],
|
55
|
+
ssl: this.options.ssl,
|
58
56
|
});
|
59
57
|
yield this.dataSource.initialize();
|
60
58
|
break;
|
@@ -65,9 +63,12 @@ class Sql {
|
|
65
63
|
continue;
|
66
64
|
}
|
67
65
|
}
|
68
|
-
this.
|
69
|
-
this.
|
70
|
-
this.
|
66
|
+
this.JacksonStore = JacksonStore;
|
67
|
+
this.JacksonIndex = JacksonIndex;
|
68
|
+
this.JacksonTTL = JacksonTTL;
|
69
|
+
this.storeRepository = this.dataSource.getRepository(JacksonStore);
|
70
|
+
this.indexRepository = this.dataSource.getRepository(JacksonIndex);
|
71
|
+
this.ttlRepository = this.dataSource.getRepository(JacksonTTL);
|
71
72
|
if (this.options.ttl && this.options.cleanupLimit) {
|
72
73
|
this.ttlCleanup = () => __awaiter(this, void 0, void 0, function* () {
|
73
74
|
const now = Date.now();
|
@@ -121,15 +122,11 @@ class Sql {
|
|
121
122
|
select: ['value', 'iv', 'tag'],
|
122
123
|
order: {
|
123
124
|
['createdAt']: 'DESC',
|
124
|
-
// ['createdAt']: 'ASC',
|
125
125
|
},
|
126
126
|
take: offsetAndLimitValueCheck ? this.options.pageLimit : pageLimit,
|
127
127
|
skip: offsetAndLimitValueCheck ? 0 : pageOffset,
|
128
128
|
});
|
129
|
-
|
130
|
-
if (returnValue)
|
131
|
-
return returnValue;
|
132
|
-
return [];
|
129
|
+
return JSON.parse(JSON.stringify(response)) || [];
|
133
130
|
});
|
134
131
|
}
|
135
132
|
getByIndex(namespace, idx) {
|
@@ -139,13 +136,19 @@ class Sql {
|
|
139
136
|
});
|
140
137
|
const ret = [];
|
141
138
|
if (res) {
|
142
|
-
|
139
|
+
for (const r of res) {
|
140
|
+
let value = r.store;
|
141
|
+
if (this.options.engine === 'planetscale') {
|
142
|
+
value = yield this.storeRepository.findOneBy({
|
143
|
+
key: r.storeKey,
|
144
|
+
});
|
145
|
+
}
|
143
146
|
ret.push({
|
144
|
-
value:
|
145
|
-
iv:
|
146
|
-
tag:
|
147
|
+
value: value.value,
|
148
|
+
iv: value.iv,
|
149
|
+
tag: value.tag,
|
147
150
|
});
|
148
|
-
}
|
151
|
+
}
|
149
152
|
}
|
150
153
|
return ret;
|
151
154
|
});
|
@@ -154,7 +157,7 @@ class Sql {
|
|
154
157
|
return __awaiter(this, void 0, void 0, function* () {
|
155
158
|
yield this.dataSource.transaction((transactionalEntityManager) => __awaiter(this, void 0, void 0, function* () {
|
156
159
|
const dbKey = dbutils.key(namespace, key);
|
157
|
-
const store = new
|
160
|
+
const store = new this.JacksonStore();
|
158
161
|
store.key = dbKey;
|
159
162
|
store.value = val.value;
|
160
163
|
store.iv = val.iv;
|
@@ -162,7 +165,7 @@ class Sql {
|
|
162
165
|
store.modifiedAt = new Date().toISOString();
|
163
166
|
yield transactionalEntityManager.save(store);
|
164
167
|
if (ttl) {
|
165
|
-
const ttlRec = new
|
168
|
+
const ttlRec = new this.JacksonTTL();
|
166
169
|
ttlRec.key = dbKey;
|
167
170
|
ttlRec.expiresAt = Date.now() + ttl * 1000;
|
168
171
|
yield transactionalEntityManager.save(ttlRec);
|
@@ -175,9 +178,14 @@ class Sql {
|
|
175
178
|
storeKey: store.key,
|
176
179
|
});
|
177
180
|
if (!rec) {
|
178
|
-
const ji = new
|
181
|
+
const ji = new this.JacksonIndex();
|
179
182
|
ji.key = key;
|
180
|
-
|
183
|
+
if (this.options.engine === 'planetscale') {
|
184
|
+
ji.storeKey = store.key;
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
ji.store = store;
|
188
|
+
}
|
181
189
|
yield transactionalEntityManager.save(ji);
|
182
190
|
}
|
183
191
|
}
|
@@ -188,6 +196,18 @@ class Sql {
|
|
188
196
|
return __awaiter(this, void 0, void 0, function* () {
|
189
197
|
const dbKey = dbutils.key(namespace, key);
|
190
198
|
yield this.ttlRepository.remove({ key: dbKey });
|
199
|
+
if (this.options.engine === 'planetscale') {
|
200
|
+
const response = yield this.indexRepository.find({
|
201
|
+
where: { storeKey: dbKey },
|
202
|
+
select: ['id'],
|
203
|
+
});
|
204
|
+
const returnValue = response || [];
|
205
|
+
for (const r of returnValue) {
|
206
|
+
yield this.indexRepository.remove({
|
207
|
+
id: r.id,
|
208
|
+
});
|
209
|
+
}
|
210
|
+
}
|
191
211
|
return yield this.storeRepository.remove({
|
192
212
|
key: dbKey,
|
193
213
|
});
|
@@ -195,7 +215,7 @@ class Sql {
|
|
195
215
|
}
|
196
216
|
}
|
197
217
|
exports.default = {
|
198
|
-
new: (options) => __awaiter(void 0, void 0, void 0, function* () {
|
199
|
-
return yield new Sql(options).init();
|
218
|
+
new: (options, entities) => __awaiter(void 0, void 0, void 0, function* () {
|
219
|
+
return yield new Sql(options).init(entities);
|
200
220
|
}),
|
201
221
|
};
|
package/dist/typings.d.ts
CHANGED
@@ -106,7 +106,7 @@ export interface Encrypted {
|
|
106
106
|
value: string;
|
107
107
|
}
|
108
108
|
export declare type EncryptionKey = any;
|
109
|
-
export declare type DatabaseEngine = 'redis' | 'sql' | 'mongo' | 'mem';
|
109
|
+
export declare type DatabaseEngine = 'redis' | 'sql' | 'mongo' | 'mem' | 'planetscale';
|
110
110
|
export declare type DatabaseType = 'postgres' | 'mysql' | 'mariadb';
|
111
111
|
export interface DatabaseOption {
|
112
112
|
engine?: DatabaseEngine;
|
@@ -116,6 +116,7 @@ export interface DatabaseOption {
|
|
116
116
|
cleanupLimit?: number;
|
117
117
|
encryptionKey?: string;
|
118
118
|
pageLimit?: number;
|
119
|
+
ssl?: any;
|
119
120
|
}
|
120
121
|
export interface JacksonOption {
|
121
122
|
externalUrl: string;
|
@@ -144,7 +145,7 @@ interface Metadata {
|
|
144
145
|
};
|
145
146
|
entityID: string;
|
146
147
|
thumbprint: string;
|
147
|
-
loginType: 'idp';
|
148
|
+
loginType: 'idp' | 'sp';
|
148
149
|
provider: string;
|
149
150
|
}
|
150
151
|
export interface SAMLConfig {
|
@@ -166,5 +167,6 @@ export interface OAuthErrorHandlerParams {
|
|
166
167
|
error: 'invalid_request' | 'access_denied' | 'unauthorized_client' | 'unsupported_response_type' | 'invalid_scope' | 'server_error' | 'temporarily_unavailable';
|
167
168
|
error_description: string;
|
168
169
|
redirect_uri: string;
|
170
|
+
state?: string;
|
169
171
|
}
|
170
172
|
export {};
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
2
|
+
|
3
|
+
export class msNocascade1653746497237 implements MigrationInterface {
|
4
|
+
name = 'msNocascade1653746497237'
|
5
|
+
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
7
|
+
await queryRunner.query(`CREATE TABLE \`jackson_store\` (\`key\` varchar(250) NOT NULL, \`value\` text NOT NULL, \`iv\` varchar(64) NULL, \`tag\` varchar(64) NULL, \`createdAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, \`modifiedAt\` timestamp NULL, PRIMARY KEY (\`key\`)) ENGINE=InnoDB`);
|
8
|
+
await queryRunner.query(`CREATE TABLE \`jackson_ttl\` (\`key\` varchar(250) NOT NULL, \`expiresAt\` bigint NOT NULL, INDEX \`_jackson_ttl_expires_at\` (\`expiresAt\`), PRIMARY KEY (\`key\`)) ENGINE=InnoDB`);
|
9
|
+
await queryRunner.query(`CREATE TABLE \`jackson_index\` (\`id\` int NOT NULL AUTO_INCREMENT, \`key\` varchar(250) NOT NULL, \`storeKey\` varchar(250) NOT NULL, INDEX \`_jackson_index_key\` (\`key\`), INDEX \`_jackson_index_store\` (\`storeKey\`), INDEX \`_jackson_index_key_store\` (\`key\`, \`storeKey\`), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
10
|
+
}
|
11
|
+
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
13
|
+
await queryRunner.query(`DROP INDEX \`_jackson_index_key_store\` ON \`jackson_index\``);
|
14
|
+
await queryRunner.query(`DROP INDEX \`_jackson_index_store\` ON \`jackson_index\``);
|
15
|
+
await queryRunner.query(`DROP INDEX \`_jackson_index_key\` ON \`jackson_index\``);
|
16
|
+
await queryRunner.query(`DROP TABLE \`jackson_index\``);
|
17
|
+
await queryRunner.query(`DROP INDEX \`_jackson_ttl_expires_at\` ON \`jackson_ttl\``);
|
18
|
+
await queryRunner.query(`DROP TABLE \`jackson_ttl\``);
|
19
|
+
await queryRunner.query(`DROP TABLE \`jackson_store\``);
|
20
|
+
}
|
21
|
+
|
22
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@boxyhq/saml-jackson",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.7",
|
4
4
|
"description": "SAML Jackson library",
|
5
5
|
"keywords": [
|
6
6
|
"SAML 2.0"
|
@@ -20,9 +20,11 @@
|
|
20
20
|
"build": "tsc -p tsconfig.build.json",
|
21
21
|
"db:migration:generate:postgres": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:generate -d typeorm.ts migration/postgres/pg_${MIGRATION_NAME}",
|
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
|
+
"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}",
|
23
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}",
|
24
25
|
"db:migration:run:postgres": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
|
25
26
|
"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
|
+
"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",
|
26
28
|
"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",
|
27
29
|
"prepublishOnly": "npm run build",
|
28
30
|
"test": "tap --ts --timeout=100 --coverage test/**/*.test.ts",
|
@@ -36,35 +38,36 @@
|
|
36
38
|
"statements": 70
|
37
39
|
},
|
38
40
|
"dependencies": {
|
39
|
-
"@boxyhq/saml20": "1.0.
|
41
|
+
"@boxyhq/saml20": "1.0.3",
|
40
42
|
"@opentelemetry/api-metrics": "0.27.0",
|
43
|
+
"@opentelemetry/api": "1.0.4",
|
41
44
|
"@peculiar/webcrypto": "1.4.0",
|
42
|
-
"@peculiar/x509": "1.
|
43
|
-
"mongodb": "4.
|
45
|
+
"@peculiar/x509": "1.7.2",
|
46
|
+
"mongodb": "4.7.0",
|
44
47
|
"mysql2": "2.3.3",
|
45
48
|
"pg": "8.7.3",
|
46
49
|
"redis": "4.0.6",
|
47
50
|
"reflect-metadata": "0.1.13",
|
48
51
|
"ripemd160": "2.0.2",
|
49
|
-
"typeorm": "0.3.
|
52
|
+
"typeorm": "0.3.7",
|
50
53
|
"xml2js": "0.4.23",
|
51
54
|
"xmlbuilder": "15.1.1"
|
52
55
|
},
|
53
56
|
"devDependencies": {
|
54
|
-
"@types/node": "
|
55
|
-
"@types/sinon": "10.0.
|
57
|
+
"@types/node": "18.0.3",
|
58
|
+
"@types/sinon": "10.0.12",
|
56
59
|
"@types/tap": "15.0.7",
|
57
|
-
"@typescript-eslint/eslint-plugin": "5.
|
58
|
-
"@typescript-eslint/parser": "5.
|
60
|
+
"@typescript-eslint/eslint-plugin": "5.30.5",
|
61
|
+
"@typescript-eslint/parser": "5.30.5",
|
59
62
|
"cross-env": "7.0.3",
|
60
|
-
"eslint": "8.
|
63
|
+
"eslint": "8.19.0",
|
61
64
|
"eslint-config-prettier": "8.5.0",
|
62
|
-
"prettier": "2.
|
65
|
+
"prettier": "2.7.1",
|
63
66
|
"sinon": "14.0.0",
|
64
|
-
"tap": "16.
|
65
|
-
"ts-node": "10.
|
67
|
+
"tap": "16.3.0",
|
68
|
+
"ts-node": "10.8.2",
|
66
69
|
"tsconfig-paths": "4.0.0",
|
67
|
-
"typescript": "4.
|
70
|
+
"typescript": "4.7.4"
|
68
71
|
},
|
69
72
|
"engines": {
|
70
73
|
"node": ">=14.18.1 <=16.x"
|