diff --git a/backend/src/lib/knex/scim.ts b/backend/src/lib/knex/scim.ts index 530a7d45a..64f7fc2f6 100644 --- a/backend/src/lib/knex/scim.ts +++ b/backend/src/lib/knex/scim.ts @@ -8,12 +8,14 @@ const appendParentToGroupingOperator = (parentPath: string, filter: Filter) => { return filter; }; -export const generateKnexQueryFromScim = ( +const processDynamicQuery = ( rootQuery: Knex.QueryBuilder, - rootScimFilter: string, - getAttributeField: (attr: string) => string | null + scimRootFilterAst: Filter, + getAttributeField: (attr: string) => string | null, + depth = 0 ) => { - const scimRootFilterAst = parse(rootScimFilter); + if (depth > 20) return; + const stack = [ { scimFilterAst: scimRootFilterAst, @@ -75,42 +77,35 @@ export const generateKnexQueryFromScim = ( break; } case "and": { - void query.andWhere((subQueryBuilder) => { - scimFilterAst.filters.forEach((el) => { - stack.push({ - query: subQueryBuilder, - scimFilterAst: el - }); + scimFilterAst.filters.forEach((el) => { + void query.andWhere((subQueryBuilder) => { + processDynamicQuery(subQueryBuilder, el, getAttributeField, depth + 1); }); }); break; } case "or": { - void query.orWhere((subQueryBuilder) => { - scimFilterAst.filters.forEach((el) => { - stack.push({ - query: subQueryBuilder, - scimFilterAst: el - }); + scimFilterAst.filters.forEach((el) => { + void query.orWhere((subQueryBuilder) => { + processDynamicQuery(subQueryBuilder, el, getAttributeField, depth + 1); }); }); break; } case "not": { void query.whereNot((subQueryBuilder) => { - stack.push({ - query: subQueryBuilder, - scimFilterAst: scimFilterAst.filter - }); + processDynamicQuery(subQueryBuilder, scimFilterAst.filter, getAttributeField, depth + 1); }); break; } case "[]": { - void query.whereNot((subQueryBuilder) => { - stack.push({ - query: subQueryBuilder, - scimFilterAst: appendParentToGroupingOperator(scimFilterAst.attrPath, scimFilterAst.valFilter) - }); + void query.where((subQueryBuilder) => { + processDynamicQuery( + subQueryBuilder, + appendParentToGroupingOperator(scimFilterAst.attrPath, scimFilterAst.valFilter), + getAttributeField, + depth + 1 + ); }); break; } @@ -119,3 +114,12 @@ export const generateKnexQueryFromScim = ( } } }; + +export const generateKnexQueryFromScim = ( + rootQuery: Knex.QueryBuilder, + rootScimFilter: string, + getAttributeField: (attr: string) => string | null +) => { + const scimRootFilterAst = parse(rootScimFilter); + return processDynamicQuery(rootQuery, scimRootFilterAst, getAttributeField); +}; diff --git a/backend/src/server/plugins/add-errors-to-response-schemas.ts b/backend/src/server/plugins/add-errors-to-response-schemas.ts index 75844040c..8eb358a1b 100644 --- a/backend/src/server/plugins/add-errors-to-response-schemas.ts +++ b/backend/src/server/plugins/add-errors-to-response-schemas.ts @@ -3,9 +3,12 @@ import fp from "fastify-plugin"; import { DefaultResponseErrorsSchema } from "../routes/sanitizedSchemas"; +const isScimRoutes = (pathname: string) => + pathname.startsWith("/api/v1/scim/Users") || pathname.startsWith("/api/v1/scim/Groups"); + export const addErrorsToResponseSchemas = fp(async (server) => { server.addHook("onRoute", (routeOptions) => { - if (routeOptions.schema && routeOptions.schema.response) { + if (routeOptions.schema && routeOptions.schema.response && !isScimRoutes(routeOptions.path)) { routeOptions.schema.response = { ...DefaultResponseErrorsSchema, ...routeOptions.schema.response diff --git a/backend/src/server/plugins/error-handler.ts b/backend/src/server/plugins/error-handler.ts index 03681b1c8..76bfa9023 100644 --- a/backend/src/server/plugins/error-handler.ts +++ b/backend/src/server/plugins/error-handler.ts @@ -97,7 +97,11 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider message }); } else { - void res.send(error); + void res.status(HttpStatusCodes.InternalServerError).send({ + statusCode: HttpStatusCodes.InternalServerError, + error: "InternalServerError", + message: "Something went wrong" + }); } }); });