function parseAllowlistUrlForATS()

in lib/prepare.js [1265:1338]


function parseAllowlistUrlForATS (url, options) {
    // Guiding principle: we only set values in retObj if they are NOT the default
    const retObj = {};

    if (url === '*') {
        retObj.Hostname = '*';
        let val;

        val = (options.allows_arbitrary_loads_in_web_content === 'true');
        if (options.allows_arbitrary_loads_in_web_content && val) { // default is false
            retObj.NSAllowsArbitraryLoadsInWebContent = true;
        }

        val = (options.allows_arbitrary_loads_for_media === 'true');
        if (options.allows_arbitrary_loads_for_media && val) { // default is false
            retObj.NSAllowsArbitraryLoadsForMedia = true;
        }

        val = (options.allows_local_networking === 'true');
        if (options.allows_local_networking && val) { // default is false
            retObj.NSAllowsLocalNetworking = true;
        }

        return retObj;
    }

    let href = null;
    try {
        href = new URL(url);
    } catch (e) {
        const scheme = url.split(':')[0];
        // If there's a wildcard in the protocol, the URL will fail to parse
        // Replace it with "http" to allow insecure loads
        if (scheme.includes('*')) {
            href = new URL(url.replace(scheme, 'http'));
        } else {
            return null;
        }
    }

    retObj.Hostname = href.hostname;

    // Handling "scheme:*" case to avoid creating of a blank key in NSExceptionDomains.
    if (retObj.Hostname === '') {
        return null;
    }

    // check origin, if it allows subdomains (wildcard in hostname), we set NSIncludesSubdomains to YES. Default is NO
    if (retObj.Hostname.startsWith('*.')) {
        retObj.NSIncludesSubdomains = true;
        retObj.Hostname = href.hostname.substring(2);
    }

    if (options.minimum_tls_version && options.minimum_tls_version !== 'TLSv1.2') { // default is TLSv1.2
        retObj.NSExceptionMinimumTLSVersion = options.minimum_tls_version;
    }

    const rfs = (options.requires_forward_secrecy === 'true');
    if (options.requires_forward_secrecy && !rfs) { // default is true
        retObj.NSExceptionRequiresForwardSecrecy = false;
    }

    const rct = (options.requires_certificate_transparency === 'true');
    if (options.requires_certificate_transparency && rct) { // default is false
        retObj.NSRequiresCertificateTransparency = true;
    }

    // if the scheme is HTTP, we set NSExceptionAllowsInsecureHTTPLoads to YES. Default is NO
    if (href.protocol === 'http:') {
        retObj.NSExceptionAllowsInsecureHTTPLoads = true;
    }

    return retObj;
}