mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
76a3ba4e83
* fix: Normalize IP addresses to avoid validation errors on audit columns Koa's `ctx.request.ip` can yield values that fail Sequelize's `isIP` validation (X-Forwarded-For chains, IPv6 zone identifiers, "unknown" from misconfigured proxies). This drops the IP metadata silently instead of raising a 500 on Event/User writes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test: Cover IP normalization on User setters Reviewer feedback. Also switches the column-options `set` to TypeScript get/set accessors — the original approach was shadowed by the class field declaration and never actually fired, which the new tests would have caught. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
28 lines
865 B
TypeScript
28 lines
865 B
TypeScript
import net from "node:net";
|
|
|
|
/**
|
|
* Normalize an IP address string for storage in audit columns.
|
|
*
|
|
* Handles common upstream-proxy artifacts that would otherwise fail
|
|
* Sequelize's `isIP` validation: IPv4-mapped IPv6 prefixes, IPv6 zone
|
|
* identifiers, and `X-Forwarded-For` chains. Returns `null` for any
|
|
* value that is not a valid IPv4 or IPv6 address after normalization.
|
|
*
|
|
* @param value the raw IP string (e.g. from `ctx.request.ip`).
|
|
* @returns a valid IP string, or `null`.
|
|
*/
|
|
export function normalizeIp(value: string | null | undefined): string | null {
|
|
if (!value || typeof value !== "string") {
|
|
return null;
|
|
}
|
|
|
|
let ip = value.split(",")[0]?.trim() ?? "";
|
|
ip = ip.replace(/^::ffff:/i, "");
|
|
const zoneIndex = ip.indexOf("%");
|
|
if (zoneIndex !== -1) {
|
|
ip = ip.slice(0, zoneIndex);
|
|
}
|
|
|
|
return net.isIP(ip) !== 0 ? ip : null;
|
|
}
|