feat(dialout) check appId for permission to call outbound destination (#12871)
This commit is contained in:
parent
3e59359563
commit
84221c5c13
|
@ -1335,6 +1335,7 @@ var config = {
|
|||
deploymentInfo
|
||||
dialOutAuthUrl
|
||||
dialOutCodesUrl
|
||||
dialOutRegionUrl
|
||||
disableRemoteControl
|
||||
displayJids
|
||||
externalConnectUrl
|
||||
|
|
|
@ -35,6 +35,11 @@ export type Props = {
|
|||
*/
|
||||
_dialOutAuthUrl: string,
|
||||
|
||||
/**
|
||||
* The URL for validating if an outbound destination is allowed.
|
||||
*/
|
||||
_dialOutRegionUrl: string;
|
||||
|
||||
/**
|
||||
* Whether or not to show Dial Out functionality.
|
||||
*/
|
||||
|
@ -235,7 +240,9 @@ export default class AbstractAddPeopleDialog<P: Props, S: State>
|
|||
_query(query = '') {
|
||||
const {
|
||||
_addPeopleEnabled: addPeopleEnabled,
|
||||
_appId: appId,
|
||||
_dialOutAuthUrl: dialOutAuthUrl,
|
||||
_dialOutRegionUrl: dialOutRegionUrl,
|
||||
_dialOutEnabled: dialOutEnabled,
|
||||
_jwt: jwt,
|
||||
_peopleSearchQueryTypes: peopleSearchQueryTypes,
|
||||
|
@ -244,8 +251,10 @@ export default class AbstractAddPeopleDialog<P: Props, S: State>
|
|||
} = this.props;
|
||||
const options = {
|
||||
addPeopleEnabled,
|
||||
appId,
|
||||
dialOutAuthUrl,
|
||||
dialOutEnabled,
|
||||
dialOutRegionUrl,
|
||||
jwt,
|
||||
peopleSearchQueryTypes,
|
||||
peopleSearchUrl,
|
||||
|
@ -275,14 +284,17 @@ export function _mapStateToProps(state: Object) {
|
|||
const {
|
||||
callFlowsEnabled,
|
||||
dialOutAuthUrl,
|
||||
dialOutRegionUrl,
|
||||
peopleSearchQueryTypes,
|
||||
peopleSearchUrl
|
||||
} = state['features/base/config'];
|
||||
|
||||
return {
|
||||
_addPeopleEnabled: isAddPeopleEnabled(state),
|
||||
_appId: state['features/base/jwt']?.tenant,
|
||||
_callFlowsEnabled: callFlowsEnabled,
|
||||
_dialOutAuthUrl: dialOutAuthUrl,
|
||||
_dialOutRegionUrl: dialOutRegionUrl,
|
||||
_dialOutEnabled: isDialOutEnabled(state),
|
||||
_jwt: state['features/base/jwt'].jwt,
|
||||
_peopleSearchQueryTypes: peopleSearchQueryTypes,
|
||||
|
|
|
@ -8,6 +8,7 @@ import { isJwtFeatureEnabled } from '../base/jwt/functions';
|
|||
import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
|
||||
import { getLocalParticipant, isLocalParticipantModerator } from '../base/participants/functions';
|
||||
import { toState } from '../base/redux/functions';
|
||||
import { doGetJSON } from '../base/util/httpUtils';
|
||||
import { parseURLParams } from '../base/util/parseURLParams';
|
||||
import {
|
||||
StatusCode,
|
||||
|
@ -55,6 +56,34 @@ export function checkDialNumber(
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an ajax request to check if the outbound call is permitted.
|
||||
*
|
||||
* @param {string} dialOutRegionUrl - The config endpoint.
|
||||
* @param {string} jwt - The jwt token.
|
||||
* @param {string} appId - The customer id.
|
||||
* @param {string} phoneNumber - The destination phone number.
|
||||
* @returns {Promise} - The promise created by the request.
|
||||
*/
|
||||
export function checkOutboundDestination(
|
||||
dialOutRegionUrl: string,
|
||||
jwt: string,
|
||||
appId: string,
|
||||
phoneNumber: string
|
||||
): Promise<any> {
|
||||
return doGetJSON(dialOutRegionUrl, true, {
|
||||
body: JSON.stringify({
|
||||
appId,
|
||||
phoneNumber
|
||||
}),
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${jwt}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all non-numeric characters from a string.
|
||||
*
|
||||
|
@ -76,6 +105,11 @@ export type GetInviteResultsOptions = {
|
|||
*/
|
||||
addPeopleEnabled: boolean;
|
||||
|
||||
/**
|
||||
* The customer id.
|
||||
*/
|
||||
appId: string;
|
||||
|
||||
/**
|
||||
* The endpoint to use for checking phone number validity.
|
||||
*/
|
||||
|
@ -86,6 +120,11 @@ export type GetInviteResultsOptions = {
|
|||
*/
|
||||
dialOutEnabled: boolean;
|
||||
|
||||
/**
|
||||
* The endpoint to use for checking dial permission to an outbound destination.
|
||||
*/
|
||||
dialOutRegionUrl: string;
|
||||
|
||||
/**
|
||||
* The jwt token to pass to the search service.
|
||||
*/
|
||||
|
@ -123,8 +162,10 @@ export function getInviteResultsForQuery(
|
|||
const text = query.trim();
|
||||
|
||||
const {
|
||||
dialOutAuthUrl,
|
||||
addPeopleEnabled,
|
||||
appId,
|
||||
dialOutAuthUrl,
|
||||
dialOutRegionUrl,
|
||||
dialOutEnabled,
|
||||
peopleSearchQueryTypes,
|
||||
peopleSearchUrl,
|
||||
|
@ -187,7 +228,7 @@ export function getInviteResultsForQuery(
|
|||
}
|
||||
|
||||
return Promise.all([ peopleSearchPromise, phoneNumberPromise ])
|
||||
.then(([ peopleResults, phoneResults ]) => {
|
||||
.then(async ([ peopleResults, phoneResults ]) => {
|
||||
const results: any[] = [
|
||||
...peopleResults
|
||||
];
|
||||
|
@ -203,14 +244,26 @@ export function getInviteResultsForQuery(
|
|||
= peopleResults.find(result => result.type === INVITE_TYPES.PHONE);
|
||||
|
||||
if (!hasPhoneResult && typeof phoneResults.allow === 'boolean') {
|
||||
results.push({
|
||||
const result = {
|
||||
allowed: phoneResults.allow,
|
||||
country: phoneResults.country,
|
||||
type: INVITE_TYPES.PHONE,
|
||||
number: phoneResults.phone,
|
||||
originalEntry: text,
|
||||
showCountryCodeReminder: !hasCountryCode
|
||||
});
|
||||
};
|
||||
|
||||
if (!phoneResults.allow) {
|
||||
try {
|
||||
const response = await checkOutboundDestination(dialOutRegionUrl, jwt, appId, text);
|
||||
|
||||
result.allowed = response.allowed;
|
||||
} catch (error) {
|
||||
logger.error('Error checking permission to dial to outbound destination', error);
|
||||
}
|
||||
}
|
||||
|
||||
results.push(result);
|
||||
}
|
||||
|
||||
if (sipInviteEnabled && isASipAddress(text)) {
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
"include": ["react/features/**/*.ts", "react/features/**/*.tsx", "./custom.d.ts", "./globals.native.d.ts"],
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "ESNext",
|
||||
"target": "es2020",
|
||||
"jsx": "react-native",
|
||||
"lib": [ "ES2017"],
|
||||
"lib": [ "es2020"],
|
||||
"types": [ "react-native" ],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "Node",
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
"include": ["react/features/**/*.ts", "react/features/**/*.tsx", "./custom.d.ts", "./globals.d.ts"],
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"module": "es6",
|
||||
"target": "es6",
|
||||
"module": "es2020",
|
||||
"target": "es2020",
|
||||
"jsx": "react",
|
||||
"lib": [ "webworker", "ES2020", "DOM" ],
|
||||
"skipLibCheck": true,
|
||||
|
|
Loading…
Reference in New Issue