mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #2528 from Infisical/meet/fix-mustache-import-error
fix: change mustache import
This commit is contained in:
4
backend/src/@types/ldif.d.ts
vendored
Normal file
4
backend/src/@types/ldif.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
declare module "ldif" {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Untyped, the function returns `any`.
|
||||||
|
function parse(input: string, ...args: any[]): any;
|
||||||
|
}
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import ldapjs from "ldapjs";
|
import ldapjs from "ldapjs";
|
||||||
import { render } from "mustache";
|
import ldif from "ldif";
|
||||||
|
import mustache from "mustache";
|
||||||
import { customAlphabet } from "nanoid";
|
import { customAlphabet } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
|
||||||
import { LdapSchema, TDynamicProviderFns } from "./models";
|
import { LdapSchema, TDynamicProviderFns } from "./models";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
|
||||||
const ldif = require("ldif");
|
|
||||||
|
|
||||||
const generatePassword = () => {
|
const generatePassword = () => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*$#";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*$#";
|
||||||
@@ -21,7 +19,7 @@ const encodePassword = (password?: string) => {
|
|||||||
const utf16lePassword = Buffer.from(quotedPassword, "utf16le");
|
const utf16lePassword = Buffer.from(quotedPassword, "utf16le");
|
||||||
const base64Password = utf16lePassword.toString("base64");
|
const base64Password = utf16lePassword.toString("base64");
|
||||||
return base64Password;
|
return base64Password;
|
||||||
}
|
};
|
||||||
|
|
||||||
const generateUsername = () => {
|
const generateUsername = () => {
|
||||||
return alphaNumericNanoId(20);
|
return alphaNumericNanoId(20);
|
||||||
@@ -36,16 +34,15 @@ const generateLDIF = ({
|
|||||||
password?: string;
|
password?: string;
|
||||||
ldifTemplate: string;
|
ldifTemplate: string;
|
||||||
}): string => {
|
}): string => {
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
EncodedPassword: encodePassword(password)
|
EncodedPassword: encodePassword(password)
|
||||||
};
|
};
|
||||||
|
|
||||||
const ldif = render(ldifTemplate, data);
|
const renderedLdif = mustache.render(ldifTemplate, data);
|
||||||
|
|
||||||
return ldif;
|
return renderedLdif;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LdapProvider = (): TDynamicProviderFns => {
|
export const LdapProvider = (): TDynamicProviderFns => {
|
||||||
@@ -64,10 +61,10 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
},
|
},
|
||||||
reconnect: true,
|
reconnect: true,
|
||||||
bindDN: providerInputs.binddn,
|
bindDN: providerInputs.binddn,
|
||||||
bindCredentials: providerInputs.bindpass,
|
bindCredentials: providerInputs.bindpass
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("error", (err) => {
|
client.on("error", (err: Error) => {
|
||||||
client.unbind();
|
client.unbind();
|
||||||
reject(new BadRequestError({ message: err.message }));
|
reject(new BadRequestError({ message: err.message }));
|
||||||
});
|
});
|
||||||
@@ -90,30 +87,53 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const executeLdif = async (client: ldapjs.Client, ldif_file: string) => {
|
const executeLdif = async (client: ldapjs.Client, ldif_file: string) => {
|
||||||
let parsedEntries;
|
type TEntry = {
|
||||||
|
dn: string;
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
changes: {
|
||||||
|
operation?: string;
|
||||||
|
attribute: {
|
||||||
|
attribute: string;
|
||||||
|
};
|
||||||
|
value: {
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
values: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Untyped, can be any for ldapjs.Change.modification.values
|
||||||
|
value: any;
|
||||||
|
}[];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
let parsedEntries: TEntry[];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parsedEntries = ldif.parse(ldif_file).entries as any[];
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
|
parsedEntries = ldif.parse(ldif_file).entries as TEntry[];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new BadRequestError({ message: "Invalid LDIF format, refer to the documentation at Dynamic secrets > LDAP > LDIF Entries." });
|
throw new BadRequestError({
|
||||||
|
message: "Invalid LDIF format, refer to the documentation at Dynamic secrets > LDAP > LDIF Entries."
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const dnArray: string[] = [];
|
const dnArray: string[] = [];
|
||||||
|
|
||||||
for (const entry of parsedEntries) {
|
for await (const entry of parsedEntries) {
|
||||||
const { dn } = entry;
|
const { dn } = entry;
|
||||||
let response_dn: string;
|
let responseDn: string;
|
||||||
|
|
||||||
if (entry.type === "add") {
|
if (entry.type === "add") {
|
||||||
const attributes: any = {};
|
const attributes: Record<string, string | string[]> = {};
|
||||||
|
|
||||||
entry.changes.forEach((change: any) => {
|
entry.changes.forEach((change) => {
|
||||||
const attrName = change.attribute.attribute;
|
const attrName = change.attribute.attribute;
|
||||||
const attrValue = change.value.value;
|
const attrValue = change.value.value;
|
||||||
|
|
||||||
attributes[attrName] = Array.isArray(attrValue) ? attrValue : [attrValue];
|
attributes[attrName] = Array.isArray(attrValue) ? attrValue : [attrValue];
|
||||||
});
|
});
|
||||||
|
|
||||||
response_dn = await new Promise((resolve, reject) => {
|
responseDn = await new Promise((resolve, reject) => {
|
||||||
client.add(dn, attributes, (err) => {
|
client.add(dn, attributes, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(new BadRequestError({ message: err.message }));
|
reject(new BadRequestError({ message: err.message }));
|
||||||
@@ -123,21 +143,22 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (entry.type === "modify") {
|
} else if (entry.type === "modify") {
|
||||||
const changes: any = [];
|
const changes: ldapjs.Change[] = [];
|
||||||
|
|
||||||
entry.changes.forEach((change: any) => {
|
entry.changes.forEach((change) => {
|
||||||
changes.push(
|
changes.push(
|
||||||
new ldapjs.Change({
|
new ldapjs.Change({
|
||||||
operation: change.operation || "replace",
|
operation: change.operation || "replace",
|
||||||
modification: {
|
modification: {
|
||||||
type: change.attribute.attribute,
|
type: change.attribute.attribute,
|
||||||
values: change.values.map((value: any) => value.value)
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
values: change.values.map((value) => value.value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
response_dn = await new Promise((resolve, reject) => {
|
responseDn = await new Promise((resolve, reject) => {
|
||||||
client.modify(dn, changes, (err) => {
|
client.modify(dn, changes, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(new BadRequestError({ message: err.message }));
|
reject(new BadRequestError({ message: err.message }));
|
||||||
@@ -147,7 +168,7 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (entry.type === "delete") {
|
} else if (entry.type === "delete") {
|
||||||
response_dn = await new Promise((resolve, reject) => {
|
responseDn = await new Promise((resolve, reject) => {
|
||||||
client.del(dn, (err) => {
|
client.del(dn, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(new BadRequestError({ message: err.message }));
|
reject(new BadRequestError({ message: err.message }));
|
||||||
@@ -161,7 +182,7 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
throw new BadRequestError({ message: `Unsupported operation type ${entry.type}` });
|
throw new BadRequestError({ message: `Unsupported operation type ${entry.type}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
dnArray.push(response_dn);
|
dnArray.push(responseDn);
|
||||||
}
|
}
|
||||||
client.unbind();
|
client.unbind();
|
||||||
return dnArray;
|
return dnArray;
|
||||||
@@ -173,10 +194,10 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
|
|
||||||
const username = generateUsername();
|
const username = generateUsername();
|
||||||
const password = generatePassword();
|
const password = generatePassword();
|
||||||
const ldif = generateLDIF({ username, password, ldifTemplate: providerInputs.creationLdif });
|
const generatedLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.creationLdif });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dnArray = await executeLdif(client, ldif);
|
const dnArray = await executeLdif(client, generatedLdif);
|
||||||
|
|
||||||
return { entityId: username, data: { DN_ARRAY: dnArray, USERNAME: username, PASSWORD: password } };
|
return { entityId: username, data: { DN_ARRAY: dnArray, USERNAME: username, PASSWORD: password } };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user