{"version":3,"sources":["../call-control-sdk/lib/utils/numberMask.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useSDKPermissions } from \"../hooks/useSDKPermissions\";\nimport { SDK_PERMISSIONS } from \"../permissions\";\n\n/**\n * Phone-number masking for the SDK pages, one rule for all of them.\n *\n * `phone_number:view_unmasked` decides whether a login sees a customer / caller number in\n * full. Without it every number these pages render keeps only its last few digits\n * (VISIBLE_DIGITS below) and everything before them becomes `x` — enough to recognise\n * the call in front of you, not enough to harvest the number.\n *\n * Fail-closed: a role that has not been granted the code gets masked numbers, and so\n * does a session whose permissions have not loaded yet. `*` grants it, like\n * everything else (see sdkStateManager.hasPermission).\n *\n * This is the SDK's own copy of the host app's src/utils/numberMask.ts — the two must\n * behave identically, since the same screens exist in both. Editable form fields, the\n * softphone keypad and internal SIP extensions are deliberately NOT masked; the host\n * copy carries the full reasoning.\n */\n\n/**\n * Digits left visible at the end of a masked number. Must match VISIBLE_DIGITS in the\n * host app's src/utils/numberMask.ts and MASK_VISIBLE_DIGITS in the browser phone's\n * ahs-cti-ui.js — the same number can appear on all three surfaces at once.\n */\nconst VISIBLE_DIGITS = 3;\n\n/**\n * `\"+919849279377\"` → `\"+xxxxxxxxx377\"`, `\"9849279377\"` → `\"xxxxxxx377\"`.\n *\n * One `x` per hidden digit, so a masked 10-digit mobile still reads as a 10-digit\n * mobile. A value with no digits in it (a name, an em-dash placeholder) is returned\n * untouched, so a placeholder never turns into a row of `x`.\n */\nexport function maskPhoneNumber(value: string | number | null | undefined): string {\n  if (value == null) return \"\";\n  const raw = String(value).trim();\n  if (!raw) return \"\";\n  const digits = raw.replace(/\\D/g, \"\");\n  if (!digits) return raw;\n  const plus = raw.startsWith(\"+\") ? \"+\" : \"\";\n  // The whole number IS its visible tail (a short code / extension) — nothing to hide\n  // beyond what is already showing.\n  if (digits.length <= VISIBLE_DIGITS) return plus + digits;\n  return plus + \"x\".repeat(digits.length - VISIBLE_DIGITS) + digits.slice(-VISIBLE_DIGITS);\n}\n\n/** Permission-list form, for code that holds raw permissions rather than the hook. */\nexport function canUnmaskNumbers(permissions: string[] | undefined): boolean {\n  const perms = permissions ?? [];\n  if (perms.includes(SDK_PERMISSIONS.WILDCARD)) return true;\n  return perms.includes(SDK_PERMISSIONS.PHONE_NUMBER_VIEW_UNMASKED);\n}\n\n/**\n * The hook the pages use: `maskNumber(value)` returns the number as-is for a role\n * that may see it and the masked form for everyone else.\n */\nexport function useNumberMask() {\n  const { hasPermission } = useSDKPermissions();\n  const unmasked = hasPermission(SDK_PERMISSIONS.PHONE_NUMBER_VIEW_UNMASKED);\n  const maskNumber = useCallback(\n    (value: string | number | null | undefined): string => {\n      if (unmasked) return value == null ? \"\" : String(value);\n      return maskPhoneNumber(value);\n    },\n    [unmasked],\n  );\n  return { unmasked, maskNumber };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,mBAAmB;AA2B5B,IAAM,iBAAiB;AAShB,SAAS,gBAAgB,OAAmD;AACjF,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,MAAM,OAAO,KAAK,EAAE,KAAK;AAC/B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,SAAS,IAAI,QAAQ,OAAO,EAAE;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,OAAO,IAAI,WAAW,GAAG,IAAI,MAAM;AAGzC,MAAI,OAAO,UAAU,eAAgB,QAAO,OAAO;AACnD,SAAO,OAAO,IAAI,OAAO,OAAO,SAAS,cAAc,IAAI,OAAO,MAAM,CAAC,cAAc;AACzF;AAaO,SAAS,gBAAgB;AAC9B,QAAM,EAAE,cAAc,IAAI,kBAAkB;AAC5C,QAAM,WAAW,cAAc,gBAAgB,0BAA0B;AACzE,QAAM,aAAa;AAAA,IACjB,CAAC,UAAsD;AACrD,UAAI,SAAU,QAAO,SAAS,OAAO,KAAK,OAAO,KAAK;AACtD,aAAO,gBAAgB,KAAK;AAAA,IAC9B;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AACA,SAAO,EAAE,UAAU,WAAW;AAChC;","names":[]}