1
0
mirror of https://github.com/bitwarden/web synced 2025-12-06 00:03:28 +00:00

Compare commits

...

20 Commits

Author SHA1 Message Date
Kyle Spearrin
20112688ab bump version 2019-05-11 21:12:58 -04:00
Kyle Spearrin
2a19bdd8d1 correct launch icon 2019-04-26 22:44:10 -04:00
Kyle Spearrin
2d95806feb import all botostrap except toasts 2019-04-26 22:29:51 -04:00
Kyle Spearrin
40da48a106 password wallet txt importer 2019-04-26 20:55:15 -04:00
Kyle Spearrin
df81d9fd5f launch uri adjustments 2019-04-26 09:12:37 -04:00
Shawn Beachy
1060775cad Add a "launch site" button directly to the list of ciphers (#384)
* Add a button to launch the primary uri for a site straight from the list.

* Take cues from the add-edit component on properly checking if we can launch.

* Move the launch button to the dropdown menu.

* Take LoginView as launch parameter instead of LoginUriView.
2019-04-26 09:07:57 -04:00
Kyle Spearrin
96cc9c681c switch to terser minimizer with safari 10 fix 2019-04-20 20:54:50 -04:00
Kyle Spearrin
b4200fba60 support authBlocked message 2019-04-18 10:11:04 -04:00
Kyle Spearrin
2ded5228cb change plan is only for free subs 2019-04-17 11:06:21 -04:00
Kyle Spearrin
7be58fb884 update jslib 2019-04-15 23:04:13 -04:00
Kyle Spearrin
a29e9e11f7 focus length input on change 2019-04-15 22:37:29 -04:00
Kyle Spearrin
18c89e4fa5 premises 2019-04-04 00:45:53 -04:00
Kyle Spearrin
84dd370cfb add A11yTitleDirective 2019-04-02 09:48:49 -04:00
Kyle Spearrin
b45c79d65b send modal state messages 2019-04-02 09:29:20 -04:00
Kyle Spearrin
52a5086f7e dont use flex for password positioning 2019-04-01 13:56:34 -04:00
Kyle Spearrin
3980dc7e84 update bootstrap 2019-03-29 00:20:49 -04:00
Kyle Spearrin
ffd0608dda npm audit fix 2019-03-29 00:12:07 -04:00
Kyle Spearrin
322bc90920 drag n drop cleanup 2019-03-28 11:59:53 -04:00
Kovah
9685f2c2b3 Drag n drop sorting for custom fields (#370)
* Implement custom field ordering with new handle placement

* Update reference for jslib
2019-03-28 11:39:49 -04:00
Kyle Spearrin
342871a216 update jslib 2019-03-28 11:37:33 -04:00
17 changed files with 1119 additions and 381 deletions

2
jslib

Submodule jslib updated: a884f77938...741e060d99

1334
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -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",

View File

@@ -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;

View File

@@ -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,

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -223,6 +223,10 @@
Open the RememBear desktop application and navigate to "Settings" &rarr; "Account" &rarr; "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" &rarr; "Export" &rarr;
"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">

View File

@@ -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">

View File

@@ -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>

View File

@@ -43,4 +43,8 @@ export class PasswordGeneratorComponent extends BasePasswordGeneratorComponent {
this.modal = null;
});
}
lengthChanged() {
document.getElementById('length').focus();
}
}

View File

@@ -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>

View File

@@ -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}}

View File

@@ -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);

View File

@@ -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."

View File

@@ -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;
}

View File

@@ -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'],