mirror of
https://github.com/lukevella/rallly.git
synced 2025-07-24 03:37:23 +02:00
♻️ Refactor licensing feature (#1831)
This commit is contained in:
parent
b4cbb629b7
commit
c9b5527432
9 changed files with 51 additions and 18 deletions
|
@ -2,8 +2,8 @@ import type { Stripe } from "@rallly/billing";
|
|||
import { stripe } from "@rallly/billing";
|
||||
import { posthog } from "@rallly/posthog/server";
|
||||
import { env } from "@/env";
|
||||
import { licensingClient } from "@/features/licensing/client";
|
||||
import { licenseCheckoutMetadataSchema } from "@/features/licensing/schema";
|
||||
import { licenseManager } from "@/features/licensing/server";
|
||||
import { subscriptionCheckoutMetadataSchema } from "@/features/subscription/schema";
|
||||
import { getEmailClient } from "@/utils/emails";
|
||||
|
||||
|
@ -61,7 +61,7 @@ async function handleSelfHostedCheckoutSessionCompleted(
|
|||
);
|
||||
}
|
||||
|
||||
const license = await licensingClient.createLicense({
|
||||
const license = await licenseManager.createLicense({
|
||||
type: licenseType,
|
||||
licenseeEmail: email,
|
||||
licenseeName: customerDetails.name ?? undefined,
|
||||
|
|
24
apps/web/src/features/licensing/actions.ts
Normal file
24
apps/web/src/features/licensing/actions.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
"use server";
|
||||
|
||||
import { prisma } from "@rallly/database";
|
||||
import { adminActionClient } from "@/features/safe-action/server";
|
||||
|
||||
export const removeInstanceLicenseAction = adminActionClient
|
||||
.metadata({
|
||||
actionName: "remove_instance_license",
|
||||
})
|
||||
.action(async () => {
|
||||
try {
|
||||
await prisma.instanceLicense.deleteMany();
|
||||
} catch (_error) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Failed to delete license",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "License deleted successfully",
|
||||
};
|
||||
});
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { prisma } from "@rallly/database";
|
||||
import { rateLimit } from "@/features/rate-limit";
|
||||
import { licensingClient } from "../client";
|
||||
import { licenseManager } from "../server";
|
||||
|
||||
export async function validateLicenseKey(key: string) {
|
||||
const { success } = await rateLimit("validate_license_key", 10, "1 m");
|
||||
|
@ -14,7 +14,7 @@ export async function validateLicenseKey(key: string) {
|
|||
};
|
||||
}
|
||||
|
||||
const { data } = await licensingClient.validateLicenseKey({
|
||||
const { data } = await licenseManager.validateLicenseKey({
|
||||
key,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import { env } from "@/env";
|
||||
import { LicensingClient } from "./lib/licensing-client";
|
||||
|
||||
export const licensingClient = new LicensingClient({
|
||||
apiUrl: env.LICENSE_API_URL,
|
||||
authToken: env.LICENSE_API_AUTH_TOKEN,
|
||||
});
|
|
@ -14,15 +14,15 @@ import {
|
|||
} from "@rallly/ui/dialog";
|
||||
import { Icon } from "@rallly/ui/icon";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTransition } from "react";
|
||||
import { Trans } from "@/components/trans";
|
||||
import { removeInstanceLicense } from "../mutations";
|
||||
import { useSafeAction } from "@/features/safe-action/client";
|
||||
import { removeInstanceLicenseAction } from "../actions";
|
||||
|
||||
export function RemoveLicenseButton() {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const router = useRouter();
|
||||
const dialog = useDialog();
|
||||
const removeInstanceLicense = useSafeAction(removeInstanceLicenseAction);
|
||||
return (
|
||||
<Dialog {...dialog.dialogProps}>
|
||||
<DialogTrigger asChild>
|
||||
|
@ -56,8 +56,7 @@ export function RemoveLicenseButton() {
|
|||
variant="destructive"
|
||||
onClick={() =>
|
||||
startTransition(async () => {
|
||||
await removeInstanceLicense();
|
||||
router.refresh();
|
||||
await removeInstanceLicense.executeAsync();
|
||||
dialog.dismiss();
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export { LicensingClient } from "./lib/licensing-client";
|
|
@ -7,7 +7,7 @@ import {
|
|||
validateLicenseKeyResponseSchema,
|
||||
} from "../schema";
|
||||
|
||||
export class LicensingClient {
|
||||
export class LicenseManager {
|
||||
apiUrl: string;
|
||||
authToken?: string;
|
||||
|
7
apps/web/src/features/licensing/server.ts
Normal file
7
apps/web/src/features/licensing/server.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { env } from "@/env";
|
||||
import { LicenseManager } from "./lib/licensing-manager";
|
||||
|
||||
export const licenseManager = new LicenseManager({
|
||||
apiUrl: env.LICENSE_API_URL,
|
||||
authToken: env.LICENSE_API_AUTH_TOKEN,
|
||||
});
|
|
@ -88,3 +88,14 @@ export const authActionClient = actionClient
|
|||
});
|
||||
})
|
||||
.use(posthogMiddleware);
|
||||
|
||||
export const adminActionClient = authActionClient.use(async ({ ctx, next }) => {
|
||||
if (ctx.user.role !== "admin") {
|
||||
throw new ActionError({
|
||||
code: "FORBIDDEN",
|
||||
message: "You do not have permission to perform this action.",
|
||||
});
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue