-
Notifications
You must be signed in to change notification settings - Fork 0
Home
_david edited this page Sep 26, 2026
·
3 revisions
Node.js/TypeScript REST API for managing candidate CVs/resumes: JWT auth (cookie + Bearer, CSRF-protected), CRUD for 7 CV sections plus a job-application tracker and named CV profiles, PDF/DOCX export, Redis-backed rate limiting/token blacklist, LinkedIn-export import, and i18n (vi/en).
Version: 1.7.0 · Author: DatVT · License: ISC · Live: nodejs-resume-api-ts.onrender.com
- Getting Started — clone, env setup, run locally (or via Docker), all npm scripts
- Architecture — project structure, request/middleware flow, module layout
- API Reference — every endpoint, grouped by area
- Authentication — JWT (cookie + Bearer) flow, CSRF, token blacklist, session revocation, i18n messages
- Data Models — Candidate + CV sections + Application/Profile/Visit, multi-language content shape, soft-delete
- Security — protections in place, invariants, past incidents and fixes
- Deployment — branching model, Render + GitHub Actions pipeline, Docker, known gotchas
- Contributing — branch/PR conventions, testing, issue tracker
| Layer | Tech |
|---|---|
| Runtime | Node.js >=20.19.0 <23.0.0 + TypeScript 5.5 (strict, CommonJS) |
| Framework | Express 4.19 |
| Database | MongoDB + Mongoose 8.4 |
| Cache / Blacklist | Redis 4.6 (in-memory fallback if unset/unreachable) |
| Auth | JWT (access + refresh, httpOnly cookie or Bearer), Bcrypt (12 rounds), double-submit CSRF |
| Validation | Joi 17.13 |
| PDF / DOCX | Puppeteer 22.13 + PDFKit 0.15 + Pug 3.0 / docx 9.7 |
| Uploads / parsing | multer 2.3 (CV/image/LinkedIn-export uploads), adm-zip + csv-parse (LinkedIn export) |
| Logging | Winston 3.19 + daily-rotate-file |
| Testing | Jest 29 + ts-jest |
| i18n | Hand-rolled (Accept-Language, vi default / en opt-in), 100+ message keys across auth/candidate/CV-section/images |
A lot has landed since the last full wiki pass (2026-08-21, v1.1.0):
-
CSRF + httpOnly cookie auth (#119, #134) — tokens can now travel as httpOnly cookies (needed once the frontend and API became genuinely cross-site), with a real double-submit CSRF check replacing the incidental protection that
SameSite=strictused to provide. -
Soft-delete + restore (#121) across every CV section — deletes are now recoverable (
POST .../restore/:id) instead of permanent. - CV Profiles (#133) — a candidate can define named subsets ("Tổng hợp"/All by default, plus custom ones) of their Education/Experience/Project/Certificate/Award/Reference entries, and share a public link filtered to just one profile.
-
Job Application tracker (#132) — a private
applicationsCV-section (applied/interview/offer/rejected pipeline), separate from the public CV. - LinkedIn export import (#141) — upload a LinkedIn "Data export" ZIP, get back parsed Education/Experience entries for the frontend to review before saving (stateless, nothing persisted server-side).
-
Vanity slug public profiles (#120) —
GET /api/me/:slug-or-email, plus per-visit analytics (IP + geo). - Logout of all devices (#74), pagination/sort on CV-section lists (#73), DOCX export alongside PDF, and Docker support for local/dev/prod parity.
- Two real security incidents were found and fixed via
/code-review: a NoSQL-filter-collapse bug that could leak an arbitrary candidate's profile (#135), and a soft-delete bypass that let an already-deleted document still be mutated via update/patch (#136) — see Security for both.
See Security for incident writeups and Data Models for the current schema shape. Full technical evidence for every change lives in the repo at agent-hub/evidence/.