diff --git a/src/server/utils/WireGuard.ts b/src/server/utils/WireGuard.ts index 048d866d..991d7893 100644 --- a/src/server/utils/WireGuard.ts +++ b/src/server/utils/WireGuard.ts @@ -1,6 +1,8 @@ import fs from 'node:fs/promises'; import debug from 'debug'; import { encodeQR } from 'qr'; +import { getCurrentPublicIpv4 } from './ip'; +import { WG_AUTO_REFRESH_ENV } from './config'; import type { InterfaceType } from '#db/repositories/interface/types'; const WG_DEBUG = debug('WireGuard'); @@ -9,6 +11,8 @@ const generateRandomHeaderValue = () => Math.floor(Math.random() * 2147483642) + 5; class WireGuard { + private lastIpCheck = 0; + /** * Save and sync config */ @@ -306,6 +310,41 @@ class WireGuard { if (needsSave) { await this.saveConfig(); } + + // Auto-refresh IP Feature + if (WG_AUTO_REFRESH_ENV.ENABLED) { + await this.checkAndUpdatePublicIp(); + } + } + + private async checkAndUpdatePublicIp() { + const now = Date.now(); + + // Only check at configured interval (default 5m) + if (now - this.lastIpCheck < WG_AUTO_REFRESH_ENV.INTERVAL) { + return; + } + this.lastIpCheck = now; + + try { + const currentIp = await getCurrentPublicIpv4(); + if (!currentIp) { + WG_DEBUG('Auto-refresh: Could not detect public IP'); + return; + } + + const userConfig = await Database.userConfigs.get(); + if (userConfig.host !== currentIp) { + WG_DEBUG( + `Auto-refresh: IP changed from ${userConfig.host} to ${currentIp}` + ); + await Database.userConfigs.updateHostPort(currentIp, userConfig.port); + WG_DEBUG('Auto-refresh: Database updated with new IP'); + } + } catch (err) { + WG_DEBUG('Auto-refresh: Failed to check/update IP'); + console.error(err); + } } } diff --git a/src/server/utils/config.ts b/src/server/utils/config.ts index 322b7ae6..62973137 100644 --- a/src/server/utils/config.ts +++ b/src/server/utils/config.ts @@ -54,6 +54,15 @@ export const WG_INITIAL_ENV = { : undefined, }; +export const WG_AUTO_REFRESH_ENV = { + /** Enable automatic IP refresh when host was set to auto-detected IP */ + ENABLED: process.env.SERVERURL_AUTO_REFRESH === 'true', + /** Interval in milliseconds between IP checks (default: 300000 = 5 minutes) */ + INTERVAL: process.env.SERVERURL_AUTO_REFRESH_INTERVAL + ? Number.parseInt(process.env.SERVERURL_AUTO_REFRESH_INTERVAL, 10) * 1000 + : 300 * 1000, +}; + function assertEnv(env: T) { const val = process.env[env]; diff --git a/src/server/utils/ip.ts b/src/server/utils/ip.ts index c3c097e1..dfa80cf4 100644 --- a/src/server/utils/ip.ts +++ b/src/server/utils/ip.ts @@ -170,3 +170,12 @@ async function getIpInformation() { export const cachedGetIpInformation = cacheFunction(getIpInformation, { expiry: 15 * 60 * 1000, }); + +/** + * Get current public IPv4 address (non-cached) + * Used for auto-refresh feature + */ +export async function getCurrentPublicIpv4(): Promise { + const ip = await getPublicIpv4(); + return ip ?? null; +}