mirror of
https://github.com/Lissy93/dashy.git
synced 2025-09-23 17:58:35 +02:00
✨ Implements guest access into Login page
This commit is contained in:
parent
8bac402802
commit
242dfe61c6
80
src/components/Settings/AuthButtons.vue
Normal file
80
src/components/Settings/AuthButtons.vue
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- If auth configured, show status text -->
|
||||||
|
<span class="user-type-note">{{ makeText() }}</span>
|
||||||
|
<div class="display-options">
|
||||||
|
<!-- If user logged in, show logout button -->
|
||||||
|
<IconLogout
|
||||||
|
v-if="userType == userStateEnum.loggedIn"
|
||||||
|
@click="logout()"
|
||||||
|
v-tooltip="tooltip($t('settings.sign-out-tooltip'))"
|
||||||
|
class="layout-icon" tabindex="-2"
|
||||||
|
/>
|
||||||
|
<!-- If not logged in, and gues mode enabled, show login button -->
|
||||||
|
<IconLogout
|
||||||
|
v-if="userType == userStateEnum.guestAccess"
|
||||||
|
@click="goToLogin()"
|
||||||
|
v-tooltip="tooltip('Login')"
|
||||||
|
class="layout-icon" tabindex="-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import router from '@/router';
|
||||||
|
import { logout as registerLogout } from '@/utils/Auth';
|
||||||
|
import { localStorageKeys, userStateEnum } from '@/utils/defaults';
|
||||||
|
import IconLogout from '@/assets/interface-icons/user-logout.svg';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AuthButtons',
|
||||||
|
components: {
|
||||||
|
IconLogout,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
userType: Number,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userStateEnum,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
logout() {
|
||||||
|
registerLogout();
|
||||||
|
this.$toasted.show(this.$t('login.logout-message'));
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push({ path: '/login' });
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
goToLogin() {
|
||||||
|
router.push({ path: '/login' });
|
||||||
|
},
|
||||||
|
tooltip(content) {
|
||||||
|
return { content, trigger: 'hover focus', delay: 250 };
|
||||||
|
},
|
||||||
|
makeText() {
|
||||||
|
if (this.userType === userStateEnum.loggedIn) return `Hello ${localStorage[localStorageKeys.USERNAME]}!`;
|
||||||
|
if (this.userType === userStateEnum.guestAccess) return 'Log In';
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/styles/style-helpers.scss';
|
||||||
|
|
||||||
|
span.user-type-note {
|
||||||
|
color: var(--settings-text-color);
|
||||||
|
text-transform: capitalize;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-options {
|
||||||
|
@extend .svg-button;
|
||||||
|
color: var(--settings-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -1,6 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login-page">
|
<div class="login-page">
|
||||||
<form class="login-form">
|
<!-- User is already logged in -->
|
||||||
|
<div v-if="isUserAlreadyLoggedIn" class="already-logged-in">
|
||||||
|
<h2>Already Logged In</h2>
|
||||||
|
<p class="already-logged-in">
|
||||||
|
You're logged in as <span class="username">{{ existingUsername }}</span>
|
||||||
|
</p>
|
||||||
|
<Button class="login-button" :click="stayLoggedIn">Proceed to Dashboard</Button>
|
||||||
|
<Button class="login-button" :click="getOut">Logout</Button>
|
||||||
|
<span class="already-logged-in-note">
|
||||||
|
You need to log out, in order to proceed as a different user.
|
||||||
|
</span>
|
||||||
|
<transition name="bounce">
|
||||||
|
<p :class="`login-error-message ${status}`" v-show="message">{{ message }}</p>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
<!-- Main login form -->
|
||||||
|
<form class="login-form" v-if="(!isUserAlreadyLoggedIn) && isAuthenticationEnabled">
|
||||||
<h2 class="login-title">{{ $t('login.title') }}</h2>
|
<h2 class="login-title">{{ $t('login.title') }}</h2>
|
||||||
<Input
|
<Input
|
||||||
v-model="username"
|
v-model="username"
|
||||||
@ -28,6 +44,27 @@
|
|||||||
<p :class="`login-error-message ${status}`" v-show="message">{{ message }}</p>
|
<p :class="`login-error-message ${status}`" v-show="message">{{ message }}</p>
|
||||||
</transition>
|
</transition>
|
||||||
</form>
|
</form>
|
||||||
|
<!-- Guest login form -->
|
||||||
|
<form class="guest-form"
|
||||||
|
v-if="appConfig.enableGuestAccess && !isUserAlreadyLoggedIn && isAuthenticationEnabled">
|
||||||
|
<h2 class="login-title">Guest Access</h2>
|
||||||
|
<Button class="login-button" :click="guestLogin">
|
||||||
|
Proceed as Guest
|
||||||
|
</Button>
|
||||||
|
<p class="guest-intro">
|
||||||
|
This instance has guest access enabled.<br>
|
||||||
|
Guests have view-only access to dashboards,
|
||||||
|
so cannot write any changes to disk.
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<!-- Edge case - guest mode enabled, but no users configured -->
|
||||||
|
<div class="not-configured" v-if="!isAuthenticationEnabled">
|
||||||
|
<h2>Error</h2>
|
||||||
|
<p>Authentication is not enabled, or no users have been configured</p>
|
||||||
|
<Button class="login-button" :click="guestLogin">
|
||||||
|
Go Home
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -36,7 +73,12 @@ import router from '@/router';
|
|||||||
import Button from '@/components/FormElements/Button';
|
import Button from '@/components/FormElements/Button';
|
||||||
import Input from '@/components/FormElements/Input';
|
import Input from '@/components/FormElements/Input';
|
||||||
import Defaults, { localStorageKeys } from '@/utils/defaults';
|
import Defaults, { localStorageKeys } from '@/utils/defaults';
|
||||||
import { checkCredentials, login } from '@/utils/Auth';
|
import {
|
||||||
|
checkCredentials,
|
||||||
|
login,
|
||||||
|
isLoggedIn,
|
||||||
|
logout,
|
||||||
|
} from '@/utils/Auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'login',
|
name: 'login',
|
||||||
@ -76,6 +118,21 @@ export default {
|
|||||||
successMsg: this.$t('login.success-message'),
|
successMsg: this.$t('login.success-message'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
existingUsername() {
|
||||||
|
return localStorage[localStorageKeys.USERNAME];
|
||||||
|
},
|
||||||
|
isUserAlreadyLoggedIn() {
|
||||||
|
const users = this.appConfig.auth;
|
||||||
|
const loggedIn = (!users || users.length === 0 || isLoggedIn(users));
|
||||||
|
return (loggedIn && this.existingUsername);
|
||||||
|
},
|
||||||
|
isGuestAccessEnabled() {
|
||||||
|
if (!this.appConfig || !this.appConfig.enableGuestAccess) return false;
|
||||||
|
return this.appConfig.enableGuestAccess;
|
||||||
|
},
|
||||||
|
isAuthenticationEnabled() {
|
||||||
|
return (this.appConfig && this.appConfig.auth && this.appConfig.auth.length > 0);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/* Checks form is filled in, then initiates the login, and redirects to /home */
|
/* Checks form is filled in, then initiates the login, and redirects to /home */
|
||||||
@ -93,10 +150,41 @@ export default {
|
|||||||
this.status = response.correct ? 'success' : 'error';
|
this.status = response.correct ? 'success' : 'error';
|
||||||
if (response.correct) { // Yay, credentials were correct :)
|
if (response.correct) { // Yay, credentials were correct :)
|
||||||
login(this.username, this.password, timeout); // Login, to set the cookie
|
login(this.username, this.password, timeout); // Login, to set the cookie
|
||||||
|
this.goHome();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Calls function to double-check guest access enabled, then log in as guest */
|
||||||
|
guestLogin() {
|
||||||
|
const isAllowed = this.isGuestAccessEnabled;
|
||||||
|
if (isAllowed) {
|
||||||
|
this.$toasted.show('Logged in as Guest, Redirecting...', { className: 'toast-success' });
|
||||||
|
this.goHome();
|
||||||
|
} else {
|
||||||
|
this.$toasted.show('Guest access not allowed', { className: 'toast-error' });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Calls logout, shows status message, and refreshed page */
|
||||||
|
getOut() {
|
||||||
|
logout();
|
||||||
|
this.status = 'success';
|
||||||
|
this.message = 'Logging out...';
|
||||||
|
this.refreshPage();
|
||||||
|
},
|
||||||
|
/* Logged in user redirects to home page */
|
||||||
|
stayLoggedIn() {
|
||||||
|
this.status = 'success';
|
||||||
|
this.message = 'Redirecting...';
|
||||||
|
this.goHome();
|
||||||
|
},
|
||||||
|
/* Refreshes the page */
|
||||||
|
refreshPage() {
|
||||||
|
setTimeout(() => { location.reload(); }, 250); // eslint-disable-line no-restricted-globals
|
||||||
|
},
|
||||||
|
/* Redirects to the homepage */
|
||||||
|
goHome() {
|
||||||
setTimeout(() => { // Wait a short while, then redirect back home
|
setTimeout(() => { // Wait a short while, then redirect back home
|
||||||
router.push({ path: '/' });
|
router.push({ path: '/' });
|
||||||
}, 250);
|
}, 250);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/* Since Theme setter isn't loaded at this point, we must manually get and apply users theme */
|
/* Since Theme setter isn't loaded at this point, we must manually get and apply users theme */
|
||||||
setTheme() {
|
setTheme() {
|
||||||
@ -119,23 +207,43 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
min-height: calc(100vh - var(--footer-height));
|
min-height: calc(100vh - var(--footer-height));
|
||||||
|
|
||||||
|
/* User is already logged in note */
|
||||||
|
div.already-logged-in {
|
||||||
|
margin: 0 auto 0.5rem;
|
||||||
|
p.already-logged-in {
|
||||||
|
margin: 0 auto 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
span.username {
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
span.already-logged-in-note {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: var(--dimming-factor);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Login form container */
|
/* Login form container */
|
||||||
form.login-form {
|
form.login-form, form.guest-form, div.already-logged-in, div.not-configured {
|
||||||
background: var(--login-form-background);
|
background: var(--login-form-background);
|
||||||
color: var(--login-form-color);
|
color: var(--login-form-color);
|
||||||
border: 1px solid var(--login-form-color);
|
border: 1px solid var(--login-form-color);
|
||||||
border-radius: var(--curve-factor);
|
border-radius: var(--curve-factor);
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
margin: 2rem auto;
|
margin: 2rem;
|
||||||
|
max-width: 22rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
/* Login form title */
|
/* Login form title */
|
||||||
h2.login-title {
|
h2 {
|
||||||
font-size: 3rem;
|
font-size: 2rem;
|
||||||
margin: 0 0 1rem 0;
|
margin: 0 0 1rem 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -177,6 +285,11 @@ export default {
|
|||||||
&.success { color: var(--success); }
|
&.success { color: var(--success); }
|
||||||
&.error { color: var(--warning); }
|
&.error { color: var(--warning); }
|
||||||
}
|
}
|
||||||
|
p.guest-intro {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: var(--dimming-factor);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user