Peak Point is a full-stack web application built for the Advanced Full Stack Development course.
This repository contains the Hapi.js backend and covers Level 1–5 of the assignment.
The backend provides:
- REST API for the Svelte frontend
- server-rendered Handlebars views
- authentication + security features (JWT, OAuth, 2FA)
- MongoDB persistence and Cloudinary integration
- testing + CI/CD pipeline
-
Backend (Render):
https://peak-point.onrender.com -
Swagger / OpenAPI:
https://peak-point.onrender.com/documentation
- Node.js (ES Modules)
- Hapi.js
- Handlebars (views)
- Joi (validation)
- MongoDB Atlas + Mongoose
- JWT auth
- Cloudinary (image hosting)
- bcryptjs (password hashing)
- @hapi/bell (OAuth)
- speakeasy (2FA)
- Mocha + Chai + Axios (tests)
- GitHub Actions (CI/CD)
- Render deploy hook (deployment trigger)
- signup/login (cookie auth)
- peaks CRUD basics
- basic API + tests
- MongoDB persistence
- categories model
- admin panel
- Cloudinary images
- Swagger docs
- tests updated for Mongo
- bcrypt hashing/salting
- CORS enabled
- user-specific endpoints
- authorisation rules (owner/admin delete)
- OAuth login via GitHub + Google (Hapi Bell)
- SSR-compatible redirect back to frontend
- Two Factor Authentication
- CI/CD pipeline for backend (GitHub Actions + Render deploy hook)
- signup & login using cookie authentication
- session stored in cookie
- create/list peaks with:
- name
- description
- latitude / longitude
- delete peaks
- REST API for users and peaks
- core unit/integration tests
- migration from LowDB → MongoDB Atlas using Mongoose
- seed data for users, categories, peaks
- peaks extended with:
- elevation
- categories (many-to-many)
- image URLs array
- full CRUD (create/update/delete)
- filter peaks by category
- categories stored in MongoDB
- linked to peaks
- admin can create/remove categories
- server-rendered admin interface:
- list/remove users
- manage categories
- protected admin routes
- OpenAPI docs (Swagger UI)
- endpoints for users/peaks/categories
- backend stores image metadata (URLs)
- image files are hosted externally on Cloudinary
- peaks store an array of image URLs
- MongoDB Atlas (DB)
- Render (backend)
- passwords hashed using
bcryptjs - seed passwords are hashed
- improved auth response fields
- CORS enabled globally (frontend runs on different domain)
- delete peak restricted:
- only the peak owner or admin can delete
- endpoints provide user-specific data (
/api/peaks/user)
OAuth login implemented using Hapi Bell.
- strategies for GitHub + Google (
github-oauth,google-oauth) - Bell handles OAuth handshake and profile fetching
- backend upserts user from OAuth provider profile
- backend generates JWT and redirects back to frontend callback (
OAUTH_REDIRECT_URL)
This makes OAuth work both locally and in production with Netlify + Render.
2FA is implemented using speakeasy.
Flow:
- backend generates a secret for the user
- frontend displays
otpauthUrlas QR code - authenticator app generates time-based codes (TOTP)
- backend verifies the code
- recovery codes are generated for backup
Backend CI/CD uses GitHub Actions:
- install dependencies
- create CI
.envfile with dummy secrets (NODE_ENV=test) - start API server
- wait for
/health - run backend tests
- only runs on push to
main - triggers Render deployment using deploy hook URL stored as GitHub secret
npm install --legacy-peer-deps
npm run dev