update main.py
kaasislekker
This commit is contained in:
+65
-1
@@ -1,7 +1,7 @@
|
||||
from database import execute, fetch_one, fetch_all
|
||||
import bcrypt
|
||||
from jose import jwt
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
from fastapi import Depends
|
||||
@@ -10,6 +10,7 @@ from email_service import (
|
||||
create_verification,
|
||||
send_password_reset_email,
|
||||
create_password_reset,
|
||||
hash_token,
|
||||
)
|
||||
|
||||
import secrets
|
||||
@@ -268,4 +269,67 @@ def reset_password(email: str):
|
||||
|
||||
return {
|
||||
"status": "sent",
|
||||
}
|
||||
|
||||
def reset_password_with_token(token: str, new_password: str):
|
||||
token_hash = hash_token(token)
|
||||
|
||||
reset = fetch_one(
|
||||
"""
|
||||
SELECT id, user_id, expires_at
|
||||
FROM password_reset_tokens
|
||||
WHERE token_hash = ?
|
||||
""",
|
||||
(token_hash,),
|
||||
)
|
||||
|
||||
if reset is None:
|
||||
return {
|
||||
"status": "failed",
|
||||
"reason": "invalid_token",
|
||||
}
|
||||
|
||||
expires_at = datetime.fromisoformat(reset["expires_at"])
|
||||
|
||||
if datetime.now(timezone.utc) >= expires_at:
|
||||
execute(
|
||||
"""
|
||||
DELETE FROM password_reset_tokens
|
||||
WHERE id = ?
|
||||
""",
|
||||
(reset["id"],),
|
||||
)
|
||||
|
||||
return {
|
||||
"status": "failed",
|
||||
"reason": "token_expired",
|
||||
}
|
||||
|
||||
password_hash = bcrypt.hashpw(
|
||||
new_password.encode(),
|
||||
bcrypt.gensalt(),
|
||||
).decode()
|
||||
|
||||
execute(
|
||||
"""
|
||||
UPDATE users
|
||||
SET password_hash = ?
|
||||
WHERE id = ?
|
||||
""",
|
||||
(
|
||||
password_hash,
|
||||
reset["user_id"],
|
||||
),
|
||||
)
|
||||
|
||||
execute(
|
||||
"""
|
||||
DELETE FROM password_reset_tokens
|
||||
WHERE id = ?
|
||||
""",
|
||||
(reset["id"],),
|
||||
)
|
||||
|
||||
return {
|
||||
"status": "updated",
|
||||
}
|
||||
@@ -30,6 +30,7 @@ from auth import (
|
||||
change_password,
|
||||
delete_me,
|
||||
reset_password,
|
||||
reset_password_with_token,
|
||||
)
|
||||
|
||||
from permissions import (
|
||||
@@ -126,6 +127,10 @@ class RoomCreate(BaseModel):
|
||||
class ForgotPassword(BaseModel):
|
||||
email: EmailStr
|
||||
|
||||
class PasswordReset(BaseModel):
|
||||
token: str
|
||||
new_password: str = Field(min_length=8)
|
||||
|
||||
|
||||
class RoomSearch(BaseModel):
|
||||
invite_code: str
|
||||
@@ -1134,6 +1139,27 @@ def api_forgot_password(
|
||||
):
|
||||
return reset_password(data.email)
|
||||
|
||||
@app.post(
|
||||
"/update-password",
|
||||
summary="Reset password with token",
|
||||
description="Sets a new password using a password reset token.",
|
||||
)
|
||||
def api_update_password(
|
||||
data: PasswordReset,
|
||||
):
|
||||
result = reset_password_with_token(
|
||||
data.token,
|
||||
data.new_password,
|
||||
)
|
||||
|
||||
if result["status"] == "failed":
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=result["reason"],
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
# easter egg
|
||||
|
||||
@app.get(
|
||||
|
||||
Reference in New Issue
Block a user