diff --git a/README.md b/README.md index 006a6b10..8723542c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,13 @@
-

pangolin

- -[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square)](https://docs.fossorial.io/) -[![Docker](https://img.shields.io/docker/pulls/fosrl/pangolin?style=flat-square)](https://hub.docker.com/r/fosrl/pangolin) -![Stars](https://img.shields.io/github/stars/fosrl/pangolin?style=flat-square) -[![Discord](https://img.shields.io/discord/1325658630518865980?logo=discord&style=flat-square)](https://discord.gg/HCJR8Xhme4) -[![Youtube](https://img.shields.io/badge/YouTube-red?logo=youtube&logoColor=white&style=flat-square)](https://www.youtube.com/@fossorial-app) - +

+ + + Pangolin Logo + +

-

Tunneled Reverse Proxy Server with Access Control

+

Tunneled Reverse Proxy Server with Access Control

_Your own self-hosted zero trust tunnel._ @@ -30,6 +28,12 @@ _Your own self-hosted zero trust tunnel._ Contact Us + +[![Docker](https://img.shields.io/docker/pulls/fosrl/pangolin?style=flat-square)](https://hub.docker.com/r/fosrl/pangolin) +![Stars](https://img.shields.io/github/stars/fosrl/pangolin?style=flat-square) +[![Discord](https://img.shields.io/discord/1325658630518865980?logo=discord&style=flat-square)](https://discord.gg/HCJR8Xhme4) +[![Youtube](https://img.shields.io/badge/YouTube-red?logo=youtube&logoColor=white&style=flat-square)](https://www.youtube.com/@fossorial-app) +
Pangolin is a self-hosted tunneled reverse proxy server with identity and access control, designed to securely expose private resources on distributed networks. Acting as a central hub, it connects isolated networks — even those behind restrictive firewalls — through encrypted tunnels, enabling easy access to remote services without opening ports. diff --git a/package.json b/package.json index b8ea5fab..c199f7c4 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "db:sqlite:generate": "drizzle-kit generate --config=./drizzle.sqlite.config.ts", "db:pg:push": "npx tsx server/db/pg/migrate.ts", "db:sqlite:push": "npx tsx server/db/sqlite/migrate.ts", - "db:studio": "drizzle-kit studio", + "db:sqlite:studio": "drizzle-kit studio --config=./drizzle.sqlite.config.ts", + "db:pg:studio": "drizzle-kit studio --config=./drizzle.pg.config.ts", "db:clear-migrations": "rm -rf server/migrations", "build:sqlite": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrationsSqlite.ts -o dist/migrations.mjs", "build:pg": "mkdir -p dist && next build && node esbuild.mjs -e server/index.ts -o dist/server.mjs && node esbuild.mjs -e server/setup/migrationsPg.ts -o dist/migrations.mjs", diff --git a/server/routers/gerbil/peers.ts b/server/routers/gerbil/peers.ts index 2f339fe4..4bc9ce7f 100644 --- a/server/routers/gerbil/peers.ts +++ b/server/routers/gerbil/peers.ts @@ -24,7 +24,7 @@ export async function addPeer(exitNodeId: number, peer: { } }); - logger.info('Peer added successfully:', response.data.status); + logger.info('Peer added successfully:', { peer: response.data.status }); return response.data; } catch (error) { if (axios.isAxiosError(error)) { diff --git a/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx b/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx index b42bc9ee..a6740b3c 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/ResourceInfoBox.tsx @@ -31,7 +31,7 @@ export default function ResourceInfoBox({}: ResourceInfoBoxType) { Resource Information - + {resource.http ? ( <> diff --git a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx index d2bfee4b..c9419865 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx @@ -60,7 +60,8 @@ import { SettingsSectionDescription, SettingsSectionBody, SettingsSectionFooter, - SettingsSectionForm + SettingsSectionForm, + SettingsSectionGrid } from "@app/components/Settings"; import { SwitchInput } from "@app/components/SwitchInput"; import { useRouter } from "next/navigation"; @@ -73,6 +74,7 @@ import { CollapsibleTrigger } from "@app/components/ui/collapsible"; import { ContainersSelector } from "@app/components/ContainersSelector"; +import { FaDocker } from "react-icons/fa"; const addTargetSchema = z.object({ ip: z.string().refine(isTargetValid), @@ -559,115 +561,6 @@ export default function ReverseProxyTargets(props: { return ( - {resource.http && ( - - - - HTTPS & TLS Settings - - - Configure TLS settings for your resource - - - - -
- - ( - - - { - field.onChange(val); - }} - /> - - - )} - /> - -
- - - -
- - ( - - - TLS Server Name - (SNI) - - - - - - The TLS Server Name - to use for SNI. - Leave empty to use - the default. - - - - )} - /> - -
- - -
-
- - - -
- )} - @@ -775,8 +668,7 @@ export default function ReverseProxyTargets(props: { - - {site && site.type == 'newt' && ( + {site && site.type == "newt" && ( )} + )} /> @@ -891,59 +784,175 @@ export default function ReverseProxyTargets(props: { {resource.http && ( - - - - Additional Proxy Settings - - - Configure how your resource handles proxy settings - - - - -
- - ( - - - Custom Host Header - - - - - - The host header to set when - proxying requests. Leave - empty to use the default. - - - + + + + + Secure Connection Configuration + + + Configure SSL/TLS settings for your resource + + + + + + - - - - - - - - + className="space-y-4" + id="tls-settings-form" + > + ( + + + { + field.onChange( + val + ); + }} + /> + + + )} + /> + +
+ + + +
+ + ( + + + TLS Server Name + (SNI) + + + + + + The TLS Server + Name to use for + SNI. Leave empty + to use the + default. + + + + )} + /> + +
+ + +
+
+ + + +
+ + + + Additional Proxy Settings + + + Configure how your resource handles proxy + settings + + + + +
+ + ( + + + Custom Host Header + + + + + + The host header to set + when proxying requests. + Leave empty to use the + default. + + + + )} + /> + + +
+
+ + + +
+ )}
); diff --git a/src/app/admin/license/page.tsx b/src/app/admin/license/page.tsx index b86c18b3..b3cc221e 100644 --- a/src/app/admin/license/page.tsx +++ b/src/app/admin/license/page.tsx @@ -289,17 +289,17 @@ export default function LicensePage() { terms corresponding to the tier associated with your license key. -
- - View Fossorial - Commercial License & - Subscription Terms - + {/*
*/} + {/* */} + {/* View Fossorial */} + {/* Commercial License & */} + {/* Subscription Terms */} + {/* */} @@ -503,32 +503,32 @@ export default function LicensePage() { )} - - {!licenseStatus?.isHostLicensed ? ( - <> - - - ) : ( - <> - - - )} - + {/* */} + {/* {!licenseStatus?.isHostLicensed ? ( */} + {/* <> */} + {/* */} + {/* */} + {/* ) : ( */} + {/* <> */} + {/* */} + {/* */} + {/* )} */} + {/* */} = ({ onContainerSelect }) => { const [open, setOpen] = useState(false); - const isDesktop = useMediaQuery("(min-width: 768px)"); - - const { isAvailable, containers, fetchContainers } = useDockerSocket( - site - ); + + const { isAvailable, containers, fetchContainers } = useDockerSocket(site); useEffect(() => { + console.log("DockerSocket isAvailable:", isAvailable); if (isAvailable) { fetchContainers(); } @@ -90,76 +80,41 @@ export const ContainersSelector: FC = ({ setOpen(false); }; - if (isDesktop) { - return ( - - - - - - - - Containers in {site.name} - - - Select any container (w/ port) to use as target for - your resource - - -
- fetchContainers()} - /> -
-
-
- ); - } - return ( - - - - - - - - Containers in {site.name} - - - Select any container to use as target for your resource - - -
- -
- - - - - -
-
+ <> + setOpen(true)} + > + View Docker Containers + + + + + Containers in {site.name} + + Select any container to use as a hostname for this + target. Click a port to use select a port. + + + +
+ fetchContainers()} + /> +
+
+ + + + + +
+
+ ); }; @@ -446,7 +401,7 @@ const DockerContainersTable: FC<{ if (initialFilters.length === 0) { return ( -
+
{(hideContainersWithoutPorts || @@ -497,8 +452,8 @@ const DockerContainersTable: FC<{ } return ( -
-
+
+
@@ -639,14 +594,11 @@ const DockerContainersTable: FC<{
- + {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( - + {header.isPlaceholder ? null : flexRender(