diff --git a/backend/Dockerfile b/backend/Dockerfile index 1e76cf841..f89fa2d3d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -23,6 +23,7 @@ COPY . . ONBUILD COPY ./branding/constants/ src/config/tmp ONBUILD RUN tools/replace-constants.sh ONBUILD COPY ./branding/email/ src/middleware/helpers/email/ +ONBUILD COPY ./branding/middlewares/ src/middleware/branding/ ONBUILD COPY ./branding/data/ src/db/data ONBUILD COPY ./branding/public/ public/ ONBUILD RUN yarn install --production=false --frozen-lockfile --non-interactive diff --git a/backend/branding/middlewares/.gitkeep b/backend/branding/middlewares/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 35e800c64..9b82299ae 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -22,7 +22,9 @@ const environment = { PRODUCTION: env.NODE_ENV === 'production', // used for staging enviroments if 'PRODUCTION=true' and 'PRODUCTION_DB_CLEAN_ALLOW=true' PRODUCTION_DB_CLEAN_ALLOW: env.PRODUCTION_DB_CLEAN_ALLOW === 'true' || false, // default = false - DISABLED_MIDDLEWARES: (env.NODE_ENV !== 'production' && env.DISABLED_MIDDLEWARES) || false, + DISABLED_MIDDLEWARES: ['test', 'development'].includes(env.NODE_ENV as string) + ? (env.DISABLED_MIDDLEWARES?.split(',') ?? []) + : [], } const required = { diff --git a/backend/src/middleware/branding/brandingMiddlewares.ts b/backend/src/middleware/branding/brandingMiddlewares.ts new file mode 100644 index 000000000..8d47043e8 --- /dev/null +++ b/backend/src/middleware/branding/brandingMiddlewares.ts @@ -0,0 +1,6 @@ +// eslint-disable-next-line import/no-cycle +import { MiddlewareOrder } from '@middleware/index' + +export default (): MiddlewareOrder[] => { + return [] +} diff --git a/backend/src/middleware/index.ts b/backend/src/middleware/index.ts index 7ce53663c..37fd33ef9 100644 --- a/backend/src/middleware/index.ts +++ b/backend/src/middleware/index.ts @@ -1,14 +1,14 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ -/* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable security/detect-object-injection */ -import { applyMiddleware } from 'graphql-middleware' +import { applyMiddleware, IMiddleware } from 'graphql-middleware' import CONFIG from '@config/index' +// eslint-disable-next-line import/no-cycle +import brandingMiddlewares from './branding/brandingMiddlewares' import chatMiddleware from './chatMiddleware' import excerpt from './excerptMiddleware' import hashtags from './hashtags/hashtagsMiddleware' @@ -26,56 +26,44 @@ import userInteractions from './userInteractions' import validation from './validation/validationMiddleware' import xss from './xssMiddleware' -export default (schema) => { - const middlewares = { - sentry, - permissions, - xss, - validation, - sluggify, - excerpt, - login, - notifications, - hashtags, - softDelete, - includedFields, - orderBy, - languages, - userInteractions, - chatMiddleware, - } - - let order = [ - 'sentry', - 'permissions', - 'xss', - // 'activityPub', disabled temporarily - 'validation', - 'userInteractions', - 'sluggify', - 'languages', - 'excerpt', - 'login', - 'notifications', - 'hashtags', - 'softDelete', - 'includedFields', - 'orderBy', - 'chatMiddleware', - ] - - // add permisions middleware at the first position (unless we're seeding) - if (CONFIG.DISABLED_MIDDLEWARES) { - const disabledMiddlewares = CONFIG.DISABLED_MIDDLEWARES.split(',') - order = order.filter((key) => { - if (disabledMiddlewares.includes(key)) { - /* eslint-disable-next-line no-console */ - console.log(`Warning: Disabled "${disabledMiddlewares}" middleware.`) - } - return !disabledMiddlewares.includes(key) - }) - } - - const appliedMiddlewares = order.map((key) => middlewares[key]) - return applyMiddleware(schema, ...appliedMiddlewares) +export interface MiddlewareOrder { + order: number + name: string + middleware: IMiddleware +} + +const ocelotMiddlewares: MiddlewareOrder[] = [ + { order: -200, name: 'sentry', middleware: sentry }, + { order: -190, name: 'permissions', middleware: permissions }, + { order: -180, name: 'xss', middleware: xss }, + { order: -170, name: 'validation', middleware: validation }, + { order: -160, name: 'userInteractions', middleware: userInteractions }, + { order: -150, name: 'sluggify', middleware: sluggify }, + { order: -140, name: 'languages', middleware: languages }, + { order: -130, name: 'excerpt', middleware: excerpt }, + { order: -120, name: 'login', middleware: login }, + { order: -110, name: 'notifications', middleware: notifications }, + { order: -100, name: 'hashtags', middleware: hashtags }, + { order: -90, name: 'softDelete', middleware: softDelete }, + { order: -80, name: 'includedFields', middleware: includedFields }, + { order: -70, name: 'orderBy', middleware: orderBy }, + { order: -60, name: 'chatMiddleware', middleware: chatMiddleware }, +] + +export default (schema) => { + const middlewares = ocelotMiddlewares + .concat(brandingMiddlewares()) + .sort((a, b) => a.order - b.order) + + const filteredMiddlewares = middlewares.filter( + (middleware) => !CONFIG.DISABLED_MIDDLEWARES.includes(middleware.name), + ) + + // Warn if we filtered + if (middlewares.length < filteredMiddlewares.length) { + // eslint-disable-next-line no-console + console.log(`Warning: Disabled "${CONFIG.DISABLED_MIDDLEWARES.join(', ')}" middleware.`) + } + + return applyMiddleware(schema, ...filteredMiddlewares.map((middleware) => middleware.middleware)) }