diff --git a/BACKLOG.md b/BACKLOG.md index 22d6cf6..43689f4 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -26,3 +26,11 @@ New suggestion? → [Open an issue](https://github.com/ulsklyc/oikos/issues/new? | BL-10 | PWA: Offline fallback for critical pages | v0.4.0 | | - | UX Polish (animations, bottom sheet, FAB, stagger, vibration) | v0.2.0 | | - | Event listener leaks, CSS gaps, modal tests | v0.2.1 | +| - | Internationalisation system (de + en), locale picker, formatDate/Time | v0.5.0 | +| - | PWA: Correct Oikos icons (192/512/maskable/apple-touch), service worker v22 | v0.5.1 | +| - | Calendar: Fix all-day RFC 5545 DTEND, DURATION support, birthday sync | v0.5.6 | +| - | Calendar: RRULE expansion fix (strip RRULE: prefix), YEARLY support | v0.5.7 | +| - | Italian (it) localization (497 keys) | v0.5.8 | +| - | Security hardening: XSS, rate limiter bypass, OAuth CSRF, CSV injection, session invalidation | v0.5.9 | +| - | Budget: Fix update failing when category changes | v0.6.0 | +| - | Upgrade bcrypt 5 → 6, ESM migration, structured logger, remove SESSION_SECRET fallback | v0.7.0 | diff --git a/CLAUDE.md.proposed b/CLAUDE.md.proposed deleted file mode 100644 index 0aca331..0000000 --- a/CLAUDE.md.proposed +++ /dev/null @@ -1,50 +0,0 @@ -# Oikos - -Self-hosted family planner PWA. Node.js/Express, Vanilla JS (no build step), SQLite, Docker. - -## Hard Constraints - -Violations are always bugs - no exceptions. - -- Never add frontend frameworks (React, Vue, Svelte), bundlers (Webpack, Vite), or CSS libraries (Tailwind, Bootstrap). -- No external frontend dependencies. Only allowed exception: Lucide Icons (`public/lucide.min.js`, self-hosted). No CDN links at runtime. -- `import`/`export` everywhere. Never `require()`. -- Never `eval()`. Never `innerHTML` with user data. Use `textContent` or DOM API. -- All UI text via `t('key')`. Never hardcode strings in components. `de` is the reference locale. -- Migrations append-only. Add entries to the `migrations` array in `server/db.js`. Never modify or reorder existing entries. -- All colors, radii, shadows, font sizes from `public/styles/tokens.css`. Never hardcode design values. -- Every route handler in `try/catch`. No unhandled promise rejections. - -## Architecture - -Request flow: client → Express static (`public/`) or `/api/v1/*` → session auth → route handler → better-sqlite3 (sync) → JSON. - -Key locations that are non-obvious: -- `public/i18n.js` - `t()`, `formatDate()`, `formatTime()`, `SUPPORTED_LOCALES` -- `public/api.js` - fetch wrapper (handles auth, CSRF, errors) -- `public/router.js` - History API router (no library) - -## Conventions - -- API responses: `{ data: ... }` on success, `{ error: string, code: number }` on failure. -- Dates/times: always `formatDate()`/`formatTime()` from `i18n.js`. Never format manually. -- Pages (`public/pages/*.js`): export `render()`. No side effects on import. -- Web Components (`public/components/*.js`): `oikos-` prefix, one component per file. -- Tests: `test-[module].js` in project root, `--experimental-sqlite` flag. Add `test:[module]` script to `package.json`. - -## Verification - -```bash -npm run dev # Start with --watch -npm test # All test suites (requires Node ≥22) -``` - -## Reference - -| What | Where | -|------|-------| -| Data model, UI specs | `docs/SPEC.md` | -| Design tokens | `public/styles/tokens.css` | -| DB schema (source of truth) | `server/db.js` | -| i18n keys | `public/locales/de.json` | -| Code conventions, commit format | `CONTRIBUTING.md` | diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index ab93c0b..b20a985 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -45,8 +45,12 @@ an individual is officially representing the community in public spaces. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement. All complaints -will be reviewed and investigated promptly and fairly. +reported via [GitHub Private Vulnerability Reporting](https://github.com/ulsklyc/oikos/security/advisories/new) +or by opening a private issue on GitHub. All complaints will be reviewed and +investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. ## Attribution diff --git a/SECURITY.md b/SECURITY.md index 2326b9f..a057ca2 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -29,12 +29,13 @@ Vulnerabilities that require physical access to the host or root on the server a - Session-based auth with `httpOnly`, `SameSite=Strict`, `Secure` cookies - CSRF protection via Double Submit Cookie on all state-changing requests -- Passwords hashed with bcrypt (cost factor 12) +- Passwords hashed with bcrypt v6 (cost factor 12) - Login rate limiting (5 attempts/min per IP) - API rate limiting (300 requests/min per IP) - Content Security Policy via Helmet (`self`-only) - Optional SQLCipher AES-256 database encryption - No API endpoint accessible without session auth (except login) +- `SESSION_SECRET` is mandatory - server refuses to start if unset ## Authorization Model diff --git a/docs/SPEC.md b/docs/SPEC.md index b087984..1e7bc75 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -335,6 +335,14 @@ All UI strings are managed via `public/i18n.js`. No hardcoded text in JS files o 2. `navigator.languages[0]` (browser language) 3. Fallback: `de` +### Supported Languages + +| Code | Language | Status | +|------|----------|--------| +| `de` | German | Reference locale (all keys defined here) | +| `en` | English | Full translation | +| `it` | Italian | Full translation (added v0.5.8) | + ### Adding a New Language 1. Create `public/locales/xx.json` (copy of `de.json`, translate)