@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"
         |