1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-24 12:06:15 +01:00

add/edit login custom fields

This commit is contained in:
Kyle Spearrin 2017-09-25 10:20:26 -04:00
parent eace0f32f0
commit 068fd5d06c
8 changed files with 153 additions and 18 deletions

View File

@ -765,5 +765,17 @@
}, },
"value": { "value": {
"message": "Value" "message": "Value"
},
"newCustomField": {
"message": "New Custom Field"
},
"cfTypeText": {
"message": "Text"
},
"cfTypeHidden": {
"message": "Hidden"
},
"cfTypeBoolean": {
"message": "Boolean"
} }
} }

View File

@ -2,8 +2,10 @@
.module('bit.vault') .module('bit.vault')
.controller('vaultAddLoginController', function ($scope, $state, $stateParams, loginService, folderService, .controller('vaultAddLoginController', function ($scope, $state, $stateParams, loginService, folderService,
cryptoService, $q, toastr, utilsService, $analytics, i18nService) { cryptoService, $q, toastr, utilsService, $analytics, i18nService, constantsService) {
$scope.i18n = i18nService; $scope.i18n = i18nService;
$scope.constants = constantsService;
$scope.addFieldType = constantsService.fieldType.text.toString();
var from = $stateParams.from, var from = $stateParams.from,
folderId = $stateParams.folderId; folderId = $stateParams.folderId;
@ -65,6 +67,25 @@
} }
}; };
$scope.addField = function (type) {
if (!$scope.login.fields) {
$scope.login.fields = [];
}
$scope.login.fields.push({
type: parseInt(type),
name: null,
value: null
});
};
$scope.removeField = function (field) {
var index = $scope.login.fields.indexOf(field);
if (index > -1) {
$scope.login.fields.splice(index, 1);
}
};
$scope.generatePassword = function () { $scope.generatePassword = function () {
$analytics.eventTrack('Clicked Generate Password'); $analytics.eventTrack('Clicked Generate Password');
$state.go('passwordGenerator', { $state.go('passwordGenerator', {

View File

@ -6,6 +6,7 @@ angular
$scope.i18n = i18nService; $scope.i18n = i18nService;
$scope.constants = constantsService; $scope.constants = constantsService;
$scope.showAttachments = !utilsService.isEdge(); $scope.showAttachments = !utilsService.isEdge();
$scope.addFieldType = constantsService.fieldType.text.toString();
var loginId = $stateParams.loginId; var loginId = $stateParams.loginId;
var fromView = $stateParams.fromView; var fromView = $stateParams.fromView;
var from = $stateParams.from; var from = $stateParams.from;
@ -94,6 +95,25 @@ angular
} }
}; };
$scope.addField = function (type) {
if (!$scope.login.fields) {
$scope.login.fields = [];
}
$scope.login.fields.push({
type: parseInt(type),
name: null,
value: null
});
};
$scope.removeField = function (field) {
var index = $scope.login.fields.indexOf(field);
if (index > -1) {
$scope.login.fields.splice(index, 1);
}
};
$scope.generatePassword = function () { $scope.generatePassword = function () {
if ($scope.login.password) { if ($scope.login.password) {
SweetAlert.swal({ SweetAlert.swal({

View File

@ -68,6 +68,45 @@
</div> </div>
</div> </div>
</div> </div>
<div class="list-section">
<div class="list-section-header">
{{i18n.customFields}}
</div>
<div class="list-section-items">
<div class="list-section-item list-section-item-table"
ng-if="login.fields && login.fields.length" ng-repeat="field in login.fields"
ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}">
<a href="#" stop-click ng-click="removeField(field)" class="action-button text-danger">
<i class="fa fa-close fa-lg"></i>
</a>
<div class="action-button-content">
<input id="field_name{{$index}}" type="text" name="Field.Name{{$index}}"
ng-model="field.name" class="item-label"
placeholder="{{i18n.name}}">
<input id="field_value{{$index}}" type="text" name="Field.Value{{$index}}"
ng-model="field.value" ng-if="field.type === constants.fieldType.text"
placeholder="{{i18n.value}}">
<input id="field_value{{$index}}" type="password" name="Field.Value{{$index}}"
ng-model="field.value" ng-if="field.type === constants.fieldType.hidden"
placeholder="{{i18n.value}}">
<input id="field_value{{$index}}" name="Field.Value{{$index}}" type="checkbox"
ng-model="field.value" data-ng-true-value="'true'"
ng-if="field.type === constants.fieldType.boolean">
</div>
</div>
<div class="list-section-item">
<a href="#" stop-click ng-click="addField(addFieldType)">
<i class="fa fa-plus-circle fa-fw fa-lg"></i> {{i18n.newCustomField}}
</a>
<select ng-model="addFieldType" class="field-type">
<option value="0">{{i18n.cfTypeText}}</option>
<option value="1">{{i18n.cfTypeHidden}}</option>
<option value="2">{{i18n.cfTypeBoolean}}</option>
</select>
</div>
</div>
</div>
</div> </div>
</div> </div>
</form> </form>

View File

@ -73,23 +73,43 @@
</div> </div>
</div> </div>
</div> </div>
<div class="list-section" ng-if="login.fields && login.fields.length"> <div class="list-section">
<div class="list-section-header"> <div class="list-section-header">
{{i18n.customFields}} {{i18n.customFields}}
</div> </div>
<div class="list-section-items"> <div class="list-section-items">
<div class="list-section-item" ng-repeat="field in login.fields" <div class="list-section-item list-section-item-table"
ng-if="login.fields && login.fields.length" ng-repeat="field in login.fields"
ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}"> ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}">
<label for="field_value{{$index}}" class="item-label">{{field.name}}</label> <a href="#" stop-click ng-click="removeField(field)" class="action-button text-danger">
<i class="fa fa-close fa-lg"></i>
</a>
<div class="action-button-content">
<input id="field_name{{$index}}" type="text" name="Field.Name{{$index}}"
ng-model="field.name" class="item-label"
placeholder="{{i18n.name}}">
<input id="field_value{{$index}}" type="text" name="Field.Value{{$index}}" <input id="field_value{{$index}}" type="text" name="Field.Value{{$index}}"
ng-model="field.value" ng-if="field.type === constants.fieldType.text"> ng-model="field.value" ng-if="field.type === constants.fieldType.text"
placeholder="{{i18n.value}}">
<input id="field_value{{$index}}" type="password" name="Field.Value{{$index}}" <input id="field_value{{$index}}" type="password" name="Field.Value{{$index}}"
ng-model="field.value" ng-if="field.type === constants.fieldType.hidden"> ng-model="field.value" ng-if="field.type === constants.fieldType.hidden"
placeholder="{{i18n.value}}">
<input id="field_value{{$index}}" name="Field.Value{{$index}}" type="checkbox" <input id="field_value{{$index}}" name="Field.Value{{$index}}" type="checkbox"
ng-model="field.value" data-ng-true-value="'true'" ng-model="field.value" data-ng-true-value="'true'"
ng-if="field.type === constants.fieldType.boolean"> ng-if="field.type === constants.fieldType.boolean">
</div> </div>
</div> </div>
<div class="list-section-item">
<a href="#" stop-click ng-click="addField(addFieldType)">
<i class="fa fa-plus-circle fa-fw fa-lg"></i> {{i18n.newCustomField}}
</a>
<select ng-model="addFieldType" class="field-type">
<option value="0">{{i18n.cfTypeText}}</option>
<option value="1">{{i18n.cfTypeHidden}}</option>
<option value="2">{{i18n.cfTypeBoolean}}</option>
</select>
</div>
</div>
</div> </div>
<div class="list-section"> <div class="list-section">
<div class="list-section-items"> <div class="list-section-items">

View File

@ -44,7 +44,7 @@
<i class="fa fa-lg" ng-class="[{'fa-eye': !showPassword}, {'fa-eye-slash': showPassword}]"></i> <i class="fa fa-lg" ng-class="[{'fa-eye': !showPassword}, {'fa-eye-slash': showPassword}]"></i>
</a> </a>
<span class="item-label">{{i18n.password}}</span> <span class="item-label">{{i18n.password}}</span>
<span ng-show="!showPassword">{{login.maskedPassword}}</span> <span ng-show="!showPassword" class="monospaced">{{login.maskedPassword}}</span>
<span id="password" ng-show="showPassword" class="monospaced">{{login.password}}</span> <span id="password" ng-show="showPassword" class="monospaced">{{login.password}}</span>
</div> </div>
<div class="list-section-item totp" ng-class="{'low': totpLow}" ng-if="login.totp && totpCode"> <div class="list-section-item totp" ng-class="{'low': totpLow}" ng-if="login.totp && totpCode">
@ -96,7 +96,7 @@
{{field.value || '&nbsp;'}} {{field.value || '&nbsp;'}}
</div> </div>
<div ng-if="field.type === constants.fieldType.hidden"> <div ng-if="field.type === constants.fieldType.hidden">
<span ng-show="!field.showValue">{{maskValue(field.value)}}</span> <span ng-show="!field.showValue" class="monospaced">{{maskValue(field.value)}}</span>
<span ng-show="field.showValue" class="monospaced">{{field.value}}</span> <span ng-show="field.showValue" class="monospaced">{{field.value}}</span>
</div> </div>
<div ng-if="field.type === constants.fieldType.boolean"> <div ng-if="field.type === constants.fieldType.boolean">

View File

@ -318,6 +318,29 @@
display: block; display: block;
width: 100%; width: 100%;
font-weight: normal; font-weight: normal;
margin-bottom: 5px;
}
&.list-section-item-table {
display: table;
width: 100%;
}
.action-button {
padding: 8px 10px 8px 5px;
display: table-cell;
width: 20px;
vertical-align: middle;
}
.action-button-content {
display: table-cell;
vertical-align: middle;
}
.field-type {
margin: 5px 0 0 27px;
width: ~"calc(100% - 27px)";
} }
.btn-list { .btn-list {
@ -387,7 +410,7 @@
} }
&.list-section-item-checkbox, &.list-section-item-input, &.list-section-item-slider { &.list-section-item-checkbox, &.list-section-item-input, &.list-section-item-slider {
label { label, .item-label {
font-size: @font-size-base; font-size: @font-size-base;
color: @text-color; color: @text-color;
display: inline; display: inline;

View File

@ -30,8 +30,8 @@ function initApiService() {
} }
// Desktop // Desktop
self.baseUrl = 'http://localhost:4000'; //self.baseUrl = 'http://localhost:4000';
self.identityBaseUrl = 'http://localhost:33656'; //self.identityBaseUrl = 'http://localhost:33656';
// Desktop HTTPS // Desktop HTTPS
//self.baseUrl = 'https://localhost:44377'; //self.baseUrl = 'https://localhost:44377';
@ -46,8 +46,8 @@ function initApiService() {
//self.identityBaseUrl = 'https://preview-identity.bitwarden.com'; //self.identityBaseUrl = 'https://preview-identity.bitwarden.com';
// Production // Production
//self.baseUrl = 'https://api.bitwarden.com'; self.baseUrl = 'https://api.bitwarden.com';
//self.identityBaseUrl = 'https://identity.bitwarden.com'; self.identityBaseUrl = 'https://identity.bitwarden.com';
}; };
// Auth APIs // Auth APIs