Add GeoIP lookup support and update device fingerprints to base58

- Add maxmind library for GeoIP database lookups when not behind Cloudflare
- Extract client IP from multiple header sources (CF, X-Real-IP, X-Forwarded-For, etc.)
- Change device fingerprints from UUID to base58 with device_ prefix
- Add isValidDeviceFingerprint() that accepts both new and legacy formats
- Colocate unit tests with source files, remove __tests__/unit directory
- Add test coverage reporting to test script

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
RevIQ
2026-01-10 16:41:21 +08:00
parent 93abba044a
commit 575ca83300
6 changed files with 405 additions and 26 deletions

View File

@@ -1,7 +1,8 @@
import { generateSecureBase58Token } from "@reviq/utils";
import { base58 } from "@scure/base";
// Re-export generateSecureBase58Token from shared utils
export { generateSecureBase58Token } from "@reviq/utils";
// Re-export for convenience
export { generateSecureBase58Token };
/**
* Token prefix for all RevIQ API tokens
@@ -59,10 +60,40 @@ export const generateSessionToken = (): string => {
};
/**
* Generate a device fingerprint (UUID v4)
* Device fingerprint prefix for new fingerprints
*/
export const DEVICE_FINGERPRINT_PREFIX = "device_";
/**
* Generate a device fingerprint (base58 with device_ prefix)
*/
export const generateDeviceFingerprint = (): string => {
return crypto.randomUUID();
return generateSecureBase58Token(DEVICE_FINGERPRINT_PREFIX);
};
/**
* Check if a string is a valid device fingerprint.
* Accepts both new format (device_ prefix) and legacy UUIDs.
*/
export const isValidDeviceFingerprint = (fingerprint: string): boolean => {
// New format: device_ prefix with base58
if (fingerprint.startsWith(DEVICE_FINGERPRINT_PREFIX)) {
const base58Part = fingerprint.slice(DEVICE_FINGERPRINT_PREFIX.length);
if (base58Part.length === 0) {
return false;
}
try {
base58.decode(base58Part);
return true;
} catch {
return false;
}
}
// Legacy format: UUID v4
const uuidRegex =
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(fingerprint);
};
/**