diff --git a/packages/web/server/lib/quota/utils/formatters.js b/packages/web/server/lib/quota/utils/formatters.js index 4e353b15..a5326394 100644 --- a/packages/web/server/lib/quota/utils/formatters.js +++ b/packages/web/server/lib/quota/utils/formatters.js @@ -1,6 +1,10 @@ export const formatResetTime = (timestamp) => { try { const resetDate = new Date(timestamp); + if (!Number.isFinite(resetDate.getTime())) { + return null; + } + const now = new Date(); const isToday = resetDate.toDateString() === now.toDateString(); @@ -25,7 +29,9 @@ export const formatResetTime = (timestamp) => { export const calculateResetAfterSeconds = (resetAt) => { if (!resetAt) return null; - const delta = Math.floor((resetAt - Date.now()) / 1000); + const resetAtTime = new Date(resetAt).getTime(); + if (!Number.isFinite(resetAtTime)) return null; + const delta = Math.floor((resetAtTime - Date.now()) / 1000); return delta < 0 ? 0 : delta; }; diff --git a/packages/web/server/lib/quota/utils/formatters.test.js b/packages/web/server/lib/quota/utils/formatters.test.js new file mode 100644 index 00000000..9965d383 --- /dev/null +++ b/packages/web/server/lib/quota/utils/formatters.test.js @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'vitest'; + +import { calculateResetAfterSeconds, formatResetTime } from './formatters.js'; + +describe('formatResetTime', () => { + it('returns null for invalid timestamps', () => { + expect(formatResetTime('not-a-date')).toBeNull(); + expect(formatResetTime(NaN)).toBeNull(); + expect(formatResetTime(Infinity)).toBeNull(); + expect(formatResetTime(-Infinity)).toBeNull(); + }); +}); + +describe('calculateResetAfterSeconds', () => { + it('returns null for invalid timestamps', () => { + expect(calculateResetAfterSeconds('not-a-date')).toBeNull(); + expect(calculateResetAfterSeconds(NaN)).toBeNull(); + expect(calculateResetAfterSeconds(Infinity)).toBeNull(); + expect(calculateResetAfterSeconds(-Infinity)).toBeNull(); + }); +});