mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
feat(licenses): refactor license handling and introduce activation functionality
- Replaced validateLicense with saveLicense in the EnablePaidFeatures component for improved clarity. - Updated user API to include saveLicense and activateLicense methods for better license management. - Enhanced validateLicense function to fetch from a new endpoint and added activateLicense for server activation. - Removed unnecessary console logging in license validation for cleaner code.
This commit is contained in:
@@ -17,8 +17,7 @@ import { useState, useEffect } from "react";
|
|||||||
export const EnablePaidFeatures = () => {
|
export const EnablePaidFeatures = () => {
|
||||||
const { data, refetch } = api.user.get.useQuery();
|
const { data, refetch } = api.user.get.useQuery();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const { mutateAsync: validateLicense } =
|
const { mutateAsync: saveLicense } = api.user.saveLicense.useMutation();
|
||||||
api.user.validateLicense.useMutation();
|
|
||||||
const { mutateAsync: update } = api.user.update.useMutation();
|
const { mutateAsync: update } = api.user.update.useMutation();
|
||||||
const [licenseKey, setLicenseKey] = useState("");
|
const [licenseKey, setLicenseKey] = useState("");
|
||||||
|
|
||||||
@@ -34,14 +33,13 @@ export const EnablePaidFeatures = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
await validateLicense({
|
await saveLicense({
|
||||||
licenseKey,
|
licenseKey,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success("License validated successfully");
|
toast.success("License validated successfully");
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error(e);
|
|
||||||
toast.error("Error validating license", {
|
toast.error("Error validating license", {
|
||||||
description: e.message,
|
description: e.message,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,7 +29,10 @@ import {
|
|||||||
protectedProcedure,
|
protectedProcedure,
|
||||||
publicProcedure,
|
publicProcedure,
|
||||||
} from "../trpc";
|
} from "../trpc";
|
||||||
import { validateLicense } from "@/server/utils/validate-license";
|
import {
|
||||||
|
validateLicense,
|
||||||
|
activateLicense,
|
||||||
|
} from "@/server/utils/validate-license";
|
||||||
const apiCreateApiKey = z.object({
|
const apiCreateApiKey = z.object({
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
prefix: z.string().optional(),
|
prefix: z.string().optional(),
|
||||||
@@ -140,7 +143,7 @@ export const userRouter = createTRPCRouter({
|
|||||||
}
|
}
|
||||||
return await updateUser(ctx.user.id, input);
|
return await updateUser(ctx.user.id, input);
|
||||||
}),
|
}),
|
||||||
validateLicense: adminProcedure
|
saveLicense: adminProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
licenseKey: z.string(),
|
licenseKey: z.string(),
|
||||||
@@ -159,9 +162,12 @@ export const userRouter = createTRPCRouter({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await activateLicense(input.licenseKey, owner?.serverIp || "");
|
||||||
|
|
||||||
await updateUser(ctx.user.id, {
|
await updateUser(ctx.user.id, {
|
||||||
licenseKey: input.licenseKey,
|
licenseKey: input.licenseKey,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}),
|
}),
|
||||||
getUserByToken: publicProcedure
|
getUserByToken: publicProcedure
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const licensesUrl = process.env.LICENSES_URL || "http://localhost:4002";
|
const licensesUrl = process.env.LICENSES_URL || "http://localhost:4002";
|
||||||
|
|
||||||
export const validateLicense = async (licenseKey: string, serverIp: string) => {
|
export const validateLicense = async (licenseKey: string, serverIp: string) => {
|
||||||
const response = await fetch(`${licensesUrl}/api/validate`, {
|
const response = await fetch(`${licensesUrl}/api/license/validate`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -16,3 +16,16 @@ export const validateLicense = async (licenseKey: string, serverIp: string) => {
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const activateLicense = async (licenseKey: string, serverIp: string) => {
|
||||||
|
const response = await fetch(`${licensesUrl}/api/license/activate`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ licenseKey, serverIp }),
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ licenseRouter.post(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await validateLicense(licenseKey, serverIp);
|
const result = await validateLicense(licenseKey, serverIp);
|
||||||
console.log("Result", result);
|
|
||||||
return c.json(result);
|
return c.json(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("Error validating license:", { error });
|
logger.error("Error validating license:", { error });
|
||||||
|
|||||||
@@ -75,6 +75,16 @@ export const validateLicense = async (licenseKey: string, serverIp: string) => {
|
|||||||
const suscription = await stripe.subscriptions.retrieve(
|
const suscription = await stripe.subscriptions.retrieve(
|
||||||
license.stripeSubscriptionId,
|
license.stripeSubscriptionId,
|
||||||
);
|
);
|
||||||
|
const currentServerQuantity = license.serverIps?.length || 0;
|
||||||
|
const serversQuantity = suscription.items.data[0].quantity || 0;
|
||||||
|
|
||||||
|
if (currentServerQuantity >= serversQuantity) {
|
||||||
|
return {
|
||||||
|
isValid: false,
|
||||||
|
error:
|
||||||
|
"You have reached the maximum number of servers, please upgrade your license to add more servers",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (suscription.status !== "active") {
|
if (suscription.status !== "active") {
|
||||||
return {
|
return {
|
||||||
@@ -120,6 +130,8 @@ export const activateLicense = async (licenseKey: string, serverIp: string) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("License", license.serverIps?.includes(serverIp));
|
||||||
|
|
||||||
if (license.serverIps && !license.serverIps.includes(serverIp)) {
|
if (license.serverIps && !license.serverIps.includes(serverIp)) {
|
||||||
throw new Error("License is already activated on a different server");
|
throw new Error("License is already activated on a different server");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user