diff --git a/jslib b/jslib
index def3c47a1e..172392ff3b 160000
--- a/jslib
+++ b/jslib
@@ -1 +1 @@
-Subproject commit def3c47a1e27a48466830e4e688efa40aae94aba
+Subproject commit 172392ff3b3d8e68795549deef5433c0d1329c9c
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 1e7282a4f5..bedab39c47 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -56,14 +56,21 @@ const SyncInterval = 6 * 60 * 60 * 1000; // 6 hours
@Component({
selector: "app-root",
styles: [],
- template: `
+ template: `
+
-
`,
+
+ `,
})
export class AppComponent implements OnInit {
@ViewChild("settings", { read: ViewContainerRef, static: true }) settingsRef: ViewContainerRef;
@@ -77,6 +84,8 @@ export class AppComponent implements OnInit {
@ViewChild("appPasswordGenerator", { read: ViewContainerRef, static: true })
passwordGeneratorModalRef: ViewContainerRef;
+ loading = false;
+
private lastActivity: number = null;
private modal: ModalRef = null;
private idleTimer: number = null;
@@ -118,10 +127,8 @@ export class AppComponent implements OnInit {
await this.updateAppMenu();
}, 1000);
- window.onmousemove = () => this.recordActivity();
- window.onmousedown = () => this.recordActivity();
window.ontouchstart = () => this.recordActivity();
- window.onclick = () => this.recordActivity();
+ window.onmousedown = () => this.recordActivity();
window.onscroll = () => this.recordActivity();
window.onkeypress = () => this.recordActivity();
});
@@ -164,16 +171,16 @@ export class AppComponent implements OnInit {
if (this.modal != null) {
this.modal.close();
}
- this.updateAppMenu();
if (
message.userId == null ||
message.userId === (await this.stateService.getUserId())
) {
- this.router.navigate(["lock"]);
+ await this.router.navigate(["lock"]);
}
this.notificationsService.updateConnection();
- await this.systemService.clearPendingClipboard();
+ await this.updateAppMenu();
this.systemService.startProcessReload();
+ await this.systemService.clearPendingClipboard();
break;
case "reloadProcess":
window.location.reload(true);
@@ -310,6 +317,21 @@ export class AppComponent implements OnInit {
await this.keyConnectorService.setConvertAccountRequired(true);
this.router.navigate(["/remove-password"]);
break;
+ case "switchAccount":
+ if (message.userId != null) {
+ await this.stateService.setActiveUser(message.userId);
+ }
+ const locked = await this.vaultTimeoutService.isLocked(message.userId);
+ if (locked) {
+ this.messagingService.send("locked", { userId: message.userId });
+ } else {
+ this.messagingService.send("unlocked");
+ this.loading = true;
+ await this.syncService.fullSync(true);
+ this.loading = false;
+ this.router.navigate(["vault"]);
+ }
+ break;
}
});
});
@@ -447,14 +469,7 @@ export class AppComponent implements OnInit {
if (this.stateService.activeAccount.getValue() == null) {
this.router.navigate(["login"]);
} else {
- const locked = await this.vaultTimeoutService.isLocked();
- if (locked) {
- this.messagingService.send("locked");
- } else {
- this.messagingService.send("unlocked");
- this.messagingService.send("syncVault");
- this.router.navigate(["vault"]);
- }
+ this.messagingService.send("switchAccount");
}
await this.updateAppMenu();
diff --git a/src/app/layout/account-switcher.component.html b/src/app/layout/account-switcher.component.html
index 62c8922c18..b6b2839b5d 100644
--- a/src/app/layout/account-switcher.component.html
+++ b/src/app/layout/account-switcher.component.html
@@ -34,11 +34,10 @@
class="account"
[ngClass]="{ active: a.value.profile.authenticationStatus == 'active' }"
href="#"
- appStopClick
- (click)="switch(a.key)"
+ (mousedown)="switch(a.key)"
>
{{ a.value.profile.email }}
- {{ a.value.settings.environmentUrls.server }}
+ {{ a.value.serverUrl }}
{{ a.value.profile.authenticationStatus }}
diff --git a/src/app/layout/account-switcher.component.ts b/src/app/layout/account-switcher.component.ts
index b8c38cd6b0..7526c7e844 100644
--- a/src/app/layout/account-switcher.component.ts
+++ b/src/app/layout/account-switcher.component.ts
@@ -10,6 +10,21 @@ import { AuthenticationStatus } from "jslib-common/enums/authenticationStatus";
import { Account } from "jslib-common/models/domain/account";
+export class SwitcherAccount extends Account {
+ get serverUrl() {
+ return this.removeWebProtocolFromString(
+ this.settings?.environmentUrls?.base ??
+ this.settings?.environmentUrls.api ??
+ "https://bitwarden.com"
+ );
+ }
+
+ private removeWebProtocolFromString(urlString: string) {
+ const regex = /http(s)?(:)?(\/\/)?|(\/\/)?(www\.)?/g;
+ return urlString.replace(regex, "");
+ }
+}
+
@Component({
selector: "app-account-switcher",
templateUrl: "account-switcher.component.html",
@@ -36,8 +51,9 @@ import { Account } from "jslib-common/models/domain/account";
})
export class AccountSwitcherComponent implements OnInit {
isOpen: boolean = false;
- accounts: { [userId: string]: Account } = {};
+ accounts: { [userId: string]: SwitcherAccount } = {};
activeAccountEmail: string;
+ serverUrl: string;
get showSwitcher() {
return this.accounts != null && Object.keys(this.accounts).length > 0;
@@ -46,8 +62,7 @@ export class AccountSwitcherComponent implements OnInit {
constructor(
private stateService: StateService,
private vaultTimeoutService: VaultTimeoutService,
- private messagingService: MessagingService,
- private router: Router
+ private messagingService: MessagingService
) {}
async ngOnInit(): Promise {
@@ -64,7 +79,7 @@ export class AccountSwitcherComponent implements OnInit {
}
}
- this.accounts = accounts;
+ this.accounts = await this.createSwitcherAccounts(accounts);
this.activeAccountEmail = await this.stateService.getEmail();
});
}
@@ -74,14 +89,24 @@ export class AccountSwitcherComponent implements OnInit {
}
async switch(userId: string) {
- await this.stateService.setActiveUser(userId);
- const locked = await this.vaultTimeoutService.isLocked(userId);
- if (locked) {
- this.messagingService.send("locked", { userId: userId });
- } else {
- this.messagingService.send("unlocked");
- this.messagingService.send("syncVault");
- this.router.navigate(["vault"]);
+ this.messagingService.send("switchAccount", { userId: userId });
+ this.toggle();
+ }
+
+ private async createSwitcherAccounts(baseAccounts: {
+ [userId: string]: Account;
+ }): Promise<{ [userId: string]: SwitcherAccount }> {
+ const switcherAccounts: { [userId: string]: SwitcherAccount } = {};
+ for (const userId in baseAccounts) {
+ if (userId == null) {
+ continue;
+ }
+ // environmentUrls are stored on disk and must be retrieved seperatly from the in memory state offered from subscribing to accounts
+ baseAccounts[userId].settings.environmentUrls = await this.stateService.getEnvironmentUrls({
+ userId: userId,
+ });
+ switcherAccounts[userId] = new SwitcherAccount(baseAccounts[userId]);
}
+ return switcherAccounts;
}
}
diff --git a/src/scss/misc.scss b/src/scss/misc.scss
index 3a7023340c..aa38b0f86d 100644
--- a/src/scss/misc.scss
+++ b/src/scss/misc.scss
@@ -316,7 +316,8 @@ form,
}
}
-app-root > #loading {
+app-root > #loading,
+.loading {
display: flex;
text-align: center;
justify-content: center;
diff --git a/src/scss/pages.scss b/src/scss/pages.scss
index a36641acb1..844b61cac0 100644
--- a/src/scss/pages.scss
+++ b/src/scss/pages.scss
@@ -11,13 +11,11 @@
height: 100%;
@media (min-height: 500px) {
- height: calc(100% + 50px);
- padding-bottom: 50px;
+ height: calc(100%);
}
@media (min-height: 800px) {
- height: calc(100% + 300px);
- padding-bottom: 300px;
+ height: calc(100%);
}
img {