Login still a bit buggy but working...

This commit is contained in:
Leo Vasanko 2023-11-03 21:19:26 +00:00
parent 119aba2b3c
commit b759d8324c
8 changed files with 66 additions and 64 deletions

View File

@ -1,19 +1,20 @@
<template> <template>
<button v-if="store.isUserLogged" @click="logout" class="action-button"> <button v-if="store.isUserLogged" @click="logout" class="action-button">
Logout Logout {{ store.user.username }}
</button> </button>
<ModalDialog v-else title="Login"> <ModalDialog v-if="store.user.isOpenLoginModal" title="Login">
<form @submit="login"> <form @submit.prevent="login">
<label for="username">Username:</label <div class="login-container">
><input <label for="username">Username:</label>
<input
id="username" id="username"
name="username" name="username"
autocomplete="username" autocomplete="username"
required required
v-model="loginForm.username" v-model="loginForm.username"
/> />
<label for="password">Password:</label <label for="password">Password:</label>
><input <input
id="password" id="password"
name="password" name="password"
type="password" type="password"
@ -21,32 +22,17 @@
required required
v-model="loginForm.password" v-model="loginForm.password"
/> />
</div>
<h3 v-if="loginForm.error.length > 0" class="error-text"> <h3 v-if="loginForm.error.length > 0" class="error-text">
{{ loginForm.error }} {{ loginForm.error }}
</h3> </h3>
<input type="submit" /> <input type="submit" class="button-login" />
</form> </form>
</ModalDialog> </ModalDialog>
<!--
<a-tooltip title="Login">
<template v-if="DocumentStore.isUserLogged">
<a-button @click="logout" type="text" class="action-button" :icon="h(UserDeleteOutlined)" />
</template>
<template v-else>
<a-button @click="showModal" type="text" class="action-button" :icon="h(UserOutlined)" />
</template>
</a-tooltip>
<a-modal v-model:open="DocumentStore.user.isOpenLoginModal" :confirm-loading="confirmLoading" okText="Login" @ok="login">
<div class="login-container">
</div>
</a-modal>
-->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue' import { reactive, ref } from 'vue'
import { loginUser, logoutUser } from '@/repositories/User' import { loginUser, logoutUser } from '@/repositories/User'
import type { ISimpleError } from '@/repositories/Client' import type { ISimpleError } from '@/repositories/Client'
import { useDocumentStore } from '@/stores/documents' import { useDocumentStore } from '@/stores/documents'
@ -62,7 +48,7 @@ const logout = async () => {
} }
} }
const loginForm = ref({ const loginForm = reactive({
username: '', username: '',
password: '', password: '',
error: '' error: ''
@ -70,16 +56,15 @@ const loginForm = ref({
const login = async () => { const login = async () => {
try { try {
loginForm.value.error = '' loginForm.error = ''
confirmLoading.value = true confirmLoading.value = true
const user = await loginUser(loginForm.value.username, loginForm.value.password) const msg = await loginUser(loginForm.username, loginForm.password)
if (user) { console.log('Logged in', msg)
location.reload() store.login(msg.username, !!msg.privileged)
}
} catch (error) { } catch (error) {
const httpError = error as ISimpleError const httpError = error as ISimpleError
if (httpError.name) { if (httpError.name) {
loginForm.value.error = httpError.message loginForm.error = httpError.message
} }
} finally { } finally {
confirmLoading.value = false confirmLoading.value = false
@ -90,11 +75,14 @@ const login = async () => {
<style scoped> <style scoped>
.login-container { .login-container {
display: grid; display: grid;
gap: 1rem;
grid-template-columns: 1fr 2fr; grid-template-columns: 1fr 2fr;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin: 1rem 0;
} }
.button-login { .button-login {
margin-left: auto;
background-color: var(--secondary-color); background-color: var(--secondary-color);
color: var(--secondary-background); color: var(--secondary-background);
} }

View File

@ -1,9 +1,6 @@
/* Base domain for all request */
export const baseURL = import.meta.env.VITE_URL_DOCUMENT
class ClientClass { class ClientClass {
async post(url: string, data?: Record<string, any>): Promise<any> { async post(url: string, data?: Record<string, any>): Promise<any> {
const res = await fetch(`${baseURL}/`, { const res = await fetch(url, {
method: 'POST', method: 'POST',
headers: { headers: {
accept: 'application/json', accept: 'application/json',
@ -11,7 +8,12 @@ class ClientClass {
}, },
body: data !== undefined ? JSON.stringify(data) : undefined body: data !== undefined ? JSON.stringify(data) : undefined
}) })
const msg = await res.json() let msg
try {
msg = await res.json()
} catch (e) {
throw new SimpleError(res.status, `HTTP ${res.status} ${res.statusText}`)
}
if ('error' in msg) throw new SimpleError(msg.error.code, msg.error.message) if ('error' in msg) throw new SimpleError(msg.error.code, msg.error.message)
return msg return msg
} }

View File

@ -1,5 +1,6 @@
import type { DocumentStore } from '@/stores/documents' import type { DocumentStore } from '@/stores/documents'
import { useDocumentStore } from '@/stores/documents' import { useDocumentStore } from '@/stores/documents'
import createWebSocket from './WS'
export type FUID = string export type FUID = string
@ -63,6 +64,19 @@ export class DocumentHandler {
handleWebSocketMessage(event: MessageEvent) { handleWebSocketMessage(event: MessageEvent) {
const msg = JSON.parse(event.data) const msg = JSON.parse(event.data)
if ("error" in msg) {
if (msg.error.code === 401) {
this.store.user.isLoggedIn = false
this.store.user.isOpenLoginModal = true
} else {
this.store.error = msg.error.message
}
// The server closes the websocket after errors, so we need to reopen it
setTimeout(
() => { this.store.wsWatch = createWebSocket(url_document_watch_ws, this.handleWebSocketMessage)},
1000
)
}
switch (true) { switch (true) {
case !!msg.root: case !!msg.root:
this.handleRootMessage(msg) this.handleRootMessage(msg)

View File

@ -1,5 +1,5 @@
import { createRouter, createWebHashHistory } from 'vue-router' import { createRouter, createWebHashHistory } from 'vue-router'
import ExplorerView from '../views/ExplorerView.vue' import ExplorerView from '@/views/ExplorerView.vue'
const router = createRouter({ const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL), history: createWebHashHistory(import.meta.env.BASE_URL),

View File

@ -15,6 +15,8 @@ type DirectoryData = {
[filename: string]: FileData [filename: string]: FileData
} }
type User = { type User = {
username: string
privileged: boolean
isOpenLoginModal: boolean isOpenLoginModal: boolean
isLoggedIn: boolean isLoggedIn: boolean
} }
@ -42,7 +44,7 @@ export const useDocumentStore = defineStore({
wsWatch: undefined, wsWatch: undefined,
wsUpload: undefined, wsUpload: undefined,
error: '' as string, error: '' as string,
user: { isLoggedIn: false, isOpenLoginModal: false } as User user: { username: "", privileged: false, isLoggedIn: false, isOpenLoginModal: false } as User
}), }),
actions: { actions: {
@ -137,6 +139,12 @@ export const useDocumentStore = defineStore({
for (const d of this.document) { for (const d of this.document) {
if ('mtime' in d) d.modified = formatUnixDate(d.mtime) if ('mtime' in d) d.modified = formatUnixDate(d.mtime)
} }
},
login(username: string, privileged: boolean) {
this.user.username = username
this.user.privileged = privileged
this.user.isLoggedIn = true
this.user.isOpenLoginModal = false
} }
}, },
getters: { getters: {

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,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang=en> <html lang=en>
<script type="module" crossorigin src="/assets/index-2034a7a8.js"></script> <script type="module" crossorigin src="/assets/index-eb4428c4.js"></script>
<link rel="stylesheet" href="/assets/index-c3cea0a2.css"> <link rel="stylesheet" href="/assets/index-683ba1dc.css">
<meta charset=UTF-8> <meta charset=UTF-8>
<title>Cista</title> <title>Cista</title>