Skip to content

Commit

Permalink
simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
Henry Fontanier committed Apr 4, 2024
1 parent d172fb1 commit e120d41
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 33 deletions.
38 changes: 38 additions & 0 deletions front/lib/api/invitation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
import { Err, sanitizeString } from "@dust-tt/types";
import sgMail from "@sendgrid/mail";
import { sign } from "jsonwebtoken";
import { Op } from "sequelize";

import config from "@app/lib/api/config";
import type { Authenticator } from "@app/lib/auth";
Expand Down Expand Up @@ -178,3 +179,40 @@ export async function getPendingInvitations(
};
});
}

/**
* Returns the pending or revoked inviations that were created today
* associated with the authenticator's owner workspace.
* @param auth Authenticator
* @returns MenbershipInvitation[] members of the workspace
*/

export async function getRecentPendingOrRevokedInvitations(
auth: Authenticator
): Promise<MembershipInvitationType[]> {
const owner = auth.workspace();
if (!owner) {
return [];
}
const oneDayAgo = new Date();
oneDayAgo.setDate(oneDayAgo.getDate() - 1);
const invitations = await MembershipInvitation.findAll({
where: {
workspaceId: owner.id,
status: ["pending", "revoked"],
createdAt: {
[Op.gt]: oneDayAgo,
},
},
});

return invitations.map((i) => {
return {
sId: i.sId,
id: i.id,
status: i.status,
inviteEmail: i.inviteEmail,
initialRole: i.initialRole,
};
});
}
7 changes: 2 additions & 5 deletions front/lib/invitations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
// Maxmimum allowed number of unconsumed invitations per workspace.
export const MAX_UNCONSUMED_INVITATIONS = 50;
// If the user already received an invitation from this workspace and hasn't consumed it yet, we won't send another one
// before this cooldown period.
export const UNCONSUMED_INVITATION_COOLDOWN_PER_EMAIL_MS = 1000 * 60 * 60 * 24; // 1 day
// Maxmimum allowed number of unconsumed invitations per workspace per day.
export const MAX_UNCONSUMED_INVITATIONS_PER_WORKSPACE_PER_DAY = 50;
35 changes: 10 additions & 25 deletions front/pages/api/w/[wId]/invitations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,16 @@ import { isLeft } from "fp-ts/lib/Either";
import * as t from "io-ts";
import * as reporter from "io-ts-reporters";
import type { NextApiRequest, NextApiResponse } from "next";
import { Op } from "sequelize";

import {
getRecentPendingOrRevokedInvitations,
sendWorkspaceInvitationEmail,
updateOrCreateInvitation,
} from "@app/lib/api/invitation";
import { getPendingInvitations } from "@app/lib/api/invitation";
import { getMembers } from "@app/lib/api/workspace";
import { Authenticator, getSession } from "@app/lib/auth";
import {
MAX_UNCONSUMED_INVITATIONS,
UNCONSUMED_INVITATION_COOLDOWN_PER_EMAIL_MS,
} from "@app/lib/invitations";
import { MembershipInvitation } from "@app/lib/models";
import { MAX_UNCONSUMED_INVITATIONS_PER_WORKSPACE_PER_DAY } from "@app/lib/invitations";
import { MembershipResource } from "@app/lib/resources/membership_resource";
import { isEmailValid } from "@app/lib/utils";
import logger from "@app/logger/logger";
Expand Down Expand Up @@ -158,18 +154,13 @@ async function handler(
});
}
const existingMembers = await getMembers(auth);
const startOfDay = new Date();
startOfDay.setHours(0, 0, 0, 0);
const unconsumedInvitations = await MembershipInvitation.findAll({
where: {
workspaceId: owner.id,
status: ["pending", "revoked"],
createdAt: {
[Op.gte]: startOfDay,
},
},
});
if (unconsumedInvitations.length > MAX_UNCONSUMED_INVITATIONS) {
const unconsumedInvitations = await getRecentPendingOrRevokedInvitations(
auth
);
if (
unconsumedInvitations.length >
MAX_UNCONSUMED_INVITATIONS_PER_WORKSPACE_PER_DAY
) {
return apiError(req, res, {
status_code: 400,
api_error: {
Expand All @@ -179,13 +170,7 @@ async function handler(
});
}
const emailsWithRecentUnconsumedInvitations = new Set(
unconsumedInvitations
.filter(
(i) =>
i.createdAt.getTime() >
new Date().getTime() - UNCONSUMED_INVITATION_COOLDOWN_PER_EMAIL_MS
)
.map((i) => i.inviteEmail.toLowerCase().trim())
unconsumedInvitations.map((i) => i.inviteEmail.toLowerCase().trim())
);
if (
invitationRequests.some((r) =>
Expand Down
8 changes: 5 additions & 3 deletions front/pages/w/[wId]/members/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
PRO_PLAN_29_COST,
} from "@app/lib/client/subscription";
import { withDefaultUserAuthRequirements } from "@app/lib/iam/session";
import { MAX_UNCONSUMED_INVITATIONS } from "@app/lib/invitations";
import { MAX_UNCONSUMED_INVITATIONS_PER_WORKSPACE_PER_DAY } from "@app/lib/invitations";
import { isUpgraded, PRO_PLAN_SEAT_29_CODE } from "@app/lib/plans/plan_codes";
import { useMembers, useWorkspaceInvitations } from "@app/lib/swr";
import { classNames, isEmailValid } from "@app/lib/utils";
Expand Down Expand Up @@ -485,11 +485,13 @@ function InviteEmailModal({
async function handleSendInvitations(
inviteEmailsList: string[]
): Promise<void> {
if (inviteEmailsList.length > MAX_UNCONSUMED_INVITATIONS) {
if (
inviteEmailsList.length > MAX_UNCONSUMED_INVITATIONS_PER_WORKSPACE_PER_DAY
) {
sendNotification({
type: "error",
title: "Too many invitations",
description: `Your cannot send more than ${MAX_UNCONSUMED_INVITATIONS} invitations.`,
description: `Your cannot send more than ${MAX_UNCONSUMED_INVITATIONS_PER_WORKSPACE_PER_DAY} invitations per day.`,
});
return;
}
Expand Down

0 comments on commit e120d41

Please sign in to comment.