From d73825dd24d4f2127be315c035568efa0d514f02 Mon Sep 17 00:00:00 2001 From: v1rusnl <18641204+v1rusnl@users.noreply.github.com> Date: Tue, 18 Nov 2025 12:41:12 +0100 Subject: [PATCH 1/5] Update Traefik image version to v3.6 --- install/config/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/config/docker-compose.yml b/install/config/docker-compose.yml index b507e914..90613b2a 100644 --- a/install/config/docker-compose.yml +++ b/install/config/docker-compose.yml @@ -35,7 +35,7 @@ services: - 80:80 {{end}} traefik: - image: docker.io/traefik:v3.5 + image: docker.io/traefik:v3.6 container_name: traefik restart: unless-stopped {{if .InstallGerbil}} @@ -59,4 +59,4 @@ networks: default: driver: bridge name: pangolin -{{if .EnableIPv6}} enable_ipv6: true{{end}} \ No newline at end of file +{{if .EnableIPv6}} enable_ipv6: true{{end}} From 51b438117a755ae449eaa248f769a62b243a28a2 Mon Sep 17 00:00:00 2001 From: v1rusnl <18641204+v1rusnl@users.noreply.github.com> Date: Tue, 18 Nov 2025 12:44:10 +0100 Subject: [PATCH 2/5] Update Traefik image version to v3.6 --- docker-compose.example.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.example.yml b/docker-compose.example.yml index 21a5134f..84a5140b 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -35,7 +35,7 @@ services: - 80:80 # Port for traefik because of the network_mode traefik: - image: traefik:v3.5 + image: traefik:v3.6 container_name: traefik restart: unless-stopped network_mode: service:gerbil # Ports appear on the gerbil service @@ -52,4 +52,4 @@ networks: default: driver: bridge name: pangolin - enable_ipv6: true \ No newline at end of file + enable_ipv6: true From 8f9b665bef763c37db227ec785cc694a7fc60178 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:43:50 +0000 Subject: [PATCH 3/5] Initial plan From 01b5158b73105f4792c2aaa0c96f1a723bfc51fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:50:06 +0000 Subject: [PATCH 4/5] Add auto-login-idp support to blueprints Co-authored-by: oschwartz10612 <4999704+oschwartz10612@users.noreply.github.com> --- blueprint.yaml | 1 + server/lib/blueprints/proxyResources.ts | 45 ++++++++++++++++++++++++- server/lib/blueprints/types.ts | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/blueprint.yaml b/blueprint.yaml index 0a524f12..2e790cba 100644 --- a/blueprint.yaml +++ b/blueprint.yaml @@ -31,6 +31,7 @@ proxy-resources: # - owen@pangolin.net # whitelist-users: # - owen@pangolin.net + # auto-login-idp: My IDP Name headers: - name: X-Example-Header value: example-value diff --git a/server/lib/blueprints/proxyResources.ts b/server/lib/blueprints/proxyResources.ts index d85befed..eb03ad49 100644 --- a/server/lib/blueprints/proxyResources.ts +++ b/server/lib/blueprints/proxyResources.ts @@ -14,7 +14,9 @@ import { Transaction, userOrgs, userResources, - users + users, + idp, + idpOrg } from "@server/db"; import { resources, targets, sites } from "@server/db"; import { eq, and, asc, or, ne, count, isNotNull } from "drizzle-orm"; @@ -208,6 +210,16 @@ export async function updateProxyResources( ); resource = existingResource; } else { + // Lookup IDP ID if auto-login-idp is specified + let skipToIdpId: number | null = null; + if (resourceData.auth?.["auto-login-idp"]) { + skipToIdpId = await getIdpIdByName( + orgId, + resourceData.auth["auto-login-idp"], + trx + ); + } + // Update existing resource [resource] = await trx .update(resources) @@ -221,6 +233,7 @@ export async function updateProxyResources( domainId: domain ? domain.domainId : null, enabled: resourceEnabled, sso: resourceData.auth?.["sso-enabled"] || false, + skipToIdpId: skipToIdpId, ssl: resourceSsl, setHostHeader: resourceData["host-header"] || null, tlsServerName: resourceData["tls-server-name"] || null, @@ -595,6 +608,16 @@ export async function updateProxyResources( ); } + // Lookup IDP ID if auto-login-idp is specified + let skipToIdpId: number | null = null; + if (resourceData.auth?.["auto-login-idp"]) { + skipToIdpId = await getIdpIdByName( + orgId, + resourceData.auth["auto-login-idp"], + trx + ); + } + // Create new resource const [newResource] = await trx .insert(resources) @@ -610,6 +633,7 @@ export async function updateProxyResources( domainId: domain ? domain.domainId : null, enabled: resourceEnabled, sso: resourceData.auth?.["sso-enabled"] || false, + skipToIdpId: skipToIdpId, setHostHeader: resourceData["host-header"] || null, tlsServerName: resourceData["tls-server-name"] || null, ssl: resourceSsl, @@ -1084,3 +1108,22 @@ async function getDomainId( domainId: domainSelection.domainId }; } + +async function getIdpIdByName( + orgId: string, + idpName: string, + trx: Transaction +): Promise { + const [idpResult] = await trx + .select({ idpId: idp.idpId }) + .from(idp) + .innerJoin(idpOrg, eq(idp.idpId, idpOrg.idpId)) + .where(and(eq(idp.name, idpName), eq(idpOrg.orgId, orgId))) + .limit(1); + + if (!idpResult) { + throw new Error(`IDP not found: ${idpName} in org ${orgId}`); + } + + return idpResult.idpId; +} diff --git a/server/lib/blueprints/types.ts b/server/lib/blueprints/types.ts index ca3177b3..d0790a65 100644 --- a/server/lib/blueprints/types.ts +++ b/server/lib/blueprints/types.ts @@ -59,6 +59,7 @@ export const AuthSchema = z.object({ }), "sso-users": z.array(z.string().email()).optional().default([]), "whitelist-users": z.array(z.string().email()).optional().default([]), + "auto-login-idp": z.string().min(1).optional(), }); export const RuleSchema = z.object({ From 6da531e99b459b2a244d7f95b20622707e98ea48 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Nov 2025 19:29:52 +0000 Subject: [PATCH 5/5] Use IDP ID instead of IDP name for auto-login-idp Co-authored-by: oschwartz10612 <4999704+oschwartz10612@users.noreply.github.com> --- blueprint.yaml | 2 +- server/lib/blueprints/proxyResources.ts | 47 ++----------------------- server/lib/blueprints/types.ts | 2 +- 3 files changed, 5 insertions(+), 46 deletions(-) diff --git a/blueprint.yaml b/blueprint.yaml index 2e790cba..adc25055 100644 --- a/blueprint.yaml +++ b/blueprint.yaml @@ -31,7 +31,7 @@ proxy-resources: # - owen@pangolin.net # whitelist-users: # - owen@pangolin.net - # auto-login-idp: My IDP Name + # auto-login-idp: 1 headers: - name: X-Example-Header value: example-value diff --git a/server/lib/blueprints/proxyResources.ts b/server/lib/blueprints/proxyResources.ts index eb03ad49..5fbebb5a 100644 --- a/server/lib/blueprints/proxyResources.ts +++ b/server/lib/blueprints/proxyResources.ts @@ -14,9 +14,7 @@ import { Transaction, userOrgs, userResources, - users, - idp, - idpOrg + users } from "@server/db"; import { resources, targets, sites } from "@server/db"; import { eq, and, asc, or, ne, count, isNotNull } from "drizzle-orm"; @@ -210,16 +208,6 @@ export async function updateProxyResources( ); resource = existingResource; } else { - // Lookup IDP ID if auto-login-idp is specified - let skipToIdpId: number | null = null; - if (resourceData.auth?.["auto-login-idp"]) { - skipToIdpId = await getIdpIdByName( - orgId, - resourceData.auth["auto-login-idp"], - trx - ); - } - // Update existing resource [resource] = await trx .update(resources) @@ -233,7 +221,7 @@ export async function updateProxyResources( domainId: domain ? domain.domainId : null, enabled: resourceEnabled, sso: resourceData.auth?.["sso-enabled"] || false, - skipToIdpId: skipToIdpId, + skipToIdpId: resourceData.auth?.["auto-login-idp"] || null, ssl: resourceSsl, setHostHeader: resourceData["host-header"] || null, tlsServerName: resourceData["tls-server-name"] || null, @@ -608,16 +596,6 @@ export async function updateProxyResources( ); } - // Lookup IDP ID if auto-login-idp is specified - let skipToIdpId: number | null = null; - if (resourceData.auth?.["auto-login-idp"]) { - skipToIdpId = await getIdpIdByName( - orgId, - resourceData.auth["auto-login-idp"], - trx - ); - } - // Create new resource const [newResource] = await trx .insert(resources) @@ -633,7 +611,7 @@ export async function updateProxyResources( domainId: domain ? domain.domainId : null, enabled: resourceEnabled, sso: resourceData.auth?.["sso-enabled"] || false, - skipToIdpId: skipToIdpId, + skipToIdpId: resourceData.auth?.["auto-login-idp"] || null, setHostHeader: resourceData["host-header"] || null, tlsServerName: resourceData["tls-server-name"] || null, ssl: resourceSsl, @@ -1108,22 +1086,3 @@ async function getDomainId( domainId: domainSelection.domainId }; } - -async function getIdpIdByName( - orgId: string, - idpName: string, - trx: Transaction -): Promise { - const [idpResult] = await trx - .select({ idpId: idp.idpId }) - .from(idp) - .innerJoin(idpOrg, eq(idp.idpId, idpOrg.idpId)) - .where(and(eq(idp.name, idpName), eq(idpOrg.orgId, orgId))) - .limit(1); - - if (!idpResult) { - throw new Error(`IDP not found: ${idpName} in org ${orgId}`); - } - - return idpResult.idpId; -} diff --git a/server/lib/blueprints/types.ts b/server/lib/blueprints/types.ts index d0790a65..e49024f9 100644 --- a/server/lib/blueprints/types.ts +++ b/server/lib/blueprints/types.ts @@ -59,7 +59,7 @@ export const AuthSchema = z.object({ }), "sso-users": z.array(z.string().email()).optional().default([]), "whitelist-users": z.array(z.string().email()).optional().default([]), - "auto-login-idp": z.string().min(1).optional(), + "auto-login-idp": z.number().int().positive().optional(), }); export const RuleSchema = z.object({