mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-28 15:56:39 +00:00
add enterprise license system
This commit is contained in:
@@ -9,7 +9,7 @@ import { AxiosResponse } from "axios";
|
||||
import { redirect } from "next/navigation";
|
||||
import { cache } from "react";
|
||||
import SetLastOrgCookie from "@app/components/SetLastOrgCookie";
|
||||
import PrivateSubscriptionStatusProvider from "@app/providers/SubscriptionStatusProvider";
|
||||
import SubscriptionStatusProvider from "@app/providers/SubscriptionStatusProvider";
|
||||
import { GetOrgSubscriptionResponse } from "#private/routers/billing/getOrgSubscription";
|
||||
import { pullEnv } from "@app/lib/pullEnv";
|
||||
import { build } from "@server/build";
|
||||
@@ -56,7 +56,7 @@ export default async function OrgLayout(props: {
|
||||
}
|
||||
|
||||
let subscriptionStatus = null;
|
||||
if (build != "oss") {
|
||||
if (build === "saas") {
|
||||
try {
|
||||
const getSubscription = cache(() =>
|
||||
internal.get<AxiosResponse<GetOrgSubscriptionResponse>>(
|
||||
@@ -73,13 +73,13 @@ export default async function OrgLayout(props: {
|
||||
}
|
||||
|
||||
return (
|
||||
<PrivateSubscriptionStatusProvider
|
||||
<SubscriptionStatusProvider
|
||||
subscriptionStatus={subscriptionStatus}
|
||||
env={env.app.environment}
|
||||
sandbox_mode={env.app.sandbox_mode}
|
||||
>
|
||||
{props.children}
|
||||
<SetLastOrgCookie orgId={orgId} />
|
||||
</PrivateSubscriptionStatusProvider>
|
||||
</SubscriptionStatusProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -60,13 +60,6 @@ export default async function BillingSettingsPage({
|
||||
|
||||
const t = await getTranslations();
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
title: t('billing'),
|
||||
href: `/{orgId}/settings/billing`,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<OrgProvider org={org}>
|
||||
|
||||
@@ -45,7 +45,10 @@ export default async function OrgIdpPage(props: OrgIdpPageProps) {
|
||||
const subRes = await getSubscription();
|
||||
subscriptionStatus = subRes.data.data;
|
||||
} catch {}
|
||||
const subscribed = subscriptionStatus?.tier === TierId.STANDARD;
|
||||
const subscribed =
|
||||
build === "enterprise"
|
||||
? true
|
||||
: subscriptionStatus?.tier === TierId.STANDARD;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
42
src/app/[orgId]/settings/(private)/license/layout.tsx
Normal file
42
src/app/[orgId]/settings/(private)/license/layout.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||
import { verifySession } from "@app/lib/auth/verifySession";
|
||||
import { redirect } from "next/navigation";
|
||||
import { cache } from "react";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { build } from "@server/build";
|
||||
|
||||
type LicensesSettingsProps = {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ orgId: string }>;
|
||||
};
|
||||
|
||||
export default async function LicensesSetingsLayoutProps({
|
||||
children,
|
||||
params
|
||||
}: LicensesSettingsProps) {
|
||||
const { orgId } = await params;
|
||||
|
||||
if (build !== "saas") {
|
||||
redirect(`/${orgId}/settings`);
|
||||
}
|
||||
|
||||
const getUser = cache(verifySession);
|
||||
const user = await getUser();
|
||||
|
||||
if (!user) {
|
||||
redirect(`/`);
|
||||
}
|
||||
|
||||
const t = await getTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingsSectionTitle
|
||||
title={t("saasLicenseKeysSettingsTitle")}
|
||||
description={t("saasLicenseKeysSettingsDescription")}
|
||||
/>
|
||||
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
}
|
||||
25
src/app/[orgId]/settings/(private)/license/page.tsx
Normal file
25
src/app/[orgId]/settings/(private)/license/page.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import GenerateLicenseKeysTable from "@app/components/GenerateLicenseKeysTable";
|
||||
import { internal } from "@app/lib/api";
|
||||
import { authCookieHeader } from "@app/lib/api/cookies";
|
||||
import { ListGeneratedLicenseKeysResponse } from "@server/private/routers/generatedLicense";
|
||||
import { AxiosResponse } from "axios";
|
||||
|
||||
type Props = {
|
||||
params: Promise<{ orgId: string }>;
|
||||
};
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function Page({ params }: Props) {
|
||||
const { orgId } = await params;
|
||||
|
||||
let licenseKeys: ListGeneratedLicenseKeysResponse = [];
|
||||
try {
|
||||
const data = await internal.get<
|
||||
AxiosResponse<ListGeneratedLicenseKeysResponse>
|
||||
>(`/org/${orgId}/license`, await authCookieHeader());
|
||||
licenseKeys = data.data.data;
|
||||
} catch {}
|
||||
|
||||
return <GenerateLicenseKeysTable licenseKeys={licenseKeys} orgId={orgId} />;
|
||||
}
|
||||
@@ -77,9 +77,10 @@ export default function Page() {
|
||||
const t = useTranslations();
|
||||
|
||||
const subscription = useSubscriptionStatusContext();
|
||||
const subscribed = subscription?.getTier() === TierId.STANDARD;
|
||||
|
||||
const [selectedOption, setSelectedOption] = useState<string | null>("internal");
|
||||
const [selectedOption, setSelectedOption] = useState<string | null>(
|
||||
"internal"
|
||||
);
|
||||
const [inviteLink, setInviteLink] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [expiresInDays, setExpiresInDays] = useState(1);
|
||||
@@ -204,7 +205,13 @@ export default function Page() {
|
||||
googleAzureForm.reset();
|
||||
genericOidcForm.reset();
|
||||
}
|
||||
}, [selectedOption, env.email.emailEnabled, internalForm, googleAzureForm, genericOidcForm]);
|
||||
}, [
|
||||
selectedOption,
|
||||
env.email.emailEnabled,
|
||||
internalForm,
|
||||
googleAzureForm,
|
||||
genericOidcForm
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedOption) {
|
||||
@@ -232,7 +239,7 @@ export default function Page() {
|
||||
}
|
||||
|
||||
async function fetchIdps() {
|
||||
if (build === "saas" && !subscribed) {
|
||||
if (build === "saas" && !subscription?.subscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -345,7 +352,9 @@ export default function Page() {
|
||||
async function onSubmitGoogleAzure(
|
||||
values: z.infer<typeof googleAzureFormSchema>
|
||||
) {
|
||||
const selectedUserOption = userOptions.find(opt => opt.id === selectedOption);
|
||||
const selectedUserOption = userOptions.find(
|
||||
(opt) => opt.id === selectedOption
|
||||
);
|
||||
if (!selectedUserOption?.idpId) return;
|
||||
|
||||
setLoading(true);
|
||||
@@ -385,7 +394,9 @@ export default function Page() {
|
||||
async function onSubmitGenericOidc(
|
||||
values: z.infer<typeof genericOidcFormSchema>
|
||||
) {
|
||||
const selectedUserOption = userOptions.find(opt => opt.id === selectedOption);
|
||||
const selectedUserOption = userOptions.find(
|
||||
(opt) => opt.id === selectedOption
|
||||
);
|
||||
if (!selectedUserOption?.idpId) return;
|
||||
|
||||
setLoading(true);
|
||||
@@ -675,214 +686,284 @@ export default function Page() {
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedOption && selectedOption !== "internal" && dataLoaded && (
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>
|
||||
{t("userSettings")}
|
||||
</SettingsSectionTitle>
|
||||
<SettingsSectionDescription>
|
||||
{t("userSettingsDescription")}
|
||||
</SettingsSectionDescription>
|
||||
</SettingsSectionHeader>
|
||||
<SettingsSectionBody>
|
||||
<SettingsSectionForm>
|
||||
{/* Google/Azure Form */}
|
||||
{(() => {
|
||||
const selectedUserOption = userOptions.find(opt => opt.id === selectedOption);
|
||||
return selectedUserOption?.variant === "google" || selectedUserOption?.variant === "azure";
|
||||
})() && (
|
||||
<Form {...googleAzureForm}>
|
||||
<form
|
||||
onSubmit={googleAzureForm.handleSubmit(
|
||||
onSubmitGoogleAzure
|
||||
{selectedOption &&
|
||||
selectedOption !== "internal" &&
|
||||
dataLoaded && (
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>
|
||||
{t("userSettings")}
|
||||
</SettingsSectionTitle>
|
||||
<SettingsSectionDescription>
|
||||
{t("userSettingsDescription")}
|
||||
</SettingsSectionDescription>
|
||||
</SettingsSectionHeader>
|
||||
<SettingsSectionBody>
|
||||
<SettingsSectionForm>
|
||||
{/* Google/Azure Form */}
|
||||
{(() => {
|
||||
const selectedUserOption =
|
||||
userOptions.find(
|
||||
(opt) =>
|
||||
opt.id ===
|
||||
selectedOption
|
||||
);
|
||||
return (
|
||||
selectedUserOption?.variant ===
|
||||
"google" ||
|
||||
selectedUserOption?.variant ===
|
||||
"azure"
|
||||
);
|
||||
})() && (
|
||||
<Form {...googleAzureForm}>
|
||||
<form
|
||||
onSubmit={googleAzureForm.handleSubmit(
|
||||
onSubmitGoogleAzure
|
||||
)}
|
||||
className="space-y-4"
|
||||
id="create-user-form"
|
||||
>
|
||||
<FormField
|
||||
control={
|
||||
googleAzureForm.control
|
||||
}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("email")}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
className="space-y-4"
|
||||
id="create-user-form"
|
||||
>
|
||||
<FormField
|
||||
control={googleAzureForm.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("email")}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={googleAzureForm.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("nameOptional")}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={
|
||||
googleAzureForm.control
|
||||
}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t(
|
||||
"nameOptional"
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={googleAzureForm.control}
|
||||
name="roleId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("role")}
|
||||
</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue
|
||||
placeholder={t("accessRoleSelect")}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{roles.map((role) => (
|
||||
<FormField
|
||||
control={
|
||||
googleAzureForm.control
|
||||
}
|
||||
name="roleId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("role")}
|
||||
</FormLabel>
|
||||
<Select
|
||||
onValueChange={
|
||||
field.onChange
|
||||
}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue
|
||||
placeholder={t(
|
||||
"accessRoleSelect"
|
||||
)}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{roles.map(
|
||||
(
|
||||
role
|
||||
) => (
|
||||
<SelectItem
|
||||
key={role.roleId}
|
||||
key={
|
||||
role.roleId
|
||||
}
|
||||
value={role.roleId.toString()}
|
||||
>
|
||||
{role.name}
|
||||
{
|
||||
role.name
|
||||
}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
)}
|
||||
|
||||
{/* Generic OIDC Form */}
|
||||
{(() => {
|
||||
const selectedUserOption = userOptions.find(opt => opt.id === selectedOption);
|
||||
return selectedUserOption?.variant !== "google" && selectedUserOption?.variant !== "azure";
|
||||
})() && (
|
||||
<Form {...genericOidcForm}>
|
||||
<form
|
||||
onSubmit={genericOidcForm.handleSubmit(
|
||||
onSubmitGenericOidc
|
||||
)
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
className="space-y-4"
|
||||
id="create-user-form"
|
||||
>
|
||||
<FormField
|
||||
control={genericOidcForm.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("username")}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
{t("usernameUniq")}
|
||||
</p>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={genericOidcForm.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("emailOptional")}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{/* Generic OIDC Form */}
|
||||
{(() => {
|
||||
const selectedUserOption =
|
||||
userOptions.find(
|
||||
(opt) =>
|
||||
opt.id ===
|
||||
selectedOption
|
||||
);
|
||||
return (
|
||||
selectedUserOption?.variant !==
|
||||
"google" &&
|
||||
selectedUserOption?.variant !==
|
||||
"azure"
|
||||
);
|
||||
})() && (
|
||||
<Form {...genericOidcForm}>
|
||||
<form
|
||||
onSubmit={genericOidcForm.handleSubmit(
|
||||
onSubmitGenericOidc
|
||||
)}
|
||||
className="space-y-4"
|
||||
id="create-user-form"
|
||||
>
|
||||
<FormField
|
||||
control={
|
||||
genericOidcForm.control
|
||||
}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t(
|
||||
"username"
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
{t(
|
||||
"usernameUniq"
|
||||
)}
|
||||
</p>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={genericOidcForm.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("nameOptional")}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={
|
||||
genericOidcForm.control
|
||||
}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t(
|
||||
"emailOptional"
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={genericOidcForm.control}
|
||||
name="roleId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("role")}
|
||||
</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue
|
||||
placeholder={t("accessRoleSelect")}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{roles.map((role) => (
|
||||
<FormField
|
||||
control={
|
||||
genericOidcForm.control
|
||||
}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t(
|
||||
"nameOptional"
|
||||
)}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={
|
||||
genericOidcForm.control
|
||||
}
|
||||
name="roleId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("role")}
|
||||
</FormLabel>
|
||||
<Select
|
||||
onValueChange={
|
||||
field.onChange
|
||||
}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue
|
||||
placeholder={t(
|
||||
"accessRoleSelect"
|
||||
)}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
{roles.map(
|
||||
(
|
||||
role
|
||||
) => (
|
||||
<SelectItem
|
||||
key={role.roleId}
|
||||
key={
|
||||
role.roleId
|
||||
}
|
||||
value={role.roleId.toString()}
|
||||
>
|
||||
{role.name}
|
||||
{
|
||||
role.name
|
||||
}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
)}
|
||||
</SettingsSectionForm>
|
||||
</SettingsSectionBody>
|
||||
</SettingsSection>
|
||||
)}
|
||||
)
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
)}
|
||||
</SettingsSectionForm>
|
||||
</SettingsSectionBody>
|
||||
</SettingsSection>
|
||||
)}
|
||||
</SettingsContainer>
|
||||
|
||||
<div className="flex justify-end space-x-2 mt-8">
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ClientRow } from "../../../../components/ClientsTable";
|
||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||
import { ListClientsResponse } from "@server/routers/client";
|
||||
import ClientsTable from "../../../../components/ClientsTable";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
|
||||
type ClientsPageProps = {
|
||||
params: Promise<{ orgId: string }>;
|
||||
@@ -13,6 +14,8 @@ type ClientsPageProps = {
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function ClientsPage(props: ClientsPageProps) {
|
||||
const t = await getTranslations();
|
||||
|
||||
const params = await props.params;
|
||||
let clients: ListClientsResponse["clients"] = [];
|
||||
try {
|
||||
@@ -48,8 +51,8 @@ export default async function ClientsPage(props: ClientsPageProps) {
|
||||
return (
|
||||
<>
|
||||
<SettingsSectionTitle
|
||||
title="Manage Clients (beta)"
|
||||
description="Clients are devices that can connect to your sites"
|
||||
title={t("manageClients")}
|
||||
description={t("manageClientsDescription")}
|
||||
/>
|
||||
|
||||
<ClientsTable clients={clientRows} orgId={params.orgId} />
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"use client";
|
||||
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
|
||||
import AuthPageSettings, { AuthPageSettingsRef } from "@app/components/private/AuthPageSettings";
|
||||
import AuthPageSettings, {
|
||||
AuthPageSettingsRef
|
||||
} from "@app/components/private/AuthPageSettings";
|
||||
|
||||
import { Button } from "@app/components/ui/button";
|
||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
@@ -134,7 +136,10 @@ export default function GeneralPage() {
|
||||
});
|
||||
|
||||
// Also save auth page settings if they have unsaved changes
|
||||
if (build === "saas" && authPageSettingsRef.current?.hasUnsavedChanges()) {
|
||||
if (
|
||||
build === "saas" &&
|
||||
authPageSettingsRef.current?.hasUnsavedChanges()
|
||||
) {
|
||||
await authPageSettingsRef.current.saveAuthSettings();
|
||||
}
|
||||
|
||||
@@ -239,7 +244,9 @@ export default function GeneralPage() {
|
||||
</SettingsSectionBody>
|
||||
</SettingsSection>
|
||||
|
||||
{build === "saas" && <AuthPageSettings ref={authPageSettingsRef} />}
|
||||
{(build === "saas") && (
|
||||
<AuthPageSettings ref={authPageSettingsRef} />
|
||||
)}
|
||||
|
||||
{/* Save Button */}
|
||||
<div className="flex justify-end">
|
||||
@@ -276,7 +283,6 @@ export default function GeneralPage() {
|
||||
</SettingsSectionFooter>
|
||||
</SettingsSection>
|
||||
)}
|
||||
|
||||
</SettingsContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,6 @@ export default function ResourceAuthenticationPage() {
|
||||
const t = useTranslations();
|
||||
|
||||
const subscription = useSubscriptionStatusContext();
|
||||
const subscribed = subscription?.getTier() === TierId.STANDARD;
|
||||
|
||||
const [pageLoading, setPageLoading] = useState(true);
|
||||
|
||||
@@ -141,8 +140,10 @@ export default function ResourceAuthenticationPage() {
|
||||
useState(false);
|
||||
const [loadingRemoveResourcePincode, setLoadingRemoveResourcePincode] =
|
||||
useState(false);
|
||||
const [loadingRemoveResourceHeaderAuth, setLoadingRemoveResourceHeaderAuth] =
|
||||
useState(false);
|
||||
const [
|
||||
loadingRemoveResourceHeaderAuth,
|
||||
setLoadingRemoveResourceHeaderAuth
|
||||
] = useState(false);
|
||||
|
||||
const [isSetPasswordOpen, setIsSetPasswordOpen] = useState(false);
|
||||
const [isSetPincodeOpen, setIsSetPincodeOpen] = useState(false);
|
||||
@@ -234,7 +235,7 @@ export default function ResourceAuthenticationPage() {
|
||||
);
|
||||
|
||||
if (build === "saas") {
|
||||
if (subscribed) {
|
||||
if (subscription?.subscribed) {
|
||||
setAllIdps(
|
||||
idpsResponse.data.data.idps.map((idp) => ({
|
||||
id: idp.idpId,
|
||||
|
||||
Reference in New Issue
Block a user