Merge branch 'dev' into distribution

This commit is contained in:
miloschwartz
2025-10-13 11:06:14 -07:00
85 changed files with 906 additions and 1639 deletions

View File

@@ -1,8 +1,6 @@
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import ProfileIcon from "@app/components/ProfileIcon";
import { verifySession } from "@app/lib/auth/verifySession";
import UserProvider from "@app/providers/UserProvider";
import { GetOrgResponse } from "@server/routers/org";
import { GetOrgUserResponse } from "@server/routers/user";
import { AxiosResponse } from "axios";
@@ -10,7 +8,7 @@ import { redirect } from "next/navigation";
import { cache } from "react";
import SetLastOrgCookie from "@app/components/SetLastOrgCookie";
import SubscriptionStatusProvider from "@app/providers/SubscriptionStatusProvider";
import { GetOrgSubscriptionResponse } from "#private/routers/billing/getOrgSubscription";
import { GetOrgSubscriptionResponse } from "@server/routers/billing/types";
import { pullEnv } from "@app/lib/pullEnv";
import { build } from "@server/build";

View File

@@ -37,7 +37,7 @@ import { InfoPopup } from "@/components/ui/info-popup";
import {
GetOrgSubscriptionResponse,
GetOrgUsageResponse
} from "#private/routers/billing";
} from "@server/routers/billing/types";
import { useTranslations } from "use-intl";
import Link from "next/link";

View File

@@ -9,7 +9,7 @@ import { cache } from "react";
import {
GetOrgSubscriptionResponse,
GetOrgTierResponse
} from "#private/routers/billing";
} from "@server/routers/billing/types";
import { TierId } from "@server/lib/billing/tiers";
import { build } from "@server/build";

View File

@@ -1,5 +1,5 @@
import { internal } from "@app/lib/api";
import { GetRemoteExitNodeResponse } from "#private/routers/remoteExitNode";
import { GetRemoteExitNodeResponse } from "@server/routers/remoteExitNode/types";
import { AxiosResponse } from "axios";
import { redirect } from "next/navigation";
import { authCookieHeader } from "@app/lib/api/cookies";

View File

@@ -30,7 +30,7 @@ import { useEnvContext } from "@app/hooks/useEnvContext";
import {
QuickStartRemoteExitNodeResponse,
PickRemoteExitNodeDefaultsResponse
} from "#private/routers/remoteExitNode";
} from "@server/routers/remoteExitNode/types";
import { toast } from "@app/hooks/useToast";
import { AxiosResponse } from "axios";
import { useParams, useRouter, useSearchParams } from "next/navigation";

View File

@@ -1,6 +1,6 @@
import { internal } from "@app/lib/api";
import { authCookieHeader } from "@app/lib/api/cookies";
import { ListRemoteExitNodesResponse } from "#private/routers/remoteExitNode";
import { ListRemoteExitNodesResponse } from "@server/routers/remoteExitNode/types";
import { AxiosResponse } from "axios";
import ExitNodesTable, { RemoteExitNodeRow } from "./ExitNodesTable";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";

View File

@@ -117,8 +117,8 @@ export default function ResourceRules(props: {
const [openAddRuleCountrySelect, setOpenAddRuleCountrySelect] = useState(false);
const router = useRouter();
const t = useTranslations();
const env = useEnvContext();
const isMaxmindAvailable = env.env.server.maxmind_db_path && env.env.server.maxmind_db_path.length > 0;
const { env } = useEnvContext();
const isMaxmindAvailable = env.server.maxmind_db_path && env.server.maxmind_db_path.length > 0;
const RuleAction = {
ACCEPT: t('alwaysAllow'),

View File

@@ -53,7 +53,7 @@ import {
CreateSiteResponse,
PickSiteDefaultsResponse
} from "@server/routers/site";
import { ListRemoteExitNodesResponse } from "#private/routers/remoteExitNode";
import { ListRemoteExitNodesResponse } from "@server/routers/remoteExitNode/types";
import { toast } from "@app/hooks/useToast";
import { AxiosResponse } from "axios";
import { useParams, useRouter } from "next/navigation";

View File

@@ -6,13 +6,12 @@ import { verifySession } from "@app/lib/auth/verifySession";
import { redirect } from "next/navigation";
import { pullEnv } from "@app/lib/pullEnv";
import { LoginFormIDP } from "@app/components/LoginForm";
import { ListOrgIdpsResponse } from "#private/routers/orgIdp";
import { ListOrgIdpsResponse } from "@server/routers/orgIdp/types";
import { build } from "@server/build";
import { headers } from "next/headers";
import {
GetLoginPageResponse,
LoadLoginPageResponse
} from "#private/routers/loginPage";
} from "@server/routers/loginPage/types";
import IdpLoginButtons from "@app/components/private/IdpLoginButtons";
import {
Card,
@@ -24,9 +23,9 @@ import {
import { Button } from "@app/components/ui/button";
import Link from "next/link";
import { getTranslations } from "next-intl/server";
import { GetSessionTransferTokenRenponse } from "#private/routers/auth/getSessionTransferToken";
import { GetSessionTransferTokenRenponse } from "@server/routers/auth/types";
import ValidateSessionTransferToken from "@app/components/private/ValidateSessionTransferToken";
import { GetOrgTierResponse } from "#private/routers/billing";
import { GetOrgTierResponse } from "@server/routers/billing/types";
import { TierId } from "@server/lib/billing/tiers";
export const dynamic = "force-dynamic";

View File

@@ -6,7 +6,7 @@ import { AxiosResponse } from "axios";
import { GetIdpResponse } from "@server/routers/idp";
import { getTranslations } from "next-intl/server";
import { pullEnv } from "@app/lib/pullEnv";
import { LoadLoginPageResponse } from "#private/routers/loginPage";
import { LoadLoginPageResponse } from "@server/routers/loginPage/types";
import { redirect } from "next/navigation";
export const dynamic = "force-dynamic";

View File

@@ -15,12 +15,12 @@ import AccessToken from "@app/components/AccessToken";
import { pullEnv } from "@app/lib/pullEnv";
import { LoginFormIDP } from "@app/components/LoginForm";
import { ListIdpsResponse } from "@server/routers/idp";
import { ListOrgIdpsResponse } from "#private/routers/orgIdp";
import { ListOrgIdpsResponse } from "@server/routers/orgIdp/types";
import AutoLoginHandler from "@app/components/AutoLoginHandler";
import { build } from "@server/build";
import { headers } from "next/headers";
import { GetLoginPageResponse } from "#private/routers/loginPage";
import { GetOrgTierResponse } from "#private/routers/billing";
import { GetLoginPageResponse } from "@server/routers/loginPage/types";
import { GetOrgTierResponse } from "@server/routers/billing/types";
import { TierId } from "@server/lib/billing/tiers";
export const dynamic = "force-dynamic";

View File

@@ -32,7 +32,7 @@ import { createApiClient, formatAxiosError } from "@/lib/api";
import { useEnvContext } from "@/hooks/useEnvContext";
import { toast } from "@/hooks/useToast";
import { ListDomainsResponse } from "@server/routers/domain/listDomains";
import { CheckDomainAvailabilityResponse } from "#private/routers/domain/checkDomainNamespaceAvailability";
import { CheckDomainAvailabilityResponse } from "@server/routers/domain/types";
import { AxiosResponse } from "axios";
import { cn } from "@/lib/cn";
import { useTranslations } from "next-intl";

View File

@@ -13,12 +13,14 @@ import {
import { useTranslations } from "next-intl";
import { build } from "@server/build";
import CertificateStatus from "@app/components/private/CertificateStatus";
import { toUnicode } from 'punycode';
import { toUnicode } from "punycode";
import { useEnvContext } from "@app/hooks/useEnvContext";
type ResourceInfoBoxType = {};
export default function ResourceInfoBox({ }: ResourceInfoBoxType) {
export default function ResourceInfoBox({}: ResourceInfoBoxType) {
const { resource, authInfo } = useResourceContext();
const { env } = useEnvContext();
const t = useTranslations();
@@ -28,7 +30,13 @@ export default function ResourceInfoBox({ }: ResourceInfoBoxType) {
<Alert>
<AlertDescription>
{/* 4 cols because of the certs */}
<InfoSections cols={resource.http && build != "oss" ? 4 : 3}>
<InfoSections
cols={
resource.http && env.flags.generateOwnCertificates
? 4
: 3
}
>
{resource.http ? (
<>
<InfoSection>
@@ -37,9 +45,9 @@ export default function ResourceInfoBox({ }: ResourceInfoBoxType) {
</InfoSectionTitle>
<InfoSectionContent>
{authInfo.password ||
authInfo.pincode ||
authInfo.sso ||
authInfo.whitelist ? (
authInfo.pincode ||
authInfo.sso ||
authInfo.whitelist ? (
<div className="flex items-start space-x-2 text-green-500">
<ShieldCheck className="w-4 h-4 mt-0.5" />
<span>{t("protected")}</span>
@@ -126,25 +134,28 @@ export default function ResourceInfoBox({ }: ResourceInfoBoxType) {
{/* </InfoSectionContent> */}
{/* </InfoSection> */}
{/* Certificate Status Column */}
{resource.http && resource.domainId && resource.fullDomain && build != "oss" && (
<InfoSection>
<InfoSectionTitle>
{t("certificateStatus", {
defaultValue: "Certificate"
})}
</InfoSectionTitle>
<InfoSectionContent>
<CertificateStatus
orgId={resource.orgId}
domainId={resource.domainId}
fullDomain={resource.fullDomain}
autoFetch={true}
showLabel={false}
polling={true}
/>
</InfoSectionContent>
</InfoSection>
)}
{resource.http &&
resource.domainId &&
resource.fullDomain &&
build != "oss" && (
<InfoSection>
<InfoSectionTitle>
{t("certificateStatus", {
defaultValue: "Certificate"
})}
</InfoSectionTitle>
<InfoSectionContent>
<CertificateStatus
orgId={resource.orgId}
domainId={resource.domainId}
fullDomain={resource.fullDomain}
autoFetch={true}
showLabel={false}
polling={true}
/>
</InfoSectionContent>
</InfoSection>
)}
<InfoSection>
<InfoSectionTitle>{t("visibility")}</InfoSectionTitle>
<InfoSectionContent>

View File

@@ -1,4 +1,5 @@
"use client";
import { Button } from "@app/components/ui/button";
import { useOrgContext } from "@app/hooks/useOrgContext";
import { toast } from "@app/hooks/useToast";
@@ -30,7 +31,7 @@ import {
SettingsSectionForm
} from "@app/components/Settings";
import { useTranslations } from "next-intl";
import { GetLoginPageResponse } from "#private/routers/loginPage";
import { GetLoginPageResponse } from "@server/routers/loginPage/types";
import { ListDomainsResponse } from "@server/routers/domain";
import { DomainRow } from "@app/components/DomainsTable";
import { toUnicode } from "punycode";
@@ -78,6 +79,7 @@ const AuthPageSettings = forwardRef<AuthPageSettingsRef, AuthPageSettingsProps>(
const api = createApiClient(useEnvContext());
const router = useRouter();
const t = useTranslations();
const { env } = useEnvContext();
const subscription = useSubscriptionStatusContext();
@@ -447,10 +449,21 @@ const AuthPageSettings = forwardRef<AuthPageSettingsRef, AuthPageSettingsProps>(
</div>
</div>
{/* Certificate Status */}
{(build === "enterprise" ||
(build === "saas" &&
subscription?.subscribed)) &&
{!form.watch(
"authPageDomainId"
) && (
<div className="text-sm text-muted-foreground">
{t(
"addDomainToEnableCustomAuthPages"
)}
</div>
)}
{env.flags
.generateOwnCertificates &&
(build === "enterprise" ||
(build === "saas" &&
subscription?.subscribed)) &&
loginPage?.domainId &&
loginPage?.fullDomain &&
!hasUnsavedChanges && (
@@ -469,16 +482,6 @@ const AuthPageSettings = forwardRef<AuthPageSettingsRef, AuthPageSettingsProps>(
polling={true}
/>
)}
{!form.watch(
"authPageDomainId"
) && (
<div className="text-sm text-muted-foreground">
{t(
"addDomainToEnableCustomAuthPages"
)}
</div>
)}
</div>
</form>
</Form>

View File

@@ -8,7 +8,7 @@ import { useEffect, useState } from "react";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { AlertCircle } from "lucide-react";
import { useTranslations } from "next-intl";
import { TransferSessionResponse } from "#private/routers/auth/transferSession";
import { TransferSessionResponse } from "@server/routers/auth/types";
type ValidateSessionTransferTokenParams = {
token: string;

View File

@@ -1,4 +1,4 @@
import { GetRemoteExitNodeResponse } from "#private/routers/remoteExitNode";
import { GetRemoteExitNodeResponse } from "@server/routers/remoteExitNode/types";
import { createContext } from "react";
type RemoteExitNodeContextType = {

View File

@@ -1,4 +1,4 @@
import { GetOrgSubscriptionResponse } from "#private/routers/billing";
import { GetOrgSubscriptionResponse } from "@server/routers/billing/types";
import { createContext } from "react";
type SubscriptionStatusContextType = {

View File

@@ -2,7 +2,7 @@
import { useState, useCallback, useEffect } from "react";
import { AxiosResponse } from "axios";
import { GetCertificateResponse } from "#private/routers/certificates";
import { GetCertificateResponse } from "@server/routers/certificates/types";
import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext";

View File

@@ -48,7 +48,11 @@ export function pullEnv(): Env {
enableClients:
process.env.FLAGS_ENABLE_CLIENTS === "true" ? true : false,
hideSupporterKey:
process.env.HIDE_SUPPORTER_KEY === "true" ? true : false
process.env.HIDE_SUPPORTER_KEY === "true" ? true : false,
generateOwnCertificates:
process.env.GENERATE_OWN_CERTIFICATES === "true"
? true
: false
},
branding: {

View File

@@ -28,6 +28,7 @@ export type Env = {
disableBasicWireguardSites: boolean;
enableClients: boolean;
hideSupporterKey: boolean;
generateOwnCertificates: boolean;
},
branding: {
appName?: string;

View File

@@ -1,7 +1,7 @@
"use client";
import RemoteExitNodeContext from "@app/contexts/remoteExitNodeContext";
import { GetRemoteExitNodeResponse } from "#private/routers/remoteExitNode";
import { GetRemoteExitNodeResponse } from "@server/routers/remoteExitNode/types";
import { useState } from "react";
import { useTranslations } from "next-intl";

View File

@@ -2,7 +2,7 @@
import SubscriptionStatusContext from "@app/contexts/subscriptionStatusContext";
import { getTierPriceSet, TierId } from "@server/lib/billing/tiers";
import { GetOrgSubscriptionResponse } from "#private/routers/billing";
import { GetOrgSubscriptionResponse } from "@server/routers/billing/types";
import { useState } from "react";
import { build } from "@server/build";