FEATURE: use raster image and autofill in 2FA input (#15429)

- switches to a raster image QR code so it can be long-pressed (or right
clicked) and added to iCloud keychain
- adds `autocomplete="one-time-code"` to the 2FA input for better
discoverability
This commit is contained in:
Penar Musaraj 2022-01-03 23:31:46 -05:00 committed by GitHub
parent ed83d7573e
commit be599513e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 12 additions and 23 deletions

View File

@ -4,7 +4,9 @@
maxlength=maxlength
class="second-factor-token-input"
id=inputId
autocorrect="off"
autocapitalize="off"
autocomplete="one-time-code"
autocorrect="off"
autofocus="autofocus"
placeholder=placeholder}}
placeholder=placeholder
}}

View File

@ -16,12 +16,9 @@
<div class="control-group">
<div class="controls">
<div class="qr-code-container">
<div class="qr-code">
{{html-safe secondFactorImage}}
</div>
<div class="qr-code">
<img src={{html-safe secondFactorImage}}>
</div>
<p>
{{#if showSecondFactorKey}}
{{secondFactorKey}}

View File

@ -28,7 +28,7 @@ function preferencesPretender(server, helper) {
server.post("/u/create_second_factor_totp.json", () => {
return helper.response({
key: "rcyryaqage3jexfj",
qr: '<div id="test-qr">qr-code</div>',
qr: "data:image/png;base64,notarealimage",
});
});
@ -207,7 +207,7 @@ acceptance("User Preferences", function (needs) {
assert.notOk(exists("#password"), "it hides the password input");
await click(".new-totp");
assert.ok(exists("#test-qr"), "shows qr code");
assert.ok(exists(".qr-code img"), "shows qr code image");
await click(".add-totp");

View File

@ -747,14 +747,6 @@
}
}
.qr-code-container {
display: flex;
.qr-code {
padding: 5px 5px 0 5px;
background-color: white;
}
}
.second-factor {
&.instructions {
color: var(--primary-medium);

View File

@ -1412,16 +1412,14 @@ class UsersController < ApplicationController
require 'rotp' if !defined? ROTP
totp_data = ROTP::Base32.random
secure_session["staged-totp-#{current_user.id}"] = totp_data
qrcode_svg = RQRCode::QRCode.new(current_user.totp_provisioning_uri(totp_data)).as_svg(
offset: 0,
color: '000',
shape_rendering: 'crispEdges',
module_size: 4
qrcode_png = RQRCode::QRCode.new(current_user.totp_provisioning_uri(totp_data)).as_png(
border_modules: 1,
size: 240
)
render json: success_json.merge(
key: totp_data.scan(/.{4}/).join(" "),
qr: qrcode_svg
qr: qrcode_png.to_data_url
)
end