mirror of
https://github.com/bitwarden/desktop.git
synced 2025-02-17 01:21:26 +01:00
[Reset Password v1] Update Temp Password (#1015)
This commit is contained in:
parent
816249a48a
commit
d82378a7a0
@ -21,6 +21,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';
|
||||
|
||||
@ -46,11 +47,15 @@ export class LoginComponent extends BaseLoginComponent implements OnDestroy {
|
||||
environmentService: EnvironmentService, passwordGenerationService: PasswordGenerationService,
|
||||
cryptoFunctionService: CryptoFunctionService, storageService: StorageService,
|
||||
private broadcasterService: BroadcasterService, private ngZone: NgZone,
|
||||
private messagingService: MessagingService) {
|
||||
private messagingService: MessagingService, private userService: UserService) {
|
||||
super(authService, router, platformUtilsService, i18nService, stateService, environmentService,
|
||||
passwordGenerationService, cryptoFunctionService, storageService);
|
||||
super.onSuccessfulLogin = () => {
|
||||
return syncService.fullSync(true);
|
||||
return syncService.fullSync(true).then(async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,13 @@ export class SetPasswordComponent extends BaseSetPasswordComponent implements On
|
||||
private broadcasterService: BroadcasterService, private ngZone: NgZone) {
|
||||
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';
|
||||
|
||||
@ -28,7 +29,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
storageService: StorageService, stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService, apiService: ApiService,
|
||||
cryptoFunctionService: CryptoFunctionService, environmentService: EnvironmentService,
|
||||
passwordGenerationService: PasswordGenerationService) {
|
||||
passwordGenerationService: PasswordGenerationService, private userService: UserService) {
|
||||
super(authService, router, i18nService, route, storageService, stateService, platformUtilsService,
|
||||
apiService, cryptoFunctionService, environmentService, passwordGenerationService);
|
||||
super.onSuccessfulLogin = () => {
|
||||
@ -36,5 +37,12 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
};
|
||||
this.redirectUri = 'bitwarden://sso-callback';
|
||||
this.clientId = 'desktop';
|
||||
super.onSuccessfulLoginNavigate = async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
} else {
|
||||
this.router.navigate([this.successRoute]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,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 { ModalComponent } from 'jslib-angular/components/modal.component';
|
||||
import { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib-angular/components/two-factor.component';
|
||||
@ -39,11 +40,16 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||
i18nService: I18nService, apiService: ApiService,
|
||||
platformUtilsService: PlatformUtilsService, syncService: SyncService,
|
||||
environmentService: EnvironmentService, private componentFactoryResolver: ComponentFactoryResolver,
|
||||
stateService: StateService, storageService: StorageService, route: ActivatedRoute) {
|
||||
stateService: StateService, storageService: StorageService, route: ActivatedRoute,
|
||||
private userService: UserService) {
|
||||
super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService,
|
||||
stateService, storageService, route);
|
||||
super.onSuccessfulLogin = () => {
|
||||
return syncService.fullSync(true);
|
||||
return syncService.fullSync(true).then(async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
75
src/app/accounts/update-temp-password.component.html
Normal file
75
src/app/accounts/update-temp-password.component.html
Normal file
@ -0,0 +1,75 @@
|
||||
<form id="update-temp-password-page" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<div class="content">
|
||||
<app-callout type="warning" title="{{'updateMasterPassword' | i18n}}">
|
||||
{{'updateMasterPasswordWarning' | i18n}}
|
||||
</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
|
||||
[appAutofocus]="masterPassword === ''" (input)="updatePasswordStrength()">
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
|
||||
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>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
|
||||
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>
|
||||
<div class="buttons">
|
||||
<button type="submit" class="btn primary block" [disabled]="form.loading" appBlurClick>
|
||||
<b [hidden]="form.loading">{{'submit' | i18n}}</b>
|
||||
<i class="fa fa-spinner fa-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
<a (click)="logOut()" class="btn block">{{'logOut' | i18n}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
62
src/app/accounts/update-temp-password.component.ts
Normal file
62
src/app/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);
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ import { RegisterComponent } from './accounts/register.component';
|
||||
import { SetPasswordComponent } from './accounts/set-password.component';
|
||||
import { SsoComponent } from './accounts/sso.component';
|
||||
import { TwoFactorComponent } from './accounts/two-factor.component';
|
||||
import { UpdateTempPasswordComponent } from './accounts/update-temp-password.component';
|
||||
|
||||
import { SendComponent } from './send/send.component';
|
||||
|
||||
@ -48,6 +49,11 @@ const routes: Routes = [
|
||||
component: SendComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: 'update-temp-password',
|
||||
component: UpdateTempPasswordComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -26,6 +26,7 @@ import { SettingsComponent } from './accounts/settings.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 { CalloutComponent } from 'jslib-angular/components/callout.component';
|
||||
import { IconComponent } from 'jslib-angular/components/icon.component';
|
||||
@ -215,6 +216,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
TrueFalseValueDirective,
|
||||
TwoFactorComponent,
|
||||
TwoFactorOptionsComponent,
|
||||
UpdateTempPasswordComponent,
|
||||
VaultComponent,
|
||||
ViewComponent,
|
||||
],
|
||||
|
@ -1693,5 +1693,14 @@
|
||||
},
|
||||
"passwordConfirmationDesc": {
|
||||
"message": "This action is protected. To continue, please re-enter your master password to verify your identity."
|
||||
},
|
||||
"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."
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#register-page, #hint-page, #two-factor-page {
|
||||
#register-page, #hint-page, #two-factor-page, #update-temp-password-page {
|
||||
padding-top: 20px;
|
||||
|
||||
.content {
|
||||
@ -39,7 +39,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#login-page, #register-page, #hint-page, #two-factor-page, #lock-page {
|
||||
#login-page, #register-page, #hint-page, #two-factor-page, #lock-page, #update-temp-password-page {
|
||||
.content {
|
||||
width: 300px;
|
||||
transition: width 0.25s linear;
|
||||
@ -184,7 +184,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#register-page {
|
||||
#register-page, #update-temp-password-page {
|
||||
.content {
|
||||
width: 400px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user