diff --git a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.html b/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.html
deleted file mode 100644
index 74aecf8..0000000
--- a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
The page you are trying to access is restricted.
- Reason: {{ message }}
-
diff --git a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.scss b/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.scss
deleted file mode 100644
index e69de29..0000000
diff --git a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.spec.ts b/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.spec.ts
deleted file mode 100644
index bab5ad8..0000000
--- a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.spec.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { UnauthorizedComponent } from './unauthorized.component';
-
-describe('UnauthorizedComponent', () => {
- let component: UnauthorizedComponent;
- let fixture: ComponentFixture;
-
- beforeEach(async () => {
- await TestBed.configureTestingModule({
- imports: [UnauthorizedComponent]
- })
- .compileComponents();
-
- fixture = TestBed.createComponent(UnauthorizedComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.ts b/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.ts
deleted file mode 100644
index e165c8d..0000000
--- a/frontend/projects/shared-meet-components/src/lib/components/errors/unauthorized/unauthorized.component.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-
-@Component({
- selector: 'ov-unauthorized',
- standalone: true,
- imports: [],
- templateUrl: './unauthorized.component.html',
- styleUrl: './unauthorized.component.scss'
-})
-export class UnauthorizedComponent implements OnInit {
- message = 'Unauthorized access';
- constructor(private route: ActivatedRoute) {}
-
- ngOnInit(): void {
- this.route.queryParams.subscribe((params) => {
- const reason = params['reason'];
- switch (reason) {
- case 'invalid-token':
- this.message = 'The token provided is not valid';
- break;
- case 'invalid-room':
- this.message = 'The room name is not valid';
- break;
- case 'invalid-participant':
- this.message = 'The participant name must be provided';
- break;
- case 'unauthorized-participant':
- this.message = 'You are not authorized to join this room';
- break;
-
- default:
- this.message = 'Unauthorized access';
- break;
- }
- });
- }
-}
diff --git a/frontend/projects/shared-meet-components/src/lib/guards/auth.guard.ts b/frontend/projects/shared-meet-components/src/lib/guards/auth.guard.ts
index 5a88c7c..b5a634f 100644
--- a/frontend/projects/shared-meet-components/src/lib/guards/auth.guard.ts
+++ b/frontend/projects/shared-meet-components/src/lib/guards/auth.guard.ts
@@ -1,7 +1,14 @@
import { inject } from '@angular/core';
-import { ActivatedRouteSnapshot, CanActivateFn, RedirectCommand, Router, RouterStateSnapshot } from '@angular/router';
-import { AuthService, ContextService, HttpService, SessionStorageService } from '../services';
+import {
+ ActivatedRouteSnapshot,
+ CanActivateFn,
+ RedirectCommand,
+ Router,
+ RouterStateSnapshot,
+ UrlTree
+} from '@angular/router';
import { AuthMode, ParticipantRole } from '@lib/typings/ce';
+import { AuthService, ContextService, HttpService, SessionStorageService } from '../services';
export const checkUserAuthenticatedGuard: CanActivateFn = async (
route: ActivatedRouteSnapshot,
@@ -64,9 +71,18 @@ export const checkParticipantRoleAndAuthGuard: CanActivateFn = async (
const roomRoleAndPermissions = await httpService.getRoomRoleAndPermissions(roomId, storageSecret || secret);
participantRole = roomRoleAndPermissions.role;
contextService.setParticipantRole(participantRole);
- } catch (error) {
+ } catch (error: any) {
console.error('Error getting participant role:', error);
- return router.createUrlTree(['unauthorized'], { queryParams: { reason: 'unauthorized-participant' } });
+ switch (error.status) {
+ case 400:
+ // Invalid secret
+ return redirectToErrorPage(router, 'invalid-secret');
+ case 404:
+ // Room not found
+ return redirectToErrorPage(router, 'invalid-room');
+ default:
+ return redirectToErrorPage(router, 'internal-error');
+ }
}
const authMode = await contextService.getAuthModeToEnterRoom();
@@ -114,3 +130,7 @@ export const checkUserNotAuthenticatedGuard: CanActivateFn = async (
// Allow access to the requested page
return true;
};
+
+const redirectToErrorPage = (router: Router, reason: string): UrlTree => {
+ return router.createUrlTree(['error'], { queryParams: { reason } });
+};
diff --git a/frontend/projects/shared-meet-components/src/lib/guards/validate-recording-access.guard.ts b/frontend/projects/shared-meet-components/src/lib/guards/validate-recording-access.guard.ts
index ae215a0..89b988b 100644
--- a/frontend/projects/shared-meet-components/src/lib/guards/validate-recording-access.guard.ts
+++ b/frontend/projects/shared-meet-components/src/lib/guards/validate-recording-access.guard.ts
@@ -31,26 +31,29 @@ export const validateRecordingAccessGuard: CanActivateFn = async (
contextService.setRecordingPermissionsFromToken(response.token);
if (!contextService.canRetrieveRecordings()) {
- // If the user does not have permission to retrieve recordings, redirect to the unauthorized page
- return redirectToUnauthorized(router, 'unauthorized-recording-access');
+ // If the user does not have permission to retrieve recordings, redirect to the error page
+ return redirectToErrorPage(router, 'unauthorized-recording-access');
}
return true;
} catch (error: any) {
console.error('Error generating recording token:', error);
switch (error.status) {
+ case 400:
+ // Invalid secret
+ return redirectToErrorPage(router, 'invalid-secret');
case 403:
// Recording access is configured for admins only
- return redirectToUnauthorized(router, 'unauthorized-recording-access');
+ return redirectToErrorPage(router, 'recordings-admin-only-access');
case 404:
// There are no recordings in the room or the room does not exist
- return redirectToUnauthorized(router, 'no-recordings');
+ return redirectToErrorPage(router, 'no-recordings');
default:
- return redirectToUnauthorized(router, 'invalid-room');
+ return redirectToErrorPage(router, 'internal-error');
}
}
};
-const redirectToUnauthorized = (router: Router, reason: string): UrlTree => {
- return router.createUrlTree(['unauthorized'], { queryParams: { reason } });
+const redirectToErrorPage = (router: Router, reason: string): UrlTree => {
+ return router.createUrlTree(['error'], { queryParams: { reason } });
};
diff --git a/frontend/projects/shared-meet-components/src/lib/guards/validate-room-access.guard.ts b/frontend/projects/shared-meet-components/src/lib/guards/validate-room-access.guard.ts
index 39cf8f6..7a62eaf 100644
--- a/frontend/projects/shared-meet-components/src/lib/guards/validate-room-access.guard.ts
+++ b/frontend/projects/shared-meet-components/src/lib/guards/validate-room-access.guard.ts
@@ -38,6 +38,12 @@ export const validateRoomAccessGuard: CanActivateFn = async (
} catch (error: any) {
console.error('Error generating participant token:', error);
switch (error.status) {
+ case 400:
+ // Invalid secret
+ return redirectToErrorPage(router, 'invalid-secret');
+ case 404:
+ // Room not found
+ return redirectToErrorPage(router, 'invalid-room');
case 409:
// Participant already exists.
// Send a timestamp to force update the query params and show the error message in participant name input form
@@ -47,14 +53,12 @@ export const validateRoomAccessGuard: CanActivateFn = async (
return new RedirectCommand(participantNameRoute, {
skipLocationChange: true
});
- case 406:
- return redirectToUnauthorized(router, 'unauthorized-participant');
default:
- return redirectToUnauthorized(router, 'invalid-room');
+ return redirectToErrorPage(router, 'internal-error');
}
}
};
-const redirectToUnauthorized = (router: Router, reason: string): UrlTree => {
- return router.createUrlTree(['unauthorized'], { queryParams: { reason } });
+const redirectToErrorPage = (router: Router, reason: string): UrlTree => {
+ return router.createUrlTree(['error'], { queryParams: { reason } });
};
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.html b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.html
new file mode 100644
index 0000000..7204206
--- /dev/null
+++ b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.html
@@ -0,0 +1,10 @@
+
+
+
+ {{ errorName }}
+
+
+ {{ message }}
+
+
+
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.scss
new file mode 100644
index 0000000..2eb04f0
--- /dev/null
+++ b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.scss
@@ -0,0 +1,33 @@
+.container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ background-color: var(--ov-background-color);
+}
+
+.card {
+ width: 400px;
+ padding: 20px;
+ text-align: center;
+ background-color: var(--ov-surface-color);
+ border-radius: var(--ov-surface-radius);
+}
+
+mat-card-header {
+ justify-content: center;
+ align-items: center;
+}
+
+mat-card-title {
+ font-size: 1.5em;
+}
+
+mat-card-content p {
+ font-size: 1em;
+ color: #555;
+}
+
+mat-card-actions {
+ margin-top: 20px;
+}
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.spec.ts b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.spec.ts
new file mode 100644
index 0000000..9c94e46
--- /dev/null
+++ b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ErrorComponent } from './error.component';
+
+describe('GenericErrorComponent', () => {
+ let component: ErrorComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ErrorComponent]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(ErrorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts
new file mode 100644
index 0000000..80ce5e3
--- /dev/null
+++ b/frontend/projects/shared-meet-components/src/lib/pages/error/error.component.ts
@@ -0,0 +1,50 @@
+import { Component, OnInit } from '@angular/core';
+import { MatCardModule } from '@angular/material/card';
+import { ActivatedRoute } from '@angular/router';
+
+@Component({
+ selector: 'ov-error',
+ standalone: true,
+ imports: [MatCardModule],
+ templateUrl: './error.component.html',
+ styleUrl: './error.component.scss'
+})
+export class ErrorComponent implements OnInit {
+ errorName = 'Error';
+ message = '';
+
+ constructor(private route: ActivatedRoute) {}
+
+ ngOnInit(): void {
+ this.route.queryParams.subscribe((params) => {
+ const reason = params['reason'];
+ switch (reason) {
+ case 'invalid-secret':
+ this.errorName = 'Invalid secret';
+ this.message =
+ 'The secret provided to join the room is neither valid for moderators nor publishers';
+ break;
+ case 'invalid-room':
+ this.errorName = 'Invalid room';
+ this.message = 'The room you are trying to join does not exist or has been deleted';
+ break;
+ case 'no-recordings':
+ this.errorName = 'No recordings';
+ this.message = 'There are no recordings in this room or the room does not exist';
+ break;
+ case 'unauthorized-recording-access':
+ this.errorName = 'Unauthorized recording access';
+ this.message = 'You are not authorized to access the recordings in this room';
+ break;
+ case 'recordings-admin-only-access':
+ this.errorName = 'Unauthorized recording access';
+ this.message = 'Recordings access is configured for admins only in this room';
+ break;
+ default:
+ this.errorName = 'Internal error';
+ this.message = 'Something went wrong...';
+ break;
+ }
+ });
+ }
+}
diff --git a/frontend/projects/shared-meet-components/src/lib/routes/base-routes.ts b/frontend/projects/shared-meet-components/src/lib/routes/base-routes.ts
index 7fdcf11..09fa944 100644
--- a/frontend/projects/shared-meet-components/src/lib/routes/base-routes.ts
+++ b/frontend/projects/shared-meet-components/src/lib/routes/base-routes.ts
@@ -1,6 +1,5 @@
import { Routes } from '@angular/router';
import { UserRole } from '@lib/typings/ce';
-import { RoomCreatorDisabledComponent, UnauthorizedComponent } from '../components';
import {
applicationModeGuard,
checkParticipantNameGuard,
@@ -20,11 +19,13 @@ import {
ConsoleComponent,
ConsoleLoginComponent,
DisconnectedComponent,
+ ErrorComponent,
LoginComponent,
OverviewComponent,
ParticipantNameFormComponent,
RecordingsComponent,
RoomCreatorComponent,
+ RoomCreatorDisabledComponent,
RoomFormComponent,
RoomRecordingsComponent,
RoomsComponent,
@@ -51,7 +52,7 @@ export const baseRoutes: Routes = [
},
{ path: 'room-creator-disabled', component: RoomCreatorDisabledComponent },
{ path: 'disconnected', component: DisconnectedComponent },
- { path: 'unauthorized', component: UnauthorizedComponent },
+ { path: 'error', component: ErrorComponent },
{
path: 'console/login',
component: ConsoleLoginComponent,