64 lines
1.2 KiB
Go
64 lines
1.2 KiB
Go
package routes
|
||
|
||
import (
|
||
"crypto/sha256"
|
||
"database/sql"
|
||
"encoding/hex"
|
||
"net/http"
|
||
"time"
|
||
|
||
"github.com/gorilla/mux"
|
||
)
|
||
|
||
// GET /api/password/reset/validate/{token}
|
||
func ValidatePasswordResetTokenHandler(db *sql.DB) http.HandlerFunc {
|
||
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
||
token := mux.Vars(r)["token"]
|
||
if token == "" {
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
|
||
// 🔐 plain token -> hash
|
||
h := sha256.Sum256([]byte(token))
|
||
tokenHash := hex.EncodeToString(h[:])
|
||
|
||
var (
|
||
userID int64
|
||
expiresAt time.Time
|
||
usedAt sql.NullTime
|
||
)
|
||
|
||
err := db.QueryRow(`
|
||
SELECT user_id, expires_at, used_at
|
||
FROM password_reset_tokens
|
||
WHERE token_hash = $1
|
||
LIMIT 1
|
||
`, tokenHash).Scan(&userID, &expiresAt, &usedAt)
|
||
|
||
if err != nil {
|
||
// ❗ bilgi sızdırma yok
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
|
||
// ⏰ Süre kontrolü
|
||
if time.Now().After(expiresAt) {
|
||
http.NotFound(w, r)
|
||
return
|
||
}
|
||
|
||
// 🔁 Tek kullanımlık
|
||
if usedAt.Valid {
|
||
http.Error(w, "token already used", http.StatusGone)
|
||
return
|
||
}
|
||
|
||
// ✅ TOKEN GEÇERLİ
|
||
w.Header().Set("Content-Type", "application/json")
|
||
w.WriteHeader(http.StatusOK)
|
||
w.Write([]byte(`{"valid":true}`))
|
||
}
|
||
}
|