Skip to content

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

todo-api-auth

Built by NOUMENON, an AI build engine. One prompt to a production-ready API. Follow the build: @noumenon.ai

What this is

A fully authenticated REST API for todo management: JWT auth, per-user data isolation, server-side input validation, parameterized SQL (injection-safe), secret hygiene, and a health endpoint.

Built from one prompt, then tested and gate-checked before shipping.

The prompt

NOUMENON: build a simple todo list API with auth. Node.js.
Show me the phases, run the tests, enforce the gates.

What NOUMENON produced

  • A working authenticated API
  • 40 tests, 40 passing
  • 7 security gates, all verified in code
  • A phased build with git checkpoints (b1 p1 through p4)
  • A broken security gate caught and fixed during the build
  • Scope drift flagged, disclosed, then removed to match the spec

Security gates (all passing)

Gate Status Evidence
Data isolation PASS Every todo query is WHERE user_id = ? bound to req.userId; all parameterized prepared statements
user_id server-derived PASS req.userId is set only from the jwt.verify() payload; a client-supplied value is never trusted
Auth rejection PASS Missing token returns 401; cross-user access returns 404; both tested
Input validation PASS src/validate.js, bounded and allow-listed, parameterized SQL only
Secret hygiene PASS .gitignore blocks .env*, *.db, and keys; nothing sensitive tracked; secrets fail fast on boot
Health and bind guard PASS /health requires no auth; loopback-only bind enforced in src/config.js
Data map PASS docs/DATA_MAP.md shipped

Test results

40/40 passing (Jest + supertest)

Coverage includes:
- Every endpoint happy path
- Bad-input and 404 error paths
- SQL injection stored as data, not executed
- No token -> 401
- Valid token, wrong user -> 404

One gate was broken; NOUMENON caught it

The secret-scan pre-commit hook hard-required ripgrep and ran the matcher inside an if condition. With set -e, a missing rg made the condition evaluate false, so the hook passed silently. A fail-open: it could never block a secret if ripgrep was absent.

The fix makes the scanner tool-agnostic: prefer rg, fall back to GNU grep -P, and exit non-zero if neither exists (fail closed). Verified with a real commit containing a planted AKIA... key, which is now rejected; a clean tree still passes.

Scope drift, flagged then removed

The engine added three things that were not in the original spec:

  • Idempotency-Key handling for POST /todos
  • express-rate-limit on the auth routes
  • a pino logging dependency

They were flagged to the operator rather than shipped silently. The operator chose to bring the build back to the bare spec, so the idempotency feature and the two extra dependencies were removed. Structured request logging was kept, because the spec called for observability, but it now uses a small built-in JSON logger with no third-party dependency. This is the reviewer-implementer loop completing: drift surfaced, decision made, build corrected.

Stack

  • Node.js and Express 5
  • better-sqlite3
  • jsonwebtoken (JWT)
  • bcrypt
  • built-in JSON structured logging (no logging dependency)
  • Jest and supertest

Run it

Requires Node.js >= 22.13.1.

npm install
npm run setup    # creates .env with a freshly generated JWT_SECRET
npm test         # 40/40
npm start        # binds to 127.0.0.1:3000 by default

npm run setup writes a local .env (gitignored) from .env.example with a secure random JWT_SECRET. It will not overwrite an existing .env. The server refuses to start with the placeholder secret by design.

The server binds to a loopback interface by default and refuses non-loopback hosts unless explicitly configured. If port 3000 is already in use on your machine, set a different PORT in .env (for example PORT=4010); the server prints a clear message instead of crashing.

Endpoints

Method Path Auth Description
POST /auth/register None Register a user
POST /auth/login None Log in, returns a JWT
GET /todos JWT List your todos
POST /todos JWT Create a todo
GET /todos/:id JWT Get one of your todos
PUT /todos/:id JWT Update your todo
DELETE /todos/:id JWT Delete your todo
GET /health None Health check

What NOUMENON is

NOUMENON is an AI build engine. You describe what you want; it architects it, writes it, tests it, enforces security gates, flags scope drift, and ships it.

Follow the build: @noumenon.ai


This repo is a proof of concept. Every gate is real and every test is real. Read the code and verify it yourself.

About

Built by NOUMENON build engine. Single prompt to 40 tests passing, 7 security gates verified in code. Read the README.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages