package auth import ( "cpone-dashboard/db" "embed" "html/template" "net/http" ) var ( tmplFS *embed.FS authSecret string basePath string ) func Init(fs *embed.FS, secret string) { tmplFS = fs authSecret = secret } func SetBasePath(p string) { basePath = p } type loginData struct { Error string } func ShowLogin(w http.ResponseWriter, r *http.Request) { if getSession(r, authSecret) != "" { http.Redirect(w, r, basePath+"/dashboard", http.StatusSeeOther) return } render(w, loginData{}) } func DoLogin(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") var hash, salt string err := db.DB.QueryRow( `SELECT User_Password, COALESCE(User_Salt, '') FROM dashboard_user WHERE User_Username = ? AND User_IsActive = 'Y'`, username, ).Scan(&hash, &salt) if err != nil || !checkPassword(password, salt, hash) { w.WriteHeader(http.StatusUnauthorized) render(w, loginData{Error: "Username atau password salah."}) return } SetSession(w, username, authSecret) http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther) } func DoLogout(w http.ResponseWriter, r *http.Request) { ClearSession(w) http.Redirect(w, r, basePath+"/mcu-login", http.StatusSeeOther) } func checkPassword(password, salt, storedHash string) bool { return hashPassword(password, salt) == storedHash } func render(w http.ResponseWriter, data loginData) { b := func(path string) string { return basePath + path } t := template.Must(template.New("").Funcs(template.FuncMap{"b": b}).ParseFS(tmplFS, "templates/login/index.html")) t.ExecuteTemplate(w, "login", data) }