feat(licenses): enhance license validation process

- Updated the validateLicense function to accept server IP for improved validation.
- Modified user API to utilize the new validateLicense signature.
- Added useEffect in EnablePaidFeatures component to set license key based on user data.
- Improved error handling and user feedback during license validation.
This commit is contained in:
Mauricio Siu
2025-03-23 04:55:16 -06:00
parent fb0272a64d
commit b7874f053f
4 changed files with 38 additions and 8 deletions

View File

@@ -12,7 +12,7 @@ import { api } from "@/utils/api";
import { SetupMonitoring } from "./servers/setup-monitoring";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { useState } from "react";
import { useState, useEffect } from "react";
export const EnablePaidFeatures = () => {
const { data, refetch } = api.user.get.useQuery();
@@ -21,14 +21,25 @@ export const EnablePaidFeatures = () => {
const { mutateAsync: update } = api.user.update.useMutation();
const [licenseKey, setLicenseKey] = useState("");
useEffect(() => {
if (data?.user?.enablePaidFeatures) {
setLicenseKey(data.user.licenseKey || "");
}
}, [data?.user?.enablePaidFeatures]);
const handleValidateLicense = async () => {
if (!licenseKey) {
toast.error("Please enter a license key");
return;
}
await validateLicense({
licenseKey,
})
.then(() => {
toast.success("License validated successfully");
})
.catch(() => {
.catch((e) => {
console.error(e);
toast.error("Error validating license");
});
};

View File

@@ -140,14 +140,18 @@ export const userRouter = createTRPCRouter({
}
return await updateUser(ctx.user.id, input);
}),
validateLicense: protectedProcedure
validateLicense: adminProcedure
.input(
z.object({
licenseKey: z.string(),
}),
)
.mutation(async ({ input, ctx }) => {
const isValid = await validateLicense(input.licenseKey);
const owner = await findUserById(ctx.user.ownerId);
const isValid = await validateLicense(
input.licenseKey,
owner?.serverIp || "",
);
if (!isValid) {
throw new TRPCError({
code: "UNAUTHORIZED",
@@ -363,7 +367,7 @@ export const userRouter = createTRPCRouter({
const user = await findUserById(ctx.user.id);
if (!validateLicense(user?.licenseKey || "")) {
if (!validateLicense(user?.licenseKey || "", user?.serverIp || "")) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "Invalid license key",

View File

@@ -1,8 +1,21 @@
export const validateLicense = async (licenseKey: string): Promise<boolean> => {
const response = await fetch(`${process.env.SERVER_URL}/validate-license`, {
const licensesUrl = process.env.LICENSES_URL || "http://localhost:4002";
export const validateLicense = async (
licenseKey: string,
serverIp: string,
): Promise<boolean> => {
const response = await fetch(`${licensesUrl}/api/validate`, {
method: "POST",
body: JSON.stringify({ licenseKey }),
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ licenseKey, serverIp }),
});
const data = await response.json();
if (!response.ok && data.error?.issues) {
console.log("Validation errors:", data.error.issues);
}
return response.ok;
};

View File

@@ -56,6 +56,8 @@ router.get("/health", async (c) => {
router.post("/validate", zValidator("json", validateSchema), async (c) => {
const { licenseKey, serverIp } = c.req.valid("json");
console.log("Validating license", licenseKey, serverIp);
try {
const result = await validateLicense(licenseKey, serverIp);
return c.json(result);