From cde96900a2309c33c78ceca6b61ebffff8b81724 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 12:48:00 +0000 Subject: [PATCH] fix: Ensure ping can handle pings larger than 24 days by changing INT to BIGINT and FLOAT(8,2) to FLOAT(20,2) (#6668) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: louislam <1336778+louislam@users.noreply.github.com> Co-authored-by: CommanderStorm <26258709+CommanderStorm@users.noreply.github.com> --- ...2026-01-10-0000-convert-float-precision.js | 43 +++++++++++++++++++ server/routers/api-router.js | 7 +++ 2 files changed, 50 insertions(+) create mode 100644 db/knex_migrations/2026-01-10-0000-convert-float-precision.js diff --git a/db/knex_migrations/2026-01-10-0000-convert-float-precision.js b/db/knex_migrations/2026-01-10-0000-convert-float-precision.js new file mode 100644 index 000000000..084bf10a7 --- /dev/null +++ b/db/knex_migrations/2026-01-10-0000-convert-float-precision.js @@ -0,0 +1,43 @@ +exports.up = function (knex) { + return knex.schema + .alterTable("heartbeat", function (table) { + table.bigInteger("ping").alter(); + }) + .alterTable("stat_minutely", function (table) { + table.float("ping", 20, 2).notNullable().alter(); + table.float("ping_min", 20, 2).notNullable().defaultTo(0).alter(); + table.float("ping_max", 20, 2).notNullable().defaultTo(0).alter(); + }) + .alterTable("stat_daily", function (table) { + table.float("ping", 20, 2).notNullable().alter(); + table.float("ping_min", 20, 2).notNullable().defaultTo(0).alter(); + table.float("ping_max", 20, 2).notNullable().defaultTo(0).alter(); + }) + .alterTable("stat_hourly", function (table) { + table.float("ping", 20, 2).notNullable().alter(); + table.float("ping_min", 20, 2).notNullable().defaultTo(0).alter(); + table.float("ping_max", 20, 2).notNullable().defaultTo(0).alter(); + }); +}; + +exports.down = function (knex) { + return knex.schema + .alterTable("heartbeat", function (table) { + table.integer("ping").alter(); + }) + .alterTable("stat_minutely", function (table) { + table.float("ping").notNullable().alter(); + table.float("ping_min").notNullable().defaultTo(0).alter(); + table.float("ping_max").notNullable().defaultTo(0).alter(); + }) + .alterTable("stat_daily", function (table) { + table.float("ping").notNullable().alter(); + table.float("ping_min").notNullable().defaultTo(0).alter(); + table.float("ping_max").notNullable().defaultTo(0).alter(); + }) + .alterTable("stat_hourly", function (table) { + table.float("ping").notNullable().alter(); + table.float("ping_min").notNullable().defaultTo(0).alter(); + table.float("ping_max").notNullable().defaultTo(0).alter(); + }); +}; diff --git a/server/routers/api-router.js b/server/routers/api-router.js index 8f6d09248..05c953756 100644 --- a/server/routers/api-router.js +++ b/server/routers/api-router.js @@ -52,6 +52,13 @@ router.all("/api/push/:pushToken", async (request, response) => { let statusString = request.query.status || "up"; const statusFromParam = statusString === "up" ? UP : DOWN; + // Validate ping value - max 100 billion ms (~3.17 years) + // Fits safely in both BIGINT and FLOAT(20,2) + const MAX_PING_MS = 100000000000; + if (ping !== null && (ping < 0 || ping > MAX_PING_MS)) { + throw new Error(`Invalid ping value. Must be between 0 and ${MAX_PING_MS} ms.`); + } + let monitor = await R.findOne("monitor", " push_token = ? AND active = 1 ", [pushToken]); if (!monitor) {