Merge remote-tracking branch 'upstream/master'

This commit is contained in:
zottel 2015-09-18 09:38:55 +02:00
commit 4d05d477f8
20 changed files with 392 additions and 361 deletions

View File

@ -13,7 +13,7 @@ Zot is a revolutionary protocol which provides [i]decentralised communications[/
Communications and social networking are an integral part of the grid. Any channel (and any services provided by that channel) can make full use of feature-rich social communications on a global scale. These communications may be public or private - and private communications comprise not only fully encrypted transport, but also encrypted storage to help protect against accidental snooping and disclosure by rogue system administrators and internet service providers.
Zot allows a wide array of background services in the grid, from offering friend suggestions, to directory services. You can also perform other things which would typically only be possibly on a centralized provider - such as "Wall to Wall" posts. Priivate/multiple profiles can be easily created, and web content can be tailored to the viewer via the [i]Affinity Slider[/i].
Zot allows a wide array of background services in the grid, from offering friend suggestions, to directory services. You can also perform other things which would typically only be possibly on a centralized provider - such as "Wall to Wall" posts. Private/multiple profiles can be easily created, and web content can be tailored to the viewer via the [i]Affinity Slider[/i].
You won't find these features at all on other decentralized communication services. In addition to providing hub (server) decentralization, perhaps the most innovative and interesting Zot feature is its provision of [i]decentralized identity[/i] services.

View File

@ -1053,11 +1053,14 @@ function discover_by_webbie($webbie) {
$webbie = strtolower($webbie);
$x = webfinger_rfc7033($webbie);
$x = webfinger_rfc7033($webbie,true);
if($x && array_key_exists('links',$x) && $x['links']) {
foreach($x['links'] as $link) {
if(array_key_exists('rel',$link) && $link['rel'] == 'http://purl.org/zot/protocol') {
logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
if(array_key_exists('zot',$x) && $x['zot']['success'])
$i = import_xchan($x['zot']);
else {
$z = z_fetch_url($link['href']);
if($z['success']) {
$j = json_decode($z['body'],true);
@ -1067,6 +1070,7 @@ function discover_by_webbie($webbie) {
}
}
}
}
$arr = array('address' => $webbie, 'success' => false);
call_hooks('discover_by_webbie', $arr);
@ -1282,7 +1286,7 @@ LSIeXnd14lQYK/uxW/8cTFjcmddsKxeXysoQxbSa9VdDK+KkpZdgYXYrTTofXs6v+
}
function webfinger_rfc7033($webbie) {
function webfinger_rfc7033($webbie,$zot = false) {
if(! strpos($webbie,'@'))
@ -1292,7 +1296,7 @@ function webfinger_rfc7033($webbie) {
$resource = 'acct:' . $webbie;
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?resource=' . $resource);
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''));
if($s['success'])
$j = json_decode($s['body'],true);

View File

@ -3404,3 +3404,291 @@ function zot_process_message_request($data) {
return $ret;
}
function zotinfo($arr) {
$ret = array('success' => false);
$zhash = ((x($arr,'guid_hash')) ? $arr['guid_hash'] : '');
$zguid = ((x($arr,'guid')) ? $arr['guid'] : '');
$zguid_sig = ((x($arr,'guid_sig')) ? $arr['guid_sig'] : '');
$zaddr = ((x($arr,'address')) ? $arr['address'] : '');
$ztarget = ((x($arr,'target')) ? $arr['target'] : '');
$zsig = ((x($arr,'target_sig')) ? $arr['target_sig'] : '');
$zkey = ((x($arr,'key')) ? $arr['key'] : '');
$mindate = ((x($arr,'mindate')) ? $arr['mindate'] : '');
$feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0);
if($ztarget) {
if((! $zkey) || (! $zsig) || (! rsa_verify($ztarget,base64url_decode($zsig),$zkey))) {
logger('zfinger: invalid target signature');
$ret['message'] = t("invalid target signature");
return($ret);
}
}
$r = null;
if(strlen($zhash)) {
$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_hash = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($zguid),
dbesc($zguid_sig)
);
}
elseif(strlen($zaddr)) {
if(strpos($zaddr,'[system]') === false) { /* normal address lookup */
$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)
);
}
else {
/**
* The special address '[system]' will return a system channel if one has been defined,
* Or the first valid channel we find if there are no system channels.
*
* This is used by magic-auth if we have no prior communications with this site - and
* returns an identity on this site which we can use to create a valid hub record so that
* we can exchange signed messages. The precise identity is irrelevant. It's the hub
* information that we really need at the other end - and this will return it.
*
*/
$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_hash = xchan_hash
where channel_removed = 0 order by channel_id limit 1");
}
}
}
else {
$ret['message'] = 'Invalid request';
return($ret);
}
if(! $r) {
$ret['message'] = 'Item not found.';
return($ret);
}
$e = $r[0];
$id = $e['channel_id'];
$sys_channel = (intval($e['channel_system']) ? true : false);
$special_channel = (($e['channel_pageflags'] & PAGE_PREMIUM) ? true : false);
$adult_channel = (($e['channel_pageflags'] & PAGE_ADULT) ? true : false);
$censored = (($e['channel_pageflags'] & PAGE_CENSORED) ? true : false);
$searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true);
$deleted = (intval($e['xchan_deleted']) ? true : false);
if($deleted || $censored || $sys_channel)
$searchable = false;
$public_forum = false;
$role = get_pconfig($e['channel_id'],'system','permissions_role');
if($role === 'forum' || $role === 'repository') {
$public_forum = true;
}
else {
// check if it has characteristics of a public forum based on custom permissions.
$t = q("select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1",
intval($e['channel_id'])
);
if(($t) && (($t[0]['abook_my_perms'] & PERMS_W_TAGWALL) && (! ($t[0]['abook_my_perms'] & PERMS_W_STREAM))))
$public_forum = true;
}
// This is for birthdays and keywords, but must check access permissions
$p = q("select * from profile where uid = %d and is_default = 1",
intval($e['channel_id'])
);
$profile = array();
if($p) {
if(! intval($p[0]['publish']))
$searchable = false;
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== ''))
$profile['next_birthday'] = $bd;
if($age = age($p[0]['dob'],$e['channel_timezone'],''))
$profile['age'] = $age;
$profile['gender'] = $p[0]['gender'];
$profile['marital'] = $p[0]['marital'];
$profile['sexual'] = $p[0]['sexual'];
$profile['locale'] = $p[0]['locality'];
$profile['region'] = $p[0]['region'];
$profile['postcode'] = $p[0]['postal_code'];
$profile['country'] = $p[0]['country_name'];
$profile['about'] = $p[0]['about'];
$profile['homepage'] = $p[0]['homepage'];
$profile['hometown'] = $p[0]['hometown'];
if($p[0]['keywords']) {
$tags = array();
$k = explode(' ',$p[0]['keywords']);
if($k) {
foreach($k as $kk) {
if(trim($kk," \t\n\r\0\x0B,")) {
$tags[] = trim($kk," \t\n\r\0\x0B,");
}
}
}
if($tags)
$profile['keywords'] = $tags;
}
}
$ret['success'] = true;
// Communication details
$ret['guid'] = $e['xchan_guid'];
$ret['guid_sig'] = $e['xchan_guid_sig'];
$ret['key'] = $e['xchan_pubkey'];
$ret['name'] = $e['xchan_name'];
$ret['name_updated'] = $e['xchan_name_date'];
$ret['address'] = $e['xchan_addr'];
$ret['photo_mimetype'] = $e['xchan_photo_mimetype'];
$ret['photo'] = $e['xchan_photo_l'];
$ret['photo_updated'] = $e['xchan_photo_date'];
$ret['url'] = $e['xchan_url'];
$ret['connections_url']= (($e['xchan_connurl']) ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']);
$ret['target'] = $ztarget;
$ret['target_sig'] = $zsig;
$ret['searchable'] = $searchable;
$ret['adult_content'] = $adult_channel;
$ret['public_forum'] = $public_forum;
if($deleted)
$ret['deleted'] = $deleted;
// premium or other channel desiring some contact with potential followers before connecting.
// This is a template - %s will be replaced with the follow_url we discover for the return channel.
if($special_channel)
$ret['connect_url'] = z_root() . '/connect/' . $e['channel_address'];
// This is a template for our follow url, %s will be replaced with a webbie
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
$ztarget_hash = (($ztarget && $zsig)
? make_xchan_hash($ztarget,$zsig)
: '' );
$permissions = get_all_perms($e['channel_id'],$ztarget_hash,false);
if($ztarget_hash) {
$permissions['connected'] = false;
$b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($ztarget_hash),
intval($e['channel_id'])
);
if($b)
$permissions['connected'] = true;
}
$ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey) : $permissions);
if($permissions['view_profile'])
$ret['profile'] = $profile;
// array of (verified) hubs this channel uses
$x = zot_encode_locations($e);
if($x)
$ret['locations'] = $x;
$ret['site'] = array();
$ret['site']['url'] = z_root();
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
$dirmode = get_config('system','directory_mode');
if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL))
$ret['site']['directory_mode'] = 'normal';
if($dirmode == DIRECTORY_MODE_PRIMARY)
$ret['site']['directory_mode'] = 'primary';
elseif($dirmode == DIRECTORY_MODE_SECONDARY)
$ret['site']['directory_mode'] = 'secondary';
elseif($dirmode == DIRECTORY_MODE_STANDALONE)
$ret['site']['directory_mode'] = 'standalone';
if($dirmode != DIRECTORY_MODE_NORMAL)
$ret['site']['directory_url'] = z_root() . '/dirsearch';
// hide detailed site information if you're off the grid
if($dirmode != DIRECTORY_MODE_STANDALONE) {
$register_policy = intval(get_config('system','register_policy'));
if($register_policy == REGISTER_CLOSED)
$ret['site']['register_policy'] = 'closed';
if($register_policy == REGISTER_APPROVE)
$ret['site']['register_policy'] = 'approve';
if($register_policy == REGISTER_OPEN)
$ret['site']['register_policy'] = 'open';
$access_policy = intval(get_config('system','access_policy'));
if($access_policy == ACCESS_PRIVATE)
$ret['site']['access_policy'] = 'private';
if($access_policy == ACCESS_PAID)
$ret['site']['access_policy'] = 'paid';
if($access_policy == ACCESS_FREE)
$ret['site']['access_policy'] = 'free';
if($access_policy == ACCESS_TIERED)
$ret['site']['access_policy'] = 'tiered';
$ret['site']['accounts'] = account_total();
require_once('include/identity.php');
$ret['site']['channels'] = channel_total();
$ret['site']['version'] = PLATFORM_NAME . ' ' . RED_VERSION . '[' . DB_UPDATE_VERSION . ']';
$ret['site']['admin'] = get_config('system','admin_email');
$a = get_app();
$visible_plugins = array();
if(is_array($a->plugins) && count($a->plugins)) {
$r = q("select * from addon where hidden = 0");
if($r)
foreach($r as $rr)
$visible_plugins[] = $rr['name'];
}
$ret['site']['plugins'] = $visible_plugins;
$ret['site']['sitehash'] = get_config('system','location_hash');
$ret['site']['sitename'] = get_config('system','sitename');
$ret['site']['sellpage'] = get_config('system','sellpage');
$ret['site']['location'] = get_config('system','site_location');
$ret['site']['realm'] = get_directory_realm();
}
call_hooks('zot_finger',$ret);
return($ret);
}

View File

@ -125,8 +125,7 @@ function mail_content(&$a) {
$tpl = get_markup_template('mail_head.tpl');
$header = replace_macros($tpl, array(
'$messages' => t('Messages'),
'$tab_content' => $tab_content
'$header' => t('Messages'),
));
if((argc() == 3) && (argv(1) === 'drop')) {
@ -160,8 +159,6 @@ function mail_content(&$a) {
if((argc() > 1) && (argv(1) === 'new')) {
$o .= $header;
$plaintext = true;
$tpl = get_markup_template('msg-header.tpl');

View File

@ -25,11 +25,7 @@ function message_content(&$a) {
$cipher = 'aes256';
$tpl = get_markup_template('mail_head.tpl');
$header = replace_macros($tpl, array(
'$messages' => t('Messages'),
'$tab_content' => $tab_content
));
if((argc() == 3) && (argv(1) === 'dropconv')) {
if(! intval(argv(2)))
@ -42,9 +38,6 @@ function message_content(&$a) {
}
if(argc() == 1) {
// list messages
$o .= $header;
// private_messages_list() can do other more complicated stuff, for now keep it simple
@ -55,24 +48,33 @@ function message_content(&$a) {
return $o;
}
$tpl = get_markup_template('mail_list.tpl');
foreach($r as $rr) {
$messages = array();
$o .= replace_macros($tpl, array(
'$id' => $rr['id'],
'$from_name' => $rr['from']['xchan_name'],
'$from_url' => chanlink_hash($rr['from_xchan']),
'$from_photo' => $rr['from']['xchan_photo_s'],
'$to_name' => $rr['to']['xchan_name'],
'$to_url' => chanlink_hash($rr['to_xchan']),
'$to_photo' => $rr['to']['xchan_photo_s'],
'$subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
'$delete' => t('Delete conversation'),
'$body' => smilies(bbcode($rr['body'])),
'$date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')),
'$seen' => $rr['seen']
));
foreach($r as $rr) {
$messages[] = array(
'id' => $rr['id'],
'from_name' => $rr['from']['xchan_name'],
'from_url' => chanlink_hash($rr['from_xchan']),
'from_photo' => $rr['from']['xchan_photo_s'],
'to_name' => $rr['to']['xchan_name'],
'to_url' => chanlink_hash($rr['to_xchan']),
'to_photo' => $rr['to']['xchan_photo_s'],
'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
'delete' => t('Delete conversation'),
'body' => smilies(bbcode($rr['body'])),
'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')),
'seen' => $rr['seen']
);
}
$tpl = get_markup_template('mail_head.tpl');
$o = replace_macros($tpl, array(
'$header' => t('Messages'),
'$messages' => $messages
));
$o .= alt_pager($a,count($r));
return $o;
}

View File

@ -15,7 +15,7 @@ function webfinger_content(&$a) {
if(x($_GET,'addr')) {
$addr = trim($_GET['addr']);
if(strpos($addr,'@') !== false) {
$res = webfinger_rfc7033($addr);
$res = webfinger_rfc7033($addr,true);
if(! $res)
$res = old_webfinger($addr);
}

View File

@ -1,5 +1,7 @@
<?php
require_once('include/zot.php');
function wfinger_init(&$a) {
$result = array();
@ -11,14 +13,13 @@ function wfinger_init(&$a) {
elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443))
$scheme = 'https';
// Don't complain to me - I'm just implementing the spec.
$zot = intval($_REQUEST['zot']);
if($scheme !== 'https') {
if(($scheme !== 'https') && (! $zot)) {
header($_SERVER["SERVER_PROTOCOL"] . ' ' . 500 . ' ' . 'Webfinger requires HTTPS');
killme();
}
$zot = intval($_REQUEST['zot']);
$resource = $_REQUEST['resource'];
logger('webfinger: ' . $resource,LOGGER_DEBUG);
@ -48,7 +49,6 @@ function wfinger_init(&$a) {
}
header('Access-Control-Allow-Origin: *');
header('Content-type: application/jrd+json');
@ -107,11 +107,8 @@ function wfinger_init(&$a) {
);
if($zot) {
// @FIXME do a lookup straightaway and return the zot-info packet
$_REQUEST['address'] = $r[0]['xchan_address'];
// get a zotinfo packet and return it with webfinger
$result['zot'] = zotinfo(array('address' => $r[0]['xchan_addr']));
}
}
else {

View File

@ -5,286 +5,9 @@ function zfinger_init(&$a) {
require_once('include/zot.php');
require_once('include/crypto.php');
$ret = array('success' => false);
$zhash = ((x($_REQUEST,'guid_hash')) ? $_REQUEST['guid_hash'] : '');
$zguid = ((x($_REQUEST,'guid')) ? $_REQUEST['guid'] : '');
$zguid_sig = ((x($_REQUEST,'guid_sig')) ? $_REQUEST['guid_sig'] : '');
$zaddr = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : '');
$ztarget = ((x($_REQUEST,'target')) ? $_REQUEST['target'] : '');
$zsig = ((x($_REQUEST,'target_sig')) ? $_REQUEST['target_sig'] : '');
$zkey = ((x($_REQUEST,'key')) ? $_REQUEST['key'] : '');
$mindate = ((x($_REQUEST,'mindate')) ? $_REQUEST['mindate'] : '');
$feed = ((x($_REQUEST,'feed')) ? intval($_REQUEST['feed']) : 0);
$x = zotinfo($_REQUEST);
json_return_and_die($x);
if($ztarget) {
if((! $zkey) || (! $zsig) || (! rsa_verify($ztarget,base64url_decode($zsig),$zkey))) {
logger('zfinger: invalid target signature');
$ret['message'] = t("invalid target signature");
json_return_and_die($ret);
}
}
$r = null;
if(strlen($zhash)) {
$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_hash = xchan_hash
where channel_guid = '%s' and channel_guid_sig = '%s' limit 1",
dbesc($zguid),
dbesc($zguid_sig)
);
}
elseif(strlen($zaddr)) {
if(strpos($zaddr,'[system]') === false) { /* normal address lookup */
$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)
);
}
else {
/**
* The special address '[system]' will return a system channel if one has been defined,
* Or the first valid channel we find if there are no system channels.
*
* This is used by magic-auth if we have no prior communications with this site - and
* returns an identity on this site which we can use to create a valid hub record so that
* we can exchange signed messages. The precise identity is irrelevant. It's the hub
* information that we really need at the other end - and this will return it.
*
*/
$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_hash = xchan_hash
where channel_removed = 0 order by channel_id limit 1");
}
}
}
else {
$ret['message'] = 'Invalid request';
json_return_and_die($ret);
}
if(! $r) {
$ret['message'] = 'Item not found.';
json_return_and_die($ret);
}
$e = $r[0];
$id = $e['channel_id'];
$sys_channel = (intval($e['channel_system']) ? true : false);
$special_channel = (($e['channel_pageflags'] & PAGE_PREMIUM) ? true : false);
$adult_channel = (($e['channel_pageflags'] & PAGE_ADULT) ? true : false);
$censored = (($e['channel_pageflags'] & PAGE_CENSORED) ? true : false);
$searchable = (($e['channel_pageflags'] & PAGE_HIDDEN) ? false : true);
$deleted = (intval($e['xchan_deleted']) ? true : false);
if($deleted || $censored || $sys_channel)
$searchable = false;
$public_forum = false;
$role = get_pconfig($e['channel_id'],'system','permissions_role');
if($role === 'forum' || $role === 'repository') {
$public_forum = true;
}
else {
// check if it has characteristics of a public forum based on custom permissions.
$t = q("select abook_my_perms from abook where abook_channel = %d and abook_self = 1 limit 1",
intval($e['channel_id'])
);
if(($t) && (($t[0]['abook_my_perms'] & PERMS_W_TAGWALL) && (! ($t[0]['abook_my_perms'] & PERMS_W_STREAM))))
$public_forum = true;
}
// This is for birthdays and keywords, but must check access permissions
$p = q("select * from profile where uid = %d and is_default = 1",
intval($e['channel_id'])
);
$profile = array();
if($p) {
if(! intval($p[0]['publish']))
$searchable = false;
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== ''))
$profile['next_birthday'] = $bd;
if($age = age($p[0]['dob'],$e['channel_timezone'],''))
$profile['age'] = $age;
$profile['gender'] = $p[0]['gender'];
$profile['marital'] = $p[0]['marital'];
$profile['sexual'] = $p[0]['sexual'];
$profile['locale'] = $p[0]['locality'];
$profile['region'] = $p[0]['region'];
$profile['postcode'] = $p[0]['postal_code'];
$profile['country'] = $p[0]['country_name'];
$profile['about'] = $p[0]['about'];
$profile['homepage'] = $p[0]['homepage'];
$profile['hometown'] = $p[0]['hometown'];
if($p[0]['keywords']) {
$tags = array();
$k = explode(' ',$p[0]['keywords']);
if($k) {
foreach($k as $kk) {
if(trim($kk," \t\n\r\0\x0B,")) {
$tags[] = trim($kk," \t\n\r\0\x0B,");
}
}
}
if($tags)
$profile['keywords'] = $tags;
}
}
$ret['success'] = true;
// Communication details
$ret['guid'] = $e['xchan_guid'];
$ret['guid_sig'] = $e['xchan_guid_sig'];
$ret['key'] = $e['xchan_pubkey'];
$ret['name'] = $e['xchan_name'];
$ret['name_updated'] = $e['xchan_name_date'];
$ret['address'] = $e['xchan_addr'];
$ret['photo_mimetype'] = $e['xchan_photo_mimetype'];
$ret['photo'] = $e['xchan_photo_l'];
$ret['photo_updated'] = $e['xchan_photo_date'];
$ret['url'] = $e['xchan_url'];
$ret['connections_url']= (($e['xchan_connurl']) ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']);
$ret['target'] = $ztarget;
$ret['target_sig'] = $zsig;
$ret['searchable'] = $searchable;
$ret['adult_content'] = $adult_channel;
$ret['public_forum'] = $public_forum;
if($deleted)
$ret['deleted'] = $deleted;
// premium or other channel desiring some contact with potential followers before connecting.
// This is a template - %s will be replaced with the follow_url we discover for the return channel.
if($special_channel)
$ret['connect_url'] = z_root() . '/connect/' . $e['channel_address'];
// This is a template for our follow url, %s will be replaced with a webbie
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
$ztarget_hash = (($ztarget && $zsig)
? make_xchan_hash($ztarget,$zsig)
: '' );
$permissions = get_all_perms($e['channel_id'],$ztarget_hash,false);
if($ztarget_hash) {
$permissions['connected'] = false;
$b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($ztarget_hash),
intval($e['channel_id'])
);
if($b)
$permissions['connected'] = true;
}
$ret['permissions'] = (($ztarget && $zkey) ? crypto_encapsulate(json_encode($permissions),$zkey) : $permissions);
if($permissions['view_profile'])
$ret['profile'] = $profile;
// array of (verified) hubs this channel uses
$x = zot_encode_locations($e);
if($x)
$ret['locations'] = $x;
$ret['site'] = array();
$ret['site']['url'] = z_root();
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
$dirmode = get_config('system','directory_mode');
if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL))
$ret['site']['directory_mode'] = 'normal';
if($dirmode == DIRECTORY_MODE_PRIMARY)
$ret['site']['directory_mode'] = 'primary';
elseif($dirmode == DIRECTORY_MODE_SECONDARY)
$ret['site']['directory_mode'] = 'secondary';
elseif($dirmode == DIRECTORY_MODE_STANDALONE)
$ret['site']['directory_mode'] = 'standalone';
if($dirmode != DIRECTORY_MODE_NORMAL)
$ret['site']['directory_url'] = z_root() . '/dirsearch';
// hide detailed site information if you're off the grid
if($dirmode != DIRECTORY_MODE_STANDALONE) {
$register_policy = intval(get_config('system','register_policy'));
if($register_policy == REGISTER_CLOSED)
$ret['site']['register_policy'] = 'closed';
if($register_policy == REGISTER_APPROVE)
$ret['site']['register_policy'] = 'approve';
if($register_policy == REGISTER_OPEN)
$ret['site']['register_policy'] = 'open';
$access_policy = intval(get_config('system','access_policy'));
if($access_policy == ACCESS_PRIVATE)
$ret['site']['access_policy'] = 'private';
if($access_policy == ACCESS_PAID)
$ret['site']['access_policy'] = 'paid';
if($access_policy == ACCESS_FREE)
$ret['site']['access_policy'] = 'free';
if($access_policy == ACCESS_TIERED)
$ret['site']['access_policy'] = 'tiered';
$ret['site']['accounts'] = account_total();
require_once('include/identity.php');
$ret['site']['channels'] = channel_total();
$ret['site']['version'] = PLATFORM_NAME . ' ' . RED_VERSION . '[' . DB_UPDATE_VERSION . ']';
$ret['site']['admin'] = get_config('system','admin_email');
$visible_plugins = array();
if(is_array($a->plugins) && count($a->plugins)) {
$r = q("select * from addon where hidden = 0");
if($r)
foreach($r as $rr)
$visible_plugins[] = $rr['name'];
}
$ret['site']['plugins'] = $visible_plugins;
$ret['site']['sitehash'] = get_config('system','location_hash');
$ret['site']['sitename'] = get_config('system','sitename');
$ret['site']['sellpage'] = get_config('system','sellpage');
$ret['site']['location'] = get_config('system','site_location');
$ret['site']['realm'] = get_directory_realm();
}
call_hooks('zot_finger',$ret);
json_return_and_die($ret);
}

View File

@ -79,7 +79,7 @@ function theme_post(&$a) {
function redbasic_form(&$a, $arr) {
$scheme_choices = array();
$scheme_choices["---"] = t("Light (Hubzilla default)");
$scheme_choices["---"] = t("Focus (Hubzilla default)");
$files = glob('view/theme/redbasic/schema/*.php');
if($files) {
foreach($files as $file) {

View File

@ -34,5 +34,8 @@
$toolicon_activecolour = '#fff';
if (! $font_colour)
$font_colour = "#ccc";
if (! $converse_width)
$converse_width = "1024";

View File

@ -34,6 +34,9 @@
$comment_border_colour = "rgba(255,255,255,0.8)";
if (! $font_colour)
$font_colour = "#000";
if (! $converse_width)
$converse_width = "1024";

View File

@ -34,3 +34,5 @@
$comment_border_colour = "rgba(0,0,0,0.8)";
if (! $font_colour)
$font_colour = "#46D43F";
if (! $converse_width)
$converse_width = "1024";

View File

@ -34,3 +34,5 @@
$comment_border_colour = "rgba(0,0,0,0.8)";
if (! $font_colour)
$font_colour = "#fff";
if (! $converse_width)
$converse_width = "1024";

View File

@ -1,4 +1,7 @@
{{include file="field_select.tpl" field=$schema}}
{{include file="field_checkbox.tpl" field=$align_left}}
{{include file="field_checkbox.tpl" field=$narrow_navbar}}
{{include file="field_input.tpl" field=$converse_width}}
{{if $expert}}
{{include file="field_colorinput.tpl" field=$nav_bg}}
{{include file="field_colorinput.tpl" field=$nav_gradient_top}}
@ -26,11 +29,7 @@
{{include file="field_input.tpl" field=$shadow}}
{{include file="field_input.tpl" field=$top_photo}}
{{include file="field_input.tpl" field=$reply_photo}}
{{/if}}
{{include file="field_input.tpl" field=$converse_width}}
{{include file="field_checkbox.tpl" field=$align_left}}
{{include file="field_checkbox.tpl" field=$narrow_navbar}}
{{if $expert}}
<script>
$(function(){
$('#id_redbasic_nav_bg,#id_redbasic_nav_gradient_top,#id_redbasic_nav_gradient_bottom,#id_redbasic_nav_active_gradient_top,#id_redbasic_nav_active_gradient_bottom').colorpicker({format: 'rgba'});

View File

@ -1,5 +1,8 @@
<h3>{{$prvmsg_header}}</h3>
<div class="generic-content-wrapper">
<div class="section-title-wrapper">
<h2>{{$prvmsg_header}}</h2>
</div>
<div class="section-content-wrapper">
{{foreach $mails as $mail}}
{{include file="mail_conv.tpl"}}
{{/foreach}}
@ -10,3 +13,4 @@
{{$unknown_text}}
{{/if}}
</div>
</div>

View File

@ -1,3 +1,10 @@
<h3>{{$messages}}</h3>
{{$tab_content}}
<div class="generic-content-wrapper">
<div class="section-title-wrapper">
<h2>{{$header}}</h2>
</div>
<div class="section-content-wrapper">
{{foreach $messages as $message}}
{{include file="mail_list.tpl"}}
{{/foreach}}
</div>
</div>

View File

@ -1,8 +1,6 @@
<div class="generic-content-wrapper" id="mail-list-wrapper">
<a href="{{$from_url}}" class ="mail-list" ><img class="mail-list-sender-photo" src="{{$from_photo}}" alt="{{$from_name}}" /></a>
<span class="mail-list">{{$from_name}}</span>
<span class="mail-list {{if $seen}}seen{{else}}unseen{{/if}}"><a href="mail/{{$id}}" class="mail-link">{{$subject}}</a></span>
<span class="mail-list" title="{{$date}}">{{$date}}</span>
<span class="mail-list mail-list-remove" class="btn btn-default btn-sm"><a href="message/dropconv/{{$id}}" onclick="return confirmDelete();" title="{{$delete}}" class="btn btn-default btn-sm" ><i class="icon-trash mail-icons drop-icons"></i></a></span>
<div class="clear">&nbsp;</div>
</div>
<a href="{{$message.from_url}}" class ="mail-list" ><img class="mail-list-sender-photo" src="{{$message.from_photo}}" alt="{{$message.from_name}}" /></a>
<span class="mail-list">{{$message.from_name}}</span>
<span class="mail-list {{if $message.seen}}seen{{else}}unseen{{/if}}"><a href="mail/{{$message.id}}" class="mail-link">{{$message.subject}}</a></span>
<span class="mail-list" title="{{$message.date}}">{{$message.date}}</span>
<span class="mail-list mail-list-remove" class="btn btn-default btn-sm"><a href="message/dropconv/{{$message.id}}" onclick="return confirmDelete();" title="{{$message.delete}}" class="btn btn-default btn-sm" ><i class="icon-trash mail-icons drop-icons"></i></a></span>
<div class="clear"></div>

View File

@ -26,6 +26,9 @@
{{include file="field_input.tpl" field=$photo_path}}
{{include file="field_input.tpl" field=$attach_path}}
<div class="settings-submit-wrapper" >
<button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button>
</div>
</div>
</div>
</div>
@ -75,6 +78,9 @@
{{include file="field_checkbox.tpl" field=$blocktags}}
{{include file="field_input.tpl" field=$expire}}
</div>
<div class="settings-submit-wrapper" >
<button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button>
</div>
</div>
</div>
</div>
@ -124,16 +130,12 @@
{{include file="field_input.tpl" field=$evdays}}
</div>
</div>
</div>
</div>
</div>
<div class="panel">
<div class"section-subtitle-wrapper" role="tab" id="form-buttons">
<div class="settings-submit-wrapper" >
<button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button>
</div>
</div>
</div>
</div>
{{if $menus}}
<div class="panel">
<div class="section-subtitle-wrapper" role="tab" id="miscellaneous-settings">