From 048ce850a832aa9b242162bd739e7505e0fa0afe Mon Sep 17 00:00:00 2001 From: miloschwartz Date: Mon, 8 Dec 2025 21:12:19 -0500 Subject: [PATCH] get coutry using maxmind and clear stale device codes --- server/routers/auth/startDeviceWebAuth.ts | 24 +++++++++++------------ server/setup/clearStaleData.ts | 10 +++++++++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/server/routers/auth/startDeviceWebAuth.ts b/server/routers/auth/startDeviceWebAuth.ts index 925df67f..85fb5262 100644 --- a/server/routers/auth/startDeviceWebAuth.ts +++ b/server/routers/auth/startDeviceWebAuth.ts @@ -13,10 +13,12 @@ import { maxmindLookup } from "@server/db/maxmind"; import { encodeHexLowerCase } from "@oslojs/encoding"; import { sha256 } from "@oslojs/crypto/sha2"; -const bodySchema = z.object({ - deviceName: z.string().optional(), - applicationName: z.string().min(1, "Application name is required") -}).strict(); +const bodySchema = z + .object({ + deviceName: z.string().optional(), + applicationName: z.string().min(1, "Application name is required") + }) + .strict(); export type StartDeviceWebAuthBody = z.infer; @@ -34,14 +36,12 @@ function generateDeviceCode(): string { // Helper function to hash device code before storing in database function hashDeviceCode(code: string): string { - return encodeHexLowerCase( - sha256(new TextEncoder().encode(code)) - ); + return encodeHexLowerCase(sha256(new TextEncoder().encode(code))); } // Helper function to extract IP from request function extractIpFromRequest(req: Request): string | undefined { - const ip = req.ip || req.socket.remoteAddress; + const ip = req.ip; if (!ip) { return undefined; } @@ -75,10 +75,10 @@ async function getCityFromIp(ip: string): Promise { return undefined; } - // MaxMind CountryResponse doesn't include city by default - // If city data is available, it would be in result.city?.names?.en - // But since we're using CountryResponse type, we'll just return undefined - // The user said "don't do this if not easy", so we'll skip city for now + if (result.country) { + return result.country.names?.en || result.country.iso_code; + } + return undefined; } catch (error) { logger.debug("Failed to get city from IP", error); diff --git a/server/setup/clearStaleData.ts b/server/setup/clearStaleData.ts index 2e54656c..8c7e85f0 100644 --- a/server/setup/clearStaleData.ts +++ b/server/setup/clearStaleData.ts @@ -1,5 +1,5 @@ import { build } from "@server/build"; -import { db, sessionTransferToken } from "@server/db"; +import { db, deviceWebAuthCodes, sessionTransferToken } from "@server/db"; import { emailVerificationCodes, newtSessions, @@ -89,4 +89,12 @@ export async function clearStaleData() { logger.warn("Error clearing expired sessionTransferToken:", e); } } + + try { + await db + .delete(deviceWebAuthCodes) + .where(lt(deviceWebAuthCodes.expiresAt, new Date().getTime())); + } catch (e) { + logger.warn("Error clearing expired deviceWebAuthCodes:", e); + } }