Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/passman.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolFi <wolfi@wolfi.es>2021-05-17 01:43:40 +0300
committerWolFi <wolfi@wolfi.es>2021-05-17 01:43:53 +0300
commit7ec0ddd78895ef679d2a878c785f8f2a113415f9 (patch)
treefd3fe589ae6ad1f5a527fdb12b906d88a5ae32c7
parente8410d1f5f171c802768e00a83cb25ec2a61fb75 (diff)
parentb996e2dc69ae3e0759b134f29d27d56c5acd82c1 (diff)
Merge branch 'migrations-2' of https://github.com/binsky08/passman into binsky08-migrations-2
-rw-r--r--README.md1
-rw-r--r--appinfo/info.xml5
-rw-r--r--controller/admincontroller.php71
-rw-r--r--controller/credentialcontroller.php62
-rw-r--r--controller/iconcontroller.php56
-rw-r--r--controller/internalcontroller.php45
-rw-r--r--controller/sharecontroller.php79
-rw-r--r--css/admin.css4
-rw-r--r--css/admin.css.map2
-rw-r--r--js/app/controllers/public_shared_credential.js4
-rw-r--r--js/app/directives/credentialtemplate.js8
-rw-r--r--js/app/directives/iconpicker.js7
-rw-r--r--js/app/filters/escapeHTML.js38
-rw-r--r--js/app/services/credentialservice.js7
-rw-r--r--js/app/services/shareservice.js2
-rw-r--r--js/settings-admin.js47
-rw-r--r--js/templates.js76
-rw-r--r--lib/Activity.php21
-rw-r--r--lib/AppInfo/Application.php55
-rw-r--r--lib/BackgroundJob/ExpireCredentials.php16
-rw-r--r--lib/Db/CredentialMapper.php151
-rw-r--r--lib/Db/CredentialRevisionMapper.php70
-rw-r--r--lib/Db/DeleteVaultRequestMapper.php50
-rw-r--r--lib/Db/FileMapper.php97
-rw-r--r--lib/Db/ShareRequestMapper.php273
-rw-r--r--lib/Db/SharingACLMapper.php143
-rw-r--r--lib/Db/VaultMapper.php114
-rw-r--r--lib/Notifier.php23
-rw-r--r--lib/Search/Provider.php8
-rw-r--r--lib/Service/CredentialRevisionService.php48
-rw-r--r--lib/Service/CredentialService.php95
-rw-r--r--lib/Service/CronService.php57
-rw-r--r--lib/Service/DeleteVaultRequestService.php25
-rw-r--r--lib/Service/EncryptService.php28
-rw-r--r--lib/Service/FileService.php69
-rw-r--r--lib/Service/NotificationService.php40
-rw-r--r--lib/Service/ShareService.php170
-rw-r--r--lib/Service/VaultService.php43
-rw-r--r--lib/Settings/Admin.php115
-rw-r--r--lib/Utility/Utils.php19
-rw-r--r--migration/serversideencryption.php33
-rw-r--r--sass/admin.scss8
-rw-r--r--templates/admin.php (renamed from templates/part.admin.php)50
-rw-r--r--templates/admin.settings.php4
-rw-r--r--templates/main.php1
-rw-r--r--templates/views/partials/icon-picker.html2
-rw-r--r--templates/views/show_vault.html6
47 files changed, 1409 insertions, 939 deletions
diff --git a/README.md b/README.md
index 6b63100e..cdee4a05 100644
--- a/README.md
+++ b/README.md
@@ -143,6 +143,7 @@ If you want a production-ready container, use the [Nextcloud Docker](https://hub
## Contributors
Add yours when creating a [pull request](https://help.github.com/articles/creating-a-pull-request/)!
* Newhinton
+ * [binsky](https://github.com/binsky08)
## FAQ
**Are you adding something to check if malicious code is executing on the browser?**
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 46d719ee..d0e0bd6e 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -37,7 +37,7 @@ For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
<screenshot small-thumbnail="https://img.passman.cc/thumbs/share_credential.png">https://img.passman.cc/share_credential.png</screenshot>
<screenshot small-thumbnail="https://img.passman.cc/thumbs/password_audit.png">https://img.passman.cc/password_audit.png</screenshot>
<dependencies>
- <php min-version="7.2"/>
+ <php min-version="7.4"/>
<database>sqlite</database>
<database>pgsql</database>
<database min-version="5.5">mysql</database>
@@ -55,4 +55,7 @@ For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
</post-migration>
</repair-steps>
+ <settings>
+ <admin>OCA\Passman\Settings\Admin</admin>
+ </settings>
</info>
diff --git a/controller/admincontroller.php b/controller/admincontroller.php
index d7e47909..5d072f1b 100644
--- a/controller/admincontroller.php
+++ b/controller/admincontroller.php
@@ -24,6 +24,7 @@ use OCP\IRequest;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\ApiController;
use OCA\Passman\Service\CredentialService;
+use OCP\IUserManager;
class AdminController extends ApiController {
@@ -34,6 +35,7 @@ class AdminController extends ApiController {
private $revisionService;
private $deleteVaultRequestService;
private $config;
+ private $userManager;
public function __construct($AppName,
IRequest $request,
@@ -43,7 +45,8 @@ class AdminController extends ApiController {
FileService $fileService,
CredentialRevisionService $revisionService,
DeleteVaultRequestService $deleteVaultRequestService,
- IConfig $config
+ IConfig $config,
+ IUserManager $userManager
) {
parent::__construct(
$AppName,
@@ -59,13 +62,13 @@ class AdminController extends ApiController {
$this->deleteVaultRequestService = $deleteVaultRequestService;
$this->config = $config;
+ $this->userManager = $userManager;
}
public function searchUser($term) {
- $um = \OC::$server->getUserManager();
$results = array();
- $searchResult = $um->search($term);
+ $searchResult = $this->userManager->search($term);
foreach ($searchResult as $user) {
array_push($results, array(
"value" => $user->getUID(),
@@ -76,37 +79,43 @@ class AdminController extends ApiController {
}
public function moveCredentials($source_account, $destination_account) {
- $vaults = $this->vaultService->getByUser($source_account);
- foreach ($vaults as $vault) {
- $credentials = $this->credentialService->getCredentialsByVaultId($vault->getId(), $source_account);
- foreach ($credentials as $credential) {
- $revisions = $this->revisionService->getRevisions($credential->getId());
- foreach ($revisions as $revision) {
- $r = new CredentialRevision();
- $r->setId($revision['revision_id']);
- $r->setGuid($revision['guid']);
- $r->setCredentialId($credential->getId());
- $r->setUserId($destination_account);
- $r->setCreated($revision['created']);
- $r->setCredentialData(base64_encode(json_encode($revision['credential_data'])));
- $r->setEditedBy($revision['edited_by']);
- $this->revisionService->updateRevision($r);
+ $succeed = false;
+ if ($source_account != $destination_account){
+ $vaults = $this->vaultService->getByUser($source_account);
+ foreach ($vaults as $vault) {
+ $credentials = $this->credentialService->getCredentialsByVaultId($vault->getId(), $source_account);
+ foreach ($credentials as $credential) {
+ $revisions = $this->revisionService->getRevisions($credential->getId());
+ foreach ($revisions as $revision) {
+ $r = new CredentialRevision();
+ $r->setId($revision['revision_id']);
+ $r->setGuid($revision['guid']);
+ $r->setCredentialId($credential->getId());
+ $r->setUserId($destination_account);
+ $r->setCreated($revision['created']);
+ $r->setCredentialData(base64_encode(json_encode($revision['credential_data'])));
+ $r->setEditedBy($revision['edited_by']);
+ $this->revisionService->updateRevision($r);
+ }
+
+ $c = $credential->jsonSerialize();
+ $c['user_id'] = $destination_account;
+ $c['icon'] = json_encode($c['icon']);
+ $this->credentialService->updateCredential($c, true);
}
+ $vault->setUserId($destination_account);
+ $this->vaultService->updateVault($vault);
+ }
- $c = $credential->jsonSerialize();
- $c['user_id'] = $destination_account;
- $this->credentialService->updateCredential($c, true);
+ $files = $this->fileService->getFilesFromUser($source_account);
+ foreach ($files as $file) {
+ $file->setUserId($destination_account);
+ $this->fileService->updateFile($file);
}
- $vault->setUserId($destination_account);
- $this->vaultService->updateVault($vault);
+ $succeed = true;
}
- $files = $this->fileService->getFilesFromUser($source_account);
- foreach ($files as $file) {
- $file->setUserId($destination_account);
- $this->fileService->updateFile($file);
- }
- return new JSONResponse(array('success' => true));
+ return new JSONResponse(array('success' => $succeed));
}
public function listRequests(){
@@ -114,7 +123,7 @@ class AdminController extends ApiController {
$results = array();
foreach($requests as $request){
$r = $request->jsonSerialize();
- $r['displayName'] = Utils::getNameByUid($request->getRequestedBy());
+ $r['displayName'] = Utils::getNameByUid($request->getRequestedBy(), $this->userManager);
array_push($results, $r);
}
return new JSONResponse($results);
@@ -188,4 +197,4 @@ class AdminController extends ApiController {
}
return new JSONResponse(array('result' => $result));
}
-} \ No newline at end of file
+}
diff --git a/controller/credentialcontroller.php b/controller/credentialcontroller.php
index abc76a21..4984df6c 100644
--- a/controller/credentialcontroller.php
+++ b/controller/credentialcontroller.php
@@ -11,22 +11,20 @@
namespace OCA\Passman\Controller;
+use OCA\Passman\Activity;
use OCA\Passman\Db\Credential;
use OCA\Passman\Db\SharingACL;
-use OCA\Passman\Service\EncryptService;
+use OCA\Passman\Service\ActivityService;
+use OCA\Passman\Service\CredentialRevisionService;
+use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\SettingsService;
+use OCA\Passman\Service\ShareService;
use OCA\Passman\Utility\NotFoundJSONResponse;
-use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
-use OCP\IRequest;
use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\ApiController;
-use OCA\Passman\Service\CredentialService;
-use OCA\Passman\Activity;
-use OCA\Passman\Service\ActivityService;
-use OCA\Passman\Service\CredentialRevisionService;
-use OCA\Passman\Service\ShareService;
+use OCP\IRequest;
class CredentialController extends ApiController {
@@ -38,13 +36,13 @@ class CredentialController extends ApiController {
private $settings;
public function __construct($AppName,
- IRequest $request,
- $userId,
- CredentialService $credentialService,
- ActivityService $activityService,
- CredentialRevisionService $credentialRevisionService,
- ShareService $sharingService,
- SettingsService $settings
+ IRequest $request,
+ $userId,
+ CredentialService $credentialService,
+ ActivityService $activityService,
+ CredentialRevisionService $credentialRevisionService,
+ ShareService $sharingService,
+ SettingsService $settings
) {
parent::__construct(
@@ -67,10 +65,10 @@ class CredentialController extends ApiController {
* @NoCSRFRequired
*/
public function createCredential($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, $compromised) {
+ $credential_id, $custom_fields, $delete_time,
+ $description, $email, $expire_time, $favicon, $files, $guid,
+ $hidden, $icon, $label, $otp, $password, $renew_interval,
+ $tags, $url, $username, $vault_id, $compromised) {
$credential = array(
'credential_id' => $credential_id,
'guid' => $guid,
@@ -85,7 +83,7 @@ class CredentialController extends ApiController {
'username' => $username,
'password' => $password,
'url' => $url,
- 'icon' => $favicon,
+ 'icon' => json_encode($icon),
'favicon' => $favicon,
'renew_interval' => $renew_interval,
'expire_time' => $expire_time,
@@ -106,7 +104,7 @@ class CredentialController extends ApiController {
$link, $this->userId, Activity::TYPE_ITEM_ACTION);
}
- return new JSONResponse($this->credentialService->getCredentialByGUID($credential->getGuid()));
+ return new JSONResponse($this->credentialService->getCredentialByGUID($credential->getGuid()));
}
/**
@@ -123,10 +121,10 @@ class CredentialController extends ApiController {
* @NoCSRFRequired
*/
public function updateCredential($changed, $created,
- $credential_id, $custom_fields, $delete_time, $credential_guid,
- $description, $email, $expire_time, $icon, $files, $guid,
- $hidden, $label, $otp, $password, $renew_interval,
- $tags, $url, $username, $vault_id, $revision_created, $shared_key, $acl, $unshare_action, $set_share_key, $skip_revision, $compromised) {
+ $credential_id, $custom_fields, $delete_time, $credential_guid,
+ $description, $email, $expire_time, $icon, $files, $guid,
+ $hidden, $label, $otp, $password, $renew_interval,
+ $tags, $url, $username, $vault_id, $revision_created, $shared_key, $acl, $unshare_action, $set_share_key, $skip_revision, $compromised) {
$storedCredential = $this->credentialService->getCredentialByGUID($credential_guid);
@@ -261,7 +259,7 @@ class CredentialController extends ApiController {
$credential = $this->credentialService->updateCredential($credential);
- return new JSONResponse($this->credentialService->getCredentialByGUID($credential->getGuid()));
+ return new JSONResponse($this->credentialService->getCredentialByGUID($credential->getGuid()));
}
/**
@@ -287,6 +285,7 @@ class CredentialController extends ApiController {
/**
* Delete leftovers from a credential
* @param Credential $credential
+ * @throws \Exception
*/
private function deleteCredentialParts(Credential $credential) {
$this->activityService->add(
@@ -295,16 +294,17 @@ class CredentialController extends ApiController {
'', $this->userId, Activity::TYPE_ITEM_ACTION);
$this->sharingService->unshareCredential($credential->getGuid());
foreach ($this->credentialRevisionService->getRevisions($credential->getId()) as $revision) {
- $id = $revision['revision_id'];
- if(isset($id)){
- $this->credentialRevisionService->deleteRevision($id, $this->userId);
- }
+ $id = $revision['revision_id'];
+ if (isset($id)) {
+ $this->credentialRevisionService->deleteRevision($id, $this->userId);
+ }
}
}
/**
* @NoAdminRequired
* @NoCSRFRequired
+ * @throws \Exception
*/
public function getRevision($credential_guid) {
try {
diff --git a/controller/iconcontroller.php b/controller/iconcontroller.php
index 97a24813..6be9a8a0 100644
--- a/controller/iconcontroller.php
+++ b/controller/iconcontroller.php
@@ -13,17 +13,14 @@ namespace OCA\Passman\Controller;
use Doctrine\DBAL\Exception\DriverException;
use OC\App\AppManager;
+use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\IconService;
use OCA\Passman\Utility\Utils;
+use OCP\AppFramework\ApiController;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\DataDownloadResponse;
-use OCP\AppFramework\Http\Response;
-use OCP\IConfig;
-use OCP\IRequest;
use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\ApiController;
-use OCA\Passman\Service\CredentialService;
-use \OCP\App;
+use OCP\IRequest;
use OCP\IURLGenerator;
class IconController extends ApiController {
@@ -33,11 +30,11 @@ class IconController extends ApiController {
private $urlGenerator;
public function __construct($AppName,
- IRequest $request,
- $UserId,
- CredentialService $credentialService,
- AppManager $am,
- IURLGenerator $urlGenerator
+ IRequest $request,
+ $UserId,
+ CredentialService $credentialService,
+ AppManager $am,
+ IURLGenerator $urlGenerator
) {
parent::__construct(
$AppName,
@@ -57,7 +54,7 @@ class IconController extends ApiController {
* @NoCSRFRequired
*/
public function getSingleIcon($base64Url) {
- $url = base64_decode(str_replace('_','/', $base64Url));
+ $url = base64_decode(str_replace('_', '/', $base64Url));
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
$url = "http://" . $url;
}
@@ -66,8 +63,8 @@ class IconController extends ApiController {
$icon = new IconService($url);
if ($icon->icoExists) {
- $icon_json['type']= $icon->icoType;
- $icon_json['content']= base64_encode($icon->icoData);
+ $icon_json['type'] = $icon->icoType;
+ $icon_json['content'] = base64_encode($icon->icoData);
return new JSONResponse($icon_json);
}
@@ -79,13 +76,13 @@ class IconController extends ApiController {
* @NoCSRFRequired
*/
public function getIcon($base64Url, $credentialId) {
- $url = base64_decode(str_replace('_','/', $base64Url));
+ $url = base64_decode(str_replace('_', '/', $base64Url));
- if($credentialId) {
+ if ($credentialId && $credentialId != "null") {
try {
$credential = $this->credentialService->getCredentialById($credentialId, $this->userId);
$credential = $credential->jsonSerialize();
- } catch (DoesNotExistException $e){
+ } catch (DoesNotExistException $e) {
// Credential is not found, continue
$credential = false;
}
@@ -95,15 +92,20 @@ class IconController extends ApiController {
$url = "http://" . $url;
}
- $icon = new IconService($url);
-
$data = base64_decode("iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABHVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADF3oJhAAAAXnRSTlMAAQIDBAUGBwgJCwwOEBITFBUWFxgaHB4hJCUnKissMDI0ODs9PkFCQ0RNUVJWV1lbXF1hY2Zna2xtcXh7f4KDhYmUm52lq62vsLW3ucHFyszO0dPV197i7/H3+fv9358zuQAAAWdJREFUWMPtldlWwjAURdPWogyKOKM4z0NRQRRHnAdE0QoI1eb/P8OnmzYlSZs+unIes+/ZbdOuFCFuBmc2Dk+qpe18EsVIptTGJJ3jrGR99B4H8jQlUTfOMSM3ZtT+SAsz8z0ZrZ//wZy4S1H6C1iQtfD+tCsS4EJYP9kV9rGTCRE0fMOfxZypITO7++5b/NCE/S3fx7PsLc9/eeuWqK/3vA9ngAJ3BPwmBIIdMnYbvNNLgo4Egg4MvelBpD0D6/F3YYJcJd0PEw7AWa6gCCNnLLoPtMoVPMJIikVNoE2uAN6BzcZ1MPA2wRA+AUIHwHkn1BAM7LH5OvBhjiAFA6tsXgCe4wjSMLDC5nPAx5Xg3wrGylfk1GlcM/MC/KFW6fvRVbBkLuj+omwf401KUJcXtCiBIy+gT4UYfawrgRIogRIogRLwBG4MAfVnsuX7XX8fWfKCU0qgvcr2mwaiDZYtsw/tMtnCP4F4Y01BhTeiAAAAAElFTkSuQmCC");
$type = 'png';
-
- if ($icon->icoExists) {
- $data = $icon->icoData;
- $type = $icon->icoType;
+
+ try {
+ $icon = new IconService($url);
+ if ($icon->icoExists) {
+ $data = $icon->icoData;
+ $type = $icon->icoType;
+ }
+ } catch (\InvalidArgumentException $e) {
+ //no need to do stuff in catch
+ //if IconService fails the predefined $data and $type are used
}
+
if (isset($credential) && $credential['user_id'] == $this->userId) {
$iconData = [
'type' => ($type) ? $type : 'x-icon',
@@ -111,7 +113,7 @@ class IconController extends ApiController {
];
$credential['icon'] = json_encode($iconData);
try {
- if($credential) {
+ if ($credential) {
$this->credentialService->updateCredential($credential);
}
} catch (DriverException $exception) {
@@ -152,12 +154,12 @@ class IconController extends ApiController {
$pack = explode('/', $path[1])[2];
$mime = mime_content_type($iconPath);
//print_r($path);
- if($mime !== 'directory') {
+ if ($mime !== 'directory') {
$icon = [];
$icon['mimetype'] = mime_content_type($iconPath);
$icon['url'] = $this->urlGenerator->linkTo('passman', $path[1]);
$icon['pack'] = $pack;
- if(!isset($icons[$pack])){
+ if (!isset($icons[$pack])) {
$icons[$pack] = [];
}
$icons[$pack][] = $icon;
@@ -165,4 +167,4 @@ class IconController extends ApiController {
}
return new JSONResponse($icons);
}
-} \ No newline at end of file
+}
diff --git a/controller/internalcontroller.php b/controller/internalcontroller.php
index 6b92c698..79c9cf26 100644
--- a/controller/internalcontroller.php
+++ b/controller/internalcontroller.php
@@ -11,23 +11,28 @@
namespace OCA\Passman\Controller;
+use OCA\Passman\Service\CredentialService;
+use OCP\App\IAppManager;
+use OCP\AppFramework\ApiController;
+use OCP\AppFramework\Http\JSONResponse;
use OCP\IConfig;
use OCP\IRequest;
-use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\ApiController;
-use OCA\Passman\Service\CredentialService;
-use \OCP\App;
+use OCP\Notification\IManager;
class InternalController extends ApiController {
private $userId;
private $credentialService;
private $config;
+ private $manager;
+ private $appManager;
public function __construct($AppName,
- IRequest $request,
- $UserId,
- CredentialService $credentialService,
- IConfig $config
+ IRequest $request,
+ $UserId,
+ CredentialService $credentialService,
+ IConfig $config,
+ IManager $IManager,
+ IAppManager $appManager
) {
parent::__construct(
$AppName,
@@ -38,6 +43,8 @@ class InternalController extends ApiController {
$this->userId = $UserId;
$this->credentialService = $credentialService;
$this->config = $config;
+ $this->manager = $IManager;
+ $this->appManager = $appManager;
}
/**
@@ -45,16 +52,15 @@ class InternalController extends ApiController {
*/
public function remind($credential_id) {
$credential = $this->credentialService->getCredentialById($credential_id, $this->userId);
- if($credential) {
+ if ($credential) {
$credential->setExpireTime(time() + (24 * 60 * 60));
$this->credentialService->upd($credential);
- $manager = \OC::$server->getNotificationManager();
- $notification = $manager->createNotification();
+ $notification = $this->manager->createNotification();
$notification->setApp('passman')
->setObject('credential', $credential_id)
->setUser($this->userId);
- $manager->markProcessed($notification);
+ $this->manager->markProcessed($notification);
}
}
@@ -62,18 +68,16 @@ class InternalController extends ApiController {
* @NoAdminRequired
*/
public function read($credential_id) {
-
$credential = $this->credentialService->getCredentialById($credential_id, $this->userId);
- if($credential) {
+ if ($credential) {
$credential->setExpireTime(0);
$this->credentialService->upd($credential);
- $manager = \OC::$server->getNotificationManager();
- $notification = $manager->createNotification();
+ $notification = $this->manager->createNotification();
$notification->setApp('passman')
->setObject('credential', $credential_id)
->setUser($this->userId);
- $manager->markProcessed($notification);
+ $this->manager->markProcessed($notification);
}
}
@@ -82,15 +86,14 @@ class InternalController extends ApiController {
* @NoCSRFRequired
*/
public function getAppVersion() {
- $AppInstance = new App();
- return new JSONResponse(array('version' => $AppInstance->getAppInfo("passman")["version"]));
+ return new JSONResponse(array('version' => $this->appManager->getAppInfo('passman')["version"]));
}
/**
* @NoAdminRequired
*/
public function generatePerson() {
- $context = [ 'http' => [ 'method' => 'GET' ], 'ssl' => [ 'verify_peer' => false, 'allow_self_signed'=> true ] ];
+ $context = ['http' => ['method' => 'GET'], 'ssl' => ['verify_peer' => false, 'allow_self_signed' => true]];
$context = stream_context_create($context);
$random_person = json_decode(file_get_contents('http://api.namefake.com/', false, $context));
return new JSONResponse($random_person);
@@ -122,4 +125,4 @@ class InternalController extends ApiController {
$this->config->setAppValue('passman', $key, $value);
}
-} \ No newline at end of file
+}
diff --git a/controller/sharecontroller.php b/controller/sharecontroller.php
index d27c185f..4b1f534e 100644
--- a/controller/sharecontroller.php
+++ b/controller/sharecontroller.php
@@ -11,26 +11,27 @@
namespace OCA\Passman\Controller;
+use OCA\Passman\Activity;
+use OCA\Passman\Db\File;
use OCA\Passman\Db\SharingACL;
-use OCA\Passman\Db\Vault;
+use OCA\Passman\Service\ActivityService;
use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\FileService;
use OCA\Passman\Service\NotificationService;
use OCA\Passman\Service\SettingsService;
use OCA\Passman\Service\ShareService;
+use OCA\Passman\Service\VaultService;
use OCA\Passman\Utility\NotFoundJSONResponse;
use OCA\Passman\Utility\Utils;
-use OCP\AppFramework\Http\NotFoundResponse;
-use OCP\IRequest;
-use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\ApiController;
-
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\NotFoundResponse;
use OCP\IGroupManager;
+use OCP\IRequest;
use OCP\IUserManager;
-
-use OCA\Passman\Service\VaultService;
-use OCA\Passman\Service\ActivityService;
-use OCA\Passman\Activity;
+use OCP\Notification\IManager;
class ShareController extends ApiController {
@@ -44,22 +45,24 @@ class ShareController extends ApiController {
private $notificationService;
private $fileService;
private $settings;
+ private $manager;
private $limit = 50;
private $offset = 0;
public function __construct($AppName,
- IRequest $request,
- $UserId,
- IGroupManager $groupManager,
- IUserManager $userManager,
- ActivityService $activityService,
- VaultService $vaultService,
- ShareService $shareService,
- CredentialService $credentialService,
- NotificationService $notificationService,
- FileService $fileService,
- SettingsService $config
+ IRequest $request,
+ $UserId,
+ IGroupManager $groupManager,
+ IUserManager $userManager,
+ ActivityService $activityService,
+ VaultService $vaultService,
+ ShareService $shareService,
+ CredentialService $credentialService,
+ NotificationService $notificationService,
+ FileService $fileService,
+ SettingsService $config,
+ IManager $IManager
) {
parent::__construct(
$AppName,
@@ -78,6 +81,7 @@ class ShareController extends ApiController {
$this->notificationService = $notificationService;
$this->fileService = $fileService;
$this->settings = $config;
+ $this->manager = $IManager;
}
@@ -222,7 +226,10 @@ class ShareController extends ApiController {
return new JSONResponse(array('result' => true));
}
-
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
public function unshareCredentialFromUser($item_guid, $user_id) {
$acl = null;
$sr = null;
@@ -232,19 +239,19 @@ class ShareController extends ApiController {
}
try {
- $sr = array_pop($this->shareService->getPendingShareRequestsForCredential($item_guid, $user_id));
+ $shareRequests = $this->shareService->getPendingShareRequestsForCredential($item_guid, $user_id);
+ $sr = array_pop($shareRequests);
} catch (\Exception $e) {
// no need to catch this
}
if ($sr) {
$this->shareService->cleanItemRequestsForUser($sr);
- $manager = \OC::$server->getNotificationManager();
- $notification = $manager->createNotification();
+ $notification = $this->manager->createNotification();
$notification->setApp('passman')
->setObject('passman_share_request', $sr->getId())
->setUser($user_id);
- $manager->markProcessed($notification);
+ $this->manager->markProcessed($notification);
}
if ($acl) {
$this->shareService->deleteShareACL($acl);
@@ -292,12 +299,11 @@ class ShareController extends ApiController {
return new NotFoundResponse();
}
- $manager = \OC::$server->getNotificationManager();
- $notification = $manager->createNotification();
+ $notification = $this->manager->createNotification();
$notification->setApp('passman')
->setObject('passman_share_request', $sr->getId())
->setUser($this->userId->getUID());
- $manager->markProcessed($notification);
+ $this->manager->markProcessed($notification);
$notification = array(
'from_user' => ucfirst($this->userId->getDisplayName()),
@@ -383,12 +389,11 @@ class ShareController extends ApiController {
);
- $manager = \OC::$server->getNotificationManager();
- $notification = $manager->createNotification();
+ $notification = $this->manager->createNotification();
$notification->setApp('passman')
->setObject('passman_share_request', $share_request_id)
->setUser($this->userId->getUID());
- $manager->markProcessed($notification);
+ $this->manager->markProcessed($notification);
$this->shareService->cleanItemRequestsForUser($sr);
return new JSONResponse(array('result' => true));
@@ -432,7 +437,8 @@ class ShareController extends ApiController {
/**
* @param $item_guid
- * @return JSONResponse
+ * @return JSONResponse|NotFoundResponse
+ * @throws \OCP\DB\Exception
* @NoAdminRequired
* @NoCSRFRequired
*/
@@ -458,10 +464,11 @@ class ShareController extends ApiController {
/**
* @param $item_guid
* @param $file_guid
+ * @return array|File|NotFoundJSONResponse
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
* @NoAdminRequired
- * @PublicPage
- * @return mixed
- * @return NotFoundJSONResponse
+ * @NoCSRFRequired
*/
public function getFile($item_guid, $file_guid) {
try {
@@ -508,4 +515,4 @@ class ShareController extends ApiController {
}
}
-} \ No newline at end of file
+}
diff --git a/css/admin.css b/css/admin.css
index f362cfb5..06ea9af9 100644
--- a/css/admin.css
+++ b/css/admin.css
@@ -2,6 +2,10 @@
padding: 5px; }
#passwordSharingSettings #mover input[type="text"] {
width: 350px; }
+#passwordSharingSettings #mover .account_mover_selector {
+ width: 350px; }
+ #passwordSharingSettings #mover .account_mover_selector .select2-choice {
+ height: 34px; }
#passwordSharingSettings #requests-table {
width: 100%; }
diff --git a/css/admin.css.map b/css/admin.css.map
index 410bb786..df50b77a 100644
--- a/css/admin.css.map
+++ b/css/admin.css.map
@@ -1,6 +1,6 @@
{
"version": 3,
-"mappings": "AAGM,wCAAE;EACA,OAAO,EAAE,GAAG;AAGhB,kDAAkB;EAChB,KAAK,EAAE,KAAK;AAGhB,wCAAe;EACb,KAAK,EAAE,IAAI",
+"mappings": "AAGM,wCAAE;EACA,OAAO,EAAE,GAAG;AAGhB,kDAAkB;EAChB,KAAK,EAAE,KAAK;AAEd,uDAAwB;EACtB,KAAK,EAAE,KAAK;EACZ,uEAAgB;IACd,MAAM,EAAE,IAAI;AAIlB,wCAAe;EACb,KAAK,EAAE,IAAI",
"sources": ["../sass/admin.scss"],
"names": [],
"file": "admin.css"
diff --git a/js/app/controllers/public_shared_credential.js b/js/app/controllers/public_shared_credential.js
index 7f055002..b03aadc5 100644
--- a/js/app/controllers/public_shared_credential.js
+++ b/js/app/controllers/public_shared_credential.js
@@ -31,7 +31,7 @@
* Controller of the passmanApp
*/
angular.module('passmanApp')
- .controller('PublicSharedCredential', ['$scope', 'ShareService', '$window', 'EncryptService', 'NotificationService', '$translate', function ($scope, ShareService, $window, EncryptService, NotificationService, $translate) {
+ .controller('PublicSharedCredential', ['$scope', 'ShareService', '$window', 'EncryptService', 'NotificationService', '$translate', 'escapeHTMLFilter', function ($scope, ShareService, $window, EncryptService, NotificationService, $translate, escapeHTMLFilter) {
var _key;
$scope.loading = false;
$scope.loadSharedCredential = function () {
@@ -58,7 +58,7 @@
return;
}
var file_data = EncryptService.decryptString(result.file_data, _key);
- download(file_data, escapeHTML(file.filename), file.mimetype);
+ download(file_data, escapeHTMLFilter(file.filename), file.mimetype);
});
};
}]);
diff --git a/js/app/directives/credentialtemplate.js b/js/app/directives/credentialtemplate.js
index 8c4f7a76..9b3e2d3e 100644
--- a/js/app/directives/credentialtemplate.js
+++ b/js/app/directives/credentialtemplate.js
@@ -29,8 +29,8 @@
* # passwordGen
*/
angular.module('passmanApp')
- .directive('credentialTemplate', ['EncryptService', '$translate', 'FileService', 'ShareService', 'NotificationService', 'CredentialService',
- function (EncryptService, $translate, FileService, ShareService, NotificationService, CredentialService) {
+ .directive('credentialTemplate', ['EncryptService', '$translate', 'FileService', 'ShareService', 'NotificationService', 'CredentialService', 'escapeHTMLFilter',
+ function (EncryptService, $translate, FileService, ShareService, NotificationService, CredentialService, escapeHTMLFilter) {
return {
templateUrl: 'views/partials/credential_template.html',
replace: true,
@@ -49,7 +49,7 @@
}
var file_data = EncryptService.decryptString(result.file_data, key);
- download(file_data, escapeHTML(file.filename), file.mimetype);
+ download(file_data, escapeHTMLFilter(file.filename), file.mimetype);
};
@@ -65,4 +65,4 @@
}
};
}]);
-}()); \ No newline at end of file
+}());
diff --git a/js/app/directives/iconpicker.js b/js/app/directives/iconpicker.js
index 2cc60594..210dfacb 100644
--- a/js/app/directives/iconpicker.js
+++ b/js/app/directives/iconpicker.js
@@ -129,7 +129,9 @@
};
scope.useIcon = function() {
-
+ if(!scope.credential.icon){
+ scope.credential.icon = {};
+ }
if(scope.customIcon){
var data = scope.customIcon.data;
scope.credential.icon.type = data.substring(data.lastIndexOf(":")+1,data.lastIndexOf(";"));
@@ -138,9 +140,6 @@
$http.get(scope.selectedIcon.url).then(function(result) {
var base64Data = window.btoa(result.data);
var mimeType = 'svg+xml';
- if(!scope.credential.icon){
- scope.credential.icon = {};
- }
scope.credential.icon.type = mimeType;
scope.credential.icon.content = base64Data;
});
diff --git a/js/app/filters/escapeHTML.js b/js/app/filters/escapeHTML.js
new file mode 100644
index 00000000..88916dd7
--- /dev/null
+++ b/js/app/filters/escapeHTML.js
@@ -0,0 +1,38 @@
+/**
+ * Nextcloud - passman
+ *
+ * @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
+ * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+(function () {
+ 'use strict';
+
+ /**
+ * @ngdoc filter
+ * @name passmanApp.filter:escapeHTML
+ * @function
+ * @description Sanitizes a HTML string by replacing all potential dangerous characters with HTML entities
+ */
+ angular.module('passmanApp')
+ .filter('escapeHTML', function () {
+ return function (s) {
+ return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('>').join('&gt;').split('"').join('&quot;').split('\'').join('&#039;');
+ };
+ });
+}());
diff --git a/js/app/services/credentialservice.js b/js/app/services/credentialservice.js
index 53fa67c0..e8bc2a41 100644
--- a/js/app/services/credentialservice.js
+++ b/js/app/services/credentialservice.js
@@ -41,10 +41,7 @@
'changed': null,
'tags': [],
'email': null,
- 'icon':{
- 'type': false,
- 'content': ''
- },
+ 'icon': null,
'username': null,
'password': null,
'url': null,
@@ -364,4 +361,4 @@
}
};
}]);
-}()); \ No newline at end of file
+}());
diff --git a/js/app/services/shareservice.js b/js/app/services/shareservice.js
index 195555cf..ff4a149c 100644
--- a/js/app/services/shareservice.js
+++ b/js/app/services/shareservice.js
@@ -313,4 +313,4 @@
}
};
}]);
-}()); \ No newline at end of file
+}());
diff --git a/js/settings-admin.js b/js/settings-admin.js
index b607e161..c9d4f32b 100644
--- a/js/settings-admin.js
+++ b/js/settings-admin.js
@@ -137,27 +137,54 @@ $(document).ready(function () {
'source_account': '',
'destination_account': ''
};
- $(".username-autocomplete").autocomplete({
- source: OC.generateUrl('apps/passman/admin/search'),
- minLength: 1,
- select: function (event, ui) {
- accountMover[$(this).attr('id')] = ui.item.value;
- }
+ $('.account_mover_selector').select2({
+ ajax: {
+ url: OC.generateUrl('apps/passman/admin/search'),
+ dataType: 'json',
+ delay: 50,
+ data: function (param) {
+ return {
+ term: param
+ };
+ },
+ results: function (data) {
+ var res = [];
+ for (var i = 0; i < data.length; i++) {
+ res.push({
+ id: i,
+ text: data[i].value
+ });
+ }
+ return {
+ results: res
+ };
+ },
+ cache: true
+ },
+ placeholder: 'Search for a user',
+ minimumInputLength: 1
});
$('#move_credentials').click(function () {
var self = this;
+ accountMover.source_account = $('#s2id_source_account a .select2-chosen').html();
+ accountMover.destination_account = $('#s2id_destination_account a .select2-chosen').html();
$('#moveStatus').hide();
$(self).attr('disabled', 'disabled');
$(self).html('<i class="fa fa-spinner fa-spin"></i> ' + OC.L10N.translate('passman', 'Moving') + '...');
if (accountMover.source_account && accountMover.destination_account) {
$.post(OC.generateUrl('apps/passman/admin/move'), accountMover, function (data) {
+ $(self).removeAttr('disabled');
+ $(self).html('Move');
if (data.success) {
- $(self).removeAttr('disabled');
- $(self).html('Move');
- $('#moveStatus').fadeIn();
+ $('#moveStatusSucceeded').fadeIn();
+ setTimeout(function () {
+ $('#moveStatusSucceeded').fadeOut();
+ }, 3500);
+ } else {
+ $('#moveStatusFailed').fadeIn();
setTimeout(function () {
- $('#moveStatus').fadeOut();
+ $('#moveStatusFailed').fadeOut();
}, 3500);
}
});
diff --git a/js/templates.js b/js/templates.js
index 07eed1ea..9096e60c 100644
--- a/js/templates.js
+++ b/js/templates.js
@@ -1,96 +1,96 @@
angular.module('templates-main', ['views/credential_revisions.html', 'views/edit_credential.html', 'views/partials/credential_template.html', 'views/partials/forms/edit_credential/basics.html', 'views/partials/forms/edit_credential/custom_fields.html', 'views/partials/forms/edit_credential/files.html', 'views/partials/forms/edit_credential/otp.html', 'views/partials/forms/edit_credential/password.html', 'views/partials/forms/settings/export.html', 'views/partials/forms/settings/general_settings.html', 'views/partials/forms/settings/generic_csv_import.html', 'views/partials/forms/settings/import.html', 'views/partials/forms/settings/password_settings.html', 'views/partials/forms/settings/sharing.html', 'views/partials/forms/settings/tool.html', 'views/partials/forms/share_credential/basics.html', 'views/partials/forms/share_credential/link_sharing.html', 'views/partials/icon-picker.html', 'views/partials/password-meter.html', 'views/settings.html', 'views/share_credential.html', 'views/show_vault.html', 'views/vault_req_deletion.html', 'views/vaults.html']);
-angular.module('views/credential_revisions.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/credential_revisions.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/credential_revisions.html',
'<div class="main_list" off-click-filter="\'.download-js-link, .sidebar-shown, #app-sidebar\'"><div id="passman-controls"><div class="actions creatable"><div class="breadcrumb"><div class="crumb svg ui-droppable"><a ng-click="logout()"><i class="fa fa-home"></i></a></div><div class="crumb svg"><a ng-click="cancelRevision()">{{active_vault.name}}</a></div><div class="crumb svg last"><a ng-if="storedCredential.credential_id">{{ \'showing.revisions\' | translate}} "{{revision.credential_data.label}}"</a></div></div></div></div><table class="credential-table" ng-init="menuOpen = false;"><tr ng-repeat="revision in revisions | orderBy:\'-created\'" ng-click="selectRevision(revision)" ng-class="{\'selected\': selectedRevision.revision_id == revision.revision_id}"><td><span class="icon"><i class="fa fa-lock"></i> </span><span class="label">{{ \'revision.of\' | translate}} {{revision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} ({{revision.credential_data.label}}) <span ng-if="revision.edited_by">{{ \'revision.edited.by\' | translate}} {{revision.edited_by}}</span></span></td></tr><tr ng-show="revisions.length == 0"><td>{{ \'no.revisions\' | translate}}</td></tr></table></div><div id="app-sidebar" class="detailsView scroll-container app_sidebar" off-click="closeSelected()" ng-show="selectedRevision"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span> <b ng-show="selectedRevision">{{ \'revision.of\' | translate}} {{selectedRevision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</b><div class="credential-data"><div class="row" ng-show="selectedRevision.credential_data.label"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'label\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="selectedRevision.credential_data.label"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.username"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'account\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="selectedRevision.credential_data.username"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.password"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'password\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="selectedRevision.credential_data.password" secret="\'true\'"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.otp.secret"><div class="col-xs-4 col-md-3 col-lg-3">{{\'otp\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span otp-generator secret="selectedRevision.credential_data.otp.secret"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.email"><div class="col-xs-4 col-md-3 col-lg-3">{{\'email\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="selectedRevision.credential_data.email"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.url"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'url\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="selectedRevision.credential_data.url"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.description"><div class="col-xs-4 col-md-3 col-lg-3">{{\'notes\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="selectedRevision.credential_data.description_html"></span></div></div><div class="row" ng-show="selectedRevision.credential_data.files.length > 0"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'files\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><div ng-repeat="file in selectedRevision.credential_data.files" class="link" ng-click="downloadFile(selectedRevision.credential_data, file)">{{file.filename}} ({{file.size | bytes}})</div></div></div><div class="row" ng-repeat="field in selectedRevision.credential_data.custom_fields"><div class="col-xs-4 col-md-3 col-lg-3">{{field.label}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="field.value" secret="field.secret" ng-if="field.field_type !== \'file\' || !field.field_type"></span> <span ng-if="field.field_type === \'file\'" class="link" ng-click="downloadFile(selectedCredential, field.value)">{{field.value.filename}} ({{field.value.size | bytes}})</span></div></div><div class="row" ng-show="selectedRevision.credential_data.expire_time > 0"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'expire.time\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9">{{selectedRevision.credential_data.expire_time * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</div></div><div class="row" ng-show="selectedRevision.credential_data.changed"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'changed\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9">{{selectedRevision.credential_data.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</div></div><div class="row" ng-show="selectedRevision.credential_data.created"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'created\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9">{{selectedRevision.credential_data.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</div></div><div class="row"><div class="col-xs-12"><div class="tags"><span class="tag" ng-repeat="tag in selectedRevision.credential_data.tags">{{tag.text}}</span></div></div></div></div><div ng-show="selectedRevision"><button class="button" ng-click="restoreRevision(selectedRevision)"><span class="fa fa-edit"></span> {{ \'restore.revision\' | translate}}</button> <button class="button" ng-click="deleteRevision(selectedRevision)"><span class="fa fa-trash"></span> {{ \'delete.revision\' | translate}}</button></div></div>');
}]);
-angular.module('views/edit_credential.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/edit_credential.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/edit_credential.html',
'<div id="passman-controls"><div class="breadcrumb"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a ng-click="logout()"><i class="fa fa-home"></i></a></div><div class="crumb svg" data-dir="/Test"><a ng-click="cancel()">{{active_vault.name}}</a></div><div class="crumb svg last" data-dir="/Test"><a ng-if="storedCredential.credential_id">{{ \'edit.credential\' | translate}} "{{storedCredential.label}}"</a> <a ng-if="!storedCredential.credential_id">{{ \'create.credential\' | translate}}</a></div></div></div></div><div><ul class="tab_header"><li ng-repeat="tab in tabs track by $index" class="tab" ng-class="isActiveTab(tab)? \'active\' : \'inactive\'" ng-click="onClickTab(tab)" use-theme color="\'true\'">{{tab.title}}<div class="indicator" use-theme negative="\'true\'"></div></li></ul><div class="tab_container edit_credential" use-theme type="\'border-top-color\'"><div ng-include="currentTab.url"></div><button ng-click="saveCredential()" ng-disabled="saving"><i class="fa fa-spinner fa-spin" ng-show="saving"></i> {{ \'save\' | translate}}</button> <button ng-click="cancel()">{{ \'cancel\' | translate}}</button></div></div>');
}]);
-angular.module('views/partials/credential_template.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/credential_template.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/credential_template.html',
'<div class="credential-data"><div class="row" ng-show="credential.label && showLabel"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'label\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="credential.label"></span></div></div><div class="compromised-details" ng-show="credential.compromised"><div class="icon-error-color icon"></div><div class="text">{{ \'compromised.warning\' | translate }}</div></div><div class="row" ng-show="credential.username"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'account\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="credential.username"></span></div></div><div class="row" ng-show="credential.password"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'password\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="credential.password" secret="\'true\'"></span></div></div><div class="row" ng-show="credential.otp.secret"><div class="col-xs-4 col-md-3 col-lg-3">{{\'otp\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span otp-generator secret="credential.otp.secret"></span></div></div><div class="row" ng-show="credential.email"><div class="col-xs-4 col-md-3 col-lg-3">{{\'email\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="credential.email"></span></div></div><div class="row" ng-show="credential.url"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'url\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="credential.url" url="true"></span></div></div><div class="row" ng-show="credential.description"><div class="col-xs-4 col-md-3 col-lg-3">{{\'notes\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="credential.description_html"></span></div></div><div class="row" ng-show="credential.files.length > 0"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'files\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9"><div ng-repeat="file in credential.files"><a class="link" ng-click="downloadFile(credential, file)">{{file.filename}} ({{file.size | bytes}})</a><br></div></div></div><div class="row" ng-repeat="field in credential.custom_fields"><div class="col-xs-4 col-md-3 col-lg-3">{{field.label}}</div><div class="col-xs-8 col-md-9 col-lg-9"><span credential-field value="field.value" secret="field.secret" ng-if="field.field_type !== \'file\' || !field.field_type"></span> <span ng-if="field.field_type === \'file\'" class="link" ng-click="downloadFile(credential, field.value)">{{field.value.filename}} ({{field.value.size | bytes}})</span></div></div><div class="row" ng-show="credential.expire_time > 0"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'expire.time\' | translate }}</div><div class="col-xs-8 col-md-9 col-lg-9">{{credential.expire_time * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</div></div><div class="row" ng-show="credential.changed"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'changed\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9">{{credential.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</div></div><div class="row" ng-show="credential.created"><div class="col-xs-4 col-md-3 col-lg-3">{{ \'created\' | translate}}</div><div class="col-xs-8 col-md-9 col-lg-9">{{credential.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</div></div><div class="row"><div class="col-xs-12"><div class="tags"><span class="tag" ng-repeat="tag in credential.tags track by $index">{{tag.text}}</span></div></div></div></div>');
}]);
-angular.module('views/partials/forms/edit_credential/basics.html', []).run(['$templateCache', function ($templateCache) {
+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\' | translate}}</label><div class="icon-label"><div class="icon-picker" icon-picker="storedCredential"></div><input type="text" class="form-control" ng-model="storedCredential.label"></div><label>{{ \'username\' | translate}}</label><div><input type="text" ng-model="storedCredential.username"></div><label>{{ \'email\' | translate}}</label><div><input type="text" ng-model="storedCredential.email"></div><label>{{ \'password\' | translate}}</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>{{ \'password.r\' | translate}}</label><input type="password" ng-model="storedCredential.password_repeat"></div><label>{{ \'url\' | translate}}</label><div><input type="text" ng-model="storedCredential.url"></div></div><div class="col-xs-12 col-md-6"><label>{{ \'notes\' | translate}}</label><div><textarea class="credential_textarea" ng-model="storedCredential.description"></textarea></div><label>{{ \'add.tag\' | translate}}</label><div class="tags_input"><tags-input ng-model="storedCredential.tags" replace-spaces-with-dashes="false"><auto-complete source="getTags($query)" min-length="0"></auto-complete></tags-input></div></div><div class="col-xs-12 col-md-6"><button class="compromised-button" ng-click="compromise()">{{ \'compromised.label\' | translate}}</button><div class="compromised-details" ng-show="storedCredential.compromised"><div class="icon-error-color icon"></div><div class="text">{{ \'compromised.warning\' | translate }}</div></div></div></div>');
+ '<div class="row"><div class="col-xs-12 col-md-6"><label>{{ \'label\' | translate}}</label><div class="icon-label"><div class="icon-picker" icon-picker="storedCredential"></div><input type="text" class="form-control" ng-model="storedCredential.label"></div><label>{{ \'username\' | translate}}</label><div><input type="text" ng-model="storedCredential.username"></div><label>{{ \'email\' | translate}}</label><div><input type="text" ng-model="storedCredential.email"></div><label>{{ \'password\' | translate}}</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>{{ \'password.r\' | translate}}</label> <input type="password" ng-model="storedCredential.password_repeat"></div><label>{{ \'url\' | translate}}</label><div><input type="text" ng-model="storedCredential.url"></div></div><div class="col-xs-12 col-md-6"><label>{{ \'notes\' | translate}}</label><div><textarea class="credential_textarea" ng-model="storedCredential.description"></textarea></div><label>{{ \'add.tag\' | translate}}</label><div class="tags_input"><tags-input ng-model="storedCredential.tags" replace-spaces-with-dashes="false"><auto-complete source="getTags($query)" min-length="0"></auto-complete></tags-input></div></div><div class="col-xs-12 col-md-6"><button class="compromised-button" ng-click="compromise()">{{ \'compromised.label\' | translate}}</button><div class="compromised-details" ng-show="storedCredential.compromised"><div class="icon-error-color icon"></div><div class="text">{{ \'compromised.warning\' | translate }}</div></div></div></div>');
}]);
-angular.module('views/partials/forms/edit_credential/custom_fields.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/edit_credential/custom_fields.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/edit_credential/custom_fields.html',
- '<div class="row"><div class="col-xs-12 col-md-4"><label>{{ \'field.label\' | translate}}</label><input type="text" ng-model="new_custom_field.label"></div><div class="col-xs-10 col-md-6 field-value"><div class="row"><div class="col-xs-12"><label>{{ \'field.value\' | translate}}</label></div></div><div class="row"><div class="col-xs-8 valueInput"><input type="text" ng-model="new_custom_field.value" ng-show="new_custom_field.field_type === \'text\'"><password-gen ng-model="new_custom_field.value" ng-show="new_custom_field.field_type ===\'password\'" settings="{generateOnCreate: false }"></password-gen><span ng-show="new_custom_field.field_type ===\'file\'"><input id="custom_field_file" class="inputfile" type="file" file-select success="addFileToCustomField" error="fileLoadError" progress="fileSelectProgress"><label for="custom_field_file"><i class="fa fa-upload" aria-hidden="true"></i> {{ new_custom_field.value.filename || \'select.file\' | translate}}</label></span></div><div class="col-xs-4 selectType"><select class="form-control" ng-model="new_custom_field.field_type"><option value="text">{{ \'text\' | translate}}</option><option value="password">{{ \'password\' | translate}}</option><option value="file">{{ \'file\' | translate}}</option></select></div></div><div class="row"><div class="col-xs-12"><ng-password-meter ng-if="new_custom_field.field_type ===\'password\'" password="new_custom_field.value"></ng-password-meter></div></div></div><div class="col-xs-2 col-md-2"><label class="invisible">{{\'add\' | translate}}</label><button ng-click="addCustomField()">+</button></div></div><div class="row custom_fields" ng-if="storedCredential.custom_fields.length > 0"><div class="col-xs-12 table"><table><thead><tr use-theme><td class="dragger"></td><th class="field_label">{{ \'label\' | translate}}</th><th class="field_value">{{ \'value\' | translate}}</th><th class="field_secret">{{ \'type\' | translate}}</th><th class="field_actions">{{ \'actions\' | translate}}</th></tr></thead><tbody ui-sortable ng-model="storedCredential.custom_fields"><tr ng-repeat="field in storedCredential.custom_fields"><td class="dragger"><i class="fa fa-arrows-v"></i></td><td><a href="#" editable-text="field.label">{{ field.label || "empty" }}</a></td><td><span ng-if="field.field_type === \'text\'"><a href="#" editable-text="field.value">{{ field.value || \'empty\' | translate }}</a></span> <span ng-if="field.field_type === \'password\'"><a href="#" editable-password="field.value"><span ng-repeat="n in [] | range:field.value.length">*</span></a></span> <span ng-if="field.field_type === \'file\'">{{field.value.filename}} ({{field.value.size | bytes}})</span></td><td>{{ field.field_type }}</td><td class="field_actions"><i class="fa fa-trash" ng-click="deleteCustomField(field)"></i></td></tr></tbody></table></div></div>');
+ '<div class="row"><div class="col-xs-12 col-md-4"><label>{{ \'field.label\' | translate}}</label> <input type="text" ng-model="new_custom_field.label"></div><div class="col-xs-10 col-md-6 field-value"><div class="row"><div class="col-xs-12"><label>{{ \'field.value\' | translate}}</label></div></div><div class="row"><div class="col-xs-8 valueInput"><input type="text" ng-model="new_custom_field.value" ng-show="new_custom_field.field_type === \'text\'"><password-gen ng-model="new_custom_field.value" ng-show="new_custom_field.field_type ===\'password\'" settings="{generateOnCreate: false }"></password-gen><span ng-show="new_custom_field.field_type ===\'file\'"><input id="custom_field_file" class="inputfile" type="file" file-select success="addFileToCustomField" error="fileLoadError" progress="fileSelectProgress"> <label for="custom_field_file"><i class="fa fa-upload" aria-hidden="true"></i> {{ new_custom_field.value.filename || \'select.file\' | translate}}</label></span></div><div class="col-xs-4 selectType"><select class="form-control" ng-model="new_custom_field.field_type"><option value="text">{{ \'text\' | translate}}</option><option value="password">{{ \'password\' | translate}}</option><option value="file">{{ \'file\' | translate}}</option></select></div></div><div class="row"><div class="col-xs-12"><ng-password-meter ng-if="new_custom_field.field_type ===\'password\'" password="new_custom_field.value"></ng-password-meter></div></div></div><div class="col-xs-2 col-md-2"><label class="invisible">{{\'add\' | translate}}</label> <button ng-click="addCustomField()">+</button></div></div><div class="row custom_fields" ng-if="storedCredential.custom_fields.length > 0"><div class="col-xs-12 table"><table><thead><tr use-theme><td class="dragger"></td><th class="field_label">{{ \'label\' | translate}}</th><th class="field_value">{{ \'value\' | translate}}</th><th class="field_secret">{{ \'type\' | translate}}</th><th class="field_actions">{{ \'actions\' | translate}}</th></tr></thead><tbody ui-sortable ng-model="storedCredential.custom_fields"><tr ng-repeat="field in storedCredential.custom_fields"><td class="dragger"><i class="fa fa-arrows-v"></i></td><td><a href="#" editable-text="field.label">{{ field.label || "empty" }}</a></td><td><span ng-if="field.field_type === \'text\'"><a href="#" editable-text="field.value">{{ field.value || \'empty\' | translate }}</a></span> <span ng-if="field.field_type === \'password\'"><a href="#" editable-password="field.value"><span ng-repeat="n in [] | range:field.value.length">*</span></a></span> <span ng-if="field.field_type === \'file\'">{{field.value.filename}} ({{field.value.size | bytes}})</span></td><td>{{ field.field_type }}</td><td class="field_actions"><i class="fa fa-trash" ng-click="deleteCustomField(field)"></i></td></tr></tbody></table></div></div>');
}]);
-angular.module('views/partials/forms/edit_credential/files.html', []).run(['$templateCache', function ($templateCache) {
+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 class="inputfile" id="file" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><label for="file"><i class="fa fa-upload" aria-hidden="true"></i> {{\'select.file\' | translate}}</label><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">{{ \'file.name\' | translate }}</th><th class="field_value">{{ \'upload.date\' | translate}}</th><th class="field_secret">{{ \'size\' | translate}}</th><th class="field_actions">{{ \'actions\' | translate}}</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>');
+ '<div class="row file_tab"><div class="col-xs-12 col-md-6"><input class="inputfile" id="file" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"> <label for="file"><i class="fa fa-upload" aria-hidden="true"></i> {{\'select.file\' | translate}}</label> <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">{{ \'file.name\' | translate }}</th><th class="field_value">{{ \'upload.date\' | translate}}</th><th class="field_secret">{{ \'size\' | translate}}</th><th class="field_actions">{{ \'actions\' | translate}}</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) {
+angular.module('views/partials/forms/edit_credential/otp.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/edit_credential/otp.html',
- '<div class="row"><div class="col-xs-12"><div class="col-xs-4 nopadding"><span class="otpText">{{ \'upload.qr\' | translate}}</span><select ng-model="otpType"><option value="qrcode">Upload QR code</option><option value="secret">Enter secret</option></select></div><div class="col-xs-6 nopadding"><input type="file" qrread on-read="parseQR(qrdata)" class="input_secret" on-read="parseQR(qrdata)" ng-show="otpType === \'qrcode\'"> <input type="text" ng-model="storedCredential.otp.secret" ng-show="otpType === \'secret\'"></div></div></div><div class="row"><div class="col-xs-12" ng-if="storedCredential.otp"><b>{{ \'current.qr\' | translate}}</b></div></div><div class="row"><div class="col-xs-5 col-sm-4 col-md-2" ng-if="storedCredential.otp.qr_uri"><img ng-src="{{storedCredential.otp.qr_uri.image}}"></div><div class="col-sm-4 col-sm-5 col-md-5"><table ng-show="storedCredential.otp"><tr ng-show="storedCredential.otp.type"><td>{{ \'type\' | translate}}:</td><td>{{storedCredential.otp.type}}</td></tr><tr ng-show="storedCredential.otp.label"><td>{{ \'label\' | translate}}:</td><td>{{storedCredential.otp.label}}</td></tr><tr ng-show="storedCredential.otp.issuer"><td>{{ \'issuer\' | translate}}:</td><td>{{storedCredential.otp.issuer}}</td></tr><tr ng-show="storedCredential.otp.secret"><td>{{ \'secret\' | translate}}:</td><td>{{storedCredential.otp.secret}}</td></tr><tr ng-show="storedCredential.otp.secret"><td>{{ \'otp\' | translate}}:</td><td><span otp-generator secret="storedCredential.otp.secret"></span></td></tr></table></div></div>');
+ '<div class="row"><div class="col-xs-12"><div class="col-xs-4 nopadding"><span class="otpText">{{ \'upload.qr\' | translate}}</span> <select ng-model="otpType"><option value="qrcode">Upload QR code</option><option value="secret">Enter secret</option></select></div><div class="col-xs-6 nopadding"><input type="file" qrread on-read="parseQR(qrdata)" class="input_secret" on-read="parseQR(qrdata)" ng-show="otpType === \'qrcode\'"> <input type="text" ng-model="storedCredential.otp.secret" ng-show="otpType === \'secret\'"></div></div></div><div class="row"><div class="col-xs-12" ng-if="storedCredential.otp"><b>{{ \'current.qr\' | translate}}</b></div></div><div class="row"><div class="col-xs-5 col-sm-4 col-md-2" ng-if="storedCredential.otp.qr_uri"><img ng-src="{{storedCredential.otp.qr_uri.image}}"></div><div class="col-sm-4 col-sm-5 col-md-5"><table ng-show="storedCredential.otp"><tr ng-show="storedCredential.otp.type"><td>{{ \'type\' | translate}}:</td><td>{{storedCredential.otp.type}}</td></tr><tr ng-show="storedCredential.otp.label"><td>{{ \'label\' | translate}}:</td><td>{{storedCredential.otp.label}}</td></tr><tr ng-show="storedCredential.otp.issuer"><td>{{ \'issuer\' | translate}}:</td><td>{{storedCredential.otp.issuer}}</td></tr><tr ng-show="storedCredential.otp.secret"><td>{{ \'secret\' | translate}}:</td><td>{{storedCredential.otp.secret}}</td></tr><tr ng-show="storedCredential.otp.secret"><td>{{ \'otp\' | translate}}:</td><td><span otp-generator secret="storedCredential.otp.secret"></span></td></tr></table></div></div>');
}]);
-angular.module('views/partials/forms/edit_credential/password.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/edit_credential/password.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/edit_credential/password.html',
- '<div class="row"><div class="col-xs-12 col-md-5 col-lg-5"><label>{{ \'password\' | translate}}</label><div><password-gen ng-model="storedCredential.password" settings="pwSettings" callback="pwGenerated"></password-gen><ng-password-meter password="storedCredential.password"></ng-password-meter></div><label>{{ \'password.r\' | translate}}</label><div><input type="password" ng-model="storedCredential.password_repeat"></div><label>{{ \'expire.date\' | translate}}</label><div><span datetime-picker ng-model="storedCredential.expire_time" class="link" future-only ng-show="storedCredential.expire_time == 0" close-on-select="false">{{\'no.expire.date\' | translate}}</span> <span datetime-picker ng-model="storedCredential.expire_time" class="link" future-only ng-show="storedCredential.expire_time != 0" close-on-select="false">{{ storedCredential.expire_time | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span></div><label>{{ \'renew.interval\' | translate}}</label><div><input type="number" ng-model="renewIntervalValue" min="0" ng-change="updateInterval(renewIntervalValue, renewIntervalModifier)"><select ng-model="renewIntervalModifier" ng-change="updateInterval(renewIntervalValue, renewIntervalModifier)"><option value="0">{{ \'disabled\' | translate}}</option><option value="86400">{{ \'days\' | translate }}</option><option value="604800">{{ \'weeks\' | translate}}</option><option value="2592000">{{ \'months\' | translate}}</option><option value="31622400">{{ \'years\' | translate}}</option></select></div></div><div class="col-xs-12 col-md-7 col-lg-7"><b>{{ \'generation.settings\' | translate}}</b><div class="row"><div class="password_settings"><div class="col-xs-12 col-sm-5 col-lg-4"><label><span class="label">{{ \'password.generation.length\' | translate}}</span><br><input type="number" ng-model="pwSettings.length" min="1"></label><label><span class="label">{{\'password.generation.min_digits\' | translate}}</span><br><input type="number" ng-model="pwSettings.minimumDigitCount" min="0"></label></div><div class="col-xs-12 col-sm-6 col-lg-6"><label><input type="checkbox" ng-model="pwSettings.useUppercase"> <span class="label sm">{{ \'password.generation.uppercase\' | translate}}</span></label><label><input ng-model="pwSettings.useLowercase" type="checkbox" id="lower"> <span class="label sm">{{ \'password.generation.lowercase\' | translate}}</span></label><label><input ng-model="pwSettings.useDigits" type="checkbox" id="digits"> <span class="label sm">{{ \'password.generation.digits\' | translate}}</span></label><label><input type="checkbox" id="special" ng-model="pwSettings.useSpecialChars"> <span class="label sm">{{ \'password.generation.special\' | translate}}</span></label><label><input type="checkbox" id="ambig" ng-model="pwSettings.avoidAmbiguousCharacters"> <span class="label sm">{{ \'password.generation.ambiguous\' | translate}}</span></label><label><input type="checkbox" ng-model="pwSettings.requireEveryCharType" id="reqevery"> <span class="label sm">{{ \'password.generation.require_same\' | translate}}</span></label></div></div></div></div></div>');
+ '<div class="row"><div class="col-xs-12 col-md-5 col-lg-5"><label>{{ \'password\' | translate}}</label><div><password-gen ng-model="storedCredential.password" settings="pwSettings" callback="pwGenerated"></password-gen><ng-password-meter password="storedCredential.password"></ng-password-meter></div><label>{{ \'password.r\' | translate}}</label><div><input type="password" ng-model="storedCredential.password_repeat"></div><label>{{ \'expire.date\' | translate}}</label><div><span datetime-picker ng-model="storedCredential.expire_time" class="link" future-only ng-show="storedCredential.expire_time == 0" close-on-select="false">{{\'no.expire.date\' | translate}}</span> <span datetime-picker ng-model="storedCredential.expire_time" class="link" future-only ng-show="storedCredential.expire_time != 0" close-on-select="false">{{ storedCredential.expire_time | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span></div><label>{{ \'renew.interval\' | translate}}</label><div><input type="number" ng-model="renewIntervalValue" min="0" ng-change="updateInterval(renewIntervalValue, renewIntervalModifier)"> <select ng-model="renewIntervalModifier" ng-change="updateInterval(renewIntervalValue, renewIntervalModifier)"><option value="0">{{ \'disabled\' | translate}}</option><option value="86400">{{ \'days\' | translate }}</option><option value="604800">{{ \'weeks\' | translate}}</option><option value="2592000">{{ \'months\' | translate}}</option><option value="31622400">{{ \'years\' | translate}}</option></select></div></div><div class="col-xs-12 col-md-7 col-lg-7"><b>{{ \'generation.settings\' | translate}}</b><div class="row"><div class="password_settings"><div class="col-xs-12 col-sm-5 col-lg-4"><label><span class="label">{{ \'password.generation.length\' | translate}}</span><br><input type="number" ng-model="pwSettings.length" min="1"></label> <label><span class="label">{{\'password.generation.min_digits\' | translate}}</span><br><input type="number" ng-model="pwSettings.minimumDigitCount" min="0"></label></div><div class="col-xs-12 col-sm-6 col-lg-6"><label><input type="checkbox" ng-model="pwSettings.useUppercase"> <span class="label sm">{{ \'password.generation.uppercase\' | translate}}</span></label> <label><input ng-model="pwSettings.useLowercase" type="checkbox" id="lower"> <span class="label sm">{{ \'password.generation.lowercase\' | translate}}</span></label> <label><input ng-model="pwSettings.useDigits" type="checkbox" id="digits"> <span class="label sm">{{ \'password.generation.digits\' | translate}}</span></label> <label><input type="checkbox" id="special" ng-model="pwSettings.useSpecialChars"> <span class="label sm">{{ \'password.generation.special\' | translate}}</span></label> <label><input type="checkbox" id="ambig" ng-model="pwSettings.avoidAmbiguousCharacters"> <span class="label sm">{{ \'password.generation.ambiguous\' | translate}}</span></label> <label><input type="checkbox" ng-model="pwSettings.requireEveryCharType" id="reqevery"> <span class="label sm">{{ \'password.generation.require_same\' | translate}}</span></label></div></div></div></div></div>');
}]);
-angular.module('views/partials/forms/settings/export.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/export.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/export.html',
- '<div ng-controller="ExportCtrl"><div class="row"><div class="col-xs-6"><label>{{ \'export.type\' | translate}}<select ng-init="raw" ng-model="raw" ng-change="setExporter(raw)"><option ng-repeat="exporter in available_exporters" value="{{exporter}}">{{exporter.name}}</option></select></label><div><b>{{selectedExporter.description}}</b></div><div ng-show="selectedExporter" class="nopadding"><label>{{ \'export.confirm.text\' | translate }}</label><input type="password" ng-model="confirm_key"><br><div class="alert alert-warning" ng-show="error">{{error}}</div></div><div class="clearfix"><button class="button" ng-click="startExport()" ng-if="selectedExporter">{{ \'export\' | translate}}</button></div></div><div class="col-xs-6"><div ng-if="log" class="import_log"><textarea id="import_log" auto-scroll="log">{{log.join(\'\\n\')}}</textarea></div></div></div></div>');
+ '<div ng-controller="ExportCtrl"><div class="row"><div class="col-xs-6"><label>{{ \'export.type\' | translate}} <select ng-init="raw" ng-model="raw" ng-change="setExporter(raw)"><option ng-repeat="exporter in available_exporters" value="{{exporter}}">{{exporter.name}}</option></select></label><div><b>{{selectedExporter.description}}</b></div><div ng-show="selectedExporter" class="nopadding"><label>{{ \'export.confirm.text\' | translate }}</label> <input type="password" ng-model="confirm_key"><br><div class="alert alert-warning" ng-show="error">{{error}}</div></div><div class="clearfix"><button class="button" ng-click="startExport()" ng-if="selectedExporter">{{ \'export\' | translate}}</button></div></div><div class="col-xs-6"><div ng-if="log" class="import_log"><textarea id="import_log" auto-scroll="log">{{log.join(\'\\n\')}}</textarea></div></div></div></div>');
}]);
-angular.module('views/partials/forms/settings/general_settings.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/general_settings.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/general_settings.html',
- '<div class="row"><div class="col-xs-12 col-md-6"><h3>{{ \'rename.vault\' | translate}}</h3><label>{{ \'rename.vault.name\' | translate}}</label><input type="text" ng-model="$parent.new_vault_name"> <button ng-click="saveVaultSettings()">{{ \'change\' | translate}}</button><h3>{{ \'change.vault.key\' | translate}}</h3><label>{{ \'old.vault.password\' | translate}}</label><input type="password" ng-model="oldVaultPass"><label>{{ \'new.vault.password\' | translate}}</label><input type="password" ng-model="newVaultPass"><ng-password-meter password="newVaultPass" score="vault_key_score"></ng-password-meter><label>{{ \'new.vault.pw.r\' | translate}}</label><input type="password" ng-model="newVaultPass2"><div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error"><ul><li>{{error}}</li><li ng-show="vault_key_score.score < minimal_value_key_strength">{{\'min.vault.key.strength\' | translate:required_score}}</li></ul></div><button ng-click="changeVaultPassword(oldVaultPass,newVaultPass,newVaultPass2)" ng-disabled="vault_key_score.score < minimal_value_key_strength">{{ \'change\' | translate}}</button><div ng-show="change_pw.total > 0">{{\'warning.leave\' | translate}}<br>{{ \'processing\' | translate}} {{cur_state.process}}<div progress-bar="cur_state.calculated" index="cur_state.current" total="cur_state.total"></div>{{ \'total.progress\' | translate}}<div progress-bar="change_pw.percent" index="change_pw.done" total="change_pw.total"></div></div><h3>{{\'delete.vault\' | translate}}</h3><b>{{ \'vault.remove.notice\' | translate }}</b><label>{{\'vault.password\' | translate}}</label><input type="password" ng-model="$parent.delete_vault_password"> <input type="checkbox" ng-model="$parent.confirm_vault_delete"> {{\'delete.vault.checkbox\' | translate}}<br><button class="btn btn-danger" ng-click="delete_vault()">{{\'delete.vault.confirm\' | translate}}</button><div ng-show="remove_pw">{{\'deleting.pw\' | translate:translationData}}<div progress-bar="remove_pw.percent" index="remove_pw.done" total="remove_pw.total"></div></div></div><div class="col-xs-12 col-md-6"><h3>{{ \'about.passman\' | translate}}</h3><p>{{ \'version\' | translate}}: <b>{{passman_version}}</b><br><br><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank" class="link">{{ \'donate.support\' | translate}}</a><br></p><h3>{{ \'bookmarklet\' | translate}}</h3><div><p>{{ \'bookmarklet.info1\' | translate}}<br>{{ \'bookmarklet.info2\' | translate}}<br></p></div><div><p ng-bind-html="bookmarklet" style="margin-top: 5px"></p></div></div></div>');
+ '<div class="row"><div class="col-xs-12 col-md-6"><h3>{{ \'rename.vault\' | translate}}</h3><label>{{ \'rename.vault.name\' | translate}}</label> <input type="text" ng-model="$parent.new_vault_name"> <button ng-click="saveVaultSettings()">{{ \'change\' | translate}}</button><h3>{{ \'change.vault.key\' | translate}}</h3><label>{{ \'old.vault.password\' | translate}}</label> <input type="password" ng-model="oldVaultPass"> <label>{{ \'new.vault.password\' | translate}}</label> <input type="password" ng-model="newVaultPass"><ng-password-meter password="newVaultPass" score="vault_key_score"></ng-password-meter><label>{{ \'new.vault.pw.r\' | translate}}</label> <input type="password" ng-model="newVaultPass2"><div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error"><ul><li>{{error}}</li><li ng-show="vault_key_score.score < minimal_value_key_strength">{{\'min.vault.key.strength\' | translate:required_score}}</li></ul></div><button ng-click="changeVaultPassword(oldVaultPass,newVaultPass,newVaultPass2)" ng-disabled="vault_key_score.score < minimal_value_key_strength">{{ \'change\' | translate}}</button><div ng-show="change_pw.total > 0">{{\'warning.leave\' | translate}}<br>{{ \'processing\' | translate}} {{cur_state.process}}<div progress-bar="cur_state.calculated" index="cur_state.current" total="cur_state.total"></div>{{ \'total.progress\' | translate}}<div progress-bar="change_pw.percent" index="change_pw.done" total="change_pw.total"></div></div><h3>{{\'delete.vault\' | translate}}</h3><b>{{ \'vault.remove.notice\' | translate }}</b> <label>{{\'vault.password\' | translate}}</label> <input type="password" ng-model="$parent.delete_vault_password"> <input type="checkbox" ng-model="$parent.confirm_vault_delete"> {{\'delete.vault.checkbox\' | translate}}<br><button class="btn btn-danger" ng-click="delete_vault()">{{\'delete.vault.confirm\' | translate}}</button><div ng-show="remove_pw">{{\'deleting.pw\' | translate:translationData}}<div progress-bar="remove_pw.percent" index="remove_pw.done" total="remove_pw.total"></div></div></div><div class="col-xs-12 col-md-6"><h3>{{ \'about.passman\' | translate}}</h3><p>{{ \'version\' | translate}}: <b>{{passman_version}}</b><br><br><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank" class="link">{{ \'donate.support\' | translate}}</a><br></p><h3>{{ \'bookmarklet\' | translate}}</h3><div><p>{{ \'bookmarklet.info1\' | translate}}<br>{{ \'bookmarklet.info2\' | translate}}<br></p></div><div><p ng-bind-html="bookmarklet" style="margin-top: 5px"></p></div></div></div>');
}]);
-angular.module('views/partials/forms/settings/generic_csv_import.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/generic_csv_import.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/generic_csv_import.html',
'<div ng-controller="GenericCsvImportCtrl"><div class="row"><div class="col-xs-12 col-md-3"><div>{{ \'select.csv\' | translate}} <input type="file" file-select accept=".csv" success="csvLoaded"></div><div ng-show="parsed_csv"><span translate="parsed.csv.rows" translate-value-rows="{{ parsed_csv.length }}"></span></div><div ng-show="parsed_csv"><input type="checkbox" ng-model="skipFirstRow" ng-checked="matched"> {{ \'skip.first.row\' | translate}}</div><div ng-show="import_fields.indexOf(\'label\') === -1 && parsed_csv"><b>{{ \'import.csv.label.req\' | translate}}</b></div><div ng-show="import_fields.indexOf(\'label\') !== -1 && parsed_csv"><button class="btn btn-success" ng-disabled="importing" ng-click="startCSVImport()"><i class="fa fa-spinner fa-spin" ng-show="importing"></i> {{ (importing) ? (\'import.importing\' | translate) : (\'import.start\' | translate) }}</button></div><div><div ng-if="import_progress.progress > 0">{{ \'upload.progress\' | translate}}<div progress-bar="import_progress.progress" index="import_progress.loaded" total="import_progress.total"></div></div></div><div><div ng-if="log" class="import_log"><textarea id="import_log" auto-scroll="log">{{log.join(\'\\n\')}}</textarea></div></div></div><div class="col-xs-12 col-md-9" ng-show="parsed_csv"><b>{{ \'first.five.lines\' | translate }}</b><br>{{ \'assign.column\' | translate }}<div class="import-table-outter"><table class="import-table"><tr ng-repeat="line in parsed_csv | limitTo:5"><td class="inspect"><i class="fa fa-search" ng-click="inspectCredential(line)" ng-if="($index > 0 && matched && import_fields.length > 0) || ($index >= 0 && !matched && import_fields.length > 0)"></i></td><td ng-repeat="prop in line track by $index">{{line[$index]}}</td></tr><tr ng-repeat="line in parsed_csv | limitTo:1"><td></td><td ng-repeat="prop in line track by $index"><select ng-model="import_fields[$index]" ng-change="updateExample()" ng-options="property.prop as property.label for property in credentialProperties"></select></td></tr></table></div><div ng-show="inspected_credential && import_fields.length > 0"><b>{{ \'example.credential\' | translate}}</b><div credential-template="inspected_credential" show-label></div></div></div></div></div>');
}]);
-angular.module('views/partials/forms/settings/import.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/import.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/import.html',
- '<div><div ng-click="showGenericImport = !showGenericImport;" class="link"><span ng-show="!showGenericImport">{{\'missing.importer\' | translate}}</span> <span ng-show="showGenericImport">{{\'missing.importer.back\' | translate}}</span></div></div><div ng-controller="ImportCtrl" ng-show="!showGenericImport"><div class="row"><div class="col-xs-6"><div class="import-selection"><label>{{ \'import.type\' | translate}}<select ng-init="importerType" ng-model="importerType" ng-change="setImporter(importerType)"><option ng-repeat="importer in available_importers" value="{{importer}}">{{importer.name}}</option></select></label></div><div ng-show="selectedImporter"><b>{{ \'import.steps\' | translate }}</b><ul class="import-steps"><li ng-repeat="step in selectedImporter.exportSteps">{{step}}</li></ul></div><input ng-if="selectedImporter" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br><button class="button" ng-click="startImport()" ng-if="selectedImporter">{{ \'import\' | translate}}</button><div ng-if="file_read_progress.percent > 0">{{ \'read.progress\' | translate}}<div progress-bar="file_read_progress.percent" index="file_read_progress.loaded" total="file_read_progress.total"></div></div><div ng-if="import_progress.progress > 0">{{ \'upload.progress\' | translate}}<div progress-bar="import_progress.progress" index="import_progress.loaded" total="import_progress.total"></div></div></div><div class="col-xs-6"><div ng-if="log" class="import_log"><textarea id="import_log" auto-scroll="log">{{log.join(\'\\n\')}}</textarea></div></div></div></div><div ng-include="\'views/partials/forms/settings/generic_csv_import.html\'" ng-show="showGenericImport"></div>');
+ '<div><div ng-click="showGenericImport = !showGenericImport;" class="link"><span ng-show="!showGenericImport">{{\'missing.importer\' | translate}}</span> <span ng-show="showGenericImport">{{\'missing.importer.back\' | translate}}</span></div></div><div ng-controller="ImportCtrl" ng-show="!showGenericImport"><div class="row"><div class="col-xs-6"><div class="import-selection"><label>{{ \'import.type\' | translate}} <select ng-init="importerType" ng-model="importerType" ng-change="setImporter(importerType)"><option ng-repeat="importer in available_importers" value="{{importer}}">{{importer.name}}</option></select></label></div><div ng-show="selectedImporter"><b>{{ \'import.steps\' | translate }}</b><ul class="import-steps"><li ng-repeat="step in selectedImporter.exportSteps">{{step}}</li></ul></div><input ng-if="selectedImporter" type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"><br><button class="button" ng-click="startImport()" ng-if="selectedImporter">{{ \'import\' | translate}}</button><div ng-if="file_read_progress.percent > 0">{{ \'read.progress\' | translate}}<div progress-bar="file_read_progress.percent" index="file_read_progress.loaded" total="file_read_progress.total"></div></div><div ng-if="import_progress.progress > 0">{{ \'upload.progress\' | translate}}<div progress-bar="import_progress.progress" index="import_progress.loaded" total="import_progress.total"></div></div></div><div class="col-xs-6"><div ng-if="log" class="import_log"><textarea id="import_log" auto-scroll="log">{{log.join(\'\\n\')}}</textarea></div></div></div></div><div ng-include="\'views/partials/forms/settings/generic_csv_import.html\'" ng-show="showGenericImport"></div>');
}]);
-angular.module('views/partials/forms/settings/password_settings.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/password_settings.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/password_settings.html',
- '<div class="password_settings"><div class="col-xs-12 col-sm-5 col-lg-4 password-settings-padding-left-fix"><label><span class="label">{{ \'password.generation.length\' | translate}}</span><br><input type="number" ng-model="vault_settings.pwSettings.length" min="1"></label><label><span class="label">{{ \'password.generation.min_digits\' | translate}}</span><br><input type="number" ng-model="vault_settings.pwSettings.minimumDigitCount" min="0"></label><label><span class="label">Generate password on creation</span><br><input type="checkbox" ng-model="vault_settings.pwSettings.generateOnCreate" min="0"></label></div><div class="col-xs-12 col-sm-6 col-lg-6"><label><input type="checkbox" ng-model="vault_settings.pwSettings.useUppercase"> <span class="label sm">{{ \'password.generation.uppercase\' | translate}}</span></label><label><input ng-model="vault_settings.pwSettings.useLowercase" type="checkbox" id="lower"> <span class="label sm">{{ \'password.generation.lowercase\' | translate}}</span></label><label><input ng-model="vault_settings.pwSettings.useDigits" type="checkbox" id="digits"> <span class="label sm">{{ \'password.generation.digits\' | translate}}</span></label><label><input type="checkbox" id="special" ng-model="vault_settings.pwSettings.useSpecialChars"> <span class="label sm">{{ \'password.generation.special\' | translate}}</span></label><label><input type="checkbox" id="ambig" ng-model="vault_settings.pwSettings.avoidAmbiguousCharacters"> <span class="label sm">{{ \'password.generation.ambiguous\' | translate}}</span></label><label><input type="checkbox" ng-model="vault_settings.pwSettings.requireEveryCharType" id="reqevery"> <span class="label sm">{{ \'password.generation.require_same\' | translate}}</span></label></div></div><div class="row"><div class="col-xs-12"><button class="button" ng-click="saveVaultSettings()">{{ \'save\' | translate}}</button></div></div>');
+ '<div class="password_settings"><div class="col-xs-12 col-sm-5 col-lg-4 password-settings-padding-left-fix"><label><span class="label">{{ \'password.generation.length\' | translate}}</span><br><input type="number" ng-model="vault_settings.pwSettings.length" min="1"></label> <label><span class="label">{{ \'password.generation.min_digits\' | translate}}</span><br><input type="number" ng-model="vault_settings.pwSettings.minimumDigitCount" min="0"></label> <label><span class="label">Generate password on creation</span><br><input type="checkbox" ng-model="vault_settings.pwSettings.generateOnCreate" min="0"></label></div><div class="col-xs-12 col-sm-6 col-lg-6"><label><input type="checkbox" ng-model="vault_settings.pwSettings.useUppercase"> <span class="label sm">{{ \'password.generation.uppercase\' | translate}}</span></label> <label><input ng-model="vault_settings.pwSettings.useLowercase" type="checkbox" id="lower"> <span class="label sm">{{ \'password.generation.lowercase\' | translate}}</span></label> <label><input ng-model="vault_settings.pwSettings.useDigits" type="checkbox" id="digits"> <span class="label sm">{{ \'password.generation.digits\' | translate}}</span></label> <label><input type="checkbox" id="special" ng-model="vault_settings.pwSettings.useSpecialChars"> <span class="label sm">{{ \'password.generation.special\' | translate}}</span></label> <label><input type="checkbox" id="ambig" ng-model="vault_settings.pwSettings.avoidAmbiguousCharacters"> <span class="label sm">{{ \'password.generation.ambiguous\' | translate}}</span></label> <label><input type="checkbox" ng-model="vault_settings.pwSettings.requireEveryCharType" id="reqevery"> <span class="label sm">{{ \'password.generation.require_same\' | translate}}</span></label></div></div><div class="row"><div class="col-xs-12"><button class="button" ng-click="saveVaultSettings()">{{ \'save\' | translate}}</button></div></div>');
}]);
-angular.module('views/partials/forms/settings/sharing.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/sharing.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/sharing.html',
- '<div ng-controller="SharingSettingsCtrl"><div class="row"><div class="col-md-6"><label>{{ \'priv.key\' | translate}}</label><textarea class="col-md-12">{{sharing_keys.private_sharing_key}}</textarea></div><div class="col-md-6"><label>{{ \'pub.key\' | translate}}</label><textarea class="col-md-12">{{sharing_keys.public_sharing_key}}</textarea></div></div><div class="row"><div class="col-md-12"><label>{{ \'key.size\' | translate}}<select ng-model="key_size" ng-options="size.name for size in available_sizes"></select><button ng-click="updateSharingKeys()"><i class="fa fa-fa-floppy-o"></i> {{ \'save.keys\' | translate}}</button> <button ng-if="!generating" ng-click="generateKeys(key_size.size)">{{ \'gen.keys\' | translate}}</button> <button ng-if="generating"><i class="fa fa-spinner fa-spin"></i> {{ \'generating.keys\' | translate}} ({{progress}}/2)</button></label></div></div></div>');
+ '<div ng-controller="SharingSettingsCtrl"><div class="row"><div class="col-md-6"><label>{{ \'priv.key\' | translate}}</label> <textarea class="col-md-12">{{sharing_keys.private_sharing_key}}</textarea></div><div class="col-md-6"><label>{{ \'pub.key\' | translate}}</label> <textarea class="col-md-12">{{sharing_keys.public_sharing_key}}</textarea></div></div><div class="row"><div class="col-md-12"><label>{{ \'key.size\' | translate}} <select ng-model="key_size" ng-options="size.name for size in available_sizes"></select> <button ng-click="updateSharingKeys()"><i class="fa fa-fa-floppy-o"></i> {{ \'save.keys\' | translate}}</button> <button ng-if="!generating" ng-click="generateKeys(key_size.size)">{{ \'gen.keys\' | translate}}</button> <button ng-if="generating"><i class="fa fa-spinner fa-spin"></i> {{ \'generating.keys\' | translate}} ({{progress}}/2)</button></label></div></div></div>');
}]);
-angular.module('views/partials/forms/settings/tool.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/settings/tool.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/settings/tool.html',
'<div class="row"><div class="col-xs-12"><p>{{ \'tool.intro\' | translate}}</p></div><div class="col-xs-12" ng-init="minStrength = 3;">{{ \'min.strength\' | translate}} <input type="number" min="1" max="4" value="3" ng-model="minStrength"> <button ng-click="startScan(minStrength)">{{ \'scan.start\' | translate}}</button></div></div><div class="row" ng-show="scan_result"><div class="col-xs-12"><p class="spacer-top-30"><b>{{ \'scan.result.msg\' | translate}}</b><br><span translate="scan.result" translate-values="{ scan_result: scan_result.length}"></span><br></p><table class="table scan-result-table spacer-top-30"><thead><tr><td><b>{{ \'label\' | translate}}</b></td><td><b>{{ \'score\' | translate}}</b></td><td><b>{{ \'password\' | translate}}</b></td><td><b>{{ \'action\' | translate}}</b></td></tr></thead><tbody><tr ng-repeat="result in scan_result | orderBy:\'password_zxcvbn_result.score\'"><td class="label-audit">{{result.label}}</td><td class="score"><ng-password-meter password="result.password"></ng-password-meter></td><td><span credential-field value="result.password" secret="\'true\'"></span></td><td><div><a href="#/vault/{{ active_vault.guid }}/edit/{{result.guid}}" class="link"><i class="fa fa-edit"></i></a></div></td></tr></tbody></table></div></div>');
}]);
-angular.module('views/partials/forms/share_credential/basics.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/share_credential/basics.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/share_credential/basics.html',
'<div class="row"><div class="col-xs-12 col-md-6"><div><table class="table sharing_table"><thead><tr><td><tags-input ng-model="inputSharedWith" replace-spaces-with-dashes="false" add-from-autocomplete-only="true" placeholder="{{ \'search.u.g\' | translate}}"><auto-complete source="searchUsers($query)" min-length="0" template="autocomplete-template"></auto-complete></tags-input></td><td><button class="button" ng-click="shareWith(inputSharedWith)">+</button></td></tr><tr><td colspan="2"><small>{{ \'search.result.missing\' | translate}}</small></td></tr></thead></table><div ng-if="share_settings.cypher_progress.done > 0">{{\'cyphering\' | translate}}...<div progress-bar="share_settings.cypher_progress.percent" index="share_settings.cypher_progress.done" total="share_settings.cypher_progress.total"></div></div><div ng-if="share_settings.upload_progress.done > 0">{{ \'uploading\' | translate}}...<div progress-bar="share_settings.upload_progress.percent" index="share_settings.upload_progress.done" total="share_settings.upload_progress.total"></div></div></div></div><div class="col-xs-12 col-md-6" ng-show="share_settings.cypher_progress.times.length > 0"><table class="table"><thead><tr><td>{{ \'user\' | translate}}</td><td>{{ \'crypto.time\' | translate}}</td></tr></thead><tr ng-repeat="user in share_settings.cypher_progress.times"><td><i class="fa fa-cogs"></i> {{user.user}}</td><td>{{user.time}} s</td></tr></table>{{ \'crypto.total.time\' | translate}}: {{ calculate_total_time() }}</div></div><div class="row"><div class="col-xs-12 col-md-6"><table class="table shared_table" ng-show="share_settings.credentialSharedWithUserAndGroup.length > 0"><thead><tr><td>{{\'user\' | translate}}</td><td>{{ \'perm.read\' | translate}}</td><td>{{ \'perm.write\' | translate}}</td><td>{{ \'perm.files\' | translate}}</td><td>{{ \'perm.revisions\' | translate}}</td><td></td></tr></thead><tr ng-repeat="user in share_settings.credentialSharedWithUserAndGroup"><td><i class="fa fa-user" ng-if="user.pending === false"></i> <i class="fa fa-user-times" ng-if="user.pending === true"></i> {{user.userId}} <small ng-if="user.pending === true" class="pull-right pending">{{ \'pending\' | translate}}</small></td><td><input type="checkbox" ng-click="setPermission(user.acl, default_permissions.permissions.READ)" ng-checked="hasPermission(user.acl, default_permissions.permissions.READ)"></td><td><input type="checkbox" ng-click="setPermission(user.acl, default_permissions.permissions.WRITE)" ng-checked="hasPermission(user.acl, default_permissions.permissions.WRITE)"></td><td><input type="checkbox" ng-click="setPermission(user.acl, default_permissions.permissions.FILES)" ng-checked="hasPermission(user.acl, default_permissions.permissions.FILES)"></td><td><input type="checkbox" ng-click="setPermission(user.acl, default_permissions.permissions.HISTORY)" ng-checked="hasPermission(user.acl, default_permissions.permissions.HISTORY)"></td><td><i class="fa fa-trash" ng-click="unshareUser(user)"></i></td></tr></table></div></div><script type="text/ng-template" id="autocomplete-template"><i class="fa fa-user" ng-if="data.type === \'user\'"></i>\n' +
@@ -98,51 +98,51 @@ angular.module('views/partials/forms/share_credential/basics.html', []).run(['$t
' {{data.text}}</script>');
}]);
-angular.module('views/partials/forms/share_credential/link_sharing.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/forms/share_credential/link_sharing.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/share_credential/link_sharing.html',
'<div class="row"><div class="col-xs-12 col-md-6"><label><input type="checkbox" ng-model="share_settings.linkSharing.enabled"> {{ \'enable.link.sharing\' | translate}}.</label><br><div class="pull-left col-xs-6 nopadding"><span credential-field value="share_link" secret="false" use-input="true" input-placeholder="\'click.share\' | translate"></span></div><div ng-show="share_settings.linkSharing.enabled" class="clearfix">{{ \'share.until.date\' | translate}} <span datetime-picker ng-model="share_settings.linkSharing.settings.expire_time" class="link" future-only close-on-select="false" timestamp="true">{{ share_settings.linkSharing.settings.expire_time | date:\'dd-MM-yyyy @ HH:mm:ss\' }}</span></div><div ng-show="share_settings.linkSharing.enabled">{{ \'expire.views\' | translate}}<br><input type="number" ng-model="share_settings.linkSharing.settings.expire_views"></div><div ng-if="share_settings.linkSharing.enabled"><table><tr><td><input type="checkbox" ng-click="setPermission(share_settings.linkSharing.settings.acl, default_permissions.permissions.FILES)" ng-checked="hasPermission(share_settings.linkSharing.settings.acl, default_permissions.permissions.FILES)"></td><td>{{ \'show.files\' | translate}}</td></tr></table></div></div></div>');
}]);
-angular.module('views/partials/icon-picker.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/icon-picker.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/icon-picker.html',
- '<div class="cell icon-category-auth" ng-if="!credential.url && !credential.icon"></div><div class="cell" ng-if="credential.url || credential.icon"><span class="icon"><credential-icon credential="credential"></credential-icon></span></div><div style="display: none" id="iconPicker" title="{{ \'pick.icon\' | translate }}"><div class="iconList"><div ng-repeat="(groupName, icons) in iconGroups"><div ng-click="expanded = !expanded" ng-init="expanded=true"><div class="icon-triangle-s arrow" ng-class="{ \'icon-triangle-e\': !expanded , \'icon-triangle-s\': expanded }"></div><div class="collapsible" id="{{groupName}}">{{groupName}}</div></div><div ng-class="{ \'content_show\': expanded , \'content\': !expanded }"><div class="icon" ng-repeat="icon in icons" ng-click="selectIcon(icon)"><img ng-src="{{icon.url}}" height="32"></div></div></div></div><div class="iconModifier"><input id="iconPicker-Search" class="iconSearch" type="text" placeholder="{{ \'pick.icon.search\' | translate }}"><label for="iconPicker-CustomIcon">{{ \'pick.icon.custom.label\' | translate }}</label><input id="iconPicker-CustomIcon" class="iconSearch" type="file"><div ng-if="selectedIcon || customIcon">{{ \'selected.icon\' | translate}}:<br><img ng-src="{{selectedIcon.url}}" height="32" ng-if="!customIcon"> <img src="{{customIcon.data}}" height="32" ng-if="customIcon"><br><button ng-click="useIcon()">{{ \'use.icon\' | translate}}</button></div><div><button ng-click="deleteIcon()" ng-if="credential.icon">{{ \'use.icon.delete\' | translate}}</button> <button ng-click="refreshUrlIcon()">{{ \'use.icon.refresh\' | translate}}</button></div></div></div>');
+ '<div class="cell fa fa-lock" ng-if="!credential.url && !credential.icon"></div><div class="cell" ng-if="credential.url || credential.icon"><span class="icon"><credential-icon credential="credential"></credential-icon></span></div><div style="display: none" id="iconPicker" title="{{ \'pick.icon\' | translate }}"><div class="iconList"><div ng-repeat="(groupName, icons) in iconGroups"><div ng-click="expanded = !expanded" ng-init="expanded=true"><div class="icon-triangle-s arrow" ng-class="{ \'icon-triangle-e\': !expanded , \'icon-triangle-s\': expanded }"></div><div class="collapsible" id="{{groupName}}">{{groupName}}</div></div><div ng-class="{ \'content_show\': expanded , \'content\': !expanded }"><div class="icon" ng-repeat="icon in icons" ng-click="selectIcon(icon)"><img ng-src="{{icon.url}}" height="32"></div></div></div></div><div class="iconModifier"><input id="iconPicker-Search" class="iconSearch" type="text" placeholder="{{ \'pick.icon.search\' | translate }}"> <label for="iconPicker-CustomIcon">{{ \'pick.icon.custom.label\' | translate }}</label> <input id="iconPicker-CustomIcon" class="iconSearch" type="file"><div ng-if="selectedIcon || customIcon">{{ \'selected.icon\' | translate}}:<br><img ng-src="{{selectedIcon.url}}" height="32" ng-if="!customIcon"> <img src="{{customIcon.data}}" height="32" ng-if="customIcon"><br><button ng-click="useIcon()">{{ \'use.icon\' | translate}}</button></div><div><button ng-click="deleteIcon()" ng-if="credential.icon">{{ \'use.icon.delete\' | translate}}</button> <button ng-click="refreshUrlIcon()">{{ \'use.icon.refresh\' | translate}}</button></div></div></div>');
}]);
-angular.module('views/partials/password-meter.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/partials/password-meter.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/password-meter.html',
'<div class="pass-meter {{masterClass}}" off-click="matchBreakdown = false;"><div class="{{colClass}} pass-meter-col {{first}}"><div class="indicator"></div></div><div class="{{colClass}} pass-meter-col {{second}}"><div class="indicator"></div></div><div class="{{colClass}} pass-meter-col {{third}}"><div class="indicator"></div></div><div class="{{colClass}} pass-meter-col {{fourth}}"><div class="indicator"></div></div><div class="details" ng-click="toggleScore()"><span ng-show="!scoreShown">{{ \'details\' | translate }}</span> <span ng-show="scoreShown">{{ \'hide.details\' | translate}}</span></div><div class="pass-meter-message">{{message}}</div><div class="detail_box" ng-show="scoreShown"><div class="row"><div class="col-xs-6">{{ \'password.score\' | translate}}:</div><div class="col-xs-6">{{score.score}}</div></div><div><b>{{ \'cracking.times\' | translate}}</b></div><div class="row"><div class="col-xs-6">{{ \'cracking.time.100h\' | translate}}<br><small>{{ \'cracking.time.100h.desc\' | translate}}</small></div><div class="col-xs-6">{{score.crack_times_display.online_throttling_100_per_hour}}</div></div><div class="row"><div class="col-xs-6">{{ \'cracking.time.10s\' | translate}}<br><small>{{ \'cracking.time.10s.desc\' | translate}}</small></div><div class="col-xs-6">{{score.crack_times_display.online_no_throttling_10_per_second}}</div></div><div class="row"><div class="col-xs-6">{{ \'cracking.time.10ks\' | translate}}<br><small>{{ \'cracking.time.10ks.desc\' | translate}}</small></div><div class="col-xs-6">{{score.crack_times_display.offline_slow_hashing_1e4_per_second}}</div></div><div class="row"><div class="col-xs-6">{{ \'cracking.time.10Bs\' | translate}}<br><small>{{ \'cracking.time.10Bs.desc\' | translate}}</small></div><div class="col-xs-6">{{score.crack_times_display.offline_fast_hashing_1e10_per_second}}</div></div><div class="row"><div class="col-xs-6">{{ \'match.sequence\' | translate}}:</div><div class="col-xs-6"><span class="link" ng-click="toggleMatchBreakdown()">{{ \'match.sequence.link\' | translate}}</span></div></div></div></div><div class="match-sequence"><div class="sequence_container" ng-style="{\'width\': score.sequence.length * 210 }"><div class="sequence" ng-repeat="sequence in score.sequence"><table><tr><td colspan="2" class="token"><code>{{sequence.token}}</code></td></tr><tr ng-if="sequence.pattern"><td>{{ \'pattern\' | translate}}</td><td>{{sequence.pattern}}</td></tr><tr ng-if="sequence.matched_word"><td>{{ \'matched.word\' | translate}}</td><td>{{sequence.matched_word}}</td></tr><tr ng-if="sequence.dictionary_name"><td>{{ \'dictionary.name\' | translate}}</td><td>{{sequence.dictionary_name}}</td></tr><tr ng-if="sequence.rank"><td>{{ \'rank\' | translate}}</td><td>{{sequence.rank}}</td></tr><tr ng-if="sequence.reversed"><td>{{ \'reversed\' | translate}}</td><td>{{sequence.reversed}}</td></tr><tr ng-if="sequence.guesses"><td>{{ \'guesses\' | translate}}</td><td>{{sequence.guesses}}</td></tr><tr ng-if="sequence.base_guesses"><td>{{ \'base.guesses\' | translate}}</td><td>{{sequence.base_guesses}}</td></tr><tr ng-if="sequence.uppercase_variations"><td>{{ \'uppercase.variations\' | translate}}</td><td>{{sequence.uppercase_variations}}</td></tr><tr ng-if="sequence.l33t_variations"><td>{{ \'leet.variations\' | translate}}</td><td>{{sequence.l33t_variations}}</td></tr></table></div></div></div>');
}]);
-angular.module('views/settings.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/settings.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/settings.html',
'<div id="passman-controls"><div class="breadcrumb"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a ng-click="logout()"><i class="fa fa-home"></i></a></div><div class="crumb svg"><a ng-click="cancel()">{{active_vault.name}}</a></div><div class="crumb svg last"><a>{{ \'settings\' | translate}}</a></div></div></div></div><div><ul class="tab_header"><li ng-repeat="tab in tabs track by $index" class="tab" ng-class="isActiveTab(tab)? \'active\' : \'inactive\'" ng-click="onClickTab(tab)" use-theme color="\'true\'">{{tab.title | translate}}<div class="indicator" use-theme negative="\'true\'"></div></li></ul><div class="tab_container settings edit_credential" use-theme type="\'border-top-color\'"><div ng-include="currentTab.url"></div></div></div>');
}]);
-angular.module('views/share_credential.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/share_credential.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/share_credential.html',
'<div class="main_list.share"><div id="passman-controls"><div class="actions creatable"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a ng-click="logout()"><i class="fa fa-home"></i></a></div><div class="crumb svg" data-dir="/Test"><a ng-click="cancel()">{{active_vault.name}}</a></div><div class="crumb svg last" data-dir="/Test"><a ng-if="storedCredential.credential_id">{{ \'share.credential\' | translate}} {{storedCredential.label}}</a></div></div></div></div><ul class="tab_header"><li ng-repeat="tab in tabs track by $index" class="tab" ng-class="{active:isActiveTab(tab)}" ng-click="onClickTab(tab)" use-theme color="\'true\'">{{tab.title | translate}}<div class="indicator" use-theme negative="\'true\'"></div></li></ul><div class="tab_container share_credential" ng-show="currentTab"><div ng-include="currentTab.url"></div><button ng-click="applyShare()" ng-disabled="share_settings.linkSharing.enabled === false && share_settings.credentialSharedWithUserAndGroup.length === 0">{{ \'share\' | translate}}</button> <button ng-click="cancel()">{{ \'cancel\' | translate}}</button> <button class="btn btn-danger" ng-disabled="!storedCredential.shared_key" ng-click="unshareCredential(storedCredential)">{{ \'unshare\' | translate}}</button></div></div>');
}]);
-angular.module('views/show_vault.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/show_vault.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/show_vault.html',
- '<div class="main_list" off-click-filter="\'.download-js-link, .sidebar-shown, #app-sidebar\'"><div id="passman-controls" ng-class="{ \'sidebar-shown\': selectedCredential }"><div class="breadcrumb"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a ng-click="logout()"><i class="fa fa-home"></i></a></div><div class="crumb svg" ng-click="clearState()"><a>{{active_vault.name}}</a></div></div><div class="addCredential" ng-hide="delete_time>0"><button ng-click="addCredential()">+</button></div></div><div class="title" credential-counter="filtered_credentials" vault="active_vault" delete-time="delete_time" filters="filterOptions"></div><div class="searchboxContainer" ng-init="filterOptionShown = false;" off-click="filterOptionShown = false;"><input type="text" ng-model="filterOptions.filterText" class="searchbox" id="searchBox" placeholder="{{\'search.credential\' | translate}}" select-on-click clear-btn ng-click="filterOptionShown = true;"><div class="searchOptions" ng-show="filterOptionShown"><input type="checkbox" ng-model="filterOptions.useRegex"> {{ \'use.regex\' | translate }}</div></div><div class="viewModes"><div class="view-mode" ng-class="{\'active\': view_mode === \'list\' }" ng-click="switchViewMode(\'list\')"><i class="fa fa-list"></i></div><div class="view-mode" ng-class="{\'active\': view_mode === \'grid\' }" ng-click="switchViewMode(\'grid\')"><i class="fa fa-th-large"></i></div></div></div><div class="loaderContainer" ng-if="show_spinner"><div class="loader" use-theme type="\'border-bottom-color\'"></div></div><div ng-init="menuOpen = false;"><table class="credential-table" ng-if="view_mode === \'list\'"><tr ng-repeat="credential in filtered_credentials | orderBy:\'label\'" ng-if="showCredentialRow(credential)" ng-click="selectCredential(credential)" ng-dblclick="editCredential(credential)" ng-class="{\'selected\': selectedCredential.credential_id == credential.credential_id}"><td ng-class="{\'compromised\': credential.compromised }"><span class="tags"><span class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</span> </span><span class="icon" ng-if="credential.url || credential.icon"><credential-icon credential="credential"></credential-icon></span><span class="icon" ng-if="!credential.url && !credential.icon"><i class="fa fa-lock" ng-if="!credential.acl && !credential.shared_key"></i> <i class="fa fa-share-alt" ng-if="credential.acl"></i> <i class="fa fa-share-alt-square" ng-if="credential.shared_key"></i> </span><a class="label">{{ ::credential.label}}</a> <span ng-if="credential.compromised" class="compromised-list"><i class="icon-error icon"></i> <span class="text">{{ \'compromised.warning.list\' | translate}}</span></span></td></tr></table><ul class="grid-view" ng-if="view_mode === \'grid\'"><li class="credential" ng-repeat="credential in filtered_credentials | orderBy:\'label\'" ng-if="credential.hidden == 0 && showCredentialRow(credential)" ng-click="selectCredential(credential)" use-theme type="\'border-color\'"><div class="credential_content"><div><span class="icon" ng-if="credential.url"><credential-icon credential="credential"></credential-icon></span><span class="icon" ng-if="!credential.url"><i class="fa fa-lock" ng-if="!credential.acl && !credential.shared_key"></i> <i class="fa fa-share-alt" ng-if="credential.acl"></i> <i class="fa fa-share-alt-square" ng-if="credential.shared_key"></i></span><div class="label">{{ ::credential.label}}</div></div><div class="tags"><div class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</div></div></div></li></ul><div ng-if="getListSizes().listsize_wout_deleted==0 && no_credentials_label.all && !show_spinner && selectedtags.length==0 && filterOptions.filterText==\'\'" class="nopasswords" ng-hide="delete_time>0"><b>{{\'vault.hint.hello\' | translate}}</b><br><div>{{\'vault.hint.hello.add\' | translate}}</div><div class=""><button ng-click="addCredential()">+</button></div></div><div ng-if="getListSizes().listsize_wout_deleted==0 && no_credentials_label.all && !show_spinner && selectedtags.length>0" class="nopasswords" ng-hide="delete_time>0"><div>{{ \'vault.hint.list.notags\' | translate}}</div></div><div ng-if="getListSizes().listsize_wout_deleted==0 && no_credentials_label.all && !show_spinner && selectedtags.length==0 && filterOptions.filterText!=\'\'" class="nopasswords" ng-hide="delete_time>0"><div>{{ \'vault.hint.list.nosearch\' | translate}} <b>\'{{filterOptions.filterText}}\'</b></div></div><div class="nopasswords" ng-if="no_credentials_label.s_good" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.nogood\' | translate}}</div></div><div class="nopasswords" ng-if="no_credentials_label.s_medium" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.nomedium\' | translate}}</div></div><div class="nopasswords" ng-if="no_credentials_label.s_low" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.nobad\' | translate}}</div></div><div class="nopasswords" ng-if="no_credentials_label.expired" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.noexpired\' | translate}}</div></div><div class="nopasswords" ng-if="getListSizes().listsize_deleted==0" ng-hide="delete_time==0"><div>{{ \'vault.hint.list.nodeleted\' | translate}}</div></div></div></div><div id="app-sidebar" class="app_sidebar" ng-show="selectedCredential" off-click="closeSelected()"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><div class="sidebar"><span class="icon sidebar-icon" ng-if="selectedCredential.url || credential.icon"><credential-icon credential="selectedCredential"></credential-icon></span><span class="icon sidebar-icon" ng-if="!selectedCredential.url && !credential.icon"><credential-icon credential="selectedCredential"></credential-icon></span><h2 class="sidebar-label">{{selectedCredential.label}}</h2></div><div credential-template="selectedCredential"></div><div ng-show="selectedCredential"><div><button class="button" ng-click="editCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && hasPermission(selectedCredential.acl.permissions, permissions.permissions.WRITE)"><span class="fa fa-edit"></span> {{ \'edit\' | translate}}</button> <button class="button" ng-click="deleteCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && hasPermission(selectedCredential.acl.permissions, permissions.permissions.WRITE)"><span class="fa fa-trash"></span> {{ \'delete\' | translate}}</button> <button class="button" ng-click="shareCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && selectedCredential.acl === undefined &&\n' +
+ '<div class="main_list" off-click-filter="\'.download-js-link, .sidebar-shown, #app-sidebar\'"><div id="passman-controls" ng-class="{ \'sidebar-shown\': selectedCredential }"><div class="breadcrumb"><div class="breadcrumb"><div class="crumb svg ui-droppable" data-dir="/"><a ng-click="logout()"><i class="fa fa-home"></i></a></div><div class="crumb svg" ng-click="clearState()"><a>{{active_vault.name}}</a></div></div><div class="addCredential" ng-hide="delete_time>0"><button ng-click="addCredential()">+</button></div></div><div class="title" credential-counter="filtered_credentials" vault="active_vault" delete-time="delete_time" filters="filterOptions"></div><div class="searchboxContainer" ng-init="filterOptionShown = false;" off-click="filterOptionShown = false;"><input type="text" ng-model="filterOptions.filterText" class="searchbox" id="searchBox" placeholder="{{\'search.credential\' | translate}}" select-on-click clear-btn ng-click="filterOptionShown = true;"><div class="searchOptions" ng-show="filterOptionShown"><input type="checkbox" ng-model="filterOptions.useRegex"> {{ \'use.regex\' | translate }}</div></div><div class="viewModes"><div class="view-mode" ng-class="{\'active\': view_mode === \'list\' }" ng-click="switchViewMode(\'list\')"><i class="fa fa-list"></i></div><div class="view-mode" ng-class="{\'active\': view_mode === \'grid\' }" ng-click="switchViewMode(\'grid\')"><i class="fa fa-th-large"></i></div></div></div><div class="loaderContainer" ng-if="show_spinner"><div class="loader" use-theme type="\'border-bottom-color\'"></div></div><div ng-init="menuOpen = false;"><table class="credential-table" ng-if="view_mode === \'list\'"><tr ng-repeat="credential in filtered_credentials | orderBy:\'label\'" ng-if="showCredentialRow(credential)" ng-click="selectCredential(credential)" ng-dblclick="editCredential(credential)" ng-class="{\'selected\': selectedCredential.credential_id == credential.credential_id}"><td ng-class="{\'compromised\': credential.compromised }"><span class="tags"><span class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</span> </span><span class="icon" ng-if="credential.url || credential.icon"><credential-icon credential="credential"></credential-icon></span><span class="icon" ng-if="!credential.url && !credential.icon"><i class="fa fa-lock" ng-if="!credential.acl && !credential.shared_key"></i> <i class="fa fa-share-alt" ng-if="credential.acl"></i> <i class="fa fa-share-alt-square" ng-if="credential.shared_key"></i> </span><a class="label">{{ ::credential.label}}</a> <span ng-if="credential.compromised" class="compromised-list"><i class="icon-error icon"></i> <span class="text">{{ \'compromised.warning.list\' | translate}}</span></span></td></tr></table><ul class="grid-view" ng-if="view_mode === \'grid\'"><li class="credential" ng-repeat="credential in filtered_credentials | orderBy:\'label\'" ng-if="credential.hidden == 0 && showCredentialRow(credential)" ng-click="selectCredential(credential)" use-theme type="\'border-color\'"><div class="credential_content"><div><span class="icon" ng-if="credential.url"><credential-icon credential="credential"></credential-icon></span><span class="icon" ng-if="!credential.url"><i class="fa fa-lock" ng-if="!credential.acl && !credential.shared_key"></i> <i class="fa fa-share-alt" ng-if="credential.acl"></i> <i class="fa fa-share-alt-square" ng-if="credential.shared_key"></i></span><div class="label">{{ ::credential.label}}</div></div><div class="tags"><div class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</div></div></div></li></ul><div ng-if="getListSizes().listsize_wout_deleted==0 && no_credentials_label.all && !show_spinner && selectedtags.length==0 && filterOptions.filterText==\'\'" class="nopasswords" ng-hide="delete_time>0"><b>{{\'vault.hint.hello\' | translate}}</b><br><div>{{\'vault.hint.hello.add\' | translate}}</div><div class=""><button ng-click="addCredential()">+</button></div></div><div ng-if="getListSizes().listsize_wout_deleted==0 && no_credentials_label.all && !show_spinner && selectedtags.length>0" class="nopasswords" ng-hide="delete_time>0"><div>{{ \'vault.hint.list.notags\' | translate}}</div></div><div ng-if="getListSizes().listsize_wout_deleted==0 && no_credentials_label.all && !show_spinner && selectedtags.length==0 && filterOptions.filterText!=\'\'" class="nopasswords" ng-hide="delete_time>0"><div>{{ \'vault.hint.list.nosearch\' | translate}} <b>\'{{filterOptions.filterText}}\'</b></div></div><div class="nopasswords" ng-if="no_credentials_label.s_good" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.nogood\' | translate}}</div></div><div class="nopasswords" ng-if="no_credentials_label.s_medium" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.nomedium\' | translate}}</div></div><div class="nopasswords" ng-if="no_credentials_label.s_low" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.nobad\' | translate}}</div></div><div class="nopasswords" ng-if="no_credentials_label.expired" ng-hide="getListSizes().listsize_wout_deleted>0"><div>{{ \'vault.hint.list.noexpired\' | translate}}</div></div><div class="nopasswords" ng-if="getListSizes().listsize_deleted==0" ng-hide="delete_time==0"><div>{{ \'vault.hint.list.nodeleted\' | translate}}</div></div></div></div><div id="app-sidebar" class="app_sidebar" ng-show="selectedCredential" off-click="closeSelected()"><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><div class="sidebar"><span class="icon sidebar-icon" ng-if="selectedCredential.url || selectedCredential.icon"><credential-icon credential="selectedCredential"></credential-icon></span><span class="icon sidebar-icon" ng-if="!selectedCredential.url && !selectedCredential.icon"><i class="fa fa-lock fa-3x icon-image"></i></span><h2 class="sidebar-label">{{selectedCredential.label}}</h2></div><div credential-template="selectedCredential"></div><div ng-show="selectedCredential"><div><button class="button" ng-click="editCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && hasPermission(selectedCredential.acl.permissions, permissions.permissions.WRITE)"><span class="fa fa-edit"></span> {{ \'edit\' | translate}}</button> <button class="button" ng-click="deleteCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && hasPermission(selectedCredential.acl.permissions, permissions.permissions.WRITE)"><span class="fa fa-trash"></span> {{ \'delete\' | translate}}</button> <button class="button" ng-click="shareCredential(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && selectedCredential.acl === undefined &&\n' +
' (settings.user_sharing_enabled === 1 || settings.user_sharing_enabled === \'1\' || settings.link_sharing_enabled === 1 || settings.link_sharing_enabled === \'1\')"><span class="fa fa-share"></span> {{ \'share\' | translate}}</button> <button class="button" ng-click="getRevisions(selectedCredential)" ng-if="selectedCredential.delete_time == 0 && hasPermission(selectedCredential.acl.permissions, permissions.permissions.HISTORY)"><span class="fa fa-undo"></span> {{ \'revisions\' | translate}}</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="recoverCredential(selectedCredential) && hasPermission(selectedCredential.acl.permissions, permissions.permissions.WRITE)"><span class="fa fa-recycle"></span> {{\'recover\' | translate}}</button> <button class="button" ng-if="selectedCredential.delete_time > 0" ng-click="destroyCredential(selectedCredential)"><span class="fa fa-bomb"></span> {{\'destroy\' | translate}}</button></div></div></div><div class="share_popup" style="display: none" title="{{ \'sharereq.title\' | translate }}"><p>{{ \'sharereq.line1\' | translate}} {{ \'sharereq.line2\' | translate}}</p><br><table class="table"><thead><tr><td><b>{{ \'label\' | translate}}</b></td><td><b>{{ \'permissions\' | translate}}</b></td><td><b>{{ \'received.from\' | translate}}</b></td><td><b>{{ \'date\' | translate}}</b></td></tr></thead><tr ng-repeat="share_request in incoming_share_requests" ng-if="share_request.target_vault_id == active_vault.vault_id"><td>{{share_request.credential_label}}</td><td>{{share_request.permissions}}</td><td>{{share_request.from_user_id}}</td><td>{{share_request.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</td><td><span class="link" ng-click="acceptShareRequest(share_request)"><b>{{ \'accept\' | translate}}</b></span> | <span class="link" ng-click="declineShareRequest(share_request)">{{ \'decline\' | translate}}</span></td></tr></table></div>');
}]);
-angular.module('views/vault_req_deletion.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/vault_req_deletion.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/vault_req_deletion.html',
- '<div class="vault_wrapper"><div class="reset_form" ng-show="!pending_deletion">{{ \'req.intro1\' | translate }}<br>{{ \'req.intro2\' | translate }}<br>{{ \'req.intro3\' | translate }}<br><br><b>{{ \'request.deletion.warning\' | translate}}</b><label>{{ \'request.deletion.reason\' | translate }}</label><input type="text" ng-model="reason" class="form-control"> <button class="button button-red" ng-click="requestDeletion()">{{ \'request.deletion.accept\' | translate }}</button> <a class="pull-right button button-geen" ng-href="#/">{{ \'cancel\' | translate}}</a></div><div class="reset_form" ng-show="pending_deletion"><button class="button button-red" ng-click="removeRequestDeletion()">Cancel destruction request</button> <a class="pull-right button button-geen" ng-href="#/">Cancel</a></div></div>');
+ '<div class="vault_wrapper"><div class="reset_form" ng-show="!pending_deletion">{{ \'req.intro1\' | translate }}<br>{{ \'req.intro2\' | translate }}<br>{{ \'req.intro3\' | translate }}<br><br><b>{{ \'request.deletion.warning\' | translate}}</b> <label>{{ \'request.deletion.reason\' | translate }}</label> <input type="text" ng-model="reason" class="form-control"> <button class="button button-red" ng-click="requestDeletion()">{{ \'request.deletion.accept\' | translate }}</button> <a class="pull-right button button-geen" ng-href="#/">{{ \'cancel\' | translate}}</a></div><div class="reset_form" ng-show="pending_deletion"><button class="button button-red" ng-click="removeRequestDeletion()">Cancel destruction request</button> <a class="pull-right button button-geen" ng-href="#/">Cancel</a></div></div>');
}]);
-angular.module('views/vaults.html', []).run(['$templateCache', function ($templateCache) {
+angular.module('views/vaults.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/vaults.html',
- '<div class="vault_wrapper"><div class="vaults" ng-if="!list_selected_vault && !creating_vault"><div class="ui-select-container ui-select-bootstrap vaultlist"><ul><li ng-click="newVault()">+ Create a new vault</li><li ng-repeat="vault in vaults" ng-class="{\'selected\': vault == list_selected_vault }" ng-click="selectVault(vault)"><div><span class="ui-select-choices-row-inner"><div class="ng-binding ng-scope">{{vault.name}} <span class="pull-right" style="color: #ce3702" ng-show="vault.delete_request_pending">{{ \'delete.request.pending\' | translate}}</span></div><small class="ng-binding ng-scope">{{ \'created\' | translate}}: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{ \'last.access\' | translate}}: <span ng-if="vault.last_access > 0">{{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="vault.last_access === 0">{{\'never\' | translate}}</span></small></span></div></li><li ng-if="vaults.length === 0">{{ \'no.vaults\' | translate}}</li></ul></div></div><div ng-if="creating_vault"><div class="login_form" ng-init="vault_name = \'\'; vault_key=\'\'; ">{{\'new.vault.name\' | translate}}<div><input type="text" ng-model="vault_name" required></div><div>{{ \'new.vault.pass\' | translate}} <input type="password" ng-model="vault_key" required><ng-password-meter password="vault_key" score="vault_key_score"></ng-password-meter></div><div>{{ \'new.vault.passr\' | translate}} <input type="password" ng-model="vault_key2" required></div><div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error"><ul><li ng-show="error">{{error}}</li><li ng-show="vault_key_score.score < minimal_value_key_strength">{{\'min.vault.key.strength\' | translate:required_score}}</li></ul></div><div><small>{{\'new.vault.sharing_key_notice\' | translate}}</small></div><div class="button_wrapper"><button class="button button-geen" ng-if="!creating_keys" click-disable ng-click="createVault(vault_name, vault_key, vault_key2)" ng-disabled="vault_key_score.score < minimal_value_key_strength || vault_key !== vault_key2 || vault_key === \'\'">{{ \'new.vault.create\' | translate }}</button><div class="button" ng-if="creating_keys"><span><i class="fa fa-spinner fa-spin"></i> {{creating_keys}}</span></div><div class="button button-red" ng-click="clearState()">{{ \'cancel\' | translate}}</div><div class="template-hidden">{{sharing_keys}}</div></div></div></div><div ng-if="list_selected_vault != false"><div class="vaultlist"><ul><li ng-click="clearState()">{{ \'go.back.vaults\' | translate }}</li></ul></div><div class="login_form"><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div>{{ \'input.vault.password\' | translate}} {{list_selected_vault.name}}<div class="pw-input"><input type="password" ng-model="vault_key" ng-enter="loginToVault(list_selected_vault, vault_key)"> <small class="last_access">{{\'last.access\' | translate}}: <span ng-if="list_selected_vault.last_access > 0">{{list_selected_vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="list_selected_vault.last_access === 0">Never</span></small></div><div class="login_opts"><div><label><input type="checkbox" ng-checked="default_vault" ng-click="toggleDefaultVault()"> {{ \'vault.default\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="remember_vault_password" ng-click="toggleRememberPassword()"> {{ \'vault.auto.login\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="auto_logout_timer" ng-click="toggleAutoLogout()"> {{ \'auto.logout\' | translate}}</label><select ng-model="logout_timer" ng-change="selectLogoutTimer(logout_timer)"><option value="0">Never</option><option value="30">30 minutes</option><option value="60">60 minutes</option><option value="90">90 minutes</option><option value="180">3 hour</option><option value="480">8 hour</option></select></div></div><div class="alert alert-danger" ng-show="vault_tries[list_selected_vault.guid].timeout !== 0" translate="vault.locked" translate-value-tries="{{ vault_tries[list_selected_vault.guid].tries }}" translate-value-time="{{ vault_tries[list_selected_vault.guid].timeout | toHHMMSS }}"></div><button class="button button-geen" ng-click="loginToVault(list_selected_vault, vault_key)" ng-disabled="vault_tries[list_selected_vault.guid].timeout !== 0">{{ \'vault.decrypt\' | translate}}</button> <span ng-click="forgottenPassword = true;" style="margin-top: 10px; padding: 6px 12px" class="link pull-right" ng-show="!forgottenPassword">Forgot password?</span> <button ng-show="forgottenPassword" class="pull-right button button-red" ng-click="requestDeletion(list_selected_vault)"><span ng-show="list_selected_vault.delete_request_pending">{{ \'cancel.request.deletion\' | translate }}</span> <span ng-show="!list_selected_vault.delete_request_pending">{{ \'request.deletion\' | translate }}</span></button></div></div></div>');
+ '<div class="vault_wrapper"><div class="vaults" ng-if="!list_selected_vault && !creating_vault"><div class="ui-select-container ui-select-bootstrap vaultlist"><ul><li ng-click="newVault()">+ Create a new vault</li><li ng-repeat="vault in vaults" ng-class="{\'selected\': vault == list_selected_vault }" ng-click="selectVault(vault)"><div><span class="ui-select-choices-row-inner"><div class="ng-binding ng-scope">{{vault.name}} <span class="pull-right" style="color: #ce3702;" ng-show="vault.delete_request_pending">{{ \'delete.request.pending\' | translate}}</span></div><small class="ng-binding ng-scope">{{ \'created\' | translate}}: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{ \'last.access\' | translate}}: <span ng-if="vault.last_access > 0">{{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="vault.last_access === 0">{{\'never\' | translate}}</span></small></span></div></li><li ng-if="vaults.length === 0">{{ \'no.vaults\' | translate}}</li></ul></div></div><div ng-if="creating_vault"><div class="login_form" ng-init="vault_name = \'\'; vault_key=\'\'; ">{{\'new.vault.name\' | translate}}<div><input type="text" ng-model="vault_name" required></div><div>{{ \'new.vault.pass\' | translate}} <input type="password" ng-model="vault_key" required><ng-password-meter password="vault_key" score="vault_key_score"></ng-password-meter></div><div>{{ \'new.vault.passr\' | translate}} <input type="password" ng-model="vault_key2" required></div><div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error"><ul><li ng-show="error">{{error}}</li><li ng-show="vault_key_score.score < minimal_value_key_strength">{{\'min.vault.key.strength\' | translate:required_score}}</li></ul></div><div><small>{{\'new.vault.sharing_key_notice\' | translate}}</small></div><div class="button_wrapper"><button class="button button-geen" ng-if="!creating_keys" click-disable ng-click="createVault(vault_name, vault_key, vault_key2)" ng-disabled="vault_key_score.score < minimal_value_key_strength || vault_key !== vault_key2 || vault_key === \'\'">{{ \'new.vault.create\' | translate }}</button><div class="button" ng-if="creating_keys"><span><i class="fa fa-spinner fa-spin"></i> {{creating_keys}}</span></div><div class="button button-red" ng-click="clearState()">{{ \'cancel\' | translate}}</div><div class="template-hidden">{{sharing_keys}}</div></div></div></div><div ng-if="list_selected_vault != false"><div class="vaultlist"><ul><li ng-click="clearState()">{{ \'go.back.vaults\' | translate }}</li></ul></div><div class="login_form"><div ng-show="error" class="error"><ul><li>{{error}}</li></ul></div>{{ \'input.vault.password\' | translate}} {{list_selected_vault.name}}<div class="pw-input"><input type="password" ng-model="vault_key" ng-enter="loginToVault(list_selected_vault, vault_key)"> <small class="last_access">{{\'last.access\' | translate}}: <span ng-if="list_selected_vault.last_access > 0">{{list_selected_vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}</span> <span ng-if="list_selected_vault.last_access === 0">Never</span></small></div><div class="login_opts"><div><label><input type="checkbox" ng-checked="default_vault" ng-click="toggleDefaultVault()"> {{ \'vault.default\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="remember_vault_password" ng-click="toggleRememberPassword()"> {{ \'vault.auto.login\' | translate}}</label></div><div><label><input type="checkbox" ng-checked="auto_logout_timer" ng-click="toggleAutoLogout()"> {{ \'auto.logout\' | translate}}</label> <select ng-model="logout_timer" ng-change="selectLogoutTimer(logout_timer)"><option value="0">Never</option><option value="30">30 minutes</option><option value="60">60 minutes</option><option value="90">90 minutes</option><option value="180">3 hour</option><option value="480">8 hour</option></select></div></div><div class="alert alert-danger" ng-show="vault_tries[list_selected_vault.guid].timeout !== 0" translate="vault.locked" translate-value-tries="{{ vault_tries[list_selected_vault.guid].tries }}" translate-value-time="{{ vault_tries[list_selected_vault.guid].timeout | toHHMMSS }}"></div><button class="button button-geen" ng-click="loginToVault(list_selected_vault, vault_key)" ng-disabled="vault_tries[list_selected_vault.guid].timeout !== 0">{{ \'vault.decrypt\' | translate}}</button> <span ng-click="forgottenPassword = true;" style="margin-top: 10px; padding: 6px 12px;" class="link pull-right" ng-show="!forgottenPassword">Forgot password?</span> <button ng-show="forgottenPassword" class="pull-right button button-red" ng-click="requestDeletion(list_selected_vault)"><span ng-show="list_selected_vault.delete_request_pending">{{ \'cancel.request.deletion\' | translate }}</span> <span ng-show="!list_selected_vault.delete_request_pending">{{ \'request.deletion\' | translate }}</span></button></div></div></div>');
}]);
diff --git a/lib/Activity.php b/lib/Activity.php
index 96c1afaf..61f6fc33 100644
--- a/lib/Activity.php
+++ b/lib/Activity.php
@@ -24,6 +24,7 @@
namespace OCA\Passman;
use OCP\IURLGenerator;
+use OCP\L10N\IFactory;
class Activity implements \OCP\Activity\IExtension {
const FILTER_PASSMAN = 'passman';
@@ -54,9 +55,11 @@ class Activity implements \OCP\Activity\IExtension {
protected $URLGenerator;
+ protected $factory;
- public function __construct( IURLGenerator $URLGenerator) {
+ public function __construct(IURLGenerator $URLGenerator, IFactory $factory) {
$this->URLGenerator = $URLGenerator;
+ $this->factory = $factory;
}
@@ -67,8 +70,8 @@ class Activity implements \OCP\Activity\IExtension {
* @param string $languageCode
* @return array|false
*/
- public function getNotificationTypes($languageCode) {
- $l = \OC::$server->getL10N(self::APP_NAME, $languageCode);
+ public function getNotificationTypes(string $languageCode) {
+ $l = $this->factory->get(self::APP_NAME, $languageCode);
return array(
self::TYPE_ITEM_ACTION => $l->t('A Passman item has been created, modified or deleted'),
self::TYPE_ITEM_EXPIRED => $l->t('A Passman item has expired'),
@@ -127,7 +130,7 @@ class Activity implements \OCP\Activity\IExtension {
* @return string|false
*/
public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
- $l = \OC::$server->getL10NFactory()->get(self::APP_NAME, $languageCode);
+ $l = $this->factory->get(self::APP_NAME, $languageCode);
if ($app === self::APP_NAME) {
switch ($text) {
case self::SUBJECT_ITEM_CREATED:
@@ -258,13 +261,13 @@ class Activity implements \OCP\Activity\IExtension {
* @return array|false
*/
public function getNavigation() {
- $l = \OC::$server->getL10N(self::APP_NAME);
+ $l = $this->factory->get(self::APP_NAME);
return array(
'top' => array(),
- 'apps' => array( self::FILTER_PASSMAN =>
+ 'apps' => array(self::FILTER_PASSMAN =>
array(
'id' => 'passman',
- 'name' => (string) $l->t('Passwords'),
+ 'name' => (string)$l->t('Passwords'),
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_PASSMAN]),
),
),
@@ -278,7 +281,7 @@ class Activity implements \OCP\Activity\IExtension {
* @return boolean
*/
public function isFilterValid($filterValue) {
- return $filterValue === self::FILTER_PASSMAN;
+ return $filterValue === self::FILTER_PASSMAN;
}
/**
@@ -300,4 +303,4 @@ class Activity implements \OCP\Activity\IExtension {
return false;
}
-} \ No newline at end of file
+}
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index f83dbcbd..2849dc99 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -39,16 +39,23 @@ use OCA\Passman\Service\SettingsService;
use OCA\Passman\Service\ShareService;
use OCA\Passman\Service\VaultService;
use OCA\Passman\Utility\Utils;
+use OCA\UserStatus\Listener\UserDeletedListener;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\IDBConnection;
+use OCP\IGroupManager;
use OCP\IL10N;
-use OCP\ILogger;
+use OCP\INavigationManager;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\IUserSession;
use OCP\Notification\IManager;
+use OCP\User\Events\BeforeUserDeletedEvent;
use OCP\Util;
use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
class Application extends App implements IBootstrap {
public const APP_ID = 'passman';
@@ -59,7 +66,6 @@ class Application extends App implements IBootstrap {
public function register(IRegistrationContext $context): void {
$this->registerNavigationEntry();
- // $this->registerPersonalPage();
$context->registerEventListener(
BeforeUserDeletedEvent::class,
@@ -80,20 +86,27 @@ class Application extends App implements IBootstrap {
$context->registerMiddleware(APIMiddleware::class);
$context->registerService('ShareController', function (ContainerInterface $c) {
- $server = $this->getContainer()->getServer();
+ /** @var IUserManager $userManager */
+ $userManager = $c->get(IUserManager::class);
+ /** @var IGroupManager $groupManager */
+ $groupManager = $c->get(IGroupManager::class);
+ /** @var IUserSession $userSession */
+ $userSession = $c->get(IUserSession::class);
+
return new ShareController(
$c->get('AppName'),
$c->get('Request'),
- $server->getUserSession()->getUser(),
- $server->getGroupManager(),
- $server->getUserManager(),
+ $userSession->getUser(),
+ $groupManager,
+ $userManager,
$c->get(ActivityService::class),
$c->get(VaultService::class),
$c->get(ShareService::class),
$c->get(CredentialService::class),
$c->get(NotificationService::class),
$c->get(FileService::class),
- $c->get(SettingsService::class)
+ $c->get(SettingsService::class),
+ $c->get(IManager::class)
);
});
@@ -101,7 +114,7 @@ class Application extends App implements IBootstrap {
$context->registerService('CronService', function (ContainerInterface $c) {
return new CronService(
$c->get(CredentialService::class),
- $c->get(ILogger::class),
+ $c->get(LoggerInterface::class),
$c->get(Utils::class),
$c->get(NotificationService::class),
$c->get(ActivityService::class),
@@ -115,14 +128,11 @@ class Application extends App implements IBootstrap {
}
public function boot(IBootContext $context): void {
- $l = \OC::$server->getL10N(self::APP_ID);
-
/** @var IManager $manager */
$manager = $context->getAppContainer()->get(IManager::class);
$manager->registerNotifierService(Notifier::class);
Util::addTranslations(self::APP_ID);
- \OCP\App::registerAdmin(self::APP_ID, 'templates/admin.settings');
}
/**
@@ -130,23 +140,20 @@ class Application extends App implements IBootstrap {
*/
public function registerNavigationEntry() {
$c = $this->getContainer();
- $server = $c->getServer();
- $navigationEntry = function () use ($c, $server) {
+ /** @var INavigationManager $navigationManager */
+ $navigationManager = $c->get(INavigationManager::class);
+
+ $navigationEntry = function () use ($c) {
+ /** @var IURLGenerator $urlGenerator */
+ $urlGenerator = $c->get(IURLGenerator::class);
return [
'id' => $c->getAppName(),
'order' => 10,
- 'name' => $c->query(IL10N::class)->t('Passwords'),
- 'href' => $server->getURLGenerator()->linkToRoute('passman.page.index'),
- 'icon' => $server->getURLGenerator()->imagePath($c->getAppName(), 'app.svg'),
+ 'name' => $c->get(IL10N::class)->t('Passwords'),
+ 'href' => $urlGenerator->linkToRoute('passman.page.index'),
+ 'icon' => $urlGenerator->imagePath($c->getAppName(), 'app.svg'),
];
};
- $server->getNavigationManager()->add($navigationEntry);
- }
-
- /**
- * Register personal settings for notifications and emails
- */
- public function registerPersonalPage() {
- \OCP\App::registerPersonal($this->getContainer()->getAppName(), 'personal');
+ $navigationManager->add($navigationEntry);
}
}
diff --git a/lib/BackgroundJob/ExpireCredentials.php b/lib/BackgroundJob/ExpireCredentials.php
index e1b06f95..a911775e 100644
--- a/lib/BackgroundJob/ExpireCredentials.php
+++ b/lib/BackgroundJob/ExpireCredentials.php
@@ -24,7 +24,7 @@
namespace OCA\Passman\BackgroundJob;
use OC\BackgroundJob\TimedJob;
-use \OCA\Passman\AppInfo\Application;
+use OCA\Passman\Service\CronService;
use OCP\IConfig;
/**
@@ -33,21 +33,23 @@ use OCP\IConfig;
* @package OCA\Passman\BackgroundJob
*/
class ExpireCredentials extends TimedJob {
- /** @var IConfig */
- protected $config;
+
+ protected IConfig $config;
+ private CronService $cronService;
/**
+ * ExpireCredentials constructor.
* @param IConfig $config
+ * @param CronService $cronService
*/
- public function __construct(IConfig $config) {
+ public function __construct(IConfig $config, CronService $cronService) {
// Run once per minute
$this->setInterval(60);
$this->config = $config;
+ $this->cronService = $cronService;
}
protected function run($argument) {
- $app = new Application();
- $container = $app->getContainer();
- $container->query('CronService')->expireCredentials();
+ $this->cronService->expireCredentials();
}
}
diff --git a/lib/Db/CredentialMapper.php b/lib/Db/CredentialMapper.php
index 2ae6e8e3..e39146bc 100644
--- a/lib/Db/CredentialMapper.php
+++ b/lib/Db/CredentialMapper.php
@@ -24,14 +24,19 @@
namespace OCA\Passman\Db;
use OCA\Passman\Utility\Utils;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-use OCP\AppFramework\Db\Mapper;
-class CredentialMapper extends Mapper {
- private $utils;
+class CredentialMapper extends QBMapper {
+ const TABLE_NAME = 'passman_credentials';
+ private Utils $utils;
public function __construct(IDBConnection $db, Utils $utils) {
- parent::__construct($db, 'passman_credentials');
+ parent::__construct($db, self::TABLE_NAME);
$this->utils = $utils;
}
@@ -39,74 +44,98 @@ class CredentialMapper extends Mapper {
/**
* Obtains the credentials by vault id (not guid)
*
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
- * @return Credential[]
+ * @param string $vault_id
+ * @param string $user_id
+ * @return Entity[]
*/
- public function getCredentialsByVaultId($vault_id, $user_id) {
- $sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
- 'WHERE `user_id` = ? and vault_id = ?';
- return $this->findEntities($sql, [$user_id, $vault_id]);
+ public function getCredentialsByVaultId(string $vault_id, string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('vault_id', $qb->createNamedParameter($vault_id, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
}
/**
- * Get a random credentail from a vault
+ * Get a random credential from a vault
*
- * @param $vault_id
- * @param $user_id
- * @return Credential
+ * @param string $vault_id
+ * @param string $user_id
+ * @return Credential[]
*/
- public function getRandomCredentialByVaultId($vault_id, $user_id) {
- $sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
- 'WHERE `user_id` = ? and vault_id = ? AND shared_key is NULL LIMIT 20';
- $entities = $this->findEntities($sql, [$user_id, $vault_id]);
+ public function getRandomCredentialByVaultId(string $vault_id, string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('vault_id', $qb->createNamedParameter($vault_id, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->isNull('shared_key'))
+ ->setMaxResults(20);
+
+ $entities = $this->findEntities($qb);
$count = count($entities) - 1;
- $entities = array_splice($entities, rand(0, $count), 1);
- return $entities;
+
+ /** @var Credential[] $entity */
+ $entity = array_splice($entities, rand(0, $count), 1);
+ return $entity;
}
/**
* Get expired credentials
*
- * @param $timestamp
- * @return Credential[]
+ * @param int $timestamp
+ * @return Entity[]
*/
- public function getExpiredCredentials($timestamp) {
- $sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
- 'WHERE `expire_time` > 0 AND `expire_time` < ?';
- return $this->findEntities($sql, [$timestamp]);
+ public function getExpiredCredentials(int $timestamp) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->gt('expire_time', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
+ ->andWhere($qb->expr()->lt('expire_time', $qb->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT)));
+
+ return $this->findEntities($qb);
}
/**
* Get an credential by id.
* Optional user id
*
- * @param $credential_id
- * @param null $user_id
- * @return Credential
+ * @param int $credential_id
+ * @param string|null $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialById($credential_id, $user_id = null) {
- $sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
- 'WHERE `id` = ?';
- // If we want to check the owner, add it to the query
- $params = [$credential_id];
+ public function getCredentialById(int $credential_id, string $user_id = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($credential_id, IQueryBuilder::PARAM_INT)));
+
if ($user_id !== null) {
- $sql .= ' and `user_id` = ? ';
- array_push($params, $user_id);
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
}
- return $this->findEntity($sql, $params);
+
+ return $this->findEntity($qb);
}
/**
* Get credential label by id
*
- * @param $credential_id
- * @return Credential
+ * @param int $credential_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialLabelById($credential_id) {
- $sql = 'SELECT id, label FROM `*PREFIX*passman_credentials` ' .
- 'WHERE `id` = ? ';
- return $this->findEntity($sql, [$credential_id]);
+ public function getCredentialLabelById(int $credential_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select(['id', 'label'])
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($credential_id, IQueryBuilder::PARAM_INT)));
+
+ return $this->findEntity($qb);
}
/**
@@ -130,7 +159,7 @@ class CredentialMapper extends Mapper {
$credential->setUsername($raw_credential['username']);
$credential->setPassword($raw_credential['password']);
$credential->setUrl($raw_credential['url']);
- $credential->setIcon($raw_credential['favicon']);
+ $credential->setIcon($raw_credential['icon']);
$credential->setRenewInterval($raw_credential['renew_interval']);
$credential->setExpireTime($raw_credential['expire_time']);
$credential->setDeleteTime($raw_credential['delete_time']);
@@ -146,13 +175,13 @@ class CredentialMapper extends Mapper {
}
/**
- * Update a credential
- *
* @param $raw_credential array An array containing all the credential fields
* @param $useRawUser bool
- * @return Credential The updated credential
+ * @return Credential|Entity The updated credential
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function updateCredential($raw_credential, $useRawUser) {
+ public function updateCredential($raw_credential, bool $useRawUser) {
$original = $this->getCredentialByGUID($raw_credential['guid']);
$uid = ($useRawUser) ? $raw_credential['user_id'] : $original->getUserId();
@@ -197,16 +226,22 @@ class CredentialMapper extends Mapper {
/**
* Finds a credential by the given guid
*
- * @param $credential_guid
- * @return Credential
+ * @param string $credential_guid
+ * @param string|null $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialByGUID($credential_guid, $user_id = null) {
- $q = 'SELECT * FROM `*PREFIX*passman_credentials` WHERE guid = ? ';
- $params = [$credential_guid];
+ public function getCredentialByGUID(string $credential_guid, string $user_id = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('guid', $qb->createNamedParameter($credential_guid, IQueryBuilder::PARAM_STR)));
+
if ($user_id !== null) {
- $q .= ' and `user_id` = ? ';
- array_push($params, $user_id);
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
}
- return $this->findEntity($q, $params);
+
+ return $this->findEntity($qb);
}
-} \ No newline at end of file
+}
diff --git a/lib/Db/CredentialRevisionMapper.php b/lib/Db/CredentialRevisionMapper.php
index a22f5d1b..001e4374 100644
--- a/lib/Db/CredentialRevisionMapper.php
+++ b/lib/Db/CredentialRevisionMapper.php
@@ -24,49 +24,61 @@
namespace OCA\Passman\Db;
use OCA\Passman\Utility\Utils;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-use OCP\AppFramework\Db\Mapper;
-class CredentialRevisionMapper extends Mapper {
- private $utils;
+class CredentialRevisionMapper extends QBMapper {
+ const TABLE_NAME = 'passman_revisions';
+ private Utils $utils;
public function __construct(IDBConnection $db, Utils $utils) {
- parent::__construct($db, 'passman_revisions');
+ parent::__construct($db, self::TABLE_NAME);
$this->utils = $utils;
}
/**
* Get revisions from a credential
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
- * @return CredentialRevision[]
+ *
+ * @param int $credential_id
+ * @param string|null $user_id
+ * @return Entity[]
*/
- public function getRevisions($credential_id, $user_id = null) {
- $sql = 'SELECT * FROM `*PREFIX*passman_revisions` ' .
- 'WHERE `credential_id` = ?';
- $params = [$credential_id];
- if ($user_id !== null) {
- $sql.= ' and `user_id` = ? ';
- $params[] = $user_id;
- }
- return $this->findEntities($sql, $params);
+ public function getRevisions(int $credential_id, string $user_id = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('credential_id', $qb->createNamedParameter($credential_id, IQueryBuilder::PARAM_INT)));
+
+ if ($user_id !== null) {
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+ }
+
+ return $this->findEntities($qb);
}
/**
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
- * @return CredentialRevision
+ * @param int $revision_id
+ * @param string|null $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getRevision($revision_id, $user_id = null) {
- $sql = 'SELECT * FROM `*PREFIX*passman_revisions` ' .
- 'WHERE `id` = ?';
- $params = [$revision_id];
- if ($user_id !== null) {
- $sql.= ' and `user_id` = ? ';
- $params[] = $user_id;
- }
- return $this->findEntity($sql, $params);
+ public function getRevision(int $revision_id, string $user_id = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($revision_id, IQueryBuilder::PARAM_INT)));
+
+ if ($user_id !== null) {
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+ }
+
+ return $this->findEntity($qb);
}
/**
@@ -101,4 +113,4 @@ class CredentialRevisionMapper extends Mapper {
$revision->setUserId($user_id);
return $this->delete($revision);
}
-} \ No newline at end of file
+}
diff --git a/lib/Db/DeleteVaultRequestMapper.php b/lib/Db/DeleteVaultRequestMapper.php
index a43fe78f..585780d4 100644
--- a/lib/Db/DeleteVaultRequestMapper.php
+++ b/lib/Db/DeleteVaultRequestMapper.php
@@ -24,13 +24,14 @@
namespace OCA\Passman\Db;
-use Icewind\SMB\Share;
-use OCA\Passman\Utility\Utils;
use OCP\AppFramework\Db\DoesNotExistException;
-use OCP\AppFramework\Db\Mapper;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-class DeleteVaultRequestMapper extends Mapper {
+class DeleteVaultRequestMapper extends QBMapper {
const TABLE_NAME = 'passman_delete_vault_request';
public function __construct(IDBConnection $db) {
@@ -40,38 +41,47 @@ class DeleteVaultRequestMapper extends Mapper {
/**
* Create a new enty in the db
* @param DeleteVaultRequest $request
- * @return \OCP\AppFramework\Db\Entity
+ * @return Entity
*/
- public function createRequest(DeleteVaultRequest $request){
+ public function createRequest(DeleteVaultRequest $request) {
return $this->insert($request);
}
/**
* Get all delete requests
- * @return \OCP\AppFramework\Db\Entity
+ * @return Entity[]
*/
- public function getDeleteRequests(){
- $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME;
- return $this->findEntities($q);
+ public function getDeleteRequests() {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME);
+
+ return $this->findEntities($qb);
}
/**
- * Get request for an vault id
- * @param $vault_id integer The vault id
- * @return \OCP\AppFramework\Db\Entity
+ * Get request for a vault guid
+ * @param string $vault_guid
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getDeleteRequestsForVault($vault_guid){
- $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME .' WHERE `vault_guid` = ?';
- return $this->findEntity($q, [$vault_guid]);
+ public function getDeleteRequestsForVault(string $vault_guid) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('vault_guid', $qb->createNamedParameter($vault_guid, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntity($qb);
}
/**
* Deletes the given delete request
- * @param DeleteVaultRequest $request Request to delete
- * @return DeleteVaultRequest The deleted request
+ * @param DeleteVaultRequest $request Request to delete
+ * @return DeleteVaultRequest The deleted request
*/
- public function removeDeleteVaultRequest(DeleteVaultRequest $request){
+ public function removeDeleteVaultRequest(DeleteVaultRequest $request) {
return $this->delete($request);
}
-} \ No newline at end of file
+}
diff --git a/lib/Db/FileMapper.php b/lib/Db/FileMapper.php
index b1e044d3..eb7bb029 100644
--- a/lib/Db/FileMapper.php
+++ b/lib/Db/FileMapper.php
@@ -25,51 +25,61 @@
namespace OCA\Passman\Db;
use OCA\Passman\Utility\Utils;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-use OCP\AppFramework\Db\Mapper;
-class FileMapper extends Mapper {
- private $utils;
+class FileMapper extends QBMapper {
+ const TABLE_NAME = 'passman_files';
+ private Utils $utils;
public function __construct(IDBConnection $db, Utils $utils) {
- parent::__construct($db, 'passman_files');
+ parent::__construct($db, self::TABLE_NAME);
$this->utils = $utils;
}
/**
- * @param $file_id
- * @param null $user_id
- * @return File
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @param int $file_id
+ * @param string|null $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getFile($file_id, $user_id = null) {
- $sql = 'SELECT * FROM `*PREFIX*passman_files` ' .
- 'WHERE `id` = ?';
- $params = [$file_id];
+ public function getFile(int $file_id, string $user_id = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($file_id, IQueryBuilder::PARAM_INT)));
+
if ($user_id !== null) {
- $sql .= ' and `user_id` = ? ';
- array_push($params, $user_id);
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
}
- return $this->findEntity($sql, $params);
+
+ return $this->findEntity($qb);
}
+
/**
- * @param $file_id
- * @param null $user_id
- * @return File
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @param string $file_guid
+ * @param string|null $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getFileByGuid($file_guid, $user_id = null) {
- $sql = 'SELECT * FROM `*PREFIX*passman_files` ' .
- 'WHERE `guid` = ?';
- $params = [$file_guid];
+ public function getFileByGuid(string $file_guid, string $user_id = null) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('guid', $qb->createNamedParameter($file_guid, IQueryBuilder::PARAM_STR)));
+
if ($user_id !== null) {
- $sql .= ' and `user_id` = ? ';
- array_push($params, $user_id);
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
}
- return $this->findEntity($sql, $params);
+
+ return $this->findEntity($qb);
}
/**
@@ -87,21 +97,21 @@ class FileMapper extends Mapper {
$file->setFileData($file_raw['file_data']);
$file->setMimetype($file_raw['mimetype']);
-
return $this->insert($file);
}
/**
* Delete a file by file_id and user id
- * @param $file_id
- * @param $userId
- * @return File
+ *
+ * @param int $file_id
+ * @param string $userId
+ * @return File|Entity
*/
- public function deleteFile($file_id, $userId) {
+ public function deleteFile(int $file_id, string $userId) {
$file = new File();
$file->setId($file_id);
$file->setUserId($userId);
- $this->delete($file);
+ return $this->delete($file);
}
/**
@@ -115,16 +125,15 @@ class FileMapper extends Mapper {
/**
- * @param $user_id
- * @return File[]
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @param string $user_id
+ * @return Entity[]
*/
- public function getFilesFromUser($user_id) {
- $sql = 'SELECT * FROM `*PREFIX*passman_files` ' .
- 'WHERE `user_id` = ?';
- $params = [$user_id];
+ public function getFilesFromUser(string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
- return $this->findEntities($sql, $params);
+ return $this->findEntities($qb);
}
-} \ No newline at end of file
+}
diff --git a/lib/Db/ShareRequestMapper.php b/lib/Db/ShareRequestMapper.php
index 0660be0f..a836fd2f 100644
--- a/lib/Db/ShareRequestMapper.php
+++ b/lib/Db/ShareRequestMapper.php
@@ -24,129 +24,182 @@
namespace OCA\Passman\Db;
-use Icewind\SMB\Share;
-use OCA\Passman\Utility\Utils;
use OCP\AppFramework\Db\DoesNotExistException;
-use OCP\AppFramework\Db\Mapper;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\Exception;
+use OCP\DB\IResult;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-class ShareRequestMapper extends Mapper {
- const TABLE_NAME = 'passman_share_request';
-
- public function __construct(IDBConnection $db) {
- parent::__construct($db, self::TABLE_NAME);
- }
-
- public function createRequest(ShareRequest $request){
- return $this->insert($request);
- }
-
- /**
- * Obtains a request by the given item and vault GUID pair
- * @param $item_guid
- * @param $target_vault_guid
- * @return ShareRequest
- */
- public function getRequestByItemAndVaultGuid($item_guid, $target_vault_guid){
- $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME . " WHERE item_guid = ? AND target_vault_guid = ?";
- return $this->findEntity($q, [$item_guid, $target_vault_guid]);
- }
-
- /**
- * Get shared items for the given item_guid
- * @param $item_guid
- * @return ShareRequest[]
- */
- public function getRequestsByItemGuidGroupedByUser($item_guid){
- if (strtolower($this->db->getDatabasePlatform()->getName()) === 'mysql'){
- $this->db->executeQuery("SET sql_mode = '';");
+class ShareRequestMapper extends QBMapper {
+ const TABLE_NAME = 'passman_share_request';
+
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, self::TABLE_NAME);
+ }
+
+ /**
+ * @param ShareRequest $request
+ * @return ShareRequest|Entity
+ */
+ public function createRequest(ShareRequest $request) {
+ return $this->insert($request);
+ }
+
+ /**
+ * Obtains a request by the given item and vault GUID pair
+ *
+ * @param string $item_guid
+ * @param string $target_vault_guid
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ */
+ public function getRequestByItemAndVaultGuid(string $item_guid, string $target_vault_guid) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('target_vault_guid', $qb->createNamedParameter($target_vault_guid, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntity($qb);
+ }
+
+ /**
+ * Get shared items for the given item_guid
+ *
+ * @param string $item_guid
+ * @return Entity[]
+ * @throws Exception
+ */
+ public function getRequestsByItemGuidGroupedByUser(string $item_guid) {
+ if (strtolower($this->db->getDatabasePlatform()->getName()) === 'mysql') {
+ $this->db->executeQuery("SET sql_mode = '';");
}
- $q = "SELECT *, target_user_id FROM *PREFIX*" . self::TABLE_NAME . " WHERE item_guid = ? GROUP BY target_user_id;";
- return $this->findEntities($q, [$item_guid]);
- }
-
- /**
- * Deletes all pending requests for the given user to the given item
- * @param $item_id The item ID
- * @param $target_user_id The target user
- * @return \PDOStatement The result of running the db query
- */
- public function cleanItemRequestsForUser($item_id, $target_user_id){
- $q = "DELETE FROM *PREFIX*" . self::TABLE_NAME . " WHERE item_id = ? AND target_user_id = ?";
- $this->execute($q, [$item_id, $target_user_id]);
- return $this->execute($q, [$item_id, $target_user_id]);
- }
-
- /**
- * Obtains all pending share requests for the given user ID
- * @param $user_id
- * @return ShareRequest[]
- */
- public function getUserPendingRequests($user_id){
- $q = "SELECT * FROM *PREFIX*". self::TABLE_NAME ." WHERE target_user_id = ?";
- return $this->findEntities($q, [$user_id]);
- }
-
- /**
- * Deletes the given share request
- * @param ShareRequest $shareRequest Request to delete
- * @return ShareRequest The deleted request
- */
- public function deleteShareRequest(ShareRequest $shareRequest){
- return $this->delete($shareRequest);
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)))
+ ->groupBy('target_user_id');
+
+ return $this->findEntities($qb);
+ }
+
+ /**
+ * Deletes all pending requests for the given user to the given item
+ *
+ * @param int $item_id
+ * @param string $target_user_id
+ * @return int|IResult
+ * @throws Exception
+ */
+ public function cleanItemRequestsForUser(int $item_id, string $target_user_id) {
+ $qb = $this->db->getQueryBuilder();
+ return $qb->delete(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_id', $qb->createNamedParameter($item_id, IQueryBuilder::PARAM_INT)))
+ ->andWhere($qb->expr()->eq('target_user_id', $qb->createNamedParameter($target_user_id, IQueryBuilder::PARAM_STR)))
+ ->execute();
+ }
+
+ /**
+ * Obtains all pending share requests for the given user ID
+ *
+ * @param string $user_id
+ * @return Entity[]
+ */
+ public function getUserPendingRequests(string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('target_user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
+ }
+
+ /**
+ * Deletes the given share request
+ * @param ShareRequest $shareRequest Request to delete
+ * @return ShareRequest The deleted request
+ */
+ public function deleteShareRequest(ShareRequest $shareRequest) {
+ return $this->delete($shareRequest);
}
- /**
- * Gets a share request by it's unique incremental id
- * @param $id
- * @return ShareRequest
+ /**
+ * Gets a share request by it's unique incremental id
+ *
+ * @param int $id
+ * @return Entity
* @throws DoesNotExistException
- */
- public function getShareRequestById($id){
- $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME . " WHERE id = ?";
- return $this->findEntity($q, [$id]);
+ * @throws MultipleObjectsReturnedException
+ */
+ public function getShareRequestById(int $id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
+
+ return $this->findEntity($qb);
}
- /**
- * Gets all share requests by a given item GUID
- * @param $item_guid
- * @return ShareRequest[]
- */
- public function getShareRequestsByItemGuid($item_guid){
- $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME . " WHERE item_guid = ?";
- return $this->findEntities($q, [$item_guid]);
+ /**
+ * Gets all share requests by a given item GUID
+ *
+ * @param string $item_guid
+ * @return Entity[]
+ */
+ public function getShareRequestsByItemGuid(string $item_guid) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
}
- /**
- * Updates the given share request,
- * @param ShareRequest $shareRequest
- * @return ShareRequest
- */
- public function updateShareRequest(ShareRequest $shareRequest){
+ /**
+ * Updates the given share request,
+ * @param ShareRequest $shareRequest
+ * @return ShareRequest
+ */
+ public function updateShareRequest(ShareRequest $shareRequest) {
return $this->update($shareRequest);
}
- /**
- * Finds pending requests sent to the given user to the given item.
- * @param $item_guid
- * @param $user_id
- * @return ShareRequest[]
- */
- public function getPendingShareRequests($item_guid, $user_id){
- $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME . " WHERE item_guid = ? and target_user_id= ?";
- return $this->findEntities($q, [$item_guid, $user_id]);
+ /**
+ * Finds pending requests sent to the given user to the given item.
+ *
+ * @param string $item_guid
+ * @param string $user_id
+ * @return Entity[]
+ */
+ public function getPendingShareRequests(string $item_guid, string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('target_user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
}
- /**
- * Updates all pending requests with the given permissions
- * @param $item_guid The item for which to update the requests
- * @param $user_id The user for which to update the requests
- * @param $permissions The new permissions to apply
- * @return \PDOStatement The result of the operation
- */
- public function updatePendingRequestPermissions($item_guid, $user_id, $permissions){
- $q = "UPDATE *PREFIX*" . self::TABLE_NAME . " SET permissions = ? WHERE item_guid = ? AND target_user_id = ?";
- return $this->execute($q, [$permissions, $item_guid, $user_id]);
- }
-
-} \ No newline at end of file
+ /**
+ * Updates all pending requests with the given permissions
+ *
+ * @param string $item_guid The item for which to update the requests
+ * @param string $user_id The user for which to update the requests
+ * @param int $permissions The new permissions to apply
+ * @return int|IResult
+ * @throws Exception
+ */
+ public function updatePendingRequestPermissions(string $item_guid, string $user_id, int $permissions) {
+ $qb = $this->db->getQueryBuilder();
+ return $qb->update(self::TABLE_NAME)
+ ->set('permissions', $qb->createNamedParameter($permissions, IQueryBuilder::PARAM_INT))
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('target_user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)))
+ ->execute();
+ }
+}
diff --git a/lib/Db/SharingACLMapper.php b/lib/Db/SharingACLMapper.php
index e251a0c4..f03b9d9f 100644
--- a/lib/Db/SharingACLMapper.php
+++ b/lib/Db/SharingACLMapper.php
@@ -24,72 +24,99 @@
namespace OCA\Passman\Db;
-use OCP\AppFramework\Db\Mapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-use OCP\IUser;
-use OCA\Passman\Utility\Utils;
-class SharingACLMapper extends Mapper {
- const TABLE_NAME = '*PREFIX*passman_sharing_acl';
+class SharingACLMapper extends QBMapper {
+ const TABLE_NAME = 'passman_sharing_acl';
- public function __construct(IDBConnection $db) {
- parent::__construct($db, 'passman_sharing_acl');
- }
+ public function __construct(IDBConnection $db) {
+ parent::__construct($db, 'passman_sharing_acl');
+ }
- public function createACLEntry(SharingACL $acl){
- return $this->insert($acl);
- }
+ /**
+ * @param SharingACL $acl
+ * @return SharingACL|Entity
+ */
+ public function createACLEntry(SharingACL $acl) {
+ return $this->insert($acl);
+ }
- /**
- * Gets the currently accepted share requests from the given user for the given vault guid
- * @param $user_id
- * @param $vault_guid
- * @return SharingACL[]
- */
- public function getVaultEntries($user_id, $vault_guid) {
- $q = "SELECT * FROM ". self::TABLE_NAME ." WHERE user_id = ? AND vault_guid = ?";
- return $this->findEntities($q, [$user_id, $vault_guid]);
- }
+ /**
+ * Gets the currently accepted share requests from the given user for the given vault guid
+ *
+ * @param string $user_id
+ * @param string $vault_guid
+ * @return Entity[]
+ */
+ public function getVaultEntries(string $user_id, string $vault_guid) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('vault_guid', $qb->createNamedParameter($vault_guid, IQueryBuilder::PARAM_STR)));
- /**
- * Gets the acl for a given item guid
- * @param $user_id
- * @param $item_guid
- * @return SharingACL
- */
- public function getItemACL($user_id, $item_guid) {
- $q = "SELECT * FROM " . self::TABLE_NAME . " WHERE item_guid = ? AND ";
- $filter = [$item_guid];
- $q .= ($user_id === null) ? 'user_id is null' : 'user_id = ? ';
- if ($user_id !== null){
- $filter[] = $user_id;
- }
+ return $this->findEntities($qb);
+ }
- return $this->findEntity($q, $filter);
- }
+ /**
+ * Gets the acl for a given item guid
+ *
+ * @param string $user_id
+ * @param string $item_guid
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ */
+ public function getItemACL(string $user_id, string $item_guid) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)));
- /**
- * Update the acl for a given item guid
- * @param $user_id
- * @param $item_guid
- * @return SharingACL
- */
- public function updateCredentialACL(SharingACL $sharingACL) {
- return $this->update($sharingACL);
- }
+ if ($user_id === null) {
+ $qb->andWhere($qb->expr()->isNull('user_id'));
+ } else {
+ $qb->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+ }
+
+ return $this->findEntity($qb);
+ }
- /**
- * Gets the currently accepted share requests from the given user for the given vault guid
- * @param $user_id
- * @param $vault_id
- * @return SharingACL[]
- */
- public function getCredentialAclList($item_guid) {
- $q = "SELECT * FROM ". self::TABLE_NAME ." WHERE item_guid = ?";
- return $this->findEntities($q, [$item_guid]);
- }
+ /**
+ * Update an acl
+ *
+ * @param SharingACL $sharingACL
+ * @return SharingACL|Entity
+ */
+ public function updateCredentialACL(SharingACL $sharingACL) {
+ return $this->update($sharingACL);
+ }
+
+ /**
+ * Gets the currently accepted share requests from the given user for the given vault guid
+ *
+ * @param string $item_guid
+ * @return Entity[]
+ */
+ public function getCredentialAclList(string $item_guid) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('item_guid', $qb->createNamedParameter($item_guid, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
+ }
- public function deleteShareACL(SharingACL $ACL){
- return $this->delete($ACL);
+ /**
+ * @param SharingACL $ACL
+ * @return SharingACL|Entity
+ */
+ public function deleteShareACL(SharingACL $ACL) {
+ return $this->delete($ACL);
}
-} \ No newline at end of file
+}
diff --git a/lib/Db/VaultMapper.php b/lib/Db/VaultMapper.php
index 6844458c..37fb942c 100644
--- a/lib/Db/VaultMapper.php
+++ b/lib/Db/VaultMapper.php
@@ -24,61 +24,80 @@
namespace OCA\Passman\Db;
use OCA\Passman\Utility\Utils;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
-use OCP\AppFramework\Db\Mapper;
-class VaultMapper extends Mapper {
- private $utils;
+class VaultMapper extends QBMapper {
+ const TABLE_NAME = 'passman_vaults';
+ private Utils $utils;
+
public function __construct(IDBConnection $db, Utils $utils) {
- parent::__construct($db, 'passman_vaults');
+ parent::__construct($db, self::TABLE_NAME);
$this->utils = $utils;
}
/**
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
- * @return Vault[]
+ * @param int $vault_id
+ * @param string $user_id
+ * @return Entity[]
*/
- public function find($vault_id, $user_id) {
- $sql = 'SELECT * FROM `*PREFIX*passman_vaults` ' .
- 'WHERE `id`= ? and `user_id` = ?';
- return $this->findEntities($sql, [$vault_id, $user_id]);
+ public function find(int $vault_id, string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('id', $qb->createNamedParameter($vault_id, IQueryBuilder::PARAM_INT)))
+ ->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
}
+
/**
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
- * @return Vault
+ * @param string $vault_guid
+ * @param string $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function findByGuid($vault_guid, $user_id) {
- $sql = 'SELECT * FROM `*PREFIX*passman_vaults` ' .
- 'WHERE `guid`= ? and `user_id` = ?';
- return $this->findEntity($sql, [$vault_guid, $user_id]);
+ public function findByGuid(string $vault_guid, string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('guid', $qb->createNamedParameter($vault_guid, IQueryBuilder::PARAM_STR)))
+ ->andWhere($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntity($qb);
}
/**
- * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
- * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
- * @return Vault[]
+ * @param string $user_id
+ * @return Entity[]
*/
- public function findVaultsFromUser($userId){
- $sql = 'SELECT * FROM `*PREFIX*passman_vaults` ' .
- 'WHERE `user_id` = ? ';
- $params = [$userId];
- return $this->findEntities($sql, $params);
+ public function findVaultsFromUser(string $user_id) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from(self::TABLE_NAME)
+ ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($user_id, IQueryBuilder::PARAM_STR)));
+
+ return $this->findEntities($qb);
}
/**
* Creates a vault
- * @param $vault_name
- * @param $userId
- * @return Vault
+ *
+ * @param string $vault_name
+ * @param string $user_id
+ * @return Vault|Entity
*/
- public function create($vault_name, $userId){
+ public function create(string $vault_name, string $user_id) {
$vault = new Vault();
$vault->setName($vault_name);
- $vault->setUserId($userId);
+ $vault->setUserId($user_id);
$vault->setGuid($this->utils->GUID());
$vault->setCreated($this->utils->getTime());
$vault->setLastAccess(0);
@@ -87,45 +106,52 @@ class VaultMapper extends Mapper {
/**
* Update last access time of a vault
- * @param $vault_id
- * @param $user_id
+ *
+ * @param int $vault_id
+ * @param string $user_id
+ * @return Vault|Entity
*/
- public function setLastAccess($vault_id, $user_id){
+ public function setLastAccess(int $vault_id, string $user_id) {
$vault = new Vault();
$vault->setId($vault_id);
$vault->setUserId($user_id);
$vault->setLastAccess(Utils::getTime());
- $this->update($vault);
+ return $this->update($vault);
}
/**
* Update vault
+ *
* @param Vault $vault
+ * @return Vault|Entity
*/
- public function updateVault(Vault $vault){
- $this->update($vault);
+ public function updateVault(Vault $vault) {
+ return $this->update($vault);
}
/**
* Update the sharing key's
- * @param $vault_id
- * @param $privateKey
- * @param $publicKey
+ *
+ * @param int $vault_id
+ * @param string $privateKey
+ * @param string $publicKey
+ * @return Vault|Entity
*/
- public function updateSharingKeys($vault_id, $privateKey, $publicKey){
+ public function updateSharingKeys(int $vault_id, string $privateKey, string $publicKey) {
$vault = new Vault();
$vault->setId($vault_id);
$vault->setPrivateSharingKey($privateKey);
$vault->setPublicSharingKey($publicKey);
$vault->setSharingKeysGenerated($this->utils->getTime());
- $this->update($vault);
+ return $this->update($vault);
}
/**
* Delete a vault
+ *
* @param Vault $vault
*/
- public function deleteVault(Vault $vault){
+ public function deleteVault(Vault $vault) {
$this->delete($vault);
}
-} \ No newline at end of file
+}
diff --git a/lib/Notifier.php b/lib/Notifier.php
index c1a1c000..38b3a8a8 100644
--- a/lib/Notifier.php
+++ b/lib/Notifier.php
@@ -22,14 +22,16 @@
*/
namespace OCA\Passman;
+
+use OCP\L10N\IFactory;
use OCP\Notification\INotification;
use OCP\Notification\INotifier;
class Notifier implements INotifier {
- protected $factory;
+ protected IFactory $factory;
- public function __construct(\OCP\L10N\IFactory $factory) {
+ public function __construct(IFactory $factory) {
$this->factory = $factory;
}
@@ -37,7 +39,7 @@ class Notifier implements INotifier {
* @param INotification $notification
* @param string $languageCode The code of the language that should be used to prepare the notification
*/
-public function prepare(INotification $notification, string $languageCode): INotification {
+ public function prepare(INotification $notification, string $languageCode): INotification {
if ($notification->getApp() !== 'passman') {
// Not my app => throw
throw new \InvalidArgumentException();
@@ -50,7 +52,7 @@ public function prepare(INotification $notification, string $languageCode): INot
// Deal with known subjects
case 'credential_expired':
$notification->setParsedSubject(
- (string) $l->t('Your credential "%s" expired, click here to update the credential.', $notification->getSubjectParameters())
+ (string)$l->t('Your credential "%s" expired, click here to update the credential.', $notification->getSubjectParameters())
);
// Deal with the actions for a known subject
@@ -58,13 +60,13 @@ public function prepare(INotification $notification, string $languageCode): INot
switch ($action->getLabel()) {
case 'remind':
$action->setParsedLabel(
- (string) $l->t('Remind me later')
+ (string)$l->t('Remind me later')
);
break;
case 'ignore':
$action->setParsedLabel(
- (string) $l->t('Ignore')
+ (string)$l->t('Ignore')
);
break;
}
@@ -76,7 +78,7 @@ public function prepare(INotification $notification, string $languageCode): INot
case 'credential_shared':
$notification->setParsedSubject(
- (string) $l->t('%s shared "%s" with you. Click here to accept', $notification->getSubjectParameters())
+ (string)$l->t('%s shared "%s" with you. Click here to accept', $notification->getSubjectParameters())
);
// Deal with the actions for a known subject
@@ -84,7 +86,7 @@ public function prepare(INotification $notification, string $languageCode): INot
switch ($action->getLabel()) {
case 'decline':
$action->setParsedLabel(
- (string) $l->t('Decline')
+ (string)$l->t('Decline')
);
break;
}
@@ -95,13 +97,13 @@ public function prepare(INotification $notification, string $languageCode): INot
case 'credential_share_denied':
$notification->setParsedSubject(
- (string) $l->t('%s has declined your share request for "%s".', $notification->getSubjectParameters())
+ (string)$l->t('%s has declined your share request for "%s".', $notification->getSubjectParameters())
);
return $notification;
case 'credential_share_accepted':
$notification->setParsedSubject(
- (string) $l->t('%s has accepted your share request for "%s".', $notification->getSubjectParameters())
+ (string)$l->t('%s has accepted your share request for "%s".', $notification->getSubjectParameters())
);
return $notification;
default:
@@ -118,6 +120,7 @@ public function prepare(INotification $notification, string $languageCode): INot
public function getID(): string {
return 'passman';
}
+
/**
* Human readable name describing the notifier
*
diff --git a/lib/Search/Provider.php b/lib/Search/Provider.php
index 098d9400..45c13151 100644
--- a/lib/Search/Provider.php
+++ b/lib/Search/Provider.php
@@ -42,10 +42,10 @@ use OCP\Search\SearchResultEntry;
class Provider implements IProvider {
- private $l10n;
- private $urlGenerator;
- private $db;
- private $settings;
+ private IL10N $l10n;
+ private IURLGenerator $urlGenerator;
+ private IDBConnection $db;
+ private SettingsService $settings;
public function __construct(IL10N $l10n, IURLGenerator $urlGenerator, IDBConnection $db, SettingsService $settings) {
$this->l10n = $l10n;
diff --git a/lib/Service/CredentialRevisionService.php b/lib/Service/CredentialRevisionService.php
index 284fff74..035c4dd1 100644
--- a/lib/Service/CredentialRevisionService.php
+++ b/lib/Service/CredentialRevisionService.php
@@ -24,22 +24,23 @@
namespace OCA\Passman\Service;
use OCA\Passman\Db\CredentialRevision;
-use OCP\IConfig;
-use OCP\AppFramework\Db\DoesNotExistException;
-
use OCA\Passman\Db\CredentialRevisionMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\IConfig;
class CredentialRevisionService {
- private $credentialRevisionMapper;
- private $encryptService;
+ private CredentialRevisionMapper $credentialRevisionMapper;
+ private EncryptService $encryptService;
private $server_key;
- public function __construct(CredentialRevisionMapper $credentialRevisionMapper, EncryptService $encryptService) {
+ public function __construct(CredentialRevisionMapper $credentialRevisionMapper, EncryptService $encryptService, IConfig $config) {
$this->credentialRevisionMapper = $credentialRevisionMapper;
$this->encryptService = $encryptService;
- $this->server_key = \OC::$server->getConfig()->getSystemValue('passwordsalt', '');
+ $this->server_key = $config->getSystemValue('passwordsalt', '');
}
/**
@@ -50,6 +51,7 @@ class CredentialRevisionService {
* @param $credential_id
* @param $edited_by
* @return CredentialRevision
+ * @throws \Exception
*/
public function createRevision($credential, $userId, $credential_id, $edited_by) {
$credential = $this->encryptService->encryptCredential($credential);
@@ -59,11 +61,12 @@ class CredentialRevisionService {
/**
* Get revisions of a credential
*
- * @param $credential_id
- * @param null $user_id
- * @return CredentialRevision[]
+ * @param int $credential_id
+ * @param string|null $user_id
+ * @return Entity[]
+ * @throws \Exception
*/
- public function getRevisions($credential_id, $user_id = null) {
+ public function getRevisions(int $credential_id, string $user_id = null) {
$result = $this->credentialRevisionMapper->getRevisions($credential_id, $user_id);
foreach ($result as $index => $revision) {
$c = json_decode(base64_decode($revision->getCredentialData()), true);
@@ -74,12 +77,14 @@ class CredentialRevisionService {
}
/**
- *
- * @param $credential_id
- * @param null $user_id
- * @return CredentialRevision
+ * @param int $credential_id
+ * @param string|null $user_id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ * @throws \Exception
*/
- public function getRevision($credential_id, $user_id = null) {
+ public function getRevision(int $credential_id, string $user_id = null) {
$revision = $this->credentialRevisionMapper->getRevision($credential_id, $user_id);
$c = json_decode(base64_decode($revision->getCredentialData()), true);
$revision->setCredentialData($this->encryptService->decryptCredential($c));
@@ -89,11 +94,11 @@ class CredentialRevisionService {
/**
* Delete a revision
*
- * @param $revision_id
- * @param $user_id
+ * @param int $revision_id
+ * @param string $user_id
* @return CredentialRevision
*/
- public function deleteRevision($revision_id, $user_id) {
+ public function deleteRevision(int $revision_id, string $user_id) {
return $this->credentialRevisionMapper->deleteRevision($revision_id, $user_id);
}
@@ -101,7 +106,8 @@ class CredentialRevisionService {
* Update revision
*
* @param CredentialRevision $credentialRevision
- * @return CredentialRevision
+ * @return CredentialRevision|Entity
+ * @throws \Exception
*/
public function updateRevision(CredentialRevision $credentialRevision) {
$credential_data = $credentialRevision->getCredentialData();
@@ -110,4 +116,4 @@ class CredentialRevisionService {
$credentialRevision->setCredentialData($credential_data);
return $this->credentialRevisionMapper->update($credentialRevision);
}
-} \ No newline at end of file
+}
diff --git a/lib/Service/CredentialService.php b/lib/Service/CredentialService.php
index 7bd45917..6ba3b0d9 100644
--- a/lib/Service/CredentialService.php
+++ b/lib/Service/CredentialService.php
@@ -24,27 +24,29 @@
namespace OCA\Passman\Service;
use OCA\Passman\Db\Credential;
-use OCA\Passman\Db\CredentialRevision;
+use OCA\Passman\Db\CredentialMapper;
use OCA\Passman\Db\SharingACL;
use OCA\Passman\Db\SharingACLMapper;
-use OCP\IConfig;
use OCP\AppFramework\Db\DoesNotExistException;
-
-use OCA\Passman\Db\CredentialMapper;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\IConfig;
class CredentialService {
- private $credentialMapper;
- private $sharingACL;
- private $encryptService;
+ private CredentialMapper $credentialMapper;
+ private SharingACLMapper $sharingACL;
+ private ShareService $shareService;
+ private EncryptService $encryptService;
private $server_key;
- public function __construct(CredentialMapper $credentialMapper, SharingACLMapper $sharingACL, EncryptService $encryptService) {
+ public function __construct(CredentialMapper $credentialMapper, SharingACLMapper $sharingACL, ShareService $shareService, EncryptService $encryptService, IConfig $config) {
$this->credentialMapper = $credentialMapper;
$this->sharingACL = $sharingACL;
+ $this->shareService = $shareService;
$this->encryptService = $encryptService;
- $this->server_key = \OC::$server->getConfig()->getSystemValue('passwordsalt', '');
+ $this->server_key = $config->getSystemValue('passwordsalt', '');
}
/**
@@ -52,8 +54,9 @@ class CredentialService {
*
* @param array $credential
* @return Credential
+ * @throws \Exception
*/
- public function createCredential($credential) {
+ public function createCredential(array $credential) {
$credential = $this->encryptService->encryptCredential($credential);
return $this->credentialMapper->create($credential);
}
@@ -61,11 +64,13 @@ class CredentialService {
/**
* Update credential
*
- * @param $credential array | Credential
- * @param $useRawUser bool
- * @return Credential
+ * @param array $credential
+ * @param false $useRawUser
+ * @return Credential|Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function updateCredential($credential, $useRawUser = false) {
+ public function updateCredential(array $credential, $useRawUser = false) {
$credential = $this->encryptService->encryptCredential($credential);
return $this->credentialMapper->updateCredential($credential, $useRawUser);
}
@@ -73,32 +78,36 @@ class CredentialService {
/**
* Update credential
*
- * @param $credential Credential
- * @return Credential
+ * @param Credential $credential
+ * @return Credential|Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
public function upd(Credential $credential) {
$credential = $this->encryptService->encryptCredential($credential);
- return $this->credentialMapper->updateCredential($credential);
+ return $this->credentialMapper->updateCredential($credential->jsonSerialize(), false);
}
/**
* Delete credential
*
* @param Credential $credential
- * @return \OCP\AppFramework\Db\Entity
+ * @return Entity
*/
public function deleteCredential(Credential $credential) {
+ $this->shareService->unshareCredential($credential->getGuid());
return $this->credentialMapper->deleteCredential($credential);
}
/**
* Get credentials by vault id
*
- * @param $vault_id
- * @param $user_id
- * @return \OCA\Passman\Db\Credential[]
+ * @param int $vault_id
+ * @param string $user_id
+ * @return Entity[]
+ * @throws \Exception
*/
- public function getCredentialsByVaultId($vault_id, $user_id) {
+ public function getCredentialsByVaultId(int $vault_id, string $user_id) {
$credentials = $this->credentialMapper->getCredentialsByVaultId($vault_id, $user_id);
foreach ($credentials as $index => $credential) {
$credentials[$index] = $this->encryptService->decryptCredential($credential);
@@ -109,11 +118,11 @@ class CredentialService {
/**
* Get a random credential from given vault
*
- * @param $vault_id
- * @param $user_id
+ * @param int $vault_id
+ * @param string $user_id
* @return mixed
*/
- public function getRandomCredentialByVaultId($vault_id, $user_id) {
+ public function getRandomCredentialByVaultId(int $vault_id, string $user_id) {
$credentials = $this->credentialMapper->getRandomCredentialByVaultId($vault_id, $user_id);
foreach ($credentials as $index => $credential) {
$credentials[$index] = $this->encryptService->decryptCredential($credential);
@@ -124,10 +133,11 @@ class CredentialService {
/**
* Get expired credentials.
*
- * @param $timestamp
- * @return \OCA\Passman\Db\Credential[]
+ * @param int $timestamp
+ * @return Entity[]
+ * @throws \Exception
*/
- public function getExpiredCredentials($timestamp) {
+ public function getExpiredCredentials(int $timestamp) {
$credentials = $this->credentialMapper->getExpiredCredentials($timestamp);
foreach ($credentials as $index => $credential) {
$credentials[$index] = $this->encryptService->decryptCredential($credential);
@@ -138,12 +148,13 @@ class CredentialService {
/**
* Get a single credential.
*
- * @param $credential_id
- * @param $user_id
- * @return Credential
+ * @param int $credential_id
+ * @param string $user_id
+ * @return array|Credential
* @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialById($credential_id, $user_id) {
+ public function getCredentialById(int $credential_id, string $user_id) {
$credential = $this->credentialMapper->getCredentialById($credential_id);
if ($credential->getUserId() === $user_id) {
return $this->encryptService->decryptCredential($credential);
@@ -160,10 +171,12 @@ class CredentialService {
/**
* Get credential label by credential id.
*
- * @param $credential_id
- * @return Credential
+ * @param int $credential_id
+ * @return array|Credential
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialLabelById($credential_id) {
+ public function getCredentialLabelById(int $credential_id) {
$credential = $this->credentialMapper->getCredentialLabelById($credential_id);
return $this->encryptService->decryptCredential($credential);
}
@@ -171,12 +184,14 @@ class CredentialService {
/**
* Get credential by guid
*
- * @param $credential_guid
- * @param null $user_id
- * @return Credential
+ * @param string $credential_guid
+ * @param string|null $user_id
+ * @return array|Credential
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialByGUID($credential_guid, $user_id = null) {
+ public function getCredentialByGUID(string $credential_guid, string $user_id = null) {
$credential = $this->credentialMapper->getCredentialByGUID($credential_guid, $user_id);
return $this->encryptService->decryptCredential($credential);
}
-} \ No newline at end of file
+}
diff --git a/lib/Service/CronService.php b/lib/Service/CronService.php
index d84deffb..84ff65f5 100644
--- a/lib/Service/CronService.php
+++ b/lib/Service/CronService.php
@@ -23,21 +23,23 @@
namespace OCA\Passman\Service;
-use OCP\IConfig;
-use OCP\AppFramework\Db\DoesNotExistException;
-use OCP\ILogger;
-use OCA\Passman\Utility\Utils;
use OCA\Passman\Activity;
+use OCA\Passman\Utility\Utils;
+use OCP\DB\Exception;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
+use Psr\Log\LoggerInterface;
+
class CronService {
- private $credentialService;
- private $logger;
- private $utils;
- private $notificationService;
- private $activityService;
- private $db;
- public function __construct(CredentialService $credentialService, ILogger $logger, Utils $utils, NotificationService $notificationService, ActivityService $activityService, IDBConnection $db) {
+ private CredentialService $credentialService;
+ private LoggerInterface $logger;
+ private Utils $utils;
+ private NotificationService $notificationService;
+ private ActivityService $activityService;
+ private IDBConnection $db;
+
+ public function __construct(CredentialService $credentialService, LoggerInterface $logger, Utils $utils, NotificationService $notificationService, ActivityService $activityService, IDBConnection $db) {
$this->credentialService = $credentialService;
$this->logger = $logger;
$this->utils = $utils;
@@ -46,24 +48,29 @@ class CronService {
$this->db = $db;
}
-
public function expireCredentials() {
$expired_credentials = $this->credentialService->getExpiredCredentials($this->utils->getTime());
- foreach($expired_credentials as $credential){
+ foreach ($expired_credentials as $credential) {
$link = ''; // @TODO create direct link to credential
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from('notifications')
+ ->where($qb->expr()->eq('object_id', $qb->createNamedParameter($credential->getId(), IQueryBuilder::PARAM_INT)))
+ ->andWhere($qb->expr()->eq('subject', $qb->createNamedParameter('credential_expired', IQueryBuilder::PARAM_STR)));
- $sql = 'SELECT count(*) as `rows` from `*PREFIX*notifications` WHERE `subject`= \'credential_expired\' AND object_id=?';
- $id = $credential->getId();
- $result = $this->db->executeQuery($sql, array($id));
- $this->logger->debug($credential->getLabel() .' is expired, checking notifications!', array('app' => 'passman'));
- $notifications = intval($result->fetch()['rows']);
- if($notifications === 0) {
- $this->logger->debug($credential->getLabel() .' is expired, adding notification!', array('app' => 'passman'));
- $this->activityService->add(
- Activity::SUBJECT_ITEM_EXPIRED, array($credential->getLabel(), $credential->getUserId()),
- '', array(),
- $link, $credential->getUserId(), Activity::TYPE_ITEM_EXPIRED);
- $this->notificationService->credentialExpiredNotification($credential);
+ try {
+ $this->logger->debug($credential->getLabel() . ' is expired, checking notifications!', array('app' => 'passman'));
+ $notificationCount = $qb->execute()->rowCount();
+ if ($notificationCount === 0) {
+ $this->logger->debug($credential->getLabel() . ' is expired, adding notification!', array('app' => 'passman'));
+ $this->activityService->add(
+ Activity::SUBJECT_ITEM_EXPIRED, array($credential->getLabel(), $credential->getUserId()),
+ '', array(),
+ $link, $credential->getUserId(), Activity::TYPE_ITEM_EXPIRED);
+ $this->notificationService->credentialExpiredNotification($credential);
+ }
+ } catch (Exception $exception) {
+ $this->logger->error('Error while creating a notification: ' . $exception->getMessage(), array('app' => 'passman'));
}
}
}
diff --git a/lib/Service/DeleteVaultRequestService.php b/lib/Service/DeleteVaultRequestService.php
index 82820722..872111c5 100644
--- a/lib/Service/DeleteVaultRequestService.php
+++ b/lib/Service/DeleteVaultRequestService.php
@@ -25,13 +25,12 @@ namespace OCA\Passman\Service;
use OCA\Passman\Db\DeleteVaultRequest;
use OCA\Passman\Db\DeleteVaultRequestMapper;
-
-use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
class DeleteVaultRequestService {
- private $deleteVaultRequestMapper;
+ private DeleteVaultRequestMapper $deleteVaultRequestMapper;
public function __construct(DeleteVaultRequestMapper $deleteVaultRequestMapper) {
$this->deleteVaultRequestMapper = $deleteVaultRequestMapper;
@@ -41,16 +40,16 @@ class DeleteVaultRequestService {
* Create a new DeleteVaultRequest
*
* @param $request DeleteVaultRequest
- * @return \OCA\Passman\Db\DeleteVaultRequest
+ * @return DeleteVaultRequest
*/
public function createRequest(DeleteVaultRequest $request) {
return $this->deleteVaultRequestMapper->insert($request);
}
/**
- * Create a new DeleteVaultRequest
+ * Create a new DeleteVaultRequest
*
- * @return \OCA\Passman\Db\DeleteVaultRequest[]
+ * @return Entity[]
*/
public function getDeleteRequests() {
return $this->deleteVaultRequestMapper->getDeleteRequests();
@@ -59,13 +58,12 @@ class DeleteVaultRequestService {
/**
* Create a new DeleteVaultRequest
*
- * @param $vault_id integer The vault id
- * @return bool | DeleteVaultRequest
+ * @param $vault_guid string The vault guid
+ * @return bool | Entity
*/
- public function getDeleteRequestForVault($vault_guid) {
+ public function getDeleteRequestForVault(string $vault_guid) {
try {
- $result = $this->deleteVaultRequestMapper->getDeleteRequestsForVault($vault_guid);
- return $result;
+ return $this->deleteVaultRequestMapper->getDeleteRequestsForVault($vault_guid);
} catch (\Exception $e) {
return false;
}
@@ -75,11 +73,8 @@ class DeleteVaultRequestService {
* Create a new DeleteVaultRequest
*
* @param $req DeleteVaultRequest
- * @return bool | DeleteVaultRequest
*/
public function removeDeleteRequestForVault(DeleteVaultRequest $req) {
$this->deleteVaultRequestMapper->removeDeleteVaultRequest($req);
}
-
-
-} \ No newline at end of file
+}
diff --git a/lib/Service/EncryptService.php b/lib/Service/EncryptService.php
index 64284c4f..9c4f3063 100644
--- a/lib/Service/EncryptService.php
+++ b/lib/Service/EncryptService.php
@@ -26,9 +26,10 @@ namespace OCA\Passman\Service;
// Class copied from http://stackoverflow.com/questions/5089841/two-way-encryption-i-need-to-store-passwords-that-can-be-retrieved?answertab=votes#tab-top
// Upgraded to use openssl
-use Icewind\SMB\Exception\Exception;
use OCA\Passman\Db\Credential;
use OCA\Passman\Db\File;
+use OCP\AppFramework\Db\Entity;
+use OCP\IConfig;
/**
* A class to handle secure encryption and decryption of arbitrary data
@@ -84,14 +85,14 @@ class EncryptService {
protected $rounds = 100;
/**
- * Constructor!
- *
+ * EncryptService constructor.
* @param SettingsService $settings
+ * @param IConfig $config
*/
- public function __construct(SettingsService $settings) {
+ public function __construct(SettingsService $settings, IConfig $config) {
$this->cipher = $settings->getAppSetting('server_side_encryption', 'aes-256-cbc');
- $password_salt = \OC::$server->getConfig()->getSystemValue('passwordsalt', '');
- $secret = \OC::$server->getConfig()->getSystemValue('secret', '');
+ $password_salt = $config->getSystemValue('passwordsalt', '');
+ $secret = $config->getSystemValue('secret', '');
$this->server_key = $password_salt . $secret;
$this->rounds = $settings->getAppSetting('rounds_pbkdf2_stretching', 100);
}
@@ -279,8 +280,9 @@ class EncryptService {
/**
* Encrypt a credential
*
- * @param Credential|array $credential the credential to decrypt
+ * @param Credential|Entity|array $credential the credential to decrypt
* @return Credential|array
+ * @throws \Exception
*/
public function decryptCredential($credential) {
return $this->handleCredential($credential, EncryptService::OP_DECRYPT);
@@ -342,10 +344,10 @@ class EncryptService {
/**
* Encrypt a file
*
- * @param File|array $file
+ * @param File|array $file
* @return File|array
+ * @throws \Exception
*/
-
public function encryptFile($file) {
return $this->handleFile($file, EncryptService::OP_ENCRYPT);
}
@@ -353,10 +355,10 @@ class EncryptService {
/**
* Decrypt a file
*
- * @param File|array $file
- * @return File|array
+ * @param File|Entity|array $file
+ * @return array|File
+ * @throws \Exception
*/
-
public function decryptFile($file) {
return $this->handleFile($file, EncryptService::OP_DECRYPT);
}
@@ -396,4 +398,4 @@ class EncryptService {
return $file;
}
-} \ No newline at end of file
+}
diff --git a/lib/Service/FileService.php b/lib/Service/FileService.php
index 829b7927..6663797c 100644
--- a/lib/Service/FileService.php
+++ b/lib/Service/FileService.php
@@ -23,33 +23,38 @@
namespace OCA\Passman\Service;
+use Exception;
use OCA\Passman\Db\File;
-use OCP\IConfig;
-use OCP\AppFramework\Db\DoesNotExistException;
-
use OCA\Passman\Db\FileMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\IConfig;
class FileService {
- private $fileMapper;
- private $encryptService;
+ private FileMapper $fileMapper;
+ private EncryptService $encryptService;
private $server_key;
- public function __construct(FileMapper $fileMapper, EncryptService $encryptService) {
+ public function __construct(FileMapper $fileMapper, EncryptService $encryptService, IConfig $config) {
$this->fileMapper = $fileMapper;
$this->encryptService = $encryptService;
- $this->server_key = \OC::$server->getConfig()->getSystemValue('passwordsalt', '');
+ $this->server_key = $config->getSystemValue('passwordsalt', '');
}
/**
* Get a single file. This function also returns the file content.
*
- * @param $fileId
- * @param null $userId
- * @return \OCA\Passman\Db\File
+ * @param int $fileId
+ * @param string|null $userId
+ * @return array|File
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ * @throws Exception
*/
- public function getFile($fileId, $userId = null) {
+ public function getFile(int $fileId, string $userId = null) {
$file = $this->fileMapper->getFile($fileId, $userId);
return $this->encryptService->decryptFile($file);
}
@@ -57,11 +62,14 @@ class FileService {
/**
* Get a single file. This function also returns the file content.
*
- * @param $file_guid
- * @param null $userId
- * @return \OCA\Passman\Db\File
+ * @param string $file_guid
+ * @param string|null $userId
+ * @return array|File
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ * @throws Exception
*/
- public function getFileByGuid($file_guid, $userId = null) {
+ public function getFileByGuid(string $file_guid, string $userId = null) {
$file = $this->fileMapper->getFileByGuid($file_guid, $userId);
return $this->encryptService->decryptFile($file);
}
@@ -69,11 +77,14 @@ class FileService {
/**
* Upload a new file,
*
- * @param $file array
- * @param $userId
- * @return \OCA\Passman\Db\File
+ * @param array $file
+ * @param string $userId
+ * @return array|File
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ * @throws Exception
*/
- public function createFile($file, $userId) {
+ public function createFile(array $file, string $userId) {
$file = $this->encryptService->encryptFile($file);
$file = $this->fileMapper->create($file, $userId);
return $this->getFile($file->getId());
@@ -82,11 +93,11 @@ class FileService {
/**
* Delete file
*
- * @param $file_id
- * @param $userId
- * @return \OCA\Passman\Db\File
+ * @param int $file_id
+ * @param string $userId
+ * @return File|Entity
*/
- public function deleteFile($file_id, $userId) {
+ public function deleteFile(int $file_id, string $userId) {
return $this->fileMapper->deleteFile($file_id, $userId);
}
@@ -94,9 +105,10 @@ class FileService {
* Update file
*
* @param File $file
- * @return \OCA\Passman\Db\File
+ * @return File
+ * @throws Exception
*/
- public function updateFile($file) {
+ public function updateFile(File $file) {
$file = $this->encryptService->encryptFile($file);
return $this->fileMapper->updateFile($file);
}
@@ -106,13 +118,14 @@ class FileService {
*
* @param string $userId
* @return File[]
+ * @throws Exception
*/
- public function getFilesFromUser($userId){
+ public function getFilesFromUser(string $userId) {
$files = $this->fileMapper->getFilesFromUser($userId);
$results = array();
- foreach ($files as $file){
+ foreach ($files as $file) {
array_push($results, $this->encryptService->decryptFile($file));
}
return $results;
}
-} \ No newline at end of file
+}
diff --git a/lib/Service/NotificationService.php b/lib/Service/NotificationService.php
index 61b251bb..5b0d2d8d 100644
--- a/lib/Service/NotificationService.php
+++ b/lib/Service/NotificationService.php
@@ -23,32 +23,31 @@
namespace OCA\Passman\Service;
-use OCP\IConfig;
-use OCP\AppFramework\Db\DoesNotExistException;
-
-use OCA\Passman\Db\FileMapper;
+use OCP\IURLGenerator;
+use OCP\Notification\IManager;
class NotificationService {
- private $manager;
+ private IManager $manager;
+ private IURLGenerator $urlGenerator;
- public function __construct() {
- $this->manager = \OC::$server->getNotificationManager();
+ public function __construct(IManager $IManager, IURLGenerator $urlGenerator) {
+ $this->manager = $IManager;
+ $this->urlGenerator = $urlGenerator;
}
- function credentialExpiredNotification($credential){
- $urlGenerator = \OC::$server->getURLGenerator();
- $link = $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('','index.php/apps/passman/#/vault/'. $credential->getVaultId() .'/edit/'. $credential->getId()));
- $api = $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'index.php/apps/passman'));
+ function credentialExpiredNotification($credential) {
+ $link = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'index.php/apps/passman/#/vault/' . $credential->getVaultId() . '/edit/' . $credential->getId()));
+ $api = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'index.php/apps/passman'));
$notification = $this->manager->createNotification();
$remindAction = $notification->createAction();
$remindAction->setLabel('remind')
- ->setLink($api. '/api/internal/notifications/remind/'. $credential->getId() , 'POST');
+ ->setLink($api . '/api/internal/notifications/remind/' . $credential->getId(), 'POST');
$declineAction = $notification->createAction();
$declineAction->setLabel('ignore')
- ->setLink($api . '/api/internal/notifications/read/'. $credential->getId(), 'DELETE');
+ ->setLink($api . '/api/internal/notifications/read/' . $credential->getId(), 'DELETE');
$notification->setApp('passman')
->setUser($credential->getUserId())
@@ -63,15 +62,14 @@ class NotificationService {
}
- function credentialSharedNotification($data){
- $urlGenerator = \OC::$server->getURLGenerator();
- $link = $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('','index.php/apps/passman/#/'));
- $api = $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'index.php/apps/passman'));
+ function credentialSharedNotification($data) {
+ $link = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'index.php/apps/passman/#/'));
+ $api = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'index.php/apps/passman'));
$notification = $this->manager->createNotification();
$declineAction = $notification->createAction();
$declineAction->setLabel('decline')
- ->setLink($api . '/api/v2/sharing/decline/'. $data['req_id'], 'DELETE');
+ ->setLink($api . '/api/v2/sharing/decline/' . $data['req_id'], 'DELETE');
$notification->setApp('passman')
->setUser($data['target_user'])
@@ -85,7 +83,7 @@ class NotificationService {
}
- function credentialDeclinedSharedNotification($data){
+ function credentialDeclinedSharedNotification($data) {
$notification = $this->manager->createNotification();
$notification->setApp('passman')
->setUser($data['target_user'])
@@ -96,7 +94,7 @@ class NotificationService {
}
- function credentialAcceptedSharedNotification($data){
+ function credentialAcceptedSharedNotification($data) {
$notification = $this->manager->createNotification();
$notification->setApp('passman')
->setUser($data['target_user'])
@@ -106,4 +104,4 @@ class NotificationService {
$this->manager->notify($notification);
}
-} \ No newline at end of file
+}
diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php
index 8dec01db..922cb5c7 100644
--- a/lib/Service/ShareService.php
+++ b/lib/Service/ShareService.php
@@ -24,22 +24,26 @@
namespace OCA\Passman\Service;
-use Icewind\SMB\Share;
use OCA\Passman\Db\CredentialMapper;
-use OCA\Passman\Db\CredentialRevision;
use OCA\Passman\Db\ShareRequest;
use OCA\Passman\Db\ShareRequestMapper;
use OCA\Passman\Db\SharingACL;
use OCA\Passman\Db\SharingACLMapper;
use OCA\Passman\Utility\Utils;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\DB\Exception;
+use OCP\DB\IResult;
+use OCP\Notification\IManager;
class ShareService {
- private $sharingACL;
- private $shareRequest;
- private $credential;
- private $revisions;
- private $encryptService;
+ private SharingACLMapper $sharingACL;
+ private ShareRequestMapper $shareRequest;
+ private CredentialMapper $credential;
+ private CredentialRevisionService $revisions;
+ private EncryptService $encryptService;
+ private IManager $IManager;
public function __construct(
@@ -47,13 +51,15 @@ class ShareService {
ShareRequestMapper $shareRequest,
CredentialMapper $credentials,
CredentialRevisionService $revisions,
- EncryptService $encryptService
+ EncryptService $encryptService,
+ IManager $IManager
) {
$this->sharingACL = $sharingACL;
$this->shareRequest = $shareRequest;
$this->credential = $credentials;
$this->revisions = $revisions;
$this->encryptService = $encryptService;
+ $this->IManager = $IManager;
}
/**
@@ -89,6 +95,10 @@ class ShareService {
return $requests;
}
+ /**
+ * @param SharingACL $acl
+ * @return Entity
+ */
public function createACLEntry(SharingACL $acl) {
if ($acl->getCreated() === null) $acl->setCreated((new \DateTime())->getTimestamp());
return $this->sharingACL->createACLEntry($acl);
@@ -97,11 +107,14 @@ class ShareService {
/**
* Applies the given share, defaults to no expire
*
- * @param $item_guid
- * @param $target_vault_guid
- * @param $final_shared_key
+ * @param string $item_guid
+ * @param string $target_vault_guid
+ * @param string $final_shared_key
+ * @throws DoesNotExistException
+ * @throws Exception
+ * @throws MultipleObjectsReturnedException
*/
- public function applyShare($item_guid, $target_vault_guid, $final_shared_key) {
+ public function applyShare(string $item_guid, string $target_vault_guid, string $final_shared_key) {
$request = $this->shareRequest->getRequestByItemAndVaultGuid($item_guid, $target_vault_guid);
$permissions = $request->getPermissions();
@@ -123,21 +136,23 @@ class ShareService {
/**
* Obtains pending requests for the given user ID
*
- * @param $user_id
- * @return \OCA\Passman\Db\ShareRequest[]
+ * @param string $user_id
+ * @return Entity[]
*/
- public function getUserPendingRequests($user_id) {
+ public function getUserPendingRequests(string $user_id) {
return $this->shareRequest->getUserPendingRequests($user_id);
}
/**
* Get shared credentials from a user
*
- * @param $user_id
- * @param $vault_guid
- * @return \OCA\Passman\Db\SharingACL[]
+ * @param string $user_id
+ * @param string $vault_guid
+ * @return array
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getSharedItems($user_id, $vault_guid) {
+ public function getSharedItems(string $user_id, string $vault_guid) {
$entries = $this->sharingACL->getVaultEntries($user_id, $vault_guid);
$return = [];
@@ -159,15 +174,24 @@ class ShareService {
/**
* Gets the acl for a given item guid
*
- * @param $user_id
- * @param $item_guid
- * @return SharingACL
+ * @param string $user_id
+ * @param string $item_guid
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getACL($user_id, $item_guid) {
+ public function getACL(string $user_id, string $item_guid) {
return $this->sharingACL->getItemACL($user_id, $item_guid);
}
- public function getSharedItem($user_id, $item_guid) {
+ /**
+ * @param string $user_id
+ * @param string $item_guid
+ * @return array|mixed
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ */
+ public function getSharedItem(string $user_id, string $item_guid) {
$acl = $this->sharingACL->getItemACL($user_id, $item_guid);
// Check if the user can read the credential, probably unnecesary, but just to be sure
@@ -188,11 +212,14 @@ class ShareService {
/**
* Gets history from the given item checking the user's permissions to access it
*
- * @param $user_id
- * @param $item_guid
- * @return CredentialRevision[]
+ * @param string $user_id
+ * @param string $item_guid
+ * @return array|Entity[]
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
+ * @throws \Exception
*/
- public function getItemHistory($user_id, $item_guid) {
+ public function getItemHistory(string $user_id, string $item_guid) {
$acl = $this->sharingACL->getItemACL($user_id, $item_guid);
if (!$acl->hasPermission(SharingACL::READ | SharingACL::HISTORY)) return [];
@@ -204,7 +231,8 @@ class ShareService {
* Deletes a share request by the item ID
*
* @param ShareRequest $request
- * @return \PDOStatement
+ * @return int|IResult
+ * @throws Exception
*/
public function cleanItemRequestsForUser(ShareRequest $request) {
return $this->shareRequest->cleanItemRequestsForUser($request->getItemId(), $request->getTargetUserId());
@@ -213,21 +241,25 @@ class ShareService {
/**
* Get an share request by id
*
- * @param $id
- * @return ShareRequest
+ * @param int $id
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getShareRequestById($id) {
+ public function getShareRequestById(int $id) {
return $this->shareRequest->getShareRequestById($id);
}
/**
* Get an share request by $item_guid and $target_vault_guid
*
- * @param $item_guid
- * @param $target_vault_guid
- * @return ShareRequest
+ * @param string $item_guid
+ * @param string $target_vault_guid
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getRequestByGuid($item_guid, $target_vault_guid) {
+ public function getRequestByGuid(string $item_guid, string $target_vault_guid) {
return $this->shareRequest->getRequestByItemAndVaultGuid($item_guid, $target_vault_guid);
}
@@ -235,41 +267,48 @@ class ShareService {
* Get the access control list by item guid
*
* @param string $item_guid
- * @return \OCA\Passman\Db\SharingACL[]
+ * @return Entity[]
*/
- public function getCredentialAclList($item_guid) {
+ public function getCredentialAclList(string $item_guid) {
return $this->sharingACL->getCredentialAclList($item_guid);
}
- public function getCredentialPendingAclList($item_guid) {
+ /**
+ * @param string $item_guid
+ * @return Entity[]
+ * @throws Exception
+ */
+ public function getCredentialPendingAclList(string $item_guid) {
return $this->shareRequest->getRequestsByItemGuidGroupedByUser($item_guid);
}
/**
* Gets the ACL on the credential for the user
*
- * @param $user_id
- * @param $item_guid
- * @return SharingACL
+ * @param string $user_id
+ * @param string $item_guid
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function getCredentialAclForUser($user_id, $item_guid) {
+ public function getCredentialAclForUser(string $user_id, string $item_guid) {
return $this->sharingACL->getItemACL($user_id, $item_guid);
}
/**
* Get pending share requests by guid
*
- * @param string $item_guid
- * @return \OCA\Passman\Db\ShareRequest[]
+ * @param string $item_guid
+ * @return Entity[]
*/
- public function getShareRequestsByGuid($item_guid) {
+ public function getShareRequestsByGuid(string $item_guid) {
return $this->shareRequest->getShareRequestsByItemGuid($item_guid);
}
/**
* Get pending share requests by guid
*
- * @param ShareRequest $request
+ * @param ShareRequest $request
* @return ShareRequest
*/
public function deleteShareRequest(ShareRequest $request) {
@@ -279,8 +318,8 @@ class ShareService {
/**
* Delete ACL
*
- * @param ShareRequest $request
- * @return \OCA\Passman\Db\ShareRequest[]
+ * @param SharingACL|Entity $ACL
+ * @return SharingACL|Entity
*/
public function deleteShareACL(SharingACL $ACL) {
return $this->sharingACL->deleteShareACL($ACL);
@@ -290,12 +329,16 @@ class ShareService {
* Updates the given ACL entry
*
* @param SharingACL $sharingACL
- * @return SharingACL
+ * @return SharingACL|Entity
*/
public function updateCredentialACL(SharingACL $sharingACL) {
return $this->sharingACL->updateCredentialACL($sharingACL);
}
+ /**
+ * @param ShareRequest $shareRequest
+ * @return ShareRequest
+ */
public function updateCredentialShareRequest(ShareRequest $shareRequest) {
return $this->shareRequest->updateShareRequest($shareRequest);
}
@@ -304,15 +347,22 @@ class ShareService {
/**
* Get pending share requests by guid and uid
*
- * @param ShareRequest $request
- * @return \OCA\Passman\Db\ShareRequest[]
+ * @param string $item_guid
+ * @param string $user_id
+ * @return Entity[]
*/
- public function getPendingShareRequestsForCredential($item_guid, $user_id) {
+ public function getPendingShareRequestsForCredential(string $item_guid, string $user_id) {
return $this->shareRequest->getPendingShareRequests($item_guid, $user_id);
}
-
- public function updatePendingShareRequestsForCredential($item_guid, $user_id, $permissions) {
+ /**
+ * @param string $item_guid
+ * @param string $user_id
+ * @param int $permissions
+ * @return int|IResult
+ * @throws Exception
+ */
+ public function updatePendingShareRequestsForCredential(string $item_guid, string $user_id, int $permissions) {
return $this->shareRequest->updatePendingRequestPermissions($item_guid, $user_id, $permissions);
}
@@ -321,8 +371,7 @@ class ShareService {
* This will delete all ACL's and share requests.
* @param string $item_guid
*/
-
- public function unshareCredential($item_guid) {
+ public function unshareCredential(string $item_guid) {
$acl_list = $this->getCredentialAclList($item_guid);
$request_list = $this->getShareRequestsByGuid($item_guid);
foreach ($acl_list as $ACL) {
@@ -330,12 +379,11 @@ class ShareService {
}
foreach ($request_list as $request) {
$this->deleteShareRequest($request);
- $manager = \OC::$server->getNotificationManager();
- $notification = $manager->createNotification();
+ $notification = $this->IManager->createNotification();
$notification->setApp('passman')
->setObject('passman_share_request', $request->getId())
->setUser($request->getTargetUserId());
- $manager->markProcessed($notification);
+ $this->IManager->markProcessed($notification);
}
}
-} \ No newline at end of file
+}
diff --git a/lib/Service/VaultService.php b/lib/Service/VaultService.php
index 43e3a519..4c0d5c20 100644
--- a/lib/Service/VaultService.php
+++ b/lib/Service/VaultService.php
@@ -24,10 +24,10 @@
namespace OCA\Passman\Service;
use OCA\Passman\Db\Vault;
-use OCP\IConfig;
-use OCP\AppFramework\Db\DoesNotExistException;
-
use OCA\Passman\Db\VaultMapper;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
class VaultService {
@@ -41,7 +41,7 @@ class VaultService {
/**
* Get vaults from a user.
* @param $userId
- * @return \OCA\Passman\Db\Vault[]
+ * @return Entity[]
*/
public function getByUser($userId) {
return $this->vaultMapper->findVaultsFromUser($userId);
@@ -51,29 +51,29 @@ class VaultService {
* Get a single vault
* @param $vault_id
* @param $user_id
- * @return \OCA\Passman\Db\Vault[]
+ * @return Entity[]
*/
public function getById($vault_id, $user_id) {
- $vault = $this->vaultMapper->find($vault_id, $user_id);
- return $vault;
+ return $this->vaultMapper->find($vault_id, $user_id);
}
/**
* Get a single vault.
* @param $vault_guid
* @param $user_id
- * @return \OCA\Passman\Db\Vault
+ * @return Entity
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
public function getByGuid($vault_guid, $user_id) {
- $vault = $this->vaultMapper->findByGuid($vault_guid, $user_id);
- return $vault;
+ return $this->vaultMapper->findByGuid($vault_guid, $user_id);
}
/**
* Create a new vault.
* @param $vault_name
* @param $userId
- * @return \OCA\Passman\Db\Vault
+ * @return Vault
*/
public function createVault($vault_name, $userId) {
return $this->vaultMapper->create($vault_name, $userId);
@@ -82,6 +82,7 @@ class VaultService {
/**
* Update vault
* @param $vault
+ * @return Vault|Entity
*/
public function updateVault($vault) {
return $this->vaultMapper->updateVault($vault);
@@ -91,30 +92,34 @@ class VaultService {
* Update last access time of a vault.
* @param $vault_id
* @param $user_id
+ * @return Vault|Entity
*/
- public function setLastAccess($vault_id, $user_id){
+ public function setLastAccess($vault_id, $user_id) {
return $this->vaultMapper->setLastAccess($vault_id, $user_id);
}
/**
- * Uodate sharing keys of a vault.
+ * Update sharing keys of a vault.
* @param $vault_id
* @param $privateKey
* @param $publicKey
+ * @return Vault|Entity
*/
- public function updateSharingKeys($vault_id, $privateKey, $publicKey){
+ public function updateSharingKeys($vault_id, $privateKey, $publicKey) {
return $this->vaultMapper->updateSharingKeys($vault_id, $privateKey, $publicKey);
}
/**
* Delete a vault from user
- * @param string $vault_guid
- * @param string $user_id
+ * @param $vault_guid
+ * @param $user_id
+ * @throws DoesNotExistException
+ * @throws MultipleObjectsReturnedException
*/
- public function deleteVault($vault_guid, $user_id){
+ public function deleteVault($vault_guid, $user_id) {
$vault = $this->getByGuid($vault_guid, $user_id);
- if($vault instanceof Vault) {
+ if ($vault instanceof Vault) {
$this->vaultMapper->deleteVault($vault);
}
}
-} \ No newline at end of file
+}
diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php
new file mode 100644
index 00000000..2196dbb6
--- /dev/null
+++ b/lib/Settings/Admin.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Nextcloud - passman
+ *
+ * @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
+ * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Passman\Settings;
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Exception\GuzzleException;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\Settings\ISettings;
+
+class Admin implements ISettings {
+
+ protected IConfig $config;
+ private IL10N $l;
+ private IAppManager $appManager;
+
+ /**
+ * Admin constructor.
+ * @param IConfig $config
+ * @param IL10N $l
+ * @param IAppManager $appManager
+ */
+ public function __construct(IConfig $config, IL10N $l, IAppManager $appManager) {
+ $this->config = $config;
+ $this->l = $l;
+ $this->appManager = $appManager;
+ }
+
+ /**
+ * @return TemplateResponse
+ */
+ public function getForm(): TemplateResponse {
+ $checkVersion = $this->config->getAppValue('passman', 'check_version', '1') === '1';
+ $localVersion = $this->appManager->getAppInfo('passman')["version"];
+ $githubVersion = $this->l->t('Unable to get version info');
+ if ($checkVersion) {
+ // get latest master version
+ $version = false;
+
+ $url = 'https://raw.githubusercontent.com/nextcloud/passman/dist/appinfo/info.xml';
+ try {
+ $httpClient = new Client();
+ $response = $httpClient->request('get', $url);
+ $xml = $response->getBody()->getContents();
+ } catch (GuzzleException $e) {
+ $xml = false;
+ }
+
+ if ($xml) {
+ $data = simplexml_load_string($xml);
+
+ // libxml_disable_entity_loader is deprecated with php8, the vulnerability is disabled by default by libxml with php8
+ if (\PHP_VERSION_ID < 80000) {
+ $loadEntities = libxml_disable_entity_loader(true);
+ $data = simplexml_load_string($xml);
+ libxml_disable_entity_loader($loadEntities);
+ }
+
+ if ($data !== false) {
+ $version = (string)$data->version;
+ } else {
+ libxml_clear_errors();
+ }
+ }
+
+ if ($version !== false) {
+ $githubVersion = $version;
+ }
+ }
+ // $ciphers = openssl_get_cipher_methods();
+
+ return new TemplateResponse('passman', 'admin', [
+ 'localVersion' => $localVersion,
+ 'githubVersion' => $githubVersion,
+ 'checkVersion' => $checkVersion,
+ ], 'blank');
+ }
+
+ /**
+ * @return string
+ */
+ public function getSection(): string {
+ return 'additional';
+ }
+
+ /**
+ * @return int
+ */
+ public function getPriority(): int {
+ return 100;
+ }
+}
diff --git a/lib/Utility/Utils.php b/lib/Utility/Utils.php
index 095d6ac6..327af271 100644
--- a/lib/Utility/Utils.php
+++ b/lib/Utility/Utils.php
@@ -23,6 +23,8 @@
namespace OCA\Passman\Utility;
+use OCP\IUserManager;
+
class Utils {
/**
* Gets the unix epoch UTC timestamp
@@ -52,16 +54,21 @@ class Utils {
}
/**
- * @param $uid
+ * @param string $uid
+ * @param IUserManager $userManager
* @return string
*/
- public static function getNameByUid($uid){
- $um = \OC::$server->getUserManager();
- $u = $um->get($uid);
+ public static function getNameByUid(string $uid, IUserManager $userManager){
+ $u = $userManager->get($uid);
return $u->getDisplayName();
}
- public static function getDirContents($dir, &$results = array()){
+ /**
+ * @param string $dir
+ * @param array $results
+ * @return array|mixed
+ */
+ public static function getDirContents(string $dir, &$results = array()){
$files = scandir($dir);
foreach($files as $value){
@@ -75,4 +82,4 @@ class Utils {
}
return $results;
}
-} \ No newline at end of file
+}
diff --git a/migration/serversideencryption.php b/migration/serversideencryption.php
index 7ecc4371..a41e7c0c 100644
--- a/migration/serversideencryption.php
+++ b/migration/serversideencryption.php
@@ -29,10 +29,12 @@ use OCA\Passman\Service\CredentialRevisionService;
use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\EncryptService;
use OCA\Passman\Service\FileService;
+use OCP\DB\Exception;
+use OCP\IConfig;
use OCP\IDBConnection;
-use OCP\ILogger;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
+use Psr\Log\LoggerInterface;
class ServerSideEncryption implements IRepairStep {
@@ -46,7 +48,7 @@ class ServerSideEncryption implements IRepairStep {
/** @var string */
private $installedVersion;
- /** @var ILogger */
+ /** @var LoggerInterface */
private $logger;
/** @var CredentialService */
@@ -58,15 +60,15 @@ class ServerSideEncryption implements IRepairStep {
/** @var FileService */
private $fileService;
- public function __construct(EncryptService $encryptService, IDBConnection $db, ILogger $logger, CredentialService $credentialService, CredentialRevisionService $revisionService,
- FileService $fileService) {
+ public function __construct(EncryptService $encryptService, IDBConnection $db, LoggerInterface $logger, CredentialService $credentialService, CredentialRevisionService $revisionService,
+ FileService $fileService, IConfig $config) {
$this->encryptService = $encryptService;
$this->db = $db;
$this->logger = $logger;
$this->credentialService = $credentialService;
$this->revisionService = $revisionService;
$this->fileService = $fileService;
- $this->installedVersion = \OC::$server->getConfig()->getAppValue('passman', 'installed_version');
+ $this->installedVersion = $config->getAppValue('passman', 'installed_version');
}
public function getName() {
@@ -83,19 +85,30 @@ class ServerSideEncryption implements IRepairStep {
}
}
- private function fetchAll($sql){
- return $this->db->executeQuery($sql)->fetchAll();
+ /**
+ * KEEP THIS METHOD PRIVATE!!!
+ *
+ * @param string $table
+ * @return mixed[]
+ * @throws Exception
+ */
+ private function fetchAll(string $table) {
+ $qb = $this->db->getQueryBuilder();
+ $result = $qb->select('*')
+ ->from($table)
+ ->execute();
+ return $result->fetchAll();
}
private function encryptCredentials() {
- $credentials = $this->fetchAll('SELECT * FROM `*PREFIX*passman_credentials`');
+ $credentials = $this->fetchAll('passman_credentials');
foreach ($credentials as $credential) {
$this->credentialService->updateCredential($credential);
}
}
private function encryptRevisions() {
- $revisions = $this->fetchAll('SELECT * FROM `*PREFIX*passman_revisions`');
+ $revisions = $this->fetchAll('passman_revisions');
foreach ($revisions as $_revision) {
$revision = new CredentialRevision();
$revision->setId($_revision['id']);
@@ -110,7 +123,7 @@ class ServerSideEncryption implements IRepairStep {
}
private function encryptFiles() {
- $files = $this->fetchAll('SELECT * FROM `*PREFIX*passman_files`');
+ $files = $this->fetchAll('passman_files');
foreach ($files as $_file) {
$file = new File();
$file->setId($_file['id']);
diff --git a/sass/admin.scss b/sass/admin.scss
index 2eae188d..b15ba68a 100644
--- a/sass/admin.scss
+++ b/sass/admin.scss
@@ -8,8 +8,14 @@
input[type="text"]{
width: 350px;
}
+ .account_mover_selector {
+ width: 350px;
+ .select2-choice {
+ height: 34px;
+ }
+ }
}
#requests-table{
width: 100%;
}
-} \ No newline at end of file
+}
diff --git a/templates/part.admin.php b/templates/admin.php
index 1f583cf3..71b38e9d 100644
--- a/templates/part.admin.php
+++ b/templates/admin.php
@@ -1,58 +1,23 @@
<?php
/** @var \OCP\IL10N $l */
/** @var array $_ */
-use \OCP\App;
script('passman', 'settings-admin');
style('passman', 'admin');
style('passman', 'vendor/font-awesome/font-awesome.min');
-
-$checkVersion = OC::$server->getConfig()->getAppValue('passman', 'check_version', '1') === '1';
-$AppInstance = new App();
-$localVersion = $AppInstance->getAppInfo("passman")["version"];
-$githubVersion = $l->t('Unable to get version info');
-if ($checkVersion) {
- // get latest master version
- $version = false;
-
- $url = 'https://raw.githubusercontent.com/nextcloud/passman/master/appinfo/info.xml';
- try {
- $client = OC::$server->getHTTPClientService()->newClient();
- $response = $client->get($url);
- $xml = $response->getBody();
- } catch (\Exception $e) {
- $xml = false;
- }
-
- if ($xml) {
- $loadEntities = libxml_disable_entity_loader(true);
- $data = @simplexml_load_string($xml);
- libxml_disable_entity_loader($loadEntities);
- if ($data !== false) {
- $version = (string)$data->version;
- } else {
- libxml_clear_errors();
- }
- }
-
- if ($version !== false) {
- $githubVersion = $version;
- }
-}
-$ciphers = openssl_get_cipher_methods();
?>
<div id="passwordSharingSettings" class="followup section">
<h2><?php p($l->t('Passman Settings')); ?></h2>
<?php
- if ($checkVersion) {
- p($l->t('GitHub version:') . ' ' . $githubVersion);
+ if ($_['checkVersion']) {
+ p($l->t('GitHub version:') . ' ' . $_['githubVersion']);
print '<br />';
} ?>
- Local version: <?php p($localVersion); ?><br/>
+ Local version: <?php p($_['localVersion']); ?><br/>
<?php
- if ($checkVersion && version_compare($githubVersion, $localVersion) === 1) {
+ if ($_['checkVersion'] && version_compare($_['githubVersion'], $_['localVersion']) === 1) {
p($l->t('A newer version of Passman is available'));
}
?>
@@ -158,15 +123,16 @@ $ciphers = openssl_get_cipher_methods();
<table class="table">
<tr>
<td><?php p($l->t('Source account')); ?> </td>
- <td><input class="username-autocomplete" type="text" id="source_account" name="source_account"></td>
+ <td><input type="hidden" class="form-control account_mover_selector" id="source_account"></td>
</tr>
<tr>
<td><?php p($l->t('Destination account')); ?> </td>
- <td><input class="username-autocomplete" type="text" id="destination_account" name="destination_account"></td>
+ <td><input type="hidden" class="form-control account_mover_selector" id="destination_account"></td>
</tr>
</table>
<button class="success" id="move_credentials">Move</button>
- <span id="moveStatus" style="display: none;"><?php p($l->t('Credentials moved!')); ?></span>
+ <span id="moveStatusSucceeded" style="display: none;"><?php p($l->t('Credentials moved!')); ?></span>
+ <span id="moveStatusFailed" style="display: none;"><?php p($l->t('An error occurred!')); ?></span>
</div>
<div id="tabs-3">
diff --git a/templates/admin.settings.php b/templates/admin.settings.php
deleted file mode 100644
index b5280153..00000000
--- a/templates/admin.settings.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-namespace OCA\Passman;
-$tmpl = new \OCP\Template('passman', 'part.admin');
-return $tmpl->fetchPage(); \ No newline at end of file
diff --git a/templates/main.php b/templates/main.php
index 4bc649a3..7300e4c1 100644
--- a/templates/main.php
+++ b/templates/main.php
@@ -51,6 +51,7 @@ script('passman', 'app/filters/range');
script('passman', 'app/filters/propsfilter');
script('passman', 'app/filters/byte');
script('passman', 'app/filters/tagfilter');
+script('passman', 'app/filters/escapeHTML');
script('passman', 'app/filters/as');
script('passman', 'app/filters/credentialsearch');
script('passman', 'app/filters/toHHMMSS');
diff --git a/templates/views/partials/icon-picker.html b/templates/views/partials/icon-picker.html
index 318c0fe4..6373a1df 100644
--- a/templates/views/partials/icon-picker.html
+++ b/templates/views/partials/icon-picker.html
@@ -1,4 +1,4 @@
-<div class="cell icon-category-auth" ng-if="!credential.url && !credential.icon"></div>
+<div class="cell fa fa-lock" ng-if="!credential.url && !credential.icon"></div>
<div class="cell" ng-if="credential.url || credential.icon">
<span class="icon">
diff --git a/templates/views/show_vault.html b/templates/views/show_vault.html
index 9b5893e2..75c97869 100644
--- a/templates/views/show_vault.html
+++ b/templates/views/show_vault.html
@@ -145,11 +145,11 @@
<span class="close icon-close" ng-click="closeSelected()" alt="Close"></span>
<div class="sidebar">
- <span class="icon sidebar-icon" ng-if="selectedCredential.url || credential.icon">
+ <span class="icon sidebar-icon" ng-if="selectedCredential.url || selectedCredential.icon">
<credential-icon credential="selectedCredential"></credential-icon>
</span>
- <span class="icon sidebar-icon" ng-if="!selectedCredential.url && !credential.icon">
- <credential-icon credential="selectedCredential"></credential-icon>
+ <span class="icon sidebar-icon" ng-if="!selectedCredential.url && !selectedCredential.icon">
+ <i class="fa fa-lock fa-3x icon-image"></i>
</span>
<h2 class="sidebar-label">{{selectedCredential.label}}</h2>
</div>