mirror of
https://github.com/simple-login/app.git
synced 2024-09-06 10:21:29 +02:00
535 lines
22 KiB
HTML
535 lines
22 KiB
HTML
{% extends 'default.html' %}
|
|
|
|
{% set active_page = "setting" %}
|
|
|
|
{% block title %}
|
|
Settings
|
|
{% endblock %}
|
|
|
|
{% block head %}
|
|
<style>
|
|
.card-title {
|
|
font-size: 22px;
|
|
font-weight: 600;
|
|
margin-bottom: 3px;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block default_content %}
|
|
|
|
<div class="col pb-3">
|
|
<!-- Current plan -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title mb-3">Current Plan</div>
|
|
|
|
{% if current_user.lifetime %}
|
|
You have lifetime access to the Premium plan.
|
|
{% if not current_user.paid_lifetime %}
|
|
<br>
|
|
To support SimpleLogin you can switch to a paid plan. <br>
|
|
<a href="{{ url_for('dashboard.pricing') }}" class="btn btn-sm btn-outline-primary">Upgrade</a>
|
|
{% endif %}
|
|
{% elif current_user.get_subscription() %}
|
|
You are on the {{ current_user.get_subscription().plan_name() }} plan. <br>
|
|
<a href="{{ url_for('dashboard.billing') }}" class="btn btn-outline-primary">
|
|
Manage Subscription
|
|
</a>
|
|
{% if current_user.lifetime %}
|
|
You have however lifetime access to the Premium plan now so make sure to cancel the previous plan :).
|
|
{% endif %}
|
|
{% elif manual_sub and manual_sub.is_active() %}
|
|
You are on the Premium plan which expires {{ manual_sub.end_at | dt }}
|
|
({{ manual_sub.end_at.format("YYYY-MM-DD") }}).
|
|
{% if manual_sub.is_giveaway %}
|
|
<br>
|
|
To gain additional features and support SimpleLogin you can upgrade to a Premium plan. <br>
|
|
<a href="{{ url_for('dashboard.pricing') }}" class="btn btn-sm btn-outline-primary">Upgrade</a>
|
|
{% endif %}
|
|
|
|
{% elif apple_sub and apple_sub.is_valid() %}
|
|
You are on the Premium plan (subscribed via Apple) which expires {{ apple_sub.expires_date | dt }}
|
|
({{ apple_sub.expires_date.format("YYYY-MM-DD") }}).
|
|
<div class="alert alert-info">
|
|
If you want to subscribe via the Web instead, please make sure to cancel your subscription
|
|
on Apple first.
|
|
<a href="{{ url_for('dashboard.pricing') }}"
|
|
class="">Upgrade <i class="fa fa-arrow-right" aria-hidden="true"></i></a>
|
|
</div>
|
|
|
|
{% elif coinbase_sub and coinbase_sub.is_active() %}
|
|
You are on the Premium plan which expires {{ coinbase_sub.end_at | dt }}
|
|
({{ coinbase_sub.end_at.format("YYYY-MM-DD") }}).
|
|
<br>
|
|
<a href="{{ url_for('dashboard.coinbase_checkout_route') }}"
|
|
class="btn btn-sm btn-outline-primary" target="_blank">
|
|
Extend Subscription <i class="fe fe-external-link"></i>
|
|
</a>
|
|
|
|
{% elif current_user.in_trial() %}
|
|
Your Premium trial expires {{ current_user.trial_end | dt }}.
|
|
{% else %}
|
|
You are on the Free plan.
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<!-- END Current plan -->
|
|
|
|
<!-- TOTP -->
|
|
<div class="card" id="totp">
|
|
<div class="card-body">
|
|
<div class="card-title">Two Factor Authentication</div>
|
|
<div class="mb-3">
|
|
Secure your account with 2FA, you'll be asked for a code generated through an app when you login. <br>
|
|
</div>
|
|
{% if not current_user.enable_otp %}
|
|
<a href="{{ url_for('dashboard.mfa_setup') }}" class="btn btn-outline-primary">Setup TOTP</a>
|
|
{% else %}
|
|
<a href="{{ url_for('dashboard.mfa_cancel') }}" class="btn btn-outline-danger">Disable TOTP</a>
|
|
<a href="{{ url_for('dashboard.recovery_code_route') }}" class="btn btn-outline-secondary">Recovery Codes</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<!-- END TOTP -->
|
|
|
|
<!-- WebAuthn -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Security Key (WebAuthn)</div>
|
|
<div class="mb-3">
|
|
You can secure your account by linking either your FIDO-supported physical key such as Yubikey, Google
|
|
Titan,
|
|
or a device with appropriate hardware to your account.
|
|
</div>
|
|
{% if current_user.fido_uuid is none %}
|
|
<a href="{{ url_for('dashboard.fido_setup') }}" class="btn btn-outline-primary">Setup WebAuthn</a>
|
|
{% else %}
|
|
<a href="{{ url_for('dashboard.fido_manage') }}" class="btn btn-outline-info">Manage WebAuthn</a>
|
|
<a href="{{ url_for('dashboard.recovery_code_route') }}" class="btn btn-outline-secondary">Recovery Codes</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<!-- END WebAuthn -->
|
|
|
|
|
|
<!-- Newsletter -->
|
|
<div class="card" id="notification">
|
|
<div class="card-body">
|
|
<div class="card-title">Newsletters</div>
|
|
<div class="mb-3">
|
|
We will occasionally send you emails with new feature announcements.
|
|
</div>
|
|
<form method="post">
|
|
<input type="hidden" name="form-name" value="notification-preference">
|
|
<div class="form-check">
|
|
<input type="checkbox" id="notification" name="notification" {% if current_user.notification %}
|
|
checked {% endif %} class="form-check-input">
|
|
<label for="notification">I want to be emailed when new features are released.</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline-primary">Submit</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Newsletter -->
|
|
|
|
<!-- Change name & profile picture -->
|
|
<div class="card">
|
|
<form method="post" enctype="multipart/form-data">
|
|
{{ form.csrf_token }}
|
|
<input type="hidden" name="form-name" value="update-profile">
|
|
|
|
<div class="card-body">
|
|
<div class="card-title">
|
|
Profile
|
|
</div>
|
|
<div>
|
|
This information will be filled in automatically when you use the
|
|
<em>Sign in with SimpleLogin</em> button.
|
|
</div>
|
|
<div class="form-group mt-3">
|
|
<label class="form-label">Name</label>
|
|
{{ form.name(class="form-control", value=current_user.name) }}
|
|
{{ render_field_errors(form.name) }}
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="form-label">Profile picture</div>
|
|
{{ form.profile_picture(class="form-control-file") }}
|
|
{{ render_field_errors(form.profile_picture) }}
|
|
{% if current_user.profile_picture_id %}
|
|
<img src="{{ current_user.profile_picture_url() }}" class="profile-picture">
|
|
{% endif %}
|
|
</div>
|
|
<button class="btn btn-outline-primary">Update</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<!-- END change name & profile picture -->
|
|
|
|
<!-- Change email -->
|
|
<div class="card">
|
|
<form method="post" enctype="multipart/form-data">
|
|
<input type="hidden" name="form-name" value="update-email">
|
|
{{ change_email_form.csrf_token }}
|
|
|
|
<div class="card-body">
|
|
<div class="card-title">
|
|
Account Email
|
|
</div>
|
|
<div class="mb-3">
|
|
This email address is used to log in to SimpleLogin. <br>
|
|
If you want to change the mailbox that emails are forwarded to, use the
|
|
<a href="{{ url_for('dashboard.mailbox_route') }}">
|
|
<i class="fe fe-inbox"></i> Mailboxes page
|
|
</a> instead.
|
|
</div>
|
|
<div class="form-group mt-2">
|
|
<!-- Not allow user to change email if there's a pending change -->
|
|
{{ change_email_form.email(class="form-control", value=current_user.email, readonly=pending_email != None) }}
|
|
{{ render_field_errors(change_email_form.email) }}
|
|
|
|
{% if pending_email %}
|
|
<div class="mt-2">
|
|
<span class="text-danger">Pending email change: {{ pending_email }}</span>
|
|
<a href="{{ url_for('dashboard.resend_email_change') }}" class="btn btn-secondary btn-sm">Resend
|
|
confirmation email</a>
|
|
<a href="{{ url_for('dashboard.cancel_email_change') }}" class="btn btn-secondary btn-sm">Cancel email
|
|
change</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<button class="btn btn-outline-primary">Change Email</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<!-- END Change email -->
|
|
|
|
<!-- Change password -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">
|
|
Password
|
|
</div>
|
|
<div class="mb-3">
|
|
You will receive an email containing instructions on how to change your password.
|
|
</div>
|
|
<form method="post">
|
|
<input type="hidden" name="form-name" value="change-password">
|
|
<button class="btn btn-outline-primary">Change password</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Change password -->
|
|
|
|
<!-- Random alias -->
|
|
<div id="random-alias" class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Aliases</div>
|
|
|
|
<div class="mt-3 mb-1">Change the way random aliases are generated by default.</div>
|
|
<form method="post" action="#random-alias" class="form-inline">
|
|
<input type="hidden" name="form-name" value="change-alias-generator">
|
|
<select class="form-control mr-sm-2" name="alias-generator-scheme">
|
|
<option value="{{ AliasGeneratorEnum.word.value }}"
|
|
{% if current_user.alias_generator == AliasGeneratorEnum.word.value %} selected {% endif %} >Based on
|
|
Random {{ AliasGeneratorEnum.word.name.capitalize() }}</option>
|
|
<option value="{{ AliasGeneratorEnum.uuid.value }}"
|
|
{% if current_user.alias_generator == AliasGeneratorEnum.uuid.value %} selected {% endif %} >Based
|
|
on {{ AliasGeneratorEnum.uuid.name.upper() }}</option>
|
|
</select>
|
|
<button class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
|
|
<div class="mt-3 mb-1">Select the default domain for aliases.</div>
|
|
<form method="post" action="#random-alias" class="form-inline">
|
|
<input type="hidden" name="form-name" value="change-random-alias-default-domain">
|
|
<select class="form-control mr-sm-2" name="random-alias-default-domain">
|
|
{% for is_public, domain in current_user.available_domains_for_random_alias() %}
|
|
<option value="{{ domain }}"
|
|
{% if current_user.default_random_alias_domain() == domain %} selected {% endif %} >
|
|
{{ domain }} ({% if is_public %} SimpleLogin domain {% else %} your domain {% endif %})
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<button class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
|
|
<div id="random-alias-suffix" class="mt-3 mb-1">Select the default suffix generator for aliases.</div>
|
|
<form method="post" action="#random-alias-suffix" class="form-inline">
|
|
<input type="hidden" name="form-name" value="random-alias-suffix">
|
|
<select class="form-control mr-sm-2" name="random-alias-suffix-generator">
|
|
|
|
<option value="0" {% if current_user.random_alias_suffix==0 %} selected {% endif %}>
|
|
Random word from our dictionary
|
|
</option>
|
|
<option value="1" {% if current_user.random_alias_suffix==1 %} selected {% endif %}>
|
|
Random combination of {{ ALIAS_RAND_SUFFIX_LENGTH }} letter and digits
|
|
</option>
|
|
</select>
|
|
<button class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
<!-- END Random alias -->
|
|
|
|
<!-- Sender Format -->
|
|
<div class="card" id="sender-format">
|
|
<div class="card-body">
|
|
<div class="card-title">Sender Address Format</div>
|
|
<div class="mt-1 mb-3">
|
|
When your alias receives an email, say from: <b>John Wick <john@wick.com></b>,
|
|
SimpleLogin forwards it to your mailbox. <br>
|
|
|
|
Due to some email constraints, SimpleLogin cannot keep the sender email address
|
|
in the original form and needs to <b>transform</b> it to one of the formats below.
|
|
</div>
|
|
|
|
<form method="post" action="#sender-format">
|
|
<input type="hidden" name="form-name" value="change-sender-format">
|
|
|
|
<select class="form-control mr-sm-2" name="sender-format">
|
|
<option value="{{ SenderFormatEnum.AT.value }}"
|
|
{% if current_user.sender_format == SenderFormatEnum.AT.value %} selected {% endif %}>
|
|
John Wick - john at wick.com
|
|
</option>
|
|
|
|
<option value="{{ SenderFormatEnum.A.value }}"
|
|
{% if current_user.sender_format == SenderFormatEnum.A.value %} selected {% endif %}>
|
|
John Wick - john(a)wick.com
|
|
</option>
|
|
|
|
</select>
|
|
|
|
<button class="btn btn-outline-primary mt-3">Update</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Sender Format -->
|
|
|
|
<!-- Reverse-alias replacement -->
|
|
<div class="card" id="reverse-alias-replacement-section">
|
|
<div class="card-body">
|
|
<div class="card-title">Reverse Alias Replacement
|
|
<div class="badge badge-warning">Experimental</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
When replying to a forwarded email, the <b>reverse-alias</b> can be automatically included
|
|
in the attached message by your email client.
|
|
If this option is enabled, SimpleLogin will try to <b>replace</b> the reverse-alias by your contact email. <br>
|
|
</div>
|
|
<form method="post" action="#reverse-alias-replacement-section">
|
|
<input type="hidden" name="form-name" value="replace-ra">
|
|
<div class="form-check">
|
|
<input type="checkbox" id="replace-ra" name="replace-ra"
|
|
{% if current_user.replace_reverse_alias %} checked {% endif %} class="form-check-input">
|
|
<label for="replace-ra">Enable replacing reverse alias</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Reverse-alias -->
|
|
|
|
<!-- Sender included in reverse-alias -->
|
|
<div class="card" id="sender-in-ra">
|
|
<div class="card-body">
|
|
<div class="card-title">Include sender address in reverse-alias</div>
|
|
<div class="mb-3">
|
|
By default, the reverse-alias is randomly generated and doesn't contain any information about
|
|
the sender.<br>
|
|
|
|
Enabling this option will include the sender address in the reverse-alias. <br>
|
|
|
|
This can be useful if you want to set up email filters based on the reverse-alias.
|
|
It will also make the reverse-alias more readable.
|
|
</div>
|
|
<form method="post" action="#sender-in-ra">
|
|
<input type="hidden" name="form-name" value="sender-in-ra">
|
|
<div class="form-check">
|
|
<input type="checkbox" id="include-sender-ra" name="enable"
|
|
{# todo: remove current_user.include_sender_in_reverse_alias is none condition #}
|
|
{% if current_user.include_sender_in_reverse_alias is none or current_user.include_sender_in_reverse_alias %}
|
|
checked {% endif %} class="form-check-input">
|
|
<label for="include-sender-ra">Include sender address in reverse-alias</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Reverse-alias -->
|
|
|
|
<!-- Always expand alias info -->
|
|
<div class="card" id="expand-alias-info-section">
|
|
<div class="card-body">
|
|
<div class="card-title">Always expand alias info</div>
|
|
<div class="mb-3">
|
|
By default, additional alias info is shown after clicking on the "More" button. <br>
|
|
When this option is enabled, alias additional info will always be shown. <br>
|
|
</div>
|
|
<form method="post" action="#expand-alias-info-section">
|
|
<input type="hidden" name="form-name" value="expand-alias-info">
|
|
<div class="form-check">
|
|
<input type="checkbox" id="expand-alias-info" name="enable"
|
|
{% if current_user.expand_alias_info %} checked {% endif %} class="form-check-input">
|
|
<label for="expand-alias-info">Automatically expand alias info</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Always expand alias info -->
|
|
|
|
<!-- Ignore Loop Email -->
|
|
<div class="card" id="ignore-loop-email-section">
|
|
<div class="card-body">
|
|
<div class="card-title">Ignore Loop Emails</div>
|
|
<div class="mb-3">
|
|
On some email clients, "Reply All" automatically includes your alias that
|
|
would send the same email to your mailbox.
|
|
<br>
|
|
You can disable these "loop" emails by enabling this option.
|
|
</div>
|
|
<form method="post" action="#ignore-loop-email-section">
|
|
<input type="hidden" name="form-name" value="ignore-loop-email">
|
|
<div class="form-check">
|
|
<input type="checkbox" id="ignore-loop-email" name="enable"
|
|
{% if current_user.ignore_loop_email %} checked {% endif %} class="form-check-input">
|
|
<label for="ignore-loop-email">Ignore Loop Emails</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END Ignore Loop Email -->
|
|
|
|
<!-- One-click subscribe -->
|
|
<div class="card" id="one-click-unsubscribe-section">
|
|
<div class="card-body">
|
|
<div class="card-title">One-click unsubscribe</div>
|
|
<div class="mb-3">
|
|
On email clients that support the
|
|
<a href="https://simplelogin.io/docs/getting-started/one-click-unsubscribe/">One-click unsubscribe</a> button,
|
|
clicking on it will disable the alias that receives the emails.
|
|
<br>
|
|
You can choose to block the sender instead of disabling the alias.
|
|
</div>
|
|
<form method="post" action="#one-click-unsubscribe-section">
|
|
<input type="hidden" name="form-name" value="one-click-unsubscribe">
|
|
<div class="form-check">
|
|
<input type="checkbox" id="one-click-unsubscribe" name="enable"
|
|
{% if current_user.one_click_unsubscribe_block_sender %} checked {% endif %} class="form-check-input">
|
|
<label for="one-click-unsubscribe">Block sender instead</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-outline-primary">Update</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END One-click subscribe -->
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Quarantine</div>
|
|
<div class="mb-3">
|
|
When an email sent to your alias is classified as spam or refused by your email provider,
|
|
it usually means your alias has been leaked to a spammer. <br>
|
|
In this case SimpleLogin will <b>keep</b> a copy of this email (so it isn't lost)
|
|
and notify you so you can take a look at its content and take appropriate actions. <br>
|
|
|
|
The emails are deleted in 7 days.
|
|
This is an exceptional case where SimpleLogin stores the email.
|
|
</div>
|
|
<a href="{{ url_for('dashboard.refused_email_route') }}" class="btn btn-outline-primary">
|
|
See refused emails
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Alias Import</div>
|
|
<div class="mb-3">
|
|
You can import your aliases created on other platforms into SimpleLogin.
|
|
</div>
|
|
<a href="{{ url_for('dashboard.batch_import_route') }}" class="btn btn-outline-primary">
|
|
Batch Import
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Data Export</div>
|
|
<div class="mb-3">
|
|
You can download all aliases you have created on SimpleLogin along with other data.
|
|
</div>
|
|
|
|
<div class="d-flex">
|
|
<div>
|
|
<form method="post">
|
|
<input type="hidden" name="form-name" value="export-data">
|
|
<button class="btn btn-outline-info">Export Data</button>
|
|
</form>
|
|
</div>
|
|
<div class="ml-5">
|
|
<form method="post">
|
|
<input type="hidden" name="form-name" value="export-alias">
|
|
<button class="btn btn-outline-primary">Export Aliases</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="card-title">Account Deletion</div>
|
|
<div class="mb-3">Please note that this operation is irreversible.
|
|
</div>
|
|
|
|
<form method="post">
|
|
<input type="hidden" name="form-name" value="delete-account">
|
|
<span class="delete-account btn btn-outline-danger">Delete account</span>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block script %}
|
|
<script>
|
|
$(".delete-account").on("click", function (e) {
|
|
let that = $(this);
|
|
|
|
bootbox.confirm({
|
|
message: "All your data including your aliases will be deleted, " +
|
|
"other people might not be able to reach you after, " +
|
|
" please confirm.",
|
|
buttons: {
|
|
confirm: {
|
|
label: 'Yes, delete my account',
|
|
className: 'btn-danger'
|
|
},
|
|
cancel: {
|
|
label: 'Cancel',
|
|
className: 'btn-outline-primary'
|
|
}
|
|
},
|
|
callback: function (result) {
|
|
if (result) {
|
|
that.closest("form").submit();
|
|
}
|
|
}
|
|
})
|
|
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|