Add support page, admin features, and auth hardening.
Rename public affiliate route to /support with localized nav labels, and include affiliate/social/wallpaper admin, 2FA login, and related site updates. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
202dc16a52
commit
fc45c35dbe
@@ -0,0 +1,116 @@
|
||||
@{
|
||||
ViewBag.Title = "User Settings";
|
||||
Layout = "~/Views/Shared/_AdminLayout.cshtml";
|
||||
var enabled = ViewBag.TwoFactorEnabled == true;
|
||||
}
|
||||
|
||||
<h2 class="text-white mt-3 mb-3">User Settings</h2>
|
||||
<p class="text-white-50">Account: <strong class="text-white">@ViewBag.Username</strong></p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="bg-dark border border-secondary rounded p-4 text-white h-100">
|
||||
<h4 class="mb-3">Change password</h4>
|
||||
|
||||
@if (TempData["pwdOk"] != null)
|
||||
{
|
||||
<div class="alert alert-success py-2">@TempData["pwdOk"]</div>
|
||||
}
|
||||
@if (TempData["pwdError"] != null)
|
||||
{
|
||||
<div class="alert alert-danger py-2">@TempData["pwdError"]</div>
|
||||
}
|
||||
|
||||
@using (Html.BeginForm("ChangePassword", "admin", FormMethod.Post))
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Current password</label>
|
||||
<input type="password" name="currentPassword" class="form-control bg-dark text-white" autocomplete="current-password" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">New password</label>
|
||||
<input type="password" name="newPassword" class="form-control bg-dark text-white" autocomplete="new-password" minlength="8" required />
|
||||
<small class="text-muted">At least 8 characters.</small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Confirm new password</label>
|
||||
<input type="password" name="confirmPassword" class="form-control bg-dark text-white" autocomplete="new-password" minlength="8" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Update password</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="bg-dark border border-secondary rounded p-4 text-white h-100">
|
||||
<h4 class="mb-3">
|
||||
Two-factor authentication
|
||||
@if (enabled)
|
||||
{
|
||||
<span class="badge text-bg-success ms-2">Enabled</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="badge text-bg-secondary ms-2">Disabled</span>
|
||||
}
|
||||
</h4>
|
||||
|
||||
@if (TempData["tfaOk"] != null)
|
||||
{
|
||||
<div class="alert alert-success py-2">@TempData["tfaOk"]</div>
|
||||
}
|
||||
@if (TempData["tfaError"] != null)
|
||||
{
|
||||
<div class="alert alert-danger py-2">@TempData["tfaError"]</div>
|
||||
}
|
||||
|
||||
@if (enabled)
|
||||
{
|
||||
<p class="text-white-50">2FA is active. Enter a current authenticator code to disable it.</p>
|
||||
using (Html.BeginForm("DisableTwoFactor", "admin", FormMethod.Post))
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Authenticator code</label>
|
||||
<input type="text" name="code" class="form-control bg-dark text-white" maxlength="6" inputmode="numeric" pattern="[0-9]*" autocomplete="one-time-code" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger" onclick="return confirm('Disable two-factor authentication?');">Disable 2FA</button>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<ol class="text-white-50">
|
||||
<li>Open your authenticator app and scan the QR code below.</li>
|
||||
<li>Or enter this secret manually: <code class="text-white">@ViewBag.SetupSecret</code></li>
|
||||
<li>Enter the 6-digit code to confirm and enable 2FA.</li>
|
||||
</ol>
|
||||
|
||||
<div class="text-center my-3">
|
||||
<div id="totpQr" class="d-inline-block bg-white p-2 rounded"></div>
|
||||
</div>
|
||||
|
||||
using (Html.BeginForm("EnableTwoFactor", "admin", FormMethod.Post))
|
||||
{
|
||||
@Html.AntiForgeryToken()
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Authenticator code</label>
|
||||
<input type="text" name="code" class="form-control bg-dark text-white" maxlength="6" inputmode="numeric" pattern="[0-9]*" autocomplete="one-time-code" required />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">Enable 2FA</button>
|
||||
}
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var uri = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject((string)ViewBag.OtpAuthUri));
|
||||
var el = document.getElementById('totpQr');
|
||||
if (el && uri && typeof QRCode !== 'undefined') {
|
||||
new QRCode(el, { text: uri, width: 200, height: 200 });
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user