Skip to content

Commit c9f8651

Browse files
ismoilovdevmlclaude
andcommitted
Add multi-user authentication system with database persistence
✨ Features: - 🔐 Hybrid authentication (admin from .env + multi-user support) - 💾 Database persistence for all user data (GitLab tokens, settings) - 🔑 Session-based auth with HTTP-only cookies (7 days expiry) - 🔒 Bcrypt password hashing with secure session management - 👤 Per-user GitLab configuration and preferences - 🌱 Auto-create admin user on first run via seed script - 🔐 Secure password generator script for .env files 📦 Changes: - Added User & Session models to Prisma schema - Created auth utilities (bcrypt, session management) - Built login/logout/session API routes - Added login page UI with modern design - Implemented middleware for route protection - Updated config API to be user-specific - Created password generator script (scripts/generate-env.sh) - Removed docker-entrypoint.sh, moved logic to docker-compose - Updated Sidebar to show user info and logout button - Enhanced security with SESSION_SECRET and HTTP-only cookies 🧪 Tests: - ✅ All ESLint checks passed - ✅ TypeScript compilation successful - ✅ Next.js build completed - ✅ Docker build verified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent deefd2c commit c9f8651

File tree

21 files changed

+1550
-219
lines changed

21 files changed

+1550
-219
lines changed

.env.example

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
1-
# =============================================================================
2-
# GitLab CI/CD Dashboard - Environment Configuration Template
3-
# =============================================================================
4-
# Copy this file to .env and update with your values
5-
# For production: Use strong, unique passwords
6-
# =============================================================================
1+
# ==========================================
2+
# Database Configuration
3+
# ==========================================
4+
POSTGRES_USER=gitlab_dashboard
5+
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD_HERE
6+
POSTGRES_DB=gitlab_dashboard
7+
POSTGRES_HOST=localhost
8+
POSTGRES_PORT=5432
9+
DATABASE_URL=postgresql://gitlab_dashboard:CHANGE_ME_STRONG_PASSWORD_HERE@localhost:5432/gitlab_dashboard?schema=public
710

8-
# -----------------------------------------------------------------------------
9-
# Database Configuration (PostgreSQL 17)
10-
# -----------------------------------------------------------------------------
11-
POSTGRES_USER="gitlab_dashboard"
12-
POSTGRES_PASSWORD="your_secure_postgres_password_here"
13-
POSTGRES_DB="gitlab_dashboard"
14-
POSTGRES_HOST="localhost"
15-
POSTGRES_PORT="5432"
16-
DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
11+
# ==========================================
12+
# Redis Configuration
13+
# ==========================================
14+
REDIS_PASSWORD=CHANGE_ME_REDIS_PASSWORD_HERE
15+
REDIS_HOST=localhost
16+
REDIS_PORT=6379
17+
REDIS_URL=redis://:CHANGE_ME_REDIS_PASSWORD_HERE@localhost:6379
1718

18-
# -----------------------------------------------------------------------------
19-
# Redis Configuration (Latest)
20-
# -----------------------------------------------------------------------------
21-
REDIS_PASSWORD="your_secure_redis_password_here"
22-
REDIS_HOST="localhost"
23-
REDIS_PORT="6379"
24-
REDIS_URL="redis://:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}"
19+
# ==========================================
20+
# App Configuration
21+
# ==========================================
22+
NODE_ENV=production
23+
NEXT_PUBLIC_APP_URL=http://localhost:3000
2524

26-
# -----------------------------------------------------------------------------
27-
# Application Configuration
28-
# -----------------------------------------------------------------------------
29-
NODE_ENV="production"
30-
NEXT_PUBLIC_APP_URL="http://localhost:3000"
25+
# ==========================================
26+
# Admin User (Auto-created on first run)
27+
# ==========================================
28+
ADMIN_USERNAME=admin
29+
ADMIN_PASSWORD=CHANGE_ME_ADMIN_PASSWORD
30+
ADMIN_EMAIL=[email protected]
3131

32+
# ==========================================
33+
# Security
34+
# ==========================================
35+
SESSION_SECRET=CHANGE_ME_RANDOM_SECRET_KEY_HERE

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ RUN chown nextjs:nodejs .next
4646
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
4747
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
4848

49-
# Copy Prisma files
49+
# Copy Prisma files (needed for migrations and seeding)
5050
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma
5151
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
5252
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
@@ -58,4 +58,5 @@ EXPOSE 3000
5858
ENV PORT=3000
5959
ENV HOSTNAME="0.0.0.0"
6060

61+
# Default command (can be overridden by docker-compose)
6162
CMD ["node", "server.js"]

README.md

Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,6 @@ Modern, real-time dashboard for monitoring and managing GitLab CI/CD pipelines w
1414
- 🌓 **Dark & Light Themes** - Comfortable viewing in any environment
1515
- 📱 **Responsive Design** - Works on desktop, tablet, and mobile
1616

17-
### Alerting System ⚡
18-
- 🎯 **Instant Webhook Alerts** - GitLab webhooks for real-time notifications (0-2 seconds)
19-
- 📢 **Multi-Channel Support** - Telegram, Slack, Discord, Email, Custom Webhooks
20-
- 🎛️ **Flexible Alert Rules** - Configure alerts per project or globally
21-
- 📊 **Alert History** - Track all sent notifications
22-
- 🔔 **Smart Filtering** - Alert only on specific events (success, failed, running, canceled)
23-
24-
### Infrastructure
25-
- 🗄️ **PostgreSQL Database** - Persistent storage for configurations and history
26-
-**Redis Cache** - Fast data access and reduced API calls
27-
- 🐳 **Docker Compose** - One-command deployment with all services
28-
2917
## 🚀 Quick Start
3018

3119
### Using Docker Compose (Recommended)
@@ -46,8 +34,8 @@ Open `http://localhost:3000` in your browser.
4634

4735
**Services:**
4836
- Dashboard UI: `http://localhost:3000`
49-
- PostgreSQL: `localhost:5432`
50-
- Redis: `localhost:6379`
37+
- PostgreSQL: `localhost:5432` (exposed for development)
38+
- Redis: `localhost:6379` (exposed for development)
5139

5240
### Stop Services
5341

@@ -75,53 +63,7 @@ docker-compose down -v
7563
- Create token with `api` scope
7664
- Copy and paste in dashboard
7765

78-
### 2. Setup Webhook Alerts (Instant Notifications)
79-
80-
1. Go to **Alerting** tab → **Webhook Setup ⚡**
81-
2. Copy the webhook URL: `http://localhost:3000/api/webhook/gitlab`
82-
3. **For local development**, expose your localhost using:
83-
```bash
84-
# Option 1: ngrok
85-
ngrok http 3000
86-
# You'll get: https://abc123.ngrok.io
87-
88-
# Option 2: Cloudflare Tunnel
89-
cloudflared tunnel --url http://localhost:3000
90-
```
91-
4. Add webhook in GitLab:
92-
- Project → Settings → Webhooks
93-
- URL: `https://your-tunnel-url.ngrok.io/api/webhook/gitlab`
94-
- Trigger: ✅ Pipeline events
95-
- Click "Add webhook"
96-
97-
### 3. Configure Alert Channels
98-
99-
1. Go to **Alerting** tab → **Channels** tab
100-
2. Enable and configure your preferred channel:
101-
102-
**Telegram Setup:**
103-
```bash
104-
# 1. Create bot with @BotFather
105-
# 2. Get bot token: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
106-
# 3. Get chat ID (send message to bot, then check):
107-
curl https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
108-
```
109-
110-
3. Add bot token and chat ID in dashboard
111-
4. Click "Test Connection" to verify
112-
113-
### 4. Create Alert Rules
114-
115-
1. Go to **Alerting** tab → **Alert Rules** tab
116-
2. Click "Add Alert Rule"
117-
3. Configure:
118-
- **Name**: Custom rule name
119-
- **Project**: Select project or "All Projects"
120-
- **Events**: Choose when to alert (Success, Failed, Running, Canceled)
121-
- **Channels**: Select notification channels (Telegram, Slack, etc)
122-
4. Enable the rule
12366

124-
**Done!** You'll now receive instant alerts when pipelines change status ⚡
12567

12668
## 🏗️ Tech Stack
12769

@@ -140,12 +82,6 @@ curl https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
14082
- **ORM**: Prisma
14183
- **API**: Next.js API Routes
14284

143-
### DevOps
144-
- **Containerization**: Docker + Docker Compose
145-
- **CI/CD**: GitHub Actions
146-
- **Registry**: Docker Hub
147-
- **Multi-arch**: AMD64 + ARM64
148-
14985
## 🛠️ Development
15086

15187
### Local Development
@@ -204,8 +140,4 @@ docker-compose up -d
204140
```
205141

206142

207-
If you have any questions or issues, please open an issue on GitHub.
208-
209-
---
210-
211-
**Built with ❤️ using Next.js & TypeScript**
143+
If you have any questions or issues, please open an issue on GitHub.

docker-compose.local.yml

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ services:
66
restart: unless-stopped
77
environment:
88
POSTGRES_USER: ${POSTGRES_USER:-gitlab_dashboard}
9-
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-gitlab_dashboard_2024}
9+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
1010
POSTGRES_DB: ${POSTGRES_DB:-gitlab_dashboard}
1111
volumes:
1212
- postgres_data:/var/lib/postgresql/data
13-
ports:
14-
- "5432:5432"
13+
# Development: expose port to host for debugging
14+
# ports:
15+
# - "127.0.0.1:5432:5432"
16+
expose:
17+
- "5432"
1518
healthcheck:
16-
test: ["CMD-SHELL", "pg_isready -U gitlab_dashboard"]
19+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-gitlab_dashboard}"]
1720
interval: 10s
1821
timeout: 5s
1922
retries: 5
@@ -25,13 +28,16 @@ services:
2528
image: redis:alpine
2629
container_name: gitlab-dashboard-redis
2730
restart: unless-stopped
28-
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-redis_2024}
31+
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
2932
volumes:
3033
- redis_data:/data
31-
ports:
32-
- "6379:6379"
34+
# Development: expose port to host for debugging
35+
# ports:
36+
# - "127.0.0.1:6379:6379"
37+
expose:
38+
- "6379"
3339
healthcheck:
34-
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
40+
test: ["CMD", "redis-cli", "--raw", "-a", "${REDIS_PASSWORD}", "ping"]
3541
interval: 10s
3642
timeout: 5s
3743
retries: 5
@@ -52,22 +58,40 @@ services:
5258
condition: service_healthy
5359
environment:
5460
# Database
55-
DATABASE_URL: postgresql://${POSTGRES_USER:-gitlab_dashboard}:${POSTGRES_PASSWORD:-gitlab_dashboard_2024}@postgres:5432/${POSTGRES_DB:-gitlab_dashboard}?schema=public
61+
DATABASE_URL: postgresql://${POSTGRES_USER:-gitlab_dashboard}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-gitlab_dashboard}?schema=public
5662

5763
# Redis
58-
REDIS_URL: redis://:${REDIS_PASSWORD:-redis_2024}@redis:6379
64+
REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379
5965

6066
# App Config
6167
NODE_ENV: production
62-
NEXT_PUBLIC_APP_URL: http://localhost:3000
68+
NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
6369
NEXT_PUBLIC_GITLAB_URL: ${NEXT_PUBLIC_GITLAB_URL:-https://gitlab.com}
70+
71+
# Admin User (Auto-created on first run)
72+
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
73+
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
74+
ADMIN_EMAIL: ${ADMIN_EMAIL:[email protected]}
75+
76+
# Security
77+
SESSION_SECRET: ${SESSION_SECRET}
6478
ports:
6579
- "3000:3000"
6680
networks:
6781
- gitlab-dashboard-network
68-
volumes:
69-
# Mount for environment config
70-
- ./.env.local:/app/.env.local:ro
82+
# Run migrations and seed before starting app
83+
command: >
84+
sh -c "
85+
echo '🔍 Waiting for database...' &&
86+
while ! nc -z postgres 5432; do sleep 1; done &&
87+
echo '✅ Database ready!' &&
88+
echo '🔄 Running migrations...' &&
89+
npx prisma db push --skip-generate &&
90+
echo '🌱 Creating admin user...' &&
91+
npx tsx prisma/seed.ts || echo '⚠️ Admin already exists or seed failed' &&
92+
echo '🚀 Starting app...' &&
93+
node server.js
94+
"
7195
7296
volumes:
7397
postgres_data:

docker-compose.yml

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ services:
88
restart: unless-stopped
99
environment:
1010
POSTGRES_USER: ${POSTGRES_USER:-gitlab_dashboard}
11-
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-gitlab_dashboard_2024}
11+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
1212
POSTGRES_DB: ${POSTGRES_DB:-gitlab_dashboard}
1313
volumes:
1414
- postgres_data:/var/lib/postgresql/data
15-
ports:
16-
- "5432:5432"
15+
# SECURITY: Only expose to internal network, not to host
16+
# For external access (development), uncomment:
17+
# ports:
18+
# - "127.0.0.1:5432:5432"
19+
expose:
20+
- "5432"
1721
healthcheck:
18-
test: ["CMD-SHELL", "pg_isready -U gitlab_dashboard"]
22+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-gitlab_dashboard}"]
1923
interval: 10s
2024
timeout: 5s
2125
retries: 5
@@ -27,13 +31,17 @@ services:
2731
image: redis:alpine
2832
container_name: gitlab-dashboard-redis
2933
restart: unless-stopped
30-
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-redis_2024}
34+
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
3135
volumes:
3236
- redis_data:/data
33-
ports:
34-
- "6379:6379"
37+
# SECURITY: Only expose to internal network, not to host
38+
# For external access (development), uncomment:
39+
# ports:
40+
# - "127.0.0.1:6379:6379"
41+
expose:
42+
- "6379"
3543
healthcheck:
36-
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
44+
test: ["CMD", "redis-cli", "--raw", "-a", "${REDIS_PASSWORD}", "ping"]
3745
interval: 10s
3846
timeout: 5s
3947
retries: 5
@@ -54,22 +62,40 @@ services:
5462
condition: service_healthy
5563
environment:
5664
# Database
57-
DATABASE_URL: postgresql://${POSTGRES_USER:-gitlab_dashboard}:${POSTGRES_PASSWORD:-gitlab_dashboard_2024}@postgres:5432/${POSTGRES_DB:-gitlab_dashboard}?schema=public
65+
DATABASE_URL: postgresql://${POSTGRES_USER:-gitlab_dashboard}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-gitlab_dashboard}?schema=public
5866

5967
# Redis
60-
REDIS_URL: redis://:${REDIS_PASSWORD:-redis_2024}@redis:6379
68+
REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379
6169

6270
# App Config
6371
NODE_ENV: production
6472
NEXT_PUBLIC_APP_URL: http://localhost:3000
6573
NEXT_PUBLIC_GITLAB_URL: ${NEXT_PUBLIC_GITLAB_URL:-https://gitlab.com}
74+
75+
# Admin User (Auto-created on first run)
76+
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
77+
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
78+
ADMIN_EMAIL: ${ADMIN_EMAIL:[email protected]}
79+
80+
# Security
81+
SESSION_SECRET: ${SESSION_SECRET}
6682
ports:
6783
- "3000:3000"
6884
networks:
6985
- gitlab-dashboard-network
70-
volumes:
71-
# Mount for hot reload in development (optional)
72-
- ./.env.local:/app/.env.local:ro
86+
# Run migrations and seed before starting app
87+
command: >
88+
sh -c "
89+
echo '🔍 Waiting for database...' &&
90+
while ! nc -z postgres 5432; do sleep 1; done &&
91+
echo '✅ Database ready!' &&
92+
echo '🔄 Running migrations...' &&
93+
npx prisma db push --skip-generate &&
94+
echo '🌱 Creating admin user from .env...' &&
95+
npx tsx prisma/seed.ts || echo '⚠️ Admin already exists or seed failed' &&
96+
echo '🚀 Starting app...' &&
97+
node server.js
98+
"
7399
74100
volumes:
75101
postgres_data:

docker-entrypoint.sh

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)