Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
"use strict";
const { IPProtectionService, IPProtectionStates } = ChromeUtils.importESModule(
"moz-src:///toolkit/components/ipprotection/IPProtectionService.sys.mjs"
);
const { IPPProxyManager, IPPProxyStates } = ChromeUtils.importESModule(
"moz-src:///toolkit/components/ipprotection/IPPProxyManager.sys.mjs"
);
const { IPPSignInWatcher } = ChromeUtils.importESModule(
"moz-src:///toolkit/components/ipprotection/IPPSignInWatcher.sys.mjs"
);
const { ProxyPass, ProxyUsage, Entitlement } = ChromeUtils.importESModule(
"moz-src:///toolkit/components/ipprotection/GuardianClient.sys.mjs"
);
const { RemoteSettings } = ChromeUtils.importESModule(
);
const { IPProtectionActivator } = ChromeUtils.importESModule(
"moz-src:///toolkit/components/ipprotection/IPProtectionActivator.sys.mjs"
);
IPProtectionActivator.setupHelpers();
const { sinon } = ChromeUtils.importESModule(
);
function waitForEvent(target, eventName, callback = () => true) {
return new Promise(resolve => {
let listener = event => {
if (callback()) {
target.removeEventListener(eventName, listener);
resolve(event);
}
};
target.addEventListener(eventName, listener);
});
}
async function putServerInRemoteSettings(
server = {
hostname: "test1.example.com",
port: 443,
quarantined: false,
}
) {
const TEST_US_CITY = {
name: "Test City",
code: "TC",
servers: [server],
};
const US = {
name: "United States",
code: "US",
cities: [TEST_US_CITY],
};
do_get_profile();
const client = RemoteSettings("vpn-serverlist");
await client.db.clear();
await client.db.create(US);
await client.db.importChanges({}, Date.now());
}
/* exported putServerInRemoteSettings */
/* exported setupStubs */
const defaultStubOptions = {
signedIn: true,
isLinkedToGuardian: true,
validProxyPass: true,
entitlement: createTestEntitlement(),
proxyUsage: new ProxyUsage(
"5368709120",
"4294967296",
"3026-02-01T00:00:00.000Z"
),
};
Object.freeze(defaultStubOptions);
function setupStubs(
sandbox,
aOptions = {
...defaultStubOptions,
}
) {
const options = { ...defaultStubOptions, ...aOptions };
sandbox.stub(IPPSignInWatcher, "isSignedIn").get(() => options.signedIn);
sandbox
.stub(IPProtectionService.guardian, "isLinkedToGuardian")
.resolves(options.isLinkedToGuardian);
sandbox.stub(IPProtectionService.guardian, "fetchUserInfo").resolves({
status: 200,
error: null,
entitlement: options.entitlement,
});
sandbox.stub(IPProtectionService.guardian, "enroll").resolves({
status: 200,
error: null,
ok: true,
});
sandbox.stub(IPProtectionService.guardian, "fetchProxyPass").resolves({
status: 200,
error: undefined,
pass: new ProxyPass(
options.validProxyPass
? createProxyPassToken()
: createExpiredProxyPassToken()
),
usage: options.proxyUsage,
});
sandbox
.stub(IPProtectionService.guardian, "fetchProxyUsage")
.resolves(options.proxyUsage);
}
/**
* Creates a Token that can be fed as a Network Response from Guardian
* to simulate a Proxy Pass.
*
* @param {Temporal.Instant} from
* @param {Temporal.Instant} until
* @returns {string} JWT Token
*/
function createProxyPassToken(
from = Temporal.Now.instant(),
until = from.add({ hours: 24 })
) {
const header = {
alg: "HS256",
typ: "JWT",
};
const body = {
iat: Math.floor(from.add({ seconds: 1 }).epochMilliseconds / 1000),
nbf: Math.floor(from.epochMilliseconds / 1000),
exp: Math.floor(until.epochMilliseconds / 1000),
sub: "proxy-pass-user-42",
aud: "guardian-proxy",
iss: "vpn.mozilla.org",
};
const encode = obj => btoa(JSON.stringify(obj));
return [encode(header), encode(body), "signature"].join(".");
}
/* exported createExpiredProxyPassToken */
function createExpiredProxyPassToken() {
return createProxyPassToken(
Temporal.Now.instant().subtract({ hours: 2 }),
Temporal.Now.instant().subtract({ hours: 1 })
);
}
/* exported createExpiredProxyPassToken */
/**
* Creates a test Entitlement with default values.
*
* @param {object} overrides - Optional fields to override
* @returns {Entitlement}
*/
function createTestEntitlement(overrides = {}) {
return new Entitlement({
autostart: false,
created_at: "2023-01-01T12:00:00.000Z",
limited_bandwidth: false,
location_controls: false,
subscribed: false,
uid: 42,
website_inclusion: false,
maxBytes: "0",
...overrides,
});
}
/* exported createTestEntitlement */