add new landing page firstlogin close #18
This commit is contained in:
@@ -3,8 +3,8 @@ module backend
|
|||||||
go 1.24.5
|
go 1.24.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.tecamino.com/paadi/access-handler v1.0.29
|
gitea.tecamino.com/paadi/access-handler v1.0.34
|
||||||
gitea.tecamino.com/paadi/memberDB v1.1.13
|
gitea.tecamino.com/paadi/memberDB v1.1.16
|
||||||
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1
|
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1
|
||||||
gitea.tecamino.com/paadi/tecamino-logger v0.2.1
|
gitea.tecamino.com/paadi/tecamino-logger v0.2.1
|
||||||
github.com/gin-contrib/cors v1.7.6
|
github.com/gin-contrib/cors v1.7.6
|
||||||
@@ -14,7 +14,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.tecamino.com/paadi/dbHandler v1.1.7 // indirect
|
gitea.tecamino.com/paadi/dbHandler v1.1.10 // indirect
|
||||||
github.com/bytedance/sonic v1.14.0 // indirect
|
github.com/bytedance/sonic v1.14.0 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
gitea.tecamino.com/paadi/access-handler v1.0.29 h1:FZ67co/rfJffftT6xOp6psZKFtdEReaAR7PnEZi7ltI=
|
gitea.tecamino.com/paadi/access-handler v1.0.34 h1:6P65HiusSfvgv/ezOvxSahqyRJMK9UrxtGsz6loLoUk=
|
||||||
gitea.tecamino.com/paadi/access-handler v1.0.29/go.mod h1:Dmme8URu3lENPhlkZcdEeIKm8VMlAgT/jNLECLLS7Vs=
|
gitea.tecamino.com/paadi/access-handler v1.0.34/go.mod h1:HyMp1WvzmqLw8Ljt3r1qlF8fY+T5WFXr9Da/CTIM0H8=
|
||||||
gitea.tecamino.com/paadi/dbHandler v1.1.7 h1:NqVbxbUwd7EZX6HYntyLYwwPbyTPevOhIBTFqoCVqOU=
|
gitea.tecamino.com/paadi/dbHandler v1.1.10 h1:zZQbDTJ0bu6CIW90Zms8yYIzTLHtWPNhVKRxLUXEDuE=
|
||||||
gitea.tecamino.com/paadi/dbHandler v1.1.7/go.mod h1:y/xn/POJg1DO++67uKvnO23lJQgh+XFQq7HZCS9Getw=
|
gitea.tecamino.com/paadi/dbHandler v1.1.10/go.mod h1:y/xn/POJg1DO++67uKvnO23lJQgh+XFQq7HZCS9Getw=
|
||||||
gitea.tecamino.com/paadi/memberDB v1.1.13 h1:P5UsTt3d8829H9d3vfMAWpDN7ONqwhr8ndIuL9lBuvQ=
|
gitea.tecamino.com/paadi/memberDB v1.1.16 h1:z8v0BSLaiP7pE+ad2LUycBJf8SFOOlbyASoxvrO1CpM=
|
||||||
gitea.tecamino.com/paadi/memberDB v1.1.13/go.mod h1:FRbhFgXq4jDpfCrCfHCVr7VcA44fR8J3XXQFeO6QSBk=
|
gitea.tecamino.com/paadi/memberDB v1.1.16/go.mod h1:xv2MA05nKh45NTnBQewaFeRJ2fs5dgcE7qTjmIjtqIA=
|
||||||
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1 h1:vAq7mwUxlxJuLzCQSDMrZCwo8ky5usWi9Qz+UP+WnkI=
|
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1 h1:vAq7mwUxlxJuLzCQSDMrZCwo8ky5usWi9Qz+UP+WnkI=
|
||||||
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1/go.mod h1:+tmf1rjPaKEoNeUcr1vdtoFIFweNG3aUGevDAl3NMBk=
|
gitea.tecamino.com/paadi/tecamino-dbm v0.1.1/go.mod h1:+tmf1rjPaKEoNeUcr1vdtoFIFweNG3aUGevDAl3NMBk=
|
||||||
gitea.tecamino.com/paadi/tecamino-logger v0.2.1 h1:sQTBKYPdzn9mmWX2JXZBtGBvNQH7cuXIwsl4TD0aMgE=
|
gitea.tecamino.com/paadi/tecamino-logger v0.2.1 h1:sQTBKYPdzn9mmWX2JXZBtGBvNQH7cuXIwsl4TD0aMgE=
|
||||||
|
|||||||
@@ -109,11 +109,8 @@ func main() {
|
|||||||
allowOrigins = append(allowOrigins, fmt.Sprintf("%s%s:9000", httpString, localIP), fmt.Sprintf("%s%s:9500", httpString, localIP))
|
allowOrigins = append(allowOrigins, fmt.Sprintf("%s%s:9000", httpString, localIP), fmt.Sprintf("%s%s:9500", httpString, localIP))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(100, allowOrigins)
|
|
||||||
|
|
||||||
s.Routes.Use(cors.New(cors.Config{
|
s.Routes.Use(cors.New(cors.Config{
|
||||||
AllowOrigins: allowOrigins,
|
AllowOrigins: allowOrigins,
|
||||||
//AllowOrigins: []string{"*"},
|
|
||||||
AllowMethods: []string{"POST", "GET", "DELETE", "OPTIONS"},
|
AllowMethods: []string{"POST", "GET", "DELETE", "OPTIONS"},
|
||||||
AllowHeaders: []string{"Origin", "Content-Type"},
|
AllowHeaders: []string{"Origin", "Content-Type"},
|
||||||
ExposeHeaders: []string{"Content-Length"},
|
ExposeHeaders: []string{"Content-Length"},
|
||||||
|
|||||||
@@ -140,3 +140,4 @@ Friday: Fritig
|
|||||||
Saturday: Samstig
|
Saturday: Samstig
|
||||||
Sunday: Suntig
|
Sunday: Suntig
|
||||||
currentPassword: Aktuelles Passwort
|
currentPassword: Aktuelles Passwort
|
||||||
|
addFirstUser: Füeg erste Admin Benutzer hinzu
|
||||||
|
|||||||
@@ -140,3 +140,4 @@ Friday: Freitag
|
|||||||
Saturday: Samstag
|
Saturday: Samstag
|
||||||
Sunday: Sonntag
|
Sunday: Sonntag
|
||||||
currentPassword: Aktuelles Passwort
|
currentPassword: Aktuelles Passwort
|
||||||
|
addFirstUser: Füge erster Admin Benutzer hinzu
|
||||||
|
|||||||
@@ -140,3 +140,4 @@ Friday: Friday
|
|||||||
Saturday: Saturday
|
Saturday: Saturday
|
||||||
Sunday: Sunday
|
Sunday: Sunday
|
||||||
currentPassword: Current Password
|
currentPassword: Current Password
|
||||||
|
addFirstUser: Add first Admin User
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default boot(async ({ router }) => {
|
|||||||
// load user
|
// load user
|
||||||
try {
|
try {
|
||||||
const { data } = await appApi.get('/login/me');
|
const { data } = await appApi.get('/login/me');
|
||||||
|
userStore.setFirstLogin(data.newDatabase);
|
||||||
|
|
||||||
data.role.role = data.role;
|
data.role.role = data.role;
|
||||||
await userStore.setUser(data);
|
await userStore.setUser(data);
|
||||||
@@ -36,7 +37,7 @@ export default boot(async ({ router }) => {
|
|||||||
// Save the route after every successful navigation
|
// Save the route after every successful navigation
|
||||||
router.afterEach((to) => {
|
router.afterEach((to) => {
|
||||||
// Don't save login page as "last route"
|
// 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);
|
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.
|
* with the Router instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export let routerInstance: ReturnType<typeof createRouter>;
|
||||||
|
|
||||||
export default defineRouter(function (/* { store, ssrContext } */) {
|
export default defineRouter(function (/* { store, ssrContext } */) {
|
||||||
const createHistory = process.env.SERVER
|
const createHistory = process.env.SERVER
|
||||||
? createMemoryHistory
|
? createMemoryHistory
|
||||||
@@ -34,10 +36,16 @@ export default defineRouter(function (/* { store, ssrContext } */) {
|
|||||||
history: createHistory(process.env.VUE_ROUTER_BASE),
|
history: createHistory(process.env.VUE_ROUTER_BASE),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
routerInstance = Router;
|
||||||
|
|
||||||
Router.beforeEach((to, from, next) => {
|
Router.beforeEach((to, from, next) => {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const isLoggedIn = userStore.isAuthenticated;
|
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');
|
next('/login');
|
||||||
} else if (
|
} else if (
|
||||||
to.meta.requiresAdmin &&
|
to.meta.requiresAdmin &&
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ const routes: RouteRecordRaw[] = [
|
|||||||
path: '',
|
path: '',
|
||||||
component: () => import('pages/LoginPage.vue'),
|
component: () => import('pages/LoginPage.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'firstlogin',
|
||||||
|
component: () => import('pages/FirstLogin.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'login',
|
path: 'login',
|
||||||
component: () => import('pages/LoginPage.vue'),
|
component: () => import('pages/LoginPage.vue'),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useNotify } from '../general/useNotify';
|
|||||||
import type { Settings } from '../models/settings';
|
import type { Settings } from '../models/settings';
|
||||||
import { appName, logo } from '../models/settings';
|
import { appName, logo } from '../models/settings';
|
||||||
import { clearLocalStorage, setLocalSettings } from 'src/localstorage/localStorage';
|
import { clearLocalStorage, setLocalSettings } from 'src/localstorage/localStorage';
|
||||||
|
import { routerInstance } from 'src/router';
|
||||||
|
|
||||||
const refreshTime = 10000;
|
const refreshTime = 10000;
|
||||||
let intervalId: ReturnType<typeof setInterval> | null = null;
|
let intervalId: ReturnType<typeof setInterval> | null = null;
|
||||||
@@ -55,6 +56,7 @@ export function useLogin() {
|
|||||||
userStore.clearUser();
|
userStore.clearUser();
|
||||||
clearLocalStorage();
|
clearLocalStorage();
|
||||||
stopRefreshInterval();
|
stopRefreshInterval();
|
||||||
|
await routerInstance.push('/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refresh() {
|
async function refresh() {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const { NotifyResponse } = useNotify();
|
|||||||
export const useUserStore = defineStore('user', {
|
export const useUserStore = defineStore('user', {
|
||||||
state: (): UserState => ({
|
state: (): UserState => ({
|
||||||
user: null,
|
user: null,
|
||||||
|
firstLogin: false,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isAuthenticated: (state: UserState): boolean => {
|
isAuthenticated: (state: UserState): boolean => {
|
||||||
@@ -42,6 +43,9 @@ export const useUserStore = defineStore('user', {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
setFirstLogin(b: boolean) {
|
||||||
|
this.firstLogin = b;
|
||||||
|
},
|
||||||
async setUser(user: User) {
|
async setUser(user: User) {
|
||||||
await appApi
|
await appApi
|
||||||
.get('roles?role=' + user.role?.role)
|
.get('roles?role=' + user.role?.role)
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ export interface User {
|
|||||||
role: Role;
|
role: Role;
|
||||||
permissions?: Permissions;
|
permissions?: Permissions;
|
||||||
settings?: Settings;
|
settings?: Settings;
|
||||||
|
newDatabase?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserState {
|
export interface UserState {
|
||||||
user: User | null;
|
user: User | null;
|
||||||
|
firstLogin: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,16 +227,12 @@ function openPwdDialog(user: User) {
|
|||||||
|
|
||||||
//change password api request
|
//change password api request
|
||||||
async function changePassword(user: User) {
|
async function changePassword(user: User) {
|
||||||
console.log(8, user);
|
|
||||||
if (user.password == user.newPassword) {
|
if (user.password == user.newPassword) {
|
||||||
NotifyResponse(i18n.global.t('samePasswordEntered'), 'error');
|
NotifyResponse(i18n.global.t('samePasswordEntered'), 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await appApi
|
await appApi.post('/users/new/password', user).catch((err) => console.error(err));
|
||||||
.post('/users/new/password', user)
|
|
||||||
.then((resp) => console.log(67, resp))
|
|
||||||
.catch((err) => console.error(err));
|
|
||||||
changePwdDialog.value.close();
|
changePwdDialog.value.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user