add api key code and oidc auto provision code

This commit is contained in:
miloschwartz
2025-04-28 21:14:09 -04:00
parent 4819f410e6
commit 599d0a52bf
84 changed files with 7021 additions and 151 deletions

View File

@@ -16,7 +16,7 @@ import CopyToClipboard from "@app/components/CopyToClipboard";
type LicenseKeysDataTableProps = {
licenseKeys: LicenseKeyCache[];
onDelete: (key: string) => void;
onDelete: (key: LicenseKeyCache) => void;
onCreate: () => void;
};
@@ -124,7 +124,7 @@ export function LicenseKeysDataTable({
<div className="flex items-center justify-end space-x-2">
<Button
variant="outlinePrimary"
onClick={() => onDelete(row.original.licenseKey)}
onClick={() => onDelete(row.original)}
>
Delete
</Button>

View File

@@ -40,19 +40,25 @@ export function SitePriceCalculator({
setSiteCount((prev) => (prev > 1 ? prev - 1 : 1));
};
const totalCost = mode === "license"
? licenseFlatRate + (siteCount * pricePerSite)
: siteCount * pricePerSite;
const totalCost =
mode === "license"
? licenseFlatRate + siteCount * pricePerSite
: siteCount * pricePerSite;
return (
<Credenza open={isOpen} onOpenChange={onOpenChange}>
<CredenzaContent>
<CredenzaHeader>
<CredenzaTitle>
{mode === "license" ? "Purchase License" : "Purchase Additional Sites"}
{mode === "license"
? "Purchase License"
: "Purchase Additional Sites"}
</CredenzaTitle>
<CredenzaDescription>
Choose how many sites you want to {mode === "license" ? "purchase a license for" : "add to your existing license"}.
Choose how many sites you want to{" "}
{mode === "license"
? "purchase a license for. You can always add more sites later."
: "add to your existing license."}
</CredenzaDescription>
</CredenzaHeader>
<CredenzaBody>
@@ -108,14 +114,26 @@ export function SitePriceCalculator({
<span className="text-sm font-medium">
Number of sites:
</span>
<span className="font-medium">
{siteCount}
</span>
<span className="font-medium">{siteCount}</span>
</div>
<div className="flex justify-between items-center mt-4 text-lg font-bold">
<span>Total:</span>
<span>${totalCost.toFixed(2)} / mo</span>
</div>
<p className="text-muted-foreground text-sm mt-2 text-center">
For the most up-to-date pricing, please visit
our{" "}
<a
href="https://docs.fossorial.io/pricing"
target="_blank"
rel="noopener noreferrer"
className="underline"
>
pricing page
</a>
.
</p>
</div>
</div>
</CredenzaBody>

View File

@@ -55,6 +55,7 @@ import { Progress } from "@app/components/ui/progress";
import { MinusCircle, PlusCircle } from "lucide-react";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { SitePriceCalculator } from "./components/SitePriceCalculator";
import Link from "next/link";
const formSchema = z.object({
licenseKey: z
@@ -75,9 +76,8 @@ export default function LicensePage() {
const [rows, setRows] = useState<LicenseKeyCache[]>([]);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [selectedLicenseKey, setSelectedLicenseKey] = useState<string | null>(
null
);
const [selectedLicenseKey, setSelectedLicenseKey] =
useState<LicenseKeyCache | null>(null);
const router = useRouter();
const { licenseStatus, updateLicenseStatus } = useLicenseStatusContext();
const [hostLicense, setHostLicense] = useState<string | null>(null);
@@ -136,7 +136,8 @@ export default function LicensePage() {
async function deleteLicenseKey(key: string) {
try {
setIsDeletingLicense(true);
const res = await api.delete(`/license/${key}`);
const encodedKey = encodeURIComponent(key);
const res = await api.delete(`/license/${encodedKey}`);
if (res.data.data) {
updateLicenseStatus(res.data.data);
}
@@ -294,7 +295,11 @@ export default function LicensePage() {
<div className="space-y-4">
<p>
Are you sure you want to delete the license key{" "}
<b>{obfuscateLicenseKey(selectedLicenseKey)}</b>
<b>
{obfuscateLicenseKey(
selectedLicenseKey.licenseKey
)}
</b>
?
</p>
<p>
@@ -310,8 +315,10 @@ export default function LicensePage() {
</div>
}
buttonText="Confirm Delete License Key"
onConfirm={async () => deleteLicenseKey(selectedLicenseKey)}
string={selectedLicenseKey}
onConfirm={async () =>
deleteLicenseKey(selectedLicenseKey.licenseKeyEncrypted)
}
string={selectedLicenseKey.licenseKey}
title="Delete License Key"
/>
)}
@@ -428,12 +435,6 @@ export default function LicensePage() {
<SettingsSectionFooter>
{!licenseStatus?.isHostLicensed ? (
<>
<Button
variant="outline"
onClick={() => {}}
>
View License Portal
</Button>
<Button
onClick={() => {
setPurchaseMode("license");
@@ -444,15 +445,17 @@ export default function LicensePage() {
</Button>
</>
) : (
<Button
variant="outline"
onClick={() => {
setPurchaseMode("additional-sites");
setIsPurchaseModalOpen(true);
}}
>
Purchase Additional Sites
</Button>
<>
<Button
variant="outline"
onClick={() => {
setPurchaseMode("additional-sites");
setIsPurchaseModalOpen(true);
}}
>
Purchase Additional Sites
</Button>
</>
)}
</SettingsSectionFooter>
</SettingsSection>