mirror of
https://github.com/bitwarden/web
synced 2025-12-06 00:03:28 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20112688ab | ||
|
|
2a19bdd8d1 | ||
|
|
2d95806feb | ||
|
|
40da48a106 | ||
|
|
df81d9fd5f | ||
|
|
1060775cad | ||
|
|
96cc9c681c | ||
|
|
b4200fba60 | ||
|
|
2ded5228cb | ||
|
|
7be58fb884 | ||
|
|
a29e9e11f7 | ||
|
|
18c89e4fa5 | ||
|
|
84dd370cfb | ||
|
|
b45c79d65b | ||
|
|
52a5086f7e | ||
|
|
3980dc7e84 | ||
|
|
ffd0608dda | ||
|
|
322bc90920 | ||
|
|
9685f2c2b3 | ||
|
|
342871a216 |
2
jslib
2
jslib
Submodule jslib updated: a884f77938...741e060d99
1334
package-lock.json
generated
1334
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bitwarden-web",
|
||||
"version": "2.10.0",
|
||||
"version": "2.10.1",
|
||||
"scripts": {
|
||||
"sub:init": "git submodule update --init --recursive",
|
||||
"sub:update": "git submodule update --remote",
|
||||
@@ -23,7 +23,7 @@
|
||||
"lint:fix": "tslint src/**/*.ts --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler-cli": "^7.2.1",
|
||||
"@angular/compiler-cli": "^7.2.11",
|
||||
"@ngtools/webpack": "^7.2.2",
|
||||
"@types/jquery": "^3.3.6",
|
||||
"@types/lunr": "^2.1.6",
|
||||
@@ -45,9 +45,10 @@
|
||||
"gulp-google-webfonts": "^2.0.0",
|
||||
"html-loader": "^0.5.5",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"node-sass": "^4.9.3",
|
||||
"node-sass": "^4.11.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.0",
|
||||
"terser-webpack-plugin": "^1.2.3",
|
||||
"ts-loader": "^5.3.3",
|
||||
"tslint": "^5.12.1",
|
||||
"tslint-loader": "^3.5.4",
|
||||
@@ -58,6 +59,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "7.2.1",
|
||||
"@angular/cdk": "7.2.1",
|
||||
"@angular/common": "7.2.1",
|
||||
"@angular/compiler": "7.2.1",
|
||||
"@angular/core": "7.2.1",
|
||||
@@ -72,7 +74,7 @@
|
||||
"angular2-toaster": "6.1.0",
|
||||
"angulartics2": "6.3.0",
|
||||
"big-integer": "1.6.36",
|
||||
"bootstrap": "4.1.3",
|
||||
"bootstrap": "4.3.1",
|
||||
"braintree-web-drop-in": "1.13.0",
|
||||
"core-js": "2.6.2",
|
||||
"duo_web_sdk": "git+https://github.com/duosecurity/duo_web_sdk.git",
|
||||
|
||||
@@ -101,6 +101,9 @@ export class AppComponent implements OnDestroy, OnInit {
|
||||
case 'unlocked':
|
||||
this.notificationsService.updateConnection(false);
|
||||
break;
|
||||
case 'authBlocked':
|
||||
this.router.navigate(['/']);
|
||||
break;
|
||||
case 'logout':
|
||||
this.logOut(!!message.expired);
|
||||
break;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
@@ -153,13 +154,14 @@ import { VaultComponent } from './vault/vault.component';
|
||||
|
||||
import { IconComponent } from 'jslib/angular/components/icon.component';
|
||||
|
||||
import { A11yTitleDirective } from 'jslib/angular/directives/a11y-title.directive';
|
||||
import { ApiActionDirective } from 'jslib/angular/directives/api-action.directive';
|
||||
import { AutofocusDirective } from 'jslib/angular/directives/autofocus.directive';
|
||||
import { BlurClickDirective } from 'jslib/angular/directives/blur-click.directive';
|
||||
import { BoxRowDirective } from 'jslib/angular/directives/box-row.directive';
|
||||
import { FallbackSrcDirective } from 'jslib/angular/directives/fallback-src.directive';
|
||||
import { FlexCopyDirective } from 'jslib/angular/directives/flex-copy.directive';
|
||||
import { InputVerbatimDirective } from 'jslib/angular/directives/input-verbatim.directive';
|
||||
import { SelectCopyDirective } from 'jslib/angular/directives/select-copy.directive';
|
||||
import { StopClickDirective } from 'jslib/angular/directives/stop-click.directive';
|
||||
import { StopPropDirective } from 'jslib/angular/directives/stop-prop.directive';
|
||||
import { TrueFalseValueDirective } from 'jslib/angular/directives/true-false-value.directive';
|
||||
@@ -228,8 +230,10 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
}),
|
||||
ToasterModule.forRoot(),
|
||||
InfiniteScrollModule,
|
||||
DragDropModule,
|
||||
],
|
||||
declarations: [
|
||||
A11yTitleDirective,
|
||||
AcceptOrganizationComponent,
|
||||
AccountComponent,
|
||||
AddCreditComponent,
|
||||
@@ -265,7 +269,6 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
ExportComponent,
|
||||
ExposedPasswordsReportComponent,
|
||||
FallbackSrcDirective,
|
||||
FlexCopyDirective,
|
||||
FolderAddEditComponent,
|
||||
FooterComponent,
|
||||
FrontendLayoutComponent,
|
||||
@@ -330,6 +333,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
|
||||
ReusedPasswordsReportComponent,
|
||||
SearchCiphersPipe,
|
||||
SearchPipe,
|
||||
SelectCopyDirective,
|
||||
SettingsComponent,
|
||||
ShareComponent,
|
||||
StopClickDirective,
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
import { ModalComponent as BaseModalComponent } from 'jslib/angular/components/modal.component';
|
||||
import { Utils } from 'jslib/misc/utils';
|
||||
|
||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-modal',
|
||||
template: `<ng-template #container></ng-template>`,
|
||||
@@ -17,8 +19,8 @@ import { Utils } from 'jslib/misc/utils';
|
||||
export class ModalComponent extends BaseModalComponent {
|
||||
el: any = null;
|
||||
|
||||
constructor(componentFactoryResolver: ComponentFactoryResolver) {
|
||||
super(componentFactoryResolver);
|
||||
constructor(componentFactoryResolver: ComponentFactoryResolver, messagingService: MessagingService) {
|
||||
super(componentFactoryResolver, messagingService);
|
||||
}
|
||||
|
||||
ngOnDestroy() { /* Nothing */ }
|
||||
@@ -37,18 +39,22 @@ export class ModalComponent extends BaseModalComponent {
|
||||
|
||||
this.el.on('show.bs.modal', () => {
|
||||
this.onShow.emit();
|
||||
this.messagingService.send('modalShow');
|
||||
});
|
||||
this.el.on('shown.bs.modal', () => {
|
||||
this.onShown.emit();
|
||||
this.messagingService.send('modalShown');
|
||||
if (!Utils.isMobileBrowser) {
|
||||
this.el.find('*[appAutoFocus]').focus();
|
||||
}
|
||||
});
|
||||
this.el.on('hide.bs.modal', () => {
|
||||
this.onClose.emit();
|
||||
this.messagingService.send('modalClose');
|
||||
});
|
||||
this.el.on('hidden.bs.modal', () => {
|
||||
this.onClosed.emit();
|
||||
this.messagingService.send('modalClosed');
|
||||
if (this.parentContainer != null) {
|
||||
this.parentContainer.clear();
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ export class OrganizationSubscriptionComponent implements OnInit {
|
||||
}
|
||||
|
||||
async changePlan() {
|
||||
if (this.subscription == null) {
|
||||
if (this.subscription == null && this.sub.planType === PlanType.Free) {
|
||||
this.showChangePlan = !this.showChangePlan;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -223,6 +223,10 @@
|
||||
Open the RememBear desktop application and navigate to "Settings" → "Account" → "Export".
|
||||
Enter your master password and select the "Export Anyway" button to save the CSV file.
|
||||
</ng-container>
|
||||
<ng-container *ngIf="format === 'passwordwallettxt'">
|
||||
Open the PasswordWallet desktop application and navigate to "File" → "Export" →
|
||||
"Visible entries to text file". Enter your password and select the "Ok" button to save the TXT file.
|
||||
</ng-container>
|
||||
</app-callout>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
</div>
|
||||
<ul class="list-group list-group-flush" *ngIf="history.length">
|
||||
<li class="list-group-item d-flex" *ngFor="let h of history">
|
||||
<div>
|
||||
<div class="password-row">
|
||||
<div class="text-monospace password-wrapper" [innerHTML]="h.password | colorPassword"
|
||||
appFlexCopy></div>
|
||||
appSelectCopy></div>
|
||||
<small class="text-muted">{{h.date | date:'medium'}}</small>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<h1>{{'passwordGenerator' | i18n}}</h1>
|
||||
</div>
|
||||
<div class="card card-password bg-light my-4">
|
||||
<div class="card-body" [innerHTML]="password | colorPassword" appFlexCopy></div>
|
||||
<div class="card-body">
|
||||
<div class="password-wrapper" [innerHTML]="password | colorPassword" appSelectCopy></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check form-check-inline">
|
||||
@@ -33,7 +35,7 @@
|
||||
<div class="form-group col-4">
|
||||
<label for="length">{{'length' | i18n}}</label>
|
||||
<input id="length" class="form-control" type="number" min="5" max="128" [(ngModel)]="options.length"
|
||||
(blur)="saveOptions()">
|
||||
(blur)="saveOptions()" (change)="lengthChanged()">
|
||||
</div>
|
||||
<div class="form-group col-4">
|
||||
<label for="min-number">{{'minNumbers' | i18n}}</label>
|
||||
|
||||
@@ -43,4 +43,8 @@ export class PasswordGeneratorComponent extends BasePasswordGeneratorComponent {
|
||||
this.modal = null;
|
||||
});
|
||||
}
|
||||
|
||||
lengthChanged() {
|
||||
document.getElementById('length').focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +125,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngIf="cipher.login.hasUris">
|
||||
<div class="row" appBoxRow
|
||||
*ngFor="let u of cipher.login.uris; let i = index; trackBy:trackByFunction">
|
||||
<div class="row" *ngFor="let u of cipher.login.uris; let i = index; trackBy:trackByFunction">
|
||||
<div class="col-7 form-group">
|
||||
<label for="loginUri{{i}}">{{'uriPosition' | i18n : (i + 1)}}</label>
|
||||
<div class="input-group">
|
||||
@@ -361,8 +360,8 @@
|
||||
class="form-control"></textarea>
|
||||
</div>
|
||||
<h3 class="mt-4">{{'customFields' | i18n}}</h3>
|
||||
<ng-container *ngIf="cipher.hasFields">
|
||||
<div class="row" appBoxRow *ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction">
|
||||
<div cdkDropList (cdkDropListDropped)="drop($event)" *ngIf="cipher.hasFields">
|
||||
<div class="row" cdkDrag *ngFor="let f of cipher.fields; let i = index; trackBy:trackByFunction">
|
||||
<div class="col-5 form-group">
|
||||
<div class="d-flex">
|
||||
<label for="fieldName{{i}}">{{'name' | i18n}}</label>
|
||||
@@ -398,7 +397,8 @@
|
||||
title="{{'toggleVisibility' | i18n}}" (click)="toggleFieldValue(f)"
|
||||
tabindex="-1">
|
||||
<i class="fa fa-lg"
|
||||
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}"></i>
|
||||
[ngClass]="{'fa-eye': !f.showValue, 'fa-eye-slash': f.showValue}">
|
||||
</i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary"
|
||||
title="{{'copyValue' | i18n}}" (click)="copy(f.value, 'value', 'Field')"
|
||||
@@ -416,10 +416,14 @@
|
||||
title="{{'remove' | i18n}}">
|
||||
<i class="fa fa-minus-circle fa-lg"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-link text-muted cursor-move"
|
||||
title="{{'dragToSort' | i18n}}">
|
||||
<i class="fa fa-bars fa-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
<a href="#" appStopClick (click)="addField()" class="d-inline-block mb-2">
|
||||
<i class="fa fa-plus-circle fa-fw"></i> {{'newCustomField' | i18n}}
|
||||
</a>
|
||||
|
||||
@@ -29,11 +29,18 @@
|
||||
<i class="fa fa-cog fa-lg"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton">
|
||||
<a class="dropdown-item" href="#" appStopClick *ngIf="c.type === cipherType.Login"
|
||||
(click)="copy(c.login.password, 'password', 'password')">
|
||||
<i class="fa fa-fw fa-clipboard"></i>
|
||||
{{'copyPassword' | i18n}}
|
||||
</a>
|
||||
<ng-container *ngIf="c.type === cipherType.Login">
|
||||
<a class="dropdown-item" href="#" appStopClick
|
||||
(click)="copy(c.login.password, 'password', 'password')">
|
||||
<i class="fa fa-fw fa-clipboard"></i>
|
||||
{{'copyPassword' | i18n}}
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" appStopClick *ngIf="c.login.canLaunch"
|
||||
(click)="launch(c.login.launchUri)">
|
||||
<i class="fa fa-fw fa-share-square-o"></i>
|
||||
{{'launch' | i18n}}
|
||||
</a>
|
||||
</ng-container>
|
||||
<a class="dropdown-item" href="#" appStopClick (click)="attachments(c)">
|
||||
<i class="fa fa-fw fa-paperclip"></i>
|
||||
{{'attachments' | i18n}}
|
||||
|
||||
@@ -50,6 +50,11 @@ export class CiphersComponent extends BaseCiphersComponent implements OnDestroy
|
||||
(c as any).checked = select == null ? !(c as any).checked : select;
|
||||
}
|
||||
|
||||
launch(uri: string) {
|
||||
this.platformUtilsService.eventTrack('Launched Login URI');
|
||||
this.platformUtilsService.launchUri(uri);
|
||||
}
|
||||
|
||||
selectAll(select: boolean) {
|
||||
if (select) {
|
||||
this.selectAll(false);
|
||||
|
||||
@@ -151,6 +151,9 @@
|
||||
"value": {
|
||||
"message": "Value"
|
||||
},
|
||||
"dragToSort": {
|
||||
"message": "Drag to sort"
|
||||
},
|
||||
"cfTypeText": {
|
||||
"message": "Text"
|
||||
},
|
||||
@@ -406,9 +409,6 @@
|
||||
"unselectAll": {
|
||||
"message": "Unselect All"
|
||||
},
|
||||
"value": {
|
||||
"message": "Value"
|
||||
},
|
||||
"launch": {
|
||||
"message": "Launch"
|
||||
},
|
||||
@@ -1809,7 +1809,7 @@
|
||||
"message": "To upgrade your account to a premium membership you need to upload a valid license file."
|
||||
},
|
||||
"uploadLicenseFileOrg": {
|
||||
"message": "To create an on-premise hosted organization you need to upload a valid license file."
|
||||
"message": "To create an on-premises hosted organization you need to upload a valid license file."
|
||||
},
|
||||
"accountEmailMustBeVerified": {
|
||||
"message": "Your account's email address must be verified."
|
||||
|
||||
@@ -73,7 +73,44 @@ $grid-breakpoints: (
|
||||
xl: 4px
|
||||
);
|
||||
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
//@import "~bootstrap/scss/bootstrap";
|
||||
@import "~bootstrap/scss/_functions";
|
||||
@import "~bootstrap/scss/_variables";
|
||||
@import "~bootstrap/scss/_mixins";
|
||||
@import "~bootstrap/scss/_root";
|
||||
@import "~bootstrap/scss/_reboot";
|
||||
@import "~bootstrap/scss/_type";
|
||||
@import "~bootstrap/scss/_images";
|
||||
@import "~bootstrap/scss/_code";
|
||||
@import "~bootstrap/scss/_grid";
|
||||
@import "~bootstrap/scss/_tables";
|
||||
@import "~bootstrap/scss/_forms";
|
||||
@import "~bootstrap/scss/_buttons";
|
||||
@import "~bootstrap/scss/_transitions";
|
||||
@import "~bootstrap/scss/_dropdown";
|
||||
@import "~bootstrap/scss/_button-group";
|
||||
@import "~bootstrap/scss/_input-group";
|
||||
@import "~bootstrap/scss/_custom-forms";
|
||||
@import "~bootstrap/scss/_nav";
|
||||
@import "~bootstrap/scss/_navbar";
|
||||
@import "~bootstrap/scss/_card";
|
||||
@import "~bootstrap/scss/_breadcrumb";
|
||||
@import "~bootstrap/scss/_pagination";
|
||||
@import "~bootstrap/scss/_badge";
|
||||
@import "~bootstrap/scss/_jumbotron";
|
||||
@import "~bootstrap/scss/_alert";
|
||||
@import "~bootstrap/scss/_progress";
|
||||
@import "~bootstrap/scss/_media";
|
||||
@import "~bootstrap/scss/_list-group";
|
||||
@import "~bootstrap/scss/_close";
|
||||
//@import "~bootstrap/scss/_toasts";
|
||||
@import "~bootstrap/scss/_modal";
|
||||
@import "~bootstrap/scss/_tooltip";
|
||||
@import "~bootstrap/scss/_popover";
|
||||
@import "~bootstrap/scss/_carousel";
|
||||
@import "~bootstrap/scss/_spinners";
|
||||
@import "~bootstrap/scss/_utilities";
|
||||
@import "~bootstrap/scss/_print";
|
||||
@import "./plugins";
|
||||
|
||||
html {
|
||||
@@ -407,8 +444,13 @@ input[type="search"]::-webkit-search-cancel-button {
|
||||
}
|
||||
|
||||
.password-wrapper {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap;
|
||||
word-break: break-all;
|
||||
white-space: pre-wrap;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.password-row {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.password-number {
|
||||
@@ -785,3 +827,14 @@ img.logo {
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cdk-drag-preview {
|
||||
z-index: $zindex-tooltip !important;
|
||||
opacity: 0.8;
|
||||
background-color: $white;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.cursor-move {
|
||||
cursor: move !important;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
|
||||
const pjson = require('./package.json');
|
||||
|
||||
@@ -167,6 +168,13 @@ const config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
safari10: true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
|
||||
Reference in New Issue
Block a user