2FA: Ability to see original QR code again

This commit is contained in:
Noah Petherbridge 2023-11-15 18:01:34 -08:00
parent ebd63bcb0d
commit f0373285eb
3 changed files with 174 additions and 100 deletions

View File

@ -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,9 +87,16 @@ 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.")
// 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) templates.Redirect(w, r.URL.Path)
return return
} }
}
// OK! // OK!
tf.Enabled = true tf.Enabled = true
@ -120,13 +130,25 @@ 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)
} }
// All POST requests redirect away except resetup.
if !isPairingSecondDevice {
templates.Redirect(w, r.URL.Path) templates.Redirect(w, r.URL.Path)
return return
} }
}
// Generate the QR code. // Generate the QR code.
qrCode, err := tf.QRCodeAsDataURL(key) qrCode, err := tf.QRCodeAsDataURL(key)
@ -138,6 +160,7 @@ func Setup2FA() http.HandlerFunc {
"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 {

View File

@ -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">

View File

@ -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,6 +192,16 @@
setting up your Authenticator App. setting up your Authenticator App.
</p> </p>
{{template "2fa-setup" .}}
</div>
</div>
</div>
</div>
{{end}}<!-- Setup -->
</div>
{{end}}
{{define "2fa-setup"}}
<h2>Set up your Authenticator App</h2> <h2>Set up your Authenticator App</h2>
<p> <p>
@ -233,13 +291,6 @@
<button type="submit" class="button is-primary">Confirm &amp; Continue</button> <button type="submit" class="button is-primary">Confirm &amp; Continue</button>
</form> </form>
</div>
</div>
</div>
</div>
{{end}}<!-- Setup -->
</div>
{{end}} {{end}}
{{define "scripts"}} {{define "scripts"}}
<script> <script>