update main.py
kaasislekker
This commit is contained in:
+65
-1
@@ -1,7 +1,7 @@
|
|||||||
from database import execute, fetch_one, fetch_all
|
from database import execute, fetch_one, fetch_all
|
||||||
import bcrypt
|
import bcrypt
|
||||||
from jose import jwt
|
from jose import jwt
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta, timezone
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import os
|
import os
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
@@ -10,6 +10,7 @@ from email_service import (
|
|||||||
create_verification,
|
create_verification,
|
||||||
send_password_reset_email,
|
send_password_reset_email,
|
||||||
create_password_reset,
|
create_password_reset,
|
||||||
|
hash_token,
|
||||||
)
|
)
|
||||||
|
|
||||||
import secrets
|
import secrets
|
||||||
@@ -268,4 +269,67 @@ def reset_password(email: str):
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "sent",
|
"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,
|
change_password,
|
||||||
delete_me,
|
delete_me,
|
||||||
reset_password,
|
reset_password,
|
||||||
|
reset_password_with_token,
|
||||||
)
|
)
|
||||||
|
|
||||||
from permissions import (
|
from permissions import (
|
||||||
@@ -126,6 +127,10 @@ class RoomCreate(BaseModel):
|
|||||||
class ForgotPassword(BaseModel):
|
class ForgotPassword(BaseModel):
|
||||||
email: EmailStr
|
email: EmailStr
|
||||||
|
|
||||||
|
class PasswordReset(BaseModel):
|
||||||
|
token: str
|
||||||
|
new_password: str = Field(min_length=8)
|
||||||
|
|
||||||
|
|
||||||
class RoomSearch(BaseModel):
|
class RoomSearch(BaseModel):
|
||||||
invite_code: str
|
invite_code: str
|
||||||
@@ -1134,6 +1139,27 @@ def api_forgot_password(
|
|||||||
):
|
):
|
||||||
return reset_password(data.email)
|
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
|
# easter egg
|
||||||
|
|
||||||
@app.get(
|
@app.get(
|
||||||
|
|||||||
Reference in New Issue
Block a user