mirror of
https://github.com/bitwarden/jslib
synced 2025-12-30 07:03:21 +00:00
Merge branch 'master' of https://github.com/bitwarden/jslib into improve-hostname-and-domain-retrieval
This commit is contained in:
@@ -118,7 +118,7 @@ export class AddEditCustomFieldsComponent implements OnChanges {
|
||||
}
|
||||
|
||||
this.cipher.fields
|
||||
.filter(f => f.type = FieldType.Linked)
|
||||
.filter(f => f.type === FieldType.Linked)
|
||||
.forEach(f => f.linkedId = this.linkedFieldOptions[0].value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +154,9 @@ export class AddEditComponent implements OnInit {
|
||||
}
|
||||
|
||||
async init() {
|
||||
if (this.ownershipOptions.length) {
|
||||
this.ownershipOptions = [];
|
||||
}
|
||||
if (await this.policyService.policyAppliesToUser(PolicyType.PersonalOwnership)) {
|
||||
this.allowPersonal = false;
|
||||
} else {
|
||||
|
||||
@@ -69,7 +69,10 @@ export class ExportComponent implements OnInit {
|
||||
}
|
||||
|
||||
const secret = this.exportForm.get('secret').value;
|
||||
if (!await this.userVerificationService.verifyUser(secret)) {
|
||||
try {
|
||||
await this.userVerificationService.verifyUser(secret);
|
||||
} catch (e) {
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Directive, OnInit } from '@angular/core';
|
||||
import { Directive, NgZone, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
@@ -37,6 +38,7 @@ export class LockComponent implements OnInit {
|
||||
supportsBiometric: boolean;
|
||||
biometricLock: boolean;
|
||||
biometricText: string;
|
||||
hideInput: boolean;
|
||||
|
||||
protected successRoute: string = 'vault';
|
||||
protected onSuccessfulSubmit: () => void;
|
||||
@@ -50,7 +52,7 @@ export class LockComponent implements OnInit {
|
||||
protected storageService: StorageService, protected vaultTimeoutService: VaultTimeoutService,
|
||||
protected environmentService: EnvironmentService, protected stateService: StateService,
|
||||
protected apiService: ApiService, private logService: LogService,
|
||||
private keyConnectorService: KeyConnectorService) { }
|
||||
private keyConnectorService: KeyConnectorService, protected ngZone: NgZone) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.pinSet = await this.vaultTimeoutService.isPinLockSet();
|
||||
@@ -60,9 +62,11 @@ export class LockComponent implements OnInit {
|
||||
(await this.cryptoService.hasKeyStored('biometric') || !this.platformUtilsService.supportsSecureStorage());
|
||||
this.biometricText = await this.storageService.get(ConstantsService.biometricText);
|
||||
this.email = await this.userService.getEmail();
|
||||
const usesKeyConnector = await this.keyConnectorService.getUsesKeyConnector();
|
||||
this.hideInput = usesKeyConnector && !this.pinLock;
|
||||
|
||||
// Users with key connector and without biometric or pin has no MP to unlock using
|
||||
if (await this.keyConnectorService.getUsesKeyConnector() && !(this.biometricLock || this.pinLock)) {
|
||||
if (usesKeyConnector && !(this.biometricLock || this.pinLock)) {
|
||||
await this.vaultTimeoutService.logOut();
|
||||
}
|
||||
|
||||
@@ -182,7 +186,12 @@ export class LockComponent implements OnInit {
|
||||
|
||||
togglePassword() {
|
||||
this.showPassword = !this.showPassword;
|
||||
document.getElementById(this.pinLock ? 'pin' : 'masterPassword').focus();
|
||||
const input = document.getElementById(this.pinLock ? 'pin' : 'masterPassword');
|
||||
if (this.ngZone.isStable) {
|
||||
input.focus();
|
||||
} else {
|
||||
this.ngZone.onStable.pipe(take(1)).subscribe(() => input.focus());
|
||||
}
|
||||
}
|
||||
|
||||
private async setKeyAndContinue(key: SymmetricCryptoKey) {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import {
|
||||
Directive,
|
||||
Input,
|
||||
NgZone,
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { AuthResult } from 'jslib-common/models/domain/authResult';
|
||||
|
||||
import { AuthService } from 'jslib-common/abstractions/auth.service';
|
||||
@@ -51,7 +54,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
|
||||
protected stateService: StateService, environmentService: EnvironmentService,
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
protected cryptoFunctionService: CryptoFunctionService, private storageService: StorageService,
|
||||
protected logService: LogService) {
|
||||
protected logService: LogService, protected ngZone: NgZone) {
|
||||
super(environmentService, i18nService, platformUtilsService);
|
||||
}
|
||||
|
||||
@@ -132,7 +135,11 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
|
||||
|
||||
togglePassword() {
|
||||
this.showPassword = !this.showPassword;
|
||||
document.getElementById('masterPassword').focus();
|
||||
if (this.ngZone.isStable) {
|
||||
document.getElementById('masterPassword').focus();
|
||||
} else {
|
||||
this.ngZone.onStable.pipe(take(1)).subscribe(() => document.getElementById('masterPassword').focus());
|
||||
}
|
||||
}
|
||||
|
||||
async launchSsoBrowser(clientId: string, ssoRedirectUri: string) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Directive } from '@angular/core';
|
||||
import {
|
||||
Directive,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.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';
|
||||
@@ -12,14 +16,20 @@ import { Utils } from 'jslib-common/misc/utils';
|
||||
import { ModalRef } from './modal/modal.ref';
|
||||
|
||||
@Directive()
|
||||
export class SetPinComponent {
|
||||
export class SetPinComponent implements OnInit {
|
||||
|
||||
pin = '';
|
||||
showPin = false;
|
||||
masterPassOnRestart = true;
|
||||
showMasterPassOnRestart = true;
|
||||
|
||||
constructor(private modalRef: ModalRef, private cryptoService: CryptoService, private userService: UserService,
|
||||
private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService) { }
|
||||
private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService,
|
||||
private keyConnectorService: KeyConnectorService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.showMasterPassOnRestart = this.masterPassOnRestart = !await this.keyConnectorService.getUsesKeyConnector();
|
||||
}
|
||||
|
||||
toggleVisibility() {
|
||||
this.showPin = !this.showPin;
|
||||
|
||||
@@ -2,17 +2,24 @@
|
||||
<label for="masterPassword">{{'masterPass' | i18n}}</label>
|
||||
<input id="masterPassword" type="password" name="MasterPasswordHash" class="form-control"
|
||||
[formControl]="secret" required appAutofocus appInputVerbatim>
|
||||
<small class="form-text text-muted">{{'confirmIdentity' | i18n}}</small>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="usesKeyConnector">
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn btn-primary" (click)="requestOTP()" [disabled]="disableRequestOTP">
|
||||
{{'requestVerificationCode' | i18n}}
|
||||
<label class="d-block">{{'sendVerificationCode' | i18n}}</label>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="requestOTP()" [disabled]="disableRequestOTP">
|
||||
{{'sendCode' | i18n}}
|
||||
</button>
|
||||
<span class="ml-2 text-success" role="alert" @sent *ngIf="sentCode">
|
||||
<i class="fa fa-check-circle-o" aria-hidden="true"></i>
|
||||
{{'codeSent' | i18n}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="verificationCode">{{'verificationCode' | i18n}}</label>
|
||||
<input id="verificationCode" type="input" name="verificationCode" class="form-control"
|
||||
[formControl]="secret" required appAutofocus appInputVerbatim>
|
||||
<small class="form-text text-muted">{{'confirmIdentity' | i18n}}</small>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import {
|
||||
animate,
|
||||
style,
|
||||
transition,
|
||||
trigger,
|
||||
} from '@angular/animations';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
@@ -8,8 +14,8 @@ import {
|
||||
NG_VALUE_ACCESSOR,
|
||||
} from '@angular/forms';
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
|
||||
import { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';
|
||||
|
||||
import { VerificationType } from 'jslib-common/enums/verificationType';
|
||||
|
||||
@@ -25,36 +31,43 @@ import { Verification } from 'jslib-common/types/verification';
|
||||
useExisting: VerifyMasterPasswordComponent,
|
||||
},
|
||||
],
|
||||
animations: [
|
||||
trigger('sent', [
|
||||
transition(':enter', [
|
||||
style({ opacity: 0 }),
|
||||
animate('100ms', style({ opacity: 1 })),
|
||||
]),
|
||||
]),
|
||||
],
|
||||
})
|
||||
export class VerifyMasterPasswordComponent implements ControlValueAccessor, OnInit {
|
||||
usesKeyConnector: boolean = false;
|
||||
disableRequestOTP: boolean = false;
|
||||
sentCode: boolean = false;
|
||||
|
||||
secret = new FormControl('');
|
||||
|
||||
private onChange: (value: Verification) => void;
|
||||
|
||||
constructor(private keyConnectorService: KeyConnectorService, private apiService: ApiService) { }
|
||||
constructor(private keyConnectorService: KeyConnectorService,
|
||||
private userVerificationService: UserVerificationService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.usesKeyConnector = await this.keyConnectorService.getUsesKeyConnector();
|
||||
this.processChanges(this.secret.value);
|
||||
|
||||
this.secret.valueChanges.subscribe(secret => {
|
||||
if (this.onChange == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onChange({
|
||||
type: this.usesKeyConnector ? VerificationType.OTP : VerificationType.MasterPassword,
|
||||
secret: secret,
|
||||
});
|
||||
});
|
||||
this.secret.valueChanges.subscribe(secret => this.processChanges(secret));
|
||||
}
|
||||
|
||||
async requestOTP() {
|
||||
if (this.usesKeyConnector) {
|
||||
this.disableRequestOTP = true;
|
||||
await this.apiService.postAccountRequestOTP();
|
||||
try {
|
||||
await this.userVerificationService.requestOTP();
|
||||
this.sentCode = true;
|
||||
} finally {
|
||||
this.disableRequestOTP = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,4 +91,15 @@ export class VerifyMasterPasswordComponent implements ControlValueAccessor, OnIn
|
||||
this.secret.enable();
|
||||
}
|
||||
}
|
||||
|
||||
private processChanges(secret: string) {
|
||||
if (this.onChange == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onChange({
|
||||
type: this.usesKeyConnector ? VerificationType.OTP : VerificationType.MasterPassword,
|
||||
secret: secret,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
395
angular/src/services/jslib-services.module.ts
Normal file
395
angular/src/services/jslib-services.module.ts
Normal file
@@ -0,0 +1,395 @@
|
||||
import {
|
||||
Injector,
|
||||
LOCALE_ID,
|
||||
NgModule,
|
||||
} from '@angular/core';
|
||||
import { ToasterModule } from 'angular2-toaster';
|
||||
|
||||
import { ApiService } from 'jslib-common/services/api.service';
|
||||
import { AppIdService } from 'jslib-common/services/appId.service';
|
||||
import { AuditService } from 'jslib-common/services/audit.service';
|
||||
import { AuthService } from 'jslib-common/services/auth.service';
|
||||
import { CipherService } from 'jslib-common/services/cipher.service';
|
||||
import { CollectionService } from 'jslib-common/services/collection.service';
|
||||
import { ConsoleLogService } from 'jslib-common/services/consoleLog.service';
|
||||
import { CryptoService } from 'jslib-common/services/crypto.service';
|
||||
import { EnvironmentService } from 'jslib-common/services/environment.service';
|
||||
import { EventService } from 'jslib-common/services/event.service';
|
||||
import { ExportService } from 'jslib-common/services/export.service';
|
||||
import { FileUploadService } from 'jslib-common/services/fileUpload.service';
|
||||
import { FolderService } from 'jslib-common/services/folder.service';
|
||||
import { KeyConnectorService } from 'jslib-common/services/keyConnector.service';
|
||||
import { NotificationsService } from 'jslib-common/services/notifications.service';
|
||||
import { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.service';
|
||||
import { PolicyService } from 'jslib-common/services/policy.service';
|
||||
import { SearchService } from 'jslib-common/services/search.service';
|
||||
import { SendService } from 'jslib-common/services/send.service';
|
||||
import { SettingsService } from 'jslib-common/services/settings.service';
|
||||
import { StateService } from 'jslib-common/services/state.service';
|
||||
import { SyncService } from 'jslib-common/services/sync.service';
|
||||
import { TokenService } from 'jslib-common/services/token.service';
|
||||
import { TotpService } from 'jslib-common/services/totp.service';
|
||||
import { UserService } from 'jslib-common/services/user.service';
|
||||
import { UserVerificationService } from 'jslib-common/services/userVerification.service';
|
||||
import { VaultTimeoutService } from 'jslib-common/services/vaultTimeout.service';
|
||||
import { WebCryptoFunctionService } from 'jslib-common/services/webCryptoFunction.service';
|
||||
|
||||
import { ApiService as ApiServiceAbstraction } from 'jslib-common/abstractions/api.service';
|
||||
import { AppIdService as AppIdServiceAbstraction } from 'jslib-common/abstractions/appId.service';
|
||||
import { AuditService as AuditServiceAbstraction } from 'jslib-common/abstractions/audit.service';
|
||||
import { AuthService as AuthServiceAbstraction } from 'jslib-common/abstractions/auth.service';
|
||||
import { BroadcasterService as BroadcasterServiceAbstraction } from 'jslib-common/abstractions/broadcaster.service';
|
||||
import { CipherService as CipherServiceAbstraction } from 'jslib-common/abstractions/cipher.service';
|
||||
import { CollectionService as CollectionServiceAbstraction } from 'jslib-common/abstractions/collection.service';
|
||||
import { CryptoService as CryptoServiceAbstraction } from 'jslib-common/abstractions/crypto.service';
|
||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from 'jslib-common/abstractions/cryptoFunction.service';
|
||||
import { EnvironmentService as EnvironmentServiceAbstraction, Urls } from 'jslib-common/abstractions/environment.service';
|
||||
import { EventService as EventServiceAbstraction } from 'jslib-common/abstractions/event.service';
|
||||
import { ExportService as ExportServiceAbstraction } from 'jslib-common/abstractions/export.service';
|
||||
import { FileUploadService as FileUploadServiceAbstraction } from 'jslib-common/abstractions/fileUpload.service';
|
||||
import { FolderService as FolderServiceAbstraction } from 'jslib-common/abstractions/folder.service';
|
||||
import { I18nService as I18nServiceAbstraction } from 'jslib-common/abstractions/i18n.service';
|
||||
import { KeyConnectorService as KeyConnectorServiceAbstraction } from 'jslib-common/abstractions/keyConnector.service';
|
||||
import { LogService } from 'jslib-common/abstractions/log.service';
|
||||
import { MessagingService as MessagingServiceAbstraction } from 'jslib-common/abstractions/messaging.service';
|
||||
import { NotificationsService as NotificationsServiceAbstraction } from 'jslib-common/abstractions/notifications.service';
|
||||
import {
|
||||
PasswordGenerationService as PasswordGenerationServiceAbstraction,
|
||||
} from 'jslib-common/abstractions/passwordGeneration.service';
|
||||
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from 'jslib-common/abstractions/passwordReprompt.service';
|
||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib-common/abstractions/platformUtils.service';
|
||||
import { PolicyService as PolicyServiceAbstraction } from 'jslib-common/abstractions/policy.service';
|
||||
import { SearchService as SearchServiceAbstraction } from 'jslib-common/abstractions/search.service';
|
||||
import { SendService as SendServiceAbstraction } from 'jslib-common/abstractions/send.service';
|
||||
import { SettingsService as SettingsServiceAbstraction } from 'jslib-common/abstractions/settings.service';
|
||||
import { StateService as StateServiceAbstraction } from 'jslib-common/abstractions/state.service';
|
||||
import { StorageService as StorageServiceAbstraction } from 'jslib-common/abstractions/storage.service';
|
||||
import { SyncService as SyncServiceAbstraction } from 'jslib-common/abstractions/sync.service';
|
||||
import { TokenService as TokenServiceAbstraction } from 'jslib-common/abstractions/token.service';
|
||||
import { TotpService as TotpServiceAbstraction } from 'jslib-common/abstractions/totp.service';
|
||||
import { UserService as UserServiceAbstraction } from 'jslib-common/abstractions/user.service';
|
||||
import { UserVerificationService as UserVerificationServiceAbstraction } from 'jslib-common/abstractions/userVerification.service';
|
||||
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from 'jslib-common/abstractions/vaultTimeout.service';
|
||||
|
||||
import { AuthGuardService } from './auth-guard.service';
|
||||
import { BroadcasterService } from './broadcaster.service';
|
||||
import { LockGuardService } from './lock-guard.service';
|
||||
import { ModalService } from './modal.service';
|
||||
import { PasswordRepromptService } from './passwordReprompt.service';
|
||||
import { UnauthGuardService } from './unauth-guard.service';
|
||||
import { ValidationService } from './validation.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
ToasterModule,
|
||||
],
|
||||
declarations: [],
|
||||
providers: [
|
||||
{ provide: 'WINDOW', useValue: window },
|
||||
{
|
||||
provide: LOCALE_ID,
|
||||
useFactory: (i18nService: I18nServiceAbstraction) => i18nService.translationLocale,
|
||||
deps: [I18nServiceAbstraction],
|
||||
},
|
||||
ValidationService,
|
||||
AuthGuardService,
|
||||
UnauthGuardService,
|
||||
LockGuardService,
|
||||
ModalService,
|
||||
{
|
||||
provide: AppIdServiceAbstraction,
|
||||
useClass: AppIdService,
|
||||
deps: [StorageServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: AuditServiceAbstraction,
|
||||
useClass: AuditService,
|
||||
deps: [CryptoFunctionServiceAbstraction, ApiServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: AuthServiceAbstraction,
|
||||
useClass: AuthService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
TokenServiceAbstraction,
|
||||
AppIdServiceAbstraction,
|
||||
I18nServiceAbstraction,
|
||||
PlatformUtilsServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
VaultTimeoutServiceAbstraction,
|
||||
LogService,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
EnvironmentServiceAbstraction,
|
||||
KeyConnectorServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: CipherServiceAbstraction,
|
||||
useFactory: (cryptoService: CryptoServiceAbstraction, userService: UserServiceAbstraction,
|
||||
settingsService: SettingsServiceAbstraction, apiService: ApiServiceAbstraction,
|
||||
fileUploadService: FileUploadServiceAbstraction, storageService: StorageServiceAbstraction,
|
||||
i18nService: I18nServiceAbstraction, injector: Injector, logService: LogService) =>
|
||||
new CipherService(cryptoService, userService, settingsService, apiService, fileUploadService,
|
||||
storageService, i18nService, () => injector.get(SearchServiceAbstraction), logService),
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
SettingsServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
FileUploadServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
I18nServiceAbstraction,
|
||||
Injector, // TODO: Get rid of this circular dependency!
|
||||
LogService,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: FolderServiceAbstraction,
|
||||
useClass: FolderService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
I18nServiceAbstraction,
|
||||
CipherServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{ provide: LogService, useFactory: () => new ConsoleLogService(false) },
|
||||
{
|
||||
provide: CollectionServiceAbstraction,
|
||||
useClass: CollectionService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
I18nServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: EnvironmentServiceAbstraction,
|
||||
useClass: EnvironmentService,
|
||||
deps: [StorageServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: TotpServiceAbstraction,
|
||||
useClass: TotpService,
|
||||
deps: [
|
||||
StorageServiceAbstraction,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
LogService,
|
||||
],
|
||||
},
|
||||
{ provide: TokenServiceAbstraction, useClass: TokenService, deps: [StorageServiceAbstraction] },
|
||||
{
|
||||
provide: CryptoServiceAbstraction,
|
||||
useClass: CryptoService,
|
||||
deps: [
|
||||
StorageServiceAbstraction,
|
||||
'SECURE_STORAGE',
|
||||
CryptoFunctionServiceAbstraction,
|
||||
PlatformUtilsServiceAbstraction,
|
||||
LogService,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: PasswordGenerationServiceAbstraction,
|
||||
useClass: PasswordGenerationService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
PolicyServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: ApiServiceAbstraction,
|
||||
useFactory: (tokenService: TokenServiceAbstraction, platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||
environmentService: EnvironmentServiceAbstraction, messagingService: MessagingServiceAbstraction) =>
|
||||
new ApiService(tokenService, platformUtilsService, environmentService,
|
||||
async (expired: boolean) => messagingService.send('logout', { expired: expired })),
|
||||
deps: [
|
||||
TokenServiceAbstraction,
|
||||
PlatformUtilsServiceAbstraction,
|
||||
EnvironmentServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: FileUploadServiceAbstraction,
|
||||
useClass: FileUploadService,
|
||||
deps: [
|
||||
LogService,
|
||||
ApiServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: SyncServiceAbstraction,
|
||||
useFactory: (userService: UserServiceAbstraction, apiService: ApiServiceAbstraction,
|
||||
settingsService: SettingsServiceAbstraction, folderService: FolderServiceAbstraction,
|
||||
cipherService: CipherServiceAbstraction, cryptoService: CryptoServiceAbstraction,
|
||||
collectionService: CollectionServiceAbstraction, storageService: StorageServiceAbstraction,
|
||||
messagingService: MessagingServiceAbstraction, policyService: PolicyServiceAbstraction,
|
||||
sendService: SendServiceAbstraction, logService: LogService, tokenService: TokenService,
|
||||
keyConnectorService: KeyConnectorServiceAbstraction) => new SyncService(userService, apiService,
|
||||
settingsService, folderService, cipherService, cryptoService, collectionService, storageService,
|
||||
messagingService, policyService, sendService, logService, tokenService, keyConnectorService,
|
||||
async (expired: boolean) => messagingService.send('logout', { expired: expired })),
|
||||
deps: [
|
||||
UserServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
SettingsServiceAbstraction,
|
||||
FolderServiceAbstraction,
|
||||
CipherServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
CollectionServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
PolicyServiceAbstraction,
|
||||
SendServiceAbstraction,
|
||||
LogService,
|
||||
TokenServiceAbstraction,
|
||||
KeyConnectorServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: UserServiceAbstraction,
|
||||
useClass: UserService,
|
||||
deps: [TokenServiceAbstraction, StorageServiceAbstraction],
|
||||
},
|
||||
{ provide: BroadcasterServiceAbstraction, useClass: BroadcasterService },
|
||||
{
|
||||
provide: SettingsServiceAbstraction,
|
||||
useClass: SettingsService,
|
||||
deps: [UserServiceAbstraction, StorageServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: VaultTimeoutServiceAbstraction,
|
||||
useFactory: (cipherService: CipherServiceAbstraction, folderService: FolderServiceAbstraction,
|
||||
collectionService: CollectionServiceAbstraction, cryptoService: CryptoServiceAbstraction,
|
||||
platformUtilsService: PlatformUtilsServiceAbstraction, storageService: StorageServiceAbstraction,
|
||||
messagingService: MessagingServiceAbstraction, searchService: SearchServiceAbstraction,
|
||||
userService: UserServiceAbstraction, tokenService: TokenServiceAbstraction,
|
||||
policyService: PolicyServiceAbstraction, keyConnectorService: KeyConnectorServiceAbstraction) =>
|
||||
new VaultTimeoutService(cipherService, folderService, collectionService, cryptoService,
|
||||
platformUtilsService, storageService, messagingService, searchService, userService, tokenService,
|
||||
policyService, keyConnectorService, null,
|
||||
async () => messagingService.send('logout', { expired: false })),
|
||||
deps: [
|
||||
CipherServiceAbstraction,
|
||||
FolderServiceAbstraction,
|
||||
CollectionServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
PlatformUtilsServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
SearchServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
TokenServiceAbstraction,
|
||||
PolicyServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{ provide: StateServiceAbstraction, useClass: StateService },
|
||||
{
|
||||
provide: ExportServiceAbstraction,
|
||||
useClass: ExportService,
|
||||
deps: [
|
||||
FolderServiceAbstraction,
|
||||
CipherServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: SearchServiceAbstraction,
|
||||
useClass: SearchService,
|
||||
deps: [
|
||||
CipherServiceAbstraction,
|
||||
LogService,
|
||||
I18nServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: NotificationsServiceAbstraction,
|
||||
useFactory: (userService: UserServiceAbstraction, syncService: SyncServiceAbstraction,
|
||||
appIdService: AppIdServiceAbstraction, apiService: ApiServiceAbstraction,
|
||||
vaultTimeoutService: VaultTimeoutServiceAbstraction, environmentService: EnvironmentServiceAbstraction,
|
||||
messagingService: MessagingServiceAbstraction, logService: LogService) =>
|
||||
new NotificationsService(userService, syncService, appIdService, apiService, vaultTimeoutService,
|
||||
environmentService, async () => messagingService.send('logout', { expired: true }), logService),
|
||||
deps: [
|
||||
UserServiceAbstraction,
|
||||
SyncServiceAbstraction,
|
||||
AppIdServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
VaultTimeoutServiceAbstraction,
|
||||
EnvironmentServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
LogService,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: CryptoFunctionServiceAbstraction,
|
||||
useClass: WebCryptoFunctionService,
|
||||
deps: ['WINDOW', PlatformUtilsServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: EventServiceAbstraction,
|
||||
useClass: EventService,
|
||||
deps: [
|
||||
StorageServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
CipherServiceAbstraction,
|
||||
LogService,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: PolicyServiceAbstraction,
|
||||
useClass: PolicyService,
|
||||
deps: [
|
||||
UserServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: SendServiceAbstraction,
|
||||
useClass: SendService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
FileUploadServiceAbstraction,
|
||||
StorageServiceAbstraction,
|
||||
I18nServiceAbstraction,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: KeyConnectorServiceAbstraction,
|
||||
useClass: KeyConnectorService,
|
||||
deps: [
|
||||
StorageServiceAbstraction,
|
||||
UserServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
TokenServiceAbstraction,
|
||||
LogService,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: UserVerificationServiceAbstraction,
|
||||
useClass: UserVerificationService,
|
||||
deps: [
|
||||
CryptoServiceAbstraction,
|
||||
I18nServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{ provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },
|
||||
],
|
||||
})
|
||||
export class JslibServicesModule {
|
||||
}
|
||||
@@ -32,6 +32,8 @@ import { ImportOrganizationCiphersRequest } from '../models/request/importOrgani
|
||||
import { KdfRequest } from '../models/request/kdfRequest';
|
||||
import { KeyConnectorUserKeyRequest } from '../models/request/keyConnectorUserKeyRequest';
|
||||
import { KeysRequest } from '../models/request/keysRequest';
|
||||
import { OrganizationSponsorshipCreateRequest } from '../models/request/organization/organizationSponsorshipCreateRequest';
|
||||
import { OrganizationSponsorshipRedeemRequest } from '../models/request/organization/organizationSponsorshipRedeemRequest';
|
||||
import { OrganizationSsoRequest } from '../models/request/organization/organizationSsoRequest';
|
||||
import { OrganizationCreateRequest } from '../models/request/organizationCreateRequest';
|
||||
import { OrganizationImportRequest } from '../models/request/organizationImportRequest';
|
||||
@@ -453,6 +455,14 @@ export abstract class ApiService {
|
||||
|
||||
preValidateSso: (identifier: string) => Promise<boolean>;
|
||||
|
||||
postCreateSponsorship: (sponsorshipOrgId: string, request: OrganizationSponsorshipCreateRequest) => Promise<void>;
|
||||
deleteRevokeSponsorship: (sponsoringOrganizationId: string) => Promise<void>;
|
||||
deleteRemoveSponsorship: (sponsoringOrgId: string) => Promise<void>;
|
||||
postPreValidateSponsorshipToken: (sponsorshipToken: string) => Promise<boolean>;
|
||||
postRedeemSponsorship: (sponsorshipToken: string, request: OrganizationSponsorshipRedeemRequest) => Promise<void>;
|
||||
postResendSponsorshipOffer: (sponsoringOrgId: string) => Promise<void>;
|
||||
|
||||
getUserKeyFromKeyConnector: (keyConnectorUrl: string) => Promise<KeyConnectorUserKeyResponse>;
|
||||
postUserKeyToKeyConnector: (keyConnectorUrl: string, request: KeyConnectorUserKeyRequest) => Promise<void>;
|
||||
getKeyConnectorAlive: (keyConnectorUrl: string) => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ export abstract class UserService {
|
||||
clear: () => Promise<any>;
|
||||
isAuthenticated: () => Promise<boolean>;
|
||||
canAccessPremium: () => Promise<boolean>;
|
||||
canManageSponsorships: () => Promise<boolean>;
|
||||
getOrganization: (id: string) => Promise<Organization>;
|
||||
getOrganizationByIdentifier: (identifier: string) => Promise<Organization>;
|
||||
getAllOrganizations: () => Promise<Organization[]>;
|
||||
|
||||
@@ -6,4 +6,5 @@ export abstract class UserVerificationService {
|
||||
buildRequest: <T extends SecretVerificationRequest> (verification: Verification,
|
||||
requestClass?: new () => T, alreadyHashed?: boolean) => Promise<T>;
|
||||
verifyUser: (verification: Verification) => Promise<boolean>;
|
||||
requestOTP: () => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ export enum EventType {
|
||||
OrganizationUser_ResetPassword_Withdraw = 1507,
|
||||
OrganizationUser_AdminResetPassword = 1508,
|
||||
OrganizationUser_ResetSsoLink = 1509,
|
||||
OrganizationUser_FirstSsoLogin = 1510,
|
||||
|
||||
Organization_Updated = 1600,
|
||||
Organization_PurgedVault = 1601,
|
||||
|
||||
3
common/src/enums/planSponsorshipType.ts
Normal file
3
common/src/enums/planSponsorshipType.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export enum PlanSponsorshipType {
|
||||
FamiliesForEnterprise = 0,
|
||||
}
|
||||
@@ -37,7 +37,7 @@ enum Saml2SigningBehavior {
|
||||
export class SsoConfigApi extends BaseResponse {
|
||||
configType: SsoType;
|
||||
|
||||
useKeyConnector: boolean;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
// OpenId
|
||||
@@ -81,7 +81,7 @@ export class SsoConfigApi extends BaseResponse {
|
||||
|
||||
this.configType = this.getResponseProperty('ConfigType');
|
||||
|
||||
this.useKeyConnector = this.getResponseProperty('UseKeyConnector');
|
||||
this.keyConnectorEnabled = this.getResponseProperty('KeyConnectorEnabled');
|
||||
this.keyConnectorUrl = this.getResponseProperty('KeyConnectorUrl');
|
||||
|
||||
this.authority = this.getResponseProperty('Authority');
|
||||
|
||||
@@ -2,6 +2,8 @@ import { ProfileOrganizationResponse } from '../response/profileOrganizationResp
|
||||
|
||||
import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';
|
||||
import { OrganizationUserType } from '../../enums/organizationUserType';
|
||||
import { ProductType } from '../../enums/productType';
|
||||
|
||||
import { PermissionsApi } from '../api/permissionsApi';
|
||||
|
||||
export class OrganizationData {
|
||||
@@ -18,6 +20,7 @@ export class OrganizationData {
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useSso: boolean;
|
||||
useKeyConnector: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
@@ -33,7 +36,10 @@ export class OrganizationData {
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
isProviderUser: boolean;
|
||||
usesKeyConnector: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(response: ProfileOrganizationResponse) {
|
||||
@@ -50,6 +56,7 @@ export class OrganizationData {
|
||||
this.use2fa = response.use2fa;
|
||||
this.useApi = response.useApi;
|
||||
this.useSso = response.useSso;
|
||||
this.useKeyConnector = response.useKeyConnector;
|
||||
this.useResetPassword = response.useResetPassword;
|
||||
this.selfHost = response.selfHost;
|
||||
this.usersGetPremium = response.usersGetPremium;
|
||||
@@ -64,7 +71,10 @@ export class OrganizationData {
|
||||
this.hasPublicAndPrivateKeys = response.hasPublicAndPrivateKeys;
|
||||
this.providerId = response.providerId;
|
||||
this.providerName = response.providerName;
|
||||
this.usesKeyConnector = response.usesKeyConnector;
|
||||
this.familySponsorshipFriendlyName = response.familySponsorshipFriendlyName;
|
||||
this.familySponsorshipAvailable = response.familySponsorshipAvailable;
|
||||
this.planProductType = response.planProductType;
|
||||
this.keyConnectorEnabled = response.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = response.keyConnectorUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { OrganizationData } from '../data/organizationData';
|
||||
|
||||
import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';
|
||||
import { OrganizationUserType } from '../../enums/organizationUserType';
|
||||
import { ProductType } from '../../enums/productType';
|
||||
import { PermissionsApi } from '../api/permissionsApi';
|
||||
|
||||
|
||||
@@ -19,6 +20,7 @@ export class Organization {
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useSso: boolean;
|
||||
useKeyConnector: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
@@ -34,7 +36,10 @@ export class Organization {
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
isProviderUser: boolean;
|
||||
usesKeyConnector: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(obj?: OrganizationData) {
|
||||
@@ -55,6 +60,7 @@ export class Organization {
|
||||
this.use2fa = obj.use2fa;
|
||||
this.useApi = obj.useApi;
|
||||
this.useSso = obj.useSso;
|
||||
this.useKeyConnector = obj.useKeyConnector;
|
||||
this.useResetPassword = obj.useResetPassword;
|
||||
this.selfHost = obj.selfHost;
|
||||
this.usersGetPremium = obj.usersGetPremium;
|
||||
@@ -70,7 +76,10 @@ export class Organization {
|
||||
this.providerId = obj.providerId;
|
||||
this.providerName = obj.providerName;
|
||||
this.isProviderUser = obj.isProviderUser;
|
||||
this.usesKeyConnector = obj.usesKeyConnector;
|
||||
this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName;
|
||||
this.familySponsorshipAvailable = obj.familySponsorshipAvailable;
|
||||
this.planProductType = obj.planProductType;
|
||||
this.keyConnectorEnabled = obj.keyConnectorEnabled;
|
||||
this.keyConnectorUrl = obj.keyConnectorUrl;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FieldType } from '../../enums/fieldType';
|
||||
import { LinkedIdType } from '../../enums/linkedIdType';
|
||||
|
||||
import { FieldView } from '../view/fieldView';
|
||||
|
||||
@@ -18,6 +19,7 @@ export class Field {
|
||||
view.type = req.type;
|
||||
view.value = req.value;
|
||||
view.name = req.name;
|
||||
view.linkedId = req.linkedId;
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -25,12 +27,14 @@ export class Field {
|
||||
domain.type = req.type;
|
||||
domain.value = req.value != null ? new EncString(req.value) : null;
|
||||
domain.name = req.name != null ? new EncString(req.name) : null;
|
||||
domain.linkedId = req.linkedId;
|
||||
return domain;
|
||||
}
|
||||
|
||||
name: string;
|
||||
value: string;
|
||||
type: FieldType;
|
||||
linkedId: LinkedIdType;
|
||||
|
||||
constructor(o?: FieldView | FieldDomain) {
|
||||
if (o == null) {
|
||||
@@ -45,5 +49,6 @@ export class Field {
|
||||
this.value = o.value?.encryptedString;
|
||||
}
|
||||
this.type = o.type;
|
||||
this.linkedId = o.linkedId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { PlanSponsorshipType } from '../../../enums/planSponsorshipType';
|
||||
|
||||
export class OrganizationSponsorshipCreateRequest {
|
||||
sponsoredEmail: string;
|
||||
planSponsorshipType: PlanSponsorshipType;
|
||||
friendlyName: string;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { PlanSponsorshipType } from '../../../enums/planSponsorshipType';
|
||||
|
||||
export class OrganizationSponsorshipRedeemRequest {
|
||||
planSponsorshipType: PlanSponsorshipType;
|
||||
sponsoredOrganizationId: string;
|
||||
}
|
||||
@@ -15,6 +15,7 @@ export class IdentityTokenResponse extends BaseResponse {
|
||||
kdf: KdfType;
|
||||
kdfIterations: number;
|
||||
forcePasswordReset: boolean;
|
||||
apiUseKeyConnector: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(response: any) {
|
||||
@@ -31,6 +32,7 @@ export class IdentityTokenResponse extends BaseResponse {
|
||||
this.kdf = this.getResponseProperty('Kdf');
|
||||
this.kdfIterations = this.getResponseProperty('KdfIterations');
|
||||
this.forcePasswordReset = this.getResponseProperty('ForcePasswordReset');
|
||||
this.apiUseKeyConnector = this.getResponseProperty('ApiUseKeyConnector');
|
||||
this.keyConnectorUrl = this.getResponseProperty('KeyConnectorUrl');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,14 @@ export class OrganizationUserUserDetailsResponse extends OrganizationUserRespons
|
||||
name: string;
|
||||
email: string;
|
||||
twoFactorEnabled: boolean;
|
||||
usesKeyConnector: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.name = this.getResponseProperty('Name');
|
||||
this.email = this.getResponseProperty('Email');
|
||||
this.twoFactorEnabled = this.getResponseProperty('TwoFactorEnabled');
|
||||
this.usesKeyConnector = this.getResponseProperty('UsesKeyConnector') ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { BaseResponse } from './baseResponse';
|
||||
|
||||
import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType';
|
||||
import { OrganizationUserType } from '../../enums/organizationUserType';
|
||||
import { ProductType } from '../../enums/productType';
|
||||
import { PermissionsApi } from '../api/permissionsApi';
|
||||
|
||||
export class ProfileOrganizationResponse extends BaseResponse {
|
||||
@@ -15,6 +16,7 @@ export class ProfileOrganizationResponse extends BaseResponse {
|
||||
use2fa: boolean;
|
||||
useApi: boolean;
|
||||
useSso: boolean;
|
||||
useKeyConnector: boolean;
|
||||
useResetPassword: boolean;
|
||||
selfHost: boolean;
|
||||
usersGetPremium: boolean;
|
||||
@@ -33,7 +35,10 @@ export class ProfileOrganizationResponse extends BaseResponse {
|
||||
userId: string;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
usesKeyConnector: boolean;
|
||||
familySponsorshipFriendlyName: string;
|
||||
familySponsorshipAvailable: boolean;
|
||||
planProductType: ProductType;
|
||||
keyConnectorEnabled: boolean;
|
||||
keyConnectorUrl: string;
|
||||
|
||||
constructor(response: any) {
|
||||
@@ -48,6 +53,7 @@ export class ProfileOrganizationResponse extends BaseResponse {
|
||||
this.use2fa = this.getResponseProperty('Use2fa');
|
||||
this.useApi = this.getResponseProperty('UseApi');
|
||||
this.useSso = this.getResponseProperty('UseSso');
|
||||
this.useKeyConnector = this.getResponseProperty('UseKeyConnector') ?? false;
|
||||
this.useResetPassword = this.getResponseProperty('UseResetPassword');
|
||||
this.selfHost = this.getResponseProperty('SelfHost');
|
||||
this.usersGetPremium = this.getResponseProperty('UsersGetPremium');
|
||||
@@ -66,7 +72,10 @@ export class ProfileOrganizationResponse extends BaseResponse {
|
||||
this.userId = this.getResponseProperty('UserId');
|
||||
this.providerId = this.getResponseProperty('ProviderId');
|
||||
this.providerName = this.getResponseProperty('ProviderName');
|
||||
this.usesKeyConnector = this.getResponseProperty('UsesKeyConnector') ?? false;
|
||||
this.familySponsorshipFriendlyName = this.getResponseProperty('FamilySponsorshipFriendlyName');
|
||||
this.familySponsorshipAvailable = this.getResponseProperty('FamilySponsorshipAvailable');
|
||||
this.planProductType = this.getResponseProperty('PlanProductType');
|
||||
this.keyConnectorEnabled = this.getResponseProperty('KeyConnectorEnabled') ?? false;
|
||||
this.keyConnectorUrl = this.getResponseProperty('KeyConnectorUrl');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@ import { ProfileOrganizationResponse } from './profileOrganizationResponse';
|
||||
export class ProfileProviderOrganizationResponse extends ProfileOrganizationResponse {
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.usesKeyConnector = false;
|
||||
this.keyConnectorEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ export class BillingSubscriptionItemResponse extends BaseResponse {
|
||||
amount: number;
|
||||
quantity: number;
|
||||
interval: string;
|
||||
sponsoredSubscriptionItem: boolean;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
@@ -66,6 +67,7 @@ export class BillingSubscriptionItemResponse extends BaseResponse {
|
||||
this.amount = this.getResponseProperty('Amount');
|
||||
this.quantity = this.getResponseProperty('Quantity');
|
||||
this.interval = this.getResponseProperty('Interval');
|
||||
this.sponsoredSubscriptionItem = this.getResponseProperty('SponsoredSubscriptionItem');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ import { ImportDirectoryRequest } from '../models/request/importDirectoryRequest
|
||||
import { ImportOrganizationCiphersRequest } from '../models/request/importOrganizationCiphersRequest';
|
||||
import { KdfRequest } from '../models/request/kdfRequest';
|
||||
import { KeysRequest } from '../models/request/keysRequest';
|
||||
import { OrganizationSponsorshipCreateRequest } from '../models/request/organization/organizationSponsorshipCreateRequest';
|
||||
import { OrganizationSponsorshipRedeemRequest } from '../models/request/organization/organizationSponsorshipRedeemRequest';
|
||||
import { OrganizationSsoRequest } from '../models/request/organization/organizationSsoRequest';
|
||||
import { OrganizationCreateRequest } from '../models/request/organizationCreateRequest';
|
||||
import { OrganizationImportRequest } from '../models/request/organizationImportRequest';
|
||||
@@ -172,6 +174,8 @@ import { KeyConnectorUserKeyRequest } from '../models/request/keyConnectorUserKe
|
||||
import { KeyConnectorUserKeyResponse } from '../models/response/keyConnectorUserKeyResponse';
|
||||
import { SendAccessView } from '../models/view/sendAccessView';
|
||||
|
||||
|
||||
|
||||
export class ApiService implements ApiServiceAbstraction {
|
||||
protected apiKeyRefresh: (clientId: string, clientSecret: string) => Promise<any>;
|
||||
private device: DeviceType;
|
||||
@@ -1491,6 +1495,21 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
}
|
||||
}
|
||||
|
||||
async getKeyConnectorAlive(keyConnectorUrl: string) {
|
||||
const response = await this.fetch(new Request(keyConnectorUrl + '/alive', {
|
||||
cache: 'no-store',
|
||||
method: 'GET',
|
||||
headers: new Headers({
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
}),
|
||||
}));
|
||||
|
||||
if (response.status !== 200) {
|
||||
const error = await this.handleError(response, false, true);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
@@ -1543,6 +1562,42 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
}
|
||||
}
|
||||
|
||||
async postCreateSponsorship(sponsoredOrgId: string, request: OrganizationSponsorshipCreateRequest): Promise<void> {
|
||||
return await this.send('POST',
|
||||
'/organization/sponsorship/' + sponsoredOrgId + '/families-for-enterprise',
|
||||
request, true, false);
|
||||
}
|
||||
|
||||
async deleteRevokeSponsorship(sponsoringOrganizationId: string): Promise<void> {
|
||||
return await this.send('DELETE',
|
||||
'/organization/sponsorship/' + sponsoringOrganizationId,
|
||||
null, true, false);
|
||||
}
|
||||
|
||||
async deleteRemoveSponsorship(sponsoringOrgId: string): Promise<void> {
|
||||
return await this.send('DELETE',
|
||||
'/organization/sponsorship/sponsored/' + sponsoringOrgId,
|
||||
null, true, false);
|
||||
}
|
||||
|
||||
async postPreValidateSponsorshipToken(sponsorshipToken: string): Promise<boolean> {
|
||||
const r = await this.send('POST', '/organization/sponsorship/validate-token?sponsorshipToken=' + encodeURIComponent(sponsorshipToken),
|
||||
null, true, true);
|
||||
return r as boolean;
|
||||
}
|
||||
|
||||
async postRedeemSponsorship(sponsorshipToken: string, request: OrganizationSponsorshipRedeemRequest): Promise<void> {
|
||||
return await this.send('POST', '/organization/sponsorship/redeem?sponsorshipToken=' + encodeURIComponent(sponsorshipToken),
|
||||
request, true, false);
|
||||
}
|
||||
|
||||
async postResendSponsorshipOffer(sponsoringOrgId: string): Promise<void> {
|
||||
return await this.send('POST',
|
||||
'/organization/sponsorship/' + sponsoringOrgId + '/families-for-enterprise/resend',
|
||||
null, true, false);
|
||||
}
|
||||
|
||||
|
||||
protected async doAuthRefresh(): Promise<void> {
|
||||
const refreshToken = await this.tokenService.getRefreshToken();
|
||||
if (refreshToken != null && refreshToken !== '') {
|
||||
|
||||
@@ -370,8 +370,9 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
|
||||
if (tokenResponse.keyConnectorUrl != null) {
|
||||
await this.keyConnectorService.getAndSetKey(tokenResponse.keyConnectorUrl);
|
||||
} else if (this.environmentService.getKeyConnectorUrl() != null) {
|
||||
await this.keyConnectorService.getAndSetKey();
|
||||
} else if (tokenResponse.apiUseKeyConnector) {
|
||||
const keyConnectorUrl = this.environmentService.getKeyConnectorUrl();
|
||||
await this.keyConnectorService.getAndSetKey(keyConnectorUrl);
|
||||
}
|
||||
|
||||
await this.cryptoService.setEncKey(tokenResponse.key);
|
||||
|
||||
@@ -85,13 +85,13 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
featuredImportOptions = [
|
||||
{ id: 'bitwardenjson', name: 'Bitwarden (json)' },
|
||||
{ id: 'bitwardencsv', name: 'Bitwarden (csv)' },
|
||||
{ id: 'lastpasscsv', name: 'LastPass (csv)' },
|
||||
{ id: 'chromecsv', name: 'Chrome (csv)' },
|
||||
{ id: 'firefoxcsv', name: 'Firefox (csv)' },
|
||||
{ id: 'safaricsv', name: 'Safari (csv)' },
|
||||
{ id: 'keepass2xml', name: 'KeePass 2 (xml)' },
|
||||
{ id: '1password1pif', name: '1Password (1pif)' },
|
||||
{ id: 'dashlanejson', name: 'Dashlane (json)' },
|
||||
{ id: 'firefoxcsv', name: 'Firefox (csv)' },
|
||||
{ id: 'keepass2xml', name: 'KeePass 2 (xml)' },
|
||||
{ id: 'lastpasscsv', name: 'LastPass (csv)' },
|
||||
{ id: 'safaricsv', name: 'Safari and macOS (csv)' },
|
||||
{ id: '1password1pif', name: '1Password (1pif)' },
|
||||
];
|
||||
|
||||
regularImportOptions: ImportOption[] = [
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ApiService } from '../abstractions/api.service';
|
||||
import { CryptoService } from '../abstractions/crypto.service';
|
||||
import { EnvironmentService } from '../abstractions/environment.service';
|
||||
import { KeyConnectorService as KeyConnectorServiceAbstraction } from '../abstractions/keyConnector.service';
|
||||
import { LogService } from '../abstractions/log.service';
|
||||
import { StorageService } from '../abstractions/storage.service';
|
||||
@@ -25,8 +24,7 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||
|
||||
constructor(private storageService: StorageService, private userService: UserService,
|
||||
private cryptoService: CryptoService, private apiService: ApiService,
|
||||
private environmentService: EnvironmentService, private tokenService: TokenService,
|
||||
private logService: LogService) { }
|
||||
private tokenService: TokenService, private logService: LogService) { }
|
||||
|
||||
setUsesKeyConnector(usesKeyConnector: boolean) {
|
||||
this.usesKeyConnector = usesKeyConnector;
|
||||
@@ -59,15 +57,7 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||
await this.apiService.postConvertToKeyConnector();
|
||||
}
|
||||
|
||||
async getAndSetKey(url?: string) {
|
||||
if (url == null) {
|
||||
url = this.environmentService.getKeyConnectorUrl();
|
||||
}
|
||||
|
||||
if (url == null) {
|
||||
throw new Error('No Key Connector URL found.');
|
||||
}
|
||||
|
||||
async getAndSetKey(url: string) {
|
||||
try {
|
||||
const userKeyResponse = await this.apiService.getUserKeyFromKeyConnector(url);
|
||||
const keyArr = Utils.fromB64ToArray(userKeyResponse.key);
|
||||
@@ -82,7 +72,7 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
|
||||
async getManagingOrganization() {
|
||||
const orgs = await this.userService.getAllOrganizations();
|
||||
return orgs.find(o =>
|
||||
o.usesKeyConnector &&
|
||||
o.keyConnectorEnabled &&
|
||||
o.type !== OrganizationUserType.Admin &&
|
||||
o.type !== OrganizationUserType.Owner &&
|
||||
!o.isProviderUser);
|
||||
|
||||
@@ -321,16 +321,16 @@ export class SyncService implements SyncServiceAbstraction {
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all([
|
||||
this.userService.replaceOrganizations(organizations),
|
||||
this.userService.replaceProviders(providers),
|
||||
]);
|
||||
|
||||
if (await this.keyConnectorService.userNeedsMigration()) {
|
||||
this.messagingService.send('convertAccountToKeyConnector');
|
||||
} else {
|
||||
this.keyConnectorService.removeConvertAccountRequired();
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
this.userService.replaceOrganizations(organizations),
|
||||
this.userService.replaceProviders(providers),
|
||||
]);
|
||||
}
|
||||
|
||||
private async syncFolders(userId: string, response: FolderResponse[]) {
|
||||
|
||||
@@ -156,6 +156,11 @@ export class UserService implements UserServiceAbstraction {
|
||||
return false;
|
||||
}
|
||||
|
||||
async canManageSponsorships(): Promise<boolean> {
|
||||
const orgs = await this.getAllOrganizations();
|
||||
return orgs.some(o => o.familySponsorshipAvailable || o.familySponsorshipFriendlyName !== null);
|
||||
}
|
||||
|
||||
async getOrganization(id: string): Promise<Organization> {
|
||||
const userId = await this.getUserId();
|
||||
const organizations = await this.storageService.get<{ [id: string]: OrganizationData; }>(
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { UserVerificationService as UserVerificationServiceAbstraction } from '../abstractions/userVerification.service';
|
||||
|
||||
import { ApiService } from '../abstractions/api.service';
|
||||
import { CryptoService } from '../abstractions/crypto.service';
|
||||
import { I18nService } from '../abstractions/i18n.service';
|
||||
import { LogService } from '../abstractions/log.service';
|
||||
import { PlatformUtilsService } from '../abstractions/platformUtils.service';
|
||||
|
||||
import { VerificationType } from '../enums/verificationType';
|
||||
|
||||
@@ -15,17 +11,13 @@ import { SecretVerificationRequest } from '../models/request/secretVerificationR
|
||||
|
||||
import { Verification } from '../types/verification';
|
||||
|
||||
@Injectable()
|
||||
export class UserVerificationService implements UserVerificationServiceAbstraction {
|
||||
constructor(private cryptoService: CryptoService, private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService, private apiService: ApiService,
|
||||
private logService: LogService) { }
|
||||
private apiService: ApiService) { }
|
||||
|
||||
async buildRequest<T extends SecretVerificationRequest>(verification: Verification,
|
||||
requestClass?: new () => T, alreadyHashed?: boolean) {
|
||||
if (verification?.secret == null || verification.secret === '') {
|
||||
throw new Error('No secret provided for verification.');
|
||||
}
|
||||
this.validateInput(verification);
|
||||
|
||||
const request = requestClass != null
|
||||
? new requestClass()
|
||||
@@ -43,28 +35,35 @@ export class UserVerificationService implements UserVerificationServiceAbstracti
|
||||
}
|
||||
|
||||
async verifyUser(verification: Verification): Promise<boolean> {
|
||||
if (verification?.secret == null || verification.secret === '') {
|
||||
throw new Error('No secret provided for verification.');
|
||||
}
|
||||
this.validateInput(verification);
|
||||
|
||||
if (verification.type === VerificationType.OTP) {
|
||||
const request = new VerifyOTPRequest(verification.secret);
|
||||
try {
|
||||
await this.apiService.postAccountVerifyOTP(request);
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('invalidVerificationCode'));
|
||||
return false;
|
||||
throw new Error(this.i18nService.t('invalidVerificationCode'));
|
||||
}
|
||||
} else {
|
||||
const passwordValid = await this.cryptoService.compareAndUpdateKeyHash(verification.secret, null);
|
||||
if (!passwordValid) {
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('invalidMasterPassword'));
|
||||
return false;
|
||||
throw new Error(this.i18nService.t('invalidMasterPassword'));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async requestOTP() {
|
||||
await this.apiService.postAccountRequestOTP();
|
||||
}
|
||||
|
||||
private validateInput(verification: Verification) {
|
||||
if (verification?.secret == null || verification.secret === '') {
|
||||
if (verification.type === VerificationType.OTP) {
|
||||
throw new Error(this.i18nService.t('verificationCodeRequired'));
|
||||
} else {
|
||||
throw new Error(this.i18nService.t('masterPassRequired'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,10 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
|
||||
return Promise.resolve(this.packageJson.version);
|
||||
}
|
||||
|
||||
getApplicationVersionSync(): string {
|
||||
return this.packageJson.version;
|
||||
}
|
||||
|
||||
supportsWebAuthn(win: Window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user