1
0
mirror of https://github.com/bitwarden/jslib synced 2025-12-19 09:43:28 +00:00

[feature] Implement account switching capable services across components and processes

* Replace calls to StorageService and deprecated services with calls to a StateService
This commit is contained in:
addison
2021-11-01 14:03:13 -04:00
parent 52d251db6c
commit 54fa024eb4
29 changed files with 273 additions and 328 deletions

View File

@@ -22,10 +22,10 @@ import { FolderService } from 'jslib-common/abstractions/folder.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { OrganizationService } from 'jslib-common/abstractions/organization.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { Cipher } from 'jslib-common/models/domain/cipher';
@@ -87,9 +87,9 @@ export class AddEditComponent implements OnInit {
constructor(protected cipherService: CipherService, protected folderService: FolderService,
protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,
protected auditService: AuditService, protected stateService: StateService,
protected userService: UserService, protected collectionService: CollectionService,
protected messagingService: MessagingService, protected eventService: EventService,
protected policyService: PolicyService, private logService: LogService) {
protected collectionService: CollectionService, protected messagingService: MessagingService,
protected eventService: EventService, protected policyService: PolicyService,
private logService: LogService, private organizationService: OrganizationService) {
this.typeOptions = [
{ name: i18nService.t('typeLogin'), value: CipherType.Login },
{ name: i18nService.t('typeCard'), value: CipherType.Card },
@@ -154,11 +154,11 @@ export class AddEditComponent implements OnInit {
if (await this.policyService.policyAppliesToUser(PolicyType.PersonalOwnership)) {
this.allowPersonal = false;
} else {
const myEmail = await this.userService.getEmail();
const myEmail = await this.stateService.getEmail();
this.ownershipOptions.push({ name: myEmail, value: null });
}
const orgs = await this.userService.getAllOrganizations();
const orgs = await this.organizationService.getAll();
orgs.sort(Utils.getSortFunction(this.i18nService, 'name')).forEach(o => {
if (o.enabled && o.status === OrganizationUserStatusType.Confirmed) {
this.ownershipOptions.push({ name: o.name, value: o.id });
@@ -185,12 +185,12 @@ export class AddEditComponent implements OnInit {
this.title = this.i18nService.t('addItem');
}
const addEditCipherInfo: any = await this.stateService.get<any>('addEditCipherInfo');
const addEditCipherInfo: any = await this.stateService.getAddEditCipherInfo();
if (addEditCipherInfo != null) {
this.cipher = addEditCipherInfo.cipher;
this.collectionIds = addEditCipherInfo.collectionIds;
}
await this.stateService.remove('addEditCipherInfo');
await this.stateService.setAddEditCipherInfo(null);
if (this.cipher == null) {
if (this.editMode) {
@@ -434,7 +434,7 @@ export class AddEditComponent implements OnInit {
}
if (this.cipher.organizationId != null) {
this.collections = this.writeableCollections.filter(c => c.organizationId === this.cipher.organizationId);
const org = await this.userService.getOrganization(this.cipher.organizationId);
const org = await this.organizationService.get(this.cipher.organizationId);
if (org != null) {
this.cipher.organizationUseTotp = org.useTotp;
}

View File

@@ -12,7 +12,7 @@ import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { Cipher } from 'jslib-common/models/domain/cipher';
import { ErrorResponse } from 'jslib-common/models/response/errorResponse';
@@ -37,9 +37,9 @@ export class AttachmentsComponent implements OnInit {
emergencyAccessId?: string = null;
constructor(protected cipherService: CipherService, protected i18nService: I18nService,
protected cryptoService: CryptoService, protected userService: UserService,
protected platformUtilsService: PlatformUtilsService, protected apiService: ApiService,
protected win: Window, private logService: LogService) { }
protected cryptoService: CryptoService, protected platformUtilsService: PlatformUtilsService,
protected apiService: ApiService, protected win: Window,
protected logService: LogService, protected stateService: StateService) { }
async ngOnInit() {
await this.init();
@@ -164,7 +164,7 @@ export class AttachmentsComponent implements OnInit {
this.cipher = await this.cipherDomain.decrypt();
this.hasUpdatedKey = await this.cryptoService.hasEncKey();
const canAccessPremium = await this.userService.canAccessPremium();
const canAccessPremium = await this.stateService.getCanAccessPremium();
this.canAccessAttachments = canAccessPremium || this.cipher.organizationId != null;
if (!this.canAccessAttachments) {

View File

@@ -45,7 +45,7 @@ export class AvatarComponent implements OnChanges, OnInit {
}
private async generate() {
const enableGravatars = await this.stateService.get<boolean>('enableGravatars');
const enableGravatars = await this.stateService.getEnableGravitars();
if (enableGravatars && this.email != null) {
const hashBytes = await this.cryptoFunctionService.hash(this.email.toLowerCase().trim(), 'md5');
const hash = Utils.fromBufferToHex(hashBytes).toLowerCase();

View File

@@ -6,7 +6,7 @@ import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { EncString } from 'jslib-common/models/domain/encString';
import { MasterPasswordPolicyOptions } from 'jslib-common/models/domain/masterPasswordPolicyOptions';
@@ -29,12 +29,12 @@ export class ChangePasswordComponent implements OnInit {
private masterPasswordStrengthTimeout: any;
constructor(protected i18nService: I18nService, protected cryptoService: CryptoService,
protected messagingService: MessagingService, protected userService: UserService,
protected passwordGenerationService: PasswordGenerationService,
protected platformUtilsService: PlatformUtilsService, protected policyService: PolicyService) { }
protected messagingService: MessagingService, protected passwordGenerationService: PasswordGenerationService,
protected platformUtilsService: PlatformUtilsService, protected policyService: PolicyService,
protected stateService: StateService) { }
async ngOnInit() {
this.email = await this.userService.getEmail();
this.email = await this.stateService.getEmail();
this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions();
}
@@ -47,12 +47,12 @@ export class ChangePasswordComponent implements OnInit {
return;
}
const email = await this.userService.getEmail();
const email = await this.stateService.getEmail();
if (this.kdf == null) {
this.kdf = await this.userService.getKdf();
this.kdf = await this.stateService.getKdfType();
}
if (this.kdfIterations == null) {
this.kdfIterations = await this.userService.getKdfIterations();
this.kdfIterations = await this.stateService.getKdfIterations();
}
const key = await this.cryptoService.makeKey(this.masterPassword, email.trim().toLowerCase(),
this.kdf, this.kdfIterations);

View File

@@ -14,10 +14,7 @@ import { TreeNode } from 'jslib-common/models/domain/treeNode';
import { CollectionService } from 'jslib-common/abstractions/collection.service';
import { FolderService } from 'jslib-common/abstractions/folder.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { StateService } from 'jslib-common/abstractions/state.service';
@Directive()
export class GroupingsComponent {
@@ -50,15 +47,12 @@ export class GroupingsComponent {
selectedCollectionId: string = null;
private collapsedGroupings: Set<string>;
private collapsedGroupingsKey: string;
constructor(protected collectionService: CollectionService, protected folderService: FolderService,
protected storageService: StorageService, protected userService: UserService) { }
private stateService: StateService) { }
async load(setLoaded = true) {
const userId = await this.userService.getUserId();
this.collapsedGroupingsKey = ConstantsService.collapsedGroupingsKey + '_' + userId;
const collapsedGroupings = await this.storageService.get<string[]>(this.collapsedGroupingsKey);
const collapsedGroupings = await this.stateService.getCollapsedGroupings();
if (collapsedGroupings == null) {
this.collapsedGroupings = new Set<string>();
} else {
@@ -149,7 +143,7 @@ export class GroupingsComponent {
this.selectedCollectionId = null;
}
collapse(grouping: FolderView | CollectionView, idPrefix = '') {
async collapse(grouping: FolderView | CollectionView, idPrefix = '') {
if (grouping.id == null) {
return;
}
@@ -159,7 +153,7 @@ export class GroupingsComponent {
} else {
this.collapsedGroupings.add(id);
}
this.storageService.save(this.collapsedGroupingsKey, this.collapsedGroupings);
await this.stateService.setCollapsedGroupings(this.collapsedGroupings);
}
isCollapsed(grouping: FolderView | CollectionView, idPrefix = '') {

View File

@@ -11,8 +11,6 @@ import { CipherView } from 'jslib-common/models/view/cipherView';
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { Utils } from 'jslib-common/misc/utils';
const IconMap: any = {
@@ -37,7 +35,7 @@ export class IconComponent implements OnChanges {
private iconsUrl: string;
constructor(environmentService: EnvironmentService, protected stateService: StateService) {
constructor(environmentService: EnvironmentService, private stateService: StateService) {
this.iconsUrl = environmentService.getIconsUrl();
}
@@ -46,7 +44,7 @@ export class IconComponent implements OnChanges {
// to avoid this we reset all state variables.
this.image = null;
this.fallbackImage = null;
this.imageEnabled = !(await this.stateService.get<boolean>(ConstantsService.disableFaviconKey));
this.imageEnabled = !(await this.stateService.getDisableFavicon());
this.load();
}

View File

@@ -9,12 +9,8 @@ import { LogService } from 'jslib-common/abstractions/log.service';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { EncString } from 'jslib-common/models/domain/encString';
import { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';
@@ -23,6 +19,7 @@ import { PasswordVerificationRequest } from 'jslib-common/models/request/passwor
import { Utils } from 'jslib-common/misc/utils';
import { HashPurpose } from 'jslib-common/enums/hashPurpose';
import { KeySuffixOptions } from 'jslib-common/enums/keySuffixOptions';
@Directive()
export class LockComponent implements OnInit {
@@ -45,19 +42,18 @@ export class LockComponent implements OnInit {
constructor(protected router: Router, protected i18nService: I18nService,
protected platformUtilsService: PlatformUtilsService, protected messagingService: MessagingService,
protected userService: UserService, protected cryptoService: CryptoService,
protected storageService: StorageService, protected vaultTimeoutService: VaultTimeoutService,
protected cryptoService: CryptoService, protected vaultTimeoutService: VaultTimeoutService,
protected environmentService: EnvironmentService, protected stateService: StateService,
protected apiService: ApiService, private logService: LogService) { }
async ngOnInit() {
this.pinSet = await this.vaultTimeoutService.isPinLockSet();
this.pinLock = (this.pinSet[0] && this.vaultTimeoutService.pinProtectedKey != null) || this.pinSet[1];
this.pinLock = (this.pinSet[0] && (await this.stateService.getEncryptedPinProtected()) != null) || this.pinSet[1];
this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
this.biometricLock = await this.vaultTimeoutService.isBiometricLockSet() &&
(await this.cryptoService.hasKeyStored('biometric') || !this.platformUtilsService.supportsSecureStorage());
this.biometricText = await this.storageService.get(ConstantsService.biometricText);
this.email = await this.userService.getEmail();
(await this.cryptoService.hasKeyStored(KeySuffixOptions.Biometric) || !this.platformUtilsService.supportsSecureStorage());
this.biometricText = await this.stateService.getBiometricText();
this.email = await this.stateService.getEmail();
const webVaultUrl = this.environmentService.getWebVaultUrl();
const vaultUrl = webVaultUrl === 'https://vault.bitwarden.com' ? 'https://bitwarden.com' : webVaultUrl;
@@ -76,17 +72,17 @@ export class LockComponent implements OnInit {
return;
}
const kdf = await this.userService.getKdf();
const kdfIterations = await this.userService.getKdfIterations();
const kdf = await this.stateService.getKdfType();
const kdfIterations = await this.stateService.getKdfIterations();
if (this.pinLock) {
let failed = true;
try {
if (this.pinSet[0]) {
const key = await this.cryptoService.makeKeyFromPin(this.pin, this.email, kdf, kdfIterations,
this.vaultTimeoutService.pinProtectedKey);
await this.stateService.getDecryptedPinProtected());
const encKey = await this.cryptoService.getEncKey(key);
const protectedPin = await this.storageService.get<string>(ConstantsService.protectedPin);
const protectedPin = await this.stateService.getProtectedPin();
const decPin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), encKey);
failed = decPin !== this.pin;
if (!failed) {
@@ -137,11 +133,11 @@ export class LockComponent implements OnInit {
if (passwordValid) {
if (this.pinSet[0]) {
const protectedPin = await this.storageService.get<string>(ConstantsService.protectedPin);
const protectedPin = await this.stateService.getProtectedPin();
const encKey = await this.cryptoService.getEncKey(key);
const decPin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), encKey);
const pinKey = await this.cryptoService.makePinKey(decPin, this.email, kdf, kdfIterations);
this.vaultTimeoutService.pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey);
await this.stateService.setDecryptedPinProtected(await this.cryptoService.encrypt(key.key, pinKey));
}
this.setKeyAndContinue(key);
} else {
@@ -164,7 +160,7 @@ export class LockComponent implements OnInit {
return;
}
const success = (await this.cryptoService.getKey('biometric')) != null;
const success = (await this.cryptoService.getKey(KeySuffixOptions.Biometric)) != null;
if (success) {
await this.doContinue();
@@ -184,10 +180,10 @@ export class LockComponent implements OnInit {
}
private async doContinue() {
this.vaultTimeoutService.biometricLocked = false;
this.vaultTimeoutService.everBeenUnlocked = true;
const disableFavicon = await this.storageService.get<boolean>(ConstantsService.disableFaviconKey);
await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);
await this.stateService.setBiometricLocked(false);
await this.stateService.setEverBeenUnlocked(true);
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
this.messagingService.send('unlocked');
if (this.onSuccessfulSubmit != null) {
this.onSuccessfulSubmit();

View File

@@ -16,19 +16,11 @@ import { LogService } from 'jslib-common/abstractions/log.service';
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { Utils } from 'jslib-common/misc/utils';
import { CaptchaProtectedComponent } from './captchaProtected.component';
const Keys = {
rememberedEmail: 'rememberedEmail',
rememberEmail: 'rememberEmail',
};
@Directive()
export class LoginComponent extends CaptchaProtectedComponent implements OnInit {
@Input() email: string = '';
@@ -50,19 +42,18 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
platformUtilsService: PlatformUtilsService, i18nService: I18nService,
protected stateService: StateService, environmentService: EnvironmentService,
protected passwordGenerationService: PasswordGenerationService,
protected cryptoFunctionService: CryptoFunctionService, private storageService: StorageService,
protected logService: LogService) {
protected cryptoFunctionService: CryptoFunctionService, protected logService: LogService) {
super(environmentService, i18nService, platformUtilsService);
}
async ngOnInit() {
if (this.email == null || this.email === '') {
this.email = await this.storageService.get<string>(Keys.rememberedEmail);
this.email = await this.stateService.getRememberedEmail();
if (this.email == null) {
this.email = '';
}
}
this.rememberEmail = await this.storageService.get<boolean>(Keys.rememberEmail);
this.rememberEmail = await this.stateService.getRememberEmail();
if (this.rememberEmail == null) {
this.rememberEmail = true;
}
@@ -93,11 +84,10 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
try {
this.formPromise = this.authService.logIn(this.email, this.masterPassword, this.captchaToken);
const response = await this.formPromise;
await this.storageService.save(Keys.rememberEmail, this.rememberEmail);
if (this.rememberEmail) {
await this.storageService.save(Keys.rememberedEmail, this.email);
await this.stateService.setRememberedEmail(this.email);
} else {
await this.storageService.remove(Keys.rememberedEmail);
await this.stateService.setRememberedEmail(null);
}
if (this.handleCaptchaRequired(response)) {
return;
@@ -114,8 +104,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
this.router.navigate([this.forcePasswordResetRoute]);
}
} else {
const disableFavicon = await this.storageService.get<boolean>(ConstantsService.disableFaviconKey);
await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
if (this.onSuccessfulLogin != null) {
this.onSuccessfulLogin();
}
@@ -151,8 +141,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
// Save sso params
await this.storageService.save(ConstantsService.ssoStateKey, state);
await this.storageService.save(ConstantsService.ssoCodeVerifierKey, ssoCodeVerifier);
await this.stateService.setSsoState(state);
await this.stateService.setSsoCodeVerifier(ssoCodeVerifier);
// Build URI
const webUrl = this.environmentService.getWebVaultUrl();

View File

@@ -4,7 +4,7 @@ import { ApiService } from 'jslib-common/abstractions/api.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
@Directive()
export class PremiumComponent implements OnInit {
@@ -13,10 +13,11 @@ export class PremiumComponent implements OnInit {
refreshPromise: Promise<any>;
constructor(protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,
protected apiService: ApiService, protected userService: UserService, private logService: LogService) { }
protected apiService: ApiService, private logService: LogService,
protected stateService: StateService) { }
async ngOnInit() {
this.isPremium = await this.userService.canAccessPremium();
this.isPremium = await this.stateService.getCanAccessPremium();
}
async refresh() {
@@ -24,7 +25,7 @@ export class PremiumComponent implements OnInit {
this.refreshPromise = this.apiService.refreshIdentityToken();
await this.refreshPromise;
this.platformUtilsService.showToast('success', null, this.i18nService.t('refreshComplete'));
this.isPremium = await this.userService.canAccessPremium();
this.isPremium = await this.stateService.getCanAccessPremium();
} catch (e) {
this.logService.error(e);
}

View File

@@ -141,7 +141,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
const request = new RegisterRequest(this.email, this.name, hashedPassword,
this.hint, encKey[1].encryptedString, kdf, kdfIterations, this.referenceData, this.captchaToken);
request.keys = new KeysRequest(keys[0], keys[1].encryptedString);
const orgInvite = await this.stateService.get<any>('orgInvitation');
const orgInvite = await this.stateService.getOrganizationInvitation();
if (orgInvite != null && orgInvite.token != null && orgInvite.organizationUserId != null) {
request.token = orgInvite.token;
request.organizationUserId = orgInvite.organizationUserId;

View File

@@ -17,7 +17,7 @@ import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { SendService } from 'jslib-common/abstractions/send.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { SendFileView } from 'jslib-common/models/view/sendFileView';
import { SendTextView } from 'jslib-common/models/view/sendTextView';
@@ -57,9 +57,9 @@ export class AddEditComponent implements OnInit {
constructor(protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService,
protected environmentService: EnvironmentService, protected datePipe: DatePipe,
protected sendService: SendService, protected userService: UserService,
protected messagingService: MessagingService, protected policyService: PolicyService,
private logService: LogService) {
protected sendService: SendService, protected messagingService: MessagingService,
protected policyService: PolicyService, private logService: LogService,
protected stateService: StateService) {
this.typeOptions = [
{ name: i18nService.t('sendTypeFile'), value: SendType.File },
{ name: i18nService.t('sendTypeText'), value: SendType.Text },
@@ -108,8 +108,8 @@ export class AddEditComponent implements OnInit {
this.disableHideEmail = await this.policyService.policyAppliesToUser(PolicyType.SendOptions,
p => p.data.disableHideEmail);
this.canAccessPremium = await this.userService.canAccessPremium();
this.emailVerified = await this.userService.getEmailVerified();
this.canAccessPremium = await this.stateService.getCanAccessPremium();
this.emailVerified = await this.stateService.getEmailVerified();
if (!this.canAccessPremium || !this.emailVerified) {
this.type = SendType.Text;
}

View File

@@ -16,7 +16,6 @@ import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.se
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { SearchService } from 'jslib-common/abstractions/search.service';
import { SendService } from 'jslib-common/abstractions/send.service';
import { UserService } from 'jslib-common/abstractions/user.service';
@Directive()
export class SendComponent implements OnInit {
@@ -48,8 +47,7 @@ export class SendComponent implements OnInit {
constructor(protected sendService: SendService, protected i18nService: I18nService,
protected platformUtilsService: PlatformUtilsService, protected environmentService: EnvironmentService,
protected ngZone: NgZone, protected searchService: SearchService,
protected policyService: PolicyService, protected userService: UserService,
private logService: LogService) { }
protected policyService: PolicyService, private logService: LogService) { }
async ngOnInit() {
this.disableSend = await this.policyService.policyAppliesToUser(PolicyType.DisableSend);

View File

@@ -13,8 +13,8 @@ import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { SyncService } from 'jslib-common/abstractions/sync.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { EncString } from 'jslib-common/models/domain/encString';
import { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';
@@ -42,12 +42,13 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
onSuccessfulChangePassword: () => Promise<any>;
successRoute = 'vault';
constructor(i18nService: I18nService, cryptoService: CryptoService, messagingService: MessagingService,
userService: UserService, passwordGenerationService: PasswordGenerationService,
platformUtilsService: PlatformUtilsService, policyService: PolicyService, protected router: Router,
private apiService: ApiService, private syncService: SyncService, private route: ActivatedRoute) {
super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,
platformUtilsService, policyService);
constructor(i18nService: I18nService, cryptoService: CryptoService,
messagingService: MessagingService, passwordGenerationService: PasswordGenerationService,
platformUtilsService: PlatformUtilsService, policyService: PolicyService,
protected router: Router, private apiService: ApiService,
private syncService: SyncService, private route: ActivatedRoute, stateService: StateService) {
super(i18nService, cryptoService, messagingService, passwordGenerationService,
platformUtilsService, policyService, stateService);
}
async ngOnInit() {
@@ -102,7 +103,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
if (response == null) {
throw new Error(this.i18nService.t('resetPasswordOrgKeysError'));
}
const userId = await this.userService.getUserId();
const userId = await this.stateService.getUserId();
const publicKey = Utils.fromB64ToArray(response.publicKey);
// RSA Encrypt user's encKey.key with organization public key
@@ -138,8 +139,8 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
}
private async onSetPasswordSuccess(key: SymmetricCryptoKey, encKey: [SymmetricCryptoKey, EncString], keys: [string, EncString]) {
await this.userService.setInformation(await this.userService.getUserId(), await this.userService.getEmail(),
this.kdf, this.kdfIterations);
await this.stateService.setKdfType(this.kdf);
await this.stateService.setKdfIterations(this.kdfIterations);
await this.cryptoService.setKey(key);
await this.cryptoService.setEncKey(encKey[1].encryptedString);
await this.cryptoService.setEncPrivateKey(keys[1].encryptedString);

View File

@@ -1,11 +1,7 @@
import { Directive } from '@angular/core';
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { Utils } from 'jslib-common/misc/utils';
@@ -18,8 +14,8 @@ export class SetPinComponent {
showPin = false;
masterPassOnRestart = true;
constructor(private modalRef: ModalRef, private cryptoService: CryptoService, private userService: UserService,
private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService) { }
constructor(private modalRef: ModalRef, private cryptoService: CryptoService,
private stateService: StateService) { }
toggleVisibility() {
this.showPin = !this.showPin;
@@ -30,18 +26,18 @@ export class SetPinComponent {
this.modalRef.close(false);
}
const kdf = await this.userService.getKdf();
const kdfIterations = await this.userService.getKdfIterations();
const email = await this.userService.getEmail();
const kdf = await this.stateService.getKdfType();
const kdfIterations = await this.stateService.getKdfIterations();
const email = await this.stateService.getEmail();
const pinKey = await this.cryptoService.makePinKey(this.pin, email, kdf, kdfIterations);
const key = await this.cryptoService.getKey();
const pinProtectedKey = await this.cryptoService.encrypt(key.key, pinKey);
if (this.masterPassOnRestart) {
const encPin = await this.cryptoService.encrypt(this.pin);
await this.storageService.save(ConstantsService.protectedPin, encPin.encryptedString);
this.vaultTimeoutService.pinProtectedKey = pinProtectedKey;
await this.stateService.setProtectedPin(encPin.encryptedString);
await this.stateService.setDecryptedPinProtected(pinProtectedKey);
} else {
await this.storageService.save(ConstantsService.pinProtectedKey, pinProtectedKey.encryptedString);
await this.stateService.setEncryptedPinProtected(pinProtectedKey.encryptedString);
}
this.modalRef.close(true);

View File

@@ -12,8 +12,8 @@ import { CipherService } from 'jslib-common/abstractions/cipher.service';
import { CollectionService } from 'jslib-common/abstractions/collection.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { OrganizationService } from 'jslib-common/abstractions/organization.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { Organization } from 'jslib-common/models/domain/organization';
import { CipherView } from 'jslib-common/models/view/cipherView';
@@ -35,8 +35,8 @@ export class ShareComponent implements OnInit {
protected writeableCollections: CollectionView[] = [];
constructor(protected collectionService: CollectionService, protected platformUtilsService: PlatformUtilsService,
protected i18nService: I18nService, protected userService: UserService,
protected cipherService: CipherService, private logService: LogService) { }
protected i18nService: I18nService, protected cipherService: CipherService,
private logService: LogService, protected organizationService: OrganizationService) { }
async ngOnInit() {
await this.load();
@@ -45,7 +45,7 @@ export class ShareComponent implements OnInit {
async load() {
const allCollections = await this.collectionService.getAllDecrypted();
this.writeableCollections = allCollections.map(c => c).filter(c => !c.readOnly);
const orgs = await this.userService.getAllOrganizations();
const orgs = await this.organizationService.getAll();
this.organizations = orgs.sort(Utils.getSortFunction(this.i18nService, 'name'))
.filter(o => o.enabled && o.status === OrganizationUserStatusType.Confirmed);

View File

@@ -15,9 +15,6 @@ import { LogService } from 'jslib-common/abstractions/log.service';
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { Utils } from 'jslib-common/misc/utils';
@@ -47,18 +44,18 @@ export class SsoComponent {
constructor(protected authService: AuthService, protected router: Router,
protected i18nService: I18nService, protected route: ActivatedRoute,
protected storageService: StorageService, protected stateService: StateService,
protected platformUtilsService: PlatformUtilsService, protected apiService: ApiService,
protected cryptoFunctionService: CryptoFunctionService, protected environmentService: EnvironmentService,
protected passwordGenerationService: PasswordGenerationService, protected logService: LogService) { }
protected stateService: StateService, protected platformUtilsService: PlatformUtilsService,
protected apiService: ApiService, protected cryptoFunctionService: CryptoFunctionService,
protected environmentService: EnvironmentService, protected passwordGenerationService: PasswordGenerationService,
protected logService: LogService) { }
async ngOnInit() {
this.route.queryParams.pipe(first()).subscribe(async qParams => {
if (qParams.code != null && qParams.state != null) {
const codeVerifier = await this.storageService.get<string>(ConstantsService.ssoCodeVerifierKey);
const state = await this.storageService.get<string>(ConstantsService.ssoStateKey);
await this.storageService.remove(ConstantsService.ssoCodeVerifierKey);
await this.storageService.remove(ConstantsService.ssoStateKey);
const codeVerifier = await this.stateService.getSsoCodeVerifier();
const state = await this.stateService.getSsoState();
await this.stateService.setSsoCodeVerifier(null);
await this.stateService.setSsoState(null);
if (qParams.code != null && codeVerifier != null && state != null && this.checkState(state, qParams.state)) {
await this.logIn(qParams.code, codeVerifier, this.getOrgIdentiferFromState(qParams.state));
}
@@ -106,7 +103,7 @@ export class SsoComponent {
const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, 'sha256');
codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
await this.storageService.save(ConstantsService.ssoCodeVerifierKey, codeVerifier);
await this.stateService.setSsoCodeVerifier(codeVerifier);
}
if (state == null) {
@@ -120,7 +117,7 @@ export class SsoComponent {
state += `_identifier=${this.identifier}`;
// Save state (regardless of new or existing)
await this.storageService.save(ConstantsService.ssoStateKey, state);
await this.stateService.setSsoState(state);
let authorizeUrl = this.environmentService.getIdentityUrl() + '/connect/authorize?' +
'client_id=' + this.clientId + '&redirect_uri=' + encodeURIComponent(this.redirectUri) + '&' +
@@ -170,8 +167,8 @@ export class SsoComponent {
this.router.navigate([this.forcePasswordResetRoute]);
}
} else {
const disableFavicon = await this.storageService.get<boolean>(ConstantsService.disableFaviconKey);
await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
if (this.onSuccessfulLogin != null) {
this.onSuccessfulLogin();
}

View File

@@ -20,10 +20,8 @@ import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { StorageService } from 'jslib-common/abstractions/storage.service';
import { TwoFactorProviders } from 'jslib-common/services/auth.service';
import { ConstantsService } from 'jslib-common/services/constants.service';
import * as DuoWebSDK from 'duo_web_sdk';
import { WebAuthnIFrame } from 'jslib-common/misc/webauthn_iframe';
@@ -58,8 +56,7 @@ export class TwoFactorComponent implements OnInit, OnDestroy {
protected i18nService: I18nService, protected apiService: ApiService,
protected platformUtilsService: PlatformUtilsService, protected win: Window,
protected environmentService: EnvironmentService, protected stateService: StateService,
protected storageService: StorageService, protected route: ActivatedRoute,
protected logService: LogService) {
protected route: ActivatedRoute, protected logService: LogService) {
this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win);
}
@@ -179,8 +176,8 @@ export class TwoFactorComponent implements OnInit, OnDestroy {
async doSubmit() {
this.formPromise = this.authService.logInTwoFactor(this.selectedProviderType, this.token, this.remember);
const response: AuthResult = await this.formPromise;
const disableFavicon = await this.storageService.get<boolean>(ConstantsService.disableFaviconKey);
await this.stateService.save(ConstantsService.disableFaviconKey, !!disableFavicon);
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
if (this.onSuccessfulLogin != null) {
this.onSuccessfulLogin();
}

View File

@@ -8,8 +8,8 @@ import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { SyncService } from 'jslib-common/abstractions/sync.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { ChangePasswordComponent as BaseChangePasswordComponent } from './change-password.component';
@@ -30,11 +30,11 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,
passwordGenerationService: PasswordGenerationService, policyService: PolicyService,
cryptoService: CryptoService, userService: UserService,
messagingService: MessagingService, private apiService: ApiService,
cryptoService: CryptoService, messagingService: MessagingService,
private apiService: ApiService, stateService: StateService,
private syncService: SyncService, private logService: LogService) {
super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,
platformUtilsService, policyService);
super(i18nService, cryptoService, messagingService, passwordGenerationService,
platformUtilsService, policyService, stateService);
}
async ngOnInit() {
@@ -49,9 +49,9 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
async setupSubmitActions(): Promise<boolean> {
this.enforcedPolicyOptions = await this.policyService.getMasterPasswordPolicyOptions();
this.email = await this.userService.getEmail();
this.kdf = await this.userService.getKdf();
this.kdfIterations = await this.userService.getKdfIterations();
this.email = await this.stateService.getEmail();
this.kdf = await this.stateService.getKdfType();
this.kdfIterations = await this.stateService.getKdfIterations();
return true;
}

View File

@@ -24,9 +24,9 @@ import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { TokenService } from 'jslib-common/abstractions/token.service';
import { TotpService } from 'jslib-common/abstractions/totp.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { ErrorResponse } from 'jslib-common/models/response/errorResponse';
@@ -67,9 +67,9 @@ export class ViewComponent implements OnDestroy, OnInit {
protected cryptoService: CryptoService, protected platformUtilsService: PlatformUtilsService,
protected auditService: AuditService, protected win: Window,
protected broadcasterService: BroadcasterService, protected ngZone: NgZone,
protected changeDetectorRef: ChangeDetectorRef, protected userService: UserService,
protected eventService: EventService, protected apiService: ApiService,
protected passwordRepromptService: PasswordRepromptService, private logService: LogService) { }
protected changeDetectorRef: ChangeDetectorRef, protected eventService: EventService,
protected apiService: ApiService, protected passwordRepromptService: PasswordRepromptService,
private logService: LogService, protected stateService: StateService) { }
ngOnInit() {
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
@@ -96,7 +96,7 @@ export class ViewComponent implements OnDestroy, OnInit {
const cipher = await this.cipherService.get(this.cipherId);
this.cipher = await cipher.decrypt();
this.canAccessPremium = await this.userService.canAccessPremium();
this.canAccessPremium = await this.stateService.getCanAccessPremium();
if (this.cipher.type === CipherType.Login && this.cipher.login.totp &&
(cipher.organizationUseTotp || this.canAccessPremium)) {

View File

@@ -7,16 +7,16 @@ import {
} from '@angular/router';
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
@Injectable()
export class AuthGuardService implements CanActivate {
constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService,
private router: Router, private messagingService: MessagingService) { }
constructor(private vaultTimeoutService: VaultTimeoutService, private router: Router,
private messagingService: MessagingService, private stateService: StateService) { }
async canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) {
const isAuthed = await this.userService.isAuthenticated();
const isAuthed = this.stateService.getIsAuthenticated();
if (!isAuthed) {
this.messagingService.send('authBlocked');
return false;

View File

@@ -4,29 +4,25 @@ import {
Router,
} from '@angular/router';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
@Injectable()
export class LockGuardService implements CanActivate {
protected homepage = 'vault';
constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService,
private router: Router) { }
constructor(private vaultTimeoutService: VaultTimeoutService, private router: Router,
private stateService: StateService) { }
async canActivate() {
const isAuthed = await this.userService.isAuthenticated();
if (isAuthed) {
const locked = await this.vaultTimeoutService.isLocked();
if (locked) {
return true;
} else {
this.router.navigate([this.homepage]);
return false;
}
if (!await this.stateService.getIsAuthenticated()) {
this.router.navigate(['login']);
return false;
}
this.router.navigate(['']);
return false;
if (!await this.vaultTimeoutService.isLocked()) {
this.router.navigate(['vault']);
return false;
}
return true;
}
}

View File

@@ -1,22 +1,21 @@
import { Injectable } from '@angular/core';
import {
ActivatedRouteSnapshot,
CanActivate,
Router,
} from '@angular/router';
import { UserService } from 'jslib-common/abstractions/user.service';
import { StateService } from 'jslib-common/abstractions/state.service';
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
@Injectable()
export class UnauthGuardService implements CanActivate {
protected homepage = 'vault';
constructor(private vaultTimeoutService: VaultTimeoutService, private userService: UserService,
private router: Router) { }
constructor(private vaultTimeoutService: VaultTimeoutService, private router: Router,
private stateService: StateService) { }
async canActivate() {
const isAuthed = await this.userService.isAuthenticated();
const isAuthed = await this.stateService.getIsAuthenticated();
if (isAuthed) {
const locked = await this.vaultTimeoutService.isLocked();
if (locked) {
@@ -26,7 +25,5 @@ export class UnauthGuardService implements CanActivate {
}
return false;
}
return true;
}
}