mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
Auth/PM-5712 - Extension & Desktop Account Switcher - Fix incorrect env showing when adding new accounts (#13362)
* PM-5712 - Refactor env service to require user id instead of having global and active user state fallbacks per working session with Justin. * PM-5712 - AccountSwitcherService tests - fix tests and add env assertions.
This commit is contained in:
@@ -128,7 +128,7 @@ export abstract class EnvironmentService {
|
||||
/**
|
||||
* Get the environment from state. Useful if you need to get the environment for another user.
|
||||
*/
|
||||
abstract getEnvironment$(userId?: string): Observable<Environment | undefined>;
|
||||
abstract getEnvironment$(userId: UserId): Observable<Environment | undefined>;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link getEnvironment$} instead.
|
||||
|
||||
@@ -304,85 +304,21 @@ describe("EnvironmentService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("getEnvironment", () => {
|
||||
describe("getEnvironment$", () => {
|
||||
it.each([
|
||||
{ region: Region.US, expectedHost: "bitwarden.com" },
|
||||
{ region: Region.EU, expectedHost: "bitwarden.eu" },
|
||||
])("gets it from user data if there is an active user", async ({ region, expectedHost }) => {
|
||||
setGlobalData(Region.US, new EnvironmentUrls());
|
||||
setUserData(region, new EnvironmentUrls());
|
||||
])("gets it from the passed in userId: %s", async ({ region, expectedHost }) => {
|
||||
setUserData(Region.US, new EnvironmentUrls());
|
||||
setUserData(region, new EnvironmentUrls(), alternateTestUser);
|
||||
|
||||
await switchUser(testUser);
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$());
|
||||
expect(env.getHostname()).toBe(expectedHost);
|
||||
const env = await firstValueFrom(sut.getEnvironment$(alternateTestUser));
|
||||
expect(env?.getHostname()).toBe(expectedHost);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ region: Region.US, expectedHost: "bitwarden.com" },
|
||||
{ region: Region.EU, expectedHost: "bitwarden.eu" },
|
||||
])("gets it from global data if there is no active user", async ({ region, expectedHost }) => {
|
||||
setGlobalData(region, new EnvironmentUrls());
|
||||
setUserData(Region.US, new EnvironmentUrls());
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$());
|
||||
expect(env.getHostname()).toBe(expectedHost);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ region: Region.US, expectedHost: "bitwarden.com" },
|
||||
{ region: Region.EU, expectedHost: "bitwarden.eu" },
|
||||
])(
|
||||
"gets it from global state if there is no active user even if a user id is passed in.",
|
||||
async ({ region, expectedHost }) => {
|
||||
setGlobalData(region, new EnvironmentUrls());
|
||||
setUserData(Region.US, new EnvironmentUrls());
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$(testUser));
|
||||
expect(env.getHostname()).toBe(expectedHost);
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
{ region: Region.US, expectedHost: "bitwarden.com" },
|
||||
{ region: Region.EU, expectedHost: "bitwarden.eu" },
|
||||
])(
|
||||
"gets it from the passed in userId if there is any active user: %s",
|
||||
async ({ region, expectedHost }) => {
|
||||
setGlobalData(Region.US, new EnvironmentUrls());
|
||||
setUserData(Region.US, new EnvironmentUrls());
|
||||
setUserData(region, new EnvironmentUrls(), alternateTestUser);
|
||||
|
||||
await switchUser(testUser);
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$(alternateTestUser));
|
||||
expect(env.getHostname()).toBe(expectedHost);
|
||||
},
|
||||
);
|
||||
|
||||
it("gets it from base url saved in self host config", async () => {
|
||||
const globalSelfHostUrls = new EnvironmentUrls();
|
||||
globalSelfHostUrls.base = "https://base.example.com";
|
||||
setGlobalData(Region.SelfHosted, globalSelfHostUrls);
|
||||
setUserData(Region.EU, new EnvironmentUrls());
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$());
|
||||
expect(env.getHostname()).toBe("base.example.com");
|
||||
});
|
||||
|
||||
it("gets it from webVault url saved in self host config", async () => {
|
||||
const globalSelfHostUrls = new EnvironmentUrls();
|
||||
globalSelfHostUrls.webVault = "https://vault.example.com";
|
||||
globalSelfHostUrls.base = "https://base.example.com";
|
||||
setGlobalData(Region.SelfHosted, globalSelfHostUrls);
|
||||
setUserData(Region.EU, new EnvironmentUrls());
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$());
|
||||
expect(env.getHostname()).toBe("vault.example.com");
|
||||
});
|
||||
|
||||
it("gets it from saved self host config from passed in user when there is an active user", async () => {
|
||||
setGlobalData(Region.US, new EnvironmentUrls());
|
||||
it("gets env from saved self host config from passed in user when there is a different active user", async () => {
|
||||
setUserData(Region.EU, new EnvironmentUrls());
|
||||
|
||||
const selfHostUserUrls = new EnvironmentUrls();
|
||||
@@ -392,7 +328,31 @@ describe("EnvironmentService", () => {
|
||||
await switchUser(testUser);
|
||||
|
||||
const env = await firstValueFrom(sut.getEnvironment$(alternateTestUser));
|
||||
expect(env.getHostname()).toBe("base.example.com");
|
||||
expect(env?.getHostname()).toBe("base.example.com");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getEnvironment (deprecated)", () => {
|
||||
it("gets self hosted env from active user when no user passed in", async () => {
|
||||
const selfHostUserUrls = new EnvironmentUrls();
|
||||
selfHostUserUrls.base = "https://base.example.com";
|
||||
setUserData(Region.SelfHosted, selfHostUserUrls);
|
||||
|
||||
await switchUser(testUser);
|
||||
|
||||
const env = await sut.getEnvironment();
|
||||
expect(env?.getHostname()).toBe("base.example.com");
|
||||
});
|
||||
|
||||
it("gets self hosted env from passed in user", async () => {
|
||||
const selfHostUserUrls = new EnvironmentUrls();
|
||||
selfHostUserUrls.base = "https://base.example.com";
|
||||
setUserData(Region.SelfHosted, selfHostUserUrls);
|
||||
|
||||
await switchUser(testUser);
|
||||
|
||||
const env = await sut.getEnvironment(testUser);
|
||||
expect(env?.getHostname()).toBe("base.example.com");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -271,19 +271,8 @@ export class DefaultEnvironmentService implements EnvironmentService {
|
||||
}
|
||||
}
|
||||
|
||||
getEnvironment$(userId?: UserId): Observable<Environment | undefined> {
|
||||
if (userId == null) {
|
||||
return this.environment$;
|
||||
}
|
||||
|
||||
return this.activeAccountId$.pipe(
|
||||
switchMap((activeUserId) => {
|
||||
// Previous rules dictated that we only get from user scoped state if there is an active user.
|
||||
if (activeUserId == null) {
|
||||
return this.globalState.state$;
|
||||
}
|
||||
return this.stateProvider.getUser(userId ?? activeUserId, USER_ENVIRONMENT_KEY).state$;
|
||||
}),
|
||||
getEnvironment$(userId: UserId): Observable<Environment | undefined> {
|
||||
return this.stateProvider.getUser(userId, USER_ENVIRONMENT_KEY).state$.pipe(
|
||||
map((state) => {
|
||||
return this.buildEnvironment(state?.region, state?.urls);
|
||||
}),
|
||||
@@ -294,7 +283,10 @@ export class DefaultEnvironmentService implements EnvironmentService {
|
||||
* @deprecated Use getEnvironment$ instead.
|
||||
*/
|
||||
async getEnvironment(userId?: UserId): Promise<Environment | undefined> {
|
||||
return firstValueFrom(this.getEnvironment$(userId));
|
||||
// Add backwards compatibility support for null userId
|
||||
const definedUserId = userId ?? (await firstValueFrom(this.activeAccountId$));
|
||||
|
||||
return firstValueFrom(this.getEnvironment$(definedUserId));
|
||||
}
|
||||
|
||||
async seedUserEnvironment(userId: UserId) {
|
||||
|
||||
Reference in New Issue
Block a user