implemented some login stuff.

This commit is contained in:
sockenklaus
2023-07-04 01:08:21 +02:00
parent 7a2b63ee07
commit f98fc36e51
11 changed files with 124 additions and 40 deletions

View File

@@ -3,10 +3,12 @@ import { schema } from '@ioc:Adonis/Core/Validator'
import Logger from '@ioc:Adonis/Core/Logger' import Logger from '@ioc:Adonis/Core/Logger'
export default class AuthController { export default class AuthController {
public async login({ auth, request, session, response }: HttpContextContract){ public async login({ auth, request, response }: HttpContextContract){
const { username, password } = request.all() Logger.info("entering login")
/*const loginSchema = schema.create({ Logger.info(JSON.stringify(request.all()))
const loginSchema = schema.create({
username: schema.string({trim: true}), username: schema.string({trim: true}),
password: schema.string() password: schema.string()
}) })
@@ -14,18 +16,12 @@ export default class AuthController {
const { username, password } = await request.validate({ const { username, password } = await request.validate({
schema: loginSchema, schema: loginSchema,
messages: { messages: {
required: 'This field is required' required: 'This field is required'
} }
})*/ })
try { await auth.attempt(username, password)
await auth.attempt(username, password) response.redirect().toRoute('events.index')
response.redirect('/events')
} catch (error) {
session.flash("notification", "Login fehlgeschlagen")
response.redirect("/")
}
} }
public async logout({ auth, response }: HttpContextContract) { public async logout({ auth, response }: HttpContextContract) {

View File

@@ -1,16 +1,21 @@
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User' import User from 'App/Models/User'
import Logger from '@ioc:Adonis/Core/Logger'
export default class UsersController { export default class UsersController {
public async index({}: HttpContextContract) { public async index({ auth, response, inertia }: HttpContextContract) {
if(auth.user?.isAdmin) {
return inertia.render('Users/Index')
}
else response.redirect().toRoute('events.index')
} }
public async create({ auth, inertia }: HttpContextContract) { public async create({ auth, inertia }: HttpContextContract) {
if(auth.user?.isAdmin) { if(auth.user?.isAdmin) {
inertia.render('Users/Create') inertia.render('Users/Create')
} else { } else {
inertia
} }
} }

View File

@@ -15,6 +15,7 @@
import Logger from '@ioc:Adonis/Core/Logger' import Logger from '@ioc:Adonis/Core/Logger'
import HttpExceptionHandler from '@ioc:Adonis/Core/HttpExceptionHandler' import HttpExceptionHandler from '@ioc:Adonis/Core/HttpExceptionHandler'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ExceptionHandler extends HttpExceptionHandler { export default class ExceptionHandler extends HttpExceptionHandler {
protected statusPages = { protected statusPages = {
@@ -26,4 +27,21 @@ export default class ExceptionHandler extends HttpExceptionHandler {
constructor() { constructor() {
super(Logger) super(Logger)
} }
public async handle(error: any, ctx: HttpContextContract) {
const { session, response } = ctx;
/**
* Handle failed authentication attempt
*/
if (['E_INVALID_AUTH_PASSWORD', 'E_INVALID_AUTH_UID'].includes(error.code)) {
session.flash('errors', { login: error.message });
return response.redirect().back();
}
/**
* Forward rest of the exceptions to the parent class
*/
return super.handle(error, ctx);
}
} }

2
components.d.ts vendored
View File

@@ -7,10 +7,12 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
NAlert: typeof import('naive-ui')['NAlert']
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
NForm: typeof import('naive-ui')['NForm'] NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem'] NFormItem: typeof import('naive-ui')['NFormItem']
NInput: typeof import('naive-ui')['NInput'] NInput: typeof import('naive-ui')['NInput']
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
} }
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<LoginLayout> <LoginLayout>
<MainNav /> <MainNav />
<slot /> <slot></slot>
</LoginLayout> </LoginLayout>
</template> </template>

View File

@@ -1,7 +1,9 @@
<template> <template>
<main class="bg-slate-100 flex justify-center h-screen"> <main class="bg-slate-100 flex justify-center h-screen">
<div class="m-auto bg-white p-4 border rounded space-y-4 drop-shadow"> <div class="m-auto bg-white p-4 border rounded space-y-4 drop-shadow">
<slot></slot> <n-message-provider>
<slot></slot>
</n-message-provider>
</div> </div>
</main> </main>
</template> </template>

View File

@@ -4,7 +4,7 @@
<script setup> <script setup>
import { Link, usePage } from '@inertiajs/vue3' import { Link, usePage } from '@inertiajs/vue3'
import { h, ref } from 'vue'; import { h, ref, watch } from 'vue';
import { NIcon, NButton } from 'naive-ui' import { NIcon, NButton } from 'naive-ui'
import { import {
GroupsFilled as Users, GroupsFilled as Users,
@@ -13,7 +13,6 @@
} from '@vicons/material' } from '@vicons/material'
const { request } = usePage().props const { request } = usePage().props
const activeKey = ref(request.url) const activeKey = ref(request.url)
const menuOptions = ref([ const menuOptions = ref([
@@ -30,7 +29,7 @@
icon: renderIcon(Events) icon: renderIcon(Events)
}, },
{ {
label: () => label: () =>
h( h(
Link, { Link, {
href: "/users", href: "/users",

View File

@@ -1,5 +1,7 @@
<template> <template>
<div>
Bin in Events
</div>
</template> </template>
<script setup> <script setup>

View File

@@ -2,42 +2,100 @@
<n-form <n-form
label-placement="top" label-placement="top"
:model="formValue" :model="form"
ref="formRef" @submit.prevent="onClickLogin"
:rules="rules" :rules="rules"
ref="formRef"
> >
<n-form-item label="Benutzername" path="username"> <n-form-item
<n-input v-model:value="formValue.username" placeholder="Benutzername" /> label="Benutzername"
path="username"
>
<n-input
v-model:value="form.username"
placeholder="Benutzername"
@keydown.enter="onClickLogin"
/>
</n-form-item> </n-form-item>
<n-form-item label="Passwort" path="password">
<n-input v-model:value="formValue.password" placeholder="Passwort"></n-input> <n-form-item
label="Passwort"
path="password"
>
<n-input
v-model:value="form.password"
placeholder="Passwort"
@keydown.enter="onClickLogin"
type="password"
show-password-on="click"
/>
</n-form-item> </n-form-item>
<div class="flex justify-center"> <div class="flex justify-center">
<n-button class="bg-[#18A058]" type="success" @click="onClickLogin">Anmelden</n-button> <n-button
class="bg-[#18A058]"
type="success"
@click="onClickLogin"
:disabled="!form.password || !form.username"
>Anmelden</n-button>
</div> </div>
</n-form> </n-form>
<div>
{{ response }}
</div>
</template> </template>
<script setup> <script setup>
import { ref, reactive } from 'vue' import { ref, reactive, watch } from 'vue'
import { useMessage } from 'naive-ui'
import { router } from '@inertiajs/vue3' import { router } from '@inertiajs/vue3'
import LoginLayout from '@/layouts/LoginLayout.vue' import LoginLayout from '@/layouts/LoginLayout.vue'
defineOptions({ layout: LoginLayout }) defineOptions({ layout: LoginLayout })
const props = defineProps(['response']) const message = useMessage()
const props = defineProps(['errors'])
const flashErrors = ref(props.errors)
const formRef = ref(null) const form = ref({
const formValue = reactive({
username: '', username: '',
password: '', password: '',
}) })
const rules = ref(undefined) const formRef = ref(null)
const rules = ref({
username: {
required: true,
message: "Benutzername erforderlich",
trigger: "input",
},
password: {
required: true,
message: "Passwort erforderlich",
trigger: "input",
}
})
watch(props, async(newVal, oldVal) => {
flashErrors.value = props.errors
if(flashErrors.value?.login) {
message.error(translateLoginError(flashErrors.value.login),{
closable: true
})
}
})
function translateLoginError(errorMsg) {
switch(errorMsg.split(":")[0]) {
case 'E_INVALID_AUTH_PASSWORD':
return "Falsches Passwort eingegeben."
case 'E_INVALID_AUTH_UID':
return "Benutzername nicht gefunden"
}
}
function onClickLogin(){ function onClickLogin(){
router.post('/login', formValue) flashErrors.value = null
formRef.value?.validate((errors) => {
if(!errors) router.post('login', form.value)
})
} }
</script> </script>

View File

@@ -1,5 +1,7 @@
<template> <template>
<div>
Bin in Users
</div>
</template> </template>
<script setup> <script setup>

View File

@@ -23,7 +23,7 @@ import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
Route.get('/', 'HomeController.index') Route.get('/', 'HomeController.index')
Route.get('/login', async({inertia, response}: HttpContextContract) =>{ Route.get('/login', async({inertia}: HttpContextContract) =>{
return inertia.render('Login') return inertia.render('Login')
}) })