A full-stack web application for Google Developer Groups on Campus (GDGoC) to generate and validate certificates.
- Certificate Generation: Single and bulk certificate creation
- Email Distribution: Automated certificate delivery via Brevo SMTP
- Public Validation: Certificate verification by unique ID
- Authentication: Secured with authentik proxy provider via Nginx Proxy Manager
- Role-based Access: Organization-based leader management
- Frontend: React 18 with Vite
- Backend: Node.js with Express
- Database: PostgreSQL
- Authentication: authentik (Proxy Provider)
- Email: Brevo SMTP
- Reverse Proxy: Nginx Proxy Manager
.
├── backend/
│ ├── src/
│ │ ├── db/
│ │ │ ├── index.js # Database connection
│ │ │ └── schema.sql # Database schema
│ │ ├── middleware/
│ │ │ └── auth.js # Authentication middleware
│ │ ├── routes/
│ │ │ ├── auth.js # Authentication routes
│ │ │ ├── certificates.js # Certificate routes
│ │ │ └── profile.js # Profile routes
│ │ ├── services/
│ │ │ └── emailService.js # Email service (Brevo)
│ │ └── index.js # Main server file
│ ├── package.json
│ └── .env.example
│
└── frontend/
├── src/
│ ├── components/
│ │ └── AdminApp.jsx # Admin application wrapper
│ ├── contexts/
│ │ └── AuthContext.jsx # Authentication context
│ ├── pages/
│ │ ├── AdminDashboard.jsx
│ │ ├── ProfileSetup.jsx
│ │ ├── Settings.jsx
│ │ └── PublicValidationPage.jsx
│ ├── utils/
│ │ └── api.js # API utility functions
│ ├── App.jsx # Main app component
│ └── main.jsx
├── package.json
└── .env.example
The application uses hostname-based routing to serve different interfaces:
sudo.certs-admin.certs.gdg-oncampus.dev: Admin interface (protected by authentik)certs.gdg-oncampus.dev: Public validation page (no authentication)api.certs.gdg-oncampus.dev: Backend API
- Nginx Proxy Manager intercepts requests to admin and API endpoints
- authentik validates the user and injects headers (
X-authentik-uid,X-authentik-name,X-authentik-email) - Backend reads these headers to identify and authorize users
- Frontend makes API calls with these headers automatically forwarded
ocid(TEXT, PRIMARY KEY): Unique user ID from authentikname(TEXT): Leader's full name (appears as issuer on certificates)email(TEXT, UNIQUE): Leader's emailorg_name(TEXT): Organization name (set once during profile setup)can_login(BOOLEAN): Enable/disable access
id(UUID, PRIMARY KEY)unique_id(TEXT, UNIQUE): Certificate validation IDrecipient_name(TEXT): Certificate recipientrecipient_email(TEXT): Optional email for deliveryevent_type(TEXT): 'workshop' or 'course'event_name(TEXT): Name of the eventissue_date(DATE): Certificate issue dateissuer_name(TEXT): Leader's nameorg_name(TEXT): Organization namegenerated_by(TEXT): Foreign key toallowed_leaders.ocidpdf_url(TEXT): Optional PDF URLcreated_at(TIMESTAMP)
- Node.js 18+ and npm
- PostgreSQL 14+
- Docker and Docker Compose (for deployment)
- Navigate to the backend directory:
cd backend- Install dependencies:
npm install- Create
.envfile (copy from.env.example):
cp .env.example .env- Configure environment variables in
.env:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gdgoc_certs
DB_USER=postgres
DB_PASSWORD=your_password
PORT=3001
NODE_ENV=development
SMTP_HOST=smtp-relay.brevo.com
SMTP_PORT=587
SMTP_USER=your_brevo_user
SMTP_PASS=your_brevo_password
SMTP_FROM="GDGoC Certificates" <noreply@gdg-oncampus.dev>- Set up PostgreSQL database:
# Create database
createdb gdgoc_certs
# Run schema
psql -d gdgoc_certs -f src/db/schema.sql- Start the backend:
npm run dev- Navigate to the frontend directory:
cd frontend- Install dependencies:
npm install- Create
.envfile:
cp .env.example .env- Configure environment variables in
.env:
VITE_API_URL=http://localhost:3001- Start the development server:
npm run devGET /api/auth/me- Get or create authenticated user (protected)
GET /api/profile- Get current user profile (protected)PUT /api/profile- Update user profile (protected)
POST /api/certificates- Create single certificate (protected)POST /api/certificates/bulk- Create multiple certificates (protected)GET /api/certificates- List user's certificates (protected)GET /api/validate/:uniqueId- Validate certificate (public)
GET /health- Service health check
The backend is configured to only accept requests from:
https://sudo.certs-admin.certs.gdg-oncampus.devhttps://certs.gdg-oncampus.devhttp://localhost:5173(development)http://localhost:3000(development)
- Host:
sudo.certs-admin.certs.gdg-oncampus.dev - Forward To:
frontend:80 - Access List: authentik (GDGoC-Admins group)
- Host:
certs.gdg-oncampus.dev - Forward To:
frontend:80 - Access List: None
- Host:
api.certs.gdg-oncampus.dev - Forward To:
backend:3001 - Default Access List: None
- Locations:
- Path:
/api/validate- Access List: None (public) - Path:
/- Access List: authentik (protected)
- Path:
Docker deployment configuration is available for production use. See the following guides:
- QUICKSTART.md - Quick start guide for Docker deployment
- DOCKER_DEPLOYMENT.md - Complete Docker deployment documentation
- PORT_REFERENCE.md - Port configuration and Nginx Proxy Manager setup
- documentation/ - Comprehensive setup guides
For production deployment with authentication:
- documentation/authentik-setup.md - Configure authentik as proxy provider
- documentation/nginx-proxy-manager-setup.md - Set up Nginx Proxy Manager with authentik
For certificate customization and email delivery:
- documentation/certificate-templates.md - Create and customize certificate templates
- documentation/smtp-provider-setup.md - Configure SMTP providers (Brevo, Gmail, SendGrid, etc.)
- documentation/email-templates.md - Choose and customize email templates for leaders
# 1. Configure environment
cp .env.example .env
cp backend/.env.example backend/.env
# Edit .env with database passwords and settings
# Edit backend/.env with SMTP and application settings
# 2. Start services
./deploy.sh up
# 3. Check status
./deploy.sh statusImportant:
- Change the PostgreSQL password in
.envbefore deploying to production - No ports are exposed to the host by default
- Services communicate through the internal
gdgoc-netDocker network - Configure Nginx Proxy Manager to provide external access (see PORT_REFERENCE.md)
All services communicate through a custom Docker network (gdgoc-net):
- No ports exposed to host
- Services communicate via service names
- Nginx Proxy Manager provides external access
- Profile Setup: First-time users set their organization name
- Certificate Generation: Leaders create single or bulk certificates
- Email Delivery: Certificates automatically emailed to recipients (if email provided)
- Public Validation: Anyone can verify certificates using the unique ID
- Authentication handled entirely by authentik proxy provider
- No credentials stored in application code
- CORS restricted to specific domains
- Database connection pooling with prepared statements
- Environment-based configuration
See LICENSE file for details.
This is a private project for GDGoC. Contact the maintainers for contribution guidelines.