Files
filing-cabinet-api/README.md
T
2026-07-29 22:35:36 +02:00

2.5 KiB

Filing Cabinet API

Node.js/Express API for accounts, JWT-authenticated actions, relationships, and posts.

Run

npm install
npm run dev       # nodemon app.js

Configure .env (never commit it):

PORT=3000
JWT_SECRET=<random secret, at least 32 characters>
JWT_EXPIRES_IN=86400
UPLOAD_DIR=./uploads
MAX_UPLOAD_SIZE_BYTES=5242880

Database and graph-database variables are also required by the relevant routes. See .env.example.

Authentication

POST /auth/register and POST /auth/login are public. Every other route requires either:

Authorization: Bearer <JWT>

or an HttpOnly session cookie set upon login:

Cookie: fc_session_token=<JWT>

POST /auth/login returns { id, token, expires_at } and sets the fc_session_token cookie (HttpOnly; Secure; SameSite=Strict; Path=/). Clients can verify their session automatically via GET /auth/me or GET /auth/verify. The token is HS256-signed and contains user_id, iat, and exp. Never log or expose tokens, passwords, password hashes, or salts.

API

The compact endpoint contract is in API.md. Unknown body/query fields are rejected with 400; clients must send only documented fields.

Authenticated clients can read profiles through GET /profiles/me or GET /profiles/:id, update their account with PUT /profiles/me, and delete it with DELETE /profiles/me (password confirmation). Post responses include the public author username as author_username and the database creation timestamp as created_at.

Security and ownership

  • The API is the authoritative validator; client validation is only UX.
  • Registration/login validation and password rules are defined in AUTH_INPUT_POLICY.md.
  • Post creation always uses author_id from the verified JWT; clients must not send author_id.
  • Post edit/delete require that the JWT user owns the post.
  • /posts is visible to any authenticated user; /posts/me filters by JWT user_id.
  • Post listings include author_username and created_at; profile responses expose id, name, username, and profile_link (nullable).
  • Relationship creation requires me to equal the JWT user ID.
  • Uploads accept only JPEG, PNG, GIF, and WebP, one file named image, up to MAX_UPLOAD_SIZE_BYTES (default 5 MiB). Files receive random names and are stored under UPLOAD_DIR.
  • Registration rejects disposable email addresses and weak/reused-pattern passwords. Login failures use the generic Invalid email or password response.
  • Do not expose database errors or stack traces to clients.