diff --git a/packages/console/src/pages/ApplicationDetails/index.tsx b/packages/console/src/pages/ApplicationDetails/index.tsx index 8cc73fad9..c2f73b3d4 100644 --- a/packages/console/src/pages/ApplicationDetails/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/index.tsx @@ -1,4 +1,4 @@ -import { Application, ApplicationDTO } from '@logto/schemas'; +import { Application, SnakeCaseOidcConfig } from '@logto/schemas'; import React, { useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; @@ -36,11 +36,15 @@ const ApplicationDetails = () => { const location = useLocation(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const { data, error, mutate } = useSWR( + const { data, error, mutate } = useSWR( id && `/api/applications/${id}` ); - const isLoading = !data && !error; + const { data: oidcConfig, error: fetchOidcConfigError } = useSWR< + SnakeCaseOidcConfig, + RequestError + >('/oidc/.well-known/openid-configuration'); + const isLoading = !data && !error && !oidcConfig && !fetchOidcConfigError; const [isReadmeOpen, setIsReadmeOpen] = useState(false); @@ -80,14 +84,14 @@ const ApplicationDetails = () => { }, }, }) - .json(); + .json(); void mutate(updatedApplication); toast.success(t('application_details.save_success')); }); const isAdvancedSettings = location.pathname.includes('advanced-settings'); - const SettingsPage = data && ( + const SettingsPage = oidcConfig && ( <> { title="admin_console.application_details.authorization_endpoint" className={styles.textField} > - + { ); - const AdvancedSettingsPage = data && ( + const AdvancedSettingsPage = oidcConfig && ( <> - + - + ); @@ -184,7 +185,7 @@ const ApplicationDetails = () => { /> {isLoading &&
loading
} {error &&
{`error occurred: ${error.body.message}`}
} - {data && ( + {data && oidcConfig && ( <> diff --git a/packages/console/src/pages/Applications/index.tsx b/packages/console/src/pages/Applications/index.tsx index 37467e1f0..a514d5c0f 100644 --- a/packages/console/src/pages/Applications/index.tsx +++ b/packages/console/src/pages/Applications/index.tsx @@ -1,4 +1,4 @@ -import { ApplicationDTO } from '@logto/schemas'; +import { Application } from '@logto/schemas'; import classNames from 'classnames'; import React, { useState } from 'react'; import { toast } from 'react-hot-toast'; @@ -33,7 +33,7 @@ const Applications = () => { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const [query, setQuery] = useSearchParams(); const pageIndex = Number(query.get('page') ?? '1'); - const { data, error, mutate } = useSWR<[ApplicationDTO[], number], RequestError>( + const { data, error, mutate } = useSWR<[Application[], number], RequestError>( `/api/applications?page=${pageIndex}&page_size=${pageSize}` ); const isLoading = !data && !error; diff --git a/packages/core/package.json b/packages/core/package.json index 61205e37b..01de4e35d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -23,7 +23,6 @@ "@logto/phrases": "^0.1.0", "@logto/schemas": "^0.1.0", "@silverhand/essentials": "^1.1.0", - "camelcase-keys": "^7.0.2", "dayjs": "^1.10.5", "decamelize": "^5.0.0", "dotenv": "^10.0.0", diff --git a/packages/core/src/__mocks__/index.ts b/packages/core/src/__mocks__/index.ts index aacfa110d..5404e4eb1 100644 --- a/packages/core/src/__mocks__/index.ts +++ b/packages/core/src/__mocks__/index.ts @@ -1,29 +1,20 @@ import { Application, - ApplicationDTO, ApplicationType, Passcode, PasscodeType, Resource, Role, Setting, - SnakeCaseOidcConfig, UserLog, UserLogResult, UserLogType, } from '@logto/schemas'; -import camelcaseKeys from 'camelcase-keys'; export * from './connector'; export * from './sign-in-experience'; export * from './user'; -export const mockOidcConfig: SnakeCaseOidcConfig = { - authorization_endpoint: 'https://logto.dev/oidc/auth', - userinfo_endpoint: 'https://logto.dev/oidc/userinfo', - token_endpoint: 'https://logto.dev/oidc/token', -}; - export const mockApplication: Application = { id: 'foo', name: 'foo', @@ -41,11 +32,6 @@ export const mockApplication: Application = { createdAt: 1_645_334_775_356, }; -export const mockApplicationDTO: ApplicationDTO = { - ...mockApplication, - oidcConfig: camelcaseKeys(mockOidcConfig), -}; - export const mockResource: Resource = { id: 'logto_api', name: 'management api', diff --git a/packages/core/src/routes/application.test.ts b/packages/core/src/routes/application.test.ts index 5f56184a2..9508beb00 100644 --- a/packages/core/src/routes/application.test.ts +++ b/packages/core/src/routes/application.test.ts @@ -1,8 +1,6 @@ import { Application, CreateApplication, ApplicationType } from '@logto/schemas'; -import nock from 'nock'; -import { mockApplicationDTO, mockOidcConfig } from '@/__mocks__'; -import { port } from '@/env/consts'; +import { mockApplication } from '@/__mocks__'; import { findApplicationById } from '@/queries/application'; import { createRequester } from '@/utils/test-utils'; @@ -10,22 +8,22 @@ import applicationRoutes from './application'; jest.mock('@/queries/application', () => ({ findTotalNumberOfApplications: jest.fn(async () => ({ count: 10 })), - findAllApplications: jest.fn(async () => [mockApplicationDTO]), - findApplicationById: jest.fn(async () => mockApplicationDTO), + findAllApplications: jest.fn(async () => [mockApplication]), + findApplicationById: jest.fn(async () => mockApplication), deleteApplicationById: jest.fn(), insertApplication: jest.fn( async (body: CreateApplication): Promise => ({ - ...mockApplicationDTO, + ...mockApplication, ...body, oidcClientMetadata: { - ...mockApplicationDTO.oidcClientMetadata, + ...mockApplication.oidcClientMetadata, ...body.oidcClientMetadata, }, }) ), updateApplicationById: jest.fn( async (_, data: Partial): Promise => ({ - ...mockApplicationDTO, + ...mockApplication, ...data, }) ), @@ -45,15 +43,10 @@ const customClientMetadata = { describe('application route', () => { const applicationRequest = createRequester({ authedRoutes: applicationRoutes }); - beforeEach(() => { - const discoveryUrl = `http://localhost:${port}/oidc/.well-known/openid-configuration`; - nock(discoveryUrl).get('').reply(200, mockOidcConfig); - }); - it('GET /applications', async () => { const response = await applicationRequest.get('/applications'); expect(response.status).toEqual(200); - expect(response.body).toEqual([mockApplicationDTO]); + expect(response.body).toEqual([mockApplication]); expect(response.header).toHaveProperty('total-number', '10'); }); @@ -67,7 +60,7 @@ describe('application route', () => { .send({ name, type, description }); expect(response.status).toEqual(200); expect(response.body).toEqual({ - ...mockApplicationDTO, + ...mockApplication, id: 'randomId', name, description, @@ -84,7 +77,7 @@ describe('application route', () => { .send({ name, type, customClientMetadata }); expect(response.status).toEqual(200); expect(response.body).toEqual({ - ...mockApplicationDTO, + ...mockApplication, id: 'randomId', name, type, @@ -123,7 +116,7 @@ describe('application route', () => { const response = await applicationRequest.get('/applications/foo'); expect(response.status).toEqual(200); - expect(response.body).toEqual(mockApplicationDTO); + expect(response.body).toEqual(mockApplication); }); it('PATCH /applications/:applicationId', async () => { @@ -134,12 +127,7 @@ describe('application route', () => { .patch('/applications/foo') .send({ name, description, customClientMetadata }); expect(response.status).toEqual(200); - expect(response.body).toEqual({ - ...mockApplicationDTO, - name, - description, - customClientMetadata, - }); + expect(response.body).toEqual({ ...mockApplication, name, description, customClientMetadata }); }); it('PATCH /applications/:applicationId expect to throw with invalid properties', async () => { diff --git a/packages/core/src/routes/application.ts b/packages/core/src/routes/application.ts index 4b0ca1a84..9d8e463ec 100644 --- a/packages/core/src/routes/application.ts +++ b/packages/core/src/routes/application.ts @@ -1,9 +1,6 @@ -import { Applications, SnakeCaseOidcConfig } from '@logto/schemas'; -import camelcaseKeys from 'camelcase-keys'; -import got from 'got'; +import { Applications } from '@logto/schemas'; import { object, string } from 'zod'; -import { port } from '@/env/consts'; import koaGuard from '@/middleware/koa-guard'; import koaPagination from '@/middleware/koa-pagination'; import { buildOidcClientMetadata } from '@/oidc/utils'; @@ -21,24 +18,18 @@ import { AuthedRouter } from './types'; const applicationId = buildIdGenerator(21); -const discoveryUrl = `http://localhost:${port}/oidc/.well-known/openid-configuration`; - export default function applicationRoutes(router: T) { router.get('/applications', koaPagination(), async (ctx, next) => { const { limit, offset } = ctx.pagination; - const [{ count }, applications, oidcConfig] = await Promise.all([ + const [{ count }, applications] = await Promise.all([ findTotalNumberOfApplications(), findAllApplications(limit, offset), - got(discoveryUrl).json(), ]); // Return totalCount to pagination middleware ctx.pagination.totalCount = count; - ctx.body = applications.map((application) => ({ - ...application, - oidcConfig: camelcaseKeys(oidcConfig), - })); + ctx.body = applications; return next(); }); @@ -54,19 +45,11 @@ export default function applicationRoutes(router: T) { async (ctx, next) => { const { oidcClientMetadata, ...rest } = ctx.guard.body; - const [application, oidcConfig] = await Promise.all([ - insertApplication({ - id: applicationId(), - oidcClientMetadata: buildOidcClientMetadata(oidcClientMetadata), - ...rest, - }), - got(discoveryUrl).json(), - ]); - - ctx.body = { - ...application, - oidcConfig: camelcaseKeys(oidcConfig), - }; + ctx.body = await insertApplication({ + id: applicationId(), + oidcClientMetadata: buildOidcClientMetadata(oidcClientMetadata), + ...rest, + }); return next(); } @@ -82,15 +65,7 @@ export default function applicationRoutes(router: T) { params: { id }, } = ctx.guard; - const [application, oidcConfig] = await Promise.all([ - findApplicationById(id), - got(discoveryUrl).json(), - ]); - - ctx.body = { - ...application, - oidcConfig: camelcaseKeys(oidcConfig), - }; + ctx.body = await findApplicationById(id); return next(); } @@ -108,17 +83,9 @@ export default function applicationRoutes(router: T) { body, } = ctx.guard; - const [application, oidcConfig] = await Promise.all([ - updateApplicationById(id, { - ...body, - }), - got(discoveryUrl).json(), - ]); - - ctx.body = { - ...application, - oidcConfig: camelcaseKeys(oidcConfig), - }; + ctx.body = await updateApplicationById(id, { + ...body, + }); return next(); } diff --git a/packages/schemas/src/types/application.ts b/packages/schemas/src/types/application.ts deleted file mode 100644 index 054f9e5d2..000000000 --- a/packages/schemas/src/types/application.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Application } from '../db-entries'; -import { OidcConfig } from './oidc-config'; - -export interface ApplicationDTO extends Application { - oidcConfig: OidcConfig; -} diff --git a/packages/schemas/src/types/index.ts b/packages/schemas/src/types/index.ts index f860c5a19..f233e035f 100644 --- a/packages/schemas/src/types/index.ts +++ b/packages/schemas/src/types/index.ts @@ -1,4 +1,3 @@ export * from './user'; export * from './connector'; export * from './oidc-config'; -export * from './application'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 837145bcf..a5358c805 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,7 +167,6 @@ importers: '@types/node': ^16.3.1 '@types/oidc-provider': ^7.8.0 '@types/supertest': ^2.0.11 - camelcase-keys: ^7.0.2 copyfiles: ^2.4.1 dayjs: ^1.10.5 decamelize: ^5.0.0 @@ -209,7 +208,6 @@ importers: '@logto/phrases': link:../phrases '@logto/schemas': link:../schemas '@silverhand/essentials': 1.1.2 - camelcase-keys: 7.0.2 dayjs: 1.10.7 decamelize: 5.0.1 dotenv: 10.0.0 @@ -7378,6 +7376,7 @@ packages: /camelcase/6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + dev: false /caniuse-api/3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} @@ -11901,7 +11900,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - camelcase: 6.3.0 + camelcase: 6.2.1 chalk: 4.1.2 jest-get-type: 27.5.1 leven: 3.1.0