mirror of https://github.com/boxyhq/jackson.git
Support for OIDC flow (#306)
* Support 'POST' at authorization endpoint * handle additional scope params * handle additional claims param * Try with `legacy-peer-deps` true * Fix logic * Set legacy-peer-deps to `true` * Remove `.npmrc` files and sync packages from main * Resolve conflicts * Load jwtSigningKeys into env * Return id_token for OIDC flow * Support `nonce` * Add type for `nonce` * Set `nonce` only if present in request * Expose OpenId provider metadata * Update metadata * Tweak path remove dot, map jwks * Add jwsAlg and source keys using base64 * Source jose from root package.json too * JWS utils * Serve jwks_uri * Load private key for signing * Fix authz endpoint * Format example env * Fix claims * Format discovery and add missing metadata * Include the basic profile in id_token * Fix claims access * Remove console log * Sync package lock * Cleanup * Support for claims is optional * cleanup type * Set `Content-Type` header * Remove default from env * Handle jwt env * oidc fixture * Test for oidc flow, check id_token in response * Add jwt envs * Fix for undefined * Remove keys check in controller init * Runtime check for JWS keys * check if id_token is absent * Check for claims and verify signature * Snapshot test oidc discovery page * Add snapshot for linux to work in CI * Test with a fontless screenshot * test with this one * add a debug step * Get the entire dir for snapshot * Test with this * Comment out debug step * snapshot test jwks * Update env * Upload screenshot for linux * Add debug step * Update snapshot * Sync package lock * Remove local testing snapshots * Assert using api request * Update to use api test for jwks endpoint * Set `JWS_ALG` env * Prefix openid vars * Fix env access * Fix e2e test * Fix options in tests * Fix env var access * Use ttl from env * Simplify exp value setting * oidc discovery controller * Fix typing * Handle case where signing keys are not set * return `oidcDiscoveryController` * Throw a JacksonError like object * Use controllers and cleanup * throw JacksonError like object * Minor formatting * Fix typing and add check for undefined * Keep order of packages same as in main * Update key generation comment * Initialise `openid` correctly in npm * Cleanup * Set `sub` claim * Set 'sub' only for oidc flow
This commit is contained in:
parent
2291aa1081
commit
9b23eed3e3
15
.env.example
15
.env.example
|
@ -30,3 +30,18 @@ NEXTAUTH_ACL=
|
|||
# OpenTelemetry
|
||||
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=
|
||||
OTEL_EXPORTER_OTLP_HEADERS=
|
||||
|
||||
# JWS Algorithm to be used for signing e.g., RS256
|
||||
# https://github.com/panva/jose/issues/114#digital-signatures
|
||||
OPENID_JWS_ALG=
|
||||
|
||||
# JWT signing keys
|
||||
# Generate keys: https://www.scottbrady91.com/openssl/creating-rsa-keys-using-openssl,
|
||||
# Load into env: https://developer.vonage.com/blog/20/07/29/using-private-keys-in-environment-variables
|
||||
# openssl genrsa -out private-key.pem 3072
|
||||
# convert to pkcs8 format: openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private-key.pem -out private_key.pem
|
||||
# cat private_key.pem | base64
|
||||
OPENID_RSA_PRIVATE_KEY=
|
||||
# openssl rsa -in private_key.pem -pubout -out public_key.pem
|
||||
# cat public-key.pem | base64
|
||||
OPENID_RSA_PUBLIC_KEY=
|
|
@ -32,6 +32,9 @@ jobs:
|
|||
DEBUG: pw:webserver
|
||||
SAML_AUDIENCE: https://saml.boxyhq.com
|
||||
JACKSON_API_KEYS: secret
|
||||
OPENID_JWS_ALG: RS256
|
||||
OPENID_RSA_PUBLIC_KEY: ${{ secrets.OPENID_RSA_PUBLIC_KEY }}
|
||||
OPENID_RSA_PRIVATE_KEY: ${{ secrets.OPENID_RSA_PRIVATE_KEY }}
|
||||
PLANETSCALE_URL: ${{ secrets.PLANETSCALE_URL }}
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import * as jose from 'jose';
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('should return public key in jwk format', async ({ request }) => {
|
||||
const response = await request.get('/oauth/jwks');
|
||||
const jwks = await response.json();
|
||||
|
||||
const spki = Buffer.from(process.env.OPENID_RSA_PUBLIC_KEY || '', 'base64').toString('ascii');
|
||||
const importedPublicKey = await jose.importSPKI(spki, process.env.OPENID_JWS_ALG || '');
|
||||
|
||||
const publicKeyJWK = await jose.exportJWK(importedPublicKey);
|
||||
const jwkThumbprint = await jose.calculateJwkThumbprint(publicKeyJWK);
|
||||
|
||||
expect(jwks).toStrictEqual({
|
||||
keys: [
|
||||
{
|
||||
...publicKeyJWK,
|
||||
kid: jwkThumbprint,
|
||||
alg: process.env.OPENID_JWS_ALG,
|
||||
use: 'sig',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('should return oidc discovery configuration', async ({ request, baseURL }) => {
|
||||
const response = await request.get('/.well-known/openid-configuration');
|
||||
const oidcDiscovery = await response.json();
|
||||
|
||||
expect(oidcDiscovery).toStrictEqual({
|
||||
issuer: process.env.SAML_AUDIENCE,
|
||||
authorization_endpoint: `${baseURL}/api/oauth/authorize`,
|
||||
token_endpoint: `${baseURL}/api/oauth/token`,
|
||||
userinfo_endpoint: `${baseURL}/api/oauth/userinfo`,
|
||||
jwks_uri: `${baseURL}/oauth/jwks`,
|
||||
response_types_supported: ['code'],
|
||||
subject_types_supported: ['public'],
|
||||
id_token_signing_alg_values_supported: ['RS256'],
|
||||
grant_types_supported: ['authorization_code'],
|
||||
code_challenge_methods_supported: ['plain', 'S256'],
|
||||
});
|
||||
});
|
|
@ -33,6 +33,13 @@ const db = {
|
|||
|
||||
const clientSecretVerifier = process.env.CLIENT_SECRET_VERIFIER;
|
||||
|
||||
const jwsAlg = process.env.OPENID_JWS_ALG || '';
|
||||
const jwtSigningKeys = {
|
||||
private: process.env.OPENID_RSA_PRIVATE_KEY || '',
|
||||
public: process.env.OPENID_RSA_PUBLIC_KEY || '',
|
||||
};
|
||||
const openid = { jwsAlg, jwtSigningKeys };
|
||||
|
||||
export default {
|
||||
hostUrl,
|
||||
hostPort,
|
||||
|
@ -45,4 +52,5 @@ export default {
|
|||
idpEnabled,
|
||||
db,
|
||||
clientSecretVerifier,
|
||||
openid,
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import jackson, {
|
|||
ILogoutController,
|
||||
IOAuthController,
|
||||
IHealthCheckController,
|
||||
IOidcDiscoveryController,
|
||||
} from '@boxyhq/saml-jackson';
|
||||
import env from '@lib/env';
|
||||
import '@lib/metrics';
|
||||
|
@ -14,6 +15,7 @@ let oauthController: IOAuthController;
|
|||
let adminController: IAdminController;
|
||||
let logoutController: ILogoutController;
|
||||
let healthCheckController: IHealthCheckController;
|
||||
let oidcDiscoveryController: IOidcDiscoveryController;
|
||||
|
||||
const g = global as any;
|
||||
|
||||
|
@ -23,7 +25,8 @@ export default async function init() {
|
|||
!g.oauthController ||
|
||||
!g.adminController ||
|
||||
!g.healthCheckController ||
|
||||
!g.logoutController
|
||||
!g.logoutController ||
|
||||
!g.oidcDiscoveryController
|
||||
) {
|
||||
const ret = await jackson(env);
|
||||
apiController = ret.apiController;
|
||||
|
@ -31,12 +34,14 @@ export default async function init() {
|
|||
adminController = ret.adminController;
|
||||
logoutController = ret.logoutController;
|
||||
healthCheckController = ret.healthCheckController;
|
||||
oidcDiscoveryController = ret.oidcDiscoveryController;
|
||||
|
||||
g.apiController = apiController;
|
||||
g.oauthController = oauthController;
|
||||
g.adminController = adminController;
|
||||
g.logoutController = logoutController;
|
||||
g.healthCheckController = healthCheckController;
|
||||
g.oidcDiscoveryController = oidcDiscoveryController;
|
||||
g.isJacksonReady = true;
|
||||
} else {
|
||||
apiController = g.apiController;
|
||||
|
@ -44,6 +49,7 @@ export default async function init() {
|
|||
adminController = g.adminController;
|
||||
logoutController = g.logoutController;
|
||||
healthCheckController = g.healthCheckController;
|
||||
oidcDiscoveryController = g.oidcDiscoveryController;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -52,6 +58,7 @@ export default async function init() {
|
|||
adminController,
|
||||
logoutController,
|
||||
healthCheckController,
|
||||
oidcDiscoveryController,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import env from '@lib/env';
|
||||
import micromatch from 'micromatch';
|
||||
import * as jose from 'jose';
|
||||
|
||||
export const validateApiKey = (token) => {
|
||||
return env.apiKeys.includes(token);
|
||||
|
|
|
@ -15,4 +15,16 @@ module.exports = {
|
|||
|
||||
return config;
|
||||
},
|
||||
rewrites: async () => {
|
||||
return [
|
||||
{
|
||||
source: '/.well-known/openid-configuration',
|
||||
destination: '/api/well-known/openid-configuration',
|
||||
},
|
||||
{
|
||||
source: '/oauth/jwks',
|
||||
destination: '/api/oauth/jwks',
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
"node": ">=14.18.1 <=16.x"
|
||||
}
|
||||
},
|
||||
"../../../../../jacksonExamples/saml20-maintained": {
|
||||
"../../jacksonExamples/saml20-maintained": {
|
||||
"name": "@boxyhq/saml20",
|
||||
"version": "1.0.0",
|
||||
"extraneous": true,
|
||||
|
@ -61,9 +61,6 @@
|
|||
"typescript": "4.6.3"
|
||||
}
|
||||
},
|
||||
"../../../../vishallodha/Desktop/boxyhq/jacksonExamples/saml20-maintained": {
|
||||
"extraneous": true
|
||||
},
|
||||
"../../saml20-maintained": {
|
||||
"name": "@boxyhq/saml20",
|
||||
"version": "1.0.0-beta-2",
|
||||
|
@ -85,6 +82,9 @@
|
|||
"typescript": "4.6.3"
|
||||
}
|
||||
},
|
||||
"../../vishallodha/Desktop/boxyhq/jacksonExamples/saml20-maintained": {
|
||||
"extraneous": true
|
||||
},
|
||||
"@boxyhq/saml20@1.0.0-beta-1": {
|
||||
"extraneous": true
|
||||
},
|
||||
|
@ -542,7 +542,7 @@
|
|||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
|
@ -650,7 +650,7 @@
|
|||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz",
|
||||
"integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
|
@ -659,13 +659,13 @@
|
|||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz",
|
||||
"integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
|
@ -981,25 +981,25 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
|
||||
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
|
||||
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
|
||||
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
|
||||
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.11",
|
||||
|
@ -1246,7 +1246,7 @@
|
|||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
|
||||
"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
@ -1267,7 +1267,7 @@
|
|||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
|
@ -1371,7 +1371,7 @@
|
|||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
|
@ -1781,7 +1781,7 @@
|
|||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "7.0.3",
|
||||
|
@ -3073,7 +3073,7 @@
|
|||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/memory-pager": {
|
||||
"version": "1.5.0",
|
||||
|
@ -6342,7 +6342,7 @@
|
|||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
|
@ -6385,7 +6385,7 @@
|
|||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
|
@ -6669,7 +6669,7 @@
|
|||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
@ -6743,7 +6743,7 @@
|
|||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/webcrypto-core": {
|
||||
"version": "1.7.5",
|
||||
|
@ -6980,7 +6980,7 @@
|
|||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
@ -7342,7 +7342,7 @@
|
|||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
}
|
||||
|
@ -7431,19 +7431,19 @@
|
|||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz",
|
||||
"integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz",
|
||||
"integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
|
@ -7452,8 +7452,7 @@
|
|||
"@node-redis/bloom": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-redis/bloom/-/bloom-1.0.1.tgz",
|
||||
"integrity": "sha512-mXEBvEIgF4tUzdIN89LiYsbi6//EdpFA7L8M+DHCvePXg+bfHWi+ct5VI6nHUFQE5+ohm/9wmgihCH3HSkeKsw==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-mXEBvEIgF4tUzdIN89LiYsbi6//EdpFA7L8M+DHCvePXg+bfHWi+ct5VI6nHUFQE5+ohm/9wmgihCH3HSkeKsw=="
|
||||
},
|
||||
"@node-redis/client": {
|
||||
"version": "1.0.5",
|
||||
|
@ -7469,26 +7468,22 @@
|
|||
"@node-redis/graph": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-redis/graph/-/graph-1.0.0.tgz",
|
||||
"integrity": "sha512-mRSo8jEGC0cf+Rm7q8mWMKKKqkn6EAnA9IA2S3JvUv/gaWW/73vil7GLNwion2ihTptAm05I9LkepzfIXUKX5g==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-mRSo8jEGC0cf+Rm7q8mWMKKKqkn6EAnA9IA2S3JvUv/gaWW/73vil7GLNwion2ihTptAm05I9LkepzfIXUKX5g=="
|
||||
},
|
||||
"@node-redis/json": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@node-redis/json/-/json-1.0.2.tgz",
|
||||
"integrity": "sha512-qVRgn8WfG46QQ08CghSbY4VhHFgaTY71WjpwRBGEuqGPfWwfRcIf3OqSpR7Q/45X+v3xd8mvYjywqh0wqJ8T+g==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-qVRgn8WfG46QQ08CghSbY4VhHFgaTY71WjpwRBGEuqGPfWwfRcIf3OqSpR7Q/45X+v3xd8mvYjywqh0wqJ8T+g=="
|
||||
},
|
||||
"@node-redis/search": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@node-redis/search/-/search-1.0.5.tgz",
|
||||
"integrity": "sha512-MCOL8iCKq4v+3HgEQv8zGlSkZyXSXtERgrAJ4TSryIG/eLFy84b57KmNNa/V7M1Q2Wd2hgn2nPCGNcQtk1R1OQ==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-MCOL8iCKq4v+3HgEQv8zGlSkZyXSXtERgrAJ4TSryIG/eLFy84b57KmNNa/V7M1Q2Wd2hgn2nPCGNcQtk1R1OQ=="
|
||||
},
|
||||
"@node-redis/time-series": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@node-redis/time-series/-/time-series-1.0.2.tgz",
|
||||
"integrity": "sha512-HGQ8YooJ8Mx7l28tD7XjtB3ImLEjlUxG1wC1PAjxu6hPJqjPshUZxAICzDqDjtIbhDTf48WXXUcx8TQJB1XTKA==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-HGQ8YooJ8Mx7l28tD7XjtB3ImLEjlUxG1wC1PAjxu6hPJqjPshUZxAICzDqDjtIbhDTf48WXXUcx8TQJB1XTKA=="
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
|
@ -7725,25 +7720,25 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
|
||||
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node12": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
|
||||
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node14": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
|
||||
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"@tsconfig/node16": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
|
||||
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.11",
|
||||
|
@ -7898,20 +7893,19 @@
|
|||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
|
||||
"integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"dev": true
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
|
@ -7987,7 +7981,7 @@
|
|||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"argparse": {
|
||||
"version": "2.0.1",
|
||||
|
@ -8274,7 +8268,7 @@
|
|||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.3",
|
||||
|
@ -8462,8 +8456,7 @@
|
|||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
|
||||
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"dev": true
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
|
@ -9233,7 +9226,7 @@
|
|||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"memory-pager": {
|
||||
"version": "1.5.0",
|
||||
|
@ -9629,8 +9622,7 @@
|
|||
"pg-pool": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz",
|
||||
"integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ=="
|
||||
},
|
||||
"pg-protocol": {
|
||||
"version": "1.5.0",
|
||||
|
@ -11339,8 +11331,7 @@
|
|||
"ws": {
|
||||
"version": "7.5.7",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
|
@ -11500,7 +11491,7 @@
|
|||
"version": "10.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
|
||||
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
|
@ -11521,7 +11512,7 @@
|
|||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -11679,7 +11670,7 @@
|
|||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"unicode-length": {
|
||||
"version": "2.0.2",
|
||||
|
@ -11738,7 +11729,7 @@
|
|||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
},
|
||||
"webcrypto-core": {
|
||||
"version": "1.7.5",
|
||||
|
@ -11928,7 +11919,7 @@
|
|||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"devOptional": true
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,4 +72,4 @@
|
|||
"engines": {
|
||||
"node": ">=14.18.1 <=16.x"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import crypto from 'crypto';
|
||||
import { promisify } from 'util';
|
||||
import { deflateRaw } from 'zlib';
|
||||
import * as jose from 'jose';
|
||||
import * as dbutils from '../db/utils';
|
||||
import * as metrics from '../opentelemetry/metrics';
|
||||
|
||||
|
@ -21,7 +22,14 @@ import { JacksonError } from './error';
|
|||
import * as allowed from './oauth/allowed';
|
||||
import * as codeVerifier from './oauth/code-verifier';
|
||||
import * as redirect from './oauth/redirect';
|
||||
import { relayStatePrefix, IndexNames, OAuthErrorResponse, getErrorMessage } from './utils';
|
||||
import {
|
||||
relayStatePrefix,
|
||||
IndexNames,
|
||||
OAuthErrorResponse,
|
||||
getErrorMessage,
|
||||
loadJWSPrivateKey,
|
||||
isJWSKeyPairLoaded,
|
||||
} from './utils';
|
||||
|
||||
const deflateRawAsync = promisify(deflateRaw);
|
||||
|
||||
|
@ -57,6 +65,10 @@ function getEncodedTenantProduct(param: string): { tenant: string | null; produc
|
|||
}
|
||||
}
|
||||
|
||||
function getScopeValues(scope?: string): string[] {
|
||||
return typeof scope === 'string' ? scope.split(' ').filter((s) => s.length > 0) : [];
|
||||
}
|
||||
|
||||
export class OAuthController implements IOAuthController {
|
||||
private configStore: Storable;
|
||||
private sessionStore: Storable;
|
||||
|
@ -131,6 +143,7 @@ export class OAuthController implements IOAuthController {
|
|||
product,
|
||||
access_type,
|
||||
scope,
|
||||
nonce,
|
||||
code_challenge,
|
||||
code_challenge_method = '',
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
@ -148,6 +161,8 @@ export class OAuthController implements IOAuthController {
|
|||
}
|
||||
|
||||
let samlConfig;
|
||||
const requestedScopes = getScopeValues(scope);
|
||||
const requestedOIDCFlow = requestedScopes.includes('openid');
|
||||
|
||||
if (tenant && product) {
|
||||
const samlConfigs = await this.configStore.getByIndex({
|
||||
|
@ -188,8 +203,11 @@ export class OAuthController implements IOAuthController {
|
|||
if (!sp && access_type) {
|
||||
sp = getEncodedTenantProduct(access_type);
|
||||
}
|
||||
if (!sp && scope) {
|
||||
sp = getEncodedTenantProduct(scope);
|
||||
if (!sp && requestedScopes) {
|
||||
const encodedParams = requestedScopes.find((scope) => scope.includes('=') && scope.includes('&')); // for now assume only one encoded param i.e. for tenant/product
|
||||
if (encodedParams) {
|
||||
sp = getEncodedTenantProduct(encodedParams);
|
||||
}
|
||||
}
|
||||
if (sp && sp.tenant && sp.product) {
|
||||
requestedTenant = sp.tenant;
|
||||
|
@ -248,6 +266,20 @@ export class OAuthController implements IOAuthController {
|
|||
throw new JacksonError('Redirect URL is not allowed.', 403);
|
||||
}
|
||||
|
||||
if (
|
||||
requestedOIDCFlow &&
|
||||
(!this.opts.openid.jwtSigningKeys || !isJWSKeyPairLoaded(this.opts.openid.jwtSigningKeys))
|
||||
) {
|
||||
return {
|
||||
redirect_url: OAuthErrorResponse({
|
||||
error: 'server_error',
|
||||
error_description:
|
||||
'OAuth server not configured correctly for openid flow, check if JWT signing keys are loaded',
|
||||
redirect_uri,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
return {
|
||||
redirect_url: OAuthErrorResponse({
|
||||
|
@ -303,7 +335,7 @@ export class OAuthController implements IOAuthController {
|
|||
|
||||
const sessionId = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
const requested = { client_id, state } as Record<string, string>;
|
||||
const requested = { client_id, state } as Record<string, string | boolean | string[]>;
|
||||
if (requestedTenant) {
|
||||
requested.tenant = requestedTenant;
|
||||
}
|
||||
|
@ -313,6 +345,15 @@ export class OAuthController implements IOAuthController {
|
|||
if (idp_hint) {
|
||||
requested.idp_hint = idp_hint;
|
||||
}
|
||||
if (requestedOIDCFlow) {
|
||||
requested.oidc = true;
|
||||
if (nonce) {
|
||||
requested.nonce = nonce;
|
||||
}
|
||||
}
|
||||
if (requestedScopes) {
|
||||
requested.scope = requestedScopes;
|
||||
}
|
||||
|
||||
await this.sessionStore.put(sessionId, {
|
||||
id: samlReq.id,
|
||||
|
@ -633,6 +674,33 @@ export class OAuthController implements IOAuthController {
|
|||
...codeVal.profile,
|
||||
requested: codeVal.requested,
|
||||
};
|
||||
const requestedOIDCFlow = !!codeVal.requested.oidc;
|
||||
const requestHasNonce = !!codeVal.requested.nonce;
|
||||
if (requestedOIDCFlow) {
|
||||
const { jwtSigningKeys, jwsAlg } = this.opts.openid;
|
||||
if (!jwtSigningKeys || !isJWSKeyPairLoaded(jwtSigningKeys)) {
|
||||
throw new JacksonError('JWT signing keys are not loaded', 500);
|
||||
}
|
||||
let claims: Record<string, string> = requestHasNonce ? { nonce: codeVal.requested.nonce } : {};
|
||||
claims = {
|
||||
...claims,
|
||||
id: codeVal.profile.claims.id,
|
||||
email: codeVal.profile.claims.email,
|
||||
firstName: codeVal.profile.claims.firstName,
|
||||
lastName: codeVal.profile.claims.lastName,
|
||||
};
|
||||
const signingKey = await loadJWSPrivateKey(jwtSigningKeys.private, jwsAlg);
|
||||
const id_token = await new jose.SignJWT(claims)
|
||||
.setProtectedHeader({ alg: jwsAlg })
|
||||
.setIssuedAt()
|
||||
.setIssuer(this.opts.samlAudience || '')
|
||||
.setSubject(codeVal.profile.claims.id)
|
||||
.setAudience(tokenVal.requested.client_id)
|
||||
.setExpirationTime(`${this.opts.db.ttl}s`) // identity token only really needs to be valid long enough for it to be verified by the client application.
|
||||
.sign(signingKey);
|
||||
tokenVal.id_token = id_token;
|
||||
tokenVal.claims.sub = codeVal.profile.claims.id;
|
||||
}
|
||||
|
||||
await this.tokenStore.put(token, tokenVal);
|
||||
|
||||
|
@ -643,11 +711,17 @@ export class OAuthController implements IOAuthController {
|
|||
// ignore error
|
||||
}
|
||||
|
||||
return {
|
||||
const tokenResponse: OAuthTokenRes = {
|
||||
access_token: token,
|
||||
token_type: 'bearer',
|
||||
expires_in: this.opts.db.ttl!,
|
||||
};
|
||||
|
||||
if (requestedOIDCFlow) {
|
||||
tokenResponse.id_token = tokenVal.id_token;
|
||||
}
|
||||
|
||||
return tokenResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import { IOidcDiscoveryController, JacksonOption } from '../typings';
|
||||
import { JacksonError } from './error';
|
||||
import { exportPublicKeyJWK, generateJwkThumbprint, importJWTPublicKey, isJWSKeyPairLoaded } from './utils';
|
||||
|
||||
export class OidcDiscoveryController implements IOidcDiscoveryController {
|
||||
private opts: JacksonOption;
|
||||
|
||||
constructor({ opts }) {
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
openidConfig() {
|
||||
return {
|
||||
issuer: this.opts.samlAudience!,
|
||||
authorization_endpoint: `${this.opts.externalUrl}/api/oauth/authorize`,
|
||||
token_endpoint: `${this.opts.externalUrl}/api/oauth/token`,
|
||||
userinfo_endpoint: `${this.opts.externalUrl}/api/oauth/userinfo`,
|
||||
jwks_uri: `${this.opts.externalUrl}/oauth/jwks`,
|
||||
response_types_supported: ['code'],
|
||||
subject_types_supported: ['public'],
|
||||
id_token_signing_alg_values_supported: ['RS256'],
|
||||
grant_types_supported: ['authorization_code'],
|
||||
code_challenge_methods_supported: ['plain', 'S256'],
|
||||
};
|
||||
}
|
||||
|
||||
async jwks() {
|
||||
const { jwtSigningKeys, jwsAlg } = this.opts.openid;
|
||||
if (!jwtSigningKeys || !isJWSKeyPairLoaded(jwtSigningKeys)) {
|
||||
throw new JacksonError('JWT signing keys are not loaded', 501);
|
||||
}
|
||||
const importedPublicKey = await importJWTPublicKey(jwtSigningKeys.public, jwsAlg);
|
||||
const publicKeyJWK = await exportPublicKeyJWK(importedPublicKey);
|
||||
const jwkThumbprint = await generateJwkThumbprint(publicKeyJWK);
|
||||
const jwks = {
|
||||
keys: [{ ...publicKeyJWK, kid: jwkThumbprint, alg: jwsAlg, use: 'sig' }],
|
||||
};
|
||||
return jwks;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import type { OAuthErrorHandlerParams } from '../typings';
|
||||
import { JacksonError } from './error';
|
||||
import * as redirect from './oauth/redirect';
|
||||
import * as jose from 'jose';
|
||||
|
||||
export enum IndexNames {
|
||||
EntityID = 'entityID',
|
||||
|
@ -33,3 +34,32 @@ export function getErrorMessage(error: unknown) {
|
|||
}
|
||||
return String(error);
|
||||
}
|
||||
|
||||
export async function loadJWSPrivateKey(key: string, alg: string): Promise<jose.KeyLike> {
|
||||
const pkcs8 = Buffer.from(key, 'base64').toString('ascii');
|
||||
const privateKey = await jose.importPKCS8(pkcs8, alg);
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
export function isJWSKeyPairLoaded(jwsKeyPair: { private: string; public: string }) {
|
||||
if (!jwsKeyPair.private || !jwsKeyPair.public) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export const importJWTPublicKey = async (key: string, jwsAlg: string): Promise<jose.KeyLike> => {
|
||||
const spki = Buffer.from(key, 'base64').toString('ascii');
|
||||
const publicKey = await jose.importSPKI(spki, jwsAlg);
|
||||
return publicKey;
|
||||
};
|
||||
|
||||
export const exportPublicKeyJWK = async (key: jose.KeyLike): Promise<jose.JWK> => {
|
||||
const publicJWK = await jose.exportJWK(key);
|
||||
return publicJWK;
|
||||
};
|
||||
|
||||
export const generateJwkThumbprint = async (jwk: jose.JWK): Promise<string> => {
|
||||
const thumbprint = await jose.calculateJwkThumbprint(jwk);
|
||||
return thumbprint;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@ import { APIController } from './controller/api';
|
|||
import { OAuthController } from './controller/oauth';
|
||||
import { HealthCheckController } from './controller/health-check';
|
||||
import { LogoutController } from './controller/logout';
|
||||
import { OidcDiscoveryController } from './controller/oidc-discovery';
|
||||
|
||||
import DB from './db/db';
|
||||
import defaultDb from './db/defaultDb';
|
||||
|
@ -30,6 +31,9 @@ const defaultOpts = (opts: JacksonOption): JacksonOption => {
|
|||
newOpts.clientSecretVerifier = newOpts.clientSecretVerifier || 'dummy';
|
||||
newOpts.db.pageLimit = newOpts.db.pageLimit || 50;
|
||||
|
||||
newOpts.openid = newOpts.openid || {};
|
||||
newOpts.openid.jwsAlg = newOpts.openid.jwsAlg || 'RS256';
|
||||
|
||||
return newOpts;
|
||||
};
|
||||
|
||||
|
@ -41,6 +45,7 @@ export const controllers = async (
|
|||
adminController: AdminController;
|
||||
logoutController: LogoutController;
|
||||
healthCheckController: HealthCheckController;
|
||||
oidcDiscoveryController: OidcDiscoveryController;
|
||||
}> => {
|
||||
opts = defaultOpts(opts);
|
||||
|
||||
|
@ -69,7 +74,7 @@ export const controllers = async (
|
|||
sessionStore,
|
||||
opts,
|
||||
});
|
||||
|
||||
const oidcDiscoveryController = new OidcDiscoveryController({ opts });
|
||||
// write pre-loaded config if present
|
||||
if (opts.preLoadedConfig && opts.preLoadedConfig.length > 0) {
|
||||
const configs = await readConfig(opts.preLoadedConfig);
|
||||
|
@ -91,6 +96,7 @@ export const controllers = async (
|
|||
adminController,
|
||||
logoutController,
|
||||
healthCheckController,
|
||||
oidcDiscoveryController,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { type JWK } from 'jose';
|
||||
|
||||
export type IdPConfig = {
|
||||
defaultRedirectUrl: string;
|
||||
redirectUrl: string[] | string;
|
||||
|
@ -37,6 +39,26 @@ export interface IHealthCheckController {
|
|||
}>;
|
||||
init(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IOidcDiscoveryController {
|
||||
openidConfig(): {
|
||||
issuer: string;
|
||||
authorization_endpoint: string;
|
||||
token_endpoint: string;
|
||||
userinfo_endpoint: string;
|
||||
jwks_uri: string;
|
||||
response_types_supported: Array<string>;
|
||||
subject_types_supported: Array<string>;
|
||||
id_token_signing_alg_values_supported: Array<string>;
|
||||
grant_types_supported: Array<string>;
|
||||
code_challenge_methods_supported: Array<string>;
|
||||
};
|
||||
|
||||
jwks(): Promise<{
|
||||
keys: JWK[];
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface OAuthReqBody {
|
||||
response_type: 'code';
|
||||
client_id: string;
|
||||
|
@ -46,6 +68,7 @@ export interface OAuthReqBody {
|
|||
product?: string;
|
||||
access_type?: string;
|
||||
scope?: string;
|
||||
nonce?: string;
|
||||
code_challenge: string;
|
||||
code_challenge_method: 'plain' | 'S256' | '';
|
||||
provider: 'saml';
|
||||
|
@ -68,12 +91,14 @@ export interface OAuthTokenReq {
|
|||
|
||||
export interface OAuthTokenRes {
|
||||
access_token: string;
|
||||
id_token?: string;
|
||||
token_type: 'bearer';
|
||||
expires_in: number;
|
||||
}
|
||||
|
||||
export interface Profile {
|
||||
id: string;
|
||||
sub?: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
|
@ -133,6 +158,13 @@ export interface JacksonOption {
|
|||
db: DatabaseOption;
|
||||
clientSecretVerifier?: string;
|
||||
idpDiscoveryPath?: string;
|
||||
openid: {
|
||||
jwsAlg: string;
|
||||
jwtSigningKeys?: {
|
||||
private: string;
|
||||
public: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface SLORequestParams {
|
||||
|
|
|
@ -18,6 +18,10 @@ const OPTIONS = <JacksonOption>{
|
|||
db: {
|
||||
engine: 'mem',
|
||||
},
|
||||
openid: {
|
||||
jwtSigningKeys: { private: 'PRIVATE_KEY', public: 'PUBLIC_KEY' },
|
||||
jwsAlg: 'RS256',
|
||||
},
|
||||
};
|
||||
|
||||
tap.before(async () => {
|
||||
|
|
|
@ -23,6 +23,13 @@ export const authz_request_normal_with_scope: Partial<OAuthReqBody> = {
|
|||
client_id: 'dummy',
|
||||
};
|
||||
|
||||
export const authz_request_normal_oidc_flow: Partial<OAuthReqBody> = {
|
||||
redirect_uri: boxyhq.defaultRedirectUrl,
|
||||
state: 'state-123',
|
||||
scope: `openid`,
|
||||
client_id: `tenant=${boxyhq.tenant}&product=${boxyhq.product}`,
|
||||
};
|
||||
|
||||
export const redirect_uri_not_set: Partial<OAuthReqBody> = {
|
||||
redirect_uri: undefined,
|
||||
state: 'state',
|
||||
|
|
|
@ -20,6 +20,10 @@ const options = <JacksonOption>{
|
|||
db: {
|
||||
engine: 'mem',
|
||||
},
|
||||
openid: {
|
||||
jwtSigningKeys: { private: 'PRIVATE_KEY', public: 'PUBLIC_KEY' },
|
||||
jwsAlg: 'RS256',
|
||||
},
|
||||
};
|
||||
|
||||
// TODO: Move this to a helper file
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import crypto from 'crypto';
|
||||
import { promises as fs } from 'fs';
|
||||
import * as utils from '../src/controller/utils';
|
||||
import path from 'path';
|
||||
import {
|
||||
IOAuthController,
|
||||
|
@ -14,8 +15,10 @@ import tap from 'tap';
|
|||
import { JacksonError } from '../src/controller/error';
|
||||
import readConfig from '../src/read-config';
|
||||
import saml from '@boxyhq/saml20';
|
||||
import * as jose from 'jose';
|
||||
import {
|
||||
authz_request_normal,
|
||||
authz_request_normal_oidc_flow,
|
||||
authz_request_normal_with_access_type,
|
||||
authz_request_normal_with_scope,
|
||||
bodyWithDummyCredentials,
|
||||
|
@ -34,6 +37,7 @@ import {
|
|||
|
||||
let apiController: IAPIController;
|
||||
let oauthController: IOAuthController;
|
||||
let keyPair: jose.GenerateKeyPairResult;
|
||||
|
||||
const code = '1234567890';
|
||||
const token = '24c1550190dd6a5a9bd6fe2a8ff69d593121c7b9';
|
||||
|
@ -48,6 +52,10 @@ const options = <JacksonOption>{
|
|||
engine: 'mem',
|
||||
},
|
||||
clientSecretVerifier: 'TOP-SECRET',
|
||||
openid: {
|
||||
jwtSigningKeys: { private: 'PRIVATE_KEY', public: 'PUBLIC_KEY' },
|
||||
jwsAlg: 'RS256',
|
||||
},
|
||||
};
|
||||
|
||||
const configRecords: Array<any> = [];
|
||||
|
@ -61,6 +69,8 @@ const addMetadata = async (metadataPath) => {
|
|||
};
|
||||
|
||||
tap.before(async () => {
|
||||
keyPair = await jose.generateKeyPair('RS256', { modulusLength: 3072 });
|
||||
|
||||
const controller = await (await import('../src/index')).default(options);
|
||||
|
||||
apiController = controller.apiController;
|
||||
|
@ -388,76 +398,155 @@ tap.test('token()', (t) => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
t.test('Should return the `access_token`/`userprofile` for a valid request', async (t) => {
|
||||
t.test('encoded client_id', async (t) => {
|
||||
const body = token_req_encoded_client_id;
|
||||
const stubRandomBytes = sinon
|
||||
.stub(crypto, 'randomBytes')
|
||||
.onFirstCall()
|
||||
t.test(
|
||||
'Should return the tokens [id_token (if openid requested), access_token] and userprofile for a valid request',
|
||||
async (t) => {
|
||||
t.test('encoded client_id', async (t) => {
|
||||
const body = token_req_encoded_client_id;
|
||||
const stubRandomBytes = sinon
|
||||
.stub(crypto, 'randomBytes')
|
||||
.onFirstCall()
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
.returns(token);
|
||||
|
||||
const response = await oauthController.token(<OAuthTokenReq>body);
|
||||
|
||||
t.ok(stubRandomBytes.calledOnce, 'randomBytes called once');
|
||||
t.ok('access_token' in response, 'includes access_token');
|
||||
t.ok('token_type' in response, 'includes token_type');
|
||||
t.ok('expires_in' in response, 'includes expires_in');
|
||||
t.notOk('id_token' in response, 'does not include id_token');
|
||||
t.match(response.access_token, token);
|
||||
t.match(response.token_type, 'bearer');
|
||||
t.match(response.expires_in, 300);
|
||||
|
||||
stubRandomBytes.restore();
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test('unencoded client_id', async (t) => {
|
||||
// have to call authorize, because previous happy path deletes the code.
|
||||
const authBody = authz_request_normal;
|
||||
|
||||
const { redirect_url } = await oauthController.authorize(<OAuthReqBody>authBody);
|
||||
|
||||
const relayState = new URLSearchParams(new URL(redirect_url!).search).get('RelayState');
|
||||
|
||||
const rawResponse = await fs.readFile(path.join(__dirname, '/data/saml_response'), 'utf8');
|
||||
const responseBody = {
|
||||
SAMLResponse: rawResponse,
|
||||
RelayState: relayState,
|
||||
};
|
||||
|
||||
const stubValidate = sinon
|
||||
.stub(saml, 'validate')
|
||||
.resolves({ audience: '', claims: {}, issuer: '', sessionIndex: '' });
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
.returns(token);
|
||||
const stubRandomBytes = sinon.stub(crypto, 'randomBytes').returns(code).onSecondCall().returns(token);
|
||||
|
||||
const response = await oauthController.token(<OAuthTokenReq>body);
|
||||
await oauthController.samlResponse(<SAMLResponsePayload>responseBody);
|
||||
|
||||
t.ok(stubRandomBytes.calledOnce, 'randomBytes called once');
|
||||
t.ok('access_token' in response, 'includes access_token');
|
||||
t.ok('token_type' in response, 'includes token_type');
|
||||
t.ok('expires_in' in response, 'includes expires_in');
|
||||
t.match(response.access_token, token);
|
||||
t.match(response.token_type, 'bearer');
|
||||
t.match(response.expires_in, 300);
|
||||
const body = token_req_unencoded_client_id_gen(configRecords);
|
||||
|
||||
stubRandomBytes.restore();
|
||||
const tokenRes = await oauthController.token(<OAuthTokenReq>body);
|
||||
|
||||
t.end();
|
||||
});
|
||||
t.ok('access_token' in tokenRes, 'includes access_token');
|
||||
t.ok('token_type' in tokenRes, 'includes token_type');
|
||||
t.ok('expires_in' in tokenRes, 'includes expires_in');
|
||||
t.notOk('id_token' in tokenRes, 'does not include id_token');
|
||||
t.match(tokenRes.access_token, token);
|
||||
t.match(tokenRes.token_type, 'bearer');
|
||||
t.match(tokenRes.expires_in, 300);
|
||||
|
||||
t.test('unencoded client_id', async (t) => {
|
||||
// have to call authorize, because previous happy path deletes the code.
|
||||
const authBody = authz_request_normal;
|
||||
const profile = await oauthController.userInfo(tokenRes.access_token);
|
||||
|
||||
const { redirect_url } = await oauthController.authorize(<OAuthReqBody>authBody);
|
||||
t.notOk('sub' in profile, 'does not include sub');
|
||||
t.equal(profile.requested.client_id, authz_request_normal.client_id);
|
||||
t.equal(profile.requested.state, authz_request_normal.state);
|
||||
t.equal(profile.requested.tenant, new URLSearchParams(authz_request_normal.client_id).get('tenant'));
|
||||
t.equal(
|
||||
profile.requested.product,
|
||||
new URLSearchParams(authz_request_normal.client_id).get('product')
|
||||
);
|
||||
|
||||
const relayState = new URLSearchParams(new URL(redirect_url!).search).get('RelayState');
|
||||
stubRandomBytes.restore();
|
||||
stubValidate.restore();
|
||||
|
||||
const rawResponse = await fs.readFile(path.join(__dirname, '/data/saml_response'), 'utf8');
|
||||
const responseBody = {
|
||||
SAMLResponse: rawResponse,
|
||||
RelayState: relayState,
|
||||
};
|
||||
t.end();
|
||||
});
|
||||
|
||||
sinon.stub(saml, 'validate').resolves({ audience: '', claims: {}, issuer: '', sessionIndex: '' });
|
||||
t.test('openid flow', async (t) => {
|
||||
const authBody = authz_request_normal_oidc_flow;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const stubRandomBytes = sinon.stub(crypto, 'randomBytes').returns(code).onSecondCall().returns(token);
|
||||
const { redirect_url } = await oauthController.authorize(<OAuthReqBody>authBody);
|
||||
|
||||
await oauthController.samlResponse(<SAMLResponsePayload>responseBody);
|
||||
const relayState = new URLSearchParams(new URL(redirect_url!).search).get('RelayState');
|
||||
|
||||
const body = token_req_unencoded_client_id_gen(configRecords);
|
||||
const rawResponse = await fs.readFile(path.join(__dirname, '/data/saml_response'), 'utf8');
|
||||
const responseBody = {
|
||||
SAMLResponse: rawResponse,
|
||||
RelayState: relayState,
|
||||
};
|
||||
|
||||
const tokenRes = await oauthController.token(<OAuthTokenReq>body);
|
||||
const stubLoadJWSPrivateKey = sinon.stub(utils, 'loadJWSPrivateKey').resolves(keyPair.privateKey);
|
||||
const stubValidate = sinon.stub(saml, 'validate').resolves({
|
||||
audience: '',
|
||||
claims: { id: 'id', firstName: 'john', lastName: 'doe', email: 'johndoe@example.com' },
|
||||
issuer: '',
|
||||
sessionIndex: '',
|
||||
});
|
||||
|
||||
t.ok('access_token' in tokenRes, 'includes access_token');
|
||||
t.ok('token_type' in tokenRes, 'includes token_type');
|
||||
t.ok('expires_in' in tokenRes, 'includes expires_in');
|
||||
t.match(tokenRes.access_token, token);
|
||||
t.match(tokenRes.token_type, 'bearer');
|
||||
t.match(tokenRes.expires_in, 300);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const stubRandomBytes = sinon.stub(crypto, 'randomBytes').returns(code).onSecondCall().returns(token);
|
||||
|
||||
const profile = await oauthController.userInfo(tokenRes.access_token);
|
||||
await oauthController.samlResponse(<SAMLResponsePayload>responseBody);
|
||||
|
||||
t.equal(profile.requested.client_id, authz_request_normal.client_id);
|
||||
t.equal(profile.requested.state, authz_request_normal.state);
|
||||
t.equal(profile.requested.tenant, new URLSearchParams(authz_request_normal.client_id).get('tenant'));
|
||||
t.equal(profile.requested.product, new URLSearchParams(authz_request_normal.client_id).get('product'));
|
||||
const body = token_req_encoded_client_id;
|
||||
|
||||
stubRandomBytes.restore();
|
||||
const tokenRes = await oauthController.token(<OAuthTokenReq>body);
|
||||
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
t.ok('access_token' in tokenRes, 'includes access_token');
|
||||
t.ok('token_type' in tokenRes, 'includes token_type');
|
||||
t.ok('expires_in' in tokenRes, 'includes expires_in');
|
||||
t.ok('id_token' in tokenRes, 'includes id_token');
|
||||
if (tokenRes.id_token) {
|
||||
const claims = jose.decodeJwt(tokenRes.id_token);
|
||||
const { protectedHeader } = await jose.jwtVerify(tokenRes.id_token, keyPair.publicKey);
|
||||
t.match(protectedHeader.alg, options.openid.jwsAlg);
|
||||
t.match(claims.aud, authz_request_normal_oidc_flow.client_id);
|
||||
t.match(claims.iss, options.samlAudience);
|
||||
}
|
||||
t.match(tokenRes.access_token, token);
|
||||
t.match(tokenRes.token_type, 'bearer');
|
||||
t.match(tokenRes.expires_in, 300);
|
||||
|
||||
const profile = await oauthController.userInfo(tokenRes.access_token);
|
||||
|
||||
t.equal(profile.sub, 'id');
|
||||
t.equal(profile.requested.client_id, authz_request_normal_oidc_flow.client_id);
|
||||
t.equal(profile.requested.state, authz_request_normal_oidc_flow.state);
|
||||
t.equal(
|
||||
profile.requested.tenant,
|
||||
new URLSearchParams(authz_request_normal_oidc_flow.client_id).get('tenant')
|
||||
);
|
||||
t.equal(
|
||||
profile.requested.product,
|
||||
new URLSearchParams(authz_request_normal_oidc_flow.client_id).get('product')
|
||||
);
|
||||
|
||||
stubRandomBytes.restore();
|
||||
stubValidate.restore();
|
||||
stubLoadJWSPrivateKey.restore();
|
||||
|
||||
t.end();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"@opentelemetry/sdk-metrics-base": "0.27.0",
|
||||
"@supabase/ui": "0.36.5",
|
||||
"cors": "2.8.5",
|
||||
"jose": "4.8.1",
|
||||
"micromatch": "4.0.5",
|
||||
"next": "12.2.2",
|
||||
"next-auth": "4.10.0",
|
||||
|
@ -1353,119 +1354,119 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-cms": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.1.9.tgz",
|
||||
"integrity": "sha512-Rlcd1hL1BK/IgWiR3wKTxpfei3OLhW0GiAPdqR6aEYCXqV9UCTFsR7dXI8eyh1wkWXx2VJthdbh+ky+w5adh9w==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.2.0.tgz",
|
||||
"integrity": "sha512-8lJe4OC83NUA/rP4/J8Zjd3Lsxbx8lkBcVWDkUJNFAsfWqDdhlwmNyhg8h0x0jr8NJ6QOCTwJ18VIs58X54/ow==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"@peculiar/asn1-x509-attr": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"@peculiar/asn1-x509-attr": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-csr": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.1.9.tgz",
|
||||
"integrity": "sha512-ncmR3AaWrm+DC1hsouxfsgDb6ZfhWfwIoqS+esxDlk0honmMfdffrDtXoxxJIQ8Njrk7AKVPMSPyxLeCyPC0tw==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.2.0.tgz",
|
||||
"integrity": "sha512-kj/pjv+Mn0culffDaxjaInZPvoAcJUuJvk3JUeGNoe5N9pIK6Bcrtt7dfA1u+NgI7K1y1TBDAzTQoYxfxmsRbA==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-ecc": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.1.9.tgz",
|
||||
"integrity": "sha512-1+ckVKJ8Bx+WatKcH5PtafWb1JxAZM+u9D6wFNYt4AKzWAwx2dmzkBMdqQmCXRk4fOvaJTr9CAfsJu0g7m6zgQ==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.2.0.tgz",
|
||||
"integrity": "sha512-/fMm9loLLLQcbZSGM0B4eNedgmagJPvwqklVRtG8OBTLidKZN3U/dmiemiKx8hf3w5IYwu52OxMSch88BHpuGQ==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-pfx": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.1.9.tgz",
|
||||
"integrity": "sha512-JwjYcPFbteDV9+0Pqz6um2oksh2RrngreXxTLgLZ/ENEU9xfmn4IEDAVN67e3V8Ei+ujBjk1UsjrEnCwRArMgg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.2.0.tgz",
|
||||
"integrity": "sha512-FrGzBQpVr2IwY6iYcmN5cp8IRGDhDsM+EzBRUs6fodvAGm8cchGid9WZszqRpBG8YCOBZXZ38bR0r6gdmH9q7g==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-cms": "^2.1.9",
|
||||
"@peculiar/asn1-pkcs8": "^2.1.9",
|
||||
"@peculiar/asn1-rsa": "^2.1.9",
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-cms": "^2.2.0",
|
||||
"@peculiar/asn1-pkcs8": "^2.2.0",
|
||||
"@peculiar/asn1-rsa": "^2.2.0",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-pkcs8": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.1.9.tgz",
|
||||
"integrity": "sha512-KtpVZ/ysOcPvIgHwrqm1BLDGCwnPjxiWlqYfvldZvK0SKXx7ogWWMoh/3M8nEdmu/dT1QdOizt1ErLoZ7xVxOw==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.2.0.tgz",
|
||||
"integrity": "sha512-tbVTUYevN1PftXz8qKvvddroGC1nHZtvsVCTRMGwMV9x5MNs6YWqxAkM5jAV75PVfwQvWSbrvQmQlo2epBYjtg==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-pkcs9": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.1.9.tgz",
|
||||
"integrity": "sha512-QBITHLAdJgEAKDYEaKbmXVdhwi8aIS9JTThXr+5BgPO8vJE3/OvogLnLZbgO3eOT5IarImrHiqiGaPLVVQDbTQ==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.2.0.tgz",
|
||||
"integrity": "sha512-gJPS7/64OjQSFPFBys2klRb32bKBCraPOmrfzuTM3FvUh+yroomG8RBtnDR4Xn8QxzOIwvMape+FqPsNQ2ldPg==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-cms": "^2.1.9",
|
||||
"@peculiar/asn1-pfx": "^2.1.9",
|
||||
"@peculiar/asn1-pkcs8": "^2.1.9",
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"@peculiar/asn1-x509-attr": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-cms": "^2.2.0",
|
||||
"@peculiar/asn1-pfx": "^2.2.0",
|
||||
"@peculiar/asn1-pkcs8": "^2.2.0",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"@peculiar/asn1-x509-attr": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-rsa": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.1.9.tgz",
|
||||
"integrity": "sha512-O7TQnJp7OFZAI9a2tOHHlDbFub9v1VzJr3aKelpBBKDebwgTgNDgXVDapXh/4SDMShWGsSu3HKbYkZORnlDr1A==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.2.0.tgz",
|
||||
"integrity": "sha512-t6CIvXYpjEzos5iXwg6QSFdKce3c3Iw9M658qARdIpbWDvosNHeVn7e97IYdmJU0sDS4ech1aS2GLuKFFKmcew==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-schema": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.1.9.tgz",
|
||||
"integrity": "sha512-Ipio+pXGpL/Vb0qB4GnOgFMgc1RAhKHOVy24rQYLvmOAVp9z/aFb+VdIiQH09NjgvGVmaWOUqSWd9vRHk3xbrg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.2.0.tgz",
|
||||
"integrity": "sha512-1ENEJNY7Lwlua/1wvzpYP194WtjQBfFxvde2FlzfBFh/ln6wvChrtxlORhbKEnYswzn6fOC4c7HdC5izLPMTJg==",
|
||||
"dependencies": {
|
||||
"asn1js": "^3.0.4",
|
||||
"asn1js": "^3.0.5",
|
||||
"pvtsutils": "^1.3.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-x509": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.1.9.tgz",
|
||||
"integrity": "sha512-mqU8ZlWaBfDSG/iafCYKOa9N7scXiaXfHNgOyqG0GIPZGGjNeeBjgLRrlup6L8/Ipvlun5VIm7vNJdR8/XIqtg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.2.0.tgz",
|
||||
"integrity": "sha512-YORcf7XFy9TKWGnPmK2MNQqAJgIvGNaCrK8vUF/ZRO+BnahZJOgX2HuEiEmoAozZpSlyJnI6CGJOABOjPiDucA==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"ipaddr.js": "^2.0.1",
|
||||
"pvtsutils": "^1.3.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@peculiar/asn1-x509-attr": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.1.9.tgz",
|
||||
"integrity": "sha512-tJ7i0ctqREk6XtlRGto81hC3hvp1Dj790N4fnhJQzHC7ZYC+zZSoO/FZr+UxJMIphDDV2BQvCbObJ1xmOEDijA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.2.0.tgz",
|
||||
"integrity": "sha512-SWX6pYWTxNy2bBcvOJriBhC7CaqvD9JQ+XUWrmiVrbw8hmzJS3Jcv6JMRfSuitjmmEE+W2wvY0s8zmghDrQK+A==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
|
@ -1496,17 +1497,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@peculiar/x509": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.7.2.tgz",
|
||||
"integrity": "sha512-yMECIsGaRBWV2GFLVxTFD6L9zdRcaFWOQO5MKPHACE4vz/7GJzRfW3trehL5KnvSnQHPXAmt8zPGLctjn488/w==",
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.7.3.tgz",
|
||||
"integrity": "sha512-TKOAH/o66qWYlODqwszPPKBYPKw9p4caaGfgPd1319IKO1PGPNQ4WK1MzCDUuWXyXDD2CAbP0mxmq9MuHwersA==",
|
||||
"dependencies": {
|
||||
"@peculiar/asn1-cms": "^2.1.9",
|
||||
"@peculiar/asn1-csr": "^2.1.9",
|
||||
"@peculiar/asn1-ecc": "^2.1.9",
|
||||
"@peculiar/asn1-pkcs9": "^2.1.9",
|
||||
"@peculiar/asn1-rsa": "^2.1.9",
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"@peculiar/asn1-cms": "^2.2.0",
|
||||
"@peculiar/asn1-csr": "^2.2.0",
|
||||
"@peculiar/asn1-ecc": "^2.2.0",
|
||||
"@peculiar/asn1-pkcs9": "^2.2.0",
|
||||
"@peculiar/asn1-rsa": "^2.2.0",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"pvtsutils": "^1.3.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"tslib": "^2.4.0",
|
||||
|
@ -1933,23 +1934,6 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz",
|
||||
"integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"@typescript-eslint/visitor-keys": "5.30.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "5.30.6",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.6.tgz",
|
||||
|
@ -1976,61 +1960,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz",
|
||||
"integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz",
|
||||
"integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"@typescript-eslint/visitor-keys": "5.30.5",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.7",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "5.30.6",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.6.tgz",
|
||||
|
@ -2144,23 +2073,6 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz",
|
||||
"integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
|
||||
|
@ -5188,9 +5100,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.6.0.tgz",
|
||||
"integrity": "sha512-0hNAkhMBNi4soKSAX4zYOFV+aqJlEz/4j4fregvasJzEVtjDChvWqRjPvHwLqr5hx28Ayr6bsOs1Kuj87V0O8w==",
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.8.1.tgz",
|
||||
"integrity": "sha512-+/hpTbRcCw9YC0TOfN1W47pej4a9lRmltdOVdRLz5FP5UvUq3CenhXjQK7u/8NdMIIShMXYAh9VLPhc7TjhvFw==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
|
@ -10995,7 +10907,7 @@
|
|||
"@opentelemetry/api": "1.0.4",
|
||||
"@opentelemetry/api-metrics": "0.27.0",
|
||||
"@peculiar/webcrypto": "1.4.0",
|
||||
"@peculiar/x509": "1.7.2",
|
||||
"@peculiar/x509": "1.7.3",
|
||||
"mongodb": "4.8.0",
|
||||
"mysql2": "2.3.3",
|
||||
"pg": "8.7.3",
|
||||
|
@ -11011,7 +10923,7 @@
|
|||
"@types/sinon": "10.0.12",
|
||||
"@types/tap": "15.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.6",
|
||||
"@typescript-eslint/parser": "5.30.5",
|
||||
"@typescript-eslint/parser": "5.30.6",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint": "8.20.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
|
@ -11031,33 +10943,6 @@
|
|||
"resolved": "npm/@boxyhq/saml20@1.0.0-beta-1",
|
||||
"link": true
|
||||
},
|
||||
"npm/node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.5.tgz",
|
||||
"integrity": "sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.30.5",
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"@typescript-eslint/typescript-estree": "5.30.5",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"npm/node_modules/bson": {
|
||||
"version": "4.6.5",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-4.6.5.tgz",
|
||||
|
@ -11551,12 +11436,12 @@
|
|||
"@opentelemetry/api": "1.0.4",
|
||||
"@opentelemetry/api-metrics": "0.27.0",
|
||||
"@peculiar/webcrypto": "1.4.0",
|
||||
"@peculiar/x509": "1.7.2",
|
||||
"@peculiar/x509": "1.7.3",
|
||||
"@types/node": "18.0.6",
|
||||
"@types/sinon": "10.0.12",
|
||||
"@types/tap": "15.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.6",
|
||||
"@typescript-eslint/parser": "5.30.5",
|
||||
"@typescript-eslint/parser": "5.30.6",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint": "8.20.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
|
@ -11580,18 +11465,6 @@
|
|||
"@boxyhq/saml20": {
|
||||
"version": "file:npm/@boxyhq/saml20@1.0.0-beta-1"
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.5.tgz",
|
||||
"integrity": "sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "5.30.5",
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"@typescript-eslint/typescript-estree": "5.30.5",
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "4.6.5",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-4.6.5.tgz",
|
||||
|
@ -12069,119 +11942,119 @@
|
|||
"integrity": "sha512-mMyQ9vjpuFqePkfe5bZVIf/H3Dmk6wA8Kjxff9RcO4kqzJo+Ek9pGKwZHpeMr7Eku0QhLXMCd7fNCSnEnRMubg=="
|
||||
},
|
||||
"@peculiar/asn1-cms": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.1.9.tgz",
|
||||
"integrity": "sha512-Rlcd1hL1BK/IgWiR3wKTxpfei3OLhW0GiAPdqR6aEYCXqV9UCTFsR7dXI8eyh1wkWXx2VJthdbh+ky+w5adh9w==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.2.0.tgz",
|
||||
"integrity": "sha512-8lJe4OC83NUA/rP4/J8Zjd3Lsxbx8lkBcVWDkUJNFAsfWqDdhlwmNyhg8h0x0jr8NJ6QOCTwJ18VIs58X54/ow==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"@peculiar/asn1-x509-attr": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"@peculiar/asn1-x509-attr": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-csr": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.1.9.tgz",
|
||||
"integrity": "sha512-ncmR3AaWrm+DC1hsouxfsgDb6ZfhWfwIoqS+esxDlk0honmMfdffrDtXoxxJIQ8Njrk7AKVPMSPyxLeCyPC0tw==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.2.0.tgz",
|
||||
"integrity": "sha512-kj/pjv+Mn0culffDaxjaInZPvoAcJUuJvk3JUeGNoe5N9pIK6Bcrtt7dfA1u+NgI7K1y1TBDAzTQoYxfxmsRbA==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-ecc": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.1.9.tgz",
|
||||
"integrity": "sha512-1+ckVKJ8Bx+WatKcH5PtafWb1JxAZM+u9D6wFNYt4AKzWAwx2dmzkBMdqQmCXRk4fOvaJTr9CAfsJu0g7m6zgQ==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.2.0.tgz",
|
||||
"integrity": "sha512-/fMm9loLLLQcbZSGM0B4eNedgmagJPvwqklVRtG8OBTLidKZN3U/dmiemiKx8hf3w5IYwu52OxMSch88BHpuGQ==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-pfx": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.1.9.tgz",
|
||||
"integrity": "sha512-JwjYcPFbteDV9+0Pqz6um2oksh2RrngreXxTLgLZ/ENEU9xfmn4IEDAVN67e3V8Ei+ujBjk1UsjrEnCwRArMgg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.2.0.tgz",
|
||||
"integrity": "sha512-FrGzBQpVr2IwY6iYcmN5cp8IRGDhDsM+EzBRUs6fodvAGm8cchGid9WZszqRpBG8YCOBZXZ38bR0r6gdmH9q7g==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-cms": "^2.1.9",
|
||||
"@peculiar/asn1-pkcs8": "^2.1.9",
|
||||
"@peculiar/asn1-rsa": "^2.1.9",
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-cms": "^2.2.0",
|
||||
"@peculiar/asn1-pkcs8": "^2.2.0",
|
||||
"@peculiar/asn1-rsa": "^2.2.0",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-pkcs8": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.1.9.tgz",
|
||||
"integrity": "sha512-KtpVZ/ysOcPvIgHwrqm1BLDGCwnPjxiWlqYfvldZvK0SKXx7ogWWMoh/3M8nEdmu/dT1QdOizt1ErLoZ7xVxOw==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.2.0.tgz",
|
||||
"integrity": "sha512-tbVTUYevN1PftXz8qKvvddroGC1nHZtvsVCTRMGwMV9x5MNs6YWqxAkM5jAV75PVfwQvWSbrvQmQlo2epBYjtg==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-pkcs9": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.1.9.tgz",
|
||||
"integrity": "sha512-QBITHLAdJgEAKDYEaKbmXVdhwi8aIS9JTThXr+5BgPO8vJE3/OvogLnLZbgO3eOT5IarImrHiqiGaPLVVQDbTQ==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.2.0.tgz",
|
||||
"integrity": "sha512-gJPS7/64OjQSFPFBys2klRb32bKBCraPOmrfzuTM3FvUh+yroomG8RBtnDR4Xn8QxzOIwvMape+FqPsNQ2ldPg==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-cms": "^2.1.9",
|
||||
"@peculiar/asn1-pfx": "^2.1.9",
|
||||
"@peculiar/asn1-pkcs8": "^2.1.9",
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"@peculiar/asn1-x509-attr": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-cms": "^2.2.0",
|
||||
"@peculiar/asn1-pfx": "^2.2.0",
|
||||
"@peculiar/asn1-pkcs8": "^2.2.0",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"@peculiar/asn1-x509-attr": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-rsa": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.1.9.tgz",
|
||||
"integrity": "sha512-O7TQnJp7OFZAI9a2tOHHlDbFub9v1VzJr3aKelpBBKDebwgTgNDgXVDapXh/4SDMShWGsSu3HKbYkZORnlDr1A==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.2.0.tgz",
|
||||
"integrity": "sha512-t6CIvXYpjEzos5iXwg6QSFdKce3c3Iw9M658qARdIpbWDvosNHeVn7e97IYdmJU0sDS4ech1aS2GLuKFFKmcew==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-schema": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.1.9.tgz",
|
||||
"integrity": "sha512-Ipio+pXGpL/Vb0qB4GnOgFMgc1RAhKHOVy24rQYLvmOAVp9z/aFb+VdIiQH09NjgvGVmaWOUqSWd9vRHk3xbrg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.2.0.tgz",
|
||||
"integrity": "sha512-1ENEJNY7Lwlua/1wvzpYP194WtjQBfFxvde2FlzfBFh/ln6wvChrtxlORhbKEnYswzn6fOC4c7HdC5izLPMTJg==",
|
||||
"requires": {
|
||||
"asn1js": "^3.0.4",
|
||||
"asn1js": "^3.0.5",
|
||||
"pvtsutils": "^1.3.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-x509": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.1.9.tgz",
|
||||
"integrity": "sha512-mqU8ZlWaBfDSG/iafCYKOa9N7scXiaXfHNgOyqG0GIPZGGjNeeBjgLRrlup6L8/Ipvlun5VIm7vNJdR8/XIqtg==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.2.0.tgz",
|
||||
"integrity": "sha512-YORcf7XFy9TKWGnPmK2MNQqAJgIvGNaCrK8vUF/ZRO+BnahZJOgX2HuEiEmoAozZpSlyJnI6CGJOABOjPiDucA==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"ipaddr.js": "^2.0.1",
|
||||
"pvtsutils": "^1.3.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@peculiar/asn1-x509-attr": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.1.9.tgz",
|
||||
"integrity": "sha512-tJ7i0ctqREk6XtlRGto81hC3hvp1Dj790N4fnhJQzHC7ZYC+zZSoO/FZr+UxJMIphDDV2BQvCbObJ1xmOEDijA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.2.0.tgz",
|
||||
"integrity": "sha512-SWX6pYWTxNy2bBcvOJriBhC7CaqvD9JQ+XUWrmiVrbw8hmzJS3Jcv6JMRfSuitjmmEE+W2wvY0s8zmghDrQK+A==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"asn1js": "^3.0.4",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"asn1js": "^3.0.5",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
|
@ -12206,17 +12079,17 @@
|
|||
}
|
||||
},
|
||||
"@peculiar/x509": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.7.2.tgz",
|
||||
"integrity": "sha512-yMECIsGaRBWV2GFLVxTFD6L9zdRcaFWOQO5MKPHACE4vz/7GJzRfW3trehL5KnvSnQHPXAmt8zPGLctjn488/w==",
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.7.3.tgz",
|
||||
"integrity": "sha512-TKOAH/o66qWYlODqwszPPKBYPKw9p4caaGfgPd1319IKO1PGPNQ4WK1MzCDUuWXyXDD2CAbP0mxmq9MuHwersA==",
|
||||
"requires": {
|
||||
"@peculiar/asn1-cms": "^2.1.9",
|
||||
"@peculiar/asn1-csr": "^2.1.9",
|
||||
"@peculiar/asn1-ecc": "^2.1.9",
|
||||
"@peculiar/asn1-pkcs9": "^2.1.9",
|
||||
"@peculiar/asn1-rsa": "^2.1.9",
|
||||
"@peculiar/asn1-schema": "^2.1.9",
|
||||
"@peculiar/asn1-x509": "^2.1.9",
|
||||
"@peculiar/asn1-cms": "^2.2.0",
|
||||
"@peculiar/asn1-csr": "^2.2.0",
|
||||
"@peculiar/asn1-ecc": "^2.2.0",
|
||||
"@peculiar/asn1-pkcs9": "^2.2.0",
|
||||
"@peculiar/asn1-rsa": "^2.2.0",
|
||||
"@peculiar/asn1-schema": "^2.2.0",
|
||||
"@peculiar/asn1-x509": "^2.2.0",
|
||||
"pvtsutils": "^1.3.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"tslib": "^2.4.0",
|
||||
|
@ -12538,16 +12411,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz",
|
||||
"integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"@typescript-eslint/visitor-keys": "5.30.5"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/type-utils": {
|
||||
"version": "5.30.6",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.6.tgz",
|
||||
|
@ -12559,38 +12422,6 @@
|
|||
"tsutils": "^3.21.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz",
|
||||
"integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz",
|
||||
"integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"@typescript-eslint/visitor-keys": "5.30.5",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"semver": "^7.3.7",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "7.3.7",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/utils": {
|
||||
"version": "5.30.6",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.6.tgz",
|
||||
|
@ -12657,16 +12488,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "5.30.5",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz",
|
||||
"integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "5.30.5",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
|
||||
|
@ -14870,9 +14691,9 @@
|
|||
}
|
||||
},
|
||||
"jose": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.6.0.tgz",
|
||||
"integrity": "sha512-0hNAkhMBNi4soKSAX4zYOFV+aqJlEz/4j4fregvasJzEVtjDChvWqRjPvHwLqr5hx28Ayr6bsOs1Kuj87V0O8w=="
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.8.1.tgz",
|
||||
"integrity": "sha512-+/hpTbRcCw9YC0TOfN1W47pej4a9lRmltdOVdRLz5FP5UvUq3CenhXjQK7u/8NdMIIShMXYAh9VLPhc7TjhvFw=="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
"@opentelemetry/api": "1.0.4",
|
||||
"@supabase/ui": "0.36.5",
|
||||
"cors": "2.8.5",
|
||||
"jose": "4.8.1",
|
||||
"micromatch": "4.0.5",
|
||||
"next": "12.2.2",
|
||||
"next-auth": "4.10.0",
|
||||
|
@ -90,4 +91,4 @@
|
|||
"engines": {
|
||||
"node": ">=14.18.1 <=16.x"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
} else if (req.method === 'DELETE') {
|
||||
res.status(204).end(await apiController.deleteConfig(req.body));
|
||||
} else {
|
||||
throw new Error('Method not allowed');
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('config api error:', err);
|
||||
|
|
|
@ -3,7 +3,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
|
|||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== 'POST') {
|
||||
throw new Error(`Method ${req.method} not allowed`);
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
|
||||
const { SAMLResponse, RelayState } = req.body;
|
||||
|
|
|
@ -3,7 +3,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
|
|||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== 'GET') {
|
||||
throw new Error(`Method ${req.method} not allowed`);
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
|
||||
const { nameId, tenant, product, redirectUrl } = req.query;
|
||||
|
|
|
@ -6,13 +6,14 @@ import { setErrorCookie } from '@lib/utils';
|
|||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
if (req.method !== 'GET') {
|
||||
throw new Error('Method not allowed');
|
||||
if (req.method !== 'GET' && req.method !== 'POST') {
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
|
||||
const { oauthController } = await jackson();
|
||||
const requestParams = req.method === 'GET' ? req.query : req.body;
|
||||
const { redirect_url, authorize_form } = await oauthController.authorize(
|
||||
req.query as unknown as OAuthReqBody
|
||||
requestParams as unknown as OAuthReqBody
|
||||
);
|
||||
if (redirect_url) {
|
||||
res.redirect(302, redirect_url);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== 'GET') {
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
const { oidcDiscoveryController } = await jackson();
|
||||
const jwks = await oidcDiscoveryController.jwks();
|
||||
|
||||
const response = JSON.stringify(jwks, null, 2);
|
||||
res.status(200).setHeader('Content-Type', 'application/json').send(response);
|
||||
}
|
|
@ -6,7 +6,7 @@ import { setErrorCookie } from '@lib/utils';
|
|||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
if (req.method !== 'POST') {
|
||||
throw new Error('Method not allowed');
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
|
||||
const { oauthController } = await jackson();
|
||||
|
|
|
@ -8,7 +8,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
await cors(req, res);
|
||||
|
||||
if (req.method !== 'POST') {
|
||||
throw new Error('Method not allowed');
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
|
||||
const { oauthController } = await jackson();
|
||||
|
|
|
@ -6,7 +6,7 @@ import { extractAuthToken } from '@lib/utils';
|
|||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
if (req.method !== 'GET') {
|
||||
throw new Error('Method not allowed');
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
|
||||
const { oauthController } = await jackson();
|
||||
|
|
|
@ -20,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
} else if (req.method === 'DELETE') {
|
||||
res.status(204).end(await apiController.deleteConfig(req.body));
|
||||
} else {
|
||||
throw new Error('Method not allowed');
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('config api error:', err);
|
||||
|
|
|
@ -19,7 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
res.status(204).end();
|
||||
}
|
||||
} else {
|
||||
throw new Error('Method not allowed');
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('config api error:', err);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import jackson from '@lib/jackson';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== 'GET') {
|
||||
throw { message: 'Method not allowed', statusCode: 405 };
|
||||
}
|
||||
const { oidcDiscoveryController } = await jackson();
|
||||
const config = await oidcDiscoveryController.openidConfig();
|
||||
|
||||
const response = JSON.stringify(config, null, 2);
|
||||
res.status(200).setHeader('Content-Type', 'application/json').send(response);
|
||||
}
|
Loading…
Reference in New Issue