Module: Otto::ResponseHelpers

Defined in:
lib/otto/helpers/response.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#requestObject

Returns the value of attribute request.



5
6
7
# File 'lib/otto/helpers/response.rb', line 5

def request
  @request
end

Instance Method Details



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/otto/helpers/response.rb', line 61

def cookie_security_headers
  # Add security headers that complement cookie security
  headers = {}

  # Prevent MIME type sniffing
  headers['x-content-type-options'] = 'nosniff'

  # Add referrer policy
  headers['referrer-policy'] = 'strict-origin-when-cross-origin'

  # Add frame options
  headers['x-frame-options'] = 'DENY'

  # Add XSS protection
  headers['x-xss-protection'] = '1; mode=block'

  headers
end


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
# File 'lib/otto/helpers/response.rb', line 7

def send_secure_cookie(name, value, ttl, opts = {})
  # Default security options
  defaults = {
    secure: true,
    httponly: true,
    same_site: :strict,
    path: '/',
  }

  # Merge with provided options
  cookie_opts = defaults.merge(opts)

  # Set expiration using max-age (preferred) and expires (fallback)
  if ttl&.positive?
    cookie_opts[:max_age] = ttl
    cookie_opts[:expires] = (Time.now.utc + ttl + 10)
  elsif ttl&.negative?
    # For deletion, set both to past date
    cookie_opts[:max_age] = 0
    cookie_opts[:expires] = Time.now.utc - 86_400
  end

  # Set the cookie value
  cookie_opts[:value] = value

  # Validate SameSite attribute
  valid_same_site         = [:strict, :lax, :none, 'Strict', 'Lax', 'None']
  cookie_opts[:same_site] = :strict unless valid_same_site.include?(cookie_opts[:same_site])

  # If SameSite=None, Secure must be true
  cookie_opts[:secure] = true if cookie_opts[:same_site].to_s.downcase == 'none'

  set_cookie name, cookie_opts
end


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/otto/helpers/response.rb', line 42

def send_session_cookie(name, value, opts = {})
  # Session cookies don't have expiration
  session_opts = opts.merge(
    secure: true,
    httponly: true,
    samesite: :strict,
  )

  # Remove expiration-related options for session cookies
  session_opts.delete(:max_age)
  session_opts.delete(:expires)

  # Adjust secure flag for local development
  session_opts[:secure] = false if request.local?

  session_opts[:value] = value
  set_cookie name, session_opts
end