refactor: remove all JWT-related code and references
JWT was never used - auth uses X-User-Id header. Removes jwt.ts utility, jsonwebtoken dependency, stubbed refresh/logout endpoints, and updates all docs (PUML diagrams, api-routes, tex, CLAUDE.md) accordingly.
This commit is contained in:
13
CLAUDE.md
13
CLAUDE.md
@@ -48,7 +48,7 @@ npm run start -w @calchat/server # Run compiled server (port 3000)
|
||||
| | MongoDB | Database |
|
||||
| | Mongoose | ODM |
|
||||
| | GPT (OpenAI) | AI/LLM for chat |
|
||||
| | X-User-Id Header | Authentication (simple, no JWT yet) |
|
||||
| | X-User-Id Header | Authentication |
|
||||
| | pino / pino-http | Structured logging |
|
||||
| | react-native-logs | Client-side logging |
|
||||
| | tsdav | CalDAV client library |
|
||||
@@ -235,7 +235,7 @@ CardBase
|
||||
src/
|
||||
├── app.ts # Entry point, DI setup, Express config
|
||||
├── controllers/ # Request handlers + middleware (per architecture diagram)
|
||||
│ ├── AuthController.ts # login(), register(), refresh(), logout()
|
||||
│ ├── AuthController.ts # login(), register()
|
||||
│ ├── ChatController.ts # sendMessage(), confirmEvent() + CalDAV push, rejectEvent(), getConversations(), getConversation(), updateProposalEvent()
|
||||
│ ├── EventController.ts # create(), getById(), getAll(), getByDateRange(), update(), delete() - pushes/deletes to CalDAV on mutations
|
||||
│ ├── CaldavController.ts # saveConfig(), loadConfig(), deleteConfig(), pullEvents(), pushEvents(), pushEvent()
|
||||
@@ -285,7 +285,6 @@ src/
|
||||
│ ├── toolDefinitions.ts # TOOL_DEFINITIONS - provider-agnostic tool specs
|
||||
│ └── toolExecutor.ts # executeToolCall() - handles getDay, proposeCreate/Update/Delete, searchEvents, getEventsInRange
|
||||
├── utils/
|
||||
│ ├── jwt.ts # signToken(), verifyToken() - NOT USED YET (no JWT)
|
||||
│ ├── password.ts # hash(), compare() using bcrypt
|
||||
│ ├── eventFormatters.ts # getWeeksOverview(), getMonthOverview() - formatted event listings
|
||||
│ └── recurrenceExpander.ts # expandRecurringEvents() - expand recurring events into occurrences
|
||||
@@ -296,8 +295,6 @@ src/
|
||||
**API Endpoints:**
|
||||
- `POST /api/auth/login` - User login
|
||||
- `POST /api/auth/register` - User registration
|
||||
- `POST /api/auth/refresh` - Refresh JWT token
|
||||
- `POST /api/auth/logout` - User logout
|
||||
- `GET /api/events` - Get all events (protected)
|
||||
- `GET /api/events/range` - Get events by date range (protected)
|
||||
- `GET /api/events/:id` - Get single event (protected)
|
||||
@@ -536,8 +533,6 @@ docker compose up -d # Start Radicale CalDAV server
|
||||
### Environment Variables
|
||||
Server requires `.env` file in `apps/server/`:
|
||||
```
|
||||
JWT_SECRET=your-secret-key
|
||||
JWT_EXPIRES_IN=1h
|
||||
MONGODB_URI=mongodb://root:mongoose@localhost:27017/calchat?authSource=admin
|
||||
OPENAI_API_KEY=sk-proj-...
|
||||
USE_TEST_RESPONSES=false # true = static test responses, false = real GPT AI
|
||||
@@ -585,10 +580,6 @@ NODE_ENV=development # development = pretty logs, production = JSON
|
||||
- `EventService`: Extended with searchByTitle(), findByCaldavUUID()
|
||||
- `utils/eventFormatters`: Refactored to use EventService instead of EventRepository
|
||||
- CORS configured to allow X-User-Id header
|
||||
- **Stubbed (TODO):**
|
||||
- `AuthController`: refresh(), logout()
|
||||
- `AuthService`: refreshToken()
|
||||
- JWT authentication (currently using simple X-User-Id header)
|
||||
|
||||
**Shared:**
|
||||
- Types, DTOs, constants (Day, Month with German translations), ExpandedEvent type, CaldavConfig, CaldavSyncStatus defined and exported
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^5.2.1",
|
||||
"ical.js": "^2.2.1",
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"mongoose": "^9.1.1",
|
||||
"openai": "^6.15.0",
|
||||
"pino": "^10.1.1",
|
||||
@@ -27,7 +26,6 @@
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/ical": "^0.8.3",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/node": "^24.10.1",
|
||||
"jest": "^30.2.0",
|
||||
"pino-pretty": "^13.1.3",
|
||||
|
||||
@@ -22,11 +22,4 @@ export class AuthController {
|
||||
}
|
||||
}
|
||||
|
||||
async refresh(req: Request, res: Response): Promise<void> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
async logout(req: Request, res: Response): Promise<void> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ export function createAuthRoutes(authController: AuthController): Router {
|
||||
|
||||
router.post("/login", (req, res) => authController.login(req, res));
|
||||
router.post("/register", (req, res) => authController.register(req, res));
|
||||
router.post("/refresh", (req, res) => authController.refresh(req, res));
|
||||
router.post("/logout", (req, res) => authController.logout(req, res));
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { User, CreateUserDTO, LoginDTO, AuthResponse } from "@calchat/shared";
|
||||
import { CreateUserDTO, LoginDTO, AuthResponse } from "@calchat/shared";
|
||||
import { UserRepository } from "./interfaces";
|
||||
import * as jwt from "../utils/jwt";
|
||||
import * as password from "../utils/password";
|
||||
|
||||
export class AuthService {
|
||||
@@ -46,11 +45,4 @@ export class AuthService {
|
||||
return { user, accessToken: "" };
|
||||
}
|
||||
|
||||
async refreshToken(refreshToken: string): Promise<AuthResponse> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
async logout(userId: string): Promise<void> {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from "./jwt";
|
||||
export * from "./password";
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
export interface TokenPayload {
|
||||
userId: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface JWTConfig {
|
||||
secret: string;
|
||||
expiresIn: string;
|
||||
}
|
||||
|
||||
const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";
|
||||
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || "1h";
|
||||
|
||||
export function signToken(payload: TokenPayload): string {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
export function verifyToken(token: string): TokenPayload {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
export function decodeToken(token: string): TokenPayload | null {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
@@ -11,15 +11,13 @@ Base URL: `/api`
|
||||
|--------|----------|--------------|
|
||||
| POST | `/auth/login` | User Login |
|
||||
| POST | `/auth/register` | User Registrierung |
|
||||
| POST | `/auth/refresh` | JWT Token erneuern |
|
||||
| POST | `/auth/logout` | User Logout |
|
||||
|
||||
---
|
||||
|
||||
## Events
|
||||
|
||||
### Event Endpoints (`/api/events`)
|
||||
Alle Endpoints erfordern JWT-Authentifizierung.
|
||||
Alle Endpoints erfordern Authentifizierung (X-User-Id Header).
|
||||
|
||||
| Method | Endpoint | Beschreibung |
|
||||
|--------|----------|--------------|
|
||||
@@ -35,7 +33,7 @@ Alle Endpoints erfordern JWT-Authentifizierung.
|
||||
## Chat
|
||||
|
||||
### Chat Endpoints (`/api/chat`)
|
||||
Alle Endpoints erfordern JWT-Authentifizierung.
|
||||
Alle Endpoints erfordern Authentifizierung (X-User-Id Header).
|
||||
|
||||
| Method | Endpoint | Beschreibung |
|
||||
|--------|----------|--------------|
|
||||
|
||||
@@ -188,11 +188,6 @@ package "Models" #D3D3D3 {
|
||||
}
|
||||
|
||||
package "Utils" #DDA0DD {
|
||||
class JWT {
|
||||
' +signToken()
|
||||
' +verifyToken()
|
||||
}
|
||||
|
||||
class Password {
|
||||
' +hash()
|
||||
' +compare()
|
||||
@@ -215,8 +210,6 @@ ChatController --> CaldavService
|
||||
EventController --> EventService
|
||||
EventController --> CaldavService
|
||||
CaldavController --> CaldavService
|
||||
AuthMiddleware --> JWT
|
||||
|
||||
' Service -> Interfaces (intern)
|
||||
AuthService --> UserRepository
|
||||
ChatService --> ChatRepository
|
||||
@@ -227,7 +220,6 @@ CaldavService --> CaldavRepository
|
||||
CaldavService --> EventService
|
||||
|
||||
' Auth uses Utils
|
||||
AuthService --> JWT
|
||||
AuthService --> Password
|
||||
|
||||
' Event/Chat uses Utils
|
||||
|
||||
@@ -77,7 +77,6 @@ package "apps/server (Express.js)" as ServerPkg #98FB98 {
|
||||
}
|
||||
|
||||
package "Utils" {
|
||||
[JWT] as JWTUtil
|
||||
[Password] as PwdUtil
|
||||
[RecurrenceExpander] as RecExpander
|
||||
[EventFormatters] as EvtFormatters
|
||||
@@ -154,9 +153,7 @@ GPT ..|> Interfaces
|
||||
Repos ..|> Interfaces
|
||||
|
||||
' Backend: Service -> Utils
|
||||
AuthSvc --> JWTUtil
|
||||
AuthSvc --> PwdUtil
|
||||
Middleware --> JWTUtil
|
||||
EventSvc --> RecExpander
|
||||
ChatSvc --> EvtFormatters
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ Backend & Express.js & Web-App Framework \\
|
||||
& MongoDB & Datenbank \\
|
||||
& Mongoose & ODM \\
|
||||
& Claude (Anthropic) & KI / LLM \\
|
||||
& JWT & Authentifizierung \\
|
||||
& X-User-Id Header & Authentifizierung \\
|
||||
\hline
|
||||
Geplant & iCalendar & Event-Export \\
|
||||
\hline
|
||||
@@ -112,8 +112,9 @@ Der wichtigste Teil der App ist die KI-Integration über \textbf{Claude}
|
||||
(Anthropic). Dieses LLM verarbeitet natürlichsprachliche Eingaben der Nutzer und
|
||||
generiert daraus strukturierte Event-Vorschläge.
|
||||
|
||||
Die Authentifizierung läuft über \textbf{JSON Web Tokens} (JWT). Der Vorteil:
|
||||
zustandslose Sessions, bei denen der Server keine Session-Daten speichern muss.
|
||||
Die Authentifizierung erfolgt über einen \textbf{X-User-Id Header}, der bei
|
||||
jedem Request die User-ID mitschickt. Diese einfache Lösung reicht für den
|
||||
aktuellen Entwicklungsstand aus.
|
||||
|
||||
Geplant ist außerdem die Unterstützung des \textbf{iCalendar}-Formats (ICAL)
|
||||
für den Export von Kalender-Events.
|
||||
@@ -157,7 +158,7 @@ Notiz-Feld) und ChatMessage.
|
||||
Der Controller Layer bildet die Schnittstelle zwischen Frontend und
|
||||
Backend-Logik. Die Routes definieren die API-Endpunkte, die Controller
|
||||
verarbeiten die eingehenden Requests und reichen diese an die Services weiter.
|
||||
Eine Auth Middleware prüft bei geschützten Routen den JWT-Token.
|
||||
Eine Auth Middleware prüft bei geschützten Routen den X-User-Id Header.
|
||||
|
||||
\subsubsection{Service Layer}
|
||||
|
||||
|
||||
102
package-lock.json
generated
102
package-lock.json
generated
@@ -72,7 +72,6 @@
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^5.2.1",
|
||||
"ical.js": "^2.2.1",
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"mongoose": "^9.1.1",
|
||||
"openai": "^6.15.0",
|
||||
"pino": "^10.1.1",
|
||||
@@ -85,7 +84,6 @@
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/ical": "^0.8.3",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/jsonwebtoken": "^9.0.10",
|
||||
"@types/node": "^24.10.1",
|
||||
"jest": "^30.2.0",
|
||||
"pino-pretty": "^13.1.3",
|
||||
@@ -4936,20 +4934,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/jsonwebtoken": {
|
||||
"version": "9.0.10",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/ms": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.10.1",
|
||||
"license": "MIT",
|
||||
@@ -6076,10 +6060,6 @@
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"license": "MIT"
|
||||
@@ -6844,13 +6824,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"license": "MIT"
|
||||
@@ -13280,36 +13253,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jws": "^4.0.1",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jsx-ast-utils": {
|
||||
"version": "3.3.5",
|
||||
"dev": true,
|
||||
@@ -13324,23 +13267,6 @@
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "2.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "^1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "4.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/kareem": {
|
||||
"version": "3.0.0",
|
||||
"license": "Apache-2.0",
|
||||
@@ -13502,30 +13428,6 @@
|
||||
"version": "4.0.8",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
@@ -13538,10 +13440,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"license": "MIT"
|
||||
|
||||
Reference in New Issue
Block a user