A modern, production-ready web application for secure user authentication and Salesforce account data integration. Built for assignment and real-world deployment, this project demonstrates robust auth, professional frontend/backend separation, and enterprise API integration.
A full-stack web app that allows users to register, verify their email, log in, and securely access Salesforce account data via a beautiful dashboard. Features include:
- User authentication (JWT, email verification)
- Secure access to Salesforce data (accounts, pagination)
- Responsive dashboard and robust error handling
- Frontend: Vue.js 3, Pinia, TypeScript, Axios, Vite
- Backend: Node.js, Express.js, TypeScript
- Database: PostgreSQL, Prisma ORM
- Authentication: JWT (stateless), bcrypt for password hashing
- Salesforce Integration: jsforce
- Deployment: Render (backend), Netlify (frontend)
Architecture:
backend/src/contains controllers (auth, salesforce), middleware (JWT, error, CORS), and Prisma modelsfrontend/src/contains views (auth, dashboard), router, Pinia store, and API service- All secrets and config are managed via
.envfiles (never committed) - Passwords are always hashed; JWT tokens are signed and verified securely
- CORS and helmet middleware protect backend endpoints
cd backend
npm install
cp .env.example .env # Edit with your DB, JWT, Salesforce details
npm run dev # or npm run build && npm startcd frontend
npm install
cp .env.example .env # Set VITE_API_BASE_URL to backend URL
npm run dev # or npm run build && npm preview- See
.env.examplein both backend and frontend for all required keys - PostgreSQL must be running and accessible from backend
- Salesforce Connected App credentials required for integration
- Backend: Deployed to Render (auto-deploy from GitHub)
- Frontend: Deployed to Netlify (auto-deploy from GitHub)
.envfiles are managed per environment (dev/prod)- Live Demo | API
curl -X POST https://full-stack-application-zvvd.onrender.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"testuser@example.com","password":"Test123!"}'curl -X POST https://full-stack-application-zvvd.onrender.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"testuser@example.com","password":"Test123!"}'curl -X GET https://full-stack-application-zvvd.onrender.com/api/salesforce/accounts \
-H "Authorization: Bearer <PASTE_YOUR_JWT_TOKEN_HERE>"curl -X GET https://full-stack-application-zvvd.onrender.com/api/salesforce/accounts
# Response: {"message":"No token provided"}curl -X GET https://full-stack-application-zvvd.onrender.com/api/salesforce/accounts \
-H "Authorization: Bearer <PASTE_YOUR_JWT_TOKEN_HERE>"/loginβ User login page/registerβ Registration page/verify-email/:tokenβ Email verification route/dashboardβ Protected dashboard (requires JWT)/verified-successβ Shown after successful email verification
On login:
- Success: JWT is stored, user is routed to
/dashboard - Failure: Error message shown, no token stored
- Session persists via localStorage (auto-login on refresh)
- Unauthorized users are redirected to
/login
- JWT chosen for stateless, scalable authentication
- Backend is stateless (no sessions on server), ideal for cloud deployment
- Passwords are never stored in plaintext (bcrypt)
- All API routes are protected by middleware
- Pagination is used for large Salesforce data sets
.envfiles and CORS protect secrets and endpoints
- Pagination for Salesforce account data
- TypeScript throughout (frontend & backend)
- Modern, accessible UI (responsive, keyboard-friendly)
- Email verification & resend functionality
- SPA routing with Netlify
_redirectsfor deep links
- Handling Salesforce OAuth and API rate limits in dev
- Debugging CORS and secure cookie/session flows
- TypeScript type mismatches in Prisma and API contracts
- Managing state when JWT expires or user is unverified
backend/
βββ src/
β βββ controllers/
β β βββ auth.controller.ts
β β βββ salesforce.controller.ts
β βββ middleware/
β β βββ auth.middleware.ts
β β βββ error.middleware.ts
β βββ utils/
β β βββ email.ts
β βββ lib/
β β βββ prisma.ts
β βββ index.ts
βββ prisma/
β βββ schema.prisma
βββ .env.example
βββ package.json
βββ ...
- Passwords are always hashed (bcrypt)
- JWT secret is never exposed
- All API endpoints are protected by auth middleware
- Environment variables are used for all secrets
- CORS and helmet used for HTTP security
- Expand tests (unit/integration)
- Add Salesforce OAuth flow for per-user data
- Improve error reporting and monitoring
- Enhance UI/UX for accessibility
For any questions, please contact the project maintainer.
- User authentication with JWT
- Secure password hashing
- Salesforce integration with user verification
- Protected routes and API endpoints
- Responsive dashboard with pagination
- Unit tests for core functionality
- Node.js (v16 or higher)
- PostgreSQL
- Salesforce Developer Account
- Render Account (for backend deployment)
- Netlify Account (for frontend deployment)
-
Create a Salesforce Connected App and get:
- Client ID
- Client Secret
- Username
- Password
- Security Token
-
Update your
.envfile with Salesforce credentials:SALESFORCE_CLIENT_ID=your_client_id SALESFORCE_CLIENT_SECRET=your_client_secret SALESFORCE_USERNAME=your_sf_username SALESFORCE_PASSWORD=your_sf_password SALESFORCE_TOKEN=your_sf_token
- Frontend: Vue.js 3, Pinia, Axios, Vite
- Backend: Node.js, Express.js, Sequelize
- Database: PostgreSQL
- Authentication: JWT
- Salesforce Integration: jsforce
- Deployment: Render (backend), Netlify (frontend)
- Navigate to the backend directory:
cd backend - Install dependencies:
npm install
- Create a
.envfile based on.env.example:cp .env.example .env
- Update the
.envfile with your configuration, for example:PORT=3000 DATABASE_URL=postgres://user:password@localhost:5432/dbname JWT_SECRET=your_jwt_secret SALESFORCE_CLIENT_ID=your_sf_client_id SALESFORCE_CLIENT_SECRET=your_sf_client_secret SALESFORCE_USERNAME=your_sf_username SALESFORCE_PASSWORD=your_sf_password SALESFORCE_TOKEN=your_sf_token CORS_ORIGIN=https://680c60fe649735669205fdd5--stellar-unicorn-be7810.netlify.app
- Start the development server:
npm run dev
- Navigate to the frontend directory:
cd frontend - Install dependencies:
npm install
- Create a
.envfile based on.env.example:cp .env.example .env
- Update the
.envfile with your configuration:VITE_API_BASE_URL=https://full-stack-application-zvvd.onrender.com
- Start the development server:
npm run dev
PORT=3000
DATABASE_URL=postgres://user:password@localhost:5432/dbname
JWT_SECRET=your_jwt_secret
SALESFORCE_CLIENT_ID=your_sf_client_id
SALESFORCE_CLIENT_SECRET=your_sf_client_secret
SALESFORCE_USERNAME=your_sf_username
SALESFORCE_PASSWORD=your_sf_password
SALESFORCE_TOKEN=your_sf_token
CORS_ORIGIN=https://680c60fe649735669205fdd5--stellar-unicorn-be7810.netlify.app
VITE_API_BASE_URL=https://full-stack-application-zvvd.onrender.com
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register | Register with Salesforce credentials |
| POST | /api/auth/login | Login with Salesforce verification |
| POST | /api/auth/logout | Logout user |
| GET | /api/salesforce/accounts | Get Salesforce Accounts |
| GET | /api/salesforce/accounts/:id | Get Account by ID |
| GET | /api/user/profile | Get current user profile |
cd backend
npm testcd frontend
npm test- See original documentation for architecture, security, performance, scalability, and integration notes.
- Register, login, and dashboard access
- Session persists after browser refresh
- Protected routes redirect unauthenticated users
- Error handling: invalid login, expired session, Salesforce errors
- Logout works and session is cleared
- Backend: Deployed on Render, auto-deploy from GitHub
- Frontend: Deployed on Netlify, auto-deploy from GitHub
- Set up CI/CD for backend (GitHub Actions)
- Expand backend and frontend tests
- Review security and CORS settings
- Finalize documentation and .env.example files
- All passwords are hashed using bcrypt
- JWT tokens are stored securely
- API routes are protected with authentication middleware
- Environment variables are used for sensitive data
- CORS is properly configured
- Input validation is implemented
MIT
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request