Merge branch 'binsky08-nc22-ready'

This commit is contained in:
WolFi 2021-03-22 15:09:41 +01:00
commit 93cd59906b
No known key found for this signature in database
GPG key ID: 7D15585354D072FF
22 changed files with 671 additions and 234 deletions

View file

@ -1,36 +0,0 @@
<?php
/**
* Nextcloud - passman
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Sander Brand <brantje@gmail.com>
* @copyright Sander Brand 2016
*/
namespace OCA\Passman\AppInfo;
use OCP\Util;
use OCP\BackgroundJob;
use OCP\App;
use OCA\Passman\Notifier;
use OCA\Passman\Activity;
require_once __DIR__ . '/autoload.php';
$app = new \OCA\Passman\AppInfo\Application();
$app->registerNavigationEntry();
$app->registerPersonalPage();
$l = \OC::$server->getL10N('passman');
$manager = \OC::$server->getNotificationManager();
$manager->registerNotifierService(Notifier::class);
/**
* Loading translations
*
* The string has to match the app's folder name
*/
Util::addTranslations('passman');
\OCP\App::registerAdmin('passman', 'templates/admin.settings');

View file

@ -37,13 +37,12 @@ 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.0"/>
<php min-version="7.2"/>
<database>sqlite</database>
<database>pgsql</database>
<database min-version="5.5">mysql</database>
<lib>openssl</lib>
<nextcloud min-version="17" max-version="19"/>
<owncloud min-version="10" max-version="10"/>
<nextcloud min-version="20" max-version="22"/>
</dependencies>
<background-jobs>

View file

@ -30,14 +30,17 @@
"angular-translate": "2.9.0",
"angular-xeditable": "0.3.0",
"angular-datetime-picker": "",
"ng-clipboard": "1.5.10",
"ng-password-meter": "0.4.0",
"ng-clipboard": "1.0.2",
"ng-password-meter": "0.1.6",
"ng-tags-input": "3.1.1",
"papa-parse": "4.1.2",
"llqrcode": "0.0.2",
"sha": " 2.0.1",
"jssha": " 2.0.1",
"sjcl": " 1.0.8",
"ui-sortable": "0.19.0",
"ui-sortable": "1.0",
"zxcvbn": "4.4.2"
},
"resolutions": {
"angular": "1.5.8"
}
}

View file

@ -85,6 +85,7 @@ class CredentialController extends ApiController {
'username' => $username,
'password' => $password,
'url' => $url,
'icon' => $favicon,
'favicon' => $favicon,
'renew_interval' => $renew_interval,
'expire_time' => $expire_time,
@ -94,7 +95,6 @@ class CredentialController extends ApiController {
'otp' => $otp,
'hidden' => $hidden,
'compromised' => $compromised
);
$credential = $this->credentialService->createCredential($credential);
@ -353,4 +353,4 @@ class CredentialController extends ApiController {
$this->credentialRevisionService->updateRevision($revision);
return new JSONResponse(array());
}
}
}

View file

@ -119,6 +119,67 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* 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/>.
*
*/
.tab_header {
width: calc(100vw - 300px);
margin: 0 0 0;
list-style: none;
padding: 0; }
.tab_header li.tab:first-child {
margin-left: 0; }
.tab_header li.tab {
/*@include border-top-radius(2px);*/
float: left;
border-bottom-width: 0;
margin: 0;
padding: 10px 10px 10px 10px;
cursor: pointer;
border-right: 1px solid #eee;
-webkit-transition: background-color 250ms linear;
-moz-transition: background-color 250ms linear;
-o-transition: background-color 250ms linear;
-ms-transition: background-color 250ms linear;
transition: background-color 250ms linear; }
.tab_header li.tab .indicator {
display: none; }
.tab_header li.inactive {
background-color: #fff !important;
color: unset !important; }
.tab_header li.active .indicator {
display: inline-block;
position: absolute;
height: 7px;
left: 0;
right: 0;
bottom: -1px; }
.tab_container {
border: 1px solid #eee;
border-top-color: #0082c9;
border-bottom-width: 0;
clear: both;
padding: 0 1em; }
/**
* Nextcloud - passman
*
@ -143,7 +204,7 @@
.pw-gen {
overflow: hidden; }
.pw-gen input {
width: calc(100% - 80px) !important;
width: calc(100% - 76px) !important;
float: left;
background: #fff;
color: #555;
@ -181,6 +242,133 @@
border-top-right-radius: 3px;
background-clip: padding-box; }
/**
* Nextcloud - passman
*
* @copyright Copyright (c) 2016, Felix Nuesse (felix.nuesse@t-online.de)
* @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/>.
*
*/
.iconpicker-dialog {
border-radius: var(--border-radius-large) !important;
box-shadow: 0 0 30px var(--color-box-shadow);
z-index: 9999 !important; }
.iconpicker-dialog .ui-dialog {
border-radius: var(--border-radius-large);
box-shadow: 0 0 30px var(--color-box-shadow); }
.iconpicker-dialog .ui-widget-header {
background: none; }
.iconpicker-dialog .ui-icon-closethick {
background-position: inherit; }
.iconpicker-dialog .ui-button .ui-icon {
background-image: var(--icon-close-000); }
.iconpicker-dialog .ui-button-icon {
border: none !important; }
.iconpicker-dialog .ui-icon {
border: none !important; }
.iconpicker-dialog .ui-icon-closethick {
border: none !important; }
.iconpicker-dialog .ui-corner-all {
border: none !important; }
.iconpicker-dialog .ui-state-default {
background: white !important; }
.iconpicker-dialog .ui-button {
background: white !important; }
#iconPicker .iconList {
float: left;
width: 60%;
max-height: 310px;
overflow: auto; }
#iconPicker .iconList .icon {
padding: 10px;
cursor: pointer;
float: left; }
#iconPicker .iconList .icon img {
cursor: pointer; }
#iconPicker .iconModifier {
margin-left: 10px;
float: right;
width: calc(40% - 10px); }
#iconPicker .iconSearch {
width: 100%; }
#iconPicker .arrow {
cursor: pointer;
padding-left: 10px;
width: 10px;
float: left; }
#iconPicker .collapsible {
cursor: pointer;
padding-left: 10px;
text-align: left;
font-size: 15px; }
#iconPicker .content {
display: none; }
#iconPicker .content_show {
display: block; }
/**
* Nextcloud - passman
*
* @copyright Copyright (c) 2019, Felix Nuesse (felix.nuesse@t-online.de)
* @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/>.
*
*/
.shareincoming-dialog {
border-radius: var(--border-radius-large) !important;
box-shadow: 0 0 30px var(--color-box-shadow);
z-index: 9999 !important; }
.shareincoming-dialog .ui-dialog {
border-radius: var(--border-radius-large);
box-shadow: 0 0 30px var(--color-box-shadow); }
.shareincoming-dialog .ui-widget-header {
background: none !important; }
.shareincoming-dialog .ui-icon-closethick {
background-position: inherit; }
.shareincoming-dialog .ui-button .ui-icon {
background-image: var(--icon-close-000); }
.shareincoming-dialog .ui-button:hover .ui-icon {
background-image: var(--icon-close-000);
cursor: pointer !important; }
.shareincoming-dialog .ui-button-icon {
border: none !important; }
.shareincoming-dialog .ui-icon {
border: none !important; }
.shareincoming-dialog .ui-icon-closethick {
border: none !important; }
.shareincoming-dialog .ui-corner-all {
border: none !important; }
.shareincoming-dialog .ui-state-default {
background: white !important; }
.shareincoming-dialog .ui-button {
background: white !important; }
/**
* Nextcloud - passman
*
@ -218,7 +406,6 @@
.vault_wrapper {
margin: 0 auto auto auto;
transform: translate(-150px);
max-width: 420px;
-webkit-border-radius: 5px;
border-radius: 5px;
@ -300,6 +487,12 @@
.icon-image {
width: 16px; }
.angularjs-datetime-picker {
z-index: 1000; }
.link {
color: var(--color-primary); }
#app-sidebar {
height: auto; }
#app-sidebar .sidebar {
@ -314,10 +507,19 @@
float: right;
line-height: 44px; }
.vaultlist_sidebar_hidden {
width: 100vw !important;
margin-left: 0px !important; }
#app-content {
margin-left: 300px;
width: calc(100vw - 300px);
overflow-x: hidden; }
@media only screen and (max-width: 769px) {
#app-content {
width: 100vw; } }
@media only screen and (min-width: 770px) {
#app-content {
width: calc(100vw - 300px); } }
#app-content #app-content-wrapper {
min-height: 95%;
display: flex;
@ -336,10 +538,7 @@
display: inline-block;
font-weight: bold;
margin-top: 10px; }
@media screen and (max-width: 575px) {
#app-content #app-content-wrapper .title {
display: none; } }
@media screen and (min-width: 769px) and (max-width: 820px) {
@media screen and (max-width: 820px) {
#app-content #app-content-wrapper .title {
display: none; } }
#app-content #app-content-wrapper .breadcrumb {
@ -395,13 +594,12 @@
display: inline-block;
padding: 7px; }
#app-content #app-content-wrapper .searchboxContainer {
/*display: inline-block;*/
visibility: hidden;
display: none;
margin-right: 14px;
display: inline-block;
visibility: visible;
float: right; }
#app-content #app-content-wrapper .searchboxContainer .searchbox {
display: inline-block; }
display: inline-block;
width: calc(100% - 3px); }
#app-content #app-content-wrapper .searchboxContainer .searchclear {
color: #ccc;
cursor: pointer;
@ -418,19 +616,33 @@
background: #fff;
border: 1px solid #ddd;
padding: 5px;
width: calc(100% - 3px);
/*width: calc(100% - 3px);*/
box-shadow: 3px 3px 5px #888888;
-webkit-border-bottom-right-radius: 3px;
border-bottom-right-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
border-bottom-left-radius: 3px;
background-clip: padding-box; }
#app-content #app-content-wrapper .searchboxContainer .searchOptions input {
cursor: pointer; }
#app-content #app-content-wrapper .credential-table {
width: 100%; }
#app-content #app-content-wrapper .credential-table tr:hover {
background-color: whitesmoke; }
#app-content #app-content-wrapper .credential-table tr.selected {
background-color: #f8f8f8; }
#app-content #app-content-wrapper .credential-table tr .compromised {
background-color: #f74040; }
#app-content #app-content-wrapper .credential-table tr .compromised:hover {
background-color: #e10909; }
#app-content #app-content-wrapper .credential-table tr .compromised-list {
display: inline-block;
margin-left: 50px; }
#app-content #app-content-wrapper .credential-table tr .compromised-list .icon {
height: 18px; }
#app-content #app-content-wrapper .credential-table tr .compromised-list .text {
font-style: italic;
font-weight: bold; }
#app-content #app-content-wrapper .credential-table tr td {
cursor: pointer;
padding: 5px;
@ -532,6 +744,20 @@
display: block; }
#app-content #app-content-wrapper .edit_credential input[type="text"], #app-content #app-content-wrapper .edit_credential input[type="password"] {
width: 100%; }
#app-content #app-content-wrapper .edit_credential .compromised-button {
margin-top: 15px;
background-color: #e60000;
color: black; }
#app-content #app-content-wrapper .edit_credential .compromised-details {
margin-top: 15px;
display: flex; }
#app-content #app-content-wrapper .edit_credential .compromised-details .icon {
float: left;
height: 20px; }
#app-content #app-content-wrapper .edit_credential .compromised-details .text {
padding-left: 5px;
padding-right: 30px;
color: #e9322d; }
#app-content #app-content-wrapper .edit_credential .tags {
float: left; }
#app-content #app-content-wrapper .edit_credential .tags .tag {
@ -552,6 +778,8 @@
float: left; }
#app-content #app-content-wrapper .edit_credential .password_settings label .label.sm {
font-size: 12px; }
#app-content #app-content-wrapper .edit_credential .password_settings .password-settings-padding-left-fix {
padding-left: 0 !important; }
#app-content #app-content-wrapper .edit_credential .field-value .valueInput {
padding-right: 0; }
#app-content #app-content-wrapper .edit_credential .field-value .valueInput input {
@ -568,7 +796,7 @@
background-clip: padding-box; }
#app-content #app-content-wrapper .edit_credential .field-value .selectType {
padding-left: 0;
margin-left: -4px; }
margin-left: 0px; }
#app-content #app-content-wrapper .edit_credential .field-value .selectType select {
-webkit-border-bottom-left-radius: 0;
border-bottom-left-radius: 0;
@ -609,6 +837,8 @@
vertical-align: middle; }
#app-content #app-content-wrapper .edit_credential .otpText {
padding-right: 10px; }
#app-content #app-content-wrapper .edit_credential .import-selection select {
margin-left: 15px; }
#app-content #app-content-wrapper .main_list {
flex: 1;
float: left;
@ -617,6 +847,16 @@
width: 100%; }
#app-content #app-content-wrapper .main_list .share {
overflow: hidden; }
#app-content #app-content-wrapper .main_list .nopasswords {
margin-right: auto;
margin-left: auto;
margin-top: 10%;
text-align: center; }
#app-content #app-content-wrapper .main_list .belowList {
margin-right: auto;
margin-left: auto;
margin-top: 1%;
text-align: center; }
#app-content #app-content-wrapper .app_sidebar {
float: right;
padding: 10px;
@ -636,6 +876,17 @@
#app-content #app-content-wrapper .app_sidebar.item_selected {
height: 25%;
display: inline-block; }
#app-content #app-content-wrapper .app_sidebar .credential-data .compromised-details {
margin-top: 15px;
margin-bottom: 15px;
display: flex; }
#app-content #app-content-wrapper .app_sidebar .credential-data .compromised-details .icon {
float: left;
height: 20px; }
#app-content #app-content-wrapper .app_sidebar .credential-data .compromised-details .text {
padding-left: 5px;
padding-right: 30px;
color: #e9322d; }
#app-content #app-content-wrapper .app_sidebar .credential-data .row {
margin-bottom: 11px; }
#app-content #app-content-wrapper .app_sidebar .credential-data .tags {
@ -653,11 +904,11 @@
float: left; }
.credential_field .value {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 70%; }
max-width: 100%; }
.credential_field .tools {
margin-left: 10px;
margin-top: 8px;
overflow: hidden;
float: left; }
.credential_field .tools .cell {
@ -684,7 +935,7 @@
width: 120px;
margin-top: 30px;
margin-left: -60px;
top: 50%;
top: 30%;
left: 50%;
position: absolute; }
@ -736,9 +987,9 @@
background-color: #ff0000; }
.icon-label {
overflow: hidden; }
overflow: hidden;
display: flex; }
.icon-label input {
width: calc(100% - 45px) !important;
float: left;
background: #fff;
color: #555;
@ -747,7 +998,7 @@
border: 1px solid #ddd;
outline: none;
border-radius: 3px;
margin: 3px 3px 3px 0;
margin: 3px 0 3px 0;
padding: 7px 6px 5px;
font-size: 13px;
-webkit-border-bottom-left-radius: 0;
@ -757,13 +1008,10 @@
background-clip: padding-box; }
.icon-label .icon-picker {
float: left;
margin-top: 3px;
padding-top: 7px; }
margin-top: 3px; }
.icon-label .icon-picker .cell {
margin-top: 0px;
margin-left: -0px;
height: 32px;
padding: 7px 12px 2px 12px;
display: inline;
font-size: 14px;
border: 1px solid #ddd;
background-color: #eaeaea;
@ -776,22 +1024,6 @@
.icon-label .icon-picker .cell:hover {
color: #0066ff; }
#iconPicker .iconList {
float: left;
width: 60%;
max-height: 310px;
overflow: auto; }
#iconPicker .iconList .icon {
padding: 10px;
cursor: pointer;
float: left; }
#iconPicker .iconList .icon img {
cursor: pointer; }
#iconPicker .iconModifier {
margin-left: 10px;
float: right;
width: calc(40% - 10px); }
/**
* Nextcloud - passman
*
@ -820,8 +1052,13 @@
margin-left: 15px;
margin-right: 15px; }
.settings-container-label {
padding-left: 15px; }
#app-navigation > ul > li > a {
z-index: auto; }
#app-navigation > ul > li {
display: block; }
.nav-trashbin {
width: inherit !important;
@ -830,23 +1067,30 @@
background-color: #fff !important;
opacity: 1 !important;
z-index: 140; }
.nav-trashbin a.active {
background-image: var(--icon-delete-e9322d); }
.nav-trashbin a .fa {
margin-right: 15px; }
#taginput {
visibility: hidden;
display: none; }
#app-navigation .collapsible:hover .app-navigation-entry-bullet {
background: var(--color-primary) !important; }
#app-navigation a .selected {
opacity: 1 !important;
box-shadow: inset 4px 0 var(--color-primary) !important; }
#app-navigation li .app-navigation-entry-bullet-color {
background-color: var(--color-primary); }
#app-navigation li .bullet-color-red {
background-color: #ff0000; }
#app-navigation li .bullet-color-yellow {
background-color: #ebbb00; }
#app-navigation li .bullet-color-green {
background-color: #4db728; }
#app-navigation li .highlight-selected {
background-color: var(--color-primary); }
#app-navigation li .autocomplete {
position: relative; }
#app-navigation li a.taginput {
visibility: hidden;
display: none;
opacity: 1; }
#app-navigation li a {
overflow: visible; }
@ -854,8 +1098,12 @@
opacity: 1.0; }
#app-navigation li a tags-input li {
width: auto !important; }
#app-navigation > ul ul {
display: inherit !important; }
.hidden-list {
display: none !important; }
.icon-expired {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path d='M0 0h24v24H0z' fill='none'/><path d='M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z'/></svg>"); }
/**
* Nextcloud - passman
@ -878,6 +1126,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
.sharing_table .button {
min-height: 42px;
margin: 5px 0 0 0; }
.sharing_table td:first-child {
width: 55%; }
.sharing_table td:first-child tags-input .tags {
@ -895,6 +1146,8 @@
.share_credential > div {
margin-bottom: 10px; }
.shared_table .pending {
margin-right: 10px; }
.shared_table .fa-trash {
cursor: pointer; }
.shared_table .fa-trash:hover {
@ -921,11 +1174,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
.scan-result-table {
margin-top: 10px; }
.scan-result-table .score {
padding-left: 0px;
padding-right: 15px; }
.spacer-top-30 {
margin-top: 30px; }
.scan-result-table td {
vertical-align: top !important; }
.scan-result-table .score {
width: 55%;
padding-left: 0px;
padding-right: 15px; }
.scan-result-table .label-audit {
width: 15%; }
.detail_box {
border: 1px solid var(--color-border-dark);
margin-top: 25px;
padding: 5px; }
.error {
color: #ce3702; }
@ -939,6 +1203,8 @@
.tab_container.settings {
margin-bottom: 50px; }
.tab_container.settings textarea {
height: 300px; }
.import-steps {
padding-left: 16px;
@ -959,16 +1225,72 @@
text-align: left;
padding: 3px 5px; }
#app-settings-content:not(.ng-hide) {
display: inherit !important;
padding: 0;
transition: height 0.15s ease-out; }
/**
* Nextcloud - passman
*
* @copyright Copyright (c) 2019, Felix Nuesse (felix.nuesse@t-online.de)
* @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/>.
*
*/
.searchbox button {
position: relative !important; }
#app-settings-content.ng-hide {
.searchbox-settings {
position: relative;
top: 50%;
opacity: 0.6; }
.searchbox-settings:hover {
opacity: 1;
cursor: pointer; }
.custom-search-dialog {
border-radius: var(--border-radius-large) !important;
box-shadow: 0 0 30px var(--color-box-shadow);
z-index: 9999 !important; }
.custom-search-dialog .ui-dialog {
border-radius: var(--border-radius-large);
box-shadow: 0 0 30px var(--color-box-shadow); }
.custom-search-dialog .ui-widget-header {
background: none; }
.custom-search-dialog .ui-icon-closethick {
background-position: inherit; }
.custom-search-dialog .ui-button-icon {
border: none !important; }
.custom-search-dialog .ui-icon {
border: none !important; }
.custom-search-dialog .ui-button .ui-icon {
background-image: var(--icon-close-000); }
.custom-search-dialog .ui-icon-closethick {
border: none !important; }
.custom-search-dialog .ui-dialog-buttonpane.ui-helper-clearfix {
display: none; }
.app-passman {
overflow-x: hidden; }
.template-hidden {
display: none !important; }
.hide-animation {
display: inherit !important;
height: 0;
padding: 0;
transition: height 0.15s ease-in; }
transition: ease-in-out .15s; }
.hide-animation.ng-hide {
opacity: 0; }
.ui-dialog {
z-index: 9999; }
@ -978,18 +1300,16 @@
margin-right: 0 !important; }
#app-content #app-content-wrapper #passman-controls {
border-bottom: 1px solid #c9c9c9;
margin-top: 5px; }
border-bottom: 1px solid #c9c9c9; }
#passman-controls {
box-sizing: border-box;
position: fixed;
top: 45px;
margin: -45px 0 0;
right: 0;
left: 0;
border-bottom: 1px solid #c9c9c9;
padding: 0 !important;
margin: 0;
background-color: rgba(255, 255, 255, 0.95);
z-index: 50;
-webkit-user-select: none;
@ -997,11 +1317,16 @@
-ms-user-select: none;
user-select: none;
height: 44px !important; }
@media only screen and (max-width: 769px) {
#passman-controls .breadcrumb {
padding-left: 15px; } }
#passman-controls .breadcrumb .addCredential {
padding-top: 1px; }
@media only screen and (max-width: 768px) {
#passman-controls {
width: 100%; } }
@media only screen and (min-width: 768px) {
@media only screen and (min-width: 1024px) {
#app-navigation + #app-content #passman-controls {
left: 300px;
width: calc( 100% - 300px ) !important; } }

File diff suppressed because one or more lines are too long

View file

@ -67,6 +67,14 @@ header {
#content-wrapper {
padding-top: 0; }
.share-controller {
width: 100%; }
.share-controller .share-container {
margin-top: 50px;
margin-left: auto;
margin-right: auto;
width: 25%; }
.credential_container {
margin-top: 20px;
margin-bottom: 20px;
@ -83,6 +91,7 @@ header {
font-weight: bold; }
.credential_container button, .credential_container .text {
margin: 0 auto;
margin-bottom: 25px;
display: block; }
.credential_container button i, .credential_container .text i {
margin-right: 5px; }

View file

@ -1,6 +1,6 @@
{
"version": 3,
"mappings": "AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;ACpBH;;;;;;;;;;;;;;;;;;;;GAoBG;ACpBH;;;;;;;;;;;;;;;;;;;;GAoBG;AFIH,MAAO;EACL,OAAO,EAAE,IAAI;;AAGf,gBAAiB;EACf,WAAW,EAAE,CAAC;;AAGhB,qBAAqB;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;EEJzB,qBAAqB,EFKE,GAAG;EEJ1B,aAAa,EFIU,GAAG;EEH1B,eAAe,EAAE,WAAW;EAAG,qDAAqD;EFIpF,2BAAK;IACJ,UAAU,EAAE,MAAM;EAEnB,wBAAE;IACA,WAAW,EAAE,IAAI;EAEnB,yDAAa;IACX,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,KAAK;IACd,6DAAC;MACC,YAAY,EAAE,GAAG;;AAKvB,iBAAkB;EAChB,QAAQ,EAAE,MAAM;EAChB,iDAAc;IACZ,KAAK,EAAE,IAAI;EAEb,wBAAO;IACL,WAAW,EAAE,IAAI;IACjB,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,IAAI;IACX,8BAAM;MACJ,MAAM,EAAE,OAAO;MACf,YAAY,EAAE,GAAG;;AAIvB,KAAK;EACF,WAAW,EAAE,MAAM;EAClB,oBAAc;IACZ,SAAS,EAAE,KAAK;EAElB,QAAE;IACA,cAAc,EAAE,GAAG;IACnB,cAAc,EAAE,GAAG;;AAKvB,UAAK;EACH,gBAAgB,EAAE,wBAAuB;EACzC,OAAO,EAAE,GAAG;EACZ,SAAS,EAAE,IAAI;EACf,YAAY,EAAE,GAAG;EEpDnB,qBAAqB,EFqDI,GAAG;EEpD5B,aAAa,EFoDY,GAAG;EEnD5B,eAAe,EAAE,WAAW;EAAG,qDAAqD;AFqDpF,qBAAgB;EACd,YAAY,EAAE,GAAG;;AAGrB,OAAO;EACL,SAAS,EAAE,IAAI;EACf,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,MAAM",
"mappings": "AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;ACpBH;;;;;;;;;;;;;;;;;;;;GAoBG;ACpBH;;;;;;;;;;;;;;;;;;;;GAoBG;AFIH,MAAO;EACL,OAAO,EAAE,IAAI;;AAGf,gBAAiB;EACf,WAAW,EAAE,CAAC;;AAGhB,iBAAiB;EACf,KAAK,EAAE,IAAI;EACX,kCAAgB;IACd,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,IAAI;IAClB,KAAK,EAAE,GAAG;;AAId,qBAAqB;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;EEdzB,qBAAqB,EFeE,GAAG;EEd1B,aAAa,EFcU,GAAG;EEb1B,eAAe,EAAE,WAAW;EAAG,qDAAqD;EFcpF,2BAAK;IACJ,UAAU,EAAE,MAAM;EAEnB,wBAAE;IACA,WAAW,EAAE,IAAI;EAEnB,yDAAa;IACX,MAAM,EAAE,MAAM;IACd,aAAa,EAAE,IAAI;IACnB,OAAO,EAAE,KAAK;IACd,6DAAC;MACC,YAAY,EAAE,GAAG;;AAKvB,iBAAkB;EAChB,QAAQ,EAAE,MAAM;EAChB,iDAAc;IACZ,KAAK,EAAE,IAAI;EAEb,wBAAO;IACL,WAAW,EAAE,IAAI;IACjB,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,IAAI;IACX,8BAAM;MACJ,MAAM,EAAE,OAAO;MACf,YAAY,EAAE,GAAG;;AAIvB,KAAK;EACF,WAAW,EAAE,MAAM;EAClB,oBAAc;IACZ,SAAS,EAAE,KAAK;EAElB,QAAE;IACA,cAAc,EAAE,GAAG;IACnB,cAAc,EAAE,GAAG;;AAKvB,UAAK;EACH,gBAAgB,EAAE,wBAAuB;EACzC,OAAO,EAAE,GAAG;EACZ,SAAS,EAAE,IAAI;EACf,YAAY,EAAE,GAAG;EE/DnB,qBAAqB,EFgEI,GAAG;EE/D5B,aAAa,EF+DY,GAAG;EE9D5B,eAAe,EAAE,WAAW;EAAG,qDAAqD;AFgEpF,qBAAgB;EACd,YAAY,EAAE,GAAG;;AAGrB,OAAO;EACL,SAAS,EAAE,IAAI;EACf,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,MAAM",
"sources": ["../sass/public-page.scss","../sass/variables.scss","../sass/mixins.scss"],
"names": [],
"file": "public-page.css"

View file

@ -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;
};

View file

@ -41,7 +41,7 @@
if (scope.tooltip) {
jQuery(el).attr('title', scope.tooltip);
jQuery(el).tooltip();
jQuery(el).attr('title', scope.tooltip).tooltip('fixTitle');
jQuery(el).attr('data-original-title', scope.tooltip);
jQuery('.tooltip-inner').text(scope.tooltip); // Dirty hack
if (jQuery(el).is(':visible')) {
//$(el).tooltip('show')
@ -52,4 +52,4 @@
}
};
}]);
}());
}());

View file

@ -94,6 +94,7 @@ $(document).ready(function () {
$('#passman_https_check').prop('checked', (settings.getKey('https_check').toString().toLowerCase() === '1'));
$('#passman_disable_contextmenu').prop('checked', (settings.getKey('disable_contextmenu').toString().toLowerCase() === '1'));
$('#passman_disable_debugger').prop('checked', (settings.getKey('disable_debugger').toString().toLowerCase() === '1'));
$('#passman_enable_global_search').prop('checked', (settings.getKey('enable_global_search').toString().toLowerCase() === '1'));
$('#vault_key_strength').val(settings.getKey('vault_key_strength'));
@ -113,6 +114,10 @@ $(document).ready(function () {
settings.setAdminKey('disable_debugger', ($(this).is(":checked")) ? 1 : 0);
});
$('#passman_enable_global_search').change(function () {
settings.setAdminKey('enable_global_search', ($(this).is(":checked")) ? 1 : 0);
});
$('#passman_sharing_enabled').change(function () {
settings.setAdminKey('user_sharing_enabled', ($(this).is(":checked")) ? 1 : 0);
});

File diff suppressed because one or more lines are too long

View file

@ -24,110 +24,105 @@
namespace OCA\Passman\AppInfo;
use OC\Files\View;
use OCA\Passman\Controller\CredentialController;
use OCA\Passman\Controller\PageController;
use OC\ServerContainer;
use OCA\Passman\Controller\ShareController;
use OCA\Passman\Controller\VaultController;
use OCA\Passman\Middleware\APIMiddleware;
use OCA\Passman\Middleware\ShareMiddleware;
use OCA\Passman\Notifier;
use OCA\Passman\Search\Provider;
use OCA\Passman\Service\ActivityService;
use OCA\Passman\Service\CronService;
use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\ShareService;
use OCA\Passman\Service\CronService;
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\Utils;
use OCA\Passman\Service\NotificationService;
Use OCA\Passman\Service\SettingsService;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\ILogger;
use OCP\Notification\IManager;
use OCP\Util;
use Psr\Container\ContainerInterface;
class Application extends App implements IBootstrap {
public const APP_ID = 'passman';
class Application extends App {
public function __construct() {
parent::__construct('passman');
$container = $this->getContainer();
// Allow automatic DI for the View, until we migrated to Nodes API
$container->registerService(View::class, function () {
parent::__construct(self::APP_ID);
}
public function register(IRegistrationContext $context): void {
$this->registerNavigationEntry();
// $this->registerPersonalPage();
$context->registerEventListener(
BeforeUserDeletedEvent::class,
UserDeletedListener::class
);
$context->registerSearchProvider(Provider::class);
$context->registerService(View::class, function () {
return new View('');
}, false);
$container->registerService('isCLI', function () {
$context->registerService('isCLI', function () {
return \OC::$CLI;
});
/**
* Middleware
*/
$container->registerService('ShareMiddleware', function ($c) {
return new ShareMiddleware($c->query('SettingsService'));
});
$container->registerMiddleware('ShareMiddleware');
$context->registerMiddleware(ShareMiddleware::class);
$context->registerMiddleware(APIMiddleware::class);
/**
* Controllers
*/
$container->registerService('ShareController', function ($c) {
$container = $this->getContainer();
$server = $container->getServer();
$context->registerService('ShareController', function (ContainerInterface $c) {
$server = $this->getContainer()->getServer();
return new ShareController(
$c->query('AppName'),
$c->query('Request'),
$c->get('AppName'),
$c->get('Request'),
$server->getUserSession()->getUser(),
$server->getGroupManager(),
$server->getUserManager(),
$c->query('ActivityService'),
$c->query('VaultService'),
$c->query('ShareService'),
$c->query('CredentialService'),
$c->query('NotificationService'),
$c->query('FileService'),
$c->query('SettingsService')
$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)
);
});
/** Cron **/
$container->registerService('CronService', function ($c) {
$context->registerService('CronService', function (ContainerInterface $c) {
return new CronService(
$c->query('CredentialService'),
$c->query('Logger'),
$c->query('Utils'),
$c->query('NotificationService'),
$c->query('ActivityService'),
$c->query('IDBConnection')
$c->get(CredentialService::class),
$c->get(ILogger::class),
$c->get(Utils::class),
$c->get(NotificationService::class),
$c->get(ActivityService::class),
$c->get(IDBConnection::class)
);
});
$container->registerService('Db', function () {
return new Db();
$context->registerService('Logger', function (ContainerInterface $c) {
return $c->get(ServerContainer::class)->getLogger();
});
}
$container->registerService('Logger', function ($c) {
return $c->query('ServerContainer')->getLogger();
});
public function boot(IBootContext $context): void {
$l = \OC::$server->getL10N(self::APP_ID);
$container->registerMiddleware('APIMiddleware');
/** @var IManager $manager */
$manager = $context->getAppContainer()->get(IManager::class);
$manager->registerNotifierService(Notifier::class);
// Aliases for the controllers so we can use the automatic DI
$container->registerAlias('CredentialController', CredentialController::class);
$container->registerAlias('PageController', PageController::class);
$container->registerAlias('VaultController', VaultController::class);
$container->registerAlias('VaultController', VaultController::class);
$container->registerAlias('CredentialService', CredentialService::class);
$container->registerAlias('NotificationService', NotificationService::class);
$container->registerAlias('ActivityService', ActivityService::class);
$container->registerAlias('VaultService', VaultService::class);
$container->registerAlias('FileService', FileService::class);
$container->registerAlias('ShareService', ShareService::class);
$container->registerAlias('Utils', Utils::class);
$container->registerAlias('IDBConnection', IDBConnection::class);
$container->registerAlias('IConfig', IConfig::class);
$container->registerAlias('SettingsService', SettingsService::class);
$container->registerAlias('APIMiddleware', APIMiddleware::class);
Util::addTranslations(self::APP_ID);
\OCP\App::registerAdmin(self::APP_ID, 'templates/admin.settings');
}
/**
@ -135,7 +130,6 @@ class Application extends App {
*/
public function registerNavigationEntry() {
$c = $this->getContainer();
/** @var \OCP\IServerContainer $server */
$server = $c->getServer();
$navigationEntry = function () use ($c, $server) {
return [
@ -155,4 +149,4 @@ class Application extends App {
public function registerPersonalPage() {
\OCP\App::registerPersonal($this->getContainer()->getAppName(), 'personal');
}
}
}

110
lib/Search/Provider.php Normal file
View file

@ -0,0 +1,110 @@
<?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\Search;
use OCA\Passman\AppInfo\Application;
use OCA\Passman\Db\CredentialMapper;
use OCA\Passman\Db\VaultMapper;
use OCA\Passman\Service\SettingsService;
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;
use OCP\Search\IProvider;
use OCP\Search\ISearchQuery;
use OCP\Search\SearchResult;
use OCP\Search\SearchResultEntry;
class Provider implements IProvider {
private $l10n;
private $urlGenerator;
private $db;
private $settings;
public function __construct(IL10N $l10n, IURLGenerator $urlGenerator, IDBConnection $db, SettingsService $settings) {
$this->l10n = $l10n;
$this->urlGenerator = $urlGenerator;
$this->db = $db;
$this->settings = $settings;
}
public function getId(): string {
return Application::APP_ID;
}
public function getName(): string {
return $this->l10n->t('Passman');
}
public function getOrder(string $route, array $routeParameters): int {
if (strpos($route, Application::APP_ID . '.') === 0) {
// Active app, prefer my results
return -1;
}
return 25;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
$searchResultEntries = [];
if ($this->settings->getAppSetting('enable_global_search', 0) === 1) {
$VaultService = new VaultService(new VaultMapper($this->db, new Utils()));
$Vaults = $VaultService->getByUser($user->getUID());
$CredentialMapper = new CredentialMapper($this->db, new Utils());
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(),
\sprintf("Part of Passman vault %s", $Vault->getName()),
$this->urlGenerator->linkToRoute('passman.page.index') . "#/vault/" . $Vault->getGuid() . "?show=" . $Credential->getGuid()
);
} catch (\Exception $e) {
}
}
}
} catch (DoesNotExistException $e) {
} catch (MultipleObjectsReturnedException $e) {
}
}
}
return SearchResult::complete(
$this->l10n->t(Application::APP_ID),
$searchResultEntries
);
}
}

View file

@ -40,6 +40,7 @@ class SettingsService {
'check_version',
'https_check',
'disable_contextmenu',
'enable_global_search',
'settings_loaded'
);
@ -57,6 +58,7 @@ class SettingsService {
'server_side_encryption' => $this->config->getAppValue('passman', 'server_side_encryption', 'aes-256-cbc'),
'rounds_pbkdf2_stretching' => $this->config->getAppValue('passman', 'rounds_pbkdf2_stretching', 100),
'disable_debugger' => $this->config->getAppValue('passman', 'disable_debugger', 1),
'enable_global_search' => $this->config->getAppValue('passman', 'enable_global_search', 0),
'settings_loaded' => 1
);
}
@ -118,4 +120,4 @@ class SettingsService {
$value = intval($this->getAppSetting($setting, false));
return ($value === 1);
}
}
}

View file

@ -6,27 +6,27 @@
},
"dependencies": {
"grunt": "~1.0.3",
"grunt-cli": "~1.2.0",
"grunt-contrib-clean": "^1.0.0",
"grunt-cli": "^1.3.2",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-cssmin": "^1.0.2",
"grunt-contrib-jshint": "^0.12.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-sass": "^1.0.0",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-html2js": "^0.3.6",
"grunt-karma": "^2.0.0",
"grunt-mkdir": "^1.0.0",
"grunt-replace": "^1.0.1",
"grunt-contrib-cssmin": "^4.0.0",
"grunt-contrib-jshint": "^3.0.0",
"grunt-contrib-nodeunit": "^2.1.0",
"grunt-contrib-sass": "^2.0.0",
"grunt-contrib-uglify": "^5.0.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-html2js": "^0.8.0",
"grunt-karma": "^4.0.0",
"grunt-mkdir": "^1.1.0",
"grunt-replace": "^2.0.1",
"html-minifier": "^3.0.2",
"jasmine-core": "2.5.2",
"jshint-stylish": "^2.2.1",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-firefox-launcher": "^1.0.0",
"karma-jasmine": "^1.0.2",
"karma": "^6.2.0",
"karma-chrome-launcher": "^3.1.0",
"karma-firefox-launcher": "^2.1.0",
"karma-jasmine": "^4.0.1",
"karma-requirejs": "^1.1.0",
"karma-verbose-reporter": "0.0.3",
"requirejs": "^2.3.2"

View file

@ -97,7 +97,7 @@
width: 100%;
}
}
@media only screen and (min-width: 768px){
@media only screen and (min-width: 1024px){
#app-navigation+#app-content #passman-controls {
left: 300px;
width: calc( 100% - 300px ) !important;
@ -134,4 +134,4 @@ input[type="checkbox"]{
.ui-button.ui-widget{
min-height: unset !important;
}
}

View file

@ -109,10 +109,7 @@
display: inline-block;
font-weight: bold;
margin-top: 10px;
@media screen and (max-width: 575px) {
display: none;
}
@media screen and (min-width: 769px) and (max-width: 820px) {
@media screen and (max-width: 820px) {
display: none;
}
}
@ -174,13 +171,12 @@
}
.searchboxContainer {
/*display: inline-block;*/
visibility: hidden;
display: none;
margin-right: 14px;
display: inline-block;
visibility: visible;
float: right;
.searchbox {
display: inline-block;
width: calc(100% - 3px);
}
.searchclear {
color: #ccc;
@ -199,9 +195,12 @@
background: #fff;
border: 1px solid #ddd;
padding: 5px;
width: calc(100% - 3px);
/*width: calc(100% - 3px);*/
box-shadow: 3px 3px 5px #888888;
@include border-bottom-radius(3px);
input {
cursor: pointer;
}
}
}
@ -730,4 +729,4 @@
color: rgb(0, 102, 255);
}
}
}
}

View file

@ -1,7 +1,7 @@
/**
* Nextcloud - passman
*
* @copyright Copyright (c) 2016, Felix Nüsse (felix.nuesse@t-online.de)
* @copyright Copyright (c) 2016, Felix Nuesse (felix.nuesse@t-online.de)
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
@ -93,4 +93,4 @@
.content_show {
display: block;
}
}
}

View file

@ -1,7 +1,7 @@
/**
* Nextcloud - passman
*
* @copyright Copyright (c) 2019, Felix Nüsse (felix.nuesse@t-online.de)
* @copyright Copyright (c) 2019, Felix Nuesse (felix.nuesse@t-online.de)
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify

View file

@ -1,7 +1,7 @@
/**
* Nextcloud - passman
*
* @copyright Copyright (c) 2019, Felix Nüsse (felix.nuesse@t-online.de)
* @copyright Copyright (c) 2019, Felix Nuesse (felix.nuesse@t-online.de)
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify

View file

@ -105,6 +105,14 @@ $ciphers = openssl_get_cipher_methods();
<?php p($l->t('Disable JavaScript debugger')); ?>
</label>
</p>
<p>
<input type="checkbox" name="passman_enable_global_search"
id="passman_enable_global_search" class="checkbox"
value="0"/>
<label for="passman_enable_global_search">
<?php p($l->t('Enable global search')); ?>
</label>
</p>
<p>
<label for="vault_key_strength">Minimum vault key
strength:</label>