[PM-5364] Create SSO Login Service and add state ownership (#7485)
* create sso service * rename sso service to sso-login service * rename service * add references to sso login service and update state calls * fix browser * fix desktop * return promises * remove sso state from account and global objects * more descriptive org sso identifier method names * fix sso tests * fix tests
This commit is contained in:
parent
c2ed6383c6
commit
304c492f24
|
@ -0,0 +1,28 @@
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
|
import { SsoLoginService } from "@bitwarden/common/auth/services/sso-login.service";
|
||||||
|
|
||||||
|
import {
|
||||||
|
CachedServices,
|
||||||
|
factory,
|
||||||
|
FactoryOptions,
|
||||||
|
} from "../../../platform/background/service-factories/factory-options";
|
||||||
|
import {
|
||||||
|
stateProviderFactory,
|
||||||
|
StateProviderInitOptions,
|
||||||
|
} from "../../../platform/background/service-factories/state-provider.factory";
|
||||||
|
|
||||||
|
type SsoLoginServiceFactoryOptions = FactoryOptions;
|
||||||
|
|
||||||
|
export type SsoLoginServiceInitOptions = SsoLoginServiceFactoryOptions & StateProviderInitOptions;
|
||||||
|
|
||||||
|
export function ssoLoginServiceFactory(
|
||||||
|
cache: { ssoLoginService?: SsoLoginServiceAbstraction } & CachedServices,
|
||||||
|
opts: SsoLoginServiceInitOptions,
|
||||||
|
): Promise<SsoLoginServiceAbstraction> {
|
||||||
|
return factory(
|
||||||
|
cache,
|
||||||
|
"ssoLoginService",
|
||||||
|
opts,
|
||||||
|
async () => new SsoLoginService(await stateProviderFactory(cache, opts)),
|
||||||
|
);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstrac
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
|
@ -45,6 +46,7 @@ export class LoginComponent extends BaseLoginComponent {
|
||||||
formValidationErrorService: FormValidationErrorsService,
|
formValidationErrorService: FormValidationErrorsService,
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
@ -64,6 +66,7 @@ export class LoginComponent extends BaseLoginComponent {
|
||||||
formValidationErrorService,
|
formValidationErrorService,
|
||||||
route,
|
route,
|
||||||
loginService,
|
loginService,
|
||||||
|
ssoLoginService,
|
||||||
webAuthnLoginService,
|
webAuthnLoginService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
super.onSuccessfulLogin = async () => {
|
||||||
|
@ -106,8 +109,8 @@ export class LoginComponent extends BaseLoginComponent {
|
||||||
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
||||||
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
||||||
|
|
||||||
await this.stateService.setSsoCodeVerifier(codeVerifier);
|
await this.ssoLoginService.setCodeVerifier(codeVerifier);
|
||||||
await this.stateService.setSsoState(state);
|
await this.ssoLoginService.setSsoState(state);
|
||||||
|
|
||||||
let url = this.environmentService.getWebVaultUrl();
|
let url = this.environmentService.getWebVaultUrl();
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso
|
||||||
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
||||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
|
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
|
@ -36,6 +37,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent {
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
organizationApiService: OrganizationApiServiceAbstraction,
|
organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
organizationUserService: OrganizationUserService,
|
organizationUserService: OrganizationUserService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
@ -53,6 +55,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent {
|
||||||
stateService,
|
stateService,
|
||||||
organizationApiService,
|
organizationApiService,
|
||||||
organizationUserService,
|
organizationUserService,
|
||||||
|
ssoLoginService,
|
||||||
dialogService,
|
dialogService,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
|
@ -25,6 +26,7 @@ import { BrowserApi } from "../../platform/browser/browser-api";
|
||||||
})
|
})
|
||||||
export class SsoComponent extends BaseSsoComponent {
|
export class SsoComponent extends BaseSsoComponent {
|
||||||
constructor(
|
constructor(
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
loginStrategyService: LoginStrategyServiceAbstraction,
|
loginStrategyService: LoginStrategyServiceAbstraction,
|
||||||
router: Router,
|
router: Router,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
|
@ -42,6 +44,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
@Inject(WINDOW) private win: Window,
|
@Inject(WINDOW) private win: Window,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
ssoLoginService,
|
||||||
loginStrategyService,
|
loginStrategyService,
|
||||||
router,
|
router,
|
||||||
i18nService,
|
i18nService,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
|
@ -55,6 +56,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||||
appIdService: AppIdService,
|
appIdService: AppIdService,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
@Inject(WINDOW) protected win: Window,
|
@Inject(WINDOW) protected win: Window,
|
||||||
private browserMessagingApi: ZonedMessageListenerService,
|
private browserMessagingApi: ZonedMessageListenerService,
|
||||||
|
@ -73,6 +75,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||||
twoFactorService,
|
twoFactorService,
|
||||||
appIdService,
|
appIdService,
|
||||||
loginService,
|
loginService,
|
||||||
|
ssoLoginService,
|
||||||
configService,
|
configService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
super.onSuccessfulLogin = async () => {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } 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";
|
||||||
|
@ -73,6 +74,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
||||||
formValidationErrorService: FormValidationErrorsService,
|
formValidationErrorService: FormValidationErrorsService,
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
@ -92,6 +94,7 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
||||||
formValidationErrorService,
|
formValidationErrorService,
|
||||||
route,
|
route,
|
||||||
loginService,
|
loginService,
|
||||||
|
ssoLoginService,
|
||||||
webAuthnLoginService,
|
webAuthnLoginService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = () => {
|
super.onSuccessfulLogin = () => {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso
|
||||||
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
||||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
|
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -43,6 +44,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On
|
||||||
stateService: StateService,
|
stateService: StateService,
|
||||||
organizationApiService: OrganizationApiServiceAbstraction,
|
organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
organizationUserService: OrganizationUserService,
|
organizationUserService: OrganizationUserService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
@ -60,6 +62,7 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On
|
||||||
stateService,
|
stateService,
|
||||||
organizationApiService,
|
organizationApiService,
|
||||||
organizationUserService,
|
organizationUserService,
|
||||||
|
ssoLoginService,
|
||||||
dialogService,
|
dialogService,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { SsoComponent as BaseSsoComponent } from "@bitwarden/angular/auth/components/sso.component";
|
import { SsoComponent as BaseSsoComponent } from "@bitwarden/angular/auth/components/sso.component";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
|
@ -20,6 +21,7 @@ import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.serv
|
||||||
})
|
})
|
||||||
export class SsoComponent extends BaseSsoComponent {
|
export class SsoComponent extends BaseSsoComponent {
|
||||||
constructor(
|
constructor(
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
loginStrategyService: LoginStrategyServiceAbstraction,
|
loginStrategyService: LoginStrategyServiceAbstraction,
|
||||||
router: Router,
|
router: Router,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
|
@ -35,6 +37,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
ssoLoginService,
|
||||||
loginStrategyService,
|
loginStrategyService,
|
||||||
router,
|
router,
|
||||||
i18nService,
|
i18nService,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
|
@ -46,6 +47,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||||
twoFactorService: TwoFactorService,
|
twoFactorService: TwoFactorService,
|
||||||
appIdService: AppIdService,
|
appIdService: AppIdService,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
@Inject(WINDOW) protected win: Window,
|
@Inject(WINDOW) protected win: Window,
|
||||||
) {
|
) {
|
||||||
|
@ -63,6 +65,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||||
twoFactorService,
|
twoFactorService,
|
||||||
appIdService,
|
appIdService,
|
||||||
loginService,
|
loginService,
|
||||||
|
ssoLoginService,
|
||||||
configService,
|
configService,
|
||||||
);
|
);
|
||||||
super.onSuccessfulLogin = async () => {
|
super.onSuccessfulLogin = async () => {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||||
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
|
import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
|
||||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||||
|
@ -64,6 +65,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit {
|
||||||
formBuilder: FormBuilder,
|
formBuilder: FormBuilder,
|
||||||
formValidationErrorService: FormValidationErrorsService,
|
formValidationErrorService: FormValidationErrorsService,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
@ -83,6 +85,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit {
|
||||||
formValidationErrorService,
|
formValidationErrorService,
|
||||||
route,
|
route,
|
||||||
loginService,
|
loginService,
|
||||||
|
ssoLoginService,
|
||||||
webAuthnLoginService,
|
webAuthnLoginService,
|
||||||
);
|
);
|
||||||
this.onSuccessfulLogin = async () => {
|
this.onSuccessfulLogin = async () => {
|
||||||
|
|
|
@ -1,59 +1,9 @@
|
||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
|
||||||
|
|
||||||
import { SetPasswordComponent as BaseSetPasswordComponent } from "@bitwarden/angular/auth/components/set-password.component";
|
import { SetPasswordComponent as BaseSetPasswordComponent } from "@bitwarden/angular/auth/components/set-password.component";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|
||||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
|
|
||||||
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
|
||||||
import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
|
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
|
||||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
|
|
||||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
|
||||||
import { DialogService } from "@bitwarden/components";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-set-password",
|
selector: "app-set-password",
|
||||||
templateUrl: "set-password.component.html",
|
templateUrl: "set-password.component.html",
|
||||||
})
|
})
|
||||||
export class SetPasswordComponent extends BaseSetPasswordComponent {
|
export class SetPasswordComponent extends BaseSetPasswordComponent {}
|
||||||
constructor(
|
|
||||||
apiService: ApiService,
|
|
||||||
i18nService: I18nService,
|
|
||||||
cryptoService: CryptoService,
|
|
||||||
messagingService: MessagingService,
|
|
||||||
passwordGenerationService: PasswordGenerationServiceAbstraction,
|
|
||||||
platformUtilsService: PlatformUtilsService,
|
|
||||||
policyApiService: PolicyApiServiceAbstraction,
|
|
||||||
policyService: PolicyService,
|
|
||||||
router: Router,
|
|
||||||
syncService: SyncService,
|
|
||||||
route: ActivatedRoute,
|
|
||||||
stateService: StateService,
|
|
||||||
organizationApiService: OrganizationApiServiceAbstraction,
|
|
||||||
organizationUserService: OrganizationUserService,
|
|
||||||
dialogService: DialogService,
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
i18nService,
|
|
||||||
cryptoService,
|
|
||||||
messagingService,
|
|
||||||
passwordGenerationService,
|
|
||||||
platformUtilsService,
|
|
||||||
policyApiService,
|
|
||||||
policyService,
|
|
||||||
router,
|
|
||||||
apiService,
|
|
||||||
syncService,
|
|
||||||
route,
|
|
||||||
stateService,
|
|
||||||
organizationApiService,
|
|
||||||
organizationUserService,
|
|
||||||
dialogService,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
|
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
|
||||||
import { OrganizationDomainSsoDetailsResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain-sso-details.response";
|
import { OrganizationDomainSsoDetailsResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain-sso-details.response";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { HttpStatusCode } from "@bitwarden/common/enums";
|
import { HttpStatusCode } from "@bitwarden/common/enums";
|
||||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
|
@ -26,6 +27,7 @@ import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/ge
|
||||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||||
export class SsoComponent extends BaseSsoComponent {
|
export class SsoComponent extends BaseSsoComponent {
|
||||||
constructor(
|
constructor(
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
loginStrategyService: LoginStrategyServiceAbstraction,
|
loginStrategyService: LoginStrategyServiceAbstraction,
|
||||||
router: Router,
|
router: Router,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
|
@ -42,6 +44,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
ssoLoginService,
|
||||||
loginStrategyService,
|
loginStrategyService,
|
||||||
router,
|
router,
|
||||||
i18nService,
|
i18nService,
|
||||||
|
@ -94,7 +97,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to state svc if domain is unclaimed
|
// Fallback to state svc if domain is unclaimed
|
||||||
const storedIdentifier = await this.stateService.getSsoOrgIdentifier();
|
const storedIdentifier = await this.ssoLoginService.getOrganizationSsoIdentifier();
|
||||||
if (storedIdentifier != null) {
|
if (storedIdentifier != null) {
|
||||||
this.identifier = storedIdentifier;
|
this.identifier = storedIdentifier;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +121,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
await this.stateService.setSsoOrganizationIdentifier(this.identifier);
|
await this.ssoLoginService.setOrganizationSsoIdentifier(this.identifier);
|
||||||
if (this.clientId === "browser") {
|
if (this.clientId === "browser") {
|
||||||
document.cookie = `ssoHandOffMessage=${this.i18nService.t("ssoHandOff")};SameSite=strict`;
|
document.cookie = `ssoHandOffMessage=${this.i18nService.t("ssoHandOff")};SameSite=strict`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
|
@ -43,6 +44,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest
|
||||||
twoFactorService: TwoFactorService,
|
twoFactorService: TwoFactorService,
|
||||||
appIdService: AppIdService,
|
appIdService: AppIdService,
|
||||||
loginService: LoginService,
|
loginService: LoginService,
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
@Inject(WINDOW) protected win: Window,
|
@Inject(WINDOW) protected win: Window,
|
||||||
) {
|
) {
|
||||||
|
@ -60,6 +62,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest
|
||||||
twoFactorService,
|
twoFactorService,
|
||||||
appIdService,
|
appIdService,
|
||||||
loginService,
|
loginService,
|
||||||
|
ssoLoginService,
|
||||||
configService,
|
configService,
|
||||||
);
|
);
|
||||||
this.onSuccessfulLoginNavigate = this.goAfterLogIn;
|
this.onSuccessfulLoginNavigate = this.goAfterLogIn;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { SsoComponent } from "@bitwarden/angular/auth/components/sso.component";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
|
@ -28,6 +29,7 @@ export class LinkSsoDirective extends SsoComponent implements AfterContentInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
platformUtilsService: PlatformUtilsService,
|
platformUtilsService: PlatformUtilsService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
apiService: ApiService,
|
apiService: ApiService,
|
||||||
|
@ -42,6 +44,7 @@ export class LinkSsoDirective extends SsoComponent implements AfterContentInit {
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
ssoLoginService,
|
||||||
loginStrategyService,
|
loginStrategyService,
|
||||||
router,
|
router,
|
||||||
i18nService,
|
i18nService,
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abst
|
||||||
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
|
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
|
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
|
@ -88,6 +89,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
|
||||||
protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
|
protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction,
|
||||||
protected platformUtilsService: PlatformUtilsService,
|
protected platformUtilsService: PlatformUtilsService,
|
||||||
protected passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction,
|
protected passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction,
|
||||||
|
protected ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
|
@ -163,7 +165,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
async loadNewUserData() {
|
async loadNewUserData() {
|
||||||
const autoEnrollStatus$ = defer(() =>
|
const autoEnrollStatus$ = defer(() =>
|
||||||
this.stateService.getUserSsoOrganizationIdentifier(),
|
this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(),
|
||||||
).pipe(
|
).pipe(
|
||||||
switchMap((organizationIdentifier) => {
|
switchMap((organizationIdentifier) => {
|
||||||
if (organizationIdentifier == undefined) {
|
if (organizationIdentifier == undefined) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { take, takeUntil } from "rxjs/operators";
|
||||||
import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitwarden/auth/common";
|
||||||
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
|
@ -78,6 +79,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
|
||||||
protected formValidationErrorService: FormValidationErrorsService,
|
protected formValidationErrorService: FormValidationErrorsService,
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
protected loginService: LoginService,
|
protected loginService: LoginService,
|
||||||
|
protected ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
protected webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
protected webAuthnLoginService: WebAuthnLoginServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(environmentService, i18nService, platformUtilsService);
|
super(environmentService, i18nService, platformUtilsService);
|
||||||
|
@ -241,8 +243,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
|
||||||
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
||||||
|
|
||||||
// Save sso params
|
// Save sso params
|
||||||
await this.stateService.setSsoState(state);
|
await this.ssoLoginService.setSsoState(state);
|
||||||
await this.stateService.setSsoCodeVerifier(ssoCodeVerifier);
|
await this.ssoLoginService.setCodeVerifier(ssoCodeVerifier);
|
||||||
|
|
||||||
// Build URI
|
// Build URI
|
||||||
const webUrl = this.environmentService.getWebVaultUrl();
|
const webUrl = this.environmentService.getWebVaultUrl();
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||||
import { OrganizationAutoEnrollStatusResponse } from "@bitwarden/common/admin-console/models/response/organization-auto-enroll-status.response";
|
import { OrganizationAutoEnrollStatusResponse } from "@bitwarden/common/admin-console/models/response/organization-auto-enroll-status.response";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request";
|
import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request";
|
||||||
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
|
||||||
|
@ -63,6 +64,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
||||||
stateService: StateService,
|
stateService: StateService,
|
||||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
private organizationUserService: OrganizationUserService,
|
private organizationUserService: OrganizationUserService,
|
||||||
|
private ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
|
@ -96,7 +98,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
||||||
} else {
|
} else {
|
||||||
// Try to get orgSsoId from state as fallback
|
// Try to get orgSsoId from state as fallback
|
||||||
// Note: this is primarily for the TDE user w/out MP obtains admin MP reset permission scenario.
|
// Note: this is primarily for the TDE user w/out MP obtains admin MP reset permission scenario.
|
||||||
return this.stateService.getUserSsoOrganizationIdentifier();
|
return this.ssoLoginService.getActiveUserOrganizationSsoIdentifier();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
filter((orgSsoId) => orgSsoId != null),
|
filter((orgSsoId) => orgSsoId != null),
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Observable, of } from "rxjs";
|
||||||
|
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
|
@ -53,6 +54,7 @@ describe("SsoComponent", () => {
|
||||||
let mockQueryParams: Observable<any>;
|
let mockQueryParams: Observable<any>;
|
||||||
let mockActivatedRoute: ActivatedRoute;
|
let mockActivatedRoute: ActivatedRoute;
|
||||||
|
|
||||||
|
let mockSsoLoginService: MockProxy<SsoLoginServiceAbstraction>;
|
||||||
let mockStateService: MockProxy<StateService>;
|
let mockStateService: MockProxy<StateService>;
|
||||||
let mockPlatformUtilsService: MockProxy<PlatformUtilsService>;
|
let mockPlatformUtilsService: MockProxy<PlatformUtilsService>;
|
||||||
let mockApiService: MockProxy<ApiService>;
|
let mockApiService: MockProxy<ApiService>;
|
||||||
|
@ -99,6 +101,7 @@ describe("SsoComponent", () => {
|
||||||
queryParams: mockQueryParams,
|
queryParams: mockQueryParams,
|
||||||
} as any as ActivatedRoute;
|
} as any as ActivatedRoute;
|
||||||
|
|
||||||
|
mockSsoLoginService = mock<SsoLoginServiceAbstraction>();
|
||||||
mockStateService = mock<StateService>();
|
mockStateService = mock<StateService>();
|
||||||
mockPlatformUtilsService = mock<PlatformUtilsService>();
|
mockPlatformUtilsService = mock<PlatformUtilsService>();
|
||||||
mockApiService = mock<ApiService>();
|
mockApiService = mock<ApiService>();
|
||||||
|
@ -167,6 +170,7 @@ describe("SsoComponent", () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [TestSsoComponent],
|
declarations: [TestSsoComponent],
|
||||||
providers: [
|
providers: [
|
||||||
|
{ provide: SsoLoginServiceAbstraction, useValue: mockSsoLoginService },
|
||||||
{ provide: LoginStrategyServiceAbstraction, useValue: mockLoginStrategyService },
|
{ provide: LoginStrategyServiceAbstraction, useValue: mockLoginStrategyService },
|
||||||
{ provide: Router, useValue: mockRouter },
|
{ provide: Router, useValue: mockRouter },
|
||||||
{ provide: I18nService, useValue: mockI18nService },
|
{ provide: I18nService, useValue: mockI18nService },
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { first } from "rxjs/operators";
|
||||||
|
|
||||||
import { LoginStrategyServiceAbstraction, SsoLoginCredentials } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction, SsoLoginCredentials } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { TrustedDeviceUserDecryptionOption } from "@bitwarden/common/auth/models/domain/user-decryption-options/trusted-device-user-decryption-option";
|
import { TrustedDeviceUserDecryptionOption } from "@bitwarden/common/auth/models/domain/user-decryption-options/trusted-device-user-decryption-option";
|
||||||
|
@ -46,6 +47,7 @@ export class SsoComponent {
|
||||||
protected codeChallenge: string;
|
protected codeChallenge: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
protected ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
protected loginStrategyService: LoginStrategyServiceAbstraction,
|
protected loginStrategyService: LoginStrategyServiceAbstraction,
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected i18nService: I18nService,
|
protected i18nService: I18nService,
|
||||||
|
@ -64,10 +66,10 @@ export class SsoComponent {
|
||||||
// eslint-disable-next-line rxjs/no-async-subscribe
|
// eslint-disable-next-line rxjs/no-async-subscribe
|
||||||
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
||||||
if (qParams.code != null && qParams.state != null) {
|
if (qParams.code != null && qParams.state != null) {
|
||||||
const codeVerifier = await this.stateService.getSsoCodeVerifier();
|
const codeVerifier = await this.ssoLoginService.getCodeVerifier();
|
||||||
const state = await this.stateService.getSsoState();
|
const state = await this.ssoLoginService.getSsoState();
|
||||||
await this.stateService.setSsoCodeVerifier(null);
|
await this.ssoLoginService.setCodeVerifier(null);
|
||||||
await this.stateService.setSsoState(null);
|
await this.ssoLoginService.setSsoState(null);
|
||||||
if (
|
if (
|
||||||
qParams.code != null &&
|
qParams.code != null &&
|
||||||
codeVerifier != null &&
|
codeVerifier != null &&
|
||||||
|
@ -133,7 +135,7 @@ export class SsoComponent {
|
||||||
const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);
|
const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);
|
||||||
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
||||||
codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
||||||
await this.stateService.setSsoCodeVerifier(codeVerifier);
|
await this.ssoLoginService.setCodeVerifier(codeVerifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
|
@ -147,7 +149,7 @@ export class SsoComponent {
|
||||||
state += `_identifier=${this.identifier}`;
|
state += `_identifier=${this.identifier}`;
|
||||||
|
|
||||||
// Save state (regardless of new or existing)
|
// Save state (regardless of new or existing)
|
||||||
await this.stateService.setSsoState(state);
|
await this.ssoLoginService.setSsoState(state);
|
||||||
|
|
||||||
let authorizeUrl =
|
let authorizeUrl =
|
||||||
this.environmentService.getIdentityUrl() +
|
this.environmentService.getIdentityUrl() +
|
||||||
|
@ -203,7 +205,7 @@ export class SsoComponent {
|
||||||
// - TDE login decryption options component
|
// - TDE login decryption options component
|
||||||
// - Browser SSO on extension open
|
// - Browser SSO on extension open
|
||||||
// Note: you cannot set this in state before 2FA b/c there won't be an account in state.
|
// Note: you cannot set this in state before 2FA b/c there won't be an account in state.
|
||||||
await this.stateService.setUserSsoOrganizationIdentifier(orgSsoIdentifier);
|
await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(orgSsoIdentifier);
|
||||||
|
|
||||||
// Users enrolled in admin acct recovery can be forced to set a new password after
|
// Users enrolled in admin acct recovery can be forced to set a new password after
|
||||||
// having the admin set a temp password for them (affects TDE & standard users)
|
// having the admin set a temp password for them (affects TDE & standard users)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
|
@ -55,6 +56,7 @@ describe("TwoFactorComponent", () => {
|
||||||
let mockTwoFactorService: MockProxy<TwoFactorService>;
|
let mockTwoFactorService: MockProxy<TwoFactorService>;
|
||||||
let mockAppIdService: MockProxy<AppIdService>;
|
let mockAppIdService: MockProxy<AppIdService>;
|
||||||
let mockLoginService: MockProxy<LoginService>;
|
let mockLoginService: MockProxy<LoginService>;
|
||||||
|
let mockSsoLoginService: MockProxy<SsoLoginServiceAbstraction>;
|
||||||
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
let mockConfigService: MockProxy<ConfigServiceAbstraction>;
|
||||||
|
|
||||||
let mockAcctDecryptionOpts: {
|
let mockAcctDecryptionOpts: {
|
||||||
|
@ -81,6 +83,7 @@ describe("TwoFactorComponent", () => {
|
||||||
mockTwoFactorService = mock<TwoFactorService>();
|
mockTwoFactorService = mock<TwoFactorService>();
|
||||||
mockAppIdService = mock<AppIdService>();
|
mockAppIdService = mock<AppIdService>();
|
||||||
mockLoginService = mock<LoginService>();
|
mockLoginService = mock<LoginService>();
|
||||||
|
mockSsoLoginService = mock<SsoLoginServiceAbstraction>();
|
||||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
mockConfigService = mock<ConfigServiceAbstraction>();
|
||||||
|
|
||||||
mockAcctDecryptionOpts = {
|
mockAcctDecryptionOpts = {
|
||||||
|
@ -150,6 +153,7 @@ describe("TwoFactorComponent", () => {
|
||||||
{ provide: TwoFactorService, useValue: mockTwoFactorService },
|
{ provide: TwoFactorService, useValue: mockTwoFactorService },
|
||||||
{ provide: AppIdService, useValue: mockAppIdService },
|
{ provide: AppIdService, useValue: mockAppIdService },
|
||||||
{ provide: LoginService, useValue: mockLoginService },
|
{ provide: LoginService, useValue: mockLoginService },
|
||||||
|
{ provide: SsoLoginServiceAbstraction, useValue: mockSsoLoginService },
|
||||||
{ provide: ConfigServiceAbstraction, useValue: mockConfigService },
|
{ provide: ConfigServiceAbstraction, useValue: mockConfigService },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
|
@ -83,6 +84,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
|
||||||
protected twoFactorService: TwoFactorService,
|
protected twoFactorService: TwoFactorService,
|
||||||
protected appIdService: AppIdService,
|
protected appIdService: AppIdService,
|
||||||
protected loginService: LoginService,
|
protected loginService: LoginService,
|
||||||
|
protected ssoLoginService: SsoLoginServiceAbstraction,
|
||||||
protected configService: ConfigServiceAbstraction,
|
protected configService: ConfigServiceAbstraction,
|
||||||
) {
|
) {
|
||||||
super(environmentService, i18nService, platformUtilsService);
|
super(environmentService, i18nService, platformUtilsService);
|
||||||
|
@ -278,7 +280,7 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
|
||||||
// Save off the OrgSsoIdentifier for use in the TDE flows
|
// Save off the OrgSsoIdentifier for use in the TDE flows
|
||||||
// - TDE login decryption options component
|
// - TDE login decryption options component
|
||||||
// - Browser SSO on extension open
|
// - Browser SSO on extension open
|
||||||
await this.stateService.setUserSsoOrganizationIdentifier(this.orgIdentifier);
|
await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(this.orgIdentifier);
|
||||||
this.loginService.clearValues();
|
this.loginService.clearValues();
|
||||||
|
|
||||||
// note: this flow affects both TDE & standard users
|
// note: this flow affects both TDE & standard users
|
||||||
|
|
|
@ -55,6 +55,7 @@ import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstraction
|
||||||
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
||||||
import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/login.service";
|
import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/login.service";
|
||||||
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
|
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
|
||||||
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||||
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction";
|
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction";
|
||||||
|
@ -73,6 +74,7 @@ import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services
|
||||||
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service";
|
||||||
import { LoginService } from "@bitwarden/common/auth/services/login.service";
|
import { LoginService } from "@bitwarden/common/auth/services/login.service";
|
||||||
import { PasswordResetEnrollmentServiceImplementation } from "@bitwarden/common/auth/services/password-reset-enrollment.service.implementation";
|
import { PasswordResetEnrollmentServiceImplementation } from "@bitwarden/common/auth/services/password-reset-enrollment.service.implementation";
|
||||||
|
import { SsoLoginService } from "@bitwarden/common/auth/services/sso-login.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/services/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/services/two-factor.service";
|
||||||
import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service";
|
import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service";
|
||||||
|
@ -534,6 +536,11 @@ import { ModalService } from "./modal.service";
|
||||||
provide: VaultTimeoutServiceAbstraction,
|
provide: VaultTimeoutServiceAbstraction,
|
||||||
useExisting: VaultTimeoutService,
|
useExisting: VaultTimeoutService,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: SsoLoginServiceAbstraction,
|
||||||
|
useClass: SsoLoginService,
|
||||||
|
deps: [StateProvider],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
provide: StateServiceAbstraction,
|
provide: StateServiceAbstraction,
|
||||||
useClass: StateService,
|
useClass: StateService,
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
export abstract class SsoLoginServiceAbstraction {
|
||||||
|
/**
|
||||||
|
* Gets the code verifier used for SSO.
|
||||||
|
*
|
||||||
|
* PKCE requires a `code_verifier` to be generated which is then used to derive a `code_challenge`.
|
||||||
|
* While the `code_challenge` is verified upon return from the SSO provider, the `code_verifier` is
|
||||||
|
* sent to the server with the `authorization_code` so that the server can derive the same `code_challenge`
|
||||||
|
* and verify it matches the one sent in the request for the `authorization_code`.
|
||||||
|
* @see https://datatracker.ietf.org/doc/html/rfc7636
|
||||||
|
* @returns The code verifier used for SSO.
|
||||||
|
*/
|
||||||
|
getCodeVerifier: () => Promise<string>;
|
||||||
|
/**
|
||||||
|
* Sets the code verifier used for SSO.
|
||||||
|
*
|
||||||
|
* PKCE requires a `code_verifier` to be generated which is then used to derive a `code_challenge`.
|
||||||
|
* While the `code_challenge` is verified upon return from the SSO provider, the `code_verifier` is
|
||||||
|
* sent to the server with the `authorization_code` so that the server can derive the same `code_challenge`
|
||||||
|
* and verify it matches the one sent in the request for the `authorization_code`.
|
||||||
|
* @see https://datatracker.ietf.org/doc/html/rfc7636
|
||||||
|
*/
|
||||||
|
setCodeVerifier: (codeVerifier: string) => Promise<void>;
|
||||||
|
/**
|
||||||
|
* Gets the value of the SSO state.
|
||||||
|
*
|
||||||
|
* `state` is a parameter used in the Authorization Code Flow of OAuth 2.0 to prevent CSRF attacks. It is an
|
||||||
|
* opaque value generated on the client and is sent to the authorization server. The authorization server
|
||||||
|
* returns the `state` in the callback and the client verifies that the value returned matches the value sent.
|
||||||
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1
|
||||||
|
* @returns The SSO state.
|
||||||
|
*/
|
||||||
|
getSsoState: () => Promise<string>;
|
||||||
|
/**
|
||||||
|
* Sets the value of the SSO state.
|
||||||
|
*
|
||||||
|
* `state` is a parameter used in the Authorization Code Flow of OAuth 2.0 to prevent CSRF attacks. It is an
|
||||||
|
* opaque value generated on the client and is sent to the authorization server. The authorization server
|
||||||
|
* returns the `state` in the callback and the client verifies that the value returned matches the value sent.
|
||||||
|
* @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1
|
||||||
|
*/
|
||||||
|
setSsoState: (ssoState: string) => Promise<void>;
|
||||||
|
/**
|
||||||
|
* Gets the value of the user's organization sso identifier.
|
||||||
|
*
|
||||||
|
* This should only be used during the SSO flow to identify the organization that the user is attempting to log in to.
|
||||||
|
* Do not use this value outside of the SSO login flow.
|
||||||
|
* @returns The user's organization identifier.
|
||||||
|
*/
|
||||||
|
getOrganizationSsoIdentifier: () => Promise<string>;
|
||||||
|
/**
|
||||||
|
* Sets the value of the user's organization sso identifier.
|
||||||
|
*
|
||||||
|
* This should only be used during the SSO flow to identify the organization that the user is attempting to log in to.
|
||||||
|
* Do not use this value outside of the SSO login flow.
|
||||||
|
*/
|
||||||
|
setOrganizationSsoIdentifier: (organizationIdentifier: string) => Promise<void>;
|
||||||
|
/**
|
||||||
|
* Gets the value of the active user's organization sso identifier.
|
||||||
|
*
|
||||||
|
* This should only be used post successful SSO login once the user is initialized.
|
||||||
|
*/
|
||||||
|
getActiveUserOrganizationSsoIdentifier: () => Promise<string>;
|
||||||
|
/**
|
||||||
|
* Sets the value of the active user's organization sso identifier.
|
||||||
|
*
|
||||||
|
* This should only be used post successful SSO login once the user is initialized.
|
||||||
|
*/
|
||||||
|
setActiveUserOrganizationSsoIdentifier: (organizationIdentifier: string) => Promise<void>;
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ActiveUserState,
|
||||||
|
GlobalState,
|
||||||
|
KeyDefinition,
|
||||||
|
SSO_DISK,
|
||||||
|
StateProvider,
|
||||||
|
} from "../../platform/state";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses disk storage so that the code verifier can be persisted across sso redirects.
|
||||||
|
*/
|
||||||
|
const CODE_VERIFIER = new KeyDefinition<string>(SSO_DISK, "ssoCodeVerifier", {
|
||||||
|
deserializer: (codeVerifier) => codeVerifier,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses disk storage so that the sso state can be persisted across sso redirects.
|
||||||
|
*/
|
||||||
|
const SSO_STATE = new KeyDefinition<string>(SSO_DISK, "ssoState", {
|
||||||
|
deserializer: (state) => state,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses disk storage so that the organization sso identifier can be persisted across sso redirects.
|
||||||
|
*/
|
||||||
|
const ORGANIZATION_SSO_IDENTIFIER = new KeyDefinition<string>(
|
||||||
|
SSO_DISK,
|
||||||
|
"organizationSsoIdentifier",
|
||||||
|
{
|
||||||
|
deserializer: (organizationIdentifier) => organizationIdentifier,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export class SsoLoginService {
|
||||||
|
private codeVerifierState: GlobalState<string>;
|
||||||
|
private ssoState: GlobalState<string>;
|
||||||
|
private orgSsoIdentifierState: GlobalState<string>;
|
||||||
|
private activeUserOrgSsoIdentifierState: ActiveUserState<string>;
|
||||||
|
|
||||||
|
constructor(private stateProvider: StateProvider) {
|
||||||
|
this.codeVerifierState = this.stateProvider.getGlobal(CODE_VERIFIER);
|
||||||
|
this.ssoState = this.stateProvider.getGlobal(SSO_STATE);
|
||||||
|
this.orgSsoIdentifierState = this.stateProvider.getGlobal(ORGANIZATION_SSO_IDENTIFIER);
|
||||||
|
this.activeUserOrgSsoIdentifierState = this.stateProvider.getActive(
|
||||||
|
ORGANIZATION_SSO_IDENTIFIER,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCodeVerifier(): Promise<string> {
|
||||||
|
return firstValueFrom(this.codeVerifierState.state$);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setCodeVerifier(codeVerifier: string): Promise<void> {
|
||||||
|
await this.codeVerifierState.update((_) => codeVerifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSsoState(): Promise<string> {
|
||||||
|
return firstValueFrom(this.ssoState.state$);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSsoState(ssoState: string): Promise<void> {
|
||||||
|
await this.ssoState.update((_) => ssoState);
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrganizationSsoIdentifier(): Promise<string> {
|
||||||
|
return firstValueFrom(this.orgSsoIdentifierState.state$);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setOrganizationSsoIdentifier(organizationIdentifier: string): Promise<void> {
|
||||||
|
await this.orgSsoIdentifierState.update((_) => organizationIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
getActiveUserOrganizationSsoIdentifier(): Promise<string> {
|
||||||
|
return firstValueFrom(this.activeUserOrgSsoIdentifierState.state$);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setActiveUserOrganizationSsoIdentifier(organizationIdentifier: string): Promise<void> {
|
||||||
|
await this.activeUserOrgSsoIdentifierState.update((_) => organizationIdentifier);
|
||||||
|
}
|
||||||
|
}
|
|
@ -460,17 +460,6 @@ export abstract class StateService<T extends Account = Account> {
|
||||||
* @deprecated Do not call this directly, use SettingsService
|
* @deprecated Do not call this directly, use SettingsService
|
||||||
*/
|
*/
|
||||||
setSettings: (value: AccountSettingsSettings, options?: StorageOptions) => Promise<void>;
|
setSettings: (value: AccountSettingsSettings, options?: StorageOptions) => Promise<void>;
|
||||||
getSsoCodeVerifier: (options?: StorageOptions) => Promise<string>;
|
|
||||||
setSsoCodeVerifier: (value: string, options?: StorageOptions) => Promise<void>;
|
|
||||||
getSsoOrgIdentifier: (options?: StorageOptions) => Promise<string>;
|
|
||||||
setSsoOrganizationIdentifier: (value: string, options?: StorageOptions) => Promise<void>;
|
|
||||||
getSsoState: (options?: StorageOptions) => Promise<string>;
|
|
||||||
setSsoState: (value: string, options?: StorageOptions) => Promise<void>;
|
|
||||||
getUserSsoOrganizationIdentifier: (options?: StorageOptions) => Promise<string>;
|
|
||||||
setUserSsoOrganizationIdentifier: (
|
|
||||||
value: string | null,
|
|
||||||
options?: StorageOptions,
|
|
||||||
) => Promise<void>;
|
|
||||||
getTheme: (options?: StorageOptions) => Promise<ThemeType>;
|
getTheme: (options?: StorageOptions) => Promise<ThemeType>;
|
||||||
setTheme: (value: ThemeType, options?: StorageOptions) => Promise<void>;
|
setTheme: (value: ThemeType, options?: StorageOptions) => Promise<void>;
|
||||||
getTwoFactorToken: (options?: StorageOptions) => Promise<string>;
|
getTwoFactorToken: (options?: StorageOptions) => Promise<string>;
|
||||||
|
|
|
@ -377,25 +377,6 @@ export class AccountDecryptionOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LoginState {
|
|
||||||
ssoOrganizationIdentifier?: string;
|
|
||||||
|
|
||||||
constructor(init?: Partial<LoginState>) {
|
|
||||||
if (init) {
|
|
||||||
Object.assign(this, init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromJSON(obj: Jsonify<LoginState>): LoginState {
|
|
||||||
if (obj == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const loginState = Object.assign(new LoginState(), obj);
|
|
||||||
return loginState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Account {
|
export class Account {
|
||||||
data?: AccountData = new AccountData();
|
data?: AccountData = new AccountData();
|
||||||
keys?: AccountKeys = new AccountKeys();
|
keys?: AccountKeys = new AccountKeys();
|
||||||
|
@ -403,7 +384,6 @@ export class Account {
|
||||||
settings?: AccountSettings = new AccountSettings();
|
settings?: AccountSettings = new AccountSettings();
|
||||||
tokens?: AccountTokens = new AccountTokens();
|
tokens?: AccountTokens = new AccountTokens();
|
||||||
decryptionOptions?: AccountDecryptionOptions = new AccountDecryptionOptions();
|
decryptionOptions?: AccountDecryptionOptions = new AccountDecryptionOptions();
|
||||||
loginState?: LoginState = new LoginState();
|
|
||||||
adminAuthRequest?: Jsonify<AdminAuthRequestStorable> = null;
|
adminAuthRequest?: Jsonify<AdminAuthRequestStorable> = null;
|
||||||
|
|
||||||
constructor(init: Partial<Account>) {
|
constructor(init: Partial<Account>) {
|
||||||
|
@ -432,10 +412,6 @@ export class Account {
|
||||||
...new AccountDecryptionOptions(),
|
...new AccountDecryptionOptions(),
|
||||||
...init?.decryptionOptions,
|
...init?.decryptionOptions,
|
||||||
},
|
},
|
||||||
loginState: {
|
|
||||||
...new LoginState(),
|
|
||||||
...init?.loginState,
|
|
||||||
},
|
|
||||||
adminAuthRequest: init?.adminAuthRequest,
|
adminAuthRequest: init?.adminAuthRequest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -452,7 +428,6 @@ export class Account {
|
||||||
settings: AccountSettings.fromJSON(json?.settings),
|
settings: AccountSettings.fromJSON(json?.settings),
|
||||||
tokens: AccountTokens.fromJSON(json?.tokens),
|
tokens: AccountTokens.fromJSON(json?.tokens),
|
||||||
decryptionOptions: AccountDecryptionOptions.fromJSON(json?.decryptionOptions),
|
decryptionOptions: AccountDecryptionOptions.fromJSON(json?.decryptionOptions),
|
||||||
loginState: LoginState.fromJSON(json?.loginState),
|
|
||||||
adminAuthRequest: AdminAuthRequestStorable.fromJSON(json?.adminAuthRequest),
|
adminAuthRequest: AdminAuthRequestStorable.fromJSON(json?.adminAuthRequest),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,6 @@ export class GlobalState {
|
||||||
installedVersion?: string;
|
installedVersion?: string;
|
||||||
locale?: string;
|
locale?: string;
|
||||||
organizationInvitation?: any;
|
organizationInvitation?: any;
|
||||||
ssoCodeVerifier?: string;
|
|
||||||
ssoOrganizationIdentifier?: string;
|
|
||||||
ssoState?: string;
|
|
||||||
rememberedEmail?: string;
|
rememberedEmail?: string;
|
||||||
theme?: ThemeType = ThemeType.System;
|
theme?: ThemeType = ThemeType.System;
|
||||||
window?: WindowState = new WindowState();
|
window?: WindowState = new WindowState();
|
||||||
|
|
|
@ -2446,77 +2446,6 @@ export class StateService<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSsoCodeVerifier(options?: StorageOptions): Promise<string> {
|
|
||||||
return (
|
|
||||||
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
|
||||||
)?.ssoCodeVerifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
async setSsoCodeVerifier(value: string, options?: StorageOptions): Promise<void> {
|
|
||||||
const globals = await this.getGlobals(
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
|
||||||
);
|
|
||||||
globals.ssoCodeVerifier = value;
|
|
||||||
await this.saveGlobals(
|
|
||||||
globals,
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSsoOrgIdentifier(options?: StorageOptions): Promise<string> {
|
|
||||||
return (
|
|
||||||
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()))
|
|
||||||
)?.ssoOrganizationIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
async setSsoOrganizationIdentifier(value: string, options?: StorageOptions): Promise<void> {
|
|
||||||
const globals = await this.getGlobals(
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()),
|
|
||||||
);
|
|
||||||
globals.ssoOrganizationIdentifier = value;
|
|
||||||
await this.saveGlobals(
|
|
||||||
globals,
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSsoState(options?: StorageOptions): Promise<string> {
|
|
||||||
return (
|
|
||||||
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
|
||||||
)?.ssoState;
|
|
||||||
}
|
|
||||||
|
|
||||||
async setSsoState(value: string, options?: StorageOptions): Promise<void> {
|
|
||||||
const globals = await this.getGlobals(
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
|
||||||
);
|
|
||||||
globals.ssoState = value;
|
|
||||||
await this.saveGlobals(
|
|
||||||
globals,
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getUserSsoOrganizationIdentifier(options?: StorageOptions): Promise<string> {
|
|
||||||
return (
|
|
||||||
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
|
||||||
)?.loginState?.ssoOrganizationIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
async setUserSsoOrganizationIdentifier(
|
|
||||||
value: string | null,
|
|
||||||
options?: StorageOptions,
|
|
||||||
): Promise<void> {
|
|
||||||
const account = await this.getAccount(
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
|
||||||
);
|
|
||||||
account.loginState.ssoOrganizationIdentifier = value;
|
|
||||||
await this.saveAccount(
|
|
||||||
account,
|
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTheme(options?: StorageOptions): Promise<ThemeType> {
|
async getTheme(options?: StorageOptions): Promise<ThemeType> {
|
||||||
return (
|
return (
|
||||||
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()))
|
await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()))
|
||||||
|
|
|
@ -23,6 +23,8 @@ export const BILLING_BANNERS_DISK = new StateDefinition("billingBanners", "disk"
|
||||||
|
|
||||||
export const CRYPTO_DISK = new StateDefinition("crypto", "disk");
|
export const CRYPTO_DISK = new StateDefinition("crypto", "disk");
|
||||||
|
|
||||||
|
export const SSO_DISK = new StateDefinition("ssoLogin", "disk");
|
||||||
|
|
||||||
export const ENVIRONMENT_DISK = new StateDefinition("environment", "disk");
|
export const ENVIRONMENT_DISK = new StateDefinition("environment", "disk");
|
||||||
|
|
||||||
export const GENERATOR_DISK = new StateDefinition("generator", "disk");
|
export const GENERATOR_DISK = new StateDefinition("generator", "disk");
|
||||||
|
|
Loading…
Reference in New Issue