mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-04 18:14:53 +02:00
ability to remove user from org
This commit is contained in:
parent
2852d62258
commit
fadfaf1f0b
28 changed files with 718 additions and 264 deletions
|
@ -1,7 +1,7 @@
|
|||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { db } from "@server/db";
|
||||
import { userInvites, userOrgs, users } from "@server/db/schema";
|
||||
import { orgs, userInvites, userOrgs, users } from "@server/db/schema";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import response from "@server/utils/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
|
@ -13,6 +13,8 @@ import { createDate, TimeSpan } from "oslo";
|
|||
import config from "@server/config";
|
||||
import { hashPassword } from "@server/auth/password";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { sendEmail } from "@server/emails";
|
||||
import SendInviteLink from "@server/emails/templates/SendInviteLink";
|
||||
|
||||
const inviteUserParamsSchema = z.object({
|
||||
orgId: z.string(),
|
||||
|
@ -31,6 +33,8 @@ export type InviteUserResponse = {
|
|||
expiresAt: number;
|
||||
};
|
||||
|
||||
const inviteTracker: Record<string, { timestamps: number[] }> = {};
|
||||
|
||||
export async function inviteUser(
|
||||
req: Request,
|
||||
res: Response,
|
||||
|
@ -73,6 +77,39 @@ export async function inviteUser(
|
|||
);
|
||||
}
|
||||
|
||||
const currentTime = Date.now();
|
||||
const oneHourAgo = currentTime - 3600000;
|
||||
|
||||
if (!inviteTracker[email]) {
|
||||
inviteTracker[email] = { timestamps: [] };
|
||||
}
|
||||
|
||||
inviteTracker[email].timestamps = inviteTracker[
|
||||
email
|
||||
].timestamps.filter((timestamp) => timestamp > oneHourAgo);
|
||||
|
||||
if (inviteTracker[email].timestamps.length >= 3) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.TOO_MANY_REQUESTS,
|
||||
"User has already been invited 3 times in the last hour"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
inviteTracker[email].timestamps.push(currentTime);
|
||||
|
||||
const org = await db
|
||||
.select()
|
||||
.from(orgs)
|
||||
.where(eq(orgs.orgId, orgId))
|
||||
.limit(1);
|
||||
if (!org.length) {
|
||||
return next(
|
||||
createHttpError(HttpCode.NOT_FOUND, "Organization not found")
|
||||
);
|
||||
}
|
||||
|
||||
const existingUser = await db
|
||||
.select()
|
||||
.from(users)
|
||||
|
@ -116,6 +153,21 @@ export async function inviteUser(
|
|||
|
||||
const inviteLink = `${config.app.base_url}/invite?token=${inviteId}-${token}`;
|
||||
|
||||
await sendEmail(
|
||||
SendInviteLink({
|
||||
email,
|
||||
inviteLink,
|
||||
expiresInDays: (validHours / 24).toString(),
|
||||
orgName: orgId,
|
||||
inviterName: req.user?.email,
|
||||
}),
|
||||
{
|
||||
to: email,
|
||||
from: config.email?.no_reply,
|
||||
subject: "You're invited to join a Fossorial organization",
|
||||
}
|
||||
);
|
||||
|
||||
return response<InviteUserResponse>(res, {
|
||||
data: {
|
||||
inviteLink,
|
||||
|
|
|
@ -11,7 +11,7 @@ import logger from "@server/logger";
|
|||
import { fromError } from "zod-validation-error";
|
||||
|
||||
const removeUserSchema = z.object({
|
||||
userId: z.string().uuid(),
|
||||
userId: z.string(),
|
||||
orgId: z.string(),
|
||||
});
|
||||
|
||||
|
@ -33,7 +33,6 @@ export async function removeUserOrg(
|
|||
|
||||
const { userId, orgId } = parsedParams.data;
|
||||
|
||||
// Check if the user has permission to list sites
|
||||
const hasPermission = await checkUserActionPermission(
|
||||
ActionsEnum.removeUser,
|
||||
req
|
||||
|
@ -56,7 +55,7 @@ export async function removeUserOrg(
|
|||
data: null,
|
||||
success: true,
|
||||
error: false,
|
||||
message: "User deleted successfully",
|
||||
message: "User remove from org successfully",
|
||||
status: HttpCode.OK,
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue