Migrated login and register components

This commit is contained in:
Fabio Manganiello 2020-11-26 23:43:16 +01:00
parent 0902099855
commit 3c6f3c5a21
28 changed files with 262 additions and 42 deletions

View file

@ -21,7 +21,6 @@ def login():
user_manager = UserManager() user_manager = UserManager()
session_token = request.cookies.get('session_token') session_token = request.cookies.get('session_token')
# redirect_page = request.args.get('redirect', request.headers.get('Referer', '/'))
redirect_page = request.args.get('redirect') redirect_page = request.args.get('redirect')
if not redirect_page: if not redirect_page:
redirect_page = request.headers.get('Referer', '/') redirect_page = request.headers.get('Referer', '/')
@ -50,7 +49,7 @@ def login():
response.set_cookie('session_token', session.session_token, expires=expires) response.set_cookie('session_token', session.session_token, expires=expires)
return response return response
return render_template('login.html', utils=HttpUtils) return render_template('index.html', utils=HttpUtils)
# vim:sw=4:ts=4:et: # vim:sw=4:ts=4:et:

View file

@ -1,4 +1,5 @@
import datetime import datetime
import re
from flask import Blueprint, request, redirect, render_template, make_response, url_for from flask import Blueprint, request, redirect, render_template, make_response, url_for
@ -18,7 +19,13 @@ __routes__ = [
def register(): def register():
""" Registration page """ """ Registration page """
user_manager = UserManager() user_manager = UserManager()
redirect_page = request.args.get('redirect', '/') redirect_page = request.args.get('redirect')
if not redirect_page:
redirect_page = request.headers.get('Referer', '/')
if re.search('(^https?://[^/]+)?/register[^?#]?', redirect_page):
# Prevent redirect loop
redirect_page = '/'
session_token = request.cookies.get('session_token') session_token = request.cookies.get('session_token')
if session_token: if session_token:
@ -47,7 +54,7 @@ def register():
if user_manager.get_user_count() > 0: if user_manager.get_user_count() > 0:
return redirect('/login?redirect=' + redirect_page, 302) return redirect('/login?redirect=' + redirect_page, 302)
return render_template('register.html', utils=HttpUtils) return render_template('index.html', utils=HttpUtils)
# vim:sw=4:ts=4:et: # vim:sw=4:ts=4:et:

View file

@ -210,7 +210,7 @@ def authenticate(redirect_page='', skip_auth_methods=None, check_csrf_token=Fals
return abort(403, 'Invalid or missing csrf_token') return abort(403, 'Invalid or missing csrf_token')
if n_users == 0 and 'session' not in skip_methods: if n_users == 0 and 'session' not in skip_methods:
return redirect('/register?redirect=' + redirect_page, 307) return redirect('/register?redirect=' + (redirect_page or request.url), 307)
if ('http' not in skip_methods and http_auth_ok) or \ if ('http' not in skip_methods and http_auth_ok) or \
('token' not in skip_methods and token_auth_ok) or \ ('token' not in skip_methods and token_auth_ok) or \

View file

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>platypush</title><link href="/static/css/chunk-2dcde994.9a64be0a.css" rel="prefetch"><link href="/static/css/chunk-4bbbb9a3.4d06e8fc.css" rel="prefetch"><link href="/static/css/chunk-5301c11c.b2e9b4e4.css" rel="prefetch"><link href="/static/css/chunk-5710a9bc.40372d79.css" rel="prefetch"><link href="/static/css/chunk-62a3d08e.46dc0c5b.css" rel="prefetch"><link href="/static/css/chunk-7c2209ed.a669bf94.css" rel="prefetch"><link href="/static/css/chunk-e8078048.0533fdce.css" rel="prefetch"><link href="/static/js/chunk-2dcde994.af8aa6cd.js" rel="prefetch"><link href="/static/js/chunk-4bbbb9a3.d3030ed8.js" rel="prefetch"><link href="/static/js/chunk-5301c11c.8418e498.js" rel="prefetch"><link href="/static/js/chunk-5710a9bc.aefd4d41.js" rel="prefetch"><link href="/static/js/chunk-62a3d08e.15815e60.js" rel="prefetch"><link href="/static/js/chunk-7c2209ed.46b43454.js" rel="prefetch"><link href="/static/js/chunk-e8078048.c3960daf.js" rel="prefetch"><link href="/static/css/app.8b86c014.css" rel="preload" as="style"><link href="/static/js/app.254c470a.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.71d8c4c8.js" rel="preload" as="script"><link href="/static/css/app.8b86c014.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but platypush doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.71d8c4c8.js"></script><script src="/static/js/app.254c470a.js"></script></body></html> <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>platypush</title><link href="/static/css/chunk-2dcde994.485c5bd7.css" rel="prefetch"><link href="/static/css/chunk-4bbbb9a3.10cf9095.css" rel="prefetch"><link href="/static/css/chunk-5301c11c.4c94d0b2.css" rel="prefetch"><link href="/static/css/chunk-5710a9bc.4905c62c.css" rel="prefetch"><link href="/static/css/chunk-62a3d08e.0347d7a3.css" rel="prefetch"><link href="/static/css/chunk-7c2209ed.42c2dda1.css" rel="prefetch"><link href="/static/css/chunk-e8078048.ed1e0d9d.css" rel="prefetch"><link href="/static/js/chunk-2dcde994.af8aa6cd.js" rel="prefetch"><link href="/static/js/chunk-4bbbb9a3.d3030ed8.js" rel="prefetch"><link href="/static/js/chunk-5301c11c.8418e498.js" rel="prefetch"><link href="/static/js/chunk-5710a9bc.aefd4d41.js" rel="prefetch"><link href="/static/js/chunk-62a3d08e.15815e60.js" rel="prefetch"><link href="/static/js/chunk-7c2209ed.46b43454.js" rel="prefetch"><link href="/static/js/chunk-e8078048.c3960daf.js" rel="prefetch"><link href="/static/css/app.26834a51.css" rel="preload" as="style"><link href="/static/js/app.c1348ae2.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.01650c7d.js" rel="preload" as="script"><link href="/static/css/app.26834a51.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but platypush doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.01650c7d.js"></script><script src="/static/js/app.c1348ae2.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,18 +1,13 @@
<template> <template>
<Events ref="events" :ws-port="config['backend.http'].websocket_port" v-if="config['backend.http']" />
<Notifications ref="notifications" />
<router-view /> <router-view />
</template> </template>
<script> <script>
import Notifications from "@/components/Notifications";
import Utils from "@/Utils"; import Utils from "@/Utils";
import Events from "@/Events";
import { bus } from "@/bus"; import { bus } from "@/bus";
export default { export default {
name: 'App', name: 'App',
components: {Events, Notifications},
mixins: [Utils], mixins: [Utils],
data() { data() {

View file

@ -0,0 +1,15 @@
<template>
<Events ref="events" :ws-port="config['backend.http'].websocket_port" v-if="config['backend.http']" />
<Notifications ref="notifications" />
</template>
<script>
import Events from "@/Events";
import Notifications from "@/components/Notifications";
export default {
name: "Base",
components: {Events, Notifications}
}
</script>

View file

@ -1,6 +1,8 @@
import { createWebHistory, createRouter } from "vue-router"; import { createWebHistory, createRouter } from "vue-router";
import Dashboard from "@/views/Dashboard.vue"; import Dashboard from "@/views/Dashboard.vue";
import NotFound from "@/views/NotFound"; import NotFound from "@/views/NotFound";
import Login from "@/views/Login";
import Register from "@/views/Register";
const routes = [ const routes = [
{ {
@ -8,6 +10,19 @@ const routes = [
name: "Dashboard", name: "Dashboard",
component: Dashboard, component: Dashboard,
}, },
{
path: "/login",
name: "Login",
component: Login,
},
{
path: "/register",
name: "Register",
component: Register,
},
{ {
path: "/:catchAll(.*)", path: "/:catchAll(.*)",
component: NotFound, component: NotFound,

View file

@ -0,0 +1,30 @@
button, .btn, .btn-default {
border: $default-border-3;
cursor: pointer;
padding: 0.5em 1em;
letter-spacing: 0.05em;
&.btn-primary, &[type=submit] {
background: $selected-bg;
color: $selected-fg;
border: $selected-border;
}
}
input[type=text], input[type=password] {
border: $default-border-3;
border-radius: 1em;
padding: 0.5em;
&:focus {
border: 1px solid $default-hover-fg;
}
}
input, button {
outline: none;
&:hover {
border: 1px solid $active-glow-bg-2;
}
}

View file

@ -93,3 +93,8 @@ $widths: (
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.pull-right {
text-align: right;
float: right;
}

View file

@ -23,13 +23,29 @@ $loading-bg: #909090;
$dashboard-bg: url('/img/dashboard-bg-light.jpg'); $dashboard-bg: url('/img/dashboard-bg-light.jpg');
//// Borders //// Borders
$default-border: 1px solid #e1e4e8 !default; $border-color-1: #e1e4e8 !default;
$default-border-2: 1px solid #dddddd !default; $border-color-2: #dddddd !default;
$default-border-3: 1px solid #cccccc !default; $border-color-3: #cccccc !default;
//// Hover $default-border: 1px solid $border-color-1 !default;
$default-border-2: 1px solid $border-color-2 !default;
$default-border-3: 1px solid $border-color-3 !default;
///// General-purpose colors
/// Selected
$selected-bg: #c8ffd0 !default;
$selected-fg: #426448;
$selected-border: 1px solid #98cfa0 !default;
/// Links
$default-link-fg: #5f7869 !default;
/// Active
$active-glow-bg-1: #d4ffe3 !default;
$active-glow-bg-2: #9cdfb0 !default;
/// Hover
$default-hover-fg: #35b870 !default; $default-hover-fg: #35b870 !default;
$default-hover-fg-2: #38cf80 !default; $default-hover-fg-2: #38cf80 !default;
$hover-bg: #def6ea !default;
//// General-purpose colors
$selected-bg: #c8ffd0 !default;

View file

@ -1,4 +1,7 @@
<template> <template>
<Base />
<Loading v-if="loading" />
<div id="dashboard" class="columns is-mobile" :class="classes" :style="style"> <div id="dashboard" class="columns is-mobile" :class="classes" :style="style">
<Row v-for="(row, i) in rows" :key="i" :class="row.class" :style="row.style"> <Row v-for="(row, i) in rows" :key="i" :class="row.class" :style="row.style">
<keep-alive v-for="(widget, j) in row.widgets" :key="j"> <keep-alive v-for="(widget, j) in row.widgets" :key="j">
@ -8,8 +11,6 @@
</keep-alive> </keep-alive>
</Row> </Row>
</div> </div>
<Loading v-if="loading" />
</template> </template>
<script> <script>
@ -18,11 +19,12 @@ import Utils from '@/Utils'
import Loading from "@/components/Loading"; import Loading from "@/components/Loading";
import Row from "@/components/widgets/Row"; import Row from "@/components/widgets/Row";
import Widget from "@/components/widgets/Widget"; import Widget from "@/components/widgets/Widget";
import Base from "@/components/Base";
export default { export default {
name: 'Dashboard', name: 'Dashboard',
mixins: [Utils], mixins: [Utils],
components: {Widget, Loading, Row}, components: {Widget, Loading, Row, Base},
props: { props: {
// Refresh interval in seconds. // Refresh interval in seconds.
refreshSeconds: { refreshSeconds: {

View file

@ -0,0 +1,113 @@
<template>
<div class="login-container">
<form class="login" method="POST">
<div class="description">
{{ _register ? 'Welcome' : 'Authenticate' }} to platypush
</div>
<div class="row">
<label>
<input type="text" name="username" placeholder="Username">
</label>
</div>
<div class="row">
<label>
<input type="password" name="password" placeholder="Password">
</label>
</div>
<div class="row" v-if="_register">
<label>
<input type="password" name="confirm_password" placeholder="Confirm password">
</label>
</div>
<div class="row pull-right">
<input type="submit" class="btn btn-primary" :value="_register ? 'Register' : 'Login'">
</div>
<div class="row pull-right">
<label class="checkbox">
<input type="checkbox" name="remember">&nbsp;
Keep me logged in on this device &nbsp;
</label>
</div>
</form>
</div>
</template>
<script>
import Utils from "@/Utils";
export default {
name: "Login",
mixins: [Utils],
props: {
// Set to true for a registration form, false for a login form
register: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
_register() {
return this.parseBoolean(this.register)
},
}
}
</script>
<style lang="scss">
body {
width: 100vw;
height: 100vh;
margin: 0;
overflow-x: hidden;
}
.login-container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.description {
margin-bottom: 2em;
text-align: center;
}
form {
display: flex;
flex-direction: column;
padding: 4em;
border: $default-border-3;
border-radius: 3em;
box-shadow: 2px 2px 3px 3px $border-color-2;
.row {
margin: 0.5em 0;
}
input[type=text],
input[type=password] {
width: 100%;
}
input[type=submit] {
border-radius: 1em;
}
.checkbox {
display: flex;
font-size: 0.8em;
}
}
a {
color: $default-link-fg;
}
</style>

View file

@ -0,0 +1,20 @@
<template>
<Login :register="true" />
</template>
<script>
import Login from "@/views/Login";
export default {
name: "Register",
mixins: [Login],
components: {Login},
props: {
register: {
type: Boolean,
required: false,
default: true,
},
},
}
</script>

View file

@ -8,6 +8,7 @@ module.exports = {
@import '~bulma'; @import '~bulma';
@import "@/style/themes/light.scss"; @import "@/style/themes/light.scss";
@import "@/style/layout.scss"; @import "@/style/layout.scss";
@import "@/style/components.scss";
` `
} }
} }