Promote some views to wms-core

This commit is contained in:
Alice Gaudon 2020-07-12 11:46:21 +02:00
parent 7da68f2715
commit 3561614f96
19 changed files with 385 additions and 34 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "wms-core", "name": "wms-core",
"version": "0.13.2", "version": "0.13.7",
"description": "Node web framework", "description": "Node web framework",
"repository": "git@gitlab.com:ArisuOngaku/wms-core.git", "repository": "git@gitlab.com:ArisuOngaku/wms-core.git",
"author": "Alice Gaudon <alice@gaudon.pro>", "author": "Alice Gaudon <alice@gaudon.pro>",
@ -13,7 +13,7 @@
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"scripts": { "scripts": {
"test": "jest --verbose --runInBand", "test": "jest --verbose --runInBand",
"build": "(test ! -d dist || rm -r dist) && tsc && cp package.json dist/ && cp yarn.lock dist/ && mkdir dist/types && cp src/types/* dist/types/ && mv dist/src/* dist/ && rm -r dist/src", "build": "(test ! -d dist || rm -r dist) && tsc && cp package.json dist/ && cp yarn.lock dist/ && cp -r views dist/ && mkdir dist/types && cp src/types/* dist/types/ && mv dist/src/* dist/ && rm -r dist/src",
"build_and_publish": "yarn test && yarn build && cd dist && yarn publish" "build_and_publish": "yarn test && yarn build && cd dist && yarn publish"
}, },
"devDependencies": { "devDependencies": {
@ -23,19 +23,19 @@
"@types/connect-redis": "^0.0.14", "@types/connect-redis": "^0.0.14",
"@types/cookie": "^0.4.0", "@types/cookie": "^0.4.0",
"@types/cookie-parser": "^1.4.2", "@types/cookie-parser": "^1.4.2",
"@types/express": "^4.17.6",
"@types/express-session": "^1.17.0",
"@types/formidable": "^1.0.31", "@types/formidable": "^1.0.31",
"@types/geoip-lite": "^1.1.31", "@types/geoip-lite": "^1.1.31",
"@types/jest": "^26.0.4", "@types/jest": "^26.0.4",
"@types/mjml": "^4.0.4", "@types/mjml": "^4.0.4",
"@types/node-fetch": "^2.5.7",
"@types/on-finished": "^2.3.1",
"@types/uuid": "^8.0.0",
"@types/express": "^4.17.6",
"@types/express-session": "^1.17.0",
"@types/mysql": "^2.15.10", "@types/mysql": "^2.15.10",
"@types/node-fetch": "^2.5.7",
"@types/nodemailer": "^6.4.0", "@types/nodemailer": "^6.4.0",
"@types/nunjucks": "^3.1.3", "@types/nunjucks": "^3.1.3",
"@types/on-finished": "^2.3.1",
"@types/redis": "^2.8.18", "@types/redis": "^2.8.18",
"@types/uuid": "^8.0.0",
"@types/ws": "^7.2.4", "@types/ws": "^7.2.4",
"jest": "^26.1.0", "jest": "^26.1.0",
"maildev": "^1.1.0", "maildev": "^1.1.0",

View File

@ -25,7 +25,11 @@ export default class NunjucksComponent extends ApplicationComponent<void> {
} }
} }
this.env = nunjucks.configure(this.viewsPath, { this.env = nunjucks.configure([
this.viewsPath,
'views',
'node_modules/wms-core/views'
], {
autoescape: true, autoescape: true,
express: app, express: app,
noCache: !config.get('view.cache'), noCache: !config.get('view.cache'),

View File

@ -1,18 +0,0 @@
{% extends './barebone.njk' %}
{% block _stylesheets %}
{{ super() }}
{% block stylesheets %}{% endblock %}
{% endblock %}
{% block _scripts %}
{{ super() }}
{% block scripts %}{% endblock %}
{% endblock %}
{% block header %}{% endblock %}
{% block _body %}
{% block body %}{% endblock %}
{% endblock %}
{% block footer %}{% endblock %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,2 +1,2 @@
{% extends './error.njk' %} {% extends 'errors/error.njk' %}
{% import 'macros.njk' as macros %} {% import 'macros.njk' as macros %}

View File

@ -1,4 +1,4 @@
{% extends '../layouts/barebone.njk' %} {% extends 'layouts/barebone.njk' %}
{% set title = error_code + ' - ' + error_message %} {% set title = error_code + ' - ' + error_message %}

19
views/magic_link.njk Normal file
View File

@ -0,0 +1,19 @@
{% 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 %}

View File

@ -0,0 +1,58 @@
{% 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 %}

View File

@ -0,0 +1,41 @@
{% extends 'mails/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 %}

View File

@ -0,0 +1,115 @@
{% 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 %}

View File

@ -0,0 +1,66 @@
{% extends 'mails/base_layout.mjml.njk' %}
{% block body %}
<mj-section>
<mj-column>
<mj-text mj-class="title">
{% if type == 'register' %}
Register an account on {{ app.name }}
{% else %}
Log in to {{ app.name }}
{% 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 %}

View File

@ -0,0 +1,66 @@
{% extends 'mails/base_layout.mjml.njk' %}
{% block body %}
<mj-section>
<mj-column>
<mj-text mj-class="title">
{% if type == 'register' %}
Register an account on {{ app.name }}
{% else %}
Log in to {{ app.name }}
{% 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 %}