feat(jwt): Adds an option to match tenant. (#15727)

* feat(jwt): Adds an option to match tenant.

There are cases where if tenant doesn't match features are ignore in the backend via prosody and session.jitsi_meet_tenant_mismatch.

* squash: add a comment explaining the change.

* squash: fix comments.

* squash: fix comments2.
This commit is contained in:
Дамян Минков
2025-03-07 12:26:19 -06:00
committed by GitHub
parent eee80941b0
commit bd7b2c6e7a
3 changed files with 22 additions and 2 deletions

View File

@@ -1567,6 +1567,8 @@ var config = {
// You can enable tokenAuthUrlAutoRedirect which will detect that you have logged in successfully before
// and will automatically redirect to the token service to get the token for the meeting.
// tokenAuthUrlAutoRedirect: false
// An option to respect the context.tenant jwt field compared to the current tenant from the url
// tokenRespectTenant: false,
// You can put an array of values to target different entity types in the invite dialog.
// Valid values are "phone", "room", "sip", "user", "videosipgw" and "email"

View File

@@ -604,6 +604,7 @@ export interface IConfig {
tokenAuthUrl?: string;
tokenAuthUrlAutoRedirect?: string;
tokenLogoutUrl?: string;
tokenRespectTenant?: string;
toolbarButtons?: Array<ToolbarButton>;
toolbarConfig?: {
alwaysVisible?: boolean;

View File

@@ -3,12 +3,14 @@ import jwtDecode from 'jwt-decode';
import { AnyAction } from 'redux';
import { IStore } from '../../app/types';
import { isVpaasMeeting } from '../../jaas/functions';
import { SET_CONFIG } from '../config/actionTypes';
import { SET_LOCATION_URL } from '../connection/actionTypes';
import { participantUpdated } from '../participants/actions';
import { getLocalParticipant } from '../participants/functions';
import { IParticipant } from '../participants/types';
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
import { parseURIString } from '../util/uri';
import { SET_JWT } from './actionTypes';
import { setJWT } from './actions';
@@ -125,6 +127,8 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
const { jwt, type, ...actionPayload } = action;
if (!Object.keys(actionPayload).length) {
const state = store.getState();
if (jwt) {
let jwtPayload;
@@ -150,9 +154,22 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
const newUser = user ? { ...user } : {};
let features = context.features;
const { tokenRespectTenant } = state['features/base/config'];
// eslint-disable-next-line max-depth
if (!isVpaasMeeting(state) && tokenRespectTenant && context.tenant) {
// we skip checking vpaas meetings as there are other backend rules in place
// this way vpaas users can still use this field if needed
const { locationURL = { href: '' } as URL } = state['features/base/connection'];
const { tenant = '' } = parseURIString(locationURL.href) || {};
features = context.tenant === tenant ? features : {};
}
_overwriteLocalParticipant(
store, { ...newUser,
features: context.features });
features });
// eslint-disable-next-line max-depth
if (context.user && context.user.role === 'visitor') {
@@ -172,7 +189,7 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
// On Web it should eventually be restored from storage, but there's
// no such use case yet.
const { user } = store.getState()['features/base/jwt'];
const { user } = state['features/base/jwt'];
user && _undoOverwriteLocalParticipant(store, user);
}