This commit is contained in:
2026-02-11 17:46:22 +03:00
commit eacfacb13b
266 changed files with 51337 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
package routes
import (
"bssapp-backend/internal/auditlog"
"bssapp-backend/internal/mailer"
"bssapp-backend/internal/security"
"database/sql"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"time"
)
func ForgotPasswordHandler(
db *sql.DB,
mailer *mailer.GraphMailer,
) http.HandlerFunc {
type request struct {
Email string `json:"email"`
}
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
// -------------------------------------------------------
// 1⃣ Request parse (enumeration yok)
// -------------------------------------------------------
var req request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
respondOK(w)
return
}
email := strings.TrimSpace(strings.ToLower(req.Email))
if email == "" {
respondOK(w)
return
}
// -------------------------------------------------------
// 2⃣ Aktif kullanıcıyı bul
// -------------------------------------------------------
var userID int64
err := db.QueryRow(`
SELECT id
FROM mk_dfusr
WHERE email = $1
AND is_active = true
`, email).Scan(&userID)
if err != nil {
// ❗ kullanıcı yok → bilgi sızdırma yok
respondOK(w)
return
}
// -------------------------------------------------------
// 3⃣ Reset token üret
// -------------------------------------------------------
plain, hash, err := security.GenerateResetToken()
if err != nil {
respondOK(w)
return
}
expires := time.Now().Add(30 * time.Minute)
// -------------------------------------------------------
// 4⃣ DBye SADECE HASH kaydet
// -------------------------------------------------------
_, _ = db.Exec(`
INSERT INTO dfusr_password_reset (
dfusr_id,
token,
expires_at
)
VALUES ($1, $2, $3)
`, userID, hash, expires)
// -------------------------------------------------------
// 5⃣ Reset URL (PLAIN token)
// -------------------------------------------------------
resetURL := fmt.Sprintf(
"%s/password-reset/%s",
os.Getenv("FRONTEND_URL"),
plain,
)
// -------------------------------------------------------
// 6⃣ Mail gönder (fail olsa bile enumeration yok)
// -------------------------------------------------------
_ = mailer.SendPasswordResetMail(email, resetURL)
// -------------------------------------------------------
// 7⃣ AUDIT LOG
// -------------------------------------------------------
auditlog.Write(auditlog.ActivityLog{
ActionType: "PASSWORD_FORGOT_REQUEST",
ActionCategory: "security",
ActionTarget: email,
IsSuccess: true,
})
respondOK(w)
}
}
func respondOK(w http.ResponseWriter) {
_ = json.NewEncoder(w).Encode(map[string]bool{
"success": true,
})
}