Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions .github/workflows/ci.yml

This file was deleted.

43 changes: 43 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Deploy to College Server

on:
push:
branches: [main]

jobs:
test:
name: Run tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Download dependencies
run: go mod download

- name: Run tests
run: go test ./test/... -v -count=1

deploy:
name: Deploy via SSH
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'

steps:
- name: Deploy to Server via SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
cd ~/cms-webb
git pull origin main
sudo docker compose up -d --build
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Stage 1: Build the Go application
FROM golang:1.26-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Stage 2: Final minimal image
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
14 changes: 14 additions & 0 deletions app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Stage 1: Build the React application
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Serve the static files using Nginx
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
20 changes: 20 additions & 0 deletions app/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}

# Proxy API requests to the Go backend
location /api/ {
proxy_pass http://backend:8080;
proxy_http_version 1.1;
Comment thread
ayush00git marked this conversation as resolved.
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
109 changes: 107 additions & 2 deletions config/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package config
import (
"fmt"
"log"
"time"

"github.com/ayush00git/cms-web/helpers"
"github.com/ayush00git/cms-web/models"

"golang.org/x/crypto/bcrypt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
Expand All @@ -17,9 +19,10 @@ func ConnectDB() {
DB_USER := helpers.GetEnv("DB_USER")
DB_NAME := helpers.GetEnv("DB_NAME")
DB_PASS := helpers.GetEnv("DB_PASS")
// DB_PORT := helpers.GetEnv("DB_PORT") // will see during deployment
DB_HOST := helpers.GetEnvWithDefault("DB_HOST", "localhost")
DB_PORT := helpers.GetEnvWithDefault("DB_PORT", "5432")

dsn := fmt.Sprintf("host=localhost user=%s password=%s dbname=%s port=5432 sslmode=disable", DB_USER, DB_PASS, DB_NAME)
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable", DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT)

db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
Expand All @@ -39,5 +42,107 @@ func ConnectDB() {
&models.Comment{},
)

if helpers.GetEnvWithDefault("SEED_DB", "false") == "true" {
seedUsers(DB)
}

log.Println("Database connected")
}

func seedUsers(db *gorm.DB) {
password := "Admin@123"
hashedPass, err := bcrypt.GenerateFromPassword([]byte(password), 10)
if err != nil {
Comment thread
ayush00git marked this conversation as resolved.
Outdated
log.Printf("Failed to hash seed password: %v", err)
return
}

// 1. Seed Admins
var adminCount int64
db.Model(&models.Admin{}).Count(&adminCount)
if adminCount == 0 {
log.Println("Seeding default admin users...")
admins := []models.Admin{
{Email: "xen_civil@nith.ac.in", Position: models.TypeXENCivil, IsVerified: true},
{Email: "ae_civil@nith.ac.in", Position: models.TypeAECivil, IsVerified: true},
{Email: "je_civil@nith.ac.in", Position: models.TypeJECivil, IsVerified: true},
{Email: "xen_electrical@nith.ac.in", Position: models.TypeXENElectrical, IsVerified: true},
{Email: "ae_electrical@nith.ac.in", Position: models.TypeAEElectrical, IsVerified: true},
{Email: "je_electrical@nith.ac.in", Position: models.TypeJEElectrical, IsVerified: true},
}
for i := range admins {
admins[i].Password = string(hashedPass)
admins[i].CreatedAt = time.Now()
if err := db.Create(&admins[i]).Error; err != nil {
log.Printf("Failed to seed admin %s: %v", admins[i].Email, err)
}
}
log.Println("Admin users seeded.")
}

// 2. Seed Faculty
var facultyCount int64
db.Model(&models.Faculty{}).Count(&facultyCount)
if facultyCount == 0 {
log.Println("Seeding default faculty user...")
faculty := models.Faculty{
Name: "Test Faculty",
Email: "faculty@nith.ac.in",
Password: string(hashedPass),
Department: models.CSE,
HouseNumber: "H-101",
Block: models.BlockA,
Type: models.Type1,
PhoneNumber: "1234567890",
IsVerified: true,
CreatedAt: time.Now(),
}
if err := db.Create(&faculty).Error; err != nil {
log.Printf("Failed to seed faculty user: %v", err)
} else {
log.Println("Faculty user seeded.")
}
}

// 3. Seed Warden
var wardenCount int64
db.Model(&models.Warden{}).Count(&wardenCount)
if wardenCount == 0 {
log.Println("Seeding default warden user...")
warden := models.Warden{
Name: "Test Warden",
Email: "warden@nith.ac.in",
Password: string(hashedPass),
Hostel: models.KBH,
PhoneNumber: "1234567890",
IsVerified: true,
CreatedAt: time.Now(),
}
if err := db.Create(&warden).Error; err != nil {
log.Printf("Failed to seed warden user: %v", err)
} else {
log.Println("Warden user seeded.")
}
}

// 4. Seed Centrehead
var centreheadCount int64
db.Model(&models.Centrehead{}).Count(&centreheadCount)
if centreheadCount == 0 {
log.Println("Seeding default centrehead user...")
centrehead := models.Centrehead{
Name: "Test Centrehead",
Email: "centrehead@nith.ac.in",
Password: string(hashedPass),
Building: models.ComputerCentre,
PhoneNumber: "1234567890",
IsVerified: true,
CreatedAt: time.Now(),
}
if err := db.Create(&centrehead).Error; err != nil {
log.Printf("Failed to seed centrehead user: %v", err)
} else {
log.Println("Centrehead user seeded.")
}
}
}
51 changes: 51 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version: '3.8'

services:
db:
image: postgres:15-alpine
container_name: cms-db
restart: always
environment:
POSTGRES_USER: ${DB_USER:-postgres}
POSTGRES_PASSWORD: ${DB_PASS:-postgres}
POSTGRES_DB: ${DB_NAME:-cms}
ports:
- "5433:5432"
volumes:
- postgres_data:/var/lib/postgresql/data

backend:
build:
context: .
dockerfile: Dockerfile
container_name: cms-backend
restart: always
depends_on:
- db
environment:
DB_HOST: db
DB_PORT: 5432
DB_USER: ${DB_USER:-postgres}
DB_PASS: ${DB_PASS:-postgres}
DB_NAME: ${DB_NAME:-cms}
JWT_SECRET: ${JWT_SECRET}
APP_PASSWORD: ${APP_PASSWORD}
SENDER_EMAIL: ${SENDER_EMAIL}
FRONTEND_URL: ${FRONTEND_URL:-http://localhost}
COOKIE_DOMAIN: ${COOKIE_DOMAIN:-}
ports:
- "8082:8080"

frontend:
build:
context: ./app
dockerfile: Dockerfile
container_name: cms-frontend
restart: always
ports:
- "8083:80"
depends_on:
- backend

volumes:
postgres_data:
2 changes: 1 addition & 1 deletion handlers/admin_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (h *AdminHandler) AdminLogin (c *gin.Context) {
token,
30 * 24 * 60 * 60,
"/",
"localhost",
helpers.GetEnvWithDefault("COOKIE_DOMAIN", "localhost"),
false,
true,
)
Expand Down
10 changes: 7 additions & 3 deletions handlers/admin_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"strings"
"time"

"github.com/ayush00git/cms-web/helpers"
"github.com/ayush00git/cms-web/middleware"
"github.com/ayush00git/cms-web/models"
"github.com/ayush00git/cms-web/services"
Expand Down Expand Up @@ -90,7 +91,8 @@ func (h *AdminHandler) AdminFacultyPostStatus(c *gin.Context) {
}

// create the postURL
postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, "faculty", post.ID)
frontendURL := helpers.GetEnvWithDefault("FRONTEND_URL", "http://localhost:5173")
postURL := fmt.Sprintf(`%s/admin/posts/%s/%d`, frontendURL, "faculty", post.ID)

switch post.Status {
// ** Posts with status type mentioned PendingXEN **
Expand Down Expand Up @@ -436,7 +438,8 @@ func (h *AdminHandler) AdminWardenPostStatus(c *gin.Context) {
}

// create the postURL
postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, "warden", post.ID)
frontendURL := helpers.GetEnvWithDefault("FRONTEND_URL", "http://localhost:5173")
postURL := fmt.Sprintf(`%s/admin/posts/%s/%d`, frontendURL, "warden", post.ID)

switch post.Status {
// ** Posts with status type mentioned PendingXEN **
Expand Down Expand Up @@ -782,7 +785,8 @@ func (h *AdminHandler) AdminCentreheadPostStatus(c *gin.Context) {
}

// create the postURL
postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, "centrehead", post.ID)
frontendURL := helpers.GetEnvWithDefault("FRONTEND_URL", "http://localhost:5173")
postURL := fmt.Sprintf(`%s/admin/posts/%s/%d`, frontendURL, "centrehead", post.ID)

switch post.Status {
// ** Posts with status type mentioned PendingXEN **
Expand Down
2 changes: 1 addition & 1 deletion handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (h *AuthHandler) Logout (c *gin.Context) {
" ",
-1,
"/",
"localhost",
helpers.GetEnvWithDefault("COOKIE_DOMAIN", "localhost"),
false,
true,
)
Expand Down
2 changes: 1 addition & 1 deletion handlers/centrehead_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (h *AuthHandler) CentreheadLogin(c *gin.Context) {
token,
30 * 24 * 60 * 60,
"/",
"localhost",
helpers.GetEnvWithDefault("COOKIE_DOMAIN", "localhost"),
false,
true,
)
Expand Down
6 changes: 3 additions & 3 deletions handlers/centrehead_post.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"
"time"

"github.com/ayush00git/cms-web/helpers"
"github.com/ayush00git/cms-web/middleware"
"github.com/ayush00git/cms-web/models"
"github.com/ayush00git/cms-web/services"
Expand Down Expand Up @@ -80,9 +81,8 @@ func (h *PostHandler) CentreheadPost(c *gin.Context) {
return
}

// send the mail to the corresponding xen
// <Route path="/admin/posts/:role/:post_id" element={<AdminPostView />} />
postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, head.Role, post.ID)
frontendURL := helpers.GetEnvWithDefault("FRONTEND_URL", "http://localhost:5173")
postURL := fmt.Sprintf(`%s/admin/posts/%s/%d`, frontendURL, head.Role, post.ID)
go func() {
var position models.PositionType
if post.TypeOfPost == "Civil" {
Expand Down
Loading