mirror of
https://github.com/nextcloud/passman.git
synced 2025-09-10 15:04:20 +08:00
Merge remote-tracking branch 'origin/fix_layout_for_14' into feature/merges_v2.2.0
This commit is contained in:
commit
5643d9c318
51 changed files with 1190 additions and 533 deletions
19
.travis.yml
19
.travis.yml
|
@ -1,7 +1,9 @@
|
|||
language: php
|
||||
php:
|
||||
- 5.6
|
||||
- 7
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
env:
|
||||
global:
|
||||
- CORE_BRANCH=master
|
||||
|
@ -15,6 +17,7 @@ env:
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- fix_layout_for_14
|
||||
|
||||
|
||||
before_install:
|
||||
|
@ -83,17 +86,13 @@ addons:
|
|||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.6
|
||||
env: DB=sqlite;CLOUD=owncloud;SERVER_FOLDER=core
|
||||
- php: 5.6
|
||||
env: DB=mysql;CLOUD=owncloud;SERVER_FOLDER=core
|
||||
- php: 5.6
|
||||
env: DB=mysql;JSTESTS=1;
|
||||
- php: 7.0
|
||||
env: DB=mysql;
|
||||
# - php: 7.0
|
||||
# env: DB=sqlite;CLOUD=owncloud;SERVER_FOLDER=core
|
||||
# - php: 7.0
|
||||
# env: DB=mysql;CLOUD=owncloud;SERVER_FOLDER=core
|
||||
- php: 7.0
|
||||
env: DB=sqlite;CLOUD=owncloud;SERVER_FOLDER=core
|
||||
- php: 7.0
|
||||
env: DB=mysql;CLOUD=owncloud;SERVER_FOLDER=core
|
||||
env: DB=mysql;JSTESTS=1;
|
||||
allow_failures:
|
||||
- env: DB=sqlite;CODECHECK=2
|
||||
|
|
16
README.md
16
README.md
|
@ -7,6 +7,12 @@ Passman is a full featured password manager.
|
|||
[](https://www.codacy.com/app/brantje/passman?utm_source=github.com&utm_medium=referral&utm_content=nextcloud/passman&utm_campaign=Badge_Coverage)
|
||||
[](https://scrutinizer-ci.com/g/nextcloud/passman/?branch=master)
|
||||
|
||||
## Join us!
|
||||
There is a Telegram-Group:
|
||||
* [Passman General](https://t.me/passman_general)
|
||||
|
||||
Those are mainly used to discuss all sorts of topics for Passman and it's apps!
|
||||
|
||||
|
||||
## Contents
|
||||
* [Screenshots](https://github.com/nextcloud/passman#Screenshots)
|
||||
|
@ -16,6 +22,7 @@ Passman is a full featured password manager.
|
|||
* [Password generation](https://github.com/nextcloud/passman#password-generation)
|
||||
* [Storing credentials](https://github.com/nextcloud/passman#storing-credentials)
|
||||
* [Support passman](https://github.com/nextcloud/passman#support-passman)
|
||||
* [Development](https://github.com/nextcloud/passman#development)
|
||||
* [API](https://github.com/nextcloud/passman#api)
|
||||
* [Docker](https://github.com/nextcloud/passman#docker)
|
||||
* [Maintainers](https://github.com/nextcloud/passman#main-developers)
|
||||
|
@ -57,8 +64,9 @@ For more screenshots: [Click here](http://imgur.com/a/giKVt)
|
|||
For a demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
||||
|
||||
## Tested on
|
||||
- NextCloud 10 / 11
|
||||
- ownCloud 9.1+
|
||||
- Nextcloud 14
|
||||
|
||||
For older Versions see the [Releases Tab](https://github.com/nextcloud/passman/releases)
|
||||
|
||||
|
||||
## External apps
|
||||
|
@ -103,8 +111,6 @@ This time using the following routine:
|
|||
### Sharing credentials.
|
||||
Passman allows users to share passwords (this can be turned off by an administrator).
|
||||
|
||||
|
||||
|
||||
## API
|
||||
For developers Passman offers an [api](https://github.com/nextcloud/passman/wiki/API).
|
||||
|
||||
|
@ -160,7 +166,7 @@ To run the unit tests install phpunit globally, and setup the environment variab
|
|||
|
||||
## Contributors
|
||||
Add yours when creating a [pull request](https://help.github.com/articles/creating-a-pull-request/)!
|
||||
- None
|
||||
- Newhinton
|
||||
|
||||
|
||||
## FAQ
|
||||
|
|
|
@ -19,7 +19,7 @@ Features:
|
|||
- Import from various password managers (KeePass, LastPass, DashLane, ZOHO, Clipperz.is )
|
||||
For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
||||
]]></description>
|
||||
<version>2.1.5</version>
|
||||
<version>2.2.0</version>
|
||||
<licence>agpl</licence>
|
||||
<author homepage="https://github.com/brantje">Sander Brand</author>
|
||||
<author homepage="https://github.com/animalillo">Marcos Zuriaga</author>
|
||||
|
@ -37,13 +37,13 @@ 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="5.6"/>
|
||||
<php min-version="7.0"/>
|
||||
<database>sqlite</database>
|
||||
<database>pgsql</database>
|
||||
<database min-version="5.5">mysql</database>
|
||||
<lib>openssl</lib>
|
||||
<owncloud min-version="9" max-version="11" />
|
||||
<nextcloud min-version="9" max-version="14" />
|
||||
<nextcloud min-version="14" />
|
||||
<owncloud min-version="14" />
|
||||
</dependencies>
|
||||
|
||||
<background-jobs>
|
||||
|
|
43
bower.json
Normal file
43
bower.json
Normal file
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "Passman",
|
||||
"description": "Passman is a fully featured password manager",
|
||||
"main": "",
|
||||
"authors": [
|
||||
"Sander Brand <brantje(AT)gmail.com>"
|
||||
],
|
||||
"license": "AGPLv3",
|
||||
"homepage": "passman.cc",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"core/vendor",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": "1.5.8",
|
||||
"angular-animate": "1.5.8",
|
||||
"angular-cookies": "1.5.8",
|
||||
"angular-local-storage": "0.4.0",
|
||||
"angular-mocks": "1.5.8",
|
||||
"angular-off-click": "1.0.6",
|
||||
"angular-resource": "1.5.8",
|
||||
"angular-route": "1.5.8",
|
||||
"angular-sanitize": "1.5.8",
|
||||
"angular-touch": "1.5.8",
|
||||
"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-tags-input": "3.1.1",
|
||||
"papa-parse": "4.1.2",
|
||||
"llqrcode": "0.0.2",
|
||||
"sha": " 2.0.1",
|
||||
"sjcl": " 1.0.8",
|
||||
"ui-sortable": "0.19.0",
|
||||
"zxcvbn": "4.4.2"
|
||||
}
|
||||
}
|
|
@ -347,6 +347,16 @@ class TranslationController extends ApiController {
|
|||
'decline' => $this->trans->t('Decline'),
|
||||
'session.time.left' => $this->trans->t('You have {{session_time}} left before logout.'),
|
||||
'vault.locked' => $this->trans->t('Your vault has been locked for {{time}} because of {{tries}} failed attempts!'),
|
||||
'vault.hint.hello' => $this->trans->t('Hello there!'),
|
||||
'vault.hint.hello.add' => $this->trans->t('It does not seem that you have any passwords. Do you want to add one?'),
|
||||
'vault.hint.list.nogood' => $this->trans->t('You don\'t have good credentials'),
|
||||
'vault.hint.list.nomedium' => $this->trans->t('You don\'t have medium credentials'),
|
||||
'vault.hint.list.nobad' => $this->trans->t('You don\'t have bad credentials'),
|
||||
'vault.hint.list.noexpired' => $this->trans->t('You don\'t have expired credentials'),
|
||||
'vault.hint.list.nodeleted' => $this->trans->t('You don\'t have deleted credentials'),
|
||||
'vault.hint.list.notags' => $this->trans->t('There are no credentials with your selected tags'),
|
||||
'vault.hint.list.nosearch' => $this->trans->t('There are no credentials matching'),
|
||||
|
||||
|
||||
// templates/views/vaults.html
|
||||
'last.access' => $this->trans->t('Last accessed'),
|
||||
|
@ -391,6 +401,16 @@ class TranslationController extends ApiController {
|
|||
'deleted.credentials' => $this->trans->t('Deleted credentials'),
|
||||
'logout' => $this->trans->t('Logout'),
|
||||
'donate' => $this->trans->t('Donate'),
|
||||
'navigation.show.all' => $this->trans->t('Show All'),
|
||||
'navigation.tags' => $this->trans->t('Tags'),
|
||||
'navigation.tags.search' => $this->trans->t('Search Tags'),
|
||||
'navigation.strength.good' => $this->trans->t('Good Strength'),
|
||||
'navigation.strength.medium' => $this->trans->t('Medium Strength'),
|
||||
'navigation.strength.bad' => $this->trans->t('Bad Strength'),
|
||||
'navigation.expired' => $this->trans->t('Expired'),
|
||||
'navigation.advanced.filter' => $this->trans->t('Filter Tags'),
|
||||
'navigation.advanced.checkbox' => $this->trans->t('Simple Navigation'),
|
||||
|
||||
|
||||
// templates/public_share.php
|
||||
'share.page.text' => $this->trans->t('Someone has shared a credential with you.'),
|
||||
|
|
|
@ -4,10 +4,5 @@
|
|||
width: 350px; }
|
||||
#passwordSharingSettings #requests-table {
|
||||
width: 100%; }
|
||||
#passwordSharingSettings .link {
|
||||
color: #0066ff !important;
|
||||
cursor: pointer; }
|
||||
#passwordSharingSettings .link:hover {
|
||||
text-decoration: underline; }
|
||||
|
||||
/*# sourceMappingURL=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;AAIb,8BAAK;EACH,KAAK,EAAE,kBAA2B;EAClC,MAAM,EAAE,OAAO;AAEjB,oCAAW;EACT,eAAe,EAAE,SAAS",
|
||||
"mappings": "AAGM,wCAAE;EACA,OAAO,EAAE,GAAG;AAGhB,kDAAkB;EAChB,KAAK,EAAE,KAAK;AAGhB,wCAAe;EACb,KAAK,EAAE,IAAI",
|
||||
"sources": ["../sass/admin.scss"],
|
||||
"names": [],
|
||||
"file": "admin.css"
|
||||
|
|
210
css/app.css
210
css/app.css
|
@ -98,13 +98,6 @@
|
|||
background: #d83a02;
|
||||
color: #fff; }
|
||||
|
||||
.link {
|
||||
color: #0066ff !important;
|
||||
cursor: pointer; }
|
||||
|
||||
.link:hover {
|
||||
text-decoration: underline; }
|
||||
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
|
@ -126,67 +119,6 @@
|
|||
* 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 {
|
||||
margin: 44px 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.active {
|
||||
color: #fff;
|
||||
position: relative; }
|
||||
.tab_header li.active .indicator {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
height: 7px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -1px; }
|
||||
|
||||
.tab_container {
|
||||
border: 1px solid;
|
||||
border-color: #eee;
|
||||
border-top-color: #0082c9;
|
||||
border-bottom: 0;
|
||||
clear: both;
|
||||
padding: 0 1em; }
|
||||
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
|
@ -231,7 +163,8 @@
|
|||
.pw-gen .generate_pw {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
margin-left: -3px; }
|
||||
margin-left: -3px;
|
||||
padding-bottom: 1px; }
|
||||
.pw-gen .generate_pw .cell {
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
|
@ -275,7 +208,7 @@
|
|||
padding: 12px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
z-index: 800;
|
||||
z-index: 1800;
|
||||
background-color: red;
|
||||
color: white; }
|
||||
.warning_bar .fa-times {
|
||||
|
@ -284,9 +217,8 @@
|
|||
cursor: pointer; }
|
||||
|
||||
.vault_wrapper {
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
margin: 0 auto auto auto;
|
||||
transform: translate(-150px);
|
||||
max-width: 420px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
|
@ -360,21 +292,45 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#content {
|
||||
padding-top: 47px !important;
|
||||
height: 100%;
|
||||
width: 100%; }
|
||||
|
||||
.icon-image {
|
||||
width: 16px; }
|
||||
|
||||
#app-sidebar {
|
||||
height: auto; }
|
||||
#app-sidebar .sidebar {
|
||||
display: inline-block; }
|
||||
#app-sidebar .sidebar .sidebar-icon {
|
||||
margin-right: 15px; }
|
||||
#app-sidebar .sidebar .sidebar-icon .icon-image {
|
||||
width: 44px; }
|
||||
#app-sidebar .sidebar .sidebar-icon i {
|
||||
width: 44px; }
|
||||
#app-sidebar .sidebar .sidebar-label {
|
||||
float: right;
|
||||
line-height: 44px; }
|
||||
|
||||
#app-content {
|
||||
margin-left: 300px;
|
||||
width: calc(100vw - 300px);
|
||||
overflow-x: hidden; }
|
||||
#app-content #app-content-wrapper {
|
||||
min-height: 95%; }
|
||||
min-height: 95%;
|
||||
display: flex;
|
||||
height: calc(100vh - 49px); }
|
||||
#app-content #app-content-wrapper #passman-controls {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #c9c9c9; }
|
||||
#app-content #app-content-wrapper #passman-controls.sidebar-shown {
|
||||
padding-right: 27% !important; }
|
||||
@media screen and (max-width: 765px) {
|
||||
#app-content #app-content-wrapper #passman-controls.sidebar-shown .title {
|
||||
display: none; } }
|
||||
@media screen and (min-width: 769px) and (max-width: 1120px) {
|
||||
#app-content #app-content-wrapper #passman-controls.sidebar-shown .title {
|
||||
display: none; } }
|
||||
@media screen and (max-width: 765px) {
|
||||
#app-content #app-content-wrapper #passman-controls.sidebar-shown .title {
|
||||
display: none; } }
|
||||
@media screen and (min-width: 769px) and (max-width: 1120px) {
|
||||
#app-content #app-content-wrapper #passman-controls.sidebar-shown .title {
|
||||
display: none; } }
|
||||
#app-content #app-content-wrapper .title {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
@ -386,6 +342,8 @@
|
|||
@media screen and (min-width: 769px) and (max-width: 820px) {
|
||||
#app-content #app-content-wrapper .title {
|
||||
display: none; } }
|
||||
#app-content #app-content-wrapper .breadcrumb {
|
||||
float: left; }
|
||||
#app-content #app-content-wrapper .actions.creatable {
|
||||
float: left;
|
||||
overflow: hidden; }
|
||||
|
@ -437,7 +395,9 @@
|
|||
display: inline-block;
|
||||
padding: 7px; }
|
||||
#app-content #app-content-wrapper .searchboxContainer {
|
||||
display: inline-block;
|
||||
/*display: inline-block;*/
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
margin-right: 14px;
|
||||
float: right; }
|
||||
#app-content #app-content-wrapper .searchboxContainer .searchbox {
|
||||
|
@ -466,8 +426,7 @@
|
|||
border-bottom-left-radius: 3px;
|
||||
background-clip: padding-box; }
|
||||
#app-content #app-content-wrapper .credential-table {
|
||||
width: 100%;
|
||||
margin-top: 44px; }
|
||||
width: 100%; }
|
||||
#app-content #app-content-wrapper .credential-table tr:hover {
|
||||
background-color: whitesmoke; }
|
||||
#app-content #app-content-wrapper .credential-table tr.selected {
|
||||
|
@ -524,7 +483,8 @@
|
|||
#app-content #app-content-wrapper .tags .tag:last-child {
|
||||
margin-right: 8px; }
|
||||
#app-content #app-content-wrapper .grid-view {
|
||||
margin-top: 44px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap; }
|
||||
#app-content #app-content-wrapper .grid-view .credential {
|
||||
|
@ -542,20 +502,21 @@
|
|||
flex-direction: column;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
font-size: 1.75em;
|
||||
text-align: center; }
|
||||
font-size: 1.75em; }
|
||||
#app-content #app-content-wrapper .grid-view .credential .credential_content .label {
|
||||
padding-top: 0.5em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
line-height: 1.3em;
|
||||
word-wrap: break-word; }
|
||||
word-wrap: break-word;
|
||||
float: right; }
|
||||
#app-content #app-content-wrapper .grid-view .credential .credential_content .tags {
|
||||
margin-bottom: 0.5em; }
|
||||
margin: 0 0 auto;
|
||||
text-align: right; }
|
||||
#app-content #app-content-wrapper .grid-view .credential .credential_content .tags .tag {
|
||||
color: #000 !important;
|
||||
margin-top: 5px;
|
||||
display: inline-block; }
|
||||
display: inline-block;
|
||||
left: 0; }
|
||||
@media all and (min-width: 40em) {
|
||||
#app-content #app-content-wrapper .grid-view .credential {
|
||||
width: 40%; } }
|
||||
|
@ -648,7 +609,16 @@
|
|||
vertical-align: middle; }
|
||||
#app-content #app-content-wrapper .edit_credential .otpText {
|
||||
padding-right: 10px; }
|
||||
#app-content #app-content-wrapper .main_list {
|
||||
flex: 1;
|
||||
float: left;
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
width: 100%; }
|
||||
#app-content #app-content-wrapper .main_list .share {
|
||||
overflow: hidden; }
|
||||
#app-content #app-content-wrapper .app_sidebar {
|
||||
float: right;
|
||||
padding: 10px;
|
||||
overflow-y: auto; }
|
||||
#app-content #app-content-wrapper .app_sidebar h2 {
|
||||
|
@ -762,7 +732,8 @@
|
|||
/* "hand" cursor */ }
|
||||
|
||||
.btn-danger {
|
||||
color: #fff; }
|
||||
color: #000000;
|
||||
background-color: #ff0000; }
|
||||
|
||||
.icon-label {
|
||||
overflow: hidden; }
|
||||
|
@ -787,15 +758,12 @@
|
|||
.icon-label .icon-picker {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
margin-left: -3px;
|
||||
-webkit-border-bottom-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
-webkit-border-top-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
background-clip: padding-box; }
|
||||
padding-top: 7px; }
|
||||
.icon-label .icon-picker .cell {
|
||||
margin-top: 0px;
|
||||
margin-left: -0px;
|
||||
padding: 7px 12px 2px 12px;
|
||||
display: inline-block;
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eaeaea;
|
||||
|
@ -805,8 +773,6 @@
|
|||
-webkit-border-top-left-radius: 6px;
|
||||
border-top-left-radius: 6px;
|
||||
background-clip: padding-box; }
|
||||
.icon-label .icon-picker .cell img {
|
||||
height: 16px; }
|
||||
.icon-label .icon-picker .cell:hover {
|
||||
color: #0066ff; }
|
||||
|
||||
|
@ -849,29 +815,38 @@
|
|||
*/
|
||||
.settings-container div {
|
||||
padding-left: 15px; }
|
||||
.settings-container button {
|
||||
width: 80%;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px; }
|
||||
|
||||
#app-navigation > ul {
|
||||
padding-bottom: 80px; }
|
||||
#app-navigation > ul > li > a {
|
||||
padding-left: 12px !important;
|
||||
z-index: auto; }
|
||||
#app-navigation > ul > li > a {
|
||||
z-index: auto; }
|
||||
|
||||
.nav-trashbin {
|
||||
position: fixed !important;
|
||||
bottom: 44px;
|
||||
width: inherit !important;
|
||||
border-right: 1px solid #eee; }
|
||||
.nav-trashbin a {
|
||||
background-color: #fff !important;
|
||||
opacity: 1 !important;
|
||||
z-index: 140;
|
||||
padding: 0 20px; }
|
||||
.nav-trashbin a.active {
|
||||
border-left: 3px solid #0082c9; }
|
||||
z-index: 140; }
|
||||
.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 li .app-navigation-entry-bullet-color {
|
||||
background-color: var(--color-primary); }
|
||||
#app-navigation li .highlight-selected {
|
||||
background-color: var(--color-primary); }
|
||||
#app-navigation li a.taginput {
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
opacity: 1; }
|
||||
#app-navigation li a {
|
||||
overflow: visible; }
|
||||
|
@ -985,7 +960,6 @@
|
|||
padding: 3px 5px; }
|
||||
|
||||
#app-settings-content:not(.ng-hide) {
|
||||
height: 90px;
|
||||
display: inherit !important;
|
||||
padding: 0;
|
||||
transition: height 0.15s ease-out; }
|
||||
|
@ -1004,7 +978,8 @@
|
|||
margin-right: 0 !important; }
|
||||
|
||||
#app-content #app-content-wrapper #passman-controls {
|
||||
border-bottom: 1px solid #c9c9c9; }
|
||||
border-bottom: 1px solid #c9c9c9;
|
||||
margin-top: 5px; }
|
||||
|
||||
#passman-controls {
|
||||
box-sizing: border-box;
|
||||
|
@ -1012,6 +987,7 @@
|
|||
top: 45px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
border-bottom: 1px solid #c9c9c9;
|
||||
padding: 0 !important;
|
||||
margin: 0;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
|
@ -1027,8 +1003,8 @@
|
|||
width: 100%; } }
|
||||
@media only screen and (min-width: 768px) {
|
||||
#app-navigation + #app-content #passman-controls {
|
||||
left: 250px;
|
||||
width: calc( 100% - 250px ) !important; } }
|
||||
left: 300px;
|
||||
width: calc( 100% - 300px ) !important; } }
|
||||
#passman-controls .button, #passman-controls, #passman-controls input[type='submit'], #passman-controls input[type='text'], #passman-controls input[type='password'], #passman-controls select {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
|
|
File diff suppressed because one or more lines are too long
9
css/vendor/bootstrap/bootstrap.min.css
vendored
9
css/vendor/bootstrap/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -44,6 +44,8 @@
|
|||
}
|
||||
|
||||
$scope.logout = function () {
|
||||
//see vault.js:54
|
||||
$rootScope.override_default_vault=true;
|
||||
$scope.active_vault = false;
|
||||
};
|
||||
if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
$scope.active_vault = vault;
|
||||
$scope.active_vault.vaultKey = vaultKey;
|
||||
if(!$rootScope.vaultCache){
|
||||
$rootScope.vaultCache = [];
|
||||
$rootScope.vaultCache = [];
|
||||
}
|
||||
VaultService.setActiveVault($scope.active_vault);
|
||||
for (var i = 0; i < _credentials.length; i++) {
|
||||
|
@ -325,97 +325,218 @@
|
|||
fields: ['label', 'username', 'email', 'custom_fields']
|
||||
};
|
||||
|
||||
//searchboxfix
|
||||
$scope.$on('nc_searchbox', function(event, args) {
|
||||
$scope.filterOptions.filterText=args;
|
||||
});
|
||||
|
||||
$scope.filtered_credentials = [];
|
||||
$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
|
||||
if (!$scope.active_vault) {
|
||||
return;
|
||||
}
|
||||
if ($scope.active_vault.credentials) {
|
||||
var credentials = angular.copy($scope.active_vault.credentials);
|
||||
var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
|
||||
filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
|
||||
filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
|
||||
$scope.filtered_credentials = filtered_credentials;
|
||||
$scope.filterOptions.selectedtags = angular.copy($scope.selectedtags);
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
var _credential = $scope.active_vault.credentials[i];
|
||||
if (_credential.tags) {
|
||||
TagService.addTags(_credential.tags);
|
||||
}
|
||||
|
||||
$scope.filtered_credentials = [];
|
||||
$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
|
||||
if (!$scope.active_vault) {
|
||||
return;
|
||||
}
|
||||
if ($scope.active_vault.credentials) {
|
||||
var credentials = angular.copy($scope.active_vault.credentials);
|
||||
var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
|
||||
filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
|
||||
filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
|
||||
$scope.filtered_credentials = filtered_credentials;
|
||||
$scope.filterOptions.selectedtags = angular.copy($scope.selectedtags);
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
var _credential = $scope.active_vault.credentials[i];
|
||||
if (_credential.tags) {
|
||||
TagService.addTags(_credential.tags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, true);
|
||||
|
||||
$scope.no_credentials_label=[];
|
||||
$scope.no_credentials_label.all=true;
|
||||
$scope.no_credentials_label.s_good=false;
|
||||
$scope.no_credentials_label.s_medium=false;
|
||||
$scope.no_credentials_label.s_low=false;
|
||||
$scope.no_credentials_label.expired=false;
|
||||
|
||||
$scope.disableAllLabels = function(){
|
||||
$scope.no_credentials_label.all=false;
|
||||
$scope.no_credentials_label.s_good=false;
|
||||
$scope.no_credentials_label.s_medium=false;
|
||||
$scope.no_credentials_label.s_low=false;
|
||||
$scope.no_credentials_label.expired=false;
|
||||
};
|
||||
|
||||
//watch for special tags
|
||||
$scope.$on('filterSpecial', function(event, args) {
|
||||
|
||||
$scope.disableAllLabels();
|
||||
switch (args) {
|
||||
case "strength_good":
|
||||
$scope.filterStrength(3,1000);
|
||||
$scope.no_credentials_label.s_good=true;
|
||||
break;
|
||||
case "strength_medium":
|
||||
$scope.filterStrength(2,3);
|
||||
$scope.no_credentials_label.s_medium=true;
|
||||
break;
|
||||
case "strength_low":
|
||||
$scope.filterStrength(0,1);
|
||||
$scope.no_credentials_label.s_low=true;
|
||||
break;
|
||||
case "expired":
|
||||
$scope.filterExpired();
|
||||
$scope.no_credentials_label.expired=true;
|
||||
break;
|
||||
case "all":
|
||||
$scope.filterAll();
|
||||
$scope.no_credentials_label.all=true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.getListSizes = function(){
|
||||
var l = $scope.filtered_credentials;
|
||||
|
||||
var deleted=0;
|
||||
for (var i = 0; i < l.length; i++) {
|
||||
if(l[i].delete_time>0){
|
||||
deleted++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, true);
|
||||
|
||||
$scope.selectedtags = [];
|
||||
var to;
|
||||
$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
|
||||
var _selectedTags = [];
|
||||
for (var x = 0; x < _sTags.length; x++) {
|
||||
_selectedTags.push(_sTags[x].text);
|
||||
}
|
||||
$scope.selectedtags = _selectedTags;
|
||||
$timeout.cancel(to);
|
||||
if (_selectedTags.length > 0) {
|
||||
to = $timeout(function () {
|
||||
if ($scope.filtered_credentials) {
|
||||
var _filtered_tags = [];
|
||||
for (var i = 0; i < $scope.filtered_credentials.length; i++) {
|
||||
var tags = $scope.filtered_credentials[i].tags_raw;
|
||||
for (var x = 0; x < tags.length; x++) {
|
||||
var tag = tags[x].text;
|
||||
if (_filtered_tags.indexOf(tag) === -1) {
|
||||
_filtered_tags.push(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootScope.$emit('limit_tags_in_list', _filtered_tags);
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.delete_time = 0;
|
||||
$scope.showCredentialRow = function (credential) {
|
||||
if ($scope.delete_time === 0) {
|
||||
return credential.delete_time === 0;
|
||||
} else {
|
||||
return credential.delete_time > $scope.delete_time;
|
||||
}
|
||||
var result=[];
|
||||
result.listsize=l.length;
|
||||
result.listsize_wout_deleted=l.length-deleted;
|
||||
result.listsize_deleted=deleted;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
$rootScope.$on('set_delete_time', function (event, time) {
|
||||
$scope.delete_time = time;
|
||||
});
|
||||
$scope.filterAll = function(){
|
||||
$scope.selectedtags=[];
|
||||
$scope.filterOptions.filterText="";
|
||||
var creds_filtered=[];
|
||||
|
||||
$scope.setDeleteTime = function (delete_time) {
|
||||
$scope.delete_time = delete_time;
|
||||
};
|
||||
for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
|
||||
if($scope.active_vault.credentials[i].delete_time===0){
|
||||
creds_filtered.push($scope.active_vault.credentials[i]);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.selectedCredential = false;
|
||||
$scope.selectCredential = function (credential) {
|
||||
if(credential.description) {
|
||||
credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
|
||||
}
|
||||
$scope.selectedCredential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
$scope.filtered_credentials=$scope.filterHidden(creds_filtered);
|
||||
};
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedCredential = false;
|
||||
};
|
||||
$scope.filterStrength = function(strength_min, strength_max){
|
||||
var initialCredentials=$scope.active_vault.credentials;
|
||||
var postFiltered=[];
|
||||
for (var i = 0; i < initialCredentials.length; i++) {
|
||||
var _credential = initialCredentials[i];
|
||||
var zxcvbn_result = zxcvbn(_credential.password);
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
if($scope.active_vault) {
|
||||
$rootScope.vaultCache[$scope.active_vault.guid] = null;
|
||||
}
|
||||
$scope.active_vault = null;
|
||||
$scope.credentials = [];
|
||||
// $scope.$parent.selectedVault = false;
|
||||
if(zxcvbn_result.score>=strength_min && zxcvbn_result.score<=strength_max){
|
||||
postFiltered.push(initialCredentials[i]);
|
||||
}
|
||||
}
|
||||
$scope.filtered_credentials=$scope.filterHidden(postFiltered);
|
||||
};
|
||||
|
||||
$scope.filterExpired = function(){
|
||||
var initialCredentials=$scope.active_vault.credentials;
|
||||
var now = Date.now();
|
||||
var postFiltered=[];
|
||||
|
||||
for (var i = 0; i < initialCredentials.length; i++) {
|
||||
var _credential = initialCredentials[i];
|
||||
|
||||
if(_credential.expire_time!==0 && _credential.expire_time <= now){
|
||||
postFiltered.push(initialCredentials[i]);
|
||||
}
|
||||
}
|
||||
$scope.filtered_credentials=$scope.filterHidden(postFiltered);
|
||||
};
|
||||
|
||||
$scope.filterHidden = function(list){
|
||||
var list_without_hidden=[];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if(list[i].hidden!==1){
|
||||
list_without_hidden.push(list[i]);
|
||||
}
|
||||
}
|
||||
return list_without_hidden;
|
||||
};
|
||||
|
||||
|
||||
|
||||
$scope.selectedtags = [];
|
||||
var to;
|
||||
$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
|
||||
var _selectedTags = [];
|
||||
for (var x = 0; x < _sTags.length; x++) {
|
||||
_selectedTags.push(_sTags[x].text);
|
||||
}
|
||||
$scope.selectedtags = _selectedTags;
|
||||
$timeout.cancel(to);
|
||||
if (_selectedTags.length > 0) {
|
||||
to = $timeout(function () {
|
||||
if ($scope.filtered_credentials) {
|
||||
var _filtered_tags = [];
|
||||
for (var i = 0; i < $scope.filtered_credentials.length; i++) {
|
||||
var tags = $scope.filtered_credentials[i].tags_raw;
|
||||
for (var x = 0; x < tags.length; x++) {
|
||||
var tag = tags[x].text;
|
||||
if (_filtered_tags.indexOf(tag) === -1) {
|
||||
_filtered_tags.push(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootScope.$emit('limit_tags_in_list', _filtered_tags);
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.delete_time = 0;
|
||||
$scope.showCredentialRow = function (credential) {
|
||||
if ($scope.delete_time === 0) {
|
||||
return credential.delete_time === 0;
|
||||
} else {
|
||||
return credential.delete_time > $scope.delete_time;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$rootScope.$on('set_delete_time', function (event, time) {
|
||||
$scope.delete_time = time;
|
||||
});
|
||||
|
||||
$scope.setDeleteTime = function (delete_time) {
|
||||
$scope.delete_time = delete_time;
|
||||
};
|
||||
|
||||
$scope.selectedCredential = false;
|
||||
$scope.selectCredential = function (credential) {
|
||||
if (credential.description) {
|
||||
credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
|
||||
}
|
||||
$scope.selectedCredential = angular.copy(credential);
|
||||
$rootScope.$emit('app_menu', true);
|
||||
};
|
||||
|
||||
$scope.closeSelected = function () {
|
||||
$rootScope.$emit('app_menu', false);
|
||||
$scope.selectedCredential = false;
|
||||
};
|
||||
|
||||
$rootScope.$on('logout', function () {
|
||||
if ($scope.active_vault) {
|
||||
$rootScope.vaultCache[$scope.active_vault.guid] = null;
|
||||
}
|
||||
$scope.active_vault = null;
|
||||
$scope.credentials = [];
|
||||
//$scope.$parent.selectedVault = false;
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', 'TagService', 'NotificationService', 'ShareService', '$translate',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService, TagService, NotificationService, ShareService, $translate) {
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', 'EncryptService', 'TagService', 'NotificationService', 'ShareService', '$translate', '$rootScope',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService, EncryptService, TagService, NotificationService, ShareService, $translate, $rootScope) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
|
||||
if (!$scope.active_vault) {
|
||||
|
@ -292,7 +292,7 @@
|
|||
};
|
||||
$scope.saving = false;
|
||||
$scope.saveCredential = function () {
|
||||
$scope.saving = true;
|
||||
$scope.saving = true;
|
||||
|
||||
|
||||
if ($scope.new_custom_field.label && $scope.new_custom_field.value) {
|
||||
|
@ -301,8 +301,8 @@
|
|||
|
||||
|
||||
if ($scope.storedCredential.password !== $scope.storedCredential.password_repeat){
|
||||
$scope.saving = false;
|
||||
NotificationService.showNotification($translate.instant('password.do.not.match'), 5000);
|
||||
$scope.saving = false;
|
||||
NotificationService.showNotification($translate.instant('password.do.not.match'), 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -313,7 +313,7 @@
|
|||
if (!$scope.storedCredential.credential_id) {
|
||||
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;
|
||||
CredentialService.createCredential($scope.storedCredential).then(function () {
|
||||
$scope.saving = false;
|
||||
$scope.saving = false;
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification($translate.instant('credential.created'), 5000);
|
||||
|
||||
|
@ -345,14 +345,26 @@
|
|||
_credential.description = _credential.description.replace(regex, "");
|
||||
}
|
||||
CredentialService.updateCredential(_credential, _useKey).then(function () {
|
||||
$scope.saving = false;
|
||||
$scope.saving = false;
|
||||
SettingsService.setSetting('edit_credential', null);
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
NotificationService.showNotification($translate.instant('credential.updated'), 5000);
|
||||
});
|
||||
}
|
||||
$scope.refreshListWithSaved();
|
||||
};
|
||||
|
||||
};
|
||||
$scope.refreshListWithSaved = function () {
|
||||
var current_vault = $rootScope.vaultCache[$scope.active_vault.guid];
|
||||
var cv_credentials = current_vault.credentials;
|
||||
for (var i = 0; i < cv_credentials.length; i++) {
|
||||
if (cv_credentials[i].credential_id === $scope.storedCredential.credential_id) {
|
||||
cv_credentials[i] = $scope.storedCredential;
|
||||
}
|
||||
}
|
||||
current_vault.credentials=cv_credentials;
|
||||
$rootScope.vaultCache[$scope.active_vault.guid] = current_vault;
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$location.path('/vault/' + $routeParams.vault_id);
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
|
||||
}
|
||||
|
||||
$scope.removeHiddenStyles = function(){
|
||||
document.getElementById('warning_bar').classList.remove('template-hidden');
|
||||
};
|
||||
|
||||
$rootScope.$on('settings_loaded', function(){
|
||||
if (SettingsService.isEnabled('disable_contextmenu')) {
|
||||
document.addEventListener('contextmenu', function (event) {
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name passmanApp.controller:MenuCtrl
|
||||
|
@ -32,15 +31,21 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MenuCtrl', ['$scope', 'VaultService', '$location', '$rootScope', 'TagService','SettingsService',
|
||||
function ($scope, VaultService, $location, $rootScope, TagService, SettingsService) {
|
||||
.controller('MenuCtrl', ['$scope', 'VaultService', '$location', '$rootScope', 'TagService','SettingsService', '$translate',
|
||||
function ($scope, VaultService, $location, $rootScope, TagService, SettingsService, $translate) {
|
||||
$rootScope.logout = function () {
|
||||
//see vault.js:54
|
||||
$rootScope.override_default_vault=true;
|
||||
SettingsService.setSetting('defaultVaultPass', false);
|
||||
TagService.resetTags();
|
||||
$rootScope.$broadcast('logout');
|
||||
$location.path('/');
|
||||
};
|
||||
|
||||
$scope.removeHiddenStyles = function(){
|
||||
document.getElementById('app-navigation').classList.remove('template-hidden');
|
||||
};
|
||||
|
||||
$scope.selectedTags = [];
|
||||
$scope.getTags = function ($query) {
|
||||
return TagService.searchTag($query);
|
||||
|
@ -77,12 +82,139 @@
|
|||
$rootScope.$broadcast('selected_tags_updated', $scope.selectedTags);
|
||||
}, true);
|
||||
|
||||
$scope.tagClicked = function (tag) {
|
||||
$scope.selectedTags.push(tag);
|
||||
$scope.tagSelected = function (tag) {
|
||||
for (var i = 0; i < $scope.selectedTags.length; i++) {
|
||||
if($scope.selectedTags[i].text === tag.text){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
$scope.removeTagFromSelected = function (tag) {
|
||||
var where =-1;
|
||||
for (var i = 0; i < $scope.selectedTags.length; i++) {
|
||||
if($scope.selectedTags[i].text === tag.text){
|
||||
where=i;
|
||||
}
|
||||
}
|
||||
if(where === -1){
|
||||
//console.log("Cant remove selected Tag, Tag not present!");
|
||||
}
|
||||
$scope.selectedTags.splice(where, 1);
|
||||
};
|
||||
|
||||
$scope.clearForm = function () {
|
||||
document.getElementById('tagsearch').value="";
|
||||
};
|
||||
|
||||
$scope.tagClickedString = function (tagtext) {
|
||||
var tag=[];
|
||||
tag.text=tagtext;
|
||||
$scope.tagClicked(tag);
|
||||
};
|
||||
|
||||
$scope.tagClicked = function (tag) {
|
||||
//check if tag already selected
|
||||
if(!$scope.tagSelected(tag)){
|
||||
$scope.selectedTags.push(tag);
|
||||
}else{
|
||||
//console.log("Already selected Tag!");
|
||||
$scope.removeTagFromSelected(tag);
|
||||
}
|
||||
};
|
||||
|
||||
//searchboxfix
|
||||
var native_search = document.getElementById("searchbox");
|
||||
if(native_search !== null){
|
||||
native_search.nextElementSibling.addEventListener('click', function (e) {
|
||||
$scope.$apply(function () {
|
||||
$rootScope.$broadcast('nc_searchbox',"");
|
||||
});
|
||||
});
|
||||
|
||||
native_search.classList.remove('hidden');
|
||||
native_search.addEventListener('keypress', function (e) {
|
||||
if(e.keyCode === 13){
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
native_search.addEventListener('keyup', function (e) {
|
||||
$scope.$apply(function () {
|
||||
$rootScope.$broadcast('nc_searchbox',native_search.value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$scope.clickedNavigationItem="all";
|
||||
$scope.filterCredentialBySpecial = function (string) {
|
||||
$scope.clickedNavigationItem=string;
|
||||
if(string !== "nav_trashbin"){
|
||||
$scope.delete_time=0;
|
||||
$rootScope.$broadcast('set_delete_time', $scope.delete_time);
|
||||
}
|
||||
$scope.selectedTags =[];
|
||||
|
||||
$rootScope.$broadcast('filterSpecial',string);
|
||||
|
||||
//close settings when item is selected
|
||||
$scope.settingsShown=false;
|
||||
};
|
||||
|
||||
$scope.collapsedDefaultValue=true;
|
||||
$scope.tagCollapsibleOpen=VaultService.getVaultSetting("vaultTagCollapsedState",$scope.collapsedDefaultValue);
|
||||
$scope.tagCollapsibleClicked = function () {
|
||||
if (VaultService.getVaultSetting("vaultTagCollapsedState",$scope.collapsedDefaultValue) === true) {
|
||||
VaultService.setVaultSetting("vaultTagCollapsedState",false);
|
||||
} else {
|
||||
VaultService.setVaultSetting("vaultTagCollapsedState",true);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.tagCollapsibleState = function () {
|
||||
if(VaultService.getVaultSetting('vaultTagCollapsedState',$scope.collapsedDefaultValue)){
|
||||
return "";
|
||||
}
|
||||
return "open";
|
||||
};
|
||||
|
||||
|
||||
|
||||
//this is needed, because the translation is not ready when the dom loads and the translation only returns the key.
|
||||
//then the key is set, and the taginput is collapsed by angular. If the correct translation loads, the collapsed dom element does not update itself.
|
||||
//here we set the value manually
|
||||
$scope.initPlaceholder = function () {
|
||||
$translate.onReady().then(function(){
|
||||
var string=$translate.instant('navigation.advanced.filter');
|
||||
document.getElementById("tags-input-outer").setAttribute("placeholder", string);
|
||||
document.getElementById("tags-input-outer").firstChild.firstChild.childNodes[1].setAttribute("placeholder", string);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.legacyNavbarDefault=true;
|
||||
$scope.legacyNavbarAlreadyInitialized=false;
|
||||
|
||||
if (typeof $scope.legacyNavbar === 'undefined') {
|
||||
$scope.legacyNavbar = $scope.legacyNavbarDefault;
|
||||
}
|
||||
|
||||
$scope.$watch('legacyNavbar', function(newValue, oldValue) {
|
||||
VaultService.setVaultSetting("vaultNavBarLegacy",newValue);
|
||||
});
|
||||
|
||||
$scope.initializeNavbar = function () {
|
||||
if($scope.legacyNavbarAlreadyInitialized){
|
||||
return;
|
||||
}
|
||||
$scope.legacyNavbar = VaultService.getVaultSetting('vaultNavBarLegacy',$scope.legacyNavbarDefault);
|
||||
$scope.legacyNavbarAlreadyInitialized=true;
|
||||
};
|
||||
|
||||
$rootScope.$on('credentials_loaded', function () {
|
||||
$rootScope.$broadcast('selected_tags_updated', $scope.selectedTags);
|
||||
$scope.initializeNavbar();
|
||||
});
|
||||
|
||||
$scope.available_tags = TagService.getTags();
|
||||
|
@ -91,10 +223,14 @@
|
|||
if ($scope.selectedTags.length === 0) {
|
||||
return TagService.getTags();
|
||||
} else {
|
||||
return $scope.filtered_tags;
|
||||
return TagService.getTags();
|
||||
//Always show all tags
|
||||
//return $scope.filtered_tags;
|
||||
}
|
||||
}, function (tags) {
|
||||
$scope.available_tags = tags;
|
||||
//Always show all tags
|
||||
//$scope.available_tags = tags;
|
||||
$scope.available_tags = TagService.getTags();
|
||||
}, true);
|
||||
|
||||
$scope.toggleDeleteTime = function () {
|
||||
|
@ -102,8 +238,9 @@
|
|||
$scope.delete_time = 0;
|
||||
} else {
|
||||
$scope.delete_time = 1;
|
||||
this.filterCredentialBySpecial('nav_trashbin');
|
||||
}
|
||||
$rootScope.$broadcast('set_delete_time', $scope.delete_time);
|
||||
};
|
||||
}]);
|
||||
}());
|
||||
}());
|
||||
|
|
|
@ -46,7 +46,11 @@
|
|||
var vault = vaults[i];
|
||||
if (vault.guid === default_vault.guid) {
|
||||
$scope.default_vault = true;
|
||||
$scope.list_selected_vault = vault;
|
||||
//This prevents the opening of the default vault if the user logs out
|
||||
if(!$rootScope.override_default_vault){
|
||||
$scope.list_selected_vault = vault;
|
||||
$rootScope.override_default_vault=false;
|
||||
}
|
||||
SettingsService.setSetting('defaultVault', vault);
|
||||
if (SettingsService.getSetting('defaultVaultPass')) {
|
||||
$location.path('/vault/' + vault.guid);
|
||||
|
@ -219,7 +223,8 @@
|
|||
};
|
||||
|
||||
|
||||
$scope.createVault = function (vault_name, vault_key, vault_key2) {
|
||||
|
||||
$scope.createVault = function (vault_name, vault_key, vault_key2) {
|
||||
if (vault_key !== vault_key2) {
|
||||
$scope.error = $translate.instant('password.do.not.match');
|
||||
return;
|
||||
|
|
|
@ -50,12 +50,12 @@
|
|||
'<div class="tools">' +
|
||||
'<div class="cell" ng-if="toggle" tooltip="tggltxt" ng-click="toggleVisibility()"><i class="fa" ng-class="{\'fa-eye\': !valueVisible, \'fa-eye-slash\': valueVisible }"></i></div>' +
|
||||
'<div class="cell" ng-if="isLink"><a ng-href="{{value}}" target="_blank" rel="nofollow noopener noreferrer"><i tooltip="\'Open in new window\'" class="link fa fa-external-link"></i></a></div>' +
|
||||
'<div class="cell" ngclipboard-success="onSuccess(e);" ngclipboard-error="onError(e);" ngclipboard data-clipboard-text="{{value}}"><i tooltip="copy_msg" class="fa fa-files-o"></i></div>' +
|
||||
'<div class="cell" ngclipboard-success="onSuccess(e);" ngclipboard-error="onError(e);" ngclipboard data-clipboard-text="{{value}}"><i tooltip="copy_msg" class="fa fa-files-o"></i></div>' +
|
||||
'</div></span>',
|
||||
link: function (scope) {
|
||||
var expression = /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi;
|
||||
var regex = new RegExp(expression);
|
||||
$translate(['toggle.visibility', 'copy', 'copied']).then(function (translations) {
|
||||
$translate(['toggle.visibility','copy.field', 'copy', 'copied']).then(function (translations) {
|
||||
scope.tggltxt = translations['toggle.visibility'];
|
||||
scope.copy_msg = translations['copy.field'];
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
angular.module('passmanApp').directive('credentialIcon', [
|
||||
'$window', function($window) {
|
||||
return {
|
||||
template: '<img ng-src="{{ iconUrl }}" width="16">',
|
||||
template: '<img ng-src="{{ iconUrl }}" class="icon-image">',
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
credential: '=',
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
return false;
|
||||
} else {
|
||||
_activeVault.vault_settings[key] = value;
|
||||
_this.updateVault(_activeVault);
|
||||
this.updateVault(_activeVault);
|
||||
}
|
||||
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@ angular.module('views/credential_revisions.html', []).run(['$templateCache', fun
|
|||
angular.module('views/edit_credential.html', []).run(['$templateCache', function ($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/edit_credential.html',
|
||||
'<div id="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">{{ \'edit.credential\' | translate}} "{{storedCredential.label}}"</a> <a ng-if="!storedCredential.credential_id">{{ \'create.credential\' | translate}}</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}}<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 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) {
|
||||
|
@ -107,7 +107,7 @@ angular.module('views/partials/forms/share_credential/link_sharing.html', []).ru
|
|||
angular.module('views/partials/icon-picker.html', []).run(['$templateCache', function ($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/partials/icon-picker.html',
|
||||
'<div><div class="cell"><credential-icon credential="credential"></credential-icon></div><div style="display: none" id="iconPicker" title="{{ \'pick.icon\' | translate }}"><div class="iconList"><div ng-repeat="(groupName, icons) in iconGroups"><h2 style="clear: both" id="{{groupName}}">{{groupName}}</h2><div class="icon" ng-repeat="icon in icons" ng-click="selectIcon(icon)"><img ng-src="{{icon.url}}" height="32"></div></div></div><div class="iconModifier"><div ng-if="selectedIcon">{{ \'selected.icon\' | translate}}:<br><img ng-src="{{selectedIcon.url}}" height="32"><br><button ng-click="useIcon()" ng-if="selectedIcon">{{ \'use.icon\' | translate}}</button></div></div></div></div>');
|
||||
'<div class="cell icon-category-auth"></div><div style="display: none" id="iconPicker" title="{{ \'pick.icon\' | translate }}"><div class="iconList"><div ng-repeat="(groupName, icons) in iconGroups"><h2 style="clear: both" id="{{groupName}}">{{groupName}}</h2><div class="icon" ng-repeat="icon in icons" ng-click="selectIcon(icon)"><img ng-src="{{icon.url}}" height="32"></div></div></div><div class="iconModifier"><div ng-if="selectedIcon">{{ \'selected.icon\' | translate}}:<br><img ng-src="{{selectedIcon.url}}" height="32"><br><button ng-click="useIcon()" ng-if="selectedIcon">{{ \'use.icon\' | translate}}</button></div></div></div>');
|
||||
}]);
|
||||
|
||||
angular.module('views/partials/password-meter.html', []).run(['$templateCache', function ($templateCache) {
|
||||
|
@ -119,7 +119,7 @@ angular.module('views/partials/password-meter.html', []).run(['$templateCache',
|
|||
angular.module('views/settings.html', []).run(['$templateCache', function ($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/settings.html',
|
||||
'<div id="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="cancel()">{{active_vault.name}}</a></div><div class="crumb svg last"><a>{{ \'settings\' | translate}}</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}}<div class="indicator" use-theme negative="\'true\'"></div></li></ul><div class="tab_container settings edit_credential"><div ng-include="currentTab.url"></div></div>');
|
||||
'<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) {
|
||||
|
@ -131,8 +131,8 @@ angular.module('views/share_credential.html', []).run(['$templateCache', functio
|
|||
angular.module('views/show_vault.html', []).run(['$templateCache', function ($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/show_vault.html',
|
||||
'<div off-click="closeSelected()" off-click-filter="\'.download-js-link, .sidebar-shown\'"><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 last" ng-click="clearState()"><span>{{active_vault.name}}</span></div></div></div><div class="actions creatable"><span ng-click="addCredential()" class="button new"><span>+</span></span></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><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="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><span class="label">{{ ::credential.label}}</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 class="label">{{ ::credential.label}}</div><div class="tags"><div class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</div></div></div></li></ul></div><div id="app-sidebar" class="detailsView scroll-container app_sidebar" ng-show="selectedCredential"><h2>{{selectedCredential.label}}</h2><span class="close icon-close" ng-click="closeSelected()" alt="Close"></span><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><div class="share_popup" style="display: none">{{ \'sharereq.title\' | translate}}<br><p>{{ \'sharereq.line1\' | translate}}</p>{{active_vault.vault_id}}<table class="table"><thead><tr><td>{{ \'label\' | translate}}</td><td>{{ \'permissions\' | translate}}</td><td>{{ \'received.from\' | translate}}</td><td>{{ \'date\' | translate}}</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)">{{ \'accept\' | translate}}</span> | <span class="link" ng-click="declineShareRequest(share_request)">{{ \'decline\' | translate}}</span></td></tr></table></div>');
|
||||
'<div class="main_list" off-click="closeSelected()" off-click-filter="\'.download-js-link, .sidebar-shown\'"><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 class="crumb svg last" ng-hide="delete_time>0"><a ng-click="addCredential()">{{ \'New\' | translate}}</a></div></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><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="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><a class="label">{{ ::credential.label}}</a></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></div><div id="app-sidebar" class="app_sidebar" ng-show="selectedCredential"><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="selectedCredential"></credential-icon></span><span class="icon sidebar-icon" ng-if="!selectedCredential.url"><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' +
|
||||
' (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">{{ \'sharereq.title\' | translate}}<br><p>{{ \'sharereq.line1\' | translate}}</p>{{active_vault.vault_id}}<table class="table"><thead><tr><td>{{ \'label\' | translate}}</td><td>{{ \'permissions\' | translate}}</td><td>{{ \'received.from\' | translate}}</td><td>{{ \'date\' | translate}}</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)">{{ \'accept\' | translate}}</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) {
|
||||
|
|
|
@ -20,7 +20,7 @@ module.exports = function (config) {
|
|||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'../../core/vendor/jquery/dist/jquery.js',
|
||||
'../../core/vendor/underscore/underscore.js',
|
||||
'../../core/vendor/underscore/underscore-min.js',
|
||||
'js/vendor/angular/angular.min.js',
|
||||
'tests/unit/js/mocks/*.js',
|
||||
'js/vendor/angular-mocks/angular-mocks.js',
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"karma-verbose-reporter": "0.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"grunt": "~0.4.5",
|
||||
"grunt": "~1.0.3",
|
||||
"grunt-cli": "~1.2.0",
|
||||
"grunt-contrib-clean": "^1.0.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
|
|
|
@ -12,13 +12,4 @@
|
|||
#requests-table{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.link{
|
||||
color: rgb(0, 102, 255) !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
.link:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
|
@ -32,18 +32,20 @@
|
|||
@import 'share_credential';
|
||||
@import 'settings';
|
||||
|
||||
#app-settings-content:not(.ng-hide) {
|
||||
height: 90px;
|
||||
display: inherit !important;
|
||||
padding: 0;
|
||||
transition: height 0.15s ease-out;
|
||||
|
||||
.template-hidden{
|
||||
display: none !important;
|
||||
}
|
||||
#app-settings-content.ng-hide{
|
||||
|
||||
.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;
|
||||
}
|
||||
|
@ -54,22 +56,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
#app-content #app-content-wrapper #passman-controls {
|
||||
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, .95);
|
||||
z-index: 50;
|
||||
-webkit-user-select: none;
|
||||
|
@ -78,6 +76,15 @@
|
|||
user-select: none;
|
||||
|
||||
height: 44px !important;
|
||||
.breadcrumb{
|
||||
//Move Homeicon to the right to prevent overlap with burgermenu
|
||||
@media only screen and (max-width: 769px) {
|
||||
padding-left: 15px;
|
||||
}
|
||||
.addCredential{
|
||||
padding-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 768px){
|
||||
#passman-controls{
|
||||
|
@ -86,8 +93,8 @@
|
|||
}
|
||||
@media only screen and (min-width: 768px){
|
||||
#app-navigation+#app-content #passman-controls {
|
||||
left: 250px;
|
||||
width: calc( 100% - 250px ) !important;
|
||||
left: 300px;
|
||||
width: calc( 100% - 300px ) !important;
|
||||
}
|
||||
}
|
||||
#passman-controls .button, #passman-controls, #passman-controls input[type='submit'], #passman-controls input[type='text'], #passman-controls input[type='password'], #passman-controls select {
|
||||
|
|
|
@ -20,14 +20,77 @@
|
|||
*
|
||||
*/
|
||||
|
||||
//override nc style to fix wrong offset
|
||||
#content {
|
||||
padding-top: 47px !important; // 45px but +2 because of borders
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
//fix for different heights of passwordicon
|
||||
.icon-image{
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
//fix for ui-element behind Background
|
||||
.angularjs-datetime-picker{
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.link{
|
||||
color:var(--color-primary);
|
||||
}
|
||||
|
||||
|
||||
//this fixes the scrollbars, because passman-contols are shown above the sidebar.
|
||||
#app-sidebar{
|
||||
height: auto;
|
||||
.sidebar{
|
||||
display: inline-block;
|
||||
.sidebar-icon {
|
||||
margin-right: 15px;
|
||||
.icon-image{
|
||||
width: 44px;
|
||||
}
|
||||
i {
|
||||
width: 44px;
|
||||
}
|
||||
}
|
||||
.sidebar-label{
|
||||
float:right;
|
||||
line-height: 44px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vaultlist_sidebar_hidden{
|
||||
width: 100vw !important;
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
#app-content {
|
||||
|
||||
margin-left: 300px;
|
||||
|
||||
@media only screen and (max-width: 769px) {
|
||||
width: 100vw;
|
||||
}
|
||||
@media only screen and (min-width: 770px) {
|
||||
width: calc(100vw - 300px);
|
||||
}
|
||||
|
||||
overflow-x: hidden;
|
||||
|
||||
//width: 100%;
|
||||
#app-content-wrapper {
|
||||
min-height: 95%;
|
||||
display:flex;
|
||||
//hack for missing separatorbar when app-sidebar is opened
|
||||
height: calc(100vh - 49px);
|
||||
|
||||
#passman-controls {
|
||||
text-align: center;
|
||||
&.sidebar-shown {
|
||||
padding-right: 27% !important;
|
||||
//padding-right: 27% !important;
|
||||
.title {
|
||||
@media screen and (max-width: 765px) {
|
||||
display: none;
|
||||
|
@ -53,6 +116,9 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
.breadcrumb {
|
||||
float: left;
|
||||
}
|
||||
.actions.creatable {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
|
@ -108,7 +174,9 @@
|
|||
}
|
||||
|
||||
.searchboxContainer {
|
||||
display: inline-block;
|
||||
/*display: inline-block;*/
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
margin-right: 14px;
|
||||
float: right;
|
||||
.searchbox {
|
||||
|
@ -136,9 +204,9 @@
|
|||
@include border-bottom-radius(3px);
|
||||
}
|
||||
}
|
||||
|
||||
.credential-table {
|
||||
width: 100%;
|
||||
margin-top: 44px;
|
||||
tr:hover {
|
||||
background-color: darken(#fff, 4%);
|
||||
}
|
||||
|
@ -212,7 +280,9 @@
|
|||
}
|
||||
|
||||
.grid-view {
|
||||
margin-top: 44px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
//margin-top: 44px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.credential {
|
||||
|
@ -228,20 +298,26 @@
|
|||
width: 100%;
|
||||
cursor: pointer;
|
||||
font-size: 1.75em;
|
||||
text-align: center;
|
||||
//text-align: center;
|
||||
.label {
|
||||
padding-top: 0.5em;
|
||||
padding-left: 1em;
|
||||
//padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
line-height: 1.3em;
|
||||
word-wrap: break-word;
|
||||
float: right;
|
||||
}
|
||||
.icon{
|
||||
}
|
||||
.tags {
|
||||
margin-bottom: 0.5em;
|
||||
margin: 0 0 auto;
|
||||
text-align: right;
|
||||
//margin-bottom: 0.5em;
|
||||
.tag {
|
||||
color: #000 !important;
|
||||
margin-top: 5px;
|
||||
display: inline-block;
|
||||
left:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +381,9 @@
|
|||
float: left;
|
||||
}
|
||||
}
|
||||
.password-settings-padding-left-fix{
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
}
|
||||
.field-value {
|
||||
.valueInput {
|
||||
|
@ -318,7 +397,7 @@
|
|||
}
|
||||
.selectType {
|
||||
padding-left: 0;
|
||||
margin-left: -4px;
|
||||
margin-left: 0px;
|
||||
select {
|
||||
@include border-left-radius(0);
|
||||
}
|
||||
|
@ -378,8 +457,40 @@
|
|||
.otpText {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.import-selection{
|
||||
select{
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.main_list{
|
||||
flex:1;
|
||||
float:left;
|
||||
height:auto;
|
||||
overflow:auto;
|
||||
width:100%;
|
||||
.share{
|
||||
overflow:hidden;
|
||||
}
|
||||
.nopasswords{
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
margin-top: 10%;
|
||||
text-align: center;
|
||||
}
|
||||
.belowList{
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
margin-top: 1%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.app_sidebar {
|
||||
float:right;
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
font-weight: 400;
|
||||
|
@ -430,12 +541,12 @@
|
|||
|
||||
}
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 70%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.tools {
|
||||
margin-left: 10px;
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
.cell {
|
||||
|
@ -468,7 +579,7 @@
|
|||
width: 120px;
|
||||
margin-top: 30px;
|
||||
margin-left: -60px;
|
||||
top: 50%;
|
||||
top: 30%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
}
|
||||
|
@ -526,13 +637,14 @@
|
|||
}
|
||||
|
||||
.btn-danger {
|
||||
color: #fff;
|
||||
color: #000000;
|
||||
background-color: #ff0000;
|
||||
}
|
||||
|
||||
.icon-label {
|
||||
overflow: hidden;
|
||||
input {
|
||||
width: calc(100% - 45px) !important;
|
||||
width: calc(100% - 28px) !important;
|
||||
float: left;
|
||||
background: #fff;
|
||||
color: #555;
|
||||
|
@ -541,7 +653,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;
|
||||
@include border-left-radius(0)
|
||||
|
@ -549,19 +661,14 @@
|
|||
.icon-picker {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
margin-left: -3px;
|
||||
@include border-left-radius(3px);
|
||||
.cell {
|
||||
height: 32px;
|
||||
padding: 7px 12px 2px 12px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: lighten(#ddd, 5%);
|
||||
cursor: pointer;
|
||||
@include border-left-radius(6px);
|
||||
img {
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
.cell:hover {
|
||||
color: rgb(0, 102, 255);
|
||||
|
@ -589,4 +696,4 @@
|
|||
float: right;
|
||||
width: calc(40% - 10px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,40 +23,90 @@
|
|||
.settings-container {
|
||||
div {
|
||||
padding-left: 15px;
|
||||
|
||||
}
|
||||
button {
|
||||
width: 80%;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-container-label {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
#app-navigation > ul{
|
||||
padding-bottom: 80px;
|
||||
> li > a{
|
||||
padding-left: 12px !important;
|
||||
z-index: auto;
|
||||
}
|
||||
> li {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-trashbin {
|
||||
position: fixed !important;
|
||||
bottom: 44px;
|
||||
//position: fixed !important;
|
||||
//bottom: 44px;
|
||||
width: inherit !important;
|
||||
|
||||
border-right: 1px solid #eee;
|
||||
a {
|
||||
&.active{
|
||||
border-left: 3px solid #0082c9;
|
||||
//border-left: 3px solid #0082c9;
|
||||
background-image: var(--icon-delete-e9322d);
|
||||
}
|
||||
background-color: #fff !important;
|
||||
opacity: 1 !important;
|
||||
z-index: 140;
|
||||
padding: 0 20px;
|
||||
//padding: 0 20px;
|
||||
.fa {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Overrides transparent entry bullet on hover from server
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
li{
|
||||
.app-navigation-entry-bullet-color {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.bullet-color-red {
|
||||
background-color: #ff0000;
|
||||
}
|
||||
|
||||
.bullet-color-yellow {
|
||||
background-color: #ebbb00;
|
||||
}
|
||||
|
||||
.bullet-color-green {
|
||||
background-color: #4db728;
|
||||
}
|
||||
|
||||
.highlight-selected{
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.autocomplete{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
a.taginput{
|
||||
opacity: 1;
|
||||
}
|
||||
|
@ -73,4 +123,13 @@
|
|||
> ul ul {
|
||||
display: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-list{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
//source https://material.io/tools/icons/?icon=restore&style=baseline
|
||||
.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>");
|
||||
}
|
|
@ -36,11 +36,4 @@
|
|||
.button-red:hover{
|
||||
background: lighten(#ce3702, 2%);
|
||||
color: #fff;
|
||||
}
|
||||
.link{
|
||||
color: rgb(0, 102, 255) !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
.link:hover{
|
||||
text-decoration: underline;
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
.pw-gen{
|
||||
overflow:hidden;
|
||||
input{
|
||||
width: calc(100% - 80px) !important;
|
||||
width: calc(100% - 76px) !important;
|
||||
float: left;
|
||||
background: #fff;
|
||||
color: #555;
|
||||
|
@ -41,6 +41,7 @@
|
|||
float: left;
|
||||
margin-top: 3px;
|
||||
margin-left: -3px;
|
||||
padding-bottom:1px;
|
||||
.cell{
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
*/
|
||||
|
||||
.tab_header {
|
||||
margin: 44px 0 0;
|
||||
width: calc(100vw - 300px);
|
||||
// margin: 44px 0 0;
|
||||
margin: 0 0 0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
li.tab:first-child {
|
||||
|
@ -45,9 +47,15 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
li.inactive {
|
||||
background-color: #fff !important;
|
||||
color: unset !important;
|
||||
}
|
||||
|
||||
li.active {
|
||||
color: #fff;
|
||||
position: relative;
|
||||
|
||||
//position: relative;
|
||||
.indicator {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
|
@ -60,10 +68,9 @@
|
|||
}
|
||||
|
||||
.tab_container {
|
||||
border: 1px solid;
|
||||
border-color: #eee;
|
||||
border: 1px solid #eee;
|
||||
border-top-color: #0082c9;
|
||||
border-bottom: 0;
|
||||
border-bottom-width: 0;
|
||||
clear: both;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,16 @@ header {
|
|||
padding-top: 0;
|
||||
}
|
||||
|
||||
.share-controller{
|
||||
width: 100%;
|
||||
.share-container{
|
||||
margin-top: 50px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.credential_container{
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
@ -45,6 +55,7 @@ header {
|
|||
}
|
||||
button, .text{
|
||||
margin: 0 auto;
|
||||
margin-bottom: 25px;
|
||||
display: block;
|
||||
i{
|
||||
margin-right: 5px;
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
}
|
||||
|
||||
.tab_container.settings {
|
||||
textarea{
|
||||
height: 300px;
|
||||
}
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
|
@ -66,4 +69,4 @@
|
|||
text-align: left;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
|
||||
.sharing_table {
|
||||
|
||||
.button{
|
||||
min-height: 42px;
|
||||
margin: 5px 0 0 0;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
width: 55%;
|
||||
|
@ -52,6 +56,10 @@
|
|||
}
|
||||
}
|
||||
.shared_table {
|
||||
.pending{
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.fa-trash {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
padding: 12px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
z-index: 800;
|
||||
z-index: 1800;
|
||||
background-color: red;
|
||||
color: white;
|
||||
.fa-times{
|
||||
|
@ -36,9 +36,8 @@
|
|||
}
|
||||
}
|
||||
.vault_wrapper{
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
margin:0 auto auto auto;
|
||||
|
||||
max-width: 420px;
|
||||
@include border-radius(5px);
|
||||
box-shadow: 0 1px 1px #777;
|
||||
|
|
|
@ -118,60 +118,121 @@ style('passman', 'app');
|
|||
?>
|
||||
|
||||
<div id="app" ng-app="passmanApp" ng-controller="MainCtrl">
|
||||
<div id="logoutTimer"> </div>
|
||||
<div class="warning_bar" ng-if="using_http && http_warning_hidden == false">
|
||||
{{ 'http.warning' | translate }}
|
||||
<i class="fa fa-times fa-2x" alt="Close" ng-click="setHttpWarning(true);"></i>
|
||||
</div>
|
||||
<div id="logoutTimer"></div>
|
||||
<div id="warning_bar" class="warning_bar template-hidden" ng-if="using_http && http_warning_hidden == false" ng-init="removeHiddenStyles()">
|
||||
{{ 'http.warning' | translate }}
|
||||
<i class="fa fa-times fa-2x" alt="Close" ng-click="setHttpWarning(true);"></i>
|
||||
</div>
|
||||
|
||||
<div id="app-navigation" ng-show="selectedVault" ng-controller="MenuCtrl">
|
||||
<ul>
|
||||
<li class="taginput">
|
||||
<a class="taginput">
|
||||
<tags-input ng-model="selectedTags" replace-spaces-with-dashes="false">
|
||||
<auto-complete source="getTags($query)" min-length="0"></auto-complete>
|
||||
</tags-input>
|
||||
</a>
|
||||
</li>
|
||||
<div id="app-navigation" class="template-hidden" ng-if="selectedVault" ng-controller="MenuCtrl" ng-init="removeHiddenStyles()">
|
||||
<ul class="with-icon" ng-class="{ 'hidden-list': !legacyNavbar }" >
|
||||
|
||||
<li ng-repeat="tag in available_tags | orderBy:'text'" ng-if="selectedTags.indexOf(tag) == -1">
|
||||
<a class="nav-icon-systemtagsfilter svg" ng-click="tagClicked(tag)">{{tag.text}}</a>
|
||||
</li>
|
||||
<li data-id="trashbin" class="nav-trashbin">
|
||||
<a ng-click="toggleDeleteTime()"
|
||||
ng-class="{'active': delete_time > 0}">
|
||||
<i href="#" class="fa fa-trash"></i>
|
||||
{{ 'deleted.credentials' | translate }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<li>
|
||||
<a ng-class="{selected: clickedNavigationItem=='all'}" class="icon-toggle svg" ng-click="filterCredentialBySpecial('all')">{{ 'navigation.show.all' | translate }}</a>
|
||||
</li>
|
||||
<li class="collapsible" ng-class="tagCollapsibleState()">
|
||||
<button class="collapse" ng-click="tagCollapsibleClicked()"></button>
|
||||
<a href="" class="icon-tag" ng-click="tagCollapsibleClicked()">{{ 'navigation.tags' | translate }}</a>
|
||||
<ul>
|
||||
<li class="taginput">
|
||||
<a class="icon-search taginput">
|
||||
<form ng-submit="tagClickedString(taginput); clearForm();">
|
||||
<input id="tagsearch" list="tags" ng-model="taginput" placeholder="{{ 'navigation.tags.search' | translate }}" />
|
||||
<datalist id="tags">
|
||||
<option ng-repeat="qtag in getTags($query)" value="{{qtag.text}}">
|
||||
</datalist>
|
||||
</form>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<div id="app-settings" ng-init="settingsShown = false;">
|
||||
<div id="app-settings-header">
|
||||
<button class="settings-button"
|
||||
ng-click="settingsShown = !settingsShown"
|
||||
>{{ 'settings' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div id="app-settings-content" ng-show="settingsShown">
|
||||
<!-- Your settings in here -->
|
||||
<div class="settings-container">
|
||||
<div><a class="link" ng-href="#/vault/{{active_vault.guid}}/settings">{{ 'settings' | translate }}</a></div>
|
||||
<div><span class="link" ng-click="logout()">{{'logout' | translate }}</span></div>
|
||||
<div><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank" class="link">{{ 'donate' | translate }}</a></div>
|
||||
<div ng-show="session_time_left">
|
||||
<small>{{'session.time.left' | translate:translationData}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li ng-repeat="tag in available_tags | orderBy:'text'">
|
||||
<div ng-if="tagSelected(tag)"
|
||||
class="app-navigation-entry-bullet app-navigation-entry-bullet-color"></div>
|
||||
<a class="icon-tag svg" ng-click="tagClicked(tag)">{{tag.text}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<div class="app-navigation-entry-bullet bullet-color-red"></div>
|
||||
<a ng-class="{selected: clickedNavigationItem=='strength_low'}" ng-click="filterCredentialBySpecial('strength_low')">{{ 'navigation.strength.bad' | translate }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="app-navigation-entry-bullet bullet-color-yellow"></div>
|
||||
<a ng-class="{selected: clickedNavigationItem=='strength_medium'}" ng-click="filterCredentialBySpecial('strength_medium')">{{ 'navigation.strength.medium' | translate }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="app-navigation-entry-bullet bullet-color-green"></div>
|
||||
<a ng-class="{selected: clickedNavigationItem=='strength_good'}" ng-click="filterCredentialBySpecial('strength_good')">{{ 'navigation.strength.good' | translate }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-class="{selected: clickedNavigationItem=='expired'}" class="icon-expired svg" ng-click="filterCredentialBySpecial('expired')">{{ 'navigation.expired' | translate }}</a>
|
||||
</li>
|
||||
<li data-id="trashbin" class="nav-trashbin pinned first-pinned">
|
||||
<a ng-click="toggleDeleteTime()" ng-class="{'active': delete_time > 0}" class="icon-delete svg">
|
||||
{{ 'deleted.credentials' | translate }}
|
||||
</a>
|
||||
</li>
|
||||
</ul >
|
||||
<ul class="with-icon hidden-list" ng-class="{ 'hidden-list': legacyNavbar }">
|
||||
<li class="taginput">
|
||||
<a class="taginput icon-search">
|
||||
<tags-input id="tags-input-outer" ng-model="selectedTags" replace-spaces-with-dashes="false" ng-init="initPlaceholder()">
|
||||
<auto-complete source="getTags($query)" min-length="0"></auto-complete>
|
||||
</tags-input>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-repeat="tag in available_tags | orderBy:'text'" ng-if="selectedTags.indexOf(tag) == -1">
|
||||
<a class="icon-tag svg" ng-click="tagClicked(tag)">{{tag.text}}</a>
|
||||
</li>
|
||||
<li data-id="trashbin" class="nav-trashbin pinned first-pinned">
|
||||
<a ng-click="toggleDeleteTime()" ng-class="{'active': delete_time > 0}" class="icon-delete svg">
|
||||
{{ 'deleted.credentials' | translate }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="app-content">
|
||||
<div id="app-content-wrapper">
|
||||
<div id="content" ng-view="">
|
||||
<div id="app-settings" ng-init="settingsShown = false;">
|
||||
<div id="app-settings-header">
|
||||
<button class="settings-button"
|
||||
ng-click="settingsShown = !settingsShown"
|
||||
>{{ 'settings' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div id="app-settings-content" class="hide-animation" ng-hide="!settingsShown">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-container-label">
|
||||
<input class="checkbox" id="navbarLegacyMode" type="checkbox" ng-model="legacyNavbar">
|
||||
<label for="navbarLegacyMode">{{'navigation.advanced.checkbox' | translate }}</label>
|
||||
</div>
|
||||
|
||||
<div class="settings-container">
|
||||
<a ng-href="#/vault/{{active_vault.guid}}/settings" class="link" ng-click="settingsShown = false;">
|
||||
<button>{{ 'settings' | translate }}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="settings-container">
|
||||
<button ng-click="logout()"><span class="link">{{'logout' | translate }}</span></button>
|
||||
</div>
|
||||
<div class="donation-container settings-container">
|
||||
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2"
|
||||
target="_blank" class="link" ng-click="settingsShown = false;">
|
||||
<button class="donation-container">{{ 'donate' | translate }}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="settings-container">
|
||||
<div ng-show="session_time_left">
|
||||
<small>{{'session.time.left' | translate:translationData}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="app-content" ng-class="{'vaultlist_sidebar_hidden': !selectedVault}">
|
||||
<div id="app-content-wrapper">
|
||||
<div id="content" ng-view="">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -66,8 +66,9 @@ style('passman', 'app');
|
|||
style('passman', 'public-page');
|
||||
|
||||
?>
|
||||
<div ng-app="passmanApp" ng-controller="PublicSharedCredential">
|
||||
<div class="row">
|
||||
<div class="share-controller" ng-app="passmanApp" ng-controller="PublicSharedCredential">
|
||||
<div class="share-container">
|
||||
<div class="row">
|
||||
<div class="col-xs-8 col-xs-push-2 col-xs-pull-2 credential_container">
|
||||
<h2>Passman</h2>
|
||||
<div ng-if="!shared_credential && !expired">
|
||||
|
@ -204,4 +205,5 @@ style('passman', 'public-page');
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
<div id="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 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>
|
||||
</div>
|
||||
|
||||
|
||||
<div off-click="closeSelected()">
|
||||
<table class="credential-table" ng-init="menuOpen = false;">
|
||||
<tr ng-repeat="revision in revisions | orderBy:'-created'"
|
||||
ng-click="selectRevision(revision)"
|
||||
|
@ -31,9 +29,10 @@
|
|||
<td>{{ 'no.revisions' | translate}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="app-sidebar" class="detailsView scroll-container app_sidebar"
|
||||
ng-show="selectedRevision">
|
||||
<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>
|
||||
|
@ -237,4 +236,4 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<div id="controls">
|
||||
<div class="actions creatable">
|
||||
<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>
|
||||
|
@ -13,11 +14,13 @@
|
|||
<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="{active:isActiveTab(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>
|
||||
|
@ -29,3 +32,4 @@
|
|||
<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>
|
||||
|
|
|
@ -47,10 +47,14 @@
|
|||
|
||||
<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"
|
||||
class="link" ng-click="downloadFile(credential, file)">
|
||||
{{file.filename}} ({{file.size | bytes}})
|
||||
</div></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">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</select></label>
|
||||
<div><b>{{selectedExporter.description}}</b></div>
|
||||
|
||||
<div ng-show="selectedExporter" class="col-xs-3 nopadding">
|
||||
<div ng-show="selectedExporter" class="nopadding">
|
||||
<label>{{ 'export.confirm.text' | translate }}</label>
|
||||
<input type="password" ng-model="confirm_key">
|
||||
<br />
|
||||
|
@ -33,4 +33,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,16 +8,16 @@
|
|||
<div ng-controller="ImportCtrl" ng-show="!showGenericImport">
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<label>{{ 'import.type' | translate}}
|
||||
<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>
|
||||
|
||||
</select></label>
|
||||
</div>
|
||||
<div ng-show="selectedImporter">
|
||||
<b>{{ 'import.steps' | translate }}</b>
|
||||
<ul class="import-steps">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="password_settings">
|
||||
<div class="col-xs-12 col-sm-5 col-lg-4">
|
||||
<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">
|
||||
|
|
|
@ -28,15 +28,17 @@
|
|||
<tr ng-repeat="result in scan_result | orderBy:'password_zxcvbn_result.score'">
|
||||
<td>{{result.label}}</td>
|
||||
<td class="score">
|
||||
<ng-password-meter
|
||||
password="result.password"></ng-password-meter>
|
||||
<ng-password-meter password="result.password"></ng-password-meter>
|
||||
</td>
|
||||
<td>
|
||||
<span credential-field value="result.password"
|
||||
secret="'true'"></span>
|
||||
<span credential-field value="result.password" secret="'true'"></span>
|
||||
</td>
|
||||
<td>
|
||||
<a class="link" ng-href="#/vault/{{active_vault.guid}}/edit/{{result.guid}}" tooltip="{{ 'edit.credential' | translate}}"><i class="fa fa-edit"></i></a>
|
||||
<div>
|
||||
<a href="#/vault/{{ active_vault.guid }}/edit/{{result.guid}}" class="link">
|
||||
<i class="fa fa-edit"></i>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<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 col-xs-4">{{ 'pending' | translate}}</small>
|
||||
<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>
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<div>
|
||||
<div class="cell">
|
||||
<credential-icon credential="credential"></credential-icon>
|
||||
</div>
|
||||
<div style="display: none" id="iconPicker" title="{{ 'pick.icon' | translate }}">
|
||||
<div class="cell icon-category-auth"></div>
|
||||
<div style="display: none" id="iconPicker" title="{{ 'pick.icon' | translate }}">
|
||||
<div class="iconList">
|
||||
<div ng-repeat="(groupName, icons) in iconGroups">
|
||||
<h2 style="clear: both" id="{{groupName}}">{{groupName}}</h2>
|
||||
|
@ -25,4 +22,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,29 +1,30 @@
|
|||
<div id="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="cancel()">{{active_vault.name}}</a>
|
||||
</div>
|
||||
<div class="crumb svg last">
|
||||
<a>{{ 'settings' | translate}}</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}}
|
||||
<div class="indicator" use-theme negative="'true'"></div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="tab_container settings edit_credential">
|
||||
<div ng-include="currentTab.url"></div>
|
||||
<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>
|
|
@ -1,4 +1,5 @@
|
|||
<div id="controls">
|
||||
<div class="main_list.share">
|
||||
<div id="passman-controls">
|
||||
<div class="actions creatable">
|
||||
<div class="breadcrumb">
|
||||
<div class="crumb svg ui-droppable" data-dir="/">
|
||||
|
@ -15,21 +16,19 @@
|
|||
</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}}
|
||||
<div class="indicator" use-theme negative="'true'"></div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="tab_container share_credential" ng-show="currentTab">
|
||||
<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>
|
||||
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
<div off-click="closeSelected()" off-click-filter="'.download-js-link, .sidebar-shown'">
|
||||
<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 last" ng-click="clearState()">
|
||||
<span>{{active_vault.name}}</span>
|
||||
<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="actions creatable">
|
||||
<span ng-click="addCredential()" class="button new">
|
||||
<span >+</span></span>
|
||||
</div>
|
||||
<div class="title" credential-counter="filtered_credentials" vault="active_vault" delete-time="delete_time" filters="filterOptions"></div>
|
||||
<!--<span class="title" ng-if="delete_time"><br />
|
||||
{{ 'deleted.since' | translate }}:
|
||||
<span ng-if="delete_time == 1">All time</span>
|
||||
<span ng-if="delete_time > 1">{{delete_time | date:'dd-MM-yyyy @ HH:mm:ss'}}</span>
|
||||
|
||||
</span> -->
|
||||
<div 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;">
|
||||
|
@ -29,6 +24,7 @@
|
|||
<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>
|
||||
|
@ -60,7 +56,7 @@
|
|||
<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>
|
||||
<span class="label">{{ ::credential.label}}</span>
|
||||
<a class="label">{{ ::credential.label}}</a>
|
||||
|
||||
|
||||
</td>
|
||||
|
@ -74,7 +70,17 @@
|
|||
ng-click="selectCredential(credential)"
|
||||
use-theme type="'border-color'">
|
||||
<div class="credential_content">
|
||||
<div class="label">{{ ::credential.label}}</div>
|
||||
<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}}
|
||||
|
@ -83,58 +89,108 @@
|
|||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="app-sidebar" class="detailsView scroll-container app_sidebar"
|
||||
ng-show="selectedCredential">
|
||||
<h2>{{selectedCredential.label}}</h2>
|
||||
<span class="close icon-close" ng-click="closeSelected()"
|
||||
alt="Close"></span>
|
||||
|
||||
<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 &&
|
||||
(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 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>
|
||||
|
||||
<!--nopassword-hint for missing tagresults -->
|
||||
<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>
|
||||
|
||||
<!--nopassword-hint for missing searchresults -->
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<!--nopassword-hint for good strength -->
|
||||
<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>
|
||||
|
||||
<!--nopassword-hint for medium strength -->
|
||||
<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>
|
||||
|
||||
<!--nopassword-hint for bad strength -->
|
||||
|
||||
<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>
|
||||
|
||||
<!--nopassword-hint for expired -->
|
||||
<div class="nopasswords" ng-if="no_credentials_label.expired" ng-hide="getListSizes().listsize_wout_deleted>0">
|
||||
<div>{{ 'vault.hint.list.noexpired' | translate}}</div>
|
||||
</div>
|
||||
|
||||
<!--nopassword-hint for deleted -->
|
||||
<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="selectedCredential"></credential-icon>
|
||||
</span>
|
||||
<span class="icon sidebar-icon" ng-if="!selectedCredential.url">
|
||||
<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 &&
|
||||
(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">
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
<li ng-if="vaults.length === 0">{{ 'no.vaults' | translate}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -58,7 +57,7 @@
|
|||
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" >
|
||||
<div class="button" ng-if="creating_keys">
|
||||
<span>
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
{{creating_keys}}
|
||||
|
@ -67,7 +66,7 @@
|
|||
<div class="button button-red" ng-click="clearState()">
|
||||
{{ 'cancel' | translate}}
|
||||
</div>
|
||||
<div class="hidden">
|
||||
<div class="template-hidden">
|
||||
{{sharing_keys}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
describe('MenuCtrl', function() {
|
||||
beforeEach(module('passmanApp'));
|
||||
beforeEach(module('LocalStorageModule'));
|
||||
beforeEach(module('mock.vaultService'));
|
||||
|
||||
var $controller;
|
||||
var $scope;
|
||||
beforeEach(inject(function(_$controller_){
|
||||
beforeEach(inject(function(_$controller_, _VaultService_){
|
||||
// The injector unwraps the underscores (_) from around the parameter names when matching
|
||||
$controller = _$controller_;
|
||||
//$controller.VaultService= _VaultService_;
|
||||
}));
|
||||
beforeEach(inject(function($rootScope) {
|
||||
$scope = $rootScope.$new();
|
||||
|
|
|
@ -730,9 +730,11 @@ var OC={
|
|||
* After 7sec the first notification is gone, then we can show another one
|
||||
* if necessary.
|
||||
*/
|
||||
_ajaxConnectionLostHandler: _.throttle(function() {
|
||||
OC.Notification.showTemporary(t('core', 'Connection to server lost'));
|
||||
}, 7 * 1000, {trailing: false}),
|
||||
_ajaxConnectionLostHandler: function(underscore){
|
||||
underscore.throttle(function() {
|
||||
OC.Notification.showTemporary(t('core', 'Connection to server lost'));
|
||||
}, 7 * 1000, {trailing: false});
|
||||
},
|
||||
|
||||
/**
|
||||
* Process ajax error, redirects to main page
|
||||
|
@ -761,7 +763,7 @@ var OC={
|
|||
// Connection lost (e.g. WiFi disconnected or server is down)
|
||||
setTimeout(function() {
|
||||
if (!self._userIsNavigatingAway && !self._reloadCalled) {
|
||||
self._ajaxConnectionLostHandler();
|
||||
self._ajaxConnectionLostHandler(_);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
|
17
tests/unit/js/mocks/VaultService.js
Normal file
17
tests/unit/js/mocks/VaultService.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
angular.module('mock.vaultService', []).
|
||||
service('VaultService', function($q) {
|
||||
var vaultService = {};
|
||||
var settings = {};
|
||||
vaultService.getVaultSetting = function (key, default_value) {
|
||||
if (settings[key]) {
|
||||
return $q.when(settings[key]);
|
||||
} else {
|
||||
return $q.when(default_value);
|
||||
}
|
||||
};
|
||||
vaultService.setVaultSetting = function (key, value) {
|
||||
settings[key]=value;
|
||||
};
|
||||
|
||||
return vaultService;
|
||||
});
|
Loading…
Add table
Reference in a new issue