This commit is contained in:
Owen
2026-06-12 14:44:45 -07:00
parent 5a8a48f9bf
commit 3fd5c98def
3 changed files with 50 additions and 5 deletions

View File

@@ -71,7 +71,10 @@ export async function applyNewtDockerBlueprint(
let skippedKeys: string[] = []; let skippedKeys: string[] = [];
try { try {
const blueprint = processContainerLabels(containers); // Some Newt clients can report null/undefined containers when Docker
// labels are unavailable. Treat that as an empty blueprint payload.
const safeContainers = Array.isArray(containers) ? containers : [];
const blueprint = processContainerLabels(safeContainers);
logger.debug( logger.debug(
`Received Docker blueprint with ${Object.keys(blueprint["proxy-resources"]).length} proxy, ${Object.keys(blueprint["client-resources"]).length} client resource(s)` `Received Docker blueprint with ${Object.keys(blueprint["proxy-resources"]).length} proxy, ${Object.keys(blueprint["client-resources"]).length} client resource(s)`

View File

@@ -945,7 +945,45 @@ export async function updatePublicResources(
} }
} else { } else {
// INLINE POLICY MODE: sync rules into policy-level table // INLINE POLICY MODE: sync rules into policy-level table
const inlinePolicyId = resource!.defaultResourcePolicyId!; let inlinePolicyId = resource!.defaultResourcePolicyId;
// Targets-only updates skip the auth/policy update branch above,
// so pre-1.19 resources can still have no inline policy linked.
if (!inlinePolicyId) {
const [adminRole] = await trx
.select()
.from(roles)
.where(
and(eq(roles.isAdmin, true), eq(roles.orgId, orgId))
)
.limit(1);
if (!adminRole) {
throw new Error(`Admin role not found`);
}
inlinePolicyId = await ensureInlinePolicy(
existingResource.defaultResourcePolicyId,
orgId,
resourceNiceId,
adminRole.roleId,
trx
);
[resource] = await trx
.update(resources)
.set({
resourcePolicyId: null,
defaultResourcePolicyId: inlinePolicyId
})
.where(
eq(
resources.resourceId,
existingResource.resourceId
)
)
.returning();
}
// Clear the old resource-level rules table // Clear the old resource-level rules table
await trx await trx

View File

@@ -3,7 +3,7 @@ import { priv } from "@app/lib/api";
import { generateBrowserGatewayMetadata } from "@app/lib/browserGatewayMetadata"; import { generateBrowserGatewayMetadata } from "@app/lib/browserGatewayMetadata";
import { getBrowserTargetForRequest } from "@app/lib/getBrowserTargetForRequest"; import { getBrowserTargetForRequest } from "@app/lib/getBrowserTargetForRequest";
import { loadOrgLoginPageBranding } from "@app/lib/loadOrgLoginPageBranding"; import { loadOrgLoginPageBranding } from "@app/lib/loadOrgLoginPageBranding";
import { AxiosResponse } from "axios"; import axios, { AxiosResponse } from "axios";
import { GetBrowserTargetResponse } from "@server/routers/browserGatewayTarget"; import { GetBrowserTargetResponse } from "@server/routers/browserGatewayTarget";
import SshClient from "./SshClient"; import SshClient from "./SshClient";
import crypto from "crypto"; import crypto from "crypto";
@@ -152,8 +152,12 @@ export default async function SshPage() {
await waitForRoundTripCompletion(messageIds, cookieHeader); await waitForRoundTripCompletion(messageIds, cookieHeader);
} catch (err) { } catch (err) {
console.error("Error signing SSH key:", err); console.error("Error signing SSH key:", err);
const detail = err instanceof Error ? err.message : String(err); if (axios.isAxiosError(err) && err.response?.status === 403) {
error = `${t("sshErrorSignKeyFailed")}: ${detail}`; error = t("accessDeniedDescription");
} else {
const detail = err instanceof Error ? err.message : String(err);
error = `${t("sshErrorSignKeyFailed")}: ${detail}`;
}
} }
} }