107 lines
2.7 KiB
Go
107 lines
2.7 KiB
Go
package controllers
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"s-class-backend/config"
|
|
"s-class-backend/models"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
// Input Register
|
|
type RegisterInput struct {
|
|
NrpNip string `json:"nrp_nip" binding:"required"`
|
|
FullName string `json:"full_name" binding:"required"`
|
|
Email string `json:"email" binding:"required,email"`
|
|
Phone string `json:"phone" binding:"required"`
|
|
Password string `json:"password" binding:"required,min=6"`
|
|
}
|
|
|
|
// Input Login
|
|
type LoginInput struct {
|
|
NrpNip string `json:"nrp_nip" binding:"required"`
|
|
Password string `json:"password" binding:"required"`
|
|
}
|
|
|
|
// --- FUNGSI REGISTER ---
|
|
func Register(c *gin.Context) {
|
|
var input RegisterInput
|
|
if err := c.ShouldBindJSON(&input); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(input.Password), bcrypt.DefaultCost)
|
|
|
|
user := models.User{
|
|
NrpNip: input.NrpNip,
|
|
FullName: input.FullName,
|
|
Email: input.Email,
|
|
Phone: input.Phone,
|
|
PasswordHash: string(hashedPassword),
|
|
Role: "student",
|
|
}
|
|
|
|
if err := config.DB.Create(&user).Error; err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "NRP/NIP atau Email sudah terdaftar!"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "Registrasi Berhasil!", "data": user})
|
|
}
|
|
|
|
// --- FUNGSI LOGIN (BARU) ---
|
|
func Login(c *gin.Context) {
|
|
var input LoginInput
|
|
|
|
// 1. Cek Input
|
|
if err := c.ShouldBindJSON(&input); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// 2. Cari User berdasarkan NRP
|
|
var user models.User
|
|
if err := config.DB.Where("nrp_nip = ?", input.NrpNip).First(&user).Error; err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "NRP atau Password salah!"})
|
|
return
|
|
}
|
|
|
|
// 3. Cek Password (Bandingkan Hash)
|
|
err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(input.Password))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "NRP atau Password salah!"})
|
|
return
|
|
}
|
|
|
|
// 4. Bikin Token JWT (Tiket Masuk)
|
|
// Token berlaku selama 24 jam
|
|
expirationTime := time.Now().Add(24 * time.Hour)
|
|
claims := &jwt.MapClaims{
|
|
"user_id": user.UserID,
|
|
"role": user.Role,
|
|
"exp": expirationTime.Unix(),
|
|
}
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
tokenString, err := token.SignedString([]byte(os.Getenv("JWT_SECRET")))
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal membuat token"})
|
|
return
|
|
}
|
|
|
|
// 5. Kirim Token ke Pengguna
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "Login Berhasil!",
|
|
"token": tokenString,
|
|
"user": gin.H{
|
|
"full_name": user.FullName,
|
|
"role": user.Role,
|
|
},
|
|
})
|
|
} |