From 44c86572c275221b5068605c64958f43a1f96ff4 Mon Sep 17 00:00:00 2001 From: Dries Augustyns Date: Thu, 16 Apr 2026 07:56:41 +0200 Subject: [PATCH] feat: Block domain changes for disabled projects with appropriate error handling --- apps/api/src/controllers/Domains.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/api/src/controllers/Domains.ts b/apps/api/src/controllers/Domains.ts index 44a19e5..6ace560 100644 --- a/apps/api/src/controllers/Domains.ts +++ b/apps/api/src/controllers/Domains.ts @@ -3,11 +3,12 @@ import {DomainSchemas, UtilitySchemas} from '@plunk/shared'; import type {NextFunction, Request, Response} from 'express'; import {redis} from '../database/redis.js'; -import {NotFound} from '../exceptions/index.js'; +import {NotAllowed, NotFound} from '../exceptions/index.js'; import {isAuthenticated, requireEmailVerified} from '../middleware/auth.js'; import {DomainService} from '../services/DomainService.js'; import {Keys} from '../services/keys.js'; import {MembershipService} from '../services/MembershipService.js'; +import {SecurityService} from '../services/SecurityService.js'; import {CatchAsync} from '../utils/asyncHandler.js'; @Controller('domains') @@ -47,6 +48,14 @@ export class Domains { // Verify user has admin access to this project await MembershipService.requireAdminAccess(auth.userId!, projectId); + // Block domain changes on disabled projects + const isDisabled = await SecurityService.isProjectDisabled(projectId); + if (isDisabled) { + throw new NotAllowed( + 'Cannot add domains to a disabled project. Please contact support to resolve security violations before making changes.', + ); + } + // Check if domain is already linked to another project const ownershipCheck = await DomainService.checkDomainOwnership(domain, auth.userId); @@ -125,6 +134,14 @@ export class Domains { // Verify user has admin access to the project this domain belongs to await MembershipService.requireAdminAccess(auth.userId!, domain.projectId); + // Block domain changes on disabled projects + const isDisabled = await SecurityService.isProjectDisabled(domain.projectId); + if (isDisabled) { + throw new NotAllowed( + 'Cannot remove domains from a disabled project. Please contact support to resolve security violations before making changes.', + ); + } + await DomainService.removeDomain(id); await redis.del(Keys.Domain.id(id));