package main import ( "context" "encoding/json" "fmt" "log" "net/http" "time" "github.com/jackc/pgx/v5" ) type AuthenticateRequest struct { Accountid int64 `json:"accountid,string"` Username string `json:"username"` Password string `json:"password"` } func authenticateHandler(w http.ResponseWriter, r *http.Request) { /* var hashText string var salt []byte var err error var checkExisting pgx.Row var req CreateIdentityRequest var accountid string */ var authenticaterequest AuthenticateRequest var err error var checkExisting pgx.Row var hashText string var ok bool var token string secret := []byte("super-secret-key") response := map[string]interface{}{} w.Header().Set("Content-Type", "application/json") // Only allow POST method if r.Method != http.MethodPost { //http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) w.WriteHeader(http.StatusMethodNotAllowed) response["status"] = "error" response["message"] = "HTTP POST Method not allowed" goto ExitAPICall } // Optional: enforce content type if r.Header.Get("Content-Type") != "application/json" { w.WriteHeader(http.StatusUnsupportedMediaType) response["status"] = "error" response["message"] = "Content-Type must be application/json" goto ExitAPICall } // Read body with size limit (protect against huge requests) const maxBodyBytes = 1 << 20 // 1 MB r.Body = http.MaxBytesReader(w, r.Body, maxBodyBytes) // Decode JSON from request body directly into struct log.Println(r.Body) err = json.NewDecoder(r.Body).Decode(&authenticaterequest) if err != nil { w.WriteHeader(http.StatusInternalServerError) response["status"] = "error" response["message"] = "Invalid JSON: " + err.Error() goto ExitAPICall } log.Println(authenticaterequest) checkExisting = pool.QueryRow(context.Background(), "SELECT password_hash FROM identities WHERE accountid = $1 AND provider = $2 AND provider_user_id = $3", authenticaterequest.Accountid, "local", authenticaterequest.Username) log.Println("Received Authentication Request: AccountID:", authenticaterequest.Accountid, "Username:", authenticaterequest.Username, "Password:", authenticaterequest.Password) err = checkExisting.Scan(&hashText) if err != nil { response["status"] = "fail" response["message"] = "User account does not exist" log.Println(err) w.WriteHeader(http.StatusUnauthorized) goto ExitAPICall } log.Println(hashText) ok = verifyPassword(authenticaterequest.Password, hashText) if ok == false { response["status"] = "fail" response["message"] = "Bad password" w.WriteHeader(http.StatusUnauthorized) goto ExitAPICall } token, err = createJWT(secret, fmt.Sprintf("%d", authenticaterequest.Accountid), authenticaterequest.Username, "user") if err != nil { w.WriteHeader(http.StatusInternalServerError) response["status"] = "error" response["message"] = "Failed to create JWT" goto ExitAPICall } w.WriteHeader(http.StatusOK) response["status"] = "success" response["token"] = token ExitAPICall: w.Header().Set("Content-Type", "application/json") response["timestamp"] = fmt.Sprintf("%d", time.Now().Unix()) json.NewEncoder(w).Encode(response) }