Account login possible

This commit is contained in:
2024-09-11 14:54:33 +02:00
parent fd06b8a9a4
commit 55fd203c7f
10 changed files with 122 additions and 48 deletions

View File

@@ -23,7 +23,7 @@ export const sequelize = new Sequelize({
export function startDatabase() { export function startDatabase() {
// Create database and tables // Create database and tables
sequelize.sync({ force: true }) sequelize.sync({ force: false })
.then(() => { .then(() => {
console.log(`Database & tables created!`) console.log(`Database & tables created!`)
}) })

View File

@@ -14,13 +14,15 @@ account.get("/", (req: Request, res: Response, next: NextFunction) => {
}) })
// Creating a new user // Creating a new user
account.post("/", (req: Request, res: Response, next: NextFunction) => { account.post("/register", (req: Request, res: Response, next: NextFunction) => {
if (!validateString(req.body.username, 4)) if (!validateString(req.body.username, 4))
{ {
// Status: 400 Bad request
res.status(400).send({ error: "Username too short!" }) res.status(400).send({ error: "Username too short!" })
} }
else if (!validateString(req.body.password, 8)) else if (!validateString(req.body.password, 8))
{ {
// Status: 400 Bad request
res.status(400).send({ error: "Password too short!" }) res.status(400).send({ error: "Password too short!" })
} }
else else
@@ -28,9 +30,31 @@ account.post("/", (req: Request, res: Response, next: NextFunction) => {
Account.create(req.body) Account.create(req.body)
.then(account => { .then(account => {
res.json(account) res.json(account)
// Status: 200 OK
res.status(200).send() res.status(200).send()
}).catch(reason => { }).catch(reason => {
// Status: 400 Bad request
res.status(400).send({ error: reason }) res.status(400).send({ error: reason })
}) })
} }
})
account.post("/login", (req: Request, res: Response, next: NextFunction) => {
Account.findOne({ raw: true, where: { username: req.body.username }})
.then(account => {
if (account != null) {
if (account.password == req.body.password) {
// Status: 200 OK
res.status(200).send({ userAccountId: account.id })
} else {
// Status: 401 Unauthorized
res.status(401).send()
}
} else {
// Status: 401 Unauthorized
res.status(401).send()
}
}
)
}) })

View File

@@ -1,13 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue';
import { useTheme } from 'vuetify/lib/framework.mjs'; import { useTheme } from 'vuetify/lib/framework.mjs';
import { useUserStore } from './data/stores/userStore'; import { useUserStore } from './data/stores/userStore';
import vuetify from './plugins/vuetify';
import { useBasketStore } from './data/stores/basketStore';
import { i18n } from './plugins/i18n'; import { i18n } from './plugins/i18n';
import { ref } from 'vue';
import vuetify from './plugins/vuetify';
import navigationDrawer from './components/navigationDrawer.vue';
const userStore = useUserStore() const userStore = useUserStore()
const basketStore = useBasketStore()
const theme = useTheme() const theme = useTheme()
const navRail = ref(vuetify.display.mobile) const navRail = ref(vuetify.display.mobile)
@@ -24,39 +23,7 @@ i18n.global.locale = userStore.language
</v-app-bar> </v-app-bar>
<v-navigation-drawer :rail="navRail" permanent> <v-navigation-drawer :rail="navRail" permanent>
<v-list> <navigation-drawer v-model:nav-rail="navRail" />
<v-list-subheader>
<div v-if="!navRail">{{ $t('menu.shopping') }}</div>
<div v-else></div>
</v-list-subheader>
<v-list-item :title="$t('menu.products')" prepend-icon="mdi-store" to="/" link />
<v-list-item :title="$t('menu.basket')" to="/basket" link >
<template v-slot:prepend>
<v-badge color="primary" :content="basketStore.itemsInBasket.length">
<v-icon icon="mdi-cart" />
</v-badge>
</template>
</v-list-item>
<v-divider />
<v-list-subheader>
<div v-if="!navRail">{{ $t('menu.account') }}</div>
<div v-else></div>
</v-list-subheader>
<v-list-item :title="$t('menu.login')" prepend-icon="mdi-login" to="/login" link />
<v-list-item :title="$t('menu.account')" prepend-icon="mdi-account" to="/account" link />
<v-list-item :title="$t('menu.orders')" prepend-icon="mdi-cart-check" to="/orders" link />
<v-divider />
<v-list-subheader>
<div v-if="!navRail">{{ $t('menu.systemAndHelp') }}</div>
<div v-else></div>
</v-list-subheader>
<v-list-item :title="$t('menu.helpInstructions')" prepend-icon="mdi-chat-question" to="/help" link />
<v-list-item :title="$t('menu.preferences')" prepend-icon="mdi-cog" to="/preferences" link />
</v-list>
</v-navigation-drawer> </v-navigation-drawer>
<v-main> <v-main>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
import { useBasketStore } from '@/data/stores/basketStore';
import vuetify from '@/plugins/vuetify';
const userStore = useUserStore()
const basketStore = useBasketStore()
const navRail = defineModel("navRail", { type: Boolean })
</script>
<template>
<v-list>
<v-list-subheader>
<div v-if="!navRail">{{ $t('menu.shopping') }}</div>
<div v-else></div>
</v-list-subheader>
<v-list-item :title="$t('menu.products')" prepend-icon="mdi-store" to="/" link />
<v-list-item :title="$t('menu.basket')" to="/basket" link >
<template v-slot:prepend>
<v-badge color="primary" :content="basketStore.itemsInBasket.length">
<v-icon icon="mdi-cart" />
</v-badge>
</template>
</v-list-item>
<v-divider />
<v-list-subheader>
<div v-if="!navRail">{{ $t('menu.account') }}</div>
<div v-else></div>
</v-list-subheader>
<v-list-item v-if="userStore.userAccountId == -1" :title="$t('menu.login')" prepend-icon="mdi-login" to="/login" link />
<v-list-item v-else :title="$t('logout')" prepend-icon="mdi-logout" @click="userStore.userAccountId = -1" link />
<v-list-item v-if="userStore.userAccountId != -1" :title="$t('menu.account')" prepend-icon="mdi-account" to="/account" link />
<v-list-item v-if="userStore.userAccountId != -1" :title="$t('menu.orders')" prepend-icon="mdi-cart-check" to="/orders" link />
<v-divider />
<v-list-subheader>
<div v-if="!navRail">{{ $t('menu.systemAndHelp') }}</div>
<div v-else></div>
</v-list-subheader>
<v-list-item :title="$t('menu.helpInstructions')" prepend-icon="mdi-chat-question" to="/help" link />
<v-list-item :title="$t('menu.preferences')" prepend-icon="mdi-cog" to="/preferences" link />
</v-list>
</template>

View File

@@ -6,6 +6,7 @@ import { LanguageEnum } from "../enums/languageEnum";
export const useUserStore = defineStore('user', { export const useUserStore = defineStore('user', {
state: () => ({ state: () => ({
theme: useLocalStorage<ThemeEnum>("hackmycart/userStore/theme", ThemeEnum.DARKRED), theme: useLocalStorage<ThemeEnum>("hackmycart/userStore/theme", ThemeEnum.DARKRED),
language: useLocalStorage<LanguageEnum>("hackmycart/userStore/language", LanguageEnum.GERMAN) language: useLocalStorage<LanguageEnum>("hackmycart/userStore/language", LanguageEnum.GERMAN),
userAccountId: useLocalStorage<number>("hackmycart/userStore/userAccountId", -1)
}) })
}) })

View File

@@ -46,5 +46,6 @@
"postalCode": "Postal Code", "postalCode": "Postal Code",
"city": "City" "city": "City"
}, },
"backToLogin": "Back to Login" "backToLogin": "Back to Login",
"logout": "Logout"
} }

View File

@@ -46,5 +46,6 @@
"postalCode": "Postleitzahl", "postalCode": "Postleitzahl",
"city": "Stadt" "city": "Stadt"
}, },
"backToLogin": "Zurück zum Login" "backToLogin": "Zurück zum Login",
"logout": "Ausloggen"
} }

View File

@@ -20,7 +20,7 @@ const banner = ref(new BannerModel())
<v-expand-transition> <v-expand-transition>
<v-row v-if="!showRegisterCard"> <v-row v-if="!showRegisterCard">
<v-col> <v-col>
<login-form v-model:show-register-card="showRegisterCard" /> <login-form v-model:show-register-card="showRegisterCard" v-model:banner="banner" />
</v-col> </v-col>
</v-row> </v-row>
</v-expand-transition> </v-expand-transition>

View File

@@ -1,5 +1,37 @@
<script setup lang="ts"> <script setup lang="ts">
import BannerModel from '@/data/models/bannerModel';
import { useUserStore } from '@/data/stores/userStore';
import axios from 'axios';
import { ref } from 'vue';
const userStore = useUserStore()
const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false }) const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false })
const banner = defineModel("banner", { type: BannerModel })
const username = ref("")
const password = ref("")
function startLogin() {
axios.post('http://127.0.0.1:3000/accounts/login', {
username: username.value,
password: password.value
})
.then(res => {
if (res.status == 200) {
banner.value.message = "Logged in!"
banner.value.color = "green"
banner.value.icon = "mdi-check"
banner.value.show = true
userStore.userAccountId = res.data.userAccountId
}
})
.catch(res => {
banner.value.message = "Wrong Username or Password!"
banner.value.color = "red"
banner.value.icon = "mdi-alert-circle"
banner.value.show = true
})
}
</script> </script>
<template> <template>
@@ -7,13 +39,13 @@ const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, defaul
<v-container> <v-container>
<v-row> <v-row>
<v-col> <v-col>
<v-text-field :label="$t('username')" prepend-icon="mdi-account" clearable /> <v-text-field :label="$t('username')" prepend-icon="mdi-account" clearable v-model="username"/>
</v-col> </v-col>
</v-row> </v-row>
<v-row> <v-row>
<v-col> <v-col>
<v-text-field :label="$t('password')" prepend-icon="mdi-key" type="password" clearable /> <v-text-field :label="$t('password')" prepend-icon="mdi-key" type="password" clearable v-model="password" />
</v-col> </v-col>
</v-row> </v-row>
</v-container> </v-container>
@@ -23,7 +55,7 @@ const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, defaul
{{ $t('noAccountRegister') }} {{ $t('noAccountRegister') }}
</v-btn> </v-btn>
<v-spacer /> <v-spacer />
<v-btn variant="outlined" append-icon="mdi-arrow-right" color="primary">{{ $t('login') }}</v-btn> <v-btn variant="outlined" append-icon="mdi-arrow-right" color="primary" @click="startLogin">{{ $t('login') }}</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>

View File

@@ -9,9 +9,9 @@ const banner = defineModel("banner", { required: true, type: BannerModel })
const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false }) const showRegisterCard = defineModel("showRegisterCard", { type: Boolean, default: false })
function registerUser() { function registerUser() {
axios.post('http://127.0.0.1:3000/accounts/', newUser.value) axios.post('http://127.0.0.1:3000/accounts/register', newUser.value)
.then(res => { .then(res => {
console.log(res.status) console.log(res)
if (res.status == 200) { if (res.status == 200) {
banner.value.message = "Created!" banner.value.message = "Created!"
banner.value.color = "green" banner.value.color = "green"
@@ -20,6 +20,7 @@ function registerUser() {
} }
}) })
.catch((error) => { .catch((error) => {
console.log(error)
if (error.status == 400) { if (error.status == 400) {
banner.value.color = "red" banner.value.color = "red"
banner.value.icon = "mdi-alert-circle" banner.value.icon = "mdi-alert-circle"