Personal data and password change
This commit is contained in:
24
app/Domains/UserManagement/Controllers/ProfileController.php
Normal file
24
app/Domains/UserManagement/Controllers/ProfileController.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\UserManagement\Controllers;
|
||||
|
||||
use App\Providers\InertiaProvider;
|
||||
use App\Scopes\CommonController;
|
||||
|
||||
class ProfileController extends CommonController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
if (!$this->checkAuth()) {
|
||||
return redirect()->intended('/login');
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
$inertiaProvider = new InertiaProvider('UserManagement/Profile', [
|
||||
'username' => $user->username,
|
||||
]);
|
||||
|
||||
return $inertiaProvider->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\UserManagement\Controllers;
|
||||
|
||||
use App\Domains\UserManagement\Actions\UserChangePassword\UserChangePasswordCommand;
|
||||
use App\Domains\UserManagement\Actions\UserChangePassword\UserChangePasswordRequest;
|
||||
use App\Scopes\CommonController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StoreProfileController extends CommonController
|
||||
{
|
||||
public function __invoke(Request $request): JsonResponse
|
||||
{
|
||||
if (!$this->checkAuth()) {
|
||||
return response()->json(['success' => false, 'message' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
$password = $request->input('password');
|
||||
$passwordConfirmation = $request->input('password_confirmation');
|
||||
|
||||
if (empty($password)) {
|
||||
return response()->json(['success' => false, 'message' => 'Bitte ein Passwort eingeben.'], 422);
|
||||
}
|
||||
|
||||
if ($password !== $passwordConfirmation) {
|
||||
return response()->json(['success' => false, 'message' => 'Die Passwörter stimmen nicht überein.'], 422);
|
||||
}
|
||||
|
||||
$actionRequest = new UserChangePasswordRequest(auth()->user(), $password);
|
||||
$command = new UserChangePasswordCommand($actionRequest);
|
||||
$command->execute();
|
||||
|
||||
auth()->logout();
|
||||
return response()->json(['success' => true, 'message' => 'Dein Passwort wurde erfolgreich geändert.']);
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,15 @@
|
||||
use App\Domains\UserManagement\Controllers\EmailVerificationController;
|
||||
use App\Domains\UserManagement\Controllers\RegistrationController;
|
||||
use App\Domains\UserManagement\Controllers\ResetPasswordController;
|
||||
use App\Domains\UserManagement\Controllers\StoreProfileController;
|
||||
use App\Middleware\IdentifyTenant;
|
||||
use App\Providers\GlobalDataProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Inertia\Inertia;
|
||||
|
||||
Route::prefix('v1')
|
||||
Route::prefix('/api/v1')
|
||||
->group(function () {
|
||||
Route::middleware(IdentifyTenant::class)->group(function () {
|
||||
Route::post('/profile', StoreProfileController::class);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use App\Domains\UserManagement\Controllers\EmailVerificationController;
|
||||
use App\Domains\UserManagement\Controllers\LoginController;
|
||||
use App\Domains\UserManagement\Controllers\LogOutController;
|
||||
use App\Domains\UserManagement\Controllers\ProfileController;
|
||||
use App\Domains\UserManagement\Controllers\RegistrationController;
|
||||
use App\Domains\UserManagement\Controllers\ResetPasswordController;
|
||||
use App\Middleware\IdentifyTenant;
|
||||
@@ -20,6 +21,8 @@ Route::middleware(IdentifyTenant::class)->group(function () {
|
||||
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::post('/logout', [LogoutController::class, 'logout']);
|
||||
Route::get('/profile', ProfileController::class);
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
100
app/Domains/UserManagement/Views/Profile.vue
Normal file
100
app/Domains/UserManagement/Views/Profile.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import AppLayout from '../../../../resources/js/layouts/AppLayout.vue'
|
||||
import ShadowedBox from '../../../Views/Components/ShadowedBox.vue'
|
||||
import { request } from '../../../../resources/js/components/HttpClient.js'
|
||||
import {toast} from "vue3-toastify";
|
||||
|
||||
const props = defineProps({
|
||||
username: String,
|
||||
})
|
||||
|
||||
const password = ref('')
|
||||
const passwordConfirmation = ref('')
|
||||
const saving = ref(false)
|
||||
const successMessage = ref('')
|
||||
const errorMessage = ref('')
|
||||
|
||||
const submit = async () => {
|
||||
if (!password.value) {
|
||||
toast.error('Bitte gib ein neues Passwort ein')
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.value !== passwordConfirmation.value) {
|
||||
toast.error('Die Wiederholung des Passworts stimmt nicht mit dem Passwort überein')
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
saving.value = true
|
||||
successMessage.value = ''
|
||||
errorMessage.value = ''
|
||||
|
||||
const result = await request('/api/v1/profile', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
password: password.value,
|
||||
password_confirmation: passwordConfirmation.value,
|
||||
},
|
||||
})
|
||||
|
||||
saving.value = false
|
||||
|
||||
if (result?.success) {
|
||||
toast.success(result.message)
|
||||
password.value = ''
|
||||
passwordConfirmation.value = ''
|
||||
} else {
|
||||
toast.error(result?.message ?? 'Beim Speichern ist ein Fehler aufgetreten.')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout title="Profil">
|
||||
<shadowed-box style="width: 95%; margin: 20px auto; padding: 20px; overflow-x: hidden;">
|
||||
<h2>Mein Profil</h2>
|
||||
<form @submit.prevent="submit">
|
||||
<table class="form-table" style="width: 90%; margin: auto;">
|
||||
<tr>
|
||||
<td style="width: 250px;">Anmeldename:</td>
|
||||
<td>
|
||||
<span>{{ username }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Neues Passwort:</td>
|
||||
<td>
|
||||
<input type="password" v-model="password" autocomplete="new-password" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Passwort wiederholen:</td>
|
||||
<td>
|
||||
<input type="password" v-model="passwordConfirmation" autocomplete="new-password" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="btn-row">
|
||||
<button type="submit" class="button" :disabled="saving">
|
||||
{{ saving ? 'Wird gespeichert…' : 'Passwort ändern' }}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</shadowed-box>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.feedback {
|
||||
padding: 10px 14px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.feedback.success { background: #f0fdf4; color: #15803d; border: 1px solid #bbf7d0; }
|
||||
.feedback.error { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user