Merge branch 'develop'
This commit is contained in:
commit
eabc9ad6ea
16
package.json
16
package.json
@ -20,8 +20,8 @@
|
|||||||
"@types/express": "^4.17.6",
|
"@types/express": "^4.17.6",
|
||||||
"@types/express-session": "^1.17.0",
|
"@types/express-session": "^1.17.0",
|
||||||
"@types/formidable": "^1.0.31",
|
"@types/formidable": "^1.0.31",
|
||||||
"@types/jest": "^25.2.1",
|
"@types/jest": "^26.0.4",
|
||||||
"@types/mysql": "^2.15.14",
|
"@types/mysql": "^2.15.15",
|
||||||
"@types/node": "^13.13.2",
|
"@types/node": "^13.13.2",
|
||||||
"@types/nodemailer": "^6.4.0",
|
"@types/nodemailer": "^6.4.0",
|
||||||
"@types/nunjucks": "^3.1.3",
|
"@types/nunjucks": "^3.1.3",
|
||||||
@ -33,16 +33,16 @@
|
|||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.0.0",
|
||||||
"imagemin": "^7.0.1",
|
"imagemin": "^7.0.1",
|
||||||
"imagemin-gifsicle": "^7.0.0",
|
"imagemin-gifsicle": "^7.0.0",
|
||||||
"imagemin-mozjpeg": "^8.0.0",
|
"imagemin-mozjpeg": "^9.0.0",
|
||||||
"imagemin-pngquant": "^8.0.0",
|
"imagemin-pngquant": "^9.0.0",
|
||||||
"imagemin-svgo": "^7.1.0",
|
"imagemin-svgo": "^8.0.0",
|
||||||
"img-loader": "^3.0.1",
|
"img-loader": "^3.0.1",
|
||||||
"jest": "^25.4.0",
|
"jest": "^26.1.0",
|
||||||
"mini-css-extract-plugin": "^0.9.0",
|
"mini-css-extract-plugin": "^0.9.0",
|
||||||
"node-sass": "^4.14.0",
|
"node-sass": "^4.14.0",
|
||||||
"nodemon": "^2.0.3",
|
"nodemon": "^2.0.3",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^9.0.2",
|
||||||
"ts-jest": "^25.4.0",
|
"ts-jest": "^26.1.1",
|
||||||
"typescript": "^3.8.3",
|
"typescript": "^3.8.3",
|
||||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
{% extends 'layouts/base.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
||||||
|
|
||||||
{% set title = 'Authentication / Registration' %}
|
|
||||||
{% set decription = 'Join ' + app.name + ' and share your files!' %}
|
|
||||||
{% set h1 = 'Authentication and registration' %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<div class="container">
|
|
||||||
<div class="panel">
|
|
||||||
{% if register_confirm_email %}
|
|
||||||
<form action="/auth" method="POST" id="register-form">
|
|
||||||
<h2>Register</h2>
|
|
||||||
{{ macros.message('question', 'Do you wish to create a new account with ' + register_confirm_email + '?', false, false) }}
|
|
||||||
{{ macros.message('warning', 'If you already have an account, please log in with your existing email first and then add your new email in the Account page.', false, true) }}
|
|
||||||
<input type="hidden" name="email" value="{{ register_confirm_email }}">
|
|
||||||
<input type="hidden" name="confirm_register" value="confirm">
|
|
||||||
|
|
||||||
<div class="form-field">
|
|
||||||
<div class="form-display">Email: {{ register_confirm_email }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a href="/auth" class="button transparent">Go back</a>
|
|
||||||
<button type="submit" class="primary">Register</button>
|
|
||||||
|
|
||||||
{{ macros.csrf(getCSRFToken) }}
|
|
||||||
</form>
|
|
||||||
{% else %}
|
|
||||||
<form action="/auth" method="POST" id="login-form">
|
|
||||||
<h2>Log in or register</h2>
|
|
||||||
{# {{ macros.message('info', 'If we don\'t find your email address in our database, you will be able to register.', false, true) }}#}
|
|
||||||
<div class="input-field">
|
|
||||||
{{ macros.field(_locals, 'email', 'email', query.email or '', 'Your email address', "If we don't find your email address in our database, you will be able to register.", 'required') }}
|
|
||||||
</div>
|
|
||||||
<button type="submit">Authenticate</button>
|
|
||||||
|
|
||||||
{{ macros.csrf(getCSRFToken) }}
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,2 +0,0 @@
|
|||||||
{% extends './error.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
@ -1,36 +0,0 @@
|
|||||||
{% extends '../layouts/barebone.njk' %}
|
|
||||||
|
|
||||||
{% set title = error_code + ' - ' + error_message %}
|
|
||||||
|
|
||||||
{% block _stylesheets %}
|
|
||||||
<link rel="stylesheet" href="/css/error.css">
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block _body %}
|
|
||||||
<div class="logo"><a href="/">{{ app.name }}</a></div>
|
|
||||||
|
|
||||||
<main class="{% block class %}{% endblock %}">
|
|
||||||
{% if flash %}
|
|
||||||
{{ macros.messages(flash) }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="error-code">{{ error_code }}</div>
|
|
||||||
<div class="error-message">{{ error_message }}</div>
|
|
||||||
<div class="error-instructions">{{ error_instructions|safe }}</div>
|
|
||||||
|
|
||||||
<nav>
|
|
||||||
{% if session.previousUrl and session.previousUrl != '/' and session.previousUrl != url %}
|
|
||||||
<a href="{{ session.previousUrl }}" class="button"><i data-feather="arrow-left"></i> Go back</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<a href="/" class="button"><i data-feather="home"></i> Go to homepage</a>
|
|
||||||
</nav>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<div class="contact">
|
|
||||||
Error ID: {{ error_id }}
|
|
||||||
<br>
|
|
||||||
If you think this isn't right, please contact us with the above error ID at
|
|
||||||
<a href="mailto:{{ app.contact_email }}">{{ app.contact_email }}</a>.
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -1,37 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>{{ title }}</title>
|
|
||||||
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/img/logox1024.png">
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/img/logox128.png">
|
|
||||||
<link rel="shortcut icon" type="image/svg" href="/img/logo.svg">
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
|
|
||||||
{% if description %}
|
|
||||||
<meta name="description" content="{{ description }}">
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if refresh_after %}
|
|
||||||
<meta http-equiv="refresh" content="{{ refresh_after }}">
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% block _stylesheets %}{% endblock %}
|
|
||||||
{% block _scripts %}
|
|
||||||
<script src="/js/app.js" defer></script>
|
|
||||||
{% endblock %}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
{% block header %}{% endblock %}
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{% block _body %}{% endblock %}
|
|
||||||
|
|
||||||
<footer>{% block footer %}{% endblock %}</footer>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,4 +1,4 @@
|
|||||||
{% extends './barebone.njk' %}
|
{% extends 'layouts/barebone.njk' %}
|
||||||
{% import 'macros.njk' as macros %}
|
{% import 'macros.njk' as macros %}
|
||||||
|
|
||||||
{% block _stylesheets %}
|
{% block _stylesheets %}
|
||||||
|
142
views/macros.njk
142
views/macros.njk
@ -1,142 +0,0 @@
|
|||||||
{% macro message(type, content, raw=false, discreet=false) %}
|
|
||||||
<div class="message{{ ' message-discreet' if discreet }}" data-type="{{ type }}">
|
|
||||||
<i class="icon"></i>
|
|
||||||
<span class="content">
|
|
||||||
{{ content|safe if raw else content }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro messages(flash) %}
|
|
||||||
{% set flashed = flash() %}
|
|
||||||
{% set display = 0 %}
|
|
||||||
|
|
||||||
{% for type, bag in flashed %}
|
|
||||||
{% if bag|length %}
|
|
||||||
{% set display = 1 %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if display %}
|
|
||||||
<div class="messages">
|
|
||||||
{% for type, bag in flashed %}
|
|
||||||
{% for content in bag %}
|
|
||||||
{{ message(type, content) }}
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro csrf(getCSRFToken) %}
|
|
||||||
<input type="hidden" name="csrf" value="{{ getCSRFToken() }}">
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro field(_locals, type, name, value, placeholder, hint, validation_attributes='', extraData='') %}
|
|
||||||
{% set validation = _locals.validation() %}
|
|
||||||
{% set validation = validation[name] if validation[name] or null %}
|
|
||||||
{% set previousFormData = _locals.previousFormData() %}
|
|
||||||
{% set value = previousFormData[name] or value or validation.value or '' %}
|
|
||||||
|
|
||||||
{% if type == 'hidden' %}
|
|
||||||
{% if validation %}
|
|
||||||
{{ message('error', validation.message) }}
|
|
||||||
{% endif %}
|
|
||||||
<input type="hidden" name="{{ name }}" value="{{ value }}">
|
|
||||||
{% else %}
|
|
||||||
<div class="form-field{{ ' inline' if type == 'checkbox' }}">
|
|
||||||
{% if type == 'duration' %}
|
|
||||||
<div class="input-group">
|
|
||||||
{% for f in extraData %}
|
|
||||||
<div class="time-input">
|
|
||||||
{% if previousFormData[name] %}
|
|
||||||
{% set v = value[f] %}
|
|
||||||
{% else %}
|
|
||||||
{% set v = (value % 60) if f == 's' else (((value - value % 60) / 60 % 60) if f == 'm' else ((value - value % 3600) / 3600 if f == 'h')) %}
|
|
||||||
{% endif %}
|
|
||||||
<input type="number" name="{{ name }}[{{ f }}]" id="field-{{ name }}-{{ f }}"
|
|
||||||
value="{{ v }}"
|
|
||||||
min="0" {{ 'max=60' if (f == 's' or f == 'm') }}
|
|
||||||
{{ validation_attributes }}>
|
|
||||||
<label for="field-{{ name }}-{{ f }}">{{ f }}</label>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% elseif type == 'select' %}
|
|
||||||
<select name="{{ name }}" id="field-{{ name }}" {{ validation_attributes|safe }}>
|
|
||||||
{% for option in extraData %}
|
|
||||||
<option value="{{ option }}" {{ 'selected' if value == option }}>{{ option }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
<i data-feather="chevron-down"></i>
|
|
||||||
{% else %}
|
|
||||||
<input type="{{ type }}" name="{{ name }}" id="field-{{ name }}"
|
|
||||||
{% if type != 'checkbox' %} value="{{ value }}" {% endif %}
|
|
||||||
{{ 'checked' if (type == 'checkbox' and value == 'on') }}
|
|
||||||
{{ validation_attributes|safe }}>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<label for="field-{{ name }}{{ '-' + extraData[0] if type == 'duration' }}">{{ placeholder }}</label>
|
|
||||||
{{ fieldError(_locals, name) }}
|
|
||||||
{% if hint %}
|
|
||||||
<div class="hint"><i data-feather="info"></i> {{ hint }}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro fieldError(_locals, name) %}
|
|
||||||
{% set validation = _locals.validation() %}
|
|
||||||
{% set validation = validation[name] if validation[name] or null %}
|
|
||||||
{% if validation %}
|
|
||||||
<div class="error"><i data-feather="x-circle"></i> {{ validation.message }}</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro websocket(websocketUrl, listener, reconnectOnClose = 1, checkFunction = 0) %}
|
|
||||||
<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
{% if checkFunction %}
|
|
||||||
if (!{{ checkFunction }}()) return;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
const run = () => {
|
|
||||||
const websocket = new WebSocket('{{ websocketUrl }}');
|
|
||||||
websocket.onopen = (e) => {
|
|
||||||
console.debug('Websocket connected');
|
|
||||||
};
|
|
||||||
websocket.onmessage = (e) => {
|
|
||||||
{{ listener }}(websocket, e);
|
|
||||||
};
|
|
||||||
websocket.onerror = (e) => {
|
|
||||||
console.error('Websocket error', e);
|
|
||||||
};
|
|
||||||
websocket.onclose = (e) => {
|
|
||||||
console.debug('Websocket closed', e.code, e.reason);
|
|
||||||
|
|
||||||
{% if reconnectOnClose %}
|
|
||||||
setTimeout(run, 1000);
|
|
||||||
{% endif %}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
run();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro paginate(pagination, routeName) %}
|
|
||||||
{% if pagination.hasPrevious() or pagination.hasNext() %}
|
|
||||||
<div class="pagination">
|
|
||||||
{% if pagination.hasPrevious() %}
|
|
||||||
<a href="{{ route(routeName, {page: pagination.page - 1}) }}"><i data-feather="chevron-left"></i></a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<span>{{ pagination.page }}</span>
|
|
||||||
|
|
||||||
{% if pagination.hasNext() %}
|
|
||||||
<a href="{{ route(routeName, {page: pagination.page + 1}) }}"><i data-feather="chevron-right"></i></a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endmacro %}
|
|
@ -1,19 +0,0 @@
|
|||||||
{% extends 'layouts/base.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
||||||
|
|
||||||
{% set actionType = magicLink.action_type %}
|
|
||||||
{% set title = 'WMS: Magic Link' + (' - ' + actionType if actionType) %}
|
|
||||||
{% set h1 = 'Magic Link' + (' - ' + actionType if actionType) %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<div class="container">
|
|
||||||
<div class="panel">
|
|
||||||
{% if err %}
|
|
||||||
{{ macros.message('error', err) }}
|
|
||||||
{% else %}
|
|
||||||
{{ macros.message('success', 'Success!') }}
|
|
||||||
<p>You can now close this page.</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -1,58 +0,0 @@
|
|||||||
{% extends 'layouts/base.njk' %}
|
|
||||||
{% import 'macros.njk' as macros %}
|
|
||||||
|
|
||||||
{% set title = 'Authentication lobby' %}
|
|
||||||
{% set h1 = 'Authentication lobby' %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<div class="container">
|
|
||||||
<div class="panel">
|
|
||||||
{{ macros.message('success', 'We sent a link to ' + email + '. To authenticate, open it from any device.') }}
|
|
||||||
{{ macros.message('info', 'This link will be valid for <span id="countdown"></span> and can only be used once.', true, true) }}
|
|
||||||
|
|
||||||
<p class="center">Waiting for you to open the link...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
const validUntil = {{ validUntil }}.0;
|
|
||||||
|
|
||||||
function isValid() {
|
|
||||||
return new Date().getTime() < validUntil;
|
|
||||||
}
|
|
||||||
|
|
||||||
function websocketListen(websocket, e) {
|
|
||||||
if (e.data === 'refresh') {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const countdown = document.getElementById('countdown');
|
|
||||||
|
|
||||||
if (!isValid()) return;
|
|
||||||
|
|
||||||
function animateCountdown() {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
let diff = Math.max(0, validUntil - new Date().getTime());
|
|
||||||
if (diff === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff /= 1000;
|
|
||||||
const seconds = Math.floor(diff % 60).toFixed(0);
|
|
||||||
const minutes = Math.floor((diff - seconds) / 60).toFixed(0);
|
|
||||||
|
|
||||||
countdown.innerText = `${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
|
|
||||||
animateCountdown();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
animateCountdown();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{{ macros.websocket(websocketUrl, 'websocketListen', 1, 'isValid') }}
|
|
||||||
{% endblock %}
|
|
@ -1,41 +0,0 @@
|
|||||||
{% extends './base_layout.mjml.njk' %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<mj-section>
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="title">
|
|
||||||
{% if approved %}
|
|
||||||
Your registration was approved!
|
|
||||||
{% else %}
|
|
||||||
Sorry, your registration was rejected.
|
|
||||||
{% endif %}
|
|
||||||
</mj-text>
|
|
||||||
<mj-text>
|
|
||||||
{% if approved %}
|
|
||||||
An administrator approved your registration. You can now log in to your account.
|
|
||||||
{% else %}
|
|
||||||
Your registration was rejected and your account was deleted from our database.
|
|
||||||
If you believe that this is an error, please contact us via email.
|
|
||||||
{% endif %}
|
|
||||||
</mj-text>
|
|
||||||
|
|
||||||
{% if approved %}
|
|
||||||
<mj-button href="{{ link | safe }}">Login</mj-button>
|
|
||||||
{% endif %}
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block text %}
|
|
||||||
{% if approved %}
|
|
||||||
Hi
|
|
||||||
Your registration was approved!
|
|
||||||
|
|
||||||
You can now log in to your account by follwing this link: {{ link|safe }}
|
|
||||||
{% else %}
|
|
||||||
Hi
|
|
||||||
Sorry, your registration was rejected. Your account was deleted from our database.
|
|
||||||
|
|
||||||
If you believe that this is an error, please contact us via email.
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
@ -1,115 +0,0 @@
|
|||||||
{% if not text %}
|
|
||||||
<mjml>
|
|
||||||
<mj-head>
|
|
||||||
<mj-title>{{ mail_subject }}</mj-title>
|
|
||||||
<mj-font
|
|
||||||
name="Nunito"
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Nunito"
|
|
||||||
/>
|
|
||||||
<mj-attributes>
|
|
||||||
<mj-all
|
|
||||||
color="#f0f0f0"
|
|
||||||
font-size="16px"
|
|
||||||
font-family="Nunito, Helvetica, sans-serif"
|
|
||||||
padding="0"
|
|
||||||
/>
|
|
||||||
<mj-section
|
|
||||||
full-width="full-width"
|
|
||||||
padding="16px 16px"
|
|
||||||
background-color="#1e2932"
|
|
||||||
/>
|
|
||||||
<mj-button
|
|
||||||
background-color="#842cff"
|
|
||||||
text-transform="uppercase"
|
|
||||||
inner-padding="16px 32px"
|
|
||||||
border-radius="50px"
|
|
||||||
font-weight="700"
|
|
||||||
padding="32px"
|
|
||||||
/>
|
|
||||||
<mj-text
|
|
||||||
padding="8px 0px"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mj-class name="header"
|
|
||||||
align="center"
|
|
||||||
font-size="20px"
|
|
||||||
background-color="#1b252d"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mj-class name="footer"
|
|
||||||
align="center"
|
|
||||||
background-color="#151d23"
|
|
||||||
font-size="14px"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mj-class name="title"
|
|
||||||
align="center"
|
|
||||||
font-size="28px"
|
|
||||||
padding-bottom="24px"
|
|
||||||
align="center"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mj-class name="subtitle"
|
|
||||||
align="center"
|
|
||||||
font-size="22px"
|
|
||||||
padding-bottom="16px"
|
|
||||||
align="center"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mj-class name="link"
|
|
||||||
color="#00766c"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mj-class name="important-line"
|
|
||||||
font-size="20px"
|
|
||||||
padding="16px 0px"
|
|
||||||
/>
|
|
||||||
</mj-attributes>
|
|
||||||
<mj-style inline="inline">
|
|
||||||
.link {
|
|
||||||
color: #00766c !important;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
</mj-style>
|
|
||||||
<mj-style>
|
|
||||||
.link:hover {
|
|
||||||
color: #00a99b !important;
|
|
||||||
}
|
|
||||||
</mj-style>
|
|
||||||
{% block head %}{% endblock %}
|
|
||||||
</mj-head>
|
|
||||||
<mj-body width="632px">
|
|
||||||
{% if mail_link %}
|
|
||||||
<mj-section background-color="#171f26" padding="2px 0px">
|
|
||||||
<mj-column>
|
|
||||||
<mj-text align="center" font-size="12px">
|
|
||||||
Does this mail display improperly?
|
|
||||||
<a href="{{ mail_link }}" class="link">Open it in the browser</a>
|
|
||||||
</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<mj-section mj-class="header">
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="header">
|
|
||||||
{{ app.name }}
|
|
||||||
</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
|
|
||||||
{% block body %}{% endblock %}
|
|
||||||
|
|
||||||
<mj-section mj-class="footer">
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="footer">
|
|
||||||
All rights reserved. Contact us at
|
|
||||||
<a href="mailto:{{ app.contact_email }}" class="link">{{ app.contact_email }}</a>
|
|
||||||
</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
</mj-body>
|
|
||||||
</mjml>
|
|
||||||
{% else %}
|
|
||||||
{% block text %}{% endblock %}
|
|
||||||
{% endif %}
|
|
@ -1,66 +0,0 @@
|
|||||||
{% extends './base_layout.mjml.njk' %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<mj-section>
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="title">
|
|
||||||
{% if type == 'register' %}
|
|
||||||
Register an account on (app)
|
|
||||||
{% else %}
|
|
||||||
Log in to (app)
|
|
||||||
{% endif %}
|
|
||||||
</mj-text>
|
|
||||||
<mj-text>
|
|
||||||
{% if type == 'register' %}
|
|
||||||
Someone has requested an account registration for <strong>{{ mail_to }}</strong>. If it was not you,
|
|
||||||
please ignore this message.
|
|
||||||
{% else %}
|
|
||||||
Someone is attempting to log in to your account <strong>{{ mail_to }}</strong>.
|
|
||||||
{% endif %}
|
|
||||||
</mj-text>
|
|
||||||
|
|
||||||
{% if type == 'register' %}
|
|
||||||
<mj-button href="{{ link | safe }}">Finalize my account registration</mj-button>
|
|
||||||
{% else %}
|
|
||||||
<mj-text>If it is not you, <strong>DO NOT CLICK ON THIS BUTTON</strong>.</mj-text>
|
|
||||||
{% endif %}
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
|
|
||||||
{% if type == 'login' %}
|
|
||||||
<mj-section background-color="#1b252d">
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="important-line" padding-bottom="0px">
|
|
||||||
IP: <strong>{{ ip }}</strong>
|
|
||||||
</mj-text>
|
|
||||||
<mj-text mj-class="important-line">
|
|
||||||
Location: <strong>{{ geo }}</strong>
|
|
||||||
</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
<mj-column>
|
|
||||||
<mj-button href="{{ link | safe }}" padding="20px 0" background-color="#caa200">
|
|
||||||
Authorize log in
|
|
||||||
</mj-button>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block text %}
|
|
||||||
{% if type == 'register' %}
|
|
||||||
Hi!
|
|
||||||
Someone requested an account registration for {{ mail_to }}. If it was not you,
|
|
||||||
please ignore this message.
|
|
||||||
|
|
||||||
To finalize your account registration, please follow this link: {{ link|safe }}
|
|
||||||
{% else %}
|
|
||||||
Hi!
|
|
||||||
Someone is attempting to log in to your account {{ mail_to }}.
|
|
||||||
|
|
||||||
If it is not you, DO NOT FOLLOW THIS LINK.
|
|
||||||
|
|
||||||
IP: {{ ip }}
|
|
||||||
Location: {{ geo }}
|
|
||||||
To authorize this log in, please follow this link: {{ link|safe }}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
@ -1,66 +0,0 @@
|
|||||||
{% extends './base_layout.mjml.njk' %}
|
|
||||||
|
|
||||||
{% block body %}
|
|
||||||
<mj-section>
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="title">
|
|
||||||
{% if type == 'register' %}
|
|
||||||
Register an account on (app)
|
|
||||||
{% else %}
|
|
||||||
Log in to (app)
|
|
||||||
{% endif %}
|
|
||||||
</mj-text>
|
|
||||||
<mj-text>
|
|
||||||
{% if type == 'register' %}
|
|
||||||
Someone has requested an account registration for <strong>{{ mail_to }}</strong>. If it was not you,
|
|
||||||
please ignore this message.
|
|
||||||
{% else %}
|
|
||||||
Someone is attempting to log in to your account <strong>{{ mail_to }}</strong>.
|
|
||||||
{% endif %}
|
|
||||||
</mj-text>
|
|
||||||
|
|
||||||
{% if type == 'register' %}
|
|
||||||
<mj-button href="{{ link | safe }}">Finalize my account registration</mj-button>
|
|
||||||
{% else %}
|
|
||||||
<mj-text>If it is not you, <strong>DO NOT CLICK ON THIS BUTTON</strong>.</mj-text>
|
|
||||||
{% endif %}
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
|
|
||||||
{% if type == 'login' %}
|
|
||||||
<mj-section background-color="#1b252d">
|
|
||||||
<mj-column>
|
|
||||||
<mj-text mj-class="important-line" padding-bottom="0px">
|
|
||||||
IP: <strong>{{ ip }}</strong>
|
|
||||||
</mj-text>
|
|
||||||
<mj-text mj-class="important-line">
|
|
||||||
Location: <strong>{{ geo }}</strong>
|
|
||||||
</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
<mj-column>
|
|
||||||
<mj-button href="{{ link | safe }}" padding="20px 0" background-color="#caa200">
|
|
||||||
Authorize log in
|
|
||||||
</mj-button>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block text %}
|
|
||||||
{% if type == 'register' %}
|
|
||||||
Hi!
|
|
||||||
Someone requested an account registration for {{ mail_to }}. If it was not you,
|
|
||||||
please ignore this message.
|
|
||||||
|
|
||||||
To finalize your account registration, please follow this link: {{ link|safe }}
|
|
||||||
{% else %}
|
|
||||||
Hi!
|
|
||||||
Someone is attempting to log in to your account {{ mail_to }}.
|
|
||||||
|
|
||||||
If it is not you, DO NOT FOLLOW THIS LINK.
|
|
||||||
|
|
||||||
IP: {{ ip }}
|
|
||||||
Location: {{ geo }}
|
|
||||||
To authorize this log in, please follow this link: {{ link|safe }}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
Loading…
Reference in New Issue
Block a user