PM-7392 - WIP - Enhancing logout callback to consider the logout reason + move show toast logic into logout callback
This commit is contained in:
parent
d0782554f2
commit
706935098b
|
@ -551,6 +551,9 @@
|
||||||
"loggedOut": {
|
"loggedOut": {
|
||||||
"message": "Logged out"
|
"message": "Logged out"
|
||||||
},
|
},
|
||||||
|
"loggedOutDesc": {
|
||||||
|
"message": "You have been logged out of your account."
|
||||||
|
},
|
||||||
"loginExpired": {
|
"loginExpired": {
|
||||||
"message": "Your login session has expired."
|
"message": "Your login session has expired."
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
import { KeyConnectorService as AbstractKeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
import { KeyConnectorService as AbstractKeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
||||||
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ import { TokenServiceInitOptions, tokenServiceFactory } from "./token-service.fa
|
||||||
|
|
||||||
type KeyConnectorServiceFactoryOptions = FactoryOptions & {
|
type KeyConnectorServiceFactoryOptions = FactoryOptions & {
|
||||||
keyConnectorServiceOptions: {
|
keyConnectorServiceOptions: {
|
||||||
logoutCallback: (expired: boolean, userId?: string) => Promise<void>;
|
logoutCallback: (logoutReason: LogoutReason, userId?: string) => Promise<void>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
AuthRequestService,
|
AuthRequestService,
|
||||||
LoginEmailServiceAbstraction,
|
LoginEmailServiceAbstraction,
|
||||||
LoginEmailService,
|
LoginEmailService,
|
||||||
|
LogoutReason,
|
||||||
} from "@bitwarden/auth/common";
|
} from "@bitwarden/auth/common";
|
||||||
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
||||||
|
@ -372,8 +373,8 @@ export default class MainBackground {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const logoutCallback = async (expired: boolean, userId?: UserId) =>
|
const logoutCallback = async (logoutReason: LogoutReason, userId?: UserId) =>
|
||||||
await this.logout(expired, userId);
|
await this.logout(logoutReason, userId);
|
||||||
|
|
||||||
this.logService = new ConsoleLogService(false);
|
this.logService = new ConsoleLogService(false);
|
||||||
this.cryptoFunctionService = new WebCryptoFunctionService(self);
|
this.cryptoFunctionService = new WebCryptoFunctionService(self);
|
||||||
|
@ -579,7 +580,7 @@ export default class MainBackground {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
this.logService,
|
this.logService,
|
||||||
(expired: boolean) => this.logout(expired),
|
(logoutReason: LogoutReason) => this.logout(logoutReason),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.domainSettingsService = new DefaultDomainSettingsService(this.stateProvider);
|
this.domainSettingsService = new DefaultDomainSettingsService(this.stateProvider);
|
||||||
|
@ -1209,7 +1210,8 @@ export default class MainBackground {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async logout(expired: boolean, userId?: UserId) {
|
// TODO: figure out what this should look like
|
||||||
|
async logout(logoutReason: LogoutReason, userId?: UserId) {
|
||||||
const activeUserId = await firstValueFrom(
|
const activeUserId = await firstValueFrom(
|
||||||
this.accountService.activeAccount$.pipe(
|
this.accountService.activeAccount$.pipe(
|
||||||
map((a) => a?.id),
|
map((a) => a?.id),
|
||||||
|
@ -1279,7 +1281,6 @@ export default class MainBackground {
|
||||||
this.messagingService.send("switchAccountFinish");
|
this.messagingService.send("switchAccountFinish");
|
||||||
} else {
|
} else {
|
||||||
this.messagingService.send("doneLoggingOut", {
|
this.messagingService.send("doneLoggingOut", {
|
||||||
expired: expired,
|
|
||||||
userId: userBeingLoggedOut,
|
userId: userBeingLoggedOut,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
import { ApiService as AbstractApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService as AbstractApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { ApiService } from "@bitwarden/common/services/api.service";
|
import { ApiService } from "@bitwarden/common/services/api.service";
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ import { stateServiceFactory, StateServiceInitOptions } from "./state-service.fa
|
||||||
type ApiServiceFactoryOptions = FactoryOptions & {
|
type ApiServiceFactoryOptions = FactoryOptions & {
|
||||||
apiServiceOptions: {
|
apiServiceOptions: {
|
||||||
refreshAccessTokenErrorCallback?: () => Promise<void>;
|
refreshAccessTokenErrorCallback?: () => Promise<void>;
|
||||||
logoutCallback: (expired: boolean) => Promise<void>;
|
logoutCallback: (logoutReason: LogoutReason) => Promise<void>;
|
||||||
customUserAgent?: string;
|
customUserAgent?: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,14 +84,6 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||||
tap((msg: any) => {
|
tap((msg: any) => {
|
||||||
if (msg.command === "doneLoggingOut") {
|
if (msg.command === "doneLoggingOut") {
|
||||||
this.authService.logOut(async () => {
|
this.authService.logOut(async () => {
|
||||||
if (msg.expired) {
|
|
||||||
this.toastService.showToast({
|
|
||||||
variant: "warning",
|
|
||||||
title: this.i18nService.t("loggedOut"),
|
|
||||||
message: this.i18nService.t("loginExpired"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.router.navigate(["home"]);
|
this.router.navigate(["home"]);
|
||||||
|
|
|
@ -743,6 +743,9 @@
|
||||||
"loggedOut": {
|
"loggedOut": {
|
||||||
"message": "Logged out"
|
"message": "Logged out"
|
||||||
},
|
},
|
||||||
|
"loggedOutDesc": {
|
||||||
|
"message": "You have been logged out of your account."
|
||||||
|
},
|
||||||
"loginExpired": {
|
"loginExpired": {
|
||||||
"message": "Your login session has expired."
|
"message": "Your login session has expired."
|
||||||
},
|
},
|
||||||
|
|
|
@ -584,6 +584,9 @@
|
||||||
"loggedOut": {
|
"loggedOut": {
|
||||||
"message": "Logged out"
|
"message": "Logged out"
|
||||||
},
|
},
|
||||||
|
"loggedOutDesc": {
|
||||||
|
"message": "You have been logged out of your account."
|
||||||
|
},
|
||||||
"loginExpired": {
|
"loginExpired": {
|
||||||
"message": "Your login session has expired."
|
"message": "Your login session has expired."
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { InjectionToken } from "@angular/core";
|
import { InjectionToken } from "@angular/core";
|
||||||
import { Observable, Subject } from "rxjs";
|
import { Observable, Subject } from "rxjs";
|
||||||
|
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
import { ClientType } from "@bitwarden/common/enums";
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import {
|
import {
|
||||||
AbstractStorageService,
|
AbstractStorageService,
|
||||||
|
@ -35,7 +36,7 @@ export const MEMORY_STORAGE = new SafeInjectionToken<AbstractStorageService>("ME
|
||||||
export const SECURE_STORAGE = new SafeInjectionToken<AbstractStorageService>("SECURE_STORAGE");
|
export const SECURE_STORAGE = new SafeInjectionToken<AbstractStorageService>("SECURE_STORAGE");
|
||||||
export const STATE_FACTORY = new SafeInjectionToken<StateFactory>("STATE_FACTORY");
|
export const STATE_FACTORY = new SafeInjectionToken<StateFactory>("STATE_FACTORY");
|
||||||
export const LOGOUT_CALLBACK = new SafeInjectionToken<
|
export const LOGOUT_CALLBACK = new SafeInjectionToken<
|
||||||
(expired: boolean, userId?: string) => Promise<void>
|
(logoutReason: LogoutReason, userId?: string) => Promise<void>
|
||||||
>("LOGOUT_CALLBACK");
|
>("LOGOUT_CALLBACK");
|
||||||
export const LOCKED_CALLBACK = new SafeInjectionToken<(userId?: string) => Promise<void>>(
|
export const LOCKED_CALLBACK = new SafeInjectionToken<(userId?: string) => Promise<void>>(
|
||||||
"LOCKED_CALLBACK",
|
"LOCKED_CALLBACK",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core";
|
import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core";
|
||||||
import { Subject } from "rxjs";
|
import { firstValueFrom, Subject } from "rxjs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AuthRequestServiceAbstraction,
|
AuthRequestServiceAbstraction,
|
||||||
|
@ -13,6 +13,7 @@ import {
|
||||||
InternalUserDecryptionOptionsServiceAbstraction,
|
InternalUserDecryptionOptionsServiceAbstraction,
|
||||||
UserDecryptionOptionsService,
|
UserDecryptionOptionsService,
|
||||||
UserDecryptionOptionsServiceAbstraction,
|
UserDecryptionOptionsServiceAbstraction,
|
||||||
|
LogoutReason,
|
||||||
} from "@bitwarden/auth/common";
|
} from "@bitwarden/auth/common";
|
||||||
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
||||||
|
@ -117,6 +118,7 @@ import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/bill
|
||||||
import { BillingApiService } from "@bitwarden/common/billing/services/billing-api.service";
|
import { BillingApiService } from "@bitwarden/common/billing/services/billing-api.service";
|
||||||
import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service";
|
import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service";
|
||||||
import { PaymentMethodWarningsService } from "@bitwarden/common/billing/services/payment-method-warnings.service";
|
import { PaymentMethodWarningsService } from "@bitwarden/common/billing/services/payment-method-warnings.service";
|
||||||
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
|
||||||
|
@ -234,7 +236,7 @@ import { SyncNotifierService } from "@bitwarden/common/vault/services/sync/sync-
|
||||||
import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service";
|
import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service";
|
||||||
import { TotpService } from "@bitwarden/common/vault/services/totp.service";
|
import { TotpService } from "@bitwarden/common/vault/services/totp.service";
|
||||||
import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service";
|
import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service";
|
||||||
import { ToastService } from "@bitwarden/components";
|
import { ToastOptions, ToastService } from "@bitwarden/components";
|
||||||
import {
|
import {
|
||||||
ImportApiService,
|
ImportApiService,
|
||||||
ImportApiServiceAbstraction,
|
ImportApiServiceAbstraction,
|
||||||
|
@ -319,9 +321,65 @@ const safeProviders: SafeProvider[] = [
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: LOGOUT_CALLBACK,
|
provide: LOGOUT_CALLBACK,
|
||||||
useFactory:
|
useFactory:
|
||||||
(messagingService: MessagingServiceAbstraction) => (expired: boolean, userId?: string) =>
|
(
|
||||||
Promise.resolve(messagingService.send("logout", { expired: expired, userId: userId })),
|
messagingService: MessagingServiceAbstraction,
|
||||||
deps: [MessagingServiceAbstraction],
|
toastService: ToastService,
|
||||||
|
i18nService: I18nServiceAbstraction,
|
||||||
|
platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||||
|
) =>
|
||||||
|
async (logoutReason: LogoutReason, userId?: string) => {
|
||||||
|
const isDesktop = platformUtilsService.getClientType() === ClientType.Desktop;
|
||||||
|
|
||||||
|
let toastOptions: ToastOptions;
|
||||||
|
switch (logoutReason) {
|
||||||
|
case "sessionExpired": {
|
||||||
|
toastOptions = {
|
||||||
|
variant: "warning",
|
||||||
|
title: i18nService.t("loggedOut"),
|
||||||
|
message: i18nService.t("loginExpired"),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "accessTokenUnableToBeDecrypted": {
|
||||||
|
toastOptions = {
|
||||||
|
variant: "error",
|
||||||
|
title: i18nService.t("loggedOut"),
|
||||||
|
message: i18nService.t("accessTokenUnableToBeDecrypted"),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "refreshTokenSecureStorageRetrievalFailure": {
|
||||||
|
toastOptions = {
|
||||||
|
variant: "error",
|
||||||
|
title: i18nService.t("loggedOut"),
|
||||||
|
message: i18nService.t("refreshTokenSecureStorageRetrievalFailure"),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
toastOptions = {
|
||||||
|
variant: "error",
|
||||||
|
title: i18nService.t("loggedOut"),
|
||||||
|
message: i18nService.t("loggedOutDesc"),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeToast = toastService.showToast(toastOptions);
|
||||||
|
if (isDesktop) {
|
||||||
|
// Since desktop has process reload on logout, we need to wait for the toast to be hidden before triggering the logout.
|
||||||
|
await firstValueFrom(activeToast.onHidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(messagingService.send("logout", { userId: userId }));
|
||||||
|
},
|
||||||
|
deps: [
|
||||||
|
MessagingServiceAbstraction,
|
||||||
|
ToastService,
|
||||||
|
I18nServiceAbstraction,
|
||||||
|
PlatformUtilsServiceAbstraction,
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: LOCKED_CALLBACK,
|
provide: LOCKED_CALLBACK,
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
export type LogoutReason =
|
export type LogoutReason =
|
||||||
|
| "invalidGrantError"
|
||||||
|
| "vaultTimeout"
|
||||||
|
| "invalidSecurityStamp"
|
||||||
|
| "logoutNotification"
|
||||||
|
| "keyConnectorError"
|
||||||
| "sessionExpired"
|
| "sessionExpired"
|
||||||
| "accessTokenUnableToBeDecrypted"
|
| "accessTokenUnableToBeDecrypted"
|
||||||
| "refreshTokenSecureStorageRetrievalFailure";
|
| "refreshTokenSecureStorageRetrievalFailure";
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
|
|
||||||
import { ApiService } from "../../abstractions/api.service";
|
import { ApiService } from "../../abstractions/api.service";
|
||||||
import { OrganizationService } from "../../admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "../../admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { OrganizationUserType } from "../../admin-console/enums";
|
import { OrganizationUserType } from "../../admin-console/enums";
|
||||||
|
@ -57,7 +59,7 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private keyGenerationService: KeyGenerationService,
|
private keyGenerationService: KeyGenerationService,
|
||||||
private logoutCallback: (expired: boolean, userId?: string) => Promise<void>,
|
private logoutCallback: (logoutReason: LogoutReason, userId?: string) => Promise<void>,
|
||||||
private stateProvider: StateProvider,
|
private stateProvider: StateProvider,
|
||||||
) {
|
) {
|
||||||
this.usesKeyConnectorState = this.stateProvider.getActive(USES_KEY_CONNECTOR);
|
this.usesKeyConnectorState = this.stateProvider.getActive(USES_KEY_CONNECTOR);
|
||||||
|
@ -192,7 +194,7 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||||
if (this.logoutCallback != null) {
|
if (this.logoutCallback != null) {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.logoutCallback(false);
|
this.logoutCallback("keyConnectorError");
|
||||||
}
|
}
|
||||||
throw new Error("Key Connector error");
|
throw new Error("Key Connector error");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
|
|
||||||
import { ApiService as ApiServiceAbstraction } from "../abstractions/api.service";
|
import { ApiService as ApiServiceAbstraction } from "../abstractions/api.service";
|
||||||
import { OrganizationConnectionType } from "../admin-console/enums";
|
import { OrganizationConnectionType } from "../admin-console/enums";
|
||||||
import { OrganizationSponsorshipCreateRequest } from "../admin-console/models/request/organization/organization-sponsorship-create.request";
|
import { OrganizationSponsorshipCreateRequest } from "../admin-console/models/request/organization/organization-sponsorship-create.request";
|
||||||
|
@ -160,7 +162,7 @@ export class ApiService implements ApiServiceAbstraction {
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private refreshAccessTokenErrorCallback: () => Promise<void>,
|
private refreshAccessTokenErrorCallback: () => Promise<void>,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private logoutCallback: (expired: boolean) => Promise<void>,
|
private logoutCallback: (logoutReason: LogoutReason) => Promise<void>,
|
||||||
private customUserAgent: string = null,
|
private customUserAgent: string = null,
|
||||||
) {
|
) {
|
||||||
this.device = platformUtilsService.getDevice();
|
this.device = platformUtilsService.getDevice();
|
||||||
|
@ -1888,7 +1890,7 @@ export class ApiService implements ApiServiceAbstraction {
|
||||||
responseJson != null &&
|
responseJson != null &&
|
||||||
responseJson.error === "invalid_grant")
|
responseJson.error === "invalid_grant")
|
||||||
) {
|
) {
|
||||||
await this.logoutCallback(true);
|
await this.logoutCallback("invalidGrantError");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import * as signalR from "@microsoft/signalr";
|
||||||
import * as signalRMsgPack from "@microsoft/signalr-protocol-msgpack";
|
import * as signalRMsgPack from "@microsoft/signalr-protocol-msgpack";
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
|
|
||||||
import { AuthRequestServiceAbstraction } from "../../../auth/src/common/abstractions";
|
import { AuthRequestServiceAbstraction } from "../../../auth/src/common/abstractions";
|
||||||
import { ApiService } from "../abstractions/api.service";
|
import { ApiService } from "../abstractions/api.service";
|
||||||
import { NotificationsService as NotificationsServiceAbstraction } from "../abstractions/notifications.service";
|
import { NotificationsService as NotificationsServiceAbstraction } from "../abstractions/notifications.service";
|
||||||
|
@ -36,7 +38,7 @@ export class NotificationsService implements NotificationsServiceAbstraction {
|
||||||
private appIdService: AppIdService,
|
private appIdService: AppIdService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private environmentService: EnvironmentService,
|
private environmentService: EnvironmentService,
|
||||||
private logoutCallback: (expired: boolean) => Promise<void>,
|
private logoutCallback: (logoutReason: LogoutReason) => Promise<void>,
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private authRequestService: AuthRequestServiceAbstraction,
|
private authRequestService: AuthRequestServiceAbstraction,
|
||||||
|
@ -188,7 +190,7 @@ export class NotificationsService implements NotificationsServiceAbstraction {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.logoutCallback(true);
|
this.logoutCallback("logoutNotification");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NotificationType.SyncSendCreate:
|
case NotificationType.SyncSendCreate:
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { combineLatest, filter, firstValueFrom, map, switchMap, timeout } from "rxjs";
|
import { combineLatest, filter, firstValueFrom, map, switchMap, timeout } from "rxjs";
|
||||||
|
|
||||||
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
|
|
||||||
import { SearchService } from "../../abstractions/search.service";
|
import { SearchService } from "../../abstractions/search.service";
|
||||||
import { VaultTimeoutSettingsService } from "../../abstractions/vault-timeout/vault-timeout-settings.service";
|
import { VaultTimeoutSettingsService } from "../../abstractions/vault-timeout/vault-timeout-settings.service";
|
||||||
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout.service";
|
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "../../abstractions/vault-timeout/vault-timeout.service";
|
||||||
|
@ -34,7 +36,10 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
||||||
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
||||||
private stateEventRunnerService: StateEventRunnerService,
|
private stateEventRunnerService: StateEventRunnerService,
|
||||||
private lockedCallback: (userId?: string) => Promise<void> = null,
|
private lockedCallback: (userId?: string) => Promise<void> = null,
|
||||||
private loggedOutCallback: (expired: boolean, userId?: string) => Promise<void> = null,
|
private loggedOutCallback: (
|
||||||
|
logoutReason: LogoutReason,
|
||||||
|
userId?: string,
|
||||||
|
) => Promise<void> = null,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async init(checkOnInterval: boolean) {
|
async init(checkOnInterval: boolean) {
|
||||||
|
@ -145,7 +150,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
|
||||||
|
|
||||||
async logOut(userId?: string): Promise<void> {
|
async logOut(userId?: string): Promise<void> {
|
||||||
if (this.loggedOutCallback != null) {
|
if (this.loggedOutCallback != null) {
|
||||||
await this.loggedOutCallback(false, userId);
|
await this.loggedOutCallback("vaultTimeout", userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common";
|
import { LogoutReason, UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
|
|
||||||
import { ApiService } from "../../../abstractions/api.service";
|
import { ApiService } from "../../../abstractions/api.service";
|
||||||
import { InternalOrganizationServiceAbstraction } from "../../../admin-console/abstractions/organization/organization.service.abstraction";
|
import { InternalOrganizationServiceAbstraction } from "../../../admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
|
@ -71,7 +71,7 @@ export class SyncService implements SyncServiceAbstraction {
|
||||||
private sendApiService: SendApiService,
|
private sendApiService: SendApiService,
|
||||||
private userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
private userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||||
private avatarService: AvatarService,
|
private avatarService: AvatarService,
|
||||||
private logoutCallback: (expired: boolean) => Promise<void>,
|
private logoutCallback: (logoutReason: LogoutReason) => Promise<void>,
|
||||||
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
private tokenService: TokenService,
|
private tokenService: TokenService,
|
||||||
) {}
|
) {}
|
||||||
|
@ -313,7 +313,7 @@ export class SyncService implements SyncServiceAbstraction {
|
||||||
const stamp = await this.tokenService.getSecurityStamp(response.id);
|
const stamp = await this.tokenService.getSecurityStamp(response.id);
|
||||||
if (stamp != null && stamp !== response.securityStamp) {
|
if (stamp != null && stamp !== response.securityStamp) {
|
||||||
if (this.logoutCallback != null) {
|
if (this.logoutCallback != null) {
|
||||||
await this.logoutCallback(true);
|
await this.logoutCallback("invalidSecurityStamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("Stamp has changed");
|
throw new Error("Stamp has changed");
|
||||||
|
|
Loading…
Reference in New Issue