add/edit/view fixes for ciphers
This commit is contained in:
parent
af973cbce3
commit
176b9a8ed0
|
@ -46,7 +46,7 @@
|
|||
|
||||
$scope.savePromise = null;
|
||||
$scope.save = function () {
|
||||
if (!cipher.name || cipher.name === '') {
|
||||
if (!$scope.cipher.name || $scope.cipher.name === '') {
|
||||
toastr.error(i18nService.nameRequired, i18nService.errorsOccurred);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ angular
|
|||
$scope.constants = constantsService;
|
||||
$scope.showAttachments = !utilsService.isEdge();
|
||||
$scope.addFieldType = constantsService.fieldType.text.toString();
|
||||
$scope.selectedType = constantsService.cipherType.login.toString();
|
||||
var cipherId = $stateParams.cipherId;
|
||||
var fromView = $stateParams.fromView;
|
||||
var from = $stateParams.from;
|
||||
|
@ -34,14 +35,18 @@ angular
|
|||
|
||||
utilsService.initListSectionItemListeners($(document), angular);
|
||||
|
||||
$scope.typeChanged = function () {
|
||||
$scope.cipher.type = parseInt($scope.selectedType);
|
||||
};
|
||||
|
||||
$scope.savePromise = null;
|
||||
$scope.save = function (model) {
|
||||
if (!model.name) {
|
||||
$scope.save = function () {
|
||||
if (!$scope.cipher.name || $scope.cipher.name === '') {
|
||||
toastr.error(i18nService.nameRequired, i18nService.errorsOccurred);
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.savePromise = loginService.encrypt(model).then(function (cipherModel) {
|
||||
$scope.savePromise = loginService.encrypt($scope.cipher).then(function (cipherModel) {
|
||||
var cipher = new Cipher(cipherModel, true);
|
||||
return loginService.saveWithServer(cipher).then(function (c) {
|
||||
$analytics.eventTrack('Edited Cipher');
|
||||
|
|
|
@ -12,34 +12,38 @@ angular
|
|||
|
||||
$scope.isPremium = tokenService.getPremium();
|
||||
$scope.cipher = null;
|
||||
var cipherObj = null;
|
||||
loginService.get($stateParams.cipherId).then(function (cipher) {
|
||||
if (!cipher) {
|
||||
return;
|
||||
}
|
||||
|
||||
cipherObj = cipher;
|
||||
return cipher.decrypt();
|
||||
}).then(function (model) {
|
||||
$scope.cipher = model;
|
||||
|
||||
if (model.password) {
|
||||
$scope.cipher.maskedPassword = $scope.maskValue(model.password);
|
||||
}
|
||||
if (model.type == constantsService.cipherType.login && model.login) {
|
||||
if (model.login.password) {
|
||||
$scope.cipher.maskedPassword = $scope.maskValue(model.login.password);
|
||||
}
|
||||
|
||||
if (model.uri) {
|
||||
$scope.cipher.showLaunch = model.uri.startsWith('http://') || model.uri.startsWith('https://');
|
||||
var domain = utilsService.getDomain(model.uri);
|
||||
if (domain) {
|
||||
$scope.cipher.website = domain;
|
||||
if (model.login.uri) {
|
||||
$scope.cipher.showLaunch = model.login.uri.startsWith('http://') || model.login.uri.startsWith('https://');
|
||||
var domain = utilsService.getDomain(model.login.uri);
|
||||
if (domain) {
|
||||
$scope.cipher.login.website = domain;
|
||||
}
|
||||
else {
|
||||
$scope.cipher.login.website = model.login.uri;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$scope.cipher.website = model.uri;
|
||||
$scope.cipher.showLaunch = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$scope.cipher.showLaunch = false;
|
||||
}
|
||||
|
||||
if (model.totp && (cipher.organizationUseTotp || tokenService.getPremium())) {
|
||||
if (model.login.totp && (cipherObj.organizationUseTotp || tokenService.getPremium())) {
|
||||
totpUpdateCode();
|
||||
totpTick();
|
||||
|
||||
|
@ -87,7 +91,7 @@ angular
|
|||
$scope.launchWebsite = function (cipher) {
|
||||
if (cipher.showLaunch) {
|
||||
$analytics.eventTrack('Launched Website');
|
||||
chrome.tabs.create({ url: cipher.uri });
|
||||
chrome.tabs.create({ url: cipher.login.uri });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -192,11 +196,11 @@ angular
|
|||
});
|
||||
|
||||
function totpUpdateCode() {
|
||||
if (!$scope.cipher.totp) {
|
||||
if ($scope.cipher.type !== constantsService.cipherType.login || !$scope.cipher.login.totp) {
|
||||
return;
|
||||
}
|
||||
|
||||
totpService.getCode($scope.cipher.totp).then(function (code) {
|
||||
totpService.getCode($scope.cipher.login.totp).then(function (code) {
|
||||
$timeout(function () {
|
||||
if (code) {
|
||||
$scope.totpCodeFormatted = code.substring(0, 3) + ' ' + code.substring(3);
|
||||
|
|
|
@ -188,7 +188,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div ng-if="cipher.type === constants.cipherType.secureNote">
|
||||
|
||||
<!-- Nothing for now -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<form name="theForm" ng-submit="save(cipher)" bit-form="savePromise" autocomplete="off">
|
||||
<form name="theForm" ng-submit="save()" bit-form="savePromise" autocomplete="off">
|
||||
<div class="header">
|
||||
<div class="left">
|
||||
<a ng-click="close()" href="">{{i18n.cancel}}</a>
|
||||
|
@ -21,29 +21,177 @@
|
|||
<label for="name" class="item-label">{{i18n.name}}</label>
|
||||
<input id="name" type="text" name="Name" ng-model="cipher.name">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="uri" class="item-label">{{i18n.uri}}</label>
|
||||
<input id="uri" type="text" name="Uri" ng-model="cipher.uri">
|
||||
|
||||
<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">
|
||||
<label for="loginUsername" class="item-label">{{i18n.username}}</label>
|
||||
<input id="loginUsername" type="text" name="Login.Username" ng-model="cipher.login.username">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="loginPassword" class="item-label">{{i18n.password}}</label>
|
||||
<input id="loginPassword" type="password" name="Login.Password" ng-model="cipher.login.password">
|
||||
</div>
|
||||
<a class="list-section-item" href="" ng-click="generatePassword()">
|
||||
{{i18n.generatePassword}}
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="username" class="item-label">{{i18n.username}}</label>
|
||||
<input id="username" type="text" name="Username" ng-model="cipher.username">
|
||||
<div ng-if="cipher.type === constants.cipherType.card">
|
||||
<div class="list-section-item">
|
||||
<label for="cardCardholderName" class="item-label">{{i18n.cardholderName}}</label>
|
||||
<input id="cardCardholderName" type="text" name="Card.CardholderName"
|
||||
ng-model="cipher.card.cardholderName">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="cardNumber" class="item-label">{{i18n.number}}</label>
|
||||
<input id="cardNumber" type="text" name="Card.Number" ng-model="cipher.card.number">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="cardBrand" class="item-label">{{i18n.brand}}</label>
|
||||
<select id="cardBrand" name="Card.Brand" ng-model="cipher.card.brand">
|
||||
<option value="">-- {{i18n.select}} --</option>
|
||||
<option value="Visa">Visa</option>
|
||||
<option value="Mastercard">Mastercard</option>
|
||||
<option value="Amex">American Express</option>
|
||||
<option value="Discover">Discover</option>
|
||||
<option value="Diners Club">Diners Club</option>
|
||||
<option value="JCB">JCB</option>
|
||||
<option value="Maestro">Maestro</option>
|
||||
<option value="UnionPay">UnionPay</option>
|
||||
<option value="Other">{{i18n.other}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="cardExpMonth" class="item-label">{{i18n.expirationMonth}}</label>
|
||||
<select id="cardExpMonth" name="Card.ExpMonth" ng-model="cipher.card.expMonth">
|
||||
<option value="">-- {{i18n.select}} --</option>
|
||||
<option value="1">01 - {{i18n.january}}</option>
|
||||
<option value="2">02 - {{i18n.february}}</option>
|
||||
<option value="3">03 - {{i18n.march}}</option>
|
||||
<option value="4">04 - {{i18n.april}}</option>
|
||||
<option value="5">05 - {{i18n.may}}</option>
|
||||
<option value="6">06 - {{i18n.june}}</option>
|
||||
<option value="7">07 - {{i18n.july}}</option>
|
||||
<option value="8">08 - {{i18n.august}}</option>
|
||||
<option value="9">09 - {{i18n.september}}</option>
|
||||
<option value="10">10 - {{i18n.october}}</option>
|
||||
<option value="11">11 - {{i18n.november}}</option>
|
||||
<option value="12">12 - {{i18n.december}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="cardExpYear" class="item-label">{{i18n.expirationYear}}</label>
|
||||
<input id="cardExpYear" type="text" name="Card.ExpYear" ng-model="cipher.card.expYear"
|
||||
placeholder="{{i18n.ex}} 2019">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="cardCode" class="item-label">{{i18n.securityCode}}</label>
|
||||
<input id="cardCode" type="text" name="Card.Code" ng-model="cipher.card.code">
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="password" class="item-label">{{i18n.password}}</label>
|
||||
<input id="password" type="password" name="Password" ng-model="cipher.password">
|
||||
<div ng-if="cipher.type === constants.cipherType.identity">
|
||||
<div class="list-section-item">
|
||||
<label for="identityTitle" class="item-label">{{i18n.title}}</label>
|
||||
<select id="identityTitle" name="Identity.Title" ng-model="cipher.identity.title">
|
||||
<option value="">-- {{i18n.select}} --</option>
|
||||
<option value="{{i18n.mr}}">{{i18n.mr}}</option>
|
||||
<option value="{{i18n.mrs}}">{{i18n.mrs}}</option>
|
||||
<option value="{{i18n.ms}}">{{i18n.ms}}</option>
|
||||
<option value="{{i18n.dr}}">{{i18n.dr}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityFirstName" class="item-label">{{i18n.firstName}}</label>
|
||||
<input id="identityFirstName" type="text" name="Identity.FirstName"
|
||||
ng-model="cipher.identity.firstName">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityMiddleName" class="item-label">{{i18n.middleName}}</label>
|
||||
<input id="identityMiddleName" type="text" name="Identity.MiddleName"
|
||||
ng-model="cipher.identity.middleName">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityLastName" class="item-label">{{i18n.lastName}}</label>
|
||||
<input id="identityLastName" type="text" name="Identity.LastName"
|
||||
ng-model="cipher.identity.lastName">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityUsername" class="item-label">{{i18n.username}}</label>
|
||||
<input id="identityUsername" type="text" name="Identity.Username"
|
||||
ng-model="cipher.identity.username">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityCompany" class="item-label">{{i18n.company}}</label>
|
||||
<input id="identityCompany" type="text" name="Identity.Company" ng-model="cipher.identity.company">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identitySsn" class="item-label">{{i18n.ssn}}</label>
|
||||
<input id="identitySsn" type="text" name="Identity.SSN" ng-model="cipher.identity.ssn">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityPassportNumber" class="item-label">{{i18n.passportNumber}}</label>
|
||||
<input id="identityPassportNumber" type="text" name="Identity.PassportNumber"
|
||||
ng-model="cipher.identity.passportNumber">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityLicenseNumber" class="item-label">{{i18n.licenseNumber}}</label>
|
||||
<input id="identityLicenseNumber" type="text" name="Identity.LicenseNumber"
|
||||
ng-model="cipher.identity.licenseNumber">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityEmail" class="item-label">{{i18n.email}}</label>
|
||||
<input id="identityEmail" type="text" name="Identity.Email" ng-model="cipher.identity.email">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityPhone" class="item-label">{{i18n.phone}}</label>
|
||||
<input id="identityPhone" type="text" name="Identity.Phone" ng-model="cipher.identity.phone">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityAddress1" class="item-label">{{i18n.address1}}</label>
|
||||
<input id="identityAddress1" type="text" name="Identity.Address1" ng-model="cipher.identity.address1">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityAddress2" class="item-label">{{i18n.address2}}</label>
|
||||
<input id="identityAddress2" type="text" name="Identity.Address2" ng-model="cipher.identity.address2">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityAddress3" class="item-label">{{i18n.address3}}</label>
|
||||
<input id="identityAddress3" type="text" name="Identity.Address3" ng-model="cipher.identity.address3">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityCity" class="item-label">{{i18n.cityTown}}</label>
|
||||
<input id="identityCity" type="text" name="Identity.City" ng-model="cipher.identity.city">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityState" class="item-label">{{i18n.stateProvince}}</label>
|
||||
<input id="identityState" type="text" name="Identity.State" ng-model="cipher.identity.state">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityPostalCode" class="item-label">{{i18n.zipPostalCode}}</label>
|
||||
<input id="identityPostalCode" type="text" name="Identity.PostalCode"
|
||||
ng-model="cipher.identity.postalCode">
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="identityCountry" class="item-label">{{i18n.country}}</label>
|
||||
<input id="identityCountry" type="text" name="Identity.Country" ng-model="cipher.identity.country">
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="cipher.type === constants.cipherType.secureNote">
|
||||
<!-- Nothing for now -->
|
||||
</div>
|
||||
<a class="list-section-item" href="" ng-click="generatePassword()">
|
||||
{{i18n.generatePassword}}
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section">
|
||||
<div class="list-section-items">
|
||||
<div class="list-section-item">
|
||||
<label for="totp" class="item-label">{{i18n.authenticatorKeyTotp}}</label>
|
||||
<input id="totp" type="text" name="Totp" ng-model="cipher.totp">
|
||||
<div ng-if="cipher.type === constants.cipherType.login">
|
||||
<div class="list-section-item">
|
||||
<label for="loginTotp" class="item-label">{{i18n.authenticatorKeyTotp}}</label>
|
||||
<input id="loginTotp" type="text" name="Login.Totp" ng-model="cipher.login.totp">
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section-item">
|
||||
<label for="folder" class="item-label">{{i18n.folder}}</label>
|
||||
|
|
|
@ -19,52 +19,97 @@
|
|||
<span class="item-label">{{i18n.name}}</span>
|
||||
{{cipher.name}}
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.uri" title="{{cipher.uri}}">
|
||||
<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>
|
||||
<span class="item-label">{{i18n.website}}</span>
|
||||
{{cipher.website}}
|
||||
<div ng-if="cipher.type === constants.cipherType.login">
|
||||
<div class="list-section-item" ng-if="cipher.login.uri" title="{{cipher.login.uri}}">
|
||||
<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>
|
||||
<span class="item-label">{{i18n.website}}</span>
|
||||
{{cipher.login.website}}
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.login.username">
|
||||
<a class="btn-list" href="" title="{{i18n.copyUsername}}"
|
||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.username)"
|
||||
data-clipboard-text="{{cipher.login.username}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<span class="item-label">{{i18n.username}}</span>
|
||||
<span id="username">{{cipher.login.username}}</span>
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.login.password">
|
||||
<a class="btn-list" href="" title="{{i18n.copyPassword}}"
|
||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.password)"
|
||||
data-clipboard-text="{{cipher.login.password}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<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>
|
||||
</a>
|
||||
<span class="item-label">{{i18n.password}}</span>
|
||||
<span ng-show="!showPassword" class="monospaced">{{cipher.maskedPassword}}</span>
|
||||
<span id="password" ng-show="showPassword" class="monospaced">{{cipher.login.password}}</span>
|
||||
</div>
|
||||
<div class="list-section-item totp" ng-class="{'low': totpLow}" ng-if="cipher.login.totp && totpCode">
|
||||
<a class="btn-list" href="" title="{{i18n.copyVerificationCode}}"
|
||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.verificationCodeTotp)" data-clipboard-text="{{totpCode}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<span class="totp-countdown">
|
||||
<span class="totp-sec">{{totpSec}}</span>
|
||||
<svg>
|
||||
<g>
|
||||
<circle class="totp-circle inner" r="12.6" cy="16" cx="16"
|
||||
style="stroke-dashoffset: {{totpDash}}px;"></circle>
|
||||
<circle class="totp-circle outer" r="14" cy="16" cx="16"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="item-label">{{i18n.verificationCodeTotp}}</span>
|
||||
<span id="totp" class="totp-code">{{totpCodeFormatted}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.username">
|
||||
<a class="btn-list" href="" title="{{i18n.copyUsername}}" ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.username)" data-clipboard-text="{{cipher.username}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<span class="item-label">{{i18n.username}}</span>
|
||||
<span id="username">{{cipher.username}}</span>
|
||||
<div ng-if="cipher.type === constants.cipherType.card">
|
||||
<div class="list-section-item" ng-if="cipher.card.cardholderName">
|
||||
<a class="btn-list" href="" title="{{i18n.copy}}"
|
||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.cardholderName)"
|
||||
data-clipboard-text="{{cipher.card.cardholderName}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<span class="item-label">{{i18n.cardholderName}}</span>
|
||||
<span id="username">{{cipher.card.cardholderName}}</span>
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.card.number">
|
||||
<a class="btn-list" href="" title="{{i18n.copy}}"
|
||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.number)"
|
||||
data-clipboard-text="{{cipher.card.number}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<span class="item-label">{{i18n.number}}</span>
|
||||
<span id="username">{{cipher.card.number}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.password">
|
||||
<a class="btn-list" href="" title="{{i18n.copyPassword}}" ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.password)" data-clipboard-text="{{cipher.password}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<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>
|
||||
</a>
|
||||
<span class="item-label">{{i18n.password}}</span>
|
||||
<span ng-show="!showPassword" class="monospaced">{{cipher.maskedPassword}}</span>
|
||||
<span id="password" ng-show="showPassword" class="monospaced">{{cipher.password}}</span>
|
||||
<div ng-if="cipher.type === constants.cipherType.identity">
|
||||
<div class="list-section-item" ng-if="cipher.identity.firstName">
|
||||
<span class="item-label">{{i18n.firstName}}</span>
|
||||
{{cipher.identity.firstName}}
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.identity.middleName">
|
||||
<span class="item-label">{{i18n.middleName}}</span>
|
||||
{{cipher.identity.middleName}}
|
||||
</div>
|
||||
<div class="list-section-item" ng-if="cipher.identity.lastName">
|
||||
<span class="item-label">{{i18n.lastName}}</span>
|
||||
{{cipher.identity.lastName}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section-item totp" ng-class="{'low': totpLow}" ng-if="cipher.totp && totpCode">
|
||||
<a class="btn-list" href="" title="{{i18n.copyVerificationCode}}"
|
||||
ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e, i18n.verificationCodeTotp)" data-clipboard-text="{{totpCode}}">
|
||||
<i class="fa fa-lg fa-clipboard"></i>
|
||||
</a>
|
||||
<span class="totp-countdown">
|
||||
<span class="totp-sec">{{totpSec}}</span>
|
||||
<svg>
|
||||
<g>
|
||||
<circle class="totp-circle inner" r="12.6" cy="16" cx="16"
|
||||
style="stroke-dashoffset: {{totpDash}}px;"></circle>
|
||||
<circle class="totp-circle outer" r="14" cy="16" cx="16"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="item-label">{{i18n.verificationCodeTotp}}</span>
|
||||
<span id="totp" class="totp-code">{{totpCodeFormatted}}</span>
|
||||
<div ng-if="cipher.type === constants.cipherType.secureNote">
|
||||
<!-- Nothing for now -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,62 +28,13 @@ function initLoginService() {
|
|||
type: login.type
|
||||
};
|
||||
|
||||
function encryptCipherData(cipher, model, key, self) {
|
||||
switch (cipher.type) {
|
||||
case constantsService.cipherType.login:
|
||||
return encryptObjProperty(cipher.login, model.login, {
|
||||
uri: null,
|
||||
username: null,
|
||||
password: null,
|
||||
totp: null
|
||||
}, key, self);
|
||||
case constantsService.cipherType.secureNote:
|
||||
model.secureNote = {
|
||||
type: cipher.secureNote.type
|
||||
};
|
||||
return Q();
|
||||
case constantsService.cipherType.card:
|
||||
return encryptObjProperty(cipher.card, model.card, {
|
||||
cardholderName: null,
|
||||
brand: null,
|
||||
number: null,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
code: null
|
||||
}, key, self);
|
||||
case constantsService.cipherType.identity:
|
||||
return encryptObjProperty(cipher.identity, model.identity, {
|
||||
title: null,
|
||||
firstName: null,
|
||||
middleName: null,
|
||||
lastName: null,
|
||||
address1: null,
|
||||
address2: null,
|
||||
address3: null,
|
||||
city: null,
|
||||
state: null,
|
||||
postalCode: null,
|
||||
country: null,
|
||||
company: null,
|
||||
email: null,
|
||||
phone: null,
|
||||
ssn: null,
|
||||
username: null,
|
||||
passportNumber: null,
|
||||
licenseNumber: null
|
||||
}, key, self);
|
||||
default:
|
||||
throw 'Unknown type.';
|
||||
}
|
||||
}
|
||||
|
||||
return self.cryptoService.getOrgKey(login.organizationId).then(function (key) {
|
||||
return Q.all([
|
||||
encryptObjProperty(login, model, {
|
||||
name: null,
|
||||
notes: null
|
||||
}, key, self),
|
||||
encryptCipherData(login, model, key),
|
||||
encryptCipherData(login, model, key, self),
|
||||
self.encryptFields(login.fields, key).then(function (fields) {
|
||||
model.fields = fields;
|
||||
})
|
||||
|
@ -93,10 +44,62 @@ function initLoginService() {
|
|||
});
|
||||
};
|
||||
|
||||
function encryptCipherData(cipher, model, key, self) {
|
||||
switch (cipher.type) {
|
||||
case self.constantsService.cipherType.login:
|
||||
model.login = {};
|
||||
return encryptObjProperty(cipher.login, model.login, {
|
||||
uri: null,
|
||||
username: null,
|
||||
password: null,
|
||||
totp: null
|
||||
}, key, self);
|
||||
case self.constantsService.cipherType.secureNote:
|
||||
model.secureNote = {
|
||||
type: cipher.secureNote.type
|
||||
};
|
||||
return Q();
|
||||
case self.constantsService.cipherType.card:
|
||||
model.card = {};
|
||||
return encryptObjProperty(cipher.card, model.card, {
|
||||
cardholderName: null,
|
||||
brand: null,
|
||||
number: null,
|
||||
expMonth: null,
|
||||
expYear: null,
|
||||
code: null
|
||||
}, key, self);
|
||||
case self.constantsService.cipherType.identity:
|
||||
model.identity = {};
|
||||
return encryptObjProperty(cipher.identity, model.identity, {
|
||||
title: null,
|
||||
firstName: null,
|
||||
middleName: null,
|
||||
lastName: null,
|
||||
address1: null,
|
||||
address2: null,
|
||||
address3: null,
|
||||
city: null,
|
||||
state: null,
|
||||
postalCode: null,
|
||||
country: null,
|
||||
company: null,
|
||||
email: null,
|
||||
phone: null,
|
||||
ssn: null,
|
||||
username: null,
|
||||
passportNumber: null,
|
||||
licenseNumber: null
|
||||
}, key, self);
|
||||
default:
|
||||
throw 'Unknown type.';
|
||||
}
|
||||
}
|
||||
|
||||
LoginService.prototype.encryptFields = function (fields, key) {
|
||||
var self = this;
|
||||
if (!fields || !fields.length) {
|
||||
return null;
|
||||
return Q(null);
|
||||
}
|
||||
|
||||
var encFields = [];
|
||||
|
@ -132,20 +135,19 @@ function initLoginService() {
|
|||
for (var prop in map) {
|
||||
if (map.hasOwnProperty(prop)) {
|
||||
/* jshint ignore:start */
|
||||
(function (theProp) {
|
||||
(function (theProp, theModel) {
|
||||
var promise = Q().then(function () {
|
||||
var objProb = obj[(map[theProp] || theProp)];
|
||||
if (objProb && objProb !== '') {
|
||||
return self.cryptoService.encrypt(objProb, key);
|
||||
var objProp = obj[(map[theProp] || theProp)];
|
||||
if (objProp && objProp !== '') {
|
||||
return self.cryptoService.encrypt(objProp, key);
|
||||
}
|
||||
return null;
|
||||
}).then(function (val) {
|
||||
model[theProp] = val;
|
||||
return;
|
||||
theModel[theProp] = val;
|
||||
});
|
||||
|
||||
promises.push(promise);
|
||||
})(prop);
|
||||
})(prop, model);
|
||||
/* jshint ignore:end */
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ function initLoginService() {
|
|||
return self.utilsService.getObjFromStorage(key);
|
||||
}).then(function (ciphers) {
|
||||
if (ciphers && id in ciphers) {
|
||||
return new Login(ciphers[id], false, localData[id]);
|
||||
return new Cipher(ciphers[id], false, localData[id]);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -329,7 +331,7 @@ function initLoginService() {
|
|||
function apiSuccess(response) {
|
||||
cipher.id = response.id;
|
||||
self.userService.getUserIdPromise().then(function (userId) {
|
||||
var data = new LoginData(response, userId);
|
||||
var data = new CipherData(response, userId);
|
||||
return self.upsert(data);
|
||||
}).then(function () {
|
||||
deferred.resolve(cipher);
|
||||
|
@ -514,11 +516,11 @@ function initLoginService() {
|
|||
return;
|
||||
}
|
||||
|
||||
data = new LoginData(response, userId);
|
||||
data = new CipherData(response, userId);
|
||||
return self.upsert(data);
|
||||
}).then(function () {
|
||||
if (data) {
|
||||
deferred.resolve(new Login(data));
|
||||
deferred.resolve(new CipherData(data));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue