Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 38 additions & 9 deletions addon/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ var MyQOnly = {
// Add a listener for the popup if it asks for review totals.
browser.runtime.onMessage.addListener(this.onMessage.bind(this));

browser.webRequest.onBeforeSendHeaders.addListener(
this.onPhabSendHeaders.bind(this),
{urls: [PHABRICATOR_ROOT + "/*"]},
["blocking", "requestHeaders"]);

console.debug("Looking for feature rev");
let { featureRev, } = await browser.storage.local.get("featureRev");
if (!featureRev) {
Expand Down Expand Up @@ -77,7 +82,7 @@ var MyQOnly = {
let phabService = this._getService("phabricator");
if (!phabService) {
await this._addService("phabricator", {
container: 0,
container: "",
inclReviewerGroups: true,
});
} else if (phabService.settings.inclReviewerGroups === undefined) {
Expand Down Expand Up @@ -234,7 +239,7 @@ var MyQOnly = {
};
}

if (await this._hasPhabricatorCookie()) {
if (await this._getPhabricatorCookies()) {
console.log("Phabricator session found! Attempting to get dashboard " +
"page.");

Expand All @@ -258,30 +263,44 @@ var MyQOnly = {
},

async _hasPhabricatorSession({ testingURL = null, } = {}) {
if (await this._hasPhabricatorCookie()) {
if (await this._getPhabricatorCookies()) {
let { ok, } = await this._phabricatorDocumentBody({ testingURL, });
return ok;
}

return false;
},

async _hasPhabricatorCookie() {
let phabCookie = await browser.cookies.get({
async _getPhabricatorCookies() {
const cookieGetOpts = {
url: PHABRICATOR_ROOT,
name: "phsid",
});
return !!phabCookie;
};

const phabService = (this.services || []).find(
s => s.type == "phabricator");
if (phabService) {
if (phabService.settings.container) {
cookieGetOpts.storeId = phabService.settings.container;
}
}

let phabCookies = await browser.cookies.getAll(cookieGetOpts);
let cookieStrings = (phabCookies || []).filter(
c => c.name == "phsid" || c.name == "phusr").map(
c => `${c.name}=${c.value}`);

return cookieStrings.join("; ");
},

async _phabricatorDocumentBody({ testingURL = null, } = {}) {
let url = testingURL ||
[PHABRICATOR_ROOT, PHABRICATOR_DASHBOARD,].join("/");

let cookies = await this._getPhabricatorCookies();
let req = new Request(url, {
method: "GET",
headers: {
"Content-Type": "text/html",
"X-MyQOnly-Phab-Cookies": cookies,
},
redirect: "follow",
});
Expand All @@ -292,6 +311,16 @@ var MyQOnly = {
return { ok, pageBody, };
},

onPhabSendHeaders(e) {
const indexOfSpecialHeader = e.requestHeaders.map(h => h.name).indexOf("X-MyQOnly-Phab-Cookies");
if (indexOfSpecialHeader >= 0) {
let [phabCookie] = e.requestHeaders.splice(indexOfSpecialHeader, 1);
let cookieHeader = e.requestHeaders.find(h => h.name == "Cookie");
cookieHeader.value = phabCookie.value;
}
return {requestHeaders: e.requestHeaders};
},

async phabricatorReviewRequests({ testingURL = null, } = {}) {
let { ok, pageBody, } =
await this._phabricatorDocumentBody({ testingURL, });
Expand Down
9 changes: 7 additions & 2 deletions addon/content/options/options.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ input[type="text"] {
width: 50ch;
}

label, .form-rows {
label, .form-rows, select {
margin-top: 5px;
}

Expand Down Expand Up @@ -54,4 +54,9 @@ section:not(:first-child) {

#debug:not(:hover) {
opacity: 0;
}
}

div.service-settings:not(.has-containers) > #phabricator-container-options,
div.service-settings.has-containers > #phabricator-no-container-options {
display: none;
}
6 changes: 5 additions & 1 deletion addon/content/options/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ <h2>Services</h2>

<h3>Phabricator</h3>
<div class="service-settings" data-type="phabricator">
<div class="form-rows">
<div id="phabricator-container-options" class="form-rows">
<label for="phabricator-container">Phabricator container</label>
<select id="phabricator-container" name="phabricator-container" data-setting="container"></select>
</div>
<div id="phabricator-no-container-options" class="form-rows">
<input type="checkbox" id="phabricator-enabled" data-setting="container" value="0">
<label for="phabricator-enabled">Use pre-existing Phabricator session in default container</label>
</div>
Expand Down
45 changes: 33 additions & 12 deletions addon/content/options/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,40 @@ const Options = {
document.dispatchEvent(initted);
},

populatePhabricator(service) {
async _getContainerNamesAndStoreIds() {
if (!browser.contextualIdentities) {
return null;
}

const identities = await browser.contextualIdentities.query({});

return [{name: "Default", cookieStoreId: ""}, ...identities];
},

async populatePhabricator(service) {
let phabricatorSettings =
document.querySelector(".service-settings[data-type='phabricator']");

let container =
phabricatorSettings.querySelector("[data-setting='container']");
container.checked = !!service.settings.container;
const identities = await this._getContainerNamesAndStoreIds();
if (identities) {
// Use UI for containers
const select = phabricatorSettings.querySelector(
"select[data-setting='container']");
phabricatorSettings.classList.add("has-containers");
for (let identity of identities) {
const option = document.createElement("option");
option.value = identity.cookieStoreId;
option.textContent = identity.name;
if (identity.cookieStoreId == service.settings.container) {
option.selected = true;
}
select.appendChild(option);
}
} else {
let container =
phabricatorSettings.querySelector("input[data-setting='container']");
container.checked = !!service.settings.container;
}

let inclReviewerGroups =
phabricatorSettings.querySelector("[data-setting='inclReviewerGroups']");
Expand Down Expand Up @@ -104,13 +131,8 @@ const Options = {

onUpdateService(event, serviceType) {
let changedSetting = event.target.dataset.setting;
let newValue;
switch (event.target.type) {
case "text":
case "password":
newValue = event.target.value;
break;
case "checkbox":
let newValue = event.target.value;
if (event.target.type == "checkbox") {
if (event.target.checked) {
if (event.target.hasAttribute("value")) {
newValue = event.target.value;
Expand All @@ -120,7 +142,6 @@ const Options = {
} else {
newValue = null;
}
break;
}

// For now, there's only a single service instance per type.
Expand Down
3 changes: 3 additions & 0 deletions addon/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@
"permissions": [
"alarms",
"cookies",
"contextualIdentities",
"storage",
"webRequest",
"webRequestBlocking",
"https://phabricator.services.mozilla.com/*",
"https://bugzilla.mozilla.org/*"
]
Expand Down
4 changes: 2 additions & 2 deletions tests/background.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe("MyQOnly initting fresh", function() {
id: 3,
type: "phabricator",
settings: {
container: 0,
container: "",
inclReviewerGroups: true,
},
},],
Expand All @@ -110,7 +110,7 @@ describe("MyQOnly initting fresh", function() {
id: 1,
type: "phabricator",
settings: {
container: 0,
container: "",
inclReviewerGroups: true,
},
},],
Expand Down