Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DX: Split out feature flags from the Me user data endpoint #7734

Merged
merged 39 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4138169
split out feature flags from Me endpoint
Feb 26, 2024
d15a213
add new file to null checks
Feb 26, 2024
bbdb775
fix tests
Feb 26, 2024
ac07b18
Update src/auth/featureFlags.ts
BLoe Feb 26, 2024
50497ba
add comment back
Feb 26, 2024
a1c8002
clean up
Feb 26, 2024
6f3232e
Merge branch 'main' into dev/separate-feature-flags-from-me
Feb 26, 2024
cf7c920
add tests
Feb 26, 2024
ca10d9d
add test file to null checks
Feb 26, 2024
cb0efeb
some pr feedback
Feb 26, 2024
28d8a57
reset feature flags on auth change
Feb 26, 2024
4d7ce7c
make sure flag is cleared
Feb 26, 2024
8df4923
convert to use webext-storage-cache
Feb 26, 2024
f37b441
fix jest config, fix storage override, update snapshots
Feb 27, 2024
5c08bbf
Merge branch 'main' into dev/separate-feature-flags-from-me
Feb 27, 2024
075ae2c
package lock changes?
Feb 27, 2024
d03a9cd
Merge branch 'main' into dev/separate-feature-flags-from-me
Feb 27, 2024
353ad78
move feature flag fetch to background, and add useFlags tests
Feb 27, 2024
692ccae
fix manifest snapshot
Feb 27, 2024
cfa8038
fix package lock
Feb 27, 2024
f725676
Merge branch 'main' into dev/separate-feature-flags-from-me
Feb 27, 2024
6334c27
Fix package lock
twschiller Feb 27, 2024
029b063
Fix package lock
twschiller Feb 27, 2024
d60d1e5
Add CI check
fregante Feb 28, 2024
e30fa32
Add unique identifiers
fregante Feb 28, 2024
c665d5e
restore lockfile
fregante Feb 28, 2024
3805446
/2
fregante Feb 28, 2024
c43f52f
Automatically hide comment once resolved
fregante Feb 28, 2024
a97c0d2
Test strictNullChecks CI check for messenger
fregante Feb 28, 2024
21b72f6
Drop CI workflows from this PR, move to their own PRs
fregante Feb 28, 2024
912f6db
`fetchFeatureFlags` - Use readonly array
fregante Feb 28, 2024
c0984ff
`fetchFeatureFlags` - Drop redundant HTTP status check
fregante Feb 28, 2024
41eb983
Merge branch 'main' into dev/separate-feature-flags-from-me
Feb 28, 2024
122ac10
remove maxAge/expiry timeouts
Feb 28, 2024
7e68a8c
Merge branch 'main' into dev/separate-feature-flags-from-me
Feb 28, 2024
8a9e055
package lock
Feb 28, 2024
4514895
fix strict null checks with messenger call
Feb 28, 2024
4ac6617
remove test function
Feb 28, 2024
cf173f2
fix import and add file to null checks
Feb 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions eslint-local-rules/persistBackgroundData.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
./src/analysis/analysisVisitors/regexAnalysis.ts
./src/analysis/analysisVisitors/varAnalysis/varMap.ts
./src/auth/authConstants.ts
./src/auth/authStorage.ts
./src/auth/authTypes.ts
./src/auth/authUtils.ts
./src/auth/token.ts
./src/auth/featureFlags.ts
./src/components/annotationAlert/FieldAnnotationAlert.tsx
./src/components/AsyncButton.tsx
./src/components/DelayedRender.tsx
Expand Down Expand Up @@ -255,7 +256,6 @@
./src/store/settings/settingsStorage.ts
./src/store/settings/settingsTypes.ts
./src/store/StorageInterface.ts
./src/store/syncFlags.ts
./src/telemetry/BackgroundLogger.ts
./src/telemetry/deployments.ts
./src/telemetry/dnt.ts
Expand Down
2 changes: 1 addition & 1 deletion src/auth/RequireAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import Loader from "@/components/Loader";
import { useGetMeQuery } from "@/data/service/api";
import { clearCachedAuthSecrets, updateUserData } from "@/auth/token";
import { clearCachedAuthSecrets, updateUserData } from "@/auth/authStorage";
import {
selectExtensionAuthState,
selectUserDataUpdate,
Expand Down
1 change: 0 additions & 1 deletion src/auth/authConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const anonAuth: AuthState = Object.freeze({
isTestAccount: false,
extension: true,
scope: null,
flags: [],
milestones: [],
organizations: [],
groups: [],
Expand Down
1 change: 0 additions & 1 deletion src/auth/authSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const selectAuth = (state: AuthRootState) => state.auth;
export const selectIsLoggedIn = (state: AuthRootState) =>
selectAuth(state).isLoggedIn;
export const selectScope = (state: AuthRootState) => selectAuth(state).scope;
export const selectFlags = (state: AuthRootState) => selectAuth(state).flags;
export const selectMilestones = (state: AuthRootState) =>
selectAuth(state).milestones;
export const selectOrganizations = (state: AuthRootState) =>
Expand Down
1 change: 0 additions & 1 deletion src/auth/authSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export const authSlice = createSlice({
return {
...payload,
scope: isEmpty(payload.scope) ? null : payload.scope,
flags: Array.isArray(payload.flags) ? payload.flags : [],
organizations: Array.isArray(payload.organizations)
? payload.organizations
: [],
Expand Down
File renamed without changes.
10 changes: 0 additions & 10 deletions src/auth/authTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ export type UserData = Partial<{
* The user's organization for engagement and error attribution
*/
telemetryOrganizationId: UUID | null;
/**
* Feature flags
*/
flags: string[];
/**
* Organizations the user is a member of
*/
Expand Down Expand Up @@ -108,7 +104,6 @@ export const USER_DATA_UPDATE_KEYS: Array<keyof UserDataUpdate> = [
"telemetryOrganizationId",
"organizations",
"groups",
"flags",
"enforceUpdateMillis",
"partner",
"partnerPrincipals",
Expand Down Expand Up @@ -235,11 +230,6 @@ export type AuthState = {
name: string;
}>;

/**
* List of feature flags for the user.
*/
readonly flags: string[];

/**
* List of milestones for the user. A Milestone represents progress through the PixieBrix product.
*/
Expand Down
14 changes: 0 additions & 14 deletions src/auth/authUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import { type Me } from "@/types/contract";
import { type UserDataUpdate, type AuthState } from "@/auth/authTypes";
import { readAuthData } from "@/auth/token";

// Used by the app
function selectOrganizations(
Expand Down Expand Up @@ -52,7 +51,6 @@ export function selectUserDataUpdate({
telemetry_organization: telemetryOrganization,
organization_memberships: organizationMemberships = [],
group_memberships = [],
flags = [],
partner,
enforce_update_millis: enforceUpdateMillis,
partner_principals: partnerPrincipals = [],
Expand All @@ -67,7 +65,6 @@ export function selectUserDataUpdate({
email: email!,
organizationId: organization?.id ?? null,
telemetryOrganizationId: telemetryOrganization?.id ?? null,
flags,
organizations,
groups,
partner: partner ?? null,
Expand All @@ -84,7 +81,6 @@ export function selectExtensionAuthState({
telemetry_organization,
is_onboarded: isOnboarded,
test_account: isTestAccount = false,
flags = [],
milestones = [],
organization_memberships: organizationMemberships = [],
group_memberships = [],
Expand All @@ -106,18 +102,8 @@ export function selectExtensionAuthState({
telemetryOrganizationId: telemetry_organization?.id,
organizations,
groups,
flags,
milestones,
partner,
enforceUpdateMillis,
};
}

/**
* Returns true if the specified flag is on for the current user.
* @param flag the feature flag to check
*/
export async function flagOn(flag: string): Promise<boolean> {
const authData = await readAuthData();
return authData.flags?.includes(flag) ?? false;
}
56 changes: 56 additions & 0 deletions src/auth/featureFlags.ts
BLoe marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2024 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { StorageItem } from "webext-storage";
import { getApiClient } from "@/data/service/apiClient";
import { type components } from "@/types/swagger";

const TIME_TO_EXPIRATION_MS = 30_000; // 30 seconds

const featureFlagStorage = new StorageItem("featureFlags", {
BLoe marked this conversation as resolved.
Show resolved Hide resolved
defaultValue: {
flags: [] as string[],
lastFetchedTime: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of recording lastFetchedTime, IIRC the more common approach to TTL is to set the expiry timestamp

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, you might be able to use @fregante's library here: https://github.com/fregante/webext-storage-cache

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used a "last fetched time" approach recently in the useTheme caching, so was just sticking to the same pattern here. At some point we should generalize/abstract this sort of api caching logic out, regardless.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might be able to use @fregante's library here: https://github.com/fregante/webext-storage-cache

Oh interesting, this definitely looks useful for abstracting out the caching logic like I mentioned! I'll keep this in mind for next steps, but I think it's out of scope right now in this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to give it a shot and use webext-storage-cache for this, but I'm running into an error in jest tests:

image

I pushed the commit so changes are here, @fregante (or anyone) any idea what's going on with this Jest error?

Copy link
Collaborator

@fregante fregante Feb 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both webext-storage-cache and that @sindresorhus/to-milliseconds need to be added to Jest's exclusion list. It's the usual issue with ESM in Jest 🥲

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's this list here:

"node_modules/(?!@cfworker|escape-string-regex|filename-reserved-regex|filenamify|idb|webext-|p-timeout|p-retry|p-defer|p-memoize|serialize-error|strip-outer|trim-repeated|mimic-fn|urlpattern-polyfill|url-join|uuid|nanoid|use-debounce|copy-text-to-clipboard|linkify-urls|create-html-element|stringify-attributes|escape-goat|stemmer|uint8array-extras|one-event|abort-utils|batched-function|is-network-error|text-field-edit)",

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the usual issue with ESM in Jest

And yet they seem to have no desire to solve it. It's infuriating.

Copy link
Collaborator

@fregante fregante Feb 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they did add ESM support but it's a pain to set up: https://jestjs.io/docs/ecmascript-modules

Mocking is still a wip in jestjs/jest#10025

},
});

/**
* Returns true if the specified flag is on for the current user.
* @param flag the feature flag to check
*/
export async function flagOn(flag: string): Promise<boolean> {
const { flags: cachedFlags = [], lastFetchedTime = 0 } =
(await featureFlagStorage.get()) ?? {};
fregante marked this conversation as resolved.
Show resolved Hide resolved
let flags = cachedFlags;
if (Date.now() - lastFetchedTime > TIME_TO_EXPIRATION_MS) {
BLoe marked this conversation as resolved.
Show resolved Hide resolved
const client = await getApiClient();
const { data, status } =
await client.get<components["schemas"]["Me"]>("/api/me/");
if (status >= 400) {
console.debug("Failed to fetch feature flags");
} else {
const newFlags = [...(data.flags ?? [])];
await featureFlagStorage.set({
flags: newFlags,
lastFetchedTime: Date.now(),
});
flags = newFlags;
}
}

return flags.includes(flag);
}
2 changes: 1 addition & 1 deletion src/auth/useLinkState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
addListener as addAuthListener,
isLinked,
removeListener as removeAuthListener,
} from "@/auth/token";
} from "@/auth/authStorage";
import useAsyncState from "@/hooks/useAsyncState";
import { useEffect } from "react";

Expand Down
2 changes: 1 addition & 1 deletion src/auth/useRequiredPartnerAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
addListener as addAuthListener,
readPartnerAuthData,
removeListener as removeAuthListener,
} from "@/auth/token";
} from "@/auth/authStorage";
import { useEffect } from "react";
import { AUTOMATION_ANYWHERE_PARTNER_KEY } from "@/data/service/constants";
import { type AuthState } from "@/auth/authTypes";
Expand Down
4 changes: 2 additions & 2 deletions src/background/deploymentUpdater.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import MockAdapter from "axios-mock-adapter";
import axios from "axios";
import { updateDeployments } from "@/background/deploymentUpdater";
import reportEvent from "@/telemetry/reportEvent";
import { isLinked, readAuthData } from "@/auth/token";
import { isLinked, readAuthData } from "@/auth/authStorage";
import { refreshRegistries } from "@/hooks/useRefreshRegistries";
import { isUpdateAvailable } from "@/background/installer";
import {
Expand Down Expand Up @@ -73,7 +73,7 @@ jest.mock("@/telemetry/reportEvent");
jest.mock("@/sidebar/messenger/api", () => {});
jest.mock("@/contentScript/messenger/api");

jest.mock("@/auth/token", () => ({
jest.mock("@/auth/authStorage", () => ({
getExtensionToken: async () => "TESTTOKEN",
getAuthHeaders: jest.fn().mockResolvedValue({}),
readAuthData: jest.fn().mockResolvedValue({
Expand Down
2 changes: 1 addition & 1 deletion src/background/deploymentUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { type Deployment, type Me } from "@/types/contract";
import { isEmpty, partition } from "lodash";
import reportError from "@/telemetry/reportError";
import { getUUID } from "@/telemetry/telemetryHelpers";
import { isLinked, readAuthData, updateUserData } from "@/auth/token";
import { isLinked, readAuthData, updateUserData } from "@/auth/authStorage";
import reportEvent from "@/telemetry/reportEvent";
import { refreshRegistries } from "@/hooks/useRefreshRegistries";
import {
Expand Down
8 changes: 2 additions & 6 deletions src/background/installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
openInstallPage,
handleInstall,
} from "@/background/installer";
import * as auth from "@/auth/token";
import * as auth from "@/auth/authStorage";
import { locator } from "@/background/locator";
import { uuidv4 } from "@/types/helpers";
import { waitForEffect } from "@/testUtils/testHelpers";
Expand All @@ -33,18 +33,14 @@ jest.mock("@/data/service/baseService", () => ({
getBaseURL: jest.fn().mockResolvedValue("https://app.pixiebrix.com"),
}));

jest.mock("@/auth/token", () => ({
jest.mock("@/auth/authStorage", () => ({
isLinked: jest.fn().mockResolvedValue(false),
getExtensionToken: jest.fn().mockResolvedValue(null),
getUserData: jest.fn().mockResolvedValue(null),
}));

jest.mock("@/background/telemetry");

jest.mock("@/store/syncFlags", () => ({
syncFlagOn: jest.fn().mockResolvedValue(false),
}));

jest.mock("@/background/locator", () => ({
locator: {
locateAllForService: jest.fn().mockResolvedValue([]),
Expand Down
2 changes: 1 addition & 1 deletion src/background/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getUUID } from "@/telemetry/telemetryHelpers";
import { allowsTrack, dntConfig } from "@/telemetry/dnt";
import { gt } from "semver";
import { getBaseURL } from "@/data/service/baseService";
import { getExtensionToken, getUserData, isLinked } from "@/auth/token";
import { getExtensionToken, getUserData, isLinked } from "@/auth/authStorage";
import { isCommunityControlRoom } from "@/contrib/automationanywhere/aaUtils";
import { isEmpty } from "lodash";
import { expectContext } from "@/utils/expectContext";
Expand Down
4 changes: 2 additions & 2 deletions src/background/makeConfiguredRequest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import serviceRegistry from "@/integrations/registry";
import axios, { type AxiosError, type AxiosRequestConfig } from "axios";
import MockAdapter from "axios-mock-adapter";
import { performConfiguredRequest } from "./requests";
import * as token from "@/auth/token";
import * as token from "@/auth/authStorage";
import Locator, * as locator from "@/integrations/locator";
import { validateRegistryId } from "@/types/helpers";
import enrichAxiosErrors from "@/utils/enrichAxiosErrors";
Expand Down Expand Up @@ -55,7 +55,7 @@ jest.mock("@/background/auth/getToken", () => ({
__esModule: true,
getToken: jest.fn().mockResolvedValue({ token: "iamatoken" }),
}));
jest.mock("@/auth/token");
jest.mock("@/auth/authStorage");
jest.mock("@/integrations/locator");

// Use real version of pixiebrixConfigurationFactory
Expand Down
2 changes: 1 addition & 1 deletion src/background/messenger/external/_implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* @file THIS FILE IS MEANT TO BE IMPORTED EXCLUSIVELY BY ./api.js
*/

import { linkExtension } from "@/auth/token";
import { linkExtension } from "@/auth/authStorage";
import { type TokenAuthData } from "@/auth/authTypes";
import reportEvent from "@/telemetry/reportEvent";
import { Events } from "@/telemetry/events";
Expand Down
2 changes: 1 addition & 1 deletion src/background/messenger/external/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import { _liftBackground as liftExternal } from "@/background/externalProtocol";
import * as local from "@/background/messenger/external/_implementation";
import { readPartnerAuthData } from "@/auth/token";
import { readPartnerAuthData } from "@/auth/authStorage";

export const connectPage = liftExternal("CONNECT_PAGE", async () =>
browser.runtime.getManifest(),
Expand Down
2 changes: 1 addition & 1 deletion src/background/messenger/strict/registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { rememberFocus } from "@/utils/focusTracker";
import writeToClipboardInFocusedContext from "@/background/clipboard";
import * as registry from "@/registry/packageRegistry";
import serviceRegistry from "@/integrations/registry";
import { getUserData } from "@/auth/token";
import { getUserData } from "@/auth/authStorage";
import {
clearExtensionDebugLogs,
clearLog,
Expand Down
2 changes: 1 addition & 1 deletion src/background/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { isScriptableUrl } from "webext-content-scripts";
import { debounce } from "lodash";
import { canAccessTab as canInjectTab, getTabUrl } from "webext-tools";
import { getTargetState } from "@/contentScript/ready";
import { flagOn } from "@/auth/authUtils";
import { flagOn } from "@/auth/featureFlags";

export function reactivateEveryTab(): void {
console.debug("Reactivate all tabs");
Expand Down
4 changes: 2 additions & 2 deletions src/background/partnerIntegrations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import tokenIntegrationDefinition from "@contrib/integrations/automation-anywher
import oauthIntegrationDefinition from "@contrib/integrations/automation-anywhere-oauth2.yaml";
import { locator as serviceLocator } from "@/background/locator";
import { uuidv4 } from "@/types/helpers";
import { readPartnerAuthData, setPartnerAuth } from "@/auth/token";
import { readPartnerAuthData, setPartnerAuth } from "@/auth/authStorage";
import { syncRemotePackages } from "@/registry/memoryRegistry";
import { type RegistryId } from "@/types/registryTypes";
import { type IntegrationConfig } from "@/integrations/integrationTypes";
Expand All @@ -45,7 +45,7 @@ const integrationDefinitionMap = new Map([
[CONTROL_ROOM_OAUTH_INTEGRATION_ID, oauthIntegrationDefinition],
]);

jest.mock("@/auth/token", () => ({
jest.mock("@/auth/authStorage", () => ({
readPartnerAuthData: jest.fn().mockResolvedValue({}),
setPartnerAuth: jest.fn(),
}));
Expand Down
2 changes: 1 addition & 1 deletion src/background/partnerIntegrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { flatten, isEmpty } from "lodash";
import { expectContext } from "@/utils/expectContext";
import { type RegistryId } from "@/types/registryTypes";
import launchOAuth2Flow from "@/background/auth/launchOAuth2Flow";
import { readPartnerAuthData, setPartnerAuth } from "@/auth/token";
import { readPartnerAuthData, setPartnerAuth } from "@/auth/authStorage";
import serviceRegistry from "@/integrations/registry";
import axios from "axios";
import { getBaseURL } from "@/data/service/baseService";
Expand Down
2 changes: 1 addition & 1 deletion src/background/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import axios, {
} from "axios";
import { pixiebrixConfigurationFactory } from "@/integrations/locator";
import serviceRegistry from "@/integrations/registry";
import { getExtensionToken } from "@/auth/token";
import { getExtensionToken } from "@/auth/authStorage";
import { locator } from "@/background/locator";
import { isEmpty } from "lodash";
import launchOAuth2Flow from "@/background/auth/launchOAuth2Flow";
Expand Down
6 changes: 3 additions & 3 deletions src/background/restrictUnauthenticatedUrlAccess.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ import {
isLinked,
TEST_clearListeners,
TEST_triggerListeners,
} from "@/auth/token";
} from "@/auth/authStorage";
import { waitForEffect } from "@/testUtils/testHelpers";
import { tabFactory } from "@/testUtils/factories/browserFactories";

jest.mock("@/auth/token", () => ({
jest.mock("@/auth/authStorage", () => ({
__esModule: true,
...jest.requireActual("@/auth/token"),
...jest.requireActual("@/auth/authStorage"),
isLinked: jest.fn(),
}));

Expand Down
2 changes: 1 addition & 1 deletion src/background/restrictUnauthenticatedUrlAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import { type OrganizationAuthUrlPattern } from "@/types/contract";
import { readManagedStorage } from "@/store/enterprise/managedStorage";
import { addListener as addAuthListener, isLinked } from "@/auth/token";
import { addListener as addAuthListener, isLinked } from "@/auth/authStorage";
import { validateUUID } from "@/types/helpers";
import { type UUID } from "@/types/stringTypes";
import { testMatchPatterns } from "@/bricks/available";
Expand Down