This is the backend API for BumpAlert. It handles user authentication, password reset, Google sign-in, and user-scoped anomaly reports.
- Node.js
- TypeScript
- Express
- Cloudflare Workers
- Cloudflare D1 with SQLite
- JWT for authentication
- bcrypt for password hashing
- Zod for validation
- User registration and login
- Password reset flow
- Google sign-in support
- Secure JWT-based auth
- User-scoped road anomaly storage
- Report listing and status updates
- SQLite storage through Cloudflare D1
- Node.js 20+
- npm
- Cloudflare account
- Wrangler
- Open the server folder.
- Copy the example environment file:
copy .env.example .env- Update the values in
.envfor local development.
Example:
PORT=3000
JWT_SECRET=change_this_to_a_secure_secret
JWT_EXPIRES_IN=365d
CORS_ORIGIN=http://localhost:4200
GOOGLE_CLIENT_ID=npm install
npm run devWrangler uses a local D1 database for development.
npm installnpx wrangler d1 migrations apply bumpalert-db --remotenpx wrangler secret put JWT_SECRET
npx wrangler secret put GOOGLE_CLIENT_ID
npx wrangler secret put RESEND_API_KEYVerify the sender domain in Resend before deploying. The sender address is configured as noreply@bumpalert.thepixelwriter.com.
npm run deployThe API is deployed to https://api.bumpalert.thepixelwriter.com.
Interactive API documentation is available at:
https://api.bumpalert.thepixelwriter.com/api/swagger
The raw OpenAPI document is available at:
https://api.bumpalert.thepixelwriter.com/api/swagger.json
POST /api/auth/registerPOST /api/auth/loginPOST /api/auth/googlePOST /api/auth/forgot-passwordPOST /api/auth/reset-password
All report routes require a bearer token.
POST /api/reportsGET /api/reportsGET /api/reports/nearbyGET /api/reports/:idPATCH /api/reports/:id/status
- Passwords are hashed before storage.
- JWT tokens are used for authenticated requests. Sessions last up to 365 days by default and are invalidated when the account password is changed.
- CORS allows the hosted web app during the transition, local development, and the default Capacitor origins (
https://localhoston Android andcapacitor://localhoston iOS). Capacitor preflight requests do not consume the stricter authentication rate limit. - The planned distribution is native-only: Android and iOS apps will call the API, while
bumpalert.thepixelwriter.comwill become a landing page linking to the app stores. Once that replaces the hosted PWA, remove its origin and the local web development origins from the productionCORS_ORIGINallowlist; retain only the origins required by native clients. - User data is isolated by user ID.
- The Worker applies Cloudflare rate limits of 120 requests per minute per client IP overall and 10 per minute for authentication routes.
- API responses are marked
Cache-Control: no-store; the API custom domain is served through Cloudflare's edge proxy/CDN without caching personalized responses. - JSON request bodies are limited to 64 KiB, report submissions are capped at 100 hazards, and outbound password-reset email requests time out after 8 seconds.
- Structured request/security events are available through Worker observability and Wrangler tail logs. Workers cannot run host-based Fail2ban; rate-limit bindings provide automated request mitigation.
- Configure Cloudflare zone WAF rules separately in the Cloudflare dashboard: enable the managed ruleset for
api.bumpalert.thepixelwriter.com, then add a custom rule matchinghttp.host eq "api.bumpalert.thepixelwriter.com" and not http.request.method in {"GET" "HEAD" "POST" "PATCH" "OPTIONS"}with the Block action. Zone-level WAF rules are not deployable from this Worker configuration. - Worker execution and D1 operations are bounded by Cloudflare platform limits; Node HTTP server keep-alive/header timeout settings are not supported in the Workers runtime.
This server keeps user-specific anomaly records separate in D1 and runs entirely on Cloudflare Workers.