generated from metcoder95/lib_template
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
127 lines (111 loc) · 3.46 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
'use strict'
const fp = require('fastify-plugin')
const { inferIPVersion, isIP, isIPv4, isIPv6 } = require('./lib/ip')
const plugin = fp(fastifyIp, {
fastify: '>=5.x',
name: 'fastify-ip'
})
function fastifyIp (
instance,
{ order: inputOrder, strict, isAWS } = {
order: null,
strict: false,
isAWS: false
},
done
) {
/*! Based on request-ip#https://github.com/pbojinov/request-ip/blob/9501cdf6e73059cc70fc6890adb086348d7cca46/src/index.js.
MIT License. 2022 Petar Bojinov - petarbojinov+github@gmail.com */
// Default headers
/** @type {string[]} */
let headersOrder = [
'x-client-ip', // Most common
'x-forwarded-for', // Mostly used by proxies
'cf-connecting-ip', // Cloudflare
'Cf-Pseudo-IPv4', // Cloudflare
'fastly-client-ip',
'true-client-ip', // Akamai and Cloudflare
'x-real-ip', // Nginx
'x-cluser-client-ip', // Rackspace LB
'forwarded-for',
'x-forwarded',
'forwarded',
'x-appengine-user-ip' // GCP App Engine
]
let error
if (strict && inputOrder == null && !isAWS) {
error = new Error('If strict provided, order or isAWS are mandatory')
} else if (inputOrder != null) {
if (Array.isArray(inputOrder) && inputOrder.length > 0) {
headersOrder = strict
? [].concat(inputOrder)
: [...new Set([].concat(inputOrder, headersOrder))]
} else if (typeof inputOrder === 'string' && inputOrder.length > 0) {
headersOrder = strict
? [inputOrder]
: (headersOrder.unshift(inputOrder), headersOrder)
} else {
error = new Error('invalid order option')
}
}
if (error != null) return done(error)
// Utility methods
instance.decorateRequest('isIP', isIP)
instance.decorateRequest('isIPv4', isIPv4)
instance.decorateRequest('isIPv6', isIPv6)
instance.decorateRequest('inferIPVersion', inferIPVersion)
instance.decorateRequest('_fastifyip', '')
const ipDecorator = {
// Core method
getter: function () {
let ip = this._fastifyip
if (ip !== '') return ip
// If is AWS context or the rules are not strict
// infer first from AWS monkey-patching
if (isAWS || !strict) {
this._fastifyip = inferFromAWSContext.apply(this)
ip = this._fastifyip
}
// If is an AWS context, the rules are soft
// or is not AWS context and the ip has not been
// inferred yet, try using the request headers
if (((isAWS && !strict) || !isAWS) && ip === '') {
for (const headerKey of headersOrder) {
const value = this.headers[headerKey]
if (value != null && this.isIP(value)) {
this._fastifyip = value
ip = this._fastifyip
break
}
}
}
return ip
}
}
const isTrustProxyOn = [
'ip',
'ips',
'hostname',
'protocol'
].every((key) => instance.hasRequestDecorator(key))
if (isTrustProxyOn) {
function redefineIpDecorator (request, unusedReply, done) {
Object.defineProperty(request, 'ip', {
get: ipDecorator.getter.bind(request)
})
done()
}
instance.addHook('onRequest', redefineIpDecorator)
} else {
instance.decorateRequest('ip', ipDecorator)
}
done()
// AWS Api Gateway + Lambda
function inferFromAWSContext () {
const pseudoIP = this.raw.requestContext?.identity?.sourceIp
return pseudoIP != null && this.isIP(pseudoIP) ? pseudoIP : ''
}
}
module.exports = plugin
module.exports.default = plugin
module.exports.fastifyIp = plugin