first commit
This commit is contained in:
commit
d416fe4cce
69 changed files with 8269 additions and 0 deletions
0
backend/app/core/__init__.py
Normal file
0
backend/app/core/__init__.py
Normal file
31
backend/app/core/config.py
Normal file
31
backend/app/core/config.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from dataclasses import dataclass, field
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
backend_env_path = Path(__file__).resolve().parents[2] / ".env"
|
||||
load_dotenv(dotenv_path=backend_env_path)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Settings:
|
||||
app_name: str = os.getenv("APP_NAME", "Zero Knowledge Platform API")
|
||||
mongo_uri: str = os.getenv("MONGODB_URI", "mongodb://localhost:27017")
|
||||
mongo_db_name: str = os.getenv("MONGODB_DB_NAME", "zero_knowledge_platform")
|
||||
jwt_secret: str = os.getenv("JWT_SECRET", "replace-with-a-long-random-secret")
|
||||
jwt_algorithm: str = os.getenv("JWT_ALGORITHM", "HS256")
|
||||
access_token_expire_minutes: int = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "60"))
|
||||
cors_origins: list[str] = field(
|
||||
default_factory=lambda: [
|
||||
origin.strip()
|
||||
for origin in os.getenv(
|
||||
"CORS_ORIGINS",
|
||||
"http://localhost:5173,http://127.0.0.1:5173",
|
||||
).split(",")
|
||||
if origin.strip()
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
settings = Settings()
|
||||
37
backend/app/core/security.py
Normal file
37
backend/app/core/security.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import re
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Any
|
||||
|
||||
from jose import jwt
|
||||
from passlib.context import CryptContext
|
||||
|
||||
from app.core.config import settings
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
|
||||
|
||||
def normalize_identifier(identifier_type: str, identifier: str) -> str:
|
||||
value = identifier.strip()
|
||||
if identifier_type == "email":
|
||||
return value.lower()
|
||||
if identifier_type == "username":
|
||||
return value
|
||||
if identifier_type == "mobile":
|
||||
return re.sub(r"[\s\-().]", "", value)
|
||||
return value
|
||||
|
||||
|
||||
def hash_auth_key(auth_key_material: str) -> str:
|
||||
return pwd_context.hash(auth_key_material)
|
||||
|
||||
|
||||
def verify_auth_key(auth_key_material: str, hashed_auth_key: str) -> bool:
|
||||
return pwd_context.verify(auth_key_material, hashed_auth_key)
|
||||
|
||||
|
||||
def create_access_token(subject: str, extra_claims: dict[str, Any] | None = None) -> str:
|
||||
expires_at = datetime.now(timezone.utc) + timedelta(minutes=settings.access_token_expire_minutes)
|
||||
payload: dict[str, Any] = {"sub": subject, "exp": expires_at, "iat": datetime.now(timezone.utc)}
|
||||
if extra_claims:
|
||||
payload.update(extra_claims)
|
||||
return jwt.encode(payload, settings.jwt_secret, algorithm=settings.jwt_algorithm)
|
||||
Loading…
Add table
Add a link
Reference in a new issue