Fix Invalid Date error in auth middleware
All checks were successful
Deploy / deploy (push) Successful in 2m28s

Add parseDate helper that safely returns null for empty/invalid date
strings from PocketBase. This prevents RangeError when pino logger
tries to serialize Invalid Date objects via toISOString().

- Make garminTokenExpiresAt and lastPeriodDate nullable in User type
- Filter garmin-sync cron to skip users without required dates
- Add test assertions for null date handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-12 14:13:02 +00:00
parent 63023550fd
commit 72706bb91b
5 changed files with 60 additions and 9 deletions

View File

@@ -127,6 +127,41 @@ describe("getCurrentUser", () => {
expect(user).not.toBeNull();
expect(user?.activeOverrides).toEqual([]);
// Empty string dates should be parsed as null
expect(user?.garminTokenExpiresAt).toBeNull();
});
it("returns null for invalid date strings", () => {
const mockRecord = {
id: "user789",
email: "invalid@test.com",
garminConnected: false,
garminOauth1Token: "",
garminOauth2Token: "",
garminTokenExpiresAt: "not-a-date",
calendarToken: "token",
lastPeriodDate: "",
cycleLength: 28,
notificationTime: "09:00",
timezone: "UTC",
activeOverrides: [],
created: "2024-01-01T00:00:00Z",
updated: "2024-01-01T00:00:00Z",
};
const mockPb = {
authStore: {
isValid: true,
model: mockRecord,
},
};
// biome-ignore lint/suspicious/noExplicitAny: test mock
const user = getCurrentUser(mockPb as any);
expect(user).not.toBeNull();
expect(user?.garminTokenExpiresAt).toBeNull();
expect(user?.lastPeriodDate).toBeNull();
});
});

View File

@@ -73,6 +73,15 @@ export function loadAuthFromCookies(
}
}
/**
* Safely parses a date string, returning null for invalid or empty values.
*/
function parseDate(value: unknown): Date | null {
if (!value || typeof value !== "string") return null;
const date = new Date(value);
return Number.isNaN(date.getTime()) ? null : date;
}
/**
* Maps a PocketBase record to our typed User interface.
*/
@@ -83,9 +92,9 @@ function mapRecordToUser(record: RecordModel): User {
garminConnected: record.garminConnected as boolean,
garminOauth1Token: record.garminOauth1Token as string,
garminOauth2Token: record.garminOauth2Token as string,
garminTokenExpiresAt: new Date(record.garminTokenExpiresAt as string),
garminTokenExpiresAt: parseDate(record.garminTokenExpiresAt),
calendarToken: record.calendarToken as string,
lastPeriodDate: new Date(record.lastPeriodDate as string),
lastPeriodDate: parseDate(record.lastPeriodDate),
cycleLength: record.cycleLength as number,
notificationTime: record.notificationTime as string,
timezone: record.timezone as string,