feat: service token introduction

This commit is contained in:
2026-08-18 19:56:14 +07:00
parent 3d79ffb384
commit 3b7606107b
12 changed files with 170 additions and 14 deletions

View File

@@ -1,7 +1,7 @@
import hashlib
import logging
import secrets
from typing import Any
from typing import Any, Literal
import jwt
from argon2 import PasswordHasher
@@ -10,7 +10,7 @@ from zxcvbn import zxcvbn
from config import cfg
from schemas.dto import KeyPair
from schemas.jwt import JWTPayload
from schemas.jwt import UserJWTPayload
from schemas.providers import ProvidersType
ctx = PasswordHasher()
@@ -36,15 +36,25 @@ def generate_jwt(payload: dict[str, Any]) -> str:
return jwt.encode(payload, cfg.private_key, "EdDSA")
def decode_jwt(token: str) -> dict[str, Any] | None:
def get_kid_from_token(token: str) -> str | None:
return jwt.get_unverified_header(token).get("kid")
def decode_jwt(
token: str, public_key: str, algo: Literal["EdDSA"] = "EdDSA"
) -> dict[str, Any] | None:
try:
return jwt.decode(token, cfg.public_key, "EdDSA")
return jwt.decode(token, public_key, algo)
except jwt.ExpiredSignatureError:
return
def decode_user_jwt(token: str) -> dict[str, Any] | None:
return decode_jwt(token, cfg.public_key, algo="EdDSA")
def generate_pair(user_id: int, iss: ProvidersType) -> KeyPair:
payload = JWTPayload(sub=str(user_id), iss=iss)
payload = UserJWTPayload(sub=str(user_id), iss=iss)
access_token = generate_jwt(payload.model_dump())
refresh_token = secrets.token_urlsafe(32)