chore: Refactor and improve UI

This commit is contained in:
Meet
2024-09-20 12:29:26 +05:30
parent 040fa511f6
commit 10574bfe26
7 changed files with 169 additions and 215 deletions
@@ -3,10 +3,7 @@ import ms from "ms";
import { z } from "zod";
import { DynamicSecretLeasesSchema } from "@app/db/schemas";
import {
DynamicSecretDataFetchTypes,
DynamicSecretProviderSchema
} from "@app/ee/services/dynamic-secret/providers/models";
import { DynamicSecretProviderSchema } from "@app/ee/services/dynamic-secret/providers/models";
import { DYNAMIC_SECRETS } from "@app/lib/api-docs";
import { daysToMillisecond } from "@app/lib/dates";
import { removeTrailingSlash } from "@app/lib/fn";
@@ -82,26 +79,33 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
server.route({
method: "POST",
url: "/fetch-provider-data",
url: "/entra-id/users",
config: {
rateLimit: readLimit
},
schema: {
body: z.object({
dataFetchType: z.string().min(1).describe("Type of data to fetch"),
provider: DynamicSecretProviderSchema.describe(DYNAMIC_SECRETS.CREATE.provider)
tenantId: z.string().min(1).describe("The tenant ID of the Azure Entra ID"),
applicationId: z.string().min(1).describe("The application ID of the Azure Entra ID App Registration"),
clientSecret: z.string().min(1).describe("The client secret of the Azure Entra ID App Registration")
}),
response: {
200: z.object({
data: z.unknown()
})
200: z
.object({
name: z.string().min(1).describe("The name of the user"),
id: z.string().min(1).describe("The ID of the user"),
email: z.string().min(1).describe("The email of the user")
})
.array()
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const dataFetchType =
DynamicSecretDataFetchTypes[req.body.dataFetchType as keyof typeof DynamicSecretDataFetchTypes];
const data = await server.services.dynamicSecret.fetchData({ provider: req.body.provider, dataFetchType });
const data = await server.services.dynamicSecret.fetchAzureEntraIdUsers({
tenantId: req.body.tenantId,
applicationId: req.body.applicationId,
clientSecret: req.body.clientSecret
});
return data;
}
});
@@ -17,10 +17,10 @@ import {
TCreateDynamicSecretDTO,
TDeleteDynamicSecretDTO,
TDetailsDynamicSecretDTO,
TDynamicSecretsFetchDataDTO,
TListDynamicSecretsDTO,
TUpdateDynamicSecretDTO
} from "./dynamic-secret-types";
import { AzureEntraIDProvider } from "./providers/azure-entra-id";
import { DynamicSecretProviders, TDynamicProviderFns } from "./providers/models";
type TDynamicSecretServiceFactoryDep = {
@@ -333,12 +333,21 @@ export const dynamicSecretServiceFactory = ({
return dynamicSecretCfg;
};
const fetchData = async ({ provider, dataFetchType }: TDynamicSecretsFetchDataDTO) => {
const selectedProvider = dynamicSecretProviders[provider.type];
if (selectedProvider.fetchData) {
const data = selectedProvider.fetchData(provider.inputs, dataFetchType);
return data;
}
const fetchAzureEntraIdUsers = async ({
tenantId,
applicationId,
clientSecret
}: {
tenantId: string;
applicationId: string;
clientSecret: string;
}) => {
const azureEntraIdUsers = await AzureEntraIDProvider().fetchAzureEntraIdUsers(
tenantId,
applicationId,
clientSecret
);
return azureEntraIdUsers;
};
return {
@@ -347,6 +356,6 @@ export const dynamicSecretServiceFactory = ({
deleteByName,
getDetails,
list,
fetchData
fetchAzureEntraIdUsers
};
};
@@ -3,7 +3,7 @@ import { customAlphabet } from "nanoid";
import { BadRequestError } from "@app/lib/errors";
import { AzureEntraIDSchema, DynamicSecretDataFetchTypes, TDynamicProviderFns } from "./models";
import { AzureEntraIDSchema, TDynamicProviderFns } from "./models";
const MSFT_GRAPH_API_URL = "https://graph.microsoft.com/v1.0/";
const MSFT_LOGIN_URL = "https://login.microsoftonline.com";
@@ -13,7 +13,11 @@ const generatePassword = () => {
return customAlphabet(charset, 64)();
};
export const AzureEntraIDProvider = (): TDynamicProviderFns => {
type User = { name: string; id: string; email: string };
export const AzureEntraIDProvider = (): TDynamicProviderFns & {
fetchAzureEntraIdUsers: (tenantId: string, applicationId: string, clientSecret: string) => Promise<User[]>;
} => {
const validateProviderInputs = async (inputs: unknown) => {
const providerInputs = await AzureEntraIDSchema.parseAsync(inputs);
return providerInputs;
@@ -93,51 +97,42 @@ export const AzureEntraIDProvider = (): TDynamicProviderFns => {
return { entityId };
};
const fetchData = async (inputs: unknown, toFetch: DynamicSecretDataFetchTypes) => {
const providerInputs = await validateProviderInputs(inputs);
const data = await getToken(providerInputs.tenantId, providerInputs.applicationId, providerInputs.clientSecret);
const fetchAzureEntraIdUsers = async (tenantId: string, applicationId: string, clientSecret: string) => {
const data = await getToken(tenantId, applicationId, clientSecret);
if (!data.success) {
throw new BadRequestError({ message: "Failed to authorize to Microsoft Entra ID" });
}
switch (toFetch) {
case DynamicSecretDataFetchTypes.Users: {
const response = await axios.get<{ value: [{ displayName: string; id: string; userPrincipalName: string }] }>(
`${MSFT_GRAPH_API_URL}/users`,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Bearer ${data.token}`
}
}
);
const users = response.data.value.map(
(user: { displayName: string; id: string; userPrincipalName: string }) => {
return {
name: user.displayName,
id: user.id,
email: user.userPrincipalName
};
}
);
return {
data: {
users
}
};
const response = await axios.get<{ value: [{ id: string; displayName: string; userPrincipalName: string }] }>(
`${MSFT_GRAPH_API_URL}/users`,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Bearer ${data.token}`
}
}
);
default:
throw new BadRequestError({ message: "Unknown data to fetch" });
if (response.status !== 200) {
throw new BadRequestError({ message: "Failed to fetch users" });
}
const users = response.data.value.map((user) => {
return {
name: user.displayName,
id: user.id,
email: user.userPrincipalName
};
});
return users;
};
return {
validateProviderInputs,
validateConnection,
create,
revoke,
renew,
fetchData
fetchAzureEntraIdUsers
};
};
@@ -187,10 +187,6 @@ export enum DynamicSecretProviders {
AzureEntraID = "azure-entra-id"
}
export enum DynamicSecretDataFetchTypes {
Users = "users"
}
export const DynamicSecretProviderSchema = z.discriminatedUnion("type", [
z.object({ type: z.literal(DynamicSecretProviders.SqlDatabase), inputs: DynamicSecretSqlDBSchema }),
z.object({ type: z.literal(DynamicSecretProviders.Cassandra), inputs: DynamicSecretCassandraSchema }),
@@ -210,5 +206,4 @@ export type TDynamicProviderFns = {
validateProviderInputs: (inputs: object) => Promise<unknown>;
revoke: (inputs: unknown, entityId: string) => Promise<{ entityId: string }>;
renew: (inputs: unknown, entityId: string, expireAt: number) => Promise<{ entityId: string }>;
fetchData?: (inputs: unknown, toFetch: DynamicSecretDataFetchTypes) => Promise<{ data: unknown }>;
};