mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 22:51:53 +00:00
Add lockout-preventative step in saml config setup, add update org slug section in org settings, revise navigate to org flow to account for org-level auth enforced orgs
This commit is contained in:
@@ -56,13 +56,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
||||
* Private
|
||||
* Send mfa code via email
|
||||
* */
|
||||
const sendUserMfaCode = async ({
|
||||
userId,
|
||||
email
|
||||
}: {
|
||||
userId: string;
|
||||
email: string;
|
||||
}) => {
|
||||
const sendUserMfaCode = async ({ userId, email }: { userId: string; email: string }) => {
|
||||
const code = await tokenService.createTokenForUser({
|
||||
type: TokenType.TOKEN_EMAIL_MFA,
|
||||
userId
|
||||
@@ -171,6 +165,10 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
||||
if (!userEnc.authMethods?.includes(AuthMethod.EMAIL)) {
|
||||
const { orgId } = validateProviderAuthToken(providerAuthToken as string, email);
|
||||
organizationId = orgId;
|
||||
} else if (providerAuthToken) {
|
||||
// SAML SSO
|
||||
const { orgId } = validateProviderAuthToken(providerAuthToken, email);
|
||||
organizationId = orgId;
|
||||
}
|
||||
|
||||
if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) throw new Error("Failed to authenticate. Try again?");
|
||||
@@ -189,22 +187,26 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
||||
});
|
||||
// send multi factor auth token if they it enabled
|
||||
if (userEnc.isMfaEnabled) {
|
||||
const mfaToken = jwt.sign({
|
||||
authTokenType: AuthTokenType.MFA_TOKEN,
|
||||
userId: userEnc.userId,
|
||||
organizationId
|
||||
}, cfg.AUTH_SECRET, {
|
||||
expiresIn: cfg.JWT_MFA_LIFETIME
|
||||
});
|
||||
|
||||
const mfaToken = jwt.sign(
|
||||
{
|
||||
authTokenType: AuthTokenType.MFA_TOKEN,
|
||||
userId: userEnc.userId,
|
||||
organizationId
|
||||
},
|
||||
cfg.AUTH_SECRET,
|
||||
{
|
||||
expiresIn: cfg.JWT_MFA_LIFETIME
|
||||
}
|
||||
);
|
||||
|
||||
await sendUserMfaCode({
|
||||
userId: userEnc.userId,
|
||||
userId: userEnc.userId,
|
||||
email: userEnc.email
|
||||
});
|
||||
|
||||
return { isMfaEnabled: true, token: mfaToken } as const;
|
||||
}
|
||||
|
||||
|
||||
const token = await generateUserTokens({
|
||||
user: {
|
||||
...userEnc,
|
||||
@@ -214,7 +216,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
||||
userAgent,
|
||||
organizationId
|
||||
});
|
||||
|
||||
|
||||
return { token, isMfaEnabled: false, user: userEnc } as const;
|
||||
};
|
||||
|
||||
@@ -227,7 +229,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
||||
if (!user) return;
|
||||
await sendUserMfaCode({
|
||||
userId: user.id,
|
||||
email: user.email,
|
||||
email: user.email
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -127,6 +127,7 @@ export const identityUaServiceFactory = ({
|
||||
expiresIn: identityAccessToken.accessTokenMaxTTL === 0 ? undefined : identityAccessToken.accessTokenMaxTTL
|
||||
}
|
||||
);
|
||||
|
||||
return { accessToken, identityUa, validClientSecretInfo, identityAccessToken };
|
||||
};
|
||||
|
||||
@@ -152,7 +153,12 @@ export const identityUaServiceFactory = ({
|
||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId, actorOrgScope);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorOrgScope
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
|
||||
|
||||
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||
@@ -241,7 +247,12 @@ export const identityUaServiceFactory = ({
|
||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId, actorOrgScope);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorOrgScope
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||
@@ -302,7 +313,12 @@ export const identityUaServiceFactory = ({
|
||||
|
||||
const uaIdentityAuth = await identityUaDAL.findOne({ identityId });
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId, actorOrgScope);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorOrgScope
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
return { ...uaIdentityAuth, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
@@ -322,7 +338,12 @@ export const identityUaServiceFactory = ({
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have universal auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId, actorOrgScope);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorOrgScope
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
@@ -369,7 +390,12 @@ export const identityUaServiceFactory = ({
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have universal auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId, actorOrgScope);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorOrgScope
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
@@ -395,14 +421,25 @@ export const identityUaServiceFactory = ({
|
||||
return { clientSecrets, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeUaClientSecret = async ({ identityId, actorId, actor, actorOrgScope, clientSecretId }: TRevokeUaClientSecretDTO) => {
|
||||
const revokeUaClientSecret = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorOrgScope,
|
||||
clientSecretId
|
||||
}: TRevokeUaClientSecretDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have universal auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId, actorOrgScope);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorOrgScope
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
TDeleteOrgMembershipDTO,
|
||||
TFindAllWorkspacesDTO,
|
||||
TInviteUserToOrgDTO,
|
||||
TUpdateOrgDTO,
|
||||
TUpdateOrgMembershipDTO,
|
||||
TVerifyUserToOrgDTO
|
||||
} from "./org-types";
|
||||
@@ -40,7 +41,7 @@ type TOrgServiceFactoryDep = {
|
||||
userDAL: TUserDALFactory;
|
||||
projectDAL: TProjectDALFactory;
|
||||
incidentContactDAL: TIncidentContactsDALFactory;
|
||||
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne">;
|
||||
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne" | "findEnforceableSamlCfg">;
|
||||
smtpService: TSmtpService;
|
||||
tokenService: TAuthTokenServiceFactory;
|
||||
permissionService: TPermissionServiceFactory;
|
||||
@@ -118,12 +119,22 @@ export const orgServiceFactory = ({
|
||||
};
|
||||
|
||||
/*
|
||||
* Update organization settings
|
||||
* Update organization details
|
||||
* */
|
||||
const updateOrgName = async (userId: string, orgId: string, name: string, actorOrgScope?: string) => {
|
||||
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgScope);
|
||||
const updateOrg = async ({ actor, actorId, actorOrgScope, orgId, data }: TUpdateOrgDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgScope);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
const org = await orgDAL.updateById(orgId, { name });
|
||||
|
||||
if (data.authEnforced) {
|
||||
const samlCfg = await samlConfigDAL.findEnforceableSamlCfg(orgId);
|
||||
if (!samlCfg)
|
||||
throw new BadRequestError({
|
||||
name: "No enforceable SAML config found",
|
||||
message: "No enforceable SAML config found"
|
||||
});
|
||||
}
|
||||
|
||||
const org = await orgDAL.updateById(orgId, data);
|
||||
if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" });
|
||||
return org;
|
||||
};
|
||||
@@ -443,7 +454,7 @@ export const orgServiceFactory = ({
|
||||
findAllOrganizationOfUser,
|
||||
inviteUserToOrganization,
|
||||
verifyUserToOrg,
|
||||
updateOrgName,
|
||||
updateOrg,
|
||||
createOrganization,
|
||||
deleteOrganizationById,
|
||||
deleteOrgMembership,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TOrgPermission } from "@app/lib/types";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
|
||||
export type TUpdateOrgMembershipDTO = {
|
||||
@@ -34,3 +36,7 @@ export type TFindAllWorkspacesDTO = {
|
||||
actorOrgScope?: string;
|
||||
orgId: string;
|
||||
};
|
||||
|
||||
export type TUpdateOrgDTO = {
|
||||
data: Partial<{ name: string; slug: string; authEnforced: boolean }>;
|
||||
} & TOrgPermission;
|
||||
|
||||
Reference in New Issue
Block a user