mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-02 03:41:09 +01:00
Merge pull request #1995 from bitwarden/m-rpv1-force-reset
This commit is contained in:
commit
a61598253c
@ -1752,5 +1752,14 @@
|
||||
},
|
||||
"emailVerificationRequiredDesc": {
|
||||
"message": "You must verify your email to use this feature. You can verify your email in the web vault."
|
||||
},
|
||||
"updatedMasterPassword": {
|
||||
"message": "Updated Master Password"
|
||||
},
|
||||
"updateMasterPassword": {
|
||||
"message": "Update Master Password"
|
||||
},
|
||||
"updateMasterPasswordWarning": {
|
||||
"message": "Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour."
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.se
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
import { StorageService } from 'jslib-common/abstractions/storage.service';
|
||||
import { SyncService } from 'jslib-common/abstractions/sync.service';
|
||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||
|
||||
import { LoginComponent as BaseLoginComponent } from 'jslib-angular/components/login.component';
|
||||
|
||||
@ -23,10 +24,14 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
protected stateService: StateService, protected environmentService: EnvironmentService,
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
protected cryptoFunctionService: CryptoFunctionService, storageService: StorageService,
|
||||
syncService: SyncService) {
|
||||
syncService: SyncService, private userService: UserService) {
|
||||
super(authService, router, platformUtilsService, i18nService, stateService, environmentService, passwordGenerationService, cryptoFunctionService, storageService);
|
||||
super.onSuccessfulLogin = () => {
|
||||
return syncService.fullSync(true);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true).then(async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
}
|
||||
});
|
||||
};
|
||||
super.successRoute = '/tabs/vault';
|
||||
}
|
||||
|
@ -31,6 +31,13 @@ export class SetPasswordComponent extends BaseSetPasswordComponent {
|
||||
syncService: SyncService, route: ActivatedRoute) {
|
||||
super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,
|
||||
platformUtilsService, policyService, router, apiService, syncService, route);
|
||||
super.onSuccessfulChangePassword = async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
} else {
|
||||
this.router.navigate([this.successRoute]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
get masterPasswordScoreWidth() {
|
||||
|
@ -15,6 +15,7 @@ import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.se
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
import { StorageService } from 'jslib-common/abstractions/storage.service';
|
||||
import { SyncService } from 'jslib-common/abstractions/sync.service';
|
||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||
|
||||
import { SsoComponent as BaseSsoComponent } from 'jslib-angular/components/sso.component';
|
||||
import { BrowserApi } from '../../browser/browserApi';
|
||||
@ -29,7 +30,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
storageService: StorageService, stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService, apiService: ApiService,
|
||||
cryptoFunctionService: CryptoFunctionService, passwordGenerationService: PasswordGenerationService,
|
||||
syncService: SyncService, environmentService: EnvironmentService) {
|
||||
syncService: SyncService, environmentService: EnvironmentService, private userService: UserService) {
|
||||
super(authService, router, i18nService, route, storageService, stateService, platformUtilsService,
|
||||
apiService, cryptoFunctionService, environmentService, passwordGenerationService);
|
||||
|
||||
@ -44,5 +45,13 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
const thisWindow = window.open('', '_self');
|
||||
thisWindow.close();
|
||||
};
|
||||
|
||||
super.onSuccessfulLoginNavigate = async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
} else {
|
||||
this.router.navigate([this.successRoute]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.se
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
import { StorageService } from 'jslib-common/abstractions/storage.service';
|
||||
import { SyncService } from 'jslib-common/abstractions/sync.service';
|
||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||
|
||||
import { BroadcasterService } from 'jslib-angular/services/broadcaster.service';
|
||||
|
||||
@ -44,11 +45,16 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||
environmentService: EnvironmentService, private ngZone: NgZone,
|
||||
private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef,
|
||||
private popupUtilsService: PopupUtilsService, stateService: StateService,
|
||||
storageService: StorageService, route: ActivatedRoute, private messagingService: MessagingService) {
|
||||
storageService: StorageService, route: ActivatedRoute, private messagingService: MessagingService,
|
||||
private userService: UserService) {
|
||||
super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService,
|
||||
stateService, storageService, route);
|
||||
super.onSuccessfulLogin = () => {
|
||||
return syncService.fullSync(true);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
return syncService.fullSync(true).then(async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
};
|
||||
});
|
||||
};
|
||||
super.successRoute = '/tabs/vault';
|
||||
this.webAuthnNewTab = this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari();
|
||||
|
100
src/popup/accounts/update-temp-password.component.html
Normal file
100
src/popup/accounts/update-temp-password.component.html
Normal file
@ -0,0 +1,100 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<a (click)="logOut()">{{'logOut' | i18n}}</a>
|
||||
</div>
|
||||
<div class="center">
|
||||
<span class="title">{{'updateMasterPassword' | i18n}}</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button type="submit" appBlurClick [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{'submit' | i18n}}</span>
|
||||
<i class="fa fa-spinner fa-lg fa-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<content>
|
||||
<app-callout type="warning" title="{{'updateMasterPassword' | i18n}}">
|
||||
{{'updateMasterPasswordWarning' | i18n}}
|
||||
</app-callout>
|
||||
<app-callout type="info" *ngIf="enforcedPolicyOptions">
|
||||
{{'masterPasswordPolicyInEffect' | i18n}}
|
||||
<ul>
|
||||
<li *ngIf="enforcedPolicyOptions?.minComplexity > 0">
|
||||
{{'policyInEffectMinComplexity' | i18n : getPasswordScoreAlertDisplay()}}
|
||||
</li>
|
||||
<li *ngIf="enforcedPolicyOptions?.minLength > 0">
|
||||
{{'policyInEffectMinLength' | i18n : enforcedPolicyOptions?.minLength.toString()}}
|
||||
</li>
|
||||
<li *ngIf="enforcedPolicyOptions?.requireUpper">{{'policyInEffectUppercase' | i18n}}</li>
|
||||
<li *ngIf="enforcedPolicyOptions?.requireLower">{{'policyInEffectLowercase' | i18n}}</li>
|
||||
<li *ngIf="enforcedPolicyOptions?.requireNumbers">{{'policyInEffectNumbers' | i18n}}</li>
|
||||
<li *ngIf="enforcedPolicyOptions?.requireSpecial">
|
||||
{{'policyInEffectSpecial' | i18n : '!@#$%^&*'}}
|
||||
</li>
|
||||
</ul>
|
||||
</app-callout>
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<div class="box-content-row-flex">
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">
|
||||
{{'masterPass' | i18n}}
|
||||
<strong class="sub-label text-{{masterPasswordScoreStyle.Color}}"
|
||||
*ngIf="masterPasswordScoreStyle.Text">
|
||||
{{masterPasswordScoreStyle.Text}}
|
||||
</strong>
|
||||
</label>
|
||||
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}"
|
||||
name="MasterPassword" class="monospaced" [(ngModel)]="masterPassword" required
|
||||
appInputVerbatim (input)="updatePasswordStrength()">
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick
|
||||
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword(false)">
|
||||
<i class="fa fa-lg" aria-hidden="true"
|
||||
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar bg-{{masterPasswordScoreStyle.Color}}" role="progressbar" aria-valuenow="0"
|
||||
aria-valuemin="0" aria-valuemax="100" [ngStyle]="{width: (masterPasswordScoreStyle.Width + '%')}"
|
||||
attr.aria-valuenow="{{masterPasswordScoreStyle.Width}}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||
<div class="row-main">
|
||||
<label for="masterPasswordRetype">{{'reTypeMasterPass' | i18n}}</label>
|
||||
<input id="masterPasswordRetype" type="{{showPassword ? 'text' : 'password'}}"
|
||||
name="MasterPasswordRetype" class="monospaced" [(ngModel)]="masterPasswordRetype" required
|
||||
appInputVerbatim>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick
|
||||
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword(true)">
|
||||
<i class="fa fa-lg" aria-hidden="true"
|
||||
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="hint">{{'masterPassHint' | i18n}}</label>
|
||||
<input id="hint" type="text" name="Hint" [(ngModel)]="hint">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{{'masterPassHintDesc' | i18n}}
|
||||
</div>
|
||||
</div>
|
||||
</content>
|
||||
</form>
|
62
src/popup/accounts/update-temp-password.component.ts
Normal file
62
src/popup/accounts/update-temp-password.component.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
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 { UpdateTempPasswordComponent as BaseUpdateTempPasswordComponent } from 'jslib-angular/components/update-temp-password.component';
|
||||
|
||||
interface MasterPasswordScore {
|
||||
Color: string;
|
||||
Text: string;
|
||||
Width: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-update-temp-password',
|
||||
templateUrl: 'update-temp-password.component.html',
|
||||
})
|
||||
export class UpdateTempPasswordComponent extends BaseUpdateTempPasswordComponent {
|
||||
get masterPasswordScoreStyle(): MasterPasswordScore {
|
||||
const scoreWidth = this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
|
||||
switch (this.masterPasswordScore) {
|
||||
case 4:
|
||||
return {
|
||||
Color: 'bg-success',
|
||||
Text: 'strong',
|
||||
Width: scoreWidth,
|
||||
};
|
||||
case 3:
|
||||
return {
|
||||
Color: 'bg-primary',
|
||||
Text: 'good',
|
||||
Width: scoreWidth,
|
||||
};
|
||||
case 2:
|
||||
return {
|
||||
Color: 'bg-warning',
|
||||
Text: 'weak',
|
||||
Width: scoreWidth,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
Color: 'bg-danger',
|
||||
Text: 'weak',
|
||||
Width: scoreWidth,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,
|
||||
passwordGenerationService: PasswordGenerationService, policyService: PolicyService,
|
||||
cryptoService: CryptoService, userService: UserService,
|
||||
messagingService: MessagingService, apiService: ApiService) {
|
||||
super(i18nService, platformUtilsService, passwordGenerationService, policyService, cryptoService,
|
||||
userService, messagingService, apiService);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import { SetPasswordComponent } from './accounts/set-password.component';
|
||||
import { SsoComponent } from './accounts/sso.component';
|
||||
import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
|
||||
import { TwoFactorComponent } from './accounts/two-factor.component';
|
||||
import { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';
|
||||
|
||||
import { PasswordGeneratorHistoryComponent } from './generator/password-generator-history.component';
|
||||
import { PasswordGeneratorComponent } from './generator/password-generator.component';
|
||||
@ -261,6 +262,12 @@ const routes: Routes = [
|
||||
canActivate: [AuthGuardService],
|
||||
data: { state: 'edit-send' },
|
||||
},
|
||||
{
|
||||
path: 'update-temp-password',
|
||||
component: UpdateTempPasswordComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
data: { state: 'update-temp-password' },
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
component: TabsComponent,
|
||||
|
@ -20,6 +20,7 @@ import { SetPasswordComponent } from './accounts/set-password.component';
|
||||
import { SsoComponent } from './accounts/sso.component';
|
||||
import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component';
|
||||
import { TwoFactorComponent } from './accounts/two-factor.component';
|
||||
import { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';
|
||||
|
||||
import { PasswordGeneratorHistoryComponent } from './generator/password-generator-history.component';
|
||||
import { PasswordGeneratorComponent } from './generator/password-generator.component';
|
||||
@ -226,8 +227,10 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
SendGroupingsComponent,
|
||||
SendListComponent,
|
||||
SendTypeComponent,
|
||||
SetPasswordComponent,
|
||||
SettingsComponent,
|
||||
ShareComponent,
|
||||
SsoComponent,
|
||||
StopClickDirective,
|
||||
StopPropDirective,
|
||||
SyncComponent,
|
||||
@ -235,9 +238,8 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
TrueFalseValueDirective,
|
||||
TwoFactorOptionsComponent,
|
||||
TwoFactorComponent,
|
||||
SsoComponent,
|
||||
UpdateTempPasswordComponent,
|
||||
ViewComponent,
|
||||
SetPasswordComponent,
|
||||
],
|
||||
entryComponents: [],
|
||||
providers: [
|
||||
|
Loading…
Reference in New Issue
Block a user