navidocs/CRITICAL_FIXES_PROMPT.md
Danny Stocker 317d8ec133 Add focused prompt for 8 critical security/UX fixes
Based on Codex + Gemini reviews:
- 4 security fixes (JWT, auth middleware, stats endpoint)
- 4 UX fixes (touch targets, fonts, ARIA, alt text)

Shorter, focused mission for quick execution
Ready for new cloud session
2025-11-14 17:25:47 +01:00

243 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NaviDocs CRITICAL Security & UX Fixes - 8 Haiku Agents
**GitHub Repository:** https://github.com/dannystocker/navidocs
**Base Branch:** `claude/install-run-ssh-01RZPPuRFwrveZKec62363vu` (latest build)
**New Branch:** `fix/critical-security-ux`
---
## Mission: Fix 8 Critical Issues Found in Code Reviews
**Context:** Codex and Gemini reviews found 8 CRITICAL blockers that must be fixed before production. The app is functionally complete but has security holes and UX issues for marine environment.
---
## CRITICAL ISSUES (Must Fix)
### 🔴 Security (Agents 1-4)
**AGENT 1: JWT Secret Enforcement**
- **File:** `server/services/auth.service.js`
- **Issue:** Line 13: `const JWT_SECRET = process.env.JWT_SECRET || 'your-jwt-secret-here-change-in-production'`
- **Risk:** If JWT_SECRET not set, attackers can forge tokens
- **Fix:**
```javascript
// BEFORE
const JWT_SECRET = process.env.JWT_SECRET || 'your-jwt-secret-here-change-in-production';
// AFTER
const JWT_SECRET = process.env.JWT_SECRET;
if (!JWT_SECRET || JWT_SECRET.length < 32) {
throw new Error('JWT_SECRET environment variable is required and must be at least 32 chars');
}
```
- **Test:** Start server without JWT_SECRET → should throw error
**AGENT 2: Document Routes Auth Gaps**
- **Files:** `server/routes/documents.js`, `server/routes/images.js`
- **Issue:** Routes use `req.user?.id || 'test-user-id'` instead of enforcing auth
- **Risk:** Synthetic user ID bypasses tenant isolation
- **Fix Pattern:**
```javascript
// BEFORE
router.get('/:id', async (req, res) => {
const userId = req.user?.id || 'test-user-id';
// ...
});
// AFTER
import { authenticateToken } from '../middleware/auth.middleware.js';
router.get('/:id', authenticateToken, async (req, res) => {
const userId = req.user.userId; // Always defined after middleware
// ...
});
```
- **Apply to:** All routes in `documents.js` and `images.js`
- **Test:** Unauthenticated request → 401
**AGENT 3: Search/Upload Route Auth**
- **Files:** `server/routes/search.js`, `server/routes/upload.js`
- **Issue:** Same `test-user-id` pattern
- **Fix:** Add `authenticateToken` middleware to all endpoints
- **Test:** Upload without token → 401
**AGENT 4: Stats Route Protection**
- **File:** `server/routes/stats.js`
- **Issue:** Global stats endpoint has no auth (reveals business metrics)
- **Fix:**
```javascript
import { authenticateToken, requireSystemAdmin } from '../middleware/auth.middleware.js';
router.get('/', authenticateToken, requireSystemAdmin, async (req, res) => {
// Only admins can see global stats
});
```
- **Test:** Non-admin request → 403
### 🎨 UX Marine Environment (Agents 5-8)
**AGENT 5: Touch Targets (60px Minimum)**
- **Issue:** Buttons as small as 12×12px found in `client/src/components/`
- **Pattern:**
```vue
<!-- BEFORE -->
<button style="width: 40px; height: 40px">
<ChevronRightIcon />
</button>
<!-- AFTER -->
<button style="min-width: 60px; min-height: 60px; padding: 10px">
<ChevronRightIcon class="w-6 h-6" />
</button>
```
- **Files to Fix:**
- `client/src/components/TocSidebar.vue` (40px → 60px)
- `client/src/components/SearchResultsSidebar.vue` (20px → 60px)
- `client/src/components/TocEntry.vue` (32px → 60px)
- **Test:** All interactive elements ≥60×60px
**AGENT 6: Font Sizes (16px Minimum)**
- **Issue:** Fonts as small as 10px found (unreadable in sunlight)
- **Pattern:**
```vue
<!-- BEFORE -->
<p style="font-size: 11px">Last updated</p>
<!-- AFTER -->
<p style="font-size: 16px">Last updated</p>
```
- **Files to Fix:**
- `client/src/views/SearchView.vue` (10px, 11px, 12px → 16px)
- `client/src/components/TocSidebar.vue` (11px → 16px)
- `client/src/components/SearchResultsSidebar.vue` (11px → 16px)
- **Test:** No fonts <16px in codebase
**AGENT 7: ARIA Labels (29 Icon Buttons)**
- **Issue:** Icon-only buttons lack screen reader labels
- **Pattern:**
```vue
<!-- BEFORE -->
<button @click="deleteItem">
<TrashIcon />
</button>
<!-- AFTER -->
<button aria-label="Delete item" @click="deleteItem">
<TrashIcon aria-hidden="true" />
</button>
```
- **Scan:** `grep -r "<button" client/src/ | grep -v "aria-label"`
- **Test:** All interactive elements have labels
**AGENT 8: Image Alt Text**
- **Issue:** Images without alt attributes
- **Pattern:**
```vue
<!-- BEFORE -->
<img :src="thumbnail">
<!-- AFTER -->
<img :src="thumbnail" :alt="title + ' thumbnail'">
```
- **Files:** `client/src/views/SearchView.vue`, `client/src/components/FigureZoom.vue`
- **Test:** All images have alt text
---
## Execution Instructions
### Step 1: Setup
```bash
git clone https://github.com/dannystocker/navidocs.git
cd navidocs
git checkout claude/install-run-ssh-01RZPPuRFwrveZKec62363vu
git checkout -b fix/critical-security-ux
```
### Step 2: Spawn 8 Haiku Agents in Parallel
**CRITICAL:** Use **one message with 8 Task tool calls**:
```
I'm spawning 8 Haiku agents in parallel to fix critical security and UX issues.
[Task 1: JWT Secret Enforcement]
[Task 2: Document Routes Auth]
[Task 3: Search/Upload Auth]
[Task 4: Stats Route Protection]
[Task 5: Touch Targets 60px]
[Task 6: Font Sizes 16px]
[Task 7: ARIA Labels]
[Task 8: Image Alt Text]
```
### Step 3: Testing
After all 8 agents complete:
```bash
# Security tests
grep -r "JWT_SECRET.*||" server/ # Should be 0 results
grep -r "test-user-id" server/routes/ # Should be 0 results
npm audit --production # 0 critical/high
# UX tests
grep -r "width.*px\|height.*px" client/src/components/ | grep -E "width: [1-5][0-9]px" | wc -l # Should be 0
grep -r "font-size.*px" client/src/ | grep -E "[0-9]{1}px|1[0-5]px" | wc -l # Should be 0
grep -r "<button" client/src/ | grep -v "aria-label" | wc -l # Should be minimal
grep -r "<img" client/src/ | grep -v "alt=" | wc -l # Should be 0
```
### Step 4: Commit & Push
```bash
git add .
git commit -m "Fix 8 critical security and UX issues
Security Fixes:
- Enforce JWT_SECRET with mandatory validation (no fallback)
- Add authenticateToken to document/image routes
- Add authenticateToken to search/upload routes
- Protect stats endpoint with requireSystemAdmin
UX Fixes (Marine Environment):
- Increase all touch targets to 60×60px minimum
- Increase all fonts to 16px minimum base
- Add ARIA labels to 29 icon-only buttons
- Add alt text to all images
Reviews: Codex + Gemini comprehensive audits
Blockers: 8 critical issues preventing production deployment
Week 1 critical path: Security + Marine UX
"
git push -u origin fix/critical-security-ux
```
---
## Success Criteria
- [ ] JWT_SECRET throws error if missing/short
- [ ] 0 routes with `test-user-id` pattern
- [ ] All document/image/search/upload/stats routes require auth
- [ ] All touch targets 60×60px
- [ ] All fonts 16px base
- [ ] All icon buttons have ARIA labels
- [ ] All images have alt text
- [ ] npm audit: 0 critical/high
- [ ] Build succeeds without errors
---
## Time Estimate
**Total:** 2-3 hours (all agents in parallel)
- Security fixes: 1 hour
- UX fixes: 1 hour
- Testing: 30 minutes
- Commit/push: 15 minutes
---
**Ready to execute. Spawn 8 Haiku agents in parallel and fix all critical issues.**