Compare commits

..

7 Commits

Author SHA1 Message Date
dependabot[bot]
c51c18af74 Bump the prod-minor-updates group across 1 directory with 3 updates
Bumps the prod-minor-updates group with 3 updates in the / directory: [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3), [@simplewebauthn/browser](https://github.com/MasterKale/SimpleWebAuthn/tree/HEAD/packages/browser) and [@simplewebauthn/server](https://github.com/MasterKale/SimpleWebAuthn/tree/HEAD/packages/server).


Updates `@aws-sdk/client-s3` from 3.1004.0 to 3.1006.0
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1006.0/clients/client-s3)

Updates `@simplewebauthn/browser` from 13.2.2 to 13.3.0
- [Release notes](https://github.com/MasterKale/SimpleWebAuthn/releases)
- [Changelog](https://github.com/MasterKale/SimpleWebAuthn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/MasterKale/SimpleWebAuthn/commits/v13.3.0/packages/browser)

Updates `@simplewebauthn/server` from 13.2.3 to 13.3.0
- [Release notes](https://github.com/MasterKale/SimpleWebAuthn/releases)
- [Changelog](https://github.com/MasterKale/SimpleWebAuthn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/MasterKale/SimpleWebAuthn/commits/v13.3.0/packages/server)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-s3"
  dependency-version: 3.1006.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: "@simplewebauthn/browser"
  dependency-version: 13.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
- dependency-name: "@simplewebauthn/server"
  dependency-version: 13.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod-minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-17 01:37:18 +00:00
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
6 changed files with 599 additions and 597 deletions

1153
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,7 @@
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "8.4.1",
"@aws-sdk/client-s3": "3.1004.0",
"@aws-sdk/client-s3": "3.1010.0",
"@faker-js/faker": "10.3.0",
"@headlessui/react": "2.2.9",
"@hookform/resolvers": "5.2.2",
@@ -62,8 +62,8 @@
"@react-email/components": "1.0.8",
"@react-email/render": "2.0.4",
"@react-email/tailwind": "2.0.5",
"@simplewebauthn/browser": "13.2.2",
"@simplewebauthn/server": "13.2.3",
"@simplewebauthn/browser": "13.3.0",
"@simplewebauthn/server": "13.3.0",
"@tailwindcss/forms": "0.5.11",
"@tanstack/react-query": "5.90.21",
"@tanstack/react-table": "8.21.3",

View File

@@ -515,6 +515,6 @@ authenticated.post(
verifyOrgAccess,
verifyLimits,
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
);

View File

@@ -14,7 +14,9 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import {
actionAuditLog,
db,
logsDb,
newts,
roles,
roundTripMessageTracker,
@@ -34,6 +36,7 @@ import { canUserAccessSiteResource } from "@server/auth/canUserAccessSiteResourc
import { signPublicKey, getOrgCAKeys } from "@server/lib/sshCA";
import config from "@server/lib/config";
import { sendToClient } from "#private/routers/ws";
import { ActionsEnum } from "@server/auth/actions";
const paramsSchema = z.strictObject({
orgId: z.string().nonempty()
@@ -446,6 +449,20 @@ export async function signSshKey(
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, {
data: {
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)
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
let isRedisRecoveryInProgress = false;
@@ -855,12 +861,16 @@ const setupConnection = async (
const newtClient = client as Newt;
ws.on("ping", async () => {
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 {
await db
.update(sites)
.set({
online: true,
lastPing: Math.floor(Date.now() / 1000)
lastPing: now
})
.where(eq(sites.siteId, newtClient.siteId));
} catch (error) {

View File

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