datasquirel/package-shared/api-paths/utils/checks.ts
2025-12-22 07:18:57 +01:00

167 lines
5.1 KiB
TypeScript

import _ from "lodash";
import { APIPathsCrudParams, APIPathsParamsAllowedTable } from "../../types";
export default async function checks<
T extends { [k: string]: any } = { [k: string]: any }
>({
table,
allowedTables,
query,
body,
method,
getMiddleware,
postMiddleware,
putMiddleware,
deleteMiddleware,
crudMiddleware,
}: APIPathsCrudParams<T>): Promise<
Pick<APIPathsCrudParams<T>, "query" | "body"> & {
allowedTable: APIPathsParamsAllowedTable;
}
> {
const allowedTable = allowedTables.find((tbl) => tbl.table == table);
if (!allowedTable) {
throw new Error(`Can't Access this table: \`${table}\``);
}
let newQuery = _.cloneDeep(query);
let newBody = _.cloneDeep(body);
const searchFields = Object.keys(newQuery?.searchQuery?.query || {});
const selectFields = (
newQuery?.searchQuery?.selectFields
? newQuery.searchQuery.selectFields.map((f) =>
typeof f == "string"
? f
: typeof f == "object"
? f.fieldName
: undefined
)
: undefined
)?.filter((f) => typeof f == "string");
const targetFields = [...(searchFields || []), ...(selectFields || [])];
if (method == "GET" && allowedTable.allowedFields) {
for (let i = 0; i < targetFields.length; i++) {
const fld = targetFields[i];
const allowedFld = allowedTable.allowedFields.find((f) =>
typeof f == "string" ? f == fld : fld.match(f)
);
if (!allowedFld) {
throw new Error(`\`${allowedFld}\` field not allowed`);
}
}
}
if (method == "GET" && allowedTable.disallowedFields) {
for (let i = 0; i < targetFields.length; i++) {
const fld = targetFields[i];
const disallowedFld = allowedTable.disallowedFields.find((f) =>
typeof f == "string" ? f == fld : fld.match(f)
);
if (disallowedFld) {
throw new Error(`\`${disallowedFld}\` field not allowed`);
}
}
}
if (method == "GET" && getMiddleware) {
newQuery = await getMiddleware({ query: newQuery || ({} as any) });
}
if (method !== "GET" && crudMiddleware) {
const middRes = await crudMiddleware({
body: newBody || ({} as any),
query: newQuery || {},
});
newBody = _.merge(newBody, middRes);
}
if (method == "POST" && postMiddleware) {
const middRes = await postMiddleware({
body: newBody || ({} as any),
query: newQuery || {},
});
newBody = _.merge(newBody, middRes);
}
if (method == "PUT" && putMiddleware) {
const middRes = await putMiddleware({
body: newBody || ({} as any),
query: newQuery || {},
});
newBody = _.merge(newBody, middRes);
}
if (method == "DELETE" && deleteMiddleware) {
const middRes = await deleteMiddleware({
body: newBody || ({} as any),
query: newQuery || {},
});
newBody = _.merge(newBody, middRes);
}
if (newQuery?.searchQuery?.join) {
for (let i = 0; i < newQuery.searchQuery.join.length; i++) {
const join = newQuery.searchQuery.join[i];
const joinTableName = join.tableName;
const selectFields = join.selectFields;
if (allowedTables?.[0]) {
const allowedJoinTable = allowedTables.find(
(t) => t.table == joinTableName
);
if (!allowedJoinTable?.table) {
throw new Error(`Can't joint \`${joinTableName}\` table`);
}
const allowedFields = allowedJoinTable.allowedFields;
const disallowedFields = allowedJoinTable.disallowedFields;
if (selectFields?.[0]) {
for (let j = 0; j < selectFields.length; j++) {
const selectField = selectFields[j];
const selectFieldName =
typeof selectField == "object"
? selectField.field
: String(selectField);
if (
allowedFields?.[0] &&
!allowedFields.find(
(f) => String(f) == selectFieldName
)
) {
throw new Error(`Can't Select this Field!`);
}
if (
disallowedFields?.[0] &&
disallowedFields.find(
(f) => String(f) == selectFieldName
)
) {
throw new Error(`Disallowed Field Selected!`);
}
}
}
}
}
}
return {
query: newQuery,
body: newBody,
allowedTable,
};
}