docs: README/SPEC current — multi-user, CLI accounts, Secure cookie, tests
- README: per-user history (was shared history.json), proxy/HTTPS access note, ANIWEB_SECURE, layout lists users.py + tests/ + login.html; merged duplicate history bullets - SPEC: session hardening (Secure flag, per-request account existence check), run steps include account creation + test suite, milestone 7 (auth), fixed corrupted out-of-scope tail
This commit is contained in:
1 parent
cdb25b1aba
commit
f0f8207cf7
2 files changed
+28
-16
No files matched your search
@@ -12,10 +12,13 @@ uv pip install --python .venv/bin/python -r requirements.txt
|
|||||||
./run.sh
|
./run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Open <http://localhost:8321>. `run.sh` restarts cleanly if the server
|
Open it through your HTTPS proxy (or <http://localhost:8321> from the
|
||||||
is already running; logs go to `server.log`. The server refuses to
|
host itself — browsers treat localhost as trusted). `run.sh` restarts
|
||||||
start without at least one user (a legacy `credentials.json`
|
cleanly if the server is already running; logs go to `server.log`.
|
||||||
password, if any, is migrated to user `admin`).
|
With `ANIWEB_SECURE=1` (set by `run.sh`), the session cookie is
|
||||||
|
`Secure`, so remote plain-HTTP access can't hold a session — only the
|
||||||
|
HTTPS proxy works. A legacy `credentials.json` password, if any,
|
||||||
|
is migrated to user `admin` on first start.
|
||||||
|
|
||||||
Account management (no self-signup by design):
|
Account management (no self-signup by design):
|
||||||
|
|
||||||
@@ -36,24 +39,25 @@ the app or CLI are rejected immediately, even with an old cookie.
|
|||||||
- Per-user accounts (CLI-created, no self-signup): 30-day signed
|
- Per-user accounts (CLI-created, no self-signup): 30-day signed
|
||||||
session cookie, 5 wrong attempts → 15-min lockout per user.
|
session cookie, 5 wrong attempts → 15-min lockout per user.
|
||||||
PBKDF2-SHA256 hashes in `server/data/users.json` (0600).
|
PBKDF2-SHA256 hashes in `server/data/users.json` (0600).
|
||||||
- Per-user watch history (`server/data/history/<user>.json`);
|
- Per-user watch history (`server/data/history/<user>.json`): position
|
||||||
in-header chip with logout + delete-account.
|
saved every ~10s, resume where you left off, top-5 "recently played"
|
||||||
|
on the home page. Nothing stored in the browser — new devices pick
|
||||||
|
up your watch state after login, isolated per account.
|
||||||
|
In-header chip shows the user, with logout + delete-account.
|
||||||
- Search with poster grid, detail view with synopsis + season tabs
|
- Search with poster grid, detail view with synopsis + season tabs
|
||||||
- HLS playback (vendored hls.js), browser ABR across 1080/720/360p
|
- HLS playback (vendored hls.js), browser ABR across 1080/720/360p
|
||||||
- Dub/sub toggle
|
- Dub/sub toggle
|
||||||
- Autoplays the first episode (or resumes the last watched one); if the
|
- Autoplays the first episode (or resumes the last watched one); if the
|
||||||
browser blocks autoplay, a "click to play" overlay appears
|
browser blocks autoplay, a "click to play" overlay appears
|
||||||
- Server-persisted watch history (`server/data/history.json`): watch
|
|
||||||
position saved every ~10s, resume where you left off, top-5 "recently
|
|
||||||
played" on the home page — shared across browsers and devices
|
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
```
|
```
|
||||||
server/ FastAPI app (app.py) + anidb.app fetchers (upstream.py)
|
server/ FastAPI app (app.py), anidb.app fetchers (upstream.py),
|
||||||
upstream.py is the ONLY Cloudflare-facing code
|
accounts (users.py). upstream.py is the ONLY Cloudflare-facing code
|
||||||
static/ front-end: index.html, app.js, style.css, hls.min.js (vendored)
|
static/ front-end: index.html, login.html, app.js, style.css, hls.min.js (vendored)
|
||||||
run.sh launch/restart the server
|
tests/ test suite (run.py orchestrator, HTTP + browser tests)
|
||||||
|
run.sh launch/restart the server (sets ANIWEB_SECURE=1)
|
||||||
SPEC.md design + the verified anidb.app data flow
|
SPEC.md design + the verified anidb.app data flow
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ Two moving parts, no database, no framework on the frontend.
|
|||||||
(`python -m server.users add|rm|list`) — no self-signup. One-time
|
(`python -m server.users add|rm|list`) — no self-signup. One-time
|
||||||
migration: legacy single-password `credentials.json` → user
|
migration: legacy single-password `credentials.json` → user
|
||||||
`admin`; `history.json` → `history/admin.json`.
|
`admin`; `history.json` → `history/admin.json`.
|
||||||
|
- Session hardening: cookies are `HttpOnly`, `SameSite=Lax`, and
|
||||||
|
`Secure` when `ANIWEB_SECURE=1` (set by `run.sh`); the middleware
|
||||||
|
re-verifies the account still exists per request, so deleted
|
||||||
|
accounts' cookies are rejected immediately.
|
||||||
- `GET /api/me`, `POST /account/delete` → current user / self-delete
|
- `GET /api/me`, `POST /account/delete` → current user / self-delete
|
||||||
(account + history file).
|
(account + history file).
|
||||||
|
|
||||||
@@ -91,17 +95,19 @@ Flow: search box → results grid (poster + title, click) → detail view
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
uv venv .venv && uv pip install --python .venv/bin/python -r requirements.txt
|
uv venv .venv && uv pip install --python .venv/bin/python -r requirements.txt
|
||||||
./run.sh # launch/restart, logs to server.log
|
.venv/bin/python -m server.users add <you> # one-time account creation
|
||||||
|
./run.sh # launch/restart, logs to server.log, sets ANIWEB_SECURE=1
|
||||||
```
|
```
|
||||||
|
|
||||||
Open `http://localhost:8321` (bound to 0.0.0.0 for LAN access).
|
Use the app through your HTTPS proxy (with `Secure` cookies, plain
|
||||||
|
remote HTTP can't hold a session). `python tests/run.py` runs the
|
||||||
|
full suite against a throwaway server on :8399.
|
||||||
|
|
||||||
## Out of scope (v1)
|
## Out of scope (v1)
|
||||||
|
|
||||||
Downloads (`-d`), next-episode countdown (`-N`), syncplay, intro skip,
|
Downloads (`-d`), next-episode countdown (`-N`), syncplay, intro skip,
|
||||||
ani-schedule integration, episode titles (not in anidb's API — needs
|
ani-schedule integration, episode titles (not in anidb's API — needs
|
||||||
a MyAnimeList API key). Add when someone asks.
|
a MyAnimeList API key). Add when someone asks.
|
||||||
anidb's API — needs a MyAnimeList API key). Add when someone asks.
|
|
||||||
|
|
||||||
## Risks
|
## Risks
|
||||||
|
|
||||||
@@ -122,3 +128,5 @@ anidb's API — needs a MyAnimeList API key). Add when someone asks.
|
|||||||
5. UI — search → detail → episodes → player.
|
5. UI — search → detail → episodes → player.
|
||||||
6. Polish — history with position + resume, sub/dub toggle, error
|
6. Polish — history with position + resume, sub/dub toggle, error
|
||||||
states, autoplay default, `run.sh`.
|
states, autoplay default, `run.sh`.
|
||||||
|
7. Auth — login screen, then multi-user CLI-created accounts with
|
||||||
|
per-user history + test suite.
|
||||||
Reference in new issue
Block a user