tmp logging
This commit is contained in:
@@ -5,7 +5,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify';
|
|||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_HEADER_ORDER,
|
DEFAULT_IP_HEADER_ORDER,
|
||||||
getClientIpFromHeaders,
|
getClientIpFromHeaders,
|
||||||
} from '@openpanel/common/server/get-client-ip';
|
} from '@openpanel/common/server/get-client-ip';
|
||||||
import { TABLE_NAMES, ch, chQuery, formatClickhouseDate } from '@openpanel/db';
|
import { TABLE_NAMES, ch, chQuery, formatClickhouseDate } from '@openpanel/db';
|
||||||
@@ -397,10 +397,10 @@ export async function stats(request: FastifyRequest, reply: FastifyReply) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getGeo(request: FastifyRequest, reply: FastifyReply) {
|
export async function getGeo(request: FastifyRequest, reply: FastifyReply) {
|
||||||
const ip = getClientIpFromHeaders(request.headers);
|
const { ip, header } = getClientIpFromHeaders(request.headers);
|
||||||
const others = await Promise.all(
|
const others = await Promise.all(
|
||||||
DEFAULT_HEADER_ORDER.map(async (header) => {
|
DEFAULT_IP_HEADER_ORDER.map(async (header) => {
|
||||||
const ip = getClientIpFromHeaders(request.headers, header);
|
const { ip } = getClientIpFromHeaders(request.headers, header);
|
||||||
return {
|
return {
|
||||||
header,
|
header,
|
||||||
ip,
|
ip,
|
||||||
@@ -417,13 +417,14 @@ export async function getGeo(request: FastifyRequest, reply: FastifyReply) {
|
|||||||
selected: {
|
selected: {
|
||||||
geo,
|
geo,
|
||||||
ip,
|
ip,
|
||||||
|
header,
|
||||||
},
|
},
|
||||||
...others.reduce(
|
...others.reduce(
|
||||||
(acc, other) => {
|
(acc, other) => {
|
||||||
acc[other.header] = other;
|
acc[other.header] = other;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as Record<string, { ip: string; geo: GeoLocation }>,
|
{} as Record<string, { ip: string; header: string; geo: GeoLocation }>,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import { getClientIpFromHeaders } from '@openpanel/common/server/get-client-ip';
|
|||||||
import type { FastifyRequest } from 'fastify';
|
import type { FastifyRequest } from 'fastify';
|
||||||
|
|
||||||
export async function ipHook(request: FastifyRequest) {
|
export async function ipHook(request: FastifyRequest) {
|
||||||
const ip = getClientIpFromHeaders(request.headers);
|
const { ip, header } = getClientIpFromHeaders(request.headers);
|
||||||
|
|
||||||
if (ip) {
|
if (ip) {
|
||||||
request.clientIp = ip;
|
request.clientIp = ip;
|
||||||
|
request.clientIpHeader = header;
|
||||||
} else {
|
} else {
|
||||||
request.clientIp = '';
|
request.clientIp = '';
|
||||||
|
request.clientIpHeader = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DEFAULT_IP_HEADER_ORDER } from '@openpanel/common';
|
||||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
import { path, pick } from 'ramda';
|
import { path, pick } from 'ramda';
|
||||||
|
|
||||||
@@ -37,12 +38,15 @@ export async function requestLoggingHook(
|
|||||||
url: request.url,
|
url: request.url,
|
||||||
method: request.method,
|
method: request.method,
|
||||||
elapsed: reply.elapsedTime,
|
elapsed: reply.elapsedTime,
|
||||||
|
clientIp: request.clientIp,
|
||||||
|
clientIpHeader: request.clientIpHeader,
|
||||||
headers: pick(
|
headers: pick(
|
||||||
[
|
[
|
||||||
'openpanel-client-id',
|
'openpanel-client-id',
|
||||||
'openpanel-sdk-name',
|
'openpanel-sdk-name',
|
||||||
'openpanel-sdk-version',
|
'openpanel-sdk-version',
|
||||||
'user-agent',
|
'user-agent',
|
||||||
|
...DEFAULT_IP_HEADER_ORDER,
|
||||||
],
|
],
|
||||||
request.headers,
|
request.headers,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ declare module 'fastify' {
|
|||||||
interface FastifyRequest {
|
interface FastifyRequest {
|
||||||
client: IServiceClientWithProject | null;
|
client: IServiceClientWithProject | null;
|
||||||
clientIp: string;
|
clientIp: string;
|
||||||
|
clientIpHeader: string;
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
session: SessionValidationResult;
|
session: SessionValidationResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Example: IP_HEADER_ORDER="cf-connecting-ip,x-real-ip,x-forwarded-for"
|
* Example: IP_HEADER_ORDER="cf-connecting-ip,x-real-ip,x-forwarded-for"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const DEFAULT_HEADER_ORDER = [
|
export const DEFAULT_IP_HEADER_ORDER = [
|
||||||
'cf-connecting-ip',
|
'cf-connecting-ip',
|
||||||
'true-client-ip',
|
'true-client-ip',
|
||||||
'x-forwarded-for',
|
'x-forwarded-for',
|
||||||
@@ -32,7 +32,7 @@ function getHeaderOrder(): string[] {
|
|||||||
if (typeof process !== 'undefined' && process.env?.IP_HEADER_ORDER) {
|
if (typeof process !== 'undefined' && process.env?.IP_HEADER_ORDER) {
|
||||||
return process.env.IP_HEADER_ORDER.split(',').map((h) => h.trim());
|
return process.env.IP_HEADER_ORDER.split(',').map((h) => h.trim());
|
||||||
}
|
}
|
||||||
return DEFAULT_HEADER_ORDER;
|
return DEFAULT_IP_HEADER_ORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidIp(ip: string): boolean {
|
function isValidIp(ip: string): boolean {
|
||||||
@@ -45,7 +45,10 @@ function isValidIp(ip: string): boolean {
|
|||||||
export function getClientIpFromHeaders(
|
export function getClientIpFromHeaders(
|
||||||
headers: Record<string, string | string[] | undefined> | Headers,
|
headers: Record<string, string | string[] | undefined> | Headers,
|
||||||
overrideHeaderName?: string,
|
overrideHeaderName?: string,
|
||||||
): string {
|
): {
|
||||||
|
ip: string;
|
||||||
|
header: string;
|
||||||
|
} {
|
||||||
let headerOrder = getHeaderOrder();
|
let headerOrder = getHeaderOrder();
|
||||||
|
|
||||||
if (overrideHeaderName) {
|
if (overrideHeaderName) {
|
||||||
@@ -73,7 +76,7 @@ export function getClientIpFromHeaders(
|
|||||||
if (headerName === 'x-forwarded-for') {
|
if (headerName === 'x-forwarded-for') {
|
||||||
const firstIp = value.split(',')[0]?.trim();
|
const firstIp = value.split(',')[0]?.trim();
|
||||||
if (firstIp && isValidIp(firstIp)) {
|
if (firstIp && isValidIp(firstIp)) {
|
||||||
return firstIp;
|
return { ip: firstIp, header: headerName };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle forwarded header (RFC 7239)
|
// Handle forwarded header (RFC 7239)
|
||||||
@@ -81,14 +84,14 @@ export function getClientIpFromHeaders(
|
|||||||
const match = value.match(/for=(?:"?\[?([^\]"]+)\]?"?)/i);
|
const match = value.match(/for=(?:"?\[?([^\]"]+)\]?"?)/i);
|
||||||
const ip = match?.[1];
|
const ip = match?.[1];
|
||||||
if (ip && isValidIp(ip)) {
|
if (ip && isValidIp(ip)) {
|
||||||
return ip;
|
return { ip, header: headerName };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Regular headers
|
// Regular headers
|
||||||
else if (isValidIp(value)) {
|
else if (isValidIp(value)) {
|
||||||
return value;
|
return { ip: value, header: headerName };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return { ip: '', header: '' };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export type OpenpanelOptions = OpenPanelOptions & {
|
|||||||
export default function createMiddleware(options: OpenpanelOptions) {
|
export default function createMiddleware(options: OpenpanelOptions) {
|
||||||
return function middleware(req: Request, res: Response, next: NextFunction) {
|
return function middleware(req: Request, res: Response, next: NextFunction) {
|
||||||
const sdk = new OpenPanel(options);
|
const sdk = new OpenPanel(options);
|
||||||
const ip = getClientIpFromHeaders(req.headers);
|
const { ip } = getClientIpFromHeaders(req.headers);
|
||||||
if (ip) {
|
if (ip) {
|
||||||
sdk.api.addHeader('x-client-ip', ip);
|
sdk.api.addHeader('x-client-ip', ip);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user