mirror of
https://github.com/logto-io/logto.git
synced 2025-02-03 21:48:55 -05:00
fix(console,core): fix application count bug (#5270)
fix application count bug
This commit is contained in:
parent
4976154e6d
commit
42e9513ca1
5 changed files with 45 additions and 10 deletions
|
@ -64,6 +64,7 @@ const useApplicationsData = (isThirdParty = false) => {
|
||||||
buildUrl(applicationsEndpoint, {
|
buildUrl(applicationsEndpoint, {
|
||||||
page: String(firstPartyApplicationPage),
|
page: String(firstPartyApplicationPage),
|
||||||
page_size: String(pageSize),
|
page_size: String(pageSize),
|
||||||
|
isThirdParty: 'false',
|
||||||
}),
|
}),
|
||||||
[firstPartyApplicationPage]
|
[firstPartyApplicationPage]
|
||||||
);
|
);
|
||||||
|
|
|
@ -73,7 +73,7 @@ export const createApplicationQueries = (pool: CommonQueryMethods) => {
|
||||||
? sql`${fields.id} not in (${sql.join(excludeApplicationIds, sql`, `)})`
|
? sql`${fields.id} not in (${sql.join(excludeApplicationIds, sql`, `)})`
|
||||||
: sql``,
|
: sql``,
|
||||||
types && types.length > 0 ? sql`${fields.type} in (${sql.join(types, sql`, `)})` : sql``,
|
types && types.length > 0 ? sql`${fields.type} in (${sql.join(types, sql`, `)})` : sql``,
|
||||||
isThirdParty ? sql`${fields.isThirdParty} = true` : sql`${fields.isThirdParty} = false`,
|
typeof isThirdParty === 'boolean' ? sql`${fields.isThirdParty} = ${isThirdParty}` : sql``,
|
||||||
buildApplicationConditions(search),
|
buildApplicationConditions(search),
|
||||||
])}
|
])}
|
||||||
`);
|
`);
|
||||||
|
@ -118,7 +118,7 @@ export const createApplicationQueries = (pool: CommonQueryMethods) => {
|
||||||
? sql`${fields.id} not in (${sql.join(excludeApplicationIds, sql`, `)})`
|
? sql`${fields.id} not in (${sql.join(excludeApplicationIds, sql`, `)})`
|
||||||
: sql``,
|
: sql``,
|
||||||
types && types.length > 0 ? sql`${fields.type} in (${sql.join(types, sql`, `)})` : sql``,
|
types && types.length > 0 ? sql`${fields.type} in (${sql.join(types, sql`, `)})` : sql``,
|
||||||
isThirdParty ? sql`${fields.isThirdParty} = true` : sql`${fields.isThirdParty} = false`,
|
typeof isThirdParty === 'boolean' ? sql`${fields.isThirdParty} = ${isThirdParty}` : sql``,
|
||||||
buildApplicationConditions(search),
|
buildApplicationConditions(search),
|
||||||
])}
|
])}
|
||||||
order by ${fields.createdAt} desc
|
order by ${fields.createdAt} desc
|
||||||
|
|
|
@ -56,6 +56,19 @@ export default function applicationRoutes<T extends AuthedRouter>(
|
||||||
} = queries.applicationsRoles;
|
} = queries.applicationsRoles;
|
||||||
const { findRoleByRoleName } = queries.roles;
|
const { findRoleByRoleName } = queries.roles;
|
||||||
|
|
||||||
|
const parseIsThirdPartQueryParam = (isThirdPartyQuery: 'true' | 'false ' | undefined) => {
|
||||||
|
// FIXME: @simeng-li Remove this guard once Logto as IdP is ready
|
||||||
|
if (!EnvSet.values.isDevFeaturesEnabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isThirdPartyQuery === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isThirdPartyQuery === 'true';
|
||||||
|
};
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/applications',
|
'/applications',
|
||||||
koaPagination({ isOptional: true }),
|
koaPagination({ isOptional: true }),
|
||||||
|
@ -72,7 +85,9 @@ export default function applicationRoutes<T extends AuthedRouter>(
|
||||||
excludeRoleId: string().optional(),
|
excludeRoleId: string().optional(),
|
||||||
// FIXME: @simeng-li Remove this guard once Logto as IdP is ready
|
// FIXME: @simeng-li Remove this guard once Logto as IdP is ready
|
||||||
...conditional(
|
...conditional(
|
||||||
EnvSet.values.isDevFeaturesEnabled && { isThirdParty: z.literal('true').optional() }
|
EnvSet.values.isDevFeaturesEnabled && {
|
||||||
|
isThirdParty: z.union([z.literal('true'), z.literal('false')]).optional(),
|
||||||
|
}
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
response: z.array(applicationResponseGuard),
|
response: z.array(applicationResponseGuard),
|
||||||
|
@ -81,10 +96,10 @@ export default function applicationRoutes<T extends AuthedRouter>(
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
const { limit, offset, disabled: paginationDisabled } = ctx.pagination;
|
const { limit, offset, disabled: paginationDisabled } = ctx.pagination;
|
||||||
const { searchParams } = ctx.URL;
|
const { searchParams } = ctx.URL;
|
||||||
const { types, excludeRoleId } = ctx.guard.query;
|
const { types, excludeRoleId, isThirdParty: isThirdPartyParam } = ctx.guard.query;
|
||||||
|
|
||||||
// FIXME: @simeng-li Remove this guard once Logto as IdP is ready
|
// @ts-expect-error FIXME: unknown type will be fixed once we have the isDevFeaturesEnabled guard removed
|
||||||
const isThirdParty = Boolean(ctx.guard.query.isThirdParty);
|
const isThirdParty = parseIsThirdPartQueryParam(isThirdPartyParam);
|
||||||
|
|
||||||
// This will only parse the `search` query param, other params will be ignored. Please use query guard to validate them.
|
// This will only parse the `search` query param, other params will be ignored. Please use query guard to validate them.
|
||||||
const search = parseSearchParamsForSearch(searchParams);
|
const search = parseSearchParamsForSearch(searchParams);
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const createApplication = async (
|
||||||
export const getApplications = async (
|
export const getApplications = async (
|
||||||
types?: ApplicationType[],
|
types?: ApplicationType[],
|
||||||
searchParameters?: Record<string, string>,
|
searchParameters?: Record<string, string>,
|
||||||
isThirdParty?: boolean
|
isThirdParty?: 'true' | 'false'
|
||||||
) => {
|
) => {
|
||||||
const searchParams = new URLSearchParams([
|
const searchParams = new URLSearchParams([
|
||||||
...(conditional(types && types.length > 0 && types.map((type) => ['types', type])) ?? []),
|
...(conditional(types && types.length > 0 && types.map((type) => ['types', type])) ?? []),
|
||||||
|
@ -37,7 +37,7 @@ export const getApplications = async (
|
||||||
Object.keys(searchParameters).length > 0 &&
|
Object.keys(searchParameters).length > 0 &&
|
||||||
Object.entries(searchParameters).map(([key, value]) => [key, value])
|
Object.entries(searchParameters).map(([key, value]) => [key, value])
|
||||||
) ?? []),
|
) ?? []),
|
||||||
...(conditional(isThirdParty && [['isThirdParty', 'true']]) ?? []),
|
...(conditional(isThirdParty && [['isThirdParty', isThirdParty]]) ?? []),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return authedAdminApi.get('applications', { searchParams }).json<Application[]>();
|
return authedAdminApi.get('applications', { searchParams }).json<Application[]>();
|
||||||
|
|
|
@ -176,7 +176,7 @@ describe('admin console application', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch all non-third party applications created above', async () => {
|
it('should fetch all non-third party applications created above', async () => {
|
||||||
const applications = await getApplications();
|
const applications = await getApplications(undefined, undefined, 'false');
|
||||||
|
|
||||||
const applicationNames = applications.map(({ name }) => name);
|
const applicationNames = applications.map(({ name }) => name);
|
||||||
expect(applicationNames).toContain('test-create-app');
|
expect(applicationNames).toContain('test-create-app');
|
||||||
|
@ -194,13 +194,32 @@ describe('admin console application', () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const applications = await getApplications(undefined, undefined, true);
|
const applications = await getApplications(undefined, undefined, 'true');
|
||||||
|
|
||||||
expect(applications.find(({ id }) => id === application.id)).toEqual(application);
|
expect(applications.find(({ id }) => id === application.id)).toEqual(application);
|
||||||
expect(applications.some(({ isThirdParty }) => !isThirdParty)).toBe(false);
|
expect(applications.some(({ isThirdParty }) => !isThirdParty)).toBe(false);
|
||||||
await deleteApplication(application.id);
|
await deleteApplication(application.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fetch all applications including third party applications', async () => {
|
||||||
|
const application = await createApplication(
|
||||||
|
'test-third-party-app',
|
||||||
|
ApplicationType.Traditional,
|
||||||
|
{
|
||||||
|
isThirdParty: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const applications = await getApplications();
|
||||||
|
const applicationNames = applications.map(({ name }) => name);
|
||||||
|
|
||||||
|
expect(applicationNames).toContain('test-create-app');
|
||||||
|
expect(applicationNames).toContain('test-update-app');
|
||||||
|
expect(applicationNames).toContain('test-third-party-app');
|
||||||
|
|
||||||
|
await deleteApplication(application.id);
|
||||||
|
});
|
||||||
|
|
||||||
it('should create m2m application successfully and can get only m2m applications by specifying types', async () => {
|
it('should create m2m application successfully and can get only m2m applications by specifying types', async () => {
|
||||||
await createApplication('test-m2m-app-1', ApplicationType.MachineToMachine);
|
await createApplication('test-m2m-app-1', ApplicationType.MachineToMachine);
|
||||||
await createApplication('test-m2m-app-2', ApplicationType.MachineToMachine);
|
await createApplication('test-m2m-app-2', ApplicationType.MachineToMachine);
|
||||||
|
|
Loading…
Add table
Reference in a new issue