feat(middleware): add session and form params middleware
This commit is contained in:
1 parent
514e8fada8
commit
6d46dfbb22
2 files changed
+84
No files matched your search
@@ -0,0 +1,44 @@
|
||||
module Prism
|
||||
module Middleware
|
||||
class ParamsParser
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
request = Request.new(env)
|
||||
body = request.body
|
||||
rewind(env)
|
||||
|
||||
if json_body?(request, body) && !valid_json?(body)
|
||||
return bad_request
|
||||
end
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rewind(env)
|
||||
input = env['rack.input']
|
||||
input.rewind if input.respond_to?(:rewind)
|
||||
end
|
||||
|
||||
def json_body?(request, body)
|
||||
request.content_type.to_s.include?('application/json') && !body.empty?
|
||||
end
|
||||
|
||||
def valid_json?(body)
|
||||
JSON.parse(body)
|
||||
true
|
||||
rescue JSON::ParserError
|
||||
false
|
||||
end
|
||||
|
||||
def bad_request
|
||||
payload = JSON.generate(error: 'invalid JSON body')
|
||||
[400, { 'Content-Type' => 'application/json' }, [payload]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
module Prism
|
||||
module Middleware
|
||||
class Session
|
||||
CookieName = 'prism.session'.freeze
|
||||
|
||||
def initialize(app, secret:, cookie_name: CookieName, **options)
|
||||
@app = app
|
||||
@secret = secret
|
||||
@cookie_name = cookie_name
|
||||
@options = options
|
||||
end
|
||||
|
||||
def call(env)
|
||||
request = Request.new(env)
|
||||
loaded = Prism::Session.decode(request.cookies[@cookie_name], @secret)
|
||||
session = Params.from(loaded)
|
||||
env['prism.session'] = session
|
||||
original = session.dup
|
||||
|
||||
status, headers, body = @app.call(env)
|
||||
|
||||
current = env['prism.session']
|
||||
if current != original
|
||||
write_cookie(headers, Prism::Session.encode(current.to_h, @secret))
|
||||
end
|
||||
[status, headers, body]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def write_cookie(headers, value)
|
||||
pieces = ["#{@cookie_name}=#{value}", 'Path=/', 'HttpOnly', 'SameSite=Lax']
|
||||
pieces << "Max-Age=#{@options[:max_age]}" if @options[:max_age]
|
||||
line = pieces.join('; ')
|
||||
existing = headers['Set-Cookie']
|
||||
headers['Set-Cookie'] = existing ? "#{existing}\n#{line}" : line
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user