@boxyhq/saml-jackson 1.0.3 → 1.0.4
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 +127 -64
 - package/dist/controller/utils.d.ts +3 -0
 - package/dist/controller/utils.js +36 -1
 - package/dist/typings.d.ts +7 -0
 - package/package.json +8 -8
 
    
        package/dist/controller/oauth.js
    CHANGED
    
    | 
         @@ -61,9 +61,9 @@ const validateResponse = (rawResponse, validateOpts) => __awaiter(void 0, void 0 
     | 
|
| 
       61 
61 
     | 
    
         
             
                }
         
     | 
| 
       62 
62 
     | 
    
         
             
                return profile;
         
     | 
| 
       63 
63 
     | 
    
         
             
            });
         
     | 
| 
       64 
     | 
    
         
            -
            function getEncodedTenantProduct( 
     | 
| 
      
 64 
     | 
    
         
            +
            function getEncodedTenantProduct(param) {
         
     | 
| 
       65 
65 
     | 
    
         
             
                try {
         
     | 
| 
       66 
     | 
    
         
            -
                    const sp = new URLSearchParams( 
     | 
| 
      
 66 
     | 
    
         
            +
                    const sp = new URLSearchParams(param);
         
     | 
| 
       67 
67 
     | 
    
         
             
                    const tenant = sp.get('tenant');
         
     | 
| 
       68 
68 
     | 
    
         
             
                    const product = sp.get('product');
         
     | 
| 
       69 
69 
     | 
    
         
             
                    if (tenant && product) {
         
     | 
| 
         @@ -128,7 +128,7 @@ class OAuthController { 
     | 
|
| 
       128 
128 
     | 
    
         
             
                }
         
     | 
| 
       129 
129 
     | 
    
         
             
                authorize(body) {
         
     | 
| 
       130 
130 
     | 
    
         
             
                    return __awaiter(this, void 0, void 0, function* () {
         
     | 
| 
       131 
     | 
    
         
            -
                        const { response_type = 'code', client_id, redirect_uri, state, tenant, product, access_type, code_challenge, code_challenge_method = '', 
         
     | 
| 
      
 131 
     | 
    
         
            +
                        const { response_type = 'code', client_id, redirect_uri, state, tenant, product, access_type, scope, code_challenge, code_challenge_method = '', 
         
     | 
| 
       132 
132 
     | 
    
         
             
                        // eslint-disable-next-line @typescript-eslint/no-unused-vars
         
     | 
| 
       133 
133 
     | 
    
         
             
                        provider = 'saml', idp_hint, } = body;
         
     | 
| 
       134 
134 
     | 
    
         
             
                        let requestedTenant = tenant;
         
     | 
| 
         @@ -137,9 +137,6 @@ class OAuthController { 
     | 
|
| 
       137 
137 
     | 
    
         
             
                        if (!redirect_uri) {
         
     | 
| 
       138 
138 
     | 
    
         
             
                            throw new error_1.JacksonError('Please specify a redirect URL.', 400);
         
     | 
| 
       139 
139 
     | 
    
         
             
                        }
         
     | 
| 
       140 
     | 
    
         
            -
                        if (!state) {
         
     | 
| 
       141 
     | 
    
         
            -
                            throw new error_1.JacksonError('Please specify a state to safeguard against XSRF attacks.', 400);
         
     | 
| 
       142 
     | 
    
         
            -
                        }
         
     | 
| 
       143 
140 
     | 
    
         
             
                        let samlConfig;
         
     | 
| 
       144 
141 
     | 
    
         
             
                        if (tenant && product) {
         
     | 
| 
       145 
142 
     | 
    
         
             
                            const samlConfigs = yield this.configStore.getByIndex({
         
     | 
| 
         @@ -169,13 +166,15 @@ class OAuthController { 
     | 
|
| 
       169 
166 
     | 
    
         
             
                                samlConfig = resolvedSamlConfig;
         
     | 
| 
       170 
167 
     | 
    
         
             
                            }
         
     | 
| 
       171 
168 
     | 
    
         
             
                        }
         
     | 
| 
       172 
     | 
    
         
            -
                        else if ( 
     | 
| 
       173 
     | 
    
         
            -
                            (access_type && access_type !== '' && access_type !== 'undefined' && access_type !== 'null')) {
         
     | 
| 
      
 169 
     | 
    
         
            +
                        else if (client_id && client_id !== '' && client_id !== 'undefined' && client_id !== 'null') {
         
     | 
| 
       174 
170 
     | 
    
         
             
                            // if tenant and product are encoded in the client_id then we parse it and check for the relevant config(s)
         
     | 
| 
       175 
171 
     | 
    
         
             
                            let sp = getEncodedTenantProduct(client_id);
         
     | 
| 
       176 
172 
     | 
    
         
             
                            if (!sp && access_type) {
         
     | 
| 
       177 
173 
     | 
    
         
             
                                sp = getEncodedTenantProduct(access_type);
         
     | 
| 
       178 
174 
     | 
    
         
             
                            }
         
     | 
| 
      
 175 
     | 
    
         
            +
                            if (!sp && scope) {
         
     | 
| 
      
 176 
     | 
    
         
            +
                                sp = getEncodedTenantProduct(scope);
         
     | 
| 
      
 177 
     | 
    
         
            +
                            }
         
     | 
| 
       179 
178 
     | 
    
         
             
                            if (sp && sp.tenant && sp.product) {
         
     | 
| 
       180 
179 
     | 
    
         
             
                                requestedTenant = sp.tenant;
         
     | 
| 
       181 
180 
     | 
    
         
             
                                requestedProduct = sp.product;
         
     | 
| 
         @@ -223,6 +222,24 @@ class OAuthController { 
     | 
|
| 
       223 
222 
     | 
    
         
             
                        if (!allowed.redirect(redirect_uri, samlConfig.redirectUrl)) {
         
     | 
| 
       224 
223 
     | 
    
         
             
                            throw new error_1.JacksonError('Redirect URL is not allowed.', 403);
         
     | 
| 
       225 
224 
     | 
    
         
             
                        }
         
     | 
| 
      
 225 
     | 
    
         
            +
                        if (!state) {
         
     | 
| 
      
 226 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 227 
     | 
    
         
            +
                                redirect_url: (0, utils_1.OAuthErrorResponse)({
         
     | 
| 
      
 228 
     | 
    
         
            +
                                    error: 'invalid_request',
         
     | 
| 
      
 229 
     | 
    
         
            +
                                    error_description: 'Please specify a state to safeguard against XSRF attacks',
         
     | 
| 
      
 230 
     | 
    
         
            +
                                    redirect_uri,
         
     | 
| 
      
 231 
     | 
    
         
            +
                                }),
         
     | 
| 
      
 232 
     | 
    
         
            +
                            };
         
     | 
| 
      
 233 
     | 
    
         
            +
                        }
         
     | 
| 
      
 234 
     | 
    
         
            +
                        if (response_type !== 'code') {
         
     | 
| 
      
 235 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 236 
     | 
    
         
            +
                                redirect_url: (0, utils_1.OAuthErrorResponse)({
         
     | 
| 
      
 237 
     | 
    
         
            +
                                    error: 'unsupported_response_type',
         
     | 
| 
      
 238 
     | 
    
         
            +
                                    error_description: 'Only Authorization Code grant is supported',
         
     | 
| 
      
 239 
     | 
    
         
            +
                                    redirect_uri,
         
     | 
| 
      
 240 
     | 
    
         
            +
                                }),
         
     | 
| 
      
 241 
     | 
    
         
            +
                            };
         
     | 
| 
      
 242 
     | 
    
         
            +
                        }
         
     | 
| 
       226 
243 
     | 
    
         
             
                        let ssoUrl;
         
     | 
| 
       227 
244 
     | 
    
         
             
                        let post = false;
         
     | 
| 
       228 
245 
     | 
    
         
             
                        const { sso } = samlConfig.idpMetadata;
         
     | 
| 
         @@ -235,60 +252,80 @@ class OAuthController { 
     | 
|
| 
       235 
252 
     | 
    
         
             
                            ssoUrl = sso.postUrl;
         
     | 
| 
       236 
253 
     | 
    
         
             
                            post = true;
         
     | 
| 
       237 
254 
     | 
    
         
             
                        }
         
     | 
| 
       238 
     | 
    
         
            -
                         
     | 
| 
       239 
     | 
    
         
            -
                             
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
       246 
     | 
    
         
            -
                        const requested = { client_id, state };
         
     | 
| 
       247 
     | 
    
         
            -
                        if (requestedTenant) {
         
     | 
| 
       248 
     | 
    
         
            -
                            requested.tenant = requestedTenant;
         
     | 
| 
       249 
     | 
    
         
            -
                        }
         
     | 
| 
       250 
     | 
    
         
            -
                        if (requestedProduct) {
         
     | 
| 
       251 
     | 
    
         
            -
                            requested.product = requestedProduct;
         
     | 
| 
      
 255 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 256 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 257 
     | 
    
         
            +
                                redirect_url: (0, utils_1.OAuthErrorResponse)({
         
     | 
| 
      
 258 
     | 
    
         
            +
                                    error: 'invalid_request',
         
     | 
| 
      
 259 
     | 
    
         
            +
                                    error_description: 'SAML binding could not be retrieved',
         
     | 
| 
      
 260 
     | 
    
         
            +
                                    redirect_uri,
         
     | 
| 
      
 261 
     | 
    
         
            +
                                }),
         
     | 
| 
      
 262 
     | 
    
         
            +
                            };
         
     | 
| 
       252 
263 
     | 
    
         
             
                        }
         
     | 
| 
       253 
     | 
    
         
            -
                         
     | 
| 
       254 
     | 
    
         
            -
                             
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
       259 
     | 
    
         
            -
             
     | 
| 
       260 
     | 
    
         
            -
                            state,
         
     | 
| 
       261 
     | 
    
         
            -
                            code_challenge,
         
     | 
| 
       262 
     | 
    
         
            -
                            code_challenge_method,
         
     | 
| 
       263 
     | 
    
         
            -
                            requested,
         
     | 
| 
       264 
     | 
    
         
            -
                        });
         
     | 
| 
       265 
     | 
    
         
            -
                        const relayState = utils_1.relayStatePrefix + sessionId;
         
     | 
| 
       266 
     | 
    
         
            -
                        let redirectUrl;
         
     | 
| 
       267 
     | 
    
         
            -
                        let authorizeForm;
         
     | 
| 
       268 
     | 
    
         
            -
                        if (!post) {
         
     | 
| 
       269 
     | 
    
         
            -
                            // HTTP Redirect binding
         
     | 
| 
       270 
     | 
    
         
            -
                            redirectUrl = redirect.success(ssoUrl, {
         
     | 
| 
       271 
     | 
    
         
            -
                                RelayState: relayState,
         
     | 
| 
       272 
     | 
    
         
            -
                                SAMLRequest: Buffer.from(yield deflateRawAsync(samlReq.request)).toString('base64'),
         
     | 
| 
      
 264 
     | 
    
         
            +
                        try {
         
     | 
| 
      
 265 
     | 
    
         
            +
                            const samlReq = saml20_1.default.request({
         
     | 
| 
      
 266 
     | 
    
         
            +
                                ssoUrl,
         
     | 
| 
      
 267 
     | 
    
         
            +
                                entityID: this.opts.samlAudience,
         
     | 
| 
      
 268 
     | 
    
         
            +
                                callbackUrl: this.opts.externalUrl + this.opts.samlPath,
         
     | 
| 
      
 269 
     | 
    
         
            +
                                signingKey: samlConfig.certs.privateKey,
         
     | 
| 
      
 270 
     | 
    
         
            +
                                publicKey: samlConfig.certs.publicKey,
         
     | 
| 
       273 
271 
     | 
    
         
             
                            });
         
     | 
| 
      
 272 
     | 
    
         
            +
                            const sessionId = crypto_1.default.randomBytes(16).toString('hex');
         
     | 
| 
      
 273 
     | 
    
         
            +
                            const requested = { client_id, state };
         
     | 
| 
      
 274 
     | 
    
         
            +
                            if (requestedTenant) {
         
     | 
| 
      
 275 
     | 
    
         
            +
                                requested.tenant = requestedTenant;
         
     | 
| 
      
 276 
     | 
    
         
            +
                            }
         
     | 
| 
      
 277 
     | 
    
         
            +
                            if (requestedProduct) {
         
     | 
| 
      
 278 
     | 
    
         
            +
                                requested.product = requestedProduct;
         
     | 
| 
      
 279 
     | 
    
         
            +
                            }
         
     | 
| 
      
 280 
     | 
    
         
            +
                            if (idp_hint) {
         
     | 
| 
      
 281 
     | 
    
         
            +
                                requested.idp_hint = idp_hint;
         
     | 
| 
      
 282 
     | 
    
         
            +
                            }
         
     | 
| 
      
 283 
     | 
    
         
            +
                            yield this.sessionStore.put(sessionId, {
         
     | 
| 
      
 284 
     | 
    
         
            +
                                id: samlReq.id,
         
     | 
| 
      
 285 
     | 
    
         
            +
                                redirect_uri,
         
     | 
| 
      
 286 
     | 
    
         
            +
                                response_type,
         
     | 
| 
      
 287 
     | 
    
         
            +
                                state,
         
     | 
| 
      
 288 
     | 
    
         
            +
                                code_challenge,
         
     | 
| 
      
 289 
     | 
    
         
            +
                                code_challenge_method,
         
     | 
| 
      
 290 
     | 
    
         
            +
                                requested,
         
     | 
| 
      
 291 
     | 
    
         
            +
                            });
         
     | 
| 
      
 292 
     | 
    
         
            +
                            const relayState = utils_1.relayStatePrefix + sessionId;
         
     | 
| 
      
 293 
     | 
    
         
            +
                            let redirectUrl;
         
     | 
| 
      
 294 
     | 
    
         
            +
                            let authorizeForm;
         
     | 
| 
      
 295 
     | 
    
         
            +
                            if (!post) {
         
     | 
| 
      
 296 
     | 
    
         
            +
                                // HTTP Redirect binding
         
     | 
| 
      
 297 
     | 
    
         
            +
                                redirectUrl = redirect.success(ssoUrl, {
         
     | 
| 
      
 298 
     | 
    
         
            +
                                    RelayState: relayState,
         
     | 
| 
      
 299 
     | 
    
         
            +
                                    SAMLRequest: Buffer.from(yield deflateRawAsync(samlReq.request)).toString('base64'),
         
     | 
| 
      
 300 
     | 
    
         
            +
                                });
         
     | 
| 
      
 301 
     | 
    
         
            +
                            }
         
     | 
| 
      
 302 
     | 
    
         
            +
                            else {
         
     | 
| 
      
 303 
     | 
    
         
            +
                                // HTTP POST binding
         
     | 
| 
      
 304 
     | 
    
         
            +
                                authorizeForm = saml20_1.default.createPostForm(ssoUrl, [
         
     | 
| 
      
 305 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 306 
     | 
    
         
            +
                                        name: 'RelayState',
         
     | 
| 
      
 307 
     | 
    
         
            +
                                        value: relayState,
         
     | 
| 
      
 308 
     | 
    
         
            +
                                    },
         
     | 
| 
      
 309 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 310 
     | 
    
         
            +
                                        name: 'SAMLRequest',
         
     | 
| 
      
 311 
     | 
    
         
            +
                                        value: Buffer.from(samlReq.request).toString('base64'),
         
     | 
| 
      
 312 
     | 
    
         
            +
                                    },
         
     | 
| 
      
 313 
     | 
    
         
            +
                                ]);
         
     | 
| 
      
 314 
     | 
    
         
            +
                            }
         
     | 
| 
      
 315 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 316 
     | 
    
         
            +
                                redirect_url: redirectUrl,
         
     | 
| 
      
 317 
     | 
    
         
            +
                                authorize_form: authorizeForm,
         
     | 
| 
      
 318 
     | 
    
         
            +
                            };
         
     | 
| 
      
 319 
     | 
    
         
            +
                        }
         
     | 
| 
      
 320 
     | 
    
         
            +
                        catch (err) {
         
     | 
| 
      
 321 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 322 
     | 
    
         
            +
                                redirect_url: (0, utils_1.OAuthErrorResponse)({
         
     | 
| 
      
 323 
     | 
    
         
            +
                                    error: 'server_error',
         
     | 
| 
      
 324 
     | 
    
         
            +
                                    error_description: (0, utils_1.getErrorMessage)(err),
         
     | 
| 
      
 325 
     | 
    
         
            +
                                    redirect_uri,
         
     | 
| 
      
 326 
     | 
    
         
            +
                                }),
         
     | 
| 
      
 327 
     | 
    
         
            +
                            };
         
     | 
| 
       274 
328 
     | 
    
         
             
                        }
         
     | 
| 
       275 
     | 
    
         
            -
                        else {
         
     | 
| 
       276 
     | 
    
         
            -
                            // HTTP POST binding
         
     | 
| 
       277 
     | 
    
         
            -
                            authorizeForm = saml20_1.default.createPostForm(ssoUrl, [
         
     | 
| 
       278 
     | 
    
         
            -
                                {
         
     | 
| 
       279 
     | 
    
         
            -
                                    name: 'RelayState',
         
     | 
| 
       280 
     | 
    
         
            -
                                    value: relayState,
         
     | 
| 
       281 
     | 
    
         
            -
                                },
         
     | 
| 
       282 
     | 
    
         
            -
                                {
         
     | 
| 
       283 
     | 
    
         
            -
                                    name: 'SAMLRequest',
         
     | 
| 
       284 
     | 
    
         
            -
                                    value: Buffer.from(samlReq.request).toString('base64'),
         
     | 
| 
       285 
     | 
    
         
            -
                                },
         
     | 
| 
       286 
     | 
    
         
            -
                            ]);
         
     | 
| 
       287 
     | 
    
         
            -
                        }
         
     | 
| 
       288 
     | 
    
         
            -
                        return {
         
     | 
| 
       289 
     | 
    
         
            -
                            redirect_url: redirectUrl,
         
     | 
| 
       290 
     | 
    
         
            -
                            authorize_form: authorizeForm,
         
     | 
| 
       291 
     | 
    
         
            -
                        };
         
     | 
| 
       292 
329 
     | 
    
         
             
                    });
         
     | 
| 
       293 
330 
     | 
    
         
             
                }
         
     | 
| 
       294 
331 
     | 
    
         
             
                samlResponse(body) {
         
     | 
| 
         @@ -346,10 +383,27 @@ class OAuthController { 
     | 
|
| 
       346 
383 
     | 
    
         
             
                            thumbprint: samlConfig.idpMetadata.thumbprint,
         
     | 
| 
       347 
384 
     | 
    
         
             
                            audience: this.opts.samlAudience,
         
     | 
| 
       348 
385 
     | 
    
         
             
                        };
         
     | 
| 
      
 386 
     | 
    
         
            +
                        if (session && session.redirect_uri && !allowed.redirect(session.redirect_uri, samlConfig.redirectUrl)) {
         
     | 
| 
      
 387 
     | 
    
         
            +
                            throw new error_1.JacksonError('Redirect URL is not allowed.', 403);
         
     | 
| 
      
 388 
     | 
    
         
            +
                        }
         
     | 
| 
       349 
389 
     | 
    
         
             
                        if (session && session.id) {
         
     | 
| 
       350 
390 
     | 
    
         
             
                            validateOpts.inResponseTo = session.id;
         
     | 
| 
       351 
391 
     | 
    
         
             
                        }
         
     | 
| 
       352 
     | 
    
         
            -
                         
     | 
| 
      
 392 
     | 
    
         
            +
                        let profile;
         
     | 
| 
      
 393 
     | 
    
         
            +
                        const redirect_uri = (session && session.redirect_uri) || samlConfig.defaultRedirectUrl;
         
     | 
| 
      
 394 
     | 
    
         
            +
                        try {
         
     | 
| 
      
 395 
     | 
    
         
            +
                            profile = yield validateResponse(rawResponse, validateOpts);
         
     | 
| 
      
 396 
     | 
    
         
            +
                        }
         
     | 
| 
      
 397 
     | 
    
         
            +
                        catch (err) {
         
     | 
| 
      
 398 
     | 
    
         
            +
                            // return error to redirect_uri
         
     | 
| 
      
 399 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 400 
     | 
    
         
            +
                                redirect_url: (0, utils_1.OAuthErrorResponse)({
         
     | 
| 
      
 401 
     | 
    
         
            +
                                    error: 'access_denied',
         
     | 
| 
      
 402 
     | 
    
         
            +
                                    error_description: (0, utils_1.getErrorMessage)(err),
         
     | 
| 
      
 403 
     | 
    
         
            +
                                    redirect_uri,
         
     | 
| 
      
 404 
     | 
    
         
            +
                                }),
         
     | 
| 
      
 405 
     | 
    
         
            +
                            };
         
     | 
| 
      
 406 
     | 
    
         
            +
                        }
         
     | 
| 
       353 
407 
     | 
    
         
             
                        // store details against a code
         
     | 
| 
       354 
408 
     | 
    
         
             
                        const code = crypto_1.default.randomBytes(20).toString('hex');
         
     | 
| 
       355 
409 
     | 
    
         
             
                        const codeVal = {
         
     | 
| 
         @@ -361,9 +415,18 @@ class OAuthController { 
     | 
|
| 
       361 
415 
     | 
    
         
             
                        if (session) {
         
     | 
| 
       362 
416 
     | 
    
         
             
                            codeVal.session = session;
         
     | 
| 
       363 
417 
     | 
    
         
             
                        }
         
     | 
| 
       364 
     | 
    
         
            -
                         
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
      
 418 
     | 
    
         
            +
                        try {
         
     | 
| 
      
 419 
     | 
    
         
            +
                            yield this.codeStore.put(code, codeVal);
         
     | 
| 
      
 420 
     | 
    
         
            +
                        }
         
     | 
| 
      
 421 
     | 
    
         
            +
                        catch (err) {
         
     | 
| 
      
 422 
     | 
    
         
            +
                            // return error to redirect_uri
         
     | 
| 
      
 423 
     | 
    
         
            +
                            return {
         
     | 
| 
      
 424 
     | 
    
         
            +
                                redirect_url: (0, utils_1.OAuthErrorResponse)({
         
     | 
| 
      
 425 
     | 
    
         
            +
                                    error: 'server_error',
         
     | 
| 
      
 426 
     | 
    
         
            +
                                    error_description: (0, utils_1.getErrorMessage)(err),
         
     | 
| 
      
 427 
     | 
    
         
            +
                                    redirect_uri,
         
     | 
| 
      
 428 
     | 
    
         
            +
                                }),
         
     | 
| 
      
 429 
     | 
    
         
            +
                            };
         
     | 
| 
       367 
430 
     | 
    
         
             
                        }
         
     | 
| 
       368 
431 
     | 
    
         
             
                        const params = {
         
     | 
| 
       369 
432 
     | 
    
         
             
                            code,
         
     | 
| 
         @@ -371,7 +434,7 @@ class OAuthController { 
     | 
|
| 
       371 
434 
     | 
    
         
             
                        if (session && session.state) {
         
     | 
| 
       372 
435 
     | 
    
         
             
                            params.state = session.state;
         
     | 
| 
       373 
436 
     | 
    
         
             
                        }
         
     | 
| 
       374 
     | 
    
         
            -
                        const redirectUrl = redirect.success( 
     | 
| 
      
 437 
     | 
    
         
            +
                        const redirectUrl = redirect.success(redirect_uri, params);
         
     | 
| 
       375 
438 
     | 
    
         
             
                        // delete the session
         
     | 
| 
       376 
439 
     | 
    
         
             
                        try {
         
     | 
| 
       377 
440 
     | 
    
         
             
                            yield this.sessionStore.delete(RelayState);
         
     | 
| 
         @@ -1,6 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import type { OAuthErrorHandlerParams } from '../typings';
         
     | 
| 
       1 
2 
     | 
    
         
             
            export declare enum IndexNames {
         
     | 
| 
       2 
3 
     | 
    
         
             
                EntityID = "entityID",
         
     | 
| 
       3 
4 
     | 
    
         
             
                TenantProduct = "tenantProduct"
         
     | 
| 
       4 
5 
     | 
    
         
             
            }
         
     | 
| 
       5 
6 
     | 
    
         
             
            export declare const relayStatePrefix = "boxyhq_jackson_";
         
     | 
| 
       6 
7 
     | 
    
         
             
            export declare const validateAbsoluteUrl: (url: any, message: any) => void;
         
     | 
| 
      
 8 
     | 
    
         
            +
            export declare const OAuthErrorResponse: ({ error, error_description, redirect_uri }: OAuthErrorHandlerParams) => string;
         
     | 
| 
      
 9 
     | 
    
         
            +
            export declare function getErrorMessage(error: unknown): string;
         
     | 
    
        package/dist/controller/utils.js
    CHANGED
    
    | 
         @@ -1,7 +1,31 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            "use strict";
         
     | 
| 
      
 2 
     | 
    
         
            +
            var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
         
     | 
| 
      
 3 
     | 
    
         
            +
                if (k2 === undefined) k2 = k;
         
     | 
| 
      
 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);
         
     | 
| 
      
 9 
     | 
    
         
            +
            }) : (function(o, m, k, k2) {
         
     | 
| 
      
 10 
     | 
    
         
            +
                if (k2 === undefined) k2 = k;
         
     | 
| 
      
 11 
     | 
    
         
            +
                o[k2] = m[k];
         
     | 
| 
      
 12 
     | 
    
         
            +
            }));
         
     | 
| 
      
 13 
     | 
    
         
            +
            var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
         
     | 
| 
      
 14 
     | 
    
         
            +
                Object.defineProperty(o, "default", { enumerable: true, value: v });
         
     | 
| 
      
 15 
     | 
    
         
            +
            }) : function(o, v) {
         
     | 
| 
      
 16 
     | 
    
         
            +
                o["default"] = v;
         
     | 
| 
      
 17 
     | 
    
         
            +
            });
         
     | 
| 
      
 18 
     | 
    
         
            +
            var __importStar = (this && this.__importStar) || function (mod) {
         
     | 
| 
      
 19 
     | 
    
         
            +
                if (mod && mod.__esModule) return mod;
         
     | 
| 
      
 20 
     | 
    
         
            +
                var result = {};
         
     | 
| 
      
 21 
     | 
    
         
            +
                if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
         
     | 
| 
      
 22 
     | 
    
         
            +
                __setModuleDefault(result, mod);
         
     | 
| 
      
 23 
     | 
    
         
            +
                return result;
         
     | 
| 
      
 24 
     | 
    
         
            +
            };
         
     | 
| 
       2 
25 
     | 
    
         
             
            Object.defineProperty(exports, "__esModule", { value: true });
         
     | 
| 
       3 
     | 
    
         
            -
            exports.validateAbsoluteUrl = exports.relayStatePrefix = exports.IndexNames = void 0;
         
     | 
| 
      
 26 
     | 
    
         
            +
            exports.getErrorMessage = exports.OAuthErrorResponse = exports.validateAbsoluteUrl = exports.relayStatePrefix = exports.IndexNames = void 0;
         
     | 
| 
       4 
27 
     | 
    
         
             
            const error_1 = require("./error");
         
     | 
| 
      
 28 
     | 
    
         
            +
            const redirect = __importStar(require("./oauth/redirect"));
         
     | 
| 
       5 
29 
     | 
    
         
             
            var IndexNames;
         
     | 
| 
       6 
30 
     | 
    
         
             
            (function (IndexNames) {
         
     | 
| 
       7 
31 
     | 
    
         
             
                IndexNames["EntityID"] = "entityID";
         
     | 
| 
         @@ -17,3 +41,14 @@ const validateAbsoluteUrl = (url, message) => { 
     | 
|
| 
       17 
41 
     | 
    
         
             
                }
         
     | 
| 
       18 
42 
     | 
    
         
             
            };
         
     | 
| 
       19 
43 
     | 
    
         
             
            exports.validateAbsoluteUrl = validateAbsoluteUrl;
         
     | 
| 
      
 44 
     | 
    
         
            +
            const OAuthErrorResponse = ({ error, error_description, redirect_uri }) => {
         
     | 
| 
      
 45 
     | 
    
         
            +
                return redirect.success(redirect_uri, { error, error_description });
         
     | 
| 
      
 46 
     | 
    
         
            +
            };
         
     | 
| 
      
 47 
     | 
    
         
            +
            exports.OAuthErrorResponse = OAuthErrorResponse;
         
     | 
| 
      
 48 
     | 
    
         
            +
            // https://kentcdodds.com/blog/get-a-catch-block-error-message-with-typescript
         
     | 
| 
      
 49 
     | 
    
         
            +
            function getErrorMessage(error) {
         
     | 
| 
      
 50 
     | 
    
         
            +
                if (error instanceof Error)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return error.message;
         
     | 
| 
      
 52 
     | 
    
         
            +
                return String(error);
         
     | 
| 
      
 53 
     | 
    
         
            +
            }
         
     | 
| 
      
 54 
     | 
    
         
            +
            exports.getErrorMessage = getErrorMessage;
         
     | 
    
        package/dist/typings.d.ts
    CHANGED
    
    | 
         @@ -52,6 +52,7 @@ export interface OAuthReqBody { 
     | 
|
| 
       52 
52 
     | 
    
         
             
                tenant?: string;
         
     | 
| 
       53 
53 
     | 
    
         
             
                product?: string;
         
     | 
| 
       54 
54 
     | 
    
         
             
                access_type?: string;
         
     | 
| 
      
 55 
     | 
    
         
            +
                scope?: string;
         
     | 
| 
       55 
56 
     | 
    
         
             
                code_challenge: string;
         
     | 
| 
       56 
57 
     | 
    
         
             
                code_challenge_method: 'plain' | 'S256' | '';
         
     | 
| 
       57 
58 
     | 
    
         
             
                provider: 'saml';
         
     | 
| 
         @@ -79,6 +80,7 @@ export interface Profile { 
     | 
|
| 
       79 
80 
     | 
    
         
             
                email: string;
         
     | 
| 
       80 
81 
     | 
    
         
             
                firstName: string;
         
     | 
| 
       81 
82 
     | 
    
         
             
                lastName: string;
         
     | 
| 
      
 83 
     | 
    
         
            +
                requested: Record<string, string>;
         
     | 
| 
       82 
84 
     | 
    
         
             
            }
         
     | 
| 
       83 
85 
     | 
    
         
             
            export interface Index {
         
     | 
| 
       84 
86 
     | 
    
         
             
                name: string;
         
     | 
| 
         @@ -160,4 +162,9 @@ export interface ILogoutController { 
     | 
|
| 
       160 
162 
     | 
    
         
             
                }>;
         
     | 
| 
       161 
163 
     | 
    
         
             
                handleResponse(body: SAMLResponsePayload): Promise<any>;
         
     | 
| 
       162 
164 
     | 
    
         
             
            }
         
     | 
| 
      
 165 
     | 
    
         
            +
            export interface OAuthErrorHandlerParams {
         
     | 
| 
      
 166 
     | 
    
         
            +
                error: 'invalid_request' | 'access_denied' | 'unauthorized_client' | 'unsupported_response_type' | 'invalid_scope' | 'server_error' | 'temporarily_unavailable';
         
     | 
| 
      
 167 
     | 
    
         
            +
                error_description: string;
         
     | 
| 
      
 168 
     | 
    
         
            +
                redirect_uri: string;
         
     | 
| 
      
 169 
     | 
    
         
            +
            }
         
     | 
| 
       163 
170 
     | 
    
         
             
            export {};
         
     | 
    
        package/package.json
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            {
         
     | 
| 
       2 
2 
     | 
    
         
             
              "name": "@boxyhq/saml-jackson",
         
     | 
| 
       3 
     | 
    
         
            -
              "version": "1.0. 
     | 
| 
      
 3 
     | 
    
         
            +
              "version": "1.0.4",
         
     | 
| 
       4 
4 
     | 
    
         
             
              "description": "SAML Jackson library",
         
     | 
| 
       5 
5 
     | 
    
         
             
              "keywords": [
         
     | 
| 
       6 
6 
     | 
    
         
             
                "SAML 2.0"
         
     | 
| 
         @@ -38,12 +38,12 @@ 
     | 
|
| 
       38 
38 
     | 
    
         
             
              "dependencies": {
         
     | 
| 
       39 
39 
     | 
    
         
             
                "@boxyhq/saml20": "1.0.2",
         
     | 
| 
       40 
40 
     | 
    
         
             
                "@opentelemetry/api-metrics": "0.27.0",
         
     | 
| 
       41 
     | 
    
         
            -
                "@peculiar/webcrypto": "1. 
     | 
| 
       42 
     | 
    
         
            -
                "@peculiar/x509": "1.6. 
     | 
| 
       43 
     | 
    
         
            -
                "mongodb": "4. 
     | 
| 
      
 41 
     | 
    
         
            +
                "@peculiar/webcrypto": "1.4.0",
         
     | 
| 
      
 42 
     | 
    
         
            +
                "@peculiar/x509": "1.6.3",
         
     | 
| 
      
 43 
     | 
    
         
            +
                "mongodb": "4.6.0",
         
     | 
| 
       44 
44 
     | 
    
         
             
                "mysql2": "2.3.3",
         
     | 
| 
       45 
45 
     | 
    
         
             
                "pg": "8.7.3",
         
     | 
| 
       46 
     | 
    
         
            -
                "redis": "4. 
     | 
| 
      
 46 
     | 
    
         
            +
                "redis": "4.0.6",
         
     | 
| 
       47 
47 
     | 
    
         
             
                "reflect-metadata": "0.1.13",
         
     | 
| 
       48 
48 
     | 
    
         
             
                "ripemd160": "2.0.2",
         
     | 
| 
       49 
49 
     | 
    
         
             
                "typeorm": "0.3.6",
         
     | 
| 
         @@ -51,11 +51,11 @@ 
     | 
|
| 
       51 
51 
     | 
    
         
             
                "xmlbuilder": "15.1.1"
         
     | 
| 
       52 
52 
     | 
    
         
             
              },
         
     | 
| 
       53 
53 
     | 
    
         
             
              "devDependencies": {
         
     | 
| 
       54 
     | 
    
         
            -
                "@types/node": "17.0. 
     | 
| 
      
 54 
     | 
    
         
            +
                "@types/node": "17.0.34",
         
     | 
| 
       55 
55 
     | 
    
         
             
                "@types/sinon": "10.0.11",
         
     | 
| 
       56 
56 
     | 
    
         
             
                "@types/tap": "15.0.7",
         
     | 
| 
       57 
     | 
    
         
            -
                "@typescript-eslint/eslint-plugin": "5. 
     | 
| 
       58 
     | 
    
         
            -
                "@typescript-eslint/parser": "5. 
     | 
| 
      
 57 
     | 
    
         
            +
                "@typescript-eslint/eslint-plugin": "5.25.0",
         
     | 
| 
      
 58 
     | 
    
         
            +
                "@typescript-eslint/parser": "5.25.0",
         
     | 
| 
       59 
59 
     | 
    
         
             
                "cross-env": "7.0.3",
         
     | 
| 
       60 
60 
     | 
    
         
             
                "eslint": "8.15.0",
         
     | 
| 
       61 
61 
     | 
    
         
             
                "eslint-config-prettier": "8.5.0",
         
     |