Module: DiscourseWebauthn

Defined in:
lib/discourse_webauthn.rb,
lib/discourse_webauthn/challenge_generator.rb,
lib/discourse_webauthn/registration_service.rb,
lib/discourse_webauthn/authentication_service.rb,
lib/discourse_webauthn/base_validation_service.rb

Defined Under Namespace

Classes: AuthenticationService, BaseValidationService, ChallengeGenerator, ChallengeMismatchError, CredentialIdInUseError, InvalidOriginError, InvalidRelyingPartyIdError, InvalidTypeError, KeyNotFoundError, MalformedAttestationError, MalformedPublicKeyCredentialError, OwnershipError, PublicKeyError, RegistrationService, SecurityKeyError, UnknownCOSEAlgorithmError, UnsupportedAttestationFormatError, UnsupportedPublicKeyAlgorithmError, UserPresenceError, UserVerificationError

Constant Summary collapse

ACCEPTABLE_REGISTRATION_TYPE =
"webauthn.create"
ACCEPTABLE_AUTHENTICATION_TYPE =
"webauthn.get"
SUPPORTED_ALGORITHMS =

-7 - ES256 -257 - RS256 (Windows Hello supported alg.)

COSE::Algorithm.registered_algorithm_ids.freeze
VALID_ATTESTATION_FORMATS =
%w[none packed fido-u2f].freeze

Class Method Summary collapse

Class Method Details

.allowed_credentials(user, secure_session) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/discourse_webauthn.rb', line 71

def self.allowed_credentials(user, secure_session)
  return {} if !user.security_keys_enabled?
  credential_ids = user.second_factor_security_key_credential_ids
  {
    allowed_credential_ids: credential_ids,
    challenge: secure_session[self.session_challenge_key(user)],
  }
end

.challenge(user, secure_session) ⇒ Object



80
81
82
# File 'lib/discourse_webauthn.rb', line 80

def self.challenge(user, secure_session)
  secure_session[self.session_challenge_key(user)]
end

.originObject



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/discourse_webauthn.rb', line 88

def self.origin
  case Rails.env
  when "development"
    # defaults to the Ember CLI local port
    # you might need to change this and the rp_id above
    # if you are using a non-default port/hostname locally
    "http://localhost:4200"
  else
    Discourse.base_url_no_prefix
  end
end

.rp_idObject



84
85
86
# File 'lib/discourse_webauthn.rb', line 84

def self.rp_id
  Rails.env.production? ? Discourse.current_hostname : "localhost"
end

.rp_nameObject



100
101
102
# File 'lib/discourse_webauthn.rb', line 100

def self.rp_name
  SiteSetting.title
end

.session_challenge_key(user) ⇒ Object



104
105
106
# File 'lib/discourse_webauthn.rb', line 104

def self.session_challenge_key(user)
  "staged-webauthn-challenge-#{user&.id}"
end

.stage_challenge(user, secure_session) ⇒ Object

Usage:

These methods should be used in controllers where we are challenging the user that has a security key, and they must respond with a valid webauthn response and credentials.



67
68
69
# File 'lib/discourse_webauthn.rb', line 67

def self.stage_challenge(user, secure_session)
  ::DiscourseWebauthn::ChallengeGenerator.generate.commit_to_session(secure_session, user)
end