@boxyhq/saml-jackson 0.4.3 → 1.0.0
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/README.md +1 -1
- package/dist/controller/admin.d.ts +2 -2
- package/dist/controller/admin.js +2 -2
- package/dist/controller/api.d.ts +48 -35
- package/dist/controller/api.js +92 -47
- package/dist/controller/health-check.d.ts +11 -0
- package/dist/controller/health-check.js +53 -0
- package/dist/controller/oauth.js +12 -3
- package/dist/controller/signout.d.ts +18 -0
- package/dist/controller/signout.js +231 -0
- package/dist/controller/utils.d.ts +2 -1
- package/dist/controller/utils.js +13 -3
- package/dist/db/db.d.ts +1 -1
- package/dist/db/db.js +7 -3
- package/dist/db/defaultDb.d.ts +2 -0
- package/dist/db/defaultDb.js +12 -0
- package/dist/db/mem.d.ts +1 -1
- package/dist/db/mem.js +43 -11
- package/dist/db/mongo.d.ts +1 -1
- package/dist/db/mongo.js +12 -13
- package/dist/db/redis.d.ts +1 -1
- package/dist/db/redis.js +63 -16
- package/dist/db/sql/sql.d.ts +2 -2
- package/dist/db/sql/sql.js +19 -11
- package/dist/db/store.js +7 -3
- package/dist/db/utils.d.ts +3 -0
- package/dist/db/utils.js +7 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +21 -8
- package/dist/read-config.js +5 -1
- package/dist/saml/saml.d.ts +3 -0
- package/dist/saml/saml.js +38 -5
- package/dist/saml/x509.js +5 -1
- package/dist/typings.d.ts +49 -11
- package/package.json +24 -24
    
        package/dist/db/sql/sql.js
    CHANGED
    
    | @@ -2,7 +2,11 @@ | |
| 2 2 | 
             
            /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
         | 
| 3 3 | 
             
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         | 
| 4 4 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 5 | 
            -
                Object. | 
| 5 | 
            +
                var desc = Object.getOwnPropertyDescriptor(m, k);
         | 
| 6 | 
            +
                if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
         | 
| 7 | 
            +
                  desc = { enumerable: true, get: function() { return m[k]; } };
         | 
| 8 | 
            +
                }
         | 
| 9 | 
            +
                Object.defineProperty(o, k2, desc);
         | 
| 6 10 | 
             
            }) : (function(o, m, k, k2) {
         | 
| 7 11 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 8 12 | 
             
                o[k2] = m[k];
         | 
| @@ -43,8 +47,8 @@ class Sql { | |
| 43 47 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 44 48 | 
             
                        while (true) {
         | 
| 45 49 | 
             
                            try {
         | 
| 46 | 
            -
                                this. | 
| 47 | 
            -
                                    name: this.options.type + Math.floor(Math.random() * 100000),
         | 
| 50 | 
            +
                                this.dataSource = new typeorm_1.DataSource({
         | 
| 51 | 
            +
                                    // name: this.options.type! + Math.floor(Math.random() * 100000),
         | 
| 48 52 | 
             
                                    type: this.options.type,
         | 
| 49 53 | 
             
                                    url: this.options.url,
         | 
| 50 54 | 
             
                                    synchronize: true,
         | 
| @@ -52,6 +56,7 @@ class Sql { | |
| 52 56 | 
             
                                    logging: ['error'],
         | 
| 53 57 | 
             
                                    entities: [JacksonStore_1.JacksonStore, JacksonIndex_1.JacksonIndex, JacksonTTL_1.JacksonTTL],
         | 
| 54 58 | 
             
                                });
         | 
| 59 | 
            +
                                yield this.dataSource.initialize();
         | 
| 55 60 | 
             
                                break;
         | 
| 56 61 | 
             
                            }
         | 
| 57 62 | 
             
                            catch (err) {
         | 
| @@ -60,9 +65,9 @@ class Sql { | |
| 60 65 | 
             
                                continue;
         | 
| 61 66 | 
             
                            }
         | 
| 62 67 | 
             
                        }
         | 
| 63 | 
            -
                        this.storeRepository = this. | 
| 64 | 
            -
                        this.indexRepository = this. | 
| 65 | 
            -
                        this.ttlRepository = this. | 
| 68 | 
            +
                        this.storeRepository = this.dataSource.getRepository(JacksonStore_1.JacksonStore);
         | 
| 69 | 
            +
                        this.indexRepository = this.dataSource.getRepository(JacksonIndex_1.JacksonIndex);
         | 
| 70 | 
            +
                        this.ttlRepository = this.dataSource.getRepository(JacksonTTL_1.JacksonTTL);
         | 
| 66 71 | 
             
                        if (this.options.ttl && this.options.cleanupLimit) {
         | 
| 67 72 | 
             
                            this.ttlCleanup = () => __awaiter(this, void 0, void 0, function* () {
         | 
| 68 73 | 
             
                                const now = Date.now();
         | 
| @@ -95,7 +100,7 @@ class Sql { | |
| 95 100 | 
             
                }
         | 
| 96 101 | 
             
                get(namespace, key) {
         | 
| 97 102 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 98 | 
            -
                        const res = yield this.storeRepository. | 
| 103 | 
            +
                        const res = yield this.storeRepository.findOneBy({
         | 
| 99 104 | 
             
                            key: dbutils.key(namespace, key),
         | 
| 100 105 | 
             
                        });
         | 
| 101 106 | 
             
                        if (res && res.value) {
         | 
| @@ -108,8 +113,9 @@ class Sql { | |
| 108 113 | 
             
                        return null;
         | 
| 109 114 | 
             
                    });
         | 
| 110 115 | 
             
                }
         | 
| 111 | 
            -
                getAll(namespace) {
         | 
| 116 | 
            +
                getAll(namespace, pageOffset, pageLimit) {
         | 
| 112 117 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 118 | 
            +
                        const offsetAndLimitValueCheck = !dbutils.isNumeric(pageOffset) && !dbutils.isNumeric(pageLimit);
         | 
| 113 119 | 
             
                        const response = yield this.storeRepository.find({
         | 
| 114 120 | 
             
                            where: { key: (0, typeorm_1.Like)(`%${namespace}%`) },
         | 
| 115 121 | 
             
                            select: ['value', 'iv', 'tag'],
         | 
| @@ -117,6 +123,8 @@ class Sql { | |
| 117 123 | 
             
                                ['createdAt']: 'DESC',
         | 
| 118 124 | 
             
                                // ['createdAt']: 'ASC',
         | 
| 119 125 | 
             
                            },
         | 
| 126 | 
            +
                            take: offsetAndLimitValueCheck ? this.options.pageLimit : pageLimit,
         | 
| 127 | 
            +
                            skip: offsetAndLimitValueCheck ? 0 : pageOffset,
         | 
| 120 128 | 
             
                        });
         | 
| 121 129 | 
             
                        const returnValue = JSON.parse(JSON.stringify(response));
         | 
| 122 130 | 
             
                        if (returnValue)
         | 
| @@ -126,7 +134,7 @@ class Sql { | |
| 126 134 | 
             
                }
         | 
| 127 135 | 
             
                getByIndex(namespace, idx) {
         | 
| 128 136 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 129 | 
            -
                        const res = yield this.indexRepository. | 
| 137 | 
            +
                        const res = yield this.indexRepository.findBy({
         | 
| 130 138 | 
             
                            key: dbutils.keyForIndex(namespace, idx),
         | 
| 131 139 | 
             
                        });
         | 
| 132 140 | 
             
                        const ret = [];
         | 
| @@ -144,7 +152,7 @@ class Sql { | |
| 144 152 | 
             
                }
         | 
| 145 153 | 
             
                put(namespace, key, val, ttl = 0, ...indexes) {
         | 
| 146 154 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 147 | 
            -
                        yield this. | 
| 155 | 
            +
                        yield this.dataSource.transaction((transactionalEntityManager) => __awaiter(this, void 0, void 0, function* () {
         | 
| 148 156 | 
             
                            const dbKey = dbutils.key(namespace, key);
         | 
| 149 157 | 
             
                            const store = new JacksonStore_1.JacksonStore();
         | 
| 150 158 | 
             
                            store.key = dbKey;
         | 
| @@ -162,7 +170,7 @@ class Sql { | |
| 162 170 | 
             
                            // no ttl support for secondary indexes
         | 
| 163 171 | 
             
                            for (const idx of indexes || []) {
         | 
| 164 172 | 
             
                                const key = dbutils.keyForIndex(namespace, idx);
         | 
| 165 | 
            -
                                const rec = yield this.indexRepository. | 
| 173 | 
            +
                                const rec = yield this.indexRepository.findOneBy({
         | 
| 166 174 | 
             
                                    key,
         | 
| 167 175 | 
             
                                    storeKey: store.key,
         | 
| 168 176 | 
             
                                });
         | 
    
        package/dist/db/store.js
    CHANGED
    
    | @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            "use strict";
         | 
| 2 2 | 
             
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         | 
| 3 3 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 4 | 
            -
                Object. | 
| 4 | 
            +
                var desc = Object.getOwnPropertyDescriptor(m, k);
         | 
| 5 | 
            +
                if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
         | 
| 6 | 
            +
                  desc = { enumerable: true, get: function() { return m[k]; } };
         | 
| 7 | 
            +
                }
         | 
| 8 | 
            +
                Object.defineProperty(o, k2, desc);
         | 
| 5 9 | 
             
            }) : (function(o, m, k, k2) {
         | 
| 6 10 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 7 11 | 
             
                o[k2] = m[k];
         | 
| @@ -40,9 +44,9 @@ class Store { | |
| 40 44 | 
             
                        return yield this.db.get(this.namespace, dbutils.keyDigest(key));
         | 
| 41 45 | 
             
                    });
         | 
| 42 46 | 
             
                }
         | 
| 43 | 
            -
                getAll() {
         | 
| 47 | 
            +
                getAll(pageOffset, pageLimit) {
         | 
| 44 48 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 45 | 
            -
                        return yield this.db.getAll(this.namespace);
         | 
| 49 | 
            +
                        return yield this.db.getAll(this.namespace, pageOffset, pageLimit);
         | 
| 46 50 | 
             
                    });
         | 
| 47 51 | 
             
                }
         | 
| 48 52 | 
             
                getByIndex(idx) {
         | 
    
        package/dist/db/utils.d.ts
    CHANGED
    
    | @@ -4,4 +4,7 @@ export declare const keyForIndex: (namespace: string, idx: Index) => string; | |
| 4 4 | 
             
            export declare const keyDigest: (k: string) => string;
         | 
| 5 5 | 
             
            export declare const keyFromParts: (...parts: string[]) => string;
         | 
| 6 6 | 
             
            export declare const sleep: (ms: number) => Promise<void>;
         | 
| 7 | 
            +
            export declare function isNumeric(num: any): boolean;
         | 
| 7 8 | 
             
            export declare const indexPrefix = "_index";
         | 
| 9 | 
            +
            export declare const createdAtPrefix = "_createdAt";
         | 
| 10 | 
            +
            export declare const modifiedAtPrefix = "_modifiedAt";
         | 
    
        package/dist/db/utils.js
    CHANGED
    
    | @@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | |
| 3 3 | 
             
                return (mod && mod.__esModule) ? mod : { "default": mod };
         | 
| 4 4 | 
             
            };
         | 
| 5 5 | 
             
            Object.defineProperty(exports, "__esModule", { value: true });
         | 
| 6 | 
            -
            exports.indexPrefix = exports.sleep = exports.keyFromParts = exports.keyDigest = exports.keyForIndex = exports.key = void 0;
         | 
| 6 | 
            +
            exports.modifiedAtPrefix = exports.createdAtPrefix = exports.indexPrefix = exports.isNumeric = exports.sleep = exports.keyFromParts = exports.keyDigest = exports.keyForIndex = exports.key = void 0;
         | 
| 7 7 | 
             
            const ripemd160_1 = __importDefault(require("ripemd160"));
         | 
| 8 8 | 
             
            const key = (namespace, k) => {
         | 
| 9 9 | 
             
                return namespace + ':' + k;
         | 
| @@ -26,4 +26,10 @@ const sleep = (ms) => { | |
| 26 26 | 
             
                return new Promise((resolve) => setTimeout(resolve, ms));
         | 
| 27 27 | 
             
            };
         | 
| 28 28 | 
             
            exports.sleep = sleep;
         | 
| 29 | 
            +
            function isNumeric(num) {
         | 
| 30 | 
            +
                return !isNaN(num);
         | 
| 31 | 
            +
            }
         | 
| 32 | 
            +
            exports.isNumeric = isNumeric;
         | 
| 29 33 | 
             
            exports.indexPrefix = '_index';
         | 
| 34 | 
            +
            exports.createdAtPrefix = '_createdAt';
         | 
| 35 | 
            +
            exports.modifiedAtPrefix = '_modifiedAt';
         | 
    
        package/dist/index.d.ts
    CHANGED
    
    | @@ -1,11 +1,15 @@ | |
| 1 | 
            +
            import { AdminController } from './controller/admin';
         | 
| 1 2 | 
             
            import { APIController } from './controller/api';
         | 
| 2 3 | 
             
            import { OAuthController } from './controller/oauth';
         | 
| 3 | 
            -
            import {  | 
| 4 | 
            +
            import { HealthCheckController } from './controller/health-check';
         | 
| 5 | 
            +
            import { LogoutController } from './controller/signout';
         | 
| 4 6 | 
             
            import { JacksonOption } from './typings';
         | 
| 5 7 | 
             
            export declare const controllers: (opts: JacksonOption) => Promise<{
         | 
| 6 8 | 
             
                apiController: APIController;
         | 
| 7 9 | 
             
                oauthController: OAuthController;
         | 
| 8 10 | 
             
                adminController: AdminController;
         | 
| 11 | 
            +
                logoutController: LogoutController;
         | 
| 12 | 
            +
                healthCheckController: HealthCheckController;
         | 
| 9 13 | 
             
            }>;
         | 
| 10 14 | 
             
            export default controllers;
         | 
| 11 15 | 
             
            export * from './typings';
         | 
    
        package/dist/index.js
    CHANGED
    
    | @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            "use strict";
         | 
| 2 2 | 
             
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         | 
| 3 3 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 4 | 
            -
                Object. | 
| 4 | 
            +
                var desc = Object.getOwnPropertyDescriptor(m, k);
         | 
| 5 | 
            +
                if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
         | 
| 6 | 
            +
                  desc = { enumerable: true, get: function() { return m[k]; } };
         | 
| 7 | 
            +
                }
         | 
| 8 | 
            +
                Object.defineProperty(o, k2, desc);
         | 
| 5 9 | 
             
            }) : (function(o, m, k, k2) {
         | 
| 6 10 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 7 11 | 
             
                o[k2] = m[k];
         | 
| @@ -23,10 +27,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | |
| 23 27 | 
             
            };
         | 
| 24 28 | 
             
            Object.defineProperty(exports, "__esModule", { value: true });
         | 
| 25 29 | 
             
            exports.controllers = void 0;
         | 
| 30 | 
            +
            const admin_1 = require("./controller/admin");
         | 
| 26 31 | 
             
            const api_1 = require("./controller/api");
         | 
| 27 32 | 
             
            const oauth_1 = require("./controller/oauth");
         | 
| 28 | 
            -
            const  | 
| 33 | 
            +
            const health_check_1 = require("./controller/health-check");
         | 
| 34 | 
            +
            const signout_1 = require("./controller/signout");
         | 
| 29 35 | 
             
            const db_1 = __importDefault(require("./db/db"));
         | 
| 36 | 
            +
            const defaultDb_1 = __importDefault(require("./db/defaultDb"));
         | 
| 30 37 | 
             
            const read_config_1 = __importDefault(require("./read-config"));
         | 
| 31 38 | 
             
            const defaultOpts = (opts) => {
         | 
| 32 39 | 
             
                const newOpts = Object.assign({}, opts);
         | 
| @@ -39,13 +46,9 @@ const defaultOpts = (opts) => { | |
| 39 46 | 
             
                newOpts.samlAudience = newOpts.samlAudience || 'https://saml.boxyhq.com';
         | 
| 40 47 | 
             
                newOpts.preLoadedConfig = newOpts.preLoadedConfig || ''; // path to folder containing static SAML config that will be preloaded. This is useful for self-hosted deployments that only have to support a single tenant (or small number of known tenants).
         | 
| 41 48 | 
             
                newOpts.idpEnabled = newOpts.idpEnabled === true;
         | 
| 42 | 
            -
                 | 
| 43 | 
            -
                newOpts.db.engine = newOpts.db.engine || 'sql';
         | 
| 44 | 
            -
                newOpts.db.url = newOpts.db.url || 'postgresql://postgres:postgres@localhost:5432/postgres';
         | 
| 45 | 
            -
                newOpts.db.type = newOpts.db.type || 'postgres'; // Only needed if DB_ENGINE is sql.
         | 
| 46 | 
            -
                newOpts.db.ttl = (newOpts.db.ttl || 300) * 1; // TTL for the code, session and token stores (in seconds)
         | 
| 47 | 
            -
                newOpts.db.cleanupLimit = (newOpts.db.cleanupLimit || 1000) * 1; // Limit cleanup of TTL entries to this many items at a time
         | 
| 49 | 
            +
                (0, defaultDb_1.default)(newOpts);
         | 
| 48 50 | 
             
                newOpts.clientSecretVerifier = newOpts.clientSecretVerifier || 'dummy';
         | 
| 51 | 
            +
                newOpts.db.pageLimit = newOpts.db.pageLimit || 50;
         | 
| 49 52 | 
             
                return newOpts;
         | 
| 50 53 | 
             
            };
         | 
| 51 54 | 
             
            const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
         | 
| @@ -55,8 +58,11 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () { | |
| 55 58 | 
             
                const sessionStore = db.store('oauth:session', opts.db.ttl);
         | 
| 56 59 | 
             
                const codeStore = db.store('oauth:code', opts.db.ttl);
         | 
| 57 60 | 
             
                const tokenStore = db.store('oauth:token', opts.db.ttl);
         | 
| 61 | 
            +
                const healthCheckStore = db.store('_health');
         | 
| 58 62 | 
             
                const apiController = new api_1.APIController({ configStore });
         | 
| 59 63 | 
             
                const adminController = new admin_1.AdminController({ configStore });
         | 
| 64 | 
            +
                const healthCheckController = new health_check_1.HealthCheckController({ healthCheckStore });
         | 
| 65 | 
            +
                yield healthCheckController.init();
         | 
| 60 66 | 
             
                const oauthController = new oauth_1.OAuthController({
         | 
| 61 67 | 
             
                    configStore,
         | 
| 62 68 | 
             
                    sessionStore,
         | 
| @@ -64,6 +70,11 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () { | |
| 64 70 | 
             
                    tokenStore,
         | 
| 65 71 | 
             
                    opts,
         | 
| 66 72 | 
             
                });
         | 
| 73 | 
            +
                const logoutController = new signout_1.LogoutController({
         | 
| 74 | 
            +
                    configStore,
         | 
| 75 | 
            +
                    sessionStore,
         | 
| 76 | 
            +
                    opts,
         | 
| 77 | 
            +
                });
         | 
| 67 78 | 
             
                // write pre-loaded config if present
         | 
| 68 79 | 
             
                if (opts.preLoadedConfig && opts.preLoadedConfig.length > 0) {
         | 
| 69 80 | 
             
                    const configs = yield (0, read_config_1.default)(opts.preLoadedConfig);
         | 
| @@ -78,6 +89,8 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () { | |
| 78 89 | 
             
                    apiController,
         | 
| 79 90 | 
             
                    oauthController,
         | 
| 80 91 | 
             
                    adminController,
         | 
| 92 | 
            +
                    logoutController,
         | 
| 93 | 
            +
                    healthCheckController,
         | 
| 81 94 | 
             
                };
         | 
| 82 95 | 
             
            });
         | 
| 83 96 | 
             
            exports.controllers = controllers;
         | 
    
        package/dist/read-config.js
    CHANGED
    
    | @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            "use strict";
         | 
| 2 2 | 
             
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         | 
| 3 3 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 4 | 
            -
                Object. | 
| 4 | 
            +
                var desc = Object.getOwnPropertyDescriptor(m, k);
         | 
| 5 | 
            +
                if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
         | 
| 6 | 
            +
                  desc = { enumerable: true, get: function() { return m[k]; } };
         | 
| 7 | 
            +
                }
         | 
| 8 | 
            +
                Object.defineProperty(o, k2, desc);
         | 
| 5 9 | 
             
            }) : (function(o, m, k, k2) {
         | 
| 6 10 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 7 11 | 
             
                o[k2] = m[k];
         | 
    
        package/dist/saml/saml.d.ts
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            import { SAMLProfile, SAMLReq } from '../typings';
         | 
| 2 2 | 
             
            export declare const stripCertHeaderAndFooter: (cert: string) => string;
         | 
| 3 | 
            +
            declare function PubKeyInfo(this: any, pubKey: string): void;
         | 
| 3 4 | 
             
            declare const _default: {
         | 
| 4 5 | 
             
                request: ({ ssoUrl, entityID, callbackUrl, isPassive, forceAuthn, identifierFormat, providerName, signingKey, publicKey, }: SAMLReq) => {
         | 
| 5 6 | 
             
                    id: string;
         | 
| @@ -8,5 +9,7 @@ declare const _default: { | |
| 8 9 | 
             
                parseAsync: (rawAssertion: string) => Promise<SAMLProfile>;
         | 
| 9 10 | 
             
                validateAsync: (rawAssertion: string, options: any) => Promise<SAMLProfile>;
         | 
| 10 11 | 
             
                parseMetadataAsync: (idpMeta: string) => Promise<Record<string, any>>;
         | 
| 12 | 
            +
                PubKeyInfo: typeof PubKeyInfo;
         | 
| 13 | 
            +
                certToPEM: (cert: string) => string;
         | 
| 11 14 | 
             
            };
         | 
| 12 15 | 
             
            export default _default;
         | 
    
        package/dist/saml/saml.js
    CHANGED
    
    | @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            "use strict";
         | 
| 2 2 | 
             
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         | 
| 3 3 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 4 | 
            -
                Object. | 
| 4 | 
            +
                var desc = Object.getOwnPropertyDescriptor(m, k);
         | 
| 5 | 
            +
                if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
         | 
| 6 | 
            +
                  desc = { enumerable: true, get: function() { return m[k]; } };
         | 
| 7 | 
            +
                }
         | 
| 8 | 
            +
                Object.defineProperty(o, k2, desc);
         | 
| 5 9 | 
             
            }) : (function(o, m, k, k2) {
         | 
| 6 10 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 7 11 | 
             
                o[k2] = m[k];
         | 
| @@ -33,12 +37,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | |
| 33 37 | 
             
            Object.defineProperty(exports, "__esModule", { value: true });
         | 
| 34 38 | 
             
            exports.stripCertHeaderAndFooter = void 0;
         | 
| 35 39 | 
             
            const saml20_1 = __importDefault(require("@boxyhq/saml20"));
         | 
| 36 | 
            -
            const  | 
| 40 | 
            +
            const crypto_1 = __importDefault(require("crypto"));
         | 
| 41 | 
            +
            const rambda = __importStar(require("rambda"));
         | 
| 37 42 | 
             
            const thumbprint_1 = __importDefault(require("thumbprint"));
         | 
| 38 43 | 
             
            const xml_crypto_1 = __importDefault(require("xml-crypto"));
         | 
| 39 | 
            -
            const  | 
| 44 | 
            +
            const xml2js_1 = __importDefault(require("xml2js"));
         | 
| 40 45 | 
             
            const xmlbuilder_1 = __importDefault(require("xmlbuilder"));
         | 
| 41 | 
            -
            const crypto_1 = __importDefault(require("crypto"));
         | 
| 42 46 | 
             
            const claims_1 = __importDefault(require("./claims"));
         | 
| 43 47 | 
             
            const idPrefix = '_';
         | 
| 44 48 | 
             
            const authnXPath = '/*[local-name(.)="AuthnRequest" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]';
         | 
| @@ -158,6 +162,8 @@ const parseMetadataAsync = (idpMeta) => __awaiter(void 0, void 0, void 0, functi | |
| 158 162 | 
             
                        let ssoPostUrl = null;
         | 
| 159 163 | 
             
                        let ssoRedirectUrl = null;
         | 
| 160 164 | 
             
                        let loginType = 'idp';
         | 
| 165 | 
            +
                        let sloRedirectUrl = null;
         | 
| 166 | 
            +
                        let sloPostUrl = null;
         | 
| 161 167 | 
             
                        let ssoDes = rambda.pathOr(null, 'EntityDescriptor.IDPSSODescriptor', res);
         | 
| 162 168 | 
             
                        if (!ssoDes) {
         | 
| 163 169 | 
             
                            ssoDes = rambda.pathOr([], 'EntityDescriptor.SPSSODescriptor', res);
         | 
| @@ -183,9 +189,19 @@ const parseMetadataAsync = (idpMeta) => __awaiter(void 0, void 0, void 0, functi | |
| 183 189 | 
             
                                    ssoRedirectUrl = rambda.path('$.Location', ssoSvcRec);
         | 
| 184 190 | 
             
                                }
         | 
| 185 191 | 
             
                            }
         | 
| 192 | 
            +
                            const sloSvc = ssoDesRec['SingleLogoutService'] || [];
         | 
| 193 | 
            +
                            for (const sloSvcRec of sloSvc) {
         | 
| 194 | 
            +
                                if (rambda.pathOr('', '$.Binding', sloSvcRec).endsWith('HTTP-Redirect')) {
         | 
| 195 | 
            +
                                    sloRedirectUrl = rambda.path('$.Location', sloSvcRec);
         | 
| 196 | 
            +
                                }
         | 
| 197 | 
            +
                                else if (rambda.pathOr('', '$.Binding', sloSvcRec).endsWith('HTTP-POST')) {
         | 
| 198 | 
            +
                                    sloPostUrl = rambda.path('$.Location', sloSvcRec);
         | 
| 199 | 
            +
                                }
         | 
| 200 | 
            +
                            }
         | 
| 186 201 | 
             
                        }
         | 
| 187 202 | 
             
                        const ret = {
         | 
| 188 203 | 
             
                            sso: {},
         | 
| 204 | 
            +
                            slo: {},
         | 
| 189 205 | 
             
                        };
         | 
| 190 206 | 
             
                        if (entityID) {
         | 
| 191 207 | 
             
                            ret.entityID = entityID;
         | 
| @@ -199,9 +215,26 @@ const parseMetadataAsync = (idpMeta) => __awaiter(void 0, void 0, void 0, functi | |
| 199 215 | 
             
                        if (ssoRedirectUrl) {
         | 
| 200 216 | 
             
                            ret.sso.redirectUrl = ssoRedirectUrl;
         | 
| 201 217 | 
             
                        }
         | 
| 218 | 
            +
                        if (sloRedirectUrl) {
         | 
| 219 | 
            +
                            ret.slo.redirectUrl = sloRedirectUrl;
         | 
| 220 | 
            +
                        }
         | 
| 221 | 
            +
                        if (sloPostUrl) {
         | 
| 222 | 
            +
                            ret.slo.postUrl = sloPostUrl;
         | 
| 223 | 
            +
                        }
         | 
| 202 224 | 
             
                        ret.loginType = loginType;
         | 
| 203 225 | 
             
                        resolve(ret);
         | 
| 204 226 | 
             
                    });
         | 
| 205 227 | 
             
                });
         | 
| 206 228 | 
             
            });
         | 
| 207 | 
            -
             | 
| 229 | 
            +
            const certToPEM = (cert) => {
         | 
| 230 | 
            +
                if (cert.indexOf('BEGIN CERTIFICATE') === -1 && cert.indexOf('END CERTIFICATE') === -1) {
         | 
| 231 | 
            +
                    const matches = cert.match(/.{1,64}/g);
         | 
| 232 | 
            +
                    if (matches) {
         | 
| 233 | 
            +
                        cert = matches.join('\n');
         | 
| 234 | 
            +
                        cert = '-----BEGIN CERTIFICATE-----\n' + cert;
         | 
| 235 | 
            +
                        cert = cert + '\n-----END CERTIFICATE-----\n';
         | 
| 236 | 
            +
                    }
         | 
| 237 | 
            +
                }
         | 
| 238 | 
            +
                return cert;
         | 
| 239 | 
            +
            };
         | 
| 240 | 
            +
            exports.default = { request, parseAsync, validateAsync, parseMetadataAsync, PubKeyInfo, certToPEM };
         | 
    
        package/dist/saml/x509.js
    CHANGED
    
    | @@ -1,7 +1,11 @@ | |
| 1 1 | 
             
            "use strict";
         | 
| 2 2 | 
             
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         | 
| 3 3 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 4 | 
            -
                Object. | 
| 4 | 
            +
                var desc = Object.getOwnPropertyDescriptor(m, k);
         | 
| 5 | 
            +
                if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
         | 
| 6 | 
            +
                  desc = { enumerable: true, get: function() { return m[k]; } };
         | 
| 7 | 
            +
                }
         | 
| 8 | 
            +
                Object.defineProperty(o, k2, desc);
         | 
| 5 9 | 
             
            }) : (function(o, m, k, k2) {
         | 
| 6 10 | 
             
                if (k2 === undefined) k2 = k;
         | 
| 7 11 | 
             
                o[k2] = m[k];
         | 
    
        package/dist/typings.d.ts
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            export declare type IdPConfig = {
         | 
| 2 2 | 
             
                defaultRedirectUrl: string;
         | 
| 3 | 
            -
                redirectUrl: string;
         | 
| 3 | 
            +
                redirectUrl: string[] | string;
         | 
| 4 4 | 
             
                tenant: string;
         | 
| 5 5 | 
             
                product: string;
         | 
| 6 6 | 
             
                name: string;
         | 
| @@ -8,14 +8,9 @@ export declare type IdPConfig = { | |
| 8 8 | 
             
                rawMetadata?: string;
         | 
| 9 9 | 
             
                encodedRawMetadata?: string;
         | 
| 10 10 | 
             
            };
         | 
| 11 | 
            -
            export interface OAuth {
         | 
| 12 | 
            -
                client_id: string;
         | 
| 13 | 
            -
                client_secret: string;
         | 
| 14 | 
            -
                provider: string;
         | 
| 15 | 
            -
            }
         | 
| 16 11 | 
             
            export interface IAPIController {
         | 
| 17 | 
            -
                config(body: IdPConfig): Promise< | 
| 18 | 
            -
                updateConfig(body: any): Promise< | 
| 12 | 
            +
                config(body: IdPConfig): Promise<any>;
         | 
| 13 | 
            +
                updateConfig(body: any): Promise<any>;
         | 
| 19 14 | 
             
                getConfig(body: {
         | 
| 20 15 | 
             
                    clientID?: string;
         | 
| 21 16 | 
             
                    tenant?: string;
         | 
| @@ -40,7 +35,13 @@ export interface IOAuthController { | |
| 40 35 | 
             
                userInfo(token: string): Promise<Profile>;
         | 
| 41 36 | 
             
            }
         | 
| 42 37 | 
             
            export interface IAdminController {
         | 
| 43 | 
            -
                getAllConfig(): any;
         | 
| 38 | 
            +
                getAllConfig(pageOffset?: number, pageLimit?: number): any;
         | 
| 39 | 
            +
            }
         | 
| 40 | 
            +
            export interface IHealthCheckController {
         | 
| 41 | 
            +
                status(): Promise<{
         | 
| 42 | 
            +
                    status: number;
         | 
| 43 | 
            +
                }>;
         | 
| 44 | 
            +
                init(): Promise<void>;
         | 
| 44 45 | 
             
            }
         | 
| 45 46 | 
             
            export interface OAuthReqBody {
         | 
| 46 47 | 
             
                response_type: 'code';
         | 
| @@ -80,14 +81,14 @@ export interface Index { | |
| 80 81 | 
             
                value: string;
         | 
| 81 82 | 
             
            }
         | 
| 82 83 | 
             
            export interface DatabaseDriver {
         | 
| 83 | 
            -
                getAll(namespace: string): Promise<unknown[]>;
         | 
| 84 | 
            +
                getAll(namespace: string, pageOffset?: number, pageLimit?: number): Promise<unknown[]>;
         | 
| 84 85 | 
             
                get(namespace: string, key: string): Promise<any>;
         | 
| 85 86 | 
             
                put(namespace: string, key: string, val: any, ttl: number, ...indexes: Index[]): Promise<any>;
         | 
| 86 87 | 
             
                delete(namespace: string, key: string): Promise<any>;
         | 
| 87 88 | 
             
                getByIndex(namespace: string, idx: Index): Promise<any>;
         | 
| 88 89 | 
             
            }
         | 
| 89 90 | 
             
            export interface Storable {
         | 
| 90 | 
            -
                getAll(): Promise<unknown[]>;
         | 
| 91 | 
            +
                getAll(pageOffset?: number, pageLimit?: number): Promise<unknown[]>;
         | 
| 91 92 | 
             
                get(key: string): Promise<any>;
         | 
| 92 93 | 
             
                put(key: string, val: any, ...indexes: Index[]): Promise<any>;
         | 
| 93 94 | 
             
                delete(key: string): Promise<any>;
         | 
| @@ -108,6 +109,7 @@ export interface DatabaseOption { | |
| 108 109 | 
             
                ttl?: number;
         | 
| 109 110 | 
             
                cleanupLimit?: number;
         | 
| 110 111 | 
             
                encryptionKey?: string;
         | 
| 112 | 
            +
                pageLimit?: number;
         | 
| 111 113 | 
             
            }
         | 
| 112 114 | 
             
            export interface SAMLReq {
         | 
| 113 115 | 
             
                ssoUrl?: string;
         | 
| @@ -135,3 +137,39 @@ export interface JacksonOption { | |
| 135 137 | 
             
                db: DatabaseOption;
         | 
| 136 138 | 
             
                clientSecretVerifier?: string;
         | 
| 137 139 | 
             
            }
         | 
| 140 | 
            +
            export interface SLORequestParams {
         | 
| 141 | 
            +
                nameId: string;
         | 
| 142 | 
            +
                tenant: string;
         | 
| 143 | 
            +
                product: string;
         | 
| 144 | 
            +
                redirectUrl?: string;
         | 
| 145 | 
            +
            }
         | 
| 146 | 
            +
            interface Metadata {
         | 
| 147 | 
            +
                sso: {
         | 
| 148 | 
            +
                    postUrl?: string;
         | 
| 149 | 
            +
                    redirectUrl: string;
         | 
| 150 | 
            +
                };
         | 
| 151 | 
            +
                slo: {
         | 
| 152 | 
            +
                    redirectUrl?: string;
         | 
| 153 | 
            +
                    postUrl?: string;
         | 
| 154 | 
            +
                };
         | 
| 155 | 
            +
                entityID: string;
         | 
| 156 | 
            +
                thumbprint: string;
         | 
| 157 | 
            +
                loginType: 'idp';
         | 
| 158 | 
            +
                provider: string;
         | 
| 159 | 
            +
            }
         | 
| 160 | 
            +
            export interface SAMLConfig {
         | 
| 161 | 
            +
                idpMetadata: Metadata;
         | 
| 162 | 
            +
                certs: {
         | 
| 163 | 
            +
                    privateKey: string;
         | 
| 164 | 
            +
                    publicKey: string;
         | 
| 165 | 
            +
                };
         | 
| 166 | 
            +
                defaultRedirectUrl: string;
         | 
| 167 | 
            +
            }
         | 
| 168 | 
            +
            export interface ILogoutController {
         | 
| 169 | 
            +
                createRequest(body: SLORequestParams): Promise<{
         | 
| 170 | 
            +
                    logoutUrl: string | null;
         | 
| 171 | 
            +
                    logoutForm: string | null;
         | 
| 172 | 
            +
                }>;
         | 
| 173 | 
            +
                handleResponse(body: SAMLResponsePayload): Promise<any>;
         | 
| 174 | 
            +
            }
         | 
| 175 | 
            +
            export {};
         | 
    
        package/package.json
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            {
         | 
| 2 2 | 
             
              "name": "@boxyhq/saml-jackson",
         | 
| 3 | 
            -
              "version": "0. | 
| 3 | 
            +
              "version": "1.0.0",
         | 
| 4 4 | 
             
              "description": "SAML Jackson library",
         | 
| 5 5 | 
             
              "keywords": [
         | 
| 6 6 | 
             
                "SAML 2.0"
         | 
| @@ -18,12 +18,12 @@ | |
| 18 18 | 
             
              ],
         | 
| 19 19 | 
             
              "scripts": {
         | 
| 20 20 | 
             
                "build": "tsc -p tsconfig.build.json",
         | 
| 21 | 
            -
                "db:migration:generate:postgres": "ts-node - | 
| 22 | 
            -
                "db:migration:generate:mysql": "cross-env DB_TYPE=mysql DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node - | 
| 23 | 
            -
                "db:migration:generate:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node - | 
| 24 | 
            -
                "db:migration:run:postgres": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run",
         | 
| 25 | 
            -
                "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",
         | 
| 26 | 
            -
                "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",
         | 
| 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 | 
            +
                "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: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 | 
            +
                "db:migration:run:postgres": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
         | 
| 25 | 
            +
                "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",
         | 
| 26 | 
            +
                "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 27 | 
             
                "prepublishOnly": "npm run build",
         | 
| 28 28 | 
             
                "test": "tap --ts --timeout=100 --coverage test/**/*.test.ts",
         | 
| 29 29 | 
             
                "sort": "npx sort-package-json"
         | 
| @@ -36,38 +36,38 @@ | |
| 36 36 | 
             
                "statements": 70
         | 
| 37 37 | 
             
              },
         | 
| 38 38 | 
             
              "dependencies": {
         | 
| 39 | 
            -
                "@boxyhq/saml20": "0.2. | 
| 39 | 
            +
                "@boxyhq/saml20": "0.2.1",
         | 
| 40 40 | 
             
                "@opentelemetry/api-metrics": "0.27.0",
         | 
| 41 | 
            -
                "@peculiar/webcrypto": "1.2 | 
| 41 | 
            +
                "@peculiar/webcrypto": "1.3.2",
         | 
| 42 42 | 
             
                "@peculiar/x509": "1.6.1",
         | 
| 43 | 
            -
                "mongodb": "4. | 
| 43 | 
            +
                "mongodb": "4.4.1",
         | 
| 44 44 | 
             
                "mysql2": "2.3.3",
         | 
| 45 45 | 
             
                "pg": "8.7.3",
         | 
| 46 | 
            -
                "rambda": "7.0. | 
| 47 | 
            -
                "redis": "4.0. | 
| 46 | 
            +
                "rambda": "7.0.3",
         | 
| 47 | 
            +
                "redis": "4.0.4",
         | 
| 48 48 | 
             
                "reflect-metadata": "0.1.13",
         | 
| 49 49 | 
             
                "ripemd160": "2.0.2",
         | 
| 50 50 | 
             
                "thumbprint": "0.0.1",
         | 
| 51 | 
            -
                "typeorm": "0. | 
| 51 | 
            +
                "typeorm": "0.3.3",
         | 
| 52 52 | 
             
                "xml-crypto": "2.1.3",
         | 
| 53 53 | 
             
                "xml2js": "0.4.23",
         | 
| 54 54 | 
             
                "xmlbuilder": "15.1.1"
         | 
| 55 55 | 
             
              },
         | 
| 56 56 | 
             
              "devDependencies": {
         | 
| 57 | 
            -
                "@types/node": "17.0. | 
| 57 | 
            +
                "@types/node": "17.0.23",
         | 
| 58 58 | 
             
                "@types/sinon": "10.0.11",
         | 
| 59 | 
            -
                "@types/tap": "15.0. | 
| 60 | 
            -
                "@typescript-eslint/eslint-plugin": "5. | 
| 61 | 
            -
                "@typescript-eslint/parser": "5. | 
| 59 | 
            +
                "@types/tap": "15.0.6",
         | 
| 60 | 
            +
                "@typescript-eslint/eslint-plugin": "5.16.0",
         | 
| 61 | 
            +
                "@typescript-eslint/parser": "5.16.0",
         | 
| 62 62 | 
             
                "cross-env": "7.0.3",
         | 
| 63 | 
            -
                "eslint": "8. | 
| 64 | 
            -
                "eslint-config-prettier": "8. | 
| 65 | 
            -
                "prettier": "2. | 
| 63 | 
            +
                "eslint": "8.11.0",
         | 
| 64 | 
            +
                "eslint-config-prettier": "8.5.0",
         | 
| 65 | 
            +
                "prettier": "2.6.0",
         | 
| 66 66 | 
             
                "sinon": "13.0.1",
         | 
| 67 | 
            -
                "tap": " | 
| 68 | 
            -
                "ts-node": "10. | 
| 69 | 
            -
                "tsconfig-paths": "3. | 
| 70 | 
            -
                "typescript": "4. | 
| 67 | 
            +
                "tap": "16.0.1",
         | 
| 68 | 
            +
                "ts-node": "10.7.0",
         | 
| 69 | 
            +
                "tsconfig-paths": "3.14.1",
         | 
| 70 | 
            +
                "typescript": "4.6.2"
         | 
| 71 71 | 
             
              },
         | 
| 72 72 | 
             
              "engines": {
         | 
| 73 73 | 
             
                "node": ">=14.18.1 <=16.x"
         |