Various fixes

This commit is contained in:
Owen
2025-10-29 12:14:33 -07:00
parent 219e213c1e
commit f5eadc9e1e
5 changed files with 146 additions and 84 deletions

View File

@@ -204,7 +204,8 @@ export const configSchema = z
.optional() .optional()
.default(["newt", "wireguard", "local"]), .default(["newt", "wireguard", "local"]),
allow_raw_resources: z.boolean().optional().default(true), allow_raw_resources: z.boolean().optional().default(true),
file_mode: z.boolean().optional().default(false) file_mode: z.boolean().optional().default(false),
pp_transport_prefix: z.string().optional().default("pp-transport-v")
}) })
.optional() .optional()
.default({}), .default({}),

View File

@@ -265,37 +265,36 @@ export async function getTraefikConfig(
const domainCertResolver = resource.domainCertResolver; const domainCertResolver = resource.domainCertResolver;
const preferWildcardCert = resource.preferWildcardCert; const preferWildcardCert = resource.preferWildcardCert;
let resolverName: string | undefined; let resolverName: string | undefined;
let preferWildcard: boolean | undefined; let preferWildcard: boolean | undefined;
// Handle both letsencrypt & custom cases // Handle both letsencrypt & custom cases
if (domainCertResolver) { if (domainCertResolver) {
resolverName = domainCertResolver.trim(); resolverName = domainCertResolver.trim();
} else { } else {
resolverName = globalDefaultResolver; resolverName = globalDefaultResolver;
} }
if ( if (
preferWildcardCert !== undefined && preferWildcardCert !== undefined &&
preferWildcardCert !== null preferWildcardCert !== null
) { ) {
preferWildcard = preferWildcardCert; preferWildcard = preferWildcardCert;
} else { } else {
preferWildcard = globalDefaultPreferWildcard; preferWildcard = globalDefaultPreferWildcard;
} }
const tls = { const tls = {
certResolver: resolverName, certResolver: resolverName,
...(preferWildcard ...(preferWildcard
? { ? {
domains: [ domains: [
{ {
main: wildCard main: wildCard
} }
] ]
} }
: {}) : {})
}; };
const additionalMiddlewares = const additionalMiddlewares =
config.getRawConfig().traefik.additional_middlewares || []; config.getRawConfig().traefik.additional_middlewares || [];
@@ -534,14 +533,14 @@ export async function getTraefikConfig(
})(), })(),
...(resource.stickySession ...(resource.stickySession
? { ? {
sticky: { sticky: {
cookie: { cookie: {
name: "p_sticky", // TODO: make this configurable via config.yml like other cookies name: "p_sticky", // TODO: make this configurable via config.yml like other cookies
secure: resource.ssl, secure: resource.ssl,
httpOnly: true httpOnly: true
} }
} }
} }
: {}) : {})
} }
}; };
@@ -587,6 +586,8 @@ export async function getTraefikConfig(
...(protocol === "tcp" ? { rule: "HostSNI(`*`)" } : {}) ...(protocol === "tcp" ? { rule: "HostSNI(`*`)" } : {})
}; };
const ppPrefix = config.getRawConfig().traefik.pp_transport_prefix;
config_output[protocol].services[serviceName] = { config_output[protocol].services[serviceName] = {
loadBalancer: { loadBalancer: {
servers: (() => { servers: (() => {
@@ -642,18 +643,18 @@ export async function getTraefikConfig(
})(), })(),
...(resource.proxyProtocol && protocol == "tcp" ...(resource.proxyProtocol && protocol == "tcp"
? { ? {
serversTransport: `pp-transport-v${resource.proxyProtocolVersion || 1}` serversTransport: `${ppPrefix}${resource.proxyProtocolVersion || 1}@file` // TODO: does @file here cause issues?
} }
: {}), : {}),
...(resource.stickySession ...(resource.stickySession
? { ? {
sticky: { sticky: {
ipStrategy: { ipStrategy: {
depth: 0, depth: 0,
sourcePort: true sourcePort: true
} }
} }
} }
: {}) : {})
} }
}; };

View File

@@ -109,7 +109,7 @@ export async function getTraefikConfig(
domainNamespaceId: domainNamespaces.domainNamespaceId, domainNamespaceId: domainNamespaces.domainNamespaceId,
// Certificate // Certificate
certificateStatus: certificates.status, certificateStatus: certificates.status,
domainCertResolver: domains.certResolver, domainCertResolver: domains.certResolver
}) })
.from(sites) .from(sites)
.innerJoin(targets, eq(targets.siteId, sites.siteId)) .innerJoin(targets, eq(targets.siteId, sites.siteId))
@@ -214,7 +214,7 @@ export async function getTraefikConfig(
rewritePath: row.rewritePath, rewritePath: row.rewritePath,
rewritePathType: row.rewritePathType, rewritePathType: row.rewritePathType,
priority: priority, // may be null, we fallback later priority: priority, // may be null, we fallback later
domainCertResolver: row.domainCertResolver, domainCertResolver: row.domainCertResolver
}); });
} }
@@ -330,29 +330,43 @@ export async function getTraefikConfig(
wildCard = resource.fullDomain; wildCard = resource.fullDomain;
} }
const configDomain = config.getDomain(resource.domainId); const globalDefaultResolver =
config.getRawConfig().traefik.cert_resolver;
const globalDefaultPreferWildcard =
config.getRawConfig().traefik.prefer_wildcard_cert;
let certResolver: string, preferWildcardCert: boolean; const domainCertResolver = resource.domainCertResolver;
if (!configDomain) { const preferWildcardCert = resource.preferWildcardCert;
certResolver = config.getRawConfig().traefik.cert_resolver;
preferWildcardCert = let resolverName: string | undefined;
config.getRawConfig().traefik.prefer_wildcard_cert; let preferWildcard: boolean | undefined;
// Handle both letsencrypt & custom cases
if (domainCertResolver) {
resolverName = domainCertResolver.trim();
} else { } else {
certResolver = configDomain.cert_resolver; resolverName = globalDefaultResolver;
preferWildcardCert = configDomain.prefer_wildcard_cert; }
if (
preferWildcardCert !== undefined &&
preferWildcardCert !== null
) {
preferWildcard = preferWildcardCert;
} else {
preferWildcard = globalDefaultPreferWildcard;
} }
tls = { tls = {
certResolver: certResolver, certResolver: resolverName,
...(preferWildcardCert ...(preferWildcard
? { ? {
domains: [ domains: [
{ {
main: wildCard, main: wildCard
}, }
], ]
} }
: {}), : {})
}; };
} else { } else {
// find a cert that matches the full domain, if not continue // find a cert that matches the full domain, if not continue
@@ -604,14 +618,14 @@ export async function getTraefikConfig(
})(), })(),
...(resource.stickySession ...(resource.stickySession
? { ? {
sticky: { sticky: {
cookie: { cookie: {
name: "p_sticky", // TODO: make this configurable via config.yml like other cookies name: "p_sticky", // TODO: make this configurable via config.yml like other cookies
secure: resource.ssl, secure: resource.ssl,
httpOnly: true httpOnly: true
} }
} }
} }
: {}) : {})
} }
}; };
@@ -657,6 +671,8 @@ export async function getTraefikConfig(
...(protocol === "tcp" ? { rule: "HostSNI(`*`)" } : {}) ...(protocol === "tcp" ? { rule: "HostSNI(`*`)" } : {})
}; };
const ppPrefix = config.getRawConfig().traefik.pp_transport_prefix;
config_output[protocol].services[serviceName] = { config_output[protocol].services[serviceName] = {
loadBalancer: { loadBalancer: {
servers: (() => { servers: (() => {
@@ -712,18 +728,18 @@ export async function getTraefikConfig(
})(), })(),
...(resource.proxyProtocol && protocol == "tcp" // proxy protocol only works for tcp ...(resource.proxyProtocol && protocol == "tcp" // proxy protocol only works for tcp
? { ? {
serversTransport: `pp-transport-v${resource.proxyProtocolVersion || 1}` serversTransport: `${ppPrefix}${resource.proxyProtocolVersion || 1}@file` // TODO: does @file here cause issues?
} }
: {}), : {}),
...(resource.stickySession ...(resource.stickySession
? { ? {
sticky: { sticky: {
ipStrategy: { ipStrategy: {
depth: 0, depth: 0,
sourcePort: true sourcePort: true
} }
} }
} }
: {}) : {})
} }
}; };
@@ -771,9 +787,10 @@ export async function getTraefikConfig(
loadBalancer: { loadBalancer: {
servers: [ servers: [
{ {
url: `http://${config.getRawConfig().server url: `http://${
config.getRawConfig().server
.internal_hostname .internal_hostname
}:${config.getRawConfig().server.next_port}` }:${config.getRawConfig().server.next_port}`
} }
] ]
} }

View File

@@ -107,6 +107,26 @@ export default async function migration() {
await db.execute(sql`ALTER TABLE "resources" ADD CONSTRAINT "resources_skipToIdpId_idp_idpId_fk" FOREIGN KEY ("skipToIdpId") REFERENCES "public"."idp"("idpId") ON DELETE set null ON UPDATE no action;`); await db.execute(sql`ALTER TABLE "resources" ADD CONSTRAINT "resources_skipToIdpId_idp_idpId_fk" FOREIGN KEY ("skipToIdpId") REFERENCES "public"."idp"("idpId") ON DELETE set null ON UPDATE no action;`);
await db.execute(sql`ALTER TABLE "orgs" DROP COLUMN "settings";`); await db.execute(sql`ALTER TABLE "orgs" DROP COLUMN "settings";`);
// get all of the domains
const domainsQuery = await db.execute(sql`SELECT "domainId", "baseDomain" FROM "domains"`);
const domains = domainsQuery.rows as {
domainId: string;
baseDomain: string;
}[];
for (const domain of domains) {
// insert two records into the dnsRecords table for each domain
await db.execute(sql`
INSERT INTO "dnsRecords" ("domainId", "recordType", "baseDomain", "value", "verified")
VALUES (${domain.domainId}, 'A', ${`*.${domain.baseDomain}`}, ${'Server IP Address'}, true)
`);
await db.execute(sql`
INSERT INTO "dnsRecords" ("domainId", "recordType", "baseDomain", "value", "verified")
VALUES (${domain.domainId}, 'A', ${domain.baseDomain}, ${'Server IP Address'}, true)
`);
}
await db.execute(sql`COMMIT`); await db.execute(sql`COMMIT`);
console.log("Migrated database"); console.log("Migrated database");
} catch (e) { } catch (e) {

View File

@@ -15,7 +15,7 @@ export default async function migration() {
db.transaction(() => { db.transaction(() => {
db.prepare( db.prepare(
`UPDATE 'resourceRules' SET 'match' = 'COUNTRY' WHERE 'match' = 'GEOIP'` `UPDATE 'resourceRules' SET match = 'COUNTRY' WHERE match = 'GEOIP'`
).run(); ).run();
db.prepare( db.prepare(
@@ -195,6 +195,29 @@ export default async function migration() {
db.prepare( db.prepare(
`ALTER TABLE 'user' ADD 'lastPasswordChange' integer;` `ALTER TABLE 'user' ADD 'lastPasswordChange' integer;`
).run(); ).run();
// get all of the domains
const domains = db.prepare(`SELECT domainId, baseDomain from domains`).all() as {
domainId: number;
baseDomain: string;
}[];
for (const domain of domains) {
// insert two records into the dnsRecords table for each domain
const insert = db.prepare(
`INSERT INTO 'dnsRecords' (domainId, recordType, baseDomain, value, verified) VALUES (?, 'A', ?, ?, 1)`
);
insert.run(
domain.domainId,
`*.${domain.baseDomain}`,
`Server IP Address`
);
insert.run(
domain.domainId,
`${domain.baseDomain}`,
`Server IP Address`
);
}
})(); })();
db.pragma("foreign_keys = ON"); db.pragma("foreign_keys = ON");