hoàn thành chức năng giai đoạn 1

This commit is contained in:
2026-03-31 15:45:46 +07:00
parent 5d5ec7fb1a
commit 5baea90d61
5 changed files with 3429 additions and 12 deletions
+4 -6
View File
@@ -1,8 +1,8 @@
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import os import os
import bcrypt
from jose import JWTError, jwt from jose import JWTError, jwt
from passlib.context import CryptContext
# ── Config (override via environment variables) ─────────────────────────────── # ── Config (override via environment variables) ───────────────────────────────
SECRET_KEY: str = os.environ["JWT_SECRET_KEY"] # must be set — no default SECRET_KEY: str = os.environ["JWT_SECRET_KEY"] # must be set — no default
@@ -11,16 +11,14 @@ ACCESS_TOKEN_EXPIRE_MINUTES: int = int(
os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "60") os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "60")
) )
# ── Password hashing ────────────────────────────────────────────────────────── # ── Password hashing (use bcrypt directly — passlib has compat issues) ────────
_pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(plain: str) -> str: def hash_password(plain: str) -> str:
return _pwd_context.hash(plain) return bcrypt.hashpw(plain.encode(), bcrypt.gensalt()).decode()
def verify_password(plain: str, hashed: str) -> bool: def verify_password(plain: str, hashed: str) -> bool:
return _pwd_context.verify(plain, hashed) return bcrypt.checkpw(plain.encode(), hashed.encode())
# ── JWT ─────────────────────────────────────────────────────────────────────── # ── JWT ───────────────────────────────────────────────────────────────────────
+1 -1
View File
@@ -2,7 +2,7 @@ fastapi==0.115.6
uvicorn[standard]==0.30.6 uvicorn[standard]==0.30.6
sqlalchemy==2.0.36 sqlalchemy==2.0.36
psycopg2-binary==2.9.10 psycopg2-binary==2.9.10
passlib[bcrypt]==1.7.4 bcrypt==4.0.1
python-jose[cryptography]==3.3.0 python-jose[cryptography]==3.3.0
pydantic[email]==2.9.2 pydantic[email]==2.9.2
python-multipart==0.0.12 python-multipart==0.0.12
+5
View File
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
@@ -1,7 +1,6 @@
import type { NextConfig } from "next"; /** @type {import('next').NextConfig} */
const nextConfig = {
const nextConfig: NextConfig = { output: "standalone",
output: "standalone", // enables minimal Docker image via .next/standalone
async rewrites() { async rewrites() {
return [ return [
{ {
@@ -12,4 +11,4 @@ const nextConfig: NextConfig = {
}, },
}; };
export default nextConfig; module.exports = nextConfig;
+3415
View File
File diff suppressed because it is too large Load Diff