Module: Parse::MFA
- Defined in:
- lib/parse/two_factor_auth.rb,
lib/parse/two_factor_auth/user_extension.rb
Overview
Multi-Factor Authentication (MFA) support for Parse Server.
This module interfaces with Parse Server’s built-in MFA adapter which supports TOTP (Time-based One-Time Password) and SMS-based authentication.
Parse Server Configuration
MFA must be enabled in your Parse Server configuration:
{
auth: {
mfa: {
enabled: true,
options: ["TOTP"], // or ["SMS", "TOTP"]
digits: 6,
period: 30,
algorithm: "SHA1"
}
}
}
TOTP Setup Flow
-
Generate a secret client-side using MFA.generate_secret
-
Display QR code to user using MFA.provisioning_uri or MFA.qr_code
-
User scans QR with authenticator app (Google Authenticator, Authy, etc.)
-
User enters the 6-digit code from their app
-
Call UserExtension#setup_mfa! with secret and token to enable MFA
-
Store the recovery codes returned - user needs these for account recovery!
Defined Under Namespace
Modules: UserExtension Classes: AlreadyEnabledError, DependencyError, ForbiddenError, NotEnabledError, RequiredError, VerificationError
Constant Summary collapse
- DEFAULT_CONFIG =
Default configuration
{ issuer: "Parse App", digits: 6, period: 30, algorithm: "SHA1", secret_length: 20, # Minimum required by Parse Server }.freeze
Class Method Summary collapse
-
.build_login_auth_data(token:) ⇒ Hash
Build authData hash for MFA login.
-
.build_setup_auth_data(secret:, token:) ⇒ Hash
Build authData hash for MFA setup.
-
.build_sms_confirm_auth_data(mobile:, token:) ⇒ Hash
Build authData hash for SMS MFA confirmation.
-
.build_sms_setup_auth_data(mobile:) ⇒ Hash
Build authData hash for SMS MFA setup.
-
.config ⇒ Hash
Global MFA configuration.
-
.configure {|config| ... } ⇒ Object
Configure MFA settings.
-
.current_code(secret) ⇒ String
Get the current TOTP code (for testing/debugging).
-
.generate_secret(length: nil) ⇒ String
Generate a new TOTP secret for MFA setup.
-
.provisioning_uri(secret, account_name, issuer: nil) ⇒ String
Generate provisioning URI for authenticator apps.
-
.qr_code(secret, account_name, issuer: nil, format: :svg) ⇒ String
Generate a QR code for the authenticator app.
-
.rotp_available? ⇒ Boolean
Check if rotp gem is available.
-
.rqrcode_available? ⇒ Boolean
Check if rqrcode gem is available.
-
.totp(secret, issuer: nil) ⇒ ROTP::TOTP
Create a TOTP instance for verification.
-
.verify(secret, code) ⇒ Boolean
Verify a TOTP code locally (for testing/validation before sending to server).
Class Method Details
.build_login_auth_data(token:) ⇒ Hash
Build authData hash for MFA login.
265 266 267 268 269 270 271 |
# File 'lib/parse/two_factor_auth.rb', line 265 def build_login_auth_data(token:) { mfa: { token: token, }, } end |
.build_setup_auth_data(secret:, token:) ⇒ Hash
Build authData hash for MFA setup.
252 253 254 255 256 257 258 259 |
# File 'lib/parse/two_factor_auth.rb', line 252 def build_setup_auth_data(secret:, token:) { mfa: { secret: secret, token: token, }, } end |
.build_sms_confirm_auth_data(mobile:, token:) ⇒ Hash
Build authData hash for SMS MFA confirmation.
290 291 292 293 294 295 296 297 |
# File 'lib/parse/two_factor_auth.rb', line 290 def build_sms_confirm_auth_data(mobile:, token:) { mfa: { mobile: mobile, token: token, }, } end |
.build_sms_setup_auth_data(mobile:) ⇒ Hash
Build authData hash for SMS MFA setup.
277 278 279 280 281 282 283 |
# File 'lib/parse/two_factor_auth.rb', line 277 def build_sms_setup_auth_data(mobile:) { mfa: { mobile: mobile, }, } end |
.config ⇒ Hash
Global MFA configuration
107 108 109 |
# File 'lib/parse/two_factor_auth.rb', line 107 def config @config ||= DEFAULT_CONFIG.dup end |
.configure {|config| ... } ⇒ Object
Configure MFA settings
117 118 119 120 |
# File 'lib/parse/two_factor_auth.rb', line 117 def configure yield config if block_given? config end |
.current_code(secret) ⇒ String
Get the current TOTP code (for testing/debugging).
194 195 196 197 |
# File 'lib/parse/two_factor_auth.rb', line 194 def current_code(secret) ensure_rotp! totp(secret).now end |
.generate_secret(length: nil) ⇒ String
Generate a new TOTP secret for MFA setup. The secret must be at least 20 characters (Parse Server requirement).
149 150 151 152 153 154 |
# File 'lib/parse/two_factor_auth.rb', line 149 def generate_secret(length: nil) ensure_rotp! length ||= config[:secret_length] length = [length, 20].max # Parse Server requires minimum 20 ROTP::Base32.random(length) end |
.provisioning_uri(secret, account_name, issuer: nil) ⇒ String
Generate provisioning URI for authenticator apps.
209 210 211 212 |
# File 'lib/parse/two_factor_auth.rb', line 209 def provisioning_uri(secret, account_name, issuer: nil) ensure_rotp! totp(secret, issuer: issuer).provisioning_uri(account_name) end |
.qr_code(secret, account_name, issuer: nil, format: :svg) ⇒ String
Generate a QR code for the authenticator app.
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/parse/two_factor_auth.rb', line 225 def qr_code(secret, account_name, issuer: nil, format: :svg) ensure_rqrcode! uri = provisioning_uri(secret, account_name, issuer: issuer) qr = RQRCode::QRCode.new(uri) case format when :svg qr.as_svg( color: "000", shape_rendering: "crispEdges", module_size: 4, standalone: true, ) when :png qr.as_png(size: 300) when :ascii qr.as_ansi else qr.as_svg end end |
.rotp_available? ⇒ Boolean
Check if rotp gem is available
124 125 126 127 128 129 |
# File 'lib/parse/two_factor_auth.rb', line 124 def rotp_available? require "rotp" true rescue LoadError false end |
.rqrcode_available? ⇒ Boolean
Check if rqrcode gem is available
133 134 135 136 137 138 |
# File 'lib/parse/two_factor_auth.rb', line 133 def rqrcode_available? require "rqrcode" true rescue LoadError false end |
.totp(secret, issuer: nil) ⇒ ROTP::TOTP
Create a TOTP instance for verification.
161 162 163 164 165 166 167 168 169 |
# File 'lib/parse/two_factor_auth.rb', line 161 def totp(secret, issuer: nil) ensure_rotp! ROTP::TOTP.new( secret, issuer: issuer || config[:issuer], interval: config[:period], digits: config[:digits], ) end |
.verify(secret, code) ⇒ Boolean
Verify a TOTP code locally (for testing/validation before sending to server).
181 182 183 184 185 186 187 188 |
# File 'lib/parse/two_factor_auth.rb', line 181 def verify(secret, code) return false if secret.blank? || code.blank? ensure_rotp! drift_seconds = config[:period] totp_instance = totp(secret) totp_instance.verify(code.to_s, drift_behind: drift_seconds, drift_ahead: drift_seconds).present? end |