Compare commits

...

689 Commits
4.7.2 ... 5.0

Author SHA1 Message Date
Mario
bafbf04164 Merge branch '5.0RC' 2020-11-05 08:46:42 +00:00
Mario
fdefa101d8 version 5.0 2020-11-05 08:42:49 +00:00
Mario
7e40eeb52a Merge branch 'dev' into 5.0RC 2020-11-05 08:41:01 +00:00
Mario
e98804693d update changelog 2020-11-05 08:37:34 +00:00
Mario
953c294778 wrong variable name 2020-11-05 08:32:21 +00:00
Mario
20d2811cd5 Merge branch 'dev' into 5.0RC 2020-11-04 15:16:52 +00:00
Mario
207df132e6 make sure we attach the public key 2020-11-04 13:36:52 +00:00
Mario
40e0fe1d25 css issue 2020-11-04 11:06:30 +00:00
Mario
fe3f42ce10 call sse_setNotificationsStatus() after fading out buttons 2020-11-03 07:29:37 +00:00
Mario
b4ca5c133c Merge branch 'dev' into 5.0RC 2020-11-01 12:38:18 +00:00
Mario
8f1a579597 update changelog 2020-11-01 12:37:49 +00:00
Mario
aa69b43e0e fix vsprintf() warning 2020-11-01 12:33:45 +00:00
Mario
cadd6fdfff fix vsprintf() error 2020-11-01 12:24:55 +00:00
Mario
85b97014c9 version 5.0RC8 2020-10-31 20:33:48 +00:00
Mario
50ca95735d fix merge conflict 2020-10-31 20:32:39 +00:00
Mario
b55c7f794b Merge branch 'dev' into 5.0RC 2020-10-31 20:30:36 +00:00
Mario
205279f7f8 more changelog 2020-10-31 20:28:16 +00:00
Mario
934721a98d remove unmaintained and deprecated schemas 2020-10-31 20:27:23 +00:00
Mario
d02a8d733e update changelog 2020-10-31 20:24:21 +00:00
Mario
d59b81f11d if restarting a previously interrupted upload just return where we ended - fix issue #1485 2020-10-31 19:57:14 +00:00
Mario
b11d2c376b Merge branch 'dev' into 'dev'
Don't try to fetch profile photo for unknown channel

See merge request hubzilla/core!1880
2020-10-31 13:53:13 +01:00
Mario
6d83b5b68d Merge branch 'cherry-pick-16d450fc' into 'dev'
HTML parsing lib change to standard PHP in scrape_feed() and scrape_vcard()

See merge request hubzilla/core!1882
2020-10-31 09:19:30 +01:00
root
0ad7c8f69e HTML parsing lib change to standard PHP in scrape_feed() and scrape_vcard()
(cherry picked from commit 16d450fc6980bb70f13e574d1b20406dd313110e)
2020-10-31 09:15:37 +01:00
Mario Vavti
e24c769f8e fix issue #1484 2020-10-27 20:27:49 +01:00
Max Kostikov
7cf9b85a97 Don't try to fetch profile photo for unknown channel 2020-10-25 11:43:35 +01:00
Mario
dd3d65cb1c Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-10-25 10:32:07 +00:00
Mario
5e19632f2d update changelog 2020-10-25 10:32:02 +00:00
Mario
cc543d1ad2 remove redundant includesà 2020-10-25 10:30:12 +00:00
Mario
35299ed7c3 Merge branch 'dev' into 'dev'
Add results caching on public tag and profile categories fetching

See merge request hubzilla/core!1875
2020-10-25 11:28:41 +01:00
Max Kostikov
7008cf3269 Add results caching on public tag and profile categories fetching 2020-10-25 11:28:40 +01:00
Mario
6979ea44f4 more directory fixes 2020-10-25 08:26:25 +00:00
Mario
81775eebe2 directory fixes 2020-10-25 07:59:49 +00:00
Mario
e70802c6ad strings update 2020-10-25 07:47:07 +00:00
Mario
7112bcd134 bt_syslog() instead of syslog flag for btlogger 2020-10-25 07:27:07 +00:00
Mario
d3d5ddfb43 enable btlogging to syslog
(cherry picked from commit 5580fc1954)
2020-10-24 23:29:11 +02:00
Mario
5580fc1954 enable btlogging to syslog 2020-10-24 21:26:46 +00:00
Mario
d0e85f05af Merge branch 'dev' into 5.0RC 2020-10-23 12:18:53 +00:00
Mario
c136741db6 more remove logging 2020-10-23 12:18:04 +00:00
Mario
5724be1f8e Merge branch 'dev' into 5.0RC 2020-10-23 11:47:23 +00:00
Mario
29e89d1152 Ãremove loggingà 2020-10-23 11:46:43 +00:00
Mario
95dfde99c6 Merge branch 'dev' into 5.0RC 2020-10-23 09:29:22 +00:00
Mario
59fd3861a7 wrong extension 2020-10-23 09:28:49 +00:00
Mario
69d627a58b Merge branch 'dev' into 5.0RC 2020-10-23 06:52:18 +00:00
Mario
2772c33563 load eager in items - lazy breaks collapsing of long items with images 2020-10-22 19:22:52 +00:00
Mario
78f655f877 more lazy, less eager 2020-10-22 19:11:03 +00:00
Mario
75a73be60c lazy/eager loading and minor css fixes 2020-10-22 18:54:21 +00:00
Mario
690874fc6e fix minor regression 2020-10-22 12:12:53 +00:00
Mario
96de38a1f0 adapt notifications and mark item seen handling to play well with client side page caching 2020-10-22 11:33:25 +00:00
Mario
cef0c2ebb2 highlight events for today in notifications and remove some redundant css 2020-10-19 08:44:44 +00:00
Mario
5e0f5460f2 provide info about dead sites in delivery report and set site_dead when marking a hubloc down. 2020-10-19 07:25:30 +00:00
Mario
ff8c9cfd14 load more notifications if visible notifications count becomes < 15 2020-10-18 09:47:46 +00:00
Mario
b5b033fe22 reduce result set for notificationsà 2020-10-16 14:12:30 +00:00
Mario
5dc2f43d1d mark private forums in acl selector 2020-10-16 11:54:14 +00:00
Mario
f0acb9f01e get_forum_channels(): fix an issue where we would not look for private forums in case we did not have any channels where tag_deliver is set 2020-10-16 11:43:21 +00:00
Mario
b6ca9b6020 make acl selector work correctly if we provide a cid in mod network 2020-10-16 10:32:07 +00:00
Mario
9c6446edbe fix image src issue in template 2020-10-16 10:29:24 +00:00
Mario
d84f0030be on refresh, always set all perms 2020-10-16 10:21:58 +00:00
Mario
61f554e0d7 remove new lines and tabs from xchan_name 2020-10-15 10:54:59 +00:00
Mario
3b252d98b8 add forums to acl selector where appropriate 2020-10-15 10:51:58 +00:00
Mario
f5315ed6a2 use logger for logging 2020-10-14 14:25:22 +00:00
Mario
c1f36802a1 version 5.0RC6 2020-10-14 12:36:10 +00:00
Mario
ba0f24bf70 Merge branch 'dev' into 5.0RC 2020-10-14 12:33:38 +00:00
Mario
522b92128f use logger for logging 2020-10-14 12:32:18 +00:00
Mario
ea77043aaf more logging 2020-10-14 08:53:12 +00:00
Mario
91dd877c2d Merge branch 'dev' into 5.0RC 2020-10-14 08:17:35 +00:00
Mario
e2e160b8e8 In find_best_identity() only look for zot and zot6 network types. Otherwise we could end up rewriting activitypub contacts to their diaspora equivalent which would be counterproductive here. Dismiss deleted hublocs. Same applies for find_best_zot_identity(). Also add logging. 2020-10-14 07:33:30 +00:00
Mario
89c74868aa Merge branch 'dev' into 5.0RC 2020-10-13 09:20:16 +00:00
Mario
45a5a04189 do not overwrite $x variable 2020-10-13 09:03:13 +00:00
Mario
1f41b1837f version 5.0RC5 2020-10-13 08:33:22 +00:00
Mario
c01e1b6c33 Merge branch 'dev' into 5.0RC 2020-10-13 08:31:57 +00:00
Mario
08e7c7b249 use a more neutral default cover image provided by bggenerator.com 2020-10-13 08:16:14 +00:00
Mario
b103993ad1 this is not required here 2020-10-13 08:14:14 +00:00
Mario
e12f375624 return if author or owner is missing and add more logging 2020-10-13 07:25:33 +00:00
Mario
8cd67a5d4a fix more php warnings and remove temporary logging 2020-10-12 21:37:44 +00:00
Mario
31e030af69 missing parenthesis 2020-10-12 21:01:36 +00:00
Mario
375986437a fix php warnings 2020-10-12 20:58:30 +00:00
Mario
5f93157d5a improve find_best_identity() and fix wrong variable 2020-10-12 20:28:48 +00:00
Mario
8d3c201830 if we receive an item with a zot xchan as author or owner rewrite them to the zot6 xchan if we have their zot6 xchan in abook 2020-10-12 20:22:07 +00:00
Mario
612ef90523 version 5.0RC4 2020-10-12 06:50:29 +00:00
Mario
e64856e957 Merge branch 'dev' into 5.0RC 2020-10-12 06:47:41 +00:00
Mario
8595835aa0 revert linebreak removing 2020-10-11 19:48:35 +00:00
Mario
4d2507263d find best identity 2020-10-11 19:35:48 +00:00
Mario
4a671fe634 replace linebreaks with spaces 2020-10-11 10:50:03 +00:00
Mario
ed845d93bc 5.0RC testing: fix issue with event responses 2020-10-10 19:06:35 +00:00
Mario
595f3d99b4 quickfix localize_item() - requires more work 2020-10-10 08:00:25 +00:00
Mario
1e2d5b0c77 only call zid_init() if session is not yet authenticated 2020-10-09 12:44:14 +00:00
Mario
1215618589 add zot6 to the authenticatable options and fix array key in reshare header 2020-10-09 12:16:55 +00:00
Mario
67533ee478 add rss network authors to the not fetchable list 2020-10-09 12:03:33 +00:00
Mario
3acd5dcc07 remove source entries for removed contacts 2020-10-09 07:38:11 +00:00
Mario
c387902a44 5.0RC testing: correctly set permissions for rss feeds 2020-10-09 07:19:23 +00:00
Mario
ad51be7dd9 reduce result set for query in zid_init() and use Libzot::zot_record_preferred() in mod rmagic 2020-10-08 18:18:44 +00:00
Mario
3514f805ea more bdi tags 2020-10-07 15:38:04 +00:00
Mario
2690159f09 5.0RC testing: use the zot6 xchan if available 2020-10-07 08:02:04 +00:00
Mario
902151918c 5.0RC testing: do not attempt zot6 delivery of anonymous comments - the author is not a valid actor 2020-10-06 10:03:57 +00:00
Mario
5dd1ea21af 5.0RC testing: dismiss activities where an author could not be found 2020-10-06 10:01:20 +00:00
Mario
b37c8bf928 code optimisation 2020-10-06 08:25:53 +00:00
hubzilla
923ae14c47 Merge pull request 'Update Spanish' (#1) from mjfriaza/hubzilla:dev into dev
Reviewed-on: https://codeberg.org/hubzilla/hubzilla/pulls/1
2020-10-05 15:14:54 +02:00
Mario
7ec6550734 version 5.0RC3 2020-10-05 12:03:14 +00:00
Mario
e622802c24 Merge branch 'dev' into 5.0RC 2020-10-05 12:01:46 +00:00
Mario
244c8edfca Ãrework undo/delete to use inline objects 2020-10-05 11:47:22 +00:00
Mario
245c0c22cd Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-10-02 15:12:53 +00:00
Mario
93b90ab23a more work on delete/undo 2020-10-02 15:12:42 +00:00
Mario
765f9ffcf0 Revert "more work on delete/undo"
This reverts commit bdfdd515d8
2020-10-02 17:12:26 +02:00
Mario Vavti
bdfdd515d8 more work on delete/undo 2020-10-02 17:08:49 +02:00
Mario
72c6d3e7ba item/activity fetching 2020-10-02 12:09:23 +00:00
Mario
869ce64f87 Merge branch 'dev' into 5.0RC 2020-10-01 12:01:52 +00:00
Mario
86117c8859 more delete fixes 2020-10-01 11:51:20 +00:00
Mario
96c4c72ee3 minor issue 2020-10-01 11:16:03 +00:00
Mario
4b0d32eb14 Merge branch 'deletefixes' into 'dev'
deleting like/dislike/accept/reject/etc. activities should be Undo rather than Delete per the spec

See merge request hubzilla/core!1879
2020-10-01 12:35:35 +02:00
nobody
1d705b9805 deleting like/dislike/accept/reject/etc. activities should be Undo rather than Delete per the spec 2020-09-30 23:38:05 -07:00
Mario
8605aee533 use object url 2020-10-01 06:34:27 +00:00
Mario
e4de9ef903 Merge branch 'deletefixes' into 'dev'
delete fixes

See merge request hubzilla/core!1878
2020-10-01 08:26:03 +02:00
nobody
e529635952 delete fixes 2020-09-30 17:05:36 -07:00
Mario
21b71401d3 version 5.0RC2 2020-09-30 10:30:17 +00:00
Mario
80bdcbb3e6 Merge branch 'dev' into 5.0RC 2020-09-30 10:28:54 +00:00
Mario
b878b69028 5.0RC testing: fix issue in relation with deletes 2020-09-30 10:10:49 +00:00
nobody
48440e368c bug: undoing a like on a comment can remove the comment
(cherry picked from commit b999456bf16a5d457a16fab1299289cfb54bfed4)
2020-09-30 08:16:59 +02:00
Mario
a7bf07b864 5.0RC testing: fix uuid for likes/dislikes 2020-09-28 20:31:26 +00:00
Mario
a80e59812b RC5.0 testing: fix purge and some cleanup 2020-09-28 12:36:22 +00:00
Mario Vavti
3f784a974a deprecate \Zotlabs\Zot\Finger where apropriate 2020-09-26 15:05:16 +02:00
mjfriaza
5ce3565109 Update Spanish 2020-09-26 13:55:57 +02:00
Mario Vavti
b25054e891 if we do not have App::$poi here we would already have returned. No need to check here. 2020-09-25 13:47:40 +02:00
Mario Vavti
2c316c788e port mod chanview 2020-09-25 13:41:21 +02:00
Mario Vavti
2fe2cc5e65 5.0RC testing: channel is not set and not required here 2020-09-25 12:44:44 +02:00
Mario
5d6a7922c1 port mod gprobe
(cherry picked from commit d23e830955)
2020-09-23 16:35:03 +02:00
Mario
d23e830955 port mod gprobe 2020-09-23 14:28:04 +00:00
Mario
762de94900 5.0RC testing: comment out global remove
(cherry picked from commit 5edec37d57)
2020-09-23 14:16:33 +02:00
Mario
d938c79385 5.0RC testing: do not use intval() on hubloc_id_url
(cherry picked from commit 42ef6208c1)
2020-09-23 14:16:17 +02:00
Mario
987a369fec 5.0RC testing: update hublocs by hubloc_id_url of we mark it deleted or change primary to catch both zot and zot6 hublocs. only set the zot6 hubloc as primary.
(cherry picked from commit 6f508b81d6)
2020-09-23 14:15:47 +02:00
Mario
586e2ef2df 5.0RC testing: fix mod locs
(cherry picked from commit 81e2f73c98)
2020-09-23 14:15:31 +02:00
Mario
5edec37d57 5.0RC testing: comment out global remove 2020-09-23 12:14:16 +00:00
Mario
42ef6208c1 5.0RC testing: do not use intval() on hubloc_id_url 2020-09-23 11:50:30 +00:00
Mario
6f508b81d6 5.0RC testing: update hublocs by hubloc_id_url of we mark it deleted or change primary to catch both zot and zot6 hublocs. only set the zot6 hubloc as primary. 2020-09-23 11:44:10 +00:00
Mario
81e2f73c98 5.0RC testing: fix mod locs 2020-09-23 09:48:14 +00:00
Mario
be43d3e0fd 5.0RC testing: on channel removal mark both zot6 and zot xchans and hublocs deleted
(cherry picked from commit 60fd27eca4)
2020-09-23 11:19:17 +02:00
Mario
60fd27eca4 5.0RC testing: on channel removal mark both zot6 and zot xchans and hublocs deleted 2020-09-23 09:18:02 +00:00
Mario
ca4a3c3cc0 fix notifications html not reset on markRead()
(cherry picked from commit dfad87f674)
2020-09-23 09:44:37 +02:00
Mario
dfad87f674 fix notifications html not reset on markRead() 2020-09-23 07:43:35 +00:00
Mario
743e575701 changelog and use dbq() where apropriate in z6trans_connections()
(cherry picked from commit be627c3f3a)
2020-09-22 10:27:52 +02:00
Mario
be627c3f3a changelog and use dbq() where apropriate in z6trans_connections() 2020-09-22 08:23:28 +00:00
Mario
80fdf53cc3 5.0RC testing: Diagnostics app should point to mod zot_probe 2020-09-21 12:09:31 +00:00
Mario
759f297aae 5.0RC testing: provide hubloc_id_url for new created zot hublocs
(cherry picked from commit 1a41c44c2f)
2020-09-21 11:27:23 +02:00
Mario
1a41c44c2f 5.0RC testing: provide hubloc_id_url for new created zot hublocs 2020-09-21 09:14:39 +00:00
nobody
88b014e9a7 use channel index
(cherry picked from commit 846d30239d97091d1e6b56e923c1965471f6bbff)

(cherry picked from commit f422362747)
2020-09-21 10:37:57 +02:00
nobody
bd0b8d768e apply channel name changes to all associated xchans
(cherry picked from commit f2ac1e4b7d2aa4854ed08ded49b2ed2dd10fab59)

(cherry picked from commit 34217f5f90)
2020-09-21 10:37:41 +02:00
nobody
f422362747 use channel index
(cherry picked from commit 846d30239d97091d1e6b56e923c1965471f6bbff)
2020-09-21 10:35:56 +02:00
nobody
34217f5f90 apply channel name changes to all associated xchans
(cherry picked from commit f2ac1e4b7d2aa4854ed08ded49b2ed2dd10fab59)
2020-09-21 10:35:14 +02:00
Mario
56e503149d allow to show unchecked box if the value is 0 or false
(cherry picked from commit 04af502e3a)
2020-09-21 10:09:03 +02:00
Mario
04af502e3a allow to show unchecked box if the value is 0 or false 2020-09-21 08:06:57 +00:00
Mario
f2c1fd2a48 ÃRC1 2020-09-20 15:10:31 +00:00
Mario Vavti
a86fd554a3 adapt mod z6trans to point to util/z6convert.php in case anyone stumbles over outdated doco.
(cherry picked from commit c38fc0b906)
2020-09-20 17:04:34 +02:00
Mario Vavti
ef0a8bcde0 add z6convert.php
(cherry picked from commit 2758d3c3eb)
2020-09-20 17:01:22 +02:00
Mario Vavti
c38fc0b906 adapt mod z6trans to point to util/z6convert.php in case anyone stumbles over outdated doco. 2020-09-20 16:49:36 +02:00
Mario Vavti
2758d3c3eb add z6convert.php 2020-09-20 16:38:48 +02:00
Mario
521a5074c9 5.0RC testing: their_perms should be reset before they are recreated. Otherwise withdrawn permissions will not take effect locally.
(cherry picked from commit 9c8d732081)
2020-09-19 22:34:32 +02:00
Max Kostikov
430c48e828 Update Russian hmessages.po
(cherry picked from commit ba0410dd24)
2020-09-19 22:34:07 +02:00
Max Kostikov
2e747bec6f Update Russian hstrings.php
(cherry picked from commit da44cef9a3)
2020-09-19 22:33:46 +02:00
Max Kostikov
d945789e1b Boost DB conversion speed to Z6
(cherry picked from commit a9377d6a3f)
2020-09-19 22:33:05 +02:00
Max Kostikov
de306cd7b8 Missprint
(cherry picked from commit b223b71d0d)
2020-09-19 22:31:38 +02:00
Mario
aedde6600e Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-09-19 19:19:29 +00:00
Mario
9c8d732081 5.0RC testing: their_perms should be reset before they are recreated. Otherwise withdrawn permissions will not take effect locally. 2020-09-19 19:19:03 +00:00
Max Kostikov
5d1e10522f Merge branch 'dev' into 'dev'
Update Russian translation

See merge request hubzilla/core!1874
2020-09-18 19:56:28 +02:00
Max Kostikov
ba0410dd24 Update Russian hmessages.po 2020-09-18 19:48:03 +02:00
Max Kostikov
da44cef9a3 Update Russian hstrings.php 2020-09-18 19:47:27 +02:00
Mario
e9227b0ffe Merge branch 'dev' into 'dev'
Boost DB conversion speed to Z6

See merge request hubzilla/core!1872
2020-09-18 13:43:02 +02:00
Max Kostikov
9299aff2af Boost DB conversion speed to Z6 2020-09-18 13:43:01 +02:00
Max Kostikov
a9377d6a3f Boost DB conversion speed to Z6 2020-09-17 23:25:55 +02:00
Max Kostikov
b223b71d0d Missprint 2020-09-17 19:49:30 +02:00
Max Kostikov
02cf85fa34 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!1
2020-09-17 19:47:44 +02:00
Mario
76a6e0b6fc bump dev version 2020-09-17 11:15:56 +00:00
Mario
2a2f032f17 update strings 2020-09-17 11:09:01 +00:00
Mario
e7ddd1a481 version 5.0RC 2020-09-17 10:57:24 +00:00
Mario
813ab2c5ed regenerate autoload file 2020-09-17 10:23:20 +00:00
Mario
4acdf9e817 deprecate $a variable for *_plugin_admin() and *_plugin_admin_post() 2020-09-16 09:16:27 +00:00
Mario
465da3a942 respect advanced profile setting in sexual preference selector - issue #1477 2020-09-14 07:41:20 +00:00
Mario
fb601cc280 Merge branch 'dev' into 'dev'
Support remote host cache directives on profile photo fetching

See merge request hubzilla/core!1871
2020-09-13 11:56:03 +02:00
Max Kostikov
25b9776bf6 Support remote host cache directives on profile photo fetching 2020-09-13 11:56:02 +02:00
Max Kostikov
5271232aa5 Fix variable name 2020-09-12 12:20:09 +02:00
Mario
7fa70108c4 whitespace 2020-09-11 12:19:24 +00:00
Mario
ff09b2131e disable community tags until we agree on how to implemnt this in zot6/activitypub 2020-09-11 12:11:09 +00:00
Max Kostikov
df758f40ef Avoid photo profile fetching more than once every 1 min 2020-09-09 11:11:52 +02:00
Max Kostikov
1d8dd949dc Update photo_driver.php 2020-09-08 22:50:59 +02:00
Max Kostikov
9dd333a2f4 Support remote host cache directives on profile photo fetching 2020-09-08 14:20:12 +02:00
Mario
d53b3b242d fix get_plink() for zot6 2020-09-04 18:56:21 +00:00
Mario
8e0e4b7b92 Merge branch 'dev' into 'dev'
Update of the .homeinstall folder

See merge request hubzilla/core!1869
2020-09-04 20:07:49 +02:00
Papa Dragon
adee24af6f Update of the home install setup script
- "hubzilla" replaced by "zotserver" in file names and file content when relevant
- Nginx can now be installed as the web server (Apache still chosen by default in the config file)
- Setup script now allows installation of multiple hub/instances on the same server
- Daily cron jobs script was updated an splitted : one global script launches shared commands
(SSL cert renewal + global backup on external device) and every instance has its own script for
git pull (individual scripts are launched by the global one)
2020-08-30 12:18:51 +02:00
Mario Vavti
1b161b0ee4 move z6trans_connections() to cron from cron daily 2020-08-26 21:13:32 +02:00
Mario Vavti
5aaa8f44a2 remove hublocs without a hubloc_hash and also remove hublocs where hubloc_id_url could not be fixed 2020-08-26 20:15:21 +02:00
Mario Vavti
1fbc6fa431 add check against null 2020-08-25 06:48:22 +02:00
Mario Vavti
6177ec9134 prefix table names 2020-08-24 20:31:59 +02:00
Mario Vavti
bd4867ef39 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-08-24 13:44:43 +02:00
Mario Vavti
0189d06375 provide some sort of feedback 2020-08-24 13:44:30 +02:00
Mario
aafdeb9000 Revert "more prefer zot6"
This reverts commit e9a264cb43
2020-08-24 11:26:52 +02:00
Mario Vavti
e9a264cb43 more prefer zot6 2020-08-24 11:18:47 +02:00
Mario Vavti
b996d82c5f prefer zot6 and also check for hubloc_deleted 2020-08-24 09:45:26 +02:00
Mario Vavti
c53794a8a2 an attempt to fix update 1238 for older hubs with broken xchan entries 2020-08-23 19:17:23 +02:00
Mario Vavti
170b2e4465 only show poke link if poke app is installed 2020-08-22 22:44:00 +02:00
Mario Vavti
4e0fc81e5d move cryptojs to addon 2020-08-22 22:14:29 +02:00
Mario
3b865d432f Revert "composer update pear/text_languagedetect"
This reverts commit 646dce7765
2020-08-22 21:32:06 +02:00
Mario Vavti
646dce7765 composer update pear/text_languagedetect 2020-08-22 20:01:59 +02:00
Mario Vavti
88a68f96da composer update html-to-markdown 2020-08-22 19:56:28 +02:00
Mario Vavti
32bdf42913 composer update htmlpurifier 2020-08-22 19:50:15 +02:00
Mario Vavti
53a010d1d4 bootstrap files 2020-08-22 19:41:57 +02:00
Mario Vavti
a9e19cb89e composer update bootstrap 2020-08-22 19:40:57 +02:00
Mario Vavti
4878611987 composer update jquery-file-upload 2020-08-22 19:36:43 +02:00
Mario Vavti
2c777acb25 composer update sabre libs 2020-08-22 19:31:29 +02:00
Mario Vavti
49df57df45 use the default setting and also add the mode to the cipher. aes-128 is to be preferred over aes-256 according to bruce schneier https://www.schneier.com/blog/archives/2009/07/another_new_aes.html#c386957 2020-08-21 10:55:55 +02:00
Mario Vavti
374c30999a whitespace 2020-08-20 22:51:19 +02:00
Mario Vavti
2ab480188a Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-08-20 22:47:53 +02:00
Mario Vavti
c4c47f7777 first cut on implementing additional encryption with the SJCL library. aes only and no backward compatibility. 2020-08-20 22:47:33 +02:00
Mario
c36b2ca915 be more clear in comment 2020-08-20 08:53:58 +00:00
Mario
e55a1a6aa8 fix item deletion 2020-08-20 08:43:13 +00:00
Mario
21e5b05b14 Merge branch 'dev' into 'dev'
issue with DAV - moveInto and variable scope

See merge request hubzilla/core!1868
2020-08-17 20:40:41 +02:00
nobody
ea845aeacd issue with DAV - moveInto and variable scope 2020-08-16 16:29:00 -07:00
nobody
ee3b077f26 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-08-16 16:28:17 -07:00
Mario Vavti
393cee6619 $id is expected to be an array with a calendarId and an instanceId for caldav 2020-08-15 13:17:04 +02:00
Mario
d9196bb82a Merge branch 'dev' into 'dev'
update profile|cover photo activities converted to z6

See merge request hubzilla/core!1865
2020-08-05 19:13:44 +02:00
Zot
5ecbbfc7df update profile|cover photo activities converted to z6 2020-08-05 19:13:44 +02:00
nobody
9244ee8094 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-08-04 16:26:44 -07:00
nobody
0b7ca61958 update profile|cover photo activities converted to z6 2020-08-04 16:25:33 -07:00
Mario
c56b140387 Ãthis should not be required anymore 2020-08-03 19:51:03 +00:00
Mario
3e7d3a20af css fix 2020-07-31 09:37:59 +00:00
Mario
2d2cab0aba event display zot/zot6 compatibility 2020-07-31 08:41:18 +00:00
Mario
364346b07c syntax 2020-07-30 19:22:02 +00:00
Mario
be15a395d8 use cursor-pointer for the lock 2020-07-30 12:32:00 +00:00
Mario
845f7e9382 add new lock icon as svg 2020-07-30 09:59:25 +00:00
Mario
976d6baf6a use the compact view in html2plain() 2020-07-30 08:48:02 +00:00
Mario
f9271bb0bd Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-07-30 08:22:01 +00:00
Mario
06f03eb13a respect notifications settings 2020-07-30 08:21:43 +00:00
Mario
1a1c0ca72c Merge branch 'dev' into 'dev'
Add minimum form displaying time before login

See merge request hubzilla/core!1863
2020-07-30 09:26:30 +02:00
Mario
73f2db09ae Merge branch 'dev' into 'dev'
foreach warning and a minor update to util/zotsh

See merge request hubzilla/core!1864
2020-07-30 09:19:32 +02:00
Mario
be533679dd raise cache lifetime - this should probably be configurable 2020-07-30 06:56:25 +00:00
Mario
e31903cbc9 add some context to the notifications 2020-07-29 19:53:00 +00:00
Mario
33d417955d version 2020-07-26 07:47:52 +00:00
Mario
9f0f794a0a whitespace 2020-07-26 07:46:22 +00:00
Mario
33e4d7c0d8 fix hubloc_id_url for activitypub with broken xchan_url 2020-07-26 07:45:20 +00:00
Mario
ad30834123 version 2020-07-26 07:31:05 +00:00
Mario
fba64e9451 improve profile detection and reduce feed result set 2020-07-26 07:16:06 +00:00
Mario
9b5e270379 tool to fix missing hubloc_id_url entries 2020-07-24 20:46:55 +00:00
Mario
ea5131db88 construct hubloc_id_url for imported legacy zot hublocs 2020-07-24 20:44:55 +00:00
zotlabs
7ae86d29d2 add api_verify to api_zot 2020-07-22 16:23:38 -07:00
zotlabs
13ff9a897d foreach warning 2020-07-22 16:20:36 -07:00
Max Kostikov
4db38ec64a Add minimum form displaying time before login 2020-07-21 23:59:26 +02:00
Mario
29c5a65e8f reset bParam_page in case of failure 2020-07-21 19:25:37 +00:00
Mario
dd2ffae8bf Revert "zot6 testing"
This reverts commit 4f95b44ff2.
2020-07-21 19:08:03 +00:00
Mario
ca969cd0ed those are not lÃikely to be parents 2020-07-21 17:54:14 +00:00
Mario
4f95b44ff2 zot6 testing 2020-07-21 17:29:40 +00:00
Mario
cb7aec0da5 slightly raise cache lifetime 2020-07-21 09:10:31 +00:00
Mario
62eebc86f6 no need to iterate the object twice 2020-07-21 09:09:41 +00:00
Max Kostikov
5ea7196e78 Merge branch 'dev' into 'dev'
Dev sync

See merge request kostikov/core!1
2020-07-19 14:58:19 +02:00
Mario
fcc47e69e4 do not cache single thread pages 2020-07-16 11:59:35 +00:00
Mario
d2f1c37431 more itemspage work 2020-07-16 10:49:08 +00:00
Mario
817fe8d485 version 2020-07-16 10:14:09 +00:00
Mario
1dbd85322d an attempt to improve lazy loading 2020-07-16 10:13:26 +00:00
Mario
fe90096ace bump zot revision to 6.0 std version to 4.7.9 2020-07-14 12:51:31 +00:00
Mario
ad60309187 minor adjustion 2020-07-14 12:48:21 +00:00
Mario
634a515ec1 reduce result sets and work around a regression in justifiedGallery 2020-07-14 12:43:34 +00:00
Mario
01abb82c37 prefer zot6 sys channel 2020-07-14 09:36:10 +00:00
Mario
1c88a8d4a0 Merge branch 'dev' into 'dev'
z6 work

See merge request hubzilla/core!1862
2020-07-14 09:24:11 +02:00
Mario
ce77f82966 more zot6 2020-07-13 20:52:15 +00:00
Mario
573af9e366 fix embeded shares 2020-07-13 18:59:23 +00:00
Mario
774cc852d4 fix php warning 2020-07-13 09:18:11 +00:00
zotlabs
c0735a5ca2 z6trans: don't swap xprof xchans on directory servers because it will fail with duplicate primary key in many cases and the migration will fail on each channel. What this means is that directory servers may take time to pick up zot6 entries if they haven't received them prior to the upgrade. I don't see an easier solution unless we check for existence of the zot6 xchan_hash in the xprof table before converting it. 2020-07-12 19:16:37 -07:00
zotlabs
fa752b0ac1 zot6 group updates to support edit and delete of top-level group posts. This is supported remotely by editing or removing the post that started it all. A W2W post can only be deleted at this time. 2020-07-12 19:06:24 -07:00
Mario
3f69fc70f1 sbom add jquery 2020-07-05 07:55:21 +00:00
Mario
137f56f994 only redirect to known sites 2020-06-19 08:18:43 +00:00
Mario
e2cbcf7039 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-06-18 19:40:18 +00:00
Mario
64f8df0a0d looks like fullcalendar now requires a date object instead of a string 2020-06-18 19:40:00 +00:00
Mario
274d556ec1 add a title 2020-06-18 10:46:45 +02:00
Mario
f28c3b441e start a software bill of materials - this is work in progress 2020-06-18 08:39:06 +00:00
Mario
4eaa893e0b Merge branch 'dev' into 'dev'
zap group support

See merge request hubzilla/core!1859
2020-06-17 09:12:15 +02:00
Zot
36e969fd79 zap group compatibility - rewrites DMs and wall-to-wall posts to group pages as new posts authored by the group with an embedded reshare. This currently has known delivery issues due to zot/zot6 xchan confusion which are already slated for resolution in hz5. Specifically "sender is not owner/author" and missing abconfig permissions on the zot6 identity for a channel we're connected with over traditional zot. 2020-06-17 09:12:15 +02:00
Mario
d8f16960c8 Merge branch 'dev_homeinstall_reminder' into 'dev'
Dev homeinstall reminder

See merge request hubzilla/core!1860
2020-06-17 09:08:20 +02:00
OJ Random
101a7648ee Dev homeinstall reminder 2020-06-17 09:08:20 +02:00
Mario
70a104f24f upÃdate copperjs to version 1.5.7 2020-06-16 07:32:55 +00:00
Mario
0f27db6271 uodate justified-gallery to version 3.8.1 2020-06-15 09:35:39 +00:00
Mario
56ec55110a update fullcalendar to version 4.4.2 2020-06-15 08:19:13 +00:00
Mario
570497071d Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-06-15 07:04:40 +00:00
Mario
49dee6312f new file 2020-06-15 07:02:18 +00:00
Mario
63a6b4a162 composer update commerceguys/intl 2020-06-15 07:01:35 +00:00
Mario Vavti
ec4dea0920 zot6 does not appear to use zfinger 2020-06-14 18:47:18 +02:00
Mario Vavti
7270da6a28 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-06-14 15:39:00 +02:00
Mario Vavti
8cd66145bd fix discovery 2020-06-14 15:38:44 +02:00
Mario
92ee27349c check for zot6 first 2020-06-14 13:35:17 +00:00
Mario
a88233a045 composer update jquery-file-upload 2020-06-13 12:01:27 +00:00
Mario
0259130cf3 update jquery to version 3.5.1 2020-06-13 11:18:57 +00:00
Mario
d0a1f0b8f9 revert additional top border 2020-06-13 11:18:26 +00:00
Mario
97dd350c61 css fixes due to bootstrap update 2020-06-13 11:13:47 +00:00
Mario
dc3b09c8f3 composer update bootstrap 2020-06-13 10:00:50 +00:00
Mario
c8c4513af9 Merge branch 'dev' into 'dev'
allow apps to be both pinned and starred independently

See merge request hubzilla/core!1858
2020-06-11 12:13:44 +02:00
Zot
3201a4bec5 allow apps to be both pinned and starred independently 2020-06-11 12:13:43 +02:00
Mario
9da8e30c37 Merge branch 'fix-invite-code-deletion' into 'dev'
Fix invite code deletion

See merge request hubzilla/core!1857
2020-06-01 14:46:47 +02:00
Keenan Pepper
6bfac1a907 Fix bug allowing invite codes to be reused unlimited times
The invite codes aren't deleted from the DB because of a malformed query.
2020-05-27 13:52:38 -07:00
Mario
d0c7c99d5e use strip_tags() on rss titles 2020-05-18 11:06:46 +00:00
Mario
934bcf5336 comment out code which is only required for loggingà 2020-05-18 08:46:30 +00:00
Mario
5b88873530 re-enable time logging 2020-05-18 07:33:32 +00:00
Mario
b161b02c51 bump version 2020-05-18 07:29:41 +00:00
Mario
ddc544e00a add images load status to spinnner if preload images is enabled 2020-05-18 07:28:25 +00:00
Mario
97d5ffe056 wrong path 2020-05-16 08:44:24 +00:00
Mario Vavti
13319985fd uuid for likes 2020-05-15 19:28:03 +02:00
Mario
e3aaa39f9e Revert "uuid for likes"
This reverts commit b6efb02ed2.
2020-05-15 15:26:05 +00:00
Mario
b6efb02ed2 uuid for likes 2020-05-15 15:08:57 +00:00
Mario
c358d8326e whitespace 2020-05-15 13:16:07 +00:00
Mario
f40fedcad6 rewriting the author for legacy compatibility only if author is from this site and add comment. 2020-05-15 12:40:06 +00:00
Mario
b4973ede44 rewriting the owner for legacy compatibility should be sufficient 2020-05-15 12:11:35 +00:00
Mario
81338e8086 use zot_record_preferred() when fetching keys 2020-05-15 10:10:07 +00:00
Mario
4270e17bc4 implement notifications for direct messages 2020-05-14 09:27:39 +00:00
Mario
1329662edc use dbq() in update 1238 2020-05-12 09:13:59 +00:00
Mario
249427365b bump version 2020-05-12 09:08:56 +00:00
Mario
326644104c really fix update for postgres 2020-05-12 08:56:05 +00:00
Mario
1520a26e0f fix update for postgres 2020-05-12 08:34:35 +00:00
Mario
6ffdc1b642 update file 2020-05-12 08:29:54 +00:00
Mario
22d8523e76 DB update 1238 to fix hubloc_id_url for existing hublocs and set hubloc_id_url in Activity::actor_store() 2020-05-12 08:23:41 +00:00
Mario
2d3740b912 Legacy Hubzilla compatibility: when we relay a comment from hubzilla < 4.0, we send it to ourself again but this time with a valid uri as mid. To catch this as duplicate, we need to check for the basename aswell. 2020-05-11 20:22:25 +00:00
Mario
c8ab5db768 Merge branch 'dev' into 'dev'
Dev

See merge request hubzilla/core!1856
2020-05-11 19:54:22 +02:00
zotlabs
c656478230 issue with quoted hashtags/mentions 2020-05-10 16:13:01 -07:00
Mario
3d02758fee deal with diaspora uuid 2020-05-10 10:55:57 +00:00
Mario
f473b5abfb as_vid_sort -> vid_sort 2020-05-10 07:53:21 +00:00
Mario
22d68ddf08 it looks like this was required at some point but is not required anymore for our autocomplete to work as expected. fixes #1463 2020-05-08 12:21:06 +00:00
Mario
2cba88f1eb new files 2020-05-07 21:49:08 +00:00
Mario
f132436af3 composer updates 2 2020-05-07 21:48:26 +00:00
Mario
fae70bf0a7 Revert "composer updates"
This reverts commit dbfe748d27
2020-05-07 23:35:02 +02:00
Mario
ffd2faf8a0 Revert "add new files"
This reverts commit c76ff4249e
2020-05-07 23:34:41 +02:00
Mario
64a8913385 tests: more declare return type 2020-05-07 21:00:49 +00:00
Mario
266dcd44bb tests: declare return type 2020-05-07 20:49:52 +00:00
Mario
8851921d6d bump php version to 7.3 for gitlab-ci 2020-05-07 20:36:45 +00:00
Mario
c76ff4249e add new files 2020-05-07 15:23:30 +00:00
Mario
dbfe748d27 composer updates 2020-05-07 15:22:25 +00:00
Mario
4ee809bed6 fix tests 2020-05-07 08:31:31 +00:00
Mario
4ebf6cda5d remove more traces of the premium channel app 2020-05-07 08:06:38 +00:00
Mario
a04b6d178b deprecate premium channel app 2020-05-07 07:55:05 +00:00
Mario
c8b45c3449 channelx caching 2020-05-07 06:57:33 +00:00
Mario
1bb74a5a01 css 2020-05-06 19:59:21 +00:00
Mario
ef94072cee Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-05-06 19:56:47 +00:00
Mario
ff3ff2478d allow to set different values for left and right aside width in $theme.php 2020-05-06 19:56:37 +00:00
Mario
2757822cd8 Merge branch 'dev' into 'dev'
Issue generating photo thumbnails when uploaded via davfs

See merge request hubzilla/core!1855
2020-05-06 11:00:30 +02:00
Zot
2cb0cade7b Revert "issue generating photo thumbnails when uploaded via davfs"
This reverts commit 7a0d9a4494.
2020-05-06 11:00:29 +02:00
zotlabs
191e01e3ec re-apply after removing from cherry-picked git hash from wrong branch 2020-05-05 20:01:09 -07:00
zotlabs
8c65e9cb4a Revert "issue generating photo thumbnails when uploaded via davfs"
This reverts commit 7a0d9a4494.
2020-05-05 19:59:22 -07:00
zotlabs
79968ea07a Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-05-05 19:42:00 -07:00
zotlabs
7a0d9a4494 issue generating photo thumbnails when uploaded via davfs 2020-05-05 19:39:09 -07:00
Mario
06d1cf83d2 deal with polls and votes in enotify 2020-05-05 14:51:00 +00:00
Mario
de058901c2 catch the owner_xchan for activity_share items in notifications filter 2020-05-05 07:40:24 +00:00
Mario
a40b882d72 typo 2020-05-04 09:26:06 +00:00
Mario
46242aeaae display complete perminfo only to owner 2020-05-04 09:24:22 +00:00
Mario
ad040a0b11 set CURLOPT_ENCODING in z_post_url() 2020-05-04 07:44:19 +00:00
Mario
4eaba326ce version 4.7.6 2020-05-03 12:33:42 +00:00
Mario
fd48f9d173 improve functionality of combined notification filters 2020-05-03 12:31:10 +00:00
Mario
104c45f6e6 Merge branch 'dev' into 'dev'
Display delayed posts on author's channel page

See merge request hubzilla/core!1854
2020-05-02 17:28:49 +02:00
Max Kostikov
f4a71db42d Display delayed posts on author's channel page 2020-05-02 17:28:49 +02:00
Mario
1ac2b93fd8 Merge branch 'iss1457' into 'dev'
stress the importance of  PHP mail()

See merge request hubzilla/core!1852
2020-05-02 17:27:40 +02:00
Mario
03c1419ad0 missing lib include 2020-05-02 11:48:11 +00:00
Mario
18938280f5 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-05-01 10:24:13 +00:00
Mario
01334d761a set CURLOPT_ENCODING to empty string so that compressed content will be uncompressed 2020-05-01 10:24:00 +00:00
Max Kostikov
446204f7d8 Merge branch 'dev' into 'dev'
Force browser photo revalidation

See merge request hubzilla/core!1853
2020-04-29 14:44:42 +02:00
Max Kostikov
328900cf3b Force browser photo revalidation 2020-04-29 14:38:11 +02:00
Mario
837dbb7a14 Ãfix photo items 2020-04-29 11:10:54 +00:00
Mario
c9794439bc adjust code comments and whitespace 2020-04-29 08:24:00 +00:00
Mario
079c13e633 more work on attach_store_item() 2020-04-29 08:21:33 +00:00
OJ Random
7b8c85cf3f stress the importance of PHP mail() 2020-04-27 09:59:17 +02:00
Mario
c229f058b4 fix mod filestorage and fetch the info from attach if only the hash is provided in attach_store_item() 2020-04-25 09:15:20 +00:00
Mario
e2b10f52e0 more work on deprecating ACTIVITY_OBJ_FILE and adapt mod sharedwithme 2020-04-24 14:25:49 +00:00
Mario
2b8afd5580 fix file notifications 2020-04-23 19:38:19 +00:00
Mario
7e89d816d7 more work on deprecating ACTIVITY_OBJ_FILE 2020-04-23 19:14:43 +00:00
Mario
77c87bcccf default item_wall to 0 2020-04-23 18:21:38 +00:00
Mario
b7a655917e some work on deprecating ACTIVITY_OBJ_FILE 2020-04-23 18:19:25 +00:00
Mario
d8bfa5dd96 Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-04-22 18:15:38 +00:00
Mario
88eb19165b the parent id is required later in the process 2020-04-22 18:15:02 +00:00
Mario
2828b8cf5c Merge branch 'dev_homeinstall' into 'dev'
fixes for real installation for debian 10

See merge request hubzilla/core!1851
2020-04-22 14:18:50 +02:00
Mario
b1b9dbe55f more prefer zot6 over zot 2020-04-22 07:44:51 +00:00
Mario
579adb4897 fix onepoll 2020-04-21 09:42:40 +00:00
OJ Random
a9d52cd296 fixes for real intallation for debian 10 2020-04-20 17:56:52 +02:00
Mario
c71422e909 add the spec folder 2020-04-20 15:53:43 +00:00
Mario
03506bd6cf use $mid as plink to prevent to long plinks 2020-04-20 11:58:08 +00:00
Mario
244936b0fd some work on improving federation of item_private and make sure we deal with an array in array_path_exists() 2020-04-20 09:34:00 +00:00
Mario
f430a24fa3 missing lib import 2020-04-19 14:24:52 +00:00
Mario
ecb1c78173 make sure $post_tags is defined somewhere outsite a clause to prevent PHP warnings 2020-04-19 14:17:00 +00:00
Mario
42631b5943 revert 2020-04-18 14:22:40 +00:00
Mario
109f9eed61 just fetch the info we need 2020-04-18 14:09:08 +00:00
Mario
c7fdc53795 more do not include hublocs with no hubloc_id_url 2020-04-18 13:59:30 +00:00
Mario
602ca91700 remove debug code 2020-04-18 13:17:37 +00:00
Mario
4cfc0b1a64 de-duplicate $post_tags 2020-04-18 12:19:34 +00:00
Mario
3d5fdd086b only return hublocs with hubloc_id_url set 2020-04-18 11:30:19 +00:00
Mario
223c4c7b9a implement addressing and fix conversation fetching 2020-04-18 09:23:48 +00:00
Mario
f7e925beaa Revert "keychange and request packets via zot6"
This reverts commit 9d0f71bfcb
2020-04-16 12:33:02 +02:00
Mario
e588ea8a8b fix notification filtering 2020-04-15 15:39:33 +00:00
Mario
91cad21d33 fetch the item for asld in Lib/Share. This probably fixes addons issue #146 2020-04-15 11:56:56 +00:00
Mario
d6b9c8b93d Ãfix php warning 2020-04-15 08:43:28 +00:00
Mario
a7273668d8 Merge branch 'dev' into 'dev'
Remove unnecessary [summary] tag processing

See merge request hubzilla/core!1850
2020-04-15 10:22:54 +02:00
Max Kostikov
b1f74f4ef4 Remove unnecessary [summary] tag processing 2020-04-15 10:22:54 +02:00
Mario
c640d1c599 Merge branch 'dev' into 'dev'
event issue when using strict sql mode

See merge request hubzilla/core!1849
2020-04-15 10:22:31 +02:00
Mario
9d0f71bfcb keychange and request packets via zot6 2020-04-15 08:21:07 +00:00
Max Kostikov
bbca6be0f9 Update Item.php 2020-04-12 23:08:11 +02:00
Max Kostikov
31e1e9cbfb Remove unnecessary [summary] tag processing 2020-04-12 21:41:32 +02:00
Mario
6de823b532 discover_feed() does not exist yet 2020-04-12 08:59:42 +00:00
Mario
69878ed628 handle some basic friendica attachment bbcodes 2020-04-12 07:54:22 +00:00
Mario
27ae9c9d34 just comment out is_edit_activity() call and add comments on why it is commented out 2020-04-12 07:35:17 +00:00
Mario
52e698cae6 function is_edit_activity() is obsolete 2020-04-12 07:05:01 +00:00
zotlabs
6a0ac591d1 event issue when using strict sql mode 2020-04-10 14:27:20 -07:00
Mario
328685d2fb move from build_sync_packet() to Libsync::build_sync_packet() 2020-04-09 09:38:36 +00:00
Mario
806c738923 remove voting from UI in favour of polls 2020-04-08 18:41:54 +00:00
Mario
9c2d48bcd4 update 1236: we have seen situations in the wild where a zot6 xchan was present while its hubloc was missing. fix those separately if required so that we cover both situations. 2020-04-08 12:20:44 +00:00
Max Kostikov
d8802e4fc8 Merge branch 'dev' into 'dev'
Fix process id disclouse

See merge request hubzilla/core!1848
2020-04-08 11:40:32 +02:00
Max Kostikov
2c8a243ece Merge branch 'dev' into 'dev'
# Conflicts:
#   Zotlabs/Daemon/Expire.php
2020-04-08 11:34:29 +02:00
Max Kostikov
3372fb0761 Fix process id disclouse 2020-04-08 11:31:17 +02:00
Mario
af7a31cd14 owa: look for zot6 first 2020-04-06 12:12:44 +00:00
Mario
cb2996a40c another import fix and do not allow importing channels < version 4.7.4 for zot6 compatibility reasons 2020-04-05 15:00:08 +00:00
Mario
ea237a97a1 more mod import fixes 2020-04-05 11:37:42 +00:00
Mario
530b1d038f fix mod import 2020-04-05 11:19:12 +00:00
Mario
a31981966e fix warning if iconfig value is an array 2020-04-05 09:29:23 +00:00
Mario
84183d9f7e show event timezone only if adjust ist set and the offset of the event timezone is different from the channel default timezone offset 2020-04-05 09:11:12 +00:00
Mario
805f8bf983 show event timezone if it differs from the channel default timezone 2020-04-05 07:59:41 +00:00
Mario
67c9b5d049 fix unseen forum posts count 2020-04-05 06:47:12 +00:00
Mario
44b935f875 another attempt to get events right 2020-04-04 15:41:58 +00:00
Mario
cade25a112 Revert "more timezone changes"
This reverts commit cec2e92fe3
2020-04-03 22:01:44 +02:00
Mario
a4831b0f7c Revert "use timezone info for timezone display only- the actual time is in utc already."
This reverts commit 625438ff64
2020-04-03 22:01:24 +02:00
Mario
ec9418b262 Revert "set timezone iconfig a little earlier in the process so that it will be included in the object"
This reverts commit 6cfaa5cba3
2020-04-03 22:01:02 +02:00
Mario
cec2e92fe3 more timezone changes 2020-04-03 19:50:50 +00:00
Mario
625438ff64 use timezone info for timezone display only- the actual time is in utc already. 2020-04-03 19:22:31 +00:00
Mario
6cfaa5cba3 set timezone iconfig a little earlier in the process so that it will be included in the object 2020-04-03 18:34:15 +00:00
Mario
31fea1014e Merge branch 'dev' into 'dev'
fix app links in DB when doing a site rename

See merge request hubzilla/core!1846
2020-04-03 10:51:34 +02:00
Mario
898fea1e0e Merge branch 'dev' into 'dev'
Avoid multiple run of expiry procedure on large sites

See merge request hubzilla/core!1847
2020-04-03 10:49:57 +02:00
Max Kostikov
4b3979df04 Avoid multiple run of expiry procedure on large sites 2020-04-03 10:49:57 +02:00
Mario
ac52bebb88 ATOM_TIME format is not compatible with the DB 2020-04-02 12:33:57 +00:00
Mario
c568f7b8d1 bump version 2020-04-01 18:22:33 +00:00
Mario
d925ec6759 fix outgoing mails to zot connections 2020-04-01 18:13:00 +00:00
Max Kostikov
c136c142b8 Use config instead pconfig 2020-04-01 12:59:12 +02:00
Mario
38be2386dd cheat with guid_sig to reflect transition to zot6 and re-enable transition of connections 2020-04-01 09:26:27 +00:00
Mario
643b2f9205 do not enable transition of connections yet 2020-04-01 08:03:19 +00:00
Mario
ffe429be65 transition connections to zot6 if their site has been updated 2020-04-01 07:44:07 +00:00
Max Kostikov
4a56b77f64 Use pconfig 2020-03-31 21:00:21 +02:00
Max Kostikov
9773ab7aab Use POSIX kill 0 to check expire process status 2020-03-31 20:45:15 +02:00
Max Kostikov
6c02fa40f1 Check if POSIX PHP module is available on PID check 2020-03-31 20:15:09 +02:00
Max Kostikov
632996f53e Add check if expire procedure is still running 2020-03-31 20:03:29 +02:00
Max Kostikov
710448e73f Update Expire.php 2020-03-31 19:58:08 +02:00
Max Kostikov
084177a20c Avoid multiple run of expiry procedure on large sites 2020-03-31 19:57:05 +02:00
Max Kostikov
5a2c62466e Merge branch 'dev' into 'dev'
Sync dev

See merge request kostikov/core!2
2020-03-31 19:54:20 +02:00
Mario
b739f91caa use Libsync::build_sync_packet() in mod item, default Lib/Queue driver to zot6 and some whitespace cleanup in queue_deliver() 2020-03-29 15:18:49 +00:00
Mario
b1590ad645 fix check for existing hublocs 2020-03-29 10:47:22 +00:00
Mario
f49010bb12 port fhublocs to zot6 and fix issue with primary detection 2020-03-29 08:33:42 +00:00
Mario
6e1c3b6d48 Merge branch 'z6connect' into 'dev'
Transition to zot6

See merge request hubzilla/core!1823
2020-03-28 11:12:22 +01:00
Mario
bcdd75b817 prevent mod fhublocs breaking things. it needs porting to zot6 but has no priority for now. 2020-03-28 09:29:49 +00:00
Mario
0271f2a1ae fix z6_discover() to do the right thing after transition 2020-03-26 08:14:20 +00:00
Mario
0c1c386a0a do not use channel_portable_id in process_channel_sync_delivery(). we should only accept sync packages from channels which are already transitioned to zot6. 2020-03-25 11:29:00 +00:00
zotlabs
a3acec9674 issue 1454 - some photo item ActivityStreams links not returning json-ld; requires related fixes in addons/pubcrawl 2020-03-24 18:26:20 -07:00
Mario
4eaddd1279 do not sync with incompatible hubs 2020-03-24 08:32:37 +00:00
Mario
eb3dbcce7b one more typo 2020-03-16 22:04:28 +00:00
Mario
3ecf1cab5e typo 2020-03-16 21:55:59 +00:00
Mario
c536526196 Update 1236 and bump version to 4.7.4 2020-03-16 20:12:30 +00:00
Mario
b2de12442d wrong variable 2020-03-13 19:32:59 +00:00
zotlabs
8f5cb0c45a Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-03-12 17:55:35 -07:00
Mario
3b4503c971 use xchan_guid_sig instead of channel_guid_sig since it slightly differs depending on *default* protocol 2020-03-12 19:09:34 +00:00
Mario
c358aa2806 first batch of zot6 transition patches. basic communication with transitioned channels *should* work now 2020-03-12 18:27:16 +00:00
zotlabs
938d26ba3e fix app links in DB when doing a site rename 2020-03-11 15:18:33 -07:00
Mario
b23751128b port create_identity() to zot6 2020-03-11 10:43:19 +00:00
Mario
d54ff4fae5 Merge branch 'dev' into z6connect 2020-03-11 10:35:05 +00:00
Mario
720d3dcedc z6trans preparation for db update 1236 2020-03-11 10:34:25 +00:00
Mario
ce4fc30439 use 24h time format 2020-03-06 10:11:10 +00:00
Mario
b39474456f Merge branch 'dev' of https://framagit.org/hubzilla/core into dev 2020-03-06 09:51:10 +00:00
Mario
25cd9b4983 provide tool to transform channels to zot6. WARNING: transformed channels will not yet be functional without additional patches. 2020-03-06 09:50:53 +00:00
Max Kostikov
2d65ce542c Merge branch 'dev' into 'dev'
Dev

See merge request hubzilla/core!1845
2020-03-06 10:42:17 +01:00
Max Kostikov
c2b691fd01 Translate 'vote' button text 2020-03-06 10:33:25 +01:00
Max Kostikov
ae691bdc7c Merge branch 'dev' into 'dev'
Sync dev

See merge request kostikov/core!1
2020-03-06 10:26:19 +01:00
Mario
ba566fd64b Merge branch 'dev' into z6connect 2020-03-02 09:50:11 +00:00
Max Kostikov
85c07d57fe Merge branch 'dev' into 'dev'
rework img alt text - preserve legacy bbcode

See merge request hubzilla/core!1844
2020-03-01 16:23:24 +01:00
zotlabs
16fd618380 rework img alt text - preserve legacy bbcode 2020-02-29 13:08:16 -08:00
Mario
06f2979e04 prevent duplicate votes 2020-02-29 10:25:22 +00:00
Mario
1ff9d1afdd Merge branch 'dev' into 'dev'
alt attribute for images

See merge request hubzilla/core!1843
2020-02-29 11:15:55 +01:00
zotlabs
a776f69a59 alt attribute for images 2020-02-28 14:31:49 -08:00
Mario
a574290235 poll UI strings 2020-02-28 13:22:30 +00:00
Mario
84c9ae04fc Merge branch 'wiki-link-titles' into 'dev'
Allow wiki link titles

See merge request hubzilla/core!1842
2020-02-28 12:23:01 +01:00
BattleMage
c74c41c3b8 Allow wiki link titles
Allow linking to wiki pages with alternating titles by separating the
title from the link with a pipe, like regular wiki markup does.
2020-02-28 10:31:07 +01:00
Mario
7cf73e0533 Merge branch 'dev' into 'dev'
add iconfig to zot6 objects

See merge request hubzilla/core!1835
2020-02-27 10:22:48 +01:00
Mario
03e9ed71b4 version 4.7.3 2020-02-27 09:22:06 +00:00
zotlabs
85cf25a2a8 add iconfig to zot6 objects 2020-02-23 15:28:16 -08:00
Mario
19bb9e0181 zap is storing perms different from hubzilla - revert Lib/Connect to use the hubzilla way. Eventually we might want to streamline this with zap. This will require a DB update to upgrade permissions in abconfig. 2020-01-30 10:12:45 +00:00
Mario
9545a81166 update create_identity() to use Lib/Connect via connect_and_sync() ported from zap 2020-01-26 19:41:52 +00:00
Mario
1712eceaf9 port Lib/Connect and Module/Follow from zap. Connect with new connections via zot6 2020-01-26 15:08:55 +00:00
Mario
6f93d9848c Disable oembed in directory profile about 2019-12-17 10:53:40 +01:00
Mario
bde429cff6 Merge branch '4.6RC' 2019-12-04 10:25:11 +00:00
Mario
4c8d33d1eb bump version 2019-12-04 10:24:03 +00:00
Mario
fac7826efa update changelog
(cherry picked from commit 295c08fcf3)
2019-12-04 11:22:56 +01:00
DM42.Net Hubzilla Development
3e133bbfa3 Move auto_save_draft to header from thread comment
(cherry picked from commit c86b35da70)
2019-11-28 09:42:59 +01:00
Max Kostikov
6c8d1bdffe Update CHANGELOG
(cherry picked from commit 9284b60a79)
2019-11-28 09:42:00 +01:00
Max Kostikov
59fc495593 Update Russian hstrings.php
(cherry picked from commit b69f8a3f29)
2019-11-28 09:41:40 +01:00
Max Kostikov
60827bdcc4 Update Russian hmessages.po
(cherry picked from commit 8ea7c08f43)
2019-11-28 09:41:19 +01:00
Mario
f992feb71c update changelog
(cherry picked from commit fcb065bcb2)
2019-11-25 22:06:59 +01:00
Mario
cf66e66db8 Merge branch '4.6RC' of https://framagit.org/hubzilla/core into 4.6RC 2019-11-25 21:03:35 +00:00
Max Kostikov
63aa3948e5 resolve merge conflict 2019-11-25 21:03:22 +00:00
Max Kostikov
7899ed6f69 Revert "Add daily cached embedded content cleanup"
This reverts commit 5c47c9ed95

(cherry picked from commit 38de059156)
2019-11-25 21:58:36 +01:00
Max Kostikov
5e44239657 Add daily cached embedded content cleanup
(cherry picked from commit 5c47c9ed95)
2019-11-25 21:58:18 +01:00
Mario
17cd452fff changelog
(cherry picked from commit f6f7e7e8d2)
2019-11-25 12:33:36 +01:00
Mario
004861fbb7 merge opengraph fixes from dev 2019-11-25 08:41:34 +00:00
Manuel Jiménez Friaza
8727f12b18 no mention notifications from mastodon (and pleroma)
(cherry picked from commit ea235c0c67)


(cherry picked from commit 0159b631fc)
2019-11-21 14:49:59 +01:00
Mario
05604e4bd2 onepoll: do not update dead feeds
(cherry picked from commit 5a6b14f878)
2019-11-15 11:03:54 +01:00
Mario
fd7d497cd1 make inline pdf a security option, move thumbnail security to security options from admin/site
(cherry picked from commit de9a7f0fa9)
2019-11-15 11:03:38 +01:00
Mario
a974d0d52d AP fixes
(cherry picked from commit 3009c88d24)
2019-11-15 11:02:55 +01:00
Mario
c850a61a89 check if file exists
(cherry picked from commit 52bd27a028)
2019-11-13 16:26:57 +01:00
zotlabs
3a2fdec241 wildcard tag issue
(cherry picked from commit 2f4c619d51)
2019-11-13 08:57:12 +01:00
Mario
08b804cd2d use minified version of jquery
(cherry picked from commit 89342ca9fb)
2019-11-11 11:17:42 +01:00
Mario Vavti
cc9f41df5f bump version 2019-08-16 20:22:16 +02:00
Mario Vavti
bb3784d8dd update changelog
(cherry picked from commit e5539c0d01)
2019-08-16 20:21:19 +02:00
zotlabs
c997360b4a show correct profile photo when previewing and editing profiles
(cherry picked from commit 808baf203d)
2019-08-16 19:33:38 +02:00
zotlabs
88fa18204f illegal offset warning (prevents encrypted signatures from being used for encrypted messages). Not fatal but can leak metadata.
(cherry picked from commit feda23587c)
2019-08-16 19:29:21 +02:00
Mario Vavti
e8f3b7f853 Merge branch '4.4RC' 2019-08-13 09:46:01 +02:00
Mario Vavti
e28341ca4b bump version 2019-08-13 09:44:28 +02:00
Mario Vavti
6c11a020ee Merge branch 'dev' into 4.4RC 2019-08-13 09:42:21 +02:00
Mario Vavti
732ca49b02 Merge branch 'dev' into 4.4RC 2019-08-13 09:34:32 +02:00
Mario Vavti
06ac3e896a Merge branch 'dev' into 4.4RC 2019-08-13 09:27:03 +02:00
Mario Vavti
f5062c0507 Merge branch 'dev' into 4.4RC 2019-08-11 10:56:00 +02:00
Mario Vavti
7a7f57fa45 Merge branch 'dev' into 4.4RC 2019-08-11 10:23:14 +02:00
Mario Vavti
0e0024218f Merge branch 'dev' into 4.4RC 2019-08-09 22:21:40 +02:00
Mario Vavti
6c12880f5b fix version 2019-08-09 20:37:06 +02:00
Mario Vavti
eb472111a8 Merge branch 'dev' into 4.4RC 2019-08-09 20:35:25 +02:00
Mario Vavti
681dc70205 Merge branch 'dev' into 4.4RC 2019-08-09 20:33:45 +02:00
Mario Vavti
130cfbf231 make fetch logging less chatty 2019-08-09 20:33:03 +02:00
Mario Vavti
3070baf04e version 2019-08-01 22:36:51 +02:00
Mario Vavti
72629ca511 bump version 2019-08-01 22:11:27 +02:00
zotlabs
892e9cd835 minor zot6 compatibility issues uncovered through daily use
(cherry picked from commit becaa3b920)
2019-06-21 13:03:58 +02:00
Mario Vavti
109c66aea3 apply calendar encoding fixes to mod cal
(cherry picked from commit 24b0f8e27e)
2019-06-20 18:45:12 +02:00
Mario Vavti
1a76e83fa4 fix encoding also for description and location
(cherry picked from commit f37387de80)
2019-06-20 18:40:57 +02:00
Mario Vavti
2fa788b01b various calendar UI improvements: make day- and weeknumbers clickable for navigation, hide start and end time fields in month view (only allday events can be generated there), remove the action arg from changeView().
;


(cherry picked from commit 4f705fc3f8)
2019-06-20 18:40:39 +02:00
zotlabs
028cbdcffa tweak to event title encoding to ensure it works with German, Russian, as well as angle chars
(cherry picked from commit 952e466d91)
2019-06-20 18:40:19 +02:00
zotlabs
8aefbd911b events: don't use htmlentities on local (hz) event titles as they are not being used in textareas and umlauts for instance are getting mangled on the calendar display
(cherry picked from commit c1cc76119c)
2019-06-20 18:39:58 +02:00
Mario
f046a34d34 Merge branch 'patch-2' into 'master'
Fix os_path replace for thumbnails

See merge request hubzilla/core!1673
2019-06-18 19:17:33 +02:00
Max Kostikov
9e3a4402e0 Fix os_path replace for thumbnails 2019-06-18 18:19:17 +02:00
Mario Vavti
df228237de fix typo
(cherry picked from commit 619b39f955)
2019-06-18 10:37:56 +02:00
Mario Vavti
958217dd55 changelog and version 2019-06-17 10:42:56 +02:00
Mario Vavti
2f80fdae97 Merge branch 'dev' 2019-06-17 10:28:47 +02:00
Mario Vavti
c5703306ef fix mod cal regression
(cherry picked from commit a26774b99e)
2019-06-14 09:53:26 +02:00
Mario
8848885d9a Merge branch 'patch-1' into 'master'
Add resize on image scale to 4 and 7

See merge request hubzilla/core!1667
2019-06-11 17:16:41 +02:00
Max Kostikov
c1cab6789e Add resize on image scale to 4 and 7 2019-06-11 12:55:28 +02:00
Mario Vavti
7889612edc remove sizeRangeSuffixes. they can cause issues with profile photos.
(cherry picked from commit e81e264988)
2019-06-10 22:40:36 +02:00
Mario
eacc29ded0 add the thumbrepair script
(cherry picked from commit 15874ac45c)
2019-06-10 22:36:10 +02:00
Mario
ea04c93bfd resolve merge conflict
(cherry picked from commit 761fc74a67)
2019-06-10 22:35:30 +02:00
Mario
8692977585 fix storageconv issue with postgres
(cherry picked from commit 0e2239e50b)
2019-06-10 22:35:14 +02:00
Mario
6a40f3ed60 Revert "PgSQL compatibility on conversion"
This reverts commit dd1f631d9d
2019-06-10 22:34:51 +02:00
Max Kostikov
dd1f631d9d PgSQL compatibility on conversion
(cherry picked from commit 94254e61c1)
2019-06-10 22:32:54 +02:00
Mario Vavti
9f403a4d6b fix css issue
(cherry picked from commit 55792d5528)
2019-06-07 09:58:51 +02:00
Mario Vavti
a3f726baa8 fix embedphotos image size
(cherry picked from commit ebc2b23c3a)
2019-06-07 08:45:58 +02:00
Mario Vavti
e4ca3609d9 Merge branch '4.2RC' 2019-06-04 10:19:04 +02:00
Mario Vavti
bc092d8d78 version 4.2 2019-06-04 10:16:06 +02:00
Mario Vavti
dd5933b048 Merge branch 'dev' into 4.2RC 2019-06-04 10:13:59 +02:00
Mario Vavti
24cb04c346 do not change default timezone in parse_ical_file()
(cherry picked from commit f1b54cf0a4)
2019-06-03 22:43:20 +02:00
Mario Vavti
e64a7b87a8 fix timezone issue when importing adjusted events
(cherry picked from commit 2b452ea3e8)
2019-06-03 21:04:51 +02:00
Mario
5b4aa1afc2 regard timezones in calendar import/export 2019-06-03 13:25:48 +02:00
Mario Vavti
89205276ab update changelog
(cherry picked from commit 6d2ab6a7d6)
2019-06-03 11:49:04 +02:00
Mario Vavti
e6da910ee2 Merge branch 'dev' into 4.2RC 2019-06-03 11:44:31 +02:00
Mario Vavti
b6bd2884d5 Merge branch 'dev' into 4.2RC 2019-05-29 09:08:40 +02:00
Mario Vavti
097b2390db update changelog
(cherry picked from commit ca8d252ad7)
2019-05-28 12:31:48 +02:00
Mario Vavti
23a0dbe3cc 4.2RC2 2019-05-27 08:19:23 +02:00
Mario Vavti
545ece82b3 Merge branch '4.2RC' of https://framagit.org/hubzilla/core into 4.2RC 2019-05-27 08:09:36 +02:00
Mario Vavti
eaea947b74 Merge branch 'dev' into 4.2RC 2019-05-27 08:07:26 +02:00
Mario Vavti
385be35ed5 fix #1374
(cherry picked from commit 528b9b6a60)
2019-05-24 12:27:14 +02:00
Mario Vavti
dd374eaebf get channel from photo uid
(cherry picked from commit 9ea483d1dc)
2019-05-24 09:59:17 +02:00
Mario Vavti
8715f74d29 Merge branch 'dev' into 4.2RC 2019-05-23 08:44:44 +02:00
Mario Vavti
152224944b add new directory fallback server 2019-05-23 08:43:48 +02:00
Mario Vavti
f86d12c8f4 Merge branch 'dev' into 4.2RC 2019-05-23 08:37:52 +02:00
Mario
e130b58b20 Merge branch 'es-es' into '4.2RC'
Update es-es

See merge request hubzilla/core!1652
2019-05-20 13:06:55 +02:00
Xanthor
a921deafd1 Fix a really disturbing comment
(cherry picked from commit 823c0434eb)

(cherry picked from commit af2b263bc7)
2019-05-17 12:28:41 +02:00
Mario Vavti
071fba2f71 wiki: urlencode the entire share link
(cherry picked from commit aa120e0478)
2019-05-17 12:28:13 +02:00
Mario Vavti
9de729e3e7 wiki: urlencode the entire share link
(cherry picked from commit aa120e0478)
2019-05-17 12:27:54 +02:00
Mario Vavti
7cf5bd30f2 use escape_tags() wiki headers
(cherry picked from commit e7f1f496c5)
2019-05-17 12:27:18 +02:00
Mario Vavti
e6cee2965a use escape_tags() wiki headers
(cherry picked from commit e7f1f496c5)
2019-05-17 12:26:03 +02:00
Mario
b07c55a0d9 Merge branch 'patch-1' into 'master'
Fix a really disturbing comment

See merge request hubzilla/core!1650
2019-05-17 12:01:21 +02:00
Xanthor
823c0434eb Fix a really disturbing comment 2019-05-17 05:23:12 +02:00
Mario Vavti
22162635e7 calendar merge: only export events that will not break the importer. this will probably dismiss some old experimental entries
(cherry picked from commit 8be0031602)
2019-05-15 18:25:59 +02:00
Mario Vavti
29c5e74d31 missing backslash
(cherry picked from commit 3c8867a1e8)
2019-05-15 11:40:36 +02:00
Mario Vavti
c439fe0437 add autocomplete js to calendar and fix issue with extended likes mid
(cherry picked from commit 15a000bb45)
2019-05-14 09:14:04 +02:00
Max Kostikov
b21db670b4 Fix comments scroll button CSS
(cherry picked from commit d0322f5fbd)
2019-05-14 09:13:40 +02:00
Mario Vavti
1f84aa9809 css fixes
(cherry picked from commit c1f01b7e35)
2019-05-14 09:13:19 +02:00
Mario Vavti
4ac249c26c deal with privacy mentions in event descriptions
(cherry picked from commit 71064f481b)
2019-05-14 09:13:02 +02:00
zotlabs
85a29fce94 bbcode map bypass wasn't catching all map forms.
(cherry picked from commit 436293713b)
2019-05-14 09:12:35 +02:00
Mario Vavti
fc726bfb4b fix button size 2019-05-13 13:11:14 +02:00
Mario
f6a4084f81 bump version 2019-04-26 11:30:23 +02:00
Mario Vavti
d5f89c165a update changelog
(cherry picked from commit a518471a27)
2019-04-26 11:29:01 +02:00
zotlabs
dce5080e53 permissions cleanup
(cherry picked from commit 2d886b65ce)
2019-04-26 10:52:35 +02:00
zotlabs
2221d4d612 add attachments to zot6 event objects, add zot6 to federated transports (webfinger)
(cherry picked from commit 0615709a7a)
2019-04-26 10:43:56 +02:00
Zot
5f73a46c05 import/export zot6 hublocs+xchans
(cherry picked from commit e2dfa1d72f)
2019-04-26 10:42:09 +02:00
Zot
b782c6bd16 update fix_system_urls() to handle zot6 hublocs (recommend cherry-pick to master)
(cherry picked from commit f8c583636c)
2019-04-26 10:41:52 +02:00
Zot
ab8d8aa552 hubloc confusion in magic auth
(cherry picked from commit 3c8f8b76aa)
2019-04-26 10:41:35 +02:00
Daniel Lowe
f955276694 Fix infinite loop using postgres as backend
unescapebin is handed a string in some cases, and it causes an infinite
loop when it does.  This ensures that the argument is a resource before
loading its contents.


(cherry picked from commit 9a6531e2a2)
2019-04-26 10:41:04 +02:00
zotlabs
77cc60faf2 required php version not available but allowed to continue
(cherry picked from commit 6feddcbced)
2019-04-26 10:40:02 +02:00
Mario Vavti
dcd8a05809 version bump 2019-04-08 11:12:02 +02:00
Mario Vavti
62e466f774 Merge branch 'dev' 2019-04-08 11:10:10 +02:00
Mario Vavti
70777a047d Merge branch 'master' of https://framagit.org/hubzilla/core 2019-04-08 11:09:55 +02:00
zotlabs
a93bd8d944 security: perms_pending not evaluated correctly
(cherry picked from commit 5a46f1229d)
2019-04-06 10:30:32 +02:00
Mario Vavti
28c3259449 Revert "item_store(): deduplicate by mid OR uuid"
This reverts commit 0d0ede7b14.
2019-03-24 15:49:03 +01:00
Mario Vavti
0d0ede7b14 item_store(): deduplicate by mid OR uuid 2019-03-24 15:47:57 +01:00
Mario Vavti
33ac85f637 bump version 2019-03-21 11:16:35 +01:00
Mario Vavti
efd9421dc9 Merge branch 'dev' 2019-03-21 11:13:54 +01:00
Mario Vavti
578230e32c fix typos
(cherry picked from commit d486b03089)
2019-03-18 21:59:09 +01:00
Mario Vavti
8559334339 some more xss prevention
(cherry picked from commit 968c6ed8be)
2019-03-18 21:37:02 +01:00
Mario Vavti
8893d9edc4 use urlencode
(cherry picked from commit 2ec3e4a912)
2019-03-18 13:31:25 +01:00
Mario Vavti
43753ec113 ENT_COMPAT will only take care of double-quotes. Use double-quotes here to prevent XSS
(cherry picked from commit a086745ec0)
2019-03-18 13:31:03 +01:00
Mario Vavti
f1fee1239b Merge branch 'dev' 2019-03-14 09:40:26 +01:00
Mario Vavti
9772726065 merge text.php and hmessages.po 2019-03-08 12:32:20 +01:00
Mario Vavti
8ecdde6cb5 Merge branch '4.0RC' 2019-03-08 11:52:57 +01:00
Mario Vavti
5b3824917d update changelog 2019-03-08 11:48:01 +01:00
Mario Vavti
ca4f10dc5e bump version 2019-03-08 11:46:36 +01:00
Mario
853fb33913 $sender is supposed to be string in libzot
(cherry picked from commit 507c71f64c)
2019-03-08 09:45:15 +01:00
zotlabs
e352cfc861 fetch private objects using delivery channel credentials
(cherry picked from commit 1f7622e4c4)
2019-03-08 09:35:04 +01:00
Mario Vavti
b019ca0746 update changelog
(cherry picked from commit 04fe7e61de)
2019-03-07 09:32:39 +01:00
zotlabs
beb4e00afb guest access tokens: xchan record not created on URL login
(cherry picked from commit 0b2213dd41)
2019-03-07 09:30:38 +01:00
Mario Vavti
9450305568 changelog
(cherry picked from commit 08725c44c6)
2019-03-06 21:10:51 +01:00
Mario Vavti
e18c64c9d9 bump version 2019-03-06 10:02:33 +01:00
Mario Vavti
7b018c60cb while in legacy zot $sender is expected to be an array, in zot6 $sender is expected to be a string (xchan_hash)
(cherry picked from commit 117a8cafca)
2019-03-06 09:58:11 +01:00
M. Dent
a81286c795 Add CURLOPT_CONNECTTIMEOUT
(cherry picked from commit 0c05e6593e)
2019-03-06 09:56:01 +01:00
zotlabs
571e9bf26a channel_type is not integer
(cherry picked from commit 26e7da0b96)
2019-03-06 09:49:40 +01:00
zotlabs
c4714e95b6 maintain compatibility with recent zot6 changes
(cherry picked from commit 98b1c7a38c)
2019-03-06 09:49:18 +01:00
zotlabs
d407e5556e api_router - allow parameters as final path argument
(cherry picked from commit 47001c3303)
2019-03-05 09:44:36 +01:00
zotlabs
6a3cfe54af remove clones from delivery recipients for top-level posts - they will get the post via clone sync
(cherry picked from commit 8e50fecccc)
2019-03-05 09:43:51 +01:00
zotlabs
a0bffe4a78 mod_oep: photos/album/xxxxx is no longer hex2bin/bin2hex but the album hash and is throwing php warnings when trying to decode
(cherry picked from commit 938fcdd1a6)
2019-03-05 09:43:29 +01:00
zotlabs
336c716a44 translate name of content filter (addon) app.
(cherry picked from commit 29cb62af3d)
2019-03-05 09:42:58 +01:00
mike
8810658858 Addressing new 'support@zotadel.net' support forum instead of old 'support@gravizot.de'
(cherry picked from commit e26de9c1d1)
2019-03-04 09:50:47 +01:00
mike
337dfd5ee4 Mention php-zip module dependency in administrator guide
(cherry picked from commit 747ce9b1f1)
2019-03-02 15:37:47 +01:00
DM42.Net (Matt Dent)
e37c9ed0a1 Use sender hash
(cherry picked from commit 5febc3e07d)
2019-03-02 15:37:22 +01:00
Mario Vavti
aa6a31eba5 iron out some kinks with scrollToItem() in combination with collapsed content and images
(cherry picked from commit 2244bf2ba2)
2019-03-02 15:32:36 +01:00
Mario Vavti
6aa041b193 version 2019-02-26 09:30:54 +01:00
Mario Vavti
0fdc0a01d0 Merge branch 'dev' into 4.0RC 2019-02-26 09:29:00 +01:00
Mario Vavti
08cacc4943 Merge branch 'dev' into 4.0RC 2019-02-26 09:06:46 +01:00
Klaus Weidenbach
87482e3746 Update PHP Version check during Setup.
Hubzilla 4.0 requires PHP7. The oldest still supported PHP branch is 7.1.
So check during Setup for PHP >= 7.1.


(cherry picked from commit 3f13c85b64)
2019-02-22 12:52:25 +01:00
Manuel Jiménez Friaza
8bb2d29a8d Update Spanish translation
(cherry picked from commit e6f289deb6)

(cherry picked from commit a3a90ea09b)
2019-02-21 12:43:03 +01:00
Mario Vavti
93039081d5 fix summary and use item_normal_search() for viewsrc so we can also view the source for articles, cards, etc.
(cherry picked from commit a0ad110cff)
2019-02-21 12:10:31 +01:00
Max Kostikov
89ee28f858 Update Russian hstrings.php
(cherry picked from commit 3a6ea57d2c)
2019-02-20 09:20:31 +01:00
Max Kostikov
5917786296 Update Russian hmessages.po
(cherry picked from commit e960bcfd1c)
2019-02-20 09:20:09 +01:00
Mario
90fd323ac5 bump version 2019-02-03 15:03:56 +01:00
Mario Vavti
b6c384a0f7 cleanup logging and return if query returns empty result
(cherry picked from commit c657d766cf)
2019-02-03 15:02:06 +01:00
Mario Vavti
cda8a7be38 do not overwrite $sql_extra
(cherry picked from commit 4706ff6938)
2019-02-03 15:01:39 +01:00
Mario Vavti
ddbc35181c fix page jumping when liking a collapsed/expanded post
(cherry picked from commit 54806f6ee8)
2019-01-24 13:39:49 +01:00
zotlabs
57dde3e980 failure to import mail
(cherry picked from commit 7b30fc4b82)
2019-01-11 12:20:50 +01:00
Mario Vavti
3eba0c2297 do not count removed channels
(cherry picked from commit 01f4ce96f1)
2019-01-10 13:36:31 +01:00
Mario
414b7e28d3 bump version 2018-12-22 21:02:49 +01:00
Mario Vavti
fca464071f update changelog
(cherry picked from commit cdb85f1309)
2018-12-22 21:01:50 +01:00
Mario Vavti
4f08f4b84c use count() instead of sizeof()
(cherry picked from commit 774dd6d5e3)
2018-12-22 20:20:58 +01:00
Mario Vavti
1b5175d018 check if we deal with an array before sizeof()
(cherry picked from commit 339c9cceec)
2018-12-22 20:20:13 +01:00
Mario Vavti
0bfda6d4c8 revert padding for text highlight. It is messing with indent punctuation and decreases legibility of the highlighted text.
(cherry picked from commit fac3579fb0)
2018-12-22 20:18:12 +01:00
Mario
880b22604b manualy Fix cURL with HTTP/2 due to merge conflicts 2018-12-22 20:17:20 +01:00
Mario
04a2dc075f manualy remove scale_external_images() due to merge conflicts 2018-12-22 20:08:44 +01:00
Max Kostikov
01448c152c Remove scale_external_images()
(cherry picked from commit 1541f67eab)
2018-12-22 20:04:09 +01:00
Max Kostikov
a09beb3833 Remove scale_external_images()
(cherry picked from commit a2959c6e9e)
2018-12-22 20:03:49 +01:00
phani00
feda1e6d84 remove color from style.css (default) but add a little padding; add color & border radius to dark.css.
(cherry picked from commit 2354bb5427)
2018-12-22 19:54:48 +01:00
phani00
4256bea418 change hl text color to the default text color in non-dark schema. looks good, except in dark, where i can change it in dark.css.
(cherry picked from commit b97143e9db)
2018-12-22 19:54:31 +01:00
phani00
4d47b098e5 remove some fancy formatting.
(cherry picked from commit aaab905e72)
2018-12-22 19:54:11 +01:00
Mario Vavti
163754a46c make mod channel deal with b64 encoded mid\s
;


(cherry picked from commit bc6d384ca9)
2018-12-22 19:53:37 +01:00
phani00
66b56416b6 new fix for dark theme
change implementation of hl-tags in include/bbcode.php
insert class='default-highlight' instead of background-color: 'yellow' into span
add span.default-highlight definition to view/theme/redbasic/css/style.css

this works for all schemas incl. dark.


(cherry picked from commit aace8a14ce)
2018-12-22 19:52:39 +01:00
phani00
c855346358 remove my dark theme fixes.
(cherry picked from commit 70a7661711)
2018-12-22 19:52:09 +01:00
Pascal Deklerck
0e32c86c3d Update OAuth2Storage.php - fix email retrieval in getUser
(cherry picked from commit 6a825cc504)
2018-12-22 19:51:16 +01:00
M. Dent
19952264c8 Add reload to util/addons
(cherry picked from commit 0e5d76e735)
2018-12-22 19:43:16 +01:00
Mario Vavti
5ec1e97cae do not add timestamp to the photo src. caching is handled in mod photo now.
(cherry picked from commit e34853e19e)
2018-12-21 21:45:33 +01:00
zotlabs
5f5746a2f6 like permission issue
(cherry picked from commit 389b4beba4)
2018-12-21 21:44:33 +01:00
Mario Vavti
d0ee6d1ad2 missing observer check
(cherry picked from commit ec769bc9f9)
2018-12-20 19:45:59 +01:00
zotlabs
06c71eec65 default curl to http/1.1
(cherry picked from commit 04a45a407e)
2018-12-17 12:17:44 +01:00
DM42.Net (Matt Dent)
aabc6c2825 Add return if no local_channel()
(cherry picked from commit 5bcc379530)
2018-12-17 10:46:43 +01:00
DM42.Net (Matt Dent)
8323458da9 ARTICLES MODULE: Default to local_channel() user when no argv(1) is passed.
(cherry picked from commit 3f06a857c2)
2018-12-17 10:46:24 +01:00
Mario Vavti
d7c7ff1c12 fix wiki preview issue with hyperlinks
(cherry picked from commit 919ea9f750)
2018-12-15 18:20:21 +01:00
Mario Vavti
d77c7d51e3 update changelog
(cherry picked from commit 4ff3c57976)
2018-12-14 21:47:20 +01:00
Mario Vavti
d51d0160d3 fix issue with linkdropper
(cherry picked from commit f81a3ba45d)
2018-12-14 21:32:23 +01:00
zotlabs
c2ad9d4996 regression: the ability to order apps messed up since adding pinned apps to the ordering
(cherry picked from commit 6464099364)
2018-12-14 21:31:02 +01:00
Mario
79f828125d version bump 2018-12-14 11:47:02 +01:00
Mario Vavti
ad4b18cbbe return on readImageBlob() exception
(cherry picked from commit 993db01400)
2018-12-14 11:31:11 +01:00
Mario Vavti
1bd49671b7 add photo_view_filter hook and fix minor issue with unset auto_save_draft variable which resultet in a javascript error
(cherry picked from commit 7894fed741)
2018-12-14 11:30:57 +01:00
zotlabs
9896057549 home notifications won't expand if there are more than 300 unseen network notifications ahead of them.
(cherry picked from commit 30efeb5bec)
2018-12-14 11:30:25 +01:00
phani00
44832bbacb change redbasic dark schema to make categories and highlights readable
additions to /view/theme/redbasic/schema/dark.css to change the appearance of category
badges and highlighted text ([hl]...[/hl]).

hl text changed from master: it's not 'strong' anymore. commented out the pseudo-class
selector that works in master but not in dev anymore.


(cherry picked from commit 18caf0273f)
2018-12-14 11:30:05 +01:00
zotlabs
f20a923dd7 total_identities restriction off by one
(cherry picked from commit e60fb17524)
2018-12-14 11:29:33 +01:00
zotlabs
30403da326 reset page title if article has no title.
(cherry picked from commit 8ab1f31058)
2018-12-14 11:29:06 +01:00
Mario Vavti
6b68a76bbe quickfix for es-es language 2018-12-03 21:22:02 +01:00
Mario Vavti
8f10b58cb1 version 3.8.6 2018-12-03 12:23:55 +01:00
Mario Vavti
f8bc408abc update strings 2018-12-03 12:07:56 +01:00
Mario Vavti
f581f6163a optimize autoload cache 2018-12-03 11:52:38 +01:00
Mario Vavti
88486a1278 changelog 2018-12-03 11:47:28 +01:00
Mario Vavti
9fcadc2d7c prevent incompatible export files (osada/zap) from being imported (manual patch from dev) 2018-12-03 11:08:39 +01:00
Mario Vavti
9ef6c57ca5 more notifications fixes 2018-12-03 10:46:49 +01:00
Mario Vavti
443d7684db catch exception if readImageBlob() receives bogus data 2018-12-03 10:45:43 +01:00
Mario Vavti
a3ba7f0788 fallback to url if we have not got an addr 2018-12-02 11:38:13 +01:00
Mario Vavti
f083c0cba1 fix filtering by addr in handleNotificationsItems() 2018-12-02 10:58:54 +01:00
Mario Vavti
defa2d9df1 make pdf preview 100% width and 300px height to match it openstreetmaps preview
(cherry picked from commit df84352385)
2018-12-02 10:18:37 +01:00
Mario Vavti
05c422ef23 redbasic sticky aside fixes
(cherry picked from commit 8d4f6a7865)
2018-12-02 10:18:20 +01:00
zotlabs
51d274961b typo
(cherry picked from commit 6f22e47feb)
2018-12-02 10:18:05 +01:00
zotlabs
4b4cc04897 allow notification filtering by name or addr
(cherry picked from commit c6acb6191c)
2018-12-02 10:17:45 +01:00
zotlabs
4bf3d4d87a attached photo permissions regression
(cherry picked from commit 6cade7d935)
2018-12-02 10:17:29 +01:00
Manuel Jiménez Friaza
71cc980e96 Revision 1 doc/es-es/about/about.bb
(cherry picked from commit 5ac08ec3aa)

(cherry picked from commit 37d563c30e)
2018-12-02 10:16:50 +01:00
Mario
58c0b81908 use flex for the default template
(cherry picked from commit 3775be4ce9)
2018-12-02 10:16:24 +01:00
M. Dent
3b42bd43ab Do not store serialized pconfig value received via to Module/Pconfig.php
(cherry picked from commit 6b02c664fb)
2018-12-02 10:15:55 +01:00
Mario
a151532ffa update jquery-file-upload and psr-log via composer
(cherry picked from commit c7ae3fdc9a)
2018-12-02 10:14:58 +01:00
Mario
a0d1ce77dc update imagesloaded to version 4.1.4 via composer
(cherry picked from commit c667572d3e)
2018-12-02 10:14:37 +01:00
Manuel Jiménez Friaza
863cae1bab Update es-es
(cherry picked from commit ca98a566ee)
2018-12-02 10:13:43 +01:00
zotlabs
4010ea814a fix mastodon tag notifications (again)
(cherry picked from commit 8e71324514)
2018-12-02 10:13:12 +01:00
zotlabs
8e25c091f4 no mention notifications from mastodon (and pleroma)
(cherry picked from commit ea235c0c67)
2018-12-02 10:12:44 +01:00
1720 changed files with 61350 additions and 115937 deletions

View File

@@ -1,8 +1,7 @@
# Select image from https://hub.docker.com/_/php/
#image: php:7.2
#image: php:7.3
# Use a prepared Hubzilla image to optimise pipeline duration
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.2
image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3
stages:
- test
@@ -82,23 +81,23 @@ before_script:
- tests/results/
# PHP7.2 with MySQL 5.7
php7.2_mysql5.7:
# PHP7.3 with MySQL 5.7
php7.3_mysql5.7:
<<: *job_definition_mysql
services:
- mysql:5.7
# PHP7.2 with MySQL 8 (latest)
php7.2_mysql8:
# PHP7.3 with MySQL 8 (latest)
php7.3_mysql8:
<<: *job_definition_mysql
services:
- name: mysql:8
command: ["--default-authentication-plugin=mysql_native_password"]
# PHP7.2 with MariaDB 10.2
php7.2_mariadb10.2:
# PHP7.3 with MariaDB 10.2
php7.3_mariadb10.2:
<<: *job_definition_mysql
services:
- name: mariadb:10.2
@@ -114,8 +113,8 @@ php7.3_mariadb10.3:
alias: mysql
# PHP7.2 with PostgreSQL latest (11)
php7.2_postgres11:
# PHP7.3 with PostgreSQL latest (11)
php7.3_postgres11:
<<: *job_definition_postgres
artifacts: *artifacts_template

View File

@@ -1,9 +1,10 @@
# How to use
## Disclaimers
- This script does work with Debian 10 only.
- This script has to be used on a fresh debian install only (it does not take account for a possibly already installed and configured webserver or sql implementation).
- This script has to be used on a fresh debian install only (it does not take account for a possibly already installed and configured webserver or sql implementation). You may use it to install several hub/instances on the same server, though.
## Preconditions
@@ -15,9 +16,12 @@ Hardware
Software
+ Fresh installation of Debian 10 (Stretch)
+ Fresh installation of Debian 10 (Buster)
+ Router with open ports 80 and 443 for your web server
You can of course run the script on a VPS or any distant server as long as the above sotfware requirements are satisfied.
## How to run the script
+ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS)
@@ -25,29 +29,29 @@ Software
- apt-get install git
- mkdir -p /var/www
- cd /var/www
- git clone https://framagit.org/hubzilla/core.git html
- git clone https://framagit.org/hubzilla/core.git html (you can replace "html" with any folder name you like, which you'll have to do if you plan to have more than one hub/instance running on your server)
- cd html/.homeinstall
- cp hubzilla-config.txt.template hubzilla-config.txt
- nano hubzilla-config.txt
- cp zotserver-config.txt.template zotserver-config.txt
- nano zotserver-config.txt
- Read the comments carefully
- Enter your values: db pass, domain, values for dyn DNS
- Prepare your external disk for backups
- hubzilla-setup.sh as root
- ... wait, wait, wait until the script is finised
+ Open your domain with a browser and step throught the initial configuration of hubzilla.
- ./zotserver-setup.sh as root
- ... wait, wait, wait until the script is finished
+ Open your domain with a browser and step throught the initial configuration of your hub/instance.
## Optional - Set path to imagemagick
In Admin settings of hubzilla or via terminal
In Admin settings of your hub/instance or via terminal
cd /var/www/html
cd /var/www/html (or the custom path you chose)
util/config system.imagick_convert_path /usr/bin/convert
## Optional - Switch verification of email on/off
Do this just befor you register the user.
Do this just before you register the first user.
In Admin settings of hubzilla or via terminal
In Admin settings of your hub/instance or via terminal
cd /var/www/html
@@ -61,18 +65,18 @@ Switch the verification on/off (1/0)
## What the script will do for you...
+ install everything required by Hubzilla, basically a web server (Apache), PHP, a database (MySQL), certbot,...
+ install everything required by your hub/instance, basically a web server (Apache or Nginx), PHP, a database (MySQL), certbot,...
+ create a database
+ run certbot to have everything for a secure connection (httpS)
+ create a script for daily maintenance
- backup to external disk (certificates, database, /var/www/)
- renew certfificate (letsencrypt)
- update of Hubzilla
- update of your hub/instance (git)
- update of Debian
- restart
+ create cron jobs for
- DynDNS (selfHOST.de or freedns.afraid.org) every 5 minutes
- Master.php for Zap/Hubzilla every 10 minutes
- Run.php for your hub/instance every 10 minutes
- daily maintenance script every day at 05:30
The script is known to work without adjustments with
@@ -80,19 +84,12 @@ The script is known to work without adjustments with
+ Hardware
- Mini-PC with Debian 10 (stretch), or
- Rapberry 3 with Raspbian, Debian 10
- Rapberry 4 with Raspbian, Debian 10
+ DynDNS
- selfHOST.de
- freedns.afraid.org
The script can install both [Hubzilla](https://zotlabs.org/page/hubzilla/hubzilla-project) and [Zap](https://zotlabs.com/zap/). Make sure to use the correct GIT repositories.
+ Hubzilla
- core: git clone https://framagit.org/hubzilla/core.git html (in this readme)
- addons: util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons (in hubzilla-setup.sh)
+ Zap
- core: git clone https://framagit.org/zot/zap.git html (in this readme)
- addons: util/add_addon_repo https://framagit.org/zot/zap-addons.git zaddons (in hubzilla-setup.sh)
The script can install [Hubzilla](https://zotlabs.org/page/hubzilla/hubzilla-project), [Zap](https://zotlabs.com/zap/) and [Mistpark 2020, aka "Misty"](https://zotlabs.com/misty/). Make sure to use the correct GIT repositories.
# Step-by-Step - some Details
@@ -101,17 +98,17 @@ The script can install both [Hubzilla](https://zotlabs.org/page/hubzilla/hubzill
## Configure your Router
Your web has to be visible in the internet.
Your webserver has to be visible in the internet.
Open the ports 80 and 443 on your router for your Debian. Make sure your web server is marked as "exposed host".
## Preparations Dynamic IP Address
Follow the instructions in .homeinstall/hubzilla-config.txt.
Follow the instructions in .homeinstall/zotserver-config.txt.
In short...
Your Hubzilla must be reachable by a domain that you can type in your browser
Your Hubzilla server must be reachable by a domain that you can type in your browser
cooldomain.org
@@ -133,8 +130,6 @@ The cost is 1,50 € per month (2019).
## Note on Rasperry
The script was tested with an Raspberry 3 under Raspian, Debian 10.
It is recommended to run the Raspi without graphical frontend (X-Server). Use...
sudo raspi-config
@@ -143,5 +138,6 @@ to boot the Rapsi to the client console.
DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI!
## Reminder for Different Web Wervers
For those of you who feel adventurous enough to use a different web server (i.e. Lighttpd...), don't forget that this script will install Apache or Nginx and that you can only have one web server listening to ports 80 & 443. Also, don't forget to tweak your daily shell script in /var/www/ accordingly.

View File

@@ -1,656 +0,0 @@
#!/bin/bash
#
# How to use
# ----------
#
# This file automates the installation of
# - hubzilla: https://zotlabs.org/page/hubzilla/hubzilla-project and
# - zap: https://zotlabs.com/zap/
# under Debian Linux
#
# 1) Copy the file "hubzilla-config.txt.template" to "hubzilla-config.txt"
# Follow the instuctions there
#
# 2) Switch to user "root" by typing "su -"
#
# 3) Run with "./hubzilla-setup.sh"
# If this fails check if you can execute the script.
# - To make it executable type "chmod +x hubzilla-setup.sh"
# - or run "bash hubzilla-setup.sh"
#
#
# What does this script do basically?
# -----------------------------------
#
# This file automates the installation of hubzilla under Debian Linux
# - install
# * apache webserer,
# * php,
# * mariadb - the database for hubzilla,
# * adminer,
# * git to download and update addons
# - configure cron
# * "Master.php" for regular background prozesses of hubzilla
# * "apt-get update" and "apt-get dist-upgrade" and "apt-get autoremove" to keep linux up-to-date
# * run command to keep the IP up-to-date > DynDNS provided by selfHOST.de or freedns.afraid.org
# * backup hubzillas database and files (rsync)
# - run letsencrypt to create, register and use a certifacte for https
#
#
# Discussion
# ----------
#
# Security - password is the same for mysql-server, phpmyadmin and hubzilla db
# - The script runs into installation errors for phpmyadmin if it uses
# different passwords. For the sake of simplicity one singel password.
#
# How to restore from backup
# --------------------------
#
# Daily backup
# - - - - - -
#
# The installation
# - writes a script /var/www/hubzilla-daily.sh
# - creates a daily cron that runs the hubzilla-daily.sh
#
# hubzilla-daily.sh makes a (daily) backup of all relevant files
# - /var/lib/mysql/ > database
# - /var/www/ > hubzilla/zap from github
# - /etc/letsencrypt/ > certificates
#
# hubzilla-daily.sh writes the backup to an external disk compatible to LUKS+ext4 (see hubzilla-config.txt)
#
# Credits
# -------
#
# The script is based on Thomas Willinghams script "debian-setup.sh"
# which he used to install the red#matrix.
#
# The documentation for bash is here
# https://www.gnu.org/software/bash/manual/bash.html
#
function check_sanity {
# Do some sanity checking.
print_info "Sanity check..."
if [ $(/usr/bin/id -u) != "0" ]
then
die 'Must be run by root user'
fi
if [ -f /etc/lsb-release ]
then
die "Distribution is not supported"
fi
if [ ! -f /etc/debian_version ]
then
die "Debian is supported only"
fi
if ! grep -q 'Linux 10' /etc/issue
then
die "Linux 10 (buster) is supported only"x
fi
}
function check_config {
print_info "config check..."
# Check for required parameters
if [ -z "$db_pass" ]
then
die "db_pass not set in $configfile"
fi
if [ -z "$le_domain" ]
then
die "le_domain not set in $configfile"
fi
# backup is important and should be checked
if [ -n "$backup_device_name" ]
then
if [ ! -d "$backup_mount_point" ]
then
mkdir "$backup_mount_point"
fi
device_mounted=0
if fdisk -l | grep -i "$backup_device_name.*linux"
then
print_info "ok - filesystem of external device is linux"
if [ -n "$backup_device_pass" ]
then
echo "$backup_device_pass" | cryptsetup luksOpen $backup_device_name cryptobackup
if mount /dev/mapper/cryptobackup /media/hubzilla_backup
then
device_mounted=1
print_info "ok - could encrypt and mount external backup device"
umount /media/hubzilla_backup
else
print_warn "backup to external device will fail because encryption failed"
fi
cryptsetup luksClose cryptobackup
else
if mount $backup_device_name /media/hubzilla_backup
then
device_mounted=1
print_info "ok - could mount external backup device"
umount /media/hubzilla_backup
else
print_warn "backup to external device will fail because mount failed"
fi
fi
else
print_warn "backup to external device will fail because filesystem is either not linux or 'backup_device_name' is not correct in $configfile"
fi
if [ $device_mounted == 0 ]
then
die "backup device not ready"
fi
fi
}
function die {
echo "ERROR: $1" > /dev/null 1>&2
exit 1
}
function update_upgrade {
print_info "updated and upgrade..."
# Run through the apt-get update/upgrade first. This should be done before
# we try to install any package
apt-get -q -y update && apt-get -q -y dist-upgrade
print_info "updated and upgraded linux"
}
function check_install {
if [ -z "`which "$1" 2>/dev/null`" ]
then
# export DEBIAN_FRONTEND=noninteractive ... answers from the package
# configuration database
# - q ... without progress information
# - y ... answer interactive questions with "yes"
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $2
print_info "installed $2 installed for $1"
else
print_warn "$2 already installed"
fi
}
function nocheck_install {
# export DEBIAN_FRONTEND=noninteractive ... answers from the package configuration database
# - q ... without progress information
# - y ... answer interactive questions with "yes"
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
# DEBIAN_FRONTEND=noninteractive apt-get --install-suggests -q -y install $1
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $1
print_info "installed $1"
}
function print_info {
echo -n -e '\e[1;34m'
echo -n $1
echo -e '\e[0m'
}
function print_warn {
echo -n -e '\e[1;31m'
echo -n $1
echo -e '\e[0m'
}
function stop_hubzilla {
print_info "stopping apache webserver..."
systemctl stop apache2
print_info "stopping mysql db..."
systemctl stop mariadb
}
function install_apache {
print_info "installing apache..."
nocheck_install "apache2 apache2-utils"
a2enmod rewrite
systemctl restart apache2
}
function install_imagemagick {
print_info "installing imagemagick..."
nocheck_install "imagemagick"
}
function install_curl {
print_info "installing curl..."
nocheck_install "curl"
}
function install_wget {
print_info "installing wget..."
nocheck_install "wget"
}
function install_sendmail {
print_info "installing sendmail..."
nocheck_install "sendmail sendmail-bin"
}
function install_php {
# openssl and mbstring are included in libapache2-mod-php
print_info "installing php..."
nocheck_install "libapache2-mod-php php php-pear php-curl php-gd php-mysqli php-mbstring php-xml php-zip"
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.3/apache2/php.ini
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.3/apache2/php.ini
}
function install_mysql {
print_info "installing mysql..."
if [ -z "$mysqlpass" ]
then
die "mysqlpass not set in $configfile"
fi
if type mysql ; then
echo "Yes, mysql is installed"
else
echo "mariadb-server"
nocheck_install "mariadb-server"
systemctl status mariadb
systemctl start mariadb
mysql --user=root <<_EOF_
UPDATE mysql.user SET Password=PASSWORD('${db_root_password}') WHERE User='root';
DELETE FROM mysql.user WHERE User='';
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;
_EOF_
fi
}
function install_adminer {
print_info "installing adminer..."
nocheck_install "adminer"
if [ ! -f /etc/adminer/adminer.conf ]
then
echo "Alias /adminer /usr/share/adminer/adminer" > /etc/adminer/adminer.conf
ln -s /etc/adminer/adminer.conf /etc/apache2/conf-available/adminer.conf
else
print_info "file /etc/adminer/adminer.conf exists already"
fi
a2enmod rewrite
if [ ! -f /etc/apache2/apache2.conf ]
then
die "could not find file /etc/apache2/apache2.conf"
fi
sed -i \
"s/AllowOverride None/AllowOverride all/" \
/etc/apache2/apache2.conf
a2enconf adminer
systemctl restart mariadb
systemctl reload apache2
}
function create_hubzilla_db {
print_info "creating hubzilla database..."
if [ -z "$hubzilla_db_name" ]
then
die "hubzilla_db_name not set in $configfile"
fi
if [ -z "$hubzilla_db_user" ]
then
die "hubzilla_db_user not set in $configfile"
fi
if [ -z "$hubzilla_db_pass" ]
then
die "hubzilla_db_pass not set in $configfile"
fi
systemctl restart mariadb
Q1="CREATE DATABASE IF NOT EXISTS $hubzilla_db_name;"
Q2="GRANT USAGE ON *.* TO $hubzilla_db_user@localhost IDENTIFIED BY '$hubzilla_db_pass';"
Q3="GRANT ALL PRIVILEGES ON $hubzilla_db_name.* to $hubzilla_db_user@localhost identified by '$hubzilla_db_pass';"
Q4="FLUSH PRIVILEGES;"
SQL="${Q1}${Q2}${Q3}${Q4}"
mysql -uroot -p$phpmyadminpass -e "$SQL"
}
function run_freedns {
print_info "run freedns (dynamic IP)..."
if [ -z "$freedns_key" ]
then
print_info "freedns was not started because 'freedns_key' is empty in $configfile"
else
if [ -n "$selfhost_user" ]
then
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
fi
wget --no-check-certificate -O - https://freedns.afraid.org/dynamic/update.php?$freedns_key
fi
}
function install_run_selfhost {
print_info "install and start selfhost (dynamic IP)..."
if [ -z "$selfhost_user" ]
then
print_info "selfHOST was not started because 'selfhost_user' is empty in $configfile"
else
if [ -n "$freedns_key" ]
then
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
fi
if [ -z "$selfhost_pass" ]
then
die "selfHOST was not started because 'selfhost_pass' is empty in $configfile"
fi
if [ ! -d $selfhostdir ]
then
mkdir $selfhostdir
fi
# the old way
# https://carol.selfhost.de/update?username=123456&password=supersafe
#
# the prefered way
wget --output-document=$selfhostdir/$selfhostscript http://jonaspasche.de/selfhost-updater
echo "router" > $selfhostdir/device
echo "$selfhost_user" > $selfhostdir/user
echo "$selfhost_pass" > $selfhostdir/pass
bash $selfhostdir/$selfhostscript update
fi
}
function ping_domain {
print_info "ping domain $domain..."
# Is the domain resolved? Try to ping 6 times à 10 seconds
COUNTER=0
for i in {1..6}
do
print_info "loop $i for ping -c 1 $domain ..."
if ping -c 4 -W 1 $le_domain
then
print_info "$le_domain resolved"
break
else
if [ $i -gt 5 ]
then
die "Failed to: ping -c 1 $domain not resolved"
fi
fi
sleep 10
done
sleep 5
}
function configure_cron_freedns {
print_info "configure cron for freedns..."
if [ -z "$freedns_key" ]
then
print_info "freedns is not configured because freedns_key is empty in $configfile"
else
# Use cron for dynamich ip update
# - at reboot
# - every 30 minutes
if [ -z "`grep 'freedns.afraid.org' /etc/crontab`" ]
then
echo "@reboot root https://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
echo "*/30 * * * * root wget --no-check-certificate -O - https://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
else
print_info "cron for freedns was configured already"
fi
fi
}
function configure_cron_selfhost {
print_info "configure cron for selfhost..."
if [ -z "$selfhost_user" ]
then
print_info "selfhost is not configured because selfhost_key is empty in $configfile"
else
# Use cron for dynamich ip update
# - at reboot
# - every 5 minutes
if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ]
then
echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
echo "*/5 * * * * root /bin/bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
else
print_info "cron for selfhost was configured already"
fi
fi
}
function install_letsencrypt {
print_info "installing let's encrypt ..."
# check if user gave domain
if [ -z "$le_domain" ]
then
die "Failed to install let's encrypt: 'le_domain' is empty in $configfile"
fi
if [ -z "$le_email" ]
then
die "Failed to install let's encrypt: 'le_email' is empty in $configfile"
fi
nocheck_install "certbot python-certbot-apache"
print_info "run certbot ..."
certbot --apache -w /var/www/html -d $le_domain -m $le_email --agree-tos --non-interactive --redirect --hsts --uir
service apache2 restart
}
function check_https {
print_info "checking httpS > testing ..."
url_https=https://$le_domain
wget_output=$(wget -nv --spider --max-redirect 0 $url_https)
if [ $? -ne 0 ]
then
print_warn "check not ok"
else
print_info "check ok"
fi
}
function install_hubzilla {
print_info "installing addons..."
cd /var/www/html/
if git remote -v | grep -i "origin.*hubzilla.*core"
then
print_info "hubzilla"
util/add_addon_repo https://framagit.org/hubzilla/addons hzaddons
elif git remote -v | grep -i "origin.*zap.*core"
then
print_info "zap"
util/add_addon_repo https://framagit.org/zot/zap-addons.git zaddons
else
die "neither zap nor hubzilla repository > did not install addons or zap/hubzilla"
fi
mkdir -p "store/[data]/smarty3"
chmod -R 777 store
touch .htconfig.php
chmod ou+w .htconfig.php
cd /var/www/
chown -R www-data:www-data html
chown root:www-data /var/www/html/
chown root:www-data /var/www/html/.htaccess
chmod 0644 /var/www/html/.htaccess
print_info "installed addons"
}
function install_rsync {
print_info "installing rsync..."
nocheck_install "rsync"
}
function install_cryptosetup {
print_info "installing cryptsetup..."
nocheck_install "cryptsetup"
}
function configure_cron_daily {
print_info "configuring cron..."
# every 10 min for poller.php
if [ -z "`grep 'Master.php' /etc/crontab`" ]
then
echo "*/10 * * * * www-data cd /var/www/html; php Zotlabs/Daemon/Master.php Cron >> /dev/null 2>&1" >> /etc/crontab
fi
# Run external script daily at 05:30
# - stop apache and mysql-server
# - renew the certificate of letsencrypt
# - backup db, files (/var/www/html), certificates if letsencrypt
# - update hubzilla core and addon
# - update and upgrade linux
# - reboot is done by "shutdown -h now" because "reboot" hangs sometimes depending on the system
echo "#!/bin/sh" > /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "echo \" \"" >> /var/www/$hubzilladaily
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
echo "echo \" \"" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$hubzilladaily
echo "certbot renew --noninteractive" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - stopping apache and mysql...\"" >> /var/www/$hubzilladaily
echo "service apache2 stop" >> /var/www/$hubzilladaily
echo "/etc/init.d/mysql stop # to avoid inconsistencies" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "# backup" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - try to mount external device for backup...\"" >> /var/www/$hubzilladaily
echo "backup_device_name=$backup_device_name" >> /var/www/$hubzilladaily
echo "backup_device_pass=$backup_device_pass" >> /var/www/$hubzilladaily
echo "backup_mount_point=$backup_mount_point" >> /var/www/$hubzilladaily
echo "device_mounted=0" >> /var/www/$hubzilladaily
echo "if [ -n \"$backup_device_name\" ]" >> /var/www/$hubzilladaily
echo "then" >> /var/www/$hubzilladaily
echo " if blkid | grep $backup_device_name" >> /var/www/$hubzilladaily
echo " then" >> /var/www/$hubzilladaily
if [ -n "$backup_device_pass" ]
then
echo " echo \"decrypting backup device...\"" >> /var/www/$hubzilladaily
echo " echo "\"$backup_device_pass\"" | cryptsetup luksOpen $backup_device_name cryptobackup" >> /var/www/$hubzilladaily
fi
echo " if [ ! -d $backup_mount_point ]" >> /var/www/$hubzilladaily
echo " then" >> /var/www/$hubzilladaily
echo " mkdir $backup_mount_point" >> /var/www/$hubzilladaily
echo " fi" >> /var/www/$hubzilladaily
echo " echo \"mounting backup device...\"" >> /var/www/$hubzilladaily
if [ -n "$backup_device_pass" ]
then
echo " if mount /dev/mapper/cryptobackup $backup_mount_point" >> /var/www/$hubzilladaily
else
echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$hubzilladaily
fi
echo " then" >> /var/www/$hubzilladaily
echo " device_mounted=1" >> /var/www/$hubzilladaily
echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$hubzilladaily
echo " rsync -a --delete /var/lib/mysql/ /media/hubzilla_backup/mysql" >> /var/www/$hubzilladaily
echo " rsync -a --delete /var/www/ /media/hubzilla_backup/www" >> /var/www/$hubzilladaily
echo " rsync -a --delete /etc/letsencrypt/ /media/hubzilla_backup/letsencrypt" >> /var/www/$hubzilladaily
echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily
echo " df -h" >> /var/www/$hubzilladaily
echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
echo " du -h $backup_mount_point | grep mysql/hubzilla" >> /var/www/$hubzilladaily
echo " echo \"unmounting backup device...\"" >> /var/www/$hubzilladaily
echo " umount $backup_mount_point" >> /var/www/$hubzilladaily
echo " else" >> /var/www/$hubzilladaily
echo " echo \"failed to mount device $backup_device_name\"" >> /var/www/$hubzilladaily
echo " fi" >> /var/www/$hubzilladaily
if [ -n "$backup_device_pass" ]
then
echo " echo \"closing decrypted backup device...\"" >> /var/www/$hubzilladaily
echo " cryptsetup luksClose cryptobackup" >> /var/www/$hubzilladaily
fi
echo " fi" >> /var/www/$hubzilladaily
echo "fi" >> /var/www/$hubzilladaily
echo "if [ \$device_mounted == 0 ]" >> /var/www/$hubzilladaily
echo "then" >> /var/www/$hubzilladaily
echo " echo \"device could not be mounted $backup_device_name. No backup written.\"" >> /var/www/$hubzilladaily
echo "fi" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
echo "du -h /var/lib/mysql/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "# update" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - updating core and addons...\"" >> /var/www/$hubzilladaily
echo "(cd /var/www/html/ ; util/udall)" >> /var/www/$hubzilladaily
echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily
echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily
echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - updating linux...\"" >> /var/www/$hubzilladaily
echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> /var/www/$hubzilladaily
echo "echo \"\$(date) - Backup and update finished. Rebooting...\"" >> /var/www/$hubzilladaily
echo "#" >> /var/www/$hubzilladaily
echo "shutdown -r now" >> /var/www/$hubzilladaily
if [ -z "`grep 'hubzilla-daily.sh' /etc/crontab`" ]
then
echo "30 05 * * * root /bin/bash /var/www/$hubzilladaily >> /var/www/html/hubzilla-daily.log 2>&1" >> /etc/crontab
echo "0 0 1 * * root rm /var/www/html/hubzilla-daily.log" >> /etc/crontab
fi
# This is active after either "reboot" or "/etc/init.d/cron reload"
print_info "configured cron for updates/upgrades"
}
########################################################################
# START OF PROGRAM
########################################################################
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
check_sanity
# Read config file edited by user
configfile=hubzilla-config.txt
source $configfile
selfhostdir=/etc/selfhost
selfhostscript=selfhost-updater.sh
hubzilladaily=hubzilla-daily.sh
backup_mount_point=/media/hubzilla_backup
#set -x # activate debugging from here
check_config
stop_hubzilla
update_upgrade
install_curl
install_wget
install_sendmail
install_apache
install_imagemagick
install_php
install_mysql
install_adminer
create_hubzilla_db
run_freedns
install_run_selfhost
ping_domain
configure_cron_freedns
configure_cron_selfhost
if [ "$le_domain" != "localhost" ]
then
install_letsencrypt
configure_apache_for_https
check_https
else
print_info "is localhost - skipped installation of letsencrypt and configuration of apache for https"
fi
install_hubzilla
if [ "$le_domain" != "localhost" ]
then
rewrite_to_https
install_rsnapshot
else
print_info "is localhost - skipped rewrite to https and installation of rsnapshot"
fi
configure_cron_daily
if [ "$le_domain" != "localhost" ]
then
install_cryptosetup
write_uninstall_script
else
print_info "is localhost - skipped installation of cryptosetup"
fi
#set +x # stop debugging from here

View File

@@ -0,0 +1,144 @@
##
# Hubzilla/Zap/Mistpark/Osada Nginx block configuration template
# based on the example created by Olaf Conradi
#
# The files generated with this template will be added to
# /etc/nginx/sites-available & /etc/nginx/sites-enabled (symlink)
##
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
#
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
##
##
# This configuration assumes
# You filled the zotserver-config.txt file
# Your domain/subdomain is functionnal
# You want all traffic to be https
# You have PHP FastCGI Process Manager (php-fpm) running on localhost
##
server {
listen 80;
server_name SERVER_NAME;
# HTTP > HTTPS #
return 301 https://$server_name$request_uri;
}
##
# Configure Red with SSL
#
# All requests are routed to the front controller
# except for certain known file types like images, css, etc.
# Those are served statically whenever possible with a
# fall back to the front controller (needed for avatars, for example)
##
server {
listen 443 ssl;
server_name SERVER_NAME;
ssl on;
ssl_certificate /etc/letsencrypt/live/SERVER_NAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SERVER_NAME/privkey.pem;
ssl_session_timeout 5m;
# DO WE NEED TO REVIEW THE FOLLOWING SETTINGS?
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
ssl_prefer_server_ciphers on;
fastcgi_param HTTPS on;
charset utf-8;
root INSTALL_PATH;
index index.php;
access_log /var/log/nginx/ZOTSERVER_LOG;
#Uncomment the following line to include a standard configuration file
#Note that the most specific rule wins and your standard configuration
#will therefore *add* to this file, but not override it.
#include standard.conf
# allow uploads up to 20MB in size
client_max_body_size 20m;
client_body_buffer_size 128k;
include mime.types;
# rewrite to front controller as default rule
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?req=$1;
}
}
# make sure webfinger and other well known services aren't blocked
# by denying dot files and rewrite request to the front controller
location ^~ /.well-known/ {
allow all;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?req=$1;
}
}
# statically serve these file types when possible
# otherwise fall back to front controller
# allow browser to cache them
# added .htm for advanced source code editor library
# location ~* \.(jpg|jpeg|gif|png|ico|css|js|htm|html|map|ttf|woff|woff2|svg)$ {
# expires 30d;
# try_files $uri /index.php?req=$uri&$args;
# }
# SHOULD WE UNCOMMENT THE ABOVE LINES ?
# block these file types
location ~* \.(tpl|md|tgz|log|out)$ {
deny all;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
# or a unix socket
location ~* \.php$ {
# IS THE FOLLOWING STILL RELEVANT AS OF AUGUST 2020?
# Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3
# Won't work properly (404 error) if the file is not stored on this
# server, which is entirely possible with php-fpm/php-fcgi.
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on
# another machine. And then cross your fingers that you won't get hacked.
try_files $uri =404;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# With php-fpm:
fastcgi_pass unix:PHP_FPM_SOCK;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# deny access to all dot files
location ~ /\. {
deny all;
}
#deny access to store
location ~ /store {
deny all;
}
}

View File

@@ -9,11 +9,11 @@ db_pass=
###############################################
### MANDATORY - let's encrypt #################
#
# Hubilla requires encrypted communication via secure HTTP (HTTPS).
# Zot requires encrypted communication via secure HTTP (HTTPS).
# This script automates installation of an SSL certificate from
# Let's Encrypt (https://letsencrypt.org)
#
# Please give the domain name of your hub
# Please give the domain name of your hub/instance
#
# Example: my.cooldomain.org
# Example: cooldomain.org
@@ -29,6 +29,18 @@ db_pass=
le_domain=
le_email=
###############################################
### OPTIONAL - Webserver choice ###############
#
# Please indicate if you want to choose Nginx
# or Apache as your web server
#
# Valid strings are nginx or apache (lower case),
# any other will stop the setup script.
#
webserver=apache
###############################################
### OPTIONAL - selfHOST - dynamic IP address ##
#
@@ -87,7 +99,7 @@ freedns_key=
# - encrypted LUKS + ext4, or
# - ext4
#
# You should test to mount the device befor you run the script
# You should test to mount the device before you run the script
# (hubzilla-setup.sh).
# How to find your (pluged-in) devices?
#
@@ -144,10 +156,13 @@ backup_device_pass=
#
###############################################
#
# Database for hubzilla
hubzilla_db_name=hubzilla
hubzilla_db_user=hubzilla
hubzilla_db_pass=$db_pass
# Database for your hub/instance
# If left empty, both your database and user will be named after your zot instance (hubzilla, zap or misty)
# Use custom name, at least fo the database, if you plan to run more than one hub/instance on the same server
#
zotserver_db_name=
zotserver_db_user=
zotserver_db_pass=$db_pass
#
#
# Password for package mysql-server

793
.homeinstall/zotserver-setup.sh Executable file
View File

@@ -0,0 +1,793 @@
#!/bin/bash
#
# How to use
# ----------
#
# This file automates the installation of
# - hubzilla: https://zotlabs.org/page/hubzilla/hubzilla-project and
# - zap: https://zotlabs.com/zap/
# - misty : https://zotlabs.com/misty/
# - osada : https://codeberg.org/zot/osada
# - redmatrix : https://codeberg.org/zot/redmatrix
# under Debian Linux "Buster"
#
# 1) Copy the file "zotserver-config.txt.template" to "zotserver-config.txt"
# Follow the instuctions there
#
# 2) Switch to user "root" by typing "su -"
#
# 3) Run with "./zotserver-setup.sh"
# If this fails check if you can execute the script.
# - To make it executable type "chmod +x zotserver-setup.sh"
# - or run "bash zotserver-setup.sh"
#
#
# What does this script do basically?
# -----------------------------------
#
# This file automates the installation of a Zot hub/instance under Debian Linux
# - install
# * apache webserver,
# * php,
# * mariadb - the database for zotserver,
# * adminer,
# * git to download and update addons
# - configure cron
# * "Run.php" for regular background processes of your Zot hub/instance
# * "apt-get update" and "apt-get dist-upgrade" and "apt-get autoremove" to keep linux up-to-date
# * run command to keep the IP up-to-date > DynDNS provided by selfHOST.de or freedns.afraid.org
# * backup your server's database and files (rsync)
# - run letsencrypt to create, register and use a certifacte for https
#
#
# Discussion
# ----------
#
# Security - password is the same for mysql-server, phpmyadmin and your hub/instance db
# - The script runs into installation errors for phpmyadmin if it uses
# different passwords. For the sake of simplicity one single password.
#
# How to restore from backup
# --------------------------
#
# (Some explanations here would certainly be useful)
#
# Daily backup
# ------------
#
# The installation
# - writes a shell script in /var/www/
# - creates a daily cron that runs this script
#
# The script makes a (daily) backup of all relevant files
# - /var/lib/mysql/ > database
# - /var/www/ > hubzilla/zap/misty from git repository
# - /etc/letsencrypt/ > certificates
#
# The backup will be written on an external disk compatible to LUKS+ext4 (see zotserver-config.txt)
#
# How to restore from backup
# --------------------------
#
# (Some explanations here would certainly be useful)
#
#
# Credits
# -------
#
# The script is based on Thomas Willinghams script "debian-setup.sh"
# which he used to install the red#matrix.
#
# The documentation for bash is here
# https://www.gnu.org/software/bash/manual/bash.html
#
function check_sanity {
# Do some sanity checking.
print_info "Sanity check..."
if [ $(/usr/bin/id -u) != "0" ]
then
die 'Must be run by root user'
fi
if [ -f /etc/lsb-release ]
then
die "Distribution is not supported"
fi
if [ ! -f /etc/debian_version ]
then
die "Debian is supported only"
fi
if ! grep -q 'Linux 10' /etc/issue
then
die "Linux 10 (buster) is supported only"x
fi
}
function check_config {
print_info "config check..."
# Check for required parameters
if [ -z "$db_pass" ]
then
die "db_pass not set in $configfile"
fi
if [ -z "$le_domain" ]
then
die "le_domain not set in $configfile"
fi
# backup is important and should be checked
if [ -n "$backup_device_name" ]
then
if [ ! -d "$backup_mount_point" ]
then
mkdir "$backup_mount_point"
fi
device_mounted=0
if fdisk -l | grep -i "$backup_device_name.*linux"
then
print_info "ok - filesystem of external device is linux"
if [ -n "$backup_device_pass" ]
then
echo "$backup_device_pass" | cryptsetup luksOpen $backup_device_name cryptobackup
if mount /dev/mapper/cryptobackup /media/zotserver_backup
then
device_mounted=1
print_info "ok - could encrypt and mount external backup device"
umount /media/zotserver_backup
else
print_warn "backup to external device will fail because encryption failed"
fi
cryptsetup luksClose cryptobackup
else
if mount $backup_device_name /media/zotserver_backup
then
device_mounted=1
print_info "ok - could mount external backup device"
umount /media/zotserver_backup
else
print_warn "backup to external device will fail because mount failed"
fi
fi
else
print_warn "backup to external device will fail because filesystem is either not linux or 'backup_device_name' is not correct in $configfile"
fi
if [ $device_mounted == 0 ]
then
die "backup device not ready"
fi
fi
}
function die {
echo "ERROR: $1" > /dev/null 1>&2
exit 1
}
function update_upgrade {
print_info "updated and upgrade..."
# Run through the apt-get update/upgrade first. This should be done before
# we try to install any package
apt-get -q -y update && apt-get -q -y dist-upgrade
print_info "updated and upgraded linux"
}
function check_install {
if [ -z "`which "$1" 2>/dev/null`" ]
then
# export DEBIAN_FRONTEND=noninteractive ... answers from the package
# configuration database
# - q ... without progress information
# - y ... answer interactive questions with "yes"
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $2
print_info "installed $2 installed for $1"
else
print_warn "$2 already installed"
fi
}
function nocheck_install {
# export DEBIAN_FRONTEND=noninteractive ... answers from the package configuration database
# - q ... without progress information
# - y ... answer interactive questions with "yes"
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
# DEBIAN_FRONTEND=noninteractive apt-get --install-suggests -q -y install $1
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $1
print_info "installed $1"
}
function print_info {
echo -n -e '\e[1;34m'
echo -n $1
echo -e '\e[0m'
}
function print_warn {
echo -n -e '\e[1;31m'
echo -n $1
echo -e '\e[0m'
}
function stop_zotserver {
if [ $webserver = "nginx" ]
then
print_info "stopping nginx webserver..."
systemctl stop nginx
elif [ $webserver = "apache" ]
then
print_info "stopping apache webserver..."
systemctl stop apache2
fi
print_info "stopping mysql db..."
systemctl stop mariadb
}
function install_apache {
print_info "installing apache..."
nocheck_install "apache2 apache2-utils"
a2enmod rewrite
systemctl restart apache2
}
function install_nginx {
print_info "installing nginx..."
nocheck_install "nginx"
systemctl restart nginx
}
function add_vhost {
print_info "adding apache vhost"
echo "<VirtualHost *:80>" >> "/etc/apache2/sites-available/${le_domain}.conf"
echo "ServerName ${le_domain}" >> "/etc/apache2/sites-available/${le_domain}.conf"
echo "DocumentRoot $install_path" >> "/etc/apache2/sites-available/${le_domain}.conf"
echo "</VirtualHost>" >> "/etc/apache2/sites-available/${le_domain}.conf"
a2ensite $le_domain
}
function add_nginx_block {
print_info "adding nginx block"
sed "s|SERVER_NAME|${le_domain}|g;s|INSTALL_PATH|${install_path}|g;s|ZOTSERVER_LOG|${install_folder}-${zotserver}.log|;s|PHP_FPM_SOCK|$(ls /var/run/php/*sock)|;" nginx-zotserver.conf.template >> /etc/nginx/sites-enabled/${le_domain}.conf
ln -s /etc/nginx/sites-enabled/${le_domain}.conf /etc/nginx/sites-available/
}
function install_imagemagick {
print_info "installing imagemagick..."
nocheck_install "imagemagick"
}
function install_curl {
print_info "installing curl..."
nocheck_install "curl"
}
function install_wget {
print_info "installing wget..."
nocheck_install "wget"
}
function install_sendmail {
print_info "installing sendmail..."
nocheck_install "sendmail sendmail-bin"
}
function install_php {
# openssl and mbstring are included in libapache2-mod-php
print_info "installing php..."
if [ $webserver = "nginx" ]
then
nocheck_install "php php-pear php-curl php-gd php-mbstring php-xml php-zip php-fpm"
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.3/fpm/php.ini
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.3/fpm/php.ini
systemctl reload php7.3-fpm
elif [ $webserver = "apache" ]
then
nocheck_install "libapache2-mod-php php php-pear php-curl php-gd php-mbstring php-xml php-zip"
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.3/apache2/php.ini
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.3/apache2/php.ini
fi
}
function install_mysql {
print_info "installing mysql..."
if [ -z "$mysqlpass" ]
then
die "mysqlpass not set in $configfile"
fi
if type mysql ; then
echo "Yes, mysql is installed"
else
echo "mariadb-server"
nocheck_install "mariadb-server"
systemctl status mariadb
systemctl start mariadb
mysql --user=root <<_EOF_
UPDATE mysql.user SET Password=PASSWORD('${mysqlpass}') WHERE User='root';
DELETE FROM mysql.user WHERE User='';
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;
_EOF_
fi
}
function install_adminer {
print_info "installing adminer..."
nocheck_install "adminer"
if [ ! -f /etc/adminer/adminer.conf ]
then
echo "Alias /adminer /usr/share/adminer/adminer" > /etc/adminer/adminer.conf
ln -s /etc/adminer/adminer.conf /etc/apache2/conf-available/adminer.conf
else
print_info "file /etc/adminer/adminer.conf exists already"
fi
a2enmod rewrite
if [ ! -f /etc/apache2/apache2.conf ]
then
die "could not find file /etc/apache2/apache2.conf"
fi
sed -i \
"s/AllowOverride None/AllowOverride all/" \
/etc/apache2/apache2.conf
a2enconf adminer
systemctl restart mariadb
systemctl reload apache2
}
function create_zotserver_db {
print_info "creating zotserver database..."
if [ -z "$zotserver_db_name" ]
then
zotserver_db_name=$zotserver
fi
if [ -z "$zotserver_db_user" ]
then
zotserver_db_user=$zotserver
fi
if [ -z "$zotserver_db_pass" ]
then
die "zotserver_db_pass not set in $configfile"
fi
systemctl restart mariadb
# Make sure we don't write over an already existing database if we install more than one Zot hub/instance
if [ -z $(mysql -h localhost -u root -p$mysqlpass -e "SHOW DATABASES;" | grep $zotserver_db_name) ]
then
Q1="CREATE DATABASE IF NOT EXISTS $zotserver_db_name;"
Q2="GRANT USAGE ON *.* TO $zotserver_db_user@localhost IDENTIFIED BY '$zotserver_db_pass';"
Q3="GRANT ALL PRIVILEGES ON $zotserver_db_name.* to $zotserver_db_user@localhost identified by '$zotserver_db_pass';"
Q4="FLUSH PRIVILEGES;"
SQL="${Q1}${Q2}${Q3}${Q4}"
mysql -uroot -p$mysqlpass -e "$SQL"
else
die "Can't write over an already existing database!"
fi
}
function run_freedns {
print_info "run freedns (dynamic IP)..."
if [ -z "$freedns_key" ]
then
print_info "freedns was not started because 'freedns_key' is empty in $configfile"
else
if [ -n "$selfhost_user" ]
then
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
fi
wget --no-check-certificate -O - http://freedns.afraid.org/dynamic/update.php?$freedns_key
fi
}
function install_run_selfhost {
print_info "install and start selfhost (dynamic IP)..."
if [ -z "$selfhost_user" ]
then
print_info "selfHOST was not started because 'selfhost_user' is empty in $configfile"
else
if [ -n "$freedns_key" ]
then
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
fi
if [ -z "$selfhost_pass" ]
then
die "selfHOST was not started because 'selfhost_pass' is empty in $configfile"
fi
if [ ! -d $selfhostdir ]
then
mkdir $selfhostdir
fi
# the old way
# https://carol.selfhost.de/update?username=123456&password=supersafe
#
# the prefered way
wget --output-document=$selfhostdir/$selfhostscript http://jonaspasche.de/selfhost-updater
echo "router" > $selfhostdir/device
echo "$selfhost_user" > $selfhostdir/user
echo "$selfhost_pass" > $selfhostdir/pass
bash $selfhostdir/$selfhostscript update
fi
}
function ping_domain {
print_info "ping domain $domain..."
# Is the domain resolved? Try to ping 6 times à 10 seconds
COUNTER=0
for i in {1..6}
do
print_info "loop $i for ping -c 1 $domain ..."
if ping -c 4 -W 1 $le_domain
then
print_info "$le_domain resolved"
break
else
if [ $i -gt 5 ]
then
die "Failed to: ping -c 1 $domain not resolved"
fi
fi
sleep 10
done
sleep 5
}
function configure_cron_freedns {
print_info "configure cron for freedns..."
if [ -z "$freedns_key" ]
then
print_info "freedns is not configured because freedns_key is empty in $configfile"
else
# Use cron for dynamich ip update
# - at reboot
# - every 30 minutes
if [ -z "`grep 'freedns.afraid.org' /etc/crontab`" ]
then
echo "@reboot root http://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
echo "*/30 * * * * root wget --no-check-certificate -O - http://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
else
print_info "cron for freedns was configured already"
fi
fi
}
function configure_cron_selfhost {
print_info "configure cron for selfhost..."
if [ -z "$selfhost_user" ]
then
print_info "selfhost is not configured because selfhost_key is empty in $configfile"
else
# Use cron for dynamich ip update
# - at reboot
# - every 5 minutes
if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ]
then
echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
echo "*/5 * * * * root /bin/bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
else
print_info "cron for selfhost was configured already"
fi
fi
}
function install_letsencrypt {
print_info "installing let's encrypt ..."
# check if user gave domain
if [ -z "$le_domain" ]
then
die "Failed to install let's encrypt: 'le_domain' is empty in $configfile"
fi
if [ -z "$le_email" ]
then
die "Failed to install let's encrypt: 'le_email' is empty in $configfile"
fi
if [ $webserver = "nginx" ]
then
nocheck_install "certbot"
print_info "run certbot..."
systemctl stop nginx
certbot certonly --standalone -d $le_domain -m $le_email --agree-tos --non-interactive
systemctl start nginx
elif [ $webserver = "apache" ]
then
nocheck_install "certbot python-certbot-apache"
print_info "run certbot ..."
certbot --apache -w $install_path -d $le_domain -m $le_email --agree-tos --non-interactive --redirect --hsts --uir
service apache2 restart
fi
}
function check_https {
print_info "checking httpS > testing ..."
url_https=https://$le_domain
wget_output=$(wget -nv --spider --max-redirect 0 $url_https)
if [ $? -ne 0 ]
then
print_warn "check not ok"
else
print_info "check ok"
fi
}
function zotserver_name {
if git remote -v | grep -i "origin.*hubzilla.*"
then
zotserver=hubzilla
elif git remote -v | grep -i "origin.*zap.*"
then
zotserver=zap
elif git remote -v | grep -i "origin.*misty.*"
then
zotserver=misty
elif git remote -v | grep -i "origin.*osada.*"
then
zotserver=osada
elif git remote -v | grep -i "origin.*redmatrix.*"
then
zotserver=redmatrix
else
die "neither redmatrix, osada, misty, zap nor hubzilla repository > did not install redmatrix/osada/misty/zap/hubzilla"
fi
}
function install_zotserver {
print_info "installing addons..."
cd $install_path/
if [ $zotserver = "hubzilla" ]
then
print_info "hubzilla"
util/add_addon_repo https://framagit.org/hubzilla/addons hzaddons
elif [ $zotserver = "zap" ]
then
print_info "zap"
util/add_addon_repo https://codeberg.org/zot/zap-addons.git zaddons
elif [ $zotserver = "misty" ]
then
print_info "misty"
util/add_addon_repo https://codeberg.org/zot/misty-addons.git maddons
elif [ $zotserver = "osada" ]
then
print_info "osada"
util/add_addon_repo https://codeberg.org/zot/osada-addons.git oaddons
elif [ $zotserver = "redmatrix" ]
then
print_info "redmatrix"
util/add_addon_repo https://codeberg.org/zot/redmatrix-addons.git raddons
else
die "neither redmatrix, osada, misty, zap nor hubzilla repository > did not install addons or redmatrix/osada/misty/zap/hubzilla"
fi
mkdir -p "cache/smarty3"
mkdir -p "store"
chmod -R 777 store
touch .htconfig.php
chmod ou+w .htconfig.php
cd /var/www/
chown -R www-data:www-data $install_path
chown root:www-data $install_path/
chown root:www-data $install_path/.htaccess
chmod 0644 $install_path/.htaccess
print_info "installed addons"
}
function install_rsync {
print_info "installing rsync..."
nocheck_install "rsync"
}
function install_cryptosetup {
print_info "installing cryptsetup..."
nocheck_install "cryptsetup"
}
function configure_zotserverdaily {
echo "#!/bin/sh" >> /var/www/$zotserverdaily
echo "#" >> /var/www/$zotserverdaily
echo "# update of $le_domain Zot hub/instance" >> /var/www/$zotserverdaily
echo "echo \"\$(date) - updating core and addons...\"" >> /var/www/$zotserverdaily
echo "echo \"reaching git repository for $le_domain $zotserver hub/instance...\"" >> /var/www/$zotserverdaily
echo "(cd $install_path ; util/udall)" >> /var/www/$zotserverdaily
echo "chown -R www-data:www-data $install_path # make all accessible for the webserver" >> /var/www/$zotserverdaily
if [ $webserver = "apache" ]
then
echo "chown root:www-data $install_path/.htaccess" >> /var/www/$zotserverdaily
echo "chmod 0644 $install_path/.htaccess # www-data can read but not write it" >> /var/www/$zotserverdaily
fi
chmod a+x /var/www/$zotserverdaily
}
function configure_cron_daily {
print_info "configuring cron..."
# every 10 min for poller.php
if [ -z "`grep '$install_path.*Run.php' /etc/crontab`" ]
then
echo "*/10 * * * * www-data cd $install_path; php Zotlabs/Daemon/Run.php Cron >> /dev/null 2>&1" >> /etc/crontab
fi
# Run external script daily at 05:30
# - stop apache/nginx and mysql-server
# - renew the certificate of letsencrypt
# - backup db, files ($install_path), certificates if letsencrypt
# - update zotserver core and addon
# - update and upgrade linux
# - reboot is done by "shutdown -h now" because "reboot" hangs sometimes depending on the system
echo "#!/bin/sh" > /var/www/$zotcron
echo "#" >> /var/www/$zotcron
echo "echo \" \"" >> /var/www/$zotcron
echo "echo \"+++ \$(date) +++\"" >> /var/www/$zotcron
echo "echo \" \"" >> /var/www/$zotcron
echo "echo \"\$(date) - stopping $webserver and mysql...\"" >> /var/www/$zotcron
if [ $webserver = "nginx" ]
then
echo "systemctl stop nginx" >> /var/www/$zotcron
elif [ $webserver = "apache" ]
then
echo "service apache2 stop" >> /var/www/$zotcron
fi
echo "/etc/init.d/mysql stop # to avoid inconsistencies" >> /var/www/$zotcron
echo "#" >> /var/www/$zotcron
echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$zotcron
echo "certbot renew --noninteractive" >> /var/www/$zotcron
echo "#" >> /var/www/$zotcron
echo "# backup" >> /var/www/$zotcron
echo "echo \"\$(date) - try to mount external device for backup...\"" >> /var/www/$zotcron
echo "backup_device_name=$backup_device_name" >> /var/www/$zotcron
echo "backup_device_pass=$backup_device_pass" >> /var/www/$zotcron
echo "backup_mount_point=$backup_mount_point" >> /var/www/$zotcron
echo "device_mounted=0" >> /var/www/$zotcron
echo "if [ -n \"\$backup_device_name\" ]" >> /var/www/$zotcron
echo "then" >> /var/www/$zotcron
echo " if blkid | grep $backup_device_name" >> /var/www/$zotcron
echo " then" >> /var/www/$zotcron
if [ -n "$backup_device_pass" ]
then
echo " echo \"decrypting backup device...\"" >> /var/www/$zotcron
echo " echo "\"$backup_device_pass\"" | cryptsetup luksOpen $backup_device_name cryptobackup" >> /var/www/$zotcron
fi
echo " if [ ! -d $backup_mount_point ]" >> /var/www/$zotcron
echo " then" >> /var/www/$zotcron
echo " mkdir $backup_mount_point" >> /var/www/$zotcron
echo " fi" >> /var/www/$zotcron
echo " echo \"mounting backup device...\"" >> /var/www/$zotcron
if [ -n "$backup_device_pass" ]
then
echo " if mount /dev/mapper/cryptobackup $backup_mount_point" >> /var/www/$zotcron
else
echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$zotcron
fi
echo " then" >> /var/www/$zotcron
echo " device_mounted=1" >> /var/www/$zotcron
echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$zotcron
echo " rsync -a --delete /var/lib/mysql/ /media/zotserver_backup/mysql" >> /var/www/$zotcron
echo " rsync -a --delete /var/www/ /media/zotserver_backup/www" >> /var/www/$zotcron
echo " rsync -a --delete /etc/letsencrypt/ /media/zotserver_backup/letsencrypt" >> /var/www/$zotcron
echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$zotcron
echo " df -h" >> /var/www/$zotcron
echo " echo \"\$(date) - db size...\"" >> /var/www/$zotcron
echo " du -h $backup_mount_point | grep mysql/zotserver" >> /var/www/$zotcron
echo " echo \"unmounting backup device...\"" >> /var/www/$zotcron
echo " umount $backup_mount_point" >> /var/www/$zotcron
echo " else" >> /var/www/$zotcron
echo " echo \"failed to mount device $backup_device_name\"" >> /var/www/$zotcron
echo " fi" >> /var/www/$zotcron
if [ -n "$backup_device_pass" ]
then
echo " echo \"closing decrypted backup device...\"" >> /var/www/$zotcron
echo " cryptsetup luksClose cryptobackup" >> /var/www/$zotcron
fi
echo " fi" >> /var/www/$zotcron
echo "fi" >> /var/www/$zotcron
echo "if [ \$device_mounted == 0 ]" >> /var/www/$zotcron
echo "then" >> /var/www/$zotcron
echo " echo \"device could not be mounted $backup_device_name. No backup written.\"" >> /var/www/$zotcron
echo "fi" >> /var/www/$zotcron
echo "#" >> /var/www/$zotcron
echo "echo \"\$(date) - db size...\"" >> /var/www/$zotcron
echo "du -h /var/lib/mysql/ | grep mysql/" >> /var/www/$zotcron
echo "#" >> /var/www/$zotcron
echo "cd /var/www" >> /var/www/$zotcron
echo "for f in *-daily.sh; do \"./\${f}\"; done" >> /var/www/$zotcron
echo "echo \"\$(date) - updating linux...\"" >> /var/www/$zotcron
echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> /var/www/$zotcron
echo "echo \"\$(date) - Backup and update finished. Rebooting...\"" >> /var/www/$zotcron
echo "#" >> /var/www/$zotcron
echo "shutdown -r now" >> /var/www/$zotcron
# If global cron job does not exist we add it to /etc/crontab
if grep -q $zotcron /etc/crontab
then
echo "cron job already in /etc/crontab"
else
echo "30 05 * * * root /bin/bash /var/www/$zotcron >> /var/www/zot-daily.log 2>&1" >> /etc/crontab
echo "0 0 1 * * root rm /var/www/zot-daily.log" >> /etc/crontab
fi
# This is active after either "reboot" or cron reload"
systemctl restart cron
print_info "configured cron for updates/upgrades"
}
########################################################################
# START OF PROGRAM
########################################################################
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
check_sanity
zotserver_name
print_info "We're installing a $zotserver instance"
install_path="$(dirname "$(pwd)")"
install_folder="$(basename $install_path)"
# Read config file edited by user
configfile=zotserver-config.txt
source $configfile
selfhostdir=/etc/selfhost
selfhostscript=selfhost-updater.sh
zotcron="zotcron.sh"
zotserverdaily="${install_folder}-${zotserver}-daily.sh"
backup_mount_point="/media/zotserver_backup"
#set -x # activate debugging from here
check_config
stop_zotserver
update_upgrade
install_curl
install_wget
install_sendmail
if [ $webserver = "nginx" ]
then
install_nginx
elif [ $webserver = "apache" ]
then
install_apache
else
die "Failed to install a Web server: 'webserver' not set to \"apache\" or \"nginx\" in $configfile"
fi
install_imagemagick
install_php
if [ $webserver = "nginx" ]
then
add_nginx_block
elif [ $webserver = "apache" ]
then
if [ "$install_path" != "/var/www/html" ]
then
add_vhost
fi
fi
install_mysql
if [ $webserver = "apache" ]
then
install_adminer
fi
create_zotserver_db
run_freedns
install_run_selfhost
ping_domain
configure_cron_freedns
configure_cron_selfhost
if [ "$le_domain" != "localhost" ]
then
install_letsencrypt
check_https
else
print_info "is localhost - skipped installation of letsencrypt and configuration of apache for https"
fi
install_zotserver
configure_zotserverdaily
configure_cron_daily
if [ "$le_domain" != "localhost" ]
then
install_cryptosetup
install_rsync
else
print_info "is localhost - skipped installation of cryptosetup"
fi
#set +x # stop debugging from here

101
CHANGELOG
View File

@@ -1,3 +1,104 @@
Hubzilla 5.0 (2020-11-05)
- Remove unmaintained and deprecated schemas
- Deprecate HTML5_Parser library
- Implement results caching for public tag and profile categories fetching
- Deprecate $a variable for *_plugin_admin() and *_plugin_admin_post()
- Support remote host cache directives on profile photo fetching
- Disable community tags until it is agreed upon on how to implement in zot6 or activitypub
- Improve home install setup script
- Cryptojs moved to addon
- Implement "more encryption" feature with the SJCL library
- Add minimum form lifetime check
- Improve updateConvItems() performance
- Improve infinite scroll experience
- Introduce a software bill of material (wip)
- Implement new forum behaviour (direct-message a forum to post on its wall) for cross-plattform forum compatibility
- Allow apps to be both pinned and starred independently
- Add images load status to spinnner if preload images is enabled
- Deprecate premium channel app
- Allow to set different values for left and right aside width in $theme.php
- Display complete permission info only to channel owner
- Set CURLOPT_ENCODING to empty string so that compressed content will be uncompressed
- Force browser photo revalidation
- Deprecate ACTIVITY_OBJ_FILE and ACTIVITY_OBJ_WIKI in favour of other object types (Document, Audio, Video)
- Use $mid as plink to prevent to long plinks
- Handle some basic friendica attachment bbcodes
- Deprecate is_edit_activity()
- Deprecate voting feature in favour of polls
- Show event timezone if it differs from the channel timezone
- Avoid multiple run of expiry procedure on large sites
- Implement zot6 as the primary protocol
- Introduce polls
- Provide titles for wiki links markup
- Implement DAV calendars sync with clones
- Optional events and poll filters for mod network
- Add new addon hook get_banner
- Provide tools to deal with spam channels for primary directory admin
- Introduce pinned posts for mod channel
- Refactor notifications to utilize server sent events
- Provide more descriptive connection status icons
Bugfixes
- Fix issue where interrupted uploads could not be resumed
- Fix photo sync issue between clones
- Fix issue where profile photos were fetched for unknown channels
- Apply channel name changes to all associated xchans
- Show unchecked box in connedit if value is false
- Reset their_perms before setting new permissions to reflect permission retractions on local hub
- Respect advanced profile setting in sexual preference selector
- Do not allow invite codes to be reused unlimited times
- Fix issue with quoted hashtags/mentions
- Fix issue generating photo thumbnails when uploaded via davfs
- Do not call System::get_platform_name() within t() unless needed
- Fix wrong URL detection with Markdown support enabled
- Fix once cached embedded content is used and stored forever
Addons
- Pubcrawl: fix issue where http signatures were not verified
- Pubcrawl: fix issue where private keys were lost from storage
- Pubcrawl: add host to signed headers (required by mastodon 3.2.1)
- Diaspora: remove relay@relay.iliketoat.net as default relay (it does not exist anymore)
- Diaspora: provide UI for admin to configure relay
- Diaspora: move the-federation.info registration to statistics addon
- Deprecate $a variable for *_plugin_admin() and *_plugin_admin_post()
- Chess: moved to addons-unmaintained repository
- Introduce cryptojs addon to allow decryption of legacy e2ee notes
- Introduce the hide aside addon - fade out aside areas after a while when using endless scroll
- Gallery: only show first row of images in the preview
- Gallery: restrict height of images to divmore_height
- Diaspora: make sure we only provide strings for unxmlify()
- Pubcrawl: fix federation with pixelfed
- Pubcrawl: dismiss announce if we already have the original item
- Gallery: implement view_storage permission for channel_apps()
- Cart: order currency param must be added to the sdk script url
- Diaspora utilize Lib/Connect
- Cart: utilize Lib/Connect
- Cart: add per item and per order customer data entry
- Pubcrawl: implement polls
- Chord Generator: moved to addons-unmaintained repository
- Custom Home: moved to addons-unmaintained repository
- Flattr Widget: moved to addons-unmaintained repository
- Friendica Photo Migrator: moved to addons-unmaintained repository
- Jappix Mini: moved to addons-unmaintained repository
- Mahjongg: moved to addons-unmaintained repository
- Torch: moved to addons-unmaintained repository
- Tour: moved to addons-unmaintained repository
- Introduce navbanner_option addon
- Pubcrawl: support image description
- Queueworker: fix duplicate checking
- Diaspora: fix dreport
- Move legacy zot/diaspora mail frontend from core to mail addon
- Diaspora: improve sql queries performance
- Pubcrawl: introduce pubcrawl_activity_mod_init()
- Twitter: replace Hubzilla bookmark with unicode icon
- Pubcrawl: add sys channel to local subscribers
- Pubcrawl: deal with arrays in attributedTo
- Workflow: various fixes
- Channelreputation: various fixes
- Introduce SSE addon to provide realtime notifications utilizing server sent events
Hubzilla 4.6 (2019-12-04)
- Improve opengraph support for channels
- Add opengraph support for articles

32
SBOM.md Normal file
View File

@@ -0,0 +1,32 @@
# Hubzilla Software Bill of Materials - WIP
|Name|Version|License|Source|
|----|-------|-------|------|
|blueimp/jquery-file-upload|10.31.0.0|MIT|https://github.com/vkhramtsov/jQuery-File-Upload.git|
|bshaffer/oauth2-server-php|1.11.1.0|MIT|https://github.com/bshaffer/oauth2-server-php.git|
|commerceguys/intl|1.0.5.0|MIT|https://github.com/commerceguys/intl.git|
|desandro/imagesloaded|4.1.4.0|MIT|https://github.com/desandro/imagesloaded.git|
|ezyang/htmlpurifier|4.13.0.0|LGPL-2.1-or-later|https://github.com/ezyang/htmlpurifier.git|
|league/html-to-markdown|4.10.0.0|MIT|https://github.com/thephpleague/html-to-markdown.git|
|lukasreschke/id3parser|0.0.3.0|GPL|https://github.com/LukasReschke/ID3Parser.git|
|michelf/php-markdown|1.9.0.0|BSD-3-Clause|https://github.com/michelf/php-markdown.git|
|paragonie/random_compat|9.99.99.0|MIT|https://github.com/paragonie/random_compat.git|
|pear/text_languagedetect|1.0.0.0|BSD-2-Clause|https://github.com/pear/Text_LanguageDetect.git|
|psr/log|1.1.3.0|MIT|https://github.com/php-fig/log.git|
|ramsey/uuid|3.9.3.0|MIT|https://github.com/ramsey/uuid.git|
|sabre/dav|4.1.1.0|BSD-3-Clause|https://github.com/sabre-io/dav.git|
|sabre/event|5.1.0.0|BSD-3-Clause|https://github.com/sabre-io/event.git|
|sabre/http|5.1.0.0|BSD-3-Clause|https://github.com/sabre-io/http.git|
|sabre/uri|2.2.0.0|BSD-3-Clause|https://github.com/sabre-io/uri.git|
|sabre/vobject|4.3.1.0|BSD-3-Clause|https://github.com/sabre-io/vobject.git|
|sabre/xml|2.2.1.0|BSD-3-Clause|https://github.com/sabre-io/xml.git|
|simplepie/simplepie|1.5.5.0|BSD-3-Clause|https://github.com/simplepie/simplepie.git|
|smarty/smarty|3.1.36.0|LGPL-3.0|https://github.com/smarty-php/smarty.git|
|symfony/polyfill-ctype|1.13.1.0|MIT|https://github.com/symfony/polyfill-ctype.git|
|twbs/bootstrap|4.5.2.0|MIT|https://github.com/twbs/bootstrap.git|
|fullcalendar/fullcalendar|4.4.2.0|MIT|https://github.com/fullcalendar/fullcalendar.git|
|miromannino/Justified-Gallery|3.8.1.0|MIT|https://github.com/miromannino/Justified-Gallery.git|
|fengyuanchen/cropperjs|1.5.7.0|MIT|https://github.com/fengyuanchen/cropperjs.git|
|ForkAwesome/Fork-Awesome|1.1.7.0|MIT,SIL OFL,CC BY 3.0|https://github.com/ForkAwesome/Fork-Awesome.git|
|leafo/sticky-kit|1.1.2.0|MIT|https://github.com/leafo/sticky-kit.git|
|jquery/jquery|3.5.1.0|MIT|https://github.com/jquery/jquery.git|

View File

@@ -100,6 +100,7 @@ class PermissionRoles {
'post_mail', 'post_like' , 'republish', 'chat'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
break;
@@ -113,6 +114,7 @@ class PermissionRoles {
'view_pages', 'view_wiki', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
break;
@@ -132,6 +134,7 @@ class PermissionRoles {
$ret['limits']['view_storage'] = PERMS_SPECIFIC;
$ret['limits']['view_pages'] = PERMS_SPECIFIC;
$ret['limits']['view_wiki'] = PERMS_SPECIFIC;
$ret['channel_type'] = 'group';
break;
@@ -187,6 +190,7 @@ class PermissionRoles {
'post_mail', 'post_like' , 'republish', 'chat', 'write_wiki'
];
$ret['limits'] = PermissionLimits::Std_Limits();
$ret['channel_type'] = 'group';
break;

View File

@@ -283,4 +283,15 @@ class Permissions {
return ( [ 'perms' => $my_perms, 'automatic' => $automatic ] );
}
}
static public function serialise($p) {
$n = [];
if($p) {
foreach($p as $k => $v) {
if(intval($v)) {
$n[] = $k;
}
}
}
return implode(',',$n);
}
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Libsync;
class Cron {
static public function run($argc,$argv) {
@@ -36,11 +38,6 @@ class Cron {
Master::Summon(array('Poller'));
// maintenance for mod sharedwithme - check for updated items and remove them
require_once('include/sharedwithme.php');
apply_updates();
/**
* Chatpresence: if somebody hasn't pinged recently, they've most likely left the page
* and shouldn't count as online anymore. We allow an expection for bots.
@@ -147,7 +144,7 @@ class Cron {
if($z) {
xchan_query($z);
$sync_item = fetch_post_tags($z);
build_sync_packet($sync_item[0]['uid'],
Libsync::build_sync_packet($sync_item[0]['uid'],
[
'item' => [ encode_item($sync_item[0],true) ]
]
@@ -158,6 +155,11 @@ class Cron {
}
}
// check if any connections transitioned to zot6 and upgrade the connections to zot6 at this hub if so.
require_once('include/connections.php');
z6trans_connections();
require_once('include/attach.php');
attach_upgrade();

View File

@@ -96,6 +96,7 @@ class Cron_daily {
Master::Summon(array('Cli_suggest'));
remove_obsolete_hublocs();
z6_discover();
call_hooks('cron_daily',datetime_convert());

View File

@@ -2,10 +2,9 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
require_once('include/dir_fns.php');
require_once('include/queue_fn.php');
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Libzotdir;
use Zotlabs\Lib\Queue;
class Directory {
@@ -42,7 +41,7 @@ class Directory {
// this is an in-memory update and we don't need to send a network packet.
local_dir_update($argv[1],$force);
Libzotdir::local_dir_update($argv[1],$force);
q("update channel set channel_dirdate = '%s' where channel_id = %d",
dbesc(datetime_convert()),
@@ -58,13 +57,15 @@ class Directory {
// otherwise send the changes upstream
$directory = find_upstream_directory($dirmode);
$directory = Libzotdir::find_upstream_directory($dirmode);
$url = $directory['url'] . '/post';
// ensure the upstream directory is updated
$packet = zot_build_packet($channel,(($force) ? 'force_refresh' : 'refresh'));
$z = zot_zot($url,$packet);
$packet = Libzot::build_packet($channel,(($force) ? 'force_refresh' : 'refresh'));
$z = Libzot::zot($url,$packet,$channel);
// re-queue if unsuccessful
@@ -76,7 +77,7 @@ class Directory {
$hash = random_string();
queue_insert(array(
Queue::insert(array(
'hash' => $hash,
'account_id' => $channel['channel_account_id'],
'channel_id' => $channel['channel_id'],

View File

@@ -8,6 +8,15 @@ class Expire {
static public function run($argc,$argv){
cli_startup();
$pid = get_config('expire', 'procid', false);
if ($pid && (function_exists('posix_kill') ? posix_kill($pid, 0) : true)) {
logger('Expire: procedure already run with pid ' . $pid, LOGGER_DEBUG);
return;
}
$pid = getmypid();
set_config('expire', 'procid', $pid);
// perform final cleanup on previously delete items
@@ -32,7 +41,7 @@ class Expire {
if (intval(get_config('system', 'optimize_items')))
q("optimize table item");
logger('expire: start', LOGGER_DEBUG);
logger('expire: start with pid ' . $pid, LOGGER_DEBUG);
$site_expire = intval(get_config('system', 'default_expire_days'));
$commented_days = intval(get_config('system','active_expire_days'));
@@ -90,5 +99,7 @@ class Expire {
logger('Expire: sys: done', LOGGER_DEBUG);
}
del_config('expire', 'procid');
}
}

View File

@@ -2,7 +2,9 @@
namespace Zotlabs\Daemon;
require_once('include/zot.php');
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Webfinger;
use Zotlabs\Lib\Zotfinger;
// performs zot_finger on $argv[1], which is a hex_encoded webbie/reddress
@@ -22,12 +24,16 @@ class Gprobe {
);
if(! $r) {
$j = \Zotlabs\Zot\Finger::run($url,null);
if($j['success']) {
$y = import_xchan($j);
$href = Webfinger::zot_url(punify($url));
if($href) {
$zf = Zotfinger::exec($href, null);
}
if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
$xc = Libzot::import_xchan($zf['data']);
}
}
return;
}
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Libsync;
class Importfile {
static public function run($argc,$argv){
@@ -40,7 +42,7 @@ class Importfile {
$sync = attach_export_data($channel,$hash);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
return;
}

View File

@@ -45,18 +45,18 @@ require_once('include/bbcode.php');
*
* where COMMAND is one of the following:
*
* activity (in diaspora.php, dfrn_confirm.php, profiles.php)
* comment-import (in diaspora.php, items.php)
* comment-new (in item.php)
* drop (in diaspora.php, items.php, photos.php)
* edit_post (in item.php)
* event (in events.php)
* expire (in items.php)
* like (in like.php, poke.php)
* mail (in message.php)
* tag (in photos.php, poke.php, tagger.php)
* tgroup (in items.php)
* wall-new (in photos.php, item.php)
* activity (in diaspora.php, dfrn_confirm.php, profiles.php)
* comment-import (in diaspora.php, items.php)
* comment-new (in item.php)
* drop (in diaspora.php, items.php, photos.php)
* edit_post (in item.php)
* event (in events.php)
* expire (in items.php)
* like (in like.php, poke.php)
* mail (in message.php)
* tag (in photos.php, poke.php, tagger.php)
* tgroup (in items.php)
* wall-new (in photos.php, item.php)
*
* and ITEM_ID is the id of the item in the database that needs to be sent to others.
*
@@ -66,9 +66,10 @@ require_once('include/bbcode.php');
* permission_reject abook_id
* permission_update abook_id
* refresh_all channel_id
* purge channel_id xchan_hash
* purge_all channel_id
* expire channel_id
* relay item_id (item was relayed to owner, we will deliver it as owner)
* relay item_id (item was relayed to owner, we will deliver it as owner)
* single_activity item_id (deliver to a singleton network from the appropriate clone)
* single_mail mail_id (deliver to a singleton network from the appropriate clone)
* location channel_id
@@ -240,25 +241,40 @@ class Notifier {
$packet_type = 'location';
$location = true;
}
elseif($cmd === 'purge') {
$xchan = $argv[3];
logger('notifier: purge: ' . $item_id . ' => ' . $xchan);
if (! $xchan) {
return;
}
$channel = channelx_by_n($item_id);
$recipients[] = $xchan;
$private = true;
$packet_type = 'purge';
$packet_recips[] = ['hash' => $xchan];
}
elseif($cmd === 'purge_all') {
logger('notifier: purge_all: ' . $item_id);
$s = q("select * from channel where channel_id = %d limit 1",
intval($item_id)
);
if($s)
$channel = $s[0];
$uid = $item_id;
$recipients = array();
$channel = channelx_by_n($item_id);
$recipients = [];
$r = q("select abook_xchan from abook where abook_channel = %d and abook_self = 0",
intval($item_id)
);
if($r) {
foreach($r as $rr) {
$recipients[] = $rr['abook_xchan'];
}
if (! $r) {
return;
}
foreach ($r as $rr) {
$recipients[] = $rr['abook_xchan'];
$packet_recips[] = ['hash' => $rr['abook_xchan']];
}
$private = false;
$packet_type = 'purge';
}
else {
@@ -278,6 +294,12 @@ class Notifier {
$r = fetch_post_tags($r);
$target_item = $r[0];
if(in_array($target_item['author']['xchan_network'], ['rss', 'anon'])) {
logger('notifier: target item author is not a fetchable actor', LOGGER_DEBUG);
return;
}
$deleted_item = false;
if(intval($target_item['item_deleted'])) {
@@ -361,24 +383,24 @@ class Notifier {
$encoded_item = encode_item($target_item);
// activitystreams version
$m = get_iconfig($target_item,'activitystreams','signed_data');
// Re-use existing signature unless the activity type changed to a Tombstone, which won't verify.
$m = ((intval($target_item['item_deleted'])) ? '' : get_iconfig($target_item,'activitystreams','signed_data'));
if($m) {
$activity = json_decode($m,true);
}
else {
$activity = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV
]], Activity::encode_activity($target_item)
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV
]], Activity::encode_activity($target_item)
);
}
logger('target_item: ' . print_r($target_item,true), LOGGER_DEBUG);
logger('encoded: ' . print_r($activity,true), LOGGER_DEBUG);
// Send comments to the owner to re-deliver to everybody in the conversation
// We only do this if the item in question originated on this site. This prevents looping.
// To clarify, a site accepting a new comment is responsible for sending it to the owner for relay.
@@ -477,7 +499,6 @@ class Notifier {
$details = q("select xchan_hash, xchan_network, xchan_addr, xchan_guid, xchan_guid_sig from xchan where xchan_hash in (" . protect_sprintf(implode(',',$recipients)) . ")");
$recip_list = array();
if($details) {
@@ -542,18 +563,40 @@ class Notifier {
// Now we have collected recipients (except for external mentions, FIXME)
// Let's reduce this to a set of hubs; checking that the site is not dead.
$r = q("select hubloc.*, site.site_crypto, site.site_flags from hubloc left join site on site_url = hubloc_url where hubloc_hash in (" . protect_sprintf(implode(',',$recipients)) . ")
and hubloc_error = 0 and hubloc_deleted = 0 and ( site_dead = 0 OR site_dead is null ) "
);
$hubs = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_version, site.site_project, site.site_dead from hubloc left join site on site_url = hubloc_url
where hubloc_hash in (" . protect_sprintf(implode(',',$recipients)) . ")
and hubloc_error = 0 and hubloc_deleted = 0"
);
if(! $r) {
// public posts won't make it to the local public stream unless there's a recipient on this site.
// This code block sees if it's a public post and localhost is missing, and if so adds an entry for the local sys channel to the $hubs list
if (! $private) {
$found_localhost = false;
if ($hubs) {
foreach ($hubs as $h) {
if ($h['hubloc_url'] === z_root()) {
$found_localhost = true;
break;
}
}
}
if (! $found_localhost) {
$localhub = q("select hubloc.*, site.site_crypto, site.site_flags, site.site_version, site.site_project, site.site_dead from hubloc
left join site on site_url = hubloc_url where hubloc_id_url = '%s' and hubloc_error = 0 and hubloc_deleted = 0",
dbesc(z_root() . '/channel/sys')
);
if ($localhub) {
$hubs = array_merge($hubs, $localhub);
}
}
}
if(! $hubs) {
logger('notifier: no hubs', LOGGER_NORMAL, LOG_NOTICE);
return;
}
$hubs = $r;
/**
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey,
* since it may have been a re-install which has not yet been detected and pruned.
@@ -566,9 +609,15 @@ class Notifier {
$keys = []; // array of keys to check uniquness for zot hubs
$urls = []; // array of urls to check uniqueness of hubs from other networks
$hub_env = []; // per-hub envelope so we don't broadcast the entire envelope to all
$dead = []; // known dead hubs - report them as undeliverable
foreach($hubs as $hub) {
if (intval($hub['site_dead'])) {
$dead[] = $hub;
continue;
}
if($env_recips) {
foreach($env_recips as $er) {
if($hub['hubloc_hash'] === $er['hash']) {
@@ -640,7 +689,7 @@ class Notifier {
}
// singleton deliveries by definition 'not got zot'.
// Single deliveries are other federated networks (plugins) and we're essentially
// Single deliveries are other federated networks (plugins) and we're essentially
// delivering only to those that have this site url in their abook_instance
// and only from within a sync operation. This means if you post from a clone,
// and a connection is connected to one of your other clones; assuming that hub
@@ -735,7 +784,24 @@ class Notifier {
$packet = zot_build_packet($channel,'notify',$env, (($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
}
}
}
// remove this after most hubs have updated to version 5.0
if(stripos($hub['site_project'], 'hubzilla') !== false && version_compare($hub['site_version'], '4.7.3', '<=')) {
if($encoded_item['type'] === 'mail') {
$encoded_item['from']['network'] = 'zot';
$encoded_item['from']['guid_sig'] = str_replace('sha256.', '', $encoded_item['from']['guid_sig']);
}
else {
$encoded_item['owner']['network'] = 'zot';
$encoded_item['owner']['guid_sig'] = str_replace('sha256.', '', $encoded_item['owner']['guid_sig']);
if(strpos($encoded_item['author']['url'], z_root()) === 0) {
$encoded_item['author']['network'] = 'zot';
$encoded_item['author']['guid_sig'] = str_replace('sha256.', '', $encoded_item['author']['guid_sig']);
}
}
}
queue_insert(
[
@@ -778,6 +844,24 @@ class Notifier {
logger('notifier: basic loop complete.', LOGGER_DEBUG);
if ($dead) {
foreach ($dead as $deceased) {
if (is_array($target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_name, dreport_result, dreport_time, dreport_xchan, dreport_queue )
values ( '%s', '%s','%s','%s','%s','%s','%s','%s' ) ",
dbesc($target_item['mid']),
dbesc($deceased['hubloc_host']),
dbesc($deceased['hubloc_host']),
dbesc($deceased['hubloc_host']),
dbesc('undeliverable/unresponsive site'),
dbesc(datetime_convert()),
dbesc($channel['channel_hash']),
dbesc(random_string(48))
);
}
}
}
call_hooks('notifier_end',$target_item);
logger('notifer: complete.');

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Daemon;
use Zotlabs\Lib\Libzot;
require_once('include/zot.php');
require_once('include/socgraph.php');
@@ -76,7 +78,11 @@ class Onepoll {
// update permissions
$x = zot_refresh($contact,$importer);
if($contact['xchan_network'] === 'zot6')
$x = Libzot::refresh($contact,$importer);
if($contact['xchan_network'] === 'zot')
$x = zot_refresh($contact,$importer);
$responded = false;
$updated = datetime_convert();

411
Zotlabs/Lib/AccessList.php Normal file
View File

@@ -0,0 +1,411 @@
<?php
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
class AccessList {
static function add($uid,$name,$public = 0) {
$ret = false;
if ($uid && $name) {
$r = self::byname($uid,$name); // check for dups
if ($r !== false) {
// This could be a problem.
// Let's assume we've just created a list which we once deleted
// all the old members are gone, but the list remains so we don't break any security
// access lists. What we're doing here is reviving the dead list, but old content which
// was restricted to this list may now be seen by the new list members.
$z = q("SELECT * FROM pgrp WHERE id = %d LIMIT 1",
intval($r)
);
if(($z) && $z[0]['deleted']) {
q('UPDATE pgrp SET deleted = 0 WHERE id = %d', intval($z[0]['id']));
notice( t('A deleted list with this name was revived. Existing item permissions <strong>may</strong> apply to this list and any future members. If this is not what you intended, please create another list with a different name.') . EOL);
}
return true;
}
$hash = new_uuid();
$r = q("INSERT INTO pgrp ( hash, uid, visible, gname )
VALUES( '%s', %d, %d, '%s' ) ",
dbesc($hash),
intval($uid),
intval($public),
dbesc($name)
);
$ret = $r;
}
Libsync::build_sync_packet($uid,null,true);
return $ret;
}
static function remove($uid,$name) {
$ret = false;
if ($uid && $name) {
$r = q("SELECT id, hash FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if ($r) {
$group_id = $r[0]['id'];
$group_hash = $r[0]['hash'];
}
else {
return false;
}
// remove group from default posting lists
$r = q("SELECT channel_default_group, channel_allow_gid, channel_deny_gid FROM channel WHERE channel_id = %d LIMIT 1",
intval($uid)
);
if ($r) {
$user_info = array_shift($r);
$change = false;
if ($user_info['channel_default_group'] == $group_hash) {
$user_info['channel_default_group'] = '';
$change = true;
}
if (strpos($user_info['channel_allow_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_allow_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_allow_gid']);
$change = true;
}
if (strpos($user_info['channel_deny_gid'], '<' . $group_hash . '>') !== false) {
$user_info['channel_deny_gid'] = str_replace('<' . $group_hash . '>', '', $user_info['channel_deny_gid']);
$change = true;
}
if ($change) {
q("UPDATE channel SET channel_default_group = '%s', channel_allow_gid = '%s', channel_deny_gid = '%s'
WHERE channel_id = %d",
intval($user_info['channel_default_group']),
dbesc($user_info['channel_allow_gid']),
dbesc($user_info['channel_deny_gid']),
intval($uid)
);
}
}
// remove all members
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d ",
intval($uid),
intval($group_id)
);
// remove group
$r = q("UPDATE pgrp SET deleted = 1 WHERE uid = %d AND gname = '%s'",
intval($uid),
dbesc($name)
);
$ret = $r;
}
Libsync::build_sync_packet($uid,null,true);
return $ret;
}
// returns the integer id of an access group owned by $uid and named $name
// or false.
static function byname($uid,$name) {
if (! ($uid && $name)) {
return false;
}
$r = q("SELECT id FROM pgrp WHERE uid = %d AND gname = '%s' LIMIT 1",
intval($uid),
dbesc($name)
);
if ($r) {
return $r[0]['id'];
}
return false;
}
static function by_id($uid,$id) {
if (! ($uid && $id)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND id = %d and deleted = 0",
intval($uid),
intval($id)
);
if ($r) {
return array_shift($r);
}
return false;
}
static function rec_byhash($uid,$hash) {
if (! ( $uid && $hash)) {
return false;
}
$r = q("SELECT * FROM pgrp WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($uid),
dbesc($hash)
);
if ($r) {
return array_shift($r);
}
return false;
}
static function member_remove($uid,$name,$member) {
$gid = self::byname($uid,$name);
if (! $gid) {
return false;
}
if (! ($uid && $gid && $member)) {
return false;
}
$r = q("DELETE FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' ",
intval($uid),
intval($gid),
dbesc($member)
);
Libsync::build_sync_packet($uid,null,true);
return $r;
}
static function member_add($uid,$name,$member,$gid = 0) {
if (! $gid) {
$gid = self::byname($uid,$name);
}
if (! ($gid && $uid && $member)) {
return false;
}
$r = q("SELECT * FROM pgrp_member WHERE uid = %d AND gid = %d AND xchan = '%s' LIMIT 1",
intval($uid),
intval($gid),
dbesc($member)
);
if ($r) {
return true; // You might question this, but
// we indicate success because the group member was in fact created
// -- It was just created at another time
}
else {
$r = q("INSERT INTO pgrp_member (uid, gid, xchan)
VALUES( %d, %d, '%s' ) ",
intval($uid),
intval($gid),
dbesc($member)
);
}
Libsync::build_sync_packet($uid,null,true);
return $r;
}
static function members($uid, $gid) {
$ret = [];
if (intval($gid)) {
$r = q("SELECT * FROM pgrp_member
LEFT JOIN abook ON abook_xchan = pgrp_member.xchan left join xchan on xchan_hash = abook_xchan
WHERE gid = %d AND abook_channel = %d and pgrp_member.uid = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 ORDER BY xchan_name ASC ",
intval($gid),
intval($uid),
intval($uid)
);
if ($r) {
$ret = $r;
}
}
return $ret;
}
static function members_xchan($uid,$gid) {
$ret = [];
if (intval($gid)) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid = %d AND uid = %d",
intval($gid),
intval($uid)
);
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['xchan'];
}
}
}
return $ret;
}
static function members_profile_xchan($uid,$gid) {
$ret = [];
if (intval($gid)) {
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
intval($gid),
intval($uid)
);
if ($r) {
foreach($r as $rv) {
$ret[] = $rv['xchan'];
}
}
}
return $ret;
}
static function select($uid,$group = '') {
$grps = [];
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($uid)
);
$grps[] = [ 'name' => '', 'hash' => '0', 'selected' => '' ];
if ($r) {
foreach ($r as $rr) {
$grps[] = [ 'name' => $rr['gname'], 'id' => $rr['hash'], 'selected' => (($group == $rr['hash']) ? 'true' : '') ];
}
}
return replace_macros(get_markup_template('group_selection.tpl'), [
'$label' => t('Add new connections to this access list'),
'$groups' => $grps
]);
}
static function widget($every="connections",$each="lists",$edit = false, $group_id = 0, $cid = '',$mode = 1) {
$o = '';
$groups = [];
$r = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval($_SESSION['uid'])
);
$member_of = [];
if ($cid) {
$member_of = self::containing(local_channel(),$cid);
}
if ($r) {
foreach ($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : '');
if ($edit) {
$groupedit = [ 'href' => "lists/".$rr['id'], 'title' => t('edit') ];
}
else {
$groupedit = null;
}
$groups[] = [
'id' => $rr['id'],
'enc_cid' => base64url_encode($cid),
'cid' => $cid,
'text' => $rr['gname'],
'selected' => $selected,
'href' => (($mode == 0) ? $each.'?f=&gid='.$rr['id'] : $each."/".$rr['id']) . ((x($_GET,'new')) ? '&new=' . $_GET['new'] : '') . ((x($_GET,'order')) ? '&order=' . $_GET['order'] : ''),
'edit' => $groupedit,
'ismember' => in_array($rr['id'],$member_of),
];
}
}
return replace_macros(get_markup_template('group_side.tpl'), [
'$title' => t('Lists'),
'$edittext' => t('Edit list'),
'$createtext' => t('Create new list'),
'$ungrouped' => (($every === 'contacts') ? t('Channels not in any access list') : ''),
'$groups' => $groups,
'$add' => t('add'),
]);
}
static function expand($g) {
if (! (is_array($g) && count($g))) {
return [];
}
$ret = [];
$x = [];
// private profile linked virtual groups
foreach ($g as $gv) {
if (substr($gv,0,3) === 'vp.') {
$profile_hash = substr($gv,3);
if ($profile_hash) {
$r = q("select abook_xchan from abook where abook_profile = '%s'",
dbesc($profile_hash)
);
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['abook_xchan'];
}
}
}
}
else {
$x[] = $gv;
}
}
if ($x) {
stringify_array_elms($x,true);
$groups = implode(',', $x);
if ($groups) {
$r = q("SELECT xchan FROM pgrp_member WHERE gid IN ( select id from pgrp where hash in ( $groups ))");
if ($r) {
foreach ($r as $rv) {
$ret[] = $rv['xchan'];
}
}
}
}
return $ret;
}
static function member_of($c) {
$r = q("SELECT pgrp.gname, pgrp.id FROM pgrp LEFT JOIN pgrp_member ON pgrp_member.gid = pgrp.id
WHERE pgrp_member.xchan = '%s' AND pgrp.deleted = 0 ORDER BY pgrp.gname ASC ",
dbesc($c)
);
return $r;
}
static function containing($uid,$c) {
$r = q("SELECT gid FROM pgrp_member WHERE uid = %d AND pgrp_member.xchan = '%s' ",
intval($uid),
dbesc($c)
);
$ret = [];
if ($r) {
foreach ($r as $rv)
$ret[] = $rv['gid'];
}
return $ret;
}
}

View File

@@ -168,7 +168,7 @@ class Activity {
if($r) {
xchan_query($r,true);
$r = fetch_post_tags($r,true);
if ($r[0]['verb'] === 'Create' && $r[0]['obj_type'] === ACTIVITY_OBJ_EVENT) {
if (in_array($r[0]['verb'], ['Create', 'Invite']) && $r[0]['obj_type'] === ACTIVITY_OBJ_EVENT) {
$r[0]['verb'] = 'Invite';
return self::encode_activity($r[0]);
}
@@ -178,7 +178,6 @@ class Activity {
static function fetch_image($x) {
$ret = [
'type' => 'Image',
'id' => $x['id'],
@@ -315,14 +314,31 @@ class Activity {
else {
$objtype = self::activity_obj_mapper($i['obj_type']);
}
if(intval($i['item_deleted'])) {
if ($i['obj']) {
$ret = Activity::encode_object($i['obj']);
}
if (intval($i['item_deleted'])) {
$ret['type'] = 'Tombstone';
$ret['formerType'] = $objtype;
$ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid']));
$ret['id'] = $i['mid'];
if($i['id'] != $i['parent'])
$ret['inReplyTo'] = $i['thr_parent'];
$ret['to'] = [ ACTIVITY_PUBLIC_INBOX ];
return $ret;
}
if ($i['obj']) {
if (is_array($i['obj'])) {
$ret = $i['obj'];
}
else {
$ret = json_decode($i['obj'],true);
}
}
$ret['type'] = $objtype;
if ($objtype === 'Question') {
@@ -342,6 +358,7 @@ class Activity {
$ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid']));
$ret['diaspora:guid'] = $i['uuid'];
if($i['title'])
$ret['name'] = $i['title'];
@@ -414,7 +431,71 @@ class Activity {
$ret['attachment'] = $a;
}
$public = (($i['item_private']) ? false : true);
$top_level = (($i['mid'] === $i['parent_mid']) ? true : false);
if ($public) {
$ret['to'] = [ ACTIVITY_PUBLIC_INBOX ];
$ret['cc'] = [ z_root() . '/followers/' . substr($i['author']['xchan_addr'],0,strpos($i['author']['xchan_addr'],'@')) ];
}
else {
// private activity
if ($top_level) {
$ret['to'] = self::map_acl($i);
}
else {
$ret['to'] = [];
if ($ret['tag']) {
foreach ($ret['tag'] as $mention) {
if (is_array($mention) && array_key_exists('href',$mention) && $mention['href']) {
$h = q("select * from hubloc where hubloc_id_url = '%s' limit 1",
dbesc($mention['href'])
);
if ($h) {
if ($h[0]['hubloc_network'] === 'activitypub') {
$addr = $h[0]['hubloc_hash'];
}
else {
$addr = $h[0]['hubloc_id_url'];
}
if (! in_array($addr,$ret['to'])) {
$ret['to'][] = $addr;
}
}
}
}
}
$d = q("select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.id = %d limit 1",
intval($i['parent'])
);
if ($d) {
if ($d[0]['hubloc_network'] === 'activitypub') {
$addr = $d[0]['hubloc_hash'];
}
else {
$addr = $d[0]['hubloc_id_url'];
}
if (! in_array($addr,$ret['to'])) {
$ret['cc'][] = $addr;
}
}
}
}
$mentions = self::map_mentions($i);
if (count($mentions) > 0) {
if (! $ret['to']) {
$ret['to'] = $mentions;
}
else {
$ret['to'] = array_values(array_unique(array_merge($ret['to'], $mentions)));
}
}
return $ret;
}
static function decode_taxonomy($item) {
@@ -504,10 +585,47 @@ class Activity {
}
}
}
if ($item['iconfig']) {
foreach ($item['iconfig'] as $att) {
if ($att['sharing']) {
$value = ((is_string($att['v']) && preg_match('|^a:[0-9]+:{.*}$|s', $att['v'])) ? unserialize($att['v']) : $att['v']);
$ret[] = [ 'type' => 'PropertyValue', 'name' => 'zot.' . $att['cat'] . '.' . $att['k'], 'value' => $value ];
}
}
}
return $ret;
}
static function decode_iconfig($item) {
$ret = [];
if (is_array($item['attachment']) && $item['attachment']) {
$ptr = $item['attachment'];
if (! array_key_exists(0,$ptr)) {
$ptr = [ $ptr ];
}
foreach ($ptr as $att) {
$entry = [];
if ($att['type'] === 'PropertyValue') {
if (array_key_exists('name',$att) && $att['name']) {
$key = explode('.',$att['name']);
if (count($key) === 3 && $key[0] === 'zot') {
$entry['cat'] = $key[1];
$entry['k'] = $key[2];
$entry['v'] = $att['value'];
$entry['sharing'] = '1';
$ret[] = $entry;
}
}
}
}
}
return $ret;
}
static function decode_attachment($item) {
@@ -534,7 +652,7 @@ class Activity {
static function encode_activity($i) {
static function encode_activity($i, $recurse = false) {
$ret = [];
$reply = false;
@@ -545,21 +663,47 @@ class Activity {
$ret['obj'] = [];
}
if(intval($i['item_deleted'])) {
$ret['type'] = 'Tombstone';
$ret['formerType'] = self::activity_obj_mapper($i['obj_type']);
$ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/item/' . urlencode($i['mid']));
$ret['type'] = self::activity_mapper($i['verb']);
$fragment = '';
if (intval($i['item_deleted']) && !$recurse) {
$is_response = false;
if (ActivityStreams::is_response_activity($ret['type'])) {
$ret['type'] = 'Undo';
$fragment = 'undo';
$is_response = true;
}
else {
$ret['type'] = 'Delete';
$fragment = 'delete';
}
$ret['id'] = str_replace('/item/','/activity/',$i['mid']) . '#' . $fragment;
$actor = self::encode_person($i['author'],false);
if($actor)
if ($actor)
$ret['actor'] = $actor;
else
return [];
$obj = (($is_response) ? self::encode_activity($i,true) : self::encode_item($i,true));
if ($obj) {
if (array_path_exists('object/id',$obj)) {
$obj['object'] = $obj['object']['id'];
}
unset($obj['cc']);
$obj['to'] = [ ACTIVITY_PUBLIC_INBOX ];
$ret['object'] = $obj;
}
else
return [];
$ret['to'] = [ ACTIVITY_PUBLIC_INBOX ];
return $ret;
}
$ret['type'] = self::activity_mapper($i['verb']);
if($ret['type'] === 'emojiReaction') {
// There may not be an object for these items for legacy reasons - it should be the conversation parent.
$p = q("select * from item where mid = '%s' and uid = %d",
@@ -602,6 +746,8 @@ class Activity {
$ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/activity/' . urlencode($i['mid']));
}
$ret['diaspora:guid'] = $i['uuid'];
if($i['title'])
$ret['name'] = html2plain(bbcode($i['title'], [ 'cache' => true ]));
@@ -714,57 +860,155 @@ class Activity {
return [];
}
$t = self::encode_taxonomy($i);
if ($t) {
$ret['tag'] = $t;
}
// addressing madness
$public = (($i['item_private']) ? false : true);
$top_level = (($reply) ? false : true);
if ($public) {
$ret['to'] = [ ACTIVITY_PUBLIC_INBOX ];
$ret['cc'] = [ z_root() . '/followers/' . substr($i['author']['xchan_addr'],0,strpos($i['author']['xchan_addr'],'@')) ];
}
else {
// private activity
if ($top_level) {
$ret['to'] = self::map_acl($i);
}
else {
$ret['to'] = [];
if ($ret['tag']) {
foreach ($ret['tag'] as $mention) {
if (is_array($mention) && array_key_exists('href',$mention) && $mention['href']) {
$h = q("select * from hubloc where hubloc_id_url = '%s' limit 1",
dbesc($mention['href'])
);
if ($h) {
if ($h[0]['hubloc_network'] === 'activitypub') {
$addr = $h[0]['hubloc_hash'];
}
else {
$addr = $h[0]['hubloc_id_url'];
}
if (! in_array($addr,$ret['to'])) {
$ret['to'][] = $addr;
}
}
}
}
}
$d = q("select hubloc.* from hubloc left join item on hubloc_hash = owner_xchan where item.id = %d limit 1",
intval($i['parent'])
);
if ($d) {
if ($d[0]['hubloc_network'] === 'activitypub') {
$addr = $d[0]['hubloc_hash'];
}
else {
$addr = $d[0]['hubloc_id_url'];
}
if (! in_array($addr,$ret['to'])) {
$ret['cc'][] = $addr;
}
}
}
}
$mentions = self::map_mentions($i);
if (count($mentions) > 0) {
if (! $ret['to']) {
$ret['to'] = $mentions;
}
else {
$ret['to'] = array_values(array_unique(array_merge($ret['to'], $mentions)));
}
}
return $ret;
}
// Returns an array of URLS for any mention tags found in the item array $i.
static function map_mentions($i) {
if(! $i['term']) {
if (! $i['term']) {
return [];
}
$list = [];
foreach ($i['term'] as $t) {
if($t['ttype'] == TERM_MENTION) {
$list[] = $t['url'];
if (! $t['url']) {
continue;
}
if ($t['ttype'] == TERM_MENTION) {
$url = self::lookup_term_url($t['url']);
$list[] = (($url) ? $url : $t['url']);
}
}
return $list;
}
static function map_acl($i,$mentions = false) {
// Returns an array of all recipients targeted by private item array $i.
$private = false;
$list = [];
$x = collect_recipients($i,$private);
if($x) {
stringify_array_elms($x);
if(! $x)
return;
static function map_acl($i) {
$ret = [];
$strict = (($mentions) ? true : get_config('activitypub','compliance'));
if (! $i['item_private']) {
return $ret;
}
$sql_extra = (($strict) ? " and xchan_network = 'activitypub' " : '');
if ($i['allow_gid']) {
$tmp = expand_acl($i['allow_gid']);
if ($tmp) {
foreach ($tmp as $t) {
$ret[] = z_root() . '/lists/' . $t;
}
}
}
$details = q("select xchan_url, xchan_addr, xchan_name from xchan where xchan_hash in (" . implode(',',$x) . ") $sql_extra");
if($details) {
foreach($details as $d) {
if($mentions) {
$list[] = [ 'type' => 'Mention', 'href' => $d['xchan_url'], 'name' => '@' . (($d['xchan_addr']) ? $d['xchan_addr'] : $d['xchan_name']) ];
}
else {
$list[] = $d['xchan_url'];
if ($i['allow_cid']) {
$tmp = expand_acl($i['allow_cid']);
$list = stringify_array($tmp,true);
if ($list) {
$details = q("select hubloc_id_url from hubloc where hubloc_hash in (" . $list . ") and hubloc_id_url != ''");
if ($details) {
foreach ($details as $d) {
$ret[] = $d['hubloc_id_url'];
}
}
}
}
return $list;
return $ret;
}
static function lookup_term_url($url) {
// The xchan_url for mastodon is a text/html rendering. This is called from map_mentions where we need
// to convert the mention url to an ActivityPub id. If this fails for any reason, return the url we have
$r = q("select hubloc_network, hubloc_hash, hubloc_id_url from hubloc where hubloc_id_url = '%s' limit 1",
dbesc($url)
);
if ($r) {
if ($r[0]['hubloc_network'] === 'activitypub') {
return $r[0]['hubloc_hash'];
}
return $r[0]['hubloc_id_url'];
}
return $url;
}
static function encode_person($p, $extended = true) {
@@ -774,6 +1018,7 @@ class Activity {
if(! $extended) {
return $p['xchan_url'];
}
$ret = [];
$c = ((array_key_exists('channel_id',$p)) ? $p : channelx_by_hash($p['xchan_hash']));
@@ -819,10 +1064,16 @@ class Activity {
]
];
$ret['publicKey'] = [
'id' => $p['xchan_url'],
'owner' => $p['xchan_url'],
'publicKeyPem' => $p['xchan_pubkey']
];
$arr = [ 'xchan' => $p, 'encoded' => $ret ];
call_hooks('encode_person', $arr);
$ret = $arr['encoded'];
$ret = $arr['encoded'];
return $ret;
}
@@ -854,6 +1105,8 @@ class Activity {
'http://purl.org/zot/activity/attendno' => 'Reject',
'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept',
'Invite' => 'Invite',
'Delete' => 'Delete',
'Undo' => 'Undo'
];
call_hooks('activity_mapper',$acts);
@@ -901,6 +1154,8 @@ class Activity {
'http://purl.org/zot/activity/attendno' => 'Reject',
'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept',
'Invite' => 'Invite',
'Delete' => 'Delete',
'Undo' => 'Undo'
];
call_hooks('activity_decode_mapper',$acts);
@@ -927,7 +1182,6 @@ class Activity {
'http://activitystrea.ms/schema/1.0/photo' => 'Image',
'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon',
'http://activitystrea.ms/schema/1.0/event' => 'Event',
'http://activitystrea.ms/schema/1.0/wiki' => 'Document',
'http://purl.org/zot/activity/location' => 'Place',
'http://purl.org/zot/activity/chessgame' => 'Game',
'http://purl.org/zot/activity/tagterm' => 'zot:Tag',
@@ -935,7 +1189,12 @@ class Activity {
'http://purl.org/zot/activity/file' => 'zot:File',
'http://purl.org/zot/activity/mood' => 'zot:Mood',
'Invite' => 'Invite',
'Question' => 'Question'
'Question' => 'Question',
'Document' => 'Document',
'Audio' => 'Audio',
'Video' => 'Video',
'Delete' => 'Delete',
'Undo' => 'Undo'
];
call_hooks('activity_obj_decode_mapper',$objs);
@@ -963,7 +1222,6 @@ class Activity {
'http://activitystrea.ms/schema/1.0/photo' => 'Image',
'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon',
'http://activitystrea.ms/schema/1.0/event' => 'Event',
'http://activitystrea.ms/schema/1.0/wiki' => 'Document',
'http://purl.org/zot/activity/location' => 'Place',
'http://purl.org/zot/activity/chessgame' => 'Game',
'http://purl.org/zot/activity/tagterm' => 'zot:Tag',
@@ -971,7 +1229,11 @@ class Activity {
'http://purl.org/zot/activity/file' => 'zot:File',
'http://purl.org/zot/activity/mood' => 'zot:Mood',
'Invite' => 'Invite',
'Question' => 'Question'
'Question' => 'Question',
'Audio' => 'Audio',
'Video' => 'Video',
'Delete' => 'Delete',
'Undo' => 'Undo'
];
call_hooks('activity_obj_mapper',$objs);
@@ -1247,11 +1509,35 @@ class Activity {
$icon = $person_obj['icon'];
}
if(is_array($person_obj['url']) && array_key_exists('href', $person_obj['url']))
$profile = $person_obj['url']['href'];
else
$profile = $url;
$links = false;
$profile = false;
if (is_array($person_obj['url'])) {
if (! array_key_exists(0,$person_obj['url'])) {
$links = [ $person_obj['url'] ];
}
else {
$links = $person_obj['url'];
}
}
if ($links) {
foreach ($links as $link) {
if (array_key_exists('mediaType',$link) && $link['mediaType'] === 'text/html') {
$profile = $link['href'];
}
}
if (! $profile) {
$profile = $links[0]['href'];
}
}
elseif (isset($person_obj['url']) && is_string($person_obj['url'])) {
$profile = $person_obj['url'];
}
if (! $profile) {
$profile = $url;
}
$inbox = $person_obj['inbox'];
@@ -1283,6 +1569,7 @@ class Activity {
);
if(! $r) {
// create a new record
$r = xchan_store_lowlevel(
[
'xchan_hash' => $url,
@@ -1341,7 +1628,8 @@ class Activity {
'hubloc_host' => $hostname,
'hubloc_callback' => $inbox,
'hubloc_updated' => datetime_convert(),
'hubloc_primary' => 1
'hubloc_primary' => 1,
'hubloc_id_url' => $profile
]
);
}
@@ -1391,7 +1679,7 @@ class Activity {
// sort function width decreasing
static function as_vid_sort($a,$b) {
static function vid_sort($a,$b) {
if($a['width'] === $b['width'])
return 0;
return (($a['width'] > $b['width']) ? -1 : 1);
@@ -1455,7 +1743,25 @@ class Activity {
$s['aid'] = $channel['channel_account_id'];
$s['uid'] = $channel['channel_id'];
// Make sure we use the zot6 identity where applicable
$s['author_xchan'] = self::find_best_identity($s['author_xchan']);
$s['owner_xchan'] = self::find_best_identity($s['owner_xchan']);
if(!$s['author_xchan']) {
logger('No author: ' . print_r($act, true));
}
if(!$s['owner_xchan']) {
logger('No owner: ' . print_r($act, true));
}
if(!$s['author_xchan'] || !$s['owner_xchan'])
return;
$s['mid'] = urldecode($act->obj['id']);
$s['uuid'] = $act->obj['diaspora:guid'];
$s['plink'] = urldecode($act->obj['id']);
@@ -1561,7 +1867,7 @@ class Activity {
}
}
if($mps) {
usort($mps,'as_vid_sort');
usort($mps,[ __CLASS__, 'vid_sort' ]);
foreach($mps as $m) {
if(intval($m['width']) < 500) {
$s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
@@ -1636,8 +1942,11 @@ class Activity {
static function update_poll($item,$mid,$content) {
static function update_poll($item,$post) {
$multi = false;
$mid = $post['mid'];
$content = $post['title'];
if (! $item) {
return false;
}
@@ -1646,6 +1955,31 @@ class Activity {
if ($o && array_key_exists('anyOf',$o)) {
$multi = true;
}
$r = q("select mid, title from item where parent_mid = '%s' and author_xchan = '%s'",
dbesc($item['mid']),
dbesc($post['author_xchan'])
);
// prevent any duplicate votes by same author for oneOf and duplicate votes with same author and same answer for anyOf
if ($r) {
if ($multi) {
foreach ($r as $rv) {
if ($rv['title'] === $content && $rv['mid'] !== $mid) {
return false;
}
}
}
else {
foreach ($r as $rv) {
if ($rv['mid'] !== $mid) {
return false;
}
}
}
}
$answer_found = false;
$found = false;
if ($multi) {
@@ -1719,6 +2053,7 @@ class Activity {
self::actor_store($act->actor['id'],$act->actor);
$s['mid'] = $act->obj['id'];
$s['uuid'] = $act->obj['diaspora:guid'];
$s['parent_mid'] = $act->parent_id;
if($act->data['published']) {
@@ -1740,12 +2075,13 @@ class Activity {
$s['expires'] = datetime_convert('UTC','UTC',$act->obj['expires']);
}
if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'emojiReaction' ])) {
if(ActivityStreams::is_response_activity($act->type)) {
$response_activity = true;
$s['mid'] = $act->id;
$s['parent_mid'] = $act->obj['id'];
// $s['parent_mid'] = $act->obj['id'];
$s['uuid'] = $act->data['diaspora:guid'];
// over-ride the object timestamp with the activity
@@ -1811,12 +2147,10 @@ class Activity {
$s['edited'] = datetime_convert();
}
if($act->type === 'Tombstone' || $act->type === 'Delete' || ($act->type === 'Create' && $act->obj['type'] === 'Tombstone')) {
if(in_array($act->type, [ 'Delete', 'Undo', 'Tombstone' ]) || ($act->type === 'Create' && $act->obj['type'] === 'Tombstone')) {
$s['item_deleted'] = 1;
}
$s['obj_type'] = self::activity_obj_decode_mapper($act->obj['type']);
if($s['obj_type'] === ACTIVITY_OBJ_NOTE && $s['mid'] !== $s['parent_mid']) {
$s['obj_type'] = ACTIVITY_OBJ_COMMENT;
@@ -1888,17 +2222,22 @@ class Activity {
}
}
$a = self::decode_attachment($act->obj);
if($a) {
$s['attach'] = $a;
}
}
$a = self::decode_attachment($act->obj);
if ($a) {
$s['attach'] = $a;
}
$a = self::decode_iconfig($act->obj);
if ($a) {
$s['iconfig'] = $a;
}
if($act->obj['type'] === 'Note' && $s['attach']) {
$s['body'] .= self::bb_attach($s['attach'],$s['body']);
}
if ($act->obj['type'] === 'Question' && in_array($act->type,['Create','Update'])) {
if ($act->obj['endTime']) {
$s['comments_closed'] = datetime_convert('UTC','UTC', $act->obj['endTime']);
@@ -2002,9 +2341,7 @@ class Activity {
}
// avoid double images from hubzilla to zap/osada
if($act->obj['type'] === 'Image' && strpos($s['body'],'zrl=') === false) {
if($act->obj['type'] === 'Image') {
$ptr = null;
@@ -2018,10 +2355,11 @@ class Activity {
}
foreach($ptr as $vurl) {
if(strpos($s['body'],$vurl['href']) === false) {
$s['body'] .= '[zmg]' . $vurl['href'] . '[/zmg]' . "\n\n" . $s['body'];
$bb_imgs .= '[zmg]' . $vurl['href'] . '[/zmg]' . "\n\n";
break;
}
}
$s['body'] = $bb_imgs . $s['body'];
}
elseif(is_string($act->obj['url'])) {
if(strpos($s['body'],$act->obj['url']) === false) {
@@ -2102,8 +2440,13 @@ class Activity {
$s['plink'] = $s['mid'];
}
if ($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips)))
$s['item_private'] = 1;
// assume this is private unless specifically told otherwise.
$s['item_private'] = 1;
if ($act->recips && in_array(ACTIVITY_PUBLIC_INBOX, $act->recips)) {
$s['item_private'] = 0;
}
if (is_array($act->obj)) {
if (array_key_exists('directMessage',$act->obj) && intval($act->obj['directMessage'])) {
@@ -2157,17 +2500,23 @@ class Activity {
$item['aid'] = $channel['channel_account_id'];
$item['uid'] = $channel['channel_id'];
$s['uuid'] = '';
// Friendica sends the diaspora guid in a nonstandard field via AP
if($act->obj['diaspora:guid'])
$s['uuid'] = $act->obj['diaspora:guid'];
// Make sure we use the zot6 identity where applicable
if(! ( $item['author_xchan'] && $item['owner_xchan'])) {
logger('owner or author missing.');
return;
$item['author_xchan'] = self::find_best_identity($item['author_xchan']);
$item['owner_xchan'] = self::find_best_identity($item['owner_xchan']);
if(!$item['author_xchan']) {
logger('No author: ' . print_r($act, true));
}
if(!$item['owner_xchan']) {
logger('No owner: ' . print_r($act, true));
}
if(!$item['author_xchan'] || !$item['owner_xchan'])
return;
if($channel['channel_system']) {
if(! MessageFilter::evaluate($item,get_config('system','pubstream_incl'),get_config('system','pubstream_excl'))) {
logger('post is filtered');
@@ -2316,8 +2665,8 @@ class Activity {
switch($a->type) {
case 'Create':
case 'Update':
case 'Like':
case 'Dislike':
//case 'Like':
//case 'Dislike':
case 'Announce':
$item = self::decode_note($a);
break;
@@ -2363,6 +2712,7 @@ class Activity {
static public function fetch_and_store_replies($channel, $arr) {
logger('fetching replies');
logger(print_r($arr,true));
$p = [];
@@ -2607,7 +2957,7 @@ class Activity {
$s['parent_mid'] = $s['mid'];
$post_type = (($parent_item['resource_type'] === 'photo') ? t('photo') : t('status'));
$post_type = (($parent_item['resource_type'] === 'photo') ? t('photo') : t('post'));
$links = array(array('rel' => 'alternate','type' => 'text/html', 'href' => $parent_item['plink']));
$objtype = (($parent_item['resource_type'] === 'photo') ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE );
@@ -2797,7 +3147,7 @@ class Activity {
}
}
if (array_key_exists('source',$act) && array_key_exists('mediaType',$act['source'])) {
if (array_path_exists('source/mediaType',$act) && array_path_exists('source/content',$act)) {
if ($act['source']['mediaType'] === 'text/bbcode') {
$content['bbcode'] = purify_html($act['source']['content']);
}
@@ -2824,5 +3174,45 @@ class Activity {
return $content;
}
// Find either an Authorization: Bearer token or 'token' request variable
// in the current web request and return it
static function token_from_request() {
foreach ( [ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $s ) {
$auth = ((array_key_exists($s,$_SERVER) && strpos($_SERVER[$s],'Bearer ') === 0)
? str_replace('Bearer ', EMPTY_STR, $_SERVER[$s])
: EMPTY_STR
);
if ($auth) {
break;
}
}
if (! $auth) {
if (array_key_exists('token',$_REQUEST) && $_REQUEST['token']) {
$auth = $_REQUEST['token'];
}
}
return $auth;
}
static function find_best_identity($xchan) {
if(filter_var($xchan, FILTER_VALIDATE_URL)) {
$r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s' and hubloc_network in ('zot6', 'zot') and hubloc_deleted = 0",
dbesc($xchan)
);
if ($r) {
$r = Libzot::zot_record_preferred($r);
logger('find_best_identity: ' . $xchan . ' > ' . $r['hubloc_hash']);
return $r['hubloc_hash'];
}
}
return $xchan;
}
}

View File

@@ -146,15 +146,20 @@ class ActivityStreams {
*/
function collect_recips($base = '', $namespace = '') {
$x = [];
$fields = [ 'to', 'cc', 'bto', 'bcc', 'audience'];
foreach($fields as $f) {
$y = $this->get_compound_property($f, $base, $namespace);
if($y) {
$x = array_merge($x, $y);
if(! is_array($this->raw_recips))
if (! is_array($this->raw_recips)) {
$this->raw_recips = [];
}
$this->raw_recips[$f] = $x;
if (! is_array($y)) {
$y = [ $y ];
}
$this->raw_recips[$f] = $y;
$x = array_merge($x, $y);
}
}
// not yet ready for prime time
@@ -269,12 +274,19 @@ class ActivityStreams {
return self::fetch($url);
}
static function fetch($url,$channel = null) {
return Activity::fetch($url,$channel);
static function fetch($url, $channel = null) {
return Activity::fetch($url, $channel);
}
static function is_an_actor($s) {
return(in_array($s,[ 'Application','Group','Organization','Person','Service' ]));
return (in_array($s, [ 'Application','Group','Organization','Person','Service' ]));
}
static function is_response_activity($s) {
if (! $s) {
return false;
}
return (in_array($s, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject', 'emojiReaction', 'EmojiReaction', 'EmojiReact' ]));
}
/**
@@ -397,7 +409,6 @@ class ActivityStreams {
return $x;
}
static function is_as_request() {
$x = getBestSupportedMimeType([
@@ -410,5 +421,4 @@ class ActivityStreams {
}
}
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
require_once('include/plugin.php');
require_once('include/channel.php');
@@ -370,7 +372,6 @@ class Apps {
'OAuth2 Apps Manager' => t('OAuth2 Apps Manager'),
'PDL Editor' => t('PDL Editor'),
'Permission Categories' => t('Permission Categories'),
'Premium Channel' => t('Premium Channel'),
'Public Stream' => t('Public Stream'),
'My Chatrooms' => t('My Chatrooms'),
'Channel Export' => t('Channel Export')
@@ -563,7 +564,8 @@ class Apps {
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
'$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
'$navapps' => (($mode == 'nav') ? true : false),
'$order' => (($mode == 'nav-order') ? true : false),
'$order' => (($mode === 'nav-order' || $mode === 'nav-order-pinned') ? true : false),
'$mode' => $mode,
'$add' => t('Add to app-tray'),
'$remove' => t('Remove from app-tray'),
'$add_nav' => t('Pin to navbar'),
@@ -603,7 +605,7 @@ class Apps {
intval(TERM_OBJ_APP),
intval($r[0]['id'])
);
build_sync_packet($uid,array('app' => $r[0]));
Libsync::build_sync_packet($uid,array('app' => $r[0]));
}
}
}
@@ -669,7 +671,7 @@ class Apps {
);
}
if(! intval($x[0]['app_system'])) {
build_sync_packet($uid,array('app' => $x));
Libsync::build_sync_packet($uid,array('app' => $x));
}
}
else {
@@ -958,9 +960,6 @@ class Apps {
if($list) {
foreach($list as $li) {
$papp = self::app_encode($li);
if($menu !== 'nav_pinned_app' && strpos($papp['categories'],'nav_pinned_app') !== false)
continue;
$syslist[] = $papp;
}
}

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
/**
* @brief A class with chatroom related static methods.
*/
@@ -91,7 +93,7 @@ class Chatroom {
return $ret;
}
build_sync_packet($channel['channel_id'],array('chatroom' => $r));
Libsync::build_sync_packet($channel['channel_id'],array('chatroom' => $r));
q("delete from chatroom where cr_id = %d",
intval($r[0]['cr_id'])

312
Zotlabs/Lib/Connect.php Normal file
View File

@@ -0,0 +1,312 @@
<?php /** @file */
namespace Zotlabs\Lib;
use App;
use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Master;
class Connect {
/**
* Takes a $channel and a $url/handle and adds a new connection
*
* Returns array
* $return['success'] boolean true if successful
* $return['abook'] Address book entry joined with xchan if successful
* $return['message'] error text if success is false.
*
* This function does NOT send sync packets to clones. The caller is responsible for doing this
*/
static function connect($channel, $url, $sub_channel = false) {
$uid = $channel['channel_id'];
if (strpos($url,'@') === false && strpos($url,'/') === false) {
$url = $url . '@' . App::get_hostname();
}
$result = [ 'success' => false, 'message' => '' ];
$my_perms = false;
$protocol = '';
if (substr($url,0,1) === '[') {
$x = strpos($url,']');
if ($x) {
$protocol = substr($url,1,$x-1);
$url = substr($url,$x+1);
}
}
if (! check_siteallowed($url)) {
$result['message'] = t('Channel is blocked on this site.');
return $result;
}
if (! $url) {
$result['message'] = t('Channel location missing.');
return $result;
}
// check service class limits
$r = q("select count(*) as total from abook where abook_channel = %d and abook_self = 0 ",
intval($uid)
);
if ($r) {
$total_channels = $r[0]['total'];
}
if (! service_class_allows($uid,'total_channels',$total_channels)) {
$result['message'] = upgrade_message();
return $result;
}
$xchan_hash = '';
$sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : '');
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s') $sql_options ",
dbesc($url),
dbesc($url),
dbesc($url)
);
if ($r) {
// reset results to the best record or the first if we don't have the best
// note: this is a single record and not an array of results
$r = Libzot::zot_record_preferred($r,'xchan_network');
}
$singleton = false;
$d = false;
if (! $r) {
// not in cache - try discovery
$wf = discover_by_webbie($url,$protocol);
if (! $wf) {
$feeds = get_config('system','feed_contacts');
if (($feeds) && (in_array($protocol, [ '', 'feed', 'rss' ]))) {
$d = discover_by_url($url);
}
else {
$result['message'] = t('Remote channel or protocol unavailable.');
return $result;
}
}
}
if ($wf || $d) {
// something was discovered - find the record which was just created.
$r = q("select * from xchan where ( xchan_hash = '%s' or xchan_url = '%s' or xchan_addr = '%s' ) $sql_options",
dbesc(($wf) ? $wf : $url),
dbesc($url),
dbesc($url)
);
// convert to a single record (once again preferring a zot solution in the case of multiples)
if ($r) {
$r = Libzot::zot_record_preferred($r,'xchan_network');
}
}
// if discovery was a success or the channel was already cached we should have an xchan record in $r
if ($r) {
$xchan = $r;
$xchan_hash = $r['xchan_hash'];
$their_perms = EMPTY_STR;
}
// failure case
if (! $xchan_hash) {
$result['message'] = t('Channel discovery failed.');
logger('follow: ' . $result['message']);
return $result;
}
if (! check_channelallowed($xchan_hash)) {
$result['message'] = t('Channel is blocked on this site.');
logger('follow: ' . $result['message']);
return $result;
}
$allowed = ((in_array($xchan['xchan_network'],['rss','zot','zot6'])) ? 1 : 0);
$hookdata = ['channel_id' => $uid, 'follow_address' => $url, 'xchan' => $xchan, 'allowed' => $allowed, 'singleton' => 0];
call_hooks('follow_allow',$hookdata);
if(! $hookdata['allowed']) {
$result['message'] = t('Protocol disabled.');
return $result;
}
$singleton = intval($hookdata['singleton']);
// Now start processing the new connection
$aid = $channel['channel_account_id'];
$default_group = $channel['channel_default_group'];
if (in_array($xchan_hash, [$channel['channel_hash'], $channel['channel_portable_id']])) {
$result['message'] = t('Cannot connect to yourself.');
return $result;
}
if ($xchan['xchan_network'] === 'rss') {
// check service class feed limits
$t = q("select count(*) as total from abook where abook_account = %d and abook_feed = 1 ",
intval($aid)
);
if ($t) {
$total_feeds = $t[0]['total'];
}
if (! service_class_allows($uid,'total_feeds',$total_feeds)) {
$result['message'] = upgrade_message();
return $result;
}
// Always set these "remote" permissions for feeds since we cannot interact with them
// to negotiate a suitable permission response
set_abconfig($uid,$xchan_hash,'their_perms','view_stream',1);
set_abconfig($uid,$xchan_hash,'their_perms','republish',1);
}
$p = Permissions::connect_perms($uid);
// parent channels have unencumbered write permission
if ($sub_channel) {
$p['perms']['post_wall'] = 1;
$p['perms']['post_comments'] = 1;
$p['perms']['write_storage'] = 1;
$p['perms']['post_like'] = 1;
$p['perms']['delegate'] = 0;
$p['perms']['moderated'] = 0;
}
$my_perms = $p['perms'];
$profile_assign = get_pconfig($uid,'system','profile_assign','');
// See if we are already connected by virtue of having an abook record
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
if ($r) {
$abook_instance = $r[0]['abook_instance'];
// If they are on a non-nomadic network, add them to this location
if (($singleton) && strpos($abook_instance,z_root()) === false) {
if ($abook_instance) {
$abook_instance .= ',';
}
$abook_instance .= z_root();
$x = q("update abook set abook_instance = '%s', abook_not_here = 0 where abook_id = %d",
dbesc($abook_instance),
intval($r[0]['abook_id'])
);
}
// if they have a pending connection, we just followed them so approve the connection request
if (intval($r[0]['abook_pending'])) {
$x = q("update abook set abook_pending = 0 where abook_id = %d",
intval($r[0]['abook_id'])
);
}
}
else {
// create a new abook record
$closeness = get_pconfig($uid,'system','new_abook_closeness',80);
$r = abook_store_lowlevel(
[
'abook_account' => intval($aid),
'abook_channel' => intval($uid),
'abook_closeness' => intval($closeness),
'abook_xchan' => $xchan_hash,
'abook_profile' => $profile_assign,
'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0),
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_instance' => (($singleton) ? z_root() : '')
]
);
}
if (! $r) {
logger('abook creation failed');
$result['message'] = t('error saving data');
return $result;
}
// Set suitable permissions to the connection
if($my_perms) {
foreach($my_perms as $k => $v) {
set_abconfig($uid,$xchan_hash,'my_perms',$k,$v);
}
}
// fetch the entire record
$r = q("select abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
if ($r) {
$result['abook'] = array_shift($r);
Master::Summon([ 'Notifier', 'permission_create', $result['abook']['abook_id'] ]);
}
$arr = [ 'channel_id' => $uid, 'channel' => $channel, 'abook' => $result['abook'] ];
call_hooks('follow', $arr);
/** If there is a default group for this channel, add this connection to it */
if ($default_group) {
$g = AccessList::rec_byhash($uid,$default_group);
if ($g) {
AccessList::member_add($uid,'',$xchan_hash,$g['id']);
}
}
$result['success'] = true;
return $result;
}
}

View File

@@ -143,19 +143,26 @@ class Enotify {
$action = t('commented on');
if(array_key_exists('item',$params) && in_array($params['item']['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
if(array_key_exists('item',$params)) {
if(in_array($params['item']['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
logger('notification: not a visible activity. Ignoring.');
pop_lang();
return;
}
if(activity_match($params['verb'], ACTIVITY_LIKE))
$action = t('liked');
if(activity_match($params['verb'], ACTIVITY_DISLIKE))
$action = t('disliked');
if(! $always_show_in_notices || !($vnotify & VNOTIFY_LIKE)) {
logger('notification: not a visible activity. Ignoring.');
pop_lang();
return;
}
if(activity_match($params['verb'], ACTIVITY_LIKE))
$action = t('liked');
if(activity_match($params['verb'], ACTIVITY_DISLIKE))
$action = t('disliked');
if($params['item']['obj_type'] === 'Answer')
$action = t('voted on');
}
@@ -818,6 +825,9 @@ class Enotify {
$itemem_text = sprintf( t('repeated %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]');
}
if(in_array($item['obj_type'], ['Document', 'Video', 'Audio', 'Image'])) {
$itemem_text = t('shared a file with you');
}
}
$edit = false;
@@ -846,11 +856,11 @@ class Enotify {
'photo' => $item[$who]['xchan_photo_s'],
'when' => (($edit) ? datetime_convert('UTC', date_default_timezone_get(), $item['edited']) : datetime_convert('UTC', date_default_timezone_get(), $item['created'])),
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
'b64mid' => 'b64.' . base64url_encode($item['mid']),
'b64mid' => (($item['mid']) ? 'b64.' . base64url_encode($item['mid']) : ''),
//'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
'notify_id' => 'undefined',
'thread_top' => (($item['item_thread_top']) ? true : false),
'message' => bbcode(escape_tags($itemem_text)),
'body' => htmlentities(html2plain(bbcode($item['body']), 75, true), ENT_COMPAT, 'UTF-8', false),
// these are for the superblock addon
'hash' => $item[$who]['xchan_hash'],
'uid' => $item['uid'],
@@ -875,7 +885,6 @@ class Enotify {
$mid = basename($tt['link']);
$b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid));
$x = [
'notify_link' => z_root() . '/notify/view/' . $tt['id'],
'name' => $tt['xname'],
@@ -883,8 +892,8 @@ class Enotify {
'photo' => $tt['photo'],
'when' => datetime_convert('UTC', date_default_timezone_get(), $tt['created']),
'hclass' => (($tt['seen']) ? 'notify-seen' : 'notify-unseen'),
'b64mid' => (($tt['otype'] == 'item') ? $b64mid : 'undefined'),
'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : 'undefined'),
'b64mid' => (($tt['otype'] == 'item') ? $b64mid : ''),
'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : ''),
'message' => $message
];
@@ -957,8 +966,8 @@ class Enotify {
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => $when,
'hclass' => ('notify-unseen'),
'message' => t('posted an event')
'hclass' => (($today) ? 'notify-unseen bg-warning' : 'notify-unseen'),
'message' => t('created an event')
];
return $x;
@@ -970,8 +979,7 @@ class Enotify {
$x = [
'notify_link' => z_root() . '/admin/accounts',
'name' => $rr['account_email'],
'addr' => $rr['account_email'],
'url' => '',
//'addr' => $rr['account_email'],
'photo' => z_root() . '/' . get_default_profile_photo(48),
'when' => datetime_convert('UTC', date_default_timezone_get(),$rr['account_created']),
'hclass' => ('notify-unseen'),

View File

@@ -69,4 +69,4 @@ class JSalmon {
}
}
}

View File

@@ -150,6 +150,7 @@ class Libsync {
'account_id' => $channel['channel_account_id'],
'channel_id' => $channel['channel_id'],
'posturl' => $hub['hubloc_callback'],
'driver' => $hub['hubloc_network'],
'notify' => $n,
'msg' => EMPTY_STR
));
@@ -818,9 +819,9 @@ class Libsync {
}
if(intval($r[0]['hubloc_primary']) && (! $location['primary'])) {
$m = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id = %d",
$m = q("update hubloc set hubloc_primary = 0, hubloc_updated = '%s' where hubloc_id_url = '%s'",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
dbesc($r[0]['hubloc_id_url'])
);
$r[0]['hubloc_primary'] = intval($location['primary']);
hubloc_change_primary($r[0]);
@@ -847,18 +848,18 @@ class Libsync {
}
}
if(intval($r[0]['hubloc_deleted']) && (! intval($location['deleted']))) {
$n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id = %d",
$n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id_url = '%s'",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
dbesc($r[0]['hubloc_id_url'])
);
$what .= 'undelete_hub ';
$changed = true;
}
elseif((! intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) {
logger('deleting hubloc: ' . $r[0]['hubloc_addr']);
$n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
$n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id_url = '%s'",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
dbesc($r[0]['hubloc_id_url'])
);
$what .= 'delete_hub ';
$changed = true;
@@ -917,9 +918,9 @@ class Libsync {
foreach($xisting as $x) {
if(! array_key_exists('updated',$x)) {
logger('Deleting unreferenced hub location ' . $x['hubloc_addr']);
$r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
$r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id_url = '%s'",
dbesc(datetime_convert()),
intval($x['hubloc_id'])
dbesc($x['hubloc_id_url'])
);
$what .= 'removed_hub ';
$changed = true;
@@ -1022,4 +1023,4 @@ class Libsync {
}
}
}

View File

@@ -105,7 +105,7 @@ class Libzot {
$data = [
'type' => $type,
'encoding' => $encoding,
'sender' => $channel['channel_portable_id'],
'sender' => $channel['channel_hash'],
'site_id' => self::make_xchan_hash(z_root(), get_config('system','pubkey')),
'version' => System::get_zot_revision(),
];
@@ -316,16 +316,20 @@ class Libzot {
$x = self::import_xchan($record['data'], (($force) ? UPDATE_FLAGS_FORCED : UPDATE_FLAGS_UPDATED));
if(! $x['success'])
return false;
if($channel && $record['data']['permissions']) {
$permissions = explode(',',$record['data']['permissions']);
if($permissions && is_array($permissions)) {
$old_read_stream_perm = get_abconfig($channel['channel_id'],$x['hash'],'their_perms','view_stream');
foreach($permissions as $p) {
set_abconfig($channel['channel_id'],$x['hash'],'their_perms',$p,'1');
$permissions = Permissions::FilledPerms($permissions);
foreach($permissions as $k => $v) {
set_abconfig($channel['channel_id'],$x['hash'],'their_perms',$k,$v);
}
}
@@ -422,7 +426,7 @@ class Libzot {
[
'type' => NOTIFY_INTRO,
'from_xchan' => $x['hash'],
'to_xchan' => $channel['channel_portable_id'],
'to_xchan' => $channel['channel_hash'],
'link' => z_root() . '/connedit/' . $new_connection[0]['abook_id']
]
);
@@ -788,7 +792,7 @@ class Libzot {
// see if this is a channel clone that's hosted locally - which we treat different from other xchans/connections
$local = q("select channel_account_id, channel_id from channel where channel_portable_id = '%s' limit 1",
$local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1",
dbesc($xchan_hash)
);
if($local) {
@@ -1133,6 +1137,7 @@ class Libzot {
}
logger($AS->debug(),LOGGER_DATA);
}
@@ -1151,7 +1156,7 @@ class Libzot {
if($recip_arr) {
stringify_array_elms($recip_arr,true);
$recips = implode(',',$recip_arr);
$r = q("select channel_portable_id as hash from channel where channel_portable_id in ( " . $recips . " ) and channel_removed = 0 ");
$r = q("select channel_hash as hash from channel where channel_hash in ( " . $recips . " ) and channel_removed = 0 ");
}
if(! $r) {
@@ -1193,10 +1198,6 @@ class Libzot {
if(in_array($env['type'],['activity','response'])) {
$arr = Activity::decode_note($AS);
//logger($AS->debug());
$r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s' ",
dbesc($AS->actor['id'])
);
@@ -1207,6 +1208,10 @@ class Libzot {
$arr['author_xchan'] = $r['hubloc_hash'];
}
if (! $arr['author_xchan']) {
logger('No author!');
return;
}
$s = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
dbesc($env['sender'])
@@ -1368,12 +1373,12 @@ class Libzot {
$r = [];
$c = q("select channel_id, channel_portable_id from channel where channel_removed = 0");
$c = q("select channel_id, channel_hash from channel where channel_removed = 0");
if($c) {
foreach($c as $cc) {
if(perm_is_allowed($cc['channel_id'],$msg['sender'],$perm)) {
$r[] = $cc['channel_portable_id'];
$r[] = $cc['channel_hash'];
}
}
}
@@ -1381,7 +1386,7 @@ class Libzot {
if($include_sys) {
$sys = get_sys_channel();
if($sys)
$r[] = $sys['channel_portable_id'];
$r[] = $sys['channel_hash'];
}
@@ -1397,7 +1402,7 @@ class Libzot {
if($tag['type'] === 'Mention' && (strpos($tag['href'],z_root()) !== false)) {
$address = basename($tag['href']);
if($address) {
$z = q("select channel_portable_id as hash from channel where channel_address = '%s'
$z = q("select channel_hash as hash from channel where channel_address = '%s'
and channel_removed = 0 limit 1",
dbesc($address)
);
@@ -1418,7 +1423,7 @@ class Libzot {
$thread_parent = self::find_parent($msg,$act);
if($thread_parent) {
$z = q("select channel_portable_id as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ",
$z = q("select channel_hash as hash from channel left join item on channel.channel_id = item.uid where ( item.thr_parent = '%s' OR item.parent_mid = '%s' ) ",
dbesc($thread_parent),
dbesc($thread_parent)
);
@@ -1473,7 +1478,7 @@ class Libzot {
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
$channel = channelx_by_portid($d);
$channel = channelx_by_hash($d);
if (! $channel) {
$DR->update('recipient not found');
@@ -1488,13 +1493,14 @@ class Libzot {
// Try again using the delivery channel credentials.
// We will also need to re-parse the $item array,
// but preserve any values that were set during anonymous parsing.
$o = Activity::fetch($act->obj,$channel);
if($o) {
$act->obj = $o;
$arr = array_merge(Activity::decode_note($act),$arr);
}
else {
$DR->update('Incomplete or corrupt activity');
$result[] = $DR->get();
continue;
@@ -1510,7 +1516,7 @@ class Libzot {
* access checks.
*/
if($sender === $channel['channel_portable_id'] && $arr['author_xchan'] === $channel['channel_portable_id'] && $arr['mid'] === $arr['parent_mid']) {
if($sender === $channel['channel_hash'] && $arr['author_xchan'] === $channel['channel_hash'] && $arr['mid'] === $arr['parent_mid']) {
$DR->update('self delivery ignored');
$result[] = $DR->get();
continue;
@@ -1717,7 +1723,7 @@ class Libzot {
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
$item_id = self::delete_imported_item($sender,$arr,$channel['channel_id'],$relay);
$item_id = self::delete_imported_item($sender,$act,$arr,$channel['channel_id'],$relay);
$DR->update(($item_id) ? 'deleted' : 'delete_failed');
$result[] = $DR->get();
@@ -1731,11 +1737,15 @@ class Libzot {
continue;
}
// reactions such as like and dislike could have an mid with /activity/ in it.
// Check for both forms in order to prevent duplicates.
$r = q("select * from item where mid = '%s' and uid = %d limit 1",
$r = q("select * from item where mid in ('%s','%s') and uid = %d limit 1",
dbesc($arr['mid']),
dbesc(str_replace(z_root() . '/activity/', z_root() . '/item/', $arr['mid'])),
intval($channel['channel_id'])
);
if($r) {
// We already have this post.
$item_id = $r[0]['id'];
@@ -1827,7 +1837,7 @@ class Libzot {
$stored = (($item_result && $item_result['item']) ? $item_result['item'] : false);
if((is_array($stored)) && ($stored['id'] != $stored['parent'])
&& ($stored['author_xchan'] === $channel['channel_hash'] || $stored['author_xchan'] === $channel['channel_portable_id'])) {
&& ($stored['author_xchan'] === $channel['channel_hash'] || $stored['author_xchan'] === $channel['channel_hash'])) {
retain_item($stored['item']['parent']);
}
@@ -1949,9 +1959,9 @@ class Libzot {
}
logger('FOF Activity received: ' . print_r($arr,true), LOGGER_DATA, LOG_DEBUG);
logger('FOF Activity recipient: ' . $channel['channel_portable_id'], LOGGER_DATA, LOG_DEBUG);
logger('FOF Activity recipient: ' . $channel['channel_hash'], LOGGER_DATA, LOG_DEBUG);
$result = self::process_delivery($arr['owner_xchan'],$AS, $arr, [ $channel['channel_portable_id'] ],false,false,true);
$result = self::process_delivery($arr['owner_xchan'],$AS, $arr, [ $channel['channel_hash'] ],false,false,true);
if ($result) {
$ret = array_merge($ret, $result);
}
@@ -2096,7 +2106,7 @@ class Libzot {
* @return boolean|int post_id
*/
static function delete_imported_item($sender, $item, $uid, $relay) {
static function delete_imported_item($sender, $act, $item, $uid, $relay) {
logger('invoked', LOGGER_DEBUG);
@@ -2104,38 +2114,39 @@ class Libzot {
$item_found = false;
$post_id = 0;
if ($item['verb'] === 'Tombstone') {
// The id of the deleted thing is the item mid (activity id)
$mid = $item['mid'];
}
else {
// The id is the object id if the type is Undo or Delete
$mid = ((is_array($act->obj)) ? $act->obj['id'] : $act->obj);
}
// we may have stored either the object id or the activity id if it was a response activity (like, dislike, etc.)
$r = q("select * from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' )
and mid = '%s' and uid = %d limit 1",
and mid IN ('%s', '%s') and uid = %d limit 1",
dbesc($sender),
dbesc($sender),
dbesc($sender),
dbesc($item['mid']),
dbesc($mid),
dbesc(str_replace('/activity/','/item/',$mid)),
intval($uid)
);
if($r) {
$stored = $r[0];
if($stored['author_xchan'] === $sender || $stored['owner_xchan'] === $sender || $stored['source_xchan'] === $sender)
$ownership_valid = true;
// we proved ownership in the sql query
$ownership_valid = true;
$post_id = $stored['id'];
$item_found = true;
}
else {
// perhaps the item is still in transit and the delete notification got here before the actual item did. Store it with the deleted flag set.
// item_store() won't try to deliver any notifications or start delivery chains if this flag is set.
// This means we won't end up with potentially even more delivery threads trying to push this delete notification.
// But this will ensure that if the (undeleted) original post comes in at a later date, we'll reject it because it will have an older timestamp.
logger('delete received for non-existent item - storing item data.');
if($item['author_xchan'] === $sender || $item['owner_xchan'] === $sender || $item['source_xchan'] === $sender) {
$ownership_valid = true;
$item_result = item_store($item);
$post_id = $item_result['item_id'];
}
// this will fail with an ownership issue, so explain the real reason
logger('delete received for non-existent item or not owned by sender - ignoring.');
}
if($ownership_valid === false) {
@@ -2207,7 +2218,7 @@ class Libzot {
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
$r = q("select * from channel where channel_portable_id = '%s' limit 1",
$r = q("select * from channel where channel_hash = '%s' limit 1",
dbesc($d['hash'])
);
@@ -2362,7 +2373,7 @@ class Libzot {
$loc = $locations[0];
$r = q("select * from channel where channel_portable_id = '%s' limit 1",
$r = q("select * from channel where channel_hash = '%s' limit 1",
dbesc($sender_hash)
);
@@ -2370,7 +2381,7 @@ class Libzot {
return;
if($loc['url'] !== z_root()) {
$x = q("update channel set channel_moved = '%s' where channel_portable_id = '%s' limit 1",
$x = q("update channel set channel_moved = '%s' where channel_hash = '%s' limit 1",
dbesc($loc['url']),
dbesc($sender_hash)
);
@@ -2404,7 +2415,7 @@ class Libzot {
static function encode_locations($channel) {
$ret = [];
$x = self::get_hublocs($channel['channel_portable_id']);
$x = self::get_hublocs($channel['channel_hash']);
if($x && count($x)) {
foreach($x as $hub) {
@@ -2752,13 +2763,13 @@ class Libzot {
$r = null;
if(strlen($zhash)) {
$r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
where channel_portable_id = '%s' limit 1",
$r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_hash = '%s' limit 1",
dbesc($zhash)
);
}
elseif(strlen($zguid) && strlen($zguid_sig)) {
$r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
$r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($zguid),
dbesc($zguid_sig)
@@ -2766,7 +2777,7 @@ class Libzot {
}
elseif(strlen($zaddr)) {
if(strpos($zaddr,'[system]') === false) { /* normal address lookup */
$r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
$r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where ( channel_address = '%s' or xchan_addr = '%s' ) limit 1",
dbesc($zaddr),
dbesc($zaddr)
@@ -2786,10 +2797,10 @@ class Libzot {
*
*/
$r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
$r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_system = 1 order by channel_id limit 1");
if(! $r) {
$r = q("select channel.*, xchan.* from channel left join xchan on channel_portable_id = xchan_hash
$r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash
where channel_removed = 0 order by channel_id limit 1");
}
}
@@ -2908,7 +2919,7 @@ class Libzot {
];
$ret['channel_role'] = get_pconfig($e['channel_id'],'system','permissions_role','custom');
$ret['protocols'] = [ 'zot', 'zot6' ];
$ret['protocols'] = [ 'zot6', 'zot' ];
$ret['searchable'] = $searchable;
$ret['adult_content'] = $adult_channel;
$ret['public_forum'] = $public_forum;

View File

@@ -3,6 +3,8 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Zotfinger;
use Zotlabs\Lib\Webfinger;
require_once('include/permissions.php');
@@ -307,9 +309,9 @@ class Libzotdir {
if ($ud['ud_addr'] && (! ($ud['ud_flags'] & UPDATE_FLAGS_DELETED))) {
$success = false;
$href = \Zotlabs\Lib\Webfinger::zot_url(punify($ud['ud_addr']));
$href = Webfinger::zot_url(punify($ud['ud_addr']));
if($href) {
$zf = \Zotlabs\Lib\Zotfinger::exec($href);
$zf = Zotfinger::exec($href);
}
if(is_array($zf) && array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $href && intval($zf['signature']['header_valid'])) {
$xc = Libzot::import_xchan($zf['data'], 0, $ud);
@@ -339,7 +341,7 @@ class Libzotdir {
logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG);
$p = q("select channel.channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
$p = q("select channel.channel_hash, channel_address, channel_timezone, channel_portable_id, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
intval($uid)
);
@@ -348,6 +350,7 @@ class Libzotdir {
if ($p) {
$hash = $p[0]['channel_hash'];
$legacy_hash = $p[0]['channel_portable_id'];
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
@@ -381,14 +384,15 @@ class Libzotdir {
logger('hidden: ' . $hidden);
$r = q("select xchan_hidden from xchan where xchan_hash = '%s' limit 1",
$r = q("select xchan_hidden from xchan where xchan_hash = '%s'",
dbesc($p[0]['channel_hash'])
);
if(intval($r[0]['xchan_hidden']) != $hidden) {
$r = q("update xchan set xchan_hidden = %d where xchan_hash = '%s'",
$r = q("update xchan set xchan_hidden = %d where xchan_hash in ('%s', '%s')",
intval($hidden),
dbesc($p[0]['channel_hash'])
dbesc($hash),
dbesc($legacy_hash)
);
}
@@ -402,11 +406,13 @@ class Libzotdir {
}
else {
// they may have made it private
$r = q("delete from xprof where xprof_hash = '%s'",
dbesc($hash)
q("delete from xprof where xprof_hash in ('%s', '%s')",
dbesc($hash),
dbesc($legacy_hash)
);
$r = q("delete from xtag where xtag_hash = '%s'",
dbesc($hash)
q("delete from xtag where xtag_hash in ('%s', '%s')",
dbesc($hash),
dbesc($legacy_hash)
);
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Libsync;
define ( 'NWIKI_ITEM_RESOURCE_TYPE', 'nwiki' );
class NativeWiki {
@@ -71,7 +73,7 @@ class NativeWiki {
$arr['item_thread_top'] = 1;
$arr['item_private'] = intval($acl->is_private());
$arr['verb'] = ACTIVITY_CREATE;
$arr['obj_type'] = ACTIVITY_OBJ_WIKI;
$arr['obj_type'] = 'Document';
$arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
$arr['public_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_wiki'),true);
@@ -178,7 +180,7 @@ class NativeWiki {
foreach($sync_item as $w) {
$pkt[] = encode_item($w,true);
}
build_sync_packet($uid,array('wiki' => $pkt));
Libsync::build_sync_packet($uid,array('wiki' => $pkt));
}
}
}

View File

@@ -530,8 +530,11 @@ class NativeWikiPage {
foreach ($match[1] as $m) {
// TODO: Why do we need to double urlencode for this to work?
//$pageURLs[] = urlencode(urlencode(escape_tags($m)));
$pageURLs[] = Zlib\NativeWiki::name_encode(escape_tags($m));
$pages[] = $m;
$titleUri = explode('|',$m);
$page = $titleUri[0] ?? '';
$title = $titleUri[1] ?? $page;
$pageURLs[] = Zlib\NativeWiki::name_encode(escape_tags($page));
$pages[] = $title;
}
$idx = 0;
while(strpos($s,'[[') !== false) {

View File

@@ -116,7 +116,7 @@ class Queue {
dbesc($arr['hash']),
intval($arr['account_id']),
intval($arr['channel_id']),
dbesc(($arr['driver']) ? $arr['driver'] : 'zot'),
dbesc(($arr['driver']) ? $arr['driver'] : 'zot6'),
dbesc($arr['posturl']),
intval(1),
intval(($arr['priority']) ? $arr['priority'] : 0),

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Lib;
use Zotlabs\Lib\Activity;
class Share {
@@ -54,7 +55,7 @@ class Share {
if(! $this->item)
return $obj;
$obj['asld'] = $this->item['mid'];
$obj['asld'] = Activity::fetch_item( [ 'id' => $this->item['mid'] ] );
$obj['type'] = $this->item['obj_type'];
$obj['id'] = $this->item['mid'];
$obj['content'] = $this->item['body'];
@@ -127,7 +128,7 @@ class Share {
"' profile='" . $this->item['author']['xchan_url'] .
"' avatar='" . $this->item['author']['xchan_photo_s'] .
"' link='" . $this->item['plink'] .
"' auth='" . (($this->item['author']['network'] === 'zot') ? 'true' : 'false') .
"' auth='" . ((in_array($this->item['author']['xchan_network'], ['zot6', 'zot'])) ? 'true' : 'false') .
"' posted='" . $this->item['created'] .
"' message_id='" . $this->item['mid'] .
"']";

View File

@@ -113,7 +113,7 @@ class ThreadItem {
if(intval($item['item_private']) && ($item['owner']['xchan_network'] === 'activitypub')) {
$recips = get_iconfig($item['parent'], 'activitypub', 'recips');
if(! in_array($observer['xchan_url'], $recips['to']))
if(! is_array($recips['to']) || ! in_array($observer['xchan_url'], $recips['to']))
$privacy_warning = true;
}
@@ -150,9 +150,11 @@ class ThreadItem {
$edpost = false;
if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
if($observer && $observer['xchan_hash']
&& ($observer['xchan_hash'] == $this->get_data_value('author_xchan')
|| $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
|| $this->get_data_value('uid') == local_channel())
|| $observer['xchan_hash'] == $this->get_data_value('source_xchan')
|| $this->get_data_value('uid') == local_channel()))
$dropping = true;
@@ -285,12 +287,16 @@ class ThreadItem {
$settings = '';
$tagger = [];
// FIXME - check this permission
if($conv->get_profile_owner() == local_channel()) {
/* disable until we agree on how to implemnt this in zot6/activitypub
$tagger = array(
'tagit' => t("Add Tag"),
'classtagger' => "",
);
*/
$settings = t('Conversation Tools');
}
@@ -426,6 +432,7 @@ class ThreadItem {
'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
'lock' => $lock,
'delayed' => $item['item_delayed'],
'privacy_warning' => $privacy_warning,
'verified' => $verified,
'unverified' => $unverified,
@@ -460,7 +467,7 @@ class ThreadItem {
'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
'filer' => ((feature_enabled($conv->get_profile_owner(),'filing') && ($item['item_type'] == ITEM_TYPE_POST)) ? $filer : ''),
'pinned' => ($pinned ? t('Pinned post') : ''),
'pinnable' => (($this->is_toplevel() && local_channel() && $item['owner_xchan'] == $observer['xchan_hash'] && $allowed_type && $item['item_private'] == 0) ? '1' : ''),
'pinnable' => (($this->is_toplevel() && local_channel() && $item['owner_xchan'] == $observer['xchan_hash'] && $allowed_type && $item['item_private'] == 0 && $item['item_delayed'] == 0) ? '1' : ''),
'pinme' => ($pinned ? t('Unpin from the top') : t('Pin to the top')),
'bookmark' => (($conv->get_profile_owner() == local_channel() && local_channel() && $has_bookmarks) ? t('Save Bookmarks') : ''),
'addtocal' => (($has_event) ? t('Add to Calendar') : ''),
@@ -488,7 +495,7 @@ class ThreadItem {
'modal_dismiss' => t('Close'),
'showlike' => $showlike,
'showdislike' => $showdislike,
'comment' => $this->get_comment_box($indent),
'comment' => ($item['item_delayed'] ? '' : $this->get_comment_box($indent)),
'previewing' => ($conv->is_preview() ? true : false ),
'preview_lbl' => t('This is an unsaved preview'),
'wait' => t('Please wait'),

View File

@@ -23,7 +23,7 @@ class ThreadStream {
private $preview = false;
private $prepared_item = '';
public $reload = '';
private $cipher = 'aes256';
private $cipher = 'AES-128-CCM';
// $prepared_item is for use by alternate conversation structures such as photos
// wherein we've already prepared a top level item which doesn't look anything like

View File

@@ -106,4 +106,4 @@ class Webfinger {
}
}

View File

@@ -60,4 +60,4 @@ class Zotfinger {
}
}

View File

@@ -21,7 +21,6 @@ class Activity extends Controller {
if (Libzot::is_zot_request()) {
$item_id = argv(1);
if (! $item_id)
http_status_exit(404, 'Not found');
@@ -170,6 +169,101 @@ class Activity extends Controller {
}
if(ActivityStreams::is_as_request()) {
$item_id = argv(1);
if (! $item_id) {
return;
}
$ob_authorise = false;
$item_uid = 0;
$bear = ZlibActivity::token_from_request();
if ($bear) {
logger('bear: ' . $bear, LOGGER_DEBUG);
$t = q("select item.uid, iconfig.v from iconfig left join item on iid = item.id where cat = 'ocap' and item.uuid = '%s'",
dbesc($item_id)
);
if ($t) {
foreach ($t as $token) {
if ($token['v'] === $bear) {
$ob_authorize = true;
$item_uid = $token['uid'];
break;
}
}
}
}
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0
and item.item_delayed = 0 and item.item_blocked = 0 ";
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
}
// if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking
// Give ocap tokens priority
if ($ob_authorize) {
$sql_extra = " and item.uid = " . intval($token['uid']) . " ";
}
else {
$sql_extra = item_permissions_sql(0);
}
$r = q("select * from item where uuid = '%s' $item_normal $sql_extra limit 1",
dbesc($item_id)
);
if (! $r) {
$r = q("select * from item where uuid = '%s' $item_normal limit 1",
dbesc($item_id)
);
if($r) {
http_status_exit(403, 'Forbidden');
}
http_status_exit(404, 'Not found');
}
xchan_query($r,true);
$items = fetch_post_tags($r,false);
$channel = channelx_by_n($items[0]['uid']);
$x = array_merge( ['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV
]], ZlibActivity::encode_activity($items[0],true));
$headers = [];
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
$x['signature'] = LDSignatures::sign($x,$channel);
$ret = json_encode($x, JSON_UNESCAPED_SLASHES);
$headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T');
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'];
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel));
HTTPSig::set_headers($h);
echo $ret;
killme();
}
goaway(z_root() . '/item/' . argv(1));
}
}

View File

@@ -18,7 +18,7 @@ class Addons {
@include_once("addon/" . argv(2) . "/" . argv(2) . ".php");
if(function_exists(argv(2).'_plugin_admin_post')) {
$func = argv(2) . '_plugin_admin_post';
$func($a);
$func();
}
goaway(z_root() . '/admin/addons/' . argv(2) );
@@ -332,7 +332,7 @@ class Addons {
@require_once("addon/$plugin/$plugin.php");
if(function_exists($plugin.'_plugin_admin')) {
$func = $plugin.'_plugin_admin';
$func($a, $admin_form);
$func($admin_form);
}
}

View File

@@ -34,9 +34,9 @@ class Apporder extends \Zotlabs\Web\Controller {
foreach($syslist as $app) {
if($l === 'nav_pinned_app') {
$navbar_apps[] = Zlib\Apps::app_render($app,'nav-order');
$navbar_apps[] = Zlib\Apps::app_render($app,'nav-order-pinned');
}
elseif(strpos($app['categories'],'nav_pinned_app') === false) {
else {
$nav_apps[] = Zlib\Apps::app_render($app,'nav-order');
}
}

View File

@@ -29,7 +29,10 @@ class Apschema extends \Zotlabs\Web\Controller {
'emojiReaction' => 'zot:emojiReaction',
'expires' => 'zot:expires',
'directMessage' => 'zot:directMessage',
'schema' => 'http://schema.org#',
'PropertyValue' => 'schema:PropertyValue',
'value' => 'schema:value',
'magicEnv' => [
'@id' => 'zot:magicEnv',
'@type' => '@id'

View File

@@ -149,7 +149,7 @@ class Articles extends Controller {
}
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));

View File

@@ -145,7 +145,7 @@ class Cards extends Controller {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));

View File

@@ -819,7 +819,7 @@ class Cdav extends Controller {
return;
}
$id = explode(':', $_REQUEST['target'])[0];
$id = explode(':', $_REQUEST['target']);
$ext = 'ics';
$table = 'calendarobjects';
$column = 'calendarid';

View File

@@ -239,8 +239,12 @@ class Channel extends Controller {
/**
* Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
*/
$item_normal = item_normal();
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0
and item.item_unpublished = 0 and item.item_pending_remove = 0
and item.item_blocked = 0 ";
if (! $is_owner)
$item_normal .= "and item.item_delayed = 0 ";
$item_normal_update = item_normal_update();
$sql_extra = item_permissions_sql(App::$profile['profile_uid']);
@@ -330,7 +334,7 @@ class Channel extends Controller {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
if($noscript_content || $load) {
@@ -438,44 +442,12 @@ class Channel extends Controller {
}
$update_unseen = '';
if($page_mode === 'list') {
/**
* in "list mode", only mark the parent item and any like activities as "seen".
* We won't distinguish between comment likes and post likes. The important thing
* is that the number of unseen comments will be accurate. The SQL to separate the
* comment likes could also get somewhat hairy.
*/
if($parents_str) {
$update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )";
$update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) ";
}
}
else {
if($parents_str) {
$update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )";
}
}
if($is_owner && $update_unseen) {
$x = [ 'channel_id' => local_channel(), 'update' => 'unset' ];
call_hooks('update_unseen',$x);
if($x['update'] === 'unset' || intval($x['update'])) {
$r = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 and item_wall = 1 AND uid = %d $update_unseen",
intval(local_channel())
);
}
}
// Add pinned content
if(! x($_REQUEST,'mid') && ! $search) {
$pinned = new \Zotlabs\Widget\Pinned;
$r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]);
$o .= $r['html'];
}
$pinned = new \Zotlabs\Widget\Pinned;
$r = $pinned->widget(intval(App::$profile['profile_uid']), [ITEM_TYPE_POST]);
$o .= $r['html'];
}
$mode = (($search) ? 'search' : 'channel');

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
require_once('include/conversation.php');
require_once('include/bbcode.php');
require_once('include/datetime.php');
@@ -16,7 +18,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
if(! local_channel())
return;
$event_id = ((x($_POST,'event_id')) ? intval($_POST['event_id']) : 0);
$event_hash = ((x($_POST,'event_hash')) ? $_POST['event_hash'] : '');
@@ -27,15 +29,19 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
if(($xchan) && ($xchan !== get_observer_hash()))
return;
$categories = escape_tags(trim($_POST['categories']));
// allday events have adjust = 0, normal events have adjust = 1
$adjust = intval($_POST['adjust']);
$start = datetime_convert((($adjust) ? $tz : 'UTC'), 'UTC', escape_tags($_REQUEST['dtstart']));
$finish = datetime_convert((($adjust) ? $tz : 'UTC'), 'UTC', escape_tags($_REQUEST['dtend']));
$timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : '');
$tz = (($timezone) ? $timezone : date_default_timezone_get());
$categories = escape_tags(trim($_POST['categories']));
$adjust = intval($_POST['adjust']);
$start = datetime_convert('UTC', 'UTC', escape_tags($_REQUEST['dtstart']));
$finish = datetime_convert('UTC', 'UTC', escape_tags($_REQUEST['dtend']));
if(! $adjust)
$tz = 'UTC';
$summary = escape_tags(trim($_POST['summary']));
$desc = escape_tags(trim($_POST['desc']));
@@ -184,7 +190,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
intval($channel['channel_id'])
);
if($z) {
build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z));
Libsync::build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z));
}
}
}
@@ -337,21 +343,16 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
}
$events = [];
if($r) {
foreach($r as $rr) {
$tz = get_iconfig($rr, 'event', 'timezone');
if(! $tz)
$tz = 'UTC';
$start = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c'));
$start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c'));
if ($rr['nofinish']){
$end = null;
} else {
$end = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
$end = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c'));
}
$catsenabled = feature_enabled(local_channel(),'categories');
@@ -371,6 +372,11 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
$drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'','');
$tz = get_iconfig($rr, 'event', 'timezone');
if(! $tz)
$tz = 'UTC';
$events[] = array(
'calendar_id' => 'channel_calendar',
'rw' => true,
@@ -426,7 +432,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
if($r) {
$sync_event['event_deleted'] = 1;
build_sync_packet(0,array('event' => array($sync_event)));
Libsync::build_sync_packet(0,array('event' => array($sync_event)));
$i = q("select * from item where resource_type = 'event' and resource_id = '%s' and uid = %d",
dbesc($event_id),
@@ -475,7 +481,7 @@ class Channel_calendar extends \Zotlabs\Web\Controller {
if($ii) {
xchan_query($ii);
$sync_item = fetch_post_tags($ii);
build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true))));
Libsync::build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true))));
}
if($complex) {

View File

@@ -1,31 +1,35 @@
<?php
namespace Zotlabs\Module;
require_once('include/zot.php');
use App;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Webfinger;
use Zotlabs\Lib\Zotfinger;
class Chanview extends \Zotlabs\Web\Controller {
function get() {
$observer = \App::get_observer();
$observer = App::get_observer();
$xchan = null;
$r = null;
if($_REQUEST['hash']) {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
$r = q("select * from xchan where xchan_hash = '%s'",
dbesc($_REQUEST['hash'])
);
}
if($_REQUEST['address']) {
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
$r = q("select * from xchan where xchan_addr = '%s'",
dbesc(punify($_REQUEST['address']))
);
}
elseif(local_channel() && intval($_REQUEST['cid'])) {
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
WHERE abook_channel = %d and abook_id = %d",
intval(local_channel()),
intval($_REQUEST['cid'])
);
@@ -35,12 +39,12 @@ class Chanview extends \Zotlabs\Web\Controller {
// if somebody re-installed they will have more than one xchan, use the most recent name date as this is
// the most useful consistently ascending table item we have.
$r = q("select * from xchan where xchan_url = '%s' order by xchan_name_date desc limit 1",
$r = q("select * from xchan where xchan_url = '%s' order by xchan_name_date desc",
dbesc($_REQUEST['url'])
);
}
if($r) {
\App::$poi = $r[0];
App::$poi = Libzot::zot_record_preferred($r, 'xchan_network');
}
@@ -49,74 +53,63 @@ class Chanview extends \Zotlabs\Web\Controller {
// address, we can and should try to import it. If it's just a hash, we can't continue, but we
// probably wouldn't have a hash if we don't already have an xchan for this channel.
if(! \App::$poi) {
if(! App::$poi) {
logger('mod_chanview: fallback');
// This is hackish - construct a zot address from the url
if($_REQUEST['url']) {
if(preg_match('/https?\:\/\/(.*?)(\/channel\/|\/profile\/)(.*?)$/ism',$_REQUEST['url'],$matches)) {
$_REQUEST['address'] = $matches[3] . '@' . $matches[1];
if($_REQUEST['address']) {
$href = Webfinger::zot_url(punify($_REQUEST['address']));
if($href) {
$_REQUEST['url'] = $href;
}
logger('mod_chanview: constructed address ' . print_r($matches,true));
}
$r = null;
if($_REQUEST['address']) {
$j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null);
if($j['success']) {
import_xchan($j);
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
dbesc($_REQUEST['address'])
if($_REQUEST['url']) {
$zf = Zotfinger::exec($_REQUEST['url'], null);
if(array_path_exists('signature/signer',$zf) && $zf['signature']['signer'] === $_REQUEST['url'] && intval($zf['signature']['header_valid'])) {
Libzot::import_xchan($j);
$r = q("select * from xchan where xchan_url = '%s'",
dbesc($_REQUEST['url'])
);
if($r) {
\App::$poi = $r[0];
App::$poi = Libzot::zot_record_preferred($r, 'xchan_network');
}
}
if(! $r) {
if(discover_by_webbie($_REQUEST['address'])) {
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
dbesc($_REQUEST['address'])
if(discover_by_webbie($_REQUEST['url'])) {
$r = q("select * from xchan where xchan_url = '%s'",
dbesc($_REQUEST['url'])
);
if($r) {
\App::$poi = $r[0];
App::$poi = Libzot::zot_record_preferred($r, 'xchan_network');
}
}
}
}
}
if(! \App::$poi) {
// We don't know who this is, and we can't figure it out from the URL
// On the plus side, there's a good chance we know somebody else at that
// hub so sending them there with a Zid will probably work anyway.
$url = ($_REQUEST['url']);
if(! $url) {
notice( t('Channel not found.') . EOL);
return;
}
if($observer)
$url = zid($url);
if(! App::$poi) {
notice( t('Channel not found.') . EOL);
return;
}
$is_zot = false;
$connected = false;
if (\App::$poi) {
$url = \App::$poi['xchan_url'];
if(in_array(\App::$poi['xchan_network'], ['zot', 'zot6'])) {
$is_zot = true;
}
if(local_channel()) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
intval(local_channel()),
dbesc(\App::$poi['xchan_hash'])
);
if($c)
$connected = true;
}
$url = App::$poi['xchan_url'];
if(in_array(App::$poi['xchan_network'], ['zot', 'zot6'])) {
$is_zot = true;
}
if(local_channel()) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
intval(local_channel()),
dbesc(App::$poi['xchan_hash'])
);
if($c)
$connected = true;
}
// We will load the chanview template if it's a foreign network,

View File

@@ -7,9 +7,7 @@ use Zotlabs\Lib\Apps;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Chatroom;
use Zotlabs\Access\AccessList;
use Zotlabs\Lib\Libsync;
require_once('include/bookmarks.php');
@@ -80,7 +78,7 @@ class Chat extends Controller {
intval(local_channel())
);
build_sync_packet(0, array('chatroom' => $x));
Libsync::build_sync_packet(0, array('chatroom' => $x));
if($x)
goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']);
@@ -199,7 +197,7 @@ class Chat extends Controller {
$cipher = get_pconfig(local_channel(),'system','default_cipher');
if(! $cipher)
$cipher = 'aes256';
$cipher = 'AES-128-CCM';
$o = replace_macros(get_markup_template('chat.tpl'),array(

View File

@@ -28,10 +28,6 @@ class Connect extends Controller {
$channel_id = App::$data['channel']['channel_id'];
if(! Apps::system_app_installed($channel_id, 'Premium Channel')) {
return;
}
profile_load($which,'');
}
@@ -42,10 +38,6 @@ class Connect extends Controller {
$channel_id = App::$data['channel']['channel_id'];
if(! Apps::system_app_installed($channel_id, 'Premium Channel')) {
return;
}
$edit = ((local_channel() && (local_channel() == $channel_id)) ? true : false);
if($edit) {
@@ -97,15 +89,6 @@ class Connect extends Controller {
$channel_id = App::$data['channel']['channel_id'];
if(! Apps::system_app_installed($channel_id, 'Premium Channel')) {
//Do not display any associated widgets at this point
App::$pdl = '';
$o = '<b>' . t('Premium Channel App') . ' (' . t('Not Installed') . '):</b><br>';
$o .= t('Allows you to set restrictions and terms on those that connect with your channel');
return $o;
}
$edit = ((local_channel() && (local_channel() == $channel_id)) ? true : false);
$text = get_pconfig($channel_id,'system','selltext');

View File

@@ -34,7 +34,7 @@ class Connections extends \Zotlabs\Web\Controller {
}
nav_set_selected('Connections');
$active = false;
$blocked = false;
$hidden = false;

View File

@@ -7,8 +7,16 @@ namespace Zotlabs\Module;
*
*/
use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Libsync;
use Zotlabs\Daemon\Master;
use Zotlabs\Web\Controller;
use Zotlabs\Access\Permissions;
use Zotlabs\Access\PermissionLimits;
use Zotlabs\Web\HTTPHeaders;
use Zotlabs\Lib\Permcat;
require_once('include/socgraph.php');
require_once('include/selectors.php');
@@ -16,7 +24,7 @@ require_once('include/group.php');
require_once('include/photos.php');
class Connedit extends \Zotlabs\Web\Controller {
class Connedit extends Controller {
/* @brief Initialize the connection-editor
*
@@ -36,12 +44,12 @@ class Connedit extends \Zotlabs\Web\Controller {
intval(argv(1))
);
if($r) {
\App::$poi = array_shift($r);
App::$poi = array_shift($r);
}
}
$channel = \App::get_channel();
$channel = App::get_channel();
if($channel)
head_set_icon($channel['xchan_photo_s']);
@@ -61,7 +69,7 @@ class Connedit extends \Zotlabs\Web\Controller {
if(! $contact_id)
return;
$channel = \App::get_channel();
$channel = App::get_channel();
// TODO if configured for hassle-free permissions, we'll post the form with ajax as soon as the
// connection enable is toggled to a special autopost url and set permissions immediately, leaving
@@ -140,7 +148,7 @@ class Connedit extends \Zotlabs\Web\Controller {
$rating_text = trim(escape_tags($_REQUEST['rating_text']));
$all_perms = \Zotlabs\Access\Permissions::Perms();
$all_perms = Permissions::Perms();
if($all_perms) {
foreach($all_perms as $perm => $desc) {
@@ -212,7 +220,7 @@ class Connedit extends \Zotlabs\Web\Controller {
$record = $z[0]['xlink_id'];
}
if($record) {
\Zotlabs\Daemon\Master::Summon(array('Ratenotif','rating',$record));
Master::Summon(array('Ratenotif','rating',$record));
}
}
@@ -227,7 +235,7 @@ class Connedit extends \Zotlabs\Web\Controller {
// request. The workaround is to approve the connection, then go back and
// adjust permissions as desired.
$p = \Zotlabs\Access\Permissions::connect_perms(local_channel());
$p = Permissions::connect_perms(local_channel());
$my_perms = $p['perms'];
if($my_perms) {
foreach($my_perms as $k => $v) {
@@ -257,12 +265,12 @@ class Connedit extends \Zotlabs\Web\Controller {
else
notice( t('Failed to update connection record.') . EOL);
if(! intval(\App::$poi['abook_self'])) {
if(! intval(App::$poi['abook_self'])) {
if($new_friend) {
\Zotlabs\Daemon\Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] );
Master::Summon( [ 'Notifier', 'permission_accept', $contact_id ] );
}
\Zotlabs\Daemon\Master::Summon( [
Master::Summon( [
'Notifier',
(($new_friend) ? 'permission_create' : 'permission_update'),
$contact_id
@@ -275,7 +283,7 @@ class Connedit extends \Zotlabs\Web\Controller {
require_once('include/group.php');
$g = group_rec_byhash(local_channel(),$default_group);
if($g)
group_add_member(local_channel(),'',\App::$poi['abook_xchan'],$g['id']);
group_add_member(local_channel(),'',App::$poi['abook_xchan'],$g['id']);
}
// Check if settings permit ("post new friend activity" is allowed, and
@@ -299,19 +307,19 @@ class Connedit extends \Zotlabs\Web\Controller {
$xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0);
$obj = array(
'type' => ACTIVITY_OBJ_PERSON,
'title' => \App::$poi['xchan_name'],
'id' => \App::$poi['xchan_hash'],
'title' => App::$poi['xchan_name'],
'id' => App::$poi['xchan_hash'],
'link' => array(
array('rel' => 'alternate', 'type' => 'text/html', 'href' => \App::$poi['xchan_url']),
array('rel' => 'photo', 'type' => \App::$poi['xchan_photo_mimetype'], 'href' => \App::$poi['xchan_photo_l'])
array('rel' => 'alternate', 'type' => 'text/html', 'href' => App::$poi['xchan_url']),
array('rel' => 'photo', 'type' => App::$poi['xchan_photo_mimetype'], 'href' => App::$poi['xchan_photo_l'])
),
);
$xarr['obj'] = json_encode($obj);
$xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . \App::$poi['xchan_url'] . ']' . \App::$poi['xchan_name'] . '[/zrl]';
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . App::$poi['xchan_url'] . ']' . App::$poi['xchan_name'] . '[/zrl]';
$xarr['body'] .= "\n\n\n" . '[zrl=' . \App::$poi['xchan_url'] . '][zmg=80x80]' . \App::$poi['xchan_photo_m'] . '[/zmg][/zrl]';
$xarr['body'] .= "\n\n\n" . '[zrl=' . App::$poi['xchan_url'] . '][zmg=80x80]' . App::$poi['xchan_photo_m'] . '[/zmg][/zrl]';
post_activity_item($xarr);
@@ -319,7 +327,7 @@ class Connedit extends \Zotlabs\Web\Controller {
// pull in a bit of content if there is any to pull in
\Zotlabs\Daemon\Master::Summon(array('Onepoll',$contact_id));
Master::Summon(array('Onepoll',$contact_id));
}
@@ -332,11 +340,11 @@ class Connedit extends \Zotlabs\Web\Controller {
intval($contact_id)
);
if($r) {
\App::$poi = $r[0];
App::$poi = $r[0];
}
if($new_friend) {
$arr = array('channel_id' => local_channel(), 'abook' => \App::$poi);
$arr = array('channel_id' => local_channel(), 'abook' => App::$poi);
call_hooks('accept_follow', $arr);
}
@@ -356,23 +364,23 @@ class Connedit extends \Zotlabs\Web\Controller {
function connedit_clone(&$a) {
if(! \App::$poi)
if(! App::$poi)
return;
$channel = \App::get_channel();
$channel = App::get_channel();
$r = q("SELECT abook.*, xchan.*
FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and abook_id = %d LIMIT 1",
intval(local_channel()),
intval(\App::$poi['abook_id'])
intval(App::$poi['abook_id'])
);
if($r) {
\App::$poi = array_shift($r);
App::$poi = array_shift($r);
}
$clone = \App::$poi;
$clone = App::$poi;
unset($clone['abook_id']);
unset($clone['abook_account']);
@@ -382,7 +390,7 @@ class Connedit extends \Zotlabs\Web\Controller {
if($abconfig)
$clone['abconfig'] = $abconfig;
build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
}
/* @brief Generate content of connection edit page
@@ -401,11 +409,11 @@ class Connedit extends \Zotlabs\Web\Controller {
}
$section = ((array_key_exists('section',$_REQUEST)) ? $_REQUEST['section'] : '');
$channel = \App::get_channel();
$channel = App::get_channel();
$yes_no = array(t('No'),t('Yes'));
$connect_perms = \Zotlabs\Access\Permissions::connect_perms(local_channel());
$connect_perms = Permissions::connect_perms(local_channel());
$o .= "<script>function connectDefaultShare() {
\$('.abook-edit-me').each(function() {
@@ -426,7 +434,7 @@ class Connedit extends \Zotlabs\Web\Controller {
return;
$cmd = argv(2);
$orig_record = q("SELECT abook.*, xchan.* FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_id = %d AND abook_channel = %d AND abook_self = 0 LIMIT 1",
intval($contact_id),
@@ -440,7 +448,7 @@ class Connedit extends \Zotlabs\Web\Controller {
if($cmd === 'update') {
// pull feed and consume it, which should subscribe to the hub.
\Zotlabs\Daemon\Master::Summon(array('Poller',$contact_id));
Master::Summon(array('Poller',$contact_id));
goaway(z_root() . '/connedit/' . $contact_id);
}
@@ -450,7 +458,7 @@ class Connedit extends \Zotlabs\Web\Controller {
$recurse = 0;
$x = z_fetch_url(zid($url),false,$recurse,['session' => true]);
if($x['success']) {
$h = new \Zotlabs\Web\HTTPHeaders($x['header']);
$h = new HTTPHeaders($x['header']);
$fields = $h->fetch();
if($fields) {
foreach($fields as $y) {
@@ -481,17 +489,17 @@ class Connedit extends \Zotlabs\Web\Controller {
if($cmd === 'refresh') {
if($orig_record[0]['xchan_network'] === 'zot') {
if(! zot_refresh($orig_record[0],\App::get_channel()))
if(! zot_refresh($orig_record[0],App::get_channel()))
notice( t('Refresh failed - channel is currently unavailable.') );
}
elseif($orig_record[0]['xchan_network'] === 'zot6') {
if(! Libzot::refresh($orig_record[0],\App::get_channel()))
if(! Libzot::refresh($orig_record[0],App::get_channel()))
notice( t('Refresh failed - channel is currently unavailable.') );
}
else {
// if you are on a different network we'll force a refresh of the connection basic info
\Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
Master::Summon(array('Notifier','permission_update',$contact_id));
}
goaway(z_root() . '/connedit/' . $contact_id);
}
@@ -549,16 +557,11 @@ class Connedit extends \Zotlabs\Web\Controller {
if($cmd === 'drop') {
// @FIXME
// We need to send either a purge or a refresh packet to the other side (the channel being unfriended).
// The issue is that the abook DB record _may_ get destroyed when we call contact_remove. As the notifier
// runs in the background there could be a race condition preventing this packet from being sent in all
// cases.
// PLACEHOLDER
contact_remove(local_channel(), $orig_record[0]['abook_id']);
build_sync_packet(0 /* use the current local_channel */,
Master::Summon( [ 'Notifier', 'purge', local_channel(), $orig_record[0]['xchan_hash'] ] );
Libsync::build_sync_packet(0 /* use the current local_channel */,
array('abook' => array(array(
'abook_xchan' => $orig_record[0]['abook_xchan'],
'entry_deleted' => true))
@@ -573,13 +576,13 @@ class Connedit extends \Zotlabs\Web\Controller {
}
}
if(\App::$poi) {
if(App::$poi) {
$abook_prev = 0;
$abook_next = 0;
$contact_id = \App::$poi['abook_id'];
$contact = \App::$poi;
$contact_id = App::$poi['abook_id'];
$contact = App::$poi;
$cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 order by xchan_name",
intval(local_channel())
@@ -787,9 +790,9 @@ class Connedit extends \Zotlabs\Web\Controller {
$perms = array();
$channel = \App::get_channel();
$channel = App::get_channel();
$global_perms = \Zotlabs\Access\Permissions::Perms();
$global_perms = Permissions::Perms();
$existing = get_all_perms(local_channel(),$contact['abook_xchan'],false);
@@ -821,7 +824,7 @@ class Connedit extends \Zotlabs\Web\Controller {
$thisperm = get_abconfig(local_channel(),$contact['abook_xchan'],'my_perms',$k);
//fixme
$checkinherited = \Zotlabs\Access\PermissionLimits::Get(local_channel(),$k);
$checkinherited = PermissionLimits::Get(local_channel(),$k);
// For auto permissions (when $self is true) we don't want to look at existing
// permissions because they are enabled for the channel owner
@@ -834,7 +837,7 @@ class Connedit extends \Zotlabs\Web\Controller {
$perms[] = array('perms_' . $k, $v, ((array_key_exists($k,$their_perms)) ? intval($their_perms[$k]) : ''),$thisperm, 1, (($checkinherited & PERMS_SPECIFIC) ? '' : '1'), '', $checkinherited);
}
$pcat = new \Zotlabs\Lib\Permcat(local_channel());
$pcat = new Permcat(local_channel());
$pcatlist = $pcat->listing();
$permcats = [];
if($pcatlist) {

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
/*
@file cover_photo.php
@brief Module-file with functions for handling of cover-photos
@@ -66,7 +68,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$sync = attach_export_data($channel,$r[0]['resource_id']);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
}
// Update directory in background
@@ -230,7 +232,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$sync = attach_export_data($channel,$base_image['resource_id']);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
// Update directory in background
\Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id']));
@@ -291,14 +293,6 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$arr['item_thread_top'] = 1;
$arr['item_origin'] = 1;
$arr['item_wall'] = 1;
$arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj'] = json_encode(array(
'type' => $arr['obj_type'],
'id' => z_root() . '/photo/' . $photo['resource_id'] . '-7',
'link' => array('rel' => 'photo', 'type' => $photo['mimetype'], 'href' => z_root() . '/photo/' . $photo['resource_id'] . '-7')
));
if($profile && stripos($profile['gender'],t('female')) !== false)
$t = t('%1$s updated her %2$s');

View File

@@ -95,7 +95,7 @@ class Dav extends \Zotlabs\Web\Controller {
$auth = new \Zotlabs\Storage\BasicAuth();
$auth->observer = get_observer_hash();
// $auth->observer = get_observer_hash();
$auth->setRealm(ucfirst(\Zotlabs\Lib\System::get_platform_name()) . ' ' . 'WebDAV');

View File

@@ -4,6 +4,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Lib\Apps;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Libsync;
require_once('include/socgraph.php');
require_once('include/selectors.php');
@@ -164,7 +165,7 @@ class Defperms extends Controller {
if($abconfig)
$clone['abconfig'] = $abconfig;
build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
Libsync::build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)));
}
/* @brief Generate content of connection default permissions page

View File

@@ -14,7 +14,7 @@ require_once('include/html2plain.php');
class Directory extends Controller {
function init() {
App::set_pager_itemspage(60);
App::set_pager_itemspage(30);
if(local_channel() && x($_GET,'ignore')) {
q("insert into xign ( uid, xchan ) values ( %d, '%s' ) ",

View File

@@ -11,7 +11,7 @@ require_once('include/dir_fns.php');
class Dirsearch extends Controller {
function init() {
App::set_pager_itemspage(60);
App::set_pager_itemspage(30);
}

View File

@@ -47,7 +47,6 @@ class Display extends \Zotlabs\Web\Controller {
}
$observer_is_owner = false;
$updateable = false;
if(local_channel() && (! $update)) {
@@ -101,7 +100,7 @@ class Display extends \Zotlabs\Web\Controller {
if($decoded)
$item_hash = $decoded;
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1",
$r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid like '%s' limit 1",
dbesc($item_hash . '%')
);
@@ -159,14 +158,17 @@ class Display extends \Zotlabs\Web\Controller {
}
}
if($target_item['item_type'] == ITEM_TYPE_CARD) {
$x = q("select * from channel where channel_id = %d limit 1",
intval($target_item['uid'])
);
$y = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'CARD' and item.id = %d limit 1",
intval($target_item['uid']),
intval($target_item['parent'])
);
if($x && $y) {
goaway(z_root() . '/cards/' . $x[0]['channel_address'] . '/' . $y[0]['v']);
}
@@ -271,9 +273,6 @@ class Display extends \Zotlabs\Web\Controller {
intval(local_channel()),
dbesc($target_item['parent_mid'])
);
if($r) {
$updateable = true;
}
}
if(! $r) {
@@ -315,9 +314,6 @@ class Display extends \Zotlabs\Web\Controller {
intval(local_channel()),
dbesc($target_item['parent_mid'])
);
if($r) {
$updateable = true;
}
}
if($r === null) {
@@ -429,13 +425,6 @@ class Display extends \Zotlabs\Web\Controller {
killme();
}
if($updateable) {
$x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
intval(local_channel()),
intval($r[0]['item_id'])
);
}
$o .= '<div id="content-complete"></div>';

View File

@@ -17,7 +17,7 @@ class Feed extends \Zotlabs\Web\Controller {
$params['pages'] = ((x($_REQUEST,'pages')) ? intval($_REQUEST['pages']) : 0);
$params['top'] = ((x($_REQUEST,'top')) ? intval($_REQUEST['top']) : 0);
$params['start'] = ((x($_REQUEST,'start')) ? intval($_REQUEST['start']) : 0);
$params['records'] = ((x($_REQUEST,'records')) ? intval($_REQUEST['records']) : 40);
$params['records'] = ((x($_REQUEST,'records')) ? intval($_REQUEST['records']) : 10);
$params['direction'] = ((x($_REQUEST,'direction')) ? dbesc($_REQUEST['direction']) : 'desc');
$params['cat'] = ((x($_REQUEST,'cat')) ? escape_tags($_REQUEST['cat']) : '');
$params['compat'] = ((x($_REQUEST,'compat')) ? intval($_REQUEST['compat']) : 0);

View File

@@ -0,0 +1,79 @@
<?php
namespace Zotlabs\Module;
/* fix missing or hubloc_id_url entries */
class Fhubloc_id_url extends \Zotlabs\Web\Controller {
function get() {
if(! is_site_admin())
return;
q("START TRANSACTION");
// remove broken xchan entries
$r0 = dbq("DELETE FROM xchan WHERE xchan_hash = ''");
// remove broken hubloc entries
$r1 = dbq("DELETE FROM hubloc WHERE hubloc_hash = ''");
// fix legacy zot hubloc_id_url
$r2 = dbq("UPDATE hubloc
SET hubloc_id_url = CONCAT(hubloc_url, '/channel/', SUBSTRING(hubloc_addr FROM 1 FOR POSITION('@' IN hubloc_addr) -1))
WHERE hubloc_network = 'zot'
AND hubloc_id_url = ''"
);
// fix singleton networks hubloc_id_url
if(ACTIVE_DBTYPE == DBTYPE_MYSQL) {
// fix entries for activitypub which miss the xchan_url due to an earlier bug
$r3 = dbq("UPDATE xchan
SET xchan_url = xchan_hash
WHERE xchan_network = 'activitypub'
AND xchan_url = ''"
);
$r4 = dbq("UPDATE hubloc
LEFT JOIN xchan ON hubloc.hubloc_hash = xchan.xchan_hash
SET hubloc.hubloc_id_url = xchan.xchan_url
WHERE hubloc.hubloc_network IN ('activitypub', 'diaspora', 'friendica-over-diaspora', 'gnusoc')
AND hubloc.hubloc_id_url = ''
AND xchan.xchan_url IS NOT NULL"
);
}
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
// fix entries for activitypub which miss the xchan_url due to an earlier bug
$r3 = dbq("UPDATE xchan
SET xchan_url = xchan_hash
WHERE xchan_network = 'activitypub'
AND xchan_url = ''"
);
$r4 = dbq("UPDATE hubloc
SET hubloc_id_url = xchan_url
FROM xchan
WHERE hubloc_hash = xchan_hash
AND hubloc_network IN ('activitypub', 'diaspora', 'friendica-over-diaspora', 'gnusoc')
AND hubloc_id_url = ''
AND xchan_url IS NOT NULL"
);
}
if($r0 && $r1 && $r2 && $r3 && $r4) {
// remove hubloc entries where hubloc_id_url could not be fixed
$r5 = dbq("DELETE FROM hubloc WHERE hubloc_id_url = ''");
}
if($r0 && $r1 && $r2 && $r3 && $r4 && $r5) {
q("COMMIT");
return 'Completed';
}
q("ROLLBACK");
return 'Failed';
}
}

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libzot;
require_once('include/zot.php');
require_once('include/crypto.php');
@@ -10,7 +12,7 @@ require_once('include/crypto.php');
class Fhublocs extends \Zotlabs\Web\Controller {
function get() {
if(! is_site_admin())
return;
@@ -21,9 +23,11 @@ class Fhublocs extends \Zotlabs\Web\Controller {
if($r) {
foreach($r as $rr) {
$found = false;
$primary_address = '';
$x = zot_get_hublocs($rr['channel_hash']);
$x = Libzot::get_hublocs($rr['channel_hash']);
if($x) {
foreach($x as $xx) {
if($xx['hubloc_url'] === z_root() && $xx['hubloc_sitekey'] === $sitekey) {
@@ -42,13 +46,12 @@ class Fhublocs extends \Zotlabs\Web\Controller {
if($y)
$primary_address = $y[0]['xchan_addr'];
$hub_address = channel_reddress($rr['channel']);
$hub_address = channel_reddress($rr);
$primary = (($hub_address === $primary_address) ? 1 : 0);
if(! $y)
$primary = 1;
$m = q("delete from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ",
dbesc($rr['channel_hash']),
dbesc(z_root())
@@ -56,7 +59,7 @@ class Fhublocs extends \Zotlabs\Web\Controller {
// Create a verified hub location pointing to this site.
/*
$h = hubloc_store_lowlevel(
[
'hubloc_guid' => $rr['channel_guid'],
@@ -72,7 +75,26 @@ class Fhublocs extends \Zotlabs\Web\Controller {
'hubloc_sitekey' => $sitekey
]
);
*/
$h = hubloc_store_lowlevel(
[
'hubloc_guid' => $rr['channel_guid'],
'hubloc_guid_sig' => $rr['channel_guid_sig'],
'hubloc_hash' => $rr['channel_hash'],
'hubloc_id_url' => channel_url($rr),
'hubloc_addr' => channel_reddress($rr),
'hubloc_primary' => intval($primary),
'hubloc_url' => z_root(),
'hubloc_url_sig' => Libzot::sign(z_root(), $rr['channel_prvkey']),
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(), $sitekey),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/zot',
'hubloc_sitekey' => $sitekey,
'hubloc_network' => 'zot6',
'hubloc_updated' => datetime_convert()
]
);
if($h)
$o . 'local hubloc created for ' . $rr['channel_name'] . EOL;
else

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
require_once('include/attach.php');
require_once('include/channel.php');
require_once('include/photos.php');
@@ -41,7 +43,7 @@ class File_upload extends \Zotlabs\Web\Controller {
$sync = attach_export_data($channel,$hash);
if($sync) {
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
}
goaway(z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path']);
@@ -97,7 +99,7 @@ class File_upload extends \Zotlabs\Web\Controller {
if($r['success']) {
$sync = attach_export_data($channel,$r['data']['hash']);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
}
}

View File

@@ -5,7 +5,7 @@ namespace Zotlabs\Module;
*
*/
use Zotlabs\Lib\Libsync;
class Filestorage extends \Zotlabs\Web\Controller {
@@ -35,12 +35,12 @@ class Filestorage extends \Zotlabs\Web\Controller {
$url = get_cloud_url($channel_id, $channel['channel_address'], $resource);
//get the object before permissions change so we can catch eventual former allowed members
$object = get_file_activity_object($channel_id, $resource, $url);
attach_change_permissions($channel_id, $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse, true);
file_activity($channel_id, $object, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], 'post', $notify);
if($notify) {
$observer = \App::get_observer();
attach_store_item($channel, $observer, $resource);
}
goaway(dirname($url));
}
@@ -131,7 +131,7 @@ class Filestorage extends \Zotlabs\Web\Controller {
if(! $admin_delete) {
$sync = attach_export_data($channel, $f['hash'], true);
if($sync) {
build_sync_packet($channel['channel_id'], array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'], array('file' => array($sync)));
}
}

View File

@@ -1,31 +1,88 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Libsync;
use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\Activity;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\LDSignatures;
use Zotlabs\Lib\Connect;
use Zotlabs\Daemon\Master;
require_once('include/follow.php');
class Follow extends \Zotlabs\Web\Controller {
class Follow extends Controller {
function init() {
if(! local_channel()) {
if (ActivityStreams::is_as_request() && argc() == 2) {
$abook_id = intval(argv(1));
if(! $abook_id)
return;
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d",
intval($abook_id)
);
if (! $r) {
return;
}
$chan = channelx_by_n($r[0]['abook_channel']);
if (! $chan) {
http_status_exit(404, 'Not found');
}
$actor = Activity::encode_person($chan,true,true);
if (! $actor) {
http_status_exit(404, 'Not found');
}
$x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV
]],
[
'id' => z_root() . '/follow/' . $r[0]['abook_id'],
'type' => 'Follow',
'actor' => $actor,
'object' => $r[0]['xchan_url']
]);
$headers = [];
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
$x['signature'] = LDSignatures::sign($x,$chan);
$ret = json_encode($x, JSON_UNESCAPED_SLASHES);
$headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T');
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'];
$h = HTTPSig::create_sig($headers,$chan['channel_prvkey'],channel_url($chan));
HTTPSig::set_headers($h);
echo $ret;
killme();
}
if (! local_channel()) {
return;
}
$uid = local_channel();
$url = notags(trim(punify($_REQUEST['url'])));
$return_url = $_SESSION['return_url'];
$confirm = intval($_REQUEST['confirm']);
$interactive = (($_REQUEST['interactive']) ? intval($_REQUEST['interactive']) : 1);
$channel = \App::get_channel();
$channel = App::get_channel();
$result = new_contact($uid,$url,$channel,$interactive,$confirm);
$result = Connect::connect($channel,$url);
if($result['success'] == false) {
if($result['message'])
if ($result['success'] == false) {
if ($result['message']) {
notice($result['message']);
if($interactive) {
}
if ($interactive) {
goaway($return_url);
}
else {
@@ -36,8 +93,8 @@ class Follow extends \Zotlabs\Web\Controller {
info( t('Connection added.') . EOL);
$clone = array();
foreach($result['abook'] as $k => $v) {
if(strpos($k,'abook_') === 0) {
foreach ($result['abook'] as $k => $v) {
if (strpos($k,'abook_') === 0) {
$clone[$k] = $v;
}
}
@@ -46,20 +103,21 @@ class Follow extends \Zotlabs\Web\Controller {
unset($clone['abook_channel']);
$abconfig = load_abconfig($channel['channel_id'],$clone['abook_xchan']);
if($abconfig)
if ($abconfig) {
$clone['abconfig'] = $abconfig;
}
Libsync::build_sync_packet(0, [ 'abook' => [ $clone ] ], true);
build_sync_packet(0 /* use the current local_channel */, array('abook' => array($clone)), true);
$can_view_stream = intval(get_abconfig($channel['channel_id'],$clone['abook_xchan'],'their_perms','view_stream'));
$can_view_stream = their_perms_contains($channel['channel_id'],$clone['abook_xchan'],'view_stream');
// If we can view their stream, pull in some posts
if(($can_view_stream) || ($result['abook']['xchan_network'] === 'rss'))
\Zotlabs\Daemon\Master::Summon(array('Onepoll',$result['abook']['abook_id']));
if (($can_view_stream) || ($result['abook']['xchan_network'] === 'rss')) {
Master::Summon([ 'Onepoll', $result['abook']['abook_id'] ]);
}
if($interactive) {
goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?f=&follow=1');
if ($interactive) {
goaway(z_root() . '/connedit/' . $result['abook']['abook_id'] . '?follow=1');
}
else {
json_return_and_die([ 'success' => true ]);
@@ -68,7 +126,7 @@ class Follow extends \Zotlabs\Web\Controller {
}
function get() {
if(! local_channel()) {
if (! local_channel()) {
return login();
}
}

View File

@@ -4,6 +4,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
require_once('include/group.php');
@@ -80,7 +81,7 @@ class Group extends Controller {
info( t('Privacy group updated.') . EOL );
build_sync_packet(local_channel(),null,true);
Libsync::build_sync_packet(local_channel(),null,true);
}
goaway(z_root() . '/group/' . argv(1) . '/' . argv(2));

View File

@@ -199,8 +199,6 @@ class Hq extends \Zotlabs\Web\Controller {
]);
}
$updateable = false;
if($load && $target_item) {
$r = null;
@@ -213,10 +211,6 @@ class Hq extends \Zotlabs\Web\Controller {
dbesc($target_item['parent_mid'])
);
if($r) {
$updateable = true;
}
if(!$r) {
$sys_item = true;
@@ -243,10 +237,6 @@ class Hq extends \Zotlabs\Web\Controller {
dbesc($target_item['parent_mid'])
);
if($r) {
$updateable = true;
}
if(!$r) {
$sys_item = true;
@@ -283,13 +273,6 @@ class Hq extends \Zotlabs\Web\Controller {
$o .= conversation($items, 'hq', $update, 'client');
if($updateable) {
$x = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d AND parent = %d ",
intval(local_channel()),
intval($r[0]['item_id'])
);
}
$o .= '<div id="content-complete"></div>';
return $o;

View File

@@ -137,6 +137,11 @@ class Import extends \Zotlabs\Web\Controller {
return;
}
if(version_compare($data['compatibility']['version'], '4.7.3', '<=')) {
// zot6 transition: cloning is not compatible with older versions
notice('Data export format is not compatible with this software (not a zot6 channel)');
return;
}
if($moving)
$seize = 1;
@@ -212,50 +217,21 @@ class Import extends \Zotlabs\Web\Controller {
// create new hubloc for the new channel at this site
if(array_key_exists('channel',$data)) {
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_hash' => $channel['channel_hash'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_network' => 'zot',
'hubloc_primary' => (($seize) ? 1 : 0),
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_updated' => datetime_convert()
]
);
// reset the original primary hubloc if it is being seized
if($seize) {
$r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ",
dbesc($channel['channel_hash']),
dbesc(z_root())
);
}
// create a new zot6 hubloc if we have got a channel_portable_id
if($channel['channel_portable_id']) {
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => 'sha256.' . $channel['channel_guid_sig'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_hash' => $channel['channel_portable_id'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_network' => 'zot6',
'hubloc_network' => 'zot',
'hubloc_primary' => (($seize) ? 1 : 0),
'hubloc_url' => z_root(),
'hubloc_url_sig' => 'sha256.' . base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/zot',
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_updated' => datetime_convert(),
'hubloc_id_url' => channel_url($channel),
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(),get_config('system','pubkey'))
'hubloc_updated' => datetime_convert()
]
);
@@ -266,7 +242,35 @@ class Import extends \Zotlabs\Web\Controller {
dbesc(z_root())
);
}
}
// create a new zot6 hubloc if we have got a channel_portable_id
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_hash' => $channel['channel_hash'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_network' => 'zot6',
'hubloc_primary' => (($seize) ? 1 : 0),
'hubloc_url' => z_root(),
'hubloc_url_sig' => 'sha256.' . base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => \App::get_hostname(),
'hubloc_callback' => z_root() . '/zot',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_updated' => datetime_convert(),
'hubloc_id_url' => channel_url($channel),
'hubloc_site_id' => Libzot::make_xchan_hash(z_root(),get_config('system','pubkey'))
]
);
// reset the original primary hubloc if it is being seized
if($seize) {
$r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ",
dbesc($channel['channel_hash']),
dbesc(z_root())
);
}
}
@@ -285,6 +289,28 @@ class Import extends \Zotlabs\Web\Controller {
dbesc($channel['channel_portable_id'])
);
if($channel['channel_portable_id']) {
$r = xchan_store_lowlevel(
[
'xchan_hash' => $channel['channel_portable_id'],
'xchan_guid' => $channel['channel_guid'],
'xchan_guid_sig' => $channel['channel_guid_sig'],
'xchan_pubkey' => $channel['channel_pubkey'],
'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
'xchan_addr' => channel_reddress($channel),
'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot',
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert()
]
);
}
$r = xchan_store_lowlevel(
[
'xchan_hash' => $channel['channel_hash'],
@@ -299,35 +325,12 @@ class Import extends \Zotlabs\Web\Controller {
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot',
'xchan_network' => 'zot6',
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert()
]
);
if($channel['channel_portable_id']) {
$r = xchan_store_lowlevel(
[
'xchan_hash' => \Zotlabs\Lib\Libzot::make_xchan_hash($channel['channel_guid'],$channel['channel_pubkey']),
'xchan_guid' => $channel['channel_guid'],
'xchan_guid_sig' => 'sha256.' . $channel['channel_guid_sig'],
'xchan_pubkey' => $channel['channel_pubkey'],
'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
'xchan_addr' => channel_reddress($channel),
'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot6',
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert()
]
);
}
}
logger('import step 6');
@@ -346,7 +349,7 @@ class Import extends \Zotlabs\Web\Controller {
}
if($xchan['xchan_network'] === 'zot6') {
$zhash = \Zotlabs\Lib\Libzot::make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_pubkey']);
$zhash = Libzot::make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_pubkey']);
if($zhash !== $xchan['xchan_hash']) {
logger('forged xchan: ' . print_r($xchan,true));
continue;

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module;
use Zotlabs\Lib\Config;
use Zotlabs\Lib\IConfig;
use Zotlabs\Lib\Enotify;
use Zotlabs\Web\Controller;
@@ -11,7 +12,9 @@ use Zotlabs\Lib\ActivityStreams;
use Zotlabs\Lib\LDSignatures;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Libsync;
use Zotlabs\Lib\ThreadListener;
use Zotlabs\Access\PermissionRoles;
use App;
require_once('include/crypto.php');
@@ -42,9 +45,11 @@ class Item extends Controller {
if (Libzot::is_zot_request()) {
$conversation = false;
$item_id = argv(1);
if (! $item_id)
if(! $item_id)
http_status_exit(404, 'Not found');
$portable_id = EMPTY_STR;
@@ -65,32 +70,24 @@ class Item extends Controller {
// process an authenticated fetch
$sigdata = HTTPSig::verify(EMPTY_STR);
if($sigdata['portable_id'] && $sigdata['header_valid']) {
$sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
// first see if we have a copy of this item's parent owned by the current signer
// include xchans for all zot-like networks - these will have the same guid and public key
$x = q("select * from xchan where xchan_hash = '%s'",
dbesc($sigdata['portable_id'])
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1",
dbesc($r[0]['parent_mid']),
dbesc($portable_id)
);
if ($x) {
$xchans = q("select xchan_hash from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ",
dbesc($sigdata['portable_id']),
dbesc($x[0]['xchan_guid']),
dbesc($x[0]['xchan_pubkey'])
);
if ($xchans) {
$hashes = ids_to_querystr($xchans,'xchan_hash',true);
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan in ( " . protect_sprintf($hashes) . " ) limit 1",
dbesc($r[0]['parent_mid'])
);
}
}
}
elseif (Config::get('system','require_authenticated_fetch',false)) {
http_status_exit(403,'Permission denied');
}
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
@@ -110,7 +107,7 @@ class Item extends Controller {
$parents_str = ids_to_querystr($i,'item_id');
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal ",
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal order by item.id asc",
dbesc($parents_str)
);
@@ -121,43 +118,10 @@ class Item extends Controller {
xchan_query($items,true);
$items = fetch_post_tags($items,true);
$observer = App::get_observer();
$parent = $items[0];
$recips = (($parent['owner']['xchan_network'] === 'activitypub') ? get_iconfig($parent['id'],'activitypub','recips', []) : []);
$to = (($recips && array_key_exists('to',$recips) && is_array($recips['to'])) ? $recips['to'] : null);
$nitems = [];
foreach($items as $i) {
$mids = [];
if(intval($i['item_private'])) {
if(! $observer) {
continue;
}
// ignore private reshare, possibly from hubzilla
if($i['verb'] === 'Announce') {
if(! in_array($i['thr_parent'],$mids)) {
$mids[] = $i['thr_parent'];
}
continue;
}
// also ignore any children of the private reshares
if(in_array($i['thr_parent'],$mids)) {
continue;
}
if((! $to) || (! in_array($observer['xchan_url'],$to))) {
continue;
}
}
$nitems[] = $i;
}
if(! $nitems)
if(! $items)
http_status_exit(404, 'Not found');
$chan = channelx_by_n($nitems[0]['uid']);
$chan = channelx_by_n($items[0]['uid']);
if(! $chan)
http_status_exit(404, 'Not found');
@@ -165,7 +129,8 @@ class Item extends Controller {
if(! perm_is_allowed($chan['channel_id'],get_observer_hash(),'view_stream'))
http_status_exit(403, 'Forbidden');
$i = Activity::encode_item_collection($nitems,'conversation/' . $item_id,'OrderedCollection');
$i = Activity::encode_item_collection($items, 'conversation/' . $item_id, 'OrderedCollection');
if($portable_id) {
ThreadListener::store(z_root() . '/item/' . $item_id,$portable_id);
}
@@ -192,9 +157,110 @@ class Item extends Controller {
}
if(ActivityStreams::is_as_request()) {
$item_id = argv(1);
if(! $item_id)
http_status_exit(404, 'Not found');
$portable_id = EMPTY_STR;
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 ";
$i = null;
// do we have the item (at all)?
// add preferential bias to item owners (item_wall = 1)
$r = q("select * from item where mid = '%s' or uuid = '%s' $item_normal order by item_wall desc limit 1",
dbesc(z_root() . '/item/' . $item_id),
dbesc($item_id)
);
if (! $r) {
http_status_exit(404,'Not found');
}
// process an authenticated fetch
$sigdata = HTTPSig::verify(EMPTY_STR);
if ($sigdata['portable_id'] && $sigdata['header_valid']) {
$portable_id = $sigdata['portable_id'];
if (! check_channelallowed($portable_id)) {
http_status_exit(403, 'Permission denied');
}
if (! check_siteallowed($sigdata['signer'])) {
http_status_exit(403, 'Permission denied');
}
observer_auth($portable_id);
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ",
dbesc($r[0]['parent_mid']),
dbesc($portable_id)
);
}
elseif (Config::get('system','require_authenticated_fetch',false)) {
http_status_exit(403,'Permission denied');
}
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
// with a bias towards those items owned by channels on this site (item_wall = 1)
$sql_extra = item_permissions_sql(0);
if (! $i) {
$i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1",
dbesc($r[0]['parent_mid'])
);
}
if(! $i) {
http_status_exit(403,'Forbidden');
}
// If we get to this point we have determined we can access the original in $r (fetched much further above), so use it.
xchan_query($r,true);
$items = fetch_post_tags($r,false);
$chan = channelx_by_n($items[0]['uid']);
if(! $chan)
http_status_exit(404, 'Not found');
if(! perm_is_allowed($chan['channel_id'],get_observer_hash(),'view_stream'))
http_status_exit(403, 'Forbidden');
$i = Activity::encode_item($items[0],true);
if(! $i)
http_status_exit(404, 'Not found');
$x = array_merge(['@context' => [
ACTIVITYSTREAMS_JSONLD_REV,
'https://w3id.org/security/v1',
z_root() . ZOT_APSCHEMA_REV
]], $i);
$headers = [];
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
$x['signature'] = LDSignatures::sign($x,$chan);
$ret = json_encode($x, JSON_UNESCAPED_SLASHES);
$headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T');
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'];
$h = HTTPSig::create_sig($headers,$chan['channel_prvkey'],channel_url($chan));
HTTPSig::set_headers($h);
echo $ret;
killme();
}
if(argc() > 1 && argv(1) !== 'drop') {
$x = q("select uid, item_wall, llink, mid from item where mid = '%s' ",
dbesc(z_root() . '/item/' . argv(1))
$x = q("select uid, item_wall, llink, mid from item where mid = '%s' or mid = '%s' ",
dbesc(z_root() . '/item/' . argv(1)),
dbesc(z_root() . '/activity/' . argv(1))
);
if($x) {
foreach($x as $xv) {
@@ -711,6 +777,27 @@ class Item extends Controller {
$str_group_allow = $gacl['allow_gid'];
$str_contact_deny = $gacl['deny_cid'];
$str_group_deny = $gacl['deny_gid'];
$groupww = false;
// if this is a wall-to-wall post to a group, turn it into a direct message
$role = get_pconfig($profile_uid,'system','permissions_role');
$rolesettings = PermissionRoles::role_perms($role);
$channel_type = isset($rolesettings['channel_type']) ? $rolesettings['channel_type'] : 'normal';
$is_group = (($channel_type === 'group') ? true : false);
if (($is_group) && ($walltowall) && (! $walltowall_comment)) {
$groupww = true;
$str_contact_allow = $owner_xchan['xchan_hash'];
$str_group_allow = '';
}
$post_tags = [];
if($mimetype === 'text/bbcode') {
@@ -722,16 +809,16 @@ class Item extends Controller {
// we may need virtual or template classes to implement the possible alternatives
if(strpos($body,'[/summary]') !== false) {
$match = '';
$cnt = preg_match("/\[summary\](.*?)\[\/summary\]/ism",$body,$match);
if($cnt) {
$summary .= $match[1];
}
$body_content = preg_replace("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/ism", '',$body);
$body = trim($body_content);
}
$summary = cleanup_bbcode($summary);
$match = '';
$cnt = preg_match("/\[summary\](.*?)\[\/summary\]/ism",$body,$match);
if($cnt) {
$summary .= $match[1];
}
$body_content = preg_replace("/\[summary\](.*?)\[\/summary\]/ism", '',$body);
$body = trim($body_content);
}
$summary = cleanup_bbcode($summary);
$body = cleanup_bbcode($body);
@@ -745,7 +832,6 @@ class Item extends Controller {
// Set permissions based on tag replacements
set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $parent_item, $private);
$post_tags = array();
foreach($results as $result) {
$success = $result['success'];
if($success['replaced']) {
@@ -758,6 +844,7 @@ class Item extends Controller {
);
}
}
}
if(($str_contact_allow) && (! $str_group_allow)) {
@@ -829,8 +916,6 @@ class Item extends Controller {
$i = 0;
foreach($match[2] as $mtch) {
$reshare = new \Zotlabs\Lib\Share($mtch);
$datarray['obj'] = $reshare->obj();
$datarray['obj_type'] = $datarray['obj']['type'];
$body = str_replace($match[1][$i],$reshare->bbcode(),$body);
$i++;
}
@@ -989,8 +1074,9 @@ class Item extends Controller {
}
if ((! $plink) && ($item_thread_top)) {
$plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . gen_link_id($mid);
$plink = substr($plink,0,190);
// $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . gen_link_id($mid);
// $plink = substr($plink,0,190);
$plink = $mid;
}
if ($datarray['obj']) {
@@ -1054,10 +1140,9 @@ class Item extends Controller {
$datarray['layout_mid'] = $layout_mid;
$datarray['public_policy'] = $public_policy;
$datarray['comment_policy'] = map_scope($comment_policy);
$datarray['term'] = $post_tags;
$datarray['term'] = array_unique($post_tags, SORT_REGULAR);
$datarray['plink'] = $plink;
$datarray['route'] = $route;
// A specific ACL over-rides public_policy completely
@@ -1155,7 +1240,7 @@ class Item extends Controller {
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
Libsync::build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
}
}
if(! $nopush)
@@ -1258,7 +1343,7 @@ class Item extends Controller {
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
Libsync::build_sync_packet($profile_uid,array('item' => array(encode_item($sync_item[0],true))));
}
}
@@ -1266,7 +1351,11 @@ class Item extends Controller {
$datarray['llink'] = z_root() . '/display/' . gen_link_id($datarray['mid']);
call_hooks('post_local_end', $datarray);
if ($groupww) {
$nopush = false;
}
if(! $nopush)
Master::Summon([ 'Notifier', $notify_type, $post_id ]);
@@ -1360,7 +1449,7 @@ class Item extends Controller {
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true))));
Libsync::build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true))));
}
if($complex) {

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\Libsync;
require_once('include/security.php');
require_once('include/bbcode.php');
@@ -209,20 +210,8 @@ class Like extends \Zotlabs\Web\Controller {
if(! $plink)
$plink = '[zrl=' . z_root() . '/profile/' . $ch[0]['channel_address'] . ']' . $post_type . '[/zrl]';
$links = array();
$links[] = array('rel' => 'alternate', 'type' => 'text/html',
'href' => z_root() . '/profile/' . $ch[0]['channel_address']);
$links[] = array('rel' => 'photo', 'type' => $ch[0]['xchan_photo_mimetype'],
'href' => $ch[0]['xchan_photo_l']);
$object = json_encode(array(
'type' => ACTIVITY_OBJ_PROFILE,
'title' => $ch[0]['channel_name'],
'id' => $ch[0]['xchan_url'] . '/' . $ch[0]['xchan_hash'],
'link' => $links
));
$object = json_encode(Activity::fetch_profile([ 'id' => channel_url($ch[0]) ]));
// second like of the same thing is "undo" for the first like
$z = q("select * from likes where channel_id = %d and liker = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' limit 1",
@@ -235,7 +224,7 @@ class Like extends \Zotlabs\Web\Controller {
if($z) {
$z[0]['deleted'] = 1;
build_sync_packet($ch[0]['channel_id'],array('likes' => $z));
Libsync::build_sync_packet($ch[0]['channel_id'],array('likes' => $z));
q("delete from likes where id = %d",
intval($z[0]['id'])
@@ -407,27 +396,8 @@ class Like extends \Zotlabs\Web\Controller {
$body = $item['body'];
$object = json_encode(array(
'type' => $objtype,
'id' => $item['mid'],
'asld' => Activity::fetch_item( [ 'id' => $item['mid'] ] ),
'parent' => (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']),
'link' => $links,
'title' => $item['title'],
'content' => $item['body'],
'created' => $item['created'],
'edited' => $item['edited'],
'author' => array(
'name' => $item_author['xchan_name'],
'address' => $item_author['xchan_addr'],
'guid' => $item_author['xchan_guid'],
'guid_sig' => $item_author['xchan_guid_sig'],
'link' => array(
array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']),
array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])),
),
));
$object = json_encode(Activity::fetch_item( [ 'id' => $item['mid'] ]));
if(! intval($item['item_thread_top']))
$post_type = 'comment';
@@ -471,15 +441,15 @@ class Like extends \Zotlabs\Web\Controller {
if($extended_like) {
$ulink = '[zrl=' . $ch[0]['xchan_url'] . ']' . $ch[0]['xchan_name'] . '[/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]';
$ulink = '[zrl=' . $ch[0]['xchan_url'] . '][bdi]' . $ch[0]['xchan_name'] . '[/bdi][/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]';
$private = (($public) ? 0 : 1);
}
else {
$arr['parent'] = $item['id'];
$arr['thr_parent'] = $item['mid'];
$ulink = '[zrl=' . $item_author['xchan_url'] . ']' . $item_author['xchan_name'] . '[/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]';
$ulink = '[zrl=' . $item_author['xchan_url'] . '][bdi]' . $item_author['xchan_name'] . '[/bdi][/zrl]';
$alink = '[zrl=' . $observer['xchan_url'] . '][bdi]' . $observer['xchan_name'] . '[/bdi][/zrl]';
$plink = '[zrl=' . z_root() . '/display/' . gen_link_id($item['mid']) . ']' . $post_type . '[/zrl]';
$allow_cid = $item['allow_cid'];
$allow_gid = $item['allow_gid'];
@@ -566,7 +536,7 @@ class Like extends \Zotlabs\Web\Controller {
dbesc($obj_id)
);
if($r)
build_sync_packet($ch[0]['channel_id'],array('likes' => $r));
Libsync::build_sync_packet($ch[0]['channel_id'],array('likes' => $r));
}

View File

@@ -1,22 +1,24 @@
<?php
namespace Zotlabs\Module; /** @file */
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Daemon\Master;
class Locs extends \Zotlabs\Web\Controller {
class Locs extends Controller {
function post() {
if(! local_channel())
return;
$channel = \App::get_channel();
$channel = App::get_channel();
if($_REQUEST['primary']) {
$hubloc_id = intval($_REQUEST['primary']);
if($hubloc_id) {
$r = q("select hubloc_id from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1",
$r = q("select * from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1",
intval($hubloc_id),
dbesc($channel['channel_hash'])
);
@@ -26,15 +28,16 @@ class Locs extends \Zotlabs\Web\Controller {
return;
}
$r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' ",
dbesc($channel['channel_hash'])
q("UPDATE hubloc SET hubloc_primary = 0 WHERE hubloc_primary = 1 AND (hubloc_hash = '%s' OR hubloc_hash = '%s')",
dbesc($channel['channel_hash']),
dbesc($channel['channel_portable_id'])
);
$r = q("update hubloc set hubloc_primary = 1 where hubloc_id = %d and hubloc_hash = '%s'",
q("UPDATE hubloc SET hubloc_primary = 1 WHERE hubloc_id = %d AND hubloc_hash = '%s'",
intval($hubloc_id),
dbesc($channel['channel_hash'])
);
\Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
Master::Summon( [ 'Notifier', 'refresh_all', $channel['channel_id'] ] );
return;
}
}
@@ -68,11 +71,12 @@ class Locs extends \Zotlabs\Web\Controller {
}
}
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_id = %d and hubloc_hash = '%s'",
intval($hubloc_id),
dbesc($channel['channel_hash'])
q("UPDATE hubloc SET hubloc_deleted = 1 WHERE hubloc_id_url = '%s' AND (hubloc_hash = '%s' OR hubloc_hash = '%s')",
dbesc($r[0]['hubloc_id_url']),
dbesc($channel['channel_hash']),
dbesc($channel['channel_portable_id'])
);
\Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
Master::Summon( [ 'Notifier', 'refresh_all', $channel['channel_id'] ] );
return;
}
}
@@ -88,10 +92,10 @@ class Locs extends \Zotlabs\Web\Controller {
return;
}
$channel = \App::get_channel();
$channel = App::get_channel();
if($_REQUEST['sync']) {
\Zotlabs\Daemon\Master::Summon(array('Notifier','location',$channel['channel_id']));
Master::Summon( [ 'Notifier', 'refresh_all', $channel['channel_id'] ] );
info( t('Syncing locations') . EOL);
goaway(z_root() . '/locs');
}

View File

@@ -1,214 +1,133 @@
<?php
namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\SConfig;
@require_once('include/zot.php');
class Magic extends \Zotlabs\Web\Controller {
class Magic extends Controller {
function init() {
$ret = array('success' => false, 'url' => '', 'message' => '');
logger('mod_magic: invoked', LOGGER_DEBUG);
logger('mod_magic: args: ' . print_r($_REQUEST,true),LOGGER_DATA);
$addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : '');
$bdest = ((x($_REQUEST,'bdest')) ? $_REQUEST['bdest'] : '');
$dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : '');
$test = ((x($_REQUEST,'test')) ? intval($_REQUEST['test']) : 0);
$rev = ((x($_REQUEST,'rev')) ? intval($_REQUEST['rev']) : 0);
$owa = ((x($_REQUEST,'owa')) ? intval($_REQUEST['owa']) : 0);
$delegate = ((x($_REQUEST,'delegate')) ? $_REQUEST['delegate'] : '');
if($bdest)
$ret = [
'success' => false,
'url' => '',
'message' => ''
];
logger('mod_magic: invoked', LOGGER_DEBUG);
logger('args: ' . print_r($_REQUEST,true),LOGGER_DATA);
$addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : '');
$bdest = ((x($_REQUEST,'bdest')) ? $_REQUEST['bdest'] : '');
$dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : '');
$rev = ((x($_REQUEST,'rev')) ? intval($_REQUEST['rev']) : 0);
$owa = ((x($_REQUEST,'owa')) ? intval($_REQUEST['owa']) : 0);
$delegate = ((x($_REQUEST,'delegate')) ? $_REQUEST['delegate'] : '');
// bdest is preferred as it is hex-encoded and can survive url rewrite and argument parsing
if ($bdest) {
$dest = hex2bin($bdest);
}
$parsed = parse_url($dest);
if(! $parsed) {
if($test) {
$ret['message'] .= 'could not parse ' . $dest . EOL;
return($ret);
}
if (! $parsed) {
goaway($dest);
}
$basepath = $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '');
$x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1",
dbesc($basepath)
);
if(! $x) {
/*
* We have no records for, or prior communications with this hub.
* If an address was supplied, let's finger them to create a hub record.
* Otherwise we'll use the special address '[system]' which will return
* either a system channel or the first available normal channel. We don't
* really care about what channel is returned - we need the hub information
* from that response so that we can create signed auth packets destined
* for that hub.
*
*/
$j = \Zotlabs\Zot\Finger::run((($addr) ? $addr : '[system]@' . $parsed['host']),null);
if($j['success']) {
import_xchan($j);
// Now try again
$x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1",
dbesc($basepath)
);
}
}
if(! $x) {
if($rev)
goaway($dest);
else {
logger('mod_magic: no channels found for requested hub.' . print_r($_REQUEST,true));
if($test) {
$ret['message'] .= 'This site has no previous connections with ' . $basepath . EOL;
return $ret;
}
notice( t('Hub not found.') . EOL);
return;
}
}
$owapath = SConfig::get($basepath,'system','openwebauth', $basepath . '/owa');
// This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating.
// By default, we'll proceed without asking.
$arr = array(
'channel_id' => local_channel(),
'xchan' => $x[0],
$arr = [
'channel_id' => local_channel(),
'destination' => $dest,
'proceed' => true
);
'proceed' => true
];
call_hooks('magic_auth',$arr);
$dest = $arr['destination'];
if(! $arr['proceed']) {
if($test) {
$ret['message'] .= 'cancelled by plugin.' . EOL;
return $ret;
}
if (! $arr['proceed']) {
goaway($dest);
}
if((get_observer_hash()) && ($x[0]['hubloc_url'] === z_root())) {
if((get_observer_hash()) && (stripos($dest,z_root()) === 0)) {
// We are already authenticated on this site and a registered observer.
// Just redirect.
if($test) {
$ret['success'] = true;
$ret['message'] .= 'Local site - you are already authenticated.' . EOL;
return $ret;
}
$delegation_success = false;
if($delegate) {
// First check if this is a delegate request on the local system and process accordingly.
// Otherwise redirect.
if ($delegate) {
$r = q("select * from channel left join hubloc on channel_hash = hubloc_hash where hubloc_addr = '%s' limit 1",
dbesc($delegate)
);
if($r && intval($r[0]['channel_id'])) {
$allowed = perm_is_allowed($r[0]['channel_id'],get_observer_hash(),'delegate');
if($allowed) {
if ($r) {
$c = array_shift($r);
if (perm_is_allowed($c['channel_id'],get_observer_hash(),'delegate')) {
$tmp = $_SESSION;
$_SESSION['delegate_push'] = $tmp;
$_SESSION['delegate_channel'] = $r[0]['channel_id'];
$_SESSION['delegate'] = get_observer_hash();
$_SESSION['account_id'] = intval($r[0]['channel_account_id']);
change_channel($r[0]['channel_id']);
$delegation_success = true;
$_SESSION['delegate_push'] = $tmp;
$_SESSION['delegate_channel'] = $c['channel_id'];
$_SESSION['delegate'] = get_observer_hash();
$_SESSION['account_id'] = intval($c['channel_account_id']);
change_channel($c['channel_id']);
}
}
}
// FIXME: check and honour local delegation
goaway($dest);
}
if(local_channel()) {
$channel = \App::get_channel();
if (local_channel()) {
$channel = App::get_channel();
// OpenWebAuth
if($owa) {
if ($owa) {
$dest = strip_zids($dest);
$dest = strip_query_param($dest,'f');
// We now post to the OWA endpoint. This improves security by providing a signed digest
$data = json_encode([ 'OpenWebAuth' => random_string() ]);
$headers = [];
$headers['Accept'] = 'application/x-zot+json' ;
$headers['Content-Type'] = 'application/x-zot+json' ;
$headers['X-Open-Web-Auth'] = random_string();
$headers['Host'] = $parsed['host'];
$headers['Digest'] = HTTPSig::generate_digest_header($data);
$headers['Host'] = $parsed['host'];
$headers['(request-target)'] = 'post ' . '/owa';
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], 'acct:' . channel_reddress($channel),true,'sha512');
$x = z_post_url($basepath . '/owa',$data,$redirects,[ 'headers' => $headers ]);
if($x['success']) {
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
$x = z_post_url($owapath,$data,$redirects,[ 'headers' => $headers ]);
logger('owa fetch returned: ' . print_r($x,true),LOGGER_DATA);
if ($x['success']) {
$j = json_decode($x['body'],true);
if($j['success']) {
if ($j['success'] && $j['encrypted_token']) {
// decrypt the token using our private key
$token = '';
if($j['encrypted_token']) {
openssl_private_decrypt(base64url_decode($j['encrypted_token']),$token,$channel['channel_prvkey']);
}
else {
$token = $j['token'];
}
$strp = strpbrk($dest,'?&');
$args = (($strp) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : '');
openssl_private_decrypt(base64url_decode($j['encrypted_token']),$token,$channel['channel_prvkey']);
$x = strpbrk($dest,'?&');
// redirect using the encrypted token which will be exchanged for an authenticated session
$args = (($x) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : '');
goaway($dest . $args);
}
}
goaway($dest);
}
$token = random_string();
\Zotlabs\Lib\Verify::create('auth',$channel['channel_id'],$token,$x[0]['hubloc_url']);
$target_url = $x[0]['hubloc_callback'] . '/?f=&auth=' . urlencode(channel_reddress($channel))
. '&sec=' . $token . '&dest=' . urlencode($dest) . '&version=' . ZOT_REVISION;
if($delegate)
$target_url .= '&delegate=' . urlencode($delegate);
logger('mod_magic: redirecting to: ' . $target_url, LOGGER_DEBUG);
if($test) {
$ret['success'] = true;
$ret['url'] = $target_url;
$ret['message'] = 'token ' . $token . ' created for channel ' . $channel['channel_id'] . ' for url ' . $x[0]['hubloc_url'] . EOL;
return $ret;
}
goaway($target_url);
}
if($test) {
$ret['message'] = 'Not authenticated or invalid arguments to mod_magic' . EOL;
return $ret;
}
goaway($dest);
}
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
require_once('include/conversation.php');
@@ -14,7 +16,7 @@ class Moderate extends \Zotlabs\Web\Controller {
return;
}
\App::set_pager_itemspage(60);
\App::set_pager_itemspage(30);
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
//show all items
@@ -77,7 +79,7 @@ class Moderate extends \Zotlabs\Web\Controller {
if($r) {
xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet(local_channel(),array('item' => array(encode_item($sync_item[0],true))));
Libsync::build_sync_packet(local_channel(),array('item' => array(encode_item($sync_item[0],true))));
}
if($action === 'approve') {
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'comment-new', $post_id));

View File

@@ -133,8 +133,6 @@ class Network extends \Zotlabs\Web\Controller {
$pf = ((x($_GET,'pf')) ? $_GET['pf'] : '');
$unseen = ((x($_GET,'unseen')) ? $_GET['unseen'] : '');
$deftag = '';
if (Apps::system_app_installed(local_channel(),'Affinity Tool')) {
$affinity_locked = intval(get_pconfig(local_channel(),'affinity','lock',1));
if ($affinity_locked) {
@@ -160,10 +158,7 @@ class Network extends \Zotlabs\Web\Controller {
goaway(z_root() . '/network');
// NOTREACHED
}
if($pf)
$deftag = '!{' . (($cid_r[0]['xchan_addr']) ? $cid_r[0]['xchan_addr'] : $cid_r[0]['xchan_url']) . '}';
else
$def_acl = [ 'allow_cid' => '<' . $cid_r[0]['abook_xchan'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
$def_acl = [ 'allow_cid' => '<' . $cid_r[0]['abook_xchan'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
}
if(! $update) {
@@ -177,6 +172,17 @@ class Network extends \Zotlabs\Web\Controller {
nav_set_selected('Network');
$bang = '!';
if($cid_r) {
$forums = get_forum_channels($channel['channel_id']);
if($forums) {
$forum_xchans = ids_to_array($forums, 'xchan_hash');
if(in_array($cid_r[0]['abook_xchan'], $forum_xchans))
$bang = $cid_r[0]['abook_xchan'];
}
}
$channel_acl = array(
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
@@ -184,7 +190,7 @@ class Network extends \Zotlabs\Web\Controller {
'deny_gid' => $channel['channel_deny_gid']
);
$private_editing = ((($group || $cid) && (! intval($_GET['pf']))) ? true : false);
$private_editing = (($group || $cid) ? true : false);
$x = array(
'is_owner' => true,
@@ -194,7 +200,7 @@ class Network extends \Zotlabs\Web\Controller {
'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
'permissions' => (($private_editing) ? $def_acl : $channel_acl),
'bang' => (($private_editing) ? '!' : ''),
'bang' => (($private_editing) ? $bang : ''),
'visitor' => true,
'profile_uid' => local_channel(),
'editor_autocomplete' => true,
@@ -203,9 +209,6 @@ class Network extends \Zotlabs\Web\Controller {
'jotnets' => true,
'reset' => t('Reset form')
);
if($deftag)
$x['pretext'] = $deftag;
$status_editor = status_editor($a,$x,false,'Network');
$o .= $status_editor;
@@ -452,7 +455,7 @@ class Network extends \Zotlabs\Web\Controller {
}
else {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(App::$pager['itemspage']), intval(App::$pager['start']));
}
@@ -490,7 +493,6 @@ class Network extends \Zotlabs\Web\Controller {
$page_mode = 'client';
$parents_str = '';
$update_unseen = '';
$simple_update = (($update) ? " and item_unseen = 1 " : '');
@@ -529,9 +531,6 @@ class Network extends \Zotlabs\Web\Controller {
);
$parents_str = ids_to_querystr($items,'item_id');
if($parents_str) {
$update_unseen = " AND id IN ( " . dbesc($parents_str) . " )";
}
require_once('include/items.php');
@@ -595,35 +594,6 @@ class Network extends \Zotlabs\Web\Controller {
$items = array();
}
if($page_mode === 'list') {
/**
* in "list mode", only mark the parent item and any like activities as "seen".
* We won't distinguish between comment likes and post likes. The important thing
* is that the number of unseen comments will be accurate. The SQL to separate the
* comment likes could also get somewhat hairy.
*/
if($parents_str) {
$update_unseen = " AND ( id IN ( " . dbesc($parents_str) . " )";
$update_unseen .= " OR ( parent IN ( " . dbesc($parents_str) . " ) AND verb in ( '" . dbesc(ACTIVITY_LIKE) . "','" . dbesc(ACTIVITY_DISLIKE) . "' ))) ";
}
}
else {
if($parents_str) {
$update_unseen = " AND parent IN ( " . dbesc($parents_str) . " )";
}
}
}
if($update_unseen) {
$x = [ 'channel_id' => local_channel(), 'update' => 'unset' ];
call_hooks('update_unseen',$x);
if($x['update'] === 'unset' || intval($x['update'])) {
$r = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d $update_unseen ",
intval(local_channel())
);
}
}
$mode = (($nouveau) ? 'network-new' : 'network');

View File

@@ -4,6 +4,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
/**
* @brief Notes Module controller.
@@ -38,7 +39,7 @@ class Notes extends Controller {
if((argc() > 1) && (argv(1) === 'sync')) {
require_once('include/zot.php');
build_sync_packet();
Libsync::build_sync_packet();
}
logger('notes saved.', LOGGER_DEBUG);

View File

@@ -125,7 +125,7 @@ class Oep extends \Zotlabs\Web\Controller {
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
"' link='".$p[0]['plink'].
"' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') .
"' auth='".((in_array($p[0]['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') .
"' posted='".$p[0]['created'].
"' message_id='".$p[0]['mid']."']";
if($p[0]['title'])
@@ -213,7 +213,7 @@ class Oep extends \Zotlabs\Web\Controller {
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
"' link='".$p[0]['plink'].
"' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') .
"' auth='".((in_array($p[0]['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') .
"' posted='".$p[0]['created'].
"' message_id='".$p[0]['mid']."']";
if($p[0]['title'])
@@ -299,7 +299,7 @@ class Oep extends \Zotlabs\Web\Controller {
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
"' link='".$p[0]['plink'].
"' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') .
"' auth='".((in_array($p[0]['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') .
"' posted='".$p[0]['created'].
"' message_id='".$p[0]['mid']."']";
if($p[0]['title'])
@@ -374,7 +374,7 @@ class Oep extends \Zotlabs\Web\Controller {
"' profile='".$p[0]['author']['xchan_url'] .
"' avatar='".$p[0]['author']['xchan_photo_s'].
"' link='".$p[0]['plink'].
"' auth='".(($p[0]['author']['network'] === 'zot') ? 'true' : 'false') .
"' auth='".((in_array($p[0]['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') .
"' posted='".$p[0]['created'].
"' message_id='".$p[0]['mid']."']";
if($p[0]['title'])

View File

@@ -3,10 +3,12 @@
namespace Zotlabs\Module;
use Zotlabs\Web\HTTPSig;
use Zotlabs\Lib\Verify;
use Zotlabs\Web\Controller;
/**
* OpenWebAuth verifier and token generator
* See https://macgirvin.com/wiki/mike/OpenWebAuth/Home
* See spec/OpenWebAuth/Home.md
* Requests to this endpoint should be signed using HTTP Signatures
* using the 'Authorization: Signature' authentication method
* If the signature verifies a token is returned.
@@ -14,74 +16,51 @@ use Zotlabs\Web\HTTPSig;
* This token may be exchanged for an authenticated cookie.
*/
class Owa extends \Zotlabs\Web\Controller {
class Owa extends Controller {
function init() {
$ret = [ 'success' => false ];
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;
}
if (array_key_exists('REDIRECT_REMOTE_USER',$_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION',$_SERVER))) {
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER'];
}
$sigblock = HTTPSig::parse_sigheader($_SERVER[$head]);
if($sigblock) {
$keyId = $sigblock['keyId'];
if($keyId) {
// Hubzilla connections can have both zot and zot6 hublocs
// The connections will usually be zot so match those first
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) and hubloc_network = 'zot' ",
dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId)
);
// If nothing was found, try searching on any network
if (! $r) {
if (array_key_exists('HTTP_AUTHORIZATION',$_SERVER) && substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,9) === 'Signature') {
$sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']);
if ($sigblock) {
$keyId = $sigblock['keyId'];
if ($keyId) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ",
dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId)
);
if (! $r) {
$found = discover_by_webbie(str_replace('acct:','',$keyId));
if ($found) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' )",
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ",
dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId)
);
}
// If nothing was found on any network, use network discovery and create a new record
if (! $r) {
$found = discover_by_webbie(str_replace('acct:','',$keyId));
if($found) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ",
dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId)
);
}
}
if ($r) {
foreach($r as $hubloc) {
$verified = HTTPSig::verify(file_get_contents('php://input'),$hubloc['xchan_pubkey']);
if($verified && $verified['header_signed'] && $verified['header_valid']) {
logger('OWA header: ' . print_r($verified,true),LOGGER_DATA);
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
$ret['success'] = true;
$token = random_string(32);
\Zotlabs\Lib\Verify::create('owt',0,$token,$hubloc['hubloc_network'] . ',' . $hubloc['hubloc_addr']);
$result = '';
openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']);
$ret['encrypted_token'] = base64url_encode($result);
break;
}
else {
logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_addr']);
}
}
if ($r) {
foreach ($r as $hubloc) {
$verified = HTTPSig::verify(file_get_contents('php://input'));
if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) {
logger('OWA header: ' . print_r($verified,true),LOGGER_DATA);
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
$ret['success'] = true;
$token = random_string(32);
Verify::create('owt',0,$token,$hubloc['hubloc_addr']);
$result = '';
openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']);
$ret['encrypted_token'] = base64url_encode($result);
break;
} else {
logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_addr']);
}
}
}

View File

@@ -1,7 +1,7 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
@@ -38,7 +38,7 @@ class Pconfig extends \Zotlabs\Web\Controller {
}
set_pconfig(local_channel(),$cat,$k,$v);
build_sync_packet();
Libsync::build_sync_packet();
if($aj)
killme();

View File

@@ -4,6 +4,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
class Pdledit extends Controller {
@@ -22,7 +23,7 @@ class Pdledit extends Controller {
goaway(z_root() . '/pdledit');
}
set_pconfig(local_channel(),'system','mod_' . $_REQUEST['module'] . '.pdl',escape_tags($_REQUEST['content']));
build_sync_packet();
Libsync::build_sync_packet();
info( t('Layout updated.') . EOL);
goaway(z_root() . '/pdledit/' . $_REQUEST['module']);
}

View File

@@ -5,6 +5,7 @@ namespace Zotlabs\Module;
use App;
use Zotlabs\Web\Controller;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
class Permcats extends Controller {
@@ -42,7 +43,7 @@ class Permcats extends Controller {
\Zotlabs\Lib\Permcat::update(local_channel(),$name,$pcarr);
build_sync_packet();
Libsync::build_sync_packet();
info( t('Permission category saved.') . EOL);
@@ -71,7 +72,7 @@ class Permcats extends Controller {
if(argc() > 2 && argv(2) === 'drop') {
\Zotlabs\Lib\Permcat::delete(local_channel(),$name);
build_sync_packet();
Libsync::build_sync_packet();
json_return_and_die([ 'success' => true ]);
}

View File

@@ -67,18 +67,20 @@ class Photo extends \Zotlabs\Web\Controller {
$data = '';
$r = q("SELECT * FROM photo WHERE imgscale = %d AND uid = %d AND photo_usage = %d LIMIT 1",
intval($resolution),
intval($uid),
intval(PHOTO_PROFILE)
);
if($r) {
$modified = strtotime($r[0]['edited'] . "Z");
$mimetype = $r[0]['mimetype'];
if(intval($r[0]['os_storage']))
$data = file_get_contents(dbunescbin($r[0]['content']));
else
$data = dbunescbin($r[0]['content']);
if ($uid > 0) {
$r = q("SELECT * FROM photo WHERE imgscale = %d AND uid = %d AND photo_usage = %d LIMIT 1",
intval($resolution),
intval($uid),
intval(PHOTO_PROFILE)
);
if($r) {
$modified = strtotime($r[0]['edited'] . "Z");
$mimetype = $r[0]['mimetype'];
if(intval($r[0]['os_storage']))
$data = file_get_contents(dbunescbin($r[0]['content']));
else
$data = dbunescbin($r[0]['content']);
}
}
if(! $data) {
@@ -213,7 +215,7 @@ class Photo extends \Zotlabs\Web\Controller {
if(! $data)
killme();
$etag = '"' . md5($data . $modified) . '"';
if($modified == 0)
@@ -269,7 +271,7 @@ class Photo extends \Zotlabs\Web\Controller {
// in the event that infrastructure caching is present.
$smaxage = intval($maxage/12);
header("Cache-Control: s-maxage=" . $smaxage . ", max-age=" . $maxage . $cachecontrol);
header("Cache-Control: no-cache, s-maxage=" . $smaxage . ", max-age=" . $maxage . $cachecontrol);
}

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
require_once('include/photo/photo_driver.php');
require_once('include/photos.php');
require_once('include/items.php');
@@ -162,7 +164,7 @@ class Photos extends \Zotlabs\Web\Controller {
$sync = attach_export_data(\App::$data['channel'],$folder_hash, true);
if($sync)
build_sync_packet($page_owner_uid,array('file' => array($sync)));
Libsync::build_sync_packet($page_owner_uid,array('file' => array($sync)));
}
}
@@ -189,7 +191,7 @@ class Photos extends \Zotlabs\Web\Controller {
$sync = attach_export_data(\App::$data['channel'],$r[0]['resource_id'], true);
if($sync)
build_sync_packet($page_owner_uid,array('file' => array($sync)));
Libsync::build_sync_packet($page_owner_uid,array('file' => array($sync)));
}
elseif(is_site_admin()) {
// If the admin deletes a photo, don't sync
@@ -208,9 +210,9 @@ class Photos extends \Zotlabs\Web\Controller {
if(($m) && ($m[0]['folder'] != $_POST['move_to_album'])) {
attach_move($page_owner_uid,argv(2),$_POST['move_to_album']);
$sync = attach_export_data(\App::$data['channel'],argv(2),true);
$sync = attach_export_data(\App::$data['channel'], argv(2), false);
if($sync)
build_sync_packet($page_owner_uid,array('file' => array($sync)));
Libsync::build_sync_packet($page_owner_uid,array('file' => array($sync)));
if(! ($_POST['desc'] && $_POST['newtag']))
goaway(z_root() . '/' . $_SESSION['photo_return']);
@@ -420,7 +422,7 @@ class Photos extends \Zotlabs\Web\Controller {
$sync = attach_export_data(\App::$data['channel'],$resource_id);
if($sync)
build_sync_packet($page_owner_uid,array('file' => array($sync)));
Libsync::build_sync_packet($page_owner_uid,array('file' => array($sync)));
goaway(z_root() . '/' . $_SESSION['photo_return']);
return; // NOTREACHED
@@ -706,7 +708,7 @@ class Photos extends \Zotlabs\Web\Controller {
]);
if($x = photos_album_exists($owner_uid, get_observer_hash(), $datum)) {
\App::set_pager_itemspage(60);
\App::set_pager_itemspage(30);
$album = $x['display_path'];
}
else {
@@ -1287,7 +1289,7 @@ class Photos extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n";
\App::set_pager_itemspage(60);
\App::set_pager_itemspage(30);
$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created, p.display_path
FROM photo p

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
/*
* @file Profile_photo.php
* @brief Module-file with functions for handling of profile-photos
@@ -73,7 +75,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$sync = attach_export_data($channel,$r[0]['resource_id']);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync:: build_sync_packet($channel['channel_id'],array('file' => array($sync)));
}
$_SESSION['reload_avatar'] = true;
@@ -243,7 +245,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$sync = attach_export_data($channel,$base_image['resource_id']);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync), 'profile' => $sync_profiles));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync), 'profile' => $sync_profiles));
// Similarly, tell the nav bar to bypass the cache and update the avatar image.
@@ -411,7 +413,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$sync = attach_export_data($channel,$resource_id);
if($sync)
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
Libsync::build_sync_packet($channel['channel_id'],array('file' => array($sync)));
$_SESSION['reload_avatar'] = true;

View File

@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libsync;
require_once('include/channel.php');
require_once('include/selectors.php');
@@ -599,16 +601,16 @@ class Profiles extends \Zotlabs\Web\Controller {
);
if($r) {
require_once('include/zot.php');
build_sync_packet(local_channel(),array('profile' => $r));
Libsync::build_sync_packet(local_channel(),array('profile' => $r));
}
$channel = \App::get_channel();
if($namechanged && $is_default) {
$r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_hash = '%s'",
$r = q("UPDATE xchan SET xchan_name = '%s', xchan_name_date = '%s' WHERE xchan_url = '%s'",
dbesc($name),
dbesc(datetime_convert()),
dbesc($channel['xchan_hash'])
dbesc(z_root() . '/channel/' . $channel['channel_address'])
);
$r = q("UPDATE channel SET channel_name = '%s' WHERE channel_hash = '%s'",
dbesc($name),

View File

@@ -169,7 +169,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
$pager_sql = '';
}
else {
\App::set_pager_itemspage(20);
\App::set_pager_itemspage(10);
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
}
@@ -264,7 +264,6 @@ class Pubstream extends \Zotlabs\Web\Controller {
// Then fetch all the children of the parents that are on this page
$parents_str = '';
$update_unseen = '';
if($r) {

View File

@@ -1,6 +1,9 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Zotfinger;
use Zotlabs\Web\Controller;
/**
* With args, register a directory server for this realm.
* With no args, return a JSON array of directory servers for this realm.
@@ -14,7 +17,7 @@ namespace Zotlabs\Module;
* @param App &$a
*/
class Regdir extends \Zotlabs\Web\Controller {
class Regdir extends Controller {
function init() {
@@ -25,7 +28,7 @@ class Regdir extends \Zotlabs\Web\Controller {
$valid = 0;
// we probably don't need the realm as we will find out in the probe.
// What we may want to die is throw an error if you're trying to register in a different realm
// What we may want to do is throw an error if you're trying to register in a different realm
// so this configuration issue can be discovered.
$realm = $_REQUEST['realm'];
@@ -59,34 +62,28 @@ class Regdir extends \Zotlabs\Web\Controller {
json_return_and_die($result);
}
$j = \Zotlabs\Zot\Finger::run('[system]@' . $m['host']);
if($j['success'] && $j['guid']) {
$x = import_xchan($j);
if($x['success']) {
$result['success'] = true;
}
$j = Zotfinger::exec($url);
if($j) {
$result['success'] = true;
}
if(! $result['success'])
else {
$valid = 0;
}
q("update site set site_valid = %d where site_url = '%s'",
intval($valid),
strtolower($url)
);
json_return_and_die($result);
} else {
}
else {
// We can put this in the sql without the condition after 31 august 2015 assuming
// most directory servers will have updated by then
// This just makes sure it happens if I forget
$sql_extra = ((datetime_convert() > datetime_convert('UTC','UTC','2015-08-31')) ? ' and site_valid = 1 ' : '' );
if ($dirmode == DIRECTORY_MODE_STANDALONE) {
$r = array(array('site_url' => z_root()));
} else {
$r = q("select site_url from site where site_flags in ( 1, 2 ) and site_realm = '%s' and site_type = %d $sql_extra ",
$r = q("select site_url from site where site_flags in ( 1, 2 ) and site_realm = '%s' and site_type = %d and site_valid = 1 ",
dbesc(get_directory_realm()),
intval(SITE_TYPE_ZOT)
);

View File

@@ -118,7 +118,7 @@ class Register extends Controller {
$invite_code = ((x($_POST,'invite_code')) ? notags(trim($_POST['invite_code'])) : '');
if($using_invites && $invite_code) {
q("delete * from register where hash = '%s'", dbesc($invite_code));
q("delete from register where hash = '%s'", dbesc($invite_code));
// @FIXME - this also needs to be considered when using 'invites_remaining' in mod/invite.php
set_aconfig($result['account']['account_id'],'system','invites_remaining',$num_invites);
}

View File

@@ -37,7 +37,7 @@ class Removeaccount extends \Zotlabs\Web\Controller {
}
}
$global_remove = intval($_POST['global']);
$global_remove = 0; //intval($_POST['global']);
account_remove($account_id, 1 - $global_remove);
}
@@ -57,7 +57,7 @@ class Removeaccount extends \Zotlabs\Web\Controller {
'$title' => t('Remove This Account'),
'$desc' => array(t('WARNING: '), t('This account and all its channels will be completely removed from the network. '), t('This action is permanent and can not be undone!')),
'$passwd' => t('Please enter your password for verification:'),
'$global' => array('global', t('Remove this account, all its channels and all its channel clones from the network'), false, t('By default only the instances of the channels located on this hub will be removed from the network')),
// '$global' => array('global', t('Remove this account, all its channels and all its channel clones from the network'), false, t('By default only the instances of the channels located on this hub will be removed from the network')),
'$submit' => t('Remove Account')
));

View File

@@ -37,7 +37,7 @@ class Removeme extends \Zotlabs\Web\Controller {
}
}
$global_remove = intval($_POST['global']);
$global_remove = 0; //intval($_POST['global']);
channel_remove(local_channel(),1 - $global_remove,true);
@@ -60,7 +60,7 @@ class Removeme extends \Zotlabs\Web\Controller {
'$title' => t('Remove This Channel'),
'$desc' => [ t('WARNING: '), t('This channel will be completely removed from the network. '), t('This action is permanent and can not be undone!') ],
'$passwd' => t('Please enter your password for verification:'),
'$global' => [ 'global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network'), [ t('No'),t('Yes') ] ],
// '$global' => [ 'global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network'), [ t('No'),t('Yes') ] ],
'$submit' => t('Remove Channel')
));

View File

@@ -1,6 +1,7 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Lib\Libzot;
class Rmagic extends \Zotlabs\Web\Controller {
@@ -11,23 +12,24 @@ class Rmagic extends \Zotlabs\Web\Controller {
$me = get_my_address();
if($me) {
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1",
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
dbesc($me)
);
if(! $r) {
$w = discover_by_webbie($me);
if($w) {
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1",
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
dbesc($me)
);
}
}
if($r) {
if($r[0]['hubloc_url'] === z_root())
if($r) {
$r = Libzot::zot_record_preferred($r);
if($r['hubloc_url'] === z_root())
goaway(z_root() . '/login');
$dest = bin2hex(z_root() . '/' . str_replace(['rmagic','zid='],['','zid_='],\App::$query_string));
goaway($r[0]['hubloc_url'] . '/magic' . '?f=&owa=1&bdest=' . $dest);
goaway($r['hubloc_url'] . '/magic' . '?f=&owa=1&bdest=' . $dest);
}
}
}
@@ -55,13 +57,13 @@ class Rmagic extends \Zotlabs\Web\Controller {
$r = null;
if($address) {
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1",
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
dbesc($address)
);
if(! $r) {
$w = discover_by_webbie($address);
if($w) {
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s' limit 1",
$r = q("select hubloc_url from hubloc where hubloc_addr = '%s'",
dbesc($address)
);
}
@@ -69,7 +71,8 @@ class Rmagic extends \Zotlabs\Web\Controller {
}
if($r) {
$url = $r[0]['hubloc_url'];
$r = Libzot::zot_record_preferred($r);
$url = $r['hubloc_url'];
}
else {
$url = 'https://' . substr($address,strpos($address,'@')+1);

View File

@@ -159,7 +159,7 @@ class Search extends \Zotlabs\Web\Controller {
if(($update) && ($load)) {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 10));
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
// in case somebody turned off public access to sys channel content with permissions

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Calendar {
@@ -15,7 +16,7 @@ class Calendar {
process_module_features_post(local_channel(), $features, $_POST);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['rpath'])
goaway($_POST['rpath']);

View File

@@ -3,6 +3,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Apps;
use Zotlabs\Lib\Libsync;
require_once('include/selectors.php');
@@ -273,10 +274,11 @@ class Channel {
}
if($name_change) {
$r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
// change name on all associated xchans by matching the url
$r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_url = '%s'",
dbesc($username),
dbesc(datetime_convert()),
dbesc($channel['channel_hash'])
dbesc(z_root() . '/channel/' . $channel['channel_address'])
);
$r = q("update profile set fullname = '%s' where uid = %d and is_default = 1",
dbesc($username),
@@ -286,7 +288,7 @@ class Channel {
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
build_sync_packet();
Libsync::build_sync_packet();
if($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) {

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
require_once('include/menu.php');
class Channel_home {
@@ -24,7 +26,7 @@ class Channel_home {
$channel_menu = ((x($_POST['channel_menu'])) ? htmlspecialchars_decode(trim($_POST['channel_menu']),ENT_QUOTES) : '');
set_pconfig(local_channel(),'system','channel_menu',$channel_menu);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['rpath'])
goaway($_POST['rpath']);

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Connections {
@@ -15,7 +16,7 @@ class Connections {
process_module_features_post(local_channel(), $features, $_POST);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['rpath'])
goaway($_POST['rpath']);

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Conversation {
@@ -15,7 +16,7 @@ class Conversation {
process_module_features_post(local_channel(), $features, $_POST);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['aj']) {
if($_POST['auto_update'] == 1)

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Directory {
@@ -15,7 +16,7 @@ class Directory {
process_module_features_post(local_channel(), $features, $_POST);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['rpath'])
goaway($_POST['rpath']);

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Display {
@@ -35,9 +36,9 @@ class Display {
if($browser_update < 10000)
$browser_update = 10000;
$itemspage = ((x($_POST,'itemspage')) ? intval($_POST['itemspage']) : 20);
if($itemspage > 100)
$itemspage = 100;
$itemspage = ((x($_POST,'itemspage')) ? intval($_POST['itemspage']) : 10);
if($itemspage > 30)
$itemspage = 30;
set_pconfig(local_channel(),'system','preload_images',$preload_images);
@@ -78,7 +79,7 @@ class Display {
);
call_hooks('display_settings_post', $_POST);
build_sync_packet();
Libsync::build_sync_packet();
goaway(z_root() . '/settings/display' );
return; // NOTREACHED
}
@@ -158,7 +159,7 @@ class Display {
$browser_update = (($browser_update == 0) ? 80 : $browser_update / 1000); // default if not set: 40 seconds
$itemspage = intval(get_pconfig(local_channel(), 'system','itemspage'));
$itemspage = (($itemspage > 0 && $itemspage < 101) ? $itemspage : 20); // default if not set: 20 items
$itemspage = (($itemspage > 0 && $itemspage <= 30) ? $itemspage : 10); // default if not set: 10 items
$nosmile = get_pconfig(local_channel(),'system','no_smilies');
$nosmile = (($nosmile===false)? '0': $nosmile); // default if not set: 0
@@ -196,7 +197,7 @@ class Display {
'$preload_images' => array('preload_images', t("Preload images before rendering the page"), $preload_images, t("The subjective page load time will be longer but the page will be ready when displayed"), $yes_no),
'$user_scalable' => array('user_scalable', t("Enable user zoom on mobile devices"), $user_scalable, '', $yes_no),
'$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')),
'$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 100 items')),
'$itemspage' => array('itemspage', t("Maximum number of conversations to load at any time:"), $itemspage, t('Maximum of 30 items')),
'$nosmile' => array('nosmile', t("Show emoticons (smilies) as images"), 1-intval($nosmile), '', $yes_no),
'$channel_menu' => [ 'channel_menu', t('Provide channel menu in navigation bar'), get_pconfig(local_channel(),'system','channel_menu',get_config('system','channel_menu',0)), t('Default: channel menu located in app menu'),$yes_no ],
'$manual_update' => array('manual_update', t('Manual conversation updates'), channel_manual_conv_update(local_channel()), t('Default is on, turning this off may increase screen jumping'), $yes_no),

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Editor {
@@ -15,7 +16,7 @@ class Editor {
process_module_features_post(local_channel(), $features, $_POST);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['rpath'])
goaway($_POST['rpath']);

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Events {
@@ -15,7 +16,7 @@ class Events {
process_module_features_post(local_channel(), $features, $_POST);
build_sync_packet();
Libsync::build_sync_packet();
if($_POST['rpath'])
goaway($_POST['rpath']);

View File

@@ -2,6 +2,7 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Featured {
@@ -10,7 +11,7 @@ class Featured {
call_hooks('feature_settings_post', $_POST);
build_sync_packet();
Libsync::build_sync_packet();
return;
}

View File

@@ -2,6 +2,8 @@
namespace Zotlabs\Module\Settings;
use Zotlabs\Lib\Libsync;
class Features {
@@ -19,7 +21,7 @@ class Features {
set_pconfig(local_channel(),'feature', $k, '');
}
}
build_sync_packet();
Libsync::build_sync_packet();
return;
}

Some files were not shown because too many files have changed in this diff Show More