add feature parity

This commit is contained in:
miloschwartz
2025-05-13 11:09:38 -04:00
parent a512148348
commit 5b0200154a
92 changed files with 353 additions and 759 deletions

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import {

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import { ColumnDef } from "@tanstack/react-table";

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
import { internal } from "@app/lib/api";
import { AxiosResponse } from "axios";
import { redirect } from "next/navigation";

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
import { redirect } from "next/navigation";
export default async function ApiKeysPage(props: {

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import PermissionsSelectBox from "@app/components/PermissionsSelectBox";

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import {

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import { AxiosResponse } from "axios";

View File

@@ -232,7 +232,6 @@ export default function GeneralPage() {
defaultChecked={form.getValues(
"autoProvision"
)}
disabled={!isUnlocked()}
onCheckedChange={(checked) => {
form.setValue(
"autoProvision",
@@ -240,14 +239,6 @@ export default function GeneralPage() {
);
}}
/>
{!isUnlocked() && (
<Badge
variant="outlinePrimary"
className="ml-2"
>
Professional
</Badge>
)}
</div>
<span className="text-sm text-muted-foreground">
When enabled, users will be

View File

@@ -43,8 +43,7 @@ export default async function SettingsLayout(props: SettingsLayoutProps) {
},
{
title: "Organization Policies",
href: `/admin/idp/${params.idpId}/policies`,
showProfessional: true
href: `/admin/idp/${params.idpId}/policies`
}
];

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import { ColumnDef } from "@tanstack/react-table";

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import { ColumnDef } from "@tanstack/react-table";

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import { useEffect, useState } from "react";
@@ -377,9 +372,7 @@ export default function PoliciesPage() {
<Input {...field} />
</FormControl>
<FormDescription>
JMESPath to extract role
information from the ID
token. The result of this
The result of this
expression must return the
role name as defined in the
organization as a string.
@@ -401,13 +394,10 @@ export default function PoliciesPage() {
<Input {...field} />
</FormControl>
<FormDescription>
JMESPath to extract
organization information
from the ID token. This
expression must return thr
org ID or true for the user
to be allowed to access the
organization.
This expression must return
thr org ID or true for the
user to be allowed to access
the organization.
</FormDescription>
<FormMessage />
</FormItem>
@@ -578,8 +568,6 @@ export default function PoliciesPage() {
<Input {...field} />
</FormControl>
<FormDescription>
JMESPath to extract role
information from the ID token.
The result of this expression
must return the role name as
defined in the organization as a
@@ -603,8 +591,6 @@ export default function PoliciesPage() {
<Input {...field} />
</FormControl>
<FormDescription>
JMESPath to extract organization
information from the ID token.
This expression must return the
org ID or true for the user to
be allowed to access the

View File

@@ -192,7 +192,6 @@ export default function Page() {
defaultChecked={form.getValues(
"autoProvision"
)}
disabled={!isUnlocked()}
onCheckedChange={(checked) => {
form.setValue(
"autoProvision",
@@ -200,14 +199,6 @@ export default function Page() {
);
}}
/>
{!isUnlocked() && (
<Badge
variant="outlinePrimary"
className="ml-2"
>
Professional
</Badge>
)}
</div>
<span className="text-sm text-muted-foreground">
When enabled, users will be
@@ -421,7 +412,7 @@ export default function Page() {
<Input {...field} />
</FormControl>
<FormDescription>
The JMESPath to the user
The path to the user
identifier in the ID
token
</FormDescription>
@@ -442,7 +433,7 @@ export default function Page() {
<Input {...field} />
</FormControl>
<FormDescription>
The JMESPath to the
The path to the
user's email in the ID
token
</FormDescription>
@@ -463,7 +454,7 @@ export default function Page() {
<Input {...field} />
</FormControl>
<FormDescription>
The JMESPath to the
The path to the
user's name in the ID
token
</FormDescription>

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import { ColumnDef } from "@tanstack/react-table";

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
import { useState } from "react";
import { Button } from "@app/components/ui/button";
import { MinusCircle, PlusCircle } from "lucide-react";
@@ -107,35 +102,6 @@ export function SitePriceCalculator({
</div>
<div className="border-t pt-4">
{mode === "license" && (
<div className="flex justify-between items-center">
<span className="text-sm font-medium">
License fee:
</span>
<span className="font-medium">
${licenseFlatRate.toFixed(2)}
</span>
</div>
)}
<div className="flex justify-between items-center mt-2">
<span className="text-sm font-medium">
Price per site:
</span>
<span className="font-medium">
${pricePerSite.toFixed(2)}
</span>
</div>
<div className="flex justify-between items-center mt-2">
<span className="text-sm font-medium">
Number of sites:
</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 and discounts,
please visit the{" "}
@@ -157,7 +123,7 @@ export function SitePriceCalculator({
<Button variant="outline">Cancel</Button>
</CredenzaClose>
<Button onClick={continueToPayment}>
Continue to Payment
See Purchase Portal
</Button>
</CredenzaFooter>
</CredenzaContent>

View File

@@ -1,8 +1,3 @@
// This file is licensed under the Fossorial Commercial License.
// Unauthorized use, copying, modification, or distribution is strictly prohibited.
//
// Copyright (c) 2025 Fossorial LLC. All rights reserved.
"use client";
import { useState, useEffect } from "react";
@@ -49,7 +44,7 @@ import {
} from "@app/components/Settings";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { Badge } from "@app/components/ui/badge";
import { Check, ShieldCheck, ShieldOff } from "lucide-react";
import { Check, Heart, InfoIcon, ShieldCheck, ShieldOff } from "lucide-react";
import CopyTextBox from "@app/components/CopyTextBox";
import { Progress } from "@app/components/ui/progress";
import { MinusCircle, PlusCircle } from "lucide-react";
@@ -57,6 +52,8 @@ import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import { SitePriceCalculator } from "./components/SitePriceCalculator";
import Link from "next/link";
import { Checkbox } from "@app/components/ui/checkbox";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { useSupporterStatusContext } from "@app/hooks/useSupporterStatusContext";
const formSchema = z.object({
licenseKey: z
@@ -95,6 +92,7 @@ export default function LicensePage() {
const [isActivatingLicense, setIsActivatingLicense] = useState(false);
const [isDeletingLicense, setIsDeletingLicense] = useState(false);
const [isRecheckingLicense, setIsRecheckingLicense] = useState(false);
const { supporterStatus } = useSupporterStatusContext();
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
@@ -370,6 +368,18 @@ export default function LicensePage() {
description="View and manage license keys in the system"
/>
<Alert variant="neutral" className="mb-6">
<InfoIcon className="h-4 w-4" />
<AlertTitle className="font-semibold">
About Licensing
</AlertTitle>
<AlertDescription>
This is for business and enterprise users who are using
Pangolin in a commercial environment. If you are using
Pangolin for personal use, you can ignore this section.
</AlertDescription>
</Alert>
<SettingsContainer>
<SettingsSectionGrid cols={2}>
<SettingsSection>
@@ -387,18 +397,25 @@ export default function LicensePage() {
<Check />
{licenseStatus?.tier ===
"PROFESSIONAL"
? "Professional License"
? "Commercial License"
: licenseStatus?.tier ===
"ENTERPRISE"
? "Enterprise License"
? "Commercial License"
: "Licensed"}
</div>
</div>
) : (
<div className="space-y-2">
<div className="text-2xl">
Not Licensed
</div>
{supporterStatus?.visible ? (
<div className="text-2xl">
Community Edition
</div>
) : (
<div className="text-2xl flex items-center gap-2 text-pink-500">
<Heart />
Community Edition
</div>
)}
</div>
)}
</div>