Skip to content

Commit

Permalink
feat: Add helpers for step up auth
Browse files Browse the repository at this point in the history
Resolves USER-980
  • Loading branch information
agis committed Nov 1, 2024
1 parent d7c944e commit 09c1c81
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/clerk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative "clerk/version"
require_relative "clerk/sdk"
require_relative "clerk/constants"

module Clerk
class << self
Expand Down
8 changes: 8 additions & 0 deletions lib/clerk/authenticatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ def clerk_user_signed_in?
!!clerk_verified_session_claims
end

def clerk_session_needs_reverification?(params=StepUp::PRESETS[:strict])
request.env['clerk'].needs_reverification?(params)
end

def clerk_render_reverification(missing_config={})
render status: 403, json: request.env['clerk'].reverification_mismatch_payload
end

def clerk_sign_in_url
ENV.fetch("CLERK_SIGN_IN_URL")
end
Expand Down
10 changes: 10 additions & 0 deletions lib/clerk/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Clerk
module StepUp
PRESETS = {
very_strict: { after_minutes: 10, level: :multi_factor },
strict: { after_minutes: 10, level: :second_factor },
moderate: { after_minutes: 60, level: :second_factor },
lax: { after_minutes: 1440, level: :second_factor }
}
end
end
40 changes: 40 additions & 0 deletions lib/clerk/rack_middleware_v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,46 @@ def org_permissions
@session_claims["org_permissions"]
end

# Returns true if the session needs to perform step up verification
def needs_reverification?(params)
return false if session_claims.nil?

fva = session_claims["fva"]
level = params[:level]
after_minutes = Integer(params[:after_minutes])

return false if fva.nil? || after_minutes.nil? || level.nil?

factor1_age, factor2_age = fva
factor1_enabled = (factor1_age == -1 ? false : after_minutes > factor1_age)
factor2_enabled = (factor2_age == -1 ? false : after_minutes > factor2_age)

case level
when :first_factor then factor1_enabled
when :second_factor then factor2_enabled
when :multi_factor
factor2_age == -1 ? factor1_enabled : factor1_enabled && factor2_enabled
end
end

def reverification_mismatch_payload(missing_config={})
{
clerk_error: {
type: "forbidden",
reason: "reverification-mismatch",
metadata: { reverification: missing_config, }
}
}
end

def reverification_response(missing_config={})
[
403,
{ "Content-Type" => "application/json" },
[reverification_mismatch_payload(missing_config).to_json],
]
end

private

def fetch_user(user_id)
Expand Down

0 comments on commit 09c1c81

Please sign in to comment.