mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 09:43:23 +00:00
Merge branch 'master' into patrickhlauke-a11y-patch2
This commit is contained in:
@@ -51,7 +51,7 @@ export class LockComponent extends BaseLockComponent {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
async unlockBiometric() {
|
||||
async unlockBiometric(): Promise<boolean> {
|
||||
if (!this.biometricLock) {
|
||||
return;
|
||||
}
|
||||
@@ -68,8 +68,13 @@ export class LockComponent extends BaseLockComponent {
|
||||
showConfirmButton: false,
|
||||
});
|
||||
|
||||
await super.unlockBiometric();
|
||||
const success = await super.unlockBiometric();
|
||||
|
||||
Swal.close();
|
||||
// Avoid closing the error dialogs
|
||||
if (success) {
|
||||
Swal.close();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ 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';
|
||||
|
||||
@@ -24,14 +23,10 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
protected stateService: StateService, protected environmentService: EnvironmentService,
|
||||
protected passwordGenerationService: PasswordGenerationService,
|
||||
protected cryptoFunctionService: CryptoFunctionService, storageService: StorageService,
|
||||
syncService: SyncService, private userService: UserService) {
|
||||
syncService: SyncService) {
|
||||
super(authService, router, platformUtilsService, i18nService, stateService, environmentService, passwordGenerationService, cryptoFunctionService, storageService);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true).then(async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
}
|
||||
});
|
||||
await syncService.fullSync(true);
|
||||
};
|
||||
super.successRoute = '/tabs/vault';
|
||||
}
|
||||
|
||||
@@ -31,13 +31,6 @@ 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,7 +15,6 @@ 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';
|
||||
@@ -30,7 +29,7 @@ export class SsoComponent extends BaseSsoComponent {
|
||||
storageService: StorageService, stateService: StateService,
|
||||
platformUtilsService: PlatformUtilsService, apiService: ApiService,
|
||||
cryptoFunctionService: CryptoFunctionService, passwordGenerationService: PasswordGenerationService,
|
||||
syncService: SyncService, environmentService: EnvironmentService, private userService: UserService) {
|
||||
syncService: SyncService, environmentService: EnvironmentService) {
|
||||
super(authService, router, i18nService, route, storageService, stateService, platformUtilsService,
|
||||
apiService, cryptoFunctionService, environmentService, passwordGenerationService);
|
||||
|
||||
@@ -45,13 +44,5 @@ 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,7 +20,6 @@ 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';
|
||||
|
||||
@@ -45,16 +44,11 @@ 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,
|
||||
private userService: UserService) {
|
||||
storageService: StorageService, route: ActivatedRoute, private messagingService: MessagingService) {
|
||||
super(authService, router, i18nService, apiService, platformUtilsService, window, environmentService,
|
||||
stateService, storageService, route);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
return syncService.fullSync(true).then(async () => {
|
||||
if (await this.userService.getForcePasswordReset()) {
|
||||
this.router.navigate(['update-temp-password']);
|
||||
}
|
||||
});
|
||||
super.onSuccessfulLogin = () => {
|
||||
return syncService.fullSync(true);
|
||||
};
|
||||
super.successRoute = '/tabs/vault';
|
||||
this.webAuthnNewTab = this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari();
|
||||
|
||||
@@ -40,6 +40,7 @@ import { SettingsComponent } from './settings/settings.component';
|
||||
import { SyncComponent } from './settings/sync.component';
|
||||
import { VaultTimeoutInputComponent } from './settings/vault-timeout-input.component';
|
||||
|
||||
import { AddEditCustomFieldsComponent } from './vault/add-edit-custom-fields.component';
|
||||
import { AddEditComponent } from './vault/add-edit.component';
|
||||
import { AttachmentsComponent } from './vault/attachments.component';
|
||||
import { CiphersComponent } from './vault/ciphers.component';
|
||||
@@ -48,6 +49,7 @@ import { CurrentTabComponent } from './vault/current-tab.component';
|
||||
import { GroupingsComponent } from './vault/groupings.component';
|
||||
import { PasswordHistoryComponent } from './vault/password-history.component';
|
||||
import { ShareComponent } from './vault/share.component';
|
||||
import { ViewCustomFieldsComponent } from './vault/view-custom-fields.component';
|
||||
import { ViewComponent } from './vault/view.component';
|
||||
|
||||
import { EffluxDatesComponent as SendEffluxDatesComponent } from './send/efflux-dates.component';
|
||||
@@ -248,6 +250,8 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
PasswordRepromptComponent,
|
||||
SetPinComponent,
|
||||
VaultTimeoutInputComponent,
|
||||
AddEditCustomFieldsComponent,
|
||||
ViewCustomFieldsComponent,
|
||||
],
|
||||
entryComponents: [],
|
||||
providers: [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "../css/webfonts.css";
|
||||
@import "../../../jslib/angular/src/scss/webfonts.css";
|
||||
@import "variables.scss";
|
||||
@import "base.scss";
|
||||
@import "grid.scss";
|
||||
|
||||
53
src/popup/vault/add-edit-custom-fields.component.html
Normal file
53
src/popup/vault/add-edit-custom-fields.component.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
{{'customFields' | i18n}}
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<!-- Current custom fields -->
|
||||
<div cdkDropList (cdkDropListDropped)="drop($event)" *ngIf="cipher.hasFields">
|
||||
<div class="box-content-row box-content-row-multi box-draggable-row" appBoxRow cdkDrag
|
||||
*ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction"
|
||||
[ngClass]="{'box-content-row-checkbox': f.type === fieldType.Boolean}">
|
||||
<a href="#" appStopClick (click)="removeField(f)" appA11yTitle="{{'remove' | i18n}}">
|
||||
<i class="fa fa-minus-circle fa-lg" aria-hidden="true"></i>
|
||||
</a>
|
||||
<label for="fieldName{{i}}" class="sr-only">{{'name' | i18n}}</label>
|
||||
<label for="fieldValue{{i}}" class="sr-only">{{'value' | i18n}}</label>
|
||||
<div class="row-main">
|
||||
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name" class="row-label"
|
||||
placeholder="{{'name' | i18n}}" appInputVerbatim>
|
||||
<!--Custom Field: Text-->
|
||||
<input id="fieldValue{{i}}" type="text" name="Field.Value{{i}}" [(ngModel)]="f.value"
|
||||
*ngIf="f.type === fieldType.Text" placeholder="{{'value' | i18n}}" appInputVerbatim>
|
||||
<!--Custom Field: Hidden-->
|
||||
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}" name="Field.Value{{i}}"
|
||||
[(ngModel)]="f.value" class="monospaced" appInputVerbatim *ngIf="f.type === fieldType.Hidden"
|
||||
placeholder="{{'value' | i18n}}" [disabled]="!cipher.viewPassword && !f.newField">
|
||||
</div>
|
||||
<!--Custom Field: Boolean-->
|
||||
<input id="fieldValue{{i}}" name="Field.Value{{i}}" type="checkbox" [(ngModel)]="f.value"
|
||||
*ngIf="f.type === fieldType.Boolean" appTrueFalseValue trueValue="true" falseValue="false">
|
||||
<div class="action-buttons" *ngIf="f.type === fieldType.Hidden && (cipher.viewPassword || f.newField)">
|
||||
<a class="row-btn" href="#" appStopClick appBlurClick appA11yTitle="{{'toggleVisibility' | i18n}}"
|
||||
(click)="toggleFieldValue(f)">
|
||||
<i class="fa fa-lg" aria-hidden="true"
|
||||
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="drag-handle" appA11yTitle="{{'dragToSort' | i18n}}" cdkDragHandle>
|
||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Add new custom field -->
|
||||
<div class="box-content-row box-content-row-newmulti" appBoxRow>
|
||||
<a href="#" appStopClick (click)="addField()">
|
||||
<i class="fa fa-plus-circle fa-fw fa-lg" aria-hidden="true"></i> {{'newCustomField' | i18n}}
|
||||
</a>
|
||||
<label for="addFieldType" class="sr-only">{{'type' | i18n}}</label>
|
||||
<select id="addFieldType" name="AddFieldType" [(ngModel)]="addFieldType" class="field-type">
|
||||
<option *ngFor="let o of addFieldTypeOptions" [ngValue]="o.value">{{o.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
18
src/popup/vault/add-edit-custom-fields.component.ts
Normal file
18
src/popup/vault/add-edit-custom-fields.component.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import {
|
||||
AddEditCustomFieldsComponent as BaseAddEditCustomFieldsComponent
|
||||
} from 'jslib-angular/components/add-edit-custom-fields.component';
|
||||
|
||||
import { EventService } from 'jslib-common/abstractions/event.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-vault-add-edit-custom-fields',
|
||||
templateUrl: 'add-edit-custom-fields.component.html',
|
||||
})
|
||||
export class AddEditCustomFieldsComponent extends BaseAddEditCustomFieldsComponent {
|
||||
constructor(i18nService: I18nService, eventService: EventService) {
|
||||
super(i18nService, eventService);
|
||||
}
|
||||
}
|
||||
@@ -324,56 +324,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
{{'customFields' | i18n}}
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<div cdkDropList (cdkDropListDropped)="drop($event)" *ngIf="cipher.hasFields">
|
||||
<div class="box-content-row box-content-row-multi box-draggable-row" appBoxRow cdkDrag
|
||||
*ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction"
|
||||
[ngClass]="{'box-content-row-checkbox': f.type === fieldType.Boolean}">
|
||||
<button type="button" appStopClick (click)="removeField(f)" appA11yTitle="{{'remove' | i18n}}">
|
||||
<i class="fa fa-minus-circle fa-lg" aria-hidden="true"></i>
|
||||
</button>
|
||||
<label for="fieldName{{i}}" class="sr-only">{{'name' | i18n}}</label>
|
||||
<label for="fieldValue{{i}}" class="sr-only">{{'value' | i18n}}</label>
|
||||
<div class="row-main">
|
||||
<input id="fieldName{{i}}" type="text" name="Field.Name{{i}}" [(ngModel)]="f.name"
|
||||
class="row-label" placeholder="{{'name' | i18n}}" appInputVerbatim>
|
||||
<input id="fieldValue{{i}}" type="text" name="Field.Value{{i}}" [(ngModel)]="f.value"
|
||||
*ngIf="f.type === fieldType.Text" placeholder="{{'value' | i18n}}" appInputVerbatim>
|
||||
<input id="fieldValue{{i}}" type="{{f.showValue ? 'text' : 'password'}}"
|
||||
name="Field.Value{{i}}" [(ngModel)]="f.value" class="monospaced" appInputVerbatim
|
||||
*ngIf="f.type === fieldType.Hidden" placeholder="{{'value' | i18n}}"
|
||||
[disabled]="!cipher.viewPassword && !f.newField">
|
||||
</div>
|
||||
<input id="fieldValue{{i}}" name="Field.Value{{i}}" type="checkbox" [(ngModel)]="f.value"
|
||||
*ngIf="f.type === fieldType.Boolean" appTrueFalseValue trueValue="true" falseValue="false">
|
||||
<div class="action-buttons"
|
||||
*ngIf="f.type === fieldType.Hidden && (cipher.viewPassword || f.newField)">
|
||||
<button type="button" class="row-btn" appStopClick appBlurClick
|
||||
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)">
|
||||
<i class="fa fa-lg" aria-hidden="true"
|
||||
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="drag-handle" appA11yTitle="{{'dragToSort' | i18n}}" cdkDragHandle>
|
||||
<i class="fa fa-bars" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-content-row box-content-row-newmulti" appBoxRow>
|
||||
<button type="button" appStopClick (click)="addField()">
|
||||
<i class="fa fa-plus-circle fa-fw fa-lg" aria-hidden="true"></i> {{'newCustomField' | i18n}}
|
||||
</button>
|
||||
<label for="addFieldType" class="sr-only">{{'type' | i18n}}</label>
|
||||
<select id="addFieldType" name="AddFieldType" [(ngModel)]="addFieldType" class="field-type">
|
||||
<option *ngFor="let o of addFieldTypeOptions" [ngValue]="o.value">{{o.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-vault-add-edit-custom-fields [cipher]="cipher" [editMode]="editMode"></app-vault-add-edit-custom-fields>
|
||||
<div class="box" *ngIf="allowOwnershipOptions()">
|
||||
<div class="box-header">
|
||||
{{'ownership' | i18n}}
|
||||
|
||||
@@ -156,7 +156,12 @@ export class CurrentTabComponent implements OnInit, OnDestroy {
|
||||
this.platformUtilsService.copyToClipboard(this.totpCode, { window: window });
|
||||
}
|
||||
if (this.popupUtilsService.inPopup(window)) {
|
||||
BrowserApi.closePopup(window);
|
||||
if (this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari()) {
|
||||
BrowserApi.closePopup(window);
|
||||
} else {
|
||||
// Slight delay to fix bug in Chromium browsers where popup closes without copying totp to clipboard
|
||||
setTimeout(() => BrowserApi.closePopup(window), 50);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
this.ngZone.run(() => {
|
||||
|
||||
37
src/popup/vault/view-custom-fields.component.html
Normal file
37
src/popup/vault/view-custom-fields.component.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<ng-container>
|
||||
<div class="box-header">
|
||||
{{'customFields' | i18n}}
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-flex" *ngFor="let field of cipher.fields">
|
||||
<div class="row-main">
|
||||
<span class="row-label">{{field.name}}</span>
|
||||
<div *ngIf="field.type === fieldType.Text">
|
||||
{{field.value || ' '}}
|
||||
</div>
|
||||
<div *ngIf="field.type === fieldType.Hidden">
|
||||
<span [hidden]="!field.showValue" class="monospaced show-whitespace">{{field.value}}</span>
|
||||
<span [hidden]="field.showValue" class="monospaced">{{field.maskedValue}}</span>
|
||||
</div>
|
||||
<div *ngIf="field.type === fieldType.Boolean">
|
||||
<i class="fa fa-check-square-o" *ngIf="field.value === 'true'" aria-hidden="true"></i>
|
||||
<i class="fa fa-square-o" *ngIf="field.value !== 'true'" aria-hidden="true"></i>
|
||||
<span class="sr-only">{{field.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'toggleVisibility' | i18n}}"
|
||||
*ngIf="field.type === fieldType.Hidden && cipher.viewPassword"
|
||||
(click)="toggleFieldValue(field)">
|
||||
<i class="fa fa-lg" aria-hidden="true"
|
||||
[ngClass]="{'fa-eye': !field.showValue, 'fa-eye-slash': field.showValue}"></i>
|
||||
</a>
|
||||
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'copyValue' | i18n}}"
|
||||
*ngIf="field.value && field.type !== fieldType.Boolean && !(field.type === fieldType.Hidden && !cipher.viewPassword)"
|
||||
(click)="copy(field.value, 'value', field.type === fieldType.Hidden ? 'H_Field' : 'Field')">
|
||||
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
19
src/popup/vault/view-custom-fields.component.ts
Normal file
19
src/popup/vault/view-custom-fields.component.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
Component,
|
||||
} from '@angular/core';
|
||||
|
||||
import { EventService } from 'jslib-common/abstractions/event.service';
|
||||
|
||||
import {
|
||||
ViewCustomFieldsComponent as BaseViewCustomFieldsComponent
|
||||
} from 'jslib-angular/components/view-custom-fields.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-vault-view-custom-fields',
|
||||
templateUrl: 'view-custom-fields.component.html',
|
||||
})
|
||||
export class ViewCustomFieldsComponent extends BaseViewCustomFieldsComponent {
|
||||
constructor(eventService: EventService) {
|
||||
super(eventService);
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@
|
||||
(click)="launch(u)">
|
||||
<i class="fa fa-lg fa-share-square-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="button" class="row-btn" appStopClick appA11yTitle="{{'copyUri' | i18n}}"
|
||||
<button type="button" class="row-btn"appStopClick appA11yTitle="{{'copyUri' | i18n}}"
|
||||
(click)="copy(u.uri, u.isWebsite ? 'website' : 'uri', 'URI')">
|
||||
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||
</button>
|
||||
@@ -221,41 +221,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="box" *ngIf="cipher.hasFields">
|
||||
<div class="box-header">
|
||||
{{'customFields' | i18n}}
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-flex" *ngFor="let field of cipher.fields">
|
||||
<div class="row-main">
|
||||
<span class="row-label">{{field.name}}</span>
|
||||
<div *ngIf="field.type === fieldType.Text">
|
||||
{{field.value || ' '}}
|
||||
</div>
|
||||
<div *ngIf="field.type === fieldType.Hidden">
|
||||
<span [hidden]="!field.showValue" class="monospaced show-whitespace">{{field.value}}</span>
|
||||
<span [hidden]="field.showValue" class="monospaced">{{field.maskedValue}}</span>
|
||||
</div>
|
||||
<div *ngIf="field.type === fieldType.Boolean">
|
||||
<i class="fa fa-check-square-o" *ngIf="field.value === 'true'" aria-hidden="true"></i>
|
||||
<i class="fa fa-square-o" *ngIf="field.value !== 'true'" aria-hidden="true"></i>
|
||||
<span class="sr-only">{{field.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<button type="button" class="row-btn" appStopClick appA11yTitle="{{'toggleVisibility' | i18n}}"
|
||||
*ngIf="field.type === fieldType.Hidden && cipher.viewPassword"
|
||||
(click)="toggleFieldValue(field)">
|
||||
<i class="fa fa-lg" aria-hidden="true"
|
||||
[ngClass]="{'fa-eye': !field.showValue, 'fa-eye-slash': field.showValue}"></i>
|
||||
</button>
|
||||
<button type="button" class="row-btn" appStopClick appA11yTitle="{{'copyValue' | i18n}}"
|
||||
*ngIf="field.value && field.type !== fieldType.Boolean && !(field.type === fieldType.Hidden && !cipher.viewPassword)"
|
||||
(click)="copy(field.value, 'value', field.type === fieldType.Hidden ? 'H_Field' : 'Field')">
|
||||
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-vault-view-custom-fields [cipher]="cipher" [promptPassword]="promptPassword.bind(this)"
|
||||
[copy]="copy.bind(this)"></app-vault-view-custom-fields>
|
||||
</div>
|
||||
<div class="box" *ngIf="cipher.hasAttachments && (canAccessPremium || cipher.organizationId) && showAttachments">
|
||||
<div class="box-header">
|
||||
@@ -269,12 +236,12 @@
|
||||
<i class="fa fa-download fa-fw row-sub-icon" *ngIf="!attachment.downloading" aria-hidden="true"></i>
|
||||
<i class="fa fa-spinner fa-fw fa-spin row-sub-icon" *ngIf="attachment.downloading"
|
||||
aria-hidden="true"></i>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box list">
|
||||
<div class="box-content single-line">
|
||||
<button type="button" class="box-content-row" appStopClick appBlurClick (click)="fillCipher()"
|
||||
<<button type="button" class="box-content-row" appStopClick appBlurClick (click)="fillCipher()"
|
||||
*ngIf="cipher.type !== cipherType.SecureNote && !cipher.isDeleted && !inPopout">
|
||||
<div class="row-main text-primary">
|
||||
<div class="icon text-primary" aria-hidden="true">
|
||||
|
||||
Reference in New Issue
Block a user