mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
add auth status to auth service (#8377)
* add auth status to auth service * fix auth service factory
This commit is contained in:
@@ -23,9 +23,12 @@ import {
|
|||||||
stateServiceFactory,
|
stateServiceFactory,
|
||||||
} from "../../../platform/background/service-factories/state-service.factory";
|
} from "../../../platform/background/service-factories/state-service.factory";
|
||||||
|
|
||||||
|
import { AccountServiceInitOptions, accountServiceFactory } from "./account-service.factory";
|
||||||
|
|
||||||
type AuthServiceFactoryOptions = FactoryOptions;
|
type AuthServiceFactoryOptions = FactoryOptions;
|
||||||
|
|
||||||
export type AuthServiceInitOptions = AuthServiceFactoryOptions &
|
export type AuthServiceInitOptions = AuthServiceFactoryOptions &
|
||||||
|
AccountServiceInitOptions &
|
||||||
MessagingServiceInitOptions &
|
MessagingServiceInitOptions &
|
||||||
CryptoServiceInitOptions &
|
CryptoServiceInitOptions &
|
||||||
ApiServiceInitOptions &
|
ApiServiceInitOptions &
|
||||||
@@ -41,6 +44,7 @@ export function authServiceFactory(
|
|||||||
opts,
|
opts,
|
||||||
async () =>
|
async () =>
|
||||||
new AuthService(
|
new AuthService(
|
||||||
|
await accountServiceFactory(cache, opts),
|
||||||
await messagingServiceFactory(cache, opts),
|
await messagingServiceFactory(cache, opts),
|
||||||
await cryptoServiceFactory(cache, opts),
|
await cryptoServiceFactory(cache, opts),
|
||||||
await apiServiceFactory(cache, opts),
|
await apiServiceFactory(cache, opts),
|
||||||
|
|||||||
@@ -568,6 +568,7 @@ export default class MainBackground {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.authService = new AuthService(
|
this.authService = new AuthService(
|
||||||
|
this.accountService,
|
||||||
backgroundMessagingService,
|
backgroundMessagingService,
|
||||||
this.cryptoService,
|
this.cryptoService,
|
||||||
this.apiService,
|
this.apiService,
|
||||||
|
|||||||
@@ -494,6 +494,7 @@ export class Main {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.authService = new AuthService(
|
this.authService = new AuthService(
|
||||||
|
this.accountService,
|
||||||
this.messagingService,
|
this.messagingService,
|
||||||
this.cryptoService,
|
this.cryptoService,
|
||||||
this.apiService,
|
this.apiService,
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ const typesafeProviders: Array<SafeProvider> = [
|
|||||||
provide: AuthServiceAbstraction,
|
provide: AuthServiceAbstraction,
|
||||||
useClass: AuthService,
|
useClass: AuthService,
|
||||||
deps: [
|
deps: [
|
||||||
|
AccountServiceAbstraction,
|
||||||
MessagingServiceAbstraction,
|
MessagingServiceAbstraction,
|
||||||
CryptoServiceAbstraction,
|
CryptoServiceAbstraction,
|
||||||
ApiServiceAbstraction,
|
ApiServiceAbstraction,
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
import { AuthenticationStatus } from "../enums/authentication-status";
|
import { AuthenticationStatus } from "../enums/authentication-status";
|
||||||
|
|
||||||
export abstract class AuthService {
|
export abstract class AuthService {
|
||||||
getAuthStatus: (userId?: string) => Promise<AuthenticationStatus>;
|
/** Authentication status for the active user */
|
||||||
logOut: (callback: () => void) => void;
|
abstract activeAccountStatus$: Observable<AuthenticationStatus>;
|
||||||
|
/** @deprecated use {@link activeAccountStatus$} instead */
|
||||||
|
abstract getAuthStatus: (userId?: string) => Promise<AuthenticationStatus>;
|
||||||
|
abstract logOut: (callback: () => void) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
61
libs/common/src/auth/services/auth.service.spec.ts
Normal file
61
libs/common/src/auth/services/auth.service.spec.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { MockProxy, mock } from "jest-mock-extended";
|
||||||
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { FakeAccountService, mockAccountServiceWith } from "../../../spec";
|
||||||
|
import { ApiService } from "../../abstractions/api.service";
|
||||||
|
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
||||||
|
import { MessagingService } from "../../platform/abstractions/messaging.service";
|
||||||
|
import { StateService } from "../../platform/abstractions/state.service";
|
||||||
|
import { Utils } from "../../platform/misc/utils";
|
||||||
|
import { UserId } from "../../types/guid";
|
||||||
|
import { AuthenticationStatus } from "../enums/authentication-status";
|
||||||
|
|
||||||
|
import { AuthService } from "./auth.service";
|
||||||
|
|
||||||
|
describe("AuthService", () => {
|
||||||
|
let sut: AuthService;
|
||||||
|
|
||||||
|
let accountService: FakeAccountService;
|
||||||
|
let messagingService: MockProxy<MessagingService>;
|
||||||
|
let cryptoService: MockProxy<CryptoService>;
|
||||||
|
let apiService: MockProxy<ApiService>;
|
||||||
|
let stateService: MockProxy<StateService>;
|
||||||
|
|
||||||
|
const userId = Utils.newGuid() as UserId;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
accountService = mockAccountServiceWith(userId);
|
||||||
|
messagingService = mock<MessagingService>();
|
||||||
|
cryptoService = mock<CryptoService>();
|
||||||
|
apiService = mock<ApiService>();
|
||||||
|
stateService = mock<StateService>();
|
||||||
|
|
||||||
|
sut = new AuthService(
|
||||||
|
accountService,
|
||||||
|
messagingService,
|
||||||
|
cryptoService,
|
||||||
|
apiService,
|
||||||
|
stateService,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("activeAccountStatus$", () => {
|
||||||
|
test.each([
|
||||||
|
AuthenticationStatus.LoggedOut,
|
||||||
|
AuthenticationStatus.Locked,
|
||||||
|
AuthenticationStatus.Unlocked,
|
||||||
|
])(
|
||||||
|
`should emit %p when activeAccount$ emits an account with %p auth status`,
|
||||||
|
async (status) => {
|
||||||
|
accountService.activeAccountSubject.next({
|
||||||
|
id: userId,
|
||||||
|
email: "email",
|
||||||
|
name: "name",
|
||||||
|
status,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await firstValueFrom(sut.activeAccountStatus$)).toEqual(status);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,18 +1,30 @@
|
|||||||
|
import { Observable, distinctUntilChanged, map, shareReplay } from "rxjs";
|
||||||
|
|
||||||
import { ApiService } from "../../abstractions/api.service";
|
import { ApiService } from "../../abstractions/api.service";
|
||||||
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
import { CryptoService } from "../../platform/abstractions/crypto.service";
|
||||||
import { MessagingService } from "../../platform/abstractions/messaging.service";
|
import { MessagingService } from "../../platform/abstractions/messaging.service";
|
||||||
import { StateService } from "../../platform/abstractions/state.service";
|
import { StateService } from "../../platform/abstractions/state.service";
|
||||||
import { KeySuffixOptions } from "../../platform/enums";
|
import { KeySuffixOptions } from "../../platform/enums";
|
||||||
|
import { AccountService } from "../abstractions/account.service";
|
||||||
import { AuthService as AuthServiceAbstraction } from "../abstractions/auth.service";
|
import { AuthService as AuthServiceAbstraction } from "../abstractions/auth.service";
|
||||||
import { AuthenticationStatus } from "../enums/authentication-status";
|
import { AuthenticationStatus } from "../enums/authentication-status";
|
||||||
|
|
||||||
export class AuthService implements AuthServiceAbstraction {
|
export class AuthService implements AuthServiceAbstraction {
|
||||||
|
activeAccountStatus$: Observable<AuthenticationStatus>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
protected accountService: AccountService,
|
||||||
protected messagingService: MessagingService,
|
protected messagingService: MessagingService,
|
||||||
protected cryptoService: CryptoService,
|
protected cryptoService: CryptoService,
|
||||||
protected apiService: ApiService,
|
protected apiService: ApiService,
|
||||||
protected stateService: StateService,
|
protected stateService: StateService,
|
||||||
) {}
|
) {
|
||||||
|
this.activeAccountStatus$ = this.accountService.activeAccount$.pipe(
|
||||||
|
map((account) => account.status),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
shareReplay({ bufferSize: 1, refCount: false }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async getAuthStatus(userId?: string): Promise<AuthenticationStatus> {
|
async getAuthStatus(userId?: string): Promise<AuthenticationStatus> {
|
||||||
// If we don't have an access token or userId, we're logged out
|
// If we don't have an access token or userId, we're logged out
|
||||||
|
|||||||
Reference in New Issue
Block a user