import type { InstanceWriteAccessService } from '@n8n/backend-services'; import type { User } from '@n8n/db'; import { RESPONSE_ERROR_MESSAGES } from '@/constants'; import { ForbiddenError } from '@n8n/errors'; import { userHasScopes } from '@/permissions.ee/check-access'; /** * On a protected instance, source control owns the table structure, so a pull * would revert or delete schema changes made here. Rows are not in source * control and stay writable. */ export function assertSchemaWriteAccess(instanceWriteAccess: InstanceWriteAccessService): void { if (instanceWriteAccess.isReadOnly()) { throw new ForbiddenError( 'Cannot change the data table structure on a protected instance. This instance is in read-only mode. Rows can still be edited.', ); } } /** * The flag pair mirrors `shouldReturnData` in `DataTableRowsRepository`: a dry run * returns rows whether or not `returnData` was asked for. Keyed on the data table * so the check resolves the same project the `dataTable:writeRow` guard resolved. */ export async function assertRowReadAccessIfReturningRows( user: User, dataTableId: string, { dryRun, returnData }: { dryRun?: boolean; returnData?: boolean }, ): Promise { if (!dryRun && !returnData) return; if (!(await userHasScopes(user, ['dataTable:readRow'], false, { dataTableId }))) { throw new ForbiddenError(RESPONSE_ERROR_MESSAGES.MISSING_SCOPE); } }