Merge pull request #2255 from automatisch/rename-app-auth-clients
refactor: Rename AppAuthClient model as OAuthClient
This commit is contained in:
@@ -6,14 +6,14 @@ export default async (request, response) => {
|
|||||||
.findOne({ key: request.params.appKey })
|
.findOne({ key: request.params.appKey })
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
const appAuthClient = await appConfig
|
const oauthClient = await appConfig
|
||||||
.$relatedQuery('appAuthClients')
|
.$relatedQuery('oauthClients')
|
||||||
.insert(appAuthClientParams(request));
|
.insert(oauthClientParams(request));
|
||||||
|
|
||||||
renderObject(response, appAuthClient, { status: 201 });
|
renderObject(response, oauthClient, { status: 201 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const appAuthClientParams = (request) => {
|
const oauthClientParams = (request) => {
|
||||||
const { active, appKey, name, formattedAuthDefaults } = request.body;
|
const { active, appKey, name, formattedAuthDefaults } = request.body;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -5,11 +5,11 @@ import app from '../../../../../app.js';
|
|||||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createUser } from '../../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../../test/factories/user.js';
|
||||||
import { createRole } from '../../../../../../test/factories/role.js';
|
import { createRole } from '../../../../../../test/factories/role.js';
|
||||||
import createAppAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-auth-client.js';
|
import createOAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-oauth-client.js';
|
||||||
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
||||||
import * as license from '../../../../../helpers/license.ee.js';
|
import * as license from '../../../../../helpers/license.ee.js';
|
||||||
|
|
||||||
describe('POST /api/v1/admin/apps/:appKey/auth-clients', () => {
|
describe('POST /api/v1/admin/apps/:appKey/oauth-clients', () => {
|
||||||
let currentUser, adminRole, token;
|
let currentUser, adminRole, token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -26,7 +26,7 @@ describe('POST /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
key: 'gitlab',
|
key: 'gitlab',
|
||||||
});
|
});
|
||||||
|
|
||||||
const appAuthClient = {
|
const oauthClient = {
|
||||||
active: true,
|
active: true,
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
name: 'First auth client',
|
name: 'First auth client',
|
||||||
@@ -39,17 +39,17 @@ describe('POST /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post('/api/v1/admin/apps/gitlab/auth-clients')
|
.post('/api/v1/admin/apps/gitlab/oauth-clients')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.send(appAuthClient)
|
.send(oauthClient)
|
||||||
.expect(201);
|
.expect(201);
|
||||||
|
|
||||||
const expectedPayload = createAppAuthClientMock(appAuthClient);
|
const expectedPayload = createOAuthClientMock(oauthClient);
|
||||||
expect(response.body).toMatchObject(expectedPayload);
|
expect(response.body).toMatchObject(expectedPayload);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return not found response for not existing app config', async () => {
|
it('should return not found response for not existing app config', async () => {
|
||||||
const appAuthClient = {
|
const oauthClient = {
|
||||||
active: true,
|
active: true,
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
name: 'First auth client',
|
name: 'First auth client',
|
||||||
@@ -62,9 +62,9 @@ describe('POST /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await request(app)
|
await request(app)
|
||||||
.post('/api/v1/admin/apps/gitlab/auth-clients')
|
.post('/api/v1/admin/apps/gitlab/oauth-clients')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.send(appAuthClient)
|
.send(oauthClient)
|
||||||
.expect(404);
|
.expect(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -73,14 +73,14 @@ describe('POST /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
key: 'gitlab',
|
key: 'gitlab',
|
||||||
});
|
});
|
||||||
|
|
||||||
const appAuthClient = {
|
const oauthClient = {
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post('/api/v1/admin/apps/gitlab/auth-clients')
|
.post('/api/v1/admin/apps/gitlab/oauth-clients')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.send(appAuthClient)
|
.send(oauthClient)
|
||||||
.expect(422);
|
.expect(422);
|
||||||
|
|
||||||
expect(response.body.meta.type).toStrictEqual('ModelValidation');
|
expect(response.body.meta.type).toStrictEqual('ModelValidation');
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
|
||||||
import AppAuthClient from '../../../../../models/app-auth-client.js';
|
|
||||||
|
|
||||||
export default async (request, response) => {
|
|
||||||
const appAuthClient = await AppAuthClient.query()
|
|
||||||
.findById(request.params.appAuthClientId)
|
|
||||||
.where({ app_key: request.params.appKey })
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
renderObject(response, appAuthClient);
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||||
|
import OAuthClient from '../../../../../models/oauth-client.js';
|
||||||
|
|
||||||
|
export default async (request, response) => {
|
||||||
|
const oauthClient = await OAuthClient.query()
|
||||||
|
.findById(request.params.oauthClientId)
|
||||||
|
.where({ app_key: request.params.appKey })
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
renderObject(response, oauthClient);
|
||||||
|
};
|
||||||
@@ -5,12 +5,12 @@ import app from '../../../../../app.js';
|
|||||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createUser } from '../../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../../test/factories/user.js';
|
||||||
import { createRole } from '../../../../../../test/factories/role.js';
|
import { createRole } from '../../../../../../test/factories/role.js';
|
||||||
import getAppAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/get-auth-client.js';
|
import getOAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/get-oauth-client.js';
|
||||||
import { createAppAuthClient } from '../../../../../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../../../../../test/factories/oauth-client.js';
|
||||||
import * as license from '../../../../../helpers/license.ee.js';
|
import * as license from '../../../../../helpers/license.ee.js';
|
||||||
|
|
||||||
describe('GET /api/v1/admin/apps/:appKey/auth-clients/:appAuthClientId', () => {
|
describe('GET /api/v1/admin/apps/:appKey/oauth-clients/:oauthClientId', () => {
|
||||||
let currentUser, adminRole, currentAppAuthClient, token;
|
let currentUser, adminRole, currentOAuthClient, token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||||
@@ -18,29 +18,29 @@ describe('GET /api/v1/admin/apps/:appKey/auth-clients/:appAuthClientId', () => {
|
|||||||
adminRole = await createRole({ name: 'Admin' });
|
adminRole = await createRole({ name: 'Admin' });
|
||||||
currentUser = await createUser({ roleId: adminRole.id });
|
currentUser = await createUser({ roleId: adminRole.id });
|
||||||
|
|
||||||
currentAppAuthClient = await createAppAuthClient({
|
currentOAuthClient = await createOAuthClient({
|
||||||
appKey: 'deepl',
|
appKey: 'deepl',
|
||||||
});
|
});
|
||||||
|
|
||||||
token = await createAuthTokenByUserId(currentUser.id);
|
token = await createAuthTokenByUserId(currentUser.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return specified app auth client', async () => {
|
it('should return specified oauth client', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`/api/v1/admin/apps/deepl/auth-clients/${currentAppAuthClient.id}`)
|
.get(`/api/v1/admin/apps/deepl/oauth-clients/${currentOAuthClient.id}`)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const expectedPayload = getAppAuthClientMock(currentAppAuthClient);
|
const expectedPayload = getOAuthClientMock(currentOAuthClient);
|
||||||
expect(response.body).toStrictEqual(expectedPayload);
|
expect(response.body).toStrictEqual(expectedPayload);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return not found response for not existing app auth client ID', async () => {
|
it('should return not found response for not existing oauth client ID', async () => {
|
||||||
const notExistingAppAuthClientUUID = Crypto.randomUUID();
|
const notExistingOAuthClientUUID = Crypto.randomUUID();
|
||||||
|
|
||||||
await request(app)
|
await request(app)
|
||||||
.get(
|
.get(
|
||||||
`/api/v1/admin/apps/deepl/auth-clients/${notExistingAppAuthClientUUID}`
|
`/api/v1/admin/apps/deepl/oauth-clients/${notExistingOAuthClientUUID}`
|
||||||
)
|
)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(404);
|
.expect(404);
|
||||||
@@ -48,7 +48,7 @@ describe('GET /api/v1/admin/apps/:appKey/auth-clients/:appAuthClientId', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await request(app)
|
await request(app)
|
||||||
.get('/api/v1/admin/apps/deepl/auth-clients/invalidAppAuthClientUUID')
|
.get('/api/v1/admin/apps/deepl/oauth-clients/invalidOAuthClientUUID')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(400);
|
.expect(400);
|
||||||
});
|
});
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||||
import AppAuthClient from '../../../../../models/app-auth-client.js';
|
import OAuthClient from '../../../../../models/oauth-client.js';
|
||||||
|
|
||||||
export default async (request, response) => {
|
export default async (request, response) => {
|
||||||
const appAuthClients = await AppAuthClient.query()
|
const oauthClients = await OAuthClient.query()
|
||||||
.where({ app_key: request.params.appKey })
|
.where({ app_key: request.params.appKey })
|
||||||
.orderBy('created_at', 'desc');
|
.orderBy('created_at', 'desc');
|
||||||
|
|
||||||
renderObject(response, appAuthClients);
|
renderObject(response, oauthClients);
|
||||||
};
|
};
|
||||||
@@ -4,11 +4,11 @@ import app from '../../../../../app.js';
|
|||||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createUser } from '../../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../../test/factories/user.js';
|
||||||
import { createRole } from '../../../../../../test/factories/role.js';
|
import { createRole } from '../../../../../../test/factories/role.js';
|
||||||
import getAuthClientsMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/get-auth-clients.js';
|
import getAdminOAuthClientsMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/get-oauth-clients.js';
|
||||||
import { createAppAuthClient } from '../../../../../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../../../../../test/factories/oauth-client.js';
|
||||||
import * as license from '../../../../../helpers/license.ee.js';
|
import * as license from '../../../../../helpers/license.ee.js';
|
||||||
|
|
||||||
describe('GET /api/v1/admin/apps/:appKey/auth-clients', () => {
|
describe('GET /api/v1/admin/apps/:appKey/oauth-clients', () => {
|
||||||
let currentUser, adminRole, token;
|
let currentUser, adminRole, token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -20,23 +20,23 @@ describe('GET /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
token = await createAuthTokenByUserId(currentUser.id);
|
token = await createAuthTokenByUserId(currentUser.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return specified app auth client info', async () => {
|
it('should return specified oauth client info', async () => {
|
||||||
const appAuthClientOne = await createAppAuthClient({
|
const oauthClientOne = await createOAuthClient({
|
||||||
appKey: 'deepl',
|
appKey: 'deepl',
|
||||||
});
|
});
|
||||||
|
|
||||||
const appAuthClientTwo = await createAppAuthClient({
|
const oauthClientTwo = await createOAuthClient({
|
||||||
appKey: 'deepl',
|
appKey: 'deepl',
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get('/api/v1/admin/apps/deepl/auth-clients')
|
.get('/api/v1/admin/apps/deepl/oauth-clients')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const expectedPayload = getAuthClientsMock([
|
const expectedPayload = getAdminOAuthClientsMock([
|
||||||
appAuthClientTwo,
|
oauthClientTwo,
|
||||||
appAuthClientOne,
|
oauthClientOne,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(response.body).toStrictEqual(expectedPayload);
|
expect(response.body).toStrictEqual(expectedPayload);
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
|
||||||
import AppAuthClient from '../../../../../models/app-auth-client.js';
|
|
||||||
|
|
||||||
export default async (request, response) => {
|
|
||||||
const appAuthClient = await AppAuthClient.query()
|
|
||||||
.findById(request.params.appAuthClientId)
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
await appAuthClient.$query().patchAndFetch(appAuthClientParams(request));
|
|
||||||
|
|
||||||
renderObject(response, appAuthClient);
|
|
||||||
};
|
|
||||||
|
|
||||||
const appAuthClientParams = (request) => {
|
|
||||||
const { active, name, formattedAuthDefaults } = request.body;
|
|
||||||
|
|
||||||
return {
|
|
||||||
active,
|
|
||||||
name,
|
|
||||||
formattedAuthDefaults,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||||
|
import OAuthClient from '../../../../../models/oauth-client.js';
|
||||||
|
|
||||||
|
export default async (request, response) => {
|
||||||
|
const oauthClient = await OAuthClient.query()
|
||||||
|
.findById(request.params.oauthClientId)
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
await oauthClient.$query().patchAndFetch(oauthClientParams(request));
|
||||||
|
|
||||||
|
renderObject(response, oauthClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
const oauthClientParams = (request) => {
|
||||||
|
const { active, name, formattedAuthDefaults } = request.body;
|
||||||
|
|
||||||
|
return {
|
||||||
|
active,
|
||||||
|
name,
|
||||||
|
formattedAuthDefaults,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -6,12 +6,12 @@ import app from '../../../../../app.js';
|
|||||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createUser } from '../../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../../test/factories/user.js';
|
||||||
import { createRole } from '../../../../../../test/factories/role.js';
|
import { createRole } from '../../../../../../test/factories/role.js';
|
||||||
import updateAppAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/update-auth-client.js';
|
import updateOAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/update-oauth-client.js';
|
||||||
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
||||||
import { createAppAuthClient } from '../../../../../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../../../../../test/factories/oauth-client.js';
|
||||||
import * as license from '../../../../../helpers/license.ee.js';
|
import * as license from '../../../../../helpers/license.ee.js';
|
||||||
|
|
||||||
describe('PATCH /api/v1/admin/apps/:appKey/auth-clients', () => {
|
describe('PATCH /api/v1/admin/apps/:appKey/oauth-clients', () => {
|
||||||
let currentUser, adminRole, token;
|
let currentUser, adminRole, token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -27,8 +27,8 @@ describe('PATCH /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return updated entity for valid app auth client', async () => {
|
it('should return updated entity for valid oauth client', async () => {
|
||||||
const appAuthClient = {
|
const oauthClient = {
|
||||||
active: true,
|
active: true,
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
formattedAuthDefaults: {
|
formattedAuthDefaults: {
|
||||||
@@ -39,33 +39,33 @@ describe('PATCH /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const existingAppAuthClient = await createAppAuthClient({
|
const existingOAuthClient = await createOAuthClient({
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
name: 'First auth client',
|
name: 'First auth client',
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.patch(
|
.patch(
|
||||||
`/api/v1/admin/apps/gitlab/auth-clients/${existingAppAuthClient.id}`
|
`/api/v1/admin/apps/gitlab/oauth-clients/${existingOAuthClient.id}`
|
||||||
)
|
)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.send(appAuthClient)
|
.send(oauthClient)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const expectedPayload = updateAppAuthClientMock({
|
const expectedPayload = updateOAuthClientMock({
|
||||||
...existingAppAuthClient,
|
...existingOAuthClient,
|
||||||
...appAuthClient,
|
...oauthClient,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(response.body).toMatchObject(expectedPayload);
|
expect(response.body).toMatchObject(expectedPayload);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return not found response for not existing app auth client', async () => {
|
it('should return not found response for not existing oauth client', async () => {
|
||||||
const notExistingAppAuthClientId = Crypto.randomUUID();
|
const notExistingOAuthClientId = Crypto.randomUUID();
|
||||||
|
|
||||||
await request(app)
|
await request(app)
|
||||||
.patch(
|
.patch(
|
||||||
`/api/v1/admin/apps/gitlab/auth-clients/${notExistingAppAuthClientId}`
|
`/api/v1/admin/apps/gitlab/oauth-clients/${notExistingOAuthClientId}`
|
||||||
)
|
)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(404);
|
.expect(404);
|
||||||
@@ -73,27 +73,27 @@ describe('PATCH /api/v1/admin/apps/:appKey/auth-clients', () => {
|
|||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await request(app)
|
await request(app)
|
||||||
.patch('/api/v1/admin/apps/gitlab/auth-clients/invalidAuthClientUUID')
|
.patch('/api/v1/admin/apps/gitlab/oauth-clients/invalidAuthClientUUID')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(400);
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return HTTP 422 for invalid payload', async () => {
|
it('should return HTTP 422 for invalid payload', async () => {
|
||||||
const appAuthClient = {
|
const oauthClient = {
|
||||||
formattedAuthDefaults: 'invalid input',
|
formattedAuthDefaults: 'invalid input',
|
||||||
};
|
};
|
||||||
|
|
||||||
const existingAppAuthClient = await createAppAuthClient({
|
const existingOAuthClient = await createOAuthClient({
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
name: 'First auth client',
|
name: 'First auth client',
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.patch(
|
.patch(
|
||||||
`/api/v1/admin/apps/gitlab/auth-clients/${existingAppAuthClient.id}`
|
`/api/v1/admin/apps/gitlab/oauth-clients/${existingOAuthClient.id}`
|
||||||
)
|
)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.send(appAuthClient)
|
.send(oauthClient)
|
||||||
.expect(422);
|
.expect(422);
|
||||||
|
|
||||||
expect(response.body.meta.type).toBe('ModelValidation');
|
expect(response.body.meta.type).toBe('ModelValidation');
|
||||||
@@ -9,18 +9,18 @@ export default async (request, response) => {
|
|||||||
.$query()
|
.$query()
|
||||||
.withGraphFetched({
|
.withGraphFetched({
|
||||||
appConfig: true,
|
appConfig: true,
|
||||||
appAuthClient: true,
|
oauthClient: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
renderObject(response, connectionWithAppConfigAndAuthClient, { status: 201 });
|
renderObject(response, connectionWithAppConfigAndAuthClient, { status: 201 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const connectionParams = (request) => {
|
const connectionParams = (request) => {
|
||||||
const { appAuthClientId, formattedData } = request.body;
|
const { oauthClientId, formattedData } = request.body;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: request.params.appKey,
|
key: request.params.appKey,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
formattedData,
|
formattedData,
|
||||||
verified: false,
|
verified: false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import request from 'supertest';
|
|||||||
import app from '../../../../app.js';
|
import app from '../../../../app.js';
|
||||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createAppConfig } from '../../../../../test/factories/app-config.js';
|
import { createAppConfig } from '../../../../../test/factories/app-config.js';
|
||||||
import { createAppAuthClient } from '../../../../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../../../../test/factories/oauth-client.js';
|
||||||
import { createUser } from '../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../test/factories/user.js';
|
||||||
import { createPermission } from '../../../../../test/factories/permission.js';
|
import { createPermission } from '../../../../../test/factories/permission.js';
|
||||||
import { createRole } from '../../../../../test/factories/role.js';
|
import { createRole } from '../../../../../test/factories/role.js';
|
||||||
@@ -267,7 +267,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('with auth client enabled', async () => {
|
describe('with auth client enabled', async () => {
|
||||||
let appAuthClient;
|
let oauthClient;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await createAppConfig({
|
await createAppConfig({
|
||||||
@@ -276,7 +276,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
useOnlyPredefinedAuthClients: false,
|
useOnlyPredefinedAuthClients: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
appAuthClient = await createAppAuthClient({
|
oauthClient = await createOAuthClient({
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
active: true,
|
active: true,
|
||||||
formattedAuthDefaults: {
|
formattedAuthDefaults: {
|
||||||
@@ -290,7 +290,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
|
|
||||||
it('should return created connection', async () => {
|
it('should return created connection', async () => {
|
||||||
const connectionData = {
|
const connectionData = {
|
||||||
appAuthClientId: appAuthClient.id,
|
oauthClientId: oauthClient.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@@ -338,7 +338,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('with auth client disabled', async () => {
|
describe('with auth client disabled', async () => {
|
||||||
let appAuthClient;
|
let oauthClient;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await createAppConfig({
|
await createAppConfig({
|
||||||
@@ -347,7 +347,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
useOnlyPredefinedAuthClients: false,
|
useOnlyPredefinedAuthClients: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
appAuthClient = await createAppAuthClient({
|
oauthClient = await createOAuthClient({
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
active: false,
|
active: false,
|
||||||
});
|
});
|
||||||
@@ -355,7 +355,7 @@ describe('POST /api/v1/apps/:appKey/connections', () => {
|
|||||||
|
|
||||||
it('should return with not authorized response', async () => {
|
it('should return with not authorized response', async () => {
|
||||||
const connectionData = {
|
const connectionData = {
|
||||||
appAuthClientId: appAuthClient.id,
|
oauthClientId: oauthClient.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
await request(app)
|
await request(app)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ describe('GET /api/v1/apps/:appKey/actions/:actionKey/substeps', () => {
|
|||||||
exampleApp = await App.findOneByKey('github');
|
exampleApp = await App.findOneByKey('github');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the app auth info', async () => {
|
it('should return the action substeps info', async () => {
|
||||||
const actions = await App.findActionsByKey('github');
|
const actions = await App.findActionsByKey('github');
|
||||||
const exampleAction = actions.find(
|
const exampleAction = actions.find(
|
||||||
(action) => action.key === 'createIssue'
|
(action) => action.key === 'createIssue'
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import { renderObject } from '../../../../helpers/renderer.js';
|
|
||||||
import AppAuthClient from '../../../../models/app-auth-client.js';
|
|
||||||
|
|
||||||
export default async (request, response) => {
|
|
||||||
const appAuthClient = await AppAuthClient.query()
|
|
||||||
.findById(request.params.appAuthClientId)
|
|
||||||
.where({ app_key: request.params.appKey, active: true })
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
renderObject(response, appAuthClient);
|
|
||||||
};
|
|
||||||
@@ -4,7 +4,7 @@ import AppConfig from '../../../../models/app-config.js';
|
|||||||
export default async (request, response) => {
|
export default async (request, response) => {
|
||||||
const appConfig = await AppConfig.query()
|
const appConfig = await AppConfig.query()
|
||||||
.withGraphFetched({
|
.withGraphFetched({
|
||||||
appAuthClients: true,
|
oauthClients: true,
|
||||||
})
|
})
|
||||||
.findOne({
|
.findOne({
|
||||||
key: request.params.appKey,
|
key: request.params.appKey,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default async (request, response) => {
|
|||||||
.select('connections.*')
|
.select('connections.*')
|
||||||
.withGraphFetched({
|
.withGraphFetched({
|
||||||
appConfig: true,
|
appConfig: true,
|
||||||
appAuthClient: true,
|
oauthClient: true,
|
||||||
})
|
})
|
||||||
.fullOuterJoinRelated('steps')
|
.fullOuterJoinRelated('steps')
|
||||||
.where({
|
.where({
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { renderObject } from '../../../../helpers/renderer.js';
|
||||||
|
import OAuthClient from '../../../../models/oauth-client.js';
|
||||||
|
|
||||||
|
export default async (request, response) => {
|
||||||
|
const oauthClient = await OAuthClient.query()
|
||||||
|
.findById(request.params.oauthClientId)
|
||||||
|
.where({ app_key: request.params.appKey, active: true })
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
renderObject(response, oauthClient);
|
||||||
|
};
|
||||||
@@ -4,46 +4,46 @@ import Crypto from 'crypto';
|
|||||||
import app from '../../../../app.js';
|
import app from '../../../../app.js';
|
||||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createUser } from '../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../test/factories/user.js';
|
||||||
import getAppAuthClientMock from '../../../../../test/mocks/rest/api/v1/apps/get-auth-client.js';
|
import getOAuthClientMock from '../../../../../test/mocks/rest/api/v1/apps/get-oauth-client.js';
|
||||||
import { createAppAuthClient } from '../../../../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../../../../test/factories/oauth-client.js';
|
||||||
import * as license from '../../../../helpers/license.ee.js';
|
import * as license from '../../../../helpers/license.ee.js';
|
||||||
|
|
||||||
describe('GET /api/v1/apps/:appKey/auth-clients/:appAuthClientId', () => {
|
describe('GET /api/v1/apps/:appKey/oauth-clients/:oauthClientId', () => {
|
||||||
let currentUser, currentAppAuthClient, token;
|
let currentUser, currentOAuthClient, token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||||
|
|
||||||
currentUser = await createUser();
|
currentUser = await createUser();
|
||||||
currentAppAuthClient = await createAppAuthClient({
|
currentOAuthClient = await createOAuthClient({
|
||||||
appKey: 'deepl',
|
appKey: 'deepl',
|
||||||
});
|
});
|
||||||
|
|
||||||
token = await createAuthTokenByUserId(currentUser.id);
|
token = await createAuthTokenByUserId(currentUser.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return specified app auth client', async () => {
|
it('should return specified oauth client', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`/api/v1/apps/deepl/auth-clients/${currentAppAuthClient.id}`)
|
.get(`/api/v1/apps/deepl/oauth-clients/${currentOAuthClient.id}`)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const expectedPayload = getAppAuthClientMock(currentAppAuthClient);
|
const expectedPayload = getOAuthClientMock(currentOAuthClient);
|
||||||
expect(response.body).toStrictEqual(expectedPayload);
|
expect(response.body).toStrictEqual(expectedPayload);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return not found response for not existing app auth client ID', async () => {
|
it('should return not found response for not existing oauth client ID', async () => {
|
||||||
const notExistingAppAuthClientUUID = Crypto.randomUUID();
|
const notExistingOAuthClientUUID = Crypto.randomUUID();
|
||||||
|
|
||||||
await request(app)
|
await request(app)
|
||||||
.get(`/api/v1/apps/deepl/auth-clients/${notExistingAppAuthClientUUID}`)
|
.get(`/api/v1/apps/deepl/oauth-clients/${notExistingOAuthClientUUID}`)
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(404);
|
.expect(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return bad request response for invalid UUID', async () => {
|
it('should return bad request response for invalid UUID', async () => {
|
||||||
await request(app)
|
await request(app)
|
||||||
.get('/api/v1/apps/deepl/auth-clients/invalidAppAuthClientUUID')
|
.get('/api/v1/apps/deepl/oauth-clients/invalidOAuthClientUUID')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(400);
|
.expect(400);
|
||||||
});
|
});
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { renderObject } from '../../../../helpers/renderer.js';
|
import { renderObject } from '../../../../helpers/renderer.js';
|
||||||
import AppAuthClient from '../../../../models/app-auth-client.js';
|
import OAuthClient from '../../../../models/oauth-client.js';
|
||||||
|
|
||||||
export default async (request, response) => {
|
export default async (request, response) => {
|
||||||
const appAuthClients = await AppAuthClient.query()
|
const oauthClients = await OAuthClient.query()
|
||||||
.where({ app_key: request.params.appKey, active: true })
|
.where({ app_key: request.params.appKey, active: true })
|
||||||
.orderBy('created_at', 'desc');
|
.orderBy('created_at', 'desc');
|
||||||
|
|
||||||
renderObject(response, appAuthClients);
|
renderObject(response, oauthClients);
|
||||||
};
|
};
|
||||||
@@ -3,11 +3,11 @@ import request from 'supertest';
|
|||||||
import app from '../../../../app.js';
|
import app from '../../../../app.js';
|
||||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||||
import { createUser } from '../../../../../test/factories/user.js';
|
import { createUser } from '../../../../../test/factories/user.js';
|
||||||
import getAuthClientsMock from '../../../../../test/mocks/rest/api/v1/apps/get-auth-clients.js';
|
import getOAuthClientsMock from '../../../../../test/mocks/rest/api/v1/apps/get-oauth-clients.js';
|
||||||
import { createAppAuthClient } from '../../../../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../../../../test/factories/oauth-client.js';
|
||||||
import * as license from '../../../../helpers/license.ee.js';
|
import * as license from '../../../../helpers/license.ee.js';
|
||||||
|
|
||||||
describe('GET /api/v1/apps/:appKey/auth-clients', () => {
|
describe('GET /api/v1/apps/:appKey/oauth-clients', () => {
|
||||||
let currentUser, token;
|
let currentUser, token;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -18,23 +18,23 @@ describe('GET /api/v1/apps/:appKey/auth-clients', () => {
|
|||||||
token = await createAuthTokenByUserId(currentUser.id);
|
token = await createAuthTokenByUserId(currentUser.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return specified app auth client info', async () => {
|
it('should return specified oauth client info', async () => {
|
||||||
const appAuthClientOne = await createAppAuthClient({
|
const oauthClientOne = await createOAuthClient({
|
||||||
appKey: 'deepl',
|
appKey: 'deepl',
|
||||||
});
|
});
|
||||||
|
|
||||||
const appAuthClientTwo = await createAppAuthClient({
|
const oauthClientTwo = await createOAuthClient({
|
||||||
appKey: 'deepl',
|
appKey: 'deepl',
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get('/api/v1/apps/deepl/auth-clients')
|
.get('/api/v1/apps/deepl/oauth-clients')
|
||||||
.set('Authorization', token)
|
.set('Authorization', token)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
const expectedPayload = getAuthClientsMock([
|
const expectedPayload = getOAuthClientsMock([
|
||||||
appAuthClientTwo,
|
oauthClientTwo,
|
||||||
appAuthClientOne,
|
oauthClientOne,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(response.body).toStrictEqual(expectedPayload);
|
expect(response.body).toStrictEqual(expectedPayload);
|
||||||
@@ -15,7 +15,7 @@ describe('GET /api/v1/apps/:appKey/triggers/:triggerKey/substeps', () => {
|
|||||||
exampleApp = await App.findOneByKey('github');
|
exampleApp = await App.findOneByKey('github');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the app auth info', async () => {
|
it('should return the trigger substeps info', async () => {
|
||||||
const triggers = await App.findTriggersByKey('github');
|
const triggers = await App.findTriggersByKey('github');
|
||||||
const exampleTrigger = triggers.find(
|
const exampleTrigger = triggers.find(
|
||||||
(trigger) => trigger.key === 'newIssues'
|
(trigger) => trigger.key === 'newIssues'
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ export default async (request, response) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const connectionParams = (request) => {
|
const connectionParams = (request) => {
|
||||||
const { formattedData, appAuthClientId } = request.body;
|
const { formattedData, oauthClientId } = request.body;
|
||||||
return { formattedData, appAuthClientId };
|
return { formattedData, oauthClientId };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
export async function up(knex) {
|
||||||
|
await knex.schema.renameTable('app_auth_clients', 'oauth_clients');
|
||||||
|
|
||||||
|
await knex.schema.raw(
|
||||||
|
'ALTER INDEX app_auth_clients_pkey RENAME TO oauth_clients_pkey'
|
||||||
|
);
|
||||||
|
|
||||||
|
await knex.schema.raw(
|
||||||
|
'ALTER INDEX app_auth_clients_name_unique RENAME TO oauth_clients_name_unique'
|
||||||
|
);
|
||||||
|
|
||||||
|
return await knex.schema.alterTable('connections', (table) => {
|
||||||
|
table.renameColumn('app_auth_client_id', 'oauth_client_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex) {
|
||||||
|
await knex.schema.renameTable('oauth_clients', 'app_auth_clients');
|
||||||
|
|
||||||
|
await knex.schema.raw(
|
||||||
|
'ALTER INDEX oauth_clients_pkey RENAME TO app_auth_clients_pkey'
|
||||||
|
);
|
||||||
|
|
||||||
|
await knex.schema.raw(
|
||||||
|
'ALTER INDEX oauth_clients_name_unique RENAME TO app_auth_clients_name_unique'
|
||||||
|
);
|
||||||
|
|
||||||
|
return await knex.schema.alterTable('connections', (table) => {
|
||||||
|
table.renameColumn('oauth_client_id', 'app_auth_client_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -88,8 +88,8 @@ const sharedAuthenticationStepsWithAuthUrl = [
|
|||||||
value: '{key}',
|
value: '{key}',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'appAuthClientId',
|
name: 'oauthClientId',
|
||||||
value: '{appAuthClientId}',
|
value: '{oauthClientId}',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,10 +3,6 @@
|
|||||||
exports[`Connection model > jsonSchema should have correct validations 1`] = `
|
exports[`Connection model > jsonSchema should have correct validations 1`] = `
|
||||||
{
|
{
|
||||||
"properties": {
|
"properties": {
|
||||||
"appAuthClientId": {
|
|
||||||
"format": "uuid",
|
|
||||||
"type": "string",
|
|
||||||
},
|
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
@@ -31,6 +27,10 @@ exports[`Connection model > jsonSchema should have correct validations 1`] = `
|
|||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
|
"oauthClientId": {
|
||||||
|
"format": "uuid",
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
"updatedAt": {
|
"updatedAt": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`AppAuthClient model > jsonSchema should have correct validations 1`] = `
|
exports[`OAuthClient model > jsonSchema should have correct validations 1`] = `
|
||||||
{
|
{
|
||||||
"properties": {
|
"properties": {
|
||||||
"active": {
|
"active": {
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
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 Base from './base.js';
|
|
||||||
import appConfig from '../config/app.js';
|
|
||||||
import { createAppAuthClient } from '../../test/factories/app-auth-client.js';
|
|
||||||
|
|
||||||
describe('AppAuthClient model', () => {
|
|
||||||
it('tableName should return correct name', () => {
|
|
||||||
expect(AppAuthClient.tableName).toBe('app_auth_clients');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('jsonSchema should have correct validations', () => {
|
|
||||||
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(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'eligibleForEncryption'
|
|
||||||
).mockReturnValue(false);
|
|
||||||
|
|
||||||
const appAuthClient = new AppAuthClient();
|
|
||||||
|
|
||||||
expect(appAuthClient.encryptData()).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should encrypt formattedAuthDefaults and set it to authDefaults', async () => {
|
|
||||||
vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'eligibleForEncryption'
|
|
||||||
).mockReturnValue(true);
|
|
||||||
|
|
||||||
const formattedAuthDefaults = {
|
|
||||||
key: 'value',
|
|
||||||
};
|
|
||||||
|
|
||||||
const appAuthClient = new AppAuthClient();
|
|
||||||
appAuthClient.formattedAuthDefaults = formattedAuthDefaults;
|
|
||||||
appAuthClient.encryptData();
|
|
||||||
|
|
||||||
const expectedDecryptedValue = JSON.parse(
|
|
||||||
AES.decrypt(
|
|
||||||
appAuthClient.authDefaults,
|
|
||||||
appConfig.encryptionKey
|
|
||||||
).toString(enc)
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(formattedAuthDefaults).toStrictEqual(expectedDecryptedValue);
|
|
||||||
expect(appAuthClient.authDefaults).not.toStrictEqual(
|
|
||||||
formattedAuthDefaults
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should encrypt formattedAuthDefaults and remove formattedAuthDefaults', async () => {
|
|
||||||
vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'eligibleForEncryption'
|
|
||||||
).mockReturnValue(true);
|
|
||||||
|
|
||||||
const formattedAuthDefaults = {
|
|
||||||
key: 'value',
|
|
||||||
};
|
|
||||||
|
|
||||||
const appAuthClient = new AppAuthClient();
|
|
||||||
appAuthClient.formattedAuthDefaults = formattedAuthDefaults;
|
|
||||||
appAuthClient.encryptData();
|
|
||||||
|
|
||||||
expect(appAuthClient.formattedAuthDefaults).not.toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('decryptData', () => {
|
|
||||||
it('should return undefined if eligibleForDecryption is not true', () => {
|
|
||||||
vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'eligibleForDecryption'
|
|
||||||
).mockReturnValue(false);
|
|
||||||
|
|
||||||
const appAuthClient = new AppAuthClient();
|
|
||||||
|
|
||||||
expect(appAuthClient.decryptData()).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should decrypt authDefaults and set it to formattedAuthDefaults', async () => {
|
|
||||||
vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'eligibleForDecryption'
|
|
||||||
).mockReturnValue(true);
|
|
||||||
|
|
||||||
const formattedAuthDefaults = {
|
|
||||||
key: 'value',
|
|
||||||
};
|
|
||||||
|
|
||||||
const authDefaults = AES.encrypt(
|
|
||||||
JSON.stringify(formattedAuthDefaults),
|
|
||||||
appConfig.encryptionKey
|
|
||||||
).toString();
|
|
||||||
|
|
||||||
const appAuthClient = new AppAuthClient();
|
|
||||||
appAuthClient.authDefaults = authDefaults;
|
|
||||||
appAuthClient.decryptData();
|
|
||||||
|
|
||||||
expect(appAuthClient.formattedAuthDefaults).toStrictEqual(
|
|
||||||
formattedAuthDefaults
|
|
||||||
);
|
|
||||||
expect(appAuthClient.authDefaults).not.toStrictEqual(
|
|
||||||
formattedAuthDefaults
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('eligibleForEncryption', () => {
|
|
||||||
it('should return true when formattedAuthDefaults property exists', async () => {
|
|
||||||
const appAuthClient = await createAppAuthClient();
|
|
||||||
|
|
||||||
expect(appAuthClient.eligibleForEncryption()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return false when formattedAuthDefaults property doesn't exist", async () => {
|
|
||||||
const appAuthClient = await createAppAuthClient();
|
|
||||||
|
|
||||||
delete appAuthClient.formattedAuthDefaults;
|
|
||||||
|
|
||||||
expect(appAuthClient.eligibleForEncryption()).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('eligibleForDecryption', () => {
|
|
||||||
it('should return true when authDefaults property exists', async () => {
|
|
||||||
const appAuthClient = await createAppAuthClient();
|
|
||||||
|
|
||||||
expect(appAuthClient.eligibleForDecryption()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return false when authDefaults property doesn't exist", async () => {
|
|
||||||
const appAuthClient = await createAppAuthClient();
|
|
||||||
|
|
||||||
delete appAuthClient.authDefaults;
|
|
||||||
|
|
||||||
expect(appAuthClient.eligibleForDecryption()).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('$beforeInsert should call AppAuthClient.encryptData', async () => {
|
|
||||||
const appAuthClientBeforeInsertSpy = vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'encryptData'
|
|
||||||
);
|
|
||||||
|
|
||||||
await createAppAuthClient();
|
|
||||||
|
|
||||||
expect(appAuthClientBeforeInsertSpy).toHaveBeenCalledOnce();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('$beforeUpdate should call AppAuthClient.encryptData', async () => {
|
|
||||||
const appAuthClient = await createAppAuthClient();
|
|
||||||
|
|
||||||
const appAuthClientBeforeUpdateSpy = vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'encryptData'
|
|
||||||
);
|
|
||||||
|
|
||||||
await appAuthClient.$query().patchAndFetch({ name: 'sample' });
|
|
||||||
|
|
||||||
expect(appAuthClientBeforeUpdateSpy).toHaveBeenCalledOnce();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('$afterFind should call AppAuthClient.decryptData', async () => {
|
|
||||||
const appAuthClient = await createAppAuthClient();
|
|
||||||
|
|
||||||
const appAuthClientAfterFindSpy = vi.spyOn(
|
|
||||||
AppAuthClient.prototype,
|
|
||||||
'decryptData'
|
|
||||||
);
|
|
||||||
|
|
||||||
await appAuthClient.$query();
|
|
||||||
|
|
||||||
expect(appAuthClientAfterFindSpy).toHaveBeenCalledOnce();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import App from './app.js';
|
import App from './app.js';
|
||||||
import AppAuthClient from './app-auth-client.js';
|
import OAuthClient from './oauth-client.js';
|
||||||
import Base from './base.js';
|
import Base from './base.js';
|
||||||
|
|
||||||
class AppConfig extends Base {
|
class AppConfig extends Base {
|
||||||
@@ -24,12 +24,12 @@ class AppConfig extends Base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static relationMappings = () => ({
|
static relationMappings = () => ({
|
||||||
appAuthClients: {
|
oauthClients: {
|
||||||
relation: Base.HasManyRelation,
|
relation: Base.HasManyRelation,
|
||||||
modelClass: AppAuthClient,
|
modelClass: OAuthClient,
|
||||||
join: {
|
join: {
|
||||||
from: 'app_configs.key',
|
from: 'app_configs.key',
|
||||||
to: 'app_auth_clients.app_key',
|
to: 'oauth_clients.app_key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { describe, it, expect } from 'vitest';
|
|||||||
import Base from './base.js';
|
import Base from './base.js';
|
||||||
import AppConfig from './app-config.js';
|
import AppConfig from './app-config.js';
|
||||||
import App from './app.js';
|
import App from './app.js';
|
||||||
import AppAuthClient from './app-auth-client.js';
|
import OAuthClient from './oauth-client.js';
|
||||||
|
|
||||||
describe('AppConfig model', () => {
|
describe('AppConfig model', () => {
|
||||||
it('tableName should return correct name', () => {
|
it('tableName should return correct name', () => {
|
||||||
@@ -22,12 +22,12 @@ describe('AppConfig model', () => {
|
|||||||
const relationMappings = AppConfig.relationMappings();
|
const relationMappings = AppConfig.relationMappings();
|
||||||
|
|
||||||
const expectedRelations = {
|
const expectedRelations = {
|
||||||
appAuthClients: {
|
oauthClients: {
|
||||||
relation: Base.HasManyRelation,
|
relation: Base.HasManyRelation,
|
||||||
modelClass: AppAuthClient,
|
modelClass: OAuthClient,
|
||||||
join: {
|
join: {
|
||||||
from: 'app_configs.key',
|
from: 'app_configs.key',
|
||||||
to: 'app_auth_clients.app_key',
|
to: 'oauth_clients.app_key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import AES from 'crypto-js/aes.js';
|
|||||||
import enc from 'crypto-js/enc-utf8.js';
|
import enc from 'crypto-js/enc-utf8.js';
|
||||||
import App from './app.js';
|
import App from './app.js';
|
||||||
import AppConfig from './app-config.js';
|
import AppConfig from './app-config.js';
|
||||||
import AppAuthClient from './app-auth-client.js';
|
import OAuthClient from './oauth-client.js';
|
||||||
import Base from './base.js';
|
import Base from './base.js';
|
||||||
import User from './user.js';
|
import User from './user.js';
|
||||||
import Step from './step.js';
|
import Step from './step.js';
|
||||||
@@ -24,7 +24,7 @@ class Connection extends Base {
|
|||||||
data: { type: 'string' },
|
data: { type: 'string' },
|
||||||
formattedData: { type: 'object' },
|
formattedData: { type: 'object' },
|
||||||
userId: { type: 'string', format: 'uuid' },
|
userId: { type: 'string', format: 'uuid' },
|
||||||
appAuthClientId: { type: 'string', format: 'uuid' },
|
oauthClientId: { type: 'string', format: 'uuid' },
|
||||||
verified: { type: 'boolean', default: false },
|
verified: { type: 'boolean', default: false },
|
||||||
draft: { type: 'boolean' },
|
draft: { type: 'boolean' },
|
||||||
deletedAt: { type: 'string' },
|
deletedAt: { type: 'string' },
|
||||||
@@ -69,12 +69,12 @@ class Connection extends Base {
|
|||||||
to: 'app_configs.key',
|
to: 'app_configs.key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
appAuthClient: {
|
oauthClient: {
|
||||||
relation: Base.BelongsToOneRelation,
|
relation: Base.BelongsToOneRelation,
|
||||||
modelClass: AppAuthClient,
|
modelClass: OAuthClient,
|
||||||
join: {
|
join: {
|
||||||
from: 'connections.app_auth_client_id',
|
from: 'connections.oauth_client_id',
|
||||||
to: 'app_auth_clients.id',
|
to: 'oauth_clients.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -136,8 +136,8 @@ class Connection extends Base {
|
|||||||
|
|
||||||
if (!this.formattedData) {
|
if (!this.formattedData) {
|
||||||
const authClient = await appConfig
|
const authClient = await appConfig
|
||||||
.$relatedQuery('appAuthClients')
|
.$relatedQuery('oauthClients')
|
||||||
.findById(this.appAuthClientId)
|
.findById(this.oauthClientId)
|
||||||
.where({ active: true })
|
.where({ active: true })
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
@@ -215,13 +215,13 @@ class Connection extends Base {
|
|||||||
return updatedConnection;
|
return updatedConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateFormattedData({ formattedData, appAuthClientId }) {
|
async updateFormattedData({ formattedData, oauthClientId }) {
|
||||||
if (appAuthClientId) {
|
if (oauthClientId) {
|
||||||
const appAuthClient = await AppAuthClient.query()
|
const oauthClient = await OAuthClient.query()
|
||||||
.findById(appAuthClientId)
|
.findById(oauthClientId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
formattedData = appAuthClient.formattedAuthDefaults;
|
formattedData = oauthClient.formattedAuthDefaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.$query().patchAndFetch({
|
return await this.$query().patchAndFetch({
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { describe, it, expect, vi } from 'vitest';
|
|||||||
import AES from 'crypto-js/aes.js';
|
import AES from 'crypto-js/aes.js';
|
||||||
import enc from 'crypto-js/enc-utf8.js';
|
import enc from 'crypto-js/enc-utf8.js';
|
||||||
import appConfig from '../config/app.js';
|
import appConfig from '../config/app.js';
|
||||||
import AppAuthClient from './app-auth-client.js';
|
import OAuthClient from './oauth-client.js';
|
||||||
import App from './app.js';
|
import App from './app.js';
|
||||||
import AppConfig from './app-config.js';
|
import AppConfig from './app-config.js';
|
||||||
import Base from './base.js';
|
import Base from './base.js';
|
||||||
@@ -12,7 +12,7 @@ import User from './user.js';
|
|||||||
import Telemetry from '../helpers/telemetry/index.js';
|
import Telemetry from '../helpers/telemetry/index.js';
|
||||||
import { createConnection } from '../../test/factories/connection.js';
|
import { createConnection } from '../../test/factories/connection.js';
|
||||||
import { createAppConfig } from '../../test/factories/app-config.js';
|
import { createAppConfig } from '../../test/factories/app-config.js';
|
||||||
import { createAppAuthClient } from '../../test/factories/app-auth-client.js';
|
import { createOAuthClient } from '../../test/factories/oauth-client.js';
|
||||||
|
|
||||||
describe('Connection model', () => {
|
describe('Connection model', () => {
|
||||||
it('tableName should return correct name', () => {
|
it('tableName should return correct name', () => {
|
||||||
@@ -61,12 +61,12 @@ describe('Connection model', () => {
|
|||||||
to: 'app_configs.key',
|
to: 'app_configs.key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
appAuthClient: {
|
oauthClient: {
|
||||||
relation: Base.BelongsToOneRelation,
|
relation: Base.BelongsToOneRelation,
|
||||||
modelClass: AppAuthClient,
|
modelClass: OAuthClient,
|
||||||
join: {
|
join: {
|
||||||
from: 'connections.app_auth_client_id',
|
from: 'connections.oauth_client_id',
|
||||||
to: 'app_auth_clients.id',
|
to: 'oauth_clients.id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -307,13 +307,13 @@ describe('Connection model', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply app auth client auth defaults when creating with shared app auth client', async () => {
|
it('should apply oauth client auth defaults when creating with shared oauth client', async () => {
|
||||||
await createAppConfig({
|
await createAppConfig({
|
||||||
key: 'gitlab',
|
key: 'gitlab',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const appAuthClient = await createAppAuthClient({
|
const oauthClient = await createOAuthClient({
|
||||||
appKey: 'gitlab',
|
appKey: 'gitlab',
|
||||||
active: true,
|
active: true,
|
||||||
formattedAuthDefaults: {
|
formattedAuthDefaults: {
|
||||||
@@ -323,7 +323,7 @@ describe('Connection model', () => {
|
|||||||
|
|
||||||
const connection = await createConnection({
|
const connection = await createConnection({
|
||||||
key: 'gitlab',
|
key: 'gitlab',
|
||||||
appAuthClientId: appAuthClient.id,
|
oauthClientId: oauthClient.id,
|
||||||
formattedData: null,
|
formattedData: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -559,22 +559,22 @@ describe('Connection model', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('updateFormattedData', () => {
|
describe('updateFormattedData', () => {
|
||||||
it('should extend connection data with app auth client auth defaults', async () => {
|
it('should extend connection data with oauth client auth defaults', async () => {
|
||||||
const appAuthClient = await createAppAuthClient({
|
const oauthClient = await createOAuthClient({
|
||||||
formattedAuthDefaults: {
|
formattedAuthDefaults: {
|
||||||
clientId: 'sample-id',
|
clientId: 'sample-id',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const connection = await createConnection({
|
const connection = await createConnection({
|
||||||
appAuthClientId: appAuthClient.id,
|
oauthClientId: oauthClient.id,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
token: 'sample-token',
|
token: 'sample-token',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedConnection = await connection.updateFormattedData({
|
const updatedConnection = await connection.updateFormattedData({
|
||||||
appAuthClientId: appAuthClient.id,
|
oauthClientId: oauthClient.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(updatedConnection.formattedData).toStrictEqual({
|
expect(updatedConnection.formattedData).toStrictEqual({
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import appConfig from '../config/app.js';
|
|||||||
import Base from './base.js';
|
import Base from './base.js';
|
||||||
import AppConfig from './app-config.js';
|
import AppConfig from './app-config.js';
|
||||||
|
|
||||||
class AppAuthClient extends Base {
|
class OAuthClient extends Base {
|
||||||
static tableName = 'app_auth_clients';
|
static tableName = 'oauth_clients';
|
||||||
|
|
||||||
static jsonSchema = {
|
static jsonSchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -27,7 +27,7 @@ class AppAuthClient extends Base {
|
|||||||
relation: Base.BelongsToOneRelation,
|
relation: Base.BelongsToOneRelation,
|
||||||
modelClass: AppConfig,
|
modelClass: AppConfig,
|
||||||
join: {
|
join: {
|
||||||
from: 'app_auth_clients.app_key',
|
from: 'oauth_clients.app_key',
|
||||||
to: 'app_configs.key',
|
to: 'app_configs.key',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -87,4 +87,4 @@ class AppAuthClient extends Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AppAuthClient;
|
export default OAuthClient;
|
||||||
192
packages/backend/src/models/oauth-client.test.js
Normal file
192
packages/backend/src/models/oauth-client.test.js
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
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 OAuthClient from './oauth-client.js';
|
||||||
|
import Base from './base.js';
|
||||||
|
import appConfig from '../config/app.js';
|
||||||
|
import { createOAuthClient } from '../../test/factories/oauth-client.js';
|
||||||
|
|
||||||
|
describe('OAuthClient model', () => {
|
||||||
|
it('tableName should return correct name', () => {
|
||||||
|
expect(OAuthClient.tableName).toBe('oauth_clients');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('jsonSchema should have correct validations', () => {
|
||||||
|
expect(OAuthClient.jsonSchema).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('relationMappings should return correct associations', () => {
|
||||||
|
const relationMappings = OAuthClient.relationMappings();
|
||||||
|
|
||||||
|
const expectedRelations = {
|
||||||
|
appConfig: {
|
||||||
|
relation: Base.BelongsToOneRelation,
|
||||||
|
modelClass: AppConfig,
|
||||||
|
join: {
|
||||||
|
from: 'oauth_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(OAuthClient.prototype, 'eligibleForEncryption').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const oauthClient = new OAuthClient();
|
||||||
|
|
||||||
|
expect(oauthClient.encryptData()).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encrypt formattedAuthDefaults and set it to authDefaults', async () => {
|
||||||
|
vi.spyOn(OAuthClient.prototype, 'eligibleForEncryption').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
const formattedAuthDefaults = {
|
||||||
|
key: 'value',
|
||||||
|
};
|
||||||
|
|
||||||
|
const oauthClient = new OAuthClient();
|
||||||
|
oauthClient.formattedAuthDefaults = formattedAuthDefaults;
|
||||||
|
oauthClient.encryptData();
|
||||||
|
|
||||||
|
const expectedDecryptedValue = JSON.parse(
|
||||||
|
AES.decrypt(oauthClient.authDefaults, appConfig.encryptionKey).toString(
|
||||||
|
enc
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(formattedAuthDefaults).toStrictEqual(expectedDecryptedValue);
|
||||||
|
expect(oauthClient.authDefaults).not.toStrictEqual(formattedAuthDefaults);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encrypt formattedAuthDefaults and remove formattedAuthDefaults', async () => {
|
||||||
|
vi.spyOn(OAuthClient.prototype, 'eligibleForEncryption').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
const formattedAuthDefaults = {
|
||||||
|
key: 'value',
|
||||||
|
};
|
||||||
|
|
||||||
|
const oauthClient = new OAuthClient();
|
||||||
|
oauthClient.formattedAuthDefaults = formattedAuthDefaults;
|
||||||
|
oauthClient.encryptData();
|
||||||
|
|
||||||
|
expect(oauthClient.formattedAuthDefaults).not.toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('decryptData', () => {
|
||||||
|
it('should return undefined if eligibleForDecryption is not true', () => {
|
||||||
|
vi.spyOn(OAuthClient.prototype, 'eligibleForDecryption').mockReturnValue(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const oauthClient = new OAuthClient();
|
||||||
|
|
||||||
|
expect(oauthClient.decryptData()).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should decrypt authDefaults and set it to formattedAuthDefaults', async () => {
|
||||||
|
vi.spyOn(OAuthClient.prototype, 'eligibleForDecryption').mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
const formattedAuthDefaults = {
|
||||||
|
key: 'value',
|
||||||
|
};
|
||||||
|
|
||||||
|
const authDefaults = AES.encrypt(
|
||||||
|
JSON.stringify(formattedAuthDefaults),
|
||||||
|
appConfig.encryptionKey
|
||||||
|
).toString();
|
||||||
|
|
||||||
|
const oauthClient = new OAuthClient();
|
||||||
|
oauthClient.authDefaults = authDefaults;
|
||||||
|
oauthClient.decryptData();
|
||||||
|
|
||||||
|
expect(oauthClient.formattedAuthDefaults).toStrictEqual(
|
||||||
|
formattedAuthDefaults
|
||||||
|
);
|
||||||
|
expect(oauthClient.authDefaults).not.toStrictEqual(formattedAuthDefaults);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('eligibleForEncryption', () => {
|
||||||
|
it('should return true when formattedAuthDefaults property exists', async () => {
|
||||||
|
const oauthClient = await createOAuthClient();
|
||||||
|
|
||||||
|
expect(oauthClient.eligibleForEncryption()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when formattedAuthDefaults property doesn't exist", async () => {
|
||||||
|
const oauthClient = await createOAuthClient();
|
||||||
|
|
||||||
|
delete oauthClient.formattedAuthDefaults;
|
||||||
|
|
||||||
|
expect(oauthClient.eligibleForEncryption()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('eligibleForDecryption', () => {
|
||||||
|
it('should return true when authDefaults property exists', async () => {
|
||||||
|
const oauthClient = await createOAuthClient();
|
||||||
|
|
||||||
|
expect(oauthClient.eligibleForDecryption()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when authDefaults property doesn't exist", async () => {
|
||||||
|
const oauthClient = await createOAuthClient();
|
||||||
|
|
||||||
|
delete oauthClient.authDefaults;
|
||||||
|
|
||||||
|
expect(oauthClient.eligibleForDecryption()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('$beforeInsert should call OAuthClient.encryptData', async () => {
|
||||||
|
const oauthClientBeforeInsertSpy = vi.spyOn(
|
||||||
|
OAuthClient.prototype,
|
||||||
|
'encryptData'
|
||||||
|
);
|
||||||
|
|
||||||
|
await createOAuthClient();
|
||||||
|
|
||||||
|
expect(oauthClientBeforeInsertSpy).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('$beforeUpdate should call OAuthClient.encryptData', async () => {
|
||||||
|
const oauthClient = await createOAuthClient();
|
||||||
|
|
||||||
|
const oauthClientBeforeUpdateSpy = vi.spyOn(
|
||||||
|
OAuthClient.prototype,
|
||||||
|
'encryptData'
|
||||||
|
);
|
||||||
|
|
||||||
|
await oauthClient.$query().patchAndFetch({ name: 'sample' });
|
||||||
|
|
||||||
|
expect(oauthClientBeforeUpdateSpy).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('$afterFind should call OAuthClient.decryptData', async () => {
|
||||||
|
const oauthClient = await createOAuthClient();
|
||||||
|
|
||||||
|
const oauthClientAfterFindSpy = vi.spyOn(
|
||||||
|
OAuthClient.prototype,
|
||||||
|
'decryptData'
|
||||||
|
);
|
||||||
|
|
||||||
|
await oauthClient.$query();
|
||||||
|
|
||||||
|
expect(oauthClientAfterFindSpy).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -4,10 +4,10 @@ import { authorizeAdmin } from '../../../../helpers/authorization.js';
|
|||||||
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
||||||
import createConfigAction from '../../../../controllers/api/v1/admin/apps/create-config.ee.js';
|
import createConfigAction from '../../../../controllers/api/v1/admin/apps/create-config.ee.js';
|
||||||
import updateConfigAction from '../../../../controllers/api/v1/admin/apps/update-config.ee.js';
|
import updateConfigAction from '../../../../controllers/api/v1/admin/apps/update-config.ee.js';
|
||||||
import getAuthClientsAction from '../../../../controllers/api/v1/admin/apps/get-auth-clients.ee.js';
|
import getOAuthClientsAction from '../../../../controllers/api/v1/admin/apps/get-oauth-clients.ee.js';
|
||||||
import getAuthClientAction from '../../../../controllers/api/v1/admin/apps/get-auth-client.ee.js';
|
import getOAuthClientAction from '../../../../controllers/api/v1/admin/apps/get-oauth-client.ee.js';
|
||||||
import createAuthClientAction from '../../../../controllers/api/v1/admin/apps/create-auth-client.ee.js';
|
import createOAuthClientAction from '../../../../controllers/api/v1/admin/apps/create-oauth-client.ee.js';
|
||||||
import updateAuthClientAction from '../../../../controllers/api/v1/admin/apps/update-auth-client.ee.js';
|
import updateOAuthClientAction from '../../../../controllers/api/v1/admin/apps/update-oauth-client.ee.js';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@@ -28,35 +28,35 @@ router.patch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:appKey/auth-clients',
|
'/:appKey/oauth-clients',
|
||||||
authenticateUser,
|
authenticateUser,
|
||||||
authorizeAdmin,
|
authorizeAdmin,
|
||||||
checkIsEnterprise,
|
checkIsEnterprise,
|
||||||
getAuthClientsAction
|
getOAuthClientsAction
|
||||||
);
|
);
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
'/:appKey/auth-clients',
|
'/:appKey/oauth-clients',
|
||||||
authenticateUser,
|
authenticateUser,
|
||||||
authorizeAdmin,
|
authorizeAdmin,
|
||||||
checkIsEnterprise,
|
checkIsEnterprise,
|
||||||
createAuthClientAction
|
createOAuthClientAction
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:appKey/auth-clients/:appAuthClientId',
|
'/:appKey/oauth-clients/:oauthClientId',
|
||||||
authenticateUser,
|
authenticateUser,
|
||||||
authorizeAdmin,
|
authorizeAdmin,
|
||||||
checkIsEnterprise,
|
checkIsEnterprise,
|
||||||
getAuthClientAction
|
getOAuthClientAction
|
||||||
);
|
);
|
||||||
|
|
||||||
router.patch(
|
router.patch(
|
||||||
'/:appKey/auth-clients/:appAuthClientId',
|
'/:appKey/oauth-clients/:oauthClientId',
|
||||||
authenticateUser,
|
authenticateUser,
|
||||||
authorizeAdmin,
|
authorizeAdmin,
|
||||||
checkIsEnterprise,
|
checkIsEnterprise,
|
||||||
updateAuthClientAction
|
updateOAuthClientAction
|
||||||
);
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import getAppsAction from '../../../controllers/api/v1/apps/get-apps.js';
|
|||||||
import getAuthAction from '../../../controllers/api/v1/apps/get-auth.js';
|
import getAuthAction from '../../../controllers/api/v1/apps/get-auth.js';
|
||||||
import getConnectionsAction from '../../../controllers/api/v1/apps/get-connections.js';
|
import getConnectionsAction from '../../../controllers/api/v1/apps/get-connections.js';
|
||||||
import getConfigAction from '../../../controllers/api/v1/apps/get-config.ee.js';
|
import getConfigAction from '../../../controllers/api/v1/apps/get-config.ee.js';
|
||||||
import getAuthClientsAction from '../../../controllers/api/v1/apps/get-auth-clients.ee.js';
|
import getOAuthClientsAction from '../../../controllers/api/v1/apps/get-oauth-clients.ee.js';
|
||||||
import getAuthClientAction from '../../../controllers/api/v1/apps/get-auth-client.ee.js';
|
import getOAuthClientAction from '../../../controllers/api/v1/apps/get-oauth-client.ee.js';
|
||||||
import getTriggersAction from '../../../controllers/api/v1/apps/get-triggers.js';
|
import getTriggersAction from '../../../controllers/api/v1/apps/get-triggers.js';
|
||||||
import getTriggerSubstepsAction from '../../../controllers/api/v1/apps/get-trigger-substeps.js';
|
import getTriggerSubstepsAction from '../../../controllers/api/v1/apps/get-trigger-substeps.js';
|
||||||
import getActionsAction from '../../../controllers/api/v1/apps/get-actions.js';
|
import getActionsAction from '../../../controllers/api/v1/apps/get-actions.js';
|
||||||
@@ -44,17 +44,17 @@ router.get(
|
|||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:appKey/auth-clients',
|
'/:appKey/oauth-clients',
|
||||||
authenticateUser,
|
authenticateUser,
|
||||||
checkIsEnterprise,
|
checkIsEnterprise,
|
||||||
getAuthClientsAction
|
getOAuthClientsAction
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:appKey/auth-clients/:appAuthClientId',
|
'/:appKey/oauth-clients/:oauthClientId',
|
||||||
authenticateUser,
|
authenticateUser,
|
||||||
checkIsEnterprise,
|
checkIsEnterprise,
|
||||||
getAuthClientAction
|
getOAuthClientAction
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get('/:appKey/triggers', authenticateUser, getTriggersAction);
|
router.get('/:appKey/triggers', authenticateUser, getTriggersAction);
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
const appAuthClientSerializer = (appAuthClient) => {
|
|
||||||
return {
|
|
||||||
id: appAuthClient.id,
|
|
||||||
appConfigId: appAuthClient.appConfigId,
|
|
||||||
name: appAuthClient.name,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default appAuthClientSerializer;
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { describe, it, expect, beforeEach } from 'vitest';
|
|
||||||
import { createAppAuthClient } from '../../test/factories/app-auth-client';
|
|
||||||
import appAuthClientSerializer from './app-auth-client';
|
|
||||||
|
|
||||||
describe('appAuthClient serializer', () => {
|
|
||||||
let appAuthClient;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
appAuthClient = await createAppAuthClient();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return app auth client data', async () => {
|
|
||||||
const expectedPayload = {
|
|
||||||
id: appAuthClient.id,
|
|
||||||
appConfigId: appAuthClient.appConfigId,
|
|
||||||
name: appAuthClient.name,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(appAuthClientSerializer(appAuthClient)).toStrictEqual(
|
|
||||||
expectedPayload
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -2,7 +2,7 @@ const connectionSerializer = (connection) => {
|
|||||||
return {
|
return {
|
||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
screenName: connection.formattedData.screenName,
|
screenName: connection.formattedData.screenName,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ describe('connectionSerializer', () => {
|
|||||||
const expectedPayload = {
|
const expectedPayload = {
|
||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
screenName: connection.formattedData.screenName,
|
screenName: connection.formattedData.screenName,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import permissionSerializer from './permission.js';
|
|||||||
import adminSamlAuthProviderSerializer from './admin-saml-auth-provider.ee.js';
|
import adminSamlAuthProviderSerializer from './admin-saml-auth-provider.ee.js';
|
||||||
import samlAuthProviderSerializer from './saml-auth-provider.ee.js';
|
import samlAuthProviderSerializer from './saml-auth-provider.ee.js';
|
||||||
import samlAuthProviderRoleMappingSerializer from './role-mapping.ee.js';
|
import samlAuthProviderRoleMappingSerializer from './role-mapping.ee.js';
|
||||||
import appAuthClientSerializer from './app-auth-client.js';
|
import oauthClientSerializer from './oauth-client.js';
|
||||||
import appConfigSerializer from './app-config.js';
|
import appConfigSerializer from './app-config.js';
|
||||||
import flowSerializer from './flow.js';
|
import flowSerializer from './flow.js';
|
||||||
import stepSerializer from './step.js';
|
import stepSerializer from './step.js';
|
||||||
@@ -28,7 +28,7 @@ const serializers = {
|
|||||||
AdminSamlAuthProvider: adminSamlAuthProviderSerializer,
|
AdminSamlAuthProvider: adminSamlAuthProviderSerializer,
|
||||||
SamlAuthProvider: samlAuthProviderSerializer,
|
SamlAuthProvider: samlAuthProviderSerializer,
|
||||||
RoleMapping: samlAuthProviderRoleMappingSerializer,
|
RoleMapping: samlAuthProviderRoleMappingSerializer,
|
||||||
AppAuthClient: appAuthClientSerializer,
|
OAuthClient: oauthClientSerializer,
|
||||||
AppConfig: appConfigSerializer,
|
AppConfig: appConfigSerializer,
|
||||||
Flow: flowSerializer,
|
Flow: flowSerializer,
|
||||||
Step: stepSerializer,
|
Step: stepSerializer,
|
||||||
|
|||||||
10
packages/backend/src/serializers/oauth-client.js
Normal file
10
packages/backend/src/serializers/oauth-client.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const oauthClientSerializer = (oauthClient) => {
|
||||||
|
return {
|
||||||
|
id: oauthClient.id,
|
||||||
|
appConfigId: oauthClient.appConfigId,
|
||||||
|
name: oauthClient.name,
|
||||||
|
active: oauthClient.active,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default oauthClientSerializer;
|
||||||
22
packages/backend/src/serializers/oauth-client.test.js
Normal file
22
packages/backend/src/serializers/oauth-client.test.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||||||
|
import { createOAuthClient } from '../../test/factories/oauth-client';
|
||||||
|
import oauthClientSerializer from './oauth-client';
|
||||||
|
|
||||||
|
describe('oauthClient serializer', () => {
|
||||||
|
let oauthClient;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
oauthClient = await createOAuthClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return oauth client data', async () => {
|
||||||
|
const expectedPayload = {
|
||||||
|
id: oauthClient.id,
|
||||||
|
appConfigId: oauthClient.appConfigId,
|
||||||
|
name: oauthClient.name,
|
||||||
|
active: oauthClient.active,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(oauthClientSerializer(oauthClient)).toStrictEqual(expectedPayload);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
import AppAuthClient from '../../src/models/app-auth-client';
|
import OAuthClient from '../../src/models/oauth-client';
|
||||||
|
|
||||||
const formattedAuthDefaults = {
|
const formattedAuthDefaults = {
|
||||||
oAuthRedirectUrl: faker.internet.url(),
|
oAuthRedirectUrl: faker.internet.url(),
|
||||||
@@ -8,14 +8,14 @@ const formattedAuthDefaults = {
|
|||||||
clientSecret: faker.string.uuid(),
|
clientSecret: faker.string.uuid(),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createAppAuthClient = async (params = {}) => {
|
export const createOAuthClient = async (params = {}) => {
|
||||||
params.name = params?.name || faker.person.fullName();
|
params.name = params?.name || faker.person.fullName();
|
||||||
params.appKey = params?.appKey || 'deepl';
|
params.appKey = params?.appKey || 'deepl';
|
||||||
params.active = params?.active ?? true;
|
params.active = params?.active ?? true;
|
||||||
params.formattedAuthDefaults =
|
params.formattedAuthDefaults =
|
||||||
params?.formattedAuthDefaults || formattedAuthDefaults;
|
params?.formattedAuthDefaults || formattedAuthDefaults;
|
||||||
|
|
||||||
const appAuthClient = await AppAuthClient.query().insertAndFetch(params);
|
const oauthClient = await OAuthClient.query().insertAndFetch(params);
|
||||||
|
|
||||||
return appAuthClient;
|
return oauthClient;
|
||||||
};
|
};
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
const createAppAuthClientMock = (appAuthClient) => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
name: appAuthClient.name,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
count: 1,
|
|
||||||
currentPage: null,
|
|
||||||
isArray: false,
|
|
||||||
totalPages: null,
|
|
||||||
type: 'AppAuthClient',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createAppAuthClientMock;
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
const createOAuthClientMock = (oauthClient) => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
name: oauthClient.name,
|
||||||
|
active: oauthClient.active,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
count: 1,
|
||||||
|
currentPage: null,
|
||||||
|
isArray: false,
|
||||||
|
totalPages: null,
|
||||||
|
type: 'OAuthClient',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createOAuthClientMock;
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const getAppAuthClientMock = (appAuthClient) => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
name: appAuthClient.name,
|
|
||||||
id: appAuthClient.id,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
count: 1,
|
|
||||||
currentPage: null,
|
|
||||||
isArray: false,
|
|
||||||
totalPages: null,
|
|
||||||
type: 'AppAuthClient',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getAppAuthClientMock;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const getAdminAppAuthClientsMock = (appAuthClients) => {
|
|
||||||
return {
|
|
||||||
data: appAuthClients.map((appAuthClient) => ({
|
|
||||||
name: appAuthClient.name,
|
|
||||||
id: appAuthClient.id,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
})),
|
|
||||||
meta: {
|
|
||||||
count: appAuthClients.length,
|
|
||||||
currentPage: null,
|
|
||||||
isArray: true,
|
|
||||||
totalPages: null,
|
|
||||||
type: 'AppAuthClient',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getAdminAppAuthClientsMock;
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const getOAuthClientMock = (oauthClient) => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
name: oauthClient.name,
|
||||||
|
id: oauthClient.id,
|
||||||
|
active: oauthClient.active,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
count: 1,
|
||||||
|
currentPage: null,
|
||||||
|
isArray: false,
|
||||||
|
totalPages: null,
|
||||||
|
type: 'OAuthClient',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getOAuthClientMock;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const getAdminOAuthClientsMock = (oauthClients) => {
|
||||||
|
return {
|
||||||
|
data: oauthClients.map((oauthClient) => ({
|
||||||
|
name: oauthClient.name,
|
||||||
|
id: oauthClient.id,
|
||||||
|
active: oauthClient.active,
|
||||||
|
})),
|
||||||
|
meta: {
|
||||||
|
count: oauthClients.length,
|
||||||
|
currentPage: null,
|
||||||
|
isArray: true,
|
||||||
|
totalPages: null,
|
||||||
|
type: 'OAuthClient',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getAdminOAuthClientsMock;
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const updateAppAuthClientMock = (appAuthClient) => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
id: appAuthClient.id,
|
|
||||||
name: appAuthClient.name,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
count: 1,
|
|
||||||
currentPage: null,
|
|
||||||
isArray: false,
|
|
||||||
totalPages: null,
|
|
||||||
type: 'AppAuthClient',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default updateAppAuthClientMock;
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const updateOAuthClientMock = (oauthClient) => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
id: oauthClient.id,
|
||||||
|
name: oauthClient.name,
|
||||||
|
active: oauthClient.active,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
count: 1,
|
||||||
|
currentPage: null,
|
||||||
|
isArray: false,
|
||||||
|
totalPages: null,
|
||||||
|
type: 'OAuthClient',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default updateOAuthClientMock;
|
||||||
@@ -2,7 +2,7 @@ const createConnection = (connection) => {
|
|||||||
const connectionData = {
|
const connectionData = {
|
||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: connection.formattedData,
|
formattedData: connection.formattedData,
|
||||||
verified: connection.verified || false,
|
verified: connection.verified || false,
|
||||||
createdAt: connection.createdAt.getTime(),
|
createdAt: connection.createdAt.getTime(),
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
const getAppAuthClientMock = (appAuthClient) => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
name: appAuthClient.name,
|
|
||||||
id: appAuthClient.id,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
count: 1,
|
|
||||||
currentPage: null,
|
|
||||||
isArray: false,
|
|
||||||
totalPages: null,
|
|
||||||
type: 'AppAuthClient',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getAppAuthClientMock;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
const getAppAuthClientsMock = (appAuthClients) => {
|
|
||||||
return {
|
|
||||||
data: appAuthClients.map((appAuthClient) => ({
|
|
||||||
name: appAuthClient.name,
|
|
||||||
id: appAuthClient.id,
|
|
||||||
active: appAuthClient.active,
|
|
||||||
})),
|
|
||||||
meta: {
|
|
||||||
count: appAuthClients.length,
|
|
||||||
currentPage: null,
|
|
||||||
isArray: true,
|
|
||||||
totalPages: null,
|
|
||||||
type: 'AppAuthClient',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getAppAuthClientsMock;
|
|
||||||
@@ -4,7 +4,7 @@ const getConnectionsMock = (connections) => {
|
|||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
verified: connection.verified,
|
verified: connection.verified,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
screenName: connection.formattedData.screenName,
|
screenName: connection.formattedData.screenName,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const getOAuthClientMock = (oauthClient) => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
name: oauthClient.name,
|
||||||
|
id: oauthClient.id,
|
||||||
|
active: oauthClient.active,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
count: 1,
|
||||||
|
currentPage: null,
|
||||||
|
isArray: false,
|
||||||
|
totalPages: null,
|
||||||
|
type: 'OAuthClient',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getOAuthClientMock;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const getOAuthClientsMock = (oauthClients) => {
|
||||||
|
return {
|
||||||
|
data: oauthClients.map((oauthClient) => ({
|
||||||
|
name: oauthClient.name,
|
||||||
|
id: oauthClient.id,
|
||||||
|
active: oauthClient.active,
|
||||||
|
})),
|
||||||
|
meta: {
|
||||||
|
count: oauthClients.length,
|
||||||
|
currentPage: null,
|
||||||
|
isArray: true,
|
||||||
|
totalPages: null,
|
||||||
|
type: 'OAuthClient',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getOAuthClientsMock;
|
||||||
@@ -3,7 +3,7 @@ const resetConnectionMock = (connection) => {
|
|||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
verified: connection.verified,
|
verified: connection.verified,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
screenName: connection.formattedData.screenName,
|
screenName: connection.formattedData.screenName,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const updateConnectionMock = (connection) => {
|
|||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
verified: connection.verified,
|
verified: connection.verified,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
screenName: connection.formattedData.screenName,
|
screenName: connection.formattedData.screenName,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const getConnectionMock = async (connection) => {
|
|||||||
id: connection.id,
|
id: connection.id,
|
||||||
key: connection.key,
|
key: connection.key,
|
||||||
verified: connection.verified,
|
verified: connection.verified,
|
||||||
appAuthClientId: connection.appAuthClientId,
|
oauthClientId: connection.oauthClientId,
|
||||||
formattedData: {
|
formattedData: {
|
||||||
screenName: connection.formattedData.screenName,
|
screenName: connection.formattedData.screenName,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import { expect } from '@playwright/test';
|
|||||||
|
|
||||||
const { AuthenticatedPage } = require('../authenticated-page');
|
const { AuthenticatedPage } = require('../authenticated-page');
|
||||||
|
|
||||||
export class AdminApplicationAuthClientsPage extends AuthenticatedPage {
|
export class AdminApplicationOAuthClientsPage extends AuthenticatedPage {
|
||||||
/**
|
/**
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
constructor(page) {
|
constructor(page) {
|
||||||
super(page);
|
super(page);
|
||||||
|
|
||||||
this.authClientsTab = this.page.getByTestId('auth-clients-tab');
|
this.authClientsTab = this.page.getByTestId('oauth-clients-tab');
|
||||||
this.saveButton = this.page.getByTestId('submitButton');
|
this.saveButton = this.page.getByTestId('submitButton');
|
||||||
this.successSnackbar = this.page.getByTestId(
|
this.successSnackbar = this.page.getByTestId(
|
||||||
'snackbar-save-admin-apps-settings-success'
|
'snackbar-save-admin-apps-settings-success'
|
||||||
@@ -8,7 +8,9 @@ const { AdminEditRolePage } = require('./edit-role-page');
|
|||||||
|
|
||||||
const { AdminApplicationsPage } = require('./applications-page');
|
const { AdminApplicationsPage } = require('./applications-page');
|
||||||
const { AdminApplicationSettingsPage } = require('./application-settings-page');
|
const { AdminApplicationSettingsPage } = require('./application-settings-page');
|
||||||
const { AdminApplicationAuthClientsPage } = require('./application-auth-clients-page');
|
const {
|
||||||
|
AdminApplicationOAuthClientsPage,
|
||||||
|
} = require('./application-oauth-clients-page');
|
||||||
|
|
||||||
export const adminFixtures = {
|
export const adminFixtures = {
|
||||||
adminUsersPage: async ({ page }, use) => {
|
adminUsersPage: async ({ page }, use) => {
|
||||||
@@ -35,8 +37,7 @@ export const adminFixtures = {
|
|||||||
adminApplicationSettingsPage: async ({ page }, use) => {
|
adminApplicationSettingsPage: async ({ page }, use) => {
|
||||||
await use(new AdminApplicationSettingsPage(page));
|
await use(new AdminApplicationSettingsPage(page));
|
||||||
},
|
},
|
||||||
adminApplicationAuthClientsPage: async ({ page }, use) => {
|
adminApplicationOAuthClientsPage: async ({ page }, use) => {
|
||||||
await use(new AdminApplicationAuthClientsPage(page));
|
await use(new AdminApplicationOAuthClientsPage(page));
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ const { insertAppConnection } = require('../../helpers/db-helpers');
|
|||||||
|
|
||||||
test.describe('Admin Applications', () => {
|
test.describe('Admin Applications', () => {
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
const deleteAppAuthClients = {
|
const deleteOAuthClients = {
|
||||||
text: 'DELETE FROM app_auth_clients WHERE app_key in ($1, $2, $3, $4, $5, $6)',
|
text: 'DELETE FROM oauth_clients WHERE app_key in ($1, $2, $3, $4, $5, $6)',
|
||||||
values: [
|
values: [
|
||||||
'carbone',
|
'carbone',
|
||||||
'spotify',
|
'spotify',
|
||||||
@@ -29,10 +29,8 @@ test.describe('Admin Applications', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const deleteAppAuthClientsResult = await pgPool.query(
|
const deleteOAuthClientsResult = await pgPool.query(deleteOAuthClients);
|
||||||
deleteAppAuthClients
|
expect(deleteOAuthClientsResult.command).toBe('DELETE');
|
||||||
);
|
|
||||||
expect(deleteAppAuthClientsResult.command).toBe('DELETE');
|
|
||||||
const deleteAppConfigsResult = await pgPool.query(deleteAppConfigs);
|
const deleteAppConfigsResult = await pgPool.query(deleteAppConfigs);
|
||||||
expect(deleteAppConfigsResult.command).toBe('DELETE');
|
expect(deleteAppConfigsResult.command).toBe('DELETE');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -73,7 +71,7 @@ test.describe('Admin Applications', () => {
|
|||||||
test('should allow only custom connections', async ({
|
test('should allow only custom connections', async ({
|
||||||
adminApplicationsPage,
|
adminApplicationsPage,
|
||||||
adminApplicationSettingsPage,
|
adminApplicationSettingsPage,
|
||||||
adminApplicationAuthClientsPage,
|
adminApplicationOAuthClientsPage,
|
||||||
flowEditorPage,
|
flowEditorPage,
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -97,9 +95,9 @@ test.describe('Admin Applications', () => {
|
|||||||
adminApplicationSettingsPage.disableConnectionsSwitch
|
adminApplicationSettingsPage.disableConnectionsSwitch
|
||||||
).not.toBeChecked();
|
).not.toBeChecked();
|
||||||
|
|
||||||
await adminApplicationAuthClientsPage.openAuthClientsTab();
|
await adminApplicationOAuthClientsPage.openAuthClientsTab();
|
||||||
await expect(
|
await expect(
|
||||||
adminApplicationAuthClientsPage.createFirstAuthClientButton
|
adminApplicationOAuthClientsPage.createFirstAuthClientButton
|
||||||
).toHaveCount(1);
|
).toHaveCount(1);
|
||||||
|
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
@@ -119,9 +117,9 @@ test.describe('Admin Applications', () => {
|
|||||||
const newConnectionOption = page
|
const newConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new connection' });
|
.filter({ hasText: 'Add new connection' });
|
||||||
const newSharedConnectionOption = page
|
const newOAuthConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new connection with auth client' });
|
.filter({ hasText: 'Add connection with OAuth client' });
|
||||||
const existingConnection = page
|
const existingConnection = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Unnamed' });
|
.filter({ hasText: 'Unnamed' });
|
||||||
@@ -129,13 +127,13 @@ test.describe('Admin Applications', () => {
|
|||||||
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
||||||
await expect(newConnectionOption).toBeEnabled();
|
await expect(newConnectionOption).toBeEnabled();
|
||||||
await expect(newConnectionOption).toHaveCount(1);
|
await expect(newConnectionOption).toHaveCount(1);
|
||||||
await expect(newSharedConnectionOption).toHaveCount(0);
|
await expect(newOAuthConnectionOption).toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should allow only predefined connections and existing custom', async ({
|
test('should allow only predefined connections and existing custom', async ({
|
||||||
adminApplicationsPage,
|
adminApplicationsPage,
|
||||||
adminApplicationSettingsPage,
|
adminApplicationSettingsPage,
|
||||||
adminApplicationAuthClientsPage,
|
adminApplicationOAuthClientsPage,
|
||||||
flowEditorPage,
|
flowEditorPage,
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -155,8 +153,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await adminApplicationSettingsPage.saveSettings();
|
await adminApplicationSettingsPage.saveSettings();
|
||||||
await adminApplicationSettingsPage.expectSuccessSnackbarToBeVisible();
|
await adminApplicationSettingsPage.expectSuccessSnackbarToBeVisible();
|
||||||
|
|
||||||
await adminApplicationAuthClientsPage.openAuthClientsTab();
|
await adminApplicationOAuthClientsPage.openAuthClientsTab();
|
||||||
await adminApplicationAuthClientsPage.openFirstAuthClientCreateForm();
|
await adminApplicationOAuthClientsPage.openFirstAuthClientCreateForm();
|
||||||
const authClientForm = page.getByTestId('auth-client-form');
|
const authClientForm = page.getByTestId('auth-client-form');
|
||||||
await authClientForm.locator(page.getByTestId('switch')).check();
|
await authClientForm.locator(page.getByTestId('switch')).check();
|
||||||
await authClientForm
|
await authClientForm
|
||||||
@@ -168,8 +166,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await authClientForm
|
await authClientForm
|
||||||
.locator(page.locator('[name="clientSecret"]'))
|
.locator(page.locator('[name="clientSecret"]'))
|
||||||
.fill('spotifyClientSecret');
|
.fill('spotifyClientSecret');
|
||||||
await adminApplicationAuthClientsPage.submitAuthClientForm();
|
await adminApplicationOAuthClientsPage.submitAuthClientForm();
|
||||||
await adminApplicationAuthClientsPage.authClientShouldBeVisible(
|
await adminApplicationOAuthClientsPage.authClientShouldBeVisible(
|
||||||
'spotifyAuthClient'
|
'spotifyAuthClient'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -189,23 +187,23 @@ test.describe('Admin Applications', () => {
|
|||||||
const newConnectionOption = page
|
const newConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new connection' });
|
.filter({ hasText: 'Add new connection' });
|
||||||
const newSharedConnectionOption = page
|
const newOAuthConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add connection with auth client' });
|
.filter({ hasText: 'Add connection with OAuth client' });
|
||||||
const existingConnection = page
|
const existingConnection = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Unnamed' });
|
.filter({ hasText: 'Unnamed' });
|
||||||
|
|
||||||
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
||||||
await expect(newConnectionOption).toHaveCount(0);
|
await expect(newConnectionOption).toHaveCount(0);
|
||||||
await expect(newSharedConnectionOption).toBeEnabled();
|
await expect(newOAuthConnectionOption).toBeEnabled();
|
||||||
await expect(newSharedConnectionOption).toHaveCount(1);
|
await expect(newOAuthConnectionOption).toHaveCount(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should allow all connections', async ({
|
test('should allow all connections', async ({
|
||||||
adminApplicationsPage,
|
adminApplicationsPage,
|
||||||
adminApplicationSettingsPage,
|
adminApplicationSettingsPage,
|
||||||
adminApplicationAuthClientsPage,
|
adminApplicationOAuthClientsPage,
|
||||||
flowEditorPage,
|
flowEditorPage,
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -221,8 +219,8 @@ test.describe('Admin Applications', () => {
|
|||||||
adminApplicationSettingsPage.disableConnectionsSwitch
|
adminApplicationSettingsPage.disableConnectionsSwitch
|
||||||
).not.toBeChecked();
|
).not.toBeChecked();
|
||||||
|
|
||||||
await adminApplicationAuthClientsPage.openAuthClientsTab();
|
await adminApplicationOAuthClientsPage.openAuthClientsTab();
|
||||||
await adminApplicationAuthClientsPage.openFirstAuthClientCreateForm();
|
await adminApplicationOAuthClientsPage.openFirstAuthClientCreateForm();
|
||||||
const authClientForm = page.getByTestId('auth-client-form');
|
const authClientForm = page.getByTestId('auth-client-form');
|
||||||
await authClientForm.locator(page.getByTestId('switch')).check();
|
await authClientForm.locator(page.getByTestId('switch')).check();
|
||||||
await authClientForm
|
await authClientForm
|
||||||
@@ -234,8 +232,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await authClientForm
|
await authClientForm
|
||||||
.locator(page.locator('[name="clientSecret"]'))
|
.locator(page.locator('[name="clientSecret"]'))
|
||||||
.fill('redditClientSecret');
|
.fill('redditClientSecret');
|
||||||
await adminApplicationAuthClientsPage.submitAuthClientForm();
|
await adminApplicationOAuthClientsPage.submitAuthClientForm();
|
||||||
await adminApplicationAuthClientsPage.authClientShouldBeVisible(
|
await adminApplicationOAuthClientsPage.authClientShouldBeVisible(
|
||||||
'redditAuthClient'
|
'redditAuthClient'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -255,23 +253,23 @@ test.describe('Admin Applications', () => {
|
|||||||
const newConnectionOption = page
|
const newConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new connection' });
|
.filter({ hasText: 'Add new connection' });
|
||||||
const newSharedConnectionOption = page
|
const newOAuthConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add connection with auth client' });
|
.filter({ hasText: 'Add connection with OAuth client' });
|
||||||
const existingConnection = page
|
const existingConnection = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Unnamed' });
|
.filter({ hasText: 'Unnamed' });
|
||||||
|
|
||||||
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
||||||
await expect(newConnectionOption).toHaveCount(1);
|
await expect(newConnectionOption).toHaveCount(1);
|
||||||
await expect(newSharedConnectionOption).toBeEnabled();
|
await expect(newOAuthConnectionOption).toBeEnabled();
|
||||||
await expect(newSharedConnectionOption).toHaveCount(1);
|
await expect(newOAuthConnectionOption).toHaveCount(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not allow new connections but existing custom', async ({
|
test('should not allow new connections but existing custom', async ({
|
||||||
adminApplicationsPage,
|
adminApplicationsPage,
|
||||||
adminApplicationSettingsPage,
|
adminApplicationSettingsPage,
|
||||||
adminApplicationAuthClientsPage,
|
adminApplicationOAuthClientsPage,
|
||||||
flowEditorPage,
|
flowEditorPage,
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -284,8 +282,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await adminApplicationSettingsPage.saveSettings();
|
await adminApplicationSettingsPage.saveSettings();
|
||||||
await adminApplicationSettingsPage.expectSuccessSnackbarToBeVisible();
|
await adminApplicationSettingsPage.expectSuccessSnackbarToBeVisible();
|
||||||
|
|
||||||
await adminApplicationAuthClientsPage.openAuthClientsTab();
|
await adminApplicationOAuthClientsPage.openAuthClientsTab();
|
||||||
await adminApplicationAuthClientsPage.openFirstAuthClientCreateForm();
|
await adminApplicationOAuthClientsPage.openFirstAuthClientCreateForm();
|
||||||
|
|
||||||
const authClientForm = page.getByTestId('auth-client-form');
|
const authClientForm = page.getByTestId('auth-client-form');
|
||||||
await authClientForm.locator(page.getByTestId('switch')).check();
|
await authClientForm.locator(page.getByTestId('switch')).check();
|
||||||
@@ -298,8 +296,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await authClientForm
|
await authClientForm
|
||||||
.locator(page.locator('[name="clientSecret"]'))
|
.locator(page.locator('[name="clientSecret"]'))
|
||||||
.fill('clickupClientSecret');
|
.fill('clickupClientSecret');
|
||||||
await adminApplicationAuthClientsPage.submitAuthClientForm();
|
await adminApplicationOAuthClientsPage.submitAuthClientForm();
|
||||||
await adminApplicationAuthClientsPage.authClientShouldBeVisible(
|
await adminApplicationOAuthClientsPage.authClientShouldBeVisible(
|
||||||
'clickupAuthClient'
|
'clickupAuthClient'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -319,22 +317,22 @@ test.describe('Admin Applications', () => {
|
|||||||
const newConnectionOption = page
|
const newConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new connection' });
|
.filter({ hasText: 'Add new connection' });
|
||||||
const newSharedConnectionOption = page
|
const newOAuthConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add connection with auth client' });
|
.filter({ hasText: 'Add connection with OAuth client' });
|
||||||
const existingConnection = page
|
const existingConnection = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Unnamed' });
|
.filter({ hasText: 'Unnamed' });
|
||||||
|
|
||||||
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
||||||
await expect(newConnectionOption).toHaveCount(0);
|
await expect(newConnectionOption).toHaveCount(0);
|
||||||
await expect(newSharedConnectionOption).toHaveCount(0);
|
await expect(newOAuthConnectionOption).toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not allow new connections but existing custom even if predefined auth clients are enabled', async ({
|
test('should not allow new connections but existing custom even if predefined OAuth clients are enabled', async ({
|
||||||
adminApplicationsPage,
|
adminApplicationsPage,
|
||||||
adminApplicationSettingsPage,
|
adminApplicationSettingsPage,
|
||||||
adminApplicationAuthClientsPage,
|
adminApplicationOAuthClientsPage,
|
||||||
flowEditorPage,
|
flowEditorPage,
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -350,8 +348,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await adminApplicationSettingsPage.saveSettings();
|
await adminApplicationSettingsPage.saveSettings();
|
||||||
await adminApplicationSettingsPage.expectSuccessSnackbarToBeVisible();
|
await adminApplicationSettingsPage.expectSuccessSnackbarToBeVisible();
|
||||||
|
|
||||||
await adminApplicationAuthClientsPage.openAuthClientsTab();
|
await adminApplicationOAuthClientsPage.openAuthClientsTab();
|
||||||
await adminApplicationAuthClientsPage.openFirstAuthClientCreateForm();
|
await adminApplicationOAuthClientsPage.openFirstAuthClientCreateForm();
|
||||||
|
|
||||||
const authClientForm = page.getByTestId('auth-client-form');
|
const authClientForm = page.getByTestId('auth-client-form');
|
||||||
await authClientForm.locator(page.getByTestId('switch')).check();
|
await authClientForm.locator(page.getByTestId('switch')).check();
|
||||||
@@ -364,8 +362,8 @@ test.describe('Admin Applications', () => {
|
|||||||
await authClientForm
|
await authClientForm
|
||||||
.locator(page.locator('[name="clientSecret"]'))
|
.locator(page.locator('[name="clientSecret"]'))
|
||||||
.fill('mailchimpClientSecret');
|
.fill('mailchimpClientSecret');
|
||||||
await adminApplicationAuthClientsPage.submitAuthClientForm();
|
await adminApplicationOAuthClientsPage.submitAuthClientForm();
|
||||||
await adminApplicationAuthClientsPage.authClientShouldBeVisible(
|
await adminApplicationOAuthClientsPage.authClientShouldBeVisible(
|
||||||
'mailchimpAuthClient'
|
'mailchimpAuthClient'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -389,9 +387,9 @@ test.describe('Admin Applications', () => {
|
|||||||
const newConnectionOption = page
|
const newConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new connection' });
|
.filter({ hasText: 'Add new connection' });
|
||||||
const newSharedConnectionOption = page
|
const newOAuthConnectionOption = page
|
||||||
.getByRole('option')
|
.getByRole('option')
|
||||||
.filter({ hasText: 'Add new shared connection' });
|
.filter({ hasText: 'Add connection with OAuth client' });
|
||||||
const noConnectionsOption = page
|
const noConnectionsOption = page
|
||||||
.locator('.MuiAutocomplete-noOptions')
|
.locator('.MuiAutocomplete-noOptions')
|
||||||
.filter({ hasText: 'No options' });
|
.filter({ hasText: 'No options' });
|
||||||
@@ -399,6 +397,6 @@ test.describe('Admin Applications', () => {
|
|||||||
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
await expect(await existingConnection.count()).toBeGreaterThan(0);
|
||||||
await expect(noConnectionsOption).toHaveCount(0);
|
await expect(noConnectionsOption).toHaveCount(0);
|
||||||
await expect(newConnectionOption).toHaveCount(0);
|
await expect(newConnectionOption).toHaveCount(0);
|
||||||
await expect(newSharedConnectionOption).toHaveCount(0);
|
await expect(newOAuthConnectionOption).toHaveCount(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ test.describe('Apps page', () => {
|
|||||||
test('goes to app page to create a connection', async ({
|
test('goes to app page to create a connection', async ({
|
||||||
applicationsPage,
|
applicationsPage,
|
||||||
}) => {
|
}) => {
|
||||||
// loading app, app config, app auth clients take time
|
// loading app, app config, app oauth clients take time
|
||||||
test.setTimeout(60000);
|
test.setTimeout(60000);
|
||||||
|
|
||||||
await applicationsPage.page.getByTestId('app-list-item').first().click();
|
await applicationsPage.page.getByTestId('app-list-item').first().click();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import * as React from 'react';
|
|||||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { AppPropType } from 'propTypes/propTypes';
|
import { AppPropType } from 'propTypes/propTypes';
|
||||||
import AppAuthClientsDialog from 'components/AppAuthClientsDialog/index.ee';
|
import AppOAuthClientsDialog from 'components/OAuthClientsDialog/index.ee';
|
||||||
import InputCreator from 'components/InputCreator';
|
import InputCreator from 'components/InputCreator';
|
||||||
import * as URLS from 'config/urls';
|
import * as URLS from 'config/urls';
|
||||||
import useAuthenticateApp from 'hooks/useAuthenticateApp.ee';
|
import useAuthenticateApp from 'hooks/useAuthenticateApp.ee';
|
||||||
@@ -31,12 +31,12 @@ function AddAppConnection(props) {
|
|||||||
const [inProgress, setInProgress] = React.useState(false);
|
const [inProgress, setInProgress] = React.useState(false);
|
||||||
const hasConnection = Boolean(connectionId);
|
const hasConnection = Boolean(connectionId);
|
||||||
const useShared = searchParams.get('shared') === 'true';
|
const useShared = searchParams.get('shared') === 'true';
|
||||||
const appAuthClientId = searchParams.get('appAuthClientId') || undefined;
|
const oauthClientId = searchParams.get('oauthClientId') || undefined;
|
||||||
const { authenticate } = useAuthenticateApp({
|
const { authenticate } = useAuthenticateApp({
|
||||||
appKey: key,
|
appKey: key,
|
||||||
connectionId,
|
connectionId,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
useShared: !!appAuthClientId,
|
useShared: !!oauthClientId,
|
||||||
});
|
});
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
@@ -52,8 +52,8 @@ function AddAppConnection(props) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
React.useEffect(
|
React.useEffect(
|
||||||
function initiateSharedAuthenticationForGivenAuthClient() {
|
function initiateSharedAuthenticationForGivenOAuthClient() {
|
||||||
if (!appAuthClientId) return;
|
if (!oauthClientId) return;
|
||||||
|
|
||||||
if (!authenticate) return;
|
if (!authenticate) return;
|
||||||
|
|
||||||
@@ -64,13 +64,13 @@ function AddAppConnection(props) {
|
|||||||
|
|
||||||
asyncAuthenticate();
|
asyncAuthenticate();
|
||||||
},
|
},
|
||||||
[appAuthClientId, authenticate, key, navigate],
|
[oauthClientId, authenticate, key, navigate],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClientClick = (appAuthClientId) =>
|
const handleClientClick = (oauthClientId) =>
|
||||||
navigate(URLS.APP_ADD_CONNECTION_WITH_AUTH_CLIENT_ID(key, appAuthClientId));
|
navigate(URLS.APP_ADD_CONNECTION_WITH_OAUTH_CLIENT_ID(key, oauthClientId));
|
||||||
|
|
||||||
const handleAuthClientsDialogClose = () =>
|
const handleOAuthClientsDialogClose = () =>
|
||||||
navigate(URLS.APP_CONNECTIONS(key));
|
navigate(URLS.APP_CONNECTIONS(key));
|
||||||
|
|
||||||
const submitHandler = React.useCallback(
|
const submitHandler = React.useCallback(
|
||||||
@@ -104,14 +104,14 @@ function AddAppConnection(props) {
|
|||||||
|
|
||||||
if (useShared)
|
if (useShared)
|
||||||
return (
|
return (
|
||||||
<AppAuthClientsDialog
|
<AppOAuthClientsDialog
|
||||||
appKey={key}
|
appKey={key}
|
||||||
onClose={handleAuthClientsDialogClose}
|
onClose={handleOAuthClientsDialogClose}
|
||||||
onClientClick={handleClientClick}
|
onClientClick={handleClientClick}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (appAuthClientId) return <React.Fragment />;
|
if (oauthClientId) return <React.Fragment />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { AppPropType } from 'propTypes/propTypes';
|
|||||||
import useAdminCreateAppConfig from 'hooks/useAdminCreateAppConfig';
|
import useAdminCreateAppConfig from 'hooks/useAdminCreateAppConfig';
|
||||||
import useAppConfig from 'hooks/useAppConfig.ee';
|
import useAppConfig from 'hooks/useAppConfig.ee';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import useAdminCreateAppAuthClient from 'hooks/useAdminCreateAppAuthClient.ee';
|
import useAdminCreateOAuthClient from 'hooks/useAdminCreateOAuthClient.ee';
|
||||||
import AdminApplicationAuthClientDialog from 'components/AdminApplicationAuthClientDialog';
|
import AdminApplicationOAuthClientDialog from 'components/AdminApplicationOAuthClientDialog';
|
||||||
import useAppAuth from 'hooks/useAppAuth';
|
import useAppAuth from 'hooks/useAppAuth';
|
||||||
|
|
||||||
function AdminApplicationCreateAuthClient(props) {
|
function AdminApplicationCreateOAuthClient(props) {
|
||||||
const { appKey, onClose } = props;
|
const { appKey, onClose } = props;
|
||||||
const { data: auth } = useAppAuth(appKey);
|
const { data: auth } = useAppAuth(appKey);
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
@@ -24,10 +24,10 @@ function AdminApplicationCreateAuthClient(props) {
|
|||||||
} = useAdminCreateAppConfig(props.appKey);
|
} = useAdminCreateAppConfig(props.appKey);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mutateAsync: createAppAuthClient,
|
mutateAsync: createOAuthClient,
|
||||||
isPending: isCreateAppAuthClientPending,
|
isPending: isCreateOAuthClientPending,
|
||||||
error: createAppAuthClientError,
|
error: createOAuthClientError,
|
||||||
} = useAdminCreateAppAuthClient(appKey);
|
} = useAdminCreateOAuthClient(appKey);
|
||||||
|
|
||||||
const submitHandler = async (values) => {
|
const submitHandler = async (values) => {
|
||||||
let appConfigKey = appConfig?.data?.key;
|
let appConfigKey = appConfig?.data?.key;
|
||||||
@@ -43,7 +43,7 @@ function AdminApplicationCreateAuthClient(props) {
|
|||||||
|
|
||||||
const { name, active, ...formattedAuthDefaults } = values;
|
const { name, active, ...formattedAuthDefaults } = values;
|
||||||
|
|
||||||
await createAppAuthClient({
|
await createOAuthClient({
|
||||||
appKey,
|
appKey,
|
||||||
name,
|
name,
|
||||||
active,
|
active,
|
||||||
@@ -81,23 +81,23 @@ function AdminApplicationCreateAuthClient(props) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AdminApplicationAuthClientDialog
|
<AdminApplicationOAuthClientDialog
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
error={createAppConfigError || createAppAuthClientError}
|
error={createAppConfigError || createOAuthClientError}
|
||||||
title={formatMessage('createAuthClient.title')}
|
title={formatMessage('createOAuthClient.title')}
|
||||||
loading={isAppConfigLoading}
|
loading={isAppConfigLoading}
|
||||||
submitHandler={submitHandler}
|
submitHandler={submitHandler}
|
||||||
authFields={auth?.data?.fields}
|
authFields={auth?.data?.fields}
|
||||||
submitting={isCreateAppConfigPending || isCreateAppAuthClientPending}
|
submitting={isCreateAppConfigPending || isCreateOAuthClientPending}
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdminApplicationCreateAuthClient.propTypes = {
|
AdminApplicationCreateOAuthClient.propTypes = {
|
||||||
appKey: PropTypes.string.isRequired,
|
appKey: PropTypes.string.isRequired,
|
||||||
application: AppPropType.isRequired,
|
application: AppPropType.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AdminApplicationCreateAuthClient;
|
export default AdminApplicationCreateOAuthClient;
|
||||||
@@ -15,7 +15,7 @@ import Switch from 'components/Switch';
|
|||||||
import TextField from 'components/TextField';
|
import TextField from 'components/TextField';
|
||||||
import { Form } from './style';
|
import { Form } from './style';
|
||||||
|
|
||||||
function AdminApplicationAuthClientDialog(props) {
|
function AdminApplicationOAuthClientDialog(props) {
|
||||||
const {
|
const {
|
||||||
error,
|
error,
|
||||||
onClose,
|
onClose,
|
||||||
@@ -52,12 +52,12 @@ function AdminApplicationAuthClientDialog(props) {
|
|||||||
<>
|
<>
|
||||||
<Switch
|
<Switch
|
||||||
name="active"
|
name="active"
|
||||||
label={formatMessage('authClient.inputActive')}
|
label={formatMessage('oauthClient.inputActive')}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
required={true}
|
required={true}
|
||||||
name="name"
|
name="name"
|
||||||
label={formatMessage('authClient.inputName')}
|
label={formatMessage('oauthClient.inputName')}
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
{authFields?.map((field) => (
|
{authFields?.map((field) => (
|
||||||
@@ -72,7 +72,7 @@ function AdminApplicationAuthClientDialog(props) {
|
|||||||
loading={submitting}
|
loading={submitting}
|
||||||
disabled={disabled || !isDirty}
|
disabled={disabled || !isDirty}
|
||||||
>
|
>
|
||||||
{formatMessage('authClient.buttonSubmit')}
|
{formatMessage('oauthClient.buttonSubmit')}
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -84,7 +84,7 @@ function AdminApplicationAuthClientDialog(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdminApplicationAuthClientDialog.propTypes = {
|
AdminApplicationOAuthClientDialog.propTypes = {
|
||||||
error: PropTypes.shape({
|
error: PropTypes.shape({
|
||||||
message: PropTypes.string,
|
message: PropTypes.string,
|
||||||
}),
|
}),
|
||||||
@@ -98,4 +98,4 @@ AdminApplicationAuthClientDialog.propTypes = {
|
|||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AdminApplicationAuthClientDialog;
|
export default AdminApplicationOAuthClientDialog;
|
||||||
@@ -8,29 +8,30 @@ import CardContent from '@mui/material/CardContent';
|
|||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import Chip from '@mui/material/Chip';
|
import Chip from '@mui/material/Chip';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
|
|
||||||
|
import NoResultFound from 'components/NoResultFound';
|
||||||
import * as URLS from 'config/urls';
|
import * as URLS from 'config/urls';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import useAdminAppAuthClients from 'hooks/useAdminAppAuthClients';
|
import useAdminOAuthClients from 'hooks/useAdminOAuthClients';
|
||||||
import NoResultFound from 'components/NoResultFound';
|
|
||||||
|
|
||||||
function AdminApplicationAuthClients(props) {
|
function AdminApplicationOAuthClients(props) {
|
||||||
const { appKey } = props;
|
const { appKey } = props;
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
const { data: appAuthClients, isLoading } = useAdminAppAuthClients(appKey);
|
const { data: appOAuthClients, isLoading } = useAdminOAuthClients(appKey);
|
||||||
|
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
return <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />;
|
return <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />;
|
||||||
|
|
||||||
if (!appAuthClients?.data.length) {
|
if (!appOAuthClients?.data.length) {
|
||||||
return (
|
return (
|
||||||
<NoResultFound
|
<NoResultFound
|
||||||
to={URLS.ADMIN_APP_AUTH_CLIENTS_CREATE(appKey)}
|
to={URLS.ADMIN_APP_AUTH_CLIENTS_CREATE(appKey)}
|
||||||
text={formatMessage('adminAppsAuthClients.noAuthClients')}
|
text={formatMessage('adminAppsOAuthClients.noOauthClients')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedAuthClients = appAuthClients.data.slice().sort((a, b) => {
|
const sortedOAuthClients = appOAuthClients.data.slice().sort((a, b) => {
|
||||||
if (a.id < b.id) {
|
if (a.id < b.id) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -42,7 +43,7 @@ function AdminApplicationAuthClients(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{sortedAuthClients.map((client) => (
|
{sortedOAuthClients.map((client) => (
|
||||||
<Card sx={{ mb: 1 }} key={client.id} data-test="auth-client">
|
<Card sx={{ mb: 1 }} key={client.id} data-test="auth-client">
|
||||||
<CardActionArea
|
<CardActionArea
|
||||||
component={Link}
|
component={Link}
|
||||||
@@ -59,8 +60,8 @@ function AdminApplicationAuthClients(props) {
|
|||||||
variant={client?.active ? 'filled' : 'outlined'}
|
variant={client?.active ? 'filled' : 'outlined'}
|
||||||
label={formatMessage(
|
label={formatMessage(
|
||||||
client?.active
|
client?.active
|
||||||
? 'adminAppsAuthClients.statusActive'
|
? 'adminAppsOAuthClients.statusActive'
|
||||||
: 'adminAppsAuthClients.statusInactive',
|
: 'adminAppsOAuthClients.statusInactive',
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -70,8 +71,13 @@ function AdminApplicationAuthClients(props) {
|
|||||||
))}
|
))}
|
||||||
<Stack justifyContent="flex-end" direction="row">
|
<Stack justifyContent="flex-end" direction="row">
|
||||||
<Link to={URLS.ADMIN_APP_AUTH_CLIENTS_CREATE(appKey)}>
|
<Link to={URLS.ADMIN_APP_AUTH_CLIENTS_CREATE(appKey)}>
|
||||||
<Button variant="contained" sx={{ mt: 2 }} component="div" data-test="create-auth-client-button">
|
<Button
|
||||||
{formatMessage('createAuthClient.button')}
|
variant="contained"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
component="div"
|
||||||
|
data-test="create-auth-client-button"
|
||||||
|
>
|
||||||
|
{formatMessage('createOAuthClient.button')}
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -79,8 +85,8 @@ function AdminApplicationAuthClients(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdminApplicationAuthClients.propTypes = {
|
AdminApplicationOAuthClients.propTypes = {
|
||||||
appKey: PropTypes.string.isRequired,
|
appKey: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AdminApplicationAuthClients;
|
export default AdminApplicationOAuthClients;
|
||||||
@@ -4,26 +4,26 @@ import { useParams } from 'react-router-dom';
|
|||||||
|
|
||||||
import { AppPropType } from 'propTypes/propTypes';
|
import { AppPropType } from 'propTypes/propTypes';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import AdminApplicationAuthClientDialog from 'components/AdminApplicationAuthClientDialog';
|
import AdminApplicationOAuthClientDialog from 'components/AdminApplicationOAuthClientDialog';
|
||||||
import useAdminAppAuthClient from 'hooks/useAdminAppAuthClient.ee';
|
import useAdminOAuthClient from 'hooks/useAdminOAuthClient.ee';
|
||||||
import useAdminUpdateAppAuthClient from 'hooks/useAdminUpdateAppAuthClient.ee';
|
import useAdminUpdateOAuthClient from 'hooks/useAdminUpdateOAuthClient.ee';
|
||||||
import useAppAuth from 'hooks/useAppAuth';
|
import useAppAuth from 'hooks/useAppAuth';
|
||||||
|
|
||||||
function AdminApplicationUpdateAuthClient(props) {
|
function AdminApplicationUpdateOAuthClient(props) {
|
||||||
const { application, onClose } = props;
|
const { application, onClose } = props;
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
const { clientId } = useParams();
|
const { clientId } = useParams();
|
||||||
|
|
||||||
const { data: adminAppAuthClient, isLoading: isAdminAuthClientLoading } =
|
const { data: adminOAuthClient, isLoading: isAdminOAuthClientLoading } =
|
||||||
useAdminAppAuthClient(application.key, clientId);
|
useAdminOAuthClient(application.key, clientId);
|
||||||
|
|
||||||
const { data: auth } = useAppAuth(application.key);
|
const { data: auth } = useAppAuth(application.key);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mutateAsync: updateAppAuthClient,
|
mutateAsync: updateOAuthClient,
|
||||||
isPending: isUpdateAppAuthClientPending,
|
isPending: isUpdateOAuthClientPending,
|
||||||
error: updateAppAuthClientError,
|
error: updateOAuthClientError,
|
||||||
} = useAdminUpdateAppAuthClient(application.key, clientId);
|
} = useAdminUpdateOAuthClient(application.key, clientId);
|
||||||
|
|
||||||
const authFields = auth?.data?.fields?.map((field) => ({
|
const authFields = auth?.data?.fields?.map((field) => ({
|
||||||
...field,
|
...field,
|
||||||
@@ -31,13 +31,13 @@ function AdminApplicationUpdateAuthClient(props) {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const submitHandler = async (values) => {
|
const submitHandler = async (values) => {
|
||||||
if (!adminAppAuthClient) {
|
if (!adminOAuthClient) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, active, ...formattedAuthDefaults } = values;
|
const { name, active, ...formattedAuthDefaults } = values;
|
||||||
|
|
||||||
await updateAppAuthClient({
|
await updateOAuthClient({
|
||||||
name,
|
name,
|
||||||
active,
|
active,
|
||||||
formattedAuthDefaults,
|
formattedAuthDefaults,
|
||||||
@@ -64,31 +64,31 @@ function AdminApplicationUpdateAuthClient(props) {
|
|||||||
|
|
||||||
const defaultValues = useMemo(
|
const defaultValues = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
name: adminAppAuthClient?.data?.name || '',
|
name: adminOAuthClient?.data?.name || '',
|
||||||
active: adminAppAuthClient?.data?.active || false,
|
active: adminOAuthClient?.data?.active || false,
|
||||||
...getAuthFieldsDefaultValues(),
|
...getAuthFieldsDefaultValues(),
|
||||||
}),
|
}),
|
||||||
[adminAppAuthClient, getAuthFieldsDefaultValues],
|
[adminOAuthClient, getAuthFieldsDefaultValues],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AdminApplicationAuthClientDialog
|
<AdminApplicationOAuthClientDialog
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
error={updateAppAuthClientError}
|
error={updateOAuthClientError}
|
||||||
title={formatMessage('updateAuthClient.title')}
|
title={formatMessage('updateOAuthClient.title')}
|
||||||
loading={isAdminAuthClientLoading}
|
loading={isAdminOAuthClientLoading}
|
||||||
submitHandler={submitHandler}
|
submitHandler={submitHandler}
|
||||||
authFields={authFields}
|
authFields={authFields}
|
||||||
submitting={isUpdateAppAuthClientPending}
|
submitting={isUpdateOAuthClientPending}
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
disabled={!adminAppAuthClient}
|
disabled={!adminOAuthClient}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdminApplicationUpdateAuthClient.propTypes = {
|
AdminApplicationUpdateOAuthClient.propTypes = {
|
||||||
application: AppPropType.isRequired,
|
application: AppPropType.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AdminApplicationUpdateAuthClient;
|
export default AdminApplicationUpdateOAuthClient;
|
||||||
@@ -70,7 +70,7 @@ function ContextMenu(props) {
|
|||||||
to={URLS.APP_RECONNECT_CONNECTION(
|
to={URLS.APP_RECONNECT_CONNECTION(
|
||||||
appKey,
|
appKey,
|
||||||
connection.id,
|
connection.id,
|
||||||
connection.appAuthClientId,
|
connection.oauthClientId,
|
||||||
)}
|
)}
|
||||||
onClick={createActionHandler({ type: 'reconnect' })}
|
onClick={createActionHandler({ type: 'reconnect' })}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import TextField from '@mui/material/TextField';
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import AddAppConnection from 'components/AddAppConnection';
|
import AddAppConnection from 'components/AddAppConnection';
|
||||||
import AppAuthClientsDialog from 'components/AppAuthClientsDialog/index.ee';
|
import AppOAuthClientsDialog from 'components/OAuthClientsDialog/index.ee';
|
||||||
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
import FlowSubstepTitle from 'components/FlowSubstepTitle';
|
||||||
import useAppConfig from 'hooks/useAppConfig.ee';
|
import useAppConfig from 'hooks/useAppConfig.ee';
|
||||||
import { EditorContext } from 'contexts/Editor';
|
import { EditorContext } from 'contexts/Editor';
|
||||||
@@ -22,7 +22,7 @@ import useStepConnection from 'hooks/useStepConnection';
|
|||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import useAppConnections from 'hooks/useAppConnections';
|
import useAppConnections from 'hooks/useAppConnections';
|
||||||
import useTestConnection from 'hooks/useTestConnection';
|
import useTestConnection from 'hooks/useTestConnection';
|
||||||
import useAppAuthClients from 'hooks/useAppAuthClients';
|
import useOAuthClients from 'hooks/useOAuthClients';
|
||||||
|
|
||||||
const ADD_CONNECTION_VALUE = 'ADD_CONNECTION';
|
const ADD_CONNECTION_VALUE = 'ADD_CONNECTION';
|
||||||
const ADD_SHARED_CONNECTION_VALUE = 'ADD_SHARED_CONNECTION';
|
const ADD_SHARED_CONNECTION_VALUE = 'ADD_SHARED_CONNECTION';
|
||||||
@@ -54,7 +54,7 @@ function ChooseConnectionSubstep(props) {
|
|||||||
const [showAddSharedConnectionDialog, setShowAddSharedConnectionDialog] =
|
const [showAddSharedConnectionDialog, setShowAddSharedConnectionDialog] =
|
||||||
React.useState(false);
|
React.useState(false);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { data: appAuthClients } = useAppAuthClients(application.key);
|
const { data: appOAuthClients } = useOAuthClients(application.key);
|
||||||
|
|
||||||
const { authenticate } = useAuthenticateApp({
|
const { authenticate } = useAuthenticateApp({
|
||||||
appKey: application.key,
|
appKey: application.key,
|
||||||
@@ -100,9 +100,9 @@ function ChooseConnectionSubstep(props) {
|
|||||||
value: ADD_CONNECTION_VALUE,
|
value: ADD_CONNECTION_VALUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const addConnectionWithAuthClient = {
|
const addConnectionWithOAuthClient = {
|
||||||
label: formatMessage(
|
label: formatMessage(
|
||||||
'chooseConnectionSubstep.addConnectionWithAuthClient',
|
'chooseConnectionSubstep.addConnectionWithOAuthClient',
|
||||||
),
|
),
|
||||||
value: ADD_SHARED_CONNECTION_VALUE,
|
value: ADD_SHARED_CONNECTION_VALUE,
|
||||||
};
|
};
|
||||||
@@ -115,33 +115,33 @@ function ChooseConnectionSubstep(props) {
|
|||||||
// app is disabled.
|
// app is disabled.
|
||||||
if (appConfig.data.disabled) return options;
|
if (appConfig.data.disabled) return options;
|
||||||
|
|
||||||
// means only auth clients are allowed for connection creation and there is app auth client
|
// means only OAuth clients are allowed for connection creation and there is OAuth client
|
||||||
if (
|
if (
|
||||||
appConfig.data.useOnlyPredefinedAuthClients === true &&
|
appConfig.data.useOnlyPredefinedAuthClients === true &&
|
||||||
appAuthClients.data.length > 0
|
appOAuthClients.data.length > 0
|
||||||
) {
|
) {
|
||||||
return options.concat([addConnectionWithAuthClient]);
|
return options.concat([addConnectionWithOAuthClient]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// means there is no app auth client. so we don't show the `addConnectionWithAuthClient`
|
// means there is no OAuth client. so we don't show the `addConnectionWithOAuthClient`
|
||||||
if (
|
if (
|
||||||
appConfig.data.useOnlyPredefinedAuthClients === true &&
|
appConfig.data.useOnlyPredefinedAuthClients === true &&
|
||||||
appAuthClients.data.length === 0
|
appOAuthClients.data.length === 0
|
||||||
) {
|
) {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appAuthClients.data.length === 0) {
|
if (appOAuthClients.data.length === 0) {
|
||||||
return options.concat([addCustomConnection]);
|
return options.concat([addCustomConnection]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options.concat([addCustomConnection, addConnectionWithAuthClient]);
|
return options.concat([addCustomConnection, addConnectionWithOAuthClient]);
|
||||||
}, [data, formatMessage, appConfig, appAuthClients]);
|
}, [data, formatMessage, appConfig, appOAuthClients]);
|
||||||
|
|
||||||
const handleClientClick = async (appAuthClientId) => {
|
const handleClientClick = async (oauthClientId) => {
|
||||||
try {
|
try {
|
||||||
const response = await authenticate?.({
|
const response = await authenticate?.({
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
});
|
});
|
||||||
const connectionId = response?.createConnection.id;
|
const connectionId = response?.createConnection.id;
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ function ChooseConnectionSubstep(props) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{application && showAddSharedConnectionDialog && (
|
{application && showAddSharedConnectionDialog && (
|
||||||
<AppAuthClientsDialog
|
<AppOAuthClientsDialog
|
||||||
appKey={application.key}
|
appKey={application.key}
|
||||||
onClose={() => setShowAddSharedConnectionDialog(false)}
|
onClose={() => setShowAddSharedConnectionDialog(false)}
|
||||||
onClientClick={handleClientClick}
|
onClientClick={handleClientClick}
|
||||||
|
|||||||
@@ -6,26 +6,26 @@ import ListItem from '@mui/material/ListItem';
|
|||||||
import ListItemButton from '@mui/material/ListItemButton';
|
import ListItemButton from '@mui/material/ListItemButton';
|
||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import useAppAuthClients from 'hooks/useAppAuthClients';
|
import useOAuthClients from 'hooks/useOAuthClients';
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
|
|
||||||
function AppAuthClientsDialog(props) {
|
function AppOAuthClientsDialog(props) {
|
||||||
const { appKey, onClientClick, onClose } = props;
|
const { appKey, onClientClick, onClose } = props;
|
||||||
const { data: appAuthClients } = useAppAuthClients(appKey);
|
const { data: appOAuthClients } = useOAuthClients(appKey);
|
||||||
|
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
|
|
||||||
if (!appAuthClients?.data.length) return <React.Fragment />;
|
if (!appOAuthClients?.data.length) return <React.Fragment />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog onClose={onClose} open={true}>
|
<Dialog onClose={onClose} open={true}>
|
||||||
<DialogTitle>{formatMessage('appAuthClientsDialog.title')}</DialogTitle>
|
<DialogTitle>{formatMessage('appOAuthClientsDialog.title')}</DialogTitle>
|
||||||
|
|
||||||
<List sx={{ pt: 0 }}>
|
<List sx={{ pt: 0 }}>
|
||||||
{appAuthClients.data.map((appAuthClient) => (
|
{appOAuthClients.data.map((oauthClient) => (
|
||||||
<ListItem disableGutters key={appAuthClient.id}>
|
<ListItem disableGutters key={oauthClient.id}>
|
||||||
<ListItemButton onClick={() => onClientClick(appAuthClient.id)}>
|
<ListItemButton onClick={() => onClientClick(oauthClient.id)}>
|
||||||
<ListItemText primary={appAuthClient.name} />
|
<ListItemText primary={oauthClient.name} />
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
@@ -34,10 +34,10 @@ function AppAuthClientsDialog(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppAuthClientsDialog.propTypes = {
|
AppOAuthClientsDialog.propTypes = {
|
||||||
appKey: PropTypes.string.isRequired,
|
appKey: PropTypes.string.isRequired,
|
||||||
onClientClick: PropTypes.func.isRequired,
|
onClientClick: PropTypes.func.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AppAuthClientsDialog;
|
export default AppOAuthClientsDialog;
|
||||||
@@ -17,19 +17,19 @@ export const APP_CONNECTIONS = (appKey) => `/app/${appKey}/connections`;
|
|||||||
export const APP_CONNECTIONS_PATTERN = '/app/:appKey/connections';
|
export const APP_CONNECTIONS_PATTERN = '/app/:appKey/connections';
|
||||||
export const APP_ADD_CONNECTION = (appKey, shared = false) =>
|
export const APP_ADD_CONNECTION = (appKey, shared = false) =>
|
||||||
`/app/${appKey}/connections/add?shared=${shared}`;
|
`/app/${appKey}/connections/add?shared=${shared}`;
|
||||||
export const APP_ADD_CONNECTION_WITH_AUTH_CLIENT_ID = (
|
export const APP_ADD_CONNECTION_WITH_OAUTH_CLIENT_ID = (
|
||||||
appKey,
|
appKey,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
) => `/app/${appKey}/connections/add?appAuthClientId=${appAuthClientId}`;
|
) => `/app/${appKey}/connections/add?oauthClientId=${oauthClientId}`;
|
||||||
export const APP_ADD_CONNECTION_PATTERN = '/app/:appKey/connections/add';
|
export const APP_ADD_CONNECTION_PATTERN = '/app/:appKey/connections/add';
|
||||||
export const APP_RECONNECT_CONNECTION = (
|
export const APP_RECONNECT_CONNECTION = (
|
||||||
appKey,
|
appKey,
|
||||||
connectionId,
|
connectionId,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
) => {
|
) => {
|
||||||
const path = `/app/${appKey}/connections/${connectionId}/reconnect`;
|
const path = `/app/${appKey}/connections/${connectionId}/reconnect`;
|
||||||
if (appAuthClientId) {
|
if (oauthClientId) {
|
||||||
return `${path}?appAuthClientId=${appAuthClientId}`;
|
return `${path}?oauthClientId=${oauthClientId}`;
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
@@ -71,18 +71,18 @@ export const ADMIN_APPS = `${ADMIN_SETTINGS}/apps`;
|
|||||||
export const ADMIN_APP = (appKey) => `${ADMIN_SETTINGS}/apps/${appKey}`;
|
export const ADMIN_APP = (appKey) => `${ADMIN_SETTINGS}/apps/${appKey}`;
|
||||||
export const ADMIN_APP_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey`;
|
export const ADMIN_APP_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey`;
|
||||||
export const ADMIN_APP_SETTINGS_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey/settings`;
|
export const ADMIN_APP_SETTINGS_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey/settings`;
|
||||||
export const ADMIN_APP_AUTH_CLIENTS_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey/auth-clients`;
|
export const ADMIN_APP_AUTH_CLIENTS_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey/oauth-clients`;
|
||||||
export const ADMIN_APP_CONNECTIONS_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey/connections`;
|
export const ADMIN_APP_CONNECTIONS_PATTERN = `${ADMIN_SETTINGS}/apps/:appKey/connections`;
|
||||||
export const ADMIN_APP_CONNECTIONS = (appKey) =>
|
export const ADMIN_APP_CONNECTIONS = (appKey) =>
|
||||||
`${ADMIN_SETTINGS}/apps/${appKey}/connections`;
|
`${ADMIN_SETTINGS}/apps/${appKey}/connections`;
|
||||||
export const ADMIN_APP_SETTINGS = (appKey) =>
|
export const ADMIN_APP_SETTINGS = (appKey) =>
|
||||||
`${ADMIN_SETTINGS}/apps/${appKey}/settings`;
|
`${ADMIN_SETTINGS}/apps/${appKey}/settings`;
|
||||||
export const ADMIN_APP_AUTH_CLIENTS = (appKey) =>
|
export const ADMIN_APP_AUTH_CLIENTS = (appKey) =>
|
||||||
`${ADMIN_SETTINGS}/apps/${appKey}/auth-clients`;
|
`${ADMIN_SETTINGS}/apps/${appKey}/oauth-clients`;
|
||||||
export const ADMIN_APP_AUTH_CLIENT = (appKey, id) =>
|
export const ADMIN_APP_AUTH_CLIENT = (appKey, id) =>
|
||||||
`${ADMIN_SETTINGS}/apps/${appKey}/auth-clients/${id}`;
|
`${ADMIN_SETTINGS}/apps/${appKey}/oauth-clients/${id}`;
|
||||||
export const ADMIN_APP_AUTH_CLIENTS_CREATE = (appKey) =>
|
export const ADMIN_APP_AUTH_CLIENTS_CREATE = (appKey) =>
|
||||||
`${ADMIN_SETTINGS}/apps/${appKey}/auth-clients/create`;
|
`${ADMIN_SETTINGS}/apps/${appKey}/oauth-clients/create`;
|
||||||
export const DASHBOARD = FLOWS;
|
export const DASHBOARD = FLOWS;
|
||||||
|
|
||||||
// External links and paths
|
// External links and paths
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import api from 'helpers/api';
|
|
||||||
|
|
||||||
export default function useAdminAppAuthClient(appKey, id) {
|
|
||||||
const query = useQuery({
|
|
||||||
queryKey: ['admin', 'apps', appKey, 'authClients', id],
|
|
||||||
queryFn: async ({ signal }) => {
|
|
||||||
const { data } = await api.get(`/v1/admin/apps/${appKey}/auth-clients/${id}`, {
|
|
||||||
signal,
|
|
||||||
});
|
|
||||||
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
enabled: !!appKey && !!id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,23 @@
|
|||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import api from 'helpers/api';
|
import api from 'helpers/api';
|
||||||
|
|
||||||
export default function useAdminCreateAppAuthClient(appKey) {
|
export default function useAdminCreateOAuthClient(appKey) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const query = useMutation({
|
const query = useMutation({
|
||||||
mutationFn: async (payload) => {
|
mutationFn: async (payload) => {
|
||||||
const { data } = await api.post(`/v1/admin/apps/${appKey}/auth-clients`, payload);
|
const { data } = await api.post(
|
||||||
|
`/v1/admin/apps/${appKey}/oauth-clients`,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: ['admin', 'apps', appKey, 'authClients'],
|
queryKey: ['admin', 'apps', appKey, 'oauthClients'],
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
22
packages/web/src/hooks/useAdminOAuthClient.ee.js
Normal file
22
packages/web/src/hooks/useAdminOAuthClient.ee.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import api from 'helpers/api';
|
||||||
|
|
||||||
|
export default function useAdminOAuthClient(appKey, id) {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: ['admin', 'apps', appKey, 'oauthClients', id],
|
||||||
|
queryFn: async ({ signal }) => {
|
||||||
|
const { data } = await api.get(
|
||||||
|
`/v1/admin/apps/${appKey}/oauth-clients/${id}`,
|
||||||
|
{
|
||||||
|
signal,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
enabled: !!appKey && !!id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import api from 'helpers/api';
|
import api from 'helpers/api';
|
||||||
|
|
||||||
export default function useAdminAppAuthClients(appKey) {
|
export default function useAdminOAuthClients(appKey) {
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ['admin', 'apps', appKey, 'authClients'],
|
queryKey: ['admin', 'apps', appKey, 'oauthClients'],
|
||||||
queryFn: async ({ signal }) => {
|
queryFn: async ({ signal }) => {
|
||||||
const { data } = await api.get(`/v1/admin/apps/${appKey}/auth-clients`, {
|
const { data } = await api.get(`/v1/admin/apps/${appKey}/oauth-clients`, {
|
||||||
signal,
|
signal,
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import api from 'helpers/api';
|
import api from 'helpers/api';
|
||||||
|
|
||||||
export default function useAdminUpdateAppAuthClient(appKey, id) {
|
export default function useAdminUpdateOAuthClient(appKey, id) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const query = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: async (payload) => {
|
mutationFn: async (payload) => {
|
||||||
const { data } = await api.patch(
|
const { data } = await api.patch(
|
||||||
`/v1/admin/apps/${appKey}/auth-clients/${id}`,
|
`/v1/admin/apps/${appKey}/oauth-clients/${id}`,
|
||||||
payload,
|
payload,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -15,14 +15,14 @@ export default function useAdminUpdateAppAuthClient(appKey, id) {
|
|||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: ['admin', 'apps', appKey, 'authClients', id],
|
queryKey: ['admin', 'apps', appKey, 'oauthClients', id],
|
||||||
});
|
});
|
||||||
|
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: ['admin', 'apps', appKey, 'authClients'],
|
queryKey: ['admin', 'apps', appKey, 'oauthClients'],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return query;
|
return mutation;
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ function getSteps(auth, hasConnection, useShared) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function useAuthenticateApp(payload) {
|
export default function useAuthenticateApp(payload) {
|
||||||
const { appKey, appAuthClientId, connectionId, useShared = false } = payload;
|
const { appKey, oauthClientId, connectionId, useShared = false } = payload;
|
||||||
const { data: auth } = useAppAuth(appKey);
|
const { data: auth } = useAppAuth(appKey);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { mutateAsync: createConnection } = useCreateConnection(appKey);
|
const { mutateAsync: createConnection } = useCreateConnection(appKey);
|
||||||
@@ -55,7 +55,7 @@ export default function useAuthenticateApp(payload) {
|
|||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
key: appKey,
|
key: appKey,
|
||||||
appAuthClientId: appAuthClientId || payload.appAuthClientId,
|
oauthClientId: oauthClientId || payload.oauthClientId,
|
||||||
connectionId,
|
connectionId,
|
||||||
fields,
|
fields,
|
||||||
};
|
};
|
||||||
@@ -133,7 +133,7 @@ export default function useAuthenticateApp(payload) {
|
|||||||
}, [
|
}, [
|
||||||
steps,
|
steps,
|
||||||
appKey,
|
appKey,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
connectionId,
|
connectionId,
|
||||||
queryClient,
|
queryClient,
|
||||||
createConnection,
|
createConnection,
|
||||||
@@ -147,7 +147,7 @@ export default function useAuthenticateApp(payload) {
|
|||||||
[
|
[
|
||||||
steps,
|
steps,
|
||||||
appKey,
|
appKey,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
connectionId,
|
connectionId,
|
||||||
queryClient,
|
queryClient,
|
||||||
createConnection,
|
createConnection,
|
||||||
@@ -156,7 +156,7 @@ export default function useAuthenticateApp(payload) {
|
|||||||
resetConnection,
|
resetConnection,
|
||||||
verifyConnection,
|
verifyConnection,
|
||||||
],
|
],
|
||||||
'steps, appKey, appAuthClientId, connectionId, queryClient, createConnection, createConnectionAuthUrl, updateConnection, resetConnection, verifyConnection',
|
'steps, appKey, oauthClientId, connectionId, queryClient, createConnection, createConnectionAuthUrl, updateConnection, resetConnection, verifyConnection',
|
||||||
'',
|
'',
|
||||||
'useAuthenticate',
|
'useAuthenticate',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import api from 'helpers/api';
|
|||||||
|
|
||||||
export default function useCreateConnection(appKey) {
|
export default function useCreateConnection(appKey) {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: async ({ appAuthClientId, formattedData }) => {
|
mutationFn: async ({ oauthClientId, formattedData }) => {
|
||||||
const { data } = await api.post(`/v1/apps/${appKey}/connections`, {
|
const { data } = await api.post(`/v1/apps/${appKey}/connections`, {
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
formattedData,
|
formattedData,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import api from 'helpers/api';
|
import api from 'helpers/api';
|
||||||
|
|
||||||
export default function useAppAuthClients(appKey) {
|
export default function useOAuthClients(appKey) {
|
||||||
const query = useQuery({
|
const query = useQuery({
|
||||||
queryKey: ['apps', appKey, 'auth-clients'],
|
queryKey: ['apps', appKey, 'oauth-clients'],
|
||||||
queryFn: async ({ signal }) => {
|
queryFn: async ({ signal }) => {
|
||||||
const { data } = await api.get(`/v1/apps/${appKey}/auth-clients`, {
|
const { data } = await api.get(`/v1/apps/${appKey}/oauth-clients`, {
|
||||||
signal,
|
signal,
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
@@ -4,10 +4,10 @@ import api from 'helpers/api';
|
|||||||
|
|
||||||
export default function useUpdateConnection() {
|
export default function useUpdateConnection() {
|
||||||
const query = useMutation({
|
const query = useMutation({
|
||||||
mutationFn: async ({ connectionId, formattedData, appAuthClientId }) => {
|
mutationFn: async ({ connectionId, formattedData, oauthClientId }) => {
|
||||||
const { data } = await api.patch(`/v1/connections/${connectionId}`, {
|
const { data } = await api.patch(`/v1/connections/${connectionId}`, {
|
||||||
formattedData,
|
formattedData,
|
||||||
appAuthClientId,
|
oauthClientId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"app.connectionCount": "{count} connections",
|
"app.connectionCount": "{count} connections",
|
||||||
"app.flowCount": "{count} flows",
|
"app.flowCount": "{count} flows",
|
||||||
"app.addConnection": "Add connection",
|
"app.addConnection": "Add connection",
|
||||||
"app.addConnectionWithAuthClient": "Add connection with auth client",
|
"app.addConnectionWithOAuthClient": "Add connection with OAuth client",
|
||||||
"app.reconnectConnection": "Reconnect connection",
|
"app.reconnectConnection": "Reconnect connection",
|
||||||
"app.createFlow": "Create flow",
|
"app.createFlow": "Create flow",
|
||||||
"app.settings": "Settings",
|
"app.settings": "Settings",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"filterConditions.orContinueIf": "OR continue if…",
|
"filterConditions.orContinueIf": "OR continue if…",
|
||||||
"chooseConnectionSubstep.continue": "Continue",
|
"chooseConnectionSubstep.continue": "Continue",
|
||||||
"chooseConnectionSubstep.addNewConnection": "Add new connection",
|
"chooseConnectionSubstep.addNewConnection": "Add new connection",
|
||||||
"chooseConnectionSubstep.addConnectionWithAuthClient": "Add connection with auth client",
|
"chooseConnectionSubstep.addConnectionWithOAuthClient": "Add connection with OAuth client",
|
||||||
"chooseConnectionSubstep.chooseConnection": "Choose connection",
|
"chooseConnectionSubstep.chooseConnection": "Choose connection",
|
||||||
"flow.createdAt": "created {datetime}",
|
"flow.createdAt": "created {datetime}",
|
||||||
"flow.updatedAt": "updated {datetime}",
|
"flow.updatedAt": "updated {datetime}",
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
"permissionSettings.cancel": "Cancel",
|
"permissionSettings.cancel": "Cancel",
|
||||||
"permissionSettings.apply": "Apply",
|
"permissionSettings.apply": "Apply",
|
||||||
"permissionSettings.title": "Conditions",
|
"permissionSettings.title": "Conditions",
|
||||||
"appAuthClientsDialog.title": "Choose your authentication client",
|
"appOAuthClientsDialog.title": "Choose your authentication client",
|
||||||
"userInterfacePage.title": "User Interface",
|
"userInterfacePage.title": "User Interface",
|
||||||
"userInterfacePage.successfullyUpdated": "User interface has been updated.",
|
"userInterfacePage.successfullyUpdated": "User interface has been updated.",
|
||||||
"userInterfacePage.titleFieldLabel": "Title",
|
"userInterfacePage.titleFieldLabel": "Title",
|
||||||
@@ -290,22 +290,22 @@
|
|||||||
"roleMappingsForm.successfullySaved": "Role mappings have been saved.",
|
"roleMappingsForm.successfullySaved": "Role mappings have been saved.",
|
||||||
"adminApps.title": "Apps",
|
"adminApps.title": "Apps",
|
||||||
"adminApps.connections": "Connections",
|
"adminApps.connections": "Connections",
|
||||||
"adminApps.authClients": "Auth clients",
|
"adminApps.oauthClients": "OAuth clients",
|
||||||
"adminApps.settings": "Settings",
|
"adminApps.settings": "Settings",
|
||||||
"adminAppsSettings.useOnlyPredefinedAuthClients": "Use only predefined auth clients",
|
"adminAppsSettings.useOnlyPredefinedAuthClients": "Use only predefined OAuth clients",
|
||||||
"adminAppsSettings.shared": "Shared",
|
"adminAppsSettings.shared": "Shared",
|
||||||
"adminAppsSettings.disabled": "Disabled",
|
"adminAppsSettings.disabled": "Disabled",
|
||||||
"adminAppsSettings.save": "Save",
|
"adminAppsSettings.save": "Save",
|
||||||
"adminAppsSettings.successfullySaved": "Settings have been saved.",
|
"adminAppsSettings.successfullySaved": "Settings have been saved.",
|
||||||
"adminAppsAuthClients.noAuthClients": "You don't have any auth clients yet.",
|
"adminAppsOAuthClients.noOauthClients": "You don't have any OAuth clients yet.",
|
||||||
"adminAppsAuthClients.statusActive": "Active",
|
"adminAppsOAuthClients.statusActive": "Active",
|
||||||
"adminAppsAuthClients.statusInactive": "Inactive",
|
"adminAppsOAuthClients.statusInactive": "Inactive",
|
||||||
"createAuthClient.button": "Create auth client",
|
"createOAuthClient.button": "Create OAuth client",
|
||||||
"createAuthClient.title": "Create auth client",
|
"createOAuthClient.title": "Create OAuth client",
|
||||||
"authClient.buttonSubmit": "Submit",
|
"oauthClient.buttonSubmit": "Submit",
|
||||||
"authClient.inputName": "Name",
|
"oauthClient.inputName": "Name",
|
||||||
"authClient.inputActive": "Active",
|
"oauthClient.inputActive": "Active",
|
||||||
"updateAuthClient.title": "Update auth client",
|
"updateOAuthClient.title": "Update OAuth client",
|
||||||
"notFoundPage.title": "We can't seem to find a page you're looking for.",
|
"notFoundPage.title": "We can't seem to find a page you're looking for.",
|
||||||
"notFoundPage.button": "Back to home page"
|
"notFoundPage.button": "Back to home page"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import AppIcon from 'components/AppIcon';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
import AdminApplicationSettings from 'components/AdminApplicationSettings';
|
import AdminApplicationSettings from 'components/AdminApplicationSettings';
|
||||||
import AdminApplicationAuthClients from 'components/AdminApplicationAuthClients';
|
import AdminApplicationOAuthClients from 'components/AdminApplicationOAuthClients';
|
||||||
import AdminApplicationCreateAuthClient from 'components/AdminApplicationCreateAuthClient';
|
import AdminApplicationCreateOAuthClient from 'components/AdminApplicationCreateOAuthClient';
|
||||||
import AdminApplicationUpdateAuthClient from 'components/AdminApplicationUpdateAuthClient';
|
import AdminApplicationUpdateOAuthClient from 'components/AdminApplicationUpdateOAuthClient';
|
||||||
import useApp from 'hooks/useApp';
|
import useApp from 'hooks/useApp';
|
||||||
|
|
||||||
export default function AdminApplication() {
|
export default function AdminApplication() {
|
||||||
@@ -39,7 +39,7 @@ export default function AdminApplication() {
|
|||||||
path: URLS.ADMIN_APP_SETTINGS_PATTERN,
|
path: URLS.ADMIN_APP_SETTINGS_PATTERN,
|
||||||
end: false,
|
end: false,
|
||||||
});
|
});
|
||||||
const authClientsPathMatch = useMatch({
|
const oauthClientsPathMatch = useMatch({
|
||||||
path: URLS.ADMIN_APP_AUTH_CLIENTS_PATTERN,
|
path: URLS.ADMIN_APP_AUTH_CLIENTS_PATTERN,
|
||||||
end: false,
|
end: false,
|
||||||
});
|
});
|
||||||
@@ -49,7 +49,7 @@ export default function AdminApplication() {
|
|||||||
|
|
||||||
const app = data?.data || {};
|
const app = data?.data || {};
|
||||||
|
|
||||||
const goToAuthClientsPage = () => navigate('auth-clients');
|
const goToAuthClientsPage = () => navigate('oauth-clients');
|
||||||
|
|
||||||
if (loading) return null;
|
if (loading) return null;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ export default function AdminApplication() {
|
|||||||
value={
|
value={
|
||||||
settingsPathMatch?.pattern?.path ||
|
settingsPathMatch?.pattern?.path ||
|
||||||
connectionsPathMatch?.pattern?.path ||
|
connectionsPathMatch?.pattern?.path ||
|
||||||
authClientsPathMatch?.pattern?.path
|
oauthClientsPathMatch?.pattern?.path
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab
|
||||||
@@ -87,8 +87,8 @@ export default function AdminApplication() {
|
|||||||
component={Link}
|
component={Link}
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
data-test="auth-clients-tab"
|
data-test="oauth-clients-tab"
|
||||||
label={formatMessage('adminApps.authClients')}
|
label={formatMessage('adminApps.oauthClients')}
|
||||||
to={URLS.ADMIN_APP_AUTH_CLIENTS(appKey)}
|
to={URLS.ADMIN_APP_AUTH_CLIENTS(appKey)}
|
||||||
value={URLS.ADMIN_APP_AUTH_CLIENTS_PATTERN}
|
value={URLS.ADMIN_APP_AUTH_CLIENTS_PATTERN}
|
||||||
component={Link}
|
component={Link}
|
||||||
@@ -102,8 +102,8 @@ export default function AdminApplication() {
|
|||||||
element={<AdminApplicationSettings appKey={appKey} />}
|
element={<AdminApplicationSettings appKey={appKey} />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={`/auth-clients/*`}
|
path={`/oauth-clients/*`}
|
||||||
element={<AdminApplicationAuthClients appKey={appKey} />}
|
element={<AdminApplicationOAuthClients appKey={appKey} />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/"
|
path="/"
|
||||||
@@ -118,9 +118,9 @@ export default function AdminApplication() {
|
|||||||
</Container>
|
</Container>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
path="/auth-clients/create"
|
path="/oauth-clients/create"
|
||||||
element={
|
element={
|
||||||
<AdminApplicationCreateAuthClient
|
<AdminApplicationCreateOAuthClient
|
||||||
application={app}
|
application={app}
|
||||||
onClose={goToAuthClientsPage}
|
onClose={goToAuthClientsPage}
|
||||||
appKey={appKey}
|
appKey={appKey}
|
||||||
@@ -128,9 +128,9 @@ export default function AdminApplication() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/auth-clients/:clientId"
|
path="/oauth-clients/:clientId"
|
||||||
element={
|
element={
|
||||||
<AdminApplicationUpdateAuthClient
|
<AdminApplicationUpdateOAuthClient
|
||||||
application={app}
|
application={app}
|
||||||
onClose={goToAuthClientsPage}
|
onClose={goToAuthClientsPage}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import AppIcon from 'components/AppIcon';
|
|||||||
import Container from 'components/Container';
|
import Container from 'components/Container';
|
||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
import useApp from 'hooks/useApp';
|
import useApp from 'hooks/useApp';
|
||||||
import useAppAuthClients from 'hooks/useAppAuthClients';
|
import useOAuthClients from 'hooks/useOAuthClients';
|
||||||
import Can from 'components/Can';
|
import Can from 'components/Can';
|
||||||
import { AppPropType } from 'propTypes/propTypes';
|
import { AppPropType } from 'propTypes/propTypes';
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ export default function Application() {
|
|||||||
const flowsPathMatch = useMatch({ path: URLS.APP_FLOWS_PATTERN, end: false });
|
const flowsPathMatch = useMatch({ path: URLS.APP_FLOWS_PATTERN, end: false });
|
||||||
const { appKey } = useParams();
|
const { appKey } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { data: appAuthClients } = useAppAuthClients(appKey);
|
const { data: appOAuthClients } = useOAuthClients(appKey);
|
||||||
|
|
||||||
const { data, loading } = useApp(appKey);
|
const { data, loading } = useApp(appKey);
|
||||||
const app = data?.data || {};
|
const app = data?.data || {};
|
||||||
@@ -86,14 +86,14 @@ export default function Application() {
|
|||||||
appConfig?.data?.disabled === true,
|
appConfig?.data?.disabled === true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const addConnectionWithAuthClient = {
|
const addConnectionWithOAuthClient = {
|
||||||
label: formatMessage('app.addConnectionWithAuthClient'),
|
label: formatMessage('app.addConnectionWithOAuthClient'),
|
||||||
key: 'addConnectionWithAuthClient',
|
key: 'addConnectionWithOAuthClient',
|
||||||
'data-test': 'add-connection-with-auth-client-button',
|
'data-test': 'add-connection-with-auth-client-button',
|
||||||
to: URLS.APP_ADD_CONNECTION(appKey, true),
|
to: URLS.APP_ADD_CONNECTION(appKey, true),
|
||||||
disabled:
|
disabled:
|
||||||
!currentUserAbility.can('create', 'Connection') ||
|
!currentUserAbility.can('create', 'Connection') ||
|
||||||
appAuthClients?.data?.length === 0 ||
|
appOAuthClients?.data?.length === 0 ||
|
||||||
appConfig?.data?.disabled === true,
|
appConfig?.data?.disabled === true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -102,18 +102,18 @@ export default function Application() {
|
|||||||
return [addCustomConnection];
|
return [addCustomConnection];
|
||||||
}
|
}
|
||||||
|
|
||||||
// means only auth clients are allowed for connection creation
|
// means only OAuth clients are allowed for connection creation
|
||||||
if (appConfig?.data?.useOnlyPredefinedAuthClients === true) {
|
if (appConfig?.data?.useOnlyPredefinedAuthClients === true) {
|
||||||
return [addConnectionWithAuthClient];
|
return [addConnectionWithOAuthClient];
|
||||||
}
|
}
|
||||||
|
|
||||||
// means there is no app auth client. so we don't show the `addConnectionWithAuthClient`
|
// means there is no OAuth client. so we don't show the `addConnectionWithOAuthClient`
|
||||||
if (appAuthClients?.data?.length === 0) {
|
if (appOAuthClients?.data?.length === 0) {
|
||||||
return [addCustomConnection];
|
return [addCustomConnection];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [addCustomConnection, addConnectionWithAuthClient];
|
return [addCustomConnection, addConnectionWithOAuthClient];
|
||||||
}, [appKey, appConfig, appAuthClients, currentUserAbility, formatMessage]);
|
}, [appKey, appConfig, appOAuthClients, currentUserAbility, formatMessage]);
|
||||||
|
|
||||||
if (loading) return null;
|
if (loading) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ export const ConnectionPropType = PropTypes.shape({
|
|||||||
flowCount: PropTypes.number,
|
flowCount: PropTypes.number,
|
||||||
appData: AppPropType,
|
appData: AppPropType,
|
||||||
createdAt: PropTypes.number,
|
createdAt: PropTypes.number,
|
||||||
appAuthClientId: PropTypes.string,
|
oauthClientId: PropTypes.string,
|
||||||
});
|
});
|
||||||
|
|
||||||
AppPropType.connection = PropTypes.arrayOf(ConnectionPropType);
|
AppPropType.connection = PropTypes.arrayOf(ConnectionPropType);
|
||||||
@@ -463,7 +463,7 @@ export const AppConfigPropType = PropTypes.shape({
|
|||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AppAuthClientPropType = PropTypes.shape({
|
export const OAuthClientPropType = PropTypes.shape({
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
appConfigKey: PropTypes.string,
|
appConfigKey: PropTypes.string,
|
||||||
|
|||||||
Reference in New Issue
Block a user