Skip to content

Outbound callback source reference

Source commit: 796717af517d50d52249a484fa35c42394ada304.

Generated from this revision's source declarations. These defaults and traits do not report a running installation's active settings, prove provider delivery, or establish that newly added components are integrated.

These excerpts are read directly from source with Python's AST; callback runtime modules are not imported. The build provenance hashes each listed module. The verifier, URL construction and captured-attempt acceptance code below are regenerated on every source build.

Maintained Phaxio setup and verification guidance. This reference covers outbound observations; it does not establish inbound verification readiness.

_pairs

Source: api/app/provider_signatures.py.

def _pairs(values, value_type):
    if not isinstance(values, Sequence) or isinstance(values, (str, bytes, bytearray)):
        return None
    pairs = []
    for pair in values:
        if (not isinstance(pair, Sequence) or isinstance(pair, (str, bytes, bytearray))
                or len(pair) != 2 or not isinstance(pair[0], str) or not isinstance(pair[1], value_type)):
            return None
        pairs.append((pair[0], pair[1]))
    # Stable sorting retains wire order for repeated names and never mutates input.
    return sorted(pairs, key=lambda pair: pair[0])

verify_phaxio_signature

Source: api/app/provider_signatures.py.

def verify_phaxio_signature(
    callback_token: str,
    callback_url: str,
    fields: Sequence[tuple[str, str]],
    files: Sequence[tuple[str, bytes]],
    signature: str,
) -> bool:
    """Verify Phaxio's lowercase hex SHA1 HMAC with its distinct Callback Token.

    URL is the exact submitted public URL, including query/trailing slash.
    Ordered repeated fields/file parts are retained; file content uses SHA1 hex.
    Malformed input fails closed. The send API secret is not a substitute token.
    """
    try:
        if (not isinstance(callback_token, str) or not callback_token or not isinstance(signature, str)
                or re.fullmatch(r'[0-9a-f]{40}', signature) is None or _public_url(callback_url) is None):
            return False
        parameters, attachments = _pairs(fields, str), _pairs(files, bytes)
        if parameters is None or attachments is None:
            return False
        message = callback_url + ''.join(name + value for name, value in parameters)
        message += ''.join(name + hashlib.sha1(content).hexdigest() for name, content in attachments)
        expected = hmac.new(callback_token.encode('utf-8'), message.encode('utf-8'), hashlib.sha1).hexdigest()
        return hmac.compare_digest(expected, signature)
    except (TypeError, ValueError):
        return False

callback_base_url

Source: api/app/callback_locator.py.

def callback_base_url(revision, profile):
    """Use the captured override or this installation's captured public URL."""
    configuration = profile.configuration
    explicit = configuration.settings.get('callback_url')
    if explicit:
        return explicit
    return revision.values.public_api_url.rstrip('/') + '/' + configuration.provider_id + '-callback'

callback_url_with_locators

Source: api/app/callback_locator.py.

def callback_url_with_locators(callback_url: str, job_id: str, attempt_id: str | None = None) -> str:
    """Preserve unrelated query bytes/order; replace reserved locators once.

    The caller supplies its captured public URL, never proxy/request headers.
    Omitting attempt_id removes stale attempt locators for the legacy interface.
    """
    try:
        if (not isinstance(callback_url, str) or not callback_url
                or any(ord(char) <= 32 or ord(char) == 127 for char in callback_url)
                or '#' in callback_url):
            raise ValueError
        parsed = urlsplit(callback_url)
        if (parsed.scheme not in {'http', 'https'} or not parsed.hostname
                or parsed.username is not None or parsed.password is not None):
            raise ValueError
        parsed.port
        if (not isinstance(job_id, str) or not job_id
                or (attempt_id is not None and (not isinstance(attempt_id, str) or not attempt_id))):
            raise ValueError
        callback_url.encode('utf-8')
        remaining = [part for part in parsed.query.split('&') if
            unquote_plus(part.partition('=')[0]) not in {'job_id', 'attempt_id'}] if parsed.query else []
        locators = [('job_id', job_id)]
        if attempt_id is not None:
            locators.append(('attempt_id', attempt_id))
        query = '&'.join(remaining + [urlencode(locators)])
        return urlunsplit((parsed.scheme, parsed.netloc, parsed.path, query, ''))
    except (TypeError, ValueError):
        raise ValueError('Invalid public callback URL or locator.') from None

CapturedCallbacks.receive

Source: api/app/outbound_callbacks.py.

def receive(self, provider, job_id, attempt_id, *, fields, files, signature):
    if (provider not in {'phaxio', 'signalwire'}
            or not isinstance(job_id, str) or re.fullmatch('[a-f0-9]{32}', job_id) is None
            or not isinstance(attempt_id, str) or re.fullmatch('[a-f0-9]{32}', attempt_id) is None):
        raise CallbackRejected()
    try:
        row = self.store.get(job_id)
    except DeliveryConflict:
        raise CallbackRejected() from None
    if row['attempt_id'] != attempt_id:
        raise CallbackRejected()
    # Authenticate against the account this attempt used, never the fax's default.
    revision, profile = self.store.attempt_context(job_id, attempt_id)
    configuration = profile.configuration
    if configuration.provider_id != provider or configuration.manifest is not None:
        raise CallbackRejected()
    url = callback_url_with_locators(callback_base_url(revision, profile), job_id, attempt_id)
    credentials = configuration.credentials
    if provider == 'phaxio':
        # Disabled verification means callbacks are disabled; it never grants
        # an unsigned request authority to change a delivery result.
        if configuration.settings.get('verify_signature', True) is not True:
            raise CallbackRejected()
        authenticated = verify_phaxio_signature(credentials.get('callback_token', ''), url, fields, files, signature)
    else:
        authenticated = not files and verify_signalwire_signature(
            credentials.get('webhook_signing_key', ''), url, fields, signature)
    if not authenticated:
        raise CallbackRejected()
    try:
        if provider == 'phaxio':
            sid, status = _phaxio_payload(fields)
        else:
            sid, status = _one(fields, {'FaxSid', 'sid'}), _one(fields, {'FaxStatus', 'status'})
        status = normalize_status(status)
        # Match signature ordering: distinct names may move, but repeated
        # names retain their signed wire order. Never sort their values.
        event = json.dumps({'fields': sorted(fields, key=lambda part: part[0]),
            'files': [(name, hashlib.sha256(data).hexdigest())
                      for name, data in sorted(files, key=lambda part: part[0])]},
            sort_keys=True, separators=(',', ':'))
        key = 'callback:' + hashlib.sha256(event.encode()).hexdigest()
    except (TypeError, ValueError):
        raise CallbackRejected() from None
    return self.store.observe(job_id, attempt_id=attempt_id, profile_id=profile.id,
                              provider_sid=sid, status=status, event_key=key)