Skip to content

Commit

Permalink
#3111: open managed extension automatically if unlinked (#3128)
Browse files Browse the repository at this point in the history
  • Loading branch information
twschiller committed Apr 8, 2022
1 parent 4af3508 commit 09f4dca
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
24 changes: 24 additions & 0 deletions src/background/deployment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const isLinkedMock = isLinked as jest.Mock;
const readAuthDataMock = readAuthData as jest.Mock;
const getManifestMock = browser.runtime.getManifest as jest.Mock;
const openOptionsPageMock = browser.runtime.openOptionsPage as jest.Mock;
const browserManagedStorageMock = browser.storage.managed.get as jest.Mock;
const containsPermissionsMock = browser.permissions.contains as jest.Mock;
const refreshRegistriesMock = refreshRegistries as jest.Mock;
const isUpdateAvailableMock = isUpdateAvailable as jest.Mock;
Expand All @@ -122,6 +123,8 @@ beforeEach(() => {
nextUpdate: undefined,
});

browserManagedStorageMock.mockResolvedValue({});

readAuthDataMock.mockResolvedValue({
organizationId: "00000000-00000000-00000000-00000000",
});
Expand All @@ -134,7 +137,28 @@ beforeEach(() => {
});

describe("updateDeployments", () => {
test("opens options page if managed enterprise customer not linked", async () => {
readAuthDataMock.mockResolvedValue({
organizationId: null,
});

browserManagedStorageMock.mockResolvedValue({
managedOrganizationId: "00000000-00000000-00000000-00000000",
});

isLinkedMock.mockResolvedValue(false);

await updateDeployments();

expect(reportEvent).toHaveBeenCalledWith(
"OrganizationExtensionLink",
expect.anything()
);
expect(openOptionsPageMock.mock.calls).toHaveLength(1);
});

test("opens options page if enterprise customer becomes unlinked", async () => {
// `readAuthDataMock` already has organizationId "00000000-00000000-00000000-00000000"
isLinkedMock.mockResolvedValue(false);

await updateDeployments();
Expand Down
39 changes: 31 additions & 8 deletions src/background/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ const { reducer, actions } = extensionsSlice;

const UPDATE_INTERVAL_MS = 5 * 60 * 1000;

// See managedStorageSchema.json
const MANAGED_CAMPAIGN_IDS_KEY = "campaignIds" as ManualStorageKey;
const MANAGED_ORGANIZATION_ID_KEY = "managedOrganizationId" as ManualStorageKey;

/**
* Deployment installed on the client. A deployment may be installed but not active (see DeploymentContext.active)
Expand Down Expand Up @@ -280,22 +282,43 @@ export async function updateDeployments(): Promise<void> {
]);

if (!linked) {
// If the Browser extension is unlinked (it doesn't have the API key):
// - If the was part of an organization, they must have somehow lost their token: 1) the token is no longer valid
const [campaignIds = [], managedOrganizationId] = await Promise.all([
readStorage(MANAGED_CAMPAIGN_IDS_KEY, undefined, "managed"),
readStorage(MANAGED_ORGANIZATION_ID_KEY, undefined, "managed"),
]);

// If the Browser extension is unlinked (it doesn't have the API key), one of the following must be true:
// - The user has managed install, and they have not linked their extension yet
// - The user is part of an organization, and somehow lost their token: 1) the token is no longer valid
// so PixieBrix cleared it out, 2) something removed the local storage entry
// - If the user is not an enterprise user (or has not linked their extension yet), just NOP. They lik
// likely they just need to reconnect their extension. If it's a non-enterprise user, they shouldn't have any
// deployments installed anyway.
// - If the user is not an enterprise user (or has not linked their extension yet), just NOP. They likely they just
// need to reconnect their extension. If it's a non-enterprise user, they shouldn't have any deployments
// installed anyway.

if (organizationId != null) {
reportEvent("OrganizationExtensionLink", {
organizationId,
managedOrganizationId,
initial: false,
campaignIds:
(await readStorage(MANAGED_CAMPAIGN_IDS_KEY, undefined, "managed")) ??
[],
campaignIds,
});

void browser.runtime.openOptionsPage();

return;
}

if (managedOrganizationId != null) {
reportEvent("OrganizationExtensionLink", {
organizationId,
managedOrganizationId,
initial: true,
campaignIds,
});

void browser.runtime.openOptionsPage();

return;
}

return;
Expand Down
2 changes: 1 addition & 1 deletion static/managedStorageSchema.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"type": "object",
"properties": {
"primaryOrganizationId": {
"managedOrganizationId": {
"type": "string",
"description": "PixieBrix organization ID the extension should link to"
},
Expand Down

0 comments on commit 09f4dca

Please sign in to comment.