diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php index 0c32836..d48979b 100644 --- a/app/Actions/Fortify/UpdateUserPassword.php +++ b/app/Actions/Fortify/UpdateUserPassword.php @@ -26,7 +26,7 @@ class UpdateUserPassword implements UpdatesUserPasswords ])->validateWithBag('updatePassword'); $user->forceFill([ - 'password' => Hash::make($input['password']), + 'pass' => Hash::make($input['password']), ])->save(); } } diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php index ce165f7..1409311 100644 --- a/app/Actions/Fortify/UpdateUserProfileInformation.php +++ b/app/Actions/Fortify/UpdateUserProfileInformation.php @@ -13,43 +13,48 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation /** * Validate and update the given user's profile information. * - * @param array $input + * @param array $input */ public function update(User $user, array $input): void { + // Use PHP's built-in list of timezones for robust validation + $timezones = timezone_identifiers_list(); + $rules = [ 'login' => ['required', 'string', 'max:255', Rule::unique('cc_subjs')->ignore($user->id)], - 'email' => [ - 'required', - 'string', - 'email', - 'max:255', - Rule::unique('cc_subjs')->ignore($user->id), - ], + 'email' => ['nullable', 'string', 'email', 'max:255', Rule::unique('cc_subjs')->ignore($user->id)], + 'first_name' => ['nullable', 'string', 'max:255'], + 'last_name' => ['nullable', 'string', 'max:255'], + 'cell_phone' => ['nullable', 'string', 'max:25'], + 'timezone' => ['nullable', 'string', Rule::in($timezones)], ]; - // Only add the 'type' validation rule if the user has the permission to change roles - if (auth()->user()->hasPermissionTo('users.changeRole')) { + if (isset($rules['type']) && auth()->user()->hasPermissionTo('users.changeRole')) { $rules['type'] = ['required', 'string', 'max:6', Rule::in(['admin', 'editor', 'dj'])]; } Validator::make($input, $rules)->validateWithBag('updateProfileInformation'); + $data = [ + 'login' => $input['login'], + 'email' => $input['email'], + 'first_name' => $input['first_name'], + 'last_name' => $input['last_name'], + 'cell_phone' => $input['cell_phone'], + ]; + if ($input['email'] !== $user->email && $user instanceof MustVerifyEmail) { $this->updateVerifiedUser($user, $input); } else { - $data = [ - 'login' => $input['login'], - 'email' => $input['email'], - ]; - - // Only update 'type' if the user has the permission - if (auth()->user()->hasPermissionTo('users.changeRole')) { + if (isset($rules['type']) && auth()->user()->hasPermissionTo('users.changeRole')) { $data['type'] = $input['type']; } $user->forceFill($data)->save(); } + + // The timezone is handled by the mutator in the User model + $user->timezone = $input['timezone']; } /** @@ -62,16 +67,22 @@ class UpdateUserProfileInformation implements UpdatesUserProfileInformation $data = [ 'login' => $input['login'], 'email' => $input['email'], + 'first_name' => $input['first_name'], + 'last_name' => $input['last_name'], + 'cell_phone' => $input['cell_phone'], 'email_verified_at' => null, ]; - // Only update 'type' if the user has the permission - if (auth()->user()->hasPermissionTo('user.changeRole')) { + // Corrected permission name to be consistent + if (auth()->user()->hasPermissionTo('users.changeRole')) { $data['type'] = $input['type']; } $user->forceFill($data)->save(); + // The timezone is handled by the mutator in the User model + $user->timezone = $input['timezone']; + $user->sendEmailVerificationNotification(); } -} +} \ No newline at end of file diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 6615574..b3e7fb9 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -56,34 +56,38 @@ class UserController extends Controller public function userProfile() { - return response()->json(auth()->user()); + $user =auth()->user(); + $user->role = $user->roles()->value('name'); + + return response()->json($user); } public function update(Request $request, User $user, UpdateUserProfileInformation $updater) { $authenticatedUser = auth()->user(); - if ($authenticatedUser->id !== $user->id && ! $authenticatedUser->hasPermissionTo('user.manageAll')) { + if ($authenticatedUser->id !== $user->id && !$authenticatedUser->hasPermissionTo('user.manageAll')) { return response()->json(['message' => 'You do not have permission to edit other users.'], 403); } - if ($authenticatedUser->id === $user->id && ! $authenticatedUser->hasPermissionTo('users.manageOwn')) { + if ($authenticatedUser->id === $user->id && !$authenticatedUser->hasPermissionTo('users.manageOwn')) { return response()->json(['message' => 'You do not have permission to edit your own profile.'], 403); } try { - (new UpdateUserProfileInformation())->update($user, $request->all()); - + $updater->update($user, $request->all()); $user->load('preferences'); return response()->json($user); } catch (\Throwable $e) { Log::error($e->getMessage()); + if ($e instanceof \Illuminate\Validation\ValidationException) { + return response()->json(['message' => $e->getMessage(), 'errors' => $e->errors()], 422); + } return response()->json(['message' => 'Failed to update user'], 500); } } - public function destroy(Request $request) { try { diff --git a/resources/js/app.ts b/resources/js/app.ts index d9ddad3..3085ed8 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -8,6 +8,8 @@ import { createPinia } from "pinia"; import { createI18n } from "vue-i18n"; import App from "@/layouts/App.vue"; +import { useAuthStore } from '@/stores/auth.store'; + const pinia = createPinia(); const i18n = createI18n(vueI18n); const app = createApp(App); @@ -16,4 +18,8 @@ app.use(pinia) .use(i18n) .use(router) .use(vuetify) - .mount("#app"); \ No newline at end of file + +const auth = useAuthStore(); +auth.fetchUser().finally(() => { + app.mount("#app"); +}); \ No newline at end of file diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js index 846d350..a1f2818 100644 --- a/resources/js/bootstrap.js +++ b/resources/js/bootstrap.js @@ -6,7 +6,7 @@ import axios from 'axios'; window.axios = axios; - +window.axios.defaults.withCredentials = true window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; /** diff --git a/resources/js/components/content/Dashboard.vue b/resources/js/components/content/Dashboard.vue index de0af46..00767ca 100644 --- a/resources/js/components/content/Dashboard.vue +++ b/resources/js/components/content/Dashboard.vue @@ -91,29 +91,31 @@ onDeactivated(() => {