mirror of
https://github.com/nextcloud/passman.git
synced 2025-10-09 21:16:18 +08:00
Start with showing Credentials
This commit is contained in:
parent
6caf31a992
commit
dee5ecda55
21 changed files with 517 additions and 295 deletions
|
@ -110,9 +110,9 @@
|
|||
</field>
|
||||
<field>
|
||||
<name>vault_id</name>
|
||||
<type>text</type>
|
||||
<type>integer</type>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
<length>8</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<description>A password manager for Nextcloud</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Sander Brand</author>
|
||||
<version>1.0.2.3</version>
|
||||
<version>1.0.2.4</version>
|
||||
<namespace>Passman</namespace>
|
||||
<category>other</category>
|
||||
<website>https://github.com/nextcloud/passman/</website>
|
||||
|
|
|
@ -20,10 +20,11 @@ use OCA\Passman\Service\CredentialService;
|
|||
class CredentialController extends ApiController {
|
||||
private $userId;
|
||||
private $credentialService;
|
||||
|
||||
public function __construct($AppName,
|
||||
IRequest $request,
|
||||
$UserId,
|
||||
CredentialService $credentialService){
|
||||
CredentialService $credentialService) {
|
||||
parent::__construct($AppName, $request);
|
||||
$this->userId = $UserId;
|
||||
$this->credentialService = $credentialService;
|
||||
|
@ -75,8 +76,33 @@ class CredentialController extends ApiController {
|
|||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function updateCredential($credential_id) {
|
||||
return;
|
||||
public function updateCredential($changed, $created,
|
||||
$credential_id, $custom_fields, $delete_time,
|
||||
$description, $email, $expire_time, $favicon, $files, $guid,
|
||||
$hidden, $label, $otp, $password, $renew_interval,
|
||||
$tags, $url, $username, $vault_id) {
|
||||
$credential = array(
|
||||
'credential_id' => $credential_id,
|
||||
'guid' => $guid,
|
||||
'user_id' => $this->userId,
|
||||
'label' => $label,
|
||||
'description' => $description,
|
||||
'created' => $created,
|
||||
'changed' => $changed,
|
||||
'tags' => $tags,
|
||||
'email' => $email,
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'url' => $url,
|
||||
'favicon' => $favicon,
|
||||
'renew_interval' => $renew_interval,
|
||||
'expire_time' => $expire_time,
|
||||
'files' => $files,
|
||||
'custom_fields' => $custom_fields,
|
||||
'otp' => $otp,
|
||||
);
|
||||
$credential = $this->credentialService->updateCredential($credential);
|
||||
return new JSONResponse($credential);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
257
css/app.css
257
css/app.css
|
@ -1,26 +1,3 @@
|
|||
.actions.creatable {
|
||||
padding-left: 10px; }
|
||||
.actions.creatable .bubble {
|
||||
position: relative;
|
||||
width: 185px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
background-clip: padding-box;
|
||||
/* stops bg color from leaking outside the border: */
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, 0.7); }
|
||||
.actions.creatable .bubble ul li {
|
||||
padding-left: 10px; }
|
||||
.actions.creatable .bubble ul .menuitem {
|
||||
font-size: 12px;
|
||||
display: inline; }
|
||||
.actions.creatable .bubble:after {
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px; }
|
||||
|
||||
#app-content-wrapper {
|
||||
min-height: 95%; }
|
||||
|
||||
.button-geen {
|
||||
background: #37ce02;
|
||||
color: #fff; }
|
||||
|
@ -156,105 +133,147 @@
|
|||
@media screen and (max-width: 768px) {
|
||||
.vault_wrapper {
|
||||
width: 90%; } }
|
||||
.credential-table {
|
||||
width: 100%;
|
||||
margin-top: 44px; }
|
||||
.credential-table tr:hover {
|
||||
background-color: whitesmoke; }
|
||||
.credential-table tr td {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #eeeeee; }
|
||||
.credential-table tr td .label {
|
||||
float: left; }
|
||||
.credential-table tr td .tags {
|
||||
float: right; }
|
||||
.credential-table tr td .tags .tag {
|
||||
background-color: rgba(240, 240, 240, 0.9);
|
||||
padding: 4px;
|
||||
font-size: 11px; }
|
||||
.credential-table tr td .icon-more {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
opacity: 0.4;
|
||||
height: 20px;
|
||||
width: 32px;
|
||||
cursor: pointer; }
|
||||
.credential-table tr td .icon-more:hover {
|
||||
opacity: 1; }
|
||||
.credential-table tr td .popovermenu {
|
||||
margin-top: 7px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, 0.7); }
|
||||
.credential-table tr td .popovermenu ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px; }
|
||||
.credential-table tr td .popovermenu ul li {
|
||||
padding: 0px; }
|
||||
.credential-table tr td .popovermenu ul .menuitem {
|
||||
#app-content {
|
||||
overflow-x: hidden; }
|
||||
#app-content #app-content-wrapper {
|
||||
min-height: 95%; }
|
||||
#app-content #app-content-wrapper .actions.creatable {
|
||||
padding-left: 10px; }
|
||||
#app-content #app-content-wrapper .actions.creatable .bubble {
|
||||
position: relative;
|
||||
width: 185px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
background-clip: padding-box;
|
||||
/* stops bg color from leaking outside the border: */
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, 0.7); }
|
||||
#app-content #app-content-wrapper .actions.creatable .bubble ul li {
|
||||
padding-left: 10px; }
|
||||
#app-content #app-content-wrapper .actions.creatable .bubble ul .menuitem {
|
||||
font-size: 12px;
|
||||
display: inline; }
|
||||
.credential-table tr td .popovermenu .action {
|
||||
padding: 10px;
|
||||
margin: -10px; }
|
||||
|
||||
.edit_credential {
|
||||
padding-top: 10px; }
|
||||
.edit_credential label {
|
||||
display: block; }
|
||||
.edit_credential input[type="text"], .edit_credential input[type="password"] {
|
||||
width: 100%; }
|
||||
.edit_credential .tags {
|
||||
float: left; }
|
||||
.edit_credential .tags .tag {
|
||||
background-color: rgba(240, 240, 240, 0.9);
|
||||
padding: 4px;
|
||||
font-size: 11px; }
|
||||
.edit_credential .credential_textarea {
|
||||
width: 100%;
|
||||
height: 100px; }
|
||||
.edit_credential .password_settings label {
|
||||
overflow: hidden; }
|
||||
.edit_credential .password_settings label input[type="checkbox"] {
|
||||
width: auto !important;
|
||||
float: left; }
|
||||
.edit_credential .password_settings label .label {
|
||||
float: left; }
|
||||
.edit_credential .password_settings label .label.sm {
|
||||
font-size: 12px; }
|
||||
.edit_credential .custom_fields, .edit_credential .files {
|
||||
margin-top: 10px; }
|
||||
.edit_credential .custom_fields table, .edit_credential .files table {
|
||||
width: 100%; }
|
||||
.edit_credential .custom_fields table thead th, .edit_credential .files table thead th {
|
||||
color: #fff; }
|
||||
.edit_credential .custom_fields table thead th.field_actions, .edit_credential .files table thead th.field_actions {
|
||||
width: 15%; }
|
||||
.edit_credential .custom_fields table tr td.field_actions, .edit_credential .files table tr td.field_actions {
|
||||
font-size: 13px;
|
||||
width: 15%; }
|
||||
.edit_credential .custom_fields table tr td.field_actions i, .edit_credential .files table tr td.field_actions i {
|
||||
#app-content #app-content-wrapper .actions.creatable .bubble:after {
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px; }
|
||||
#app-content #app-content-wrapper .credential-table {
|
||||
width: 100%;
|
||||
margin-top: 44px; }
|
||||
#app-content #app-content-wrapper .credential-table tr:hover {
|
||||
background-color: whitesmoke; }
|
||||
#app-content #app-content-wrapper .credential-table tr.selected {
|
||||
background-color: #f8f8f8; }
|
||||
#app-content #app-content-wrapper .credential-table tr td {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #eeeeee; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .label {
|
||||
float: left; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .tags {
|
||||
float: right; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .tags .tag {
|
||||
background-color: rgba(240, 240, 240, 0.9);
|
||||
padding: 4px;
|
||||
font-size: 11px; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .icon-more {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
opacity: 0.4;
|
||||
height: 20px;
|
||||
width: 32px;
|
||||
cursor: pointer; }
|
||||
.edit_credential .custom_fields table tr td, .edit_credential .custom_fields table tr th, .edit_credential .files table tr td, .edit_credential .files table tr th {
|
||||
width: 20%;
|
||||
padding: 5px; }
|
||||
.edit_credential .custom_fields table tr td .editable-has-buttons.editable-input, .edit_credential .custom_fields table tr th .editable-has-buttons.editable-input, .edit_credential .files table tr td .editable-has-buttons.editable-input, .edit_credential .files table tr th .editable-has-buttons.editable-input {
|
||||
width: 55%; }
|
||||
.edit_credential .custom_fields table tr td, .edit_credential .files table tr td {
|
||||
height: 50px;
|
||||
vertical-align: middle; }
|
||||
.edit_credential .file_tab .progress {
|
||||
margin-top: 10px;
|
||||
height: 10px; }
|
||||
.edit_credential .file_tab .progress .progress-bar {
|
||||
height: 10px;
|
||||
background-image: none;
|
||||
background-color: #0082c9; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .icon-more:hover {
|
||||
opacity: 1; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .popovermenu {
|
||||
margin-top: 25px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, 0.7); }
|
||||
#app-content #app-content-wrapper .credential-table tr td .popovermenu ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .popovermenu ul li {
|
||||
padding: 0px; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .popovermenu ul .menuitem {
|
||||
font-size: 12px;
|
||||
display: inline; }
|
||||
#app-content #app-content-wrapper .credential-table tr td .popovermenu .action {
|
||||
padding: 10px;
|
||||
margin: -10px; }
|
||||
#app-content #app-content-wrapper .edit_credential {
|
||||
padding-top: 10px; }
|
||||
#app-content #app-content-wrapper .edit_credential label {
|
||||
display: block; }
|
||||
#app-content #app-content-wrapper .edit_credential input[type="text"], #app-content #app-content-wrapper .edit_credential input[type="password"] {
|
||||
width: 100%; }
|
||||
#app-content #app-content-wrapper .edit_credential .tags {
|
||||
float: left; }
|
||||
#app-content #app-content-wrapper .edit_credential .tags .tag {
|
||||
background-color: rgba(240, 240, 240, 0.9);
|
||||
padding: 4px;
|
||||
font-size: 11px; }
|
||||
#app-content #app-content-wrapper .edit_credential .credential_textarea {
|
||||
width: 100%;
|
||||
height: 100px; }
|
||||
#app-content #app-content-wrapper .edit_credential .password_settings label {
|
||||
overflow: hidden; }
|
||||
#app-content #app-content-wrapper .edit_credential .password_settings label input[type="checkbox"] {
|
||||
width: auto !important;
|
||||
float: left; }
|
||||
#app-content #app-content-wrapper .edit_credential .password_settings label .label {
|
||||
float: left; }
|
||||
#app-content #app-content-wrapper .edit_credential .password_settings label .label.sm {
|
||||
font-size: 12px; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields, #app-content #app-content-wrapper .edit_credential .files {
|
||||
margin-top: 10px; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table, #app-content #app-content-wrapper .edit_credential .files table {
|
||||
width: 100%; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table thead th, #app-content #app-content-wrapper .edit_credential .files table thead th {
|
||||
color: #fff; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table thead th.field_actions, #app-content #app-content-wrapper .edit_credential .files table thead th.field_actions {
|
||||
width: 15%; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table tr td.field_actions, #app-content #app-content-wrapper .edit_credential .files table tr td.field_actions {
|
||||
font-size: 13px;
|
||||
width: 15%; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table tr td.field_actions i, #app-content #app-content-wrapper .edit_credential .files table tr td.field_actions i {
|
||||
cursor: pointer; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table tr td, #app-content #app-content-wrapper .edit_credential .custom_fields table tr th, #app-content #app-content-wrapper .edit_credential .files table tr td, #app-content #app-content-wrapper .edit_credential .files table tr th {
|
||||
width: 20%;
|
||||
padding: 5px; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table tr td .editable-has-buttons.editable-input, #app-content #app-content-wrapper .edit_credential .custom_fields table tr th .editable-has-buttons.editable-input, #app-content #app-content-wrapper .edit_credential .files table tr td .editable-has-buttons.editable-input, #app-content #app-content-wrapper .edit_credential .files table tr th .editable-has-buttons.editable-input {
|
||||
width: 55%; }
|
||||
#app-content #app-content-wrapper .edit_credential .custom_fields table tr td, #app-content #app-content-wrapper .edit_credential .files table tr td {
|
||||
height: 50px;
|
||||
vertical-align: middle; }
|
||||
#app-content #app-content-wrapper .edit_credential .file_tab .progress {
|
||||
margin-top: 10px;
|
||||
height: 10px; }
|
||||
#app-content #app-content-wrapper .edit_credential .file_tab .progress .progress-bar {
|
||||
height: 10px;
|
||||
background-image: none;
|
||||
background-color: #0082c9; }
|
||||
#app-content #app-content-wrapper .view_pane {
|
||||
-webkit-box-shadow: 0px -4px 3px rgba(150, 150, 150, 0.75);
|
||||
-moz-box-shadow: 0px -4px 3px rgba(150, 150, 150, 0.75);
|
||||
box-shadow: 0px -4px 3px rgba(150, 150, 150, 0.75);
|
||||
padding-top: 10px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
background-color: #eee;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
overflow-y: auto; }
|
||||
#app-content #app-content-wrapper .view_pane .row {
|
||||
margin-left: 0;
|
||||
margin-right: 0; }
|
||||
#app-content #app-content-wrapper .view_pane.item_selected {
|
||||
height: 20%;
|
||||
display: inline-block; }
|
||||
|
||||
.settings-container div {
|
||||
padding-left: 15px; }
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -31,6 +31,18 @@ angular.module('passmanApp')
|
|||
$location.path('/vault/'+ $scope.active_vault.vault_id +'/new')
|
||||
};
|
||||
|
||||
$scope.editCredential = function(credential){
|
||||
var credential = angular.copy(credential);
|
||||
SettingsService.setSetting('edit_credential',credential);
|
||||
$location.path('/vault/'+ $scope.active_vault.vault_id +'/edit/'+ credential.credential_id)
|
||||
};
|
||||
|
||||
$scope.selectedCredential = false;
|
||||
$scope.selectCredential = function (credential) {
|
||||
console.log(credential);
|
||||
$scope.selectedCredential = credential
|
||||
}
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
console.log('Logout received, clean up');
|
||||
$scope.credentials = [];
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService) {
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
|
||||
|
||||
|
@ -143,6 +143,7 @@ angular.module('passmanApp')
|
|||
};
|
||||
FileService.uploadFile(_file).then(function (result) {
|
||||
delete result.file_data;
|
||||
result.filename = EncryptService.decryptString(result.filename);
|
||||
$scope.storedCredential.files.push(result);
|
||||
});
|
||||
|
||||
|
@ -177,5 +178,27 @@ angular.module('passmanApp')
|
|||
qrInfo[parsedQR[5]] = parsedQR[6];
|
||||
$scope.storedCredential.otp = qrInfo;
|
||||
$scope.$apply()
|
||||
};
|
||||
|
||||
$scope.saveCredential = function () {
|
||||
|
||||
delete $scope.storedCredential.password_repeat;
|
||||
if(!$scope.storedCredential.credential_id){
|
||||
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;
|
||||
CredentialService.createCredential($scope.storedCredential).then(function (result) {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
//@TODO Show notification
|
||||
})
|
||||
} else {
|
||||
CredentialService.updateCredential($scope.storedCredential).then(function (result) {
|
||||
SettingsService.setSetting('edit_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
//@TODO Show notification
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
$scope.cancel = function(){
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
}
|
||||
}]);
|
||||
|
|
18
js/app/filters/decrypt.js
Normal file
18
js/app/filters/decrypt.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:decrypt
|
||||
* @function
|
||||
* @description
|
||||
* # decrypt
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('decrypt',['EncryptService', function (EncryptService) {
|
||||
return function (input) {
|
||||
if(input) {
|
||||
return EncryptService.decryptString(input);
|
||||
}
|
||||
};
|
||||
}]);
|
|
@ -24,28 +24,31 @@ angular.module('passmanApp')
|
|||
'url': null,
|
||||
'favicon': null,
|
||||
'renew_interval': null,
|
||||
'expire_time': null,
|
||||
'expire_time': 0,
|
||||
'delete_time': 0,
|
||||
'files': [],
|
||||
'custom_fields': [],
|
||||
'otp': {},
|
||||
'hidden': false
|
||||
};
|
||||
var _encryptedFields = ['description','username','password','files','custom_fields','otp'];
|
||||
var _encryptedFields = ['description', 'username', 'password', 'files', 'custom_fields', 'otp', 'email', 'tags', 'url'];
|
||||
|
||||
|
||||
return {
|
||||
newCredential: function () {
|
||||
return angular.copy(credential);
|
||||
},
|
||||
createCredential: function (credential) {
|
||||
for(var i = 0; i < _encryptedFields.length; i++){
|
||||
var _credential = angular.copy(credential);
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
}
|
||||
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials');
|
||||
return $http.post(queryUrl, credential).then(function (response) {
|
||||
if(response.data){
|
||||
return $http.post(queryUrl, _credential).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
|
@ -53,15 +56,16 @@ angular.module('passmanApp')
|
|||
});
|
||||
},
|
||||
updateCredential: function (credential) {
|
||||
for(var i = 0; i < _encryptedFields.length; i++){
|
||||
var _credential = angular.copy(credential);
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
_credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
}
|
||||
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/'+ credential.credential_id);
|
||||
return $http.post(queryUrl, credential).then(function (response) {
|
||||
if(response.data){
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/credentials/' + credential.credential_id);
|
||||
return $http.patch(queryUrl, _credential).then(function (response) {
|
||||
if (response.data) {
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
|
@ -69,7 +73,7 @@ angular.module('passmanApp')
|
|||
});
|
||||
},
|
||||
encryptCredential: function (credential) {
|
||||
for(var i = 0; i < _encryptedFields.length; i++){
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
credential[field] = EncryptService.encryptString(JSON.stringify(fieldValue));
|
||||
|
@ -77,7 +81,7 @@ angular.module('passmanApp')
|
|||
return credential;
|
||||
},
|
||||
decryptCredential: function (credential) {
|
||||
for(var i = 0; i < _encryptedFields.length; i++){
|
||||
for (var i = 0; i < _encryptedFields.length; i++) {
|
||||
var field = _encryptedFields[i];
|
||||
var fieldValue = angular.copy(credential[field]);
|
||||
credential[field] = JSON.parse(EncryptService.decryptString(fieldValue));
|
||||
|
|
|
@ -13,6 +13,7 @@ angular.module('passmanApp')
|
|||
uploadFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file');
|
||||
var _file = angular.copy(file);
|
||||
_file.filename = EncryptService.encryptString(_file.filename);
|
||||
var data = EncryptService.encryptString(angular.copy(file.data));
|
||||
_file.data = data;
|
||||
return $http.post(queryUrl, _file).then(function (response) {
|
||||
|
|
|
@ -3,7 +3,7 @@ angular.module('templates-main', ['views/edit_credential.html', 'views/partials/
|
|||
angular.module('views/edit_credential.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/edit_credential.html',
|
||||
'<ul class="tab_header"><li ng-repeat="tab in tabs track by $index" class="tab" ng-class="{active:isActiveTab(tab)}" ng-click="onClickTab(tab)">{{tab.title}}</li></ul><div class="tab_container edit_credential"><div ng-include="currentTab.url"></div></div><textarea>\n' +
|
||||
'<ul class="tab_header"><li ng-repeat="tab in tabs track by $index" class="tab" ng-class="{active:isActiveTab(tab)}" ng-click="onClickTab(tab)">{{tab.title}}</li></ul><div class="tab_container edit_credential"><div ng-include="currentTab.url"></div></div><button ng-click="saveCredential()">Save</button> <button ng-click="cancel()">Cancel</button><textarea>\n' +
|
||||
'{{storedCredential}}\n' +
|
||||
' </textarea>');
|
||||
}]);
|
||||
|
@ -11,7 +11,7 @@ angular.module('views/edit_credential.html', []).run(['$templateCache', function
|
|||
angular.module('views/partials/forms/edit_credential/basics.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/partials/forms/edit_credential/basics.html',
|
||||
'<div class="row"><div class="col-xs-12 col-md-6"><label>Label</label><div><input type="text" ng-model="storedCredential.label"></div><label>Usermame</label><div><input type="text" ng-model="storedCredential.username"></div><label>E-mail</label><div><input type="text" ng-model="storedCredential.email"></div><label>Password</label><div><password-gen ng-model="storedCredential.password" settings="pwSettings" callback="pwGenerated"></password-gen><ng-password-meter password="storedCredential.password"></ng-password-meter></div><div><label>Repeat password</label><input type="password" ng-model="storedCredential.password_repeat"></div><label>URL</label><div><input type="text" ng-model="storedCredential.url"></div></div><div class="col-xs-12 col-md-6"><label>Description</label><div><textarea class="credential_textarea"></textarea></div><label>Add Tag</label><div><input type="text" placeholder="Add a tag"></div><label>Tags</label><div><div class="tags"><div class="tag">test</div></div></div></div></div>');
|
||||
'<div class="row"><div class="col-xs-12 col-md-6"><label>Label</label><div><input type="text" ng-model="storedCredential.label"></div><label>Usermame</label><div><input type="text" ng-model="storedCredential.username"></div><label>E-mail</label><div><input type="text" ng-model="storedCredential.email"></div><label>Password</label><div><password-gen ng-model="storedCredential.password" settings="pwSettings" callback="pwGenerated"></password-gen><ng-password-meter password="storedCredential.password"></ng-password-meter></div><div><label>Repeat password</label><input type="password" ng-model="storedCredential.password_repeat"></div><label>URL</label><div><input type="text" ng-model="storedCredential.url"></div></div><div class="col-xs-12 col-md-6"><label>Description</label><div><textarea class="credential_textarea" ng-model="storedCredential.description"></textarea></div><label>Add Tag</label><div><input type="text" placeholder="Add a tag"></div><label>Tags</label><div><div class="tags"><div class="tag">test</div></div></div></div></div>');
|
||||
}]);
|
||||
|
||||
angular.module('views/partials/forms/edit_credential/custom_fields.html', []).run(['$templateCache', function($templateCache) {
|
||||
|
@ -47,7 +47,7 @@ angular.module('views/partials/password-meter.html', []).run(['$templateCache',
|
|||
angular.module('views/show_vault.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/show_vault.html',
|
||||
'<div id="controls"><div class="breadcrumb"></div><div class="actions creatable"><span ng-click="menuOpen = !menuOpen" class="button new" ng-init="menuOpen = false" off-click="menuOpen = false;"><span>New</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span ng-click="addCredential()" class="menuitem action"><span class="icon icon-rename"></span> <span>New credential</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-shared"></span> <span>New shared credential</span></span></li></ul></div></div></div><table class="credential-table" ng-init="menuOpen = false"><tr ng-repeat="credential in credentials"><td><span class="label">{{credential.label}}</span> <span class="icon icon-more" ng-click="menuOpen = !menuOpen" off-click="menuOpen = false;"></span> <span class="tags"><span class="tag">Tag 1</span> <span class="tag">Tag 2</span> <span class="tag">Tag 4</span> <span class="tag">Tag 4</span> <span class="tag">Long tag xD</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span class="menuitem action"><span class="icon icon-rename"></span><span>Edit</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-share"></span><span>Share</span></span></li><li><span class="menuitem action" data-action="Delete"><span class="icon icon-delete"></span><span>Delete</span></span></li></ul></div></td></tr></table>');
|
||||
'<div id="controls"><div class="breadcrumb"></div><div class="actions creatable"><span ng-click="menuOpen = !menuOpen" class="button new" ng-init="menuOpen = false" off-click="menuOpen = false;"><span>New</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li><span ng-click="addCredential()" class="menuitem action"><span class="icon icon-rename"></span> <span>New credential</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-shared"></span> <span>New shared credential</span></span></li></ul></div></div></div><table class="credential-table" ng-init="menuOpen = false;"><tr ng-repeat="credential in credentials" ng-if="credential.hidden == 0 && credential.delete_time == 0" ng-click="selectCredential(credential)" ng-class="{\'selected\': selectedCredential.credential_id == credential.credential_id}"><td><span class="label">{{credential.label}}</span> <span class="icon icon-more" ng-click="menuOpen = !menuOpen" off-click="menuOpen = false;"></span> <span class="tags"><span class="tag">Tag 1</span> <span class="tag">Tag 2</span> <span class="tag">Tag 4</span> <span class="tag">Tag 4</span> <span class="tag">Long tag xD</span></span><div class="actionList popovermenu bubble menu" ng-show="menuOpen"><ul><li ng-click="editCredential(credential)"><span class="menuitem action"><span class="icon icon-rename"></span><span>Edit</span></span></li><li><span href="#" class="menuitem action"><span class="icon icon-share"></span><span>Share</span></span></li><li><span class="menuitem action" data-action="Delete"><span class="icon icon-delete"></span><span>Delete</span></span></li></ul></div></td></tr></table><div class="view_pane" ng-class="{\'item_selected\': selectedCredential}"><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Label</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Account</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Password</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Files</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Custom fields</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Changed</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div><div class="row"><div class="col-xs-2 col-sm-2 col-md-1">Created</div><div class="col-xs-6 col-sm-4 col-md-4">{{selectedCredential.label}}</div></div></div>');
|
||||
}]);
|
||||
|
||||
angular.module('views/vaults.html', []).run(['$templateCache', function($templateCache) {
|
||||
|
|
|
@ -93,6 +93,8 @@ class Credential extends Entity implements \JsonSerializable{
|
|||
$this->addType('renewInterval', 'integer');
|
||||
$this->addType('expireTime', 'integer');
|
||||
$this->addType('deleteTime', 'integer');
|
||||
$this->addType('vault_id', 'integer');
|
||||
$this->addType('credential_id', 'integer');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,4 +58,26 @@ class CredentialMapper extends Mapper {
|
|||
return parent::insert($credential);
|
||||
}
|
||||
|
||||
public function update($raw_credential){
|
||||
$credential = new Credential();
|
||||
$credential->setId($raw_credential['credential_id']);
|
||||
$credential->setUserId($raw_credential['user_id']);
|
||||
$credential->setLabel($raw_credential['label']);
|
||||
$credential->setDescription($raw_credential['description']);
|
||||
$credential->setChanged($this->utils->getTime());
|
||||
$credential->setTags($raw_credential['tags']);
|
||||
$credential->setEmail($raw_credential['email']);
|
||||
$credential->setUsername($raw_credential['username']);
|
||||
$credential->setPassword($raw_credential['password']);
|
||||
$credential->setUrl($raw_credential['url']);
|
||||
$credential->setFavicon($raw_credential['favicon']);
|
||||
$credential->setRenewInterval($raw_credential['renew_interval']);
|
||||
$credential->setExpireTime($raw_credential['expire_time']);
|
||||
$credential->setFiles($raw_credential['files']);
|
||||
$credential->setCustomFields($raw_credential['custom_fields']);
|
||||
$credential->setOtp($raw_credential['otp']);
|
||||
$credential->setHidden($raw_credential['hidden']);
|
||||
return parent::update($credential);
|
||||
}
|
||||
|
||||
}
|
|
@ -29,6 +29,10 @@ class CredentialService {
|
|||
return $this->credentialMapper->create($credential);
|
||||
}
|
||||
|
||||
public function updateCredential($credential) {
|
||||
return $this->credentialMapper->update($credential);
|
||||
}
|
||||
|
||||
public function getCredentialsByVaultId($vault_id, $user_id){
|
||||
return $this->credentialMapper->getCredentialsByVaultId($vault_id, $user_id);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
@import 'container';
|
||||
@import 'partials/button';
|
||||
@import 'partials/popovermenu';
|
||||
@import 'partials/tabs';
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
.actions.creatable{
|
||||
padding-left: 10px;
|
||||
.bubble{
|
||||
position: relative;
|
||||
width: 185px;
|
||||
@include border-radius(5px);
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, .7);
|
||||
ul{
|
||||
li{
|
||||
padding-left: 10px;
|
||||
}
|
||||
.menuitem{
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bubble:after{
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px;
|
||||
}
|
||||
}
|
||||
#app-content-wrapper{
|
||||
min-height: 95%;
|
||||
}
|
|
@ -1,143 +1,196 @@
|
|||
.credential-table {
|
||||
width: 100%;
|
||||
margin-top: 44px;
|
||||
tr:hover {
|
||||
background-color: darken(#fff, 4%);
|
||||
}
|
||||
tr {
|
||||
td {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
.label {
|
||||
float: left;
|
||||
}
|
||||
.tags {
|
||||
float: right;
|
||||
.tag {
|
||||
background-color: rgba(240, 240, 240, .9);
|
||||
padding: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
.icon-more {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
opacity: 0.4;
|
||||
height: 20px;
|
||||
width: 32px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-more:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.popovermenu {
|
||||
margin-top: 7px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
#app-content {
|
||||
overflow-x: hidden;
|
||||
#app-content-wrapper {
|
||||
min-height: 95%;
|
||||
.actions.creatable {
|
||||
padding-left: 10px;
|
||||
.bubble {
|
||||
position: relative;
|
||||
width: 185px;
|
||||
@include border-radius(5px);
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, .7);
|
||||
ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px;
|
||||
li {
|
||||
padding: 0px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.menuitem {
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.action {
|
||||
padding: 10px;
|
||||
margin: -10px;
|
||||
}
|
||||
}
|
||||
.bubble:after {
|
||||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit_credential {
|
||||
padding-top: 10px;
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
input[type="text"], input[type="password"] {
|
||||
width: 100%;
|
||||
}
|
||||
.tags {
|
||||
float: left;
|
||||
.tag {
|
||||
background-color: rgba(240, 240, 240, .9);
|
||||
padding: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
.credential_textarea {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
}
|
||||
.password_settings {
|
||||
label {
|
||||
overflow: hidden;
|
||||
input[type="checkbox"] {
|
||||
width: auto !important;
|
||||
float: left;
|
||||
}
|
||||
.label {
|
||||
&.sm{
|
||||
font-size: 12px;
|
||||
}
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
.custom_fields, .files {
|
||||
margin-top: 10px;
|
||||
table {
|
||||
.credential-table {
|
||||
width: 100%;
|
||||
thead {
|
||||
th {
|
||||
color: #fff;
|
||||
}
|
||||
th.field_actions {
|
||||
width: 15%;
|
||||
}
|
||||
margin-top: 44px;
|
||||
tr:hover {
|
||||
background-color: darken(#fff, 4%);
|
||||
}
|
||||
tr {
|
||||
td.field_actions {
|
||||
font-size: 13px;
|
||||
width: 15%;
|
||||
i{
|
||||
&.selected {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
td {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
.label {
|
||||
float: left;
|
||||
}
|
||||
.tags {
|
||||
float: right;
|
||||
.tag {
|
||||
background-color: rgba(240, 240, 240, .9);
|
||||
padding: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
.icon-more {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
opacity: 0.4;
|
||||
height: 20px;
|
||||
width: 32px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
td, th {
|
||||
width: 20%;
|
||||
padding: 5px;
|
||||
.editable-has-buttons.editable-input {
|
||||
width: 55%;
|
||||
.icon-more:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.popovermenu {
|
||||
margin-top: 25px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
right: -2px !important;
|
||||
box-shadow: 0 1px 10px rgba(50, 50, 50, .7);
|
||||
ul {
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 75px;
|
||||
li {
|
||||
padding: 0px;
|
||||
}
|
||||
.menuitem {
|
||||
font-size: 12px;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.action {
|
||||
padding: 10px;
|
||||
margin: -10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
td{
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.file_tab{
|
||||
.progress{
|
||||
margin-top: 10px;
|
||||
height: 10px;
|
||||
.progress-bar{
|
||||
height: 10px;
|
||||
background-image: none;
|
||||
background-color: #0082c9;
|
||||
|
||||
.edit_credential {
|
||||
padding-top: 10px;
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
input[type="text"], input[type="password"] {
|
||||
width: 100%;
|
||||
}
|
||||
.tags {
|
||||
float: left;
|
||||
.tag {
|
||||
background-color: rgba(240, 240, 240, .9);
|
||||
padding: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
.credential_textarea {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
}
|
||||
.password_settings {
|
||||
label {
|
||||
overflow: hidden;
|
||||
input[type="checkbox"] {
|
||||
width: auto !important;
|
||||
float: left;
|
||||
}
|
||||
.label {
|
||||
&.sm {
|
||||
font-size: 12px;
|
||||
}
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
.custom_fields, .files {
|
||||
margin-top: 10px;
|
||||
table {
|
||||
width: 100%;
|
||||
thead {
|
||||
th {
|
||||
color: #fff;
|
||||
}
|
||||
th.field_actions {
|
||||
width: 15%;
|
||||
}
|
||||
}
|
||||
tr {
|
||||
td.field_actions {
|
||||
font-size: 13px;
|
||||
width: 15%;
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
td, th {
|
||||
width: 20%;
|
||||
padding: 5px;
|
||||
.editable-has-buttons.editable-input {
|
||||
width: 55%;
|
||||
}
|
||||
}
|
||||
td {
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.file_tab {
|
||||
.progress {
|
||||
margin-top: 10px;
|
||||
height: 10px;
|
||||
.progress-bar {
|
||||
height: 10px;
|
||||
background-image: none;
|
||||
background-color: #0082c9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.view_pane {
|
||||
-webkit-box-shadow: 0px -4px 3px rgba(150, 150, 150, 0.75);
|
||||
-moz-box-shadow: 0px -4px 3px rgba(150, 150, 150, 0.75);
|
||||
box-shadow: 0px -4px 3px rgba(150, 150, 150, 0.75);
|
||||
padding-top: 10px;
|
||||
.row {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
&.item_selected {
|
||||
height: 20%;
|
||||
display: inline-block;
|
||||
}
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
background-color: #eee;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ script('passman', 'app/controllers/credential');
|
|||
script('passman', 'app/controllers/edit_credential');
|
||||
script('passman', 'app/filters/range');
|
||||
script('passman', 'app/filters/propsfilter');
|
||||
script('passman', 'app/filters/decrypt');
|
||||
script('passman', 'app/services/cacheservice');
|
||||
script('passman', 'app/services/vaultservice');
|
||||
script('passman', 'app/services/credentialservice');
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<div class="tab_container edit_credential">
|
||||
<div ng-include="currentTab.url"></div>
|
||||
</div>
|
||||
<button ng-click="saveCredential()">Save</button>
|
||||
<button ng-click="cancel()">Cancel</button>
|
||||
<textarea>
|
||||
{{storedCredential}}
|
||||
</textarea>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<div class="col-xs-12 col-md-6">
|
||||
<label>Description</label>
|
||||
<div>
|
||||
<textarea class="credential_textarea"></textarea>
|
||||
<textarea class="credential_textarea" ng-model="storedCredential.description"></textarea>
|
||||
</div>
|
||||
<label>Add Tag</label>
|
||||
<div>
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="credential-table" ng-init="menuOpen = false">
|
||||
<tr ng-repeat="credential in credentials">
|
||||
<table class="credential-table" ng-init="menuOpen = false;">
|
||||
<tr ng-repeat="credential in credentials" ng-if="credential.hidden == 0 && credential.delete_time == 0" ng-click="selectCredential(credential)" ng-class="{'selected': selectedCredential.credential_id == credential.credential_id}">
|
||||
<td>
|
||||
<span class="label">{{credential.label}}</span>
|
||||
<span class="icon icon-more" ng-click="menuOpen = !menuOpen"
|
||||
|
@ -44,7 +44,7 @@
|
|||
</span>
|
||||
<div class="actionList popovermenu bubble menu" ng-show="menuOpen">
|
||||
<ul>
|
||||
<li><span
|
||||
<li ng-click="editCredential(credential)"><span
|
||||
class="menuitem action"
|
||||
><span
|
||||
class="icon icon-rename"></span><span>Edit</span></span>
|
||||
|
@ -63,4 +63,66 @@
|
|||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
<div class="view_pane" ng-class="{'item_selected': selectedCredential}" >
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Label
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Account
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Password
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Files
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Custom fields
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Changed
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
Created
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{selectedCredential.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
Loading…
Add table
Reference in a new issue