Files
study-bible-project/README.md
nmemmertandClaude Sonnet 5.5 f274bc9c8a
Build and Push Docker Image / build-and-push (push) Successful in 7m14s
Harden sync and security; add IQ Bible, templates, password reset, backups
Sync and data safety
- Autosave flushes on leaving a study or the tab; storage-full errors are reported
- Unsynced studies, deletes and ink are queued and retried when back online
- Deletes propagate across devices (with a "Keep it" undo) and no longer resurrect
- Server assigns study versions (no client-clock conflicts); "Combine both"
  merges a conflicted study chunk by chunk
- Reading-plan progress made offline is merged, not overwritten; plans, ink and
  marks are cleared from the device on sign-out

Security
- Block SSRF through the ntfy reminder URL; failure-only rate limiting per IP and
  account; constant-time login; TOTP replay protection; input validation;
  SESSION_SECRET required in production; admin user delete fixed
- Forgot password: one-time code sent to the account's ntfy topic

Features
- IQ Bible proxy (route allow-list, text-only caching per its terms): more
  commentaries, lexicons, study aids, daily verse and devotional, plan calendar
  export, narrations, podcast background
- Study templates, reading-plan catch-up, account export, daily database snapshots

Tests and tooling
- ESLint config; App tests split into src/test; tests for sync queues, library
  hook, merge, templates, IQ Bible UI and reset form

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 08:13:36 -04:00

159 lines
4.7 KiB
Markdown

# Bible Study App
A self-hosted Bible study tool with notes, projects, and user accounts.
---
## Requirements
- **Node.js v18 or higher** — [nodejs.org](https://nodejs.org/)
- **npm** (bundled with Node.js)
- **GCC / make** (only needed for production/server installs — required to build the `better-sqlite3` native module)
---
## Quick Start
```bash
git clone https://github.com/nmemmert/study-bible-project.git
cd study-bible-project
bash setup.sh
```
`setup.sh` installs dependencies, builds the optimized frontend, and runs one
production server (frontend + API) on **http://localhost:5173**. Set `APP_PORT`
to use a different port. If the build fails, the previously running server is
left untouched. `bash restart.sh` pulls the latest code and does the same.
**Stop / logs:**
```bash
kill $(cat .api.pid)
tail -f .api.log
```
### Development mode (hot reload)
```bash
bash setup.sh --dev
```
Starts the API on http://localhost:3001 and the Vite dev server on
http://localhost:5173. Dev mode is much slower, so don't use it for real users.
---
## Optional keys (set in `.env` or the environment)
| Variable | What it turns on |
| --- | --- |
| `SESSION_SECRET` | **Required in production.** A long random string; the server refuses to start without it. |
| `ADMIN_EMAIL` | The one admin account. |
| `ESV_API_KEY`, `API_BIBLE_KEY` | ESV, NLT, CSB and NASB in the Reader. |
| `IQBIBLE_API_KEY` | IQ Bible: more commentaries, lexicons (BDB, LSJ, Abbott-Smith), places, topics, people, textual notes, Gospel parallels, daily verse and Spurgeon devotional, plan calendar export, more audio narrations, and background for podcast prompts. Hidden when unset. |
| `IQBIBLE_CACHE_HOURS` | Leave unset unless IQ Bible has given written permission to cache non-verse data; only verse/chapter text is cached by default (24h), as their terms require. |
| `BACKUP_KEEP`, `BACKUP_DISABLED=1` | The server saves a snapshot of the whole database once a day to `DATA_DIR/backups` (default: keep 7). Restore with `scripts/restore-data.sh`. |
| `ALLOW_PRIVATE_NTFY=1` | Lets reading reminders use an ntfy server on your own network (blocked by default). |
## Production Install (Ubuntu / systemd)
Installs the app as a persistent systemd service under `/opt/study-app`.
```bash
# Install Node.js 20 (if not already installed)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install build tools (required for better-sqlite3)
sudo apt-get install -y build-essential python3
# Clone and install
git clone https://github.com/nmemmert/study-bible-project.git
cd study-bible-project
sudo bash deploy/install.sh
```
The installer will:
1. Install Node.js dependencies and build the frontend
2. Create a `study-app` system user
3. Register and start a systemd service
**Useful commands after install:**
```bash
systemctl status study-app # Check service status
journalctl -u study-app -f # Stream logs
systemctl restart study-app # Restart after an update
```
**Open the firewall port (if needed):**
```bash
sudo ufw allow 3001/tcp
sudo ufw reload
```
The app listens on **port 3001** by default. Set the `PORT` environment variable in the systemd unit to change it.
---
## Updating (Production)
```bash
cd /path/to/study-bible-project
git pull
sudo bash deploy/install.sh
```
The installer preserves the session secret across updates so logged-in users are not signed out.
---
## Migrating to a New Machine
**On the old machine — create a backup:**
```bash
npm run backup
```
This creates `study-app-backup_<timestamp>.zip` in the project root.
**On the new machine — restore after cloning and installing:**
Development:
```bash
npm run restore study-app-backup_<timestamp>.zip
```
Production (after `sudo bash deploy/install.sh` completes):
```bash
sudo bash scripts/restore-data.sh study-app-backup_<timestamp>.zip --production
```
See [scripts/backup-data.sh](scripts/backup-data.sh) and [scripts/restore-data.sh](scripts/restore-data.sh) for details.
---
## Project Structure
```
├── server/ # Express API + SQLite database
│ └── data/ # projects.db lives here (gitignored)
├── src/ # React frontend (Vite)
├── deploy/ # systemd service unit + install script
├── scripts/ # backup / restore helpers
└── setup.sh # Development quick-start
```
---
## License
Private / personal use.
## Development
```bash
npm run test:run # all tests
npm run lint # ESLint (errors fail; warnings are advice)
```
Forgotten passwords: the sign-in page's "Forgot your password?" sends a one-time code to the account's ntfy topic (the one used for reading reminders). Accounts without a topic still ask the administrator for a temporary password.