From ecb04b4ba90629f9d414b0cdd724364809c6e371 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Tue, 1 Oct 2024 15:52:28 +0000 Subject: [PATCH 01/30] test(app-config): write model tests --- .../__snapshots__/app-config.test.js.snap | 44 +++++++ .../backend/src/models/app-config.test.js | 115 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 packages/backend/src/models/__snapshots__/app-config.test.js.snap create mode 100644 packages/backend/src/models/app-config.test.js diff --git a/packages/backend/src/models/__snapshots__/app-config.test.js.snap b/packages/backend/src/models/__snapshots__/app-config.test.js.snap new file mode 100644 index 00000000..ee1e862c --- /dev/null +++ b/packages/backend/src/models/__snapshots__/app-config.test.js.snap @@ -0,0 +1,44 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` +{ + "properties": { + "allowCustomConnection": { + "default": false, + "type": "boolean", + }, + "createdAt": { + "type": "string", + }, + "disabled": { + "default": false, + "type": "boolean", + }, + "id": { + "format": "uuid", + "type": "string", + }, + "key": { + "type": "string", + }, + "shared": { + "default": false, + "type": "boolean", + }, + "updatedAt": { + "type": "string", + }, + }, + "required": [ + "key", + ], + "type": "object", +} +`; + +exports[`AppConfig model > virtualAttributes should return correct properties 1`] = ` +[ + "canConnect", + "canCustomConnect", +] +`; diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js new file mode 100644 index 00000000..7c14f19e --- /dev/null +++ b/packages/backend/src/models/app-config.test.js @@ -0,0 +1,115 @@ +import { describe, it, expect } from 'vitest'; + +import Base from './base.js'; +import AppConfig from './app-config.js'; +import AppAuthClient from './app-auth-client.js'; +import { createAppConfig } from '../../test/factories/app-config.js'; +import { createAppAuthClient } from '../../test/factories/app-auth-client.js'; + +describe('AppConfig model', () => { + it('tableName should return correct name', () => { + expect(AppConfig.tableName).toBe('app_configs'); + }); + + it('jsonSchema should have correct validations', () => { + expect(AppConfig.jsonSchema).toMatchSnapshot(); + }); + + it('relationMappings should return correct associations', () => { + const relationMappings = AppConfig.relationMappings(); + + const expectedRelations = { + appAuthClients: { + relation: Base.HasManyRelation, + modelClass: AppAuthClient, + join: { + from: 'app_configs.key', + to: 'app_auth_clients.app_key', + }, + }, + }; + + expect(relationMappings).toStrictEqual(expectedRelations); + }); + + it('virtualAttributes should return correct properties', () => { + expect(AppConfig.virtualAttributes).toMatchSnapshot(); + }); + + it('getApp should return associated application', async () => { + const appConfig = await createAppConfig({ key: 'deepl' }); + + const app = await appConfig.getApp(); + + expect(app.key).toBe('deepl'); + }); + + describe('canCustomConnect', () => { + it('should return true when app is enabled and allows custom connection', async () => { + const appConfig = await createAppConfig({ + disabled: false, + allowCustomConnection: true, + }); + + expect(appConfig.canCustomConnect).toBe(true); + }); + + it('should return false when app is disabled', async () => { + const appConfig = await createAppConfig({ + disabled: true, + allowCustomConnection: true, + }); + + expect(appConfig.canCustomConnect).toBe(false); + }); + + it(`should return false when app doesn't allow custom connection`, async () => { + const appConfig = await createAppConfig({ + disabled: false, + allowCustomConnection: false, + }); + + expect(appConfig.canCustomConnect).toBe(false); + }); + }); + + describe('canConnect', () => { + it('should return true when app is enabled, shared and allows custom connection', async () => { + await createAppAuthClient({ + appKey: 'deepl', + active: true, + }); + + let appConfig = await createAppConfig({ + disabled: false, + allowCustomConnection: true, + shared: true, + key: 'deepl', + }); + + appConfig = await appConfig.$query().withGraphFetched({ + appAuthClients: true, + }); + + expect(appConfig.canConnect).toBe(true); + }); + + it('should return false when app is disabled', async () => { + const appConfig = await createAppConfig({ + disabled: true, + allowCustomConnection: true, + }); + + expect(appConfig.canConnect).toBe(false); + }); + + it(`should return false when app doesn't allow custom connection`, async () => { + const appConfig = await createAppConfig({ + disabled: false, + allowCustomConnection: false, + }); + + expect(appConfig.canConnect).toBe(false); + }); + }); +}); From f5d796ea77ec887d02239c5278443fc21517b842 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Mon, 7 Oct 2024 09:11:55 +0000 Subject: [PATCH 02/30] feat(app-config): persist relational virtual attrs --- ...ersist_virtual_attributes_in_app_config.js | 33 +++++++++++++++++ .../backend/src/models/app-auth-client.js | 30 ++++++++++++++++ packages/backend/src/models/app-config.js | 36 ++++++++++++------- .../backend/src/models/app-config.test.js | 16 ++++----- 4 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js diff --git a/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js b/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js new file mode 100644 index 00000000..2559c66d --- /dev/null +++ b/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js @@ -0,0 +1,33 @@ +export async function up(knex) { + await knex.schema.alterTable('app_configs', (table) => { + table.boolean('can_connect').defaultTo(false); + }); + + const appConfigs = await knex('app_configs').select('*'); + + for (const appConfig of appConfigs) { + const appAuthClients = await knex('app_auth_clients').where( + 'app_key', + appConfig.key + ); + + const hasSomeActiveAppAuthClients = !!appAuthClients?.some( + (appAuthClient) => appAuthClient.active + ); + const shared = appConfig.shared; + const active = appConfig.disabled === false; + + const canConnectConditions = [hasSomeActiveAppAuthClients, shared, active]; + const canConnect = canConnectConditions.every(Boolean); + + await knex('app_configs') + .where('id', appConfig.id) + .update({ can_connect: canConnect }); + } +} + +export async function down(knex) { + await knex.schema.alterTable('app_configs', (table) => { + table.dropColumn('can_connect'); + }); +} diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index e4e9753e..ab209713 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -2,6 +2,7 @@ import AES from 'crypto-js/aes.js'; import enc from 'crypto-js/enc-utf8.js'; import appConfig from '../config/app.js'; import Base from './base.js'; +import AppConfig from './app-config.js'; class AppAuthClient extends Base { static tableName = 'app_auth_clients'; @@ -21,6 +22,17 @@ class AppAuthClient extends Base { }, }; + static relationMappings = () => ({ + appConfig: { + relation: Base.HasOneRelation, + modelClass: AppConfig, + join: { + from: 'app_auth_clients.app_key', + to: 'app_configs.key', + }, + }, + }); + encryptData() { if (!this.eligibleForEncryption()) return; @@ -48,6 +60,12 @@ class AppAuthClient extends Base { return this.authDefaults ? true : false; } + async triggerAppConfigUpdate() { + const appConfig = await this.$relatedQuery('appConfig').select('*'); + + await appConfig.$query().patch({}); + } + // TODO: Make another abstraction like beforeSave instead of using // beforeInsert and beforeUpdate separately for the same operation. async $beforeInsert(queryContext) { @@ -55,11 +73,23 @@ class AppAuthClient extends Base { this.encryptData(); } + async $afterInsert(queryContext) { + await super.$afterInsert(queryContext); + + await this.triggerAppConfigUpdate(); + } + async $beforeUpdate(opt, queryContext) { await super.$beforeUpdate(opt, queryContext); this.encryptData(); } + async $afterUpdate(queryContext) { + await super.$afterUpdate(queryContext); + + await this.triggerAppConfigUpdate(); + } + async $afterFind() { this.decryptData(); } diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index 885cbbb1..e72ef1e3 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -12,6 +12,7 @@ class AppConfig extends Base { properties: { id: { type: 'string', format: 'uuid' }, key: { type: 'string' }, + canConnect: { type: 'boolean', default: false }, allowCustomConnection: { type: 'boolean', default: false }, shared: { type: 'boolean', default: false }, disabled: { type: 'boolean', default: false }, @@ -32,30 +33,39 @@ class AppConfig extends Base { }); static get virtualAttributes() { - return ['canConnect', 'canCustomConnect']; + return ['canCustomConnect']; } get canCustomConnect() { return !this.disabled && this.allowCustomConnection; } - get canConnect() { - const hasSomeActiveAppAuthClients = !!this.appAuthClients?.some( - (appAuthClient) => appAuthClient.active - ); - const shared = this.shared; - const active = this.disabled === false; - - const conditions = [hasSomeActiveAppAuthClients, shared, active]; - - return conditions.every(Boolean); - } - async getApp() { if (!this.key) return null; return await App.findOneByKey(this.key); } + + async updateCanConnectValue() { + const appAuthClients = await this.$relatedQuery('appAuthClients'); + const hasSomeActiveAppAuthClients = !!appAuthClients?.some( + (appAuthClient) => appAuthClient.active + ); + const shared = this.shared; + const active = this.disabled === false; + + const conditions = [hasSomeActiveAppAuthClients, shared, active]; + + this.canConnect = conditions.every(Boolean); + + return this; + } + + async $beforeUpdate(opt, queryContext) { + await super.$beforeUpdate(opt, queryContext); + + await opt.old.updateCanConnectValue(); + } } export default AppConfig; diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 7c14f19e..1c9f7651 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -36,14 +36,6 @@ describe('AppConfig model', () => { expect(AppConfig.virtualAttributes).toMatchSnapshot(); }); - it('getApp should return associated application', async () => { - const appConfig = await createAppConfig({ key: 'deepl' }); - - const app = await appConfig.getApp(); - - expect(app.key).toBe('deepl'); - }); - describe('canCustomConnect', () => { it('should return true when app is enabled and allows custom connection', async () => { const appConfig = await createAppConfig({ @@ -112,4 +104,12 @@ describe('AppConfig model', () => { expect(appConfig.canConnect).toBe(false); }); }); + + it('getApp should return associated application', async () => { + const appConfig = await createAppConfig({ key: 'deepl' }); + + const app = await appConfig.getApp(); + + expect(app.key).toBe('deepl'); + }); }); From aed61209faeac0809c520a5c4bf02be30520a505 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Tue, 8 Oct 2024 12:17:44 +0000 Subject: [PATCH 03/30] feat(app-config): update canConnect upon dependent changes --- .../__snapshots__/app-config.test.js.snap | 5 ++- .../backend/src/models/app-auth-client.js | 6 +-- packages/backend/src/models/app-config.js | 35 +++++++++++++---- .../backend/src/models/app-config.test.js | 38 ++++++++++++++++--- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/packages/backend/src/models/__snapshots__/app-config.test.js.snap b/packages/backend/src/models/__snapshots__/app-config.test.js.snap index ee1e862c..d92ce25f 100644 --- a/packages/backend/src/models/__snapshots__/app-config.test.js.snap +++ b/packages/backend/src/models/__snapshots__/app-config.test.js.snap @@ -7,6 +7,10 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` "default": false, "type": "boolean", }, + "canConnect": { + "default": false, + "type": "boolean", + }, "createdAt": { "type": "string", }, @@ -38,7 +42,6 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` exports[`AppConfig model > virtualAttributes should return correct properties 1`] = ` [ - "canConnect", "canCustomConnect", ] `; diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index ab209713..72882685 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -63,7 +63,7 @@ class AppAuthClient extends Base { async triggerAppConfigUpdate() { const appConfig = await this.$relatedQuery('appConfig').select('*'); - await appConfig.$query().patch({}); + await appConfig?.updateCanConnectProperty(); } // TODO: Make another abstraction like beforeSave instead of using @@ -84,8 +84,8 @@ class AppAuthClient extends Base { this.encryptData(); } - async $afterUpdate(queryContext) { - await super.$afterUpdate(queryContext); + async $afterUpdate(opt, queryContext) { + await super.$afterUpdate(opt, queryContext); await this.triggerAppConfigUpdate(); } diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index e72ef1e3..e36cd437 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -46,25 +46,46 @@ class AppConfig extends Base { return await App.findOneByKey(this.key); } - async updateCanConnectValue() { - const appAuthClients = await this.$relatedQuery('appAuthClients'); + async computeCanConnectProperty(oldAppConfig) { + const appAuthClients = await oldAppConfig.$relatedQuery('appAuthClients'); const hasSomeActiveAppAuthClients = !!appAuthClients?.some( (appAuthClient) => appAuthClient.active ); - const shared = this.shared; - const active = this.disabled === false; + const shared = this.shared ?? oldAppConfig.shared; + const disabled = this.disabled ?? oldAppConfig.disabled; + const active = disabled === false; const conditions = [hasSomeActiveAppAuthClients, shared, active]; - this.canConnect = conditions.every(Boolean); + const canConnect = conditions.every(Boolean); - return this; + return canConnect; + } + + async updateCanConnectProperty() { + const canConnect = await this.computeCanConnectProperty(this); + + return await this.$query().patch({ + canConnect, + }); + } + + async computeAndAssignCanConnectProperty(oldAppConfig) { + this.canConnect = await this.computeCanConnectProperty(oldAppConfig); + } + + async $beforeInsert(queryContext) { + await super.$beforeInsert(queryContext); + + await this.computeAndAssignCanConnectProperty(this); } async $beforeUpdate(opt, queryContext) { await super.$beforeUpdate(opt, queryContext); - await opt.old.updateCanConnectValue(); + const oldAppConfig = opt.old; + + await this.computeAndAssignCanConnectProperty(oldAppConfig); } } diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 1c9f7651..11a37acd 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -66,24 +66,52 @@ describe('AppConfig model', () => { }); describe('canConnect', () => { - it('should return true when app is enabled, shared and allows custom connection', async () => { + it('should return true when app is enabled, shared and allows custom connection with an active app auth client at least', async () => { await createAppAuthClient({ appKey: 'deepl', active: true, }); - let appConfig = await createAppConfig({ + await createAppAuthClient({ + appKey: 'deepl', + active: false, + }); + + const appConfig = await createAppConfig({ disabled: false, allowCustomConnection: true, shared: true, key: 'deepl', }); - appConfig = await appConfig.$query().withGraphFetched({ - appAuthClients: true, + expect(appConfig.canConnect).toBe(true); + }); + + it('should return true when app is enabled, shared and allows custom connection with no active app auth client', async () => { + await createAppAuthClient({ + appKey: 'deepl', + active: false, }); - expect(appConfig.canConnect).toBe(true); + const appConfig = await createAppConfig({ + disabled: false, + allowCustomConnection: true, + shared: true, + key: 'deepl', + }); + + expect(appConfig.canConnect).toBe(false); + }); + + it('should return false when app is enabled, shared and allows custom connection without any app auth clients', async () => { + const appConfig = await createAppConfig({ + disabled: false, + allowCustomConnection: true, + shared: true, + key: 'deepl', + }); + + expect(appConfig.canConnect).toBe(false); }); it('should return false when app is disabled', async () => { From 6e42b52414bb1438c6f8bbf272786ea49b03498f Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 08:48:53 +0000 Subject: [PATCH 04/30] refactor(app-config): rename canConnect as connectionAllowed --- ...ersist_virtual_attributes_in_app_config.js | 14 +++++++---- .../__snapshots__/app-config.test.js.snap | 2 +- .../backend/src/models/app-auth-client.js | 2 +- packages/backend/src/models/app-config.js | 24 ++++++++++--------- .../backend/src/models/app-config.test.js | 12 +++++----- .../backend/src/serializers/app-config.js | 2 +- .../src/serializers/app-config.test.js | 2 +- .../test/mocks/rest/api/v1/apps/get-config.js | 2 +- .../ChooseConnectionSubstep/index.jsx | 2 +- packages/web/src/pages/Application/index.jsx | 6 ++--- packages/web/src/propTypes/propTypes.js | 2 +- 11 files changed, 38 insertions(+), 32 deletions(-) diff --git a/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js b/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js index 2559c66d..e2e94670 100644 --- a/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js +++ b/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js @@ -1,6 +1,6 @@ export async function up(knex) { await knex.schema.alterTable('app_configs', (table) => { - table.boolean('can_connect').defaultTo(false); + table.boolean('connectionAllowed').defaultTo(false); }); const appConfigs = await knex('app_configs').select('*'); @@ -17,17 +17,21 @@ export async function up(knex) { const shared = appConfig.shared; const active = appConfig.disabled === false; - const canConnectConditions = [hasSomeActiveAppAuthClients, shared, active]; - const canConnect = canConnectConditions.every(Boolean); + const connectionAllowedConditions = [ + hasSomeActiveAppAuthClients, + shared, + active, + ]; + const connectionAllowed = connectionAllowedConditions.every(Boolean); await knex('app_configs') .where('id', appConfig.id) - .update({ can_connect: canConnect }); + .update({ connection_allowed: connectionAllowed }); } } export async function down(knex) { await knex.schema.alterTable('app_configs', (table) => { - table.dropColumn('can_connect'); + table.dropColumn('connectionAllowed'); }); } diff --git a/packages/backend/src/models/__snapshots__/app-config.test.js.snap b/packages/backend/src/models/__snapshots__/app-config.test.js.snap index d92ce25f..7542159e 100644 --- a/packages/backend/src/models/__snapshots__/app-config.test.js.snap +++ b/packages/backend/src/models/__snapshots__/app-config.test.js.snap @@ -7,7 +7,7 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` "default": false, "type": "boolean", }, - "canConnect": { + "connectionAllowed": { "default": false, "type": "boolean", }, diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index 72882685..0696051c 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -63,7 +63,7 @@ class AppAuthClient extends Base { async triggerAppConfigUpdate() { const appConfig = await this.$relatedQuery('appConfig').select('*'); - await appConfig?.updateCanConnectProperty(); + await appConfig?.updateConnectionAllowedProperty(); } // TODO: Make another abstraction like beforeSave instead of using diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index e36cd437..7a95f1de 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -12,7 +12,7 @@ class AppConfig extends Base { properties: { id: { type: 'string', format: 'uuid' }, key: { type: 'string' }, - canConnect: { type: 'boolean', default: false }, + connectionAllowed: { type: 'boolean', default: false }, allowCustomConnection: { type: 'boolean', default: false }, shared: { type: 'boolean', default: false }, disabled: { type: 'boolean', default: false }, @@ -46,7 +46,7 @@ class AppConfig extends Base { return await App.findOneByKey(this.key); } - async computeCanConnectProperty(oldAppConfig) { + async computeConnectionAllowedProperty(oldAppConfig) { const appAuthClients = await oldAppConfig.$relatedQuery('appAuthClients'); const hasSomeActiveAppAuthClients = !!appAuthClients?.some( (appAuthClient) => appAuthClient.active @@ -57,27 +57,29 @@ class AppConfig extends Base { const conditions = [hasSomeActiveAppAuthClients, shared, active]; - const canConnect = conditions.every(Boolean); + const connectionAllowed = conditions.every(Boolean); - return canConnect; + return connectionAllowed; } - async updateCanConnectProperty() { - const canConnect = await this.computeCanConnectProperty(this); + async updateConnectionAllowedProperty() { + const connectionAllowed = await this.computeConnectionAllowedProperty(this); return await this.$query().patch({ - canConnect, + connectionAllowed, }); } - async computeAndAssignCanConnectProperty(oldAppConfig) { - this.canConnect = await this.computeCanConnectProperty(oldAppConfig); + async computeAndAssignConnectionAllowedProperty(oldAppConfig) { + this.connectionAllowed = await this.computeConnectionAllowedProperty( + oldAppConfig + ); } async $beforeInsert(queryContext) { await super.$beforeInsert(queryContext); - await this.computeAndAssignCanConnectProperty(this); + await this.computeAndAssignConnectionAllowedProperty(this); } async $beforeUpdate(opt, queryContext) { @@ -85,7 +87,7 @@ class AppConfig extends Base { const oldAppConfig = opt.old; - await this.computeAndAssignCanConnectProperty(oldAppConfig); + await this.computeAndAssignConnectionAllowedProperty(oldAppConfig); } } diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 11a37acd..26f08077 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -65,7 +65,7 @@ describe('AppConfig model', () => { }); }); - describe('canConnect', () => { + describe('connectionAllowed', () => { it('should return true when app is enabled, shared and allows custom connection with an active app auth client at least', async () => { await createAppAuthClient({ appKey: 'deepl', @@ -84,7 +84,7 @@ describe('AppConfig model', () => { key: 'deepl', }); - expect(appConfig.canConnect).toBe(true); + expect(appConfig.connectionAllowed).toBe(true); }); it('should return true when app is enabled, shared and allows custom connection with no active app auth client', async () => { @@ -100,7 +100,7 @@ describe('AppConfig model', () => { key: 'deepl', }); - expect(appConfig.canConnect).toBe(false); + expect(appConfig.connectionAllowed).toBe(false); }); it('should return false when app is enabled, shared and allows custom connection without any app auth clients', async () => { @@ -111,7 +111,7 @@ describe('AppConfig model', () => { key: 'deepl', }); - expect(appConfig.canConnect).toBe(false); + expect(appConfig.connectionAllowed).toBe(false); }); it('should return false when app is disabled', async () => { @@ -120,7 +120,7 @@ describe('AppConfig model', () => { allowCustomConnection: true, }); - expect(appConfig.canConnect).toBe(false); + expect(appConfig.connectionAllowed).toBe(false); }); it(`should return false when app doesn't allow custom connection`, async () => { @@ -129,7 +129,7 @@ describe('AppConfig model', () => { allowCustomConnection: false, }); - expect(appConfig.canConnect).toBe(false); + expect(appConfig.connectionAllowed).toBe(false); }); }); diff --git a/packages/backend/src/serializers/app-config.js b/packages/backend/src/serializers/app-config.js index 0efd562b..56e6243e 100644 --- a/packages/backend/src/serializers/app-config.js +++ b/packages/backend/src/serializers/app-config.js @@ -5,7 +5,7 @@ const appConfigSerializer = (appConfig) => { allowCustomConnection: appConfig.allowCustomConnection, shared: appConfig.shared, disabled: appConfig.disabled, - canConnect: appConfig.canConnect, + connectionAllowed: appConfig.connectionAllowed, canCustomConnect: appConfig.canCustomConnect, createdAt: appConfig.createdAt.getTime(), updatedAt: appConfig.updatedAt.getTime(), diff --git a/packages/backend/src/serializers/app-config.test.js b/packages/backend/src/serializers/app-config.test.js index c0ede918..9ade2769 100644 --- a/packages/backend/src/serializers/app-config.test.js +++ b/packages/backend/src/serializers/app-config.test.js @@ -16,7 +16,7 @@ describe('appConfig serializer', () => { allowCustomConnection: appConfig.allowCustomConnection, shared: appConfig.shared, disabled: appConfig.disabled, - canConnect: appConfig.canConnect, + connectionAllowed: appConfig.connectionAllowed, canCustomConnect: appConfig.canCustomConnect, createdAt: appConfig.createdAt.getTime(), updatedAt: appConfig.updatedAt.getTime(), diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-config.js b/packages/backend/test/mocks/rest/api/v1/apps/get-config.js index 5faee118..4cc6e011 100644 --- a/packages/backend/test/mocks/rest/api/v1/apps/get-config.js +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-config.js @@ -6,7 +6,7 @@ const getAppConfigMock = (appConfig) => { allowCustomConnection: appConfig.allowCustomConnection, shared: appConfig.shared, disabled: appConfig.disabled, - canConnect: appConfig.canConnect, + connectionAllowed: appConfig.connectionAllowed, canCustomConnect: appConfig.canCustomConnect, createdAt: appConfig.createdAt.getTime(), updatedAt: appConfig.updatedAt.getTime(), diff --git a/packages/web/src/components/ChooseConnectionSubstep/index.jsx b/packages/web/src/components/ChooseConnectionSubstep/index.jsx index 4792045e..345e0dac 100644 --- a/packages/web/src/components/ChooseConnectionSubstep/index.jsx +++ b/packages/web/src/components/ChooseConnectionSubstep/index.jsx @@ -100,7 +100,7 @@ function ChooseConnectionSubstep(props) { }); } - if (appConfig?.data?.canConnect) { + if (appConfig?.data?.connectionAllowed) { options.push({ label: formatMessage('chooseConnectionSubstep.addNewSharedConnection'), value: ADD_SHARED_CONNECTION_VALUE, diff --git a/packages/web/src/pages/Application/index.jsx b/packages/web/src/pages/Application/index.jsx index e143c01b..bd3c9540 100644 --- a/packages/web/src/pages/Application/index.jsx +++ b/packages/web/src/pages/Application/index.jsx @@ -77,14 +77,14 @@ export default function Application() { const connectionOptions = React.useMemo(() => { const shouldHaveCustomConnection = - appConfig?.data?.canConnect && appConfig?.data?.canCustomConnect; + appConfig?.data?.connectionAllowed && appConfig?.data?.canCustomConnect; const options = [ { label: formatMessage('app.addConnection'), key: 'addConnection', 'data-test': 'add-connection-button', - to: URLS.APP_ADD_CONNECTION(appKey, appConfig?.data?.canConnect), + to: URLS.APP_ADD_CONNECTION(appKey, appConfig?.data?.connectionAllowed), disabled: !currentUserAbility.can('create', 'Connection'), }, ]; @@ -155,7 +155,7 @@ export default function Application() { disabled={ !allowed || (appConfig?.data && - !appConfig?.data?.canConnect && + !appConfig?.data?.connectionAllowed && !appConfig?.data?.canCustomConnect) || connectionOptions.every(({ disabled }) => disabled) } diff --git a/packages/web/src/propTypes/propTypes.js b/packages/web/src/propTypes/propTypes.js index 29629d23..ef730f33 100644 --- a/packages/web/src/propTypes/propTypes.js +++ b/packages/web/src/propTypes/propTypes.js @@ -460,7 +460,7 @@ export const AppConfigPropType = PropTypes.shape({ id: PropTypes.string, key: PropTypes.string, allowCustomConnection: PropTypes.bool, - canConnect: PropTypes.bool, + connectionAllowed: PropTypes.bool, canCustomConnect: PropTypes.bool, shared: PropTypes.bool, disabled: PropTypes.bool, From a76bee51fc3fdae00bac81478934c69c9d9f5f0a Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 09:35:36 +0000 Subject: [PATCH 05/30] refactor(app-config): remove canCustomConnect virtual attribute --- .../src/models/__snapshots__/app-config.test.js.snap | 6 ------ packages/backend/src/models/app-config.js | 8 -------- packages/backend/src/models/app-config.test.js | 8 ++++---- packages/backend/src/serializers/app-config.js | 1 - packages/backend/src/serializers/app-config.test.js | 1 - .../backend/test/mocks/rest/api/v1/apps/get-config.js | 1 - .../web/src/components/ChooseConnectionSubstep/index.jsx | 5 ++++- packages/web/src/pages/Application/index.jsx | 6 ++++-- packages/web/src/propTypes/propTypes.js | 1 - 9 files changed, 12 insertions(+), 25 deletions(-) diff --git a/packages/backend/src/models/__snapshots__/app-config.test.js.snap b/packages/backend/src/models/__snapshots__/app-config.test.js.snap index 7542159e..81015bef 100644 --- a/packages/backend/src/models/__snapshots__/app-config.test.js.snap +++ b/packages/backend/src/models/__snapshots__/app-config.test.js.snap @@ -39,9 +39,3 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` "type": "object", } `; - -exports[`AppConfig model > virtualAttributes should return correct properties 1`] = ` -[ - "canCustomConnect", -] -`; diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index 7a95f1de..15968890 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -32,14 +32,6 @@ class AppConfig extends Base { }, }); - static get virtualAttributes() { - return ['canCustomConnect']; - } - - get canCustomConnect() { - return !this.disabled && this.allowCustomConnection; - } - async getApp() { if (!this.key) return null; diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 26f08077..10534857 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -36,14 +36,14 @@ describe('AppConfig model', () => { expect(AppConfig.virtualAttributes).toMatchSnapshot(); }); - describe('canCustomConnect', () => { + describe('allowCustomConnection', () => { it('should return true when app is enabled and allows custom connection', async () => { const appConfig = await createAppConfig({ disabled: false, allowCustomConnection: true, }); - expect(appConfig.canCustomConnect).toBe(true); + expect(appConfig.allowCustomConnection).toBe(true); }); it('should return false when app is disabled', async () => { @@ -52,7 +52,7 @@ describe('AppConfig model', () => { allowCustomConnection: true, }); - expect(appConfig.canCustomConnect).toBe(false); + expect(appConfig.allowCustomConnection).toBe(false); }); it(`should return false when app doesn't allow custom connection`, async () => { @@ -61,7 +61,7 @@ describe('AppConfig model', () => { allowCustomConnection: false, }); - expect(appConfig.canCustomConnect).toBe(false); + expect(appConfig.allowCustomConnection).toBe(false); }); }); diff --git a/packages/backend/src/serializers/app-config.js b/packages/backend/src/serializers/app-config.js index 56e6243e..7355f467 100644 --- a/packages/backend/src/serializers/app-config.js +++ b/packages/backend/src/serializers/app-config.js @@ -6,7 +6,6 @@ const appConfigSerializer = (appConfig) => { shared: appConfig.shared, disabled: appConfig.disabled, connectionAllowed: appConfig.connectionAllowed, - canCustomConnect: appConfig.canCustomConnect, createdAt: appConfig.createdAt.getTime(), updatedAt: appConfig.updatedAt.getTime(), }; diff --git a/packages/backend/src/serializers/app-config.test.js b/packages/backend/src/serializers/app-config.test.js index 9ade2769..cbd8d5e1 100644 --- a/packages/backend/src/serializers/app-config.test.js +++ b/packages/backend/src/serializers/app-config.test.js @@ -17,7 +17,6 @@ describe('appConfig serializer', () => { shared: appConfig.shared, disabled: appConfig.disabled, connectionAllowed: appConfig.connectionAllowed, - canCustomConnect: appConfig.canCustomConnect, createdAt: appConfig.createdAt.getTime(), updatedAt: appConfig.updatedAt.getTime(), }; diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-config.js b/packages/backend/test/mocks/rest/api/v1/apps/get-config.js index 4cc6e011..b854301a 100644 --- a/packages/backend/test/mocks/rest/api/v1/apps/get-config.js +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-config.js @@ -7,7 +7,6 @@ const getAppConfigMock = (appConfig) => { shared: appConfig.shared, disabled: appConfig.disabled, connectionAllowed: appConfig.connectionAllowed, - canCustomConnect: appConfig.canCustomConnect, createdAt: appConfig.createdAt.getTime(), updatedAt: appConfig.updatedAt.getTime(), }, diff --git a/packages/web/src/components/ChooseConnectionSubstep/index.jsx b/packages/web/src/components/ChooseConnectionSubstep/index.jsx index 345e0dac..740e541b 100644 --- a/packages/web/src/components/ChooseConnectionSubstep/index.jsx +++ b/packages/web/src/components/ChooseConnectionSubstep/index.jsx @@ -93,7 +93,10 @@ function ChooseConnectionSubstep(props) { appWithConnections?.map((connection) => optionGenerator(connection)) || []; - if (!appConfig?.data || appConfig?.data?.canCustomConnect) { + if ( + !appConfig?.data || + (!appConfig.data?.disabled && appConfig.data?.allowCustomConnection) + ) { options.push({ label: formatMessage('chooseConnectionSubstep.addNewConnection'), value: ADD_CONNECTION_VALUE, diff --git a/packages/web/src/pages/Application/index.jsx b/packages/web/src/pages/Application/index.jsx index bd3c9540..bb8c2fdc 100644 --- a/packages/web/src/pages/Application/index.jsx +++ b/packages/web/src/pages/Application/index.jsx @@ -77,7 +77,8 @@ export default function Application() { const connectionOptions = React.useMemo(() => { const shouldHaveCustomConnection = - appConfig?.data?.connectionAllowed && appConfig?.data?.canCustomConnect; + appConfig?.data?.connectionAllowed && + appConfig?.data?.allowCustomConnection; const options = [ { @@ -155,8 +156,9 @@ export default function Application() { disabled={ !allowed || (appConfig?.data && + !appConfig?.data?.disabled && !appConfig?.data?.connectionAllowed && - !appConfig?.data?.canCustomConnect) || + !appConfig?.data?.allowCustomConnection) || connectionOptions.every(({ disabled }) => disabled) } options={connectionOptions} diff --git a/packages/web/src/propTypes/propTypes.js b/packages/web/src/propTypes/propTypes.js index ef730f33..f62c2d57 100644 --- a/packages/web/src/propTypes/propTypes.js +++ b/packages/web/src/propTypes/propTypes.js @@ -461,7 +461,6 @@ export const AppConfigPropType = PropTypes.shape({ key: PropTypes.string, allowCustomConnection: PropTypes.bool, connectionAllowed: PropTypes.bool, - canCustomConnect: PropTypes.bool, shared: PropTypes.bool, disabled: PropTypes.bool, }); From 0bbe362660c88541526fe06f6da1dbc19f4cf4d0 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 10:10:40 +0000 Subject: [PATCH 06/30] refactor(app-config): rename allow_custom_connection as custom_connection_allowed --- .../api/v1/admin/apps/create-config.ee.js | 4 +- .../v1/admin/apps/create-config.ee.test.js | 4 +- .../api/v1/admin/apps/update-config.ee.js | 4 +- .../v1/admin/apps/update-config.ee.test.js | 8 ++-- .../api/v1/apps/create-connection.test.js | 4 +- .../api/v1/apps/get-config.ee.test.js | 2 +- ...connection_as_custom_connection_allowed.js | 11 ++++++ .../__snapshots__/app-config.test.js.snap | 10 +++-- packages/backend/src/models/app-config.js | 2 +- .../backend/src/models/app-config.test.js | 39 +++---------------- packages/backend/src/models/connection.js | 4 +- .../backend/src/serializers/app-config.js | 2 +- .../src/serializers/app-config.test.js | 2 +- .../rest/api/v1/admin/apps/create-config.js | 2 +- .../test/mocks/rest/api/v1/apps/get-config.js | 2 +- 15 files changed, 42 insertions(+), 58 deletions(-) create mode 100644 packages/backend/src/db/migrations/20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js diff --git a/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js index 7d5021aa..edf0ff9a 100644 --- a/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js +++ b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js @@ -10,11 +10,11 @@ export default async (request, response) => { }; const appConfigParams = (request) => { - const { allowCustomConnection, shared, disabled } = request.body; + const { customConnectionAllowed, shared, disabled } = request.body; return { key: request.params.appKey, - allowCustomConnection, + customConnectionAllowed, shared, disabled, }; diff --git a/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js index ad9b7600..f92df586 100644 --- a/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js +++ b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js @@ -23,7 +23,7 @@ describe('POST /api/v1/admin/apps/:appKey/config', () => { it('should return created app config', async () => { const appConfig = { - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, disabled: false, }; @@ -44,7 +44,7 @@ describe('POST /api/v1/admin/apps/:appKey/config', () => { it('should return HTTP 422 for already existing app config', async () => { const appConfig = { key: 'gitlab', - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, disabled: false, }; diff --git a/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js b/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js index 0467d573..ff94c583 100644 --- a/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js +++ b/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js @@ -14,10 +14,10 @@ export default async (request, response) => { }; const appConfigParams = (request) => { - const { allowCustomConnection, shared, disabled } = request.body; + const { customConnectionAllowed, shared, disabled } = request.body; return { - allowCustomConnection, + customConnectionAllowed, shared, disabled, }; diff --git a/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.test.js b/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.test.js index 20d7f8ae..c5436ad5 100644 --- a/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.test.js +++ b/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.test.js @@ -24,7 +24,7 @@ describe('PATCH /api/v1/admin/apps/:appKey/config', () => { it('should return updated app config', async () => { const appConfig = { key: 'gitlab', - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, disabled: false, }; @@ -34,7 +34,7 @@ describe('PATCH /api/v1/admin/apps/:appKey/config', () => { const newAppConfigValues = { shared: false, disabled: true, - allowCustomConnection: false, + customConnectionAllowed: false, }; const response = await request(app) @@ -55,7 +55,7 @@ describe('PATCH /api/v1/admin/apps/:appKey/config', () => { const appConfig = { shared: false, disabled: true, - allowCustomConnection: false, + customConnectionAllowed: false, }; await request(app) @@ -68,7 +68,7 @@ describe('PATCH /api/v1/admin/apps/:appKey/config', () => { it('should return HTTP 422 for invalid app config data', async () => { const appConfig = { key: 'gitlab', - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, disabled: false, }; diff --git a/packages/backend/src/controllers/api/v1/apps/create-connection.test.js b/packages/backend/src/controllers/api/v1/apps/create-connection.test.js index c6e3634f..4a12aa99 100644 --- a/packages/backend/src/controllers/api/v1/apps/create-connection.test.js +++ b/packages/backend/src/controllers/api/v1/apps/create-connection.test.js @@ -155,7 +155,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => { await createAppConfig({ key: 'gitlab', disabled: false, - allowCustomConnection: true, + customConnectionAllowed: true, }); }); @@ -218,7 +218,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => { await createAppConfig({ key: 'gitlab', disabled: false, - allowCustomConnection: false, + customConnectionAllowed: false, }); }); diff --git a/packages/backend/src/controllers/api/v1/apps/get-config.ee.test.js b/packages/backend/src/controllers/api/v1/apps/get-config.ee.test.js index d10c2bd7..a39b315b 100644 --- a/packages/backend/src/controllers/api/v1/apps/get-config.ee.test.js +++ b/packages/backend/src/controllers/api/v1/apps/get-config.ee.test.js @@ -17,7 +17,7 @@ describe('GET /api/v1/apps/:appKey/config', () => { appConfig = await createAppConfig({ key: 'deepl', - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, disabled: false, }); diff --git a/packages/backend/src/db/migrations/20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js b/packages/backend/src/db/migrations/20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js new file mode 100644 index 00000000..b8fab01a --- /dev/null +++ b/packages/backend/src/db/migrations/20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js @@ -0,0 +1,11 @@ +export async function up(knex) { + return knex.schema.alterTable('app_configs', (table) => { + table.renameColumn('allow_custom_connection', 'custom_connection_allowed'); + }); +} + +export async function down(knex) { + return knex.schema.alterTable('app_configs', (table) => { + table.renameColumn('custom_connection_allowed', 'allow_custom_connection'); + }); +} diff --git a/packages/backend/src/models/__snapshots__/app-config.test.js.snap b/packages/backend/src/models/__snapshots__/app-config.test.js.snap index 81015bef..e620514d 100644 --- a/packages/backend/src/models/__snapshots__/app-config.test.js.snap +++ b/packages/backend/src/models/__snapshots__/app-config.test.js.snap @@ -3,10 +3,6 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` { "properties": { - "allowCustomConnection": { - "default": false, - "type": "boolean", - }, "connectionAllowed": { "default": false, "type": "boolean", @@ -14,6 +10,10 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` "createdAt": { "type": "string", }, + "customConnectionAllowed": { + "default": false, + "type": "boolean", + }, "disabled": { "default": false, "type": "boolean", @@ -39,3 +39,5 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` "type": "object", } `; + +exports[`AppConfig model > virtualAttributes should return correct properties 1`] = `null`; diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index 15968890..1fb0ee46 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -13,7 +13,7 @@ class AppConfig extends Base { id: { type: 'string', format: 'uuid' }, key: { type: 'string' }, connectionAllowed: { type: 'boolean', default: false }, - allowCustomConnection: { type: 'boolean', default: false }, + customConnectionAllowed: { type: 'boolean', default: false }, shared: { type: 'boolean', default: false }, disabled: { type: 'boolean', default: false }, createdAt: { type: 'string' }, diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 10534857..6ae574fb 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -36,35 +36,6 @@ describe('AppConfig model', () => { expect(AppConfig.virtualAttributes).toMatchSnapshot(); }); - describe('allowCustomConnection', () => { - it('should return true when app is enabled and allows custom connection', async () => { - const appConfig = await createAppConfig({ - disabled: false, - allowCustomConnection: true, - }); - - expect(appConfig.allowCustomConnection).toBe(true); - }); - - it('should return false when app is disabled', async () => { - const appConfig = await createAppConfig({ - disabled: true, - allowCustomConnection: true, - }); - - expect(appConfig.allowCustomConnection).toBe(false); - }); - - it(`should return false when app doesn't allow custom connection`, async () => { - const appConfig = await createAppConfig({ - disabled: false, - allowCustomConnection: false, - }); - - expect(appConfig.allowCustomConnection).toBe(false); - }); - }); - describe('connectionAllowed', () => { it('should return true when app is enabled, shared and allows custom connection with an active app auth client at least', async () => { await createAppAuthClient({ @@ -79,7 +50,7 @@ describe('AppConfig model', () => { const appConfig = await createAppConfig({ disabled: false, - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, key: 'deepl', }); @@ -95,7 +66,7 @@ describe('AppConfig model', () => { const appConfig = await createAppConfig({ disabled: false, - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, key: 'deepl', }); @@ -106,7 +77,7 @@ describe('AppConfig model', () => { it('should return false when app is enabled, shared and allows custom connection without any app auth clients', async () => { const appConfig = await createAppConfig({ disabled: false, - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, key: 'deepl', }); @@ -117,7 +88,7 @@ describe('AppConfig model', () => { it('should return false when app is disabled', async () => { const appConfig = await createAppConfig({ disabled: true, - allowCustomConnection: true, + customConnectionAllowed: true, }); expect(appConfig.connectionAllowed).toBe(false); @@ -126,7 +97,7 @@ describe('AppConfig model', () => { it(`should return false when app doesn't allow custom connection`, async () => { const appConfig = await createAppConfig({ disabled: false, - allowCustomConnection: false, + customConnectionAllowed: false, }); expect(appConfig.connectionAllowed).toBe(false); diff --git a/packages/backend/src/models/connection.js b/packages/backend/src/models/connection.js index c743bbdc..325e1e07 100644 --- a/packages/backend/src/models/connection.js +++ b/packages/backend/src/models/connection.js @@ -89,7 +89,7 @@ class Connection extends Base { } if (this.appConfig) { - return !this.appConfig.disabled && this.appConfig.allowCustomConnection; + return !this.appConfig.disabled && this.appConfig.customConnectionAllowed; } return true; @@ -144,7 +144,7 @@ class Connection extends Base { ); } - if (!appConfig.allowCustomConnection && this.formattedData) { + if (!appConfig.customConnectionAllowed && this.formattedData) { throw new NotAuthorizedError( `New custom connections have been disabled for ${app.name}!` ); diff --git a/packages/backend/src/serializers/app-config.js b/packages/backend/src/serializers/app-config.js index 7355f467..97afcb76 100644 --- a/packages/backend/src/serializers/app-config.js +++ b/packages/backend/src/serializers/app-config.js @@ -2,7 +2,7 @@ const appConfigSerializer = (appConfig) => { return { id: appConfig.id, key: appConfig.key, - allowCustomConnection: appConfig.allowCustomConnection, + customConnectionAllowed: appConfig.customConnectionAllowed, shared: appConfig.shared, disabled: appConfig.disabled, connectionAllowed: appConfig.connectionAllowed, diff --git a/packages/backend/src/serializers/app-config.test.js b/packages/backend/src/serializers/app-config.test.js index cbd8d5e1..edf1d107 100644 --- a/packages/backend/src/serializers/app-config.test.js +++ b/packages/backend/src/serializers/app-config.test.js @@ -13,7 +13,7 @@ describe('appConfig serializer', () => { const expectedPayload = { id: appConfig.id, key: appConfig.key, - allowCustomConnection: appConfig.allowCustomConnection, + customConnectionAllowed: appConfig.customConnectionAllowed, shared: appConfig.shared, disabled: appConfig.disabled, connectionAllowed: appConfig.connectionAllowed, diff --git a/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js b/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js index a1c1aad4..52e425ab 100644 --- a/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js +++ b/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js @@ -2,7 +2,7 @@ const createAppConfigMock = (appConfig) => { return { data: { key: appConfig.key, - allowCustomConnection: appConfig.allowCustomConnection, + customConnectionAllowed: appConfig.customConnectionAllowed, shared: appConfig.shared, disabled: appConfig.disabled, }, diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-config.js b/packages/backend/test/mocks/rest/api/v1/apps/get-config.js index b854301a..60772644 100644 --- a/packages/backend/test/mocks/rest/api/v1/apps/get-config.js +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-config.js @@ -3,7 +3,7 @@ const getAppConfigMock = (appConfig) => { data: { id: appConfig.id, key: appConfig.key, - allowCustomConnection: appConfig.allowCustomConnection, + customConnectionAllowed: appConfig.customConnectionAllowed, shared: appConfig.shared, disabled: appConfig.disabled, connectionAllowed: appConfig.connectionAllowed, From 73edb45ff7f779c48d8d9d1c7f6cd012adf175fa Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 12:03:57 +0000 Subject: [PATCH 07/30] refactor(app-config): rename allowCustomConnection as customConnectionAllowed --- ...241002121145_add_connection_allowed_to_app_configs.js} | 0 ...ection_as_custom_connection_allowed_in_app_configs.js} | 0 .../e2e-tests/fixtures/admin/application-settings-page.js | 8 ++++++-- .../components/AdminApplicationCreateAuthClient/index.jsx | 4 ++-- .../web/src/components/AdminApplicationSettings/index.jsx | 7 ++++--- .../web/src/components/ChooseConnectionSubstep/index.jsx | 2 +- packages/web/src/locales/en.json | 2 +- packages/web/src/pages/Application/index.jsx | 4 ++-- packages/web/src/propTypes/propTypes.js | 2 +- 9 files changed, 17 insertions(+), 12 deletions(-) rename packages/backend/src/db/migrations/{20241002121145_persist_virtual_attributes_in_app_config.js => 20241002121145_add_connection_allowed_to_app_configs.js} (100%) rename packages/backend/src/db/migrations/{20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js => 20241009094438_rename_allow_custom_connection_as_custom_connection_allowed_in_app_configs.js} (100%) diff --git a/packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js b/packages/backend/src/db/migrations/20241002121145_add_connection_allowed_to_app_configs.js similarity index 100% rename from packages/backend/src/db/migrations/20241002121145_persist_virtual_attributes_in_app_config.js rename to packages/backend/src/db/migrations/20241002121145_add_connection_allowed_to_app_configs.js diff --git a/packages/backend/src/db/migrations/20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js b/packages/backend/src/db/migrations/20241009094438_rename_allow_custom_connection_as_custom_connection_allowed_in_app_configs.js similarity index 100% rename from packages/backend/src/db/migrations/20241009094438_rename_app_config_allow_custom_connection_as_custom_connection_allowed.js rename to packages/backend/src/db/migrations/20241009094438_rename_allow_custom_connection_as_custom_connection_allowed_in_app_configs.js diff --git a/packages/e2e-tests/fixtures/admin/application-settings-page.js b/packages/e2e-tests/fixtures/admin/application-settings-page.js index 37dda591..57858ccb 100644 --- a/packages/e2e-tests/fixtures/admin/application-settings-page.js +++ b/packages/e2e-tests/fixtures/admin/application-settings-page.js @@ -8,11 +8,15 @@ export class AdminApplicationSettingsPage extends AuthenticatedPage { constructor(page) { super(page); - this.allowCustomConnectionsSwitch = this.page.locator('[name="allowCustomConnection"]'); + this.allowCustomConnectionsSwitch = this.page.locator( + '[name="customConnectionAllowed"]' + ); this.allowSharedConnectionsSwitch = this.page.locator('[name="shared"]'); this.disableConnectionsSwitch = this.page.locator('[name="disabled"]'); this.saveButton = this.page.getByTestId('submit-button'); - this.successSnackbar = this.page.getByTestId('snackbar-save-admin-apps-settings-success'); + this.successSnackbar = this.page.getByTestId( + 'snackbar-save-admin-apps-settings-success' + ); } async allowCustomConnections() { diff --git a/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx b/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx index dd385217..75f2b79b 100644 --- a/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx +++ b/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx @@ -20,7 +20,7 @@ function AdminApplicationCreateAuthClient(props) { const { mutateAsync: createAppConfig, isPending: isCreateAppConfigPending, - error: createAppConfigError + error: createAppConfigError, } = useAdminCreateAppConfig(props.appKey); const { @@ -34,7 +34,7 @@ function AdminApplicationCreateAuthClient(props) { if (!appConfigId) { const { data: appConfigData } = await createAppConfig({ - allowCustomConnection: true, + customConnectionAllowed: true, shared: false, disabled: false, }); diff --git a/packages/web/src/components/AdminApplicationSettings/index.jsx b/packages/web/src/components/AdminApplicationSettings/index.jsx index b24d2557..34ef8d0c 100644 --- a/packages/web/src/components/AdminApplicationSettings/index.jsx +++ b/packages/web/src/components/AdminApplicationSettings/index.jsx @@ -46,7 +46,8 @@ function AdminApplicationSettings(props) { const defaultValues = useMemo( () => ({ - allowCustomConnection: appConfig?.data?.allowCustomConnection || false, + customConnectionAllowed: + appConfig?.data?.customConnectionAllowed || false, shared: appConfig?.data?.shared || false, disabled: appConfig?.data?.disabled || false, }), @@ -61,8 +62,8 @@ function AdminApplicationSettings(props) { { const shouldHaveCustomConnection = appConfig?.data?.connectionAllowed && - appConfig?.data?.allowCustomConnection; + appConfig?.data?.customConnectionAllowed; const options = [ { @@ -158,7 +158,7 @@ export default function Application() { (appConfig?.data && !appConfig?.data?.disabled && !appConfig?.data?.connectionAllowed && - !appConfig?.data?.allowCustomConnection) || + !appConfig?.data?.customConnectionAllowed) || connectionOptions.every(({ disabled }) => disabled) } options={connectionOptions} diff --git a/packages/web/src/propTypes/propTypes.js b/packages/web/src/propTypes/propTypes.js index f62c2d57..82d6fd6b 100644 --- a/packages/web/src/propTypes/propTypes.js +++ b/packages/web/src/propTypes/propTypes.js @@ -459,7 +459,7 @@ export const SamlAuthProviderRolePropType = PropTypes.shape({ export const AppConfigPropType = PropTypes.shape({ id: PropTypes.string, key: PropTypes.string, - allowCustomConnection: PropTypes.bool, + customConnectionAllowed: PropTypes.bool, connectionAllowed: PropTypes.bool, shared: PropTypes.bool, disabled: PropTypes.bool, From 8189cbc171d456bcd2b39ab81417b5c9f9af8685 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 12:12:04 +0000 Subject: [PATCH 08/30] fix(app-config): use correct case in connection_allowed --- .../20241002121145_add_connection_allowed_to_app_configs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/db/migrations/20241002121145_add_connection_allowed_to_app_configs.js b/packages/backend/src/db/migrations/20241002121145_add_connection_allowed_to_app_configs.js index e2e94670..3b12b083 100644 --- a/packages/backend/src/db/migrations/20241002121145_add_connection_allowed_to_app_configs.js +++ b/packages/backend/src/db/migrations/20241002121145_add_connection_allowed_to_app_configs.js @@ -1,6 +1,6 @@ export async function up(knex) { await knex.schema.alterTable('app_configs', (table) => { - table.boolean('connectionAllowed').defaultTo(false); + table.boolean('connection_allowed').defaultTo(false); }); const appConfigs = await knex('app_configs').select('*'); @@ -32,6 +32,6 @@ export async function up(knex) { export async function down(knex) { await knex.schema.alterTable('app_configs', (table) => { - table.dropColumn('connectionAllowed'); + table.dropColumn('connection_allowed'); }); } From 4ca84aa515b65d0dcc182410073a8982f1641ed4 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 13:53:49 +0000 Subject: [PATCH 09/30] refactor(app-auth-client): remove redundant column selection --- packages/backend/src/models/app-auth-client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index 0696051c..e3593c4c 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -61,7 +61,7 @@ class AppAuthClient extends Base { } async triggerAppConfigUpdate() { - const appConfig = await this.$relatedQuery('appConfig').select('*'); + const appConfig = await this.$relatedQuery('appConfig'); await appConfig?.updateConnectionAllowedProperty(); } From 6791e002ffce16e1a5e7cba82ec6d68c405d9544 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 9 Oct 2024 13:59:36 +0000 Subject: [PATCH 10/30] test(app-config): remove redundant virtual attributes test case --- .../backend/src/models/__snapshots__/app-config.test.js.snap | 2 -- packages/backend/src/models/app-config.test.js | 4 ---- 2 files changed, 6 deletions(-) diff --git a/packages/backend/src/models/__snapshots__/app-config.test.js.snap b/packages/backend/src/models/__snapshots__/app-config.test.js.snap index e620514d..aea9fa56 100644 --- a/packages/backend/src/models/__snapshots__/app-config.test.js.snap +++ b/packages/backend/src/models/__snapshots__/app-config.test.js.snap @@ -39,5 +39,3 @@ exports[`AppConfig model > jsonSchema should have correct validations 1`] = ` "type": "object", } `; - -exports[`AppConfig model > virtualAttributes should return correct properties 1`] = `null`; diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 6ae574fb..7517449f 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -32,10 +32,6 @@ describe('AppConfig model', () => { expect(relationMappings).toStrictEqual(expectedRelations); }); - it('virtualAttributes should return correct properties', () => { - expect(AppConfig.virtualAttributes).toMatchSnapshot(); - }); - describe('connectionAllowed', () => { it('should return true when app is enabled, shared and allows custom connection with an active app auth client at least', async () => { await createAppAuthClient({ From d87ee4daa32abffee83db07251ac975aa66045dd Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Tue, 15 Oct 2024 13:53:16 +0200 Subject: [PATCH 11/30] refactor: Move and adjust getApp tests for app config model --- .../backend/src/models/app-config.test.js | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 7517449f..786924fc 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -2,6 +2,7 @@ import { describe, it, expect } from 'vitest'; import Base from './base.js'; import AppConfig from './app-config.js'; +import App from './app.js'; import AppAuthClient from './app-auth-client.js'; import { createAppConfig } from '../../test/factories/app-config.js'; import { createAppAuthClient } from '../../test/factories/app-auth-client.js'; @@ -32,6 +33,25 @@ describe('AppConfig model', () => { expect(relationMappings).toStrictEqual(expectedRelations); }); + describe('getApp', () => { + it('getApp should return null if there is no key', async () => { + const appConfig = new AppConfig(); + const app = await appConfig.getApp(); + + expect(app).toBeNull(); + }); + + it('getApp should return app with provided key', async () => { + const appConfig = new AppConfig(); + appConfig.key = 'deepl'; + + const app = await appConfig.getApp(); + const expectedApp = await App.findOneByKey(appConfig.key); + + expect(app).toStrictEqual(expectedApp); + }); + }); + describe('connectionAllowed', () => { it('should return true when app is enabled, shared and allows custom connection with an active app auth client at least', async () => { await createAppAuthClient({ @@ -99,12 +119,4 @@ describe('AppConfig model', () => { expect(appConfig.connectionAllowed).toBe(false); }); }); - - it('getApp should return associated application', async () => { - const appConfig = await createAppConfig({ key: 'deepl' }); - - const app = await appConfig.getApp(); - - expect(app.key).toBe('deepl'); - }); }); From 91993dbb07e1bddd8556935f2d71bc2f308149b1 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Tue, 15 Oct 2024 14:22:38 +0200 Subject: [PATCH 12/30] refactor: AppConfig model and corresponding tests --- packages/backend/src/models/app-config.js | 47 +++++---- .../backend/src/models/app-config.test.js | 99 +++++++++++++++++-- 2 files changed, 111 insertions(+), 35 deletions(-) diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index 1fb0ee46..465600be 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -38,48 +38,45 @@ class AppConfig extends Base { return await App.findOneByKey(this.key); } - async computeConnectionAllowedProperty(oldAppConfig) { - const appAuthClients = await oldAppConfig.$relatedQuery('appAuthClients'); - const hasSomeActiveAppAuthClients = !!appAuthClients?.some( - (appAuthClient) => appAuthClient.active - ); - const shared = this.shared ?? oldAppConfig.shared; - const disabled = this.disabled ?? oldAppConfig.disabled; - const active = disabled === false; - - const conditions = [hasSomeActiveAppAuthClients, shared, active]; - - const connectionAllowed = conditions.every(Boolean); - - return connectionAllowed; - } - async updateConnectionAllowedProperty() { - const connectionAllowed = await this.computeConnectionAllowedProperty(this); + const connectionAllowed = await this.computeConnectionAllowedProperty(); return await this.$query().patch({ connectionAllowed, }); } - async computeAndAssignConnectionAllowedProperty(oldAppConfig) { - this.connectionAllowed = await this.computeConnectionAllowedProperty( - oldAppConfig - ); + async computeAndAssignConnectionAllowedProperty() { + this.connectionAllowed = await this.computeConnectionAllowedProperty(); + } + + async computeConnectionAllowedProperty() { + const appAuthClients = await this.$relatedQuery('appAuthClients'); + + const hasSomeActiveAppAuthClients = + appAuthClients?.some((appAuthClient) => appAuthClient.active) || false; + + const conditions = [ + hasSomeActiveAppAuthClients, + this.shared, + !this.disabled, + ]; + + const connectionAllowed = conditions.every(Boolean); + + return connectionAllowed; } async $beforeInsert(queryContext) { await super.$beforeInsert(queryContext); - await this.computeAndAssignConnectionAllowedProperty(this); + await this.computeAndAssignConnectionAllowedProperty(); } async $beforeUpdate(opt, queryContext) { await super.$beforeUpdate(opt, queryContext); - const oldAppConfig = opt.old; - - await this.computeAndAssignConnectionAllowedProperty(oldAppConfig); + await this.computeAndAssignConnectionAllowedProperty(); } } diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 786924fc..03bf6b71 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { vi, describe, it, expect } from 'vitest'; import Base from './base.js'; import AppConfig from './app-config.js'; @@ -52,8 +52,48 @@ describe('AppConfig model', () => { }); }); - describe('connectionAllowed', () => { - it('should return true when app is enabled, shared and allows custom connection with an active app auth client at least', async () => { + describe('updateConnectionAllowedProperty', () => { + it('should call computeConnectionAllowedProperty and patch the result', async () => { + const appConfig = await createAppConfig(); + + const computeConnectionAllowedPropertySpy = vi + .spyOn(appConfig, 'computeConnectionAllowedProperty') + .mockResolvedValue(true); + + const patchSpy = vi + .fn() + .mockImplementation((newAppConfig) => newAppConfig); + + vi.spyOn(appConfig, '$query').mockImplementation(() => ({ + patch: patchSpy, + })); + + await appConfig.updateConnectionAllowedProperty(); + + expect(computeConnectionAllowedPropertySpy).toHaveBeenCalled(); + expect(patchSpy).toHaveBeenCalledWith({ + connectionAllowed: true, + }); + }); + }); + + describe('computeAndAssignConnectionAllowedProperty', () => { + it('should call computeConnectionAllowedProperty and assign the result', async () => { + const appConfig = await createAppConfig(); + + const computeConnectionAllowedPropertySpy = vi + .spyOn(appConfig, 'computeConnectionAllowedProperty') + .mockResolvedValue(true); + + await appConfig.computeAndAssignConnectionAllowedProperty(); + + expect(computeConnectionAllowedPropertySpy).toHaveBeenCalled(); + expect(appConfig.connectionAllowed).toBe(true); + }); + }); + + describe('computeConnectionAllowedProperty', () => { + it('should return true when app is enabled, shared and allows custom connection with an active app auth client', async () => { await createAppAuthClient({ appKey: 'deepl', active: true, @@ -71,10 +111,13 @@ describe('AppConfig model', () => { key: 'deepl', }); - expect(appConfig.connectionAllowed).toBe(true); + const connectionAllowed = + await appConfig.computeConnectionAllowedProperty(); + + expect(connectionAllowed).toBe(true); }); - it('should return true when app is enabled, shared and allows custom connection with no active app auth client', async () => { + it('should return false if there is no active app auth client', async () => { await createAppAuthClient({ appKey: 'deepl', active: false, @@ -87,10 +130,13 @@ describe('AppConfig model', () => { key: 'deepl', }); - expect(appConfig.connectionAllowed).toBe(false); + const connectionAllowed = + await appConfig.computeConnectionAllowedProperty(); + + expect(connectionAllowed).toBe(false); }); - it('should return false when app is enabled, shared and allows custom connection without any app auth clients', async () => { + it('should return false if there is no app auth clients', async () => { const appConfig = await createAppConfig({ disabled: false, customConnectionAllowed: true, @@ -98,7 +144,10 @@ describe('AppConfig model', () => { key: 'deepl', }); - expect(appConfig.connectionAllowed).toBe(false); + const connectionAllowed = + await appConfig.computeConnectionAllowedProperty(); + + expect(connectionAllowed).toBe(false); }); it('should return false when app is disabled', async () => { @@ -107,7 +156,10 @@ describe('AppConfig model', () => { customConnectionAllowed: true, }); - expect(appConfig.connectionAllowed).toBe(false); + const connectionAllowed = + await appConfig.computeConnectionAllowedProperty(); + + expect(connectionAllowed).toBe(false); }); it(`should return false when app doesn't allow custom connection`, async () => { @@ -116,7 +168,34 @@ describe('AppConfig model', () => { customConnectionAllowed: false, }); - expect(appConfig.connectionAllowed).toBe(false); + const connectionAllowed = + await appConfig.computeConnectionAllowedProperty(); + + expect(connectionAllowed).toBe(false); }); }); + + it('$beforeInsert should call computeAndAssignConnectionAllowedProperty', async () => { + const computeAndAssignConnectionAllowedPropertySpy = vi + .spyOn(AppConfig.prototype, 'computeAndAssignConnectionAllowedProperty') + .mockResolvedValue(true); + + await createAppConfig(); + + expect(computeAndAssignConnectionAllowedPropertySpy).toHaveBeenCalledOnce(); + }); + + it('$beforeUpdate should call computeAndAssignConnectionAllowedProperty', async () => { + const appConfig = await createAppConfig(); + + const computeAndAssignConnectionAllowedPropertySpy = vi + .spyOn(AppConfig.prototype, 'computeAndAssignConnectionAllowedProperty') + .mockResolvedValue(true); + + await appConfig.$query().patch({ + key: 'deepl', + }); + + expect(computeAndAssignConnectionAllowedPropertySpy).toHaveBeenCalledOnce(); + }); }); From de72e62470255c659e5cdf2a6a1e341a887c1087 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 17 Oct 2024 16:21:42 +0200 Subject: [PATCH 13/30] fix: Pass app config key to fix associations --- .../src/controllers/api/v1/admin/apps/update-config.ee.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js b/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js index ff94c583..8475a264 100644 --- a/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js +++ b/packages/backend/src/controllers/api/v1/admin/apps/update-config.ee.js @@ -8,7 +8,10 @@ export default async (request, response) => { }) .throwIfNotFound(); - await appConfig.$query().patchAndFetch(appConfigParams(request)); + await appConfig.$query().patchAndFetch({ + ...appConfigParams(request), + key: request.params.appKey, + }); renderObject(response, appConfig); }; From 2583e08f7ae2c711504916625884e1d1fd484133 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 17 Oct 2024 16:27:55 +0200 Subject: [PATCH 14/30] fix: Don't compute connectionAllowed column twice --- packages/backend/src/models/app-auth-client.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index e3593c4c..0e96d188 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -63,7 +63,8 @@ class AppAuthClient extends Base { async triggerAppConfigUpdate() { const appConfig = await this.$relatedQuery('appConfig'); - await appConfig?.updateConnectionAllowedProperty(); + // This is a workaround to update connection allowed column for AppConfig + await appConfig?.$query().patch({}); } // TODO: Make another abstraction like beforeSave instead of using From 55d0966d48c7e4ce153fb3a0f79f6164c8d70399 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 17 Oct 2024 16:32:32 +0200 Subject: [PATCH 15/30] fix: Pass app key while triggering app config update --- packages/backend/src/models/app-auth-client.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index 0e96d188..574c9394 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -64,7 +64,9 @@ class AppAuthClient extends Base { const appConfig = await this.$relatedQuery('appConfig'); // This is a workaround to update connection allowed column for AppConfig - await appConfig?.$query().patch({}); + await appConfig?.$query().patch({ + key: appConfig.key, + }); } // TODO: Make another abstraction like beforeSave instead of using From 6fcd126ff86ae24202449dd69b3d05953218f4d0 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Mon, 21 Oct 2024 14:32:03 +0000 Subject: [PATCH 16/30] test(app-auth-client): cover lifecycle hooks and triggerAppConfigUpdate method --- .../src/models/app-auth-client.test.js | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/backend/src/models/app-auth-client.test.js b/packages/backend/src/models/app-auth-client.test.js index d95ade3d..d9ef9d99 100644 --- a/packages/backend/src/models/app-auth-client.test.js +++ b/packages/backend/src/models/app-auth-client.test.js @@ -2,9 +2,11 @@ import { describe, it, expect, vi } from 'vitest'; import AES from 'crypto-js/aes.js'; import enc from 'crypto-js/enc-utf8.js'; +import AppConfig from './app-config.js'; import AppAuthClient from './app-auth-client.js'; import appConfig from '../config/app.js'; import { createAppAuthClient } from '../../test/factories/app-auth-client.js'; +import { createAppConfig } from '../../test/factories/app-config.js'; describe('AppAuthClient model', () => { it('tableName should return correct name', () => { @@ -140,6 +142,23 @@ describe('AppAuthClient model', () => { }); }); + it('triggerAppConfigUpdate should trigger an update in related app config', async () => { + await createAppConfig({ key: 'gitlab' }); + + const appAuthClient = await createAppAuthClient({ + appKey: 'gitlab', + }); + + const appConfigBeforeUpdateSpy = vi.spyOn( + AppConfig.prototype, + '$beforeUpdate' + ); + + await appAuthClient.triggerAppConfigUpdate(); + + expect(appConfigBeforeUpdateSpy).toHaveBeenCalledOnce(); + }); + it('$beforeInsert should call AppAuthClient.encryptData', async () => { const appAuthClientBeforeInsertSpy = vi.spyOn( AppAuthClient.prototype, @@ -151,6 +170,17 @@ describe('AppAuthClient model', () => { expect(appAuthClientBeforeInsertSpy).toHaveBeenCalledOnce(); }); + it('$afterInsert should call AppAuthClient.triggerAppConfigUpdate', async () => { + const appAuthClientAfterInsertSpy = vi.spyOn( + AppAuthClient.prototype, + '$afterInsert' + ); + + await createAppAuthClient(); + + expect(appAuthClientAfterInsertSpy).toHaveBeenCalledOnce(); + }); + it('$beforeUpdate should call AppAuthClient.encryptData', async () => { const appAuthClient = await createAppAuthClient(); @@ -164,6 +194,19 @@ describe('AppAuthClient model', () => { expect(appAuthClientBeforeUpdateSpy).toHaveBeenCalledOnce(); }); + it('$afterUpdate should call AppAuthClient.triggerAppConfigUpdate', async () => { + const appAuthClient = await createAppAuthClient(); + + const appAuthClientAfterUpdateSpy = vi.spyOn( + AppAuthClient.prototype, + 'triggerAppConfigUpdate' + ); + + await appAuthClient.$query().patchAndFetch({ name: 'sample' }); + + expect(appAuthClientAfterUpdateSpy).toHaveBeenCalledOnce(); + }); + it('$afterFind should call AppAuthClient.decryptData', async () => { const appAuthClient = await createAppAuthClient(); From ac8ddedfb5d81a77433d296f26f61506b9d639df Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Mon, 21 Oct 2024 15:49:09 +0000 Subject: [PATCH 17/30] test(connection): use new properties from app-config --- packages/backend/src/models/connection.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/models/connection.test.js b/packages/backend/src/models/connection.test.js index e64d5fad..9818a3ec 100644 --- a/packages/backend/src/models/connection.test.js +++ b/packages/backend/src/models/connection.test.js @@ -121,7 +121,7 @@ describe('Connection model', () => { const appConfig = await createAppConfig({ key: 'gitlab', disabled: false, - allowCustomConnection: true, + customConnectionAllowed: true, }); const connection = await createConnection({ @@ -151,7 +151,7 @@ describe('Connection model', () => { await createAppConfig({ key: 'gitlab', disabled: true, - allowCustomConnection: false, + customConnectionAllowed: false, }); const connectionWithAppAuthClient = await connection @@ -373,7 +373,7 @@ describe('Connection model', () => { vi.spyOn(Connection.prototype, 'getAppConfig').mockResolvedValue({ disabled: false, - allowCustomConnection: false, + customConnectionAllowed: false, }); const connection = new Connection(); @@ -410,7 +410,7 @@ describe('Connection model', () => { await createAppConfig({ key: 'gitlab', disabled: false, - allowCustomConnection: true, + customConnectionAllowed: true, shared: true, }); From 6a7a90536bf52ace69c0cc7429cabcbc35f8f403 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 15:14:41 +0200 Subject: [PATCH 18/30] feat: Make key field primary key for app config model --- ...241024130418_make_key_primary_for_app_configs.js | 13 +++++++++++++ packages/backend/src/models/app-config.js | 4 ++++ 2 files changed, 17 insertions(+) create mode 100644 packages/backend/src/db/migrations/20241024130418_make_key_primary_for_app_configs.js diff --git a/packages/backend/src/db/migrations/20241024130418_make_key_primary_for_app_configs.js b/packages/backend/src/db/migrations/20241024130418_make_key_primary_for_app_configs.js new file mode 100644 index 00000000..cae7f315 --- /dev/null +++ b/packages/backend/src/db/migrations/20241024130418_make_key_primary_for_app_configs.js @@ -0,0 +1,13 @@ +export async function up(knex) { + return knex.schema.alterTable('app_configs', function (table) { + table.dropPrimary(); + table.primary('key'); + }); +} + +export async function down(knex) { + return knex.schema.alterTable('app_configs', function (table) { + table.dropPrimary(); + table.primary('id'); + }); +} diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index 465600be..a4f3a0fb 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -5,6 +5,10 @@ import Base from './base.js'; class AppConfig extends Base { static tableName = 'app_configs'; + static get idColumn() { + return 'key'; + } + static jsonSchema = { type: 'object', required: ['key'], From f0bd763e729734542f245e9fce557f44cb4f0de4 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 15:14:55 +0200 Subject: [PATCH 19/30] feat: Remove id field from app config model --- ...0241024131158_remove_id_column_from_app_configs.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js diff --git a/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js b/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js new file mode 100644 index 00000000..a9d955bd --- /dev/null +++ b/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js @@ -0,0 +1,11 @@ +export async function up(knex) { + return knex.schema.alterTable('app_configs', function (table) { + table.dropColumn('id'); + }); +} + +export async function down(knex) { + return knex.schema.alterTable('app_configs', function (table) { + table.increments('id').primary(); + }); +} From e0e313b8d1c0a08ff455eeb0ec58df6170e865c5 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 16:45:44 +0200 Subject: [PATCH 20/30] refactor: Remove id from app config factory --- packages/backend/test/factories/app-auth-client.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend/test/factories/app-auth-client.js b/packages/backend/test/factories/app-auth-client.js index 0cadf197..831d4c14 100644 --- a/packages/backend/test/factories/app-auth-client.js +++ b/packages/backend/test/factories/app-auth-client.js @@ -10,7 +10,6 @@ const formattedAuthDefaults = { export const createAppAuthClient = async (params = {}) => { params.name = params?.name || faker.person.fullName(); - params.id = params?.id || faker.string.uuid(); params.appKey = params?.appKey || 'deepl'; params.active = params?.active ?? true; params.formattedAuthDefaults = From 997e729535813448dc7c50a514300d15de6d6047 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 16:46:08 +0200 Subject: [PATCH 21/30] refactor: Use hooks with refetched record for app config --- packages/backend/src/models/app-config.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index a4f3a0fb..a996f378 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -55,15 +55,21 @@ class AppConfig extends Base { } async computeConnectionAllowedProperty() { - const appAuthClients = await this.$relatedQuery('appAuthClients'); + const refetchedRecord = await AppConfig.query().findOne({ key: this.key }); + + if (!refetchedRecord) return; + + const appAuthClients = await refetchedRecord.$relatedQuery( + 'appAuthClients' + ); const hasSomeActiveAppAuthClients = appAuthClients?.some((appAuthClient) => appAuthClient.active) || false; const conditions = [ hasSomeActiveAppAuthClients, - this.shared, - !this.disabled, + refetchedRecord.shared, + !refetchedRecord.disabled, ]; const connectionAllowed = conditions.every(Boolean); From e4c17c1bc7ac7db93c49c10443381f46472dd6da Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 16:53:13 +0200 Subject: [PATCH 22/30] refactor: Use belongsTo relation for app config association --- packages/backend/src/models/app-auth-client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index 574c9394..d94e6408 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -24,7 +24,7 @@ class AppAuthClient extends Base { static relationMappings = () => ({ appConfig: { - relation: Base.HasOneRelation, + relation: Base.BelongsToOneRelation, modelClass: AppConfig, join: { from: 'app_auth_clients.app_key', From f73ffc8711137b575ce8f0eb76bbc720552d46b2 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 16:58:54 +0200 Subject: [PATCH 23/30] test: Add idColumn test to app config model --- packages/backend/src/models/app-config.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 03bf6b71..410d31b5 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -12,6 +12,10 @@ describe('AppConfig model', () => { expect(AppConfig.tableName).toBe('app_configs'); }); + it('idColumn should return key field', () => { + expect(AppConfig.idColumn).toBe('key'); + }); + it('jsonSchema should have correct validations', () => { expect(AppConfig.jsonSchema).toMatchSnapshot(); }); From d66be231b3bd29a9d6c70dfee7bcb467a6b97455 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 17:00:47 +0200 Subject: [PATCH 24/30] refactor: Remove redundant updateConnectionAllowedProperty --- packages/backend/src/models/app-config.js | 8 ------ .../backend/src/models/app-config.test.js | 25 ------------------- 2 files changed, 33 deletions(-) diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index a996f378..2511f437 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -42,14 +42,6 @@ class AppConfig extends Base { return await App.findOneByKey(this.key); } - async updateConnectionAllowedProperty() { - const connectionAllowed = await this.computeConnectionAllowedProperty(); - - return await this.$query().patch({ - connectionAllowed, - }); - } - async computeAndAssignConnectionAllowedProperty() { this.connectionAllowed = await this.computeConnectionAllowedProperty(); } diff --git a/packages/backend/src/models/app-config.test.js b/packages/backend/src/models/app-config.test.js index 410d31b5..4945066c 100644 --- a/packages/backend/src/models/app-config.test.js +++ b/packages/backend/src/models/app-config.test.js @@ -56,31 +56,6 @@ describe('AppConfig model', () => { }); }); - describe('updateConnectionAllowedProperty', () => { - it('should call computeConnectionAllowedProperty and patch the result', async () => { - const appConfig = await createAppConfig(); - - const computeConnectionAllowedPropertySpy = vi - .spyOn(appConfig, 'computeConnectionAllowedProperty') - .mockResolvedValue(true); - - const patchSpy = vi - .fn() - .mockImplementation((newAppConfig) => newAppConfig); - - vi.spyOn(appConfig, '$query').mockImplementation(() => ({ - patch: patchSpy, - })); - - await appConfig.updateConnectionAllowedProperty(); - - expect(computeConnectionAllowedPropertySpy).toHaveBeenCalled(); - expect(patchSpy).toHaveBeenCalledWith({ - connectionAllowed: true, - }); - }); - }); - describe('computeAndAssignConnectionAllowedProperty', () => { it('should call computeConnectionAllowedProperty and assign the result', async () => { const appConfig = await createAppConfig(); From c6f2a975916546f15c8c07d51fbe4b7005dddd7c Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 17:04:45 +0200 Subject: [PATCH 25/30] test: Add missing associations test for app auth client --- .../backend/src/models/app-auth-client.test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/backend/src/models/app-auth-client.test.js b/packages/backend/src/models/app-auth-client.test.js index d9ef9d99..0f5c2764 100644 --- a/packages/backend/src/models/app-auth-client.test.js +++ b/packages/backend/src/models/app-auth-client.test.js @@ -4,6 +4,7 @@ import enc from 'crypto-js/enc-utf8.js'; import AppConfig from './app-config.js'; import AppAuthClient from './app-auth-client.js'; +import Base from './base.js'; import appConfig from '../config/app.js'; import { createAppAuthClient } from '../../test/factories/app-auth-client.js'; import { createAppConfig } from '../../test/factories/app-config.js'; @@ -17,6 +18,23 @@ describe('AppAuthClient model', () => { expect(AppAuthClient.jsonSchema).toMatchSnapshot(); }); + it('relationMappings should return correct associations', () => { + const relationMappings = AppAuthClient.relationMappings(); + + const expectedRelations = { + appConfig: { + relation: Base.BelongsToOneRelation, + modelClass: AppConfig, + join: { + from: 'app_auth_clients.app_key', + to: 'app_configs.key', + }, + }, + }; + + expect(relationMappings).toStrictEqual(expectedRelations); + }); + describe('encryptData', () => { it('should return undefined if eligibleForEncryption is not true', async () => { vi.spyOn( From 62a1072682ff88f2424a5494fabb7f4328cb2502 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 17:07:23 +0200 Subject: [PATCH 26/30] fix: Use triggerAppConfigUpdate spy instead of --- packages/backend/src/models/app-auth-client.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/models/app-auth-client.test.js b/packages/backend/src/models/app-auth-client.test.js index 0f5c2764..d38a198f 100644 --- a/packages/backend/src/models/app-auth-client.test.js +++ b/packages/backend/src/models/app-auth-client.test.js @@ -191,7 +191,7 @@ describe('AppAuthClient model', () => { it('$afterInsert should call AppAuthClient.triggerAppConfigUpdate', async () => { const appAuthClientAfterInsertSpy = vi.spyOn( AppAuthClient.prototype, - '$afterInsert' + 'triggerAppConfigUpdate' ); await createAppAuthClient(); From b47e859225088c74b984c458ac8df81bcb07bb31 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Thu, 24 Oct 2024 17:10:47 +0200 Subject: [PATCH 27/30] test: Add additional cases for triggerAppConfigUpdate method --- .../src/models/app-auth-client.test.js | 60 +++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/packages/backend/src/models/app-auth-client.test.js b/packages/backend/src/models/app-auth-client.test.js index d38a198f..94b5c9f8 100644 --- a/packages/backend/src/models/app-auth-client.test.js +++ b/packages/backend/src/models/app-auth-client.test.js @@ -160,21 +160,61 @@ describe('AppAuthClient model', () => { }); }); - it('triggerAppConfigUpdate should trigger an update in related app config', async () => { - await createAppConfig({ key: 'gitlab' }); + describe('triggerAppConfigUpdate', () => { + it('should trigger an update in related app config', async () => { + await createAppConfig({ key: 'gitlab' }); - const appAuthClient = await createAppAuthClient({ - appKey: 'gitlab', + const appAuthClient = await createAppAuthClient({ + appKey: 'gitlab', + }); + + const appConfigBeforeUpdateSpy = vi.spyOn( + AppConfig.prototype, + '$beforeUpdate' + ); + + await appAuthClient.triggerAppConfigUpdate(); + + expect(appConfigBeforeUpdateSpy).toHaveBeenCalledOnce(); }); - const appConfigBeforeUpdateSpy = vi.spyOn( - AppConfig.prototype, - '$beforeUpdate' - ); + it('should update related AppConfig after creating an instance', async () => { + const appConfig = await createAppConfig({ + key: 'gitlab', + disabled: false, + shared: true, + }); - await appAuthClient.triggerAppConfigUpdate(); + await createAppAuthClient({ + appKey: 'gitlab', + active: true, + }); - expect(appConfigBeforeUpdateSpy).toHaveBeenCalledOnce(); + const refetchedAppConfig = await appConfig.$query(); + + expect(refetchedAppConfig.connectionAllowed).toBe(true); + }); + + it('should update related AppConfig after updating an instance', async () => { + const appConfig = await createAppConfig({ + key: 'gitlab', + disabled: false, + shared: true, + }); + + const appAuthClient = await createAppAuthClient({ + appKey: 'gitlab', + active: false, + }); + + let refetchedAppConfig = await appConfig.$query(); + expect(refetchedAppConfig.connectionAllowed).toBe(false); + + await appAuthClient.$query().patchAndFetch({ active: true }); + + refetchedAppConfig = await appConfig.$query(); + expect(refetchedAppConfig.connectionAllowed).toBe(true); + }); }); it('$beforeInsert should call AppAuthClient.encryptData', async () => { From 0e4fc7efbcb96086a0c30ae7fc7cdb14ff99c0d5 Mon Sep 17 00:00:00 2001 From: "Jakub P." Date: Thu, 24 Oct 2024 19:42:54 +0200 Subject: [PATCH 28/30] fix: use key instead of id in appConfig --- .../components/AdminApplicationCreateAuthClient/index.jsx | 7 +++---- packages/web/src/propTypes/propTypes.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx b/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx index 75f2b79b..ccda0d0e 100644 --- a/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx +++ b/packages/web/src/components/AdminApplicationCreateAuthClient/index.jsx @@ -30,16 +30,15 @@ function AdminApplicationCreateAuthClient(props) { } = useAdminCreateAppAuthClient(appKey); const submitHandler = async (values) => { - let appConfigId = appConfig?.data?.id; + let appConfigKey = appConfig?.data?.key; - if (!appConfigId) { + if (!appConfigKey) { const { data: appConfigData } = await createAppConfig({ customConnectionAllowed: true, shared: false, disabled: false, }); - - appConfigId = appConfigData.id; + appConfigKey = appConfigData.key; } const { name, active, ...formattedAuthDefaults } = values; diff --git a/packages/web/src/propTypes/propTypes.js b/packages/web/src/propTypes/propTypes.js index 82d6fd6b..e6660c75 100644 --- a/packages/web/src/propTypes/propTypes.js +++ b/packages/web/src/propTypes/propTypes.js @@ -468,7 +468,7 @@ export const AppConfigPropType = PropTypes.shape({ export const AppAuthClientPropType = PropTypes.shape({ id: PropTypes.string, name: PropTypes.string, - appConfigId: PropTypes.string, + appConfigKey: PropTypes.string, authDefaults: PropTypes.string, formattedAuthDefaults: PropTypes.object, active: PropTypes.bool, From 240854e4ac49e4ceedb523f77ed8d9adce76be6a Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Fri, 25 Oct 2024 00:59:00 +0200 Subject: [PATCH 29/30] fix: Use uuid for down migration of app config id removal --- .../20241024131158_remove_id_column_from_app_configs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js b/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js index a9d955bd..9059828f 100644 --- a/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js +++ b/packages/backend/src/db/migrations/20241024131158_remove_id_column_from_app_configs.js @@ -6,6 +6,6 @@ export async function up(knex) { export async function down(knex) { return knex.schema.alterTable('app_configs', function (table) { - table.increments('id').primary(); + table.uuid('id').defaultTo(knex.raw('gen_random_uuid()')); }); } From 91c9ef3068df12583d650acb77049a197fc7133d Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Fri, 25 Oct 2024 01:07:44 +0200 Subject: [PATCH 30/30] fix: Pass app config parameters to be used for hooks --- packages/backend/src/models/app-auth-client.js | 2 ++ packages/backend/src/models/app-config.js | 12 +++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/backend/src/models/app-auth-client.js b/packages/backend/src/models/app-auth-client.js index d94e6408..90a9bda3 100644 --- a/packages/backend/src/models/app-auth-client.js +++ b/packages/backend/src/models/app-auth-client.js @@ -66,6 +66,8 @@ class AppAuthClient extends Base { // This is a workaround to update connection allowed column for AppConfig await appConfig?.$query().patch({ key: appConfig.key, + shared: appConfig.shared, + disabled: appConfig.disabled, }); } diff --git a/packages/backend/src/models/app-config.js b/packages/backend/src/models/app-config.js index 2511f437..1a9176b9 100644 --- a/packages/backend/src/models/app-config.js +++ b/packages/backend/src/models/app-config.js @@ -47,21 +47,15 @@ class AppConfig extends Base { } async computeConnectionAllowedProperty() { - const refetchedRecord = await AppConfig.query().findOne({ key: this.key }); - - if (!refetchedRecord) return; - - const appAuthClients = await refetchedRecord.$relatedQuery( - 'appAuthClients' - ); + const appAuthClients = await this.$relatedQuery('appAuthClients'); const hasSomeActiveAppAuthClients = appAuthClients?.some((appAuthClient) => appAuthClient.active) || false; const conditions = [ hasSomeActiveAppAuthClients, - refetchedRecord.shared, - !refetchedRecord.disabled, + this.shared, + !this.disabled, ]; const connectionAllowed = conditions.every(Boolean);