mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-09 17:18:31 +00:00
Move proxy and client to public and private
This commit is contained in:
parent
b99e9a6468
commit
08a2923cfc
25 changed files with 53 additions and 81 deletions
|
|
@ -22,7 +22,21 @@ const nextConfig: NextConfig = {
|
||||||
reactCompiler: true,
|
reactCompiler: true,
|
||||||
transpilePackages: ["@novnc/novnc"],
|
transpilePackages: ["@novnc/novnc"],
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
allowedDevOrigins
|
allowedDevOrigins,
|
||||||
|
async redirects() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: "/:orgId/settings/resources/proxy/:path*",
|
||||||
|
destination: "/:orgId/settings/resources/public/:path*",
|
||||||
|
permanent: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: "/:orgId/settings/resources/client/:path*",
|
||||||
|
destination: "/:orgId/settings/resources/private/:path*",
|
||||||
|
permanent: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withNextIntl(nextConfig);
|
export default withNextIntl(nextConfig);
|
||||||
|
|
|
||||||
|
|
@ -343,8 +343,8 @@ export default function GeneralPage() {
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
row.original.type === "ssh"
|
row.original.type === "ssh"
|
||||||
? `/${row.original.orgId}/settings/resources/client?query=${row.original.resourceNiceId}`
|
? `/${row.original.orgId}/settings/resources/private?query=${row.original.resourceNiceId}`
|
||||||
: `/${row.original.orgId}/settings/resources/proxy/${row.original.resourceNiceId}`
|
: `/${row.original.orgId}/settings/resources/public/${row.original.resourceNiceId}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Button variant="outline" size="sm">
|
<Button variant="outline" size="sm">
|
||||||
|
|
|
||||||
|
|
@ -325,7 +325,7 @@ export default function ConnectionLogsPage() {
|
||||||
if (row.original.resourceName && row.original.resourceNiceId) {
|
if (row.original.resourceName && row.original.resourceNiceId) {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/${row.original.orgId}/settings/resources/client/?query=${row.original.resourceNiceId}`}
|
href={`/${row.original.orgId}/settings/resources/private/?query=${row.original.resourceNiceId}`}
|
||||||
>
|
>
|
||||||
<Button variant="outline" size="sm">
|
<Button variant="outline" size="sm">
|
||||||
{row.original.resourceName}
|
{row.original.resourceName}
|
||||||
|
|
|
||||||
|
|
@ -400,8 +400,8 @@ export default function GeneralPage() {
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
row.original.reason == 108 // for now the client will only have reason 108 so we know where to go
|
row.original.reason == 108 // for now the client will only have reason 108 so we know where to go
|
||||||
? `/${row.original.orgId}/settings/resources/client?query=${row.original.resourceNiceId}`
|
? `/${row.original.orgId}/settings/resources/private?query=${row.original.resourceNiceId}`
|
||||||
: `/${row.original.orgId}/settings/resources/proxy/${row.original.resourceNiceId}`
|
: `/${row.original.orgId}/settings/resources/public/${row.original.resourceNiceId}`
|
||||||
}
|
}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,5 @@ export interface ResourcesPageProps {
|
||||||
|
|
||||||
export default async function ResourcesPage(props: ResourcesPageProps) {
|
export default async function ResourcesPage(props: ResourcesPageProps) {
|
||||||
const params = await props.params;
|
const params = await props.params;
|
||||||
redirect(`/${params.orgId}/settings/resources/proxy`);
|
redirect(`/${params.orgId}/settings/resources/public`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { InternalResourceRow } from "@app/components/ClientResourcesTable";
|
import type { InternalResourceRow } from "@app/components/PrivateResourcesTable";
|
||||||
import PrivateResourcesTable from "@app/components/ClientResourcesTable";
|
import PrivateResourcesTable from "@app/components/PrivateResourcesTable";
|
||||||
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
|
||||||
import PrivateResourcesBanner from "@app/components/PrivateResourcesBanner";
|
import PrivateResourcesBanner from "@app/components/PrivateResourcesBanner";
|
||||||
import { internal } from "@app/lib/api";
|
import { internal } from "@app/lib/api";
|
||||||
|
|
@ -548,7 +548,7 @@ export default function GeneralForm() {
|
||||||
|
|
||||||
if (data.niceId && data.niceId !== resource?.niceId) {
|
if (data.niceId && data.niceId !== resource?.niceId) {
|
||||||
router.replace(
|
router.replace(
|
||||||
`/${updated.orgId}/settings/resources/proxy/${data.niceId}/general`
|
`/${updated.orgId}/settings/resources/public/${data.niceId}/general`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,69 +39,27 @@ import {
|
||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage
|
FormMessage
|
||||||
} from "@app/components/ui/form";
|
} from "@app/components/ui/form";
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow
|
|
||||||
} from "@app/components/ui/table";
|
|
||||||
import {
|
|
||||||
Tooltip,
|
|
||||||
TooltipContent,
|
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger
|
|
||||||
} from "@app/components/ui/tooltip";
|
|
||||||
import type { ResourceContextType } from "@app/contexts/resourceContext";
|
import type { ResourceContextType } from "@app/contexts/resourceContext";
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
import { useResourceContext } from "@app/hooks/useResourceContext";
|
import { useResourceContext } from "@app/hooks/useResourceContext";
|
||||||
import { toast } from "@app/hooks/useToast";
|
import { toast } from "@app/hooks/useToast";
|
||||||
import { createApiClient } from "@app/lib/api";
|
import { createApiClient } from "@app/lib/api";
|
||||||
import { formatAxiosError } from "@app/lib/api/formatAxiosError";
|
import { formatAxiosError } from "@app/lib/api/formatAxiosError";
|
||||||
import { DockerManager, DockerState } from "@app/lib/docker";
|
import { resourceQueries } from "@app/lib/queries";
|
||||||
import { orgQueries, resourceQueries } from "@app/lib/queries";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { build } from "@server/build";
|
|
||||||
import { tlsNameSchema } from "@server/lib/schemas";
|
import { tlsNameSchema } from "@server/lib/schemas";
|
||||||
import { type GetResourceResponse } from "@server/routers/resource";
|
|
||||||
import type { ListSitesResponse } from "@server/routers/site";
|
|
||||||
import { CreateTargetResponse } from "@server/routers/target";
|
|
||||||
import { ListTargetsResponse } from "@server/routers/target/listTargets";
|
|
||||||
import { ArrayElement } from "@server/types/ArrayElement";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
LocalTarget,
|
|
||||||
ProxyResourceTargetsForm
|
ProxyResourceTargetsForm
|
||||||
} from "@app/app/[orgId]/settings/resources/proxy/ProxyResourceTargetsForm";
|
} from "@app/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm";
|
||||||
import {
|
|
||||||
ColumnDef,
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getFilteredRowModel,
|
|
||||||
getPaginationRowModel,
|
|
||||||
getSortedRowModel,
|
|
||||||
useReactTable
|
|
||||||
} from "@tanstack/react-table";
|
|
||||||
import { AxiosResponse } from "axios";
|
|
||||||
import {
|
import {
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
CircleCheck,
|
|
||||||
CircleX,
|
|
||||||
ExternalLink,
|
|
||||||
Info,
|
|
||||||
Plus,
|
|
||||||
Settings
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import {
|
import {
|
||||||
use,
|
use,
|
||||||
useActionState,
|
useActionState,
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useState
|
|
||||||
} from "react";
|
} from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
@ -83,22 +83,22 @@ export default async function ResourceLayout(props: ResourceLayoutProps) {
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{
|
{
|
||||||
title: t("general"),
|
title: t("general"),
|
||||||
href: `/{orgId}/settings/resources/proxy/{niceId}/general`
|
href: `/{orgId}/settings/resources/public/{niceId}/general`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t(`${resource.mode}Settings`),
|
title: t(`${resource.mode}Settings`),
|
||||||
href: `/{orgId}/settings/resources/proxy/{niceId}/${resource.mode}`
|
href: `/{orgId}/settings/resources/public/{niceId}/${resource.mode}`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
if (["http", "ssh", "rdp", "vnc"].includes(resource.mode)) {
|
if (["http", "ssh", "rdp", "vnc"].includes(resource.mode)) {
|
||||||
navItems.push({
|
navItems.push({
|
||||||
title: t("authentication"),
|
title: t("authentication"),
|
||||||
href: `/{orgId}/settings/resources/proxy/{niceId}/authentication`
|
href: `/{orgId}/settings/resources/public/{niceId}/authentication`
|
||||||
});
|
});
|
||||||
// navItems.push({
|
// navItems.push({
|
||||||
// title: t("rules"),
|
// title: t("rules"),
|
||||||
// href: `/{orgId}/settings/resources/proxy/{niceId}/rules`
|
// href: `/{orgId}/settings/resources/public/{niceId}/rules`
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10,6 +10,6 @@ export default async function ResourcePage(props: {
|
||||||
}) {
|
}) {
|
||||||
const params = await props.params;
|
const params = await props.params;
|
||||||
redirect(
|
redirect(
|
||||||
`/${params.orgId}/settings/resources/proxy/${params.niceId}/general`
|
`/${params.orgId}/settings/resources/public/${params.niceId}/general`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
LocalTarget,
|
LocalTarget,
|
||||||
ProxyResourceTargetsForm
|
ProxyResourceTargetsForm
|
||||||
} from "@app/app/[orgId]/settings/resources/proxy/ProxyResourceTargetsForm";
|
} from "@app/app/[orgId]/settings/resources/public/ProxyResourceTargetsForm";
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
flexRender,
|
flexRender,
|
||||||
|
|
@ -514,7 +514,7 @@ export default function Page() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
router.push(
|
router.push(
|
||||||
`/${orgId}/settings/resources/proxy/${newNiceId}`
|
`/${orgId}/settings/resources/public/${newNiceId}`
|
||||||
);
|
);
|
||||||
} else if (resourceType === "ssh") {
|
} else if (resourceType === "ssh") {
|
||||||
if (isNative) {
|
if (isNative) {
|
||||||
|
|
@ -550,7 +550,7 @@ export default function Page() {
|
||||||
}
|
}
|
||||||
|
|
||||||
router.push(
|
router.push(
|
||||||
`/${orgId}/settings/resources/proxy/${newNiceId}`
|
`/${orgId}/settings/resources/public/${newNiceId}`
|
||||||
);
|
);
|
||||||
} else if (resourceType === "rdp" || resourceType === "vnc") {
|
} else if (resourceType === "rdp" || resourceType === "vnc") {
|
||||||
for (const site of bgSelectedSites) {
|
for (const site of bgSelectedSites) {
|
||||||
|
|
@ -566,7 +566,7 @@ export default function Page() {
|
||||||
}
|
}
|
||||||
|
|
||||||
router.push(
|
router.push(
|
||||||
`/${orgId}/settings/resources/proxy/${newNiceId}`
|
`/${orgId}/settings/resources/public/${newNiceId}`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// TCP / UDP — create targets then show snippets
|
// TCP / UDP — create targets then show snippets
|
||||||
|
|
@ -1308,7 +1308,7 @@ export default function Page() {
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push(
|
||||||
`/${orgId}/settings/resources/proxy/${niceId}`
|
`/${orgId}/settings/resources/public/${niceId}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -71,12 +71,12 @@ export const orgNavSections = (
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
title: "sidebarProxyResources",
|
title: "sidebarProxyResources",
|
||||||
href: "/{orgId}/settings/resources/proxy",
|
href: "/{orgId}/settings/resources/public",
|
||||||
icon: <Globe className="size-4 flex-none" />
|
icon: <Globe className="size-4 flex-none" />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "sidebarClientResources",
|
title: "sidebarClientResources",
|
||||||
href: "/{orgId}/settings/resources/client",
|
href: "/{orgId}/settings/resources/private",
|
||||||
icon: <GlobeLock className="size-4 flex-none" />
|
icon: <GlobeLock className="size-4 flex-none" />
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,7 @@ export default function HealthChecksTable({
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/${orgId}/settings/resources/proxy/${r.resourceNiceId}`}
|
href={`/${orgId}/settings/resources/public/${r.resourceNiceId}`}
|
||||||
>
|
>
|
||||||
<Button variant="outline" size="sm">
|
<Button variant="outline" size="sm">
|
||||||
{r.resourceName}
|
{r.resourceName}
|
||||||
|
|
@ -627,7 +627,7 @@ export default function HealthChecksTable({
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
{r.resourceId && r.resourceName && r.resourceNiceId ? (
|
{r.resourceId && r.resourceName && r.resourceNiceId ? (
|
||||||
<Link
|
<Link
|
||||||
href={`/${orgId}/settings/resources/proxy/${r.resourceNiceId}`}
|
href={`/${orgId}/settings/resources/public/${r.resourceNiceId}`}
|
||||||
>
|
>
|
||||||
<Button variant="outline" disabled={!isPaid}>
|
<Button variant="outline" disabled={!isPaid}>
|
||||||
{t("edit")}
|
{t("edit")}
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,7 @@ export default function ProxyResourcesTable({
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
<Link
|
<Link
|
||||||
className="block w-full"
|
className="block w-full"
|
||||||
href={`/${resourceRow.orgId}/settings/resources/proxy/${resourceRow.nice}`}
|
href={`/${resourceRow.orgId}/settings/resources/public/${resourceRow.nice}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
{t("viewSettings")}
|
{t("viewSettings")}
|
||||||
|
|
@ -628,7 +628,7 @@ export default function ProxyResourcesTable({
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<Link
|
<Link
|
||||||
href={`/${resourceRow.orgId}/settings/resources/proxy/${resourceRow.nice}`}
|
href={`/${resourceRow.orgId}/settings/resources/public/${resourceRow.nice}`}
|
||||||
>
|
>
|
||||||
<Button variant={"outline"}>
|
<Button variant={"outline"}>
|
||||||
{t("edit")}
|
{t("edit")}
|
||||||
|
|
@ -744,7 +744,9 @@ export default function ProxyResourcesTable({
|
||||||
onPaginationChange={handlePaginationChange}
|
onPaginationChange={handlePaginationChange}
|
||||||
onAdd={() =>
|
onAdd={() =>
|
||||||
startNavigation(() =>
|
startNavigation(() =>
|
||||||
router.push(`/${orgId}/settings/resources/proxy/create`)
|
router.push(
|
||||||
|
`/${orgId}/settings/resources/public/create`
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
addButtonText={t("resourceAdd")}
|
addButtonText={t("resourceAdd")}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ export default function ShareLinksTable({
|
||||||
const r = row.original;
|
const r = row.original;
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/${orgId}/settings/resources/proxy/${r.resourceNiceId}`}
|
href={`/${orgId}/settings/resources/public/${r.resourceNiceId}`}
|
||||||
>
|
>
|
||||||
<Button variant="outline" size="sm">
|
<Button variant="outline" size="sm">
|
||||||
{r.resourceName}
|
{r.resourceName}
|
||||||
|
|
@ -328,9 +328,7 @@ export default function ShareLinksTable({
|
||||||
onConfirm={async () =>
|
onConfirm={async () =>
|
||||||
deleteSharelink(selectedLink.accessTokenId)
|
deleteSharelink(selectedLink.accessTokenId)
|
||||||
}
|
}
|
||||||
string={
|
string={selectedLink.title || selectedLink.resourceName}
|
||||||
selectedLink.title || selectedLink.resourceName
|
|
||||||
}
|
|
||||||
title={t("shareDelete")}
|
title={t("shareDelete")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -421,15 +421,15 @@ export default function SiteResourcesOverview({
|
||||||
publicList.length === 0 &&
|
publicList.length === 0 &&
|
||||||
privateList.length === 0;
|
privateList.length === 0;
|
||||||
|
|
||||||
const publicViewAllHref = `/${orgId}/settings/resources/proxy?siteId=${siteId}`;
|
const publicViewAllHref = `/${orgId}/settings/resources/public?siteId=${siteId}`;
|
||||||
const privateViewAllHref = `/${orgId}/settings/resources/client?siteId=${siteId}`;
|
const privateViewAllHref = `/${orgId}/settings/resources/private?siteId=${siteId}`;
|
||||||
|
|
||||||
const publicRows = publicList.map((r) => ({
|
const publicRows = publicList.map((r) => ({
|
||||||
key: r.resourceId,
|
key: r.resourceId,
|
||||||
meta: <PublicResourceMeta resource={r} />,
|
meta: <PublicResourceMeta resource={r} />,
|
||||||
name: r.name,
|
name: r.name,
|
||||||
access: <PublicAccessMethod resource={r} />,
|
access: <PublicAccessMethod resource={r} />,
|
||||||
editHref: `/${orgId}/settings/resources/proxy/${r.niceId}`
|
editHref: `/${orgId}/settings/resources/public/${r.niceId}`
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const privateRows = privateList.map((row) => {
|
const privateRows = privateList.map((row) => {
|
||||||
|
|
@ -442,7 +442,7 @@ export default function SiteResourcesOverview({
|
||||||
meta: <PrivateResourceMeta row={row} />,
|
meta: <PrivateResourceMeta row={row} />,
|
||||||
name: row.name,
|
name: row.name,
|
||||||
access: <PrivateAccessMethod row={row} />,
|
access: <PrivateAccessMethod row={row} />,
|
||||||
editHref: `/${orgId}/settings/resources/client?${qs.toString()}`
|
editHref: `/${orgId}/settings/resources/private?${qs.toString()}`
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -506,7 +506,7 @@ export default function SitesTable({
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
className="block w-full"
|
className="block w-full"
|
||||||
href={`/${siteRow.orgId}/settings/resources/proxy?siteId=${siteRow.id}`}
|
href={`/${siteRow.orgId}/settings/resources/public?siteId=${siteRow.id}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
{t("sitesTableViewPublicResources")}
|
{t("sitesTableViewPublicResources")}
|
||||||
|
|
@ -514,7 +514,7 @@ export default function SitesTable({
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
className="block w-full"
|
className="block w-full"
|
||||||
href={`/${siteRow.orgId}/settings/resources/client?siteId=${siteRow.id}`}
|
href={`/${siteRow.orgId}/settings/resources/private?siteId=${siteRow.id}`}
|
||||||
>
|
>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
{t(
|
{t(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue