fix: refactor and handle modify

This commit is contained in:
Meet
2024-10-02 20:51:02 +05:30
parent 27afad583b
commit e0199084ad
5 changed files with 434 additions and 444 deletions
@@ -5,11 +5,10 @@ import { render } from "mustache";
import { customAlphabet } from "nanoid";
import { z } from "zod";
import { logger } from "@app/lib/logger";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { LdapSchema, TDynamicProviderFns } from "./models";
import { BadRequestError } from "@app/lib/errors";
const ldif = require("ldif");
const generatePassword = () => {
@@ -17,8 +16,15 @@ const generatePassword = () => {
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 = () => {
return alphaNumericNanoId(32);
return alphaNumericNanoId(20);
};
const generateLDIF = ({
@@ -30,9 +36,11 @@ const generateLDIF = ({
password?: string;
ldifTemplate: string;
}): string => {
const data = {
Username: username,
Password: password
Password: password,
EncodedPassword: encodePassword(password)
};
const ldif = render(ldifTemplate, data);
@@ -47,7 +55,7 @@ export const LdapProvider = (): TDynamicProviderFns => {
};
const getClient = async (providerInputs: z.infer<typeof LdapSchema>): Promise<ldapjs.Client> => {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
const client = ldapjs.createClient({
url: providerInputs.url,
tlsOptions: {
@@ -57,18 +65,17 @@ export const LdapProvider = (): TDynamicProviderFns => {
reconnect: true,
bindDN: providerInputs.binddn,
bindCredentials: providerInputs.bindpass,
log: logger
});
client.on("error", (err) => {
client.unbind();
throw new Error(err.message);
reject(new BadRequestError({ message: err.message }));
});
client.bind(providerInputs.binddn, providerInputs.bindpass, (err) => {
if (err) {
client.unbind();
throw new Error(err.message);
reject(new BadRequestError({ message: err.message }));
} else {
resolve(client);
}
@@ -100,10 +107,10 @@ export const LdapProvider = (): TDynamicProviderFns => {
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) => {
if (err) {
throw new Error(err.message);
reject(new BadRequestError({ message: err.message }));
} else {
resolve(dn);
}
@@ -117,28 +124,27 @@ export const LdapProvider = (): TDynamicProviderFns => {
new ldapjs.Change({
operation: change.operation || "replace",
modification: {
[change.attribute.attribute]: Array.isArray(change.value.value)
? change.value.value
: [change.value.value]
type: change.attribute.attribute,
values: change.values.map((value: any) => value.value)
}
})
);
});
response_dn = await new Promise((resolve) => {
response_dn = await new Promise((resolve, reject) => {
client.modify(dn, changes, (err) => {
if (err) {
throw new Error(err.message);
reject(new BadRequestError({ message: err.message }));
} else {
resolve(dn);
}
});
});
} else if (entry.type === "delete") {
response_dn = await new Promise((resolve) => {
response_dn = await new Promise((resolve, reject) => {
client.del(dn, (err) => {
if (err) {
throw new Error(err.message);
reject(new BadRequestError({ message: err.message }));
} else {
resolve(dn);
}
@@ -168,11 +174,11 @@ export const LdapProvider = (): TDynamicProviderFns => {
return { entityId: username, data: { DN_ARRAY: dnArray, USERNAME: username, PASSWORD: password } };
} catch (err) {
if (providerInputs.rollbackLdif) {
const rollbackLdif = generateLDIF({ username, password, ldifTemplate: providerInputs.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),
ca: z.string().optional(),
creationLdif: z.string().trim().min(1),
revocationLdif: z.string().trim().min(1),
rollbackLdif: z.string().trim().min(1)
creationLdif: z.string().min(1),
revocationLdif: z.string().min(1),
rollbackLdif: z.string().optional()
});
export enum DynamicSecretProviders {
@@ -199,7 +199,7 @@ export type TDynamicSecretProvider =
ca?: string | undefined;
creationLdif: string;
revocationLdif: string;
rollbackLdif: string;
rollbackLdif?: string;
};
};
;
@@ -16,9 +16,9 @@ const formSchema = z.object({
bindpass: z.string().trim().min(1),
ca: z.string().optional(),
creationLdif: z.string().trim().min(1),
revocationLdif: z.string().trim().min(1),
rollbackLdif: z.string().trim().min(1),
creationLdif: z.string().min(1),
revocationLdif: z.string().min(1),
rollbackLdif: z.string().optional()
}),
defaultTTL: z.string().superRefine((val, ctx) => {
@@ -54,15 +54,13 @@ type Props = {
environment: string;
};
export const LdapInputForm = (
{
export const LdapInputForm = ({
onCompleted,
onCancel,
secretPath,
projectSlug,
environment,
}: Props
) => {
environment
}: Props) => {
const {
control,
formState: { isSubmitting },
@@ -78,7 +76,7 @@ export const LdapInputForm = (
creationLdif: "",
revocationLdif: "",
rollbackLdif: ""
},
}
}
});
@@ -203,7 +201,7 @@ export const LdapInputForm = (
isError={Boolean(error?.message)}
errorText={error?.message}
>
<Input {...field} />
<Input {...field} type="password" />
</FormControl>
)}
/>
@@ -263,8 +261,6 @@ export const LdapInputForm = (
</FormControl>
)}
/>
</div>
</div>
</div>
@@ -279,5 +275,5 @@ export const LdapInputForm = (
</Button>
</div>
</form>
)
);
};
@@ -16,9 +16,9 @@ const formSchema = z.object({
binddn: z.string().trim().min(1),
bindpass: z.string().trim().min(1),
ca: z.string().optional(),
creationLdif: z.string().trim().min(1),
revocationLdif: z.string().trim().min(1),
rollbackLdif: z.string().trim().min(1),
creationLdif: z.string().min(1),
revocationLdif: z.string().min(1),
rollbackLdif: z.string().optional()
})
.partial(),
defaultTTL: z.string().superRefine((val, ctx) => {
@@ -166,11 +166,7 @@ export const EditDynamicSecretLdapForm = ({
control={control}
name="inputs.url"
render={({ field, fieldState: { error } }) => (
<FormControl
label="URL"
isError={Boolean(error)}
errorText={error?.message}
>
<FormControl label="URL" isError={Boolean(error)} errorText={error?.message}>
<Input {...field} />
</FormControl>
)}
@@ -179,11 +175,7 @@ export const EditDynamicSecretLdapForm = ({
control={control}
name="inputs.binddn"
render={({ field, fieldState: { error } }) => (
<FormControl
label="Bind DN"
isError={Boolean(error)}
errorText={error?.message}
>
<FormControl label="Bind DN" isError={Boolean(error)} errorText={error?.message}>
<Input {...field} />
</FormControl>
)}
@@ -197,7 +189,7 @@ export const EditDynamicSecretLdapForm = ({
isError={Boolean(error)}
errorText={error?.message}
>
<Input {...field} />
<Input {...field} type="password" />
</FormControl>
)}
/>
@@ -205,11 +197,7 @@ export const EditDynamicSecretLdapForm = ({
control={control}
name="inputs.ca"
render={({ field, fieldState: { error } }) => (
<FormControl
label="CA"
isError={Boolean(error)}
errorText={error?.message}
>
<FormControl label="CA" isError={Boolean(error)} errorText={error?.message}>
<TextArea {...field} />
</FormControl>
)}
@@ -264,5 +252,5 @@ export const EditDynamicSecretLdapForm = ({
</div>
</form>
</div>
)
}
);
};