mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-31 22:51:28 +01:00
Define account service observable responsibilities
This commit is contained in:
parent
5e8feb22d0
commit
0a9c8a416a
@ -1,4 +1,16 @@
|
||||
export abstract class AccountService {}
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { UserId } from "../../types/guid";
|
||||
import { AuthenticationStatus } from "../enums/authentication-status";
|
||||
|
||||
export abstract class AccountService {
|
||||
accounts$: Observable<Record<UserId, AuthenticationStatus>>;
|
||||
activeAccount$: Observable<{ id: UserId | undefined; status: AuthenticationStatus | undefined }>;
|
||||
accountLock$: Observable<UserId>;
|
||||
accountLogout$: Observable<UserId>;
|
||||
abstract setAccountStatus(userId: UserId, status: AuthenticationStatus): void;
|
||||
abstract switchAccount(userId: UserId): void;
|
||||
}
|
||||
|
||||
export abstract class InternalAccountService extends AccountService {
|
||||
abstract delete(): void;
|
||||
|
@ -1,10 +1,43 @@
|
||||
import { BehaviorSubject, Subject } from "rxjs";
|
||||
|
||||
import { InternalAccountService } from "../../auth/abstractions/account.service";
|
||||
import { LogService } from "../../platform/abstractions/log.service";
|
||||
import { MessagingService } from "../../platform/abstractions/messaging.service";
|
||||
import { UserId } from "../../types/guid";
|
||||
import { AuthenticationStatus } from "../enums/authentication-status";
|
||||
|
||||
export class AccountServiceImplementation implements InternalAccountService {
|
||||
private accounts = new BehaviorSubject<Record<UserId, AuthenticationStatus>>({});
|
||||
private activeAccount = new BehaviorSubject<{
|
||||
id: UserId | undefined;
|
||||
status: AuthenticationStatus | undefined;
|
||||
}>({ id: undefined, status: undefined });
|
||||
private lock = new Subject<UserId>();
|
||||
private logout = new Subject<UserId>();
|
||||
|
||||
accounts$ = this.accounts.asObservable();
|
||||
activeAccount$ = this.activeAccount.asObservable();
|
||||
accountLock$ = this.lock.asObservable();
|
||||
accountLogout$ = this.logout.asObservable();
|
||||
constructor(private messagingService: MessagingService, private logService: LogService) {}
|
||||
|
||||
setAccountStatus(userId: UserId, status: AuthenticationStatus): void {
|
||||
this.accounts.value[userId] = status;
|
||||
this.accounts.next(this.accounts.value);
|
||||
if (status === AuthenticationStatus.LoggedOut) {
|
||||
this.logout.next(userId);
|
||||
} else if (status === AuthenticationStatus.Locked) {
|
||||
this.lock.next(userId);
|
||||
}
|
||||
}
|
||||
|
||||
switchAccount(userId: UserId) {
|
||||
if (this.accounts.value[userId] != null) {
|
||||
throw new Error("Account does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: update to use our own account status settings.
|
||||
async delete(): Promise<void> {
|
||||
try {
|
||||
this.messagingService.send("logout");
|
||||
|
73
libs/common/src/services/account/account.service.ts
Normal file
73
libs/common/src/services/account/account.service.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { BehaviorSubject, filter, Subject } from "rxjs";
|
||||
|
||||
import { InternalAccountService } from "../../abstractions/account/account.service";
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { MessagingService } from "../../abstractions/messaging.service";
|
||||
import { AuthenticationStatus } from "../../enums/authenticationStatus";
|
||||
|
||||
export class AccountServiceImplementation implements InternalAccountService {
|
||||
private accounts = new BehaviorSubject<Map<string, AuthenticationStatus>>(new Map());
|
||||
private activeAccount = new BehaviorSubject<{
|
||||
id: string | undefined;
|
||||
status: AuthenticationStatus | undefined;
|
||||
}>({ id: undefined, status: undefined });
|
||||
private lock = new Subject<string>();
|
||||
private logout = new Subject<string>();
|
||||
private unlock = new Subject<string>();
|
||||
|
||||
accounts$ = this.accounts.asObservable();
|
||||
activeAccount$ = this.activeAccount.asObservable();
|
||||
accountLocked$ = this.lock.asObservable();
|
||||
accountLogout$ = this.logout.asObservable();
|
||||
accountUnlocked$ = this.unlock.asObservable();
|
||||
|
||||
activeAccountLocked$ = this.accountLocked$.pipe(
|
||||
filter((userId) => userId === this.activeAccount.value.id)
|
||||
);
|
||||
activeAccountUnlocked$ = this.accountUnlocked$.pipe(
|
||||
filter((userId) => userId === this.activeAccount.value.id)
|
||||
);
|
||||
activeAccountLogout$ = this.accountLogout$.pipe(
|
||||
filter((userId) => userId === this.activeAccount.value.id)
|
||||
);
|
||||
|
||||
constructor(private messagingService: MessagingService, private logService: LogService) {}
|
||||
|
||||
setAccountStatus(userId: string, status: AuthenticationStatus) {
|
||||
this.accounts.value.set(userId, status);
|
||||
this.accounts.next(this.accounts.value);
|
||||
if (status === AuthenticationStatus.LoggedOut) {
|
||||
this.logout.next(userId);
|
||||
} else if (status === AuthenticationStatus.Locked) {
|
||||
this.lock.next(userId);
|
||||
} else if (status === AuthenticationStatus.Unlocked) {
|
||||
this.unlock.next(userId);
|
||||
}
|
||||
}
|
||||
|
||||
switchAccount(userId: string) {
|
||||
if (!this.accounts.value.has(userId)) {
|
||||
throw new Error("Account does not exist");
|
||||
}
|
||||
this.activeAccount.next({ id: userId, status: this.accounts.value.get(userId) });
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
try {
|
||||
this.logout.next(this.activeAccount.value.id);
|
||||
this.accounts.value.delete(this.activeAccount.value.id);
|
||||
this.accounts.next(this.accounts.value);
|
||||
this.messagingService.send("logout");
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
complete() {
|
||||
this.accounts.complete();
|
||||
this.activeAccount.complete();
|
||||
this.lock.complete();
|
||||
this.logout.complete();
|
||||
}
|
||||
}
|
5
libs/common/src/types/guid.d.ts
vendored
Normal file
5
libs/common/src/types/guid.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { Opaque } from "type-fest";
|
||||
|
||||
type Guid = Opaque<string, "Guid">;
|
||||
|
||||
type UserId = Opaque<string, "UserId">;
|
Loading…
Reference in New Issue
Block a user