diff --git a/packages/@webex/contact-center/src/cc.ts b/packages/@webex/contact-center/src/cc.ts index 41292d68e6a..68973628bfa 100644 --- a/packages/@webex/contact-center/src/cc.ts +++ b/packages/@webex/contact-center/src/cc.ts @@ -785,7 +785,11 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter METRIC_EVENT_NAMES.STATION_LOGIN_FAILED, ]); - if (data.loginOption === LoginOption.AGENT_DN && !isValidDialNumber(data.dialNumber)) { + const dialPlanEntries = this.agentConfig?.dialPlan?.dialPlanEntity ?? []; + if ( + data.loginOption === LoginOption.AGENT_DN && + !isValidDialNumber(data.dialNumber, dialPlanEntries) + ) { const error = new Error('INVALID_DIAL_NUMBER'); // @ts-ignore - adding custom key to the error object error.details = {data: {reason: 'INVALID_DIAL_NUMBER'}} as Failure; diff --git a/packages/@webex/contact-center/src/services/core/Utils.ts b/packages/@webex/contact-center/src/services/core/Utils.ts index 8e439607933..c6b99b9589a 100644 --- a/packages/@webex/contact-center/src/services/core/Utils.ts +++ b/packages/@webex/contact-center/src/services/core/Utils.ts @@ -10,6 +10,7 @@ import { Interaction, } from '../task/types'; import {PARTICIPANT_TYPES, STATE_CONSULT} from './constants'; +import {DialPlan} from '../config/types'; /** * Extracts common error details from a Webex request payload. @@ -48,11 +49,37 @@ const getAgentActionTypeFromTask = (taskData?: TaskData): 'DIAL_NUMBER' | '' => return isDialNumber || isEntryPointVariant ? 'DIAL_NUMBER' : ''; }; -export const isValidDialNumber = (input: string): boolean => { - // This regex checks for a valid dial number format for only few countries such as US, Canada. - const regexForDn = /1[0-9]{3}[2-9][0-9]{6}([,]{1,10}[0-9]+){0,1}/; +// Fallback regex for US/Canada dial numbers when no dial plan entries are configured +export const FALLBACK_DIAL_NUMBER_REGEX = /1[0-9]{3}[2-9][0-9]{6}([,]{1,10}[0-9]+){0,1}/; - return regexForDn.test(input); +/** + * Validates a dial number against the provided dial plan regex patterns. + * A number is valid if it matches at least one regex pattern in the dial plans. + * Falls back to US/Canada regex validation if no dial plan entries are configured. + * + * @param input - The dial number to validate + * @param dialPlanEntries - Array of dial plan entries containing regex patterns + * @returns true if the input matches at least one dial plan regex pattern, false otherwise + */ +export const isValidDialNumber = ( + input: string, + dialPlanEntries: DialPlan['dialPlanEntity'] +): boolean => { + if (!dialPlanEntries || dialPlanEntries.length === 0) { + LoggerProxy.info('No dial plan entries found. Falling back to US number validation.'); + + return FALLBACK_DIAL_NUMBER_REGEX.test(input); + } + + return dialPlanEntries.some((entry) => { + try { + const regex = new RegExp(entry.regex); + + return regex.test(input); + } catch { + return false; + } + }); }; export const getStationLoginErrorData = (failure: Failure, loginOption: LoginOption) => { @@ -74,7 +101,7 @@ export const getStationLoginErrorData = (failure: Failure, loginOption: LoginOpt }, INVALID_DIAL_NUMBER: { message: - 'Enter a valid US dial number. For help, reach out to your administrator or support team.', + 'Enter a valid dial number. For help, reach out to your administrator or support team.', fieldName: loginOption, }, }; diff --git a/packages/@webex/contact-center/test/unit/spec/services/core/Utils.ts b/packages/@webex/contact-center/test/unit/spec/services/core/Utils.ts index 35c0e895574..ac0543c415d 100644 --- a/packages/@webex/contact-center/test/unit/spec/services/core/Utils.ts +++ b/packages/@webex/contact-center/test/unit/spec/services/core/Utils.ts @@ -1,4 +1,5 @@ import * as Utils from '../../../../../src/services/core/Utils'; +import {FALLBACK_DIAL_NUMBER_REGEX} from '../../../../../src/services/core/Utils'; import LoggerProxy from '../../../../../src/logger-proxy'; import WebexRequest from '../../../../../src/services/core/WebexRequest'; import {LoginOption, WebexRequestPayload} from '../../../../../src/types'; @@ -244,7 +245,7 @@ describe('Utils', () => { const result = Utils.getStationLoginErrorData(failure, LoginOption.AGENT_DN); expect(result).toEqual({ message: - 'Enter a valid US dial number. For help, reach out to your administrator or support team.', + 'Enter a valid dial number. For help, reach out to your administrator or support team.', fieldName: LoginOption.AGENT_DN, }); }); @@ -557,4 +558,65 @@ describe('Utils', () => { }); }); + describe('isValidDialNumber', () => { + const anyFormatEntry = { + name: 'Any Format', + prefix: '', + regex: '([0-9a-zA-Z]+[-._])*[0-9a-zA-Z]+', + strippedChars: '( )-', + }; + + const usOnlyEntry = { + name: 'US', + prefix: '1', + regex: FALLBACK_DIAL_NUMBER_REGEX.source, + strippedChars: '( )-', + }; + + describe('with multiple dial plan entries (Any Format + US)', () => { + const dialPlanEntries = [anyFormatEntry, usOnlyEntry]; + + it('should return true for a valid US phone number', () => { + const result = Utils.isValidDialNumber('12223334567', dialPlanEntries); + expect(result).toBe(true); + }); + + it('should return true for a UK phone number', () => { + const result = Utils.isValidDialNumber('+442030484377', dialPlanEntries); + expect(result).toBe(true); + }); + }); + + describe('with US-only dial plan entry', () => { + const dialPlanEntries = [usOnlyEntry]; + + it('should return true for a valid US phone number', () => { + const result = Utils.isValidDialNumber('12223334567', dialPlanEntries); + expect(result).toBe(true); + }); + + it('should return false for a UK phone number', () => { + const result = Utils.isValidDialNumber('+442030484377', dialPlanEntries); + expect(result).toBe(false); + }); + + it('should return false for an invalid US number format', () => { + const result = Utils.isValidDialNumber('1234567890', dialPlanEntries); + expect(result).toBe(false); + }); + }); + + describe('with empty dial plan entries (fallback to US regex)', () => { + it('should return true for a valid US phone number', () => { + const result = Utils.isValidDialNumber('12223334567', []); + expect(result).toBe(true); + }); + + it('should return false for a UK phone number', () => { + const result = Utils.isValidDialNumber('+442030484377', []); + expect(result).toBe(false); + }); + }); + }); + });