From bf1ec44186ac87827ed7fc9b21e96101b6c4fad2 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 08:34:47 +0100 Subject: [PATCH 01/10] rework liveUpdate() and notificationsUpdate() (aka ping) to first do the liveUpdate and when this is done only do the ping once. rename initLiveUpdate() to initUpdate() and more main.js cleanup. --- view/js/main.js | 221 +++++++++++++++++----------------------------- view/js/mod_hq.js | 39 ++------ 2 files changed, 89 insertions(+), 171 deletions(-) diff --git a/view/js/main.js b/view/js/main.js index 91a64631a..626118b95 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -53,8 +53,7 @@ $(document).ready(function() { savedTitle = document.title; - NavUpdate(); - liveUpdateInit(); + updateInit(); $('a[rel^="#"]').click(function(e){ manage_popup_menu(this, e); @@ -94,7 +93,9 @@ $(document).ready(function() { }); -function confirmDelete() { return confirm(aStr.delitem); } +function confirmDelete() { + return confirm(aStr.delitem); +} function handle_comment_form(e) { e.stopPropagation(); @@ -341,7 +342,7 @@ function markRead(notifType) { $.get('ping?f=&markRead='+notifType); if(timer) clearTimeout(timer); $('.' + notifType + '-button').hide(); - timer = setTimeout(NavUpdate,2000); + timer = setTimeout(updateInit,2000); } function markItemRead(itemId) { @@ -362,68 +363,57 @@ function manage_popup_menu(w,e) { } } -function NavUpdate() { - if(liking) - $('.like-rotator').hide(); +function notificationsUpdate() { + var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : ''); - if((! stopped) && (! mediaPlaying)) { - var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : ''); + $.get(pingCmd,function(data) { - $.get(pingCmd,function(data) { + if(data.invalid == 1) { + window.location.href=window.location.href; + } - if(data.invalid == 1) { - window.location.href=window.location.href; + if(data.network || data.home || data.intros || data.register || data.mail || data.all_events || data.notify || data.files || data.pubs) { + $('.notifications-btn').css('opacity', 1); + } + else { + $('.notifications-btn').css('opacity', 0.5); + $('#navbar-collapse-1').removeClass('show'); + } + + if(data.home || data.intros || data.register || data.mail || data.notify || data.files) { + $('.notifications-btn-icon').removeClass('fa-exclamation-circle'); + $('.notifications-btn-icon').addClass('fa-exclamation-triangle'); + } + if(!data.home && !data.intros && !data.register && !data.mail && !data.notify && !data.files) { + $('.notifications-btn-icon').removeClass('fa-exclamation-triangle'); + $('.notifications-btn-icon').addClass('fa-exclamation-circle'); + } + + $.each(data, function(index, item) { + //do not process those + var arr = ['notice', 'info', 'invalid']; + if(arr.indexOf(index) !== -1) + return; + + if(item == 0) { + $('.' + index + '-button').fadeOut(); + } else { + $('.' + index + '-button').fadeIn(); + $('.' + index + '-update').html(item); } + }); - if(! updateCountsOnly) { - liveUpdateInit(); - } + $.jGrowl.defaults.closerTemplate = '
[ ' + aStr.closeAll + ']
'; - updateCountsOnly = false; + $(data.notice).each(function() { + $.jGrowl(this.message, { sticky: true, theme: 'notice' }); + }); - if(data.network || data.home || data.intros || data.register || data.mail || data.all_events || data.notify || data.files || data.pubs) { - $('.notifications-btn').css('opacity', 1); - } - else { - $('.notifications-btn').css('opacity', 0.5); - $('#navbar-collapse-1').removeClass('show'); - } - - if(data.home || data.intros || data.register || data.mail || data.notify || data.files) { - $('.notifications-btn-icon').removeClass('fa-exclamation-circle'); - $('.notifications-btn-icon').addClass('fa-exclamation-triangle'); - } - if(!data.home && !data.intros && !data.register && !data.mail && !data.notify && !data.files) { - $('.notifications-btn-icon').removeClass('fa-exclamation-triangle'); - $('.notifications-btn-icon').addClass('fa-exclamation-circle'); - } - - $.each(data, function(index, item) { - //do not process those - var arr = ['notice', 'info', 'invalid']; - if(arr.indexOf(index) !== -1) - return; - - if(item == 0) { - $('.' + index + '-button').hide(); - } else { - $('.' + index + '-button').show(); - $('.' + index + '-update').html(item); - } - }); - - $.jGrowl.defaults.closerTemplate = '
[ ' + aStr.closeAll + ']
'; - - $(data.notice).each(function() { - $.jGrowl(this.message, { sticky: true, theme: 'notice' }); - }); - - $(data.info).each(function(){ - $.jGrowl(this.message, { sticky: false, theme: 'info', life: 10000 }); - }); - }) ; - } - timer = setTimeout(NavUpdate, updateInterval); + $(data.info).each(function(){ + $.jGrowl(this.message, { sticky: false, theme: 'info', life: 10000 }); + }); + }) + timer = setTimeout(updateInit, updateInterval); } function contextualHelp() { @@ -627,7 +617,6 @@ function updateConvItems(mode,data) { } $(document.body).trigger("sticky_kit:recalc"); - } function collapseHeight() { @@ -676,20 +665,25 @@ function collapseHeight() { console.log('collapsed above viewport count: ' + i); $(window).scrollTop(sval); } - - } -function liveUpdateInit() { - // start live update - if($('#live-network').length) { src = 'network'; liveUpdate(); } - if($('#live-channel').length) { src = 'channel'; liveUpdate(); } - if($('#live-pubstream').length) { src = 'pubstream'; liveUpdate(); } - if($('#live-display').length) { src = 'display'; liveUpdate(); } - if($('#live-hq').length) { src = 'hq'; liveUpdate(); } - if($('#live-search').length) { src = 'search'; liveUpdate(); } - // if($('#live-cards').length) { src = 'cards'; liveUpdate(); } - // if($('#live-articles').length) { src = 'articles'; liveUpdate(); } +function updateInit() { + + if($('#live-network').length) { src = 'network'; } + if($('#live-channel').length) { src = 'channel'; } + if($('#live-pubstream').length) { src = 'pubstream'; } + if($('#live-display').length) { src = 'display'; } + if($('#live-hq').length) { src = 'hq'; } + if($('#live-search').length) { src = 'search'; } + // if($('#live-cards').length) { src = 'cards'; } + // if($('#live-articles').length) { src = 'articles'; } + + if(! src) { + notificationsUpdate(); + } + else { + liveUpdate(); + } if($('#live-photos').length || $('#live-cards').length || $('#live-articles').length ) { if(liking) { @@ -702,14 +696,17 @@ function liveUpdateInit() { function liveUpdate() { if(typeof profile_uid === 'undefined') profile_uid = false; /* Should probably be unified with channelId defined in head.tpl */ + if((src === null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; } - if(($('.comment-edit-text.expanded').length) || (in_progress)) { + + if(($('.comment-edit-text.expanded').length) || (in_progress) || (mediaPlaying)) { if(livetime) { clearTimeout(livetime); } livetime = setTimeout(liveUpdate, 10000); return; } + if(livetime !== null) livetime = null; @@ -789,20 +786,6 @@ function liveUpdate() { in_progress = false; - // FIXME - the following lines were added so that almost - // immediately after we update the posts on the page, we - // re-check and update the notification counts. - // As it turns out this causes a bit of an inefficiency - // as we're pinging twice for every update, once before - // and once after. A btter way to do this is to rewrite - // NavUpdate and perhaps LiveUpdate so that we check for - // post updates first and only call the notification ping - // once. - - updateCountsOnly = true; - if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,10); - }); } else { @@ -814,22 +797,11 @@ function liveUpdate() { in_progress = false; - // FIXME - the following lines were added so that almost - // immediately after we update the posts on the page, we - // re-check and update the notification counts. - // As it turns out this causes a bit of an inefficiency - // as we're pinging twice for every update, once before - // and once after. A btter way to do this is to rewrite - // NavUpdate and perhaps LiveUpdate so that we check for - // post updates first and only call the notification ping - // once. - - updateCountsOnly = true; - if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,10); - } + }) + .done(function() { + notificationsUpdate(); }); } @@ -930,7 +902,6 @@ function notify_popup_loader(notifyType) { }, 1000); } - // Since our ajax calls are asynchronous, we will give a few // seconds for the first ajax call (setting like/dislike), then // run the updater to pick up any changes and display on the page. @@ -939,13 +910,11 @@ function notify_popup_loader(notifyType) { // events have completed and therefore there won't be any // visible feedback that anything changed without all this // trickery. This still could cause confusion if the "like" ajax call -// is delayed and NavUpdate runs before it completes. - - +// is delayed and updateInit runs before it completes. function dolike(ident, verb) { unpause(); $('#like-rotator-' + ident.toString()).show(); - $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate ); + $.get('like/' + ident.toString() + '?verb=' + verb, updateInit ); liking = 1; } @@ -953,7 +922,6 @@ function doprofilelike(ident, verb) { $.get('like/' + ident + '?verb=' + verb, function() { window.location.href=window.location.href; }); } - function dropItem(url, object) { var confirm = confirmDelete(); if(confirm) { @@ -975,20 +943,17 @@ function dropItem(url, object) { function dosubthread(ident) { unpause(); $('#like-rotator-' + ident.toString()).show(); - $.get('subthread/sub/' + ident.toString(), NavUpdate ); + $.get('subthread/sub/' + ident.toString(), updateInit ); liking = 1; } - function dounsubthread(ident) { unpause(); $('#like-rotator-' + ident.toString()).show(); - $.get('subthread/unsub/' + ident.toString(), NavUpdate ); + $.get('subthread/unsub/' + ident.toString(), updateInit ); liking = 1; } - - function dostar(ident) { ident = ident.toString(); $('#like-rotator-' + ident).show(); @@ -1071,7 +1036,7 @@ function post_comment(id) { $(document).unbind( "click.commentOpen"); } if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,1500); + timer = setTimeout(updateInit,1500); } if(data.reload) { window.location.href=data.reload; @@ -1106,7 +1071,7 @@ function importElement(elem) { { "element" : elem }, function(data) { if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,10); + timer = setTimeout(updateInit,10); } ); return false; @@ -1115,7 +1080,6 @@ function importElement(elem) { function preview_post() { $("#jot-preview").val("1"); $("#jot-preview-content").show(); -// tinyMCE.triggerSave(); $.post( "item", $("#profile-jot-form").serialize(), @@ -1221,30 +1185,6 @@ function checkboxhighlight(box) { } } - -// code from http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser -function fcFileBrowser (field_name, url, type, win) { - /* TODO: If you work with sessions in PHP and your client doesn't accept cookies you might need to carry - the session name and session ID in the request string (can look like this: "?PHPSESSID=88p0n70s9dsknra96qhuk6etm5"). - These lines of code extract the necessary parameters and add them back to the filebrowser URL again. */ - - var cmsURL = baseurl+"/fbrowser/"+type+"/"; - - tinyMCE.activeEditor.windowManager.open({ - file : cmsURL, - title : 'File Browser', - width : 420, // Your dimensions may differ - toy around with them! - height : 400, - resizable : "yes", - inline : "yes", // This parameter only has an effect if you use the inlinepopups plugin! - close_previous : "no" - }, { - window : win, - input : field_name - }); - return false; -} - /** * sprintf in javascript * "{0} and {1}".format('zero','uno'); @@ -1257,6 +1197,7 @@ String.prototype.format = function() { } return formatted; }; + // Array Remove Array.prototype.remove = function(item) { to = undefined; @@ -1333,8 +1274,6 @@ function addeditortext(data) { var currentText = $("#profile-jot-text").val(); $("#profile-jot-text").val(currentText + data); } - else - tinyMCE.execCommand('mceInsertRawHTML',false,data); } function h2b(s) { diff --git a/view/js/mod_hq.js b/view/js/mod_hq.js index 3ce5f1ca6..d61a4ff3b 100644 --- a/view/js/mod_hq.js +++ b/view/js/mod_hq.js @@ -9,18 +9,20 @@ $(document).on('click', '#jot-toggle', function(e) { }); - function hqLiveUpdate(notify_id) { if(typeof profile_uid === 'undefined') profile_uid = false; /* Should probably be unified with channelId defined in head.tpl */ + if((src === null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; } - if(($('.comment-edit-text.expanded').length) || (in_progress)) { + + if(($('.comment-edit-text.expanded').length) || (in_progress) || (mediaPlaying)) { if(livetime) { clearTimeout(livetime); } livetime = setTimeout(liveUpdate, 10000); return; } + if(livetime !== null) livetime = null; @@ -113,20 +115,6 @@ function hqLiveUpdate(notify_id) { in_progress = false; - // FIXME - the following lines were added so that almost - // immediately after we update the posts on the page, we - // re-check and update the notification counts. - // As it turns out this causes a bit of an inefficiency - // as we're pinging twice for every update, once before - // and once after. A btter way to do this is to rewrite - // NavUpdate and perhaps LiveUpdate so that we check for - // post updates first and only call the notification ping - // once. - - updateCountsOnly = true; - if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,10); - }); } else { @@ -138,20 +126,11 @@ function hqLiveUpdate(notify_id) { in_progress = false; - // FIXME - the following lines were added so that almost - // immediately after we update the posts on the page, we - // re-check and update the notification counts. - // As it turns out this causes a bit of an inefficiency - // as we're pinging twice for every update, once before - // and once after. A btter way to do this is to rewrite - // NavUpdate and perhaps LiveUpdate so that we check for - // post updates first and only call the notification ping - // once. - - updateCountsOnly = true; - if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,10); - } + + }) + .done(function() { + notificationsUpdate(); }); } + From f55ef7e728a70ebca052635b073c84a716a41e48 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 08:38:58 +0100 Subject: [PATCH 02/10] remove the updateCountsOnly variable which is not used anymore now --- view/js/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/view/js/main.js b/view/js/main.js index 626118b95..84a963d3f 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -17,7 +17,6 @@ var next_page = 1; var page_load = true; var loadingPage = true; var pageHasMoreContent = true; -var updateCountsOnly = false; var divmore_height = 400; var last_filestorage_id = null; var mediaPlaying = false; From e375224dfec3706b32bc840337f0b6f546708ace Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 08:40:18 +0100 Subject: [PATCH 03/10] bump version to prevent caching issues related to recent updates to main.js --- boot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot.php b/boot.php index af4f75ae3..4b9a43faa 100755 --- a/boot.php +++ b/boot.php @@ -50,7 +50,7 @@ require_once('include/hubloc.php'); require_once('include/attach.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '2.9.2' ); +define ( 'STD_VERSION', '2.9.3' ); define ( 'ZOT_REVISION', '1.3' ); define ( 'DB_UPDATE_VERSION', 1198 ); From e6a59ad36fcdbe4dcb534ff700663d9588b5d734 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 11:22:59 +0100 Subject: [PATCH 04/10] allow an optional notify_id arg for liveUpdate() --- view/js/main.js | 11 ++- view/js/mod_hq.js | 126 ------------------------------ view/tpl/notifications_widget.tpl | 2 +- 3 files changed, 11 insertions(+), 128 deletions(-) diff --git a/view/js/main.js b/view/js/main.js index 84a963d3f..c9bde8452 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -692,7 +692,7 @@ function updateInit() { } } -function liveUpdate() { +function liveUpdate(notify_id) { if(typeof profile_uid === 'undefined') profile_uid = false; /* Should probably be unified with channelId defined in head.tpl */ @@ -762,6 +762,15 @@ function liveUpdate() { // else data was valid - reset the recursion counter liveRecurse = 0; + if(notify_id !== 'undefined') { + $.post( + "hq", + { + "notify_id" : notify_id + } + ); + } + var dready = new Date(); console.log('DATA ready in: ' + (dready - dstart)/1000 + ' seconds.'); diff --git a/view/js/mod_hq.js b/view/js/mod_hq.js index d61a4ff3b..b321382bd 100644 --- a/view/js/mod_hq.js +++ b/view/js/mod_hq.js @@ -8,129 +8,3 @@ $(document).on('click', '#jot-toggle', function(e) { $('#profile-jot-text').focus(); }); - -function hqLiveUpdate(notify_id) { - - if(typeof profile_uid === 'undefined') profile_uid = false; /* Should probably be unified with channelId defined in head.tpl */ - - if((src === null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; } - - if(($('.comment-edit-text.expanded').length) || (in_progress) || (mediaPlaying)) { - if(livetime) { - clearTimeout(livetime); - } - livetime = setTimeout(liveUpdate, 10000); - return; - } - - if(livetime !== null) - livetime = null; - - prev = 'live-' + src; - - in_progress = true; - - var update_url; - var update_mode; - - if(scroll_next) { - bParam_page = next_page; - page_load = true; - } - else { - bParam_page = 1; - } - - update_url = buildCmd(); - - if(page_load) { - $("#page-spinner").show(); - if(bParam_page == 1) - update_mode = 'replace'; - else - update_mode = 'append'; - } - else { - update_mode = 'update'; - var orgHeight = $("#region_2").height(); - } - - var dstart = new Date(); - console.log('LOADING data...'); - $.get(update_url, function(data) { - - // on shared hosts occasionally the live update process will be killed - // leaving an incomplete HTML structure, which leads to conversations getting - // truncated and the page messed up if all the divs aren't closed. We will try - // again and give up if we can't get a valid HTML response after 10 tries. - - if((data.indexOf("") != (-1)) && (data.indexOf("") == (-1))) { - console.log('Incomplete data. Reloading'); - in_progress = false; - liveRecurse ++; - if(liveRecurse < 10) { - liveUpdate(); - } - else { - console.log('Incomplete data. Too many attempts. Giving up.'); - } - } - - // else data was valid - reset the recursion counter - liveRecurse = 0; - - if(notify_id !== 'undefined') { - $.post( - "hq", - { - "notify_id" : notify_id - }, - function(data) { - if(timer) clearTimeout(timer); - timer = setTimeout(NavUpdate,10); - } - ); - } - - var dready = new Date(); - console.log('DATA ready in: ' + (dready - dstart)/1000 + ' seconds.'); - - if(update_mode === 'update' || preloadImages) { - console.log('LOADING images...'); - - $('.wall-item-body, .wall-photo-item',data).imagesLoaded( function() { - var iready = new Date(); - console.log('IMAGES ready in: ' + (iready - dready)/1000 + ' seconds.'); - - page_load = false; - scroll_next = false; - updateConvItems(update_mode,data); - $("#page-spinner").hide(); - $("#profile-jot-text-loading").hide(); - - // adjust scroll position if new content was added above viewport - if(update_mode === 'update') { - $(window).scrollTop($(window).scrollTop() + $("#region_2").height() - orgHeight + contentHeightDiff); - } - - in_progress = false; - - }); - } - else { - page_load = false; - scroll_next = false; - updateConvItems(update_mode,data); - $("#page-spinner").hide(); - $("#profile-jot-text-loading").hide(); - - in_progress = false; - - } - - }) - .done(function() { - notificationsUpdate(); - }); -} - diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl index e8d51caca..60acb1654 100644 --- a/view/tpl/notifications_widget.tpl +++ b/view/tpl/notifications_widget.tpl @@ -59,7 +59,7 @@ mode = 'replace'; page_load = true; {{if $module == 'hq'}} - hqLiveUpdate(notify_id); + liveUpdate(notify_id); {{/if}} {{if $module == 'display'}} liveUpdate(); From bc0f4b4fa5dc80f314eb72256c17051b66ba3979 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 11:26:33 +0100 Subject: [PATCH 05/10] an additional on touch event might improve things for mobile handling --- view/tpl/notifications_widget.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl index 60acb1654..18f3ef12d 100644 --- a/view/tpl/notifications_widget.tpl +++ b/view/tpl/notifications_widget.tpl @@ -22,7 +22,7 @@ }); {{if $module == 'display' || $module == 'hq'}} - $(document).on('click', '.notification', function(e) { + $(document).on('click touch', '.notification', function(e) { var b64mid = $(this).data('b64mid'); var notify_id = $(this).data('notify_id'); var path = $(this)[0].pathname.substr(1,7); From b1f82257e80a2d015c7468ed62cdb2ba6668d6ea Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 11:35:13 +0100 Subject: [PATCH 06/10] load the profile images in the custom acl selector only if we actually need them --- view/js/acl.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/view/js/acl.js b/view/js/acl.js index e016158e9..6042b43ca 100644 --- a/view/js/acl.js +++ b/view/js/acl.js @@ -173,6 +173,12 @@ ACL.prototype.on_custom = function(event) { that.deny_cid = []; that.deny_gid = []; + $("#acl-list-content .acl-list-item img[data-src]").each(function(i, el) { + //Replace data-src attribute with src attribute for every image + $(el).attr('src', $(el).data("src")); + $(el).removeAttr("data-src"); + }); + that.update_view('custom'); that.on_submit(); @@ -408,10 +414,4 @@ ACL.prototype.populate = function(data) { } that.list_content.append(html); }); - - $("#acl-list-content .acl-list-item img[data-src]").each(function(i, el) { - // Replace data-src attribute with src attribute for every image - $(el).attr('src', $(el).data("src")); - $(el).removeAttr("data-src"); - }); }; From aa7f6111a69e8b25901b5e2c8f4c4828551316a9 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 29 Nov 2017 12:01:36 +0100 Subject: [PATCH 07/10] use typeof if checking for undefined var and always clear timeout before setting a new one --- view/js/main.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/view/js/main.js b/view/js/main.js index c9bde8452..888934ea8 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -339,8 +339,8 @@ function closeMenu(theID) { function markRead(notifType) { $.get('ping?f=&markRead='+notifType); - if(timer) clearTimeout(timer); $('.' + notifType + '-button').hide(); + if(timer) clearTimeout(timer); timer = setTimeout(updateInit,2000); } @@ -412,7 +412,8 @@ function notificationsUpdate() { $.jGrowl(this.message, { sticky: false, theme: 'info', life: 10000 }); }); }) - timer = setTimeout(updateInit, updateInterval); + if(timer) clearTimeout(timer); + timer = setTimeout(updateInit,updateInterval); } function contextualHelp() { @@ -762,7 +763,7 @@ function liveUpdate(notify_id) { // else data was valid - reset the recursion counter liveRecurse = 0; - if(notify_id !== 'undefined') { + if(typeof notify_id !== 'undefined') { $.post( "hq", { From 5abcb8c97813d66b63ca697ca626347a9fd8d95c Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 29 Nov 2017 13:51:54 -0800 Subject: [PATCH 08/10] use httpsig auth for getfile --- Zotlabs/Module/Getfile.php | 57 ++++++++++++++++++++++++++++++-------- include/import.php | 9 +++++- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php index 413a68e0c..3f84b4050 100644 --- a/Zotlabs/Module/Getfile.php +++ b/Zotlabs/Module/Getfile.php @@ -28,17 +28,51 @@ class Getfile extends \Zotlabs\Web\Controller { function post() { - logger('post: ' . print_r($_POST,true),LOGGER_DEBUG,LOG_INFO); - + $header_verification = false; + $hash = $_POST['hash']; $time = $_POST['time']; $sig = $_POST['signature']; $resource = $_POST['resource']; $revision = intval($_POST['revision']); $resolution = (-1); - + if(! $hash) killme(); + + foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) { + if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') { + if($head !== 'HTTP_AUTHORIZATION') { + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head]; + continue; + } + + $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]); + if($sigblock) { + $keyId = $sigblock['keyId']; + + if($keyId) { + $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash + where hubloc_addr = '%s' limit 1", + dbesc(str_replace('acct:','',$keyId)) + ); + if($r) { + $hubloc = $r[0]; + $verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']); + if($verified && $verified['header_signed'] && $verified['header_valid'] && $hash == $hubloc['hubloc_hash']) { + $header_verified = true; + } + } + } + } + } + } + + + logger('post: ' . print_r($_POST,true),LOGGER_DEBUG,LOG_INFO); + if($header_verified) { + logger('HTTPSig verified'); + } $channel = channelx_by_hash($hash); @@ -59,16 +93,17 @@ class Getfile extends \Zotlabs\Web\Controller { $d1 = datetime_convert('UTC','UTC',"now + $slop minutes"); $d2 = datetime_convert('UTC','UTC',"now - $slop minutes"); - if(($time > $d1) || ($time < $d2)) { - logger('time outside allowable range'); - killme(); - } + if(! $header_verified) { + if(($time > $d1) || ($time < $d2)) { + logger('time outside allowable range'); + killme(); + } - if(! rsa_verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) { - logger('verify failed.'); - killme(); + if(! rsa_verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) { + logger('verify failed.'); + killme(); + } } - if($resolution > 0) { $r = q("select * from photo where resource_id = '%s' and uid = %d limit 1", diff --git a/include/import.php b/include/import.php index 702fa7e54..8cab16342 100644 --- a/include/import.php +++ b/include/import.php @@ -1199,7 +1199,14 @@ function sync_files($channel, $files) { continue; } $redirects = 0; - $x = z_post_url($fetch_url,$parr,$redirects,array('filep' => $fp)); + + + $headers = []; + $headers['Accept'] = 'application/x-zot+json' ; + $headers['Sigtoken'] = random_string(); + $headers = \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'], 'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,true,'sha512'); + + $x = z_post_url($fetch_url,$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]); fclose($fp); if($x['success']) { From 6a4050cc9386effc86d2b0279c33ae1a1925a5ab Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 29 Nov 2017 14:08:30 -0800 Subject: [PATCH 09/10] use the same variable name consistently --- Zotlabs/Module/Getfile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php index 3f84b4050..abc9f50d9 100644 --- a/Zotlabs/Module/Getfile.php +++ b/Zotlabs/Module/Getfile.php @@ -28,7 +28,7 @@ class Getfile extends \Zotlabs\Web\Controller { function post() { - $header_verification = false; + $header_verified = false; $hash = $_POST['hash']; $time = $_POST['time']; From fc5b6887168a25992fb089ed7da7ac917e7aaf6b Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 30 Nov 2017 13:40:36 +0100 Subject: [PATCH 10/10] fix issue #921 - default addressbook has no name --- Zotlabs/Module/Cdav.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index 77052f97c..91d279f7a 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -1250,7 +1250,7 @@ class Cdav extends \Zotlabs\Web\Controller { //create default addressbook $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); $properties = ['{DAV:}displayname' => t('Default Addressbook')]; - $carddavBackend->createAddressBook($uri, $default, $properties); + $carddavBackend->createAddressBook($uri, 'default', $properties); } }