mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 04:27:29 +00:00
Minor LDAP patches, docs for JumpCloud LDAP
This commit is contained in:
@@ -17,8 +17,8 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
t.string("encryptedBindPass");
|
t.string("encryptedBindPass");
|
||||||
t.string("bindPassIV");
|
t.string("bindPassIV");
|
||||||
t.string("bindPassTag");
|
t.string("bindPassTag");
|
||||||
t.text("searchBase").notNullable();
|
t.string("searchBase").notNullable();
|
||||||
t.string("encryptedCACert");
|
t.text("encryptedCACert");
|
||||||
t.string("caCertIV");
|
t.string("caCertIV");
|
||||||
t.string("caCertTag");
|
t.string("caCertTag");
|
||||||
t.timestamps(true, true, true);
|
t.timestamps(true, true, true);
|
||||||
@@ -43,7 +43,7 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
await knex.schema.alterTable(TableName.Users, (t) => {
|
await knex.schema.alterTable(TableName.Users, (t) => {
|
||||||
t.dropColumn("username");
|
t.dropColumn("username");
|
||||||
t.dropColumn("orgId");
|
t.dropColumn("orgId");
|
||||||
t.string("email").notNullable().alter();
|
// t.string("email").notNullable().alter();
|
||||||
});
|
});
|
||||||
await dropOnUpdateTrigger(knex, TableName.LdapConfig);
|
await dropOnUpdateTrigger(knex, TableName.LdapConfig);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
return cb(null, { isUserCompleted, providerAuthToken });
|
return cb(null, { isUserCompleted, providerAuthToken });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
return cb(null, false);
|
return cb(err, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -57,9 +57,9 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
preValidation: passport.authenticate("ldapauth", {
|
preValidation: passport.authenticate("ldapauth", {
|
||||||
session: false,
|
session: false
|
||||||
failureFlash: true,
|
// failureFlash: true,
|
||||||
failureRedirect: "/login/provider/error"
|
// failureRedirect: "/login/provider/error"
|
||||||
// this is due to zod type difference
|
// this is due to zod type difference
|
||||||
}) as any,
|
}) as any,
|
||||||
handler: (req, res) => {
|
handler: (req, res) => {
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ export const userServiceFactory = ({ userDAL }: TUserServiceFactoryDep) => {
|
|||||||
const user = await userDAL.findById(userId);
|
const user = await userDAL.findById(userId);
|
||||||
if (!user) throw new BadRequestError({ name: "Update auth methods" });
|
if (!user) throw new BadRequestError({ name: "Update auth methods" });
|
||||||
|
|
||||||
|
if (user.authMethods?.includes(AuthMethod.LDAP))
|
||||||
|
throw new BadRequestError({ message: "LDAP auth method cannot be updated", name: "Update auth methods" });
|
||||||
|
|
||||||
|
if (authMethods.includes(AuthMethod.LDAP))
|
||||||
|
throw new BadRequestError({ message: "LDAP auth method cannot be updated", name: "Update auth methods" });
|
||||||
|
|
||||||
const updatedUser = await userDAL.updateById(userId, { authMethods });
|
const updatedUser = await userDAL.updateById(userId, { authMethods });
|
||||||
return updatedUser;
|
return updatedUser;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
title: "JumpCloud LDAP"
|
||||||
|
description: "Configure JumpCloud LDAP for Logging into Infisical"
|
||||||
|
---
|
||||||
|
|
||||||
|
<Info>
|
||||||
|
LDAP is a paid feature.
|
||||||
|
|
||||||
|
If you're using Infisical Cloud, then it is available under the **Enterprise Tier**. If you're self-hosting Infisical,
|
||||||
|
then you should contact [email protected] to purchase an enterprise license to use it.
|
||||||
|
</Info>
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
<Step title="Prepare LDAP in JumpCloud">
|
||||||
|
In JumpCloud, head to USER MANAGEMENT > Users and create a new user via the **Manual user entry** option. This user
|
||||||
|
will be used as a privileged service account to facilitate Infisical's ability to bind/search the LDAP directory.
|
||||||
|
|
||||||
|
When creating the user, input their **First Name**, **Last Name**, **Username** (required), **Company Email** (required), and **Description**.
|
||||||
|
Also, create a password for the user.
|
||||||
|
|
||||||
|
Next, under User Security Settings and Permissions > Permission Settings, check the box next to **Enable as LDAP Bind DN**.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</Step>
|
||||||
|
<Step title="Prepare the LDAP configuration in Infisical">
|
||||||
|
In Infisical, head to your Organization Settings > Authentication > LDAP Configuration and select **Set up LDAP**.
|
||||||
|
|
||||||
|
Next, input your JumpCloud LDAP server settings.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Here's some guidance for each field:
|
||||||
|
|
||||||
|
- URL: The LDAP server to connect to (`ldaps://ldap.jumpcloud.com:636`).
|
||||||
|
- Bind DN: The distinguished name of object to bind when performing the user search (`uid=<ldap-user-username>,ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
||||||
|
- Bind Pass: The password to use along with `Bind DN` when performing the user search.
|
||||||
|
- Search Base / User DN: Base DN under which to perform user search (`ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
||||||
|
- CA Certificate: The CA certificate to use when verifying the LDAP server certificate (instructions to obtain the certificate for JumpCloud [here](https://jumpcloud.com/support/connect-to-ldap-with-tls-ssl)).
|
||||||
|
|
||||||
|
<Tip>
|
||||||
|
When filling out the **Bind DN** and **Bind Pass** fields, refer to the username and password of the user created in Step 1.
|
||||||
|
|
||||||
|
Also, for the **Bind DN** and **Search Base / User DN** fields, you'll want to use the organization ID that appears
|
||||||
|
in your LDAP instance **ORG DN**.
|
||||||
|
</Tip>
|
||||||
|
</Step>
|
||||||
|
<Step title="Enable LDAP in Infisical">
|
||||||
|
Enabling LDAP allows members in your organization to log into Infisical via LDAP.
|
||||||
|
|
||||||
|

|
||||||
|
</Step>
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
- [JumpCloud Cloud LDAP Guide](https://jumpcloud.com/support/use-cloud-ldap)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: "LDAP Overview"
|
||||||
|
description: "Log in to Infisical with LDAP"
|
||||||
|
---
|
||||||
|
<Info>
|
||||||
|
LDAP is a paid feature.
|
||||||
|
|
||||||
|
If you're using Infisical Cloud, then it is available under the **Enterprise Tier**. If you're self-hosting Infisical,
|
||||||
|
then you should contact [email protected] to purchase an enterprise license to use it.
|
||||||
|
</Info>
|
||||||
|
|
||||||
|
You can configure your organization in Infisical to have members authenticate with the platform via [LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol)
|
||||||
|
|
||||||
|
To note, configuring LDAP retains the end-to-end encrypted architecture of Infisical because we decouple the authentication and decryption steps; the LDAP server cannot and will not have access to the decryption key needed to decrypt your secrets.
|
||||||
|
|
||||||
|
LDAP providers:
|
||||||
|
|
||||||
|
- [JumpCloud LDAP](/documentation/platform/ldap/jumpcloud)
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 436 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 351 KiB |
+7
-1
@@ -149,7 +149,13 @@
|
|||||||
"documentation/platform/sso/jumpcloud"
|
"documentation/platform/sso/jumpcloud"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"documentation/platform/ldap",
|
{
|
||||||
|
"group": "LDAP",
|
||||||
|
"pages": [
|
||||||
|
"documentation/platform/ldap/overview",
|
||||||
|
"documentation/platform/ldap/jumpcloud"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"group": "SCIM",
|
"group": "SCIM",
|
||||||
"pages": [
|
"pages": [
|
||||||
|
|||||||
@@ -7,13 +7,15 @@ export enum AuthMethod {
|
|||||||
GITLAB = "gitlab",
|
GITLAB = "gitlab",
|
||||||
OKTA_SAML = "okta-saml",
|
OKTA_SAML = "okta-saml",
|
||||||
AZURE_SAML = "azure-saml",
|
AZURE_SAML = "azure-saml",
|
||||||
JUMPCLOUD_SAML = "jumpcloud-saml"
|
JUMPCLOUD_SAML = "jumpcloud-saml",
|
||||||
|
LDAP = "ldap"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
email: string;
|
username: string;
|
||||||
|
email?: string;
|
||||||
superAdmin: boolean;
|
superAdmin: boolean;
|
||||||
firstName?: string;
|
firstName?: string;
|
||||||
lastName?: string;
|
lastName?: string;
|
||||||
|
|||||||
+1
-3
@@ -48,8 +48,6 @@ export const ChangePasswordSection = () => {
|
|||||||
|
|
||||||
const onFormSubmit = async ({ oldPassword, newPassword }: FormData) => {
|
const onFormSubmit = async ({ oldPassword, newPassword }: FormData) => {
|
||||||
try {
|
try {
|
||||||
if (!user?.email) return;
|
|
||||||
|
|
||||||
const errorCheck = await checkPassword({
|
const errorCheck = await checkPassword({
|
||||||
password: newPassword,
|
password: newPassword,
|
||||||
setErrors
|
setErrors
|
||||||
@@ -59,7 +57,7 @@ export const ChangePasswordSection = () => {
|
|||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
await attemptChangePassword({
|
await attemptChangePassword({
|
||||||
email: user.email,
|
email: user.username,
|
||||||
currentPassword: oldPassword,
|
currentPassword: oldPassword,
|
||||||
newPassword
|
newPassword
|
||||||
});
|
});
|
||||||
|
|||||||
+12
-2
@@ -1,12 +1,22 @@
|
|||||||
|
import {
|
||||||
|
useGetUser
|
||||||
|
} from "@app/hooks/api";
|
||||||
|
import { AuthMethod } from "@app/hooks/api/users/types";
|
||||||
|
|
||||||
import { AuthMethodSection } from "../AuthMethodSection";
|
import { AuthMethodSection } from "../AuthMethodSection";
|
||||||
import { ChangePasswordSection } from "../ChangePasswordSection";
|
import { ChangePasswordSection } from "../ChangePasswordSection";
|
||||||
import { MFASection } from "../SecuritySection";
|
import { MFASection } from "../SecuritySection";
|
||||||
|
|
||||||
export const PersonalAuthTab = () => {
|
export const PersonalAuthTab = () => {
|
||||||
|
const { data: user } = useGetUser();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<MFASection />
|
{user && !user.authMethods.includes(AuthMethod.LDAP) && (
|
||||||
<AuthMethodSection />
|
<>
|
||||||
|
<MFASection />
|
||||||
|
<AuthMethodSection />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<ChangePasswordSection />
|
<ChangePasswordSection />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
useGetUser,
|
useGetUser,
|
||||||
useUpdateMfaEnabled} from "@app/hooks/api";
|
useUpdateMfaEnabled} from "@app/hooks/api";
|
||||||
import { useFetchServerStatus } from "@app/hooks/api/serverDetails";
|
import { useFetchServerStatus } from "@app/hooks/api/serverDetails";
|
||||||
|
import { AuthMethod } from "@app/hooks/api/users/types";
|
||||||
import { usePopUp } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
export const MFASection = () => {
|
export const MFASection = () => {
|
||||||
@@ -18,6 +19,15 @@ export const MFASection = () => {
|
|||||||
|
|
||||||
const toggleMfa = async (state: boolean) => {
|
const toggleMfa = async (state: boolean) => {
|
||||||
try {
|
try {
|
||||||
|
if (!user) return;
|
||||||
|
if (user.authMethods.includes(AuthMethod.LDAP)) {
|
||||||
|
createNotification({
|
||||||
|
text: "Two-factor authentication is not available for LDAP users.",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const newUser = await mutateAsync({
|
const newUser = await mutateAsync({
|
||||||
isMfaEnabled: state
|
isMfaEnabled: state
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user