You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: backend/README.md
+44-27Lines changed: 44 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,29 +10,52 @@ npm run backend
10
10
11
11
Server starts at `http://localhost:4000` by default.
12
12
13
-
## Database
13
+
## Security Layer
14
14
15
-
### Issue #26: Move from in-memory store to persistent DB
15
+
### Helmet-style security headers
16
16
17
-
- Uses a local JSON database file at `backend/data/brocode.json`.
18
-
- You can override the location with `BROCODE_DB_PATH=/custom/path.json npm run backend`.
19
-
- On first start, seed data is inserted for users, spots, catalog items, and a sample order.
20
-
- New orders are validated against DB data (known `spotId`, `userId`, `productId`) and item pricing is always derived from catalog prices in the database.
17
+
The server now sends strict security headers on every API response, including:
18
+
19
+
-`Content-Security-Policy`
20
+
-`Strict-Transport-Security`
21
+
-`X-Content-Type-Options`
22
+
-`X-Frame-Options`
23
+
-`Referrer-Policy`
24
+
-`Cross-Origin-*` hardening headers
25
+
26
+
Configure CSP via `SECURITY_HEADERS_CSP`.
27
+
28
+
### CORS
29
+
30
+
CORS is applied to all endpoints with these defaults:
31
+
32
+
- Allowed origin from `CORS_ALLOW_ORIGIN` (defaults to `*`)
### Issue #28: Secure credential storage and verification
36
+
### Rate limiting
23
37
24
-
- Passwords are stored as salted `scrypt` hashes (not plaintext).
25
-
- Legacy plaintext user passwords are auto-migrated to hashed values on successful login.
38
+
Two limits are active:
26
39
27
-
### Issue #29: Protect login endpoint from brute-force attempts
40
+
1.**Global API limiter** per IP (`GLOBAL_RATE_LIMIT_MAX_REQUESTS` in `GLOBAL_RATE_LIMIT_WINDOW_MS`)
41
+
2.**Login brute-force limiter** per `IP + username`
42
+
(`LOGIN_RATE_LIMIT_MAX_ATTEMPTS` in `LOGIN_RATE_LIMIT_WINDOW_MS`, temporary block for `LOGIN_RATE_LIMIT_BLOCK_MS`)
28
43
29
-
- Login is now rate-limited per `IP + username` key.
30
-
- Defaults: 5 failed attempts within 15 minutes triggers a 15 minute temporary block (`429`).
31
-
- Configure via env vars:
32
-
-`LOGIN_RATE_LIMIT_MAX_ATTEMPTS`
33
-
-`LOGIN_RATE_LIMIT_WINDOW_MS`
34
-
-`LOGIN_RATE_LIMIT_BLOCK_MS`
44
+
Both return HTTP `429` and `Retry-After` headers.
45
+
46
+
### Password hashing
47
+
48
+
User credentials are stored as salted hashes (using Node crypto `scrypt`) and never as plaintext.
49
+
Legacy plaintext records auto-migrate to hashed values at successful login.
50
+
51
+
## Database
52
+
53
+
- Uses a local JSON database file at `backend/data/brocode.json`.
54
+
- You can override the location with `BROCODE_DB_PATH=/custom/path.json npm run backend`.
55
+
- On first start, seed data is inserted for users, spots, catalog items, and a sample order.
56
+
- New orders are validated against DB data (known `spotId`, `userId`, `productId`) and item pricing is always derived from catalog prices in the database.
This project can be deployed with the following stack:
4
+
5
+
-**Backend**: Render, Railway, or AWS EC2
6
+
-**Database (PostgreSQL)**: Supabase or Neon
7
+
-**Redis**: Upstash
8
+
-**File storage**: AWS S3 or Cloudinary
9
+
10
+
> Current repo runtime still uses a local JSON DB for persistence. `DATABASE_URL`, `REDIS_URL`, and storage variables are wired into env validation so you can safely provide production credentials while evolving integrations.
0 commit comments