mirror of
https://github.com/bitwarden/browser.git
synced 2024-09-27 04:03:00 +02:00
add support for add/edit/view of login uris
This commit is contained in:
parent
d67b95421c
commit
f952cd5642
2
jslib
2
jslib
@ -1 +1 @@
|
|||||||
Subproject commit 0d80216921efa53dfc095fd25dde9b370a070da8
|
Subproject commit 848f50afe7b9dc9e193a036c062ef2f0e4d93018
|
@ -455,6 +455,9 @@
|
|||||||
"uri": {
|
"uri": {
|
||||||
"message": "URI"
|
"message": "URI"
|
||||||
},
|
},
|
||||||
|
"newUri": {
|
||||||
|
"message": "New URI"
|
||||||
|
},
|
||||||
"addedItem": {
|
"addedItem": {
|
||||||
"message": "Added item"
|
"message": "Added item"
|
||||||
},
|
},
|
||||||
@ -989,5 +992,33 @@
|
|||||||
},
|
},
|
||||||
"passwordSafe": {
|
"passwordSafe": {
|
||||||
"message": "This password was not found in any known data breaches. It should be safe to use."
|
"message": "This password was not found in any known data breaches. It should be safe to use."
|
||||||
|
},
|
||||||
|
"baseDomain": {
|
||||||
|
"message": "Base domain"
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"message": "Host",
|
||||||
|
"description": "A URL's host value. For example, the host of https://sub.domain.com:443 is 'sub.domain.com:443'."
|
||||||
|
},
|
||||||
|
"exact": {
|
||||||
|
"message": "Exact"
|
||||||
|
},
|
||||||
|
"startsWith": {
|
||||||
|
"message": "Starts with"
|
||||||
|
},
|
||||||
|
"regEx": {
|
||||||
|
"message": "Regular expression",
|
||||||
|
"description": "A programming term, also known as 'RegEx'."
|
||||||
|
},
|
||||||
|
"autofillDetection": {
|
||||||
|
"message": "Auto-fill Detection",
|
||||||
|
"description": "URI auto-fill match detection."
|
||||||
|
},
|
||||||
|
"defaultAutofillDetection": {
|
||||||
|
"message": "Default auto-fill detection",
|
||||||
|
"description": "Default URI auto-fill match detection."
|
||||||
|
},
|
||||||
|
"toggleOptions": {
|
||||||
|
"message": "Toggle Options"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,12 @@ angular
|
|||||||
folderId: folderId,
|
folderId: folderId,
|
||||||
name: $stateParams.name,
|
name: $stateParams.name,
|
||||||
type: constantsService.cipherType.login,
|
type: constantsService.cipherType.login,
|
||||||
login: {},
|
login: {
|
||||||
|
uris: [{
|
||||||
|
uri: null,
|
||||||
|
match: null
|
||||||
|
}]
|
||||||
|
},
|
||||||
identity: {},
|
identity: {},
|
||||||
card: {},
|
card: {},
|
||||||
secureNote: {
|
secureNote: {
|
||||||
@ -23,13 +28,15 @@ angular
|
|||||||
};
|
};
|
||||||
|
|
||||||
if ($stateParams.uri) {
|
if ($stateParams.uri) {
|
||||||
$scope.cipher.login.uri = $stateParams.uri;
|
$scope.cipher.login.uris[0].uri = $stateParams.uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($stateParams.cipher) {
|
if ($stateParams.cipher) {
|
||||||
angular.extend($scope.cipher, $stateParams.cipher);
|
angular.extend($scope.cipher, $stateParams.cipher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setUriMatchValues();
|
||||||
|
|
||||||
$timeout(function () {
|
$timeout(function () {
|
||||||
popupUtilsService.initListSectionItemListeners(document, angular);
|
popupUtilsService.initListSectionItemListeners(document, angular);
|
||||||
|
|
||||||
@ -109,6 +116,50 @@ angular
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.addUri = function () {
|
||||||
|
if (!$scope.cipher.login) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$scope.cipher.login.uris) {
|
||||||
|
$scope.cipher.login.uris = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.cipher.login.uris.push({
|
||||||
|
uri: null,
|
||||||
|
match: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
$timeout(function () {
|
||||||
|
popupUtilsService.initListSectionItemListeners(document, angular);
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.removeUri = function (uri) {
|
||||||
|
if (!$scope.cipher.login || !$scope.cipher.login.uris) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = $scope.cipher.login.uris.indexOf(uri);
|
||||||
|
if (index > -1) {
|
||||||
|
$scope.cipher.login.uris.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.uriMatchChanged = function (uri) {
|
||||||
|
uri.showOptions = uri.showOptions == null ? true : uri.showOptions;
|
||||||
|
if ((!uri.matchValue && uri.matchValue !== 0) || uri.matchValue === '') {
|
||||||
|
uri.match = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uri.match = parseInt(uri.matchValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleUriOptions = function (u) {
|
||||||
|
u.showOptions = u.showOptions == null && u.match != null ? false : !u.showOptions;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.addField = function (type) {
|
$scope.addField = function (type) {
|
||||||
if (!$scope.cipher.fields) {
|
if (!$scope.cipher.fields) {
|
||||||
$scope.cipher.fields = [];
|
$scope.cipher.fields = [];
|
||||||
@ -142,4 +193,14 @@ angular
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setUriMatchValues() {
|
||||||
|
if ($scope.cipher.login && $scope.cipher.login.uris) {
|
||||||
|
for (var i = 0; i < $scope.cipher.login.uris.length; i++) {
|
||||||
|
$scope.cipher.login.uris[i].matchValue =
|
||||||
|
$scope.cipher.login.uris[i].match || $scope.cipher.login.uris[i].match === 0 ?
|
||||||
|
$scope.cipher.login.uris[i].match.toString() : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -24,12 +24,14 @@ angular
|
|||||||
|
|
||||||
if ($stateParams.cipher) {
|
if ($stateParams.cipher) {
|
||||||
angular.extend($scope.cipher, $stateParams.cipher);
|
angular.extend($scope.cipher, $stateParams.cipher);
|
||||||
|
setUriMatchValues();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cipherService.get(cipherId).then(function (cipher) {
|
cipherService.get(cipherId).then(function (cipher) {
|
||||||
return cipher.decrypt();
|
return cipher.decrypt();
|
||||||
}).then(function (model) {
|
}).then(function (model) {
|
||||||
$scope.cipher = model;
|
$scope.cipher = model;
|
||||||
|
setUriMatchValues();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +129,50 @@ angular
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.addUri = function () {
|
||||||
|
if (!$scope.cipher.login) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$scope.cipher.login.uris) {
|
||||||
|
$scope.cipher.login.uris = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.cipher.login.uris.push({
|
||||||
|
uri: null,
|
||||||
|
match: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
$timeout(function () {
|
||||||
|
popupUtilsService.initListSectionItemListeners(document, angular);
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.removeUri = function (uri) {
|
||||||
|
if (!$scope.cipher.login || !$scope.cipher.login.uris) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = $scope.cipher.login.uris.indexOf(uri);
|
||||||
|
if (index > -1) {
|
||||||
|
$scope.cipher.login.uris.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.uriMatchChanged = function (uri) {
|
||||||
|
uri.showOptions = uri.showOptions == null ? true : uri.showOptions;
|
||||||
|
if ((!uri.matchValue && uri.matchValue !== 0) || uri.matchValue === '') {
|
||||||
|
uri.match = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uri.match = parseInt(uri.matchValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleUriOptions = function (u) {
|
||||||
|
u.showOptions = u.showOptions == null && u.match != null ? false : !u.showOptions;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.addField = function (type) {
|
$scope.addField = function (type) {
|
||||||
if (!$scope.cipher.fields) {
|
if (!$scope.cipher.fields) {
|
||||||
$scope.cipher.fields = [];
|
$scope.cipher.fields = [];
|
||||||
@ -182,4 +228,14 @@ angular
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setUriMatchValues() {
|
||||||
|
if ($scope.cipher.login && $scope.cipher.login.uris) {
|
||||||
|
for (var i = 0; i < $scope.cipher.login.uris.length; i++) {
|
||||||
|
$scope.cipher.login.uris[i].matchValue =
|
||||||
|
$scope.cipher.login.uris[i].match || $scope.cipher.login.uris[i].match === 0 ?
|
||||||
|
$scope.cipher.login.uris[i].match.toString() : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -28,20 +28,6 @@ angular
|
|||||||
if (model.login.password) {
|
if (model.login.password) {
|
||||||
$scope.cipher.maskedPassword = $scope.maskValue(model.login.password);
|
$scope.cipher.maskedPassword = $scope.maskValue(model.login.password);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.login.uri) {
|
|
||||||
$scope.cipher.showLaunch = model.login.uri.startsWith('http://') || model.login.uri.startsWith('https://');
|
|
||||||
var domain = platformUtilsService.getDomain(model.login.uri);
|
|
||||||
if (domain) {
|
|
||||||
$scope.cipher.login.website = domain;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$scope.cipher.login.website = model.login.uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$scope.cipher.showLaunch = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.login && model.login.totp && (cipherObj.organizationUseTotp || tokenService.getPremium())) {
|
if (model.login && model.login.totp && (cipherObj.organizationUseTotp || tokenService.getPremium())) {
|
||||||
@ -90,11 +76,13 @@ angular
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.launchWebsite = function (cipher) {
|
$scope.launch = function (uri) {
|
||||||
if (cipher.showLaunch) {
|
if (!uri.canLaunch) {
|
||||||
$analytics.eventTrack('Launched Website');
|
return;
|
||||||
BrowserApi.createNewTab(cipher.login.uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$analytics.eventTrack('Launched Login URI');
|
||||||
|
BrowserApi.createNewTab(uri.uri);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.clipboardError = function (e, password) {
|
$scope.clipboardError = function (e, password) {
|
||||||
|
@ -30,10 +30,6 @@
|
|||||||
<input id="name" type="text" name="Name" ng-model="cipher.name">
|
<input id="name" type="text" name="Name" ng-model="cipher.name">
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="cipher.type === constants.cipherType.login">
|
<div ng-if="cipher.type === constants.cipherType.login">
|
||||||
<div class="list-section-item">
|
|
||||||
<label for="loginUri" class="item-label">{{i18n.uri}}</label>
|
|
||||||
<input id="loginUri" type="text" name="Login.Uri" ng-model="cipher.login.uri">
|
|
||||||
</div>
|
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="loginUsername" class="item-label">{{i18n.username}}</label>
|
<label for="loginUsername" class="item-label">{{i18n.username}}</label>
|
||||||
<input id="loginUsername" type="text" name="Login.Username" ng-model="cipher.login.username">
|
<input id="loginUsername" type="text" name="Login.Username" ng-model="cipher.login.username">
|
||||||
@ -50,12 +46,15 @@
|
|||||||
<a class="btn-list" href="" title="{{i18n.togglePassword}}" ng-click="togglePassword()">
|
<a class="btn-list" href="" title="{{i18n.togglePassword}}" ng-click="togglePassword()">
|
||||||
<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>
|
||||||
|
<a class="btn-list" href="" title="{{i18n.generatePassword}}" ng-click="generatePassword()">
|
||||||
|
<i class="fa fa-lg fa-refresh"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="list-section-item" href="" ng-click="generatePassword()">
|
<div class="list-section-item">
|
||||||
{{i18n.generatePassword}}
|
<label for="loginTotp" class="item-label">{{i18n.authenticatorKeyTotp}}</label>
|
||||||
<i class="fa fa-chevron-right"></i>
|
<input id="loginTotp" type="text" name="Login.Totp" ng-model="cipher.login.totp">
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="cipher.type === constants.cipherType.card">
|
<div ng-if="cipher.type === constants.cipherType.card">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
@ -202,12 +201,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="list-section" ng-if="cipher.type === constants.cipherType.login">
|
||||||
|
<div class="list-section-items">
|
||||||
|
<div class="list-section-item list-section-item-table"
|
||||||
|
ng-if="cipher.login.uris && cipher.login.uris.length" ng-repeat="u in cipher.login.uris">
|
||||||
|
<a href="#" stop-click ng-click="removeUri(u)" class="action-button text-danger">
|
||||||
|
<i class="fa fa-minus-circle fa-lg"></i>
|
||||||
|
</a>
|
||||||
|
<div class="action-button-content">
|
||||||
|
<label for="loginUri{{$index}}" class="item-label">{{i18n.uri}} {{$index + 1}}</label>
|
||||||
|
<input id="loginUri{{$index}}" type="text" name="Login.Uris[{{$index}}].Uri"
|
||||||
|
ng-model="u.uri" placeholder="{{i18n.ex}} https://google.com">
|
||||||
|
<label for="loginUriMatch{{$index}}" class="sr-only">
|
||||||
|
{{i18n.autofillDetection}} {{$index + 1}}
|
||||||
|
</label>
|
||||||
|
<select id="loginUriMatch{{$index}}" name="Login.Uris[{{$index}}].Match"
|
||||||
|
ng-hide="u.showOptions === false || (u.showOptions == null && u.match == null)"
|
||||||
|
ng-model="u.matchValue" ng-change="uriMatchChanged(u)">
|
||||||
|
<option value="">{{i18n.defaultAutofillDetection}}</option>
|
||||||
|
<option value="0">{{i18n.baseDomain}}</option>
|
||||||
|
<option value="1">{{i18n.host}}</option>
|
||||||
|
<option value="2">{{i18n.startsWith}}</option>
|
||||||
|
<option value="4">{{i18n.regEx}}</option>
|
||||||
|
<option value="3">{{i18n.exact}}</option>
|
||||||
|
<option value="5">{{i18n.never}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<a href="#" stop-click ng-click="toggleUriOptions(u)" class="action-button"
|
||||||
|
title="{{i18n.toggleOptions}}">
|
||||||
|
<i class="fa fa-cog fa-lg"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<a class="list-section-item text-primary" href="#" stop-click ng-click="addUri()">
|
||||||
|
<i class="fa fa-plus-circle fa-fw fa-lg"></i> {{i18n.newUri}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="list-section">
|
<div class="list-section">
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item" ng-if="cipher.type === constants.cipherType.login">
|
|
||||||
<label for="loginTotp" class="item-label">{{i18n.authenticatorKeyTotp}}</label>
|
|
||||||
<input id="loginTotp" type="text" name="Login.Totp" ng-model="cipher.login.totp">
|
|
||||||
</div>
|
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="folder" class="item-label">{{i18n.folder}}</label>
|
<label for="folder" class="item-label">{{i18n.folder}}</label>
|
||||||
<select id="folder" name="FolderId" ng-model="cipher.folderId">
|
<select id="folder" name="FolderId" ng-model="cipher.folderId">
|
||||||
@ -241,7 +272,7 @@
|
|||||||
ng-if="cipher.fields && cipher.fields.length" ng-repeat="field in cipher.fields"
|
ng-if="cipher.fields && cipher.fields.length" ng-repeat="field in cipher.fields"
|
||||||
ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}">
|
ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}">
|
||||||
<a href="#" stop-click ng-click="removeField(field)" class="action-button text-danger">
|
<a href="#" stop-click ng-click="removeField(field)" class="action-button text-danger">
|
||||||
<i class="fa fa-close fa-lg"></i>
|
<i class="fa fa-minus-circle fa-lg"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="action-button-content">
|
<div class="action-button-content">
|
||||||
<input id="field_name{{$index}}" type="text" name="Field.Name{{$index}}"
|
<input id="field_name{{$index}}" type="text" name="Field.Name{{$index}}"
|
||||||
|
@ -23,10 +23,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="cipher.type === constants.cipherType.login">
|
<div ng-if="cipher.type === constants.cipherType.login">
|
||||||
<div class="list-section-item">
|
|
||||||
<label for="loginUri" class="item-label">{{i18n.uri}}</label>
|
|
||||||
<input id="loginUri" type="text" name="Login.Uri" ng-model="cipher.login.uri">
|
|
||||||
</div>
|
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="loginUsername" class="item-label">{{i18n.username}}</label>
|
<label for="loginUsername" class="item-label">{{i18n.username}}</label>
|
||||||
<input id="loginUsername" type="text" name="Login.Username" ng-model="cipher.login.username">
|
<input id="loginUsername" type="text" name="Login.Username" ng-model="cipher.login.username">
|
||||||
@ -43,12 +39,15 @@
|
|||||||
<a class="btn-list" href="" title="{{i18n.togglePassword}}" ng-click="togglePassword()">
|
<a class="btn-list" href="" title="{{i18n.togglePassword}}" ng-click="togglePassword()">
|
||||||
<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>
|
||||||
|
<a class="btn-list" href="" title="{{i18n.generatePassword}}" ng-click="generatePassword()">
|
||||||
|
<i class="fa fa-lg fa-refresh"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="list-section-item" href="" ng-click="generatePassword()">
|
<div class="list-section-item">
|
||||||
{{i18n.generatePassword}}
|
<label for="loginTotp" class="item-label">{{i18n.authenticatorKeyTotp}}</label>
|
||||||
<i class="fa fa-chevron-right"></i>
|
<input id="loginTotp" type="text" name="Login.Totp" ng-model="cipher.login.totp">
|
||||||
</a>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="cipher.type === constants.cipherType.card">
|
<div ng-if="cipher.type === constants.cipherType.card">
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
@ -195,12 +194,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="list-section" ng-if="cipher.type === constants.cipherType.login">
|
||||||
|
<div class="list-section-items">
|
||||||
|
<div class="list-section-item list-section-item-table"
|
||||||
|
ng-if="cipher.login.uris && cipher.login.uris.length" ng-repeat="u in cipher.login.uris">
|
||||||
|
<a href="#" stop-click ng-click="removeUri(u)" class="action-button text-danger">
|
||||||
|
<i class="fa fa-minus-circle fa-lg"></i>
|
||||||
|
</a>
|
||||||
|
<div class="action-button-content">
|
||||||
|
<label for="loginUri{{$index}}" class="item-label">{{i18n.uri}} {{$index + 1}}</label>
|
||||||
|
<input id="loginUri{{$index}}" type="text" name="Login.Uris[{{$index}}].Uri"
|
||||||
|
ng-model="u.uri" placeholder="{{i18n.ex}} https://google.com">
|
||||||
|
<label for="loginUriMatch{{$index}}" class="sr-only">
|
||||||
|
{{i18n.autofillDetection}} {{$index + 1}}
|
||||||
|
</label>
|
||||||
|
<select id="loginUriMatch{{$index}}" name="Login.Uris[{{$index}}].Match"
|
||||||
|
ng-hide="u.showOptions === false || (u.showOptions == null && u.match == null)"
|
||||||
|
ng-model="u.matchValue" ng-change="uriMatchChanged(u)">
|
||||||
|
<option value="">{{i18n.defaultAutofillDetection}}</option>
|
||||||
|
<option value="0">{{i18n.baseDomain}}</option>
|
||||||
|
<option value="1">{{i18n.host}}</option>
|
||||||
|
<option value="2">{{i18n.startsWith}}</option>
|
||||||
|
<option value="4">{{i18n.regEx}}</option>
|
||||||
|
<option value="3">{{i18n.exact}}</option>
|
||||||
|
<option value="5">{{i18n.never}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<a href="#" stop-click ng-click="toggleUriOptions(u)" class="action-button"
|
||||||
|
title="{{i18n.toggleOptions}}">
|
||||||
|
<i class="fa fa-cog fa-lg"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<a class="list-section-item text-primary" href="#" stop-click ng-click="addUri()">
|
||||||
|
<i class="fa fa-plus-circle fa-fw fa-lg"></i> {{i18n.newUri}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="list-section">
|
<div class="list-section">
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item" ng-if="cipher.type === constants.cipherType.login">
|
|
||||||
<label for="loginTotp" class="item-label">{{i18n.authenticatorKeyTotp}}</label>
|
|
||||||
<input id="loginTotp" type="text" name="Login.Totp" ng-model="cipher.login.totp">
|
|
||||||
</div>
|
|
||||||
<div class="list-section-item">
|
<div class="list-section-item">
|
||||||
<label for="folder" class="item-label">{{i18n.folder}}</label>
|
<label for="folder" class="item-label">{{i18n.folder}}</label>
|
||||||
<select id="folder" name="FolderId" ng-model="cipher.folderId">
|
<select id="folder" name="FolderId" ng-model="cipher.folderId">
|
||||||
@ -238,7 +269,7 @@
|
|||||||
ng-if="cipher.fields && cipher.fields.length" ng-repeat="field in cipher.fields"
|
ng-if="cipher.fields && cipher.fields.length" ng-repeat="field in cipher.fields"
|
||||||
ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}">
|
ng-class="{'list-section-item-checkbox' : field.type === constants.fieldType.boolean}">
|
||||||
<a href="#" stop-click ng-click="removeField(field)" class="action-button text-danger">
|
<a href="#" stop-click ng-click="removeField(field)" class="action-button text-danger">
|
||||||
<i class="fa fa-close fa-lg"></i>
|
<i class="fa fa-minus-circle fa-lg"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="action-button-content">
|
<div class="action-button-content">
|
||||||
<input id="field_name{{$index}}" type="text" name="Field.Name{{$index}}"
|
<input id="field_name{{$index}}" type="text" name="Field.Name{{$index}}"
|
||||||
|
@ -20,22 +20,6 @@
|
|||||||
{{cipher.name}}
|
{{cipher.name}}
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="cipher.type === constants.cipherType.login">
|
<div ng-if="cipher.type === constants.cipherType.login">
|
||||||
<div class="list-section-item wrap" ng-if="cipher.login.uri" title="{{cipher.login.uri}}">
|
|
||||||
<div class="action-buttons">
|
|
||||||
<a class="btn-list" href="" title="{{i18n.launchWebsite}}" ng-click="launchWebsite(cipher)"
|
|
||||||
ng-show="cipher.showLaunch">
|
|
||||||
<i class="fa fa-lg fa-share-square-o"></i>
|
|
||||||
</a>
|
|
||||||
<a class="btn-list" href="" title="{{i18n.copyUri}}"
|
|
||||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
|
||||||
ngclipboard-success="clipboardSuccess(e, i18n.uri, 'URI')"
|
|
||||||
data-clipboard-text="{{cipher.login.uri}}">
|
|
||||||
<i class="fa fa-lg fa-clipboard"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<span class="item-label">{{i18n.website}}</span>
|
|
||||||
{{cipher.login.website}}
|
|
||||||
</div>
|
|
||||||
<div class="list-section-item wrap" ng-if="cipher.login.username">
|
<div class="list-section-item wrap" ng-if="cipher.login.username">
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<a class="btn-list" href="" title="{{i18n.copyUsername}}"
|
<a class="btn-list" href="" title="{{i18n.copyUsername}}"
|
||||||
@ -183,6 +167,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="list-section"
|
||||||
|
ng-if="cipher.type === constants.cipherType.login && cipher.login.uris && cipher.login.uris.length">
|
||||||
|
<div class="list-section-items">
|
||||||
|
<div class="list-section-item wrap" title="{{u.uri}}" ng-repeat="u in cipher.login.uris">
|
||||||
|
<div class="action-buttons">
|
||||||
|
<a class="btn-list" href="" title="{{i18n.launchWebsite}}" ng-click="launch(u)"
|
||||||
|
ng-show="u.canLaunch">
|
||||||
|
<i class="fa fa-lg fa-share-square-o"></i>
|
||||||
|
</a>
|
||||||
|
<a class="btn-list" href="" title="{{i18n.copyUri}}"
|
||||||
|
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||||
|
ngclipboard-success="clipboardSuccess(e, i18n.uri, 'URI')"
|
||||||
|
data-clipboard-text="{{u.uri}}">
|
||||||
|
<i class="fa fa-lg fa-clipboard"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<span class="item-label" ng-if="u.isWebsite">{{i18n.website}}</span>
|
||||||
|
<span class="item-label" ng-if="!u.isWebsite">{{i18n.uri}}</span>
|
||||||
|
{{u.domainOrUri}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="list-section" ng-if="cipher.notes">
|
<div class="list-section" ng-if="cipher.notes">
|
||||||
<div class="list-section-header">
|
<div class="list-section-header">
|
||||||
{{i18n.notes}}
|
{{i18n.notes}}
|
||||||
|
@ -329,7 +329,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
padding: 8px 10px 8px 5px;
|
padding: 8px 8px 8px 4px;
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
@ -342,6 +342,14 @@
|
|||||||
.action-button-content {
|
.action-button-content {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
|
input + label.sr-only + select {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button-content + .action-button {
|
||||||
|
padding: 8px 0 8px 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-type {
|
.field-type {
|
||||||
|
Loading…
Reference in New Issue
Block a user