diff --git a/packages/backend/src/controllers/api/v1/apps/get-auth.js b/packages/backend/src/controllers/api/v1/apps/get-auth.js new file mode 100644 index 0000000000..37b307539e --- /dev/null +++ b/packages/backend/src/controllers/api/v1/apps/get-auth.js @@ -0,0 +1,8 @@ +import App from '../../../../models/app.js'; +import { renderObject } from '../../../../helpers/renderer.js'; + +export default async (request, response) => { + const auth = await App.findAuthByKey(request.params.appKey); + + renderObject(response, auth, { serializer: 'Auth' }); +}; diff --git a/packages/backend/src/controllers/api/v1/apps/get-auth.test.js b/packages/backend/src/controllers/api/v1/apps/get-auth.test.js new file mode 100644 index 0000000000..b846e607e1 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/apps/get-auth.test.js @@ -0,0 +1,35 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import request from 'supertest'; +import App from '../../../../models/app'; +import app from '../../../../app.js'; +import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id'; +import { createUser } from '../../../../../test/factories/user'; +import getAuthMock from '../../../../../test/mocks/rest/api/v1/apps/get-auth.js'; + +describe('GET /api/v1/apps/:appKey/auth', () => { + let currentUser, token; + + beforeEach(async () => { + currentUser = await createUser(); + token = createAuthTokenByUserId(currentUser.id); + }); + + it('should return the app auth info', async () => { + const exampleApp = await App.findOneByKey('github'); + + const response = await request(app) + .get(`/api/v1/apps/${exampleApp.key}/auth`) + .set('Authorization', token) + .expect(200); + + const expectedPayload = getAuthMock(exampleApp.auth); + expect(response.body).toEqual(expectedPayload); + }); + + it('should return not found response for invalid app key', async () => { + await request(app) + .get('/api/v1/apps/invalid-app-key') + .set('Authorization', token) + .expect(404); + }); +}); diff --git a/packages/backend/src/models/app.js b/packages/backend/src/models/app.js index 6131f014cf..865f9a3e70 100644 --- a/packages/backend/src/models/app.js +++ b/packages/backend/src/models/app.js @@ -39,6 +39,13 @@ class App { return appInfoConverter(rawAppData); } + static async findAuthByKey(key, stripFuncs = false) { + const rawAppData = await getApp(key, stripFuncs); + const appData = appInfoConverter(rawAppData); + + return appData.auth; + } + static async checkAppAndAction(appKey, actionKey) { const app = await this.findOneByKey(appKey); diff --git a/packages/backend/src/routes/api/v1/apps.js b/packages/backend/src/routes/api/v1/apps.js index b5d23b4ab9..2f696bb122 100644 --- a/packages/backend/src/routes/api/v1/apps.js +++ b/packages/backend/src/routes/api/v1/apps.js @@ -2,9 +2,11 @@ import { Router } from 'express'; import asyncHandler from 'express-async-handler'; import { authenticateUser } from '../../../helpers/authentication.js'; import getAppAction from '../../../controllers/api/v1/apps/get-app.js'; +import getAuthAction from '../../../controllers/api/v1/apps/get-auth.js'; const router = Router(); router.get('/:appKey', authenticateUser, asyncHandler(getAppAction)); +router.get('/:appKey/auth', authenticateUser, asyncHandler(getAuthAction)); export default router; diff --git a/packages/backend/src/serializers/app.test.js b/packages/backend/src/serializers/app.test.js index 8527f103ac..c2714dc2c9 100644 --- a/packages/backend/src/serializers/app.test.js +++ b/packages/backend/src/serializers/app.test.js @@ -3,7 +3,7 @@ import App from '../models/app'; import appSerializer from './app'; describe('appSerializer', () => { - it('should return permission data', async () => { + it('should return app data', async () => { const app = await App.findOneByKey('deepl'); const expectedPayload = { diff --git a/packages/backend/src/serializers/auth.js b/packages/backend/src/serializers/auth.js new file mode 100644 index 0000000000..c5d60a4eef --- /dev/null +++ b/packages/backend/src/serializers/auth.js @@ -0,0 +1,9 @@ +const authSerializer = (auth) => { + return { + fields: auth.fields, + authenticationSteps: auth.authenticationSteps, + reconnectionSteps: auth.reconnectionSteps, + }; +}; + +export default authSerializer; diff --git a/packages/backend/src/serializers/auth.test.js b/packages/backend/src/serializers/auth.test.js new file mode 100644 index 0000000000..6746c5597e --- /dev/null +++ b/packages/backend/src/serializers/auth.test.js @@ -0,0 +1,17 @@ +import { describe, it, expect } from 'vitest'; +import App from '../models/app'; +import authSerializer from './auth'; + +describe('authSerializer', () => { + it('should return auth data', async () => { + const auth = await App.findAuthByKey('deepl'); + + const expectedPayload = { + fields: auth.fields, + authenticationSteps: auth.authenticationSteps, + reconnectionSteps: auth.reconnectionSteps, + }; + + expect(authSerializer(auth)).toEqual(expectedPayload); + }); +}); diff --git a/packages/backend/src/serializers/index.js b/packages/backend/src/serializers/index.js index 9a63ca7211..1732ac6258 100644 --- a/packages/backend/src/serializers/index.js +++ b/packages/backend/src/serializers/index.js @@ -6,6 +6,7 @@ import appAuthClientSerializer from './app-auth-client.js'; import flowSerializer from './flow.js'; import stepSerializer from './step.js'; import appSerializer from './app.js'; +import authSerializer from './auth.js'; const serializers = { User: userSerializer, @@ -16,6 +17,7 @@ const serializers = { Flow: flowSerializer, Step: stepSerializer, App: appSerializer, + Auth: authSerializer, }; export default serializers; diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-auth.js b/packages/backend/test/mocks/rest/api/v1/apps/get-auth.js new file mode 100644 index 0000000000..68ea18cdf4 --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-auth.js @@ -0,0 +1,18 @@ +const getAuthMock = (auth) => { + return { + data: { + fields: auth.fields, + authenticationSteps: auth.authenticationSteps, + reconnectionSteps: auth.reconnectionSteps, + }, + meta: { + count: 1, + currentPage: null, + isArray: false, + totalPages: null, + type: 'Object', + }, + }; +}; + +export default getAuthMock;