mirror of
https://github.com/nextcloud/passman.git
synced 2025-09-14 17:04:43 +08:00
Filtering with tags work, add oc notificaton service
This commit is contained in:
parent
2fc84e2a7b
commit
8d0f70f357
19 changed files with 462 additions and 125 deletions
|
@ -89,6 +89,7 @@ class CredentialController extends ApiController {
|
|||
'description' => $description,
|
||||
'created' => $created,
|
||||
'changed' => $changed,
|
||||
'vault_id' => $vault_id,
|
||||
'tags' => $tags,
|
||||
'email' => $email,
|
||||
'username' => $username,
|
||||
|
@ -99,6 +100,8 @@ class CredentialController extends ApiController {
|
|||
'expire_time' => $expire_time,
|
||||
'files' => $files,
|
||||
'custom_fields' => $custom_fields,
|
||||
'delete_time' => $delete_time,
|
||||
'hidden' => $hidden,
|
||||
'otp' => $otp,
|
||||
);
|
||||
$credential = $this->credentialService->updateCredential($credential);
|
||||
|
|
37
css/app.css
37
css/app.css
|
@ -56,7 +56,7 @@
|
|||
.pw-gen {
|
||||
overflow: hidden; }
|
||||
.pw-gen input {
|
||||
width: calc(100% - 76px) !important;
|
||||
width: calc(100% - 80px) !important;
|
||||
float: left;
|
||||
background: #fff;
|
||||
color: #555;
|
||||
|
@ -163,6 +163,10 @@
|
|||
right: inherit;
|
||||
left: 10px;
|
||||
top: -19px; }
|
||||
#app-content #app-content-wrapper .actions.creatable .title {
|
||||
width: calc( 100% - 185px);
|
||||
text-align: center;
|
||||
display: inline-block; }
|
||||
#app-content #app-content-wrapper .credential-table {
|
||||
width: 100%;
|
||||
margin-top: 44px; }
|
||||
|
@ -287,8 +291,15 @@
|
|||
padding: 2px;
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
height: 20px;
|
||||
height: 25px;
|
||||
vertical-align: middle; }
|
||||
#app-content #app-content-wrapper .app_sidebar .tags {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px; }
|
||||
#app-content #app-content-wrapper .app_sidebar .tags .tag {
|
||||
background-color: rgba(240, 240, 240, 0.9);
|
||||
padding: 4px;
|
||||
margin-right: 3px; }
|
||||
|
||||
.credential_field {
|
||||
overflow: hidden; }
|
||||
|
@ -305,6 +316,28 @@
|
|||
.settings-container div {
|
||||
padding-left: 15px; }
|
||||
|
||||
.nav-trashbin {
|
||||
position: fixed !important;
|
||||
bottom: 44px;
|
||||
width: inherit !important;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #eee; }
|
||||
.nav-trashbin a {
|
||||
padding: 0 20px; }
|
||||
.nav-trashbin a .fa {
|
||||
margin-right: 15px; }
|
||||
|
||||
#app-navigation li a.taginput {
|
||||
opacity: 1; }
|
||||
#app-navigation li a {
|
||||
overflow: visible; }
|
||||
#app-navigation li a tags-input {
|
||||
opacity: 1.0; }
|
||||
#app-navigation li a tags-input li {
|
||||
width: auto !important; }
|
||||
#app-navigation > ul ul {
|
||||
display: inherit !important; }
|
||||
|
||||
#app-settings-content:not(.ng-hide) {
|
||||
height: 60px;
|
||||
display: inherit !important;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -51,3 +51,30 @@ angular
|
|||
localStorageServiceProvider
|
||||
.setNotify(true, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery for notification handling D:
|
||||
**/
|
||||
jQuery(document).ready(function () {
|
||||
var findItemByID = function(id){
|
||||
var credentials,foundItem=false;
|
||||
credentials = angular.element('#app-content-wrapper').scope().credentials;
|
||||
console.log(id, credentials)
|
||||
angular.forEach(credentials, function(credential){
|
||||
if(credential.credential_id == id){
|
||||
foundItem = credential;
|
||||
}
|
||||
});
|
||||
return foundItem;
|
||||
};
|
||||
jQuery(document).on('click', '.undoDelete', function () {
|
||||
var credential = findItemByID($(this).attr('data-item-id'));
|
||||
angular.element('#app-content-wrapper').scope().recoverCredential(credential);
|
||||
angular.element('#app-content-wrapper').scope().$apply();
|
||||
});
|
||||
jQuery(document).on('click', '.undoRestore', function () {
|
||||
var credential = findItemByID($(this).attr('data-item-id'));
|
||||
angular.element('#app-content-wrapper').scope().deleteCredential(credential);
|
||||
angular.element('#app-content-wrapper').scope().$apply();
|
||||
});
|
||||
});
|
|
@ -8,92 +8,179 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService', '$rootScope', 'FileService', 'EncryptService', 'TagService', function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
//@TODO check if vault exists
|
||||
.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
|
||||
'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService',
|
||||
function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
$location.path('/')
|
||||
}
|
||||
} else {
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
|
||||
_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
|
||||
VaultService.setActiveVault(_vault);
|
||||
$scope.active_vault = _vault;
|
||||
//@TODO check if vault exists
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
$scope.addCredential = function () {
|
||||
var new_credential = CredentialService.newCredential();
|
||||
var enc_c = CredentialService.encryptCredential(new_credential);
|
||||
SettingsService.setSetting('edit_credential', enc_c);
|
||||
$location.path('/vault/' + $scope.active_vault.vault_id + '/new')
|
||||
};
|
||||
|
||||
$scope.addCredential = function(){
|
||||
var new_credential = CredentialService.newCredential();
|
||||
var enc_c = CredentialService.encryptCredential(new_credential);
|
||||
SettingsService.setSetting('edit_credential',enc_c);
|
||||
$location.path('/vault/'+ $scope.active_vault.vault_id +'/new')
|
||||
};
|
||||
$scope.editCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/' + $scope.active_vault.vault_id + '/edit/' + _credential.credential_id)
|
||||
};
|
||||
|
||||
$scope.editCredential = function(credential){
|
||||
var _credential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', false);
|
||||
SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
|
||||
$location.path('/vault/'+ $scope.active_vault.vault_id +'/edit/'+ _credential.credential_id)
|
||||
};
|
||||
var notification;
|
||||
$scope.deleteCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
try {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
} catch (e) {
|
||||
|
||||
$scope.selectedCredential = false;
|
||||
$scope.selectCredential = function (credential) {
|
||||
$scope.selectedCredential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
}
|
||||
_credential.delete_time = new Date().getTime() / 1000;
|
||||
for (var i = 0; i < $scope.credentials.length; i++) {
|
||||
if ($scope.credentials[i].credential_id == credential.credential_id) {
|
||||
$scope.credentials[i].delete_time = _credential.delete_time;
|
||||
}
|
||||
}
|
||||
$scope.closeSelected();
|
||||
if (notification) {
|
||||
NotificationService.hideNotification(notification);
|
||||
}
|
||||
notification = NotificationService.showNotification('Credential deleted <a class="undoDelete" data-item-id="' + credential.credential_id + '">[Undo]</a>', 5000,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
if (result.delete_time > 0) {
|
||||
notification = false;
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.recoverCredential = function (credential) {
|
||||
var _credential = angular.copy(credential);
|
||||
try {
|
||||
_credential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
for (var i = 0; i < $scope.credentials.length; i++) {
|
||||
if ($scope.credentials[i].credential_id == credential.credential_id) {
|
||||
$scope.credentials[i].delete_time = 0;
|
||||
}
|
||||
}
|
||||
_credential.delete_time = 0;
|
||||
$scope.closeSelected();
|
||||
if (notification) {
|
||||
NotificationService.hideNotification(notification);
|
||||
}
|
||||
NotificationService.showNotification('Credential recovered <a class="undoRestore" data-item-id="' + credential.credential_id + '">[Undo]</a>', 7500,
|
||||
function () {
|
||||
CredentialService.updateCredential(_credential).then(function (result) {
|
||||
notification = false;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.itemFilter = {
|
||||
label: ''
|
||||
};
|
||||
$scope.selectedtags = [];
|
||||
$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
|
||||
var _selectedTags = []
|
||||
for(var x = 0; x < _sTags.length; x++){
|
||||
_selectedTags.push(_sTags[x].text)
|
||||
}
|
||||
console.log(_selectedTags)
|
||||
$scope.selectedtags = _selectedTags;
|
||||
});
|
||||
|
||||
$scope.delete_time = 0;
|
||||
$scope.showCredentialRow = function (credential) {
|
||||
if ($scope.delete_time == 0) {
|
||||
return credential.delete_time == 0
|
||||
} else {
|
||||
return credential.delete_time > $scope.delete_time;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$rootScope.$on('set_delete_time', function (event, time) {
|
||||
$scope.delete_time = time;
|
||||
});
|
||||
|
||||
$scope.setDeleteTime = function (delete_time) {
|
||||
$scope.delete_time = delete_time;
|
||||
};
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedCredential = false;
|
||||
};
|
||||
$scope.selectCredential = function (credential) {
|
||||
$scope.selectedCredential = CredentialService.decryptCredential(angular.copy(credential));
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
console.log('Logout received, clean up');
|
||||
$scope.credentials = [];
|
||||
if ($scope.hasOwnProperty('$parent')) {
|
||||
if ($scope.$parent.hasOwnProperty('selectedVault')) {
|
||||
$scope.$parent.selectedVault = false;
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedCredential = false;
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
console.log('Logout received, clean up');
|
||||
$scope.credentials = [];
|
||||
if ($scope.hasOwnProperty('$parent')) {
|
||||
if ($scope.$parent.hasOwnProperty('selectedVault')) {
|
||||
$scope.$parent.selectedVault = false;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.active_vault = null;
|
||||
});
|
||||
|
||||
var fetchCredentials = function () {
|
||||
VaultService.getVault($scope.active_vault).then(function (credentials) {
|
||||
var _credentials = [];
|
||||
for (var i = 0; i < credentials.length; i++) {
|
||||
var credential = angular.copy(credentials[i]);
|
||||
var _tags = CredentialService.decryptCredential(angular.copy(credentials[i])).tags;
|
||||
TagService.addTags(_tags);
|
||||
credential.tags_raw = _tags;
|
||||
_credentials.push(credential);
|
||||
}
|
||||
$scope.credentials = _credentials;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.downloadFile = function (file) {
|
||||
FileService.getFile(file).then(function (result) {
|
||||
var file_data = EncryptService.decryptString(result.file_data);
|
||||
var uriContent = FileService.dataURItoBlob(file_data, file.mimetype), a = document.createElement("a");
|
||||
a.style = "display: none";
|
||||
a.href = uriContent;
|
||||
a.download = escapeHTML(file.filename);
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(uriContent);
|
||||
});
|
||||
};
|
||||
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
fetchCredentials();
|
||||
}
|
||||
|
||||
$scope.active_vault = null;
|
||||
});
|
||||
|
||||
var fetchCredentials = function () {
|
||||
VaultService.getVault($scope.active_vault).then(function (credentials) {
|
||||
var _credentials = [];
|
||||
for (var i = 0; i < credentials.length; i++) {
|
||||
var credential = angular.copy(credentials[i]);
|
||||
var _tags = CredentialService.decryptCredential(angular.copy(credentials[i])).tags;
|
||||
TagService.addTags(_tags)
|
||||
credential.tags_raw = _tags;
|
||||
_credentials.push(credential);
|
||||
}
|
||||
$scope.credentials = _credentials;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.downloadFile = function (file) {
|
||||
FileService.getFile(file).then(function (result) {
|
||||
var file_data = EncryptService.decryptString(result.file_data);
|
||||
var uriContent = FileService.dataURItoBlob(file_data, file.mimetype), a = document.createElement("a");
|
||||
a.style = "display: none";
|
||||
a.href = uriContent;
|
||||
a.download = escapeHTML(file.filename);
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(uriContent);
|
||||
});
|
||||
};
|
||||
|
||||
//@TODO TagService which holds all the tags
|
||||
//@TODO Show otp field
|
||||
|
||||
if ($scope.active_vault) {
|
||||
$scope.$parent.selectedVault = true;
|
||||
fetchCredentials();
|
||||
}
|
||||
}]);
|
||||
}]);
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', 'TagService', function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService, TagService) {
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', 'TagService', 'NotificationService',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService, TagService, NotificationService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
|
||||
|
||||
|
@ -105,12 +106,10 @@ angular.module('passmanApp')
|
|||
|
||||
$scope.addCustomField = function () {
|
||||
if (!$scope.new_custom_field.label) {
|
||||
//@TODO move OC.Notification to a service
|
||||
OC.Notification.showTemporary('Please fill in a label');
|
||||
NotificationService.showNotification('Please fill in a label', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.value) {
|
||||
//@TODO move OC.Notification to a service
|
||||
OC.Notification.showTemporary('Please fill in a value!');
|
||||
NotificationService.showNotification('Please fill in a value!', 3000);
|
||||
}
|
||||
if (!$scope.new_custom_field.label || !$scope.new_custom_field.value) {
|
||||
return;
|
||||
|
@ -166,7 +165,7 @@ angular.module('passmanApp')
|
|||
|
||||
}
|
||||
};
|
||||
//@TODO Set tags, read them from tag service
|
||||
|
||||
|
||||
$scope.parseQR = function(QRCode){
|
||||
var re = /otpauth:\/\/(totp|hotp)\/(.*)\?(secret|issuer)=(.*)&(issuer|secret)=(.*)/, parsedQR,qrInfo;
|
||||
|
@ -191,13 +190,13 @@ angular.module('passmanApp')
|
|||
$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
|
||||
NotificationService.showNotification('Credential created!', 5000)
|
||||
})
|
||||
} else {
|
||||
CredentialService.updateCredential($scope.storedCredential).then(function (result) {
|
||||
SettingsService.setSetting('edit_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
//@TODO Show notification
|
||||
NotificationService.showNotification('Credential updated!', 5000)
|
||||
})
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,10 +8,42 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MenuCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', '$rootScope', function ($scope, VaultService, SettingsService, $location, $rootScope) {
|
||||
$scope.logout = function () {
|
||||
SettingsService.setSetting('defaultVaultPass', false);
|
||||
$rootScope.$broadcast('logout');
|
||||
$location.path('/');
|
||||
}
|
||||
}]);
|
||||
.controller('MenuCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', '$rootScope', 'TagService',
|
||||
function ($scope, VaultService, SettingsService, $location, $rootScope, TagService) {
|
||||
$scope.logout = function () {
|
||||
SettingsService.setSetting('defaultVaultPass', false);
|
||||
$rootScope.$broadcast('logout');
|
||||
$location.path('/');
|
||||
};
|
||||
|
||||
$scope.selectedTags = [];
|
||||
$scope.getTags = function ($query) {
|
||||
console.log(TagService.searchTag($query));
|
||||
return TagService.searchTag($query);
|
||||
};
|
||||
|
||||
$scope.$watch('selectedTags', function () {
|
||||
$rootScope.$broadcast('selected_tags_updated', $scope.selectedTags)
|
||||
}, true);
|
||||
|
||||
$scope.tagClicked = function (tag) {
|
||||
$scope.selectedTags.push(tag)
|
||||
};
|
||||
|
||||
$scope.available_tags = TagService.getTags();
|
||||
|
||||
$scope.$watch(function () {
|
||||
return TagService.getTags();
|
||||
}, function (tags) {
|
||||
$scope.available_tags = tags;
|
||||
}, true);
|
||||
|
||||
$scope.toggleDeleteTime = function () {
|
||||
if ($scope.delete_time > 0) {
|
||||
$scope.delete_time = 0;
|
||||
} else {
|
||||
$scope.delete_time = 1;
|
||||
}
|
||||
$rootScope.$broadcast('set_delete_time', $scope.delete_time);
|
||||
};
|
||||
}]);
|
||||
|
|
|
@ -41,10 +41,12 @@ angular.module('passmanApp')
|
|||
}
|
||||
return {
|
||||
restrict: 'A',
|
||||
template: '<span class="otp_generator"><span credential-field value="otp" secret="\'true\'"></span> <span ng-bind="timeleft"></span></span>',
|
||||
transclude: false,
|
||||
scope: {
|
||||
secret: '='
|
||||
},
|
||||
replace: true,
|
||||
link: function (scope, element) {
|
||||
scope.otp = null;
|
||||
scope.timeleft = null;
|
||||
|
@ -82,10 +84,6 @@ angular.module('passmanApp')
|
|||
$timeout.cancel(scope.timer);
|
||||
}
|
||||
}, true);
|
||||
//@TODO FIX THIS UGLY SHIT
|
||||
var html = '<span pw="otp">{{otp}}</span> Time left: <span ng-bind="timeleft"></span>';
|
||||
element.html($compile(html)(scope));
|
||||
|
||||
scope.$on(
|
||||
"$destroy",
|
||||
function (event) {
|
||||
|
|
31
js/app/filters/tagfilter.js
Normal file
31
js/app/filters/tagfilter.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name passmanApp.filter:selectedTags
|
||||
* @function
|
||||
* @description
|
||||
* # selectedTags
|
||||
* Filter in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.filter('tagFilter', function() {
|
||||
return function(credentials, tags) {
|
||||
var _credentials = [];
|
||||
if(tags.length > 0) {
|
||||
for (var ci = 0; ci < credentials.length; ci++) {
|
||||
var c = credentials[ci];
|
||||
for (var ct = 0; ct < c.tags_raw.length; ct++) {
|
||||
var t = c.tags_raw[ct];
|
||||
if(tags.indexOf(t.text) != -1){
|
||||
_credentials.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(tags.length == 0){
|
||||
_credentials = credentials;
|
||||
}
|
||||
return _credentials;
|
||||
};
|
||||
});
|
29
js/app/services/notificationservice.js
Normal file
29
js/app/services/notificationservice.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.NotificationService
|
||||
* @description
|
||||
* # NotificationService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('NotificationService', ['$timeout', function ($timeout) {
|
||||
var to ;
|
||||
return {
|
||||
showNotification: function (text, time, closeCallback) {
|
||||
var notification = OC.Notification.showHtml(text);
|
||||
to =$timeout(function () {
|
||||
OC.Notification.hide(notification, closeCallback)
|
||||
}, time);
|
||||
return notification;
|
||||
},
|
||||
hideNotification: function (notification) {
|
||||
$timeout.cancel(to);
|
||||
OC.Notification.hide(notification)
|
||||
},
|
||||
hideAll: function () {
|
||||
OC.Notification.hide();
|
||||
}
|
||||
}
|
||||
}]);
|
|
@ -19,8 +19,8 @@ angular.module('passmanApp')
|
|||
},
|
||||
addTags: function (tags) {
|
||||
for(var i =0; i < tags.length; i++){
|
||||
if(_tags.indexOf(tags[i]) == -1){
|
||||
_tags.push(tags[i]);
|
||||
if( $filter('filter')(_tags,{text: tags[i].text }).length == 0){
|
||||
_tags.push(tags[i])
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -23,7 +23,7 @@ angular.module('views/partials/forms/edit_credential/custom_fields.html', []).ru
|
|||
angular.module('views/partials/forms/edit_credential/files.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/partials/forms/edit_credential/files.html',
|
||||
'<div class="row file_tab"><div class="col-xs-12 col-md-6"><input type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"> <span ng-if="fileprogress.file_percent > 0"><div progress-bar="fileprogress.file_percent"></div></span></div></div><div class="row files" ng-if="storedCredential.files.length > 0"><div class="col-xs-12 table"><table><thead use-theme><tr><th class="field_label">Filename</th><th class="field_value">Upload date</th><th class="field_secret">Size</th><th class="field_actions">Actions</th></tr></thead><tr ng-repeat="file in storedCredential.files"><td><a href="#" editable-text="file.filename">{{ file.filename || "empty" }}</a></td><td>{{file.created}}</td><td>{{file.size | bytes}}</td><td class="field_actions"><i class="fa fa-trash" ng-click="deleteFile(file)"></i></td></tr></table></div></div>');
|
||||
'<div class="row file_tab"><div class="col-xs-12 col-md-6"><input type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"> <span ng-if="fileprogress.file_percent > 0"><div progress-bar="fileprogress.file_percent"></div></span></div></div><div class="row files" ng-if="storedCredential.files.length > 0"><div class="col-xs-12 table"><table><thead use-theme><tr><th class="field_label">Filename</th><th class="field_value">Upload date</th><th class="field_secret">Size</th><th class="field_actions">Actions</th></tr></thead><tr ng-repeat="file in storedCredential.files"><td><a href="#" editable-text="file.filename">{{ file.filename || "empty" }}</a></td><td>{{file.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td><td>{{file.size | bytes}}</td><td class="field_actions"><i class="fa fa-trash" ng-click="deleteFile(file)"></i></td></tr></table></div></div>');
|
||||
}]);
|
||||
|
||||
angular.module('views/partials/forms/edit_credential/otp.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><div off-click="closeSelected()"><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="tags"><span class="tag" ng-repeat="tag in credential.tags_raw">{{tag.text}}</span></span></td></tr></table><div id="app-sidebar" class="detailsView scroll-container app_sidebar" ng-show="selectedCredential"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><table><tr ng-show="selectedCredential.label"><td>Label</td><td>{{selectedCredential.label}}</td></tr><tr ng-show="selectedCredential.username"><td>Account</td><td><span credential-field value="selectedCredential.username"></span></td></tr><tr ng-show="selectedCredential.password"><td>Password</td><td><span credential-field value="selectedCredential.password" secret="\'true\'"></span></td></tr><tr ng-show="selectedCredential.email"><td>E-mail</td><td><span credential-field value="selectedCredential.email"></span></td></tr><tr ng-show="selectedCredential.url"><td>URL</td><td><span credential-field value="selectedCredential.url"></span></td></tr><tr ng-show="selectedCredential.files.length > 0"><td>Files</td><td><div ng-repeat="file in selectedCredential.files" class="link" ng-click="downloadFile(file)">{{file.filename}} ({{file.size | bytes}})</div></td></tr><tr ng-repeat="field in selectedCredential.custom_fields"><td>{{field.label}}</td><td><span credential-field value="field.value" secret="field.secret"></span></td></tr><tr ng-show="selectedCredential.changed"><td>Changed</td><td>{{selectedCredential.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr><tr ng-show="selectedCredential.created"><td>Created</td><td>{{selectedCredential.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr></table><div ng-show="selectedCredential"><span class="button" ng-click="editCredential(selectedCredential)"><span class="fa fa-edit"></span> Edit</span> <span class="button"><span class="fa fa-trash"></span> Delete</span> <span class="button"><span class="fa fa-share"></span> Share</span></div></div></div>');
|
||||
'<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><input type="text" ng-model="itemFilter.label"> <span class="title" ng-if="delete_time">Showing deleted since: <span ng-if="delete_time == 1">All time</span> <span ng-if="delete_time > 1">{{delete_time | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span></span></div></div><div off-click="closeSelected()"><table class="credential-table" ng-init="menuOpen = false;"><tr ng-repeat="credential in credentials | filter:itemFilter | tagFilter:selectedtags" ng-if="credential.hidden == 0 && showCredentialRow(credential)" ng-click="selectCredential(credential)" ng-class="{\'selected\': selectedCredential.credential_id == credential.credential_id}"><td><span class="label">{{credential.label}}</span> <span class="tags"><span class="tag" ng-repeat="tag in credential.tags_raw">{{tag.text}}</span></span></td></tr></table><div id="app-sidebar" class="detailsView scroll-container app_sidebar" ng-show="selectedCredential"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><table><tr ng-show="selectedCredential.label"><td>Label</td><td>{{selectedCredential.label}}</td></tr><tr ng-show="selectedCredential.username"><td>Account</td><td><span credential-field value="selectedCredential.username"></span></td></tr><tr ng-show="selectedCredential.password"><td>Password</td><td><span credential-field value="selectedCredential.password" secret="\'true\'"></span></td></tr><tr ng-show="selectedCredential.otp.secret"><td>OTP</td><td><span otp-generator secret="selectedCredential.otp.secret"></span></td></tr><tr ng-show="selectedCredential.email"><td>E-mail</td><td><span credential-field value="selectedCredential.email"></span></td></tr><tr ng-show="selectedCredential.url"><td>URL</td><td><span credential-field value="selectedCredential.url"></span></td></tr><tr ng-show="selectedCredential.files.length > 0"><td>Files</td><td><div ng-repeat="file in selectedCredential.files" class="link" ng-click="downloadFile(file)">{{file.filename}} ({{file.size | bytes}})</div></td></tr><tr ng-repeat="field in selectedCredential.custom_fields"><td>{{field.label}}</td><td><span credential-field value="field.value" secret="field.secret"></span></td></tr><tr ng-show="selectedCredential.changed"><td>Changed</td><td>{{selectedCredential.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr><tr ng-show="selectedCredential.created"><td>Created</td><td>{{selectedCredential.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td></tr></table><div class="tags"><span class="tag" ng-repeat="tag in selectedCredential.tags">{{tag.text}}</span></div><div ng-show="selectedCredential"><span class="button" ng-click="editCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-edit"></span> Edit</span> <span class="button" ng-click="deleteCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-trash"></span> Delete</span> <span class="button" ng-if="selectedCredential.delete_time > 0" ng-click="recoverCredential(selectedCredential)"><span class="fa fa-recycle"></span> Recover</span> <span class="button" ng-if="selectedCredential.delete_time == 0"><span class="fa fa-share"></span> Share</span></div></div></div>');
|
||||
}]);
|
||||
|
||||
angular.module('views/vaults.html', []).run(['$templateCache', function($templateCache) {
|
||||
|
|
|
@ -59,11 +59,20 @@ class CredentialMapper extends Mapper {
|
|||
}
|
||||
|
||||
public function update($raw_credential){
|
||||
if(!$raw_credential['guid']){
|
||||
$raw_credential['guid'] = $this->utils->GUID();
|
||||
}
|
||||
if(!$raw_credential['created']){
|
||||
$raw_credential['created'] = $this->utils->getTime();
|
||||
}
|
||||
$credential = new Credential();
|
||||
$credential->setId($raw_credential['credential_id']);
|
||||
$credential->setGuid($raw_credential['guid']);
|
||||
$credential->setVaultId($raw_credential['vault_id']);
|
||||
$credential->setUserId($raw_credential['user_id']);
|
||||
$credential->setLabel($raw_credential['label']);
|
||||
$credential->setDescription($raw_credential['description']);
|
||||
$credential->setCreated($raw_credential['created']);
|
||||
$credential->setChanged($this->utils->getTime());
|
||||
$credential->setTags($raw_credential['tags']);
|
||||
$credential->setEmail($raw_credential['email']);
|
||||
|
@ -77,6 +86,7 @@ class CredentialMapper extends Mapper {
|
|||
$credential->setCustomFields($raw_credential['custom_fields']);
|
||||
$credential->setOtp($raw_credential['otp']);
|
||||
$credential->setHidden($raw_credential['hidden']);
|
||||
$credential->setDeleteTime($raw_credential['delete_time']);
|
||||
return parent::update($credential);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
left: 10px;
|
||||
top: -19px;
|
||||
}
|
||||
.title{
|
||||
width: calc( 100% - 185px);
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.credential-table {
|
||||
width: 100%;
|
||||
|
@ -208,11 +213,21 @@
|
|||
padding: 2px;
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
height: 20px;
|
||||
height: 25px;
|
||||
vertical-align: middle;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
.tags {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
.tag {
|
||||
background-color: rgba(240, 240, 240, .9);
|
||||
padding: 4px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,40 @@
|
|||
.settings-container{
|
||||
div{
|
||||
.settings-container {
|
||||
div {
|
||||
padding-left: 15px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.nav-trashbin {
|
||||
position: fixed !important;
|
||||
bottom: 44px;
|
||||
width: inherit !important;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #eee;
|
||||
a {
|
||||
padding: 0 20px;
|
||||
.fa {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#app-navigation {
|
||||
li{
|
||||
a.taginput{
|
||||
opacity: 1;
|
||||
}
|
||||
a{
|
||||
overflow: visible;
|
||||
tags-input{
|
||||
opacity: 1.0;
|
||||
li{
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> ul ul {
|
||||
display: inherit !important;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
.pw-gen{
|
||||
overflow:hidden;
|
||||
input{
|
||||
width: calc(100% - 76px) !important;
|
||||
width: calc(100% - 80px) !important;
|
||||
float: left;
|
||||
background: #fff;
|
||||
color: #555;
|
||||
|
|
|
@ -32,6 +32,7 @@ script('passman', 'app/controllers/edit_credential');
|
|||
script('passman', 'app/filters/range');
|
||||
script('passman', 'app/filters/propsfilter');
|
||||
script('passman', 'app/filters/byte');
|
||||
script('passman', 'app/filters/tagfilter');
|
||||
script('passman', 'app/services/cacheservice');
|
||||
script('passman', 'app/services/vaultservice');
|
||||
script('passman', 'app/services/credentialservice');
|
||||
|
@ -39,6 +40,7 @@ script('passman', 'app/services/settingsservice');
|
|||
script('passman', 'app/services/fileservice');
|
||||
script('passman', 'app/services/encryptservice');
|
||||
script('passman', 'app/services/tagservice');
|
||||
script('passman', 'app/services/notificationservice');
|
||||
script('passman', 'app/directives/passwordgen');
|
||||
script('passman', 'app/directives/fileselect');
|
||||
script('passman', 'app/directives/progressbar');
|
||||
|
@ -65,26 +67,38 @@ style('passman', 'app');
|
|||
<div id="app" ng-app="passmanApp" ng-controller="MainCtrl">
|
||||
<div id="app-navigation" ng-if="selectedVault" ng-controller="MenuCtrl">
|
||||
<ul>
|
||||
<li><a href="#">First level entry</a></li>
|
||||
<li>
|
||||
<a href="#">First level container</a>
|
||||
<ul>
|
||||
<li><a href="#">Second level entry</a></li>
|
||||
<li><a href="#">Second level entry</a></li>
|
||||
</ul>
|
||||
<li class="taginput">
|
||||
<a class="taginput">
|
||||
<tags-input ng-model="selectedTags" replace-spaces-with-dashes="false">
|
||||
<auto-complete source="getTags($query)" min-length="0"></auto-complete>
|
||||
</tags-input>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="tag in available_tags" ng-if="selectedTags.indexOf(tag) == -1">
|
||||
<a ng-click="tagClicked(tag)">{{tag.text}}</a>
|
||||
</li>
|
||||
<li data-id="trashbin" class="nav-trashbin">
|
||||
<a ng-click="toggleDeleteTime()"
|
||||
ng-class="{'active': delete_time > 0}">
|
||||
<i href="#" class="fa fa-trash"></i>
|
||||
Deleted credentials
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="app-settings" ng-init="settingsShown = false;">
|
||||
<div id="app-settings-header">
|
||||
<button class="settings-button"
|
||||
ng-click="settingsShown = !settingsShown"
|
||||
>Settings</button>
|
||||
>Settings
|
||||
</button>
|
||||
</div>
|
||||
<div id="app-settings-content" ng-show="settingsShown">
|
||||
<!-- Your settings in here -->
|
||||
<div class="settings-container">
|
||||
<div><span class="link">Settings</span></div>
|
||||
<div><span class="link" ng-click="logout()">Logout</span></div>
|
||||
<div><span class="link" ng-click="logout()">Logout</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<a href="#" editable-text="file.filename">{{ file.filename || "empty" }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{file.created}}
|
||||
{{file.created * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}}
|
||||
</td>
|
||||
<td>{{file.size | bytes}}</td>
|
||||
<td class="field_actions">
|
||||
|
|
|
@ -29,12 +29,19 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="text" ng-model="itemFilter.label">
|
||||
<span class="title" ng-if="delete_time">
|
||||
Showing deleted since:
|
||||
<span ng-if="delete_time == 1">All time</span>
|
||||
<span ng-if="delete_time > 1">{{delete_time | date:'dd-MM-yyyy @ HH:mm:ss'}}</span>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div off-click="closeSelected()">
|
||||
<table class="credential-table" ng-init="menuOpen = false;">
|
||||
<tr ng-repeat="credential in credentials"
|
||||
ng-if="credential.hidden == 0 && credential.delete_time == 0"
|
||||
<tr ng-repeat="credential in credentials | filter:itemFilter | tagFilter:selectedtags"
|
||||
ng-if="credential.hidden == 0 && showCredentialRow(credential)"
|
||||
ng-click="selectCredential(credential)"
|
||||
ng-class="{'selected': selectedCredential.credential_id == credential.credential_id}">
|
||||
<td>
|
||||
|
@ -97,6 +104,15 @@
|
|||
secret="'true'"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-show="selectedCredential.otp.secret">
|
||||
<td>
|
||||
OTP
|
||||
</td>
|
||||
<td>
|
||||
<span otp-generator
|
||||
secret="selectedCredential.otp.secret"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-show="selectedCredential.email">
|
||||
<td>
|
||||
E-mail
|
||||
|
@ -151,15 +167,24 @@
|
|||
{{selectedCredential.created * 1000 | date:'dd-MM-yyyy @ HH:mm:ss'}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="tags">
|
||||
<span class="tag" ng-repeat="tag in selectedCredential.tags">{{tag.text}}</span>
|
||||
</div>
|
||||
|
||||
<div ng-show="selectedCredential">
|
||||
<span class="button" ng-click="editCredential(selectedCredential)">
|
||||
<span class="button" ng-click="editCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0" >
|
||||
<span class="fa fa-edit"></span> Edit
|
||||
</span>
|
||||
<span class="button">
|
||||
<span class="fa fa-trash"></span> Delete
|
||||
<span class="button" ng-click="deleteCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0" >
|
||||
<span class="fa fa-trash" ></span> Delete
|
||||
</span>
|
||||
<span class="button">
|
||||
<span class="button" ng-if="selectedCredential.delete_time > 0" ng-click="recoverCredential(selectedCredential)">
|
||||
<span class="fa fa-recycle" ></span> Recover
|
||||
</span>
|
||||
<span class="button" ng-if="selectedCredential.delete_time == 0" >
|
||||
<span class="fa fa-share"></span> Share
|
||||
</span>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue