Files
twenty/tools/eslint-rules/rules/rest-api-methods-should-be-guarded.ts
T
Félix Malfait 44aee860d9 Consolidate Prettier config and improve consistency (#15191)
## Summary

Clean up and consolidate formatting configuration across the monorepo.

## Changes

### 1. Remove Redundant Configs
-  Delete `packages/twenty-server/.prettierrc` (had invalid
`brakeBeforeElse` typo)
-  Delete `packages/twenty-zapier/.prettierrc`
-  Use root `.prettierrc` only (Prettier searches up directory tree
automatically)

### 2. Improve Root Prettier Config
- Change `endOfLine: 'auto'` → `'lf'` for consistent Unix line endings
across all OSes

### 3. Enhance VSCode Settings
- `files.eol: 'auto'` → `'\\n'` (consistent with Prettier)
- Add `files.insertFinalNewline: true` (explicit editor behavior)
- Add `files.trimTrailingWhitespace: true` (cleaner files)

### 4. Add `.gitattributes`
- Enforce LF line endings at Git level
- Prevents `core.autocrlf` from converting based on contributor's OS
- Mark patch files as binary (they have mixed line endings by design)
- Explicitly define binary file types

### 5. Fix Line Endings
- Convert 3 selectable-list state files from CRLF → LF
- These were the only source files with Windows line endings

## Why These Changes Matter

**Before:**
- 3 different Prettier configs (inconsistent, one had typo)
- Mixed CRLF/LF depending on contributor's OS
- No Git-level enforcement

**After:**
- Single source of truth for formatting
- All files use LF (Unix standard)
- Git enforces line endings regardless of OS
- Prettier warning about invalid option removed

## Result

-  Single `.prettierrc` config
-  Consistent LF line endings enforced by Git
-  Better VSCode defaults
-  No more CRLF files sneaking in from Windows contributors
2025-10-18 12:24:35 +02:00

71 lines
2.2 KiB
TypeScript

import { TSESTree } from '@typescript-eslint/utils';
import { createRule } from '../utils/createRule';
import { typedTokenHelpers } from '../utils/typedTokenHelpers';
// NOTE: The rule will be available in ESLint configs as "@nx/workspace-rest-api-methods-should-be-guarded"
export const RULE_NAME = 'rest-api-methods-should-be-guarded';
export const restApiMethodsShouldBeGuarded = (node: TSESTree.MethodDefinition) => {
const hasRestApiMethodDecorator = typedTokenHelpers.nodeHasDecoratorsNamed(
node,
['Get', 'Post', 'Put', 'Delete', 'Patch', 'Options', 'Head', 'All']
);
const hasAuthGuards = typedTokenHelpers.nodeHasAuthGuards(node);
function findClassDeclaration(
node: TSESTree.Node
): TSESTree.ClassDeclaration | null {
if (node.type === TSESTree.AST_NODE_TYPES.ClassDeclaration) {
return node;
}
if (node.parent) {
return findClassDeclaration(node.parent);
}
return null;
}
const classNode = findClassDeclaration(node);
const hasAuthGuardsOnController = classNode
? typedTokenHelpers.nodeHasAuthGuards(classNode)
: false;
return (
hasRestApiMethodDecorator &&
!hasAuthGuards &&
!hasAuthGuardsOnController
);
};
export const rule = createRule<[], 'restApiMethodsShouldBeGuarded'>({
name: RULE_NAME,
meta: {
docs: {
description:
'REST API endpoints should have authentication guards (UserAuthGuard or WorkspaceAuthGuard) or be explicitly marked as public (PublicEndpointGuard) to maintain our security model.',
},
messages: {
restApiMethodsShouldBeGuarded:
'All REST API controller endpoints should have @UseGuards(UserAuthGuard), @UseGuards(WorkspaceAuthGuard), or @UseGuards(PublicEndpointGuard) decorators, or one decorating the root of the Controller.',
},
schema: [],
hasSuggestions: false,
type: 'suggestion',
},
defaultOptions: [],
create(context) {
return {
MethodDefinition(node: TSESTree.MethodDefinition): void {
if (restApiMethodsShouldBeGuarded(node)) {
context.report({
node: node,
messageId: 'restApiMethodsShouldBeGuarded',
});
}
},
};
},
});