mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
Merge pull request #2907 from logto-io/gao-log-5161-core-remove-deprecated-query-functions
refactor(core): remove deprecated query functions
This commit is contained in:
commit
a5467e265b
33 changed files with 300 additions and 353 deletions
|
@ -50,8 +50,8 @@ export const createUserLibrary = (queries: Queries) => {
|
|||
const {
|
||||
pool,
|
||||
roles: { findRolesByRoleNames, insertRoles, findRoleByRoleName },
|
||||
users: { hasUser, hasUserWithEmail, hasUserWithId, hasUserWithPhone },
|
||||
usersRoles: { insertUsersRoles },
|
||||
users: { hasUser, hasUserWithEmail, hasUserWithId, hasUserWithPhone, findUsersByIds },
|
||||
usersRoles: { insertUsersRoles, findUsersRolesByRoleId },
|
||||
} = queries;
|
||||
|
||||
const generateUserId = async (retries = 500) =>
|
||||
|
@ -140,9 +140,26 @@ export const createUserLibrary = (queries: Queries) => {
|
|||
}
|
||||
};
|
||||
|
||||
const findUsersByRoleName = async (roleName: string) => {
|
||||
const role = await findRoleByRoleName(roleName);
|
||||
|
||||
if (!role) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const usersRoles = await findUsersRolesByRoleId(role.id);
|
||||
|
||||
if (usersRoles.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return findUsersByIds(usersRoles.map(({ userId }) => userId));
|
||||
};
|
||||
|
||||
return {
|
||||
generateUserId,
|
||||
insertUser,
|
||||
checkIdentifierCollision,
|
||||
findUsersByRoleName,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { demoAppApplicationId } from '@logto/schemas';
|
||||
import type { MiddlewareType } from 'koa';
|
||||
|
||||
import { findApplicationById } from '#src/queries/application.js';
|
||||
import type Queries from '#src/tenants/Queries.js';
|
||||
|
||||
export default function koaCheckDemoApp<StateT, ContextT, ResponseBodyT>(
|
||||
queries: Queries
|
||||
): MiddlewareType<StateT, ContextT, ResponseBodyT> {
|
||||
const { findApplicationById } = queries.applications;
|
||||
|
||||
export default function koaCheckDemoApp<StateT, ContextT, ResponseBodyT>(): MiddlewareType<
|
||||
StateT,
|
||||
ContextT,
|
||||
ResponseBodyT
|
||||
> {
|
||||
return async (ctx, next) => {
|
||||
try {
|
||||
await findApplicationById(demoAppApplicationId);
|
||||
|
|
|
@ -3,6 +3,7 @@ import { createMockUtils } from '@logto/shared/esm';
|
|||
import snakecaseKeys from 'snakecase-keys';
|
||||
|
||||
import { mockApplication } from '#src/__mocks__/index.js';
|
||||
import { MockQueries } from '#src/test-utils/tenant.js';
|
||||
|
||||
import { getConstantClientMetadata } from './utils.js';
|
||||
|
||||
|
@ -10,19 +11,6 @@ const { jest } = import.meta;
|
|||
|
||||
const { mockEsm } = createMockUtils(jest);
|
||||
|
||||
mockEsm('#src/queries/application.js', () => ({
|
||||
findApplicationById: jest.fn(async (): Promise<Application> => mockApplication),
|
||||
}));
|
||||
|
||||
mockEsm('#src/queries/oidc-model-instance.js', () => ({
|
||||
upsertInstance: jest.fn(),
|
||||
findPayloadById: jest.fn(),
|
||||
findPayloadByPayloadField: jest.fn(),
|
||||
consumeInstanceById: jest.fn(),
|
||||
destroyInstanceById: jest.fn(),
|
||||
revokeInstanceByGrantId: jest.fn(),
|
||||
}));
|
||||
|
||||
mockEsm(
|
||||
'date-fns',
|
||||
jest.fn(() => ({
|
||||
|
@ -31,6 +19,15 @@ mockEsm(
|
|||
);
|
||||
|
||||
const { default: postgresAdapter } = await import('./adapter.js');
|
||||
|
||||
const oidcModelInstances = {
|
||||
upsertInstance: jest.fn(),
|
||||
findPayloadById: jest.fn(),
|
||||
findPayloadByPayloadField: jest.fn(),
|
||||
consumeInstanceById: jest.fn(),
|
||||
destroyInstanceById: jest.fn(),
|
||||
revokeInstanceByGrantId: jest.fn(),
|
||||
};
|
||||
const {
|
||||
consumeInstanceById,
|
||||
destroyInstanceById,
|
||||
|
@ -38,14 +35,19 @@ const {
|
|||
findPayloadByPayloadField,
|
||||
revokeInstanceByGrantId,
|
||||
upsertInstance,
|
||||
} = await import('#src/queries/oidc-model-instance.js');
|
||||
} = oidcModelInstances;
|
||||
|
||||
const queries = new MockQueries({
|
||||
applications: { findApplicationById: jest.fn(async (): Promise<Application> => mockApplication) },
|
||||
oidcModelInstances,
|
||||
});
|
||||
|
||||
const now = Date.now();
|
||||
|
||||
describe('postgres Adapter', () => {
|
||||
it('Client Modal', async () => {
|
||||
const rejectError = new Error('Not implemented');
|
||||
const adapter = postgresAdapter('Client');
|
||||
const adapter = postgresAdapter(queries, 'Client');
|
||||
|
||||
await expect(adapter.upsert('client', {}, 0)).rejects.toMatchError(rejectError);
|
||||
await expect(adapter.findByUserCode('foo')).rejects.toMatchError(rejectError);
|
||||
|
@ -82,7 +84,7 @@ describe('postgres Adapter', () => {
|
|||
const id = 'fooId';
|
||||
const grantId = 'grantId';
|
||||
const expireAt = 60;
|
||||
const adapter = postgresAdapter(modelName);
|
||||
const adapter = postgresAdapter(queries, modelName);
|
||||
|
||||
await adapter.upsert(id, { uid, userCode }, expireAt);
|
||||
expect(upsertInstance).toBeCalledWith({
|
||||
|
|
|
@ -8,15 +8,7 @@ import { errors } from 'oidc-provider';
|
|||
import snakecaseKeys from 'snakecase-keys';
|
||||
|
||||
import envSet, { MountedApps } from '#src/env-set/index.js';
|
||||
import { findApplicationById } from '#src/queries/application.js';
|
||||
import {
|
||||
consumeInstanceById,
|
||||
destroyInstanceById,
|
||||
findPayloadById,
|
||||
findPayloadByPayloadField,
|
||||
revokeInstanceByGrantId,
|
||||
upsertInstance,
|
||||
} from '#src/queries/oidc-model-instance.js';
|
||||
import type Queries from '#src/tenants/Queries.js';
|
||||
import { appendPath } from '#src/utils/url.js';
|
||||
|
||||
import { getConstantClientMetadata } from './utils.js';
|
||||
|
@ -54,7 +46,22 @@ const buildDemoAppUris = (
|
|||
return data;
|
||||
};
|
||||
|
||||
export default function postgresAdapter(modelName: string): ReturnType<AdapterFactory> {
|
||||
export default function postgresAdapter(
|
||||
queries: Queries,
|
||||
modelName: string
|
||||
): ReturnType<AdapterFactory> {
|
||||
const {
|
||||
applications: { findApplicationById },
|
||||
oidcModelInstances: {
|
||||
consumeInstanceById,
|
||||
destroyInstanceById,
|
||||
findPayloadById,
|
||||
findPayloadByPayloadField,
|
||||
revokeInstanceByGrantId,
|
||||
upsertInstance,
|
||||
},
|
||||
} = queries;
|
||||
|
||||
if (modelName === 'Client') {
|
||||
const reject = async () => {
|
||||
throw new Error('Not implemented');
|
||||
|
|
|
@ -45,7 +45,7 @@ export default function initOidc(queries: Queries): Provider {
|
|||
} as const);
|
||||
|
||||
const oidc = new Provider(issuer, {
|
||||
adapter: postgresAdapter,
|
||||
adapter: postgresAdapter.bind(null, queries),
|
||||
renderError: (_ctx, _out, error) => {
|
||||
console.error(error);
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import { buildFindEntityByIdWithPool } from '#src/database/find-entity-by-id.js'
|
|||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import { getTotalRowCountWithPool } from '#src/database/row-count.js';
|
||||
import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Applications);
|
||||
|
@ -65,14 +64,3 @@ export const createApplicationQueries = (pool: CommonQueryMethods) => {
|
|||
deleteApplicationById,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createApplicationQueries() factory instead. */
|
||||
export const {
|
||||
findTotalNumberOfApplications,
|
||||
findAllApplications,
|
||||
findApplicationById,
|
||||
insertApplication,
|
||||
updateApplication,
|
||||
updateApplicationById,
|
||||
deleteApplicationById,
|
||||
} = createApplicationQueries(envSet.pool);
|
||||
|
|
|
@ -6,7 +6,6 @@ import { sql } from 'slonik';
|
|||
|
||||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Connectors);
|
||||
|
@ -72,14 +71,3 @@ export const createConnectorQueries = (pool: CommonQueryMethods) => {
|
|||
updateConnector,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createConnectorQueries() factory instead. */
|
||||
export const {
|
||||
findAllConnectors,
|
||||
findConnectorById,
|
||||
countConnectorByConnectorId,
|
||||
deleteConnectorById,
|
||||
deleteConnectorByIds,
|
||||
insertConnector,
|
||||
updateConnector,
|
||||
} = createConnectorQueries(envSet.pool);
|
||||
|
|
|
@ -5,7 +5,6 @@ import type { CommonQueryMethods } from 'slonik';
|
|||
import { sql } from 'slonik';
|
||||
|
||||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(CustomPhrases);
|
||||
|
@ -69,12 +68,3 @@ export const createCustomPhraseQueries = (pool: CommonQueryMethods) => {
|
|||
deleteCustomPhraseByLanguageTag,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createCustomPhraseQueries() factory instead. */
|
||||
export const {
|
||||
findAllCustomLanguageTags,
|
||||
findAllCustomPhrases,
|
||||
findCustomPhraseByLanguageTag,
|
||||
upsertCustomPhrase,
|
||||
deleteCustomPhraseByLanguageTag,
|
||||
} = createCustomPhraseQueries(envSet.pool);
|
||||
|
|
|
@ -6,7 +6,6 @@ import { sql } from 'slonik';
|
|||
|
||||
import { buildFindEntityByIdWithPool } from '#src/database/find-entity-by-id.js';
|
||||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Logs);
|
||||
|
||||
|
@ -88,13 +87,3 @@ export const createLogQueries = (pool: CommonQueryMethods) => {
|
|||
countActiveUsersByTimeInterval,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createLogQueries() factory instead. */
|
||||
export const {
|
||||
insertLog,
|
||||
countLogs,
|
||||
findLogs,
|
||||
findLogById,
|
||||
getDailyActiveUserCountsByTimeInterval,
|
||||
countActiveUsersByTimeInterval,
|
||||
} = createLogQueries(envSet.pool);
|
||||
|
|
|
@ -131,14 +131,3 @@ export const createOidcModelInstanceQueries = (pool: CommonQueryMethods) => {
|
|||
revokeInstanceByUserId,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createOidcModelInstanceQueries() factory instead. */
|
||||
export const {
|
||||
upsertInstance,
|
||||
findPayloadById,
|
||||
findPayloadByPayloadField,
|
||||
consumeInstanceById,
|
||||
destroyInstanceById,
|
||||
revokeInstanceByGrantId,
|
||||
revokeInstanceByUserId,
|
||||
} = createOidcModelInstanceQueries(envSet.pool);
|
||||
|
|
|
@ -6,7 +6,6 @@ import type { CommonQueryMethods } from 'slonik';
|
|||
import { sql } from 'slonik';
|
||||
|
||||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Passcodes);
|
||||
|
@ -82,14 +81,3 @@ export const createPasscodeQueries = (pool: CommonQueryMethods) => {
|
|||
deletePasscodesByIds,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createPasscodeQueries() factory instead. */
|
||||
export const {
|
||||
findUnconsumedPasscodeByJtiAndType,
|
||||
findUnconsumedPasscodesByJtiAndType,
|
||||
insertPasscode,
|
||||
consumePasscode,
|
||||
increasePasscodeTryCount,
|
||||
deletePasscodeById,
|
||||
deletePasscodesByIds,
|
||||
} = createPasscodeQueries(envSet.pool);
|
||||
|
|
|
@ -9,7 +9,6 @@ import { buildFindEntityByIdWithPool } from '#src/database/find-entity-by-id.js'
|
|||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import { getTotalRowCountWithPool } from '#src/database/row-count.js';
|
||||
import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Resources);
|
||||
|
@ -80,16 +79,3 @@ export const createResourceQueries = (pool: CommonQueryMethods) => {
|
|||
deleteResourceById,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createResourceQueries() factory instead. */
|
||||
export const {
|
||||
findTotalNumberOfResources,
|
||||
findAllResources,
|
||||
findResourceByIndicator,
|
||||
findResourceById,
|
||||
findResourcesByIds,
|
||||
insertResource,
|
||||
updateResource,
|
||||
updateResourceById,
|
||||
deleteResourceById,
|
||||
} = createResourceQueries(envSet.pool);
|
||||
|
|
|
@ -4,7 +4,6 @@ import { convertToIdentifiers } from '@logto/shared';
|
|||
import type { CommonQueryMethods } from 'slonik';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(RolesScopes);
|
||||
|
@ -39,7 +38,3 @@ export const createRolesScopesQueries = (pool: CommonQueryMethods) => {
|
|||
|
||||
return { insertRolesScopes, findRolesScopesByRoleId, deleteRolesScope };
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createRolesScopesQueries() factory instead. */
|
||||
export const { insertRolesScopes, findRolesScopesByRoleId, deleteRolesScope } =
|
||||
createRolesScopesQueries(envSet.pool);
|
||||
|
|
|
@ -8,7 +8,6 @@ import { sql } from 'slonik';
|
|||
import { buildFindEntityByIdWithPool } from '#src/database/find-entity-by-id.js';
|
||||
import { buildInsertIntoWithPool } from '#src/database/insert-into.js';
|
||||
import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
import { DeletionError } from '#src/errors/SlonikError/index.js';
|
||||
import type { Search } from '#src/utils/search.js';
|
||||
import { buildConditionsFromSearch } from '#src/utils/search.js';
|
||||
|
@ -117,18 +116,3 @@ export const createScopeQueries = (pool: CommonQueryMethods) => {
|
|||
deleteScopeById,
|
||||
};
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createScopeQueries() factory instead. */
|
||||
export const {
|
||||
findScopes,
|
||||
countScopes,
|
||||
findScopeByNameAndResourceId,
|
||||
findScopesByResourceId,
|
||||
findScopesByResourceIds,
|
||||
findScopesByIds,
|
||||
insertScope,
|
||||
findScopeById,
|
||||
updateScope,
|
||||
updateScopeById,
|
||||
deleteScopeById,
|
||||
} = createScopeQueries(envSet.pool);
|
||||
|
|
|
@ -5,7 +5,6 @@ import type { CommonQueryMethods } from 'slonik';
|
|||
|
||||
import { buildFindEntityByIdWithPool } from '#src/database/find-entity-by-id.js';
|
||||
import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
|
||||
export const defaultSettingId = 'default';
|
||||
|
||||
|
@ -23,6 +22,3 @@ export const createSettingQueries = (pool: CommonQueryMethods) => {
|
|||
|
||||
return { getSetting, updateSetting };
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createSettingQueries() factory instead. */
|
||||
export const { getSetting, updateSetting } = createSettingQueries(envSet.pool);
|
||||
|
|
|
@ -4,7 +4,6 @@ import type { CommonQueryMethods } from 'slonik';
|
|||
|
||||
import { buildFindEntityByIdWithPool } from '#src/database/find-entity-by-id.js';
|
||||
import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||
import envSet from '#src/env-set/index.js';
|
||||
|
||||
const id = 'default';
|
||||
|
||||
|
@ -24,7 +23,3 @@ export const createSignInExperienceQueries = (pool: CommonQueryMethods) => {
|
|||
|
||||
return { updateDefaultSignInExperience, findDefaultSignInExperience };
|
||||
};
|
||||
|
||||
/** @deprecated Will be removed soon. Use createSignInExperienceQueries() factory instead. */
|
||||
export const { updateDefaultSignInExperience, findDefaultSignInExperience } =
|
||||
createSignInExperienceQueries(envSet.pool);
|
||||
|
|
|
@ -11,8 +11,9 @@ import { DeletionError } from '#src/errors/SlonikError/index.js';
|
|||
import type { Search } from '#src/utils/search.js';
|
||||
import { buildConditionsFromSearch } from '#src/utils/search.js';
|
||||
|
||||
import { findRoleByRoleName, findRolesByRoleIds } from './roles.js';
|
||||
import { findUsersRolesByRoleId, findUsersRolesByUserId } from './users-roles.js';
|
||||
// TODO: @sijie remove this
|
||||
import { findRolesByRoleIds } from './roles.js';
|
||||
import { findUsersRolesByUserId } from './users-roles.js';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Users);
|
||||
|
||||
|
@ -215,22 +216,6 @@ export const createUserQueries = (pool: CommonQueryMethods) => {
|
|||
group by date(${fields.createdAt})
|
||||
`);
|
||||
|
||||
const findUsersByRoleName = async (roleName: string) => {
|
||||
const role = await findRoleByRoleName(roleName);
|
||||
|
||||
if (!role) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const usersRoles = await findUsersRolesByRoleId(role.id);
|
||||
|
||||
if (usersRoles.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return findUsersByIds(usersRoles.map(({ userId }) => userId));
|
||||
};
|
||||
|
||||
return {
|
||||
findUserByUsername,
|
||||
findUserByEmail,
|
||||
|
@ -250,7 +235,6 @@ export const createUserQueries = (pool: CommonQueryMethods) => {
|
|||
deleteUserIdentity,
|
||||
hasActiveUsers,
|
||||
getDailyNewUserCountsByTimeInterval,
|
||||
findUsersByRoleName,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -274,5 +258,4 @@ export const {
|
|||
deleteUserIdentity,
|
||||
hasActiveUsers,
|
||||
getDailyNewUserCountsByTimeInterval,
|
||||
findUsersByRoleName,
|
||||
} = createUserQueries(envSet.pool);
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
import { pickDefault, createMockUtils } from '@logto/shared/esm';
|
||||
import { pickDefault } from '@logto/shared/esm';
|
||||
|
||||
import { mockRole, mockUser } from '#src/__mocks__/index.js';
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
|
||||
const { mockEsmWithActual } = createMockUtils(jest);
|
||||
const users = { findUserById: jest.fn() };
|
||||
|
||||
await mockEsmWithActual('#src/queries/user.js', () => ({
|
||||
findUserById: jest.fn(),
|
||||
}));
|
||||
const { findRolesByRoleIds } = await mockEsmWithActual('#src/queries/roles.js', () => ({
|
||||
const roles = {
|
||||
findRolesByRoleIds: jest.fn(),
|
||||
findRoleById: jest.fn(),
|
||||
}));
|
||||
const { findUsersRolesByUserId, insertUsersRoles, deleteUsersRolesByUserIdAndRoleId } =
|
||||
await mockEsmWithActual('#src/queries/users-roles.js', () => ({
|
||||
findUsersRolesByUserId: jest.fn(),
|
||||
insertUsersRoles: jest.fn(),
|
||||
deleteUsersRolesByUserIdAndRoleId: jest.fn(),
|
||||
}));
|
||||
};
|
||||
const { findRolesByRoleIds } = roles;
|
||||
|
||||
const usersRoles = {
|
||||
findUsersRolesByUserId: jest.fn(),
|
||||
insertUsersRoles: jest.fn(),
|
||||
deleteUsersRolesByUserIdAndRoleId: jest.fn(),
|
||||
};
|
||||
const { findUsersRolesByUserId, insertUsersRoles, deleteUsersRolesByUserIdAndRoleId } = usersRoles;
|
||||
|
||||
const tenantContext = new MockTenant(undefined, { usersRoles, users, roles });
|
||||
|
||||
const roleRoutes = await pickDefault(import('./admin-user-role.js'));
|
||||
|
||||
describe('user role routes', () => {
|
||||
const roleRequester = createRequester({ authedRoutes: roleRoutes });
|
||||
const roleRequester = createRequester({ authedRoutes: roleRoutes, tenantContext });
|
||||
|
||||
it('GET /users/:id/roles', async () => {
|
||||
findUsersRolesByUserId.mockResolvedValueOnce([]);
|
||||
|
|
|
@ -2,20 +2,19 @@ import { object, string } from 'zod';
|
|||
|
||||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import { findRolesByRoleIds, findRoleById } from '#src/queries/roles.js';
|
||||
import { findUserById } from '#src/queries/user.js';
|
||||
import {
|
||||
deleteUsersRolesByUserIdAndRoleId,
|
||||
findUsersRolesByUserId,
|
||||
insertUsersRoles,
|
||||
} from '#src/queries/users-roles.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
|
||||
import type { AuthedRouter, RouterInitArgs } from './types.js';
|
||||
|
||||
export default function adminUserRoleRoutes<T extends AuthedRouter>(
|
||||
...[router]: RouterInitArgs<T>
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const {
|
||||
roles: { findRolesByRoleIds, findRoleById },
|
||||
users: { findUserById },
|
||||
usersRoles: { deleteUsersRolesByUserIdAndRoleId, findUsersRolesByUserId, insertUsersRoles },
|
||||
} = queries;
|
||||
|
||||
router.get(
|
||||
'/users/:userId/roles',
|
||||
koaGuard({
|
||||
|
|
|
@ -30,12 +30,11 @@ export default function adminUserRoutes<T extends AuthedRouter>(
|
|||
updateUserById,
|
||||
hasUserWithEmail,
|
||||
hasUserWithPhone,
|
||||
findUsersByRoleName,
|
||||
},
|
||||
usersRoles: { deleteUsersRolesByUserIdAndRoleId, findUsersRolesByRoleId, insertUsersRoles },
|
||||
} = queries;
|
||||
const {
|
||||
users: { checkIdentifierCollision, generateUserId, insertUser },
|
||||
users: { checkIdentifierCollision, generateUserId, insertUser, findUsersByRoleName },
|
||||
} = libraries;
|
||||
|
||||
router.get('/users', koaPagination(), async (ctx, next) => {
|
||||
|
|
|
@ -3,32 +3,12 @@ import { ApplicationType } from '@logto/schemas';
|
|||
import { pickDefault, createMockUtils } from '@logto/shared/esm';
|
||||
|
||||
import { mockApplication } from '#src/__mocks__/index.js';
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
const { mockEsm, mockEsmWithActual } = createMockUtils(jest);
|
||||
const { mockEsmWithActual } = createMockUtils(jest);
|
||||
|
||||
const { findApplicationById } = await mockEsmWithActual('#src/queries/application.js', () => ({
|
||||
findTotalNumberOfApplications: jest.fn(async () => ({ count: 10 })),
|
||||
findAllApplications: jest.fn(async () => [mockApplication]),
|
||||
findApplicationById: jest.fn(async () => mockApplication),
|
||||
deleteApplicationById: jest.fn(),
|
||||
insertApplication: jest.fn(
|
||||
async (body: CreateApplication): Promise<Application> => ({
|
||||
...mockApplication,
|
||||
...body,
|
||||
oidcClientMetadata: {
|
||||
...mockApplication.oidcClientMetadata,
|
||||
...body.oidcClientMetadata,
|
||||
},
|
||||
})
|
||||
),
|
||||
updateApplicationById: jest.fn(
|
||||
async (_, data: Partial<CreateApplication>): Promise<Application> => ({
|
||||
...mockApplication,
|
||||
...data,
|
||||
})
|
||||
),
|
||||
}));
|
||||
const findApplicationById = jest.fn(async () => mockApplication);
|
||||
|
||||
await mockEsmWithActual('@logto/core-kit', () => ({
|
||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
|
@ -36,6 +16,31 @@ await mockEsmWithActual('@logto/core-kit', () => ({
|
|||
generateStandardId: () => 'randomId',
|
||||
}));
|
||||
|
||||
const tenantContext = new MockTenant(undefined, {
|
||||
applications: {
|
||||
findTotalNumberOfApplications: jest.fn(async () => ({ count: 10 })),
|
||||
findAllApplications: jest.fn(async () => [mockApplication]),
|
||||
findApplicationById,
|
||||
deleteApplicationById: jest.fn(),
|
||||
insertApplication: jest.fn(
|
||||
async (body: CreateApplication): Promise<Application> => ({
|
||||
...mockApplication,
|
||||
...body,
|
||||
oidcClientMetadata: {
|
||||
...mockApplication.oidcClientMetadata,
|
||||
...body.oidcClientMetadata,
|
||||
},
|
||||
})
|
||||
),
|
||||
updateApplicationById: jest.fn(
|
||||
async (_, data: Partial<CreateApplication>): Promise<Application> => ({
|
||||
...mockApplication,
|
||||
...data,
|
||||
})
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const { createRequester } = await import('#src/utils/test-utils.js');
|
||||
const applicationRoutes = await pickDefault(import('./application.js'));
|
||||
|
||||
|
@ -46,7 +51,7 @@ const customClientMetadata = {
|
|||
};
|
||||
|
||||
describe('application route', () => {
|
||||
const applicationRequest = createRequester({ authedRoutes: applicationRoutes });
|
||||
const applicationRequest = createRequester({ authedRoutes: applicationRoutes, tenantContext });
|
||||
|
||||
it('GET /applications', async () => {
|
||||
const response = await applicationRequest.get('/applications');
|
||||
|
|
|
@ -5,20 +5,23 @@ import { object, string } from 'zod';
|
|||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import koaPagination from '#src/middleware/koa-pagination.js';
|
||||
import { buildOidcClientMetadata } from '#src/oidc/utils.js';
|
||||
import {
|
||||
deleteApplicationById,
|
||||
findApplicationById,
|
||||
findAllApplications,
|
||||
insertApplication,
|
||||
updateApplicationById,
|
||||
findTotalNumberOfApplications,
|
||||
} from '#src/queries/application.js';
|
||||
|
||||
import type { AuthedRouter, RouterInitArgs } from './types.js';
|
||||
|
||||
const applicationId = buildIdGenerator(21);
|
||||
|
||||
export default function applicationRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
|
||||
export default function applicationRoutes<T extends AuthedRouter>(
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const {
|
||||
deleteApplicationById,
|
||||
findApplicationById,
|
||||
findAllApplications,
|
||||
insertApplication,
|
||||
updateApplicationById,
|
||||
findTotalNumberOfApplications,
|
||||
} = queries.applications;
|
||||
|
||||
router.get('/applications', koaPagination(), async (ctx, next) => {
|
||||
const { limit, offset } = ctx.pagination;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { pickDefault, createMockUtils } from '@logto/shared/esm';
|
|||
import { mockZhCnCustomPhrase, trTrTag, zhCnTag } from '#src/__mocks__/custom-phrase.js';
|
||||
import { mockSignInExperience } from '#src/__mocks__/index.js';
|
||||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
|
@ -16,12 +17,7 @@ const mockCustomPhrases: Record<string, CustomPhrase> = {
|
|||
[mockLanguageTag]: mockPhrase,
|
||||
};
|
||||
|
||||
const {
|
||||
deleteCustomPhraseByLanguageTag,
|
||||
findAllCustomPhrases,
|
||||
findCustomPhraseByLanguageTag,
|
||||
upsertCustomPhrase,
|
||||
} = mockEsm('#src/queries/custom-phrase.js', () => ({
|
||||
const customPhrases = {
|
||||
deleteCustomPhraseByLanguageTag: jest.fn(async (languageTag: string) => {
|
||||
if (!mockCustomPhrases[languageTag]) {
|
||||
throw new RequestError({ code: 'entity.not_found', status: 404 });
|
||||
|
@ -38,15 +34,15 @@ const {
|
|||
return mockCustomPhrase;
|
||||
}),
|
||||
upsertCustomPhrase: jest.fn(async () => mockPhrase),
|
||||
}));
|
||||
};
|
||||
const {
|
||||
deleteCustomPhraseByLanguageTag,
|
||||
findAllCustomPhrases,
|
||||
findCustomPhraseByLanguageTag,
|
||||
upsertCustomPhrase,
|
||||
} = customPhrases;
|
||||
|
||||
const { isStrictlyPartial } = mockEsm('#src/utils/translation.js', () => ({
|
||||
isStrictlyPartial: jest.fn(() => true),
|
||||
}));
|
||||
|
||||
const mockFallbackLanguage = trTrTag;
|
||||
|
||||
mockEsm('#src/queries/sign-in-experience.js', () => ({
|
||||
const signInExperiences = {
|
||||
findDefaultSignInExperience: jest.fn(
|
||||
async (): Promise<SignInExperience> => ({
|
||||
...mockSignInExperience,
|
||||
|
@ -56,10 +52,18 @@ mockEsm('#src/queries/sign-in-experience.js', () => ({
|
|||
},
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
const { isStrictlyPartial } = mockEsm('#src/utils/translation.js', () => ({
|
||||
isStrictlyPartial: jest.fn(() => true),
|
||||
}));
|
||||
|
||||
const mockFallbackLanguage = trTrTag;
|
||||
|
||||
const tenantContext = new MockTenant(undefined, { customPhrases, signInExperiences });
|
||||
|
||||
const customPhraseRoutes = await pickDefault(import('./custom-phrase.js'));
|
||||
const customPhraseRequest = createRequester({ authedRoutes: customPhraseRoutes });
|
||||
const customPhraseRequest = createRequester({ authedRoutes: customPhraseRoutes, tenantContext });
|
||||
|
||||
describe('customPhraseRoutes', () => {
|
||||
afterEach(() => {
|
||||
|
|
|
@ -7,13 +7,6 @@ import { object } from 'zod';
|
|||
|
||||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import {
|
||||
deleteCustomPhraseByLanguageTag,
|
||||
findAllCustomPhrases,
|
||||
findCustomPhraseByLanguageTag,
|
||||
upsertCustomPhrase,
|
||||
} from '#src/queries/custom-phrase.js';
|
||||
import { findDefaultSignInExperience } from '#src/queries/sign-in-experience.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
import { isStrictlyPartial } from '#src/utils/translation.js';
|
||||
|
||||
|
@ -24,7 +17,19 @@ const cleanDeepTranslation = (translation: Translation) =>
|
|||
// eslint-disable-next-line no-restricted-syntax
|
||||
cleanDeep(translation) as Translation;
|
||||
|
||||
export default function customPhraseRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
|
||||
export default function customPhraseRoutes<T extends AuthedRouter>(
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const {
|
||||
customPhrases: {
|
||||
deleteCustomPhraseByLanguageTag,
|
||||
findAllCustomPhrases,
|
||||
findCustomPhraseByLanguageTag,
|
||||
upsertCustomPhrase,
|
||||
},
|
||||
signInExperiences: { findDefaultSignInExperience },
|
||||
} = queries;
|
||||
|
||||
router.get(
|
||||
'/custom-phrases',
|
||||
koaGuard({
|
||||
|
|
|
@ -1,24 +1,18 @@
|
|||
// The FP version works better for `format()`
|
||||
/* eslint-disable import/no-duplicates */
|
||||
import { pickDefault } from '@logto/shared/esm';
|
||||
import { createMockUtils } from '@logto/shared/esm';
|
||||
import { endOfDay, subDays } from 'date-fns';
|
||||
import { format } from 'date-fns/fp';
|
||||
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
/* eslint-enable import/no-duplicates */
|
||||
|
||||
const { jest } = import.meta;
|
||||
const { mockEsm } = createMockUtils(jest);
|
||||
|
||||
const totalUserCount = 1000;
|
||||
const formatToQueryDate = format('yyyy-MM-dd');
|
||||
|
||||
const { countUsers, getDailyNewUserCountsByTimeInterval } = mockEsm('#src/queries/user.js', () => ({
|
||||
countUsers: jest.fn(async () => ({ count: totalUserCount })),
|
||||
getDailyNewUserCountsByTimeInterval: jest.fn(async () => mockDailyNewUserCounts),
|
||||
}));
|
||||
|
||||
const mockDailyNewUserCounts = [
|
||||
{ date: '2022-05-01', count: 1 },
|
||||
{ date: '2022-05-02', count: 2 },
|
||||
|
@ -41,17 +35,23 @@ const mockDailyActiveUserCounts = [
|
|||
|
||||
const mockActiveUserCount = 1000;
|
||||
|
||||
const { getDailyActiveUserCountsByTimeInterval, countActiveUsersByTimeInterval } = mockEsm(
|
||||
'#src/queries/log.js',
|
||||
() => ({
|
||||
getDailyActiveUserCountsByTimeInterval: jest.fn().mockResolvedValue(mockDailyActiveUserCounts),
|
||||
countActiveUsersByTimeInterval: jest.fn().mockResolvedValue({ count: mockActiveUserCount }),
|
||||
})
|
||||
);
|
||||
const users = {
|
||||
countUsers: jest.fn(async () => ({ count: totalUserCount })),
|
||||
getDailyNewUserCountsByTimeInterval: jest.fn(async () => mockDailyNewUserCounts),
|
||||
};
|
||||
const { countUsers, getDailyNewUserCountsByTimeInterval } = users;
|
||||
|
||||
const logs = {
|
||||
getDailyActiveUserCountsByTimeInterval: jest.fn().mockResolvedValue(mockDailyActiveUserCounts),
|
||||
countActiveUsersByTimeInterval: jest.fn().mockResolvedValue({ count: mockActiveUserCount }),
|
||||
};
|
||||
const { getDailyActiveUserCountsByTimeInterval, countActiveUsersByTimeInterval } = logs;
|
||||
|
||||
const tenantContext = new MockTenant(undefined, { logs, users });
|
||||
const dashboardRoutes = await pickDefault(import('./dashboard.js'));
|
||||
|
||||
describe('dashboardRoutes', () => {
|
||||
const logRequest = createRequester({ authedRoutes: dashboardRoutes });
|
||||
const logRequest = createRequester({ authedRoutes: dashboardRoutes, tenantContext });
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
|
|
@ -3,11 +3,6 @@ import { endOfDay, format, subDays } from 'date-fns';
|
|||
import { object, string } from 'zod';
|
||||
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import {
|
||||
countActiveUsersByTimeInterval,
|
||||
getDailyActiveUserCountsByTimeInterval,
|
||||
} from '#src/queries/log.js';
|
||||
import { countUsers, getDailyNewUserCountsByTimeInterval } from '#src/queries/user.js';
|
||||
|
||||
import type { AuthedRouter, RouterInitArgs } from './types.js';
|
||||
|
||||
|
@ -17,7 +12,14 @@ const indices = (length: number) => [...Array.from({ length }).keys()];
|
|||
|
||||
const getEndOfDayTimestamp = (date: Date | number) => endOfDay(date).valueOf();
|
||||
|
||||
export default function dashboardRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
|
||||
export default function dashboardRoutes<T extends AuthedRouter>(
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const {
|
||||
logs: { countActiveUsersByTimeInterval, getDailyActiveUserCountsByTimeInterval },
|
||||
users: { countUsers, getDailyNewUserCountsByTimeInterval },
|
||||
} = queries;
|
||||
|
||||
router.get('/dashboard/users/total', async (ctx, next) => {
|
||||
const { count: totalUserCount } = await countUsers();
|
||||
ctx.body = { totalUserCount };
|
||||
|
|
|
@ -1,27 +1,31 @@
|
|||
import { LogResult } from '@logto/schemas';
|
||||
import type { Log } from '@logto/schemas';
|
||||
import { pickDefault, createMockUtils } from '@logto/shared/esm';
|
||||
import { pickDefault } from '@logto/shared/esm';
|
||||
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
const { mockEsm } = createMockUtils(jest);
|
||||
|
||||
const mockBody = { key: 'a', payload: { key: 'a', result: LogResult.Success }, createdAt: 123 };
|
||||
const mockLog: Log = { id: '1', ...mockBody };
|
||||
const mockLogs = [mockLog, { id: '2', ...mockBody }];
|
||||
|
||||
const { countLogs, findLogs, findLogById } = mockEsm('#src/queries/log.js', () => ({
|
||||
const logs = {
|
||||
countLogs: jest.fn().mockResolvedValue({
|
||||
count: mockLogs.length,
|
||||
}),
|
||||
findLogs: jest.fn().mockResolvedValue(mockLogs),
|
||||
findLogById: jest.fn().mockResolvedValue(mockLog),
|
||||
}));
|
||||
};
|
||||
const { countLogs, findLogs, findLogById } = logs;
|
||||
const logRoutes = await pickDefault(import('./log.js'));
|
||||
|
||||
describe('logRoutes', () => {
|
||||
const logRequest = createRequester({ authedRoutes: logRoutes });
|
||||
const logRequest = createRequester({
|
||||
authedRoutes: logRoutes,
|
||||
tenantContext: new MockTenant(undefined, { logs }),
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
|
|
@ -3,11 +3,14 @@ import { object, string } from 'zod';
|
|||
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import koaPagination from '#src/middleware/koa-pagination.js';
|
||||
import { countLogs, findLogById, findLogs } from '#src/queries/log.js';
|
||||
|
||||
import type { AuthedRouter, RouterInitArgs } from './types.js';
|
||||
|
||||
export default function logRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
|
||||
export default function logRoutes<T extends AuthedRouter>(
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const { countLogs, findLogById, findLogs } = queries.logs;
|
||||
|
||||
router.get(
|
||||
'/logs',
|
||||
koaPagination(),
|
||||
|
|
|
@ -1,68 +1,82 @@
|
|||
import type { Role } from '@logto/schemas';
|
||||
import { pickDefault, createMockUtils } from '@logto/shared/esm';
|
||||
import { pickDefault } from '@logto/shared/esm';
|
||||
|
||||
import { mockRole, mockScope, mockUser, mockResource } from '#src/__mocks__/index.js';
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
|
||||
const { mockEsm, mockEsmWithActual } = createMockUtils(jest);
|
||||
const roles = {
|
||||
findRoles: jest.fn(async (): Promise<Role[]> => [mockRole]),
|
||||
countRoles: jest.fn(async () => ({ count: 10 })),
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
findRoleByRoleName: jest.fn(async (): Promise<Role | null> => null),
|
||||
insertRole: jest.fn(async (data) => ({
|
||||
...data,
|
||||
id: mockRole.id,
|
||||
})),
|
||||
deleteRoleById: jest.fn(),
|
||||
findRoleById: jest.fn(),
|
||||
updateRoleById: jest.fn(async (id, data) => ({
|
||||
...mockRole,
|
||||
...data,
|
||||
})),
|
||||
findRolesByRoleIds: jest.fn(),
|
||||
};
|
||||
const { findRoleByRoleName, findRoleById, deleteRoleById } = roles;
|
||||
|
||||
const { findRoleByRoleName, findRoleById, deleteRoleById } = mockEsm(
|
||||
'#src/queries/roles.js',
|
||||
() => ({
|
||||
findRoles: jest.fn(async (): Promise<Role[]> => [mockRole]),
|
||||
countRoles: jest.fn(async () => ({ count: 10 })),
|
||||
findRoleByRoleName: jest.fn(async (): Promise<Role | undefined> => undefined),
|
||||
insertRole: jest.fn(async (data) => ({
|
||||
...data,
|
||||
id: mockRole.id,
|
||||
})),
|
||||
deleteRoleById: jest.fn(),
|
||||
findRoleById: jest.fn(),
|
||||
updateRoleById: jest.fn(async (id, data) => ({
|
||||
...mockRole,
|
||||
...data,
|
||||
})),
|
||||
findRolesByRoleIds: jest.fn(),
|
||||
})
|
||||
);
|
||||
const { findScopeById, findScopesByIds } = await mockEsmWithActual('#src/queries/scope.js', () => ({
|
||||
const scopes = {
|
||||
findScopeById: jest.fn(),
|
||||
findScopesByIds: jest.fn(),
|
||||
}));
|
||||
await mockEsmWithActual('#src/queries/resource.js', () => ({
|
||||
};
|
||||
const { findScopeById, findScopesByIds } = scopes;
|
||||
|
||||
const resources = {
|
||||
findResourcesByIds: jest.fn(async () => [mockResource]),
|
||||
}));
|
||||
const { insertRolesScopes, findRolesScopesByRoleId } = await mockEsmWithActual(
|
||||
'#src/queries/roles-scopes.js',
|
||||
() => ({
|
||||
insertRolesScopes: jest.fn(),
|
||||
findRolesScopesByRoleId: jest.fn(),
|
||||
deleteRolesScope: jest.fn(),
|
||||
})
|
||||
);
|
||||
const { findUsersByIds } = await mockEsmWithActual('#src/queries/user.js', () => ({
|
||||
};
|
||||
|
||||
const rolesScopes = {
|
||||
insertRolesScopes: jest.fn(),
|
||||
findRolesScopesByRoleId: jest.fn(),
|
||||
deleteRolesScope: jest.fn(),
|
||||
};
|
||||
const { insertRolesScopes, findRolesScopesByRoleId } = rolesScopes;
|
||||
|
||||
const users = {
|
||||
findUsersByIds: jest.fn(),
|
||||
findUserById: jest.fn(),
|
||||
}));
|
||||
};
|
||||
const { findUsersByIds } = users;
|
||||
|
||||
const usersRoles = {
|
||||
insertUsersRoles: jest.fn(),
|
||||
countUsersRolesByRoleId: jest.fn(),
|
||||
findUsersRolesByRoleId: jest.fn(),
|
||||
findFirstUsersRolesByRoleIdAndUserIds: jest.fn(),
|
||||
deleteUsersRolesByUserIdAndRoleId: jest.fn(),
|
||||
};
|
||||
const {
|
||||
insertUsersRoles,
|
||||
findUsersRolesByRoleId,
|
||||
deleteUsersRolesByUserIdAndRoleId,
|
||||
findFirstUsersRolesByRoleIdAndUserIds,
|
||||
countUsersRolesByRoleId,
|
||||
} = await mockEsmWithActual('#src/queries/users-roles.js', () => ({
|
||||
insertUsersRoles: jest.fn(),
|
||||
countUsersRolesByRoleId: jest.fn(),
|
||||
findUsersRolesByRoleId: jest.fn(),
|
||||
findFirstUsersRolesByRoleIdAndUserIds: jest.fn(),
|
||||
deleteUsersRolesByUserIdAndRoleId: jest.fn(),
|
||||
}));
|
||||
} = usersRoles;
|
||||
|
||||
const roleRoutes = await pickDefault(import('./role.js'));
|
||||
|
||||
const tenantContext = new MockTenant(undefined, {
|
||||
usersRoles,
|
||||
users,
|
||||
rolesScopes,
|
||||
resources,
|
||||
scopes,
|
||||
roles,
|
||||
});
|
||||
|
||||
describe('role routes', () => {
|
||||
const roleRequester = createRequester({ authedRoutes: roleRoutes });
|
||||
const roleRequester = createRequester({ authedRoutes: roleRoutes, tenantContext });
|
||||
|
||||
it('GET /roles?page=1', async () => {
|
||||
countUsersRolesByRoleId.mockResolvedValueOnce({ count: 1 });
|
||||
|
|
|
@ -8,31 +8,6 @@ import { object, string, z } from 'zod';
|
|||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import koaPagination from '#src/middleware/koa-pagination.js';
|
||||
import { findResourcesByIds } from '#src/queries/resource.js';
|
||||
import {
|
||||
deleteRolesScope,
|
||||
findRolesScopesByRoleId,
|
||||
insertRolesScopes,
|
||||
} from '#src/queries/roles-scopes.js';
|
||||
import {
|
||||
countRoles,
|
||||
deleteRoleById,
|
||||
findRoleById,
|
||||
findRoleByRoleName,
|
||||
findRoles,
|
||||
insertRole,
|
||||
updateRoleById,
|
||||
} from '#src/queries/roles.js';
|
||||
import { findScopeById, findScopesByIds } from '#src/queries/scope.js';
|
||||
import { findUserById, findUsersByIds } from '#src/queries/user.js';
|
||||
import {
|
||||
countUsersRolesByRoleId,
|
||||
deleteUsersRolesByUserIdAndRoleId,
|
||||
findFirstUsersRolesByRoleIdAndUserIds,
|
||||
findUsersRolesByRoleId,
|
||||
findUsersRolesByUserId,
|
||||
insertUsersRoles,
|
||||
} from '#src/queries/users-roles.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
import { parseSearchParamsForSearch } from '#src/utils/search.js';
|
||||
|
||||
|
@ -40,7 +15,33 @@ import type { AuthedRouter, RouterInitArgs } from './types.js';
|
|||
|
||||
const roleId = buildIdGenerator(21);
|
||||
|
||||
export default function roleRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
|
||||
export default function roleRoutes<T extends AuthedRouter>(
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const {
|
||||
resources: { findResourcesByIds },
|
||||
rolesScopes: { deleteRolesScope, findRolesScopesByRoleId, insertRolesScopes },
|
||||
roles: {
|
||||
countRoles,
|
||||
deleteRoleById,
|
||||
findRoleById,
|
||||
findRoleByRoleName,
|
||||
findRoles,
|
||||
insertRole,
|
||||
updateRoleById,
|
||||
},
|
||||
scopes: { findScopeById, findScopesByIds },
|
||||
users: { findUserById, findUsersByIds },
|
||||
usersRoles: {
|
||||
countUsersRolesByRoleId,
|
||||
deleteUsersRolesByUserIdAndRoleId,
|
||||
findFirstUsersRolesByRoleIdAndUserIds,
|
||||
findUsersRolesByRoleId,
|
||||
findUsersRolesByUserId,
|
||||
insertUsersRoles,
|
||||
},
|
||||
} = queries;
|
||||
|
||||
router.get('/roles', koaPagination({ isOptional: true }), async (ctx, next) => {
|
||||
const { limit, offset, disabled } = ctx.pagination;
|
||||
const { searchParams } = ctx.request.URL;
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
import type { Setting, CreateSetting } from '@logto/schemas';
|
||||
import { pickDefault, createMockUtils } from '@logto/shared/esm';
|
||||
import { pickDefault } from '@logto/shared/esm';
|
||||
|
||||
import { mockSetting } from '#src/__mocks__/index.js';
|
||||
import { MockTenant } from '#src/test-utils/tenant.js';
|
||||
import { createRequester } from '#src/utils/test-utils.js';
|
||||
|
||||
const { mockEsm } = createMockUtils(import.meta.jest);
|
||||
|
||||
mockEsm('#src/queries/setting.js', () => ({
|
||||
const settings = {
|
||||
getSetting: async (): Promise<Setting> => mockSetting,
|
||||
updateSetting: async (data: Partial<CreateSetting>): Promise<Setting> => ({
|
||||
...mockSetting,
|
||||
...data,
|
||||
}),
|
||||
}));
|
||||
};
|
||||
|
||||
const settingRoutes = await pickDefault(import('./setting.js'));
|
||||
|
||||
describe('settings routes', () => {
|
||||
const roleRequester = createRequester({ authedRoutes: settingRoutes });
|
||||
const roleRequester = createRequester({
|
||||
authedRoutes: settingRoutes,
|
||||
tenantContext: new MockTenant(undefined, { settings }),
|
||||
});
|
||||
|
||||
it('GET /settings', async () => {
|
||||
const response = await roleRequester.get('/settings');
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { Settings } from '@logto/schemas';
|
||||
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import { getSetting, updateSetting } from '#src/queries/setting.js';
|
||||
|
||||
import type { AuthedRouter, RouterInitArgs } from './types.js';
|
||||
|
||||
export default function settingRoutes<T extends AuthedRouter>(...[router]: RouterInitArgs<T>) {
|
||||
export default function settingRoutes<T extends AuthedRouter>(
|
||||
...[router, { queries }]: RouterInitArgs<T>
|
||||
) {
|
||||
const { getSetting, updateSetting } = queries.settings;
|
||||
|
||||
router.get('/settings', async (ctx, next) => {
|
||||
const { id, ...rest } = await getSetting();
|
||||
ctx.body = rest;
|
||||
|
|
|
@ -73,7 +73,10 @@ export default class Tenant implements TenantContext {
|
|||
app.use(
|
||||
mount(
|
||||
'/' + MountedApps.DemoApp,
|
||||
compose([koaCheckDemoApp(), koaSpaProxy(MountedApps.DemoApp, 5003, MountedApps.DemoApp)])
|
||||
compose([
|
||||
koaCheckDemoApp(this.queries),
|
||||
koaSpaProxy(MountedApps.DemoApp, 5003, MountedApps.DemoApp),
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue