sumi128's picture
initial commit
1c2ad4f
from datetime import datetime, timezone
from dateutil import parser
from fastapi import APIRouter, Request
from pydantic import BaseModel
from src.common.logger import logger
from src.common.utils import get_client_ip, response_error, response_success, rsa_sign
from src.db.supabase_client import (
get_first_activated_device,
get_license,
insert_activation,
supabase,
)
router = APIRouter()
class ActivationRequest(BaseModel):
email: str
license_key: str
device_id: str
@router.post("/verify")
def verify(req: ActivationRequest, request: Request):
logger.info(
f"Verifying license for email: {req.email}, device_id: {req.device_id}, license_key: {req.license_key}"
)
lic = get_license(req.license_key)
if not lic:
return response_error("LICENSE_NOT_FOUND", "License not found", 404)
if lic["user_id"] != req.email:
return response_error("EMAIL_NOT_MATCH", "Email mismatch", 403)
activated_device = get_first_activated_device(lic["id"])
if activated_device and activated_device["device_id"] != req.device_id:
return response_error("DEVICE_LIMIT", "Bound to another device", 403)
if lic["status"] != "active":
return response_error("LICENSE_INACTIVE", "Inactive license", 403)
if lic["expires_at"]:
exp = parser.isoparse(lic["expires_at"])
if exp < datetime.now(timezone.utc):
return response_error("LICENSE_EXPIRED", "License expired", 403)
tool_res = (
supabase.table("tools")
.select("id, name")
.eq("id", lic["tool_id"])
.limit(1)
.execute()
)
tool = tool_res.data[0] if tool_res.data else None
features_res = (
supabase.table("license_features")
.select("feature_id, tool_features ( id, name )")
.eq("license_id", lic["id"])
.execute()
)
purchased_features = [
row["tool_features"] for row in features_res.data if row.get("tool_features")
]
verified_at = (
activated_device.get("verified_at")
if activated_device and activated_device.get("verified_at")
else datetime.now(timezone.utc).isoformat()
)
license_obj = {
"product": tool["name"],
"product_id": tool["id"],
"features": purchased_features,
"license_key": req.license_key,
"device_id": req.device_id,
"user_id": lic["user_id"],
"period_type": lic["period_type"],
"verified_at": verified_at,
"expires_at": lic["expires_at"],
}
signature = rsa_sign(license_obj)
if not activated_device:
insert_activation(
lic["id"], req.license_key, req.model_dump(), get_client_ip(request)
)
supabase.table("licenses").update(
{"last_verified_at": datetime.now(timezone.utc).isoformat()}
).eq("id", lic["id"]).execute()
return response_success({"license": license_obj, "signature": signature})