@cryptotaxi247 / CoPilot / commits / 72538b3f

Enhance license management: allow optional retrieval of license and create new license if none exists

taylorwalton committed Oct 18, 2025 at 11:26 UTC 72538b3f751984f386ef26be1865a988d5424020
1 file changed +49 -13
backend/app/middleware/license.py
+49 -13
@@ -388,17 +388,21 @@ async def add_license_to_db(session: AsyncSession, result, request: AddLicenseTo
388 return new_license
389
390
391 -async def get_license(session: AsyncSession) -> License:
391 +async def get_license(session: AsyncSession, raise_on_missing: bool = True) -> Optional[License]:
392 """
393 Get the license from the database
394
395 :param session: The AsyncSession object for the database
396 - :return: The License object
396 + :param raise_on_missing: If True, raise HTTPException when no license found. If False, return None.
397 + :return: The License object or None
398 """
399 result = await session.execute(select(License))
400 license = result.scalars().first()
401 if license is None:
401 - raise HTTPException(status_code=404, detail="No license found. A license must be created first.")
402 + if raise_on_missing:
403 + raise HTTPException(status_code=404, detail="No license found. A license must be created first.")
404 + else:
405 + return None
406 else:
407 return license
408
@@ -1045,21 +1049,53 @@ async def get_license_features(session: AsyncSession = Depends(get_db)) -> GetLi
1049
1050 @license_router.post(
1051 "/replace_license_in_db",
1048 - description="Replace a license",
1052 + description="Replace a license or create one if it doesn't exist",
1053 )
1054 async def replace_license_in_db(request: ReplaceLicenseRequest, session: AsyncSession = Depends(get_db)):
1051 - # ! Remove get_license becasue we don't need to fetch old license
1052 - #license = await get_license(session)
1055 + # Get license without raising error if it doesn't exist
1056 + license = await get_license(session, raise_on_missing=False)
1057
1054 - # Invalidate cache for old license
1055 - await invalidate_license_cache(session, license.license_key)
1058 + if license:
1059 + # Existing license - replace it
1060 + logger.info(f"Replacing existing license {license.license_key[:8]}... with {request.license_key[:8]}...")
1061
1057 - # Update license key
1058 - license.license_key = request.license_key
1059 - await session.commit()
1062 + # Invalidate cache for old license
1063 + await invalidate_license_cache(session, license.license_key)
1064 +
1065 + # Update license key
1066 + license.license_key = request.license_key
1067 + await session.commit()
1068 +
1069 + logger.info("License replaced successfully")
1070 + return {"success": True, "message": "License replaced successfully"}
1071 + else:
1072 + # No existing license - create a new one
1073 + logger.info("No existing license found, creating new license")
1074 +
1075 + # Verify the new license key first to get customer details
1076 + results = await send_post_request("verify-license", data={"license_key": request.license_key})
1077 + normalized_results = normalize_api_response(results)
1078 +
1079 + if not normalized_results.get("success", True):
1080 + raise HTTPException(status_code=400, detail="Invalid license key")
1081 +
1082 + # Extract customer info from license verification
1083 + license_data = normalized_results["data"]["license"]
1084 + customer_data = license_data["customer"]
1085 +
1086 + # Create new license in database
1087 + await add_license_to_db(
1088 + session,
1089 + request.license_key,
1090 + AddLicenseToDB(
1091 + customer_email=customer_data["email"],
1092 + customer_name=customer_data["name"],
1093 + company_name=customer_data["companyName"],
1094 + ),
1095 + )
1096
1061 - logger.info("License replaced successfully")
1062 - return {"success": True, "message": "License replaced successfully"}
1097 + logger.info("License created successfully")
1098 + return {"success": True, "message": "License created successfully"}
1099
1100
1101 @license_router.post(