From ad8fb063091844130b7f403fa0df623ffdb1ae0b Mon Sep 17 00:00:00 2001 From: Max Polsky Date: Wed, 22 Nov 2023 05:35:47 -0800 Subject: [PATCH] refactor: remove allowed metaSite env (#473) --- apps/velo-external-db/src/app.ts | 3 +- .../src/readers/aws_config_reader.ts | 22 +-- .../src/readers/azure_config_reader.ts | 6 +- .../src/readers/common_config_reader.ts | 4 +- .../src/readers/gcp_config_reader.ts | 31 ++-- .../src/service/config_validator.spec.ts | 3 - .../common_config_validator.spec.ts | 4 +- .../src/validators/common_config_validator.ts | 4 +- .../drivers/aws_mongo_config_test_support.ts | 11 +- .../drivers/aws_mysql_config_test_support.ts | 11 +- .../azure_mysql_config_test_support.ts | 6 +- .../external_db_config_test_support.ts | 4 - .../gcp_firestore_config_test_support.ts | 6 +- .../drivers/gcp_mysql_config_test_support.ts | 6 +- .../gcp_spanner_config_test_support.ts | 6 +- libs/external-db-config/test/gen.ts | 2 - libs/external-db-config/test/test_types.ts | 7 - libs/external-db-config/test/test_utils.ts | 2 +- libs/velo-external-db-core/src/index.ts | 2 +- libs/velo-external-db-core/src/router.ts | 4 +- libs/velo-external-db-core/src/types.ts | 1 - .../src/web/jwt-auth-middleware.spec.ts | 134 ------------------ .../src/web/jwt-auth-middleware.ts | 80 ----------- 23 files changed, 47 insertions(+), 312 deletions(-) delete mode 100644 libs/velo-external-db-core/src/web/jwt-auth-middleware.spec.ts delete mode 100644 libs/velo-external-db-core/src/web/jwt-auth-middleware.ts diff --git a/apps/velo-external-db/src/app.ts b/apps/velo-external-db/src/app.ts index 32f876cd2..fc20bf23d 100644 --- a/apps/velo-external-db/src/app.ts +++ b/apps/velo-external-db/src/app.ts @@ -4,7 +4,7 @@ import { ExternalDbRouter, Hooks } from '@wix-velo/velo-external-db-core' import { engineConnectorFor } from './storage/factory' const initConnector = async(wixDataBaseUrl?: string, hooks?: Hooks) => { - const { vendor, type: adapterType, allowedMetasites, hideAppInfo } = readCommonConfig() + const { vendor, type: adapterType, hideAppInfo } = readCommonConfig() const configReader = create() const { authorization, jwtPublicKey, appDefId, ...dbConfig } = await configReader.readConfig() @@ -18,7 +18,6 @@ const initConnector = async(wixDataBaseUrl?: string, hooks?: Hooks) => { }, jwtPublicKey, appDefId, - allowedMetasites, vendor, adapterType, commonExtended: true, diff --git a/libs/external-db-config/src/readers/aws_config_reader.ts b/libs/external-db-config/src/readers/aws_config_reader.ts index 05efa5183..16ef9d828 100644 --- a/libs/external-db-config/src/readers/aws_config_reader.ts +++ b/libs/external-db-config/src/readers/aws_config_reader.ts @@ -13,8 +13,8 @@ export class AwsConfigReader implements IConfigReader { async readConfig() { const { config } = await this.readExternalAndLocalConfig() - const { host, username, password, DB, ALLOWED_METASITES, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } = config - return { host, user: username, password, db: DB, allowedMetasites: ALLOWED_METASITES, port: DB_PORT, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + const { host, username, password, DB, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } = config + return { host, user: username, password, db: DB, port: DB_PORT, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } async readExternalConfig() { @@ -29,8 +29,8 @@ export class AwsConfigReader implements IConfigReader { async readExternalAndLocalConfig() { const { externalConfig, secretMangerError }: {[key: string]: any} = await this.readExternalConfig() - const { host, username, password, DB, ALLOWED_METASITES, HOST, PASSWORD, USER, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID }: {[key: string]: string} = { ...process.env, ...externalConfig } - const config = { host: host || HOST, username: username || USER, password: password || PASSWORD, DB, ALLOWED_METASITES, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } + const { host, username, password, DB, HOST, PASSWORD, USER, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID }: {[key: string]: string} = { ...process.env, ...externalConfig } + const config = { host: host || HOST, username: username || USER, password: password || PASSWORD, DB, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } return { config, secretMangerError } } } @@ -48,13 +48,13 @@ export class AwsDynamoConfigReader implements IConfigReader { if (process.env['NODE_ENV'] === 'test') { return { region: this.region, endpoint: process.env['ENDPOINT_URL'], jwtPublicKey: config.JWT_PUBLIC_KEY, appDefId: config.APP_DEF_ID } } - return { region: this.region, jwtPublicKey: config.JWT_PUBLIC_KEY, appDefId: config.APP_DEF_ID, allowedMetasites: config.ALLOWED_METASITES } + return { region: this.region, jwtPublicKey: config.JWT_PUBLIC_KEY, appDefId: config.APP_DEF_ID } } async readExternalAndLocalConfig() { const { externalConfig, secretMangerError }: {[key: string]: any} = await this.readExternalConfig() - const { ALLOWED_METASITES = undefined, JWT_PUBLIC_KEY = undefined, APP_DEF_ID = undefined } = { ...process.env, ...externalConfig } - const config = { JWT_PUBLIC_KEY, APP_DEF_ID, ALLOWED_METASITES } + const { JWT_PUBLIC_KEY = undefined, APP_DEF_ID = undefined } = { ...process.env, ...externalConfig } + const config = { JWT_PUBLIC_KEY, APP_DEF_ID } return { config, secretMangerError } } @@ -90,8 +90,8 @@ export class AwsMongoConfigReader implements IConfigReader { async readExternalAndLocalConfig() { const { externalConfig, secretMangerError } :{[key: string]: any} = await this.readExternalConfig() - const { ALLOWED_METASITES, URI, JWT_PUBLIC_KEY, APP_DEF_ID }: { ALLOWED_METASITES: string, URI: string, JWT_PUBLIC_KEY: string, APP_DEF_ID: string } = { ...process.env, ...externalConfig } - const config = { ALLOWED_METASITES, URI, JWT_PUBLIC_KEY, APP_DEF_ID } + const { URI, JWT_PUBLIC_KEY, APP_DEF_ID }: { URI: string, JWT_PUBLIC_KEY: string, APP_DEF_ID: string } = { ...process.env, ...externalConfig } + const config = { URI, JWT_PUBLIC_KEY, APP_DEF_ID } return { config, secretMangerError } } @@ -99,8 +99,8 @@ export class AwsMongoConfigReader implements IConfigReader { async readConfig() { const { config } = await this.readExternalAndLocalConfig() - const { ALLOWED_METASITES, URI, JWT_PUBLIC_KEY, APP_DEF_ID } = config + const { URI, JWT_PUBLIC_KEY, APP_DEF_ID } = config - return { allowedMetasites: ALLOWED_METASITES, connectionUri: URI, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + return { connectionUri: URI, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } diff --git a/libs/external-db-config/src/readers/azure_config_reader.ts b/libs/external-db-config/src/readers/azure_config_reader.ts index 0e9089dcd..704d6e3b1 100644 --- a/libs/external-db-config/src/readers/azure_config_reader.ts +++ b/libs/external-db-config/src/readers/azure_config_reader.ts @@ -5,8 +5,8 @@ export class AzureConfigReader implements IConfigReader { } async readConfig() { - const { HOST, USER, PASSWORD, DB, ALLOWED_METASITES, UNSECURED_ENV, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env - return { host: HOST, user: USER, password: PASSWORD, db: DB, allowedMetasites: ALLOWED_METASITES, - unsecuredEnv: UNSECURED_ENV, port: DB_PORT, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + const { HOST, USER, PASSWORD, DB, UNSECURED_ENV, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + return { host: HOST, user: USER, password: PASSWORD, db: DB, unsecuredEnv: UNSECURED_ENV, port: DB_PORT, + jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } diff --git a/libs/external-db-config/src/readers/common_config_reader.ts b/libs/external-db-config/src/readers/common_config_reader.ts index c6e23a3ef..9fa5982a1 100644 --- a/libs/external-db-config/src/readers/common_config_reader.ts +++ b/libs/external-db-config/src/readers/common_config_reader.ts @@ -4,7 +4,7 @@ export default class CommonConfigReader implements IConfigReader { constructor() { } readConfig() { - const { CLOUD_VENDOR, TYPE, REGION, SECRET_NAME, ALLOWED_METASITES, HIDE_APP_INFO } = process.env - return { vendor: CLOUD_VENDOR, type: TYPE, region: REGION, secretId: SECRET_NAME, allowedMetasites: ALLOWED_METASITES, hideAppInfo: HIDE_APP_INFO ? HIDE_APP_INFO === 'true' : undefined } + const { CLOUD_VENDOR, TYPE, REGION, SECRET_NAME, HIDE_APP_INFO } = process.env + return { vendor: CLOUD_VENDOR, type: TYPE, region: REGION, secretId: SECRET_NAME, hideAppInfo: HIDE_APP_INFO ? HIDE_APP_INFO === 'true' : undefined } } } diff --git a/libs/external-db-config/src/readers/gcp_config_reader.ts b/libs/external-db-config/src/readers/gcp_config_reader.ts index 51ef523f6..c37c0f388 100644 --- a/libs/external-db-config/src/readers/gcp_config_reader.ts +++ b/libs/external-db-config/src/readers/gcp_config_reader.ts @@ -5,9 +5,9 @@ export class GcpConfigReader implements IConfigReader { } async readConfig() { - const { CLOUD_SQL_CONNECTION_NAME, USER, PASSWORD, DB, ALLOWED_METASITES, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + const { CLOUD_SQL_CONNECTION_NAME, USER, PASSWORD, DB, DB_PORT, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env return { cloudSqlConnectionName: CLOUD_SQL_CONNECTION_NAME, user: USER, password: PASSWORD, db: DB, - allowedMetasites: ALLOWED_METASITES, port: DB_PORT, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + port: DB_PORT, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } @@ -17,9 +17,8 @@ export class GcpSpannerConfigReader implements IConfigReader { } async readConfig() { - const { PROJECT_ID, INSTANCE_ID, DATABASE_ID, ALLOWED_METASITES, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env - return { projectId: PROJECT_ID, instanceId: INSTANCE_ID, databaseId: DATABASE_ID, - allowedMetasites: ALLOWED_METASITES, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + const { PROJECT_ID, INSTANCE_ID, DATABASE_ID, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + return { projectId: PROJECT_ID, instanceId: INSTANCE_ID, databaseId: DATABASE_ID, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } @@ -29,8 +28,8 @@ export class GcpFirestoreConfigReader implements IConfigReader { constructor() { } async readConfig() { - const { PROJECT_ID, ALLOWED_METASITES, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env - return { projectId: PROJECT_ID, allowedMetasites: ALLOWED_METASITES, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + const { PROJECT_ID, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + return { projectId: PROJECT_ID, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } @@ -40,9 +39,9 @@ export class GcpGoogleSheetsConfigReader implements IConfigReader { constructor() { } async readConfig() { - const { CLIENT_EMAIL, SHEET_ID, API_PRIVATE_KEY, ALLOWED_METASITES, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + const { CLIENT_EMAIL, SHEET_ID, API_PRIVATE_KEY, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env return { clientEmail: CLIENT_EMAIL, apiPrivateKey: API_PRIVATE_KEY, sheetId: SHEET_ID, - allowedMetasites: ALLOWED_METASITES, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } @@ -51,9 +50,8 @@ export class GcpMongoConfigReader implements IConfigReader { constructor() { } async readConfig() { - const { URI, ALLOWED_METASITES, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env - return { connectionUri: URI, allowedMetasites: ALLOWED_METASITES, - jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + const { URI, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + return { connectionUri: URI, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } @@ -61,9 +59,9 @@ export class GcpAirtableConfigReader implements IConfigReader { constructor() { } async readConfig() { - const { AIRTABLE_API_KEY, META_API_KEY, BASE_ID, ALLOWED_METASITES, BASE_URL, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + const { AIRTABLE_API_KEY, META_API_KEY, BASE_ID, BASE_URL, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env return { apiPrivateKey: AIRTABLE_API_KEY, metaApiKey: META_API_KEY, baseId: BASE_ID, - allowedMetasites: ALLOWED_METASITES, baseUrl: BASE_URL, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + baseUrl: BASE_URL, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } @@ -72,8 +70,7 @@ export class GcpBigQueryConfigReader implements IConfigReader { } async readConfig() { - const { PROJECT_ID, DATABASE_ID, ALLOWED_METASITES, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env - return { projectId: PROJECT_ID, databaseId: DATABASE_ID, - allowedMetasites: ALLOWED_METASITES, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } + const { PROJECT_ID, DATABASE_ID, JWT_PUBLIC_KEY, APP_DEF_ID } = process.env + return { projectId: PROJECT_ID, databaseId: DATABASE_ID, jwtPublicKey: JWT_PUBLIC_KEY, appDefId: APP_DEF_ID } } } diff --git a/libs/external-db-config/src/service/config_validator.spec.ts b/libs/external-db-config/src/service/config_validator.spec.ts index 2d36fd2fd..5034e10e7 100644 --- a/libs/external-db-config/src/service/config_validator.spec.ts +++ b/libs/external-db-config/src/service/config_validator.spec.ts @@ -10,7 +10,6 @@ describe('Config Reader Client', () => { test('read config will retrieve config from secret provider and validate retrieved data', async() => { driver.givenConfig(ctx.config) - driver.givenCommonConfig(ctx.externalDatabaseId, ctx.allowedMetasites) driver.givenAuthorizationConfig(ctx.authorizationConfig) expect( env.configValidator.readConfig() ).toEqual(matchers.configResponseFor(ctx.config, ctx.authorizationConfig)) @@ -86,7 +85,6 @@ describe('Config Reader Client', () => { missingProperties: Uninitialized, moreMissingProperties: Uninitialized, externalDatabaseId: Uninitialized, - allowedMetasites: Uninitialized, authorizationConfig: Uninitialized, } @@ -104,7 +102,6 @@ describe('Config Reader Client', () => { ctx.missingProperties = Array.from({ length: 5 }, () => chance.word()) ctx.moreMissingProperties = Array.from({ length: 5 }, () => chance.word()) ctx.externalDatabaseId = chance.guid() - ctx.allowedMetasites = chance.guid() env.configValidator = new ConfigValidator(driver.configValidator, driver.authorizationConfigValidator, driver.commonConfigValidator) }) }) diff --git a/libs/external-db-config/src/validators/common_config_validator.spec.ts b/libs/external-db-config/src/validators/common_config_validator.spec.ts index 97ccb9171..fa31812eb 100644 --- a/libs/external-db-config/src/validators/common_config_validator.spec.ts +++ b/libs/external-db-config/src/validators/common_config_validator.spec.ts @@ -11,9 +11,9 @@ describe('MySqlConfigValidator', () => { expect(env.CommonConfigValidator.validate()).toEqual({ missingRequiredSecretsKeys: [] }) }) - test('not extended common config validator will return if externalDatabaseId or allowedMetasites are missing', () => { + test('not extended common config validator will return if jwtPublicKey or appDefId are missing', () => { env.CommonConfigValidator = new CommonConfigValidator({}) - expect(env.CommonConfigValidator.validate()).toEqual({ missingRequiredSecretsKeys: ['jwtPublicKey', 'appDefId', 'allowedMetasites'] }) + expect(env.CommonConfigValidator.validate()).toEqual({ missingRequiredSecretsKeys: ['jwtPublicKey', 'appDefId'] }) }) each( diff --git a/libs/external-db-config/src/validators/common_config_validator.ts b/libs/external-db-config/src/validators/common_config_validator.ts index 1d6cb1544..74ea797db 100644 --- a/libs/external-db-config/src/validators/common_config_validator.ts +++ b/libs/external-db-config/src/validators/common_config_validator.ts @@ -22,7 +22,7 @@ export class CommonConfigValidator { validateBasic() { return { - missingRequiredSecretsKeys: checkRequiredKeys(this.config, ['jwtPublicKey', 'appDefId', 'allowedMetasites']) + missingRequiredSecretsKeys: checkRequiredKeys(this.config, ['jwtPublicKey', 'appDefId']) } } @@ -32,7 +32,7 @@ export class CommonConfigValidator { return { validType, validVendor, - missingRequiredSecretsKeys: checkRequiredKeys(this.config, ['type', 'vendor', 'jwtPublicKey', 'appDefId', 'allowedMetasites']) + missingRequiredSecretsKeys: checkRequiredKeys(this.config, ['type', 'vendor', 'jwtPublicKey', 'appDefId']) } } } diff --git a/libs/external-db-config/test/drivers/aws_mongo_config_test_support.ts b/libs/external-db-config/test/drivers/aws_mongo_config_test_support.ts index 1714d76d3..f8893fdc0 100644 --- a/libs/external-db-config/test/drivers/aws_mongo_config_test_support.ts +++ b/libs/external-db-config/test/drivers/aws_mongo_config_test_support.ts @@ -17,9 +17,6 @@ export const defineValidConfig = (config: MongoConfig) => { if (config.connectionUri) { awsConfig['URI'] = config.connectionUri } - if (config.allowedMetasites) { - awsConfig['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { awsConfig['PERMISSIONS'] = JSON.stringify( config.authorization ) } @@ -36,9 +33,6 @@ const defineLocalEnvs = (config: MongoConfig) => { if (config.connectionUri) { process.env['URI'] = config.connectionUri } - if (config.allowedMetasites) { - process.env['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { process.env['PERMISSIONS'] = JSON.stringify( config.authorization ) } @@ -54,7 +48,6 @@ export const defineInvalidConfig = () => defineValidConfig({}) export const validConfig = () => ({ connectionUri: chance.word(), - allowedMetasites: chance.word(), jwtPublicKey: chance.word(), appDefId: chance.word(), }) @@ -70,8 +63,8 @@ export const validConfigWithAuthorization = () => ({ authorization: validAuthorizationConfig.collectionPermissions }) -export const ExpectedProperties = ['URI', 'ALLOWED_METASITES', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] -export const RequiredProperties = ['URI', 'ALLOWED_METASITES', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const ExpectedProperties = ['URI', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const RequiredProperties = ['URI', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] export const reset = () => { mockedAwsSdk.reset() diff --git a/libs/external-db-config/test/drivers/aws_mysql_config_test_support.ts b/libs/external-db-config/test/drivers/aws_mysql_config_test_support.ts index fbb20106f..3e518a3ac 100644 --- a/libs/external-db-config/test/drivers/aws_mysql_config_test_support.ts +++ b/libs/external-db-config/test/drivers/aws_mysql_config_test_support.ts @@ -26,9 +26,6 @@ export const defineValidConfig = (config: MySqlConfig) => { if (config.db) { awsConfig['DB'] = config.db } - if (config.allowedMetasites) { - awsConfig['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { awsConfig['PERMISSIONS'] = JSON.stringify(config.authorization) } @@ -54,9 +51,6 @@ const defineLocalEnvs = (config: MySqlConfig) => { if (config.db) { process.env['DB'] = config.db } - if (config.allowedMetasites) { - process.env['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { process.env['PERMISSIONS'] = JSON.stringify(config.authorization) } @@ -82,7 +76,6 @@ export const validConfig = (): MySqlConfig => ({ user: chance.word(), password: chance.word(), db: chance.word(), - allowedMetasites: chance.word(), jwtPublicKey: chance.word(), appDefId: chance.word(), }) @@ -103,8 +96,8 @@ export const validConfigWithAuthConfig = () => ({ } }) -export const ExpectedProperties = ['host', 'username', 'password', 'DB', 'ALLOWED_METASITES', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] -export const RequiredProperties = ['host', 'username', 'password', 'DB', 'ALLOWED_METASITES', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const ExpectedProperties = ['host', 'username', 'password', 'DB', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const RequiredProperties = ['host', 'username', 'password', 'DB', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] export const reset = () => { mockedAwsSdk.reset() diff --git a/libs/external-db-config/test/drivers/azure_mysql_config_test_support.ts b/libs/external-db-config/test/drivers/azure_mysql_config_test_support.ts index 6bf60fa50..920d3fdc4 100644 --- a/libs/external-db-config/test/drivers/azure_mysql_config_test_support.ts +++ b/libs/external-db-config/test/drivers/azure_mysql_config_test_support.ts @@ -17,9 +17,6 @@ export const defineValidConfig = (config: MySqlConfig) => { if (config.db) { process.env['DB'] = config.db } - if (config.allowedMetasites) { - process.env['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { process.env['PERMISSIONS'] = JSON.stringify( config.authorization ) } @@ -36,7 +33,6 @@ export const validConfig = (): MySqlConfig => ({ user: chance.word(), password: chance.word(), db: chance.word(), - allowedMetasites: chance.word(), jwtPublicKey: chance.word(), appDefId: chance.word(), }) @@ -57,7 +53,7 @@ export const validConfigWithAuthConfig = () => ({ export const defineInvalidConfig = () => defineValidConfig({}) -export const ExpectedProperties = ['HOST', 'USER', 'PASSWORD', 'DB', 'ALLOWED_METASITES', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const ExpectedProperties = ['HOST', 'USER', 'PASSWORD', 'DB', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] export const reset = () => ExpectedProperties.forEach(p => delete process.env[p]) diff --git a/libs/external-db-config/test/drivers/external_db_config_test_support.ts b/libs/external-db-config/test/drivers/external_db_config_test_support.ts index 20da29647..e05f3bf4c 100644 --- a/libs/external-db-config/test/drivers/external_db_config_test_support.ts +++ b/libs/external-db-config/test/drivers/external_db_config_test_support.ts @@ -27,10 +27,6 @@ export const givenValidConfig = () => when(configValidator.validate).calledWith() .mockReturnValue({ missingRequiredSecretsKeys: [] }) -export const givenCommonConfig = (externalDatabaseId: any, allowedMetasites: any) => - when(commonConfigValidator.readConfig).calledWith() - .mockReturnValue({ externalDatabaseId, allowedMetasites }) - export const givenValidCommonConfig = () => when(commonConfigValidator.validate).calledWith() .mockReturnValueOnce({ missingRequiredSecretsKeys: [], validType: true, validVendor: true }) diff --git a/libs/external-db-config/test/drivers/gcp_firestore_config_test_support.ts b/libs/external-db-config/test/drivers/gcp_firestore_config_test_support.ts index fbaffb5fc..f1a59f664 100644 --- a/libs/external-db-config/test/drivers/gcp_firestore_config_test_support.ts +++ b/libs/external-db-config/test/drivers/gcp_firestore_config_test_support.ts @@ -8,9 +8,6 @@ export const defineValidConfig = (config: FiresStoreConfig) => { if (config.projectId) { process.env['PROJECT_ID'] = config.projectId } - if (config.allowedMetasites) { - process.env['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { process.env['PERMISSIONS'] = JSON.stringify( config.authorization ) } @@ -24,7 +21,6 @@ export const defineValidConfig = (config: FiresStoreConfig) => { export const validConfig = (): FiresStoreConfig => ({ projectId: chance.word(), - allowedMetasites: chance.word(), jwtPublicKey: chance.word(), appDefId: chance.word(), }) @@ -45,7 +41,7 @@ export const validConfigWithAuthConfig = () => ({ export const defineInvalidConfig = () => defineValidConfig({}) -export const ExpectedProperties = ['PROJECT_ID', 'ALLOWED_METASITES', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const ExpectedProperties = ['PROJECT_ID', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] export const reset = () => ExpectedProperties.forEach(p => delete process.env[p]) diff --git a/libs/external-db-config/test/drivers/gcp_mysql_config_test_support.ts b/libs/external-db-config/test/drivers/gcp_mysql_config_test_support.ts index b782fd602..2135fee8c 100644 --- a/libs/external-db-config/test/drivers/gcp_mysql_config_test_support.ts +++ b/libs/external-db-config/test/drivers/gcp_mysql_config_test_support.ts @@ -17,9 +17,6 @@ export const defineValidConfig = (config: MySqlConfig) => { if (config.db) { process.env['DB'] = config.db } - if (config.allowedMetasites) { - process.env['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { process.env['PERMISSIONS'] = JSON.stringify( config.authorization ) } @@ -36,7 +33,6 @@ export const validConfig = (): MySqlConfig => ({ user: chance.word(), password: chance.word(), db: chance.word(), - allowedMetasites: chance.word(), jwtPublicKey: chance.word(), appDefId: chance.word(), }) @@ -55,7 +51,7 @@ export const validConfigWithAuthConfig = () => ({ } }) -export const ExpectedProperties = ['CLOUD_SQL_CONNECTION_NAME', 'USER', 'PASSWORD', 'DB', 'ALLOWED_METASITES', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const ExpectedProperties = ['CLOUD_SQL_CONNECTION_NAME', 'USER', 'PASSWORD', 'DB', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] export const defineInvalidConfig = () => defineValidConfig({}) diff --git a/libs/external-db-config/test/drivers/gcp_spanner_config_test_support.ts b/libs/external-db-config/test/drivers/gcp_spanner_config_test_support.ts index faf9f6a6f..8b66ac395 100644 --- a/libs/external-db-config/test/drivers/gcp_spanner_config_test_support.ts +++ b/libs/external-db-config/test/drivers/gcp_spanner_config_test_support.ts @@ -14,9 +14,6 @@ export const defineValidConfig = (config: SpannerConfig) => { if (config.databaseId) { process.env['DATABASE_ID'] = config.databaseId } - if (config.allowedMetasites) { - process.env['ALLOWED_METASITES'] = config.allowedMetasites - } if (config.authorization) { process.env['PERMISSIONS'] = JSON.stringify( config.authorization ) } @@ -32,7 +29,6 @@ export const validConfig = (): SpannerConfig => ({ projectId: chance.word(), instanceId: chance.word(), databaseId: chance.word(), - allowedMetasites: chance.word(), jwtPublicKey: chance.word(), appDefId: chance.word(), }) @@ -55,7 +51,7 @@ export const validConfigWithAuthConfig = () => ({ export const defineInvalidConfig = () => defineValidConfig({}) -export const ExpectedProperties = ['PROJECT_ID', 'INSTANCE_ID', 'DATABASE_ID', 'ALLOWED_METASITES', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] +export const ExpectedProperties = ['PROJECT_ID', 'INSTANCE_ID', 'DATABASE_ID', 'PERMISSIONS', 'JWT_PUBLIC_KEY', 'APP_DEF_ID'] export const reset = () => ExpectedProperties.forEach(p => delete process.env[p]) diff --git a/libs/external-db-config/test/gen.ts b/libs/external-db-config/test/gen.ts index d520fe8a9..647d2062d 100644 --- a/libs/external-db-config/test/gen.ts +++ b/libs/external-db-config/test/gen.ts @@ -12,13 +12,11 @@ export const randomConfig = () => ({ export const randomCommonConfig = () => ({ jwtPublicKey: chance.guid(), appDefId: chance.guid(), - allowedMetasites: chance.guid(), }) export const randomExtendedCommonConfig = () => ({ jwtPublicKey: chance.guid(), appDefId: chance.guid(), - allowedMetasites: chance.guid(), vendor: chance.pickone(supportedVendors), type: chance.pickone(supportedDBs), }) diff --git a/libs/external-db-config/test/test_types.ts b/libs/external-db-config/test/test_types.ts index 60ee813b9..626794c27 100644 --- a/libs/external-db-config/test/test_types.ts +++ b/libs/external-db-config/test/test_types.ts @@ -1,7 +1,6 @@ export interface MongoConfig { connectionUri?: string - allowedMetasites?: string authorization?: any jwtPublicKey?: string appDefId?: string @@ -9,7 +8,6 @@ export interface MongoConfig { export interface MongoAwsConfig { URI?: string - ALLOWED_METASITES?: string PERMISSIONS?: string JWT_PUBLIC_KEY?: string APP_DEF_ID?: string @@ -21,7 +19,6 @@ export interface MySqlConfig { user?: string password?: string db?: string - allowedMetasites?: string authorization?: any jwtPublicKey?: string appDefId?: string @@ -32,7 +29,6 @@ export interface AwsMysqlConfig { username?: string password?: string DB?: string - ALLOWED_METASITES?: string PERMISSIONS?: string JWT_PUBLIC_KEY?: string APP_DEF_ID?: string @@ -42,14 +38,12 @@ export interface CommonConfig { type?: string vendor?: string hideAppInfo?: boolean - allowedMetasites?: string jwtPublicKey?: string appDefId?: string } export interface FiresStoreConfig { projectId?: string - allowedMetasites?: string authorization?: any jwtPublicKey?: string appDefId?: string @@ -59,7 +53,6 @@ export interface SpannerConfig { projectId?: string instanceId?: string databaseId?: string - allowedMetasites?: string authorization?: any jwtPublicKey?: string appDefId?: string diff --git a/libs/external-db-config/test/test_utils.ts b/libs/external-db-config/test/test_utils.ts index 3d57e1257..6cf6f970d 100644 --- a/libs/external-db-config/test/test_utils.ts +++ b/libs/external-db-config/test/test_utils.ts @@ -23,4 +23,4 @@ export const splitConfig = (config: {[key: string]: any}) => { return { firstPart, secondPart } } -export const extendedCommonConfigRequiredProperties = ['jwtPublicKey', 'appDefId', 'allowedMetasites', 'vendor', 'type'] +export const extendedCommonConfigRequiredProperties = ['jwtPublicKey', 'appDefId', 'vendor', 'type'] diff --git a/libs/velo-external-db-core/src/index.ts b/libs/velo-external-db-core/src/index.ts index 42d2c1cd1..200e1d6c5 100644 --- a/libs/velo-external-db-core/src/index.ts +++ b/libs/velo-external-db-core/src/index.ts @@ -39,7 +39,7 @@ export class ExternalDbRouter { this.isInitialized(connector) this.connector = connector this.configValidator = new ConfigValidator(connector.configValidator, new AuthorizationConfigValidator(config.authorization), - new CommonConfigValidator({ allowedMetasites: config.allowedMetasites, vendor: config.vendor, type: config.adapterType, jwtPublicKey: config.jwtPublicKey, appDefId: config.appDefId }, + new CommonConfigValidator({ vendor: config.vendor, type: config.adapterType, jwtPublicKey: config.jwtPublicKey, appDefId: config.appDefId }, config.commonExtended)) this.config = config this.operationService = new OperationService(connector.databaseOperations) diff --git a/libs/velo-external-db-core/src/router.ts b/libs/velo-external-db-core/src/router.ts index b6f0d4e11..4f0f83158 100644 --- a/libs/velo-external-db-core/src/router.ts +++ b/libs/velo-external-db-core/src/router.ts @@ -29,10 +29,10 @@ import { JWTVerifierDecoderMiddleware } from './web/jwt-verifier-decoder-middlew const { query: Query, count: Count, aggregate: Aggregate, insert: Insert, update: Update, remove: Remove, truncate: Truncate } = DataOperation const { Get, Create, Update: UpdateSchema, Delete } = CollectionOperationSPI -let schemaService: SchemaService, operationService: OperationService, externalDbConfigClient: ConfigValidator, schemaAwareDataService: SchemaAwareDataService, cfg: { allowedMetasites: string, type?: any; vendor?: any, wixDataBaseUrl: string, hideAppInfo?: boolean, jwtPublicKey: string, appDefId: string }, filterTransformer: FilterTransformer, aggregationTransformer: AggregationTransformer, dataHooks: DataHooks, schemaHooks: SchemaHooks //roleAuthorizationService: RoleAuthorizationService, +let schemaService: SchemaService, operationService: OperationService, externalDbConfigClient: ConfigValidator, schemaAwareDataService: SchemaAwareDataService, cfg: { type?: any; vendor?: any, wixDataBaseUrl: string, hideAppInfo?: boolean, jwtPublicKey: string, appDefId: string }, filterTransformer: FilterTransformer, aggregationTransformer: AggregationTransformer, dataHooks: DataHooks, schemaHooks: SchemaHooks //roleAuthorizationService: RoleAuthorizationService, export const initServices = (_schemaAwareDataService: SchemaAwareDataService, _schemaService: SchemaService, _operationService: OperationService, - _externalDbConfigClient: ConfigValidator, _cfg: { allowedMetasites: string, type?: string, vendor?: string, wixDataBaseUrl: string, hideAppInfo?: boolean, jwtPublicKey: string, appDefId: string }, + _externalDbConfigClient: ConfigValidator, _cfg: { type?: string, vendor?: string, wixDataBaseUrl: string, hideAppInfo?: boolean, jwtPublicKey: string, appDefId: string }, _filterTransformer: FilterTransformer, _aggregationTransformer: AggregationTransformer, _roleAuthorizationService: RoleAuthorizationService, _hooks: Hooks) => { schemaService = _schemaService diff --git a/libs/velo-external-db-core/src/types.ts b/libs/velo-external-db-core/src/types.ts index adcd13d52..5b2dec394 100644 --- a/libs/velo-external-db-core/src/types.ts +++ b/libs/velo-external-db-core/src/types.ts @@ -82,7 +82,6 @@ export interface SchemaHooks { } export interface ExternalDbRouterConfig { - allowedMetasites: string authorization?: { roleConfig: RoleConfig } vendor?: string adapterType?: string diff --git a/libs/velo-external-db-core/src/web/jwt-auth-middleware.spec.ts b/libs/velo-external-db-core/src/web/jwt-auth-middleware.spec.ts deleted file mode 100644 index 9620b5b72..000000000 --- a/libs/velo-external-db-core/src/web/jwt-auth-middleware.spec.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { sleep, Uninitialized } from '@wix-velo/test-commons' -import * as driver from '../../test/drivers/auth_middleware_test_support' -import { errors } from '@wix-velo/velo-external-db-commons' -const { UnauthorizedError } = errors -import * as Chance from 'chance' -import { JwtAuthenticator, TOKEN_ISSUER } from './jwt-auth-middleware' -import { - signedToken, - WixDataFacadeMock -} from '../../test/drivers/auth_middleware_test_support' -import { authConfig } from '@wix-velo/test-commons' -import { PublicKeyMap } from './wix_data_facade' - -const chance = Chance() - -describe('JWT Auth Middleware', () => { - - test('should authorize when JWT valid', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite, aud: ctx.externalDatabaseId }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), ctx.res, ctx.next) - - expectAuthorized() - }) - - test('should authorize when JWT valid, only with second public key', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite, aud: ctx.externalDatabaseId }, ctx.keyId) - env.auth = new JwtAuthenticator(ctx.externalDatabaseId, ctx.allowedMetasites, ctx.otherWixDataMock).authorizeJwt() - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), ctx.res, ctx.next) - expectAuthorized() - }) - - test('should throw when JWT siteId is not allowed', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: chance.word(), aud: ctx.externalDatabaseId }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT has no siteId claim', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, aud: ctx.externalDatabaseId }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT issuer is not Wix-Data', async() => { - const token = signedToken({ iss: chance.word(), siteId: ctx.metasite, aud: ctx.externalDatabaseId }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT has no issuer', async() => { - const token = signedToken({ siteId: ctx.metasite, aud: ctx.externalDatabaseId }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT audience is not externalDatabaseId of adapter', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite, aud: chance.word() }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT has no audience', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite }, ctx.keyId) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT kid is not found in Wix-Data keys', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite, aud: ctx.externalDatabaseId }, chance.word()) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT kid is absent', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite, aud: ctx.externalDatabaseId }) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - test('should throw when JWT is expired', async() => { - const token = signedToken({ iss: TOKEN_ISSUER, siteId: ctx.metasite, aud: ctx.externalDatabaseId }, ctx.keyId, '10ms') - await sleep(1000) - await env.auth(driver.requestBodyWith(Uninitialized, Uninitialized, `Bearer ${token}`), null, ctx.next) - - expectUnauthorized() - }) - - const ctx = { - externalDatabaseId: Uninitialized, - metasite: Uninitialized, - allowedMetasites: Uninitialized, - next: Uninitialized, - keyId: Uninitialized, - otherWixDataMock: Uninitialized, - res: Uninitialized, - } - - const env = { - auth: Uninitialized, - } - - const expectUnauthorized = () => { - expect(ctx.next).toHaveBeenCalledWith(new UnauthorizedError('You are not authorized')) - } - - const expectAuthorized = () => { - expect(ctx.next).not.toHaveBeenCalledWith(new UnauthorizedError('You are not authorized')) - expect(ctx.next).toHaveBeenCalledWith() - } - - beforeEach(() => { - ctx.externalDatabaseId = chance.word() - ctx.metasite = chance.word() - ctx.allowedMetasites = ctx.metasite - ctx.keyId = chance.word() - const otherKeyId = chance.word() - ctx.next = jest.fn().mockName('next') - const publicKeys: PublicKeyMap = {} - publicKeys[ctx.keyId] = authConfig.authPublicKey - const otherPublicKeys: PublicKeyMap = {} - otherPublicKeys[otherKeyId] = authConfig.otherAuthPublicKey - ctx.otherWixDataMock = new WixDataFacadeMock(otherPublicKeys, publicKeys) - ctx.res = { locals: {} } - env.auth = new JwtAuthenticator(ctx.externalDatabaseId, ctx.allowedMetasites, new WixDataFacadeMock(publicKeys)).authorizeJwt() - }) -}) diff --git a/libs/velo-external-db-core/src/web/jwt-auth-middleware.ts b/libs/velo-external-db-core/src/web/jwt-auth-middleware.ts deleted file mode 100644 index cd36f7cb9..000000000 --- a/libs/velo-external-db-core/src/web/jwt-auth-middleware.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { errors } from '@wix-velo/velo-external-db-commons' -const { UnauthorizedError } = errors -import { JwtHeader, JwtPayload, SigningKeyCallback, verify } from 'jsonwebtoken' -import * as express from 'express' -import { IWixDataFacade, PublicKeyMap } from './wix_data_facade' - - -export const TOKEN_ISSUER = 'wix-data.wix.com' - -export class JwtAuthenticator { - publicKeys: PublicKeyMap | undefined - externalDatabaseId: string - allowedMetasites: string[] - wixDataFacade: IWixDataFacade - - constructor(externalDatabaseId: string, allowedMetasites: string, wixDataFacade: IWixDataFacade) { - this.externalDatabaseId = externalDatabaseId - this.allowedMetasites = allowedMetasites ? allowedMetasites.split(',') : [] - this.wixDataFacade = wixDataFacade - } - - authorizeJwt() { - return async(req: express.Request, res: express.Response, next: express.NextFunction) => { - try { - const token = this.extractToken(req.header('authorization')) - this.publicKeys = this.publicKeys ?? await this.wixDataFacade.getPublicKeys(this.externalDatabaseId) - res.locals['metaSiteId'] = await this.verify(token) - } catch (err: any) { - console.error('Authorization failed: ' + err.message) - next(new UnauthorizedError('You are not authorized')) - } - next() - } - } - - getKey(header: JwtHeader, callback: SigningKeyCallback) { - if (header.kid === undefined) { - callback(new UnauthorizedError('No kid set on JWT header')) - return - } - const publicKey = this.publicKeys![header.kid!] - if (publicKey === undefined) { - callback(new UnauthorizedError(`No public key fetched for kid ${header.kid}. Available keys: ${JSON.stringify(this.publicKeys)}`)) - } else { - callback(null, publicKey) - } - } - - verifyJwt(token: string) { - return new Promise((resolve, reject) => - verify(token, this.getKey.bind(this), { audience: this.externalDatabaseId, issuer: TOKEN_ISSUER }, (err, decoded) => - (err) ? reject(err) : resolve(decoded!) - )) - } - - - async verifyWithRetry(token: string): Promise { - try { - return await this.verifyJwt(token) - } catch (err) { - this.publicKeys = await this.wixDataFacade.getPublicKeys(this.externalDatabaseId) - return await this.verifyJwt(token) - } - } - - async verify(token: string) { - const { siteId } = await this.verifyWithRetry(token) as JwtPayload - if (siteId === undefined || !this.allowedMetasites.includes(siteId)) { - throw new UnauthorizedError(`Unauthorized: ${siteId ? `site not allowed ${siteId}` : 'no siteId'}`) - } - return siteId - } - - private extractToken(header: string | undefined) { - if (header===undefined) { - throw new UnauthorizedError('No Authorization header') - } - return header.replace(/^(Bearer )/, '') - } -}