mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add reset email password email for oauth user
This commit is contained in:
@@ -785,6 +785,7 @@ export const registerRoutes = async (
|
||||
smtpService,
|
||||
authDAL,
|
||||
userDAL,
|
||||
orgMembershipDAL,
|
||||
totpConfigDAL
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { OrgServiceActor } from "@app/lib/types";
|
||||
|
||||
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
|
||||
import { TokenType } from "../auth-token/auth-token-types";
|
||||
import { TOrgMembershipDALFactory } from "../org-membership/org-membership-dal";
|
||||
import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service";
|
||||
import { TTotpConfigDALFactory } from "../totp/totp-config-dal";
|
||||
import { TUserDALFactory } from "../user/user-dal";
|
||||
@@ -22,6 +23,7 @@ import { ActorType, AuthMethod, AuthTokenType } from "./auth-type";
|
||||
type TAuthPasswordServiceFactoryDep = {
|
||||
authDAL: TAuthDALFactory;
|
||||
userDAL: TUserDALFactory;
|
||||
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "find">;
|
||||
tokenService: TAuthTokenServiceFactory;
|
||||
smtpService: TSmtpService;
|
||||
totpConfigDAL: Pick<TTotpConfigDALFactory, "delete">;
|
||||
@@ -31,6 +33,7 @@ export type TAuthPasswordFactory = ReturnType<typeof authPaswordServiceFactory>;
|
||||
export const authPaswordServiceFactory = ({
|
||||
authDAL,
|
||||
userDAL,
|
||||
orgMembershipDAL,
|
||||
tokenService,
|
||||
smtpService,
|
||||
totpConfigDAL
|
||||
@@ -47,21 +50,46 @@ export const authPaswordServiceFactory = ({
|
||||
|
||||
if (user && user.isAccepted) {
|
||||
const cfg = getConfig();
|
||||
const token = await tokenService.createTokenForUser({
|
||||
type: TokenType.TOKEN_EMAIL_PASSWORD_RESET,
|
||||
userId: user.id
|
||||
});
|
||||
|
||||
await smtpService.sendMail({
|
||||
template: SmtpTemplates.ResetPassword,
|
||||
recipients: [email],
|
||||
subjectLine: "Infisical password reset",
|
||||
substitutions: {
|
||||
const hasEmailAuth = user.authMethods?.includes(AuthMethod.EMAIL);
|
||||
|
||||
if (!hasEmailAuth) {
|
||||
const orgMemberships = await orgMembershipDAL.find({ userId: user.id });
|
||||
const lastLoginMethod =
|
||||
orgMemberships.length > 0
|
||||
? orgMemberships.find((membership) => membership.lastLoginAuthMethod)?.lastLoginAuthMethod || null
|
||||
: null;
|
||||
|
||||
const substitutions = {
|
||||
email,
|
||||
token,
|
||||
callback_url: cfg.SITE_URL ? `${cfg.SITE_URL}/password-reset` : ""
|
||||
}
|
||||
});
|
||||
lastLoginMethod,
|
||||
isCloud: cfg.isCloud,
|
||||
siteUrl: cfg.SITE_URL || ""
|
||||
};
|
||||
|
||||
await smtpService.sendMail({
|
||||
template: SmtpTemplates.OAuthPasswordReset,
|
||||
recipients: [email],
|
||||
subjectLine: "Password reset not available",
|
||||
substitutions
|
||||
});
|
||||
} else {
|
||||
const token = await tokenService.createTokenForUser({
|
||||
type: TokenType.TOKEN_EMAIL_PASSWORD_RESET,
|
||||
userId: user.id
|
||||
});
|
||||
|
||||
await smtpService.sendMail({
|
||||
template: SmtpTemplates.ResetPassword,
|
||||
recipients: [email],
|
||||
subjectLine: "Infisical password reset",
|
||||
substitutions: {
|
||||
email,
|
||||
token,
|
||||
callback_url: cfg.SITE_URL ? `${cfg.SITE_URL}/password-reset` : ""
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { Heading, Section, Text } from "@react-email/components";
|
||||
|
||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||
import { BaseLink } from "./BaseLink";
|
||||
|
||||
interface OAuthPasswordResetTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||
email: string;
|
||||
lastLoginMethod?: string | null;
|
||||
isCloud: boolean;
|
||||
}
|
||||
|
||||
export const OAuthPasswordResetTemplate = ({
|
||||
email,
|
||||
lastLoginMethod,
|
||||
isCloud,
|
||||
siteUrl
|
||||
}: OAuthPasswordResetTemplateProps) => {
|
||||
const getAuthMethodDisplayName = (method: string) => {
|
||||
return method
|
||||
.split("-")
|
||||
.map((word) => {
|
||||
const upperWord = word.toUpperCase();
|
||||
if (["SAML", "LDAP", "OIDC", "SSO"].includes(upperWord)) {
|
||||
return upperWord;
|
||||
}
|
||||
return word.charAt(0).toUpperCase() + word.slice(1);
|
||||
})
|
||||
.join(" ");
|
||||
};
|
||||
|
||||
const getAuthMethodMessage = () => {
|
||||
if (lastLoginMethod) {
|
||||
const displayName = getAuthMethodDisplayName(lastLoginMethod);
|
||||
return `Please continue signing in with ${displayName}, which aligns with your account's configured authentication method.`;
|
||||
}
|
||||
return "Please continue using the same authentication method you previously used to sign in (e.g., SSO, SAML, OAuth, or another configured provider).";
|
||||
};
|
||||
return (
|
||||
<BaseEmailWrapper
|
||||
title="Password Reset Not Available"
|
||||
preview="Your account doesn't have password login enabled."
|
||||
siteUrl={siteUrl}
|
||||
>
|
||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||
<strong>Password Reset Not Available</strong>
|
||||
</Heading>
|
||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||
<Text className="text-[14px]">
|
||||
A password reset was requested for your Infisical account ({email}), but your account doesn't have password
|
||||
login enabled.
|
||||
</Text>
|
||||
<Text className="text-[14px]">
|
||||
<strong>Password reset is not available for this account.</strong>
|
||||
</Text>
|
||||
<Text className="text-[14px]">{getAuthMethodMessage()}</Text>
|
||||
</Section>
|
||||
<Section className="px-[24px] mb-[28px] pt-[12px] pb-[8px] border border-solid border-orange-200 rounded-md bg-orange-50">
|
||||
<Text className="text-[14px]">
|
||||
<strong>Need help?</strong>
|
||||
</Text>
|
||||
<Text className="text-[14px]">
|
||||
If you're having trouble accessing your account or need to change your authentication method, please contact{" "}
|
||||
{isCloud ? (
|
||||
<>
|
||||
our support team at <BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>
|
||||
</>
|
||||
) : (
|
||||
"your instance administrator"
|
||||
)}
|
||||
.
|
||||
</Text>
|
||||
</Section>
|
||||
</BaseEmailWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default OAuthPasswordResetTemplate;
|
||||
|
||||
OAuthPasswordResetTemplate.PreviewProps = {
|
||||
email: "user@example.com",
|
||||
lastLoginMethod: "github",
|
||||
isCloud: true,
|
||||
siteUrl: "https://infisical.com"
|
||||
} as OAuthPasswordResetTemplateProps;
|
||||
@@ -7,6 +7,7 @@ export * from "./ExternalImportStartedTemplate";
|
||||
export * from "./ExternalImportSucceededTemplate";
|
||||
export * from "./IntegrationSyncFailedTemplate";
|
||||
export * from "./NewDeviceLoginTemplate";
|
||||
export * from "./OAuthPasswordResetTemplate";
|
||||
export * from "./OrgAdminBreakglassAccessTemplate";
|
||||
export * from "./OrgAdminProjectGrantAccessTemplate";
|
||||
export * from "./OrganizationAssignmentTemplate";
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
ExternalImportSucceededTemplate,
|
||||
IntegrationSyncFailedTemplate,
|
||||
NewDeviceLoginTemplate,
|
||||
OAuthPasswordResetTemplate,
|
||||
OrgAdminBreakglassAccessTemplate,
|
||||
OrgAdminProjectGrantAccessTemplate,
|
||||
OrganizationAssignmentTemplate,
|
||||
@@ -63,6 +64,7 @@ export enum SmtpTemplates {
|
||||
NewDeviceJoin = "newDevice",
|
||||
OrgInvite = "organizationInvitation",
|
||||
OrgAssignment = "organizationAssignment",
|
||||
OAuthPasswordReset = "oAuthPasswordReset",
|
||||
ResetPassword = "passwordReset",
|
||||
SetupPassword = "passwordSetup",
|
||||
SecretLeakIncident = "secretLeakIncident",
|
||||
@@ -121,6 +123,7 @@ const EmailTemplateMap: Record<SmtpTemplates, React.FC<any>> = {
|
||||
[SmtpTemplates.OrgAdminProjectDirectAccess]: OrgAdminProjectGrantAccessTemplate,
|
||||
[SmtpTemplates.ProjectAccessRequest]: ProjectAccessRequestTemplate,
|
||||
[SmtpTemplates.SecretApprovalRequestNeedsReview]: SecretApprovalRequestNeedsReviewTemplate,
|
||||
[SmtpTemplates.OAuthPasswordReset]: OAuthPasswordResetTemplate,
|
||||
[SmtpTemplates.ResetPassword]: PasswordResetTemplate,
|
||||
[SmtpTemplates.SetupPassword]: PasswordSetupTemplate,
|
||||
[SmtpTemplates.PkiExpirationAlert]: PkiExpirationAlertTemplate,
|
||||
|
||||
Reference in New Issue
Block a user