misc: moved to group project v3 for get with ID based

This commit is contained in:
Sheen Capadngan
2024-09-22 19:46:36 +08:00
parent 8d71b295ea
commit 02111c2dc2
6 changed files with 84 additions and 71 deletions
@@ -231,61 +231,4 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
return { groupMemberships }; return { groupMemberships };
} }
}); });
server.route({
method: "GET",
url: "/:projectSlug/groups/:groupSlug",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
config: {
rateLimit: readLimit
},
schema: {
description: "Return project group",
security: [
{
bearerAuth: []
}
],
params: z.object({
projectSlug: z.string().trim(),
groupSlug: z.string().trim()
}),
response: {
200: z.object({
groupMembership: z.object({
id: z.string(),
groupId: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
roles: z.array(
z.object({
id: z.string(),
role: z.string(),
customRoleId: z.string().optional().nullable(),
customRoleName: z.string().optional().nullable(),
customRoleSlug: z.string().optional().nullable(),
isTemporary: z.boolean(),
temporaryMode: z.string().optional().nullable(),
temporaryRange: z.string().nullable().optional(),
temporaryAccessStartTime: z.date().nullable().optional(),
temporaryAccessEndTime: z.date().nullable().optional()
})
),
group: GroupsSchema.pick({ name: true, id: true, slug: true })
})
})
}
},
handler: async (req) => {
const groupMembership = await server.services.groupProject.getGroupInProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
...req.params
});
return { groupMembership };
}
});
}; };
@@ -0,0 +1,65 @@
import { z } from "zod";
import { GroupsSchema } from "@app/db/schemas";
import { readLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
export const registerGroupProjectRouter = async (server: FastifyZodProvider) => {
server.route({
method: "GET",
url: "/:projectId/groups/:groupId",
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
config: {
rateLimit: readLimit
},
schema: {
description: "Return project group",
security: [
{
bearerAuth: []
}
],
params: z.object({
projectId: z.string().trim(),
groupId: z.string().trim()
}),
response: {
200: z.object({
groupMembership: z.object({
id: z.string(),
groupId: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
roles: z.array(
z.object({
id: z.string(),
role: z.string(),
customRoleId: z.string().optional().nullable(),
customRoleName: z.string().optional().nullable(),
customRoleSlug: z.string().optional().nullable(),
isTemporary: z.boolean(),
temporaryMode: z.string().optional().nullable(),
temporaryRange: z.string().nullable().optional(),
temporaryAccessStartTime: z.date().nullable().optional(),
temporaryAccessEndTime: z.date().nullable().optional()
})
),
group: GroupsSchema.pick({ name: true, id: true, slug: true })
})
})
}
},
handler: async (req) => {
const groupMembership = await server.services.groupProject.getGroupInProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
...req.params
});
return { groupMembership };
}
});
};
+8 -1
View File
@@ -1,3 +1,4 @@
import { registerGroupProjectRouter } from "./group-project-router";
import { registerLoginRouter } from "./login-router"; import { registerLoginRouter } from "./login-router";
import { registerSecretBlindIndexRouter } from "./secret-blind-index-router"; import { registerSecretBlindIndexRouter } from "./secret-blind-index-router";
import { registerSecretRouter } from "./secret-router"; import { registerSecretRouter } from "./secret-router";
@@ -9,5 +10,11 @@ export const registerV3Routes = async (server: FastifyZodProvider) => {
await server.register(registerLoginRouter, { prefix: "/auth" }); await server.register(registerLoginRouter, { prefix: "/auth" });
await server.register(registerUserRouter, { prefix: "/users" }); await server.register(registerUserRouter, { prefix: "/users" });
await server.register(registerSecretRouter, { prefix: "/secrets" }); await server.register(registerSecretRouter, { prefix: "/secrets" });
await server.register(registerSecretBlindIndexRouter, { prefix: "/workspaces" }); await server.register(
async (projectServer) => {
await projectServer.register(registerSecretBlindIndexRouter);
await projectServer.register(registerGroupProjectRouter);
},
{ prefix: "/workspaces" }
);
}; };
@@ -10,13 +10,13 @@ export type TGroupProjectDALFactory = ReturnType<typeof groupProjectDALFactory>;
export const groupProjectDALFactory = (db: TDbClient) => { export const groupProjectDALFactory = (db: TDbClient) => {
const groupProjectOrm = ormify(db, TableName.GroupProjectMembership); const groupProjectOrm = ormify(db, TableName.GroupProjectMembership);
const findByProjectId = async (projectId: string, filter?: { groupSlug?: string }, tx?: Knex) => { const findByProjectId = async (projectId: string, filter?: { groupId?: string }, tx?: Knex) => {
try { try {
const docs = await (tx || db.replicaNode())(TableName.GroupProjectMembership) const docs = await (tx || db.replicaNode())(TableName.GroupProjectMembership)
.where(`${TableName.GroupProjectMembership}.projectId`, projectId) .where(`${TableName.GroupProjectMembership}.projectId`, projectId)
.where((qb) => { .where((qb) => {
if (filter?.groupSlug) { if (filter?.groupId) {
void qb.where(`${TableName.Groups}.slug`, "=", filter.groupSlug); void qb.where(`${TableName.Groups}.id`, "=", filter.groupId);
} }
}) })
.join(TableName.Groups, `${TableName.GroupProjectMembership}.groupId`, `${TableName.Groups}.id`) .join(TableName.Groups, `${TableName.GroupProjectMembership}.groupId`, `${TableName.Groups}.id`)
@@ -34,7 +34,7 @@ type TGroupProjectServiceFactoryDep = {
"create" | "transaction" | "insertMany" | "delete" "create" | "transaction" | "insertMany" | "delete"
>; >;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembersNotInProject">; userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembersNotInProject">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser">; projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser" | "findById">;
projectKeyDAL: Pick<TProjectKeyDALFactory, "findLatestProjectKey" | "delete" | "insertMany" | "transaction">; projectKeyDAL: Pick<TProjectKeyDALFactory, "findLatestProjectKey" | "delete" | "insertMany" | "transaction">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">; projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
projectBotDAL: TProjectBotDALFactory; projectBotDAL: TProjectBotDALFactory;
@@ -403,19 +403,17 @@ export const groupProjectServiceFactory = ({
}; };
const getGroupInProject = async ({ const getGroupInProject = async ({
projectSlug,
actor, actor,
actorId, actorId,
actorAuthMethod, actorAuthMethod,
actorOrgId, actorOrgId,
groupSlug groupId,
projectId
}: TGetGroupInProjectDTO) => { }: TGetGroupInProjectDTO) => {
const project = await projectDAL.findOne({ const project = await projectDAL.findById(projectId);
slug: projectSlug
});
if (!project) { if (!project) {
throw new NotFoundError({ message: `Failed to find project with slug ${projectSlug}` }); throw new NotFoundError({ message: `Failed to find project with ID ${projectId}` });
} }
const { permission } = await permissionService.getProjectPermission( const { permission } = await permissionService.getProjectPermission(
@@ -428,7 +426,7 @@ export const groupProjectServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Groups); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Groups);
const [groupMembership] = await groupProjectDAL.findByProjectId(project.id, { const [groupMembership] = await groupProjectDAL.findByProjectId(project.id, {
groupSlug groupId
}); });
if (!groupMembership) { if (!groupMembership) {
@@ -1,4 +1,4 @@
import { TProjectSlugPermission } from "@app/lib/types"; import { TProjectPermission, TProjectSlugPermission } from "@app/lib/types";
import { ProjectUserMembershipTemporaryMode } from "../project-membership/project-membership-types"; import { ProjectUserMembershipTemporaryMode } from "../project-membership/project-membership-types";
@@ -42,4 +42,4 @@ export type TDeleteProjectGroupDTO = {
export type TListProjectGroupDTO = TProjectSlugPermission; export type TListProjectGroupDTO = TProjectSlugPermission;
export type TGetGroupInProjectDTO = TProjectSlugPermission & { groupSlug: string }; export type TGetGroupInProjectDTO = TProjectPermission & { groupId: string };