add new landing page firstlogin close #18
This commit is contained in:
@@ -140,3 +140,4 @@ Friday: Fritig
|
||||
Saturday: Samstig
|
||||
Sunday: Suntig
|
||||
currentPassword: Aktuelles Passwort
|
||||
addFirstUser: Füeg erste Admin Benutzer hinzu
|
||||
|
||||
@@ -140,3 +140,4 @@ Friday: Freitag
|
||||
Saturday: Samstag
|
||||
Sunday: Sonntag
|
||||
currentPassword: Aktuelles Passwort
|
||||
addFirstUser: Füge erster Admin Benutzer hinzu
|
||||
|
||||
@@ -140,3 +140,4 @@ Friday: Friday
|
||||
Saturday: Saturday
|
||||
Sunday: Sunday
|
||||
currentPassword: Current Password
|
||||
addFirstUser: Add first Admin User
|
||||
|
||||
@@ -8,6 +8,7 @@ export default boot(async ({ router }) => {
|
||||
// load user
|
||||
try {
|
||||
const { data } = await appApi.get('/login/me');
|
||||
userStore.setFirstLogin(data.newDatabase);
|
||||
|
||||
data.role.role = data.role;
|
||||
await userStore.setUser(data);
|
||||
@@ -36,7 +37,7 @@ export default boot(async ({ router }) => {
|
||||
// Save the route after every successful navigation
|
||||
router.afterEach((to) => {
|
||||
// Don't save login page as "last route"
|
||||
if (to.path !== '/login' && to.path !== '/') {
|
||||
if (to.path !== '/login' && to.path !== '/firstlogin' && to.path !== '/') {
|
||||
setLocalLastRoute(to.fullPath);
|
||||
}
|
||||
});
|
||||
|
||||
82
src/pages/FirstLogin.vue
Normal file
82
src/pages/FirstLogin.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<SiteTitle :title="$t('addFirstUser')" />
|
||||
<div :class="$q.screen.width > 600 ? 'q-ma-xl q-pa-xs' : 'q-ma-none q-pa-none'">
|
||||
<q-card :class="$q.screen.width > 600 ? 'q-ma-xl q-pa-xl' : 'q-gutter-md'">
|
||||
<q-form ref="form">
|
||||
<div class="q-pt-md">
|
||||
<div class="row justify-center q-gutter-md">
|
||||
<q-input
|
||||
class="col-6 required"
|
||||
:label="$t('user')"
|
||||
filled
|
||||
:lazy-rules="false"
|
||||
:rules="[(val) => !!val || $t('userIsRequired')]"
|
||||
v-model="localUser.user"
|
||||
autofocus
|
||||
></q-input>
|
||||
<q-input
|
||||
class="col-6 required"
|
||||
:label="$t('email')"
|
||||
filled
|
||||
:lazy-rules="false"
|
||||
:rules="[(val) => !!val || $t('emailIsRequired')]"
|
||||
v-model="localUser.email"
|
||||
></q-input>
|
||||
<EnterNewPassword class="col-6 required" v-model:password="localUser.password!" />
|
||||
</div>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">{{ $t('save') }}</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import type { User } from 'src/vueLib/models/users';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
import { validateQForm } from 'src/vueLib/utils/validation';
|
||||
import { i18n } from 'src/boot/lang';
|
||||
import { DefaultSettings } from 'src/vueLib/models/settings';
|
||||
import EnterNewPassword from 'src/vueLib/login/EnterNewPassword.vue';
|
||||
import { defaultPermissions } from 'src/vueLib/checkboxes/permissions';
|
||||
import SiteTitle from 'src/vueLib/general/SiteTitle.vue';
|
||||
|
||||
const { NotifyResponse } = useNotify();
|
||||
const form = ref();
|
||||
const localUser = ref<User>({
|
||||
user: '',
|
||||
email: '',
|
||||
});
|
||||
|
||||
async function save() {
|
||||
if (!(await validateQForm(form.value))) {
|
||||
NotifyResponse(i18n.global.t('notAllRequiredFieldsFilled'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
localUser.value.role = { role: 'admin', permissions: defaultPermissions };
|
||||
localUser.value.role.permissions.forEach((p) => (p.permission = 31));
|
||||
localUser.value.settings = DefaultSettings();
|
||||
|
||||
await appApi
|
||||
.post('users/add', JSON.stringify(localUser.value))
|
||||
.then(() => {
|
||||
window.location.reload();
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse(err, 'error');
|
||||
return;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.required .q-field__label::after {
|
||||
content: ' *';
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
@@ -17,6 +17,8 @@ import { useUserStore } from 'src/vueLib/login/userStore';
|
||||
* with the Router instance.
|
||||
*/
|
||||
|
||||
export let routerInstance: ReturnType<typeof createRouter>;
|
||||
|
||||
export default defineRouter(function (/* { store, ssrContext } */) {
|
||||
const createHistory = process.env.SERVER
|
||||
? createMemoryHistory
|
||||
@@ -34,10 +36,16 @@ export default defineRouter(function (/* { store, ssrContext } */) {
|
||||
history: createHistory(process.env.VUE_ROUTER_BASE),
|
||||
});
|
||||
|
||||
routerInstance = Router;
|
||||
|
||||
Router.beforeEach((to, from, next) => {
|
||||
const userStore = useUserStore();
|
||||
const isLoggedIn = userStore.isAuthenticated;
|
||||
if (to.meta.requiresAuth && !isLoggedIn) {
|
||||
if (!userStore.$state.firstLogin && to.path === '/firstlogin') {
|
||||
next('/login');
|
||||
} else if (userStore.$state.firstLogin && to.path !== '/firstlogin') {
|
||||
next('/firstlogin');
|
||||
} else if (to.meta.requiresAuth && !isLoggedIn) {
|
||||
next('/login');
|
||||
} else if (
|
||||
to.meta.requiresAdmin &&
|
||||
|
||||
@@ -9,6 +9,10 @@ const routes: RouteRecordRaw[] = [
|
||||
path: '',
|
||||
component: () => import('pages/LoginPage.vue'),
|
||||
},
|
||||
{
|
||||
path: 'firstlogin',
|
||||
component: () => import('pages/FirstLogin.vue'),
|
||||
},
|
||||
{
|
||||
path: 'login',
|
||||
component: () => import('pages/LoginPage.vue'),
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useNotify } from '../general/useNotify';
|
||||
import type { Settings } from '../models/settings';
|
||||
import { appName, logo } from '../models/settings';
|
||||
import { clearLocalStorage, setLocalSettings } from 'src/localstorage/localStorage';
|
||||
import { routerInstance } from 'src/router';
|
||||
|
||||
const refreshTime = 10000;
|
||||
let intervalId: ReturnType<typeof setInterval> | null = null;
|
||||
@@ -55,6 +56,7 @@ export function useLogin() {
|
||||
userStore.clearUser();
|
||||
clearLocalStorage();
|
||||
stopRefreshInterval();
|
||||
await routerInstance.push('/login');
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
|
||||
@@ -12,6 +12,7 @@ const { NotifyResponse } = useNotify();
|
||||
export const useUserStore = defineStore('user', {
|
||||
state: (): UserState => ({
|
||||
user: null,
|
||||
firstLogin: false,
|
||||
}),
|
||||
getters: {
|
||||
isAuthenticated: (state: UserState): boolean => {
|
||||
@@ -42,6 +43,9 @@ export const useUserStore = defineStore('user', {
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setFirstLogin(b: boolean) {
|
||||
this.firstLogin = b;
|
||||
},
|
||||
async setUser(user: User) {
|
||||
await appApi
|
||||
.get('roles?role=' + user.role?.role)
|
||||
|
||||
@@ -8,8 +8,10 @@ export interface User {
|
||||
role: Role;
|
||||
permissions?: Permissions;
|
||||
settings?: Settings;
|
||||
newDatabase?: boolean;
|
||||
}
|
||||
|
||||
export interface UserState {
|
||||
user: User | null;
|
||||
firstLogin: boolean;
|
||||
}
|
||||
|
||||
@@ -227,16 +227,12 @@ function openPwdDialog(user: User) {
|
||||
|
||||
//change password api request
|
||||
async function changePassword(user: User) {
|
||||
console.log(8, user);
|
||||
if (user.password == user.newPassword) {
|
||||
NotifyResponse(i18n.global.t('samePasswordEntered'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
await appApi
|
||||
.post('/users/new/password', user)
|
||||
.then((resp) => console.log(67, resp))
|
||||
.catch((err) => console.error(err));
|
||||
await appApi.post('/users/new/password', user).catch((err) => console.error(err));
|
||||
changePwdDialog.value.close();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user