2FA: Ability to see original QR code again
This commit is contained in:
parent
ebd63bcb0d
commit
f0373285eb
|
@ -70,6 +70,9 @@ func Setup2FA() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are they (re)viewing their original QR code?
|
||||||
|
var isPairingSecondDevice bool
|
||||||
|
|
||||||
// POST form actions.
|
// POST form actions.
|
||||||
if r.Method == http.MethodPost {
|
if r.Method == http.MethodPost {
|
||||||
var intent = r.PostFormValue("intent")
|
var intent = r.PostFormValue("intent")
|
||||||
|
@ -84,8 +87,15 @@ func Setup2FA() http.HandlerFunc {
|
||||||
// Valid?
|
// Valid?
|
||||||
if !valid {
|
if !valid {
|
||||||
session.FlashError(w, r, "The passcode you submitted didn't seem correct. Try a new six-digit code.")
|
session.FlashError(w, r, "The passcode you submitted didn't seem correct. Try a new six-digit code.")
|
||||||
templates.Redirect(w, r.URL.Path)
|
|
||||||
return
|
// If they were reconfiguring a second device, go back to the re-setup screen.
|
||||||
|
if tf.Enabled {
|
||||||
|
isPairingSecondDevice = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
templates.Redirect(w, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK!
|
// OK!
|
||||||
|
@ -120,12 +130,24 @@ func Setup2FA() http.HandlerFunc {
|
||||||
session.Flash(w, r, "Your 2FA settings have been cleared and disabled.")
|
session.Flash(w, r, "Your 2FA settings have been cleared and disabled.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "resetup":
|
||||||
|
// View the original QR code to set up a new device.
|
||||||
|
var password = r.PostFormValue("password")
|
||||||
|
if err := currentUser.CheckPassword(password); err != nil {
|
||||||
|
session.FlashError(w, r, "Couldn't access your 2FA QR code: the password you entered is incorrect.")
|
||||||
|
} else {
|
||||||
|
session.Flash(w, r, "Password accepted. Your 2FA QR code and setup steps will be displayed below.")
|
||||||
|
isPairingSecondDevice = true
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
session.FlashError(w, r, "Unknown intent: %s", intent)
|
session.FlashError(w, r, "Unknown intent: %s", intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.Redirect(w, r.URL.Path)
|
// All POST requests redirect away except resetup.
|
||||||
return
|
if !isPairingSecondDevice {
|
||||||
|
templates.Redirect(w, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the QR code.
|
// Generate the QR code.
|
||||||
|
@ -135,9 +157,10 @@ func Setup2FA() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
var vars = map[string]interface{}{
|
var vars = map[string]interface{}{
|
||||||
"TwoFactor": tf,
|
"TwoFactor": tf,
|
||||||
"Key": key,
|
"Key": key,
|
||||||
"QRCode": qrCode,
|
"QRCode": qrCode,
|
||||||
|
"IsPairingSecondDevice": isPairingSecondDevice,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<!-- New Feature: Two Factor Auth -->
|
<!-- New Feature: Two Factor Auth -->
|
||||||
{{if not .TwoFactorEnabled}}
|
<!--
|
||||||
<div class="card block">
|
<div class="card block">
|
||||||
<header class="card-header has-background-success-dark">
|
<header class="card-header has-background-success-dark">
|
||||||
<p class="card-header-title has-text-light">
|
<p class="card-header-title has-text-light">
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
-->
|
||||||
|
|
||||||
<div class="card block">
|
<div class="card block">
|
||||||
<header class="card-header has-background-link">
|
<header class="card-header has-background-link">
|
||||||
|
|
|
@ -38,7 +38,13 @@
|
||||||
the time-limited six-digit code to log in.
|
the time-limited six-digit code to log in.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>Backup Codes</h4>
|
<!-- Are they reconfiguring their 2FA app (viewing the barcode)? -->
|
||||||
|
{{if .IsPairingSecondDevice}}
|
||||||
|
{{template "2fa-setup" .}}
|
||||||
|
<hr>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<h4 class="mt-4">Backup Codes</h4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In case you lose access to your Authenticator App, please print off or write down these
|
In case you lose access to your Authenticator App, please print off or write down these
|
||||||
|
@ -72,7 +78,12 @@
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h4 class="has-text-danger mt-4">Disable Two-Factor Auth</h4>
|
<hr>
|
||||||
|
|
||||||
|
<h4 class="has-text-danger mt-4">
|
||||||
|
<i class="fa fa-exclamation-triangle mr-1"></i>
|
||||||
|
Disable Two-Factor Auth
|
||||||
|
</h4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If you wish to <strong>disable</strong> two-factor authentication for your account, please enter
|
If you wish to <strong>disable</strong> two-factor authentication for your account, please enter
|
||||||
|
@ -95,6 +106,43 @@
|
||||||
Disable Two-Factor Authentication
|
Disable Two-Factor Authentication
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4 class="has-text-warning mt-4">
|
||||||
|
<i class="fa fa-qrcode mr-1"></i>
|
||||||
|
Set Up Another Device
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you wish to <strong>set up another authenticator device</strong> and view your original
|
||||||
|
QR code, you may do so by entering your current account password below. This may be useful
|
||||||
|
if you have bought a new phone or want to migrate your authenticator to a different device,
|
||||||
|
so that you may access the original QR code and configure the new authenticator.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Note:</strong> this will not change your 2FA security key or backup codes. If you
|
||||||
|
have lost your old authenticator, it will be more secure to <strong>disable and then set up
|
||||||
|
2FA from scratch</strong>, which will generate a new secret key and backup codes.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form action="{{.Request.URL.Path}}" method="POST">
|
||||||
|
{{InputCSRF}}
|
||||||
|
<input type="hidden" name="intent" value="resetup">
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="password">Your account password:</label>
|
||||||
|
<input type="password" class="input"
|
||||||
|
name="password"
|
||||||
|
placeholder="Password"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="button is-warning">
|
||||||
|
View my original 2FA QR code
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -144,95 +192,7 @@
|
||||||
setting up your Authenticator App.
|
setting up your Authenticator App.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Set up your Authenticator App</h2>
|
{{template "2fa-setup" .}}
|
||||||
|
|
||||||
<p>
|
|
||||||
To set up Two-Factor Auth, you'll need to download and install a compatible
|
|
||||||
Authenticator App on your device. Some suggestions for apps that are compatible
|
|
||||||
with {{PrettyTitle}} are as follows:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<strong>Google Authenticator:</strong>
|
|
||||||
for <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target="_blank">
|
|
||||||
<i class="fab fa-android"></i> Android
|
|
||||||
</a> or <a href="https://apps.apple.com/us/app/google-authenticator/id388497605" target="_blank">
|
|
||||||
<i class="fab fa-apple"></i> iOS
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<strong>
|
|
||||||
<a href="https://authy.com/download/" target="_blank">Authy:</a>
|
|
||||||
</strong>
|
|
||||||
available for <i class="fab fa-android"></i> Android and <i class="fab fa-apple"></i> iOS
|
|
||||||
as well as Windows, macOS and Linux computers.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Add {{PrettyTitle}} to your Authenticator App</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
When you have your Authenticator App ready, click on its "Add a new site" button and scan
|
|
||||||
the following QR code to enroll your device for {{PrettyTitle}}:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{{ToHTML .QRCode}}
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Alternatively (if you can't scan the QR code), you may copy and paste this secret text
|
|
||||||
in to your Authenticator app:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="columns is-mobile">
|
|
||||||
<div class="column is-half-tablet pr-1">
|
|
||||||
<input type="text" class="input"
|
|
||||||
id="totp-secret"
|
|
||||||
value="{{.Key.Secret}}"
|
|
||||||
readonly
|
|
||||||
onclick="copySecret()">
|
|
||||||
</div>
|
|
||||||
<div class="column is-narrow pl-0">
|
|
||||||
<button type="button"
|
|
||||||
class="button is-success"
|
|
||||||
id="copy-button"
|
|
||||||
onclick="copySecret()">
|
|
||||||
<i class="fa fa-copy mr-1"></i> Copy
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3>Test your Authenticator App</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
After scanning the QR code (or copying the secret key) into your Authenticator app, you
|
|
||||||
should be able to generate temporary six-digit authentication codes.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Test that you have enrolled your authenticator correctly by entering the current six-digit
|
|
||||||
code below:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form action="{{.Request.URL.Path}}" method="POST">
|
|
||||||
{{InputCSRF}}
|
|
||||||
<input type="hidden" name="intent" value="setup-verify">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="code">
|
|
||||||
Authentication Code:
|
|
||||||
</label>
|
|
||||||
<input type="text" class="input is-one-quarter"
|
|
||||||
name="code" id="code"
|
|
||||||
pattern="^[0-9]{6}$"
|
|
||||||
maxlength="6"
|
|
||||||
placeholder="000000"
|
|
||||||
style="max-width: 12em"
|
|
||||||
autocomplete="off">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="button is-primary">Confirm & Continue</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -241,6 +201,97 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{define "2fa-setup"}}
|
||||||
|
<h2>Set up your Authenticator App</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To set up Two-Factor Auth, you'll need to download and install a compatible
|
||||||
|
Authenticator App on your device. Some suggestions for apps that are compatible
|
||||||
|
with {{PrettyTitle}} are as follows:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>Google Authenticator:</strong>
|
||||||
|
for <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target="_blank">
|
||||||
|
<i class="fab fa-android"></i> Android
|
||||||
|
</a> or <a href="https://apps.apple.com/us/app/google-authenticator/id388497605" target="_blank">
|
||||||
|
<i class="fab fa-apple"></i> iOS
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<strong>
|
||||||
|
<a href="https://authy.com/download/" target="_blank">Authy:</a>
|
||||||
|
</strong>
|
||||||
|
available for <i class="fab fa-android"></i> Android and <i class="fab fa-apple"></i> iOS
|
||||||
|
as well as Windows, macOS and Linux computers.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Add {{PrettyTitle}} to your Authenticator App</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When you have your Authenticator App ready, click on its "Add a new site" button and scan
|
||||||
|
the following QR code to enroll your device for {{PrettyTitle}}:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{ToHTML .QRCode}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Alternatively (if you can't scan the QR code), you may copy and paste this secret text
|
||||||
|
in to your Authenticator app:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="columns is-mobile">
|
||||||
|
<div class="column is-half-tablet pr-1">
|
||||||
|
<input type="text" class="input"
|
||||||
|
id="totp-secret"
|
||||||
|
value="{{.Key.Secret}}"
|
||||||
|
readonly
|
||||||
|
onclick="copySecret()">
|
||||||
|
</div>
|
||||||
|
<div class="column is-narrow pl-0">
|
||||||
|
<button type="button"
|
||||||
|
class="button is-success"
|
||||||
|
id="copy-button"
|
||||||
|
onclick="copySecret()">
|
||||||
|
<i class="fa fa-copy mr-1"></i> Copy
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Test your Authenticator App</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
After scanning the QR code (or copying the secret key) into your Authenticator app, you
|
||||||
|
should be able to generate temporary six-digit authentication codes.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Test that you have enrolled your authenticator correctly by entering the current six-digit
|
||||||
|
code below:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form action="{{.Request.URL.Path}}" method="POST">
|
||||||
|
{{InputCSRF}}
|
||||||
|
<input type="hidden" name="intent" value="setup-verify">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="code">
|
||||||
|
Authentication Code:
|
||||||
|
</label>
|
||||||
|
<input type="text" class="input is-one-quarter"
|
||||||
|
name="code" id="code"
|
||||||
|
pattern="^[0-9]{6}$"
|
||||||
|
maxlength="6"
|
||||||
|
placeholder="000000"
|
||||||
|
style="max-width: 12em"
|
||||||
|
autocomplete="off">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="button is-primary">Confirm & Continue</button>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
{{define "scripts"}}
|
{{define "scripts"}}
|
||||||
<script>
|
<script>
|
||||||
function copySecret() {
|
function copySecret() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user