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