Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

namespace App\Exceptions;

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Foundation\ViteException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Psr\Log\LogLevel;
use Spatie\LaravelIgnition\Exceptions\ViewException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;

class Handler extends ExceptionHandler
Expand Down Expand Up @@ -77,5 +80,21 @@ public function register(): void

return null;
});

$this->renderable(function (NotFoundHttpException $e, Request $request) {
if ($request->expectsJson()) {
$modelNotFoundException = $e->getPrevious() instanceof ModelNotFoundException ? $e->getPrevious() : null;

if ($modelNotFoundException) {
$json = [
'message' => 'model_not_found',
'model' => Str::snake(class_basename($modelNotFoundException->getModel())),
'ids' => $modelNotFoundException->getIds(),
];

return response()->json($json, 404);
}
}
});
}
}
18 changes: 6 additions & 12 deletions app/Http/Controllers/api/v1/RoomMemberController.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,11 @@ public function bulkImport(Room $room, BulkImportRequest $request)
*
* @return Response
*/
public function update(Room $room, User $user, UpdateRoomMemberRequest $request)
public function update(Room $room, User $member, UpdateRoomMemberRequest $request)
{
if (! $room->members->contains($user)) {
abort(410, __('app.errors.not_member_of_room'));
}
$room->members()->updateExistingPivot($user, ['role' => $request->role]);
$room->members()->updateExistingPivot($member, ['role' => $request->role]);

Log::info('Changed role for member {member} to {role} in room {room}', ['room' => $room->getLogLabel(), 'role' => RoomUserRole::from($request->role)->label(), 'member' => $user->getLogLabel()]);
Log::info('Changed role for member {member} to {role} in room {room}', ['room' => $room->getLogLabel(), 'role' => RoomUserRole::from($request->role)->label(), 'member' => $member->getLogLabel()]);

return response()->noContent();
}
Expand All @@ -155,14 +152,11 @@ public function bulkUpdate(Room $room, BulkUpdateRequest $request)
*
* @return Response
*/
public function destroy(Room $room, User $user)
public function destroy(Room $room, User $member)
{
if (! $room->members->contains($user)) {
abort(410, __('app.errors.not_member_of_room'));
}
$room->members()->detach($user);
$room->members()->detach($member);

Log::info('Removed member {member} from room {room}', ['room' => $room->getLogLabel(), 'member' => $user->getLogLabel()]);
Log::info('Removed member {member} from room {room}', ['room' => $room->getLogLabel(), 'member' => $member->getLogLabel()]);

return response()->noContent();
}
Expand Down
28 changes: 10 additions & 18 deletions app/Http/Controllers/api/v1/RoomPersonalizedLinkController.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,16 @@ public function store(Room $room, RoomPersonalizedLinkRequest $request)
*
* @return RoomPersonalizedLinkResource
*/
public function update(Room $room, RoomPersonalizedLink $link, RoomPersonalizedLinkRequest $request)
public function update(Room $room, RoomPersonalizedLink $personalizedLink, RoomPersonalizedLinkRequest $request)
{
if (! $link->room->is($room)) {
abort(404, __('app.errors.personalized_link_not_found'));
}

$link->firstname = $request->firstname;
$link->lastname = $request->lastname;
$link->role = $request->role;
$link->save();
$personalizedLink->firstname = $request->firstname;
$personalizedLink->lastname = $request->lastname;
$personalizedLink->role = $request->role;
$personalizedLink->save();

Log::info('Updated personalized room link for guest {name} with the role {role} for room {room}', ['room' => $room->getLogLabel(), 'role' => $link->role->label(), 'name' => $link->fullname]);
Log::info('Updated personalized room link for guest {name} with the role {role} for room {room}', ['room' => $room->getLogLabel(), 'role' => $personalizedLink->role->label(), 'name' => $personalizedLink->fullname]);

return new RoomPersonalizedLinkResource($link);
return new RoomPersonalizedLinkResource($personalizedLink);
}

/**
Expand All @@ -126,15 +122,11 @@ public function update(Room $room, RoomPersonalizedLink $link, RoomPersonalizedL
*
* @throws \Exception
*/
public function destroy(Room $room, RoomPersonalizedLink $link)
public function destroy(Room $room, RoomPersonalizedLink $personalizedLink)
{
if (! $link->room->is($room)) {
abort(404, __('app.errors.personalized_link_not_found'));
}

$link->delete();
$personalizedLink->delete();

Log::info('Removed personalized room link for guest {name} with the role {role} for room {room}', ['room' => $room->getLogLabel(), 'role' => $link->role->label(), 'name' => $link->fullname]);
Log::info('Removed personalized room link for guest {name} with the role {role} for room {room}', ['room' => $room->getLogLabel(), 'role' => $personalizedLink->role->label(), 'name' => $personalizedLink->fullname]);

return response()->noContent();
}
Expand Down
31 changes: 30 additions & 1 deletion lang/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
'membership_disabled' => 'Membership failed! Membership for this room is currently not available.',
'no_room_access' => 'You does not have the necessary permissions, to edit this room.',
'no_server_available' => 'Currently there are no servers available.',
'not_member_of_room' => 'The person is not a member of this room (anymore).',
'not_member_of_room' => 'The user is not a member of this room.',
'not_running' => 'Joining the room has failed as it is currently closed.',
'personalized_link_not_found' => 'The personalized room link could not be found.',
'record_agreement_missing' => 'Consent to the recording is required.',
Expand All @@ -66,6 +66,10 @@
'flash' => [
'client_error' => 'An unknown error occurred in the application!',
'guests_only' => 'The request can only be made by guests!',
'model_not_found' => [
'title' => 'The :model was not found!',
'details' => ' Model id: :ids',
],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
'server_error' => [
'empty_message' => 'An error occurred on the server during request!',
'error_code' => 'Error code: :statusCode',
Expand Down Expand Up @@ -97,11 +101,36 @@
'fr' => 'French',
],
'model' => [
'included_permission_permission' => 'Included permission',
'meeting' => 'Meeting',
'meeting_attendee' => 'Meeting attendee',
'meeting_stat' => 'Meeting stat',
'permission' => 'Permission',
'permission_role' => 'Permission role',
'recording' => 'Recording',
'recording_format' => 'Recording format',
'role' => 'Role',
'role_user' => 'Role user',
'roles' => 'role',
'room' => 'Room',
'room_auth_token' => 'Room auth token',
'room_file' => 'Room file',
'room_personalized_link' => 'Room personalized link',
'room_streaming' => 'Room streaming',
'room_type' => 'Room type',
'room_types' => 'room type',
'room_type_streaming_settings' => 'Room type streaming settings',
'room_user' => 'Room user',
'server' => 'Server',
'server_pool' => 'Server pool',
'server_pools' => 'server pool',
'server_stat' => 'Server stat',
'session' => 'Session',
'session_data' => 'Session data',
'servers' => 'server',
'user' => 'User',
'users' => 'user',
'verify_email' => 'Verify Email',
],
'model_name' => 'Name',
'next' => 'Next',
Expand Down
2 changes: 2 additions & 0 deletions resources/js/components/RoomCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<RoomFavoriteButton
:room="props.room"
class="room-card-button h-8 w-8 p-0 text-sm"
:redirect-on-room-model-not-found="false"
@favorites-changed="$emit('favoritesChanged')"
/>
</div>
Expand Down Expand Up @@ -72,6 +73,7 @@
<div class="room-card-buttons shrink-0">
<RoomFavoriteButton
:room="props.room"
:redirect-on-room-model-not-found="false"
@favorites-changed="$emit('favoritesChanged')"
/>
</div>
Expand Down
5 changes: 5 additions & 0 deletions resources/js/components/RoomFavoriteButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const props = defineProps({
type: Boolean,
default: true,
},
redirectOnRoomModelNotFound: {
type: Boolean,
default: true,
},
});

const isLoading = ref(false);
Expand All @@ -57,6 +61,7 @@ function toggleFavorite() {
.catch((error) => {
api.error(error, {
redirectOnUnauthenticated: props.redirectOnUnauthenticated,
redirectOnRoomModelNotFound: props.redirectOnRoomModelNotFound,
});
})
.finally(() => {
Expand Down
6 changes: 5 additions & 1 deletion resources/js/components/RoomTabFilesDeleteButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { useApi } from "../composables/useApi.js";
import { ref } from "vue";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";
import { ROOM_FILE } from "../constants/modelNames.js";

const props = defineProps({
roomId: {
Expand Down Expand Up @@ -101,7 +102,10 @@ function deleteFile() {
// deleting failed
if (error.response) {
// file not found
if (error.response.status === env.HTTP_NOT_FOUND) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === ROOM_FILE
) {
toast.error(t("rooms.flash.file_gone"));
emit("notFound");
modalVisible.value = false;
Expand Down
6 changes: 5 additions & 1 deletion resources/js/components/RoomTabFilesEditButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ import { ref, watch } from "vue";
import { useFormErrors } from "../composables/useFormErrors.js";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";
import { ROOM_FILE } from "../constants/modelNames.js";

const props = defineProps({
roomId: {
Expand Down Expand Up @@ -195,7 +196,10 @@ function save() {
// editing failed
if (error.response) {
// file not found
if (error.response.status === env.HTTP_NOT_FOUND) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === ROOM_FILE
) {
toast.error(t("rooms.flash.file_gone"));
emit("notFound");
modalVisible.value = false;
Expand Down
12 changes: 11 additions & 1 deletion resources/js/components/RoomTabMembersDeleteButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
import env from "../env";
import { useApi } from "../composables/useApi.js";
import { ref } from "vue";
import { USER } from "../constants/modelNames.js";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";

const props = defineProps({
roomId: {
Expand Down Expand Up @@ -83,6 +86,8 @@ const props = defineProps({
const emit = defineEmits(["deleted", "gone"]);

const api = useApi();
const toast = useToast();
const { t } = useI18n();

const modalVisible = ref(false);
const isLoadingAction = ref(false);
Expand All @@ -106,9 +111,14 @@ function deleteMember() {
// editing failed
if (error.response) {
// user not found
if (error.response.status === env.HTTP_GONE) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === USER
) {
toast.error(t("app.errors.not_member_of_room"));
emit("gone");
modalVisible.value = false;
return;
}
}
api.error(error, { redirectOnUnauthenticated: false });
Expand Down
12 changes: 11 additions & 1 deletion resources/js/components/RoomTabMembersEditButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ import env from "../env";
import { useApi } from "../composables/useApi.js";
import { useFormErrors } from "../composables/useFormErrors.js";
import { ref } from "vue";
import { USER } from "../constants/modelNames.js";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";

const props = defineProps({
roomId: {
Expand Down Expand Up @@ -131,6 +134,8 @@ const emit = defineEmits(["edited", "gone"]);

const api = useApi();
const formErrors = useFormErrors();
const toast = useToast();
const { t } = useI18n();

const modalVisible = ref(false);
const newRole = ref(null);
Expand Down Expand Up @@ -168,9 +173,14 @@ function save() {
// editing failed
if (error.response) {
// user not found
if (error.response.status === env.HTTP_GONE) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === USER
) {
toast.error(t("app.errors.not_member_of_room"));
emit("gone");
modalVisible.value = false;
return;
}
// failed due to form validation errors
if (error.response.status === env.HTTP_UNPROCESSABLE_ENTITY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { useApi } from "../composables/useApi.js";
import { ref } from "vue";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";
import { ROOM_PERSONALIZED_LINK } from "../constants/modelNames.js";

const props = defineProps({
roomId: {
Expand Down Expand Up @@ -120,7 +121,10 @@ function deleteLink() {
// deleting failed
if (error.response) {
// personalized link not found
if (error.response.status === env.HTTP_NOT_FOUND) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === ROOM_PERSONALIZED_LINK
) {
toast.error(t("rooms.flash.personalized_link_gone"));
modalVisible.value = false;
emit("notFound");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ import { ref } from "vue";
import env from "../env.js";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";
import { ROOM_PERSONALIZED_LINK } from "../constants/modelNames.js";

const props = defineProps({
roomId: {
Expand Down Expand Up @@ -189,7 +190,10 @@ function save() {
// editing failed
if (error.response) {
// token not found
if (error.response.status === env.HTTP_NOT_FOUND) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === ROOM_PERSONALIZED_LINK
) {
toast.error(t("rooms.flash.personalized_link_gone"));
modalVisible.value = false;
emit("notFound");
Expand Down
6 changes: 5 additions & 1 deletion resources/js/components/RoomTabRecordingsDeleteButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { useApi } from "../composables/useApi.js";
import { ref } from "vue";
import { useToast } from "../composables/useToast.js";
import { useI18n } from "vue-i18n";
import { RECORDING } from "../constants/modelNames.js";

const props = defineProps({
recordingId: {
Expand Down Expand Up @@ -97,7 +98,10 @@ function deleteRecording() {
// editing failed
if (error.response) {
// recording not found
if (error.response.status === env.HTTP_NOT_FOUND) {
if (
error.response.status === env.HTTP_NOT_FOUND &&
error.response.data?.model === RECORDING
) {
toast.error(t("rooms.flash.recording_gone"));
emit("notFound");
return;
Expand Down
Loading
Loading