Finish frame for LDAP auth

This commit is contained in:
Tuan Dang
2024-02-23 10:00:30 -08:00
parent acfa89ba8b
commit 5053069bfc
51 changed files with 1652 additions and 68 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { AuthModeProviderJwtTokenPayload, AuthModeProviderSignUpTokenPayload, AuthTokenType } from "./auth-type";
export const validateProviderAuthToken = (providerToken: string, email: string) => {
export const validateProviderAuthToken = (providerToken: string, email?: string) => {
if (!providerToken) throw new UnauthorizedError();
const appCfg = getConfig();
const decodedToken = jwt.verify(providerToken, appCfg.AUTH_SECRET) as AuthModeProviderJwtTokenPayload;
+20 -16
View File
@@ -38,17 +38,19 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
if (!isDeviceSeen) {
const newDeviceList = devices.concat([{ ip, userAgent }]);
await userDAL.updateById(user.id, { devices: JSON.stringify(newDeviceList) });
await smtpService.sendMail({
template: SmtpTemplates.NewDeviceJoin,
subjectLine: "Successful login from new device",
recipients: [user.email],
substitutions: {
email: user.email,
timestamp: new Date().toString(),
ip,
userAgent
}
});
if (user.email) {
await smtpService.sendMail({
template: SmtpTemplates.NewDeviceJoin,
subjectLine: "Successful login from new device",
recipients: [user.email],
substitutions: {
email: user.email,
timestamp: new Date().toString(),
ip,
userAgent
}
});
}
}
};
@@ -199,10 +201,12 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
}
);
await sendUserMfaCode({
userId: userEnc.userId,
email: userEnc.email
});
if (userEnc.email) {
await sendUserMfaCode({
userId: userEnc.userId,
email: userEnc.email
});
}
return { isMfaEnabled: true, token: mfaToken } as const;
}
@@ -226,7 +230,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
*/
const resendMfaToken = async (userId: string) => {
const user = await userDAL.findById(userId);
if (!user) return;
if (!user || !user.email) return;
await sendUserMfaCode({
userId: user.id,
email: user.email
@@ -122,7 +122,7 @@ export const authSignupServiceFactory = ({
let organizationId;
if (providerAuthToken) {
const { orgId } = validateProviderAuthToken(providerAuthToken, user.email);
const { orgId } = validateProviderAuthToken(providerAuthToken, user.email as string);
organizationId = orgId;
} else {
validateSignUpAuthorization(authorization, user.id);
@@ -150,7 +150,11 @@ export const authSignupServiceFactory = ({
});
if (!organizationId) {
await orgService.createOrganization(user.id, user.email, organizationName);
await orgService.createOrganization({
userId: user.id,
userEmail: user.email,
orgName: organizationName
});
}
const updatedMembersips = await orgDAL.updateMembership(
+2 -1
View File
@@ -5,7 +5,8 @@ export enum AuthMethod {
GITLAB = "gitlab",
OKTA_SAML = "okta-saml",
AZURE_SAML = "azure-saml",
JUMPCLOUD_SAML = "jumpcloud-saml"
JUMPCLOUD_SAML = "jumpcloud-saml",
LDAP = "ldap"
}
export enum AuthTokenType {
+1
View File
@@ -243,6 +243,7 @@ export const orgDALFactory = (db: TDbClient) => {
.select(
selectAllTableCols(TableName.OrgMembership),
db.ref("email").withSchema(TableName.Users),
db.ref("username").withSchema(TableName.Users),
db.ref("firstName").withSchema(TableName.Users),
db.ref("lastName").withSchema(TableName.Users),
db.ref("scimEnabled").withSchema(TableName.Organization)
+9 -1
View File
@@ -233,7 +233,15 @@ export const orgServiceFactory = ({
/*
* Create organization
* */
const createOrganization = async (userId: string, userEmail: string, orgName: string) => {
const createOrganization = async ({
userId,
userEmail,
orgName
}: {
userId: string;
orgName: string;
userEmail?: string | null;
}) => {
const { privateKey, publicKey } = generateAsymmetricKeyPair();
const key = generateSymmetricKey();
const {
@@ -135,7 +135,7 @@ export const projectMembershipServiceFactory = ({
await smtpService.sendMail({
template: SmtpTemplates.WorkspaceInvite,
subjectLine: "Infisical workspace invitation",
recipients: invitees.map((i) => i.email),
recipients: invitees.filter((i) => i.email).map((i) => i.email as string),
substitutions: {
workspaceName: project.name,
callback_url: `${appCfg.SITE_URL}/login`
@@ -207,7 +207,9 @@ export const projectMembershipServiceFactory = ({
await smtpService.sendMail({
template: SmtpTemplates.WorkspaceInvite,
subjectLine: "Infisical workspace invitation",
recipients: orgMembers.map(({ email }) => email).filter(Boolean),
recipients: orgMembers
.map(({ email }) => email)
.filter((email): email is string => email !== null && email !== undefined),
substitutions: {
workspaceName: project.name,
callback_url: `${appCfg.SITE_URL}/login`
@@ -317,7 +319,7 @@ export const projectMembershipServiceFactory = ({
await smtpService.sendMail({
template: SmtpTemplates.WorkspaceInvite,
subjectLine: "Infisical workspace invitation",
recipients: orgMembers.map(({ user }) => user.email).filter(Boolean),
recipients: orgMembers.filter(({ user }) => user.email).map(({ user }) => user.email as string),
substitutions: {
workspaceName: project.name,
callback_url: `${appCfg.SITE_URL}/login`
+1 -1
View File
@@ -350,7 +350,7 @@ export const secretQueueFactory = ({
await smtpService.sendMail({
template: SmtpTemplates.SecretReminder,
subjectLine: "Infisical secret reminder",
recipients: [...projectMembers.map((m) => m.user.email)],
recipients: [...projectMembers.map((m) => m.user.email)].filter((email) => email).map((email) => email as string),
substitutions: {
reminderNote: data.note, // May not be present.
projectName: project.name,
@@ -68,6 +68,7 @@ export const superAdminServiceFactory = ({
{
firstName,
lastName,
username: email,
email,
superAdmin: true,
isGhost: false,
@@ -97,11 +98,11 @@ export const superAdminServiceFactory = ({
const initialOrganizationName = appCfg.INITIAL_ORGANIZATION_NAME ?? "Admin Org";
const organization = await orgService.createOrganization(
userInfo.user.id,
userInfo.user.email,
initialOrganizationName
);
const organization = await orgService.createOrganization({
userId: userInfo.user.id,
userEmail: userInfo.user.email,
orgName: initialOrganizationName
});
await updateServerCfg({ initialized: true });
const token = await authService.generateUserTokens({
@@ -11,6 +11,10 @@ export type TUserServiceFactory = ReturnType<typeof userServiceFactory>;
export const userServiceFactory = ({ userDAL }: TUserServiceFactoryDep) => {
const toggleUserMfa = async (userId: string, isMfaEnabled: boolean) => {
const user = await userDAL.findById(userId);
if (!user || !user.email) throw new BadRequestError({ name: "Failed to toggle MFA" });
const updatedUser = await userDAL.updateById(userId, {
isMfaEnabled,
mfaMethods: isMfaEnabled ? ["email"] : []