Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Improved error handling when a room requires an access code but none was provided ([#3035])

## [v4.14.2] - 2026-04-10

### Fixed
Expand Down Expand Up @@ -769,6 +773,7 @@ You can find the changelog for older versions there [here](https://github.com/TH
[#3014]: https://github.com/THM-Health/PILOS/pull/3014
[#3028]: https://github.com/THM-Health/PILOS/issues/3028
[#3029]: https://github.com/THM-Health/PILOS/pull/3029
[#3035]: https://github.com/THM-Health/PILOS/pull/3035
[#3039]: https://github.com/THM-Health/PILOS/issues/3039
[#3040]: https://github.com/THM-Health/PILOS/pull/3040
[unreleased]: https://github.com/THM-Health/PILOS/compare/v4.14.2...develop
Expand Down
3 changes: 2 additions & 1 deletion resources/js/components/RoomHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
:room="props.room"
:room-auth-token="roomAuthToken"
@joined-membership="emit('joinedMembership')"
@left-membership="emit('reload')"
@left-membership="emit('leftMembership')"
@invalid-room-auth-token="emit('invalidRoomAuthToken')"
@membership-disabled="emit('reload')"
/>
Expand Down Expand Up @@ -116,5 +116,6 @@ const emit = defineEmits([
"joinedMembership",
"reload",
"invalidRoomAuthToken",
"leftMembership",
]);
</script>
3 changes: 2 additions & 1 deletion resources/js/components/RoomJoinButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ const props = defineProps({

const emit = defineEmits([
"invalidRoomAuthToken",
"requireCode",
"guestsNotAllowed",
"changed",
]);
Expand Down Expand Up @@ -446,7 +447,7 @@ function handleError(error) {
error.response.status === env.HTTP_FORBIDDEN &&
error.response.data.message === HTTP_ROOM_REQUIRE_CODE
) {
emit("invalidRoomAuthToken");
emit("requireCode");
modalVisible.value = false;
return true;
}
Expand Down
10 changes: 7 additions & 3 deletions resources/js/components/RoomTabFiles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,11 @@ const props = defineProps({
},
});

const emit = defineEmits(["invalidRoomAuthToken", "guestsNotAllowed"]);
const emit = defineEmits([
"invalidRoomAuthToken",
"requireCode",
"guestsNotAllowed",
]);

const api = useApi();
const userPermissions = useUserPermissions();
Expand Down Expand Up @@ -422,7 +426,7 @@ function loadData(page = null) {
error.response.status === env.HTTP_FORBIDDEN &&
error.response.data.message === HTTP_ROOM_REQUIRE_CODE
) {
return emit("invalidRoomAuthToken");
return emit("requireCode");
}
}
api.error(error, { redirectOnUnauthenticated: false });
Expand Down Expand Up @@ -457,7 +461,7 @@ function handleFileErrorMessages(event) {
emit("invalidRoomAuthToken");
} else if (event.data.type === HTTP_ROOM_REQUIRE_CODE) {
// Forbidden, require access code
emit("invalidRoomAuthToken");
emit("requireCode");
} else if (event.data.type === HTTP_FORBIDDEN) {
// Forbidden, not allowed to view file
toast.error(t("rooms.flash.file_forbidden"));
Expand Down
10 changes: 7 additions & 3 deletions resources/js/components/RoomTabRecordings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,11 @@ const props = defineProps({
},
});
const emit = defineEmits(["invalidRoomAuthToken", "guestsNotAllowed"]);
const emit = defineEmits([
"invalidRoomAuthToken",
"requireCode",
"guestsNotAllowed",
]);
const api = useApi();
const userPermissions = useUserPermissions();
Expand Down Expand Up @@ -435,7 +439,7 @@ function loadData(page = null) {
error.response.status === env.HTTP_FORBIDDEN &&
error.response.data.message === HTTP_ROOM_REQUIRE_CODE
) {
return emit("invalidRoomAuthToken");
return emit("requireCode");
}
}
loadingError.value = true;
Expand Down Expand Up @@ -482,7 +486,7 @@ function handleRecordingErrorMessages(event) {
emit("invalidRoomAuthToken");
} else if (event.data.type === HTTP_ROOM_REQUIRE_CODE) {
// Forbidden, require access code
emit("invalidRoomAuthToken");
emit("requireCode");
} else if (event.data.type === HTTP_FORBIDDEN) {
// Forbidden, not allowed to view recording
toast.error(t("rooms.flash.recording_forbidden"));
Expand Down
8 changes: 7 additions & 1 deletion resources/js/components/RoomTabSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
:room-auth-token="roomAuthToken"
:room="props.room"
@invalid-room-auth-token="$emit('invalidRoomAuthToken')"
@require-code="$emit('requireCode')"
@guests-not-allowed="$emit('guestsNotAllowed')"
@settings-changed="$emit('settingsChanged')"
/>
Expand Down Expand Up @@ -146,7 +147,12 @@ import { useUrlSearchParams } from "@vueuse/core";
import { useSettingsStore } from "../stores/settings.js";
import RoomTabStreaming from "./RoomTabStreaming.vue";

defineEmits(["invalidRoomAuthToken", "guestsNotAllowed", "settingsChanged"]);
defineEmits([
"invalidRoomAuthToken",
"requireCode",
"guestsNotAllowed",
"settingsChanged",
]);

const props = defineProps({
room: {
Expand Down
38 changes: 36 additions & 2 deletions resources/js/views/RoomsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
roomAuthToken = null;
reload();
"
@left-membership="reload(false)"
/>
</template>
<template #content>
Expand Down Expand Up @@ -204,6 +205,10 @@
:can-start="room.can_start"
:room-auth-token="roomAuthToken"
@invalid-room-auth-token="handleInvalidRoomAuthToken"
@require-code="
handleRequireCode();
reload(false);
"
@guests-not-allowed="handleGuestsNotAllowed"
@changed="reload"
/>
Expand All @@ -223,6 +228,10 @@
:room-auth-token="roomAuthToken"
:room="room"
@invalid-room-auth-token="handleInvalidRoomAuthToken"
@require-code="
handleRequireCode();
reload(false);
"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
@guests-not-allowed="handleGuestsNotAllowed"
@settings-changed="reload"
/>
Expand Down Expand Up @@ -394,7 +403,22 @@ function handleInvalidCode() {

// Show error message
toast.error(t("rooms.flash.access_code_invalid"));
reload();
reload(false);
}

/**
* Reset access code error states and access code input and display error message
*/
function handleRequireCode() {
// Reset access code error states to prevent confusing error state
accessCodeInvalid.value = null;
formErrors.clear();

// Reset access code input
accessCodeInput.value = "";

// Show error message
toast.error(t("rooms.require_access_code"));
}

/**
Expand Down Expand Up @@ -481,8 +505,9 @@ watch(authThrottledFor, (value) => {

/**
* Reload the room details/settings
* @param {boolean} [checkForRequireCodeError=true]
*/
function reload() {
function reload(checkForRequireCodeError = true) {
// Enable loading indicator
loading.value = true;
// Build room api url, include access code if set
Expand All @@ -501,6 +526,15 @@ function reload() {
api
.call(url, config)
.then((response) => {
// Room was authenticated but now requires an access code
if (
checkForRequireCodeError &&
room.value?.authenticated &&
!response.data.data.authenticated
) {
handleRequireCode();
}
Comment thread
Sabr1n4W marked this conversation as resolved.

room.value = response.data.data;

setPageTitle(room.value.name);
Expand Down
20 changes: 9 additions & 11 deletions tests/Frontend/e2e/RoomsViewFiles.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ describe("Rooms View Files", function () {
"roomRequest",
);

cy.get('[data-test="room-login-button"]').click();
// Reload room to trigger files request again (but without setting room auth token)
cy.get('[data-test="reload-room-button"]').click();

cy.fixture("room.json").then((room2) => {
room2.data.owner = { id: 2, name: "Max Doe" };
Expand All @@ -353,28 +354,25 @@ describe("Rooms View Files", function () {
});
});

cy.wait("@roomAuthRequest");

cy.wait("@roomRequest");

cy.wait("@roomFilesRequest").then((interception) => {
// Check that room auth token is set
expect(interception.request.query).to.contain({
room_auth_token: "roomAuthToken",
room_auth_token_type: "0",
});
// Check that room auth token is not set
expect(interception.request.query.room_auth_token).to.be.undefined;
expect(interception.request.query.room_auth_token_type).to.be.undefined;
});

cy.wait("@roomRequest").then((interception) => {
// Check that room auth token is reset
// Check that room auth token is not set
expect(interception.request.query.room_auth_token).to.be.undefined;
expect(interception.request.query.room_auth_token_type).to.be.undefined;
});

// Check if error message is shown
cy.checkToastMessage("rooms.flash.access_code_invalid");
cy.checkToastMessage("rooms.require_access_code");

cy.contains("rooms.flash.access_code_invalid").should("be.visible");
cy.contains("rooms.flash.access_code_invalid").should("not.exist");
cy.get("#access-code").should("have.value", "");
});

it("load files with personalized link", function () {
Expand Down
11 changes: 6 additions & 5 deletions tests/Frontend/e2e/RoomsViewFilesFileActions.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -863,9 +863,9 @@ describe("Rooms view files file actions", function () {
}).as("roomRequest");
});

cy.get('[data-test="room-login-button"]').click();
// Reload room (but without setting room auth token)
cy.get('[data-test="reload-room-button"]').click();

cy.wait("@roomAuthRequest");
cy.wait("@roomRequest");
cy.wait("@roomFilesRequest");

Expand All @@ -887,16 +887,17 @@ describe("Rooms view files file actions", function () {
$window.postMessage(message, Cypress.config("baseUrl"));
});

// Check that room auth token is reset
// Check that room auth token is not set
cy.wait("@roomRequest").then((interception) => {
expect(interception.request.query.room_auth_token).to.be.undefined;
expect(interception.request.query.room_auth_token_type).to.be.undefined;
});

// Check if error message is shown and close it
cy.checkToastMessage("rooms.flash.access_code_invalid");
cy.checkToastMessage("rooms.require_access_code");

cy.contains("rooms.flash.access_code_invalid").should("be.visible");
cy.contains("rooms.flash.access_code_invalid").should("not.exist");
cy.get("#access-code").should("have.value", "");
});

it("download file with personalized link errors", function () {
Expand Down
3 changes: 3 additions & 0 deletions tests/Frontend/e2e/RoomsViewGeneral.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,9 @@ describe("Room View general", function () {

cy.get('[data-test="room-access-code-overlay"]').should("be.visible");
cy.get("#access-code").should("have.value", "123-456-789");

// Check that no error message is shown even though room request returned authenticated false again
cy.get(".p-toast-message").should("not.exist");
});

it("membership button errors", function () {
Expand Down
Loading
Loading