mirror of
https://github.com/fosrl/pangolin.git
synced 2026-04-13 05:16:37 +00:00
CRUD and newt mode http mostly working
This commit is contained in:
@@ -2436,6 +2436,7 @@
|
|||||||
"validPassword": "Valid Password",
|
"validPassword": "Valid Password",
|
||||||
"validEmail": "Valid email",
|
"validEmail": "Valid email",
|
||||||
"validSSO": "Valid SSO",
|
"validSSO": "Valid SSO",
|
||||||
|
"connectedClient": "Connected Client",
|
||||||
"resourceBlocked": "Resource Blocked",
|
"resourceBlocked": "Resource Blocked",
|
||||||
"droppedByRule": "Dropped by Rule",
|
"droppedByRule": "Dropped by Rule",
|
||||||
"noSessions": "No Sessions",
|
"noSessions": "No Sessions",
|
||||||
|
|||||||
@@ -662,10 +662,10 @@ export async function generateSubnetProxyTargetV2(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!siteResource.alias ||
|
|
||||||
!siteResource.aliasAddress ||
|
!siteResource.aliasAddress ||
|
||||||
!siteResource.destinationPort ||
|
!siteResource.destinationPort ||
|
||||||
!siteResource.scheme
|
!siteResource.scheme ||
|
||||||
|
!siteResource.fullDomain
|
||||||
) {
|
) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Site resource ${siteResource.siteResourceId} is in HTTP mode but is missing alias or alias address or destinationPort or scheme, skipping alias target generation.`
|
`Site resource ${siteResource.siteResourceId} is in HTTP mode but is missing alias or alias address or destinationPort or scheme, skipping alias target generation.`
|
||||||
@@ -676,10 +676,10 @@ export async function generateSubnetProxyTargetV2(
|
|||||||
let tlsCert: string | undefined;
|
let tlsCert: string | undefined;
|
||||||
let tlsKey: string | undefined;
|
let tlsKey: string | undefined;
|
||||||
|
|
||||||
if (siteResource.ssl && siteResource.alias) {
|
if (siteResource.ssl && siteResource.fullDomain) {
|
||||||
try {
|
try {
|
||||||
const certs = await getValidCertificatesForDomains(
|
const certs = await getValidCertificatesForDomains(
|
||||||
new Set([siteResource.alias]),
|
new Set([siteResource.fullDomain]),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (certs.length > 0 && certs[0].certFile && certs[0].keyFile) {
|
if (certs.length > 0 && certs[0].certFile && certs[0].keyFile) {
|
||||||
@@ -687,12 +687,12 @@ export async function generateSubnetProxyTargetV2(
|
|||||||
tlsKey = certs[0].keyFile;
|
tlsKey = certs[0].keyFile;
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`No valid certificate found for SSL site resource ${siteResource.siteResourceId} with domain ${siteResource.alias}`
|
`No valid certificate found for SSL site resource ${siteResource.siteResourceId} with domain ${siteResource.fullDomain}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Failed to retrieve certificate for site resource ${siteResource.siteResourceId} domain ${siteResource.alias}: ${err}`
|
`Failed to retrieve certificate for site resource ${siteResource.siteResourceId} domain ${siteResource.fullDomain}: ${err}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export const handleRequestLogMessage: MessageHandler = async (context) => {
|
|||||||
await logRequestAudit(
|
await logRequestAudit(
|
||||||
{
|
{
|
||||||
action: true,
|
action: true,
|
||||||
reason: 100,
|
reason: 108,
|
||||||
resourceId: entry.resourceId,
|
resourceId: entry.resourceId,
|
||||||
orgId
|
orgId
|
||||||
},
|
},
|
||||||
@@ -163,4 +163,4 @@ export const handleRequestLogMessage: MessageHandler = async (context) => {
|
|||||||
logger.debug(
|
logger.debug(
|
||||||
`Buffered ${entries.length} request log entry/entries from newt ${newt.newtId} (site ${newt.siteId})`
|
`Buffered ${entries.length} request log entry/entries from newt ${newt.newtId} (site ${newt.siteId})`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Reasons:
|
|||||||
105 - Valid Password
|
105 - Valid Password
|
||||||
106 - Valid email
|
106 - Valid email
|
||||||
107 - Valid SSO
|
107 - Valid SSO
|
||||||
|
108 - Connected Client
|
||||||
|
|
||||||
201 - Resource Not Found
|
201 - Resource Not Found
|
||||||
202 - Resource Blocked
|
202 - Resource Blocked
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export const handleGetConfigMessage: MessageHandler = async (context) => {
|
|||||||
|
|
||||||
if (existingSite.lastHolePunch && now - existingSite.lastHolePunch > 5) {
|
if (existingSite.lastHolePunch && now - existingSite.lastHolePunch > 5) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`Site last hole punch is too old; skipping this register. The site is failing to hole punch and identify its network address with the server. Can the client reach the server on UDP port ${config.getRawConfig().gerbil.clients_start_port}?`
|
`Site last hole punch is too old; skipping this register. The site is failing to hole punch and identify its network address with the server. Can the site reach the server on UDP port ${config.getRawConfig().gerbil.clients_start_port}?`
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ export async function createSiteResource(
|
|||||||
|
|
||||||
let fullDomain: string | null = null;
|
let fullDomain: string | null = null;
|
||||||
let finalSubdomain: string | null = null;
|
let finalSubdomain: string | null = null;
|
||||||
if (domainId && subdomain) {
|
if (domainId) {
|
||||||
// Validate domain and construct full domain
|
// Validate domain and construct full domain
|
||||||
const domainResult = await validateAndConstructDomain(
|
const domainResult = await validateAndConstructDomain(
|
||||||
domainId,
|
domainId,
|
||||||
|
|||||||
@@ -80,18 +80,15 @@ const updateSiteResourceSchema = z
|
|||||||
.strict()
|
.strict()
|
||||||
.refine(
|
.refine(
|
||||||
(data) => {
|
(data) => {
|
||||||
if (
|
if (data.mode === "host" && data.destination) {
|
||||||
data.mode === "host" &&
|
const isValidIP = z
|
||||||
data.destination
|
// .union([z.ipv4(), z.ipv6()])
|
||||||
) {
|
.union([z.ipv4()]) // for now lets just do ipv4 until we verify ipv6 works everywhere
|
||||||
const isValidIP = z
|
.safeParse(data.destination).success;
|
||||||
// .union([z.ipv4(), z.ipv6()])
|
|
||||||
.union([z.ipv4()]) // for now lets just do ipv4 until we verify ipv6 works everywhere
|
|
||||||
.safeParse(data.destination).success;
|
|
||||||
|
|
||||||
if (isValidIP) {
|
if (isValidIP) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it's a valid domain (hostname pattern, TLD not required)
|
// Check if it's a valid domain (hostname pattern, TLD not required)
|
||||||
const domainRegex =
|
const domainRegex =
|
||||||
@@ -306,7 +303,7 @@ export async function updateSiteResource(
|
|||||||
|
|
||||||
let fullDomain: string | null = null;
|
let fullDomain: string | null = null;
|
||||||
let finalSubdomain: string | null = null;
|
let finalSubdomain: string | null = null;
|
||||||
if (domainId && subdomain) {
|
if (domainId) {
|
||||||
// Validate domain and construct full domain
|
// Validate domain and construct full domain
|
||||||
const domainResult = await validateAndConstructDomain(
|
const domainResult = await validateAndConstructDomain(
|
||||||
domainId,
|
domainId,
|
||||||
@@ -324,12 +321,16 @@ export async function updateSiteResource(
|
|||||||
finalSubdomain = domainResult.subdomain;
|
finalSubdomain = domainResult.subdomain;
|
||||||
|
|
||||||
// make sure the full domain is unique
|
// make sure the full domain is unique
|
||||||
const existingResource = await db
|
const [existingDomain] = await db
|
||||||
.select()
|
.select()
|
||||||
.from(siteResources)
|
.from(siteResources)
|
||||||
.where(eq(siteResources.fullDomain, fullDomain));
|
.where(eq(siteResources.fullDomain, fullDomain));
|
||||||
|
|
||||||
if (existingResource.length > 0) {
|
if (
|
||||||
|
existingDomain &&
|
||||||
|
existingDomain.siteResourceId !==
|
||||||
|
existingSiteResource.siteResourceId
|
||||||
|
) {
|
||||||
return next(
|
return next(
|
||||||
createHttpError(
|
createHttpError(
|
||||||
HttpCode.CONFLICT,
|
HttpCode.CONFLICT,
|
||||||
@@ -666,9 +667,14 @@ export async function handleMessagingForUpdatedSiteResource(
|
|||||||
const destinationChanged =
|
const destinationChanged =
|
||||||
existingSiteResource &&
|
existingSiteResource &&
|
||||||
existingSiteResource.destination !== updatedSiteResource.destination;
|
existingSiteResource.destination !== updatedSiteResource.destination;
|
||||||
|
const destinationPortChanged =
|
||||||
|
existingSiteResource &&
|
||||||
|
existingSiteResource.destinationPort !==
|
||||||
|
updatedSiteResource.destinationPort;
|
||||||
const aliasChanged =
|
const aliasChanged =
|
||||||
existingSiteResource &&
|
existingSiteResource &&
|
||||||
existingSiteResource.alias !== updatedSiteResource.alias;
|
(existingSiteResource.alias !== updatedSiteResource.alias ||
|
||||||
|
existingSiteResource.fullDomain !== updatedSiteResource.fullDomain); // because the full domain gets sent down to the stuff as an alias
|
||||||
const portRangesChanged =
|
const portRangesChanged =
|
||||||
existingSiteResource &&
|
existingSiteResource &&
|
||||||
(existingSiteResource.tcpPortRangeString !==
|
(existingSiteResource.tcpPortRangeString !==
|
||||||
@@ -680,7 +686,7 @@ export async function handleMessagingForUpdatedSiteResource(
|
|||||||
|
|
||||||
// if the existingSiteResource is undefined (new resource) we don't need to do anything here, the rebuild above handled it all
|
// if the existingSiteResource is undefined (new resource) we don't need to do anything here, the rebuild above handled it all
|
||||||
|
|
||||||
if (destinationChanged || aliasChanged || portRangesChanged) {
|
if (destinationChanged || aliasChanged || portRangesChanged || destinationPortChanged) {
|
||||||
const [newt] = await trx
|
const [newt] = await trx
|
||||||
.select()
|
.select()
|
||||||
.from(newts)
|
.from(newts)
|
||||||
@@ -694,7 +700,7 @@ export async function handleMessagingForUpdatedSiteResource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only update targets on newt if destination changed
|
// Only update targets on newt if destination changed
|
||||||
if (destinationChanged || portRangesChanged) {
|
if (destinationChanged || portRangesChanged || destinationPortChanged) {
|
||||||
const oldTarget = await generateSubnetProxyTargetV2(
|
const oldTarget = await generateSubnetProxyTargetV2(
|
||||||
existingSiteResource,
|
existingSiteResource,
|
||||||
mergedAllClients
|
mergedAllClients
|
||||||
|
|||||||
@@ -360,6 +360,7 @@ export default function GeneralPage() {
|
|||||||
// 105 - Valid Password
|
// 105 - Valid Password
|
||||||
// 106 - Valid email
|
// 106 - Valid email
|
||||||
// 107 - Valid SSO
|
// 107 - Valid SSO
|
||||||
|
// 108 - Connected Client
|
||||||
|
|
||||||
// 201 - Resource Not Found
|
// 201 - Resource Not Found
|
||||||
// 202 - Resource Blocked
|
// 202 - Resource Blocked
|
||||||
@@ -377,6 +378,7 @@ export default function GeneralPage() {
|
|||||||
105: t("validPassword"),
|
105: t("validPassword"),
|
||||||
106: t("validEmail"),
|
106: t("validEmail"),
|
||||||
107: t("validSSO"),
|
107: t("validSSO"),
|
||||||
|
108: t("connectedClient"),
|
||||||
201: t("resourceNotFound"),
|
201: t("resourceNotFound"),
|
||||||
202: t("resourceBlocked"),
|
202: t("resourceBlocked"),
|
||||||
203: t("droppedByRule"),
|
203: t("droppedByRule"),
|
||||||
@@ -634,6 +636,7 @@ export default function GeneralPage() {
|
|||||||
{ value: "105", label: t("validPassword") },
|
{ value: "105", label: t("validPassword") },
|
||||||
{ value: "106", label: t("validEmail") },
|
{ value: "106", label: t("validEmail") },
|
||||||
{ value: "107", label: t("validSSO") },
|
{ value: "107", label: t("validSSO") },
|
||||||
|
{ value: "108", label: t("connectedClient") },
|
||||||
{ value: "201", label: t("resourceNotFound") },
|
{ value: "201", label: t("resourceNotFound") },
|
||||||
{ value: "202", label: t("resourceBlocked") },
|
{ value: "202", label: t("resourceBlocked") },
|
||||||
{ value: "203", label: t("droppedByRule") },
|
{ value: "203", label: t("droppedByRule") },
|
||||||
|
|||||||
Reference in New Issue
Block a user