mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 18:15:53 +00:00
Merge branch 'main' into feat/remindersImprovement
This commit is contained in:
@@ -36,6 +36,8 @@ import { getConfig } from "@app/lib/config/env";
|
||||
import { generateAsymmetricKeyPair } from "@app/lib/crypto";
|
||||
import { generateSymmetricKey, infisicalSymmetricDecrypt, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
||||
import { generateUserSrpKeys } from "@app/lib/crypto/srp";
|
||||
import { applyJitter } from "@app/lib/dates";
|
||||
import { delay as delayMs } from "@app/lib/delay";
|
||||
import {
|
||||
BadRequestError,
|
||||
ForbiddenRequestError,
|
||||
@@ -44,8 +46,10 @@ import {
|
||||
UnauthorizedError
|
||||
} from "@app/lib/errors";
|
||||
import { groupBy } from "@app/lib/fn";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { isDisposableEmail } from "@app/lib/validator";
|
||||
import { QueueName } from "@app/queue";
|
||||
import { getDefaultOrgMembershipRoleForUpdateOrg } from "@app/services/org/org-role-fns";
|
||||
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
|
||||
import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal";
|
||||
@@ -107,7 +111,15 @@ type TOrgServiceFactoryDep = {
|
||||
"findProjectMembershipsByUserId" | "delete" | "create" | "find" | "insertMany" | "transaction"
|
||||
>;
|
||||
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "delete" | "insertMany" | "findLatestProjectKey" | "create">;
|
||||
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "findOrgMembershipById" | "findOne" | "findById">;
|
||||
orgMembershipDAL: Pick<
|
||||
TOrgMembershipDALFactory,
|
||||
| "findOrgMembershipById"
|
||||
| "findOne"
|
||||
| "findById"
|
||||
| "findRecentInvitedMemberships"
|
||||
| "updateById"
|
||||
| "updateLastInvitedAtByIds"
|
||||
>;
|
||||
incidentContactDAL: TIncidentContactsDALFactory;
|
||||
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne">;
|
||||
oidcConfigDAL: Pick<TOidcConfigDALFactory, "findOne">;
|
||||
@@ -760,6 +772,10 @@ export const orgServiceFactory = ({
|
||||
}
|
||||
});
|
||||
|
||||
await orgMembershipDAL.updateById(inviteeOrgMembership.id, {
|
||||
lastInvitedAt: new Date()
|
||||
});
|
||||
|
||||
return { signupToken: undefined };
|
||||
};
|
||||
|
||||
@@ -1422,6 +1438,63 @@ export const orgServiceFactory = ({
|
||||
return incidentContact;
|
||||
};
|
||||
|
||||
/**
|
||||
* Re-send emails to users who haven't accepted an invite yet
|
||||
*/
|
||||
const notifyInvitedUsers = async () => {
|
||||
logger.info(`${QueueName.DailyResourceCleanUp}: notify invited users started`);
|
||||
|
||||
const invitedUsers = await orgMembershipDAL.findRecentInvitedMemberships();
|
||||
const appCfg = getConfig();
|
||||
|
||||
const orgCache: Record<string, { name: string; id: string } | undefined> = {};
|
||||
const notifiedUsers: string[] = [];
|
||||
|
||||
await Promise.all(
|
||||
invitedUsers.map(async (invitedUser) => {
|
||||
let org = orgCache[invitedUser.orgId];
|
||||
if (!org) {
|
||||
org = await orgDAL.findById(invitedUser.orgId);
|
||||
orgCache[invitedUser.orgId] = org;
|
||||
}
|
||||
|
||||
if (!org || !invitedUser.userId) return;
|
||||
|
||||
const token = await tokenService.createTokenForUser({
|
||||
type: TokenType.TOKEN_EMAIL_ORG_INVITATION,
|
||||
userId: invitedUser.userId,
|
||||
orgId: org.id
|
||||
});
|
||||
|
||||
if (invitedUser.inviteEmail) {
|
||||
await delayMs(Math.max(0, applyJitter(0, 2000)));
|
||||
|
||||
try {
|
||||
await smtpService.sendMail({
|
||||
template: SmtpTemplates.OrgInvite,
|
||||
subjectLine: `Reminder: You have been invited to ${org.name} on Infisical`,
|
||||
recipients: [invitedUser.inviteEmail],
|
||||
substitutions: {
|
||||
organizationName: org.name,
|
||||
email: invitedUser.inviteEmail,
|
||||
organizationId: org.id.toString(),
|
||||
token,
|
||||
callback_url: `${appCfg.SITE_URL}/signupinvite`
|
||||
}
|
||||
});
|
||||
notifiedUsers.push(invitedUser.id);
|
||||
} catch (err) {
|
||||
logger.error(err, `${QueueName.DailyResourceCleanUp}: notify invited users failed to send email`);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await orgMembershipDAL.updateLastInvitedAtByIds(notifiedUsers);
|
||||
|
||||
logger.info(`${QueueName.DailyResourceCleanUp}: notify invited users completed`);
|
||||
};
|
||||
|
||||
return {
|
||||
findOrganizationById,
|
||||
findAllOrgMembers,
|
||||
@@ -1445,6 +1518,7 @@ export const orgServiceFactory = ({
|
||||
listProjectMembershipsByOrgMembershipId,
|
||||
findOrgBySlug,
|
||||
resendOrgMemberInvitation,
|
||||
upgradePrivilegeSystem
|
||||
upgradePrivilegeSystem,
|
||||
notifyInvitedUsers
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user