mirror of
https://github.com/fosrl/pangolin.git
synced 2026-10-29 15:09:07 +01:00
Add olm agentVersion to separate the library from the agent
This commit is contained in:
@@ -1488,6 +1488,7 @@ export const olms = pgTable(
|
||||
dateCreated: varchar("dateCreated").notNull(),
|
||||
version: text("version"),
|
||||
agent: text("agent"),
|
||||
agentVersion: text("agentVersion"),
|
||||
name: varchar("name"),
|
||||
clientId: integer("clientId").references(() => clients.clientId, {
|
||||
// we will switch this depending on the current org it wants to connect to
|
||||
|
||||
@@ -843,6 +843,7 @@ export const olms = sqliteTable(
|
||||
dateCreated: text("dateCreated").notNull(),
|
||||
version: text("version"),
|
||||
agent: text("agent"),
|
||||
agentVersion: text("agentVersion"),
|
||||
name: text("name"),
|
||||
clientId: integer("clientId").references(() => clients.clientId, {
|
||||
// we will switch this depending on the current org it wants to connect to
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import semver from "semver";
|
||||
|
||||
// NEWT AND OLM
|
||||
// Pass the newt/olm library version (newts.version / olms.version), not
|
||||
// agentVersion: the agent may be an app embedding the library (the CLI,
|
||||
// Pangolin Windows, ...) whose version is unrelated to the protocol support.
|
||||
export function canCompress(
|
||||
clientVersion: string | null | undefined,
|
||||
type: "newt" | "olm"
|
||||
agent: "newt" | "olm"
|
||||
): boolean {
|
||||
try {
|
||||
if (!clientVersion) return false;
|
||||
// check if it is a valid semver
|
||||
if (!semver.valid(clientVersion)) return false;
|
||||
if (type === "newt") {
|
||||
if (agent === "newt") {
|
||||
return semver.gte(clientVersion, "1.10.3");
|
||||
} else if (type === "olm") {
|
||||
} else if (agent === "olm") {
|
||||
return semver.gte(clientVersion, "1.4.3");
|
||||
}
|
||||
return false;
|
||||
@@ -23,6 +27,7 @@ export function canCompress(
|
||||
// sync message's `certs` array, instead of requiring each target to carry
|
||||
// its own inline `tlsCert`/`tlsKey` PEM data. Bump the version floor here to
|
||||
// match whatever release first ships the newt-side support.
|
||||
// NEWT
|
||||
export function supportsCertReferences(
|
||||
clientVersion: string | null | undefined
|
||||
): boolean {
|
||||
@@ -38,6 +43,7 @@ export function supportsCertReferences(
|
||||
// Whether this newt client understands newt/wg/client-identities/add, used to
|
||||
// set Remote-* headers on requests through its HTTP proxy. Bump the version
|
||||
// floor here to match whatever release first ships the newt-side support.
|
||||
// NEWT
|
||||
export function supportsClientIdentities(
|
||||
clientVersion: string | null | undefined
|
||||
): boolean {
|
||||
@@ -49,3 +55,33 @@ export function supportsClientIdentities(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Whether this newt client understands the v2 subnet proxy target format.
|
||||
// Older clients need targets converted back to v1 before they are sent.
|
||||
// NEWT
|
||||
export function supportsTargetsV2(
|
||||
clientVersion: string | null | undefined
|
||||
): boolean {
|
||||
try {
|
||||
if (!clientVersion) return false;
|
||||
if (!semver.valid(clientVersion)) return false;
|
||||
return semver.gte(clientVersion, "1.10.3");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Whether this newt client understands the sync message sent when its config
|
||||
// version falls behind the server's.
|
||||
// NEWT
|
||||
export function supportsSync(
|
||||
clientVersion: string | null | undefined
|
||||
): boolean {
|
||||
try {
|
||||
if (!clientVersion) return false;
|
||||
if (!semver.valid(clientVersion)) return false;
|
||||
return semver.gte(clientVersion, "1.14.0");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +228,7 @@ export type GetClientResponse = NonNullable<
|
||||
olmId: string | null;
|
||||
agent: string | null;
|
||||
olmVersion: string | null;
|
||||
agentVersion: string | null;
|
||||
userEmail: string | null;
|
||||
userName: string | null;
|
||||
userUsername: string | null;
|
||||
@@ -421,6 +422,7 @@ export async function getClient(
|
||||
olmId: client.olms ? client.olms.olmId : null,
|
||||
agent: client.olms?.agent || null,
|
||||
olmVersion: client.olms?.version || null,
|
||||
agentVersion: client.olms?.agentVersion || null,
|
||||
userEmail: client.user?.email ?? null,
|
||||
userName: client.user?.name ?? null,
|
||||
userUsername: client.user?.username ?? null,
|
||||
|
||||
@@ -187,6 +187,7 @@ function queryClientsBase() {
|
||||
userEmail: users.email,
|
||||
niceId: clients.niceId,
|
||||
agent: olms.agent,
|
||||
agentVersion: olms.agentVersion,
|
||||
approvalState: clients.approvalState,
|
||||
olmArchived: olms.archived,
|
||||
archived: clients.archived,
|
||||
|
||||
@@ -172,6 +172,7 @@ function queryUserDevicesBase() {
|
||||
idpVariant: idpOidcConfig.variant,
|
||||
niceId: clients.niceId,
|
||||
agent: olms.agent,
|
||||
agentVersion: olms.agentVersion,
|
||||
approvalState: clients.approvalState,
|
||||
olmArchived: olms.archived,
|
||||
archived: clients.archived,
|
||||
|
||||
@@ -6,12 +6,12 @@ import {
|
||||
SubnetProxyTarget,
|
||||
SubnetProxyTargetV2
|
||||
} from "@server/lib/ip";
|
||||
import { canCompress } from "@server/lib/clientVersionChecks";
|
||||
import {
|
||||
canCompress,
|
||||
supportsTargetsV2
|
||||
} from "@server/lib/clientVersionChecks";
|
||||
import logger from "@server/logger";
|
||||
import { eq, inArray } from "drizzle-orm";
|
||||
import semver from "semver";
|
||||
|
||||
const NEWT_V2_TARGETS_VERSION = ">=1.10.3";
|
||||
|
||||
export async function convertTargetsIfNecessary(
|
||||
newtId: string,
|
||||
@@ -27,10 +27,7 @@ export async function convertTargetsIfNecessary(
|
||||
}
|
||||
|
||||
// check the semver
|
||||
if (
|
||||
newt.version &&
|
||||
!semver.satisfies(newt.version, NEWT_V2_TARGETS_VERSION)
|
||||
) {
|
||||
if (newt.version && !supportsTargetsV2(newt.version)) {
|
||||
logger.debug(
|
||||
`addTargets Newt version ${newt.version} does not support targets v2 falling back`
|
||||
);
|
||||
@@ -167,10 +164,7 @@ export async function updateTargets(
|
||||
}
|
||||
|
||||
// check the semver
|
||||
if (
|
||||
newt.version &&
|
||||
!semver.satisfies(newt.version, NEWT_V2_TARGETS_VERSION)
|
||||
) {
|
||||
if (newt.version && !supportsTargetsV2(newt.version)) {
|
||||
logger.debug(
|
||||
`addTargets Newt version ${newt.version} does not support targets v2 falling back`
|
||||
);
|
||||
|
||||
@@ -5,10 +5,9 @@ import { Newt } from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import logger from "@server/logger";
|
||||
import { sendNewtSyncMessage } from "./sync";
|
||||
import semver from "semver";
|
||||
import { recordSitePing } from "./pingAccumulator";
|
||||
import { supportsSync } from "@server/lib/clientVersionChecks";
|
||||
|
||||
const NEWT_SUPPORTS_SYNC_VERSION = ">=1.14.0";
|
||||
const PONG = {
|
||||
message: {
|
||||
type: "pong",
|
||||
@@ -50,10 +49,7 @@ export const handleNewtPingMessage: MessageHandler = async (context) => {
|
||||
// cross-region latency to the database.
|
||||
recordSitePing(newt.siteId);
|
||||
|
||||
if (
|
||||
newt.version &&
|
||||
!semver.satisfies(newt.version, NEWT_SUPPORTS_SYNC_VERSION)
|
||||
) {
|
||||
if (newt.version && !supportsSync(newt.version)) {
|
||||
// Newt does not support the sync message so not checking - stop here -
|
||||
return PONG;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
||||
relay,
|
||||
olmVersion,
|
||||
olmAgent,
|
||||
agentVersion,
|
||||
orgId,
|
||||
userToken,
|
||||
pingResults,
|
||||
@@ -92,9 +93,17 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
||||
await handleFingerprintInsertion(olm, fingerprint, postures);
|
||||
}
|
||||
|
||||
// Olm clients that predate agentVersion report the version of the app
|
||||
// embedding olm (Pangolin Windows, the CLI, ...) in olmVersion, so it
|
||||
// doubles as the agent version. Newer clients report the olm library
|
||||
// version in olmVersion and the app version in agentVersion.
|
||||
const reportedAgentVersion =
|
||||
agentVersion === undefined ? olmVersion : agentVersion;
|
||||
|
||||
if (
|
||||
(olmVersion && olm.version !== olmVersion) ||
|
||||
(olmAgent && olm.agent !== olmAgent) ||
|
||||
(reportedAgentVersion && olm.agentVersion !== reportedAgentVersion) ||
|
||||
olm.archived
|
||||
) {
|
||||
await db
|
||||
@@ -102,6 +111,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
||||
.set({
|
||||
version: olmVersion,
|
||||
agent: olmAgent,
|
||||
agentVersion: reportedAgentVersion,
|
||||
archived: false
|
||||
})
|
||||
.where(eq(olms.olmId, olm.olmId));
|
||||
|
||||
Reference in New Issue
Block a user