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

View File

@@ -231,61 +231,4 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
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 };
}
});
};

View File

@@ -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 };
}
});
};

View File

@@ -1,3 +1,4 @@
import { registerGroupProjectRouter } from "./group-project-router";
import { registerLoginRouter } from "./login-router";
import { registerSecretBlindIndexRouter } from "./secret-blind-index-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(registerUserRouter, { prefix: "/users" });
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" }
);
};

View File

@@ -10,13 +10,13 @@ export type TGroupProjectDALFactory = ReturnType<typeof groupProjectDALFactory>;
export const groupProjectDALFactory = (db: TDbClient) => {
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 {
const docs = await (tx || db.replicaNode())(TableName.GroupProjectMembership)
.where(`${TableName.GroupProjectMembership}.projectId`, projectId)
.where((qb) => {
if (filter?.groupSlug) {
void qb.where(`${TableName.Groups}.slug`, "=", filter.groupSlug);
if (filter?.groupId) {
void qb.where(`${TableName.Groups}.id`, "=", filter.groupId);
}
})
.join(TableName.Groups, `${TableName.GroupProjectMembership}.groupId`, `${TableName.Groups}.id`)

View File

@@ -34,7 +34,7 @@ type TGroupProjectServiceFactoryDep = {
"create" | "transaction" | "insertMany" | "delete"
>;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findGroupMembersNotInProject">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "findProjectGhostUser" | "findById">;
projectKeyDAL: Pick<TProjectKeyDALFactory, "findLatestProjectKey" | "delete" | "insertMany" | "transaction">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
projectBotDAL: TProjectBotDALFactory;
@@ -403,19 +403,17 @@ export const groupProjectServiceFactory = ({
};
const getGroupInProject = async ({
projectSlug,
actor,
actorId,
actorAuthMethod,
actorOrgId,
groupSlug
groupId,
projectId
}: TGetGroupInProjectDTO) => {
const project = await projectDAL.findOne({
slug: projectSlug
});
const project = await projectDAL.findById(projectId);
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(
@@ -428,7 +426,7 @@ export const groupProjectServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Groups);
const [groupMembership] = await groupProjectDAL.findByProjectId(project.id, {
groupSlug
groupId
});
if (!groupMembership) {

View File

@@ -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";
@@ -42,4 +42,4 @@ export type TDeleteProjectGroupDTO = {
export type TListProjectGroupDTO = TProjectSlugPermission;
export type TGetGroupInProjectDTO = TProjectSlugPermission & { groupSlug: string };
export type TGetGroupInProjectDTO = TProjectPermission & { groupId: string };