forked from rDrama/rDrama
270 lines
13 KiB
HTML
270 lines
13 KiB
HTML
{% extends "settings.html" %}
|
|
{% block pagetitle %}Security Settings{% endblock %}
|
|
{% block content %}
|
|
<script defer src="{{'js/settings_security.js' | asset}}"></script>
|
|
<div class="row settings-page" id="settings-page-security">
|
|
<div class="col col-lg-8">
|
|
<div class="settings">
|
|
<section id="site-settings-email-section" class="settings-section-section">
|
|
<h5>Email</h5>
|
|
<div class="settings-section rounded">
|
|
<form action="/settings/security" method="post">
|
|
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
|
<input type="hidden" name="now" value="{{now}}">
|
|
<div class="body">
|
|
<div class="d-lg-flex">
|
|
<label for="new-email" class="w-lg-25">Email</label>
|
|
<div class="w-lg-100">
|
|
<input autocomplete="off" class="form-control" id="new_email" {% if v.email %}placeholder="{{v.email}}"{% else %}placeholder="Your email"{% endif %}
|
|
aria-describedby="new_email" type="email" pattern='{{EMAIL_REGEX_PATTERN}}' name="new_email" required>
|
|
{% if v.email and not v.is_activated %}
|
|
<div class="text-danger text-small mt-1" id="email-verify-text">Email not verified. You will not be able to recover your account with this email until you verify it. <u><button type="button" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/verify_email');emailVerifyText()"class="text-primary font-weight-bold ml-1">Verify now.</button></u></div>
|
|
{% elif not v.email %}
|
|
<div class="text-danger text-small mt-1" id="email-verify-text">Add an email to secure your account in case you forget your password.</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="d-lg-flex mt-3">
|
|
<label for="email-password" class="w-lg-25 d-none" id="email-password-label">Password</label>
|
|
<div class="w-lg-100">
|
|
<input autocomplete="off" type="password" class="form-control mb-2 d-none" id="email-password" name="password" required>
|
|
<small id="emailpasswordRequired" class="form-text font-weight-bold text-danger d-none mt-1">Password required to update your email.</small>
|
|
</div>
|
|
</div>
|
|
<small id="emailpasswordRequired" class="form-text font-weight-bold text-danger d-none mt-1">Password required to update your email.</small>
|
|
</div>
|
|
<div class="footer">
|
|
<div class="d-flex">
|
|
{% if FEATURES['MARSEYBUX'] %}
|
|
{% if KOFI_TOKEN %}
|
|
<button type="button" class="btn btn-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/settings/kofi')">Claim {{patron}} rewards</button>
|
|
{% else %}
|
|
<button type="button" class="btn btn-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/settings/gumroad')">Claim {{patron}} rewards</button>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if v.email %}
|
|
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" value="Update email">
|
|
{% else %}
|
|
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" value="Add email">
|
|
{% endif %}
|
|
</div>
|
|
{% if FEATURES['MARSEYBUX'] %}
|
|
<span class="text-small text-muted pl-1">Must be same email as the one you used to donate
|
|
{% if v.truescore >= TRUESCORE_DONATE_MINIMUM %}
|
|
on
|
|
{% if KOFI_TOKEN %}
|
|
<a rel="nofollow noopener" class="text-primary" href="{{KOFI_LINK}}">Kofi</a>
|
|
{% else %}
|
|
<a rel="nofollow noopener" class="text-primary" href="{{GUMROAD_LINK}}">Gumroad</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
<section id="site-settings-password-section" class="settings-section-section">
|
|
<h5>Password</h5>
|
|
<div class="settings-section rounded">
|
|
<form action="/settings/security" method="post">
|
|
<div class="body">
|
|
<div class="d-lg-flex">
|
|
<label for="old_password" class="mb-0 w-lg-25">Old Password</label>
|
|
<input autocomplete="off" class="form-control mb-2 w-lg-100" id="old_password" type="password" name="old_password" required>
|
|
</div>
|
|
<div class="d-lg-flex mt-5">
|
|
<label for="new_password" class="mb-0 w-lg-25">New Password</label>
|
|
<input autocomplete="off" class="form-control w-lg-100" id="new_password" type="password" name="new_password" required>
|
|
<small id="passwordHelpChange" class="form-text font-weight-bold text-muted d-none mt-1 w-lg-100">Minimum of 8 characters required.</small>
|
|
<small id="passwordHelpChangeSuccess" class="form-text font-weight-bold text-success d-none mt-1 w-lg-100">Your password meets the requirements.</small>
|
|
</div>
|
|
<div class="d-lg-flex mt-4">
|
|
<label for="cnf_password" class="mb-0 w-lg-25">Confirm New Password</label>
|
|
<input autocomplete="off" class="form-control w-lg-100" id="cnf_password" type="password" name="cnf_password" required>
|
|
<small id="passwordHelpCnf" class="form-text font-weight-bold text-muted d-none mt-1 w-lg-100">Passwords do not match.</small>
|
|
<small id="passwordHelpCnfSuccess" class="form-text font-weight-bold text-success d-none mt-1 w-lg-100">Passwords match.</small>
|
|
</div>
|
|
</div>
|
|
<div class="footer">
|
|
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
|
<input type="hidden" name="now" value="{{now}}">
|
|
<div class="d-flex">
|
|
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" value="Change Password">
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
<section id="site-settings-2fa-section" class="settings-section-section">
|
|
<h5>Two-Factor Authentication</h5>
|
|
<div class="settings-section rounded">
|
|
<div class="d-lg-flex">
|
|
<div class="title w-lg-25">
|
|
<label for="2faToggle">Use 2-step login</label>
|
|
</div>
|
|
<div class="body w-lg-100">
|
|
<div class="custom-control custom-switch">
|
|
<input autocomplete="off" type="checkbox" class="custom-control-input" id="2faToggle" name="2faToggle" data-nonce="{{g.nonce}}" {% if v.mfa_secret %}checked{% endif %}>
|
|
<label class="custom-control-label" for="2faToggle"></label>
|
|
</div>
|
|
<span class="text-small text-muted">This requires entering a randomly-generated, 6-digit code and your password to login.</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section id="site-settings-logout-everywhere-section" class="settings-section-section">
|
|
<h5>Log Out Everywhere</h5>
|
|
<form action="/settings/log_out_all_others" method="post">
|
|
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
|
<div class="body">
|
|
<div class="d-lg-flex">
|
|
<label for="forcelog-password" class="w-lg-25" id="email-password-label">Password</label>
|
|
<div class="w-lg-100">
|
|
<input autocomplete="off" type="password" class="form-control mb-2" id="forcelog-password" name="password" required>
|
|
</div>
|
|
</div>
|
|
<small id="emailpasswordRequired" class="form-text mt-1">This will also invalidate any existing recovery links associated with this account.</small>
|
|
</div>
|
|
<div class="footer">
|
|
<div class="d-flex">
|
|
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" value="Log out everywhere">
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
<section id="site-settings-blocks-section" class="settings-section-section">
|
|
<div class="row">
|
|
<div class="col">
|
|
<div class="d-md-flex justify-content-between mb-3">
|
|
<div>
|
|
<h5>Users you block</h5>
|
|
<p class="text-small text-muted mb-md-0">You have blocked the following users. They cannot reply to your content or notify you with a username mention.</p>
|
|
</div>
|
|
<div class="mt-auto">
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#blockmodal">Block user</button>
|
|
</div>
|
|
</div>
|
|
{% if v.blocking.first() %}
|
|
<div class="card mb-5">
|
|
<div class="overflow-x-auto"><table class="table table-hover rounded mb-0">
|
|
<thead class="thead-dark">
|
|
<tr>
|
|
<th>User</th>
|
|
<th>Unblock</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="text-muted">
|
|
{% for block in v.blocking %}
|
|
{% set user=block.target %}
|
|
<tr>
|
|
<td>
|
|
{% include "user_in_table.html" %}
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-primary" data-nonce="{{g.nonce}}" data-onclick="unblock_user(this, '/settings/unblock?username={{user.username}}&formkey={{v|formkey}}')">Unblock</button>
|
|
</td>
|
|
</tr>
|
|
{% else %}
|
|
<td>There are no blocked users</td>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
{{macros.ghost_box('No blocked users', '', 2)}}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="2faModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
{% if mfa_secret %}
|
|
Setup two-step login
|
|
{% elif mfa_secret and not v.email %}
|
|
Email required for two-step login
|
|
{% else %}
|
|
Disable two-step login
|
|
{% endif %}
|
|
</h5>
|
|
<button type="button" class="close" data-bs-dismiss="modal">
|
|
<span><i class="far fa-times"></i></span>
|
|
</button>
|
|
</div>
|
|
<form action="/settings/security" method="post">
|
|
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
|
<input type="hidden" name="2fa_secret" value="{{mfa_secret}}">
|
|
<div class="modal-body">
|
|
{% if mfa_secret %}
|
|
<p><span class="font-weight-bold">Step 1:</span> Scan this QR code (or enter the code) using a two-factor authentication app such as Google Authenticator or Authy.</p>
|
|
<div class="text-center mb-3">
|
|
<img alt="two-factor QR code" loading="lazy" class="img-fluid" width=175 src="/2faqr/{{mfa_secret}}">
|
|
<div class="text-small text-muted mt-1">Or enter this code: {{mfa_secret}}</div>
|
|
</div>
|
|
<p><span class="font-weight-bold">Step 2:</span> Enter the six-digit code generated in the authenticator app and your {{SITE_NAME}} account password.</p>
|
|
<label for="2fa_input">6-digit code</label>
|
|
<input autocomplete="off" type="text" class="form-control mb-2" id="2fa_input" name="2fa_token" placeholder="# # # # # #" required>
|
|
|
|
<label for="2fa_input_password">Password</label>
|
|
<input autocomplete="off" type="password" class="form-control mb-2" id="2fa_input_password" name="password" data-nonce="{{g.nonce}}" data-undisablelement="toggle2faButton" required>
|
|
{% set action = "Enable" %}
|
|
{% else %}
|
|
<div class="alert alert-warning" role="alert">
|
|
<i class="fas fa-info-circle"></i>
|
|
To disable two-step login, please enter your {{SITE_NAME}} account password and the 6-digit code generated in your authentication app. If you no longer have your two-step device, <a href="/lost_2fa">click here</a>.
|
|
</div>
|
|
|
|
<label for="2fa_input_password">Password</label>
|
|
<input autocomplete="off" type="password" class="form-control mb-2" id="2fa_input_password" name="password" required>
|
|
|
|
<label for="2fa_input">6-digit code</label>
|
|
<input autocomplete="off" type="text" class="form-control mb-2" id="2fa_input" name="2fa_remove" placeholder="# # # # # #" data-nonce="{{g.nonce}}" data-undisablelement="toggle2faButton" required>
|
|
{% set action = "Disable" %}
|
|
{% endif %}
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-link text-muted" data-bs-dismiss="modal">Cancel</button>
|
|
<input autocomplete="off" id="toggle2faButton" class="btn btn-primary" type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" value="{{action}} 2-step login" disabled>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="blockmodal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
|
<form class="m-auto" action="/settings/block" id="block-form" method="post" data-nonce="{{g.nonce}}" data-onsubmit="return false;">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Block user</h5>
|
|
<button type="button" class="close" data-bs-dismiss="modal">
|
|
<span><i class="far fa-times"></i></span>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
|
<input autocomplete="off" type="text" name="username" placeholder="Enter username..." id="block-username" class="form-control" maxlength=25 required>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-link text-muted" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn btn-primary" id="blockUserButton" data-nonce="{{g.nonce}}" data-onclick="block_user()">Block user</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="toast error" id="toast-exile-error" role="alert" data-bs-animation="true" data-bs-autohide="true" data-bs-delay="5000">
|
|
<div class="toast-body text-center">
|
|
<i class="fas fa-exclamation-circle text-danger mr-2"></i><span id="toast-error-message">Error. Please try again.</span>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|