@boxyhq/saml-jackson 1.1.3 → 1.1.6
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 +18 -4
- package/dist/controller/sp-config.d.ts +21 -0
- package/dist/controller/sp-config.js +74 -0
- package/dist/db/mem.js +0 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/typings.d.ts +15 -2
- package/package.json +15 -14
    
        package/dist/controller/oauth.js
    CHANGED
    
    | @@ -161,6 +161,10 @@ class OAuthController { | |
| 161 161 | 
             
                                state,
         | 
| 162 162 | 
             
                                tenant,
         | 
| 163 163 | 
             
                                product,
         | 
| 164 | 
            +
                                access_type,
         | 
| 165 | 
            +
                                resource,
         | 
| 166 | 
            +
                                scope,
         | 
| 167 | 
            +
                                nonce,
         | 
| 164 168 | 
             
                                code_challenge,
         | 
| 165 169 | 
             
                                code_challenge_method,
         | 
| 166 170 | 
             
                                provider,
         | 
| @@ -206,6 +210,10 @@ class OAuthController { | |
| 206 210 | 
             
                                    state,
         | 
| 207 211 | 
             
                                    tenant,
         | 
| 208 212 | 
             
                                    product,
         | 
| 213 | 
            +
                                    access_type,
         | 
| 214 | 
            +
                                    resource,
         | 
| 215 | 
            +
                                    scope,
         | 
| 216 | 
            +
                                    nonce,
         | 
| 209 217 | 
             
                                    code_challenge,
         | 
| 210 218 | 
             
                                    code_challenge_method,
         | 
| 211 219 | 
             
                                    provider,
         | 
| @@ -294,7 +302,7 @@ class OAuthController { | |
| 294 302 | 
             
                                publicKey: samlConfig.certs.publicKey,
         | 
| 295 303 | 
             
                            });
         | 
| 296 304 | 
             
                            const sessionId = crypto_1.default.randomBytes(16).toString('hex');
         | 
| 297 | 
            -
                            const requested = { client_id, state };
         | 
| 305 | 
            +
                            const requested = { client_id, state, redirect_uri };
         | 
| 298 306 | 
             
                            if (requestedTenant) {
         | 
| 299 307 | 
             
                                requested.tenant = requestedTenant;
         | 
| 300 308 | 
             
                            }
         | 
| @@ -542,8 +550,9 @@ class OAuthController { | |
| 542 550 | 
             
                 *             expires_in: 300
         | 
| 543 551 | 
             
                 */
         | 
| 544 552 | 
             
                token(body) {
         | 
| 553 | 
            +
                    var _a, _b, _c;
         | 
| 545 554 | 
             
                    return __awaiter(this, void 0, void 0, function* () {
         | 
| 546 | 
            -
                        const { client_id, client_secret, code_verifier, code, grant_type = 'authorization_code' } = body;
         | 
| 555 | 
            +
                        const { client_id, client_secret, code_verifier, code, grant_type = 'authorization_code', redirect_uri, } = body;
         | 
| 547 556 | 
             
                        metrics.increment('oauthToken');
         | 
| 548 557 | 
             
                        if (grant_type !== 'authorization_code') {
         | 
| 549 558 | 
             
                            throw new error_1.JacksonError('Unsupported grant_type', 400);
         | 
| @@ -555,6 +564,11 @@ class OAuthController { | |
| 555 564 | 
             
                        if (!codeVal || !codeVal.profile) {
         | 
| 556 565 | 
             
                            throw new error_1.JacksonError('Invalid code', 403);
         | 
| 557 566 | 
             
                        }
         | 
| 567 | 
            +
                        if ((_a = codeVal.requested) === null || _a === void 0 ? void 0 : _a.redirect_uri) {
         | 
| 568 | 
            +
                            if (redirect_uri !== codeVal.requested.redirect_uri) {
         | 
| 569 | 
            +
                                throw new error_1.JacksonError(`Invalid request: ${!redirect_uri ? 'redirect_uri missing' : 'redirect_uri mismatch'}`, 400);
         | 
| 570 | 
            +
                            }
         | 
| 571 | 
            +
                        }
         | 
| 558 572 | 
             
                        if (code_verifier) {
         | 
| 559 573 | 
             
                            // PKCE flow
         | 
| 560 574 | 
             
                            let cv = code_verifier;
         | 
| @@ -594,8 +608,8 @@ class OAuthController { | |
| 594 608 | 
             
                        // store details against a token
         | 
| 595 609 | 
             
                        const token = crypto_1.default.randomBytes(20).toString('hex');
         | 
| 596 610 | 
             
                        const tokenVal = Object.assign(Object.assign({}, codeVal.profile), { requested: codeVal.requested });
         | 
| 597 | 
            -
                        const requestedOIDCFlow = !!codeVal.requested.oidc;
         | 
| 598 | 
            -
                        const requestHasNonce = !!codeVal.requested.nonce;
         | 
| 611 | 
            +
                        const requestedOIDCFlow = !!((_b = codeVal.requested) === null || _b === void 0 ? void 0 : _b.oidc);
         | 
| 612 | 
            +
                        const requestHasNonce = !!((_c = codeVal.requested) === null || _c === void 0 ? void 0 : _c.nonce);
         | 
| 599 613 | 
             
                        if (requestedOIDCFlow) {
         | 
| 600 614 | 
             
                            const { jwtSigningKeys, jwsAlg } = this.opts.openid;
         | 
| 601 615 | 
             
                            if (!jwtSigningKeys || !(0, utils_1.isJWSKeyPairLoaded)(jwtSigningKeys)) {
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            import type { JacksonOption } from '../typings';
         | 
| 2 | 
            +
            export declare class SPSAMLConfig {
         | 
| 3 | 
            +
                private opts;
         | 
| 4 | 
            +
                constructor(opts: JacksonOption);
         | 
| 5 | 
            +
                private get acsUrl();
         | 
| 6 | 
            +
                private get entityId();
         | 
| 7 | 
            +
                private get responseSigned();
         | 
| 8 | 
            +
                private get assertionSignature();
         | 
| 9 | 
            +
                private get signatureAlgorithm();
         | 
| 10 | 
            +
                private get assertionEncryption();
         | 
| 11 | 
            +
                get(): {
         | 
| 12 | 
            +
                    acsUrl: string;
         | 
| 13 | 
            +
                    entityId: string;
         | 
| 14 | 
            +
                    response: string;
         | 
| 15 | 
            +
                    assertionSignature: string;
         | 
| 16 | 
            +
                    signatureAlgorithm: string;
         | 
| 17 | 
            +
                    assertionEncryption: string;
         | 
| 18 | 
            +
                };
         | 
| 19 | 
            +
                toMarkdown(): string;
         | 
| 20 | 
            +
                toHTML(): string;
         | 
| 21 | 
            +
            }
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
            Object.defineProperty(exports, "__esModule", { value: true });
         | 
| 3 | 
            +
            exports.SPSAMLConfig = void 0;
         | 
| 4 | 
            +
            const marked_1 = require("marked");
         | 
| 5 | 
            +
            // Service Provider SAML Configuration
         | 
| 6 | 
            +
            class SPSAMLConfig {
         | 
| 7 | 
            +
                constructor(opts) {
         | 
| 8 | 
            +
                    this.opts = opts;
         | 
| 9 | 
            +
                }
         | 
| 10 | 
            +
                get acsUrl() {
         | 
| 11 | 
            +
                    return `${this.opts.externalUrl}${this.opts.samlPath}`;
         | 
| 12 | 
            +
                }
         | 
| 13 | 
            +
                get entityId() {
         | 
| 14 | 
            +
                    return `${this.opts.samlAudience}`;
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
                get responseSigned() {
         | 
| 17 | 
            +
                    return 'Signed';
         | 
| 18 | 
            +
                }
         | 
| 19 | 
            +
                get assertionSignature() {
         | 
| 20 | 
            +
                    return 'Signed';
         | 
| 21 | 
            +
                }
         | 
| 22 | 
            +
                get signatureAlgorithm() {
         | 
| 23 | 
            +
                    return 'RSA-SHA256';
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
                get assertionEncryption() {
         | 
| 26 | 
            +
                    return 'Unencrypted';
         | 
| 27 | 
            +
                }
         | 
| 28 | 
            +
                get() {
         | 
| 29 | 
            +
                    return {
         | 
| 30 | 
            +
                        acsUrl: this.acsUrl,
         | 
| 31 | 
            +
                        entityId: this.entityId,
         | 
| 32 | 
            +
                        response: this.responseSigned,
         | 
| 33 | 
            +
                        assertionSignature: this.assertionSignature,
         | 
| 34 | 
            +
                        signatureAlgorithm: this.signatureAlgorithm,
         | 
| 35 | 
            +
                        assertionEncryption: this.assertionEncryption,
         | 
| 36 | 
            +
                    };
         | 
| 37 | 
            +
                }
         | 
| 38 | 
            +
                toMarkdown() {
         | 
| 39 | 
            +
                    return markdownTemplate
         | 
| 40 | 
            +
                        .replace('{{acsUrl}}', this.acsUrl)
         | 
| 41 | 
            +
                        .replace('{{entityId}}', this.entityId)
         | 
| 42 | 
            +
                        .replace('{{responseSigned}}', this.responseSigned)
         | 
| 43 | 
            +
                        .replace('{{assertionSignature}}', this.assertionSignature)
         | 
| 44 | 
            +
                        .replace('{{signatureAlgorithm}}', this.signatureAlgorithm)
         | 
| 45 | 
            +
                        .replace('{{assertionEncryption}}', this.assertionEncryption);
         | 
| 46 | 
            +
                }
         | 
| 47 | 
            +
                toHTML() {
         | 
| 48 | 
            +
                    return marked_1.marked.parse(this.toMarkdown());
         | 
| 49 | 
            +
                }
         | 
| 50 | 
            +
            }
         | 
| 51 | 
            +
            exports.SPSAMLConfig = SPSAMLConfig;
         | 
| 52 | 
            +
            const markdownTemplate = `
         | 
| 53 | 
            +
            ## Service Provider (SP) SAML Configuration
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            Your Identity Provider (IdP) will ask for the following information while configuring the SAML application. Share this information with your IT administrator.
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            **ACS (Assertion Consumer Service) URL / Single Sign-On URL / Destination URL** <br />
         | 
| 58 | 
            +
            {{acsUrl}}
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            **SP Entity ID / Identifier / Audience URI / Audience Restriction** <br />
         | 
| 61 | 
            +
            {{entityId}}
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            **Response** <br />
         | 
| 64 | 
            +
            {{responseSigned}}
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            **Assertion Signature** <br />
         | 
| 67 | 
            +
            {{assertionSignature}}
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            **Signature Algorithm** <br />
         | 
| 70 | 
            +
            {{signatureAlgorithm}}
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            **Assertion Encryption** <br />
         | 
| 73 | 
            +
            {{assertionEncryption}}
         | 
| 74 | 
            +
            `;
         | 
    
        package/dist/db/mem.js
    CHANGED
    
    
    
        package/dist/index.d.ts
    CHANGED
    
    | @@ -4,6 +4,7 @@ import { OAuthController } from './controller/oauth'; | |
| 4 4 | 
             
            import { HealthCheckController } from './controller/health-check';
         | 
| 5 5 | 
             
            import { LogoutController } from './controller/logout';
         | 
| 6 6 | 
             
            import { OidcDiscoveryController } from './controller/oidc-discovery';
         | 
| 7 | 
            +
            import { SPSAMLConfig } from './controller/sp-config';
         | 
| 7 8 | 
             
            import { JacksonOption } from './typings';
         | 
| 8 9 | 
             
            export declare const controllers: (opts: JacksonOption) => Promise<{
         | 
| 9 10 | 
             
                apiController: APIController;
         | 
| @@ -12,6 +13,7 @@ export declare const controllers: (opts: JacksonOption) => Promise<{ | |
| 12 13 | 
             
                logoutController: LogoutController;
         | 
| 13 14 | 
             
                healthCheckController: HealthCheckController;
         | 
| 14 15 | 
             
                oidcDiscoveryController: OidcDiscoveryController;
         | 
| 16 | 
            +
                spConfig: SPSAMLConfig;
         | 
| 15 17 | 
             
            }>;
         | 
| 16 18 | 
             
            export default controllers;
         | 
| 17 19 | 
             
            export * from './typings';
         | 
    
        package/dist/index.js
    CHANGED
    
    | @@ -33,6 +33,7 @@ const oauth_1 = require("./controller/oauth"); | |
| 33 33 | 
             
            const health_check_1 = require("./controller/health-check");
         | 
| 34 34 | 
             
            const logout_1 = require("./controller/logout");
         | 
| 35 35 | 
             
            const oidc_discovery_1 = require("./controller/oidc-discovery");
         | 
| 36 | 
            +
            const sp_config_1 = require("./controller/sp-config");
         | 
| 36 37 | 
             
            const db_1 = __importDefault(require("./db/db"));
         | 
| 37 38 | 
             
            const defaultDb_1 = __importDefault(require("./db/defaultDb"));
         | 
| 38 39 | 
             
            const read_config_1 = __importDefault(require("./read-config"));
         | 
| @@ -79,6 +80,7 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () { | |
| 79 80 | 
             
                    opts,
         | 
| 80 81 | 
             
                });
         | 
| 81 82 | 
             
                const oidcDiscoveryController = new oidc_discovery_1.OidcDiscoveryController({ opts });
         | 
| 83 | 
            +
                const spConfig = new sp_config_1.SPSAMLConfig(opts);
         | 
| 82 84 | 
             
                // write pre-loaded config if present
         | 
| 83 85 | 
             
                if (opts.preLoadedConfig && opts.preLoadedConfig.length > 0) {
         | 
| 84 86 | 
             
                    const configs = yield (0, read_config_1.default)(opts.preLoadedConfig);
         | 
| @@ -90,6 +92,7 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () { | |
| 90 92 | 
             
                const type = opts.db.engine === 'sql' && opts.db.type ? ' Type: ' + opts.db.type : '';
         | 
| 91 93 | 
             
                console.log(`Using engine: ${opts.db.engine}.${type}`);
         | 
| 92 94 | 
             
                return {
         | 
| 95 | 
            +
                    spConfig,
         | 
| 93 96 | 
             
                    apiController,
         | 
| 94 97 | 
             
                    oauthController,
         | 
| 95 98 | 
             
                    adminController,
         | 
    
        package/dist/typings.d.ts
    CHANGED
    
    | @@ -4,8 +4,8 @@ export declare type IdPConfig = { | |
| 4 4 | 
             
                redirectUrl: string[] | string;
         | 
| 5 5 | 
             
                tenant: string;
         | 
| 6 6 | 
             
                product: string;
         | 
| 7 | 
            -
                name | 
| 8 | 
            -
                description | 
| 7 | 
            +
                name?: string;
         | 
| 8 | 
            +
                description?: string;
         | 
| 9 9 | 
             
                rawMetadata?: string;
         | 
| 10 10 | 
             
                encodedRawMetadata?: string;
         | 
| 11 11 | 
             
            };
         | 
| @@ -89,6 +89,7 @@ export interface OAuthTokenReq { | |
| 89 89 | 
             
                code_verifier: string;
         | 
| 90 90 | 
             
                code: string;
         | 
| 91 91 | 
             
                grant_type: 'authorization_code';
         | 
| 92 | 
            +
                redirect_uri?: string;
         | 
| 92 93 | 
             
            }
         | 
| 93 94 | 
             
            export interface OAuthTokenRes {
         | 
| 94 95 | 
             
                access_token: string;
         | 
| @@ -198,4 +199,16 @@ export interface OAuthErrorHandlerParams { | |
| 198 199 | 
             
                redirect_uri: string;
         | 
| 199 200 | 
             
                state?: string;
         | 
| 200 201 | 
             
            }
         | 
| 202 | 
            +
            export interface ISPSAMLConfig {
         | 
| 203 | 
            +
                get(): {
         | 
| 204 | 
            +
                    acsUrl: string;
         | 
| 205 | 
            +
                    entityId: string;
         | 
| 206 | 
            +
                    response: string;
         | 
| 207 | 
            +
                    assertionSignature: string;
         | 
| 208 | 
            +
                    signatureAlgorithm: string;
         | 
| 209 | 
            +
                    assertionEncryption: string;
         | 
| 210 | 
            +
                };
         | 
| 211 | 
            +
                toMarkdown(): string;
         | 
| 212 | 
            +
                toHTML(): string;
         | 
| 213 | 
            +
            }
         | 
| 201 214 | 
             
            export {};
         | 
    
        package/package.json
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            {
         | 
| 2 2 | 
             
              "name": "@boxyhq/saml-jackson",
         | 
| 3 | 
            -
              "version": "1.1. | 
| 3 | 
            +
              "version": "1.1.6",
         | 
| 4 4 | 
             
              "description": "SAML Jackson library",
         | 
| 5 5 | 
             
              "keywords": [
         | 
| 6 6 | 
             
                "SAML 2.0"
         | 
| @@ -39,36 +39,37 @@ | |
| 39 39 | 
             
              },
         | 
| 40 40 | 
             
              "dependencies": {
         | 
| 41 41 | 
             
                "@boxyhq/saml20": "1.0.6",
         | 
| 42 | 
            -
                "@opentelemetry/api-metrics": "0.27.0",
         | 
| 43 42 | 
             
                "@opentelemetry/api": "1.0.4",
         | 
| 43 | 
            +
                "@opentelemetry/api-metrics": "0.27.0",
         | 
| 44 44 | 
             
                "@peculiar/webcrypto": "1.4.0",
         | 
| 45 | 
            -
                "@peculiar/x509": "1.8. | 
| 46 | 
            -
                "jose": "4. | 
| 47 | 
            -
                " | 
| 45 | 
            +
                "@peculiar/x509": "1.8.3",
         | 
| 46 | 
            +
                "jose": "4.9.2",
         | 
| 47 | 
            +
                "marked": "4.1.0",
         | 
| 48 | 
            +
                "mongodb": "4.9.1",
         | 
| 48 49 | 
             
                "mysql2": "2.3.3",
         | 
| 49 | 
            -
                "pg": "8. | 
| 50 | 
            -
                "redis": "4. | 
| 50 | 
            +
                "pg": "8.8.0",
         | 
| 51 | 
            +
                "redis": "4.3.1",
         | 
| 51 52 | 
             
                "reflect-metadata": "0.1.13",
         | 
| 52 53 | 
             
                "ripemd160": "2.0.2",
         | 
| 53 | 
            -
                "typeorm": "0.3. | 
| 54 | 
            +
                "typeorm": "0.3.9",
         | 
| 54 55 | 
             
                "xml2js": "0.4.23",
         | 
| 55 56 | 
             
                "xmlbuilder": "15.1.1"
         | 
| 56 57 | 
             
              },
         | 
| 57 58 | 
             
              "devDependencies": {
         | 
| 58 | 
            -
                "@types/node": "18. | 
| 59 | 
            +
                "@types/node": "18.7.16",
         | 
| 59 60 | 
             
                "@types/sinon": "10.0.13",
         | 
| 60 61 | 
             
                "@types/tap": "15.0.7",
         | 
| 61 | 
            -
                "@typescript-eslint/eslint-plugin": "5. | 
| 62 | 
            -
                "@typescript-eslint/parser": "5. | 
| 62 | 
            +
                "@typescript-eslint/eslint-plugin": "5.36.2",
         | 
| 63 | 
            +
                "@typescript-eslint/parser": "5.36.2",
         | 
| 63 64 | 
             
                "cross-env": "7.0.3",
         | 
| 64 | 
            -
                "eslint": "8. | 
| 65 | 
            +
                "eslint": "8.23.0",
         | 
| 65 66 | 
             
                "eslint-config-prettier": "8.5.0",
         | 
| 66 67 | 
             
                "prettier": "2.7.1",
         | 
| 67 68 | 
             
                "sinon": "14.0.0",
         | 
| 68 69 | 
             
                "tap": "16.3.0",
         | 
| 69 70 | 
             
                "ts-node": "10.9.1",
         | 
| 70 | 
            -
                "tsconfig-paths": "4. | 
| 71 | 
            -
                "typescript": "4. | 
| 71 | 
            +
                "tsconfig-paths": "4.1.0",
         | 
| 72 | 
            +
                "typescript": "4.8.2"
         | 
| 72 73 | 
             
              },
         | 
| 73 74 | 
             
              "engines": {
         | 
| 74 75 | 
             
                "node": ">=14.18.1 <=16.x"
         |