mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-12 15:29:10 +00:00
Update various SSO / SAML auth methods to support username
This commit is contained in:
@@ -329,7 +329,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
await userDAL.transaction(async (tx) => {
|
await userDAL.transaction(async (tx) => {
|
||||||
const [orgMembership] = await orgDAL.findMembership({ userId: user.id, orgId }, { tx });
|
const [orgMembership] = await orgDAL.findMembership({ userId: user.id }, { tx });
|
||||||
if (!orgMembership) {
|
if (!orgMembership) {
|
||||||
await orgDAL.createMembership(
|
await orgDAL.createMembership(
|
||||||
{
|
{
|
||||||
@@ -366,7 +366,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
await orgDAL.createMembership({
|
await orgDAL.createMembership({
|
||||||
orgId,
|
orgId,
|
||||||
role: OrgMembershipRole.Member,
|
role: OrgMembershipRole.Member,
|
||||||
status: OrgMembershipStatus.Invited // should this be invited?
|
status: OrgMembershipStatus.Invited
|
||||||
});
|
});
|
||||||
return newUser;
|
return newUser;
|
||||||
});
|
});
|
||||||
@@ -378,6 +378,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
{
|
{
|
||||||
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
username: user.username,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
organizationName: organization.name,
|
organizationName: organization.name,
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ export const samlConfigServiceFactory = ({
|
|||||||
{
|
{
|
||||||
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
email: user.email,
|
username: user.username,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
organizationName: organization.name,
|
organizationName: organization.name,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
email: z.string().email().trim(),
|
email: z.string().trim(),
|
||||||
providerAuthToken: z.string().trim().optional(),
|
providerAuthToken: z.string().trim().optional(),
|
||||||
clientPublicKey: z.string().trim()
|
clientPublicKey: z.string().trim()
|
||||||
}),
|
}),
|
||||||
@@ -42,7 +42,7 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
email: z.string().email().trim(),
|
email: z.string().trim(),
|
||||||
providerAuthToken: z.string().trim().optional(),
|
providerAuthToken: z.string().trim().optional(),
|
||||||
clientProof: z.string().trim()
|
clientProof: z.string().trim()
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => {
|
|||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
email: z.string().email().trim(),
|
email: z.string().trim(),
|
||||||
firstName: z.string().trim(),
|
firstName: z.string().trim(),
|
||||||
lastName: z.string().trim().optional(),
|
lastName: z.string().trim().optional(),
|
||||||
protectedKey: z.string().trim(),
|
protectedKey: z.string().trim(),
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
|||||||
|
|
||||||
import { AuthModeProviderJwtTokenPayload, AuthModeProviderSignUpTokenPayload, AuthTokenType } from "./auth-type";
|
import { AuthModeProviderJwtTokenPayload, AuthModeProviderSignUpTokenPayload, AuthTokenType } from "./auth-type";
|
||||||
|
|
||||||
export const validateProviderAuthToken = (providerToken: string, email?: string) => {
|
export const validateProviderAuthToken = (providerToken: string, username?: string) => {
|
||||||
if (!providerToken) throw new UnauthorizedError();
|
if (!providerToken) throw new UnauthorizedError();
|
||||||
const appCfg = getConfig();
|
const appCfg = getConfig();
|
||||||
const decodedToken = jwt.verify(providerToken, appCfg.AUTH_SECRET) as AuthModeProviderJwtTokenPayload;
|
const decodedToken = jwt.verify(providerToken, appCfg.AUTH_SECRET) as AuthModeProviderJwtTokenPayload;
|
||||||
|
|
||||||
if (decodedToken.authTokenType !== AuthTokenType.PROVIDER_TOKEN) throw new UnauthorizedError();
|
if (decodedToken.authTokenType !== AuthTokenType.PROVIDER_TOKEN) throw new UnauthorizedError();
|
||||||
if (decodedToken.email !== email) throw new Error("Invalid auth credentials");
|
|
||||||
|
if (decodedToken.username !== username) throw new Error("Invalid auth credentials");
|
||||||
|
|
||||||
if (decodedToken.organizationId) {
|
if (decodedToken.organizationId) {
|
||||||
return { orgId: decodedToken.organizationId };
|
return { orgId: decodedToken.organizationId };
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
|||||||
providerAuthToken,
|
providerAuthToken,
|
||||||
clientPublicKey
|
clientPublicKey
|
||||||
}: TLoginGenServerPublicKeyDTO) => {
|
}: TLoginGenServerPublicKeyDTO) => {
|
||||||
const userEnc = await userDAL.findUserEncKeyByEmail(email);
|
const userEnc = await userDAL.findUserEncKeyByUsername(email);
|
||||||
if (!userEnc || (userEnc && !userEnc.isAccepted)) {
|
if (!userEnc || (userEnc && !userEnc.isAccepted)) {
|
||||||
throw new Error("Failed to find user");
|
throw new Error("Failed to find user");
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
|||||||
ip,
|
ip,
|
||||||
userAgent
|
userAgent
|
||||||
}: TLoginClientProofDTO) => {
|
}: TLoginClientProofDTO) => {
|
||||||
const userEnc = await userDAL.findUserEncKeyByEmail(email);
|
const userEnc = await userDAL.findUserEncKeyByUsername(email);
|
||||||
if (!userEnc) throw new Error("Failed to find user");
|
if (!userEnc) throw new Error("Failed to find user");
|
||||||
const cfg = getConfig();
|
const cfg = getConfig();
|
||||||
|
|
||||||
@@ -301,7 +301,8 @@ export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }:
|
|||||||
{
|
{
|
||||||
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
authTokenType: AuthTokenType.PROVIDER_TOKEN,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
email: user.email,
|
// email: user.email,
|
||||||
|
username: user.username,
|
||||||
firstName: user.firstName,
|
firstName: user.firstName,
|
||||||
lastName: user.lastName,
|
lastName: user.lastName,
|
||||||
authMethod,
|
authMethod,
|
||||||
|
|||||||
@@ -115,14 +115,14 @@ export const authSignupServiceFactory = ({
|
|||||||
userAgent,
|
userAgent,
|
||||||
authorization
|
authorization
|
||||||
}: TCompleteAccountSignupDTO) => {
|
}: TCompleteAccountSignupDTO) => {
|
||||||
const user = await userDAL.findUserByEmail(email);
|
const user = await userDAL.findOne({ username: email });
|
||||||
if (!user || (user && user.isAccepted)) {
|
if (!user || (user && user.isAccepted)) {
|
||||||
throw new Error("Failed to complete account for complete user");
|
throw new Error("Failed to complete account for complete user");
|
||||||
}
|
}
|
||||||
|
|
||||||
let organizationId;
|
let organizationId;
|
||||||
if (providerAuthToken) {
|
if (providerAuthToken) {
|
||||||
const { orgId } = validateProviderAuthToken(providerAuthToken, user.email as string);
|
const { orgId } = validateProviderAuthToken(providerAuthToken, user.username);
|
||||||
organizationId = orgId;
|
organizationId = orgId;
|
||||||
} else {
|
} else {
|
||||||
validateSignUpAuthorization(authorization, user.id);
|
validateSignUpAuthorization(authorization, user.id);
|
||||||
@@ -152,7 +152,7 @@ export const authSignupServiceFactory = ({
|
|||||||
if (!organizationId) {
|
if (!organizationId) {
|
||||||
await orgService.createOrganization({
|
await orgService.createOrganization({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
userEmail: user.email,
|
userEmail: user.email ?? user.username ?? "", // TODO: look into
|
||||||
orgName: organizationName
|
orgName: organizationName
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export type AuthModeRefreshJwtTokenPayload = {
|
|||||||
|
|
||||||
export type AuthModeProviderJwtTokenPayload = {
|
export type AuthModeProviderJwtTokenPayload = {
|
||||||
authTokenType: AuthTokenType.PROVIDER_TOKEN;
|
authTokenType: AuthTokenType.PROVIDER_TOKEN;
|
||||||
email: string;
|
username: string;
|
||||||
organizationId?: string;
|
organizationId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ export const userDALFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
// USER ENCRYPTION FUNCTIONS
|
// USER ENCRYPTION FUNCTIONS
|
||||||
// -------------------------
|
// -------------------------
|
||||||
const findUserEncKeyByEmail = async (email: string) => {
|
const findUserEncKeyByUsername = async (username: string) => {
|
||||||
try {
|
try {
|
||||||
return await db(TableName.Users)
|
return await db(TableName.Users)
|
||||||
.where({ email, isGhost: false })
|
.where({ username, isGhost: false })
|
||||||
.join(TableName.UserEncryptionKey, `${TableName.Users}.id`, `${TableName.UserEncryptionKey}.userId`)
|
.join(TableName.UserEncryptionKey, `${TableName.Users}.id`, `${TableName.UserEncryptionKey}.userId`)
|
||||||
.first();
|
.first();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -119,7 +119,7 @@ export const userDALFactory = (db: TDbClient) => {
|
|||||||
return {
|
return {
|
||||||
...userOrm,
|
...userOrm,
|
||||||
findUserByEmail,
|
findUserByEmail,
|
||||||
findUserEncKeyByEmail,
|
findUserEncKeyByUsername,
|
||||||
findUserEncKeyByUserId,
|
findUserEncKeyByUserId,
|
||||||
updateUserEncryptionByUserId,
|
updateUserEncryptionByUserId,
|
||||||
findUserByProjectMembershipId,
|
findUserByProjectMembershipId,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const LoginSSO = ({ providerAuthToken }: Props) => {
|
|||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
email,
|
username,
|
||||||
isUserCompleted
|
isUserCompleted
|
||||||
} = jwt_decode(providerAuthToken) as any;
|
} = jwt_decode(providerAuthToken) as any;
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export const LoginSSO = ({ providerAuthToken }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<PasswordStep
|
<PasswordStep
|
||||||
providerAuthToken={providerAuthToken}
|
providerAuthToken={providerAuthToken}
|
||||||
email={email}
|
email={username}
|
||||||
password={password}
|
password={password}
|
||||||
setPassword={setPassword}
|
setPassword={setPassword}
|
||||||
setStep={setStep}
|
setStep={setStep}
|
||||||
@@ -45,7 +45,7 @@ export const LoginSSO = ({ providerAuthToken }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<MFAStep
|
<MFAStep
|
||||||
providerAuthToken={providerAuthToken}
|
providerAuthToken={providerAuthToken}
|
||||||
email={email}
|
email={username}
|
||||||
password={password}
|
password={password}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
+2
-2
@@ -113,8 +113,8 @@ export const OrgMembersSection = () => {
|
|||||||
/>
|
/>
|
||||||
<DeleteActionModal
|
<DeleteActionModal
|
||||||
isOpen={popUp.removeMember.isOpen}
|
isOpen={popUp.removeMember.isOpen}
|
||||||
title={`Are you sure want to remove member with email ${
|
title={`Are you sure want to remove member with username ${
|
||||||
(popUp?.removeMember?.data as { email: string })?.email || ""
|
(popUp?.removeMember?.data as { username: string })?.username || ""
|
||||||
}?`}
|
}?`}
|
||||||
onChange={(isOpen) => handlePopUpToggle("removeMember", isOpen)}
|
onChange={(isOpen) => handlePopUpToggle("removeMember", isOpen)}
|
||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
|
|||||||
+4
-3
@@ -41,7 +41,7 @@ type Props = {
|
|||||||
popUpName: keyof UsePopUpState<["removeMember", "upgradePlan"]>,
|
popUpName: keyof UsePopUpState<["removeMember", "upgradePlan"]>,
|
||||||
data?: {
|
data?: {
|
||||||
orgMembershipId?: string;
|
orgMembershipId?: string;
|
||||||
email?: string;
|
username?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
) => void;
|
) => void;
|
||||||
@@ -174,6 +174,7 @@ export const OrgMembersTable = ({ handlePopUpOpen, setCompleteInviteLink }: Prop
|
|||||||
filterdUser?.map(
|
filterdUser?.map(
|
||||||
({ user: u, inviteEmail, role, roleId, id: orgMembershipId, status }) => {
|
({ user: u, inviteEmail, role, roleId, id: orgMembershipId, status }) => {
|
||||||
const name = u && u.firstName ? `${u.firstName} ${u.lastName}` : "-";
|
const name = u && u.firstName ? `${u.firstName} ${u.lastName}` : "-";
|
||||||
|
const email = u?.email || inviteEmail;
|
||||||
const username = u?.username ?? inviteEmail ?? "-";
|
const username = u?.username ?? inviteEmail ?? "-";
|
||||||
return (
|
return (
|
||||||
<Tr key={`org-membership-${orgMembershipId}`} className="w-full">
|
<Tr key={`org-membership-${orgMembershipId}`} className="w-full">
|
||||||
@@ -207,7 +208,7 @@ export const OrgMembersTable = ({ handlePopUpOpen, setCompleteInviteLink }: Prop
|
|||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
)}
|
)}
|
||||||
{(status === "invited" || status === "verified") &&
|
{(status === "invited" || status === "verified") && email &&
|
||||||
serverDetails?.emailConfigured && (
|
serverDetails?.emailConfigured && (
|
||||||
<Button
|
<Button
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
@@ -240,7 +241,7 @@ export const OrgMembersTable = ({ handlePopUpOpen, setCompleteInviteLink }: Prop
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpOpen("removeMember", { orgMembershipId, email });
|
handlePopUpOpen("removeMember", { orgMembershipId, username });
|
||||||
}}
|
}}
|
||||||
size="lg"
|
size="lg"
|
||||||
colorSchema="danger"
|
colorSchema="danger"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const SignupSSO = ({
|
|||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
email,
|
username,
|
||||||
organizationName,
|
organizationName,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
@@ -27,7 +27,7 @@ export const SignupSSO = ({
|
|||||||
case 0:
|
case 0:
|
||||||
return (
|
return (
|
||||||
<UserInfoSSOStep
|
<UserInfoSSOStep
|
||||||
email={email}
|
username={username}
|
||||||
name={`${firstName} ${lastName}`}
|
name={`${firstName} ${lastName}`}
|
||||||
providerOrganizationName={organizationName}
|
providerOrganizationName={organizationName}
|
||||||
password={password}
|
password={password}
|
||||||
@@ -39,7 +39,7 @@ export const SignupSSO = ({
|
|||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
<BackupPDFStep
|
<BackupPDFStep
|
||||||
email={email}
|
email={username}
|
||||||
password={password}
|
password={password}
|
||||||
name={`${firstName} ${lastName}`}
|
name={`${firstName} ${lastName}`}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const client = new jsrp.client();
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setStep: (step: number) => void;
|
setStep: (step: number) => void;
|
||||||
email: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
setPassword: (value: string) => void;
|
setPassword: (value: string) => void;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -57,7 +57,7 @@ type Errors = {
|
|||||||
* @param {string} obj.setLastName - function managing the state of user's last name
|
* @param {string} obj.setLastName - function managing the state of user's last name
|
||||||
*/
|
*/
|
||||||
export const UserInfoSSOStep = ({
|
export const UserInfoSSOStep = ({
|
||||||
email,
|
username,
|
||||||
name,
|
name,
|
||||||
providerOrganizationName,
|
providerOrganizationName,
|
||||||
password,
|
password,
|
||||||
@@ -113,7 +113,7 @@ export const UserInfoSSOStep = ({
|
|||||||
|
|
||||||
client.init(
|
client.init(
|
||||||
{
|
{
|
||||||
username: email,
|
username,
|
||||||
password
|
password
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
@@ -156,7 +156,7 @@ export const UserInfoSSOStep = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const response = await completeAccountSignup({
|
const response = await completeAccountSignup({
|
||||||
email,
|
email: username,
|
||||||
firstName: name.split(" ")[0],
|
firstName: name.split(" ")[0],
|
||||||
lastName: name.split(" ").slice(1).join(" "),
|
lastName: name.split(" ").slice(1).join(" "),
|
||||||
protectedKey,
|
protectedKey,
|
||||||
|
|||||||
Reference in New Issue
Block a user