Module: BetterAuth::RequestIP

Defined in:
lib/better_auth/request_ip.rb

Constant Summary collapse

LOCALHOST_IP =
"127.0.0.1"

Class Method Summary collapse

Class Method Details

.client_ip(request, options) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/better_auth/request_ip.rb', line 11

def client_ip(request, options)
  ip_options = options.advanced[:ip_address] || {}
  return nil if ip_options[:disable_ip_tracking]

  Array(ip_options[:ip_address_headers] || ["x-forwarded-for"]).each do |header|
    value = header_value(request, header)
    next unless value.is_a?(String)

    ip = value.split(",").first.to_s.strip
    return normalize_ip(ip, ipv6_subnet: ip_options[:ipv6_subnet]) if valid_ip?(ip)
  end

  ip = fallback_ip(request)
  return normalize_ip(ip, ipv6_subnet: ip_options[:ipv6_subnet]) if valid_ip?(ip)

  LOCALHOST_IP if test_or_development?
end

.fallback_ip(request) ⇒ Object



37
38
39
40
41
# File 'lib/better_auth/request_ip.rb', line 37

def fallback_ip(request)
  return request.ip.to_s if request.respond_to?(:ip)

  nil
end

.header_value(request, header) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/better_auth/request_ip.rb', line 29

def header_value(request, header)
  return request.get_header(rack_header_name(header)) if request.respond_to?(:get_header)
  return request.headers[header.to_s.downcase] if request.respond_to?(:headers)
  return request[header.to_s.downcase] || request[header.to_s] || request[header.to_sym] if request.is_a?(Hash)

  nil
end

.normalize_ip(ip, ipv6_subnet: nil) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/better_auth/request_ip.rb', line 56

def normalize_ip(ip, ipv6_subnet: nil)
  address = IPAddr.new(ip)
  return address.native.to_s if address.respond_to?(:ipv4_mapped?) && address.ipv4_mapped?
  return address.to_s if address.ipv4?

  address.mask((ipv6_subnet || 64).to_i).to_s
end

.rack_header_name(header) ⇒ Object



43
44
45
# File 'lib/better_auth/request_ip.rb', line 43

def rack_header_name(header)
  "HTTP_#{header.to_s.upcase.tr("-", "_")}"
end

.test_or_development?Boolean

Returns:

  • (Boolean)


64
65
66
67
68
# File 'lib/better_auth/request_ip.rb', line 64

def test_or_development?
  ["test", "development"].include?(ENV["RACK_ENV"]) ||
    ["test", "development"].include?(ENV["RAILS_ENV"]) ||
    ["test", "development"].include?(ENV["APP_ENV"])
end

.valid_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
# File 'lib/better_auth/request_ip.rb', line 47

def valid_ip?(ip)
  return false if ip.to_s.empty? || ip.to_s.match?(/\s/)

  IPAddr.new(ip)
  true
rescue ArgumentError
  false
end