frontend: enhance E2EE key handling and storage management
This commit is contained in:
parent
fb4bdbfcfb
commit
9a2597a997
@ -2,7 +2,7 @@ import { inject } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivateFn } from '@angular/router';
|
||||
import { NavigationService } from '../../../shared/services/navigation.service';
|
||||
import { SessionStorageService } from '../../../shared/services/session-storage.service';
|
||||
import { extractParams, handleLeaveRedirectUrl } from '../../../shared/utils/url-params.utils';
|
||||
import { extractParams } from '../../../shared/utils/url-params.utils';
|
||||
import { RoomMemberContextService } from '../../room-members/services/room-member-context.service';
|
||||
import { MeetingContextService } from '../services/meeting-context.service';
|
||||
|
||||
@ -21,7 +21,6 @@ export const extractRoomParamsGuard: CanActivateFn = (route: ActivatedRouteSnaps
|
||||
e2eeKey: queryE2eeKey
|
||||
} = extractParams(route);
|
||||
const secret = querySecret || sessionStorageService.getRoomSecret();
|
||||
const e2eeKey = queryE2eeKey || sessionStorageService.getE2EEKey();
|
||||
|
||||
// Handle leave redirect URL logic
|
||||
navigationService.handleLeaveRedirectUrl(leaveRedirectUrl);
|
||||
@ -31,9 +30,16 @@ export const extractRoomParamsGuard: CanActivateFn = (route: ActivatedRouteSnaps
|
||||
if (secret) {
|
||||
meetingContextService.setRoomSecret(secret, true);
|
||||
}
|
||||
if (e2eeKey) {
|
||||
meetingContextService.setE2eeKey(e2eeKey);
|
||||
|
||||
// Handle E2EE key: prioritize query param, fallback to storage
|
||||
if (queryE2eeKey) {
|
||||
// E2EE key came from URL parameter
|
||||
meetingContextService.setE2eeKey(queryE2eeKey, true);
|
||||
} else {
|
||||
// Try to load E2EE key from storage
|
||||
meetingContextService.loadE2eeKeyFromStorage();
|
||||
}
|
||||
|
||||
if (participantName) {
|
||||
roomMemberContextService.setParticipantName(participantName);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ export class MeetingContextService {
|
||||
private readonly _roomId = signal<string | undefined>(undefined);
|
||||
private readonly _meetingUrl = signal<string>('');
|
||||
private readonly _e2eeKey = signal<string>('');
|
||||
private readonly _isE2eeKeyFromUrl = signal<boolean>(false);
|
||||
private readonly _roomSecret = signal<string | undefined>(undefined);
|
||||
private readonly _hasRecordings = signal<boolean>(false);
|
||||
private readonly _meetingEndedBy = signal<'self' | 'other' | null>(null);
|
||||
@ -56,6 +57,11 @@ export class MeetingContextService {
|
||||
*/
|
||||
readonly e2eeKey = this._e2eeKey.asReadonly();
|
||||
|
||||
/**
|
||||
* Readonly signal for whether the E2EE key came from a URL parameter
|
||||
*/
|
||||
readonly isE2eeKeyFromUrl = this._isE2eeKeyFromUrl.asReadonly();
|
||||
|
||||
/**
|
||||
* Readonly signal for the room secret
|
||||
*/
|
||||
@ -106,6 +112,11 @@ export class MeetingContextService {
|
||||
*/
|
||||
readonly allowLayoutSwitching = computed(() => this.roomFeatureService.features().allowLayoutSwitching);
|
||||
|
||||
/**
|
||||
* Computed signal for captions status based on room and global configuration
|
||||
*/
|
||||
readonly getCaptionsStatus = computed(() => this.roomFeatureService.features().captionsStatus);
|
||||
|
||||
/**
|
||||
* Computed signal for whether the device is mobile
|
||||
*/
|
||||
@ -174,26 +185,23 @@ export class MeetingContextService {
|
||||
/**
|
||||
* Stores the E2EE key in context
|
||||
* @param key The E2EE key
|
||||
* @param fromUrl Whether the key came from a URL parameter (default: false)
|
||||
*/
|
||||
setE2eeKey(key: string): void {
|
||||
this.sessionStorageService.setE2EEKey(key);
|
||||
setE2eeKey(key: string, fromUrl = false): void {
|
||||
this.sessionStorageService.setE2EEData(key, fromUrl);
|
||||
this._e2eeKey.set(key);
|
||||
this._isE2eeKeyFromUrl.set(fromUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether E2EE is enabled (has a key set)
|
||||
* @returns true if E2EE is enabled, false otherwise
|
||||
* Loads the E2EE key data from session storage
|
||||
*/
|
||||
isE2eeEnabled(): boolean {
|
||||
return this._e2eeKey().length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the captions status based on room and global configuration
|
||||
* @returns CaptionsStatus ('HIDDEN' | 'ENABLED' | 'DISABLED_WITH_WARNING')
|
||||
*/
|
||||
getCaptionsStatus() {
|
||||
return this.roomFeatureService.features().captionsStatus;
|
||||
loadE2eeKeyFromStorage(): void {
|
||||
const e2eeData = this.sessionStorageService.getE2EEData();
|
||||
if (e2eeData) {
|
||||
this._e2eeKey.set(e2eeData.key);
|
||||
this._isE2eeKeyFromUrl.set(e2eeData.fromUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,6 +250,7 @@ export class MeetingContextService {
|
||||
this._roomId.set(undefined);
|
||||
this._meetingUrl.set('');
|
||||
this._e2eeKey.set('');
|
||||
this._isE2eeKeyFromUrl.set(false);
|
||||
this._roomSecret.set(undefined);
|
||||
this._hasRecordings.set(false);
|
||||
this._meetingEndedBy.set(null);
|
||||
|
||||
@ -160,12 +160,6 @@ export class MeetingEventHandlerService {
|
||||
// Clear participant identity and token
|
||||
this.roomMemberContextService.clearContext();
|
||||
|
||||
// Clean up room secret and e2ee key (if any), except on browser unload)
|
||||
if (event.reason !== ParticipantLeftReason.BROWSER_UNLOAD) {
|
||||
this.sessionStorageService.removeRoomSecret();
|
||||
this.sessionStorageService.removeE2EEKey();
|
||||
}
|
||||
|
||||
// Navigate to disconnected page
|
||||
await this.navigationService.navigateTo('disconnected', { reason: leftReason }, true);
|
||||
};
|
||||
|
||||
@ -175,8 +175,10 @@ export class MeetingLobbyService {
|
||||
const contextE2eeKey = this.meetingContextService.e2eeKey();
|
||||
if (contextE2eeKey) {
|
||||
this.setE2eeKey(contextE2eeKey);
|
||||
// fill the e2eeKey form control if already set in context (e.g., from URL param)
|
||||
form.get('e2eeKey')?.disable();
|
||||
// Disable input only if the E2EE key was originally provided via URL parameter
|
||||
if (this.meetingContextService.isE2eeKeyFromUrl()) {
|
||||
form.get('e2eeKey')?.disable();
|
||||
}
|
||||
}
|
||||
form.get('e2eeKey')?.updateValueAndValidity();
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { Injectable } from '@angular/core';
|
||||
export class SessionStorageService {
|
||||
private readonly ROOM_SECRET_KEY = 'ovMeet-roomSecret';
|
||||
private readonly REDIRECT_URL_KEY = 'ovMeet-redirectUrl';
|
||||
private readonly E2EE_KEY = 'ovMeet-e2eeKey';
|
||||
private readonly E2EE_DATA_KEY = 'ovMeet-e2eeData';
|
||||
|
||||
/**
|
||||
* Stores the room secret.
|
||||
@ -56,28 +56,29 @@ export class SessionStorageService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the E2EE key.
|
||||
* Stores the E2EE key data (key and origin flag).
|
||||
*
|
||||
* @param e2eeKey The E2EE key to store.
|
||||
* @param fromUrl True if the E2EE key came from a URL parameter.
|
||||
*/
|
||||
public setE2EEKey(e2eeKey: string): void {
|
||||
this.set(this.E2EE_KEY, e2eeKey);
|
||||
public setE2EEData(e2eeKey: string, fromUrl: boolean): void {
|
||||
this.set(this.E2EE_DATA_KEY, { key: e2eeKey, fromUrl });
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the E2EE key.
|
||||
* Retrieves the E2EE key data (key and origin flag).
|
||||
*
|
||||
* @returns The stored E2EE key or null if not found.
|
||||
* @returns The stored E2EE data or null if not found.
|
||||
*/
|
||||
public getE2EEKey(): string | null {
|
||||
return this.get<string>(this.E2EE_KEY);
|
||||
public getE2EEData(): { key: string; fromUrl: boolean } | null {
|
||||
return this.get<{ key: string; fromUrl: boolean }>(this.E2EE_DATA_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the E2EE key.
|
||||
* Removes the E2EE key data.
|
||||
*/
|
||||
public removeE2EEKey(): void {
|
||||
this.remove(this.E2EE_KEY);
|
||||
public removeE2EEData(): void {
|
||||
this.remove(this.E2EE_DATA_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user