mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 20:26:44 +00:00
fix: refactor and handle modify
This commit is contained in:
@@ -5,11 +5,10 @@ import { render } from "mustache";
|
|||||||
import { customAlphabet } from "nanoid";
|
import { customAlphabet } from "nanoid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { logger } from "@app/lib/logger";
|
|
||||||
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 ldif = require("ldif");
|
||||||
|
|
||||||
const generatePassword = () => {
|
const generatePassword = () => {
|
||||||
@@ -17,8 +16,15 @@ const generatePassword = () => {
|
|||||||
return customAlphabet(charset, 64)();
|
return customAlphabet(charset, 64)();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const encodePassword = (password?: string) => {
|
||||||
|
const quotedPassword = `"${password}"`;
|
||||||
|
const utf16lePassword = Buffer.from(quotedPassword, "utf16le");
|
||||||
|
const base64Password = utf16lePassword.toString("base64");
|
||||||
|
return base64Password;
|
||||||
|
}
|
||||||
|
|
||||||
const generateUsername = () => {
|
const generateUsername = () => {
|
||||||
return alphaNumericNanoId(32);
|
return alphaNumericNanoId(20);
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateLDIF = ({
|
const generateLDIF = ({
|
||||||
@@ -30,9 +36,11 @@ 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)
|
||||||
};
|
};
|
||||||
|
|
||||||
const ldif = render(ldifTemplate, data);
|
const ldif = render(ldifTemplate, data);
|
||||||
@@ -47,7 +55,7 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getClient = async (providerInputs: z.infer<typeof LdapSchema>): Promise<ldapjs.Client> => {
|
const getClient = async (providerInputs: z.infer<typeof LdapSchema>): Promise<ldapjs.Client> => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve, reject) => {
|
||||||
const client = ldapjs.createClient({
|
const client = ldapjs.createClient({
|
||||||
url: providerInputs.url,
|
url: providerInputs.url,
|
||||||
tlsOptions: {
|
tlsOptions: {
|
||||||
@@ -57,18 +65,17 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
reconnect: true,
|
reconnect: true,
|
||||||
bindDN: providerInputs.binddn,
|
bindDN: providerInputs.binddn,
|
||||||
bindCredentials: providerInputs.bindpass,
|
bindCredentials: providerInputs.bindpass,
|
||||||
log: logger
|
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("error", (err) => {
|
client.on("error", (err) => {
|
||||||
client.unbind();
|
client.unbind();
|
||||||
throw new Error(err.message);
|
reject(new BadRequestError({ message: err.message }));
|
||||||
});
|
});
|
||||||
|
|
||||||
client.bind(providerInputs.binddn, providerInputs.bindpass, (err) => {
|
client.bind(providerInputs.binddn, providerInputs.bindpass, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
client.unbind();
|
client.unbind();
|
||||||
throw new Error(err.message);
|
reject(new BadRequestError({ message: err.message }));
|
||||||
} else {
|
} else {
|
||||||
resolve(client);
|
resolve(client);
|
||||||
}
|
}
|
||||||
@@ -100,10 +107,10 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
attributes[attrName] = Array.isArray(attrValue) ? attrValue : [attrValue];
|
attributes[attrName] = Array.isArray(attrValue) ? attrValue : [attrValue];
|
||||||
});
|
});
|
||||||
|
|
||||||
response_dn = await new Promise((resolve) => {
|
response_dn = await new Promise((resolve, reject) => {
|
||||||
client.add(dn, attributes, (err) => {
|
client.add(dn, attributes, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error(err.message);
|
reject(new BadRequestError({ message: err.message }));
|
||||||
} else {
|
} else {
|
||||||
resolve(dn);
|
resolve(dn);
|
||||||
}
|
}
|
||||||
@@ -117,28 +124,27 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
new ldapjs.Change({
|
new ldapjs.Change({
|
||||||
operation: change.operation || "replace",
|
operation: change.operation || "replace",
|
||||||
modification: {
|
modification: {
|
||||||
[change.attribute.attribute]: Array.isArray(change.value.value)
|
type: change.attribute.attribute,
|
||||||
? change.value.value
|
values: change.values.map((value: any) => value.value)
|
||||||
: [change.value.value]
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
response_dn = await new Promise((resolve) => {
|
response_dn = await new Promise((resolve, reject) => {
|
||||||
client.modify(dn, changes, (err) => {
|
client.modify(dn, changes, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error(err.message);
|
reject(new BadRequestError({ message: err.message }));
|
||||||
} else {
|
} else {
|
||||||
resolve(dn);
|
resolve(dn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (entry.type === "delete") {
|
} else if (entry.type === "delete") {
|
||||||
response_dn = await new Promise((resolve) => {
|
response_dn = await new Promise((resolve, reject) => {
|
||||||
client.del(dn, (err) => {
|
client.del(dn, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new Error(err.message);
|
reject(new BadRequestError({ message: err.message }));
|
||||||
} else {
|
} else {
|
||||||
resolve(dn);
|
resolve(dn);
|
||||||
}
|
}
|
||||||
@@ -168,11 +174,11 @@ export const LdapProvider = (): TDynamicProviderFns => {
|
|||||||
|
|
||||||
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) {
|
||||||
|
if (providerInputs.rollbackLdif) {
|
||||||
const rollbackLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.rollbackLdif });
|
const rollbackLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.rollbackLdif });
|
||||||
|
|
||||||
await executeLdif(client, rollbackLdif);
|
await executeLdif(client, rollbackLdif);
|
||||||
|
}
|
||||||
throw new Error((err as Error).message);
|
throw new BadRequestError({ message: (err as Error).message });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -180,9 +180,9 @@ export const LdapSchema = z.object({
|
|||||||
bindpass: z.string().trim().min(1),
|
bindpass: z.string().trim().min(1),
|
||||||
ca: z.string().optional(),
|
ca: z.string().optional(),
|
||||||
|
|
||||||
creationLdif: z.string().trim().min(1),
|
creationLdif: z.string().min(1),
|
||||||
revocationLdif: z.string().trim().min(1),
|
revocationLdif: z.string().min(1),
|
||||||
rollbackLdif: z.string().trim().min(1)
|
rollbackLdif: z.string().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
export enum DynamicSecretProviders {
|
export enum DynamicSecretProviders {
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ export type TDynamicSecretProvider =
|
|||||||
ca?: string | undefined;
|
ca?: string | undefined;
|
||||||
creationLdif: string;
|
creationLdif: string;
|
||||||
revocationLdif: string;
|
revocationLdif: string;
|
||||||
rollbackLdif: string;
|
rollbackLdif?: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
;
|
;
|
||||||
|
|||||||
+9
-13
@@ -16,9 +16,9 @@ const formSchema = z.object({
|
|||||||
bindpass: z.string().trim().min(1),
|
bindpass: z.string().trim().min(1),
|
||||||
ca: z.string().optional(),
|
ca: z.string().optional(),
|
||||||
|
|
||||||
creationLdif: z.string().trim().min(1),
|
creationLdif: z.string().min(1),
|
||||||
revocationLdif: z.string().trim().min(1),
|
revocationLdif: z.string().min(1),
|
||||||
rollbackLdif: z.string().trim().min(1),
|
rollbackLdif: z.string().optional()
|
||||||
}),
|
}),
|
||||||
|
|
||||||
defaultTTL: z.string().superRefine((val, ctx) => {
|
defaultTTL: z.string().superRefine((val, ctx) => {
|
||||||
@@ -54,15 +54,13 @@ type Props = {
|
|||||||
environment: string;
|
environment: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LdapInputForm = (
|
export const LdapInputForm = ({
|
||||||
{
|
|
||||||
onCompleted,
|
onCompleted,
|
||||||
onCancel,
|
onCancel,
|
||||||
secretPath,
|
secretPath,
|
||||||
projectSlug,
|
projectSlug,
|
||||||
environment,
|
environment
|
||||||
}: Props
|
}: Props) => {
|
||||||
) => {
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
@@ -78,7 +76,7 @@ export const LdapInputForm = (
|
|||||||
creationLdif: "",
|
creationLdif: "",
|
||||||
revocationLdif: "",
|
revocationLdif: "",
|
||||||
rollbackLdif: ""
|
rollbackLdif: ""
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -203,7 +201,7 @@ export const LdapInputForm = (
|
|||||||
isError={Boolean(error?.message)}
|
isError={Boolean(error?.message)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
>
|
>
|
||||||
<Input {...field} />
|
<Input {...field} type="password" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@@ -263,8 +261,6 @@ export const LdapInputForm = (
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -279,5 +275,5 @@ export const LdapInputForm = (
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
+9
-21
@@ -16,9 +16,9 @@ const formSchema = z.object({
|
|||||||
binddn: z.string().trim().min(1),
|
binddn: z.string().trim().min(1),
|
||||||
bindpass: z.string().trim().min(1),
|
bindpass: z.string().trim().min(1),
|
||||||
ca: z.string().optional(),
|
ca: z.string().optional(),
|
||||||
creationLdif: z.string().trim().min(1),
|
creationLdif: z.string().min(1),
|
||||||
revocationLdif: z.string().trim().min(1),
|
revocationLdif: z.string().min(1),
|
||||||
rollbackLdif: z.string().trim().min(1),
|
rollbackLdif: z.string().optional()
|
||||||
})
|
})
|
||||||
.partial(),
|
.partial(),
|
||||||
defaultTTL: z.string().superRefine((val, ctx) => {
|
defaultTTL: z.string().superRefine((val, ctx) => {
|
||||||
@@ -166,11 +166,7 @@ export const EditDynamicSecretLdapForm = ({
|
|||||||
control={control}
|
control={control}
|
||||||
name="inputs.url"
|
name="inputs.url"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl label="URL" isError={Boolean(error)} errorText={error?.message}>
|
||||||
label="URL"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} />
|
<Input {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
@@ -179,11 +175,7 @@ export const EditDynamicSecretLdapForm = ({
|
|||||||
control={control}
|
control={control}
|
||||||
name="inputs.binddn"
|
name="inputs.binddn"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl label="Bind DN" isError={Boolean(error)} errorText={error?.message}>
|
||||||
label="Bind DN"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<Input {...field} />
|
<Input {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
@@ -197,7 +189,7 @@ export const EditDynamicSecretLdapForm = ({
|
|||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
>
|
>
|
||||||
<Input {...field} />
|
<Input {...field} type="password" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@@ -205,11 +197,7 @@ export const EditDynamicSecretLdapForm = ({
|
|||||||
control={control}
|
control={control}
|
||||||
name="inputs.ca"
|
name="inputs.ca"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl label="CA" isError={Boolean(error)} errorText={error?.message}>
|
||||||
label="CA"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
|
||||||
>
|
|
||||||
<TextArea {...field} />
|
<TextArea {...field} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
@@ -264,5 +252,5 @@ export const EditDynamicSecretLdapForm = ({
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user