diff --git a/js/app/controllers/credential.js b/js/app/controllers/credential.js
index 3c70736a..9d84f33c 100644
--- a/js/app/controllers/credential.js
+++ b/js/app/controllers/credential.js
@@ -118,6 +118,7 @@
VaultService.updateSharingKeys($scope.active_vault);
});
}
+ $scope.checkURLAction();
});
});
};
@@ -544,6 +545,24 @@
VaultService.clearVaultService();
});
+ $scope.$watch(function(){ return $location.search(); }, function(params){
+ $scope.checkURLAction();
+ });
+
+ $scope.checkURLAction = function () {
+ var search = $location.search();
+ if (search.show !== undefined && $scope.active_vault.credentials !== undefined &&
+ $scope.active_vault.credentials.length > 0) {
+ $scope.closeSelected();
+ $scope.active_vault.credentials.forEach(function(credential, index, myArray) {
+ if (credential.guid === search.show) {
+ $scope.selectCredential(credential);
+ return true;
+ }
+ });
+ }
+ };
+
$scope.clearState = function () {
$scope.delete_time = 0;
};
diff --git a/js/templates.js b/js/templates.js
index 0cf3ef7c..07eed1ea 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',
'
| {{ \'revision.of\' | translate}} {{revision.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} ({{revision.credential_data.label}}) {{ \'revision.edited.by\' | translate}} {{revision.edited_by}} |
| {{ \'no.revisions\' | translate}} |
');
}]);
-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',
' ');
}]);
-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',
'{{ \'label\' | translate }}
{{ \'compromised.warning\' | translate }}
{{ \'account\' | translate }}
{{ \'password\' | translate }}
{{\'email\' | translate}}
{{\'notes\' | translate}}
{{ \'files\' | translate}}
{{field.label}}
{{field.value.filename}} ({{field.value.size | bytes}})
{{ \'expire.time\' | translate }}
{{credential.expire_time * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
{{ \'changed\' | translate}}
{{credential.changed * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
{{ \'created\' | translate}}
{{credential.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}}
');
}]);
-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',
- '{{ \'compromised.warning\' | translate }}
');
+ '{{ \'compromised.warning\' | translate }}
');
}]);
-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',
- '
');
+ ' ');
}]);
-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',
- '| {{ \'file.name\' | translate }} | {{ \'upload.date\' | translate}} | {{ \'size\' | translate}} | {{ \'actions\' | translate}} |
|---|
| {{ file.filename || "empty" }} | {{file.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{file.size | bytes}} | |
');
+ '| {{ \'file.name\' | translate }} | {{ \'upload.date\' | translate}} | {{ \'size\' | translate}} | {{ \'actions\' | translate}} |
|---|
| {{ file.filename || "empty" }} | {{file.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{file.size | bytes}} | |
');
}]);
-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',
- '{{ \'current.qr\' | translate}}
| {{ \'type\' | translate}}: | {{storedCredential.otp.type}} |
| {{ \'label\' | translate}}: | {{storedCredential.otp.label}} |
| {{ \'issuer\' | translate}}: | {{storedCredential.otp.issuer}} |
| {{ \'secret\' | translate}}: | {{storedCredential.otp.secret}} |
| {{ \'otp\' | translate}}: | |
');
+ '{{ \'current.qr\' | translate}}
| {{ \'type\' | translate}}: | {{storedCredential.otp.type}} |
| {{ \'label\' | translate}}: | {{storedCredential.otp.label}} |
| {{ \'issuer\' | translate}}: | {{storedCredential.otp.issuer}} |
| {{ \'secret\' | translate}}: | {{storedCredential.otp.secret}} |
| {{ \'otp\' | translate}}: | |
');
}]);
-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',
- '{{ \'generation.settings\' | translate}} ');
+ '{{ \'generation.settings\' | translate}} ');
}]);
-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',
- '{{selectedExporter.description}}
');
+ '{{selectedExporter.description}}
');
}]);
-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',
- '{{ \'about.passman\' | translate}}
{{ \'version\' | translate}}: {{passman_version}}
{{ \'donate.support\' | translate}}
{{ \'bookmarklet\' | translate}}
{{ \'bookmarklet.info1\' | translate}}
{{ \'bookmarklet.info2\' | translate}}
');
+ '{{ \'about.passman\' | translate}}
{{ \'version\' | translate}}: {{passman_version}}
{{ \'donate.support\' | translate}}
{{ \'bookmarklet\' | translate}}
{{ \'bookmarklet.info1\' | translate}}
{{ \'bookmarklet.info2\' | translate}}
');
}]);
-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',
'{{ \'select.csv\' | translate}}
{{ \'skip.first.row\' | translate}}
{{ \'import.csv.label.req\' | translate}}
{{ \'upload.progress\' | translate}}
{{ \'first.five.lines\' | translate }}{{ \'assign.column\' | translate }}
{{ \'example.credential\' | translate}} ');
}]);
-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',
- '{{\'missing.importer\' | translate}} {{\'missing.importer.back\' | translate}}
{{ \'import.steps\' | translate }} {{ \'read.progress\' | translate}}
{{ \'upload.progress\' | translate}}
');
+ '{{\'missing.importer\' | translate}} {{\'missing.importer.back\' | translate}}
{{ \'import.steps\' | translate }} {{ \'read.progress\' | translate}}
{{ \'upload.progress\' | translate}}
');
}]);
-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',
- ' ');
+ ' ');
}]);
-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',
- '
');
+ ' ');
}]);
-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',
'{{ \'scan.result.msg\' | translate}}
| {{ \'label\' | translate}} | {{ \'score\' | translate}} | {{ \'password\' | translate}} | {{ \'action\' | translate}} |
| {{result.label}} | | | |
');
}]);
-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',
' | |
| {{ \'search.result.missing\' | translate}} |
{{\'cyphering\' | translate}}...
{{ \'uploading\' | translate}}...
| {{ \'user\' | translate}} | {{ \'crypto.time\' | translate}} |
| {{user.user}} | {{user.time}} s |
{{ \'crypto.total.time\' | translate}}: {{ calculate_total_time() }}
');
}]);
-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',
'');
}]);
-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',
- '
');
+ '
');
}]);
-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',
'{{ \'details\' | translate }} {{ \'hide.details\' | translate}}
{{message}}
{{ \'password.score\' | translate}}:
{{score.score}}
{{ \'cracking.times\' | translate}}
{{ \'cracking.time.100h\' | translate}}
{{ \'cracking.time.100h.desc\' | translate}}
{{score.crack_times_display.online_throttling_100_per_hour}}
{{ \'cracking.time.10s\' | translate}}
{{ \'cracking.time.10s.desc\' | translate}}
{{score.crack_times_display.online_no_throttling_10_per_second}}
{{ \'cracking.time.10ks\' | translate}}
{{ \'cracking.time.10ks.desc\' | translate}}
{{score.crack_times_display.offline_slow_hashing_1e4_per_second}}
{{ \'cracking.time.10Bs\' | translate}}
{{ \'cracking.time.10Bs.desc\' | translate}}
{{score.crack_times_display.offline_fast_hashing_1e10_per_second}}
{{ \'match.sequence\' | translate}}:
{{ \'match.sequence.link\' | translate}}
{{sequence.token}} |
| {{ \'pattern\' | translate}} | {{sequence.pattern}} |
| {{ \'matched.word\' | translate}} | {{sequence.matched_word}} |
| {{ \'dictionary.name\' | translate}} | {{sequence.dictionary_name}} |
| {{ \'rank\' | translate}} | {{sequence.rank}} |
| {{ \'reversed\' | translate}} | {{sequence.reversed}} |
| {{ \'guesses\' | translate}} | {{sequence.guesses}} |
| {{ \'base.guesses\' | translate}} | {{sequence.base_guesses}} |
| {{ \'uppercase.variations\' | translate}} | {{sequence.uppercase_variations}} |
| {{ \'leet.variations\' | translate}} | {{sequence.l33t_variations}} |
');
}]);
-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',
'');
}]);
-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',
' ');
}]);
-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',
'{{\'vault.hint.hello\' | translate}}{{\'vault.hint.hello.add\' | translate}}
{{ \'vault.hint.list.notags\' | translate}}
{{ \'vault.hint.list.nosearch\' | translate}} \'{{filterOptions.filterText}}\'
{{ \'vault.hint.list.nogood\' | translate}}
{{ \'vault.hint.list.nomedium\' | translate}}
{{ \'vault.hint.list.nobad\' | translate}}
{{ \'vault.hint.list.noexpired\' | translate}}
{{ \'vault.hint.list.nodeleted\' | translate}}
');
}]);
-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',
- '');
+ '');
}]);
-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',
- '- + Create a new vault
{{vault.name}} {{ \'delete.request.pending\' | translate}}
{{ \'created\' | translate}}: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{ \'last.access\' | translate}}: {{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} {{\'never\' | translate}}- {{ \'no.vaults\' | translate}}
- {{ \'go.back.vaults\' | translate }}
');
+ '- + Create a new vault
{{vault.name}} {{ \'delete.request.pending\' | translate}}
{{ \'created\' | translate}}: {{vault.created * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} | {{ \'last.access\' | translate}}: {{vault.last_access * 1000 | date:\'dd-MM-yyyy @ HH:mm:ss\'}} {{\'never\' | translate}}- {{ \'no.vaults\' | translate}}
- {{ \'go.back.vaults\' | translate }}
');
}]);
diff --git a/lib/Search/Provider.php b/lib/Search/Provider.php
index 0a7292aa..d4b0da97 100644
--- a/lib/Search/Provider.php
+++ b/lib/Search/Provider.php
@@ -24,6 +24,13 @@
namespace OCA\Passman\Search;
use OCA\Passman\AppInfo\Application;
+use OCA\Passman\Db\CredentialMapper;
+use OCA\Passman\Db\VaultMapper;
+use OCA\Passman\Service\VaultService;
+use OCA\Passman\Utility\Utils;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Db\MultipleObjectsReturnedException;
+use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
@@ -31,6 +38,7 @@ use OCP\Search\IProvider;
use OCP\Search\ISearchQuery;
use OCP\Search\SearchResult;
use OCP\Search\SearchResultEntry;
+use Safe\Exceptions\StringsException;
class Provider implements IProvider {
@@ -40,9 +48,12 @@ class Provider implements IProvider {
/** @var IURLGenerator */
private IURLGenerator $urlGenerator;
- public function __construct(IL10N $l10n, IURLGenerator $urlGenerator) {
+ private IDBConnection $db;
+
+ public function __construct(IL10N $l10n, IURLGenerator $urlGenerator, IDBConnection $db) {
$this->l10n = $l10n;
$this->urlGenerator = $urlGenerator;
+ $this->db = $db;
}
public function getId(): string {
@@ -63,16 +74,37 @@ class Provider implements IProvider {
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
+ $VaultService = new VaultService(new VaultMapper($this->db, new Utils()));
+ $Vaults = $VaultService->getByUser($user->getUID());
+ $CredentialMapper = new CredentialMapper($this->db, new Utils());
+
+ $searchResultEntries = [];
+
+ foreach ($Vaults as $Vault) {
+ try {
+ $Credentials = $CredentialMapper->getCredentialsByVaultId($Vault->getId(), $Vault->getUserId());
+
+ foreach ($Credentials as $Credential) {
+ if (strpos($Credential->getLabel(), $query->getTerm()) !== false) {
+ try {
+ $searchResultEntries[] = new SearchResultEntry(
+ $this->urlGenerator->imagePath(Application::APP_ID, 'app.svg'),
+ $Credential->getLabel(),
+ \Safe\sprintf("Part of Passman vault %s", $Vault->getName()),
+ $this->urlGenerator->linkToRoute('passman.page.index') . "#/vault/" . $Vault->getGuid() . "?show=" . $Credential->getGuid()
+ );
+ } catch (StringsException $e) {
+ }
+ }
+ }
+ } catch (DoesNotExistException $e) {
+ } catch (MultipleObjectsReturnedException $e) {
+ }
+ }
+
return SearchResult::complete(
$this->l10n->t(Application::APP_ID),
- [
- new SearchResultEntry(
- $this->urlGenerator->imagePath(Application::APP_ID, 'app.svg'),
- $this->l10n->t('Search in current page'),
- $this->l10n->t('This requires an already unlocked Passman vault'),
- '#?search=' . $query->getTerm()
- )
- ]
+ $searchResultEntries
);
}
}