Branding and auth views
This commit is contained in:
parent
6fd4f167f3
commit
fae5e54066
@ -4,6 +4,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
neverExpireCheckbox.addEventListener('change', () => {
|
||||
// noinspection RedundantConditionalExpressionJS
|
||||
expireAfterDaysField.disabled = neverExpireCheckbox.value ? true : false;
|
||||
expireAfterDaysField.disabled = neverExpireCheckbox.checked ? true : false;
|
||||
});
|
||||
});
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "aldap",
|
||||
"name": "ily.li",
|
||||
"version": "0.1.0",
|
||||
"description": "Authentication LDAP server",
|
||||
"repository": "git@gitlab.com:ArisuOngaku/aldap.git",
|
||||
"description": "Self-hosted file pusher",
|
||||
"repository": "git@gitlab.com:ArisuOngaku/ily.li.git",
|
||||
"author": "Alice Gaudon <alice@gaudon.pro>",
|
||||
"private": true,
|
||||
"main": "dist/main.js",
|
||||
|
@ -3,7 +3,8 @@ import {Request, Response} from "express";
|
||||
|
||||
export default class AboutController extends Controller {
|
||||
routes(): void {
|
||||
this.get('/about', this.getAbout, 'about');
|
||||
this.get('/', this.getAbout, 'home');
|
||||
this.get('/', this.getAbout, 'about');
|
||||
}
|
||||
|
||||
private async getAbout(req: Request, res: Response) {
|
||||
|
@ -118,12 +118,15 @@ export default class FileController extends Controller {
|
||||
return slug;
|
||||
}
|
||||
i++;
|
||||
} while (i < tries)
|
||||
} while (i < tries);
|
||||
throw new ServerError('Failed to generate slug; newly generated slug size should be increased by 1.');
|
||||
}
|
||||
}
|
||||
|
||||
const FILE_UPLOAD_MAX_SIZE_MIDDLEWARE = express.urlencoded({limit: config.get<string>('max_upload_size')});
|
||||
const FILE_UPLOAD_MAX_SIZE_MIDDLEWARE = express.urlencoded({
|
||||
limit: config.get<string>('max_upload_size'),
|
||||
extended: true,
|
||||
});
|
||||
|
||||
const FILE_UPLOAD_MIDDLEWARE = fileUpload({
|
||||
tempFileDir: 'storage/tmp',
|
||||
|
@ -1,8 +1,9 @@
|
||||
import Logger from "wms-core/Logger";
|
||||
import App from "./App";
|
||||
import config from "config";
|
||||
|
||||
(async () => {
|
||||
const app = new App(4899);
|
||||
const app = new App(config.get<number>('port'));
|
||||
await app.start();
|
||||
})().catch(err => {
|
||||
Logger.error(err);
|
||||
|
42
views/auth.njk
Normal file
42
views/auth.njk
Normal file
@ -0,0 +1,42 @@
|
||||
{% extends 'layouts/base.njk' %}
|
||||
{% import 'macros.njk' as macros %}
|
||||
|
||||
{% set title = 'Authentication / Registration' %}
|
||||
{% set decription = 'Join Watch My Stream and power up your streams!' %}
|
||||
{% 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 %}
|
@ -15,7 +15,7 @@
|
||||
<h2>Upload a file</h2>
|
||||
|
||||
<form action="{{ route('post-file') }}" method="POST">
|
||||
{{ macros.field(_locals, 'file', 'upload', '', 'Choose wisely', 'The maximum upload size is' + max_upload_size, validation_attributes='required') }}
|
||||
{{ macros.field(_locals, 'file', 'upload', '', 'Choose wisely', 'The maximum upload size is ' + max_upload_size, validation_attributes='required') }}
|
||||
|
||||
{{ macros.field(_locals, 'number', 'expire_after_days', '30', 'How many days to delete this file after', null, validation_attributes='max="1825"') }}
|
||||
|
||||
|
@ -12,12 +12,15 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
<a href="/" class="logo"><img src="/img/logo.svg" alt="Logo"> Example app</a>
|
||||
<a href="/" class="logo"><img src="/img/logo.svg" alt="Logo"> ily.li</a>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="{{ route('about') }}"><i data-feather="info"></i> About</a></li>
|
||||
{% if user %}
|
||||
<li><a href="{{ route('file-manager') }}"><i data-feather="folder"></i>File manager</a></li>
|
||||
<li><a href="{{ route('logout') }}"><i data-feather="logout"></i> Logout</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ route('auth') }}"><i data-feather="user"></i> Login / Register</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
@ -40,4 +43,4 @@
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}Example app v{{ app_version }} - all rights reserved.{% endblock %}
|
||||
{% block footer %}ily.li v{{ app_version }} - all rights reserved.{% endblock %}
|
19
views/magic_link.njk
Normal file
19
views/magic_link.njk
Normal 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 %}
|
58
views/magic_link_lobby.njk
Normal file
58
views/magic_link_lobby.njk
Normal 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 %}
|
Loading…
Reference in New Issue
Block a user