Merge branch 'sharing_no_groups' of github.com:nextcloud/passman into sharing_no_groups

This commit is contained in:
Marcos Zuriaga 2016-10-03 14:00:07 +02:00
commit e38885ed41
No known key found for this signature in database
GPG key ID: 7D15585354D072FF
14 changed files with 477 additions and 6 deletions

View file

@ -42,6 +42,13 @@ module.exports = function (grunt) {
src: ["**/bookmarklet.scss"],
dest: "css",
ext: ".css"
},
{
expand: true,
cwd: "sass",
src: ["**/public-page.scss"],
dest: "css",
ext: ".css"
}
]
}

View file

@ -21,6 +21,7 @@ return [
'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
['name' => 'page#bookmarklet', 'url' => '/bookmarklet', 'verb' => 'GET'],
['name' => 'page#publicSharePage', 'url' => '/share/public', 'verb' => 'GET'],
//Vault
['name' => 'vault#listVaults', 'url' => '/api/v2/vaults', 'verb' => 'GET'],

View file

@ -48,7 +48,16 @@ class PageController extends Controller {
*/
public function bookmarklet($url='',$title='') {
$params = array('url' => $url, 'label' => $title);
return new TemplateResponse('passman', 'bookmarklet', $params);
}
/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
*/
public function publicSharePage($shareKey) {
return new TemplateResponse('passman', 'public_share');
}
}

65
css/public-page.css Normal file
View file

@ -0,0 +1,65 @@
header {
display: none; }
#content-wrapper {
padding-top: 0; }
.credential_container {
margin-top: 20px;
margin-bottom: 20px;
padding: 20px;
background: #f8f8f8;
border: 1px solid #c9c9c9;
-webkit-border-radius: 5px;
border-radius: 5px;
background-clip: padding-box;
/* stops bg color from leaking outside the border: */ }
.credential_container .text {
text-align: center; }
.credential_container h2 {
font-weight: bold; }
.credential_container button, .credential_container .text {
margin: 0 auto;
display: block; }
.credential_container button i, .credential_container .text i {
margin-right: 5px; }
.credential_field {
overflow: hidden; }
.credential_field .cell, .credential_field .value {
float: left; }
.credential_field .tools {
margin-left: 10px;
overflow: hidden;
float: left; }
.credential_field .tools .cell {
cursor: pointer;
margin-right: 4px; }
table {
white-space: normal; }
table td:first-child {
min-width: 110px; }
table td {
padding-bottom: 1em;
vertical-align: top; }
.tags .tag {
background-color: rgba(240, 240, 240, 0.9);
padding: 4px;
font-size: 12px;
margin-right: 3px;
-webkit-border-radius: 5px;
border-radius: 5px;
background-clip: padding-box;
/* stops bg color from leaking outside the border: */ }
.tags .tag:last-child {
margin-right: 8px; }
.footer {
font-size: 10px;
position: relative;
bottom: -20px;
text-align: center; }
/*# sourceMappingURL=public-page.css.map */

7
css/public-page.css.map Normal file
View file

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAEA,MAAO;EACL,OAAO,EAAE,IAAI;;AAGf,gBAAiB;EACf,WAAW,EAAE,CAAC;;AAGhB,qBAAqB;EACnB,UAAU,EAAE,IAAI;EAChB,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,iBAAiB;ECJzB,qBAAqB,EDKE,GAAG;ECJ1B,aAAa,EDIU,GAAG;ECH1B,eAAe,EAAE,WAAW;EAAG,qDAAqD;EDIpF,2BAAK;IACJ,UAAU,EAAE,MAAM;EAEnB,wBAAE;IACA,WAAW,EAAE,IAAI;EAEnB,yDAAa;IACX,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,KAAK;IACd,6DAAC;MACC,YAAY,EAAE,GAAG;;AAKvB,iBAAkB;EAChB,QAAQ,EAAE,MAAM;EAChB,iDAAc;IACZ,KAAK,EAAE,IAAI;EAEb,wBAAO;IACL,WAAW,EAAE,IAAI;IACjB,QAAQ,EAAE,MAAM;IAChB,KAAK,EAAE,IAAI;IACX,8BAAM;MACJ,MAAM,EAAE,OAAO;MACf,YAAY,EAAE,GAAG;;AAIvB,KAAK;EACF,WAAW,EAAE,MAAM;EAClB,oBAAc;IACZ,SAAS,EAAE,KAAK;EAElB,QAAE;IACA,cAAc,EAAE,GAAG;IACnB,cAAc,EAAE,GAAG;;AAKvB,UAAK;EACH,gBAAgB,EAAE,wBAAuB;EACzC,OAAO,EAAE,GAAG;EACZ,SAAS,EAAE,IAAI;EACf,YAAY,EAAE,GAAG;ECpDnB,qBAAqB,EDqDI,GAAG;ECpD5B,aAAa,EDoDY,GAAG;ECnD5B,eAAe,EAAE,WAAW;EAAG,qDAAqD;ADqDpF,qBAAgB;EACd,YAAY,EAAE,GAAG;;AAGrB,OAAO;EACL,SAAS,EAAE,IAAI;EACf,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,MAAM",
"sources": ["../sass/public-page.scss","../sass/mixins.scss"],
"names": [],
"file": "public-page.css"
}

14
js/app/app_public.js Normal file
View file

@ -0,0 +1,14 @@
'use strict';
angular
.module('passmanApp', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'ngclipboard',
]).config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
}]);

View file

@ -214,7 +214,7 @@ angular.module('passmanApp')
$scope.saveCredential = function () {
//@TODO validation
//@TODO When credential is expired and has renew interval set, calc new expire time.
console.log(JSON.stringify($scope.storedCredential));
delete $scope.storedCredential.password_repeat;
if (!$scope.storedCredential.credential_id) {
$scope.storedCredential.vault_id = $scope.active_vault.vault_id;

View file

@ -0,0 +1,89 @@
/**
* @ngdoc function
* @name passmanApp.controller:MainCtrl
* @description
* # MainCtrl
* Controller of the passmanApp
*/
angular.module('passmanApp')
.controller('PublicSharedCredential', ['$scope', 'ShareService', function ($scope, ShareService) {
$scope.test = 'hello world';
$scope.loading = false;
var example_shared_credential = {
"credential_id": 292,
"guid": "3D18EAD3-CF40-4B2B-B568-82CD7CB3D47F",
"user_id": "sander",
"vault_id": 2,
"label": "donnelly.com",
"description": null,
"created": 1475479693,
"changed": 1475479693,
"tags": [{"text": "Games"}],
"email": null,
"username": "ebrekke",
"password": "hd%/U_%vzvh%",
"url": "http://api.namefake.com/english-united-states/male/2854dda4938c9c5f60a288fa6fbe5095",
"favicon": null,
"renew_interval": null,
"expire_time": 0,
"delete_time": 0,
"files": [{
"file_id": 1,
"filename": "20160925-Clipperz_Export.html",
"guid": "6DA2CE41-A26B-4F97-A334-2CC74F7E9890",
"size": 13863,
"created": 1475485368,
"mimetype": "text/html",
"$$hashKey": "object:1261"
}, {
"file_id": 2,
"filename": "20160925_Clipperz_Offline.html",
"guid": "9337D189-B79E-4750-BEF9-3C912A9EA59D",
"size": 3088428,
"created": 1475485376,
"mimetype": "text/html",
"$$hashKey": "object:1268"
}],
"custom_fields": [{
"label": "Test field",
"value": "blah blah",
"secret": false,
"$$hashKey": "object:1205"
}, {
"label": "another field =)",
"value": "vlaue",
"secret": true,
"$$hashKey": "object:1220"
}],
"otp": {
"type": "totp",
"label": "Google:fake@gmail.com",
"qr_uri": {
"qrData": "otpauth://totp/Google%3Afake%40gmail.com?secret=oyonyttithtryvpnqqrxluytgwon2mhw&issuer=Google",
"image": ""
},
"secret": "oyonyttithtryvpnqqrxluytgwon2mhw",
"issuer": "Google"
},
"hidden": 0,
"shared_key": null,
"tags_raw": [{"text": "Games"}]
};
$scope.loadSharedCredential = function () {
$scope.loading = true;
ShareService.getPublicSharedCredential().then(function (sharedCredential) {
//Decrypt stuff here
//And then set it
$scope.loading = false;
$scope.shared_credential = example_shared_credential;
})
}
}])
;

View file

@ -59,8 +59,8 @@ angular.module('passmanApp')
$location.path('/vault/' + $scope.storedCredential.vault_id);
};
console.log($location);
$scope.share_link = $location.$$protocol + '://'+ $location.$$host + OC.generateUrl('apps/passman/share/public#') + $scope.storedCredential.guid;
$scope.share_settings = {
linkSharing:{
enabled: false,

View file

@ -67,6 +67,16 @@ angular.module('passmanApp')
return response.data;
})
},
getPublicSharedCredential: function (request, crypted_shared_key) {
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/public/view');
return $http.get(queryUrl).then(function (response) {
if (response.data) {
return response.data;
} else {
return response;
}
});
},
getCredendialsSharedWithUs: function (vault_guid) {
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/'+ vault_guid +'/get');
return $http.get(queryUrl).then(function (response) {

View file

@ -89,7 +89,7 @@ angular.module('views/partials/forms/share_credential/basics.html', []).run(['$t
angular.module('views/partials/forms/share_credential/expire_settings.html', []).run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('views/partials/forms/share_credential/expire_settings.html',
'<div class="row"><div class="col-xs-12 col-md-6"><input type="checkbox" ng-model="share_settings.linkSharing.enabled"> Enable link sharing.<div>Expire settings:<select ng-model="share_settings.linkSharing.settings.type"><option value="null">Does not expire</option><option value="view_amount">Expire after a certain amount of views</option><option value="date">Expire after a date</option></select></div><div ng-show="share_settings.linkSharing.settings.type == \'date\'">Share until date <span datetime-picker ng-model="share_settings.linkSharing.settings.value" class="link" future-only ng-show="!share_settings.linkSharing.settings.value" close-on-select="false">No expire date set</span></div><div ng-show="share_settings.linkSharing.settings.type == \'view_amount\'">Share until views <input type="number" ng-model="share_settings.linkSharing.settings.value"></div></div></div>');
'<div class="row"><div class="col-xs-12 col-md-6"><input type="checkbox" ng-model="share_settings.linkSharing.enabled"> Enable link sharing.<br><input type="text" ng-model="share_link" select-on-click ng-if="share_settings.linkSharing.enabled"><div>Expire settings:<select ng-model="share_settings.linkSharing.settings.type"><option value="null">Does not expire</option><option value="view_amount">Expire after a certain amount of views</option><option value="date">Expire after a date</option></select></div><div ng-show="share_settings.linkSharing.settings.type == \'date\'">Share until date <span datetime-picker ng-model="share_settings.linkSharing.settings.value" class="link" future-only ng-show="!share_settings.linkSharing.settings.value" close-on-select="false">No expire date set</span></div><div ng-show="share_settings.linkSharing.settings.type == \'view_amount\'">Share until views <input type="number" ng-model="share_settings.linkSharing.settings.value"></div></div></div>');
}]);
angular.module('views/partials/password-meter.html', []).run(['$templateCache', function($templateCache) {

76
sass/public-page.scss Normal file
View file

@ -0,0 +1,76 @@
@import 'variables';
@import 'mixins';
header {
display: none;
}
#content-wrapper {
padding-top: 0;
}
.credential_container{
margin-top: 20px;
margin-bottom: 20px;
padding: 20px;
background: #f8f8f8;
border: 1px solid #c9c9c9;
@include border-radius(5px);
.text{
text-align: center;
}
h2{
font-weight: bold;
}
button, .text{
margin: 0 auto;
display: block;
i{
margin-right: 5px;
}
}
}
.credential_field {
overflow: hidden;
.cell, .value {
float: left;
}
.tools {
margin-left: 10px;
overflow: hidden;
float: left;
.cell {
cursor: pointer;
margin-right: 4px;
}
}
}
table{
white-space: normal;
td:first-child{
min-width: 110px;
}
td{
padding-bottom: 1em;
vertical-align: top;
}
}
.tags {
.tag {
background-color: rgba(240, 240, 240, .9);
padding: 4px;
font-size: 12px;
margin-right: 3px;
@include border-radius(5px);
}
.tag:last-child {
margin-right: 8px;
}
}
.footer{
font-size: 10px;
position: relative;
bottom: -20px;
text-align: center;
}

192
templates/public_share.php Normal file
View file

@ -0,0 +1,192 @@
<?php
/*
* Javascripts
*/
script('passman', 'vendor/angular/angular.min');
script('passman', 'vendor/angular-animate/angular-animate.min');
script('passman', 'vendor/angular-cookies/angular-cookies.min');
script('passman', 'vendor/angular-resource/angular-resource.min');
script('passman', 'vendor/angular-route/angular-route.min');
script('passman', 'vendor/angular-sanitize/angular-sanitize.min');
script('passman', 'vendor/angular-touch/angular-touch.min');
script('passman', 'vendor/angular-local-storage/angular-local-storage.min');
script('passman', 'vendor/angular-off-click/angular-off-click.min');
script('passman', 'vendor/angularjs-datetime-picker/angularjs-datetime-picker.min');
script('passman', 'vendor/ng-password-meter/ng-password-meter');
script('passman', 'vendor/sjcl/sjcl');
script('passman', 'vendor/zxcvbn/zxcvbn');
script('passman', 'vendor/ng-clipboard/clipboard.min');
script('passman', 'vendor/ng-clipboard/ngclipboard');
script('passman', 'vendor/ng-tags-input/ng-tags-input.min');
script('passman', 'vendor/angular-xeditable/xeditable.min');
script('passman', 'vendor/sha/sha');
script('passman', 'vendor/llqrcode/llqrcode');
script('passman', 'vendor/forge.0.6.9.min');
script('passman', 'lib/promise');
script('passman', 'lib/crypto_wrap');
script('passman', 'app/app_public');
script('passman', 'app/controllers/public_shared_credential');
script('passman', 'app/filters/range');
script('passman', 'app/filters/propsfilter');
script('passman', 'app/filters/byte');
script('passman', 'app/services/vaultservice');
script('passman', 'app/services/credentialservice');
script('passman', 'app/services/settingsservice');
script('passman', 'app/services/fileservice');
script('passman', 'app/services/encryptservice');
script('passman', 'app/services/tagservice');
script('passman', 'app/services/notificationservice');
script('passman', 'app/services/shareservice');
script('passman', 'app/directives/otp');
script('passman', 'app/directives/tooltip');
script('passman', 'app/directives/use-theme');
script('passman', 'app/directives/credentialfield');
script('passman', 'app/directives/ngenter');
/*
* Styles
*/
style('passman', 'vendor/ng-password-meter/ng-password-meter');
style('passman', 'vendor/bootstrap/bootstrap.min');
style('passman', 'vendor/bootstrap/bootstrap-theme.min');
style('passman', 'vendor/font-awesome/font-awesome.min');
style('passman', 'vendor/angular-xeditable/xeditable.min');
style('passman', 'vendor/ng-tags-input/ng-tags-input.min');
style('passman', 'vendor/angularjs-datetime-picker/angularjs-datetime-picker');
style('passman', 'app');
style('passman', 'public-page');
?>
<div ng-app="passmanApp" ng-controller="PublicSharedCredential">
<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">
<span class="text">{name} has shared a credential with you.</span>
<button class="button-geen" ng-if="!loading"
ng-click="loadSharedCredential()">Click here to request
it
</button>
<button class="button-geen" ng-if="loading"><i
class="fa fa-spinner fa-spin"></i>Loading...
</button>
</div>
<div ng-if="shared_credential">
<table class="table">
<tr ng-show="shared_credential.label">
<td>
Label
</td>
<td>
{{shared_credential.label}}
</td>
</tr>
<tr ng-show="shared_credential.username">
<td>
Account
</td>
<td>
<span credential-field
value="shared_credential.username"></span>
</td>
</tr>
<tr ng-show="shared_credential.password">
<td>
Password
</td>
<td>
<span credential-field value="shared_credential.password"
secret="'true'"></span>
</td>
</tr>
<tr ng-show="shared_credential.otp.secret">
<td>
OTP
</td>
<td>
<span otp-generator
secret="shared_credential.otp.secret"></span>
</td>
</tr>
<tr ng-show="shared_credential.email">
<td>
E-mail
</td>
<td>
<span credential-field
value="shared_credential.email"></span>
</td>
</tr>
<tr ng-show="shared_credential.url">
<td>
URL
</td>
<td>
<span credential-field
value="shared_credential.url"></span>
</td>
</tr>
<tr ng-show="shared_credential.files.length > 0">
<td>
Files
</td>
<td>
<div ng-repeat="file in shared_credential.files"
class="link" ng-click="downloadFile(file)">
{{file.filename}} ({{file.size | bytes}})
</div>
</td>
</tr>
<tr ng-repeat="field in shared_credential.custom_fields">
<td>
{{field.label}}
</td>
<td>
<span credential-field value="field.value"
secret="field.secret"></span>
</td>
</tr>
<tr ng-show="shared_credential.expire_time > 0">
<td>
Expire time
</td>
<td>
{{shared_credential.expire_time * 1000 |
date:'dd-MM-yyyy @ HH:mm:ss'}}
</td>
</tr>
<tr ng-show="shared_credential.changed">
<td>
Changed
</td>
<td>
{{shared_credential.changed * 1000 |
date:'dd-MM-yyyy @ HH:mm:ss'}}
</td>
</tr>
<tr ng-show="shared_credential.created">
<td>
Created
</td>
<td>
{{shared_credential.created * 1000 |
date:'dd-MM-yyyy @ HH:mm:ss'}}
</td>
</tr>
</table>
<div class="tags">
<span class="tag" ng-repeat="tag in shared_credential.tags">{{tag.text}}</span>
</div>
</div>
<div class="footer">
<a href="https://github.com/nextcloud/passman" target="_blank" class="link">Github</a> | <a href="https://github.com/nextcloud/passman/wiki" target="_blank" class="link">Wiki</a> | <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2" target="_blank" class="link">Donate</a>
</div>
</div>
</div>
</div>

View file

@ -1,7 +1,8 @@
<div class="row">
<div class="col-xs-12 col-md-6">
<input type="checkbox" ng-model="share_settings.linkSharing.enabled">
Enable link sharing.
Enable link sharing.<br />
<input type="text" ng-model="share_link" select-on-click ng-if="share_settings.linkSharing.enabled">
<div>
Expire settings:
<select ng-model="share_settings.linkSharing.settings.type">