Compare commits

...

8 Commits

Author SHA1 Message Date
Owen Schwartz
4ca5acf158 Merge pull request #2660 from fosrl/dev
Also update lastPing for legacy
2026-03-16 17:13:10 -07:00
Owen
ea41fcc566 Also update lastPing for legacy 2026-03-16 17:12:37 -07:00
Owen Schwartz
5736c1d8ce Merge pull request #2659 from fosrl/dev
Small improvements
2026-03-16 16:37:26 -07:00
Owen
d142366dd9 Merge branch 'main' into dev 2026-03-16 16:32:28 -07:00
Owen
bab09dff95 Add better metadata to ssh 2026-03-16 15:33:21 -07:00
Owen
23d3345ab9 Reduce writes 2026-03-16 14:37:27 -07:00
Owen Schwartz
09a64815d4 Merge pull request #2657 from fosrl/hotfix-jit
Fix jit on by default
2026-03-15 22:02:12 -07:00
Owen
6d5f969798 Fix jit on by default 2026-03-15 22:01:39 -07:00
5 changed files with 34 additions and 5 deletions

View File

@@ -515,6 +515,6 @@ authenticated.post(
verifyOrgAccess, verifyOrgAccess,
verifyLimits, verifyLimits,
verifyUserHasAction(ActionsEnum.signSshKey), verifyUserHasAction(ActionsEnum.signSshKey),
logActionAudit(ActionsEnum.signSshKey), // logActionAudit(ActionsEnum.signSshKey), // it is handled inside of the function below so we can include more metadata
ssh.signSshKey ssh.signSshKey
); );

View File

@@ -14,7 +14,9 @@
import { Request, Response, NextFunction } from "express"; import { Request, Response, NextFunction } from "express";
import { z } from "zod"; import { z } from "zod";
import { import {
actionAuditLog,
db, db,
logsDb,
newts, newts,
roles, roles,
roundTripMessageTracker, roundTripMessageTracker,
@@ -34,6 +36,7 @@ import { canUserAccessSiteResource } from "@server/auth/canUserAccessSiteResourc
import { signPublicKey, getOrgCAKeys } from "@server/lib/sshCA"; import { signPublicKey, getOrgCAKeys } from "@server/lib/sshCA";
import config from "@server/lib/config"; import config from "@server/lib/config";
import { sendToClient } from "#private/routers/ws"; import { sendToClient } from "#private/routers/ws";
import { ActionsEnum } from "@server/auth/actions";
const paramsSchema = z.strictObject({ const paramsSchema = z.strictObject({
orgId: z.string().nonempty() orgId: z.string().nonempty()
@@ -446,6 +449,20 @@ export async function signSshKey(
sshHost = resource.destination; sshHost = resource.destination;
} }
await logsDb.insert(actionAuditLog).values({
timestamp: Math.floor(Date.now() / 1000),
orgId: orgId,
actorType: "user",
actor: req.user?.username ?? "",
actorId: req.user?.userId ?? "",
action: ActionsEnum.signSshKey,
metadata: JSON.stringify({
resourceId: resource.siteResourceId,
resource: resource.name,
siteId: resource.siteId,
})
});
return response<SignSshKeyResponse>(res, { return response<SignSshKeyResponse>(res, {
data: { data: {
certificate: cert.certificate, certificate: cert.certificate,

View File

@@ -197,6 +197,12 @@ const connectedClients: Map<string, AuthenticatedWebSocket[]> = new Map();
// Config version tracking map (local to this node, resets on server restart) // Config version tracking map (local to this node, resets on server restart)
const clientConfigVersions: Map<string, number> = new Map(); const clientConfigVersions: Map<string, number> = new Map();
// Tracks the last Unix timestamp (seconds) at which a ping was flushed to the
// DB for a given siteId. Resets on server restart which is fine the first
// ping after startup will always write, re-establishing the online state.
const lastPingDbWrite: Map<number, number> = new Map();
const PING_DB_WRITE_INTERVAL = 45; // seconds
// Recovery tracking // Recovery tracking
let isRedisRecoveryInProgress = false; let isRedisRecoveryInProgress = false;
@@ -855,12 +861,16 @@ const setupConnection = async (
const newtClient = client as Newt; const newtClient = client as Newt;
ws.on("ping", async () => { ws.on("ping", async () => {
if (!newtClient.siteId) return; if (!newtClient.siteId) return;
const now = Math.floor(Date.now() / 1000);
const lastWrite = lastPingDbWrite.get(newtClient.siteId) ?? 0;
if (now - lastWrite < PING_DB_WRITE_INTERVAL) return;
lastPingDbWrite.set(newtClient.siteId, now);
try { try {
await db await db
.update(sites) .update(sites)
.set({ .set({
online: true, online: true,
lastPing: Math.floor(Date.now() / 1000) lastPing: now
}) })
.where(eq(sites.siteId, newtClient.siteId)); .where(eq(sites.siteId, newtClient.siteId));
} catch (error) { } catch (error) {

View File

@@ -97,6 +97,7 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
accumulator = new Map<string, AccumulatorEntry>(); accumulator = new Map<string, AccumulatorEntry>();
const currentTime = new Date().toISOString(); const currentTime = new Date().toISOString();
const currentTimeEpochSeconds = Math.floor(new Date().getTime() / 1000);
// Sort by publicKey for consistent lock ordering across concurrent // Sort by publicKey for consistent lock ordering across concurrent
// writers — deadlock-prevention strategy. // writers — deadlock-prevention strategy.
@@ -119,7 +120,8 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
.set({ .set({
megabytesOut: sql`COALESCE(${sites.megabytesOut}, 0) + ${bytesIn}`, megabytesOut: sql`COALESCE(${sites.megabytesOut}, 0) + ${bytesIn}`,
megabytesIn: sql`COALESCE(${sites.megabytesIn}, 0) + ${bytesOut}`, megabytesIn: sql`COALESCE(${sites.megabytesIn}, 0) + ${bytesOut}`,
lastBandwidthUpdate: currentTime lastBandwidthUpdate: currentTime,
lastPing: currentTimeEpochSeconds
}) })
.where(eq(sites.pubKey, publicKey)) .where(eq(sites.pubKey, publicKey))
.returning({ .returning({
@@ -321,4 +323,4 @@ export const receiveBandwidth = async (
) )
); );
} }
}; };

View File

@@ -227,7 +227,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
// Prepare an array to store site configurations // Prepare an array to store site configurations
logger.debug(`Found ${sitesCount} sites for client ${client.clientId}`); logger.debug(`Found ${sitesCount} sites for client ${client.clientId}`);
let jitMode = true; let jitMode = false;
if (sitesCount > 250 && build == "saas") { if (sitesCount > 250 && build == "saas") {
// THIS IS THE MAX ON THE BUSINESS TIER // THIS IS THE MAX ON THE BUSINESS TIER
// we have too many sites // we have too many sites