Initial commit - Migrated to Dev environment
This commit is contained in:
91
backend/app/api/v1/endpoints/auth.py
Executable file
91
backend/app/api/v1/endpoints/auth.py
Executable file
@@ -0,0 +1,91 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, text
|
||||
from datetime import datetime, timedelta
|
||||
import hashlib, secrets
|
||||
|
||||
from app.db.session import get_db
|
||||
from app.models.user import User
|
||||
from app.core.security import get_password_hash
|
||||
from app.services.email_manager import email_manager
|
||||
from app.services.config_service import config
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.post("/register")
|
||||
async def register(
|
||||
request: Request,
|
||||
email: str,
|
||||
password: str,
|
||||
first_name: str,
|
||||
last_name: str,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
ip = request.client.host
|
||||
|
||||
# 1. BOT-VÉDELEM
|
||||
throttle_min = await config.get_setting('registration_throttle_minutes', default=10)
|
||||
check_throttle = await db.execute(text("""
|
||||
SELECT count(*) FROM data.audit_logs
|
||||
WHERE ip_address = :ip AND action = 'USER_REGISTERED' AND created_at > :t
|
||||
"""), {'ip': ip, 't': datetime.utcnow() - timedelta(minutes=int(throttle_min))})
|
||||
|
||||
if check_throttle.scalar() > 0:
|
||||
raise HTTPException(status_code=429, detail="Túl sok próbálkozás. Várj pár percet!")
|
||||
|
||||
# 2. REGISZTRÁCIÓ
|
||||
res = await db.execute(select(User).where(User.email == email))
|
||||
if res.scalars().first():
|
||||
raise HTTPException(status_code=400, detail="Ez az email már foglalt.")
|
||||
|
||||
new_user = User(
|
||||
email=email,
|
||||
hashed_password=get_password_hash(password),
|
||||
first_name=first_name,
|
||||
last_name=last_name,
|
||||
is_active=False
|
||||
)
|
||||
db.add(new_user)
|
||||
await db.flush()
|
||||
|
||||
# 3. TOKEN & LOG
|
||||
raw_token = secrets.token_urlsafe(48)
|
||||
token_hash = hashlib.sha256(raw_token.encode()).hexdigest()
|
||||
await db.execute(text("""
|
||||
INSERT INTO data.verification_tokens (user_id, token_hash, token_type, expires_at)
|
||||
VALUES (:u, :t, 'email_verify', :e)
|
||||
"""), {'u': new_user.id, 't': token_hash, 'e': datetime.utcnow() + timedelta(days=2)})
|
||||
|
||||
await db.execute(text("""
|
||||
INSERT INTO data.audit_logs (user_id, action, endpoint, method, ip_address)
|
||||
VALUES (:u, 'USER_REGISTERED', '/register', 'POST', :ip)
|
||||
"""), {'u': new_user.id, 'ip': ip})
|
||||
|
||||
# 4. EMAIL KÜLDÉS
|
||||
verify_link = f"http://{request.headers.get('host')}/api/v1/auth/verify?token={raw_token}"
|
||||
email_body = f"<h1>Szia {first_name}!</h1><p>Aktiváld a fiókod: <a href='{verify_link}'>{verify_link}</a></p>"
|
||||
|
||||
await email_manager.send_email(
|
||||
recipient=email,
|
||||
subject="Regisztráció megerősítése",
|
||||
body=email_body,
|
||||
email_type="registration",
|
||||
user_id=new_user.id
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
return {"message": "Sikeres regisztráció! Ellenőrizd az email fiókodat."}
|
||||
|
||||
@router.get("/verify")
|
||||
async def verify_account(token: str, db: AsyncSession = Depends(get_db)):
|
||||
token_hash = hashlib.sha256(token.encode()).hexdigest()
|
||||
query = text("SELECT user_id FROM data.verification_tokens WHERE token_hash = :t AND is_used = False")
|
||||
res = await db.execute(query, {'t': token_hash})
|
||||
row = res.fetchone()
|
||||
if not row:
|
||||
raise HTTPException(status_code=400, detail="Érvénytelen aktiváló link")
|
||||
|
||||
await db.execute(text("UPDATE data.users SET is_active = True WHERE id = :id"), {'id': row[0]})
|
||||
await db.execute(text("UPDATE data.verification_tokens SET is_used = True WHERE token_hash = :t"), {'t': token_hash})
|
||||
await db.commit()
|
||||
return {"message": "Fiók aktiválva!"}
|
||||
Reference in New Issue
Block a user