diff --git a/README.md b/README.md index c5e4f5c..24828e2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- + Oikos

@@ -7,44 +7,57 @@

Oikos

- Self-hosted family planner — tasks, calendars, shopping, meals, budget.
- Your data stays on your server. No subscriptions. No tracking. No cloud lock-in. + The self-hosted family planner that respects your privacy.
+ Tasks, calendars, shopping, meals, budget, notes, contacts —
+ all in one place, on your own server.

+ Latest Release MIT License - Node.js ≥22 + Node.js ≥22 Docker Ready SQLCipher Encrypted PWA Offline - GitHub Stars - Last Commit

- Features · Quick Start · Configuration · Calendar Sync · Security + Screenshots ·  + Features ·  + Quick Start ·  + Security ·  + Contributing

---- - -Oikos is a self-hosted family organizer for 2–6 people. Tasks, calendars, shopping lists, meal plans, budget tracking, notes, and contacts — all running on your own server inside a single Docker container. No cloud dependency, no telemetry, no data leaves your network. - -Built with Express.js, SQLite (optionally encrypted via SQLCipher), and vanilla JavaScript — no frontend framework, no build step. Works offline as a PWA on phones and tablets. - -Oikos is **not** a SaaS product, not a team collaboration tool, and not designed for public multi-tenant use. It is a private tool for one family on one server. - ---- - -## Screenshots +

- Dashboard + Oikos Dashboard

+--- + +## Why Oikos? + +Most family organizers are cloud apps with monthly subscriptions, data mining, and vendor lock-in. Oikos takes a different approach: + +- **Your server, your data** — runs in a single Docker container on your own hardware. Nothing leaves your network. +- **No subscriptions** — free and open source, forever. MIT licensed. +- **No tracking** — zero telemetry, zero analytics, zero third-party scripts. +- **Offline-first** — works as a PWA on phones and tablets, even without connectivity. +- **Encrypted at rest** — optional AES-256 database encryption via SQLCipher. +- **Lightweight** — vanilla JavaScript frontend with no framework and no build step. Express + SQLite backend. Minimal resource footprint. + +Oikos is designed for **one family on one server** — not a SaaS product, not a team tool, not multi-tenant. It's a private, self-contained household organizer for 2–6 people. + +--- + +## 📸 Screenshots +
@@ -95,34 +108,113 @@ Oikos is **not** a SaaS product, not a team collaboration tool, and not designed Dashboard Mobile -
Dashboard — Mobile +
Dashboard
+
+Tablet views +
+ + + + + + + + + + + + + +
+ + + + Tasks — Tablet + +
Tasks +
+ + + + Shopping — Tablet + +
Shopping +
+ + + + Notes — Tablet + +
Notes +
+ + + + Budget — Tablet + +
Budget +
+ + + + Contacts — Tablet + +
Contacts +
+
+

- Screenshots adapt to your GitHub theme — switch between light and dark mode to see both variants. + Screenshots adapt to your GitHub theme — toggle light/dark mode to see both variants.

--- -## Features +## ✨ Features -| | Module | What it does | Highlights | -|---|---|---|---| -| 📋 | **Dashboard** | At-a-glance overview of your family's day | Weather widget · upcoming events · urgent tasks · today's meals · pinned notes | -| ✅ | **Tasks** | Shared to-do lists with accountability | List + Kanban views · subtasks · recurring tasks (RRULE) · swipe gestures · priority levels | -| 🛒 | **Shopping** | Collaborative grocery lists | Multiple lists · aisle-grouped categories · auto-import from meal plan | -| 🍽️ | **Meals** | Weekly meal planning with ingredients | Week view (Mon–Sun) · ingredient management · one-click export to shopping list | -| 📅 | **Calendar** | Family calendar with external sync | Month/week/day/agenda views · Google Calendar & Apple iCloud two-way sync | -| 📌 | **Notes** | Shared family pinboard | Colored sticky notes · pinning · full-text search · lightweight Markdown (bold, italic, lists) | -| 👥 | **Contacts** | Important family contacts | Category filters · tap-to-call · tap-to-email · map links · vCard import/export | -| 💰 | **Budget** | Income & expense tracking | Category breakdown · month-over-month comparison · CSV export | -| ⚙️ | **Settings** | User & sync management | Password changes · calendar sync config · family member admin | + + + + + +
+ +**📋 Dashboard** +At-a-glance family overview — weather, upcoming events, urgent tasks, today's meals, pinned notes. + +**✅ Tasks** +List + Kanban views, subtasks, recurring tasks (RRULE), swipe gestures, priority levels. + +**🛒 Shopping** +Multiple lists, aisle-grouped categories, auto-import from meal plan, swipe to check off. + +**🍽️ Meals** +Weekly planner (Mon–Sun), drag & drop between slots, ingredients, one-click shopping list export. + + + +**📅 Calendar** +Month / week / day / agenda views. Two-way sync with Google Calendar and Apple iCloud. + +**📌 Notes** +Colored sticky notes, pinning, full-text search, Markdown formatting toolbar. + +**👥 Contacts** +Category filters, tap-to-call/email, map links, vCard import & export. + +**💰 Budget** +Income & expense tracking, recurring entries, month-over-month trends, CSV export. + +
+ +**And also:** dark mode with system detection · responsive design (mobile / tablet / desktop) · offline PWA with install prompt · per-module accent colors · accessibility (skip links, ARIA, reduced motion) · staggered animations · bottom sheet modals on mobile. --- -## Tech Stack +## 🛠 Tech Stack

Express @@ -133,78 +225,75 @@ Oikos is **not** a SaaS product, not a team collaboration tool, and not designed

| Layer | Technology | -|---|---| +|:---|:---| | **Server** | Node.js ≥ 22 · Express · better-sqlite3 · bcrypt · Helmet | -| **Database** | SQLite with optional SQLCipher encryption (AES-256) | -| **Frontend** | Vanilla JavaScript ES modules — no framework, no build step. Web Components (`oikos-*`). Lucide Icons (self-hosted SVG sprite) | -| **Auth** | Session-based · httpOnly cookies · CSRF double-submit · express-session | +| **Database** | SQLite with optional [SQLCipher](https://www.zetetic.net/sqlcipher/) encryption (AES-256) | +| **Frontend** | Vanilla JavaScript ES modules — no framework, no build step. [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) (`oikos-*`). [Lucide Icons](https://lucide.dev) (self-hosted) | +| **Auth** | Session-based · httpOnly cookies · CSRF double-submit · [express-session](https://github.com/expressjs/session) | | **Deployment** | Docker + Docker Compose · Nginx reverse proxy · Let's Encrypt SSL | -| **Integrations** | Google Calendar API v3 (OAuth 2.0) · Apple iCloud CalDAV (tsdav) · OpenWeatherMap | +| **Integrations** | [Google Calendar API v3](https://developers.google.com/calendar) (OAuth 2.0) · [Apple iCloud CalDAV](https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitWebServicesReference/) (tsdav) · [OpenWeatherMap](https://openweathermap.org/api) | --- -## Quick Start +## 🚀 Quick Start -**Prerequisites:** Docker + Docker Compose on a Linux server. - -### 1. Clone +> **Prerequisites:** Docker and Docker Compose installed on a Linux server. ```bash -git clone https://github.com/ulsklyc/oikos.git -cd oikos -``` +# 1. Clone the repository +git clone https://github.com/ulsklyc/oikos.git && cd oikos -### 2. Configure - -```bash +# 2. Configure environment cp .env.example .env -``` +# Edit .env — set SESSION_SECRET (≥32 chars) and optionally DB_ENCRYPTION_KEY -Edit `.env` and set the two required variables: - -```env -SESSION_SECRET=your-random-string-at-least-32-chars -DB_ENCRYPTION_KEY=your-sqlcipher-aes256-key -``` - -### 3. Start - -```bash +# 3. Start the container docker compose up -d -``` +# First build takes 2–3 minutes (compiles SQLCipher) -First build takes 2–3 minutes (compiles SQLCipher against better-sqlite3). - -### 4. Create admin account - -```bash +# 4. Create your admin account docker compose exec oikos node setup.js + +# 5. Open http://localhost:3000 ``` -Interactive script — sets up username, display name, and password. This admin can create additional family members from the settings page. +The admin can create additional family members from **Settings → Family Members**. -### 5. Open +> **Production:** See [`nginx.conf.example`](nginx.conf.example) for a reverse proxy config with SSL. If you use [Nginx Proxy Manager](https://nginxproxymanager.com), paste the contents into the Advanced tab. Ensure `X-Forwarded-Proto` is set for session cookies to work correctly. -Navigate to `http://localhost:3000` — or your configured domain after Nginx setup. +--- -> **Nginx:** See [`nginx.conf.example`](nginx.conf.example) for a production-ready config. If you use [Nginx Proxy Manager](https://nginxproxymanager.com), paste the contents into the "Advanced" tab. Make sure `X-Forwarded-Proto` is set so session cookies work correctly in production. +## 🔒 Security + +Oikos is designed to run on a private server behind SSL. No public endpoints exist except the login page. + +| Layer | Implementation | +|:---|:---| +| **Sessions** | `httpOnly`, `SameSite=Strict`, `Secure` in production, 7-day TTL | +| **CSRF** | Double-submit cookie pattern on all state-changing requests | +| **Passwords** | bcrypt with cost factor 12 | +| **Rate limiting** | 5 login attempts/min, 300 API requests/min per IP | +| **Headers** | Strict Content Security Policy via Helmet (`self`-only) | +| **Encryption** | Optional SQLCipher AES-256 database encryption at rest | +| **Access control** | No API endpoint accessible without session auth (except login) | +| **Registration** | Disabled — only admins can create user accounts | ---
-

Configuration

+Configuration ### Required | Variable | Description | -|---|---| +|:---|:---| | `SESSION_SECRET` | Random string ≥ 32 characters for session signing | -| `DB_ENCRYPTION_KEY` | SQLCipher AES-256 key. Leave empty to disable encryption | +| `DB_ENCRYPTION_KEY` | SQLCipher AES-256 key — leave empty to disable encryption | ### Optional | Variable | Default | Description | -|---|---|---| +|:---|:---|:---| | `PORT` | `3000` | Server port | | `NODE_ENV` | `development` | Set to `production` for deployment | | `DB_PATH` | `./oikos.db` | Path to SQLite database file | @@ -216,7 +305,7 @@ Navigate to `http://localhost:3000` — or your configured domain after Nginx se Register a free API key at [openweathermap.org](https://openweathermap.org/api): | Variable | Default | Description | -|---|---|---| +|:---|:---|:---| | `OPENWEATHER_API_KEY` | — | Your API key | | `OPENWEATHER_CITY` | `Berlin` | City name | | `OPENWEATHER_UNITS` | `metric` | `metric` (°C) or `imperial` (°F) | @@ -225,7 +314,7 @@ Register a free API key at [openweathermap.org](https://openweathermap.org/api): ### Integrations | Variable | Description | -|---|---| +|:---|:---| | `GOOGLE_CLIENT_ID` | Google OAuth 2.0 Client ID | | `GOOGLE_CLIENT_SECRET` | Google OAuth 2.0 Client Secret | | `GOOGLE_REDIRECT_URI` | `https://your-domain/api/v1/calendar/google/callback` | @@ -237,10 +326,8 @@ Full template: [`.env.example`](.env.example)
---- -
-

Calendar Sync

+Calendar Sync Oikos syncs bidirectionally with Google Calendar and Apple iCloud. External events are visually distinguished in the UI. On conflict, the external source wins. @@ -266,13 +353,13 @@ Oikos syncs bidirectionally with Google Calendar and Apple iCloud. External even ### Apple Calendar (iCloud CalDAV) -**Option A — via Settings UI (recommended, no restart required):** +**Option A — via Settings UI** (recommended, no restart required): 1. Go to [appleid.apple.com](https://appleid.apple.com) → Sign-In and Security → App-Specific Passwords 2. Generate a new password for "Oikos" -3. In Oikos: **Settings → Calendar Sync → Apple Calendar** → enter the CalDAV URL, Apple ID email and the app-specific password → click **Verbinden & testen** +3. In Oikos: **Settings → Calendar Sync → Apple Calendar** → enter CalDAV URL, Apple ID, and app-specific password → click **Verbinden & testen** -Credentials are stored in the database. No server restart required. +Credentials are stored in the database. No server restart needed. **Option B — via `.env`:** @@ -282,29 +369,12 @@ APPLE_USERNAME=your@apple-id.com APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx ``` -Restart: `docker compose up -d`. The sync button appears automatically in Settings. `.env`-credentials are used as fallback when no UI-credentials are saved. +Restart: `docker compose up -d`. The sync button appears automatically in Settings. `.env` credentials are used as fallback when no UI credentials are saved.
---- - -## Security - -Oikos is designed to run on a private server behind SSL. No public endpoints exist except the login page. - -- **Sessions** — `httpOnly`, `SameSite=Strict`, `Secure` in production, 7-day TTL -- **CSRF** — Double-submit cookie pattern on all state-changing requests -- **Passwords** — bcrypt with cost factor 12 -- **Rate limiting** — 5 login attempts/min, 300 API requests/min per IP -- **Headers** — Strict Content Security Policy via Helmet (`self`-only) -- **Encryption** — Optional SQLCipher AES-256 database encryption at rest -- **Access control** — No API endpoint accessible without session auth (except `/api/v1/auth/login`) -- **No public registration** — Only admins can create user accounts - ---- -
-

Development

+Development ### Local Setup @@ -318,7 +388,7 @@ npm run dev # Starts server with --watch (auto-reload) ### Tests ```bash -npm test # 146 tests across 7 suites +npm test # 146+ tests across 9 suites ``` Tests use Node.js built-in test runner with `--experimental-sqlite` for in-memory SQLite. No running server required. @@ -330,6 +400,7 @@ server/ index.js # Express entry, middleware, static serving db.js # SQLite connection, migration runner auth.js # Session auth + user management routes + middleware/ # CSRF, input validation routes/ # One file per module services/ # Calendar sync, recurrence engine public/ @@ -339,19 +410,17 @@ public/ styles/ # Design tokens, reset, layout, per-module CSS components/ # Web Components (oikos-* prefix) pages/ # Page modules with render() export - sw.js # Service worker + sw.js # Service worker (app-shell caching) ``` -**Request flow:** Client → Express static or `/api/v1/*` → session auth middleware → route handler → better-sqlite3 (sync) → JSON response. +**Request flow:** Browser → Express static (`public/`) or `/api/v1/*` → session auth middleware → route handler → better-sqlite3 (sync) → JSON response. **Database migrations** run automatically on startup. Each migration is an idempotent SQL block in `server/db.js`. Append new migrations — never modify existing ones.
---- -
-

Backup & Restore

+Backup & Restore ### Backup @@ -373,16 +442,12 @@ docker run --rm \ docker compose up -d ``` -Database migrations run automatically on startup. Data in the `oikos_data` volume is preserved across container rebuilds. +Migrations run automatically on startup. Data in the `oikos_data` volume is preserved across container rebuilds.
---- -
-

Updates & Family Members

- -### Updating Oikos +Updates ```bash git pull @@ -393,19 +458,18 @@ Migrations run automatically. Your data volume stays intact. ### Adding Family Members -Only admins can create new accounts — there is no public registration endpoint. +Only admins can create accounts — there is no public registration. -**In the browser:** Settings → Family Members → Add Member - -**Via CLI:** `docker compose exec oikos node setup.js` +- **In the browser:** Settings → Family Members → Add Member +- **Via CLI:** `docker compose exec oikos node setup.js`
--- -## Contributing +## 🤝 Contributing -Contributions are welcome. If you find a bug or have a feature idea, [open an issue](https://github.com/ulsklyc/oikos/issues). Pull requests are appreciated — please keep the vanilla JS constraint in mind (no frameworks, no build tools). +Contributions are welcome! If you find a bug or have a feature idea, [open an issue](https://github.com/ulsklyc/oikos/issues). Pull requests are appreciated — please keep the vanilla JS constraint in mind (no frameworks, no build tools). See [`CONTRIBUTING.md`](CONTRIBUTING.md) for setup instructions, code conventions, commit format, and workflow. @@ -413,10 +477,8 @@ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for setup instructions, code convention ## License -[MIT](LICENSE) © 2025 ulsklyc - ---- +[MIT](LICENSE) © 2026 ulsklyc

- Made with ☕ by ulsklyc + Made with care for families who value their privacy.

diff --git a/SECURITY.md b/SECURITY.md index 60beda9..8239fdf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ If you discover a security vulnerability in Oikos, please report it responsibly. **Do not open a public issue.** - +Instead, use [GitHub Private Vulnerability Reporting](https://github.com/ulsklyc/oikos/security/advisories/new) to submit your report. This creates a private advisory visible only to you and the maintainers. Include: diff --git a/docs/social-preview.html b/docs/social-preview.html new file mode 100644 index 0000000..2dbeaa7 --- /dev/null +++ b/docs/social-preview.html @@ -0,0 +1,193 @@ + + + + +Oikos — Social Preview + + + + +
+
Self-Hosted · Open Source
+
Oikos
+

The family planner that respects your privacy. Tasks, calendars, shopping, meals, budget — on your own server.

+
+ Tasks + 📅 Calendar + 🛒 Shopping + 🍝 Meals + 💰 Budget + 📌 Notes + 👥 Contacts + 🔒 Encrypted +
+
+ +
+ +
+ Dashboard +
+
+ + + + +