mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-30 14:36:46 +00:00
support multi role on create user and invites
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { db } from "@server/db";
|
||||
import { userInvites, roles } from "@server/db";
|
||||
import { userInvites, userInviteRoles, roles } from "@server/db";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import { sql } from "drizzle-orm";
|
||||
import { sql, eq, and, inArray } from "drizzle-orm";
|
||||
import logger from "@server/logger";
|
||||
import { fromZodError } from "zod-validation-error";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
@@ -29,24 +29,66 @@ const listInvitationsQuerySchema = z.strictObject({
|
||||
.pipe(z.int().nonnegative())
|
||||
});
|
||||
|
||||
async function queryInvitations(orgId: string, limit: number, offset: number) {
|
||||
return await db
|
||||
export type InvitationListRow = {
|
||||
inviteId: string;
|
||||
email: string;
|
||||
expiresAt: number;
|
||||
roles: { roleId: number; roleName: string | null }[];
|
||||
};
|
||||
|
||||
async function queryInvitations(
|
||||
orgId: string,
|
||||
limit: number,
|
||||
offset: number
|
||||
): Promise<InvitationListRow[]> {
|
||||
const inviteRows = await db
|
||||
.select({
|
||||
inviteId: userInvites.inviteId,
|
||||
email: userInvites.email,
|
||||
expiresAt: userInvites.expiresAt,
|
||||
roleId: userInvites.roleId,
|
||||
roleName: roles.name
|
||||
expiresAt: userInvites.expiresAt
|
||||
})
|
||||
.from(userInvites)
|
||||
.leftJoin(roles, sql`${userInvites.roleId} = ${roles.roleId}`)
|
||||
.where(sql`${userInvites.orgId} = ${orgId}`)
|
||||
.where(eq(userInvites.orgId, orgId))
|
||||
.limit(limit)
|
||||
.offset(offset);
|
||||
|
||||
if (inviteRows.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const inviteIds = inviteRows.map((r) => r.inviteId);
|
||||
const roleRows = await db
|
||||
.select({
|
||||
inviteId: userInviteRoles.inviteId,
|
||||
roleId: userInviteRoles.roleId,
|
||||
roleName: roles.name
|
||||
})
|
||||
.from(userInviteRoles)
|
||||
.innerJoin(roles, eq(userInviteRoles.roleId, roles.roleId))
|
||||
.where(
|
||||
and(eq(roles.orgId, orgId), inArray(userInviteRoles.inviteId, inviteIds))
|
||||
);
|
||||
|
||||
const rolesByInvite = new Map<
|
||||
string,
|
||||
{ roleId: number; roleName: string | null }[]
|
||||
>();
|
||||
for (const row of roleRows) {
|
||||
const list = rolesByInvite.get(row.inviteId) ?? [];
|
||||
list.push({ roleId: row.roleId, roleName: row.roleName });
|
||||
rolesByInvite.set(row.inviteId, list);
|
||||
}
|
||||
|
||||
return inviteRows.map((inv) => ({
|
||||
inviteId: inv.inviteId,
|
||||
email: inv.email,
|
||||
expiresAt: inv.expiresAt,
|
||||
roles: rolesByInvite.get(inv.inviteId) ?? []
|
||||
}));
|
||||
}
|
||||
|
||||
export type ListInvitationsResponse = {
|
||||
invitations: NonNullable<Awaited<ReturnType<typeof queryInvitations>>>;
|
||||
invitations: InvitationListRow[];
|
||||
pagination: { total: number; limit: number; offset: number };
|
||||
};
|
||||
|
||||
@@ -95,7 +137,7 @@ export async function listInvitations(
|
||||
const [{ count }] = await db
|
||||
.select({ count: sql<number>`count(*)` })
|
||||
.from(userInvites)
|
||||
.where(sql`${userInvites.orgId} = ${orgId}`);
|
||||
.where(eq(userInvites.orgId, orgId));
|
||||
|
||||
return response<ListInvitationsResponse>(res, {
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user