Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3b1ab5e79c
345
Zotlabs/Zot/Auth.php
Normal file
345
Zotlabs/Zot/Auth.php
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zotlabs\Zot;
|
||||||
|
|
||||||
|
class Auth {
|
||||||
|
|
||||||
|
protected $test;
|
||||||
|
protected $test_results;
|
||||||
|
protected $debug_msg;
|
||||||
|
|
||||||
|
protected $address;
|
||||||
|
protected $desturl;
|
||||||
|
protected $sec;
|
||||||
|
protected $version;
|
||||||
|
protected $delegate;
|
||||||
|
protected $success;
|
||||||
|
protected $delegate_success;
|
||||||
|
|
||||||
|
protected $remote;
|
||||||
|
protected $remote_service_class;
|
||||||
|
protected $remote_level;
|
||||||
|
protected $remote_hub;
|
||||||
|
protected $dnt;
|
||||||
|
|
||||||
|
function __construct($req) {
|
||||||
|
|
||||||
|
|
||||||
|
$this->test = ((array_key_exists('test',$req)) ? intval($req['test']) : 0);
|
||||||
|
$this->test_results = array('success' => false);
|
||||||
|
$this->debug_msg = '';
|
||||||
|
|
||||||
|
$this->success = false;
|
||||||
|
$this->address = $req['auth'];
|
||||||
|
$this->desturl = $req['dest'];
|
||||||
|
$this->sec = $req['sec'];
|
||||||
|
$this->version = $req['version'];
|
||||||
|
$this->delegate = $req['delegate'];
|
||||||
|
|
||||||
|
$c = get_sys_channel();
|
||||||
|
if(! $c) {
|
||||||
|
logger('unable to obtain response (sys) channel');
|
||||||
|
$this->Debug('no local channels found.');
|
||||||
|
$this->Finalise();
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = $this->GetHublocs($this->address);
|
||||||
|
|
||||||
|
if($x) {
|
||||||
|
foreach($x as $xx) {
|
||||||
|
if($this->Verify($c,$xx))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @FIXME we really want to save the return_url in the session before we
|
||||||
|
* visit rmagic. This does however prevent a recursion if you visit
|
||||||
|
* rmagic directly, as it would otherwise send you back here again.
|
||||||
|
* But z_root() probably isn't where you really want to go.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(strstr($this->desturl,z_root() . '/rmagic'))
|
||||||
|
goaway(z_root());
|
||||||
|
|
||||||
|
$this->Finalise();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetHublocs($address) {
|
||||||
|
|
||||||
|
// Try and find a hubloc for the person attempting to auth.
|
||||||
|
// Since we're matching by address, we have to return all entries
|
||||||
|
// some of which may be from re-installed hubs; and we'll need to
|
||||||
|
// try each sequentially to see if one can pass the test
|
||||||
|
|
||||||
|
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||||
|
where hubloc_addr = '%s' order by hubloc_id desc",
|
||||||
|
dbesc($address)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! $x) {
|
||||||
|
// finger them if they can't be found.
|
||||||
|
$ret = zot_finger($address, null);
|
||||||
|
if ($ret['success']) {
|
||||||
|
$j = json_decode($ret['body'], true);
|
||||||
|
if($j)
|
||||||
|
import_xchan($j);
|
||||||
|
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||||
|
where hubloc_addr = '%s' order by hubloc_id desc",
|
||||||
|
dbesc($address)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(! $x) {
|
||||||
|
logger('mod_zot: auth: unable to finger ' . $address);
|
||||||
|
$this->Debug('no hubloc found for ' . $address . ' and probing failed.');
|
||||||
|
$this->Finalise();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Verify($channel,$hubloc) {
|
||||||
|
|
||||||
|
logger('auth request received from ' . $hubloc['hubloc_addr'] );
|
||||||
|
|
||||||
|
$this->remote = remote_channel();
|
||||||
|
$this->remote_service_class = '';
|
||||||
|
$this->remote_level = 0;
|
||||||
|
$this->remote_hub = $hubloc['hubloc_url'];
|
||||||
|
$this->dnt = 0;
|
||||||
|
|
||||||
|
// check credentials and access
|
||||||
|
|
||||||
|
// If they are already authenticated and haven't changed credentials,
|
||||||
|
// we can save an expensive network round trip and improve performance.
|
||||||
|
|
||||||
|
// Also check that they are coming from the same site as they authenticated with originally.
|
||||||
|
|
||||||
|
$already_authed = (((remote_channel()) && ($hubloc['hubloc_hash'] == remote_channel())
|
||||||
|
&& ($hubloc['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false);
|
||||||
|
|
||||||
|
if($this->delegate && $this->delegate !== $_SESSION['delegate_channel'])
|
||||||
|
$already_authed = false;
|
||||||
|
|
||||||
|
if($already_authed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(local_channel()) {
|
||||||
|
|
||||||
|
// tell them to logout if they're logged in locally as anything but the target remote account
|
||||||
|
// in which case just shut up because they don't need to be doing this at all.
|
||||||
|
|
||||||
|
if (get_app()->channel['channel_hash'] == $hubloc['xchan_hash']) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger('already authenticated locally as somebody else.');
|
||||||
|
notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
|
||||||
|
if($this->test) {
|
||||||
|
$this->Debug('already logged in locally with a conflicting identity.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the
|
||||||
|
// site private key
|
||||||
|
// The actual channel sending the packet ($c[0]) is not important, but this provides a
|
||||||
|
// generic zot packet with a sender which can be verified
|
||||||
|
|
||||||
|
$p = zot_build_packet($channel,$type = 'auth_check',
|
||||||
|
array(array('guid' => $hubloc['hubloc_guid'],'guid_sig' => $hubloc['hubloc_guid_sig'])),
|
||||||
|
$hubloc['hubloc_sitekey'], $this->sec);
|
||||||
|
|
||||||
|
$this->Debug('auth check packet created using sitekey ' . $hubloc['hubloc_sitekey']);
|
||||||
|
$this->Debug('packet contents: ' . $p);
|
||||||
|
|
||||||
|
$result = zot_zot($hubloc['hubloc_callback'],$p);
|
||||||
|
if(! $result['success']) {
|
||||||
|
logger('auth_check callback failed.');
|
||||||
|
if($this->test)
|
||||||
|
$this->Debug('auth check request to your site returned .' . print_r($result, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$j = json_decode($result['body'], true);
|
||||||
|
if(! $j) {
|
||||||
|
logger('auth_check json data malformed.');
|
||||||
|
if($this->test)
|
||||||
|
$this->Debug('json malformed: ' . $result['body']);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Debug('auth check request returned .' . print_r($j, true));
|
||||||
|
|
||||||
|
if(! $j['success'])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// legit response, but we do need to check that this wasn't answered by a man-in-middle
|
||||||
|
|
||||||
|
if (! rsa_verify($this->sec . $hubloc['xchan_hash'],base64url_decode($j['confirm']),$hubloc['xchan_pubkey'])) {
|
||||||
|
logger('final confirmation failed.');
|
||||||
|
if($this->test)
|
||||||
|
$this->Debug('final confirmation failed. ' . $sec . print_r($j,true) . print_r($hubloc,true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('service_class',$j))
|
||||||
|
$this->remote_service_class = $j['service_class'];
|
||||||
|
if (array_key_exists('level',$j))
|
||||||
|
$this->remote_level = $j['level'];
|
||||||
|
if (array_key_exists('DNT',$j))
|
||||||
|
$this->dnt = $j['DNT'];
|
||||||
|
|
||||||
|
|
||||||
|
// log them in
|
||||||
|
|
||||||
|
if ($this->test) {
|
||||||
|
// testing only - return the success result
|
||||||
|
$this->test_results['success'] = true;
|
||||||
|
$this->Debug('Authentication Success!');
|
||||||
|
$this->Finalise();
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION['authenticated'] = 1;
|
||||||
|
|
||||||
|
// check for delegation and if all is well, log them in locally with delegation restrictions
|
||||||
|
|
||||||
|
$this->delegate_success = false;
|
||||||
|
|
||||||
|
if($this->delegate) {
|
||||||
|
$r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1",
|
||||||
|
dbesc($this->delegate)
|
||||||
|
);
|
||||||
|
if ($r && intval($r[0]['channel_id'])) {
|
||||||
|
$allowed = perm_is_allowed($r[0]['channel_id'],$hubloc['xchan_hash'],'delegate');
|
||||||
|
if($allowed) {
|
||||||
|
$_SESSION['delegate_channel'] = $r[0]['channel_id'];
|
||||||
|
$_SESSION['delegate'] = $hubloc['xchan_hash'];
|
||||||
|
$_SESSION['account_id'] = intval($r[0]['channel_account_id']);
|
||||||
|
require_once('include/security.php');
|
||||||
|
// this will set the local_channel authentication in the session
|
||||||
|
change_channel($r[0]['channel_id']);
|
||||||
|
$this->delegate_success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->delegate_success) {
|
||||||
|
// normal visitor (remote_channel) login session credentials
|
||||||
|
$_SESSION['visitor_id'] = $hubloc['xchan_hash'];
|
||||||
|
$_SESSION['my_url'] = $hubloc['xchan_url'];
|
||||||
|
$_SESSION['my_address'] = $this->address;
|
||||||
|
$_SESSION['remote_service_class'] = $this->remote_service_class;
|
||||||
|
$_SESSION['remote_level'] = $this->remote_level;
|
||||||
|
$_SESSION['remote_hub'] = $this->remote_hub;
|
||||||
|
$_SESSION['DNT'] = $this->dnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr = array('xchan' => $hubloc, 'url' => $this->desturl, 'session' => $_SESSION);
|
||||||
|
call_hooks('magic_auth_success',$arr);
|
||||||
|
get_app()->set_observer($hubloc);
|
||||||
|
require_once('include/security.php');
|
||||||
|
get_app()->set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||||
|
info(sprintf( t('Welcome %s. Remote authentication successful.'),$hubloc['xchan_name']));
|
||||||
|
logger('mod_zot: auth success from ' . $hubloc['xchan_addr']);
|
||||||
|
$this->success = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Debug($msg) {
|
||||||
|
$this->debug_msg .= $msg . EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Finalise() {
|
||||||
|
|
||||||
|
if($this->test) {
|
||||||
|
$this->test_results['message'] = $this->debug_msg;
|
||||||
|
json_return_and_die($this->test_results);
|
||||||
|
}
|
||||||
|
|
||||||
|
goaway($this->desturl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Magic Auth
|
||||||
|
* ==========
|
||||||
|
*
|
||||||
|
* So-called "magic auth" takes place by a special exchange. On the site where the "channel to be authenticated" lives (e.g. $mysite),
|
||||||
|
* a redirection is made via $mysite/magic to the zot endpoint of the remote site ($remotesite) with special GET parameters.
|
||||||
|
*
|
||||||
|
* The endpoint is typically https://$remotesite/post - or whatever was specified as the callback url in prior communications
|
||||||
|
* (we will bootstrap an address and fetch a zot info packet if possible where no prior communications exist)
|
||||||
|
*
|
||||||
|
* Five GET parameters are supplied:
|
||||||
|
* * auth => the urlencoded webbie (channel@host.domain) of the channel requesting access
|
||||||
|
* * dest => the desired destination URL (urlencoded)
|
||||||
|
* * sec => a random string which is also stored on $mysite for use during the verification phase.
|
||||||
|
* * version => the zot revision
|
||||||
|
* * delegate => optional urlencoded webbie of a local channel to invoke delegation rights for
|
||||||
|
*
|
||||||
|
* * test => (optional 1 or 0 - debugs the authentication exchange and returns a json response instead of redirecting the browser session)
|
||||||
|
*
|
||||||
|
* When this packet is received, an "auth-check" zot message is sent to $mysite.
|
||||||
|
* (e.g. if $_GET['auth'] is foobar@podunk.edu, a zot packet is sent to the podunk.edu zot endpoint, which is typically /post)
|
||||||
|
* If no information has been recorded about the requesting identity a zot information packet will be retrieved before
|
||||||
|
* continuing.
|
||||||
|
*
|
||||||
|
* The sender of this packet is an arbitrary/random site channel. The recipients will be a single recipient corresponding
|
||||||
|
* to the guid and guid_sig we have associated with the requesting auth identity
|
||||||
|
*
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "type":"auth_check",
|
||||||
|
* "sender":{
|
||||||
|
* "guid":"kgVFf_...",
|
||||||
|
* "guid_sig":"PT9-TApz...",
|
||||||
|
* "url":"http:\/\/podunk.edu",
|
||||||
|
* "url_sig":"T8Bp7j...",
|
||||||
|
* "sitekey":"aMtgKTiirXrICP..."
|
||||||
|
* },
|
||||||
|
* "recipients":{
|
||||||
|
* {
|
||||||
|
* "guid":"ZHSqb...",
|
||||||
|
* "guid_sig":"JsAAXi..."
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* "callback":"\/post",
|
||||||
|
* "version":1,
|
||||||
|
* "secret":"1eaa661",
|
||||||
|
* "secret_sig":"eKV968b1..."
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* auth_check messages MUST use encapsulated encryption. This message is sent to the origination site, which checks the 'secret' to see
|
||||||
|
* if it is the same as the 'sec' which it passed originally. It also checks the secret_sig which is the secret signed by the
|
||||||
|
* destination channel's private key and base64url encoded. If everything checks out, a json packet is returned:
|
||||||
|
*
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "success":1,
|
||||||
|
* "confirm":"q0Ysovd1u...",
|
||||||
|
* "service_class":(optional)
|
||||||
|
* "level":(optional)
|
||||||
|
* "DNT": (optional do-not-track - 1 or 0)
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* 'confirm' in this case is the base64url encoded RSA signature of the concatenation of 'secret' with the
|
||||||
|
* base64url encoded whirlpool hash of the requestor's guid and guid_sig; signed with the source channel private key.
|
||||||
|
* This prevents a man-in-the-middle from inserting a rogue success packet. Upon receipt and successful
|
||||||
|
* verification of this packet, the destination site will redirect to the original destination URL and indicate a successful remote login.
|
||||||
|
* Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is
|
||||||
|
* a string whose contents are not defined by protocol. Example: "basic" or "gold".
|
||||||
|
*
|
||||||
|
* @param[in,out] App &$a
|
||||||
|
*/
|
@ -127,3 +127,170 @@ class Receiver {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief zot communications and messaging.
|
||||||
|
*
|
||||||
|
* Sender HTTP posts to this endpoint ($site/post typically) with 'data' parameter set to json zot message packet.
|
||||||
|
* This packet is optionally encrypted, which we will discover if the json has an 'iv' element.
|
||||||
|
* $contents => array( 'alg' => 'aes256cbc', 'iv' => initialisation vector, 'key' => decryption key, 'data' => encrypted data);
|
||||||
|
* $contents->iv and $contents->key are random strings encrypted with this site's RSA public key and then base64url encoded.
|
||||||
|
* Currently only 'aes256cbc' is used, but this is extensible should that algorithm prove inadequate.
|
||||||
|
*
|
||||||
|
* Once decrypted, one will find the normal json_encoded zot message packet.
|
||||||
|
*
|
||||||
|
* Defined packet types are: notify, purge, refresh, force_refresh, auth_check, ping, and pickup
|
||||||
|
*
|
||||||
|
* Standard packet: (used by notify, purge, refresh, force_refresh, and auth_check)
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "type": "notify",
|
||||||
|
* "sender":{
|
||||||
|
* "guid":"kgVFf_1...",
|
||||||
|
* "guid_sig":"PT9-TApzp...",
|
||||||
|
* "url":"http:\/\/podunk.edu",
|
||||||
|
* "url_sig":"T8Bp7j5...",
|
||||||
|
* },
|
||||||
|
* "recipients": { optional recipient array },
|
||||||
|
* "callback":"\/post",
|
||||||
|
* "version":1,
|
||||||
|
* "secret":"1eaa...",
|
||||||
|
* "secret_sig": "df89025470fac8..."
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* Signature fields are all signed with the sender channel private key and base64url encoded.
|
||||||
|
* Recipients are arrays of guid and guid_sig, which were previously signed with the recipients private
|
||||||
|
* key and base64url encoded and later obtained via channel discovery. Absence of recipients indicates
|
||||||
|
* a public message or visible to all potential listeners on this site.
|
||||||
|
*
|
||||||
|
* "pickup" packet:
|
||||||
|
* The pickup packet is sent in response to a notify packet from another site
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "type":"pickup",
|
||||||
|
* "url":"http:\/\/example.com",
|
||||||
|
* "callback":"http:\/\/example.com\/post",
|
||||||
|
* "callback_sig":"teE1_fLI...",
|
||||||
|
* "secret":"1eaa...",
|
||||||
|
* "secret_sig":"O7nB4_..."
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* In the pickup packet, the sig fields correspond to the respective data
|
||||||
|
* element signed with this site's system private key and then base64url encoded.
|
||||||
|
* The "secret" is the same as the original secret from the notify packet.
|
||||||
|
*
|
||||||
|
* If verification is successful, a json structure is returned containing a
|
||||||
|
* success indicator and an array of type 'pickup'.
|
||||||
|
* Each pickup element contains the original notify request and a message field
|
||||||
|
* whose contents are dependent on the message type.
|
||||||
|
*
|
||||||
|
* This JSON array is AES encapsulated using the site public key of the site
|
||||||
|
* that sent the initial zot pickup packet.
|
||||||
|
* Using the above example, this would be example.com.
|
||||||
|
*
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "success":1,
|
||||||
|
* "pickup":{
|
||||||
|
* "notify":{
|
||||||
|
* "type":"notify",
|
||||||
|
* "sender":{
|
||||||
|
* "guid":"kgVFf_...",
|
||||||
|
* "guid_sig":"PT9-TApz...",
|
||||||
|
* "url":"http:\/\/z.podunk.edu",
|
||||||
|
* "url_sig":"T8Bp7j5D..."
|
||||||
|
* },
|
||||||
|
* "callback":"\/post",
|
||||||
|
* "version":1,
|
||||||
|
* "secret":"1eaa661..."
|
||||||
|
* },
|
||||||
|
* "message":{
|
||||||
|
* "type":"activity",
|
||||||
|
* "message_id":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
|
||||||
|
* "message_top":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
|
||||||
|
* "message_parent":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
|
||||||
|
* "created":"2012-11-20 04:04:16",
|
||||||
|
* "edited":"2012-11-20 04:04:16",
|
||||||
|
* "title":"",
|
||||||
|
* "body":"Hi Nickordo",
|
||||||
|
* "app":"",
|
||||||
|
* "verb":"post",
|
||||||
|
* "object_type":"",
|
||||||
|
* "target_type":"",
|
||||||
|
* "permalink":"",
|
||||||
|
* "location":"",
|
||||||
|
* "longlat":"",
|
||||||
|
* "owner":{
|
||||||
|
* "name":"Indigo",
|
||||||
|
* "address":"indigo@podunk.edu",
|
||||||
|
* "url":"http:\/\/podunk.edu",
|
||||||
|
* "photo":{
|
||||||
|
* "mimetype":"image\/jpeg",
|
||||||
|
* "src":"http:\/\/podunk.edu\/photo\/profile\/m\/5"
|
||||||
|
* },
|
||||||
|
* "guid":"kgVFf_...",
|
||||||
|
* "guid_sig":"PT9-TAp...",
|
||||||
|
* },
|
||||||
|
* "author":{
|
||||||
|
* "name":"Indigo",
|
||||||
|
* "address":"indigo@podunk.edu",
|
||||||
|
* "url":"http:\/\/podunk.edu",
|
||||||
|
* "photo":{
|
||||||
|
* "mimetype":"image\/jpeg",
|
||||||
|
* "src":"http:\/\/podunk.edu\/photo\/profile\/m\/5"
|
||||||
|
* },
|
||||||
|
* "guid":"kgVFf_...",
|
||||||
|
* "guid_sig":"PT9-TAp..."
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* Currently defined message types are 'activity', 'mail', 'profile', 'location'
|
||||||
|
* and 'channel_sync', which each have different content schemas.
|
||||||
|
*
|
||||||
|
* Ping packet:
|
||||||
|
* A ping packet does not require any parameters except the type. It may or may
|
||||||
|
* not be encrypted.
|
||||||
|
*
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "type": "ping"
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* On receipt of a ping packet a ping response will be returned:
|
||||||
|
*
|
||||||
|
* \code{.json}
|
||||||
|
* {
|
||||||
|
* "success" : 1,
|
||||||
|
* "site" {
|
||||||
|
* "url": "http:\/\/podunk.edu",
|
||||||
|
* "url_sig": "T8Bp7j5...",
|
||||||
|
* "sitekey": "-----BEGIN PUBLIC KEY-----
|
||||||
|
* MIICIjANBgkqhkiG9w0BAQE..."
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* The ping packet can be used to verify that a site has not been re-installed, and to
|
||||||
|
* initiate corrective action if it has. The url_sig is signed with the site private key
|
||||||
|
* and base64url encoded - and this should verify with the enclosed sitekey. Failure to
|
||||||
|
* verify indicates the site is corrupt or otherwise unable to communicate using zot.
|
||||||
|
* This return packet is not otherwise verified, so should be compared with other
|
||||||
|
* results obtained from this site which were verified prior to taking action. For instance
|
||||||
|
* if you have one verified result with this signature and key, and other records for this
|
||||||
|
* url which have different signatures and keys, it indicates that the site was re-installed
|
||||||
|
* and corrective action may commence (remove or mark invalid any entries with different
|
||||||
|
* signatures).
|
||||||
|
* If you have no records which match this url_sig and key - no corrective action should
|
||||||
|
* be taken as this packet may have been returned by an imposter.
|
||||||
|
*
|
||||||
|
* @param[in,out] App &$a
|
||||||
|
*/
|
||||||
|
|
||||||
|
13
boot.php
13
boot.php
@ -83,7 +83,7 @@ $DIRECTORY_FALLBACK_SERVERS = array(
|
|||||||
'https://zothub.com',
|
'https://zothub.com',
|
||||||
'https://hubzilla.site',
|
'https://hubzilla.site',
|
||||||
'https://red.zottel.red',
|
'https://red.zottel.red',
|
||||||
'https://gravizot.de',
|
'https://hub.pixelbits.de',
|
||||||
'https://my.federated.social',
|
'https://my.federated.social',
|
||||||
'https://hubzilla.nl'
|
'https://hubzilla.nl'
|
||||||
);
|
);
|
||||||
@ -704,11 +704,18 @@ class App {
|
|||||||
'smarty3' => '}}'
|
'smarty3' => '}}'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// These represent the URL which was used to access the page
|
||||||
|
|
||||||
private $scheme;
|
private $scheme;
|
||||||
private $hostname;
|
private $hostname;
|
||||||
private $baseurl;
|
|
||||||
private $path;
|
private $path;
|
||||||
|
|
||||||
|
// This is our standardised URL - regardless of what was used
|
||||||
|
// to access the page
|
||||||
|
|
||||||
|
private $baseurl;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App constructor.
|
* App constructor.
|
||||||
*/
|
*/
|
||||||
@ -1324,7 +1331,7 @@ function check_config(&$a) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$r = q("SELECT * FROM `addon` WHERE `installed` = 1");
|
$r = q("SELECT * FROM addon WHERE installed = 1");
|
||||||
if($r)
|
if($r)
|
||||||
$installed = $r;
|
$installed = $r;
|
||||||
else
|
else
|
||||||
|
@ -39,8 +39,9 @@
|
|||||||
[tr][td]abook_unconnected[/td][td]currently unused. Projected usage is to indicate "one-way" connections which were insitgated on this end but are still pending on the remote end. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_unconnected[/td][td]currently unused. Projected usage is to indicate "one-way" connections which were insitgated on this end but are still pending on the remote end. [/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[tr][td]abook_self[/td][td]is a special case where the owner is the target. Every channel has one abook entry with abook_self and with a target abook_xchan set to channel.channel_hash . When this flag is present, abook_my_perms is the default permissions granted to all new connections and several other fields are unused.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_self[/td][td]is a special case where the owner is the target. Every channel has one abook entry with abook_self and with a target abook_xchan set to channel.channel_hash . When this flag is present, abook_my_perms is the default permissions granted to all new connections and several other fields are unused.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[tr][td]abook_feed[/td][td]indicates this connection is an RSS/Atom feed and may trigger special handling.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_feed[/td][td]indicates this connection is an RSS/Atom feed and may trigger special handling.[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[tr][td]abook_incl[/td][td]connection filter allow rules separated by LF[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_incl[/td][td]connection filter allow rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[tr][td]abook_excl[/td][td]connection filter deny rules separated by LF[/td][td]int(11)[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
[tr][td]abook_excl[/td][td]connection filter deny rules separated by LF[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
|
[tr][td]abook_instance[/td][td]comma separated list of site urls of all channel clones that this connection is connected with (used only for singleton networks which don't support cloning)[/td][td]text[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||||
[/table]
|
[/table]
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ This document assumes you're an administrator.
|
|||||||
this website. Can be overwritten by user settings.
|
this website. Can be overwritten by user settings.
|
||||||
[b]system > projecthome[/b]
|
[b]system > projecthome[/b]
|
||||||
Set the project homepage as the homepage of your hub.
|
Set the project homepage as the homepage of your hub.
|
||||||
[b]system > workflowchannelnext[/b]
|
[b]system > workflow_channel_next[/b]
|
||||||
The page to direct users to immediately after creating a channel.
|
The page to direct users to immediately after creating a channel.
|
||||||
[b]system > max_daily_registrations[/b]
|
[b]system > max_daily_registrations[/b]
|
||||||
Set the maximum number of new registrations allowed on any day.
|
Set the maximum number of new registrations allowed on any day.
|
||||||
|
@ -67,7 +67,7 @@ function check_account_invite($invite_code) {
|
|||||||
$result['message'] .= t('An invitation is required.') . EOL;
|
$result['message'] .= t('An invitation is required.') . EOL;
|
||||||
}
|
}
|
||||||
$r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_code));
|
$r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_code));
|
||||||
if(! results($r)) {
|
if(! $r) {
|
||||||
$result['message'] .= t('Invitation could not be verified.') . EOL;
|
$result['message'] .= t('Invitation could not be verified.') . EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<?php /** @file */
|
<?php /** @file */
|
||||||
|
|
||||||
require_once("bbcode.php");
|
require_once("include/bbcode.php");
|
||||||
require_once("datetime.php");
|
require_once("include/datetime.php");
|
||||||
require_once("conversation.php");
|
require_once("include/conversation.php");
|
||||||
require_once("oauth.php");
|
require_once("include/oauth.php");
|
||||||
require_once("html2plain.php");
|
require_once("include/html2plain.php");
|
||||||
require_once('include/security.php');
|
require_once('include/security.php');
|
||||||
require_once('include/photos.php');
|
require_once('include/photos.php');
|
||||||
require_once('include/items.php');
|
require_once('include/items.php');
|
||||||
@ -112,8 +112,11 @@ require_once('include/api_auth.php');
|
|||||||
break;
|
break;
|
||||||
case "json":
|
case "json":
|
||||||
header ("Content-Type: application/json");
|
header ("Content-Type: application/json");
|
||||||
foreach($r as $rr)
|
foreach($r as $rr) {
|
||||||
|
if(! $rr)
|
||||||
|
$rr = array();
|
||||||
$json = json_encode($rr);
|
$json = json_encode($rr);
|
||||||
|
}
|
||||||
if ($_GET['callback'])
|
if ($_GET['callback'])
|
||||||
$json = $_GET['callback']."(".$json.")";
|
$json = $_GET['callback']."(".$json.")";
|
||||||
return $json;
|
return $json;
|
||||||
@ -852,15 +855,26 @@ require_once('include/api_auth.php');
|
|||||||
$_REQUEST['type'] = 'wall';
|
$_REQUEST['type'] = 'wall';
|
||||||
|
|
||||||
if(x($_FILES,'media')) {
|
if(x($_FILES,'media')) {
|
||||||
$_FILES['userfile'] = $_FILES['media'];
|
$num_uploads = count($_FILES['media']['name']);
|
||||||
// upload the image if we have one
|
for($x = 0; $x < $num_uploads; $x ++) {
|
||||||
|
$_FILES['userfile'] = array();
|
||||||
|
$_FILES['userfile']['name'] = $_FILES['media']['name'][$x];
|
||||||
|
$_FILES['userfile']['type'] = $_FILES['media']['type'][$x];
|
||||||
|
$_FILES['userfile']['tmp_name'] = $_FILES['media']['tmp_name'][$x];
|
||||||
|
$_FILES['userfile']['error'] = $_FILES['media']['error'][$x];
|
||||||
|
$_FILES['userfile']['size'] = $_FILES['media']['size'][$x];
|
||||||
|
|
||||||
|
// upload each image if we have any
|
||||||
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
|
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
|
||||||
require_once('mod/wall_attach.php');
|
require_once('mod/wall_attach.php');
|
||||||
|
$a->data['api_info'] = $user_info;
|
||||||
$media = wall_attach_post($a);
|
$media = wall_attach_post($a);
|
||||||
|
|
||||||
if(strlen($media)>0)
|
if(strlen($media)>0)
|
||||||
$_REQUEST['body'] .= "\n\n" . $media;
|
$_REQUEST['body'] .= "\n\n" . $media;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// call out normal post function
|
// call out normal post function
|
||||||
|
|
||||||
@ -870,6 +884,7 @@ require_once('include/api_auth.php');
|
|||||||
// this should output the last post (the one we just posted).
|
// this should output the last post (the one we just posted).
|
||||||
return api_status_show($a,$type);
|
return api_status_show($a,$type);
|
||||||
}
|
}
|
||||||
|
api_register_func('api/statuses/update_with_media','api_statuses_update', true);
|
||||||
api_register_func('api/statuses/update','api_statuses_update', true);
|
api_register_func('api/statuses/update','api_statuses_update', true);
|
||||||
|
|
||||||
|
|
||||||
@ -1078,6 +1093,8 @@ require_once('include/api_auth.php');
|
|||||||
'contributors' => ''
|
'contributors' => ''
|
||||||
);
|
);
|
||||||
$status_info['user'] = $user_info;
|
$status_info['user'] = $user_info;
|
||||||
|
if(array_key_exists('status',$status_info['user']))
|
||||||
|
unset($status_info['user']['status']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return api_apply_template("status", $type, array('$status' => $status_info));
|
return api_apply_template("status", $type, array('$status' => $status_info));
|
||||||
@ -1319,6 +1336,8 @@ require_once('include/api_auth.php');
|
|||||||
|
|
||||||
// params
|
// params
|
||||||
$id = intval(argv(3));
|
$id = intval(argv(3));
|
||||||
|
if(! $id)
|
||||||
|
$id = $_REQUEST['id'];
|
||||||
|
|
||||||
logger('API: api_statuses_show: '.$id);
|
logger('API: api_statuses_show: '.$id);
|
||||||
|
|
||||||
@ -1335,10 +1354,12 @@ require_once('include/api_auth.php');
|
|||||||
$r = q("select * from item where true $item_normal $sql_extra",
|
$r = q("select * from item where true $item_normal $sql_extra",
|
||||||
intval($id)
|
intval($id)
|
||||||
);
|
);
|
||||||
|
|
||||||
xchan_query($r,true);
|
xchan_query($r,true);
|
||||||
|
|
||||||
$ret = api_format_items($r,$user_info);
|
$ret = api_format_items($r,$user_info);
|
||||||
|
|
||||||
|
|
||||||
if ($conversation) {
|
if ($conversation) {
|
||||||
$data = array('$statuses' => $ret);
|
$data = array('$statuses' => $ret);
|
||||||
return api_apply_template("timeline", $type, $data);
|
return api_apply_template("timeline", $type, $data);
|
||||||
@ -2298,28 +2319,28 @@ require_once('include/api_auth.php');
|
|||||||
api_register_func('api/direct_messages','api_direct_messages_inbox',true);
|
api_register_func('api/direct_messages','api_direct_messages_inbox',true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function api_oauth_request_token(&$a, $type){
|
function api_oauth_request_token(&$a, $type){
|
||||||
try{
|
try{
|
||||||
$oauth = new FKOAuth1();
|
$oauth = new ZotOAuth1();
|
||||||
$req = OAuthRequest::from_request();
|
$req = OAuth1Request::from_request();
|
||||||
logger('Req: ' . var_export($req,true));
|
logger('Req: ' . var_export($req,true),LOGGER_DATA);
|
||||||
$r = $oauth->fetch_request_token($req);
|
$r = $oauth->fetch_request_token($req);
|
||||||
}catch(Exception $e){
|
}catch(Exception $e){
|
||||||
logger('oauth_exception: ' . print_r($e->getMessage(),true));
|
logger('oauth_exception: ' . print_r($e->getMessage(),true));
|
||||||
echo "error=". OAuthUtil::urlencode_rfc3986($e->getMessage());
|
echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage());
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
echo $r;
|
echo $r;
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
|
|
||||||
function api_oauth_access_token(&$a, $type){
|
function api_oauth_access_token(&$a, $type){
|
||||||
try{
|
try{
|
||||||
$oauth = new FKOAuth1();
|
$oauth = new ZotOAuth1();
|
||||||
$req = OAuthRequest::from_request();
|
$req = OAuth1Request::from_request();
|
||||||
$r = $oauth->fetch_access_token($req);
|
$r = $oauth->fetch_access_token($req);
|
||||||
}catch(Exception $e){
|
}catch(Exception $e){
|
||||||
echo "error=". OAuthUtil::urlencode_rfc3986($e->getMessage()); killme();
|
echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage()); killme();
|
||||||
}
|
}
|
||||||
echo $r;
|
echo $r;
|
||||||
killme();
|
killme();
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
<?php /** @file */
|
<?php /** @file */
|
||||||
|
|
||||||
require_once("oauth.php");
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple HTTP Login
|
* API Login via basic-auth or OAuth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function api_login(&$a){
|
function api_login(&$a){
|
||||||
|
|
||||||
|
$record = null;
|
||||||
|
|
||||||
|
require_once('include/oauth.php');
|
||||||
|
|
||||||
// login with oauth
|
// login with oauth
|
||||||
try {
|
try {
|
||||||
$oauth = new FKOAuth1();
|
$oauth = new ZotOAuth1();
|
||||||
$req = OAuthRequest::from_request();
|
$req = OAuth1Request::from_request();
|
||||||
|
|
||||||
list($consumer,$token) = $oauth->verify_request($req);
|
list($consumer,$token) = $oauth->verify_request($req);
|
||||||
|
|
||||||
@ -23,16 +25,14 @@ function api_login(&$a){
|
|||||||
call_hooks('logged_in', $a->user);
|
call_hooks('logged_in', $a->user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
echo __file__.__line__.__function__."<pre>";
|
killme();
|
||||||
// var_dump($consumer, $token);
|
|
||||||
die();
|
|
||||||
}
|
}
|
||||||
catch(Exception $e) {
|
catch(Exception $e) {
|
||||||
logger(__file__.__line__.__function__."\n".$e);
|
logger($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workarounds for HTTP-auth in CGI mode
|
||||||
|
|
||||||
// workaround for HTTP-auth in CGI mode
|
|
||||||
if(x($_SERVER,'REDIRECT_REMOTE_USER')) {
|
if(x($_SERVER,'REDIRECT_REMOTE_USER')) {
|
||||||
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"],6)) ;
|
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"],6)) ;
|
||||||
if(strlen($userpass)) {
|
if(strlen($userpass)) {
|
||||||
@ -51,45 +51,49 @@ function api_login(&$a){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once('include/auth.php');
|
||||||
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
require_once('include/security.php');
|
||||||
logger('API_login: ' . print_r($_SERVER,true), LOGGER_DEBUG);
|
|
||||||
header('WWW-Authenticate: Basic realm="Red"');
|
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
|
||||||
die('This api requires login');
|
|
||||||
}
|
|
||||||
|
|
||||||
// process normal login request
|
// process normal login request
|
||||||
require_once('include/auth.php');
|
|
||||||
|
if(isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
$channel_login = 0;
|
$channel_login = 0;
|
||||||
$record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
|
$record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
|
||||||
if(! $record) {
|
if(! $record) {
|
||||||
$r = q("select * from channel where channel_address = '%s' limit 1",
|
$r = q("select * from channel left join account on account.account_id = channel.channel_account_id
|
||||||
|
where channel.channel_address = '%s' limit 1",
|
||||||
dbesc($_SERVER['PHP_AUTH_USER'])
|
dbesc($_SERVER['PHP_AUTH_USER'])
|
||||||
);
|
);
|
||||||
if ($r) {
|
if ($r) {
|
||||||
$x = q("select * from account where account_id = %d limit 1",
|
$record = account_verify_password($r[0]['account_email'],$_SERVER['PHP_AUTH_PW']);
|
||||||
intval($r[0]['channel_account_id'])
|
|
||||||
);
|
|
||||||
if ($x) {
|
|
||||||
$record = account_verify_password($x[0]['account_email'],$_SERVER['PHP_AUTH_PW']);
|
|
||||||
if($record)
|
if($record)
|
||||||
$channel_login = $r[0]['channel_id'];
|
$channel_login = $r[0]['channel_id'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(! $record) {
|
|
||||||
logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
|
|
||||||
header('WWW-Authenticate: Basic realm="Red"');
|
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
|
||||||
die('This api requires login');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once('include/security.php');
|
if($record) {
|
||||||
authenticate_success($record);
|
authenticate_success($record);
|
||||||
|
|
||||||
if($channel_login)
|
if($channel_login)
|
||||||
change_channel($channel_login);
|
change_channel($channel_login);
|
||||||
|
|
||||||
$_SESSION['allow_api'] = true;
|
$_SESSION['allow_api'] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$_SERVER['PHP_AUTH_PW'] = '*****';
|
||||||
|
logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
|
||||||
|
log_failed_login('API login failure');
|
||||||
|
retry_basic_auth();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function retry_basic_auth() {
|
||||||
|
header('WWW-Authenticate: Basic realm="Hubzilla"');
|
||||||
|
header('HTTP/1.0 401 Unauthorized');
|
||||||
|
echo('This api requires login');
|
||||||
|
killme();
|
||||||
}
|
}
|
@ -430,7 +430,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||||||
$observer = $x[0];
|
$observer = $x[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
logger('arr: ' . print_r($arr,true));
|
logger('arr: ' . print_r($arr,true), LOGGER_DATA);
|
||||||
|
|
||||||
if(! perm_is_allowed($channel_id,$observer_hash, 'write_storage')) {
|
if(! perm_is_allowed($channel_id,$observer_hash, 'write_storage')) {
|
||||||
$ret['message'] = t('Permission denied.');
|
$ret['message'] = t('Permission denied.');
|
||||||
|
@ -1227,7 +1227,7 @@ function status_editor($a, $x, $popup = false) {
|
|||||||
'$wait' => t('Please wait'),
|
'$wait' => t('Please wait'),
|
||||||
'$permset' => t('Permission settings'),
|
'$permset' => t('Permission settings'),
|
||||||
'$shortpermset' => t('permissions'),
|
'$shortpermset' => t('permissions'),
|
||||||
'$ptyp' => (($notes_cid) ? 'note' : 'wall'),
|
'$ptyp' => '',
|
||||||
'$content' => ((x($x,'body')) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8') : ''),
|
'$content' => ((x($x,'body')) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8') : ''),
|
||||||
'$attachment' => ((x($x, 'attachment')) ? $x['attachment'] : ''),
|
'$attachment' => ((x($x, 'attachment')) ? $x['attachment'] : ''),
|
||||||
'$post_id' => '',
|
'$post_id' => '',
|
||||||
|
@ -161,6 +161,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($r) {
|
if($r) {
|
||||||
|
$xchan = $r[0];
|
||||||
$xchan_hash = $r[0]['xchan_hash'];
|
$xchan_hash = $r[0]['xchan_hash'];
|
||||||
$their_perms = 0;
|
$their_perms = 0;
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => 1);
|
$x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => 1, 'singleton' => 0);
|
||||||
|
|
||||||
call_hooks('follow_allow',$x);
|
call_hooks('follow_allow',$x);
|
||||||
|
|
||||||
@ -180,7 +181,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||||||
$result['message'] = t('Protocol disabled.');
|
$result['message'] = t('Protocol disabled.');
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
$singleton = intval($x['singleton']);
|
||||||
|
|
||||||
if((local_channel()) && $uid == local_channel()) {
|
if((local_channel()) && $uid == local_channel()) {
|
||||||
$aid = get_account_id();
|
$aid = get_account_id();
|
||||||
@ -221,13 +222,22 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("select abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
$r = q("select abook_xchan, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||||
dbesc($xchan_hash),
|
dbesc($xchan_hash),
|
||||||
intval($uid)
|
intval($uid)
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
$x = q("update abook set abook_their_perms = %d where abook_id = %d",
|
$abook_instance = $r[0]['abook_instance'];
|
||||||
|
|
||||||
|
if(($singleton) && strpos($abook_instance,z_root()) === false) {
|
||||||
|
if($abook_instance)
|
||||||
|
$abook_instance .= ',';
|
||||||
|
$abook_instance .= z_root();
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = q("update abook set abook_their_perms = %d, abook_instance = '%s' where abook_id = %d",
|
||||||
intval($their_perms),
|
intval($their_perms),
|
||||||
|
dbesc($abook_instance),
|
||||||
intval($r[0]['abook_id'])
|
intval($r[0]['abook_id'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -237,8 +247,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||||||
if($closeness === false)
|
if($closeness === false)
|
||||||
$closeness = 80;
|
$closeness = 80;
|
||||||
|
|
||||||
$r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_their_perms, abook_my_perms, abook_created, abook_updated )
|
$r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_their_perms, abook_my_perms, abook_created, abook_updated, abook_instance )
|
||||||
values( %d, %d, %d, '%s', %d, %d, %d, '%s', '%s' ) ",
|
values( %d, %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s' ) ",
|
||||||
intval($aid),
|
intval($aid),
|
||||||
intval($uid),
|
intval($uid),
|
||||||
intval($closeness),
|
intval($closeness),
|
||||||
@ -247,7 +257,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||||||
intval(($is_http) ? $their_perms|PERMS_R_STREAM|PERMS_A_REPUBLISH : $their_perms),
|
intval(($is_http) ? $their_perms|PERMS_R_STREAM|PERMS_A_REPUBLISH : $their_perms),
|
||||||
intval($my_perms),
|
intval($my_perms),
|
||||||
dbesc(datetime_convert()),
|
dbesc(datetime_convert()),
|
||||||
dbesc(datetime_convert())
|
dbesc(datetime_convert()),
|
||||||
|
dbesc(($singleton) ? z_root() : '')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,12 +896,6 @@ function profile_load(&$a, $nickname, $profile = '') {
|
|||||||
|
|
||||||
$_SESSION['theme'] = $p[0]['channel_theme'];
|
$_SESSION['theme'] = $p[0]['channel_theme'];
|
||||||
|
|
||||||
// $a->set_template_engine(); // reset the template engine to the default in case the user's theme doesn't specify one
|
|
||||||
|
|
||||||
// $theme_info_file = "view/theme/".current_theme()."/php/theme.php";
|
|
||||||
// if (file_exists($theme_info_file)){
|
|
||||||
// require_once($theme_info_file);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2349,7 +2349,7 @@ function item_store($arr, $allow_exec = false) {
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($arr['obj_type'] == ACTIVITY_OBJ_NOTE)
|
if(($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['object']))
|
||||||
$arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
|
$arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
|
||||||
|
|
||||||
// is the new message multi-level threaded?
|
// is the new message multi-level threaded?
|
||||||
@ -2870,6 +2870,7 @@ function send_status_notifications($post_id,$item) {
|
|||||||
if($x) {
|
if($x) {
|
||||||
foreach($x as $xx) {
|
foreach($x as $xx) {
|
||||||
if($xx['author_xchan'] === $r[0]['channel_hash']) {
|
if($xx['author_xchan'] === $r[0]['channel_hash']) {
|
||||||
|
|
||||||
$notify = true;
|
$notify = true;
|
||||||
|
|
||||||
// check for an unfollow thread activity - we should probably decode the obj and check the id
|
// check for an unfollow thread activity - we should probably decode the obj and check the id
|
||||||
|
@ -1883,3 +1883,16 @@ function check_channelallowed($hash) {
|
|||||||
return $retvalue;
|
return $retvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deliverable_singleton($xchan) {
|
||||||
|
$r = q("select abook_instance from abook where abook_xchan = '%s' limit 1",
|
||||||
|
dbesc($xchan['xchan_hash'])
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
if(! $r[0]['abook_instance'])
|
||||||
|
return true;
|
||||||
|
if(strpos($r[0]['abook_instance'],z_root()) !== false)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ require_once('include/html2plain.php');
|
|||||||
* purge_all channel_id
|
* purge_all channel_id
|
||||||
* expire 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
|
* location channel_id
|
||||||
* request channel_id xchan_hash message_id
|
* request channel_id xchan_hash message_id
|
||||||
* rating xlink_id
|
* rating xlink_id
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php /** @file */
|
<?php /** @file */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OAuth server
|
* OAuth server
|
||||||
* Based on oauth2-php <http://code.google.com/p/oauth2-php/>
|
* Based on oauth2-php <http://code.google.com/p/oauth2-php/>
|
||||||
@ -9,16 +10,17 @@ define('REQUEST_TOKEN_DURATION', 300);
|
|||||||
define('ACCESS_TOKEN_DURATION', 31536000);
|
define('ACCESS_TOKEN_DURATION', 31536000);
|
||||||
|
|
||||||
require_once("library/OAuth1.php");
|
require_once("library/OAuth1.php");
|
||||||
require_once("library/oauth2-php/lib/OAuth2.inc");
|
|
||||||
|
|
||||||
class FKOAuthDataStore extends OAuthDataStore {
|
//require_once("library/oauth2-php/lib/OAuth2.inc");
|
||||||
|
|
||||||
|
class ZotOAuth1DataStore extends OAuth1DataStore {
|
||||||
|
|
||||||
function gen_token(){
|
function gen_token(){
|
||||||
return md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
|
return md5(base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), uniqid())));
|
||||||
}
|
}
|
||||||
|
|
||||||
function lookup_consumer($consumer_key) {
|
function lookup_consumer($consumer_key) {
|
||||||
logger(__function__.":".$consumer_key);
|
logger('consumer_key: ' . $consumer_key, LOGGER_DEBUG);
|
||||||
// echo "<pre>"; var_dump($consumer_key); killme();
|
|
||||||
|
|
||||||
$r = q("SELECT client_id, pw, redirect_uri FROM clients WHERE client_id = '%s'",
|
$r = q("SELECT client_id, pw, redirect_uri FROM clients WHERE client_id = '%s'",
|
||||||
dbesc($consumer_key)
|
dbesc($consumer_key)
|
||||||
@ -26,13 +28,14 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
|
|
||||||
if($r) {
|
if($r) {
|
||||||
get_app()->set_oauth_key($consumer_key);
|
get_app()->set_oauth_key($consumer_key);
|
||||||
return new OAuthConsumer($r[0]['client_id'],$r[0]['pw'],$r[0]['redirect_uri']);
|
return new OAuth1Consumer($r[0]['client_id'],$r[0]['pw'],$r[0]['redirect_uri']);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function lookup_token($consumer, $token_type, $token) {
|
function lookup_token($consumer, $token_type, $token) {
|
||||||
logger(__function__.":".$consumer.", ". $token_type.", ".$token);
|
|
||||||
|
logger(__function__.":".$consumer.", ". $token_type.", ".$token, LOGGER_DEBUG);
|
||||||
|
|
||||||
$r = q("SELECT id, secret, scope, expires, uid FROM tokens WHERE client_id = '%s' AND scope = '%s' AND id = '%s'",
|
$r = q("SELECT id, secret, scope, expires, uid FROM tokens WHERE client_id = '%s' AND scope = '%s' AND id = '%s'",
|
||||||
dbesc($consumer->key),
|
dbesc($consumer->key),
|
||||||
@ -41,7 +44,7 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (count($r)){
|
if (count($r)){
|
||||||
$ot=new OAuthToken($r[0]['id'],$r[0]['secret']);
|
$ot=new OAuth1Token($r[0]['id'],$r[0]['secret']);
|
||||||
$ot->scope=$r[0]['scope'];
|
$ot->scope=$r[0]['scope'];
|
||||||
$ot->expires = $r[0]['expires'];
|
$ot->expires = $r[0]['expires'];
|
||||||
$ot->uid = $r[0]['uid'];
|
$ot->uid = $r[0]['uid'];
|
||||||
@ -51,7 +54,6 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {
|
function lookup_nonce($consumer, $token, $nonce, $timestamp) {
|
||||||
// echo __file__.":".__line__."<pre>"; var_dump($consumer,$key); killme();
|
|
||||||
|
|
||||||
$r = q("SELECT id, secret FROM tokens WHERE client_id = '%s' AND id = '%s' AND expires = %d",
|
$r = q("SELECT id, secret FROM tokens WHERE client_id = '%s' AND id = '%s' AND expires = %d",
|
||||||
dbesc($consumer->key),
|
dbesc($consumer->key),
|
||||||
@ -60,12 +62,14 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (count($r))
|
if (count($r))
|
||||||
return new OAuthToken($r[0]['id'],$r[0]['secret']);
|
return new OAuth1Token($r[0]['id'],$r[0]['secret']);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function new_request_token($consumer, $callback = null) {
|
function new_request_token($consumer, $callback = null) {
|
||||||
logger(__function__.":".$consumer.", ". $callback);
|
|
||||||
|
logger(__function__.":".$consumer.", ". $callback, LOGGER_DEBUG);
|
||||||
|
|
||||||
$key = $this->gen_token();
|
$key = $this->gen_token();
|
||||||
$sec = $this->gen_token();
|
$sec = $this->gen_token();
|
||||||
|
|
||||||
@ -82,12 +86,14 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
'request',
|
'request',
|
||||||
time()+intval(REQUEST_TOKEN_DURATION));
|
time()+intval(REQUEST_TOKEN_DURATION));
|
||||||
|
|
||||||
if (!$r) return null;
|
if(! $r)
|
||||||
return new OAuthToken($key,$sec);
|
return null;
|
||||||
|
return new OAuth1Token($key,$sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
function new_access_token($token, $consumer, $verifier = null) {
|
function new_access_token($token, $consumer, $verifier = null) {
|
||||||
logger(__function__.":".$token.", ". $consumer.", ". $verifier);
|
|
||||||
|
logger(__function__.":".$token.", ". $consumer.", ". $verifier, LOGGER_DEBUG);
|
||||||
|
|
||||||
// return a new access token attached to this consumer
|
// return a new access token attached to this consumer
|
||||||
// for the user associated with this token if the request token
|
// for the user associated with this token if the request token
|
||||||
@ -98,7 +104,7 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
|
|
||||||
// get user for this verifier
|
// get user for this verifier
|
||||||
$uverifier = get_config("oauth", $verifier);
|
$uverifier = get_config("oauth", $verifier);
|
||||||
logger(__function__.":".$verifier.",".$uverifier);
|
logger(__function__.":".$verifier.",".$uverifier, LOGGER_DEBUG);
|
||||||
if (is_null($verifier) || ($uverifier!==false)) {
|
if (is_null($verifier) || ($uverifier!==false)) {
|
||||||
|
|
||||||
$key = $this->gen_token();
|
$key = $this->gen_token();
|
||||||
@ -113,7 +119,7 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
intval($uverifier));
|
intval($uverifier));
|
||||||
|
|
||||||
if ($r)
|
if ($r)
|
||||||
$ret = new OAuthToken($key,$sec);
|
$ret = new OAuth1Token($key,$sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,71 +128,60 @@ class FKOAuthDataStore extends OAuthDataStore {
|
|||||||
|
|
||||||
if (!is_null($ret) && $uverifier!==false) {
|
if (!is_null($ret) && $uverifier!==false) {
|
||||||
del_config("oauth", $verifier);
|
del_config("oauth", $verifier);
|
||||||
/* $apps = get_pconfig($uverifier, "oauth", "apps");
|
|
||||||
if ($apps===false) $apps=array();
|
|
||||||
$apps[] = $consumer->key;
|
|
||||||
set_pconfig($uverifier, "oauth", "apps", $apps);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// $apps = get_pconfig($uverifier, "oauth", "apps");
|
||||||
|
// if ($apps===false) $apps=array();
|
||||||
|
// $apps[] = $consumer->key;
|
||||||
|
// set_pconfig($uverifier, "oauth", "apps", $apps);
|
||||||
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FKOAuth1 extends OAuthServer {
|
class ZotOAuth1 extends OAuth1Server {
|
||||||
|
|
||||||
function __construct() {
|
function __construct() {
|
||||||
parent::__construct(new FKOAuthDataStore());
|
parent::__construct(new ZotOAuth1DataStore());
|
||||||
$this->add_signature_method(new OAuthSignatureMethod_PLAINTEXT());
|
$this->add_signature_method(new OAuth1SignatureMethod_PLAINTEXT());
|
||||||
$this->add_signature_method(new OAuthSignatureMethod_HMAC_SHA1());
|
$this->add_signature_method(new OAuth1SignatureMethod_HMAC_SHA1());
|
||||||
}
|
}
|
||||||
|
|
||||||
function loginUser($uid){
|
function loginUser($uid){
|
||||||
logger("RedOAuth1::loginUser $uid");
|
|
||||||
$a = get_app();
|
logger("ZotOAuth1::loginUser $uid");
|
||||||
|
|
||||||
$r = q("SELECT * FROM channel WHERE channel_id = %d LIMIT 1",
|
$r = q("SELECT * FROM channel WHERE channel_id = %d LIMIT 1",
|
||||||
intval($uid)
|
intval($uid)
|
||||||
);
|
);
|
||||||
if(count($r)){
|
if(count($r)){
|
||||||
$record = $r[0];
|
$record = $r[0];
|
||||||
} else {
|
} else {
|
||||||
logger('FKOAuth1::loginUser failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
|
logger('ZotOAuth1::loginUser failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
header('HTTP/1.0 401 Unauthorized');
|
||||||
die('This api requires login');
|
echo('This api requires login');
|
||||||
|
killme();
|
||||||
}
|
}
|
||||||
|
|
||||||
$_SESSION['uid'] = $record['channel_id'];
|
$_SESSION['uid'] = $record['channel_id'];
|
||||||
$_SESSION['theme'] = $record['channel_theme'];
|
|
||||||
$_SESSION['account_id'] = $record['channel_account_id'];
|
|
||||||
$_SESSION['mobile_theme'] = get_pconfig($record['channel_id'], 'system', 'mobile_theme');
|
|
||||||
$_SESSION['authenticated'] = 1;
|
|
||||||
$_SESSION['my_url'] = $a->get_baseurl() . '/channel/' . $record['channel_address'];
|
|
||||||
$_SESSION['addr'] = $_SERVER['REMOTE_ADDR'];
|
$_SESSION['addr'] = $_SERVER['REMOTE_ADDR'];
|
||||||
$_SESSION['allow_api'] = true;
|
|
||||||
$x = q("select * from account where account_id = %d limit 1",
|
$x = q("select * from account where account_id = %d limit 1",
|
||||||
intval($record['channel_account_id'])
|
intval($record['channel_account_id'])
|
||||||
);
|
);
|
||||||
if($x)
|
if($x) {
|
||||||
$a->account = $x[0];
|
require_once('include/security.php');
|
||||||
|
authenticate_success($x[0],true,false,true,true);
|
||||||
change_channel($record['channel_id']);
|
$_SESSION['allow_api'] = true;
|
||||||
|
|
||||||
$a->channel = $record;
|
|
||||||
|
|
||||||
if(strlen($a->channel['channel_timezone'])) {
|
|
||||||
date_default_timezone_set($a->channel['channel_timezone']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// q("UPDATE `user` SET `login_date` = '%s' WHERE `uid` = %d LIMIT 1",
|
|
||||||
// dbesc(datetime_convert()),
|
|
||||||
// intval($_SESSION['uid'])
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// call_hooks('logged_in', $a->user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
*
|
||||||
|
|
||||||
|
not yet used
|
||||||
|
|
||||||
class FKOAuth2 extends OAuth2 {
|
class FKOAuth2 extends OAuth2 {
|
||||||
|
|
||||||
private function db_secret($client_secret){
|
private function db_secret($client_secret){
|
||||||
|
@ -93,6 +93,7 @@ function change_channel($change_channel) {
|
|||||||
$ret = false;
|
$ret = false;
|
||||||
|
|
||||||
if($change_channel) {
|
if($change_channel) {
|
||||||
|
|
||||||
$r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and channel_removed = 0 limit 1",
|
$r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and channel_removed = 0 limit 1",
|
||||||
intval($change_channel),
|
intval($change_channel),
|
||||||
intval(get_account_id())
|
intval(get_account_id())
|
||||||
@ -136,14 +137,14 @@ function change_channel($change_channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates an addiontal SQL where statement to check permissions.
|
* @brief Creates an additional SQL where statement to check permissions.
|
||||||
*
|
*
|
||||||
* @param int $owner_id
|
* @param int $owner_id
|
||||||
* @param bool $remote_verified default false, not used at all
|
* @param bool $remote_observer - if unset use current observer
|
||||||
* @param string $groups this param is not used at all
|
|
||||||
*
|
*
|
||||||
* @return string additional SQL where statement
|
* @return string additional SQL where statement
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function permissions_sql($owner_id, $remote_observer = null) {
|
function permissions_sql($owner_id, $remote_observer = null) {
|
||||||
|
|
||||||
$local_channel = local_channel();
|
$local_channel = local_channel();
|
||||||
@ -208,8 +209,7 @@ function permissions_sql($owner_id, $remote_observer = null) {
|
|||||||
* @brief Creates an addiontal SQL where statement to check permissions for an item.
|
* @brief Creates an addiontal SQL where statement to check permissions for an item.
|
||||||
*
|
*
|
||||||
* @param int $owner_id
|
* @param int $owner_id
|
||||||
* @param bool $remote_verified default false, not used at all
|
* @param bool $remote_observer, use current observer if unset
|
||||||
* @param string $groups this param is not used at all
|
|
||||||
*
|
*
|
||||||
* @return string additional SQL where statement
|
* @return string additional SQL where statement
|
||||||
*/
|
*/
|
||||||
@ -400,11 +400,9 @@ function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'f
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns an array of group id's this contact is a member of.
|
// Returns an array of group hash id's on this entire site (across all channels) that this connection is a member of.
|
||||||
// This array will only contain group id's related to the uid of this
|
// var $contact_id = xchan_hash of connection
|
||||||
// DFRN contact. They are *not* neccessarily unique across the entire site.
|
|
||||||
|
|
||||||
if(! function_exists('init_groups_visitor')) {
|
|
||||||
function init_groups_visitor($contact_id) {
|
function init_groups_visitor($contact_id) {
|
||||||
$groups = array();
|
$groups = array();
|
||||||
$r = q("SELECT hash FROM `groups` left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
|
$r = q("SELECT hash FROM `groups` left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
|
||||||
@ -415,7 +413,7 @@ function init_groups_visitor($contact_id) {
|
|||||||
$groups[] = $rr['hash'];
|
$groups[] = $rr['hash'];
|
||||||
}
|
}
|
||||||
return $groups;
|
return $groups;
|
||||||
}}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3798,6 +3798,7 @@ function zotinfo($arr) {
|
|||||||
$ret['site'] = array();
|
$ret['site'] = array();
|
||||||
$ret['site']['url'] = z_root();
|
$ret['site']['url'] = z_root();
|
||||||
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
|
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
|
||||||
|
$ret['site']['zot_auth'] = z_root() . '/magic';
|
||||||
|
|
||||||
$dirmode = get_config('system','directory_mode');
|
$dirmode = get_config('system','directory_mode');
|
||||||
if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL))
|
if(($dirmode === false) || ($dirmode == DIRECTORY_MODE_NORMAL))
|
||||||
|
@ -382,3 +382,8 @@ stuff on your server that might access MySQL, and Hubzilla's poller which
|
|||||||
needs MySQL access, too. A good setting for a medium-sized hub might be to
|
needs MySQL access, too. A good setting for a medium-sized hub might be to
|
||||||
keep MySQL's max_connections at 100 and set mpm_prefork's
|
keep MySQL's max_connections at 100 and set mpm_prefork's
|
||||||
MaxRequestWorkers to 70.
|
MaxRequestWorkers to 70.
|
||||||
|
|
||||||
|
Here you can read more about Apache performance tuning:
|
||||||
|
https://httpd.apache.org/docs/2.4/misc/perf-tuning.html
|
||||||
|
|
||||||
|
There are tons of scripts to help you with fine-tuning your Apache installation. Just search with your favorite search engine 'apache fine-tuning script'.
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
/* Generic exception class
|
/* Generic exception class
|
||||||
*/
|
*/
|
||||||
class OAuthException extends Exception {
|
class OAuth1Exception extends Exception {
|
||||||
// pass
|
// pass
|
||||||
}
|
}
|
||||||
|
|
||||||
class OAuthConsumer {
|
class OAuth1Consumer {
|
||||||
public $key;
|
public $key;
|
||||||
public $secret;
|
public $secret;
|
||||||
|
|
||||||
@ -18,11 +18,11 @@ class OAuthConsumer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function __toString() {
|
function __toString() {
|
||||||
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
return "OAuth1Consumer[key=$this->key,secret=$this->secret]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OAuthToken {
|
class OAuth1Token {
|
||||||
// access tokens and request tokens
|
// access tokens and request tokens
|
||||||
public $key;
|
public $key;
|
||||||
public $secret;
|
public $secret;
|
||||||
@ -46,9 +46,9 @@ class OAuthToken {
|
|||||||
*/
|
*/
|
||||||
function to_string() {
|
function to_string() {
|
||||||
return "oauth_token=" .
|
return "oauth_token=" .
|
||||||
OAuthUtil::urlencode_rfc3986($this->key) .
|
OAuth1Util::urlencode_rfc3986($this->key) .
|
||||||
"&oauth_token_secret=" .
|
"&oauth_token_secret=" .
|
||||||
OAuthUtil::urlencode_rfc3986($this->secret);
|
OAuth1Util::urlencode_rfc3986($this->secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __toString() {
|
function __toString() {
|
||||||
@ -60,7 +60,7 @@ class OAuthToken {
|
|||||||
* A class for implementing a Signature Method
|
* A class for implementing a Signature Method
|
||||||
* See section 9 ("Signing Requests") in the spec
|
* See section 9 ("Signing Requests") in the spec
|
||||||
*/
|
*/
|
||||||
abstract class OAuthSignatureMethod {
|
abstract class OAuth1SignatureMethod {
|
||||||
/**
|
/**
|
||||||
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
||||||
* @return string
|
* @return string
|
||||||
@ -70,20 +70,20 @@ abstract class OAuthSignatureMethod {
|
|||||||
/**
|
/**
|
||||||
* Build up the signature
|
* Build up the signature
|
||||||
* NOTE: The output of this function MUST NOT be urlencoded.
|
* NOTE: The output of this function MUST NOT be urlencoded.
|
||||||
* the encoding is handled in OAuthRequest when the final
|
* the encoding is handled in OAuth1Request when the final
|
||||||
* request is serialized
|
* request is serialized
|
||||||
* @param OAuthRequest $request
|
* @param OAuth1Request $request
|
||||||
* @param OAuthConsumer $consumer
|
* @param OAuth1Consumer $consumer
|
||||||
* @param OAuthToken $token
|
* @param OAuth1Token $token
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
abstract public function build_signature($request, $consumer, $token);
|
abstract public function build_signature($request, $consumer, $token);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that a given signature is correct
|
* Verifies that a given signature is correct
|
||||||
* @param OAuthRequest $request
|
* @param OAuth1Request $request
|
||||||
* @param OAuthConsumer $consumer
|
* @param OAuth1Consumer $consumer
|
||||||
* @param OAuthToken $token
|
* @param OAuth1Token $token
|
||||||
* @param string $signature
|
* @param string $signature
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@ -101,7 +101,7 @@ abstract class OAuthSignatureMethod {
|
|||||||
* character (ASCII code 38) even if empty.
|
* character (ASCII code 38) even if empty.
|
||||||
* - Chapter 9.2 ("HMAC-SHA1")
|
* - Chapter 9.2 ("HMAC-SHA1")
|
||||||
*/
|
*/
|
||||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
class OAuth1SignatureMethod_HMAC_SHA1 extends OAuth1SignatureMethod {
|
||||||
function get_name() {
|
function get_name() {
|
||||||
return "HMAC-SHA1";
|
return "HMAC-SHA1";
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
|||||||
($token) ? $token->secret : ""
|
($token) ? $token->secret : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
$key_parts = OAuth1Util::urlencode_rfc3986($key_parts);
|
||||||
$key = implode('&', $key_parts);
|
$key = implode('&', $key_parts);
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
|||||||
* over a secure channel such as HTTPS. It does not use the Signature Base String.
|
* over a secure channel such as HTTPS. It does not use the Signature Base String.
|
||||||
* - Chapter 9.4 ("PLAINTEXT")
|
* - Chapter 9.4 ("PLAINTEXT")
|
||||||
*/
|
*/
|
||||||
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
class OAuth1SignatureMethod_PLAINTEXT extends OAuth1SignatureMethod {
|
||||||
public function get_name() {
|
public function get_name() {
|
||||||
return "PLAINTEXT";
|
return "PLAINTEXT";
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
|||||||
* - Chapter 9.4.1 ("Generating Signatures")
|
* - Chapter 9.4.1 ("Generating Signatures")
|
||||||
*
|
*
|
||||||
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
||||||
* OAuthRequest handles this!
|
* OAuth1Request handles this!
|
||||||
*/
|
*/
|
||||||
public function build_signature($request, $consumer, $token) {
|
public function build_signature($request, $consumer, $token) {
|
||||||
$key_parts = array(
|
$key_parts = array(
|
||||||
@ -149,7 +149,7 @@ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
|||||||
($token) ? $token->secret : ""
|
($token) ? $token->secret : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
$key_parts = OAuth1Util::urlencode_rfc3986($key_parts);
|
||||||
$key = implode('&', $key_parts);
|
$key = implode('&', $key_parts);
|
||||||
$request->base_string = $key;
|
$request->base_string = $key;
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
|||||||
* specification.
|
* specification.
|
||||||
* - Chapter 9.3 ("RSA-SHA1")
|
* - Chapter 9.3 ("RSA-SHA1")
|
||||||
*/
|
*/
|
||||||
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
abstract class OAuth1SignatureMethod_RSA_SHA1 extends OAuth1SignatureMethod {
|
||||||
public function get_name() {
|
public function get_name() {
|
||||||
return "RSA-SHA1";
|
return "RSA-SHA1";
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OAuthRequest {
|
class OAuth1Request {
|
||||||
private $parameters;
|
private $parameters;
|
||||||
private $http_method;
|
private $http_method;
|
||||||
private $http_url;
|
private $http_url;
|
||||||
@ -235,7 +235,7 @@ class OAuthRequest {
|
|||||||
|
|
||||||
function __construct($http_method, $http_url, $parameters=NULL) {
|
function __construct($http_method, $http_url, $parameters=NULL) {
|
||||||
@$parameters or $parameters = array();
|
@$parameters or $parameters = array();
|
||||||
$parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
$parameters = array_merge( OAuth1Util::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
$this->http_method = $http_method;
|
$this->http_method = $http_method;
|
||||||
$this->http_url = $http_url;
|
$this->http_url = $http_url;
|
||||||
@ -262,10 +262,10 @@ class OAuthRequest {
|
|||||||
// parsed parameter-list
|
// parsed parameter-list
|
||||||
if (!$parameters) {
|
if (!$parameters) {
|
||||||
// Find request headers
|
// Find request headers
|
||||||
$request_headers = OAuthUtil::get_headers();
|
$request_headers = OAuth1Util::get_headers();
|
||||||
|
|
||||||
// Parse the query-string to find GET parameters
|
// Parse the query-string to find GET parameters
|
||||||
$parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
|
$parameters = OAuth1Util::parse_parameters($_SERVER['QUERY_STRING']);
|
||||||
|
|
||||||
// It's a POST request of the proper content-type, so parse POST
|
// It's a POST request of the proper content-type, so parse POST
|
||||||
// parameters and add those overriding any duplicates from GET
|
// parameters and add those overriding any duplicates from GET
|
||||||
@ -274,7 +274,7 @@ class OAuthRequest {
|
|||||||
"application/x-www-form-urlencoded")
|
"application/x-www-form-urlencoded")
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$post_data = OAuthUtil::parse_parameters(
|
$post_data = OAuth1Util::parse_parameters(
|
||||||
file_get_contents(self::$POST_INPUT)
|
file_get_contents(self::$POST_INPUT)
|
||||||
);
|
);
|
||||||
$parameters = array_merge($parameters, $post_data);
|
$parameters = array_merge($parameters, $post_data);
|
||||||
@ -283,7 +283,7 @@ class OAuthRequest {
|
|||||||
// We have a Authorization-header with OAuth data. Parse the header
|
// We have a Authorization-header with OAuth data. Parse the header
|
||||||
// and add those overriding any duplicates from GET or POST
|
// and add those overriding any duplicates from GET or POST
|
||||||
if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
|
if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
|
||||||
$header_parameters = OAuthUtil::split_header(
|
$header_parameters = OAuth1Util::split_header(
|
||||||
$request_headers['Authorization']
|
$request_headers['Authorization']
|
||||||
);
|
);
|
||||||
$parameters = array_merge($parameters, $header_parameters);
|
$parameters = array_merge($parameters, $header_parameters);
|
||||||
@ -296,7 +296,7 @@ class OAuthRequest {
|
|||||||
$http_url = substr($http_url, 0, strpos($http_url,$parameters['q'])+strlen($parameters['q']));
|
$http_url = substr($http_url, 0, strpos($http_url,$parameters['q'])+strlen($parameters['q']));
|
||||||
unset( $parameters['q'] );
|
unset( $parameters['q'] );
|
||||||
|
|
||||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
return new OAuth1Request($http_method, $http_url, $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,16 +304,16 @@ class OAuthRequest {
|
|||||||
*/
|
*/
|
||||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
|
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
|
||||||
@$parameters or $parameters = array();
|
@$parameters or $parameters = array();
|
||||||
$defaults = array("oauth_version" => OAuthRequest::$version,
|
$defaults = array("oauth_version" => OAuth1Request::$version,
|
||||||
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
"oauth_nonce" => OAuth1Request::generate_nonce(),
|
||||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
"oauth_timestamp" => OAuth1Request::generate_timestamp(),
|
||||||
"oauth_consumer_key" => $consumer->key);
|
"oauth_consumer_key" => $consumer->key);
|
||||||
if ($token)
|
if ($token)
|
||||||
$defaults['oauth_token'] = $token->key;
|
$defaults['oauth_token'] = $token->key;
|
||||||
|
|
||||||
$parameters = array_merge($defaults, $parameters);
|
$parameters = array_merge($defaults, $parameters);
|
||||||
|
|
||||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
return new OAuth1Request($http_method, $http_url, $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function set_parameter($name, $value, $allow_duplicates = true) {
|
public function set_parameter($name, $value, $allow_duplicates = true) {
|
||||||
@ -357,7 +357,7 @@ class OAuthRequest {
|
|||||||
unset($params['oauth_signature']);
|
unset($params['oauth_signature']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OAuthUtil::build_http_query($params);
|
return OAuth1Util::build_http_query($params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -374,7 +374,7 @@ class OAuthRequest {
|
|||||||
$this->get_signable_parameters()
|
$this->get_signable_parameters()
|
||||||
);
|
);
|
||||||
|
|
||||||
$parts = OAuthUtil::urlencode_rfc3986($parts);
|
$parts = OAuth1Util::urlencode_rfc3986($parts);
|
||||||
|
|
||||||
return implode('&', $parts);
|
return implode('&', $parts);
|
||||||
}
|
}
|
||||||
@ -423,7 +423,7 @@ class OAuthRequest {
|
|||||||
* builds the data one would send in a POST request
|
* builds the data one would send in a POST request
|
||||||
*/
|
*/
|
||||||
public function to_postdata() {
|
public function to_postdata() {
|
||||||
return OAuthUtil::build_http_query($this->parameters);
|
return OAuth1Util::build_http_query($this->parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -432,7 +432,7 @@ class OAuthRequest {
|
|||||||
public function to_header($realm=null) {
|
public function to_header($realm=null) {
|
||||||
$first = true;
|
$first = true;
|
||||||
if($realm) {
|
if($realm) {
|
||||||
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
|
$out = 'Authorization: OAuth realm="' . OAuth1Util::urlencode_rfc3986($realm) . '"';
|
||||||
$first = false;
|
$first = false;
|
||||||
} else
|
} else
|
||||||
$out = 'Authorization: OAuth';
|
$out = 'Authorization: OAuth';
|
||||||
@ -441,12 +441,12 @@ class OAuthRequest {
|
|||||||
foreach ($this->parameters as $k => $v) {
|
foreach ($this->parameters as $k => $v) {
|
||||||
if (substr($k, 0, 5) != "oauth") continue;
|
if (substr($k, 0, 5) != "oauth") continue;
|
||||||
if (is_array($v)) {
|
if (is_array($v)) {
|
||||||
throw new OAuthException('Arrays not supported in headers');
|
throw new OAuth1Exception('Arrays not supported in headers');
|
||||||
}
|
}
|
||||||
$out .= ($first) ? ' ' : ',';
|
$out .= ($first) ? ' ' : ',';
|
||||||
$out .= OAuthUtil::urlencode_rfc3986($k) .
|
$out .= OAuth1Util::urlencode_rfc3986($k) .
|
||||||
'="' .
|
'="' .
|
||||||
OAuthUtil::urlencode_rfc3986($v) .
|
OAuth1Util::urlencode_rfc3986($v) .
|
||||||
'"';
|
'"';
|
||||||
$first = false;
|
$first = false;
|
||||||
}
|
}
|
||||||
@ -491,7 +491,7 @@ class OAuthRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OAuthServer {
|
class OAuth1Server {
|
||||||
protected $timestamp_threshold = 300; // in seconds, five minutes
|
protected $timestamp_threshold = 300; // in seconds, five minutes
|
||||||
protected $version = '1.0'; // hi blaine
|
protected $version = '1.0'; // hi blaine
|
||||||
protected $signature_methods = array();
|
protected $signature_methods = array();
|
||||||
@ -572,7 +572,7 @@ class OAuthServer {
|
|||||||
$version = '1.0';
|
$version = '1.0';
|
||||||
}
|
}
|
||||||
if ($version !== $this->version) {
|
if ($version !== $this->version) {
|
||||||
throw new OAuthException("OAuth version '$version' not supported");
|
throw new OAuth1Exception("OAuth1 version '$version' not supported");
|
||||||
}
|
}
|
||||||
return $version;
|
return $version;
|
||||||
}
|
}
|
||||||
@ -587,12 +587,12 @@ class OAuthServer {
|
|||||||
if (!$signature_method) {
|
if (!$signature_method) {
|
||||||
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
|
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
|
||||||
// parameter is required, and we can't just fallback to PLAINTEXT
|
// parameter is required, and we can't just fallback to PLAINTEXT
|
||||||
throw new OAuthException('No signature method parameter. This parameter is required');
|
throw new OAuth1Exception('No signature method parameter. This parameter is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($signature_method,
|
if (!in_array($signature_method,
|
||||||
array_keys($this->signature_methods))) {
|
array_keys($this->signature_methods))) {
|
||||||
throw new OAuthException(
|
throw new OAuth1Exception(
|
||||||
"Signature method '$signature_method' not supported " .
|
"Signature method '$signature_method' not supported " .
|
||||||
"try one of the following: " .
|
"try one of the following: " .
|
||||||
implode(", ", array_keys($this->signature_methods))
|
implode(", ", array_keys($this->signature_methods))
|
||||||
@ -607,12 +607,12 @@ class OAuthServer {
|
|||||||
private function get_consumer(&$request) {
|
private function get_consumer(&$request) {
|
||||||
$consumer_key = @$request->get_parameter("oauth_consumer_key");
|
$consumer_key = @$request->get_parameter("oauth_consumer_key");
|
||||||
if (!$consumer_key) {
|
if (!$consumer_key) {
|
||||||
throw new OAuthException("Invalid consumer key");
|
throw new OAuth1Exception("Invalid consumer key");
|
||||||
}
|
}
|
||||||
|
|
||||||
$consumer = $this->data_store->lookup_consumer($consumer_key);
|
$consumer = $this->data_store->lookup_consumer($consumer_key);
|
||||||
if (!$consumer) {
|
if (!$consumer) {
|
||||||
throw new OAuthException("Invalid consumer");
|
throw new OAuth1Exception("Invalid consumer");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $consumer;
|
return $consumer;
|
||||||
@ -627,7 +627,7 @@ class OAuthServer {
|
|||||||
$consumer, $token_type, $token_field
|
$consumer, $token_type, $token_field
|
||||||
);
|
);
|
||||||
if (!$token) {
|
if (!$token) {
|
||||||
throw new OAuthException("Invalid $token_type token: $token_field");
|
throw new OAuth1Exception("Invalid $token_type token: $token_field");
|
||||||
}
|
}
|
||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
@ -656,7 +656,7 @@ class OAuthServer {
|
|||||||
|
|
||||||
|
|
||||||
if (!$valid_sig) {
|
if (!$valid_sig) {
|
||||||
throw new OAuthException("Invalid signature");
|
throw new OAuth1Exception("Invalid signature");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,14 +665,14 @@ class OAuthServer {
|
|||||||
*/
|
*/
|
||||||
private function check_timestamp($timestamp) {
|
private function check_timestamp($timestamp) {
|
||||||
if( ! $timestamp )
|
if( ! $timestamp )
|
||||||
throw new OAuthException(
|
throw new OAuth1Exception(
|
||||||
'Missing timestamp parameter. The parameter is required'
|
'Missing timestamp parameter. The parameter is required'
|
||||||
);
|
);
|
||||||
|
|
||||||
// verify that timestamp is recentish
|
// verify that timestamp is recentish
|
||||||
$now = time();
|
$now = time();
|
||||||
if (abs($now - $timestamp) > $this->timestamp_threshold) {
|
if (abs($now - $timestamp) > $this->timestamp_threshold) {
|
||||||
throw new OAuthException(
|
throw new OAuth1Exception(
|
||||||
"Expired timestamp, yours $timestamp, ours $now"
|
"Expired timestamp, yours $timestamp, ours $now"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -683,7 +683,7 @@ class OAuthServer {
|
|||||||
*/
|
*/
|
||||||
private function check_nonce($consumer, $token, $nonce, $timestamp) {
|
private function check_nonce($consumer, $token, $nonce, $timestamp) {
|
||||||
if( ! $nonce )
|
if( ! $nonce )
|
||||||
throw new OAuthException(
|
throw new OAuth1Exception(
|
||||||
'Missing nonce parameter. The parameter is required'
|
'Missing nonce parameter. The parameter is required'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -695,13 +695,13 @@ class OAuthServer {
|
|||||||
$timestamp
|
$timestamp
|
||||||
);
|
);
|
||||||
if ($found) {
|
if ($found) {
|
||||||
throw new OAuthException("Nonce already used: $nonce");
|
throw new OAuth1Exception("Nonce already used: $nonce");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class OAuthDataStore {
|
class OAuth1DataStore {
|
||||||
function lookup_consumer($consumer_key) {
|
function lookup_consumer($consumer_key) {
|
||||||
// implement me
|
// implement me
|
||||||
}
|
}
|
||||||
@ -727,10 +727,10 @@ class OAuthDataStore {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class OAuthUtil {
|
class OAuth1Util {
|
||||||
public static function urlencode_rfc3986($input) {
|
public static function urlencode_rfc3986($input) {
|
||||||
if (is_array($input)) {
|
if (is_array($input)) {
|
||||||
return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
|
return array_map(array('OAuth1Util', 'urlencode_rfc3986'), $input);
|
||||||
} else if (is_scalar($input)) {
|
} else if (is_scalar($input)) {
|
||||||
return str_replace(
|
return str_replace(
|
||||||
'+',
|
'+',
|
||||||
@ -762,7 +762,7 @@ class OAuthUtil {
|
|||||||
$header_name = $matches[2][0];
|
$header_name = $matches[2][0];
|
||||||
$header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
|
$header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
|
||||||
if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
|
if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
|
||||||
$params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
|
$params[$header_name] = OAuth1Util::urldecode_rfc3986($header_content);
|
||||||
}
|
}
|
||||||
$offset = $match[1] + strlen($match[0]);
|
$offset = $match[1] + strlen($match[0]);
|
||||||
}
|
}
|
||||||
@ -834,8 +834,8 @@ class OAuthUtil {
|
|||||||
$parsed_parameters = array();
|
$parsed_parameters = array();
|
||||||
foreach ($pairs as $pair) {
|
foreach ($pairs as $pair) {
|
||||||
$split = explode('=', $pair, 2);
|
$split = explode('=', $pair, 2);
|
||||||
$parameter = OAuthUtil::urldecode_rfc3986($split[0]);
|
$parameter = OAuth1Util::urldecode_rfc3986($split[0]);
|
||||||
$value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
|
$value = isset($split[1]) ? OAuth1Util::urldecode_rfc3986($split[1]) : '';
|
||||||
|
|
||||||
if (isset($parsed_parameters[$parameter])) {
|
if (isset($parsed_parameters[$parameter])) {
|
||||||
// We have already recieved parameter(s) with this name, so add to the list
|
// We have already recieved parameter(s) with this name, so add to the list
|
||||||
@ -859,8 +859,8 @@ class OAuthUtil {
|
|||||||
if (!$params) return '';
|
if (!$params) return '';
|
||||||
|
|
||||||
// Urlencode both keys and values
|
// Urlencode both keys and values
|
||||||
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
|
$keys = OAuth1Util::urlencode_rfc3986(array_keys($params));
|
||||||
$values = OAuthUtil::urlencode_rfc3986(array_values($params));
|
$values = OAuth1Util::urlencode_rfc3986(array_values($params));
|
||||||
$params = array_combine($keys, $values);
|
$params = array_combine($keys, $values);
|
||||||
|
|
||||||
// Parameters are sorted by name, using lexicographical byte value ordering.
|
// Parameters are sorted by name, using lexicographical byte value ordering.
|
||||||
@ -885,5 +885,3 @@ class OAuthUtil {
|
|||||||
return implode('&', $pairs);
|
return implode('&', $pairs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
@ -4078,3 +4078,33 @@ Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
|
|||||||
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
|
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
|
||||||
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
|
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Lets Encrypt
|
||||||
|
============
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw
|
||||||
|
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
|
||||||
|
Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa
|
||||||
|
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
|
||||||
|
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||||
|
ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB
|
||||||
|
BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg
|
||||||
|
PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG
|
||||||
|
dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1
|
||||||
|
gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4
|
||||||
|
4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud
|
||||||
|
EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy
|
||||||
|
BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j
|
||||||
|
b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv
|
||||||
|
ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ
|
||||||
|
MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH
|
||||||
|
AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw
|
||||||
|
MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM
|
||||||
|
LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3
|
||||||
|
pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd
|
||||||
|
v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd
|
||||||
|
ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW
|
||||||
|
ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk
|
||||||
|
6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj
|
||||||
|
f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
@ -3986,3 +3986,33 @@ PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
|
|||||||
kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
|
kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
|
||||||
ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
|
ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
Lets Encrypt
|
||||||
|
============
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw
|
||||||
|
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
|
||||||
|
Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa
|
||||||
|
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
|
||||||
|
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||||
|
ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB
|
||||||
|
BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg
|
||||||
|
PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG
|
||||||
|
dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1
|
||||||
|
gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4
|
||||||
|
4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud
|
||||||
|
EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy
|
||||||
|
BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j
|
||||||
|
b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv
|
||||||
|
ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ
|
||||||
|
MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH
|
||||||
|
AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw
|
||||||
|
MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM
|
||||||
|
LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3
|
||||||
|
pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd
|
||||||
|
v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd
|
||||||
|
ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW
|
||||||
|
ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk
|
||||||
|
6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj
|
||||||
|
f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
379
library/ical.php
379
library/ical.php
@ -1,379 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* This PHP-Class should only read a iCal-File (*.ics), parse it and give an
|
|
||||||
* array with its content.
|
|
||||||
*
|
|
||||||
* PHP Version 5
|
|
||||||
*
|
|
||||||
* @category Parser
|
|
||||||
* @package Ics-parser
|
|
||||||
* @author Martin Thoma <info@martin-thoma.de>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
|
||||||
* @version SVN: <svn_id>
|
|
||||||
* @link http://code.google.com/p/ics-parser/
|
|
||||||
* @example $ical = new ical('MyCal.ics');
|
|
||||||
* print_r( $ical->events() );
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This example demonstrates how the Ics-Parser should be used.
|
|
||||||
*
|
|
||||||
* PHP Version 5
|
|
||||||
*
|
|
||||||
* @category Example
|
|
||||||
* @package Ics-parser
|
|
||||||
* @author Martin Thoma <info@martin-thoma.de>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
|
||||||
* @version SVN: <svn_id>
|
|
||||||
* @link http://code.google.com/p/ics-parser/
|
|
||||||
* @example $ical = new ical('MyCal.ics');
|
|
||||||
* print_r( $ical->get_event_array() );
|
|
||||||
|
|
||||||
require 'class.iCalReader.php';
|
|
||||||
|
|
||||||
$ical = new ICal('MyCal.ics');
|
|
||||||
$events = $ical->events();
|
|
||||||
|
|
||||||
$date = $events[0]['DTSTART'];
|
|
||||||
echo "The ical date: ";
|
|
||||||
echo $date;
|
|
||||||
echo "<br/>";
|
|
||||||
|
|
||||||
echo "The Unix timestamp: ";
|
|
||||||
echo $ical->iCalDateToUnixTimestamp($date);
|
|
||||||
echo "<br/>";
|
|
||||||
|
|
||||||
echo "The number of events: ";
|
|
||||||
echo $ical->event_count;
|
|
||||||
echo "<br/>";
|
|
||||||
|
|
||||||
echo "The number of todos: ";
|
|
||||||
echo $ical->todo_count;
|
|
||||||
echo "<br/>";
|
|
||||||
echo "<hr/><hr/>";
|
|
||||||
|
|
||||||
foreach ($events as $event) {
|
|
||||||
echo "SUMMARY: ".$event['SUMMARY']."<br/>";
|
|
||||||
echo "DTSTART: ".$event['DTSTART']." - UNIX-Time: ".$ical->iCalDateToUnixTimestamp($event['DTSTART'])."<br/>";
|
|
||||||
echo "DTEND: ".$event['DTEND']."<br/>";
|
|
||||||
echo "DTSTAMP: ".$event['DTSTAMP']."<br/>";
|
|
||||||
echo "UID: ".$event['UID']."<br/>";
|
|
||||||
echo "CREATED: ".$event['CREATED']."<br/>";
|
|
||||||
echo "DESCRIPTION: ".$event['DESCRIPTION']."<br/>";
|
|
||||||
echo "LAST-MODIFIED: ".$event['LAST-MODIFIED']."<br/>";
|
|
||||||
echo "LOCATION: ".$event['LOCATION']."<br/>";
|
|
||||||
echo "SEQUENCE: ".$event['SEQUENCE']."<br/>";
|
|
||||||
echo "STATUS: ".$event['STATUS']."<br/>";
|
|
||||||
echo "TRANSP: ".$event['TRANSP']."<br/>";
|
|
||||||
echo "<hr/>";
|
|
||||||
}
|
|
||||||
|
|
||||||
(end example)
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// error_reporting(E_ALL);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the iCal-class
|
|
||||||
*
|
|
||||||
* @category Parser
|
|
||||||
* @package Ics-parser
|
|
||||||
* @author Martin Thoma <info@martin-thoma.de>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
|
||||||
* @link http://code.google.com/p/ics-parser/
|
|
||||||
*
|
|
||||||
* @param {string} filename The name of the file which should be parsed
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
class ICal
|
|
||||||
{
|
|
||||||
/* How many ToDos are in this ical? */
|
|
||||||
public /** @type {int} */ $todo_count = 0;
|
|
||||||
|
|
||||||
/* How many events are in this ical? */
|
|
||||||
public /** @type {int} */ $event_count = 0;
|
|
||||||
|
|
||||||
/* The parsed calendar */
|
|
||||||
public /** @type {Array} */ $cal;
|
|
||||||
|
|
||||||
/* Which keyword has been added to cal at last? */
|
|
||||||
private /** @type {string} */ $_lastKeyWord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the iCal-Object
|
|
||||||
*
|
|
||||||
* @param {string} $filename The path to the iCal-file
|
|
||||||
*
|
|
||||||
* @return Object The iCal-Object
|
|
||||||
*/
|
|
||||||
public function __construct($filename)
|
|
||||||
{
|
|
||||||
if (!$filename) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
||||||
if (stristr($lines[0], 'BEGIN:VCALENDAR') === false) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// TODO: Fix multiline-description problem (see http://tools.ietf.org/html/rfc2445#section-4.8.1.5)
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
$line = trim($line);
|
|
||||||
$add = $this->keyValueFromString($line);
|
|
||||||
if ($add === false) {
|
|
||||||
$this->addCalendarComponentWithKeyAndValue($type, false, $line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($keyword, $value) = $add;
|
|
||||||
|
|
||||||
switch ($line) {
|
|
||||||
// http://www.kanzaki.com/docs/ical/vtodo.html
|
|
||||||
case "BEGIN:VTODO":
|
|
||||||
$this->todo_count++;
|
|
||||||
$type = "VTODO";
|
|
||||||
break;
|
|
||||||
|
|
||||||
// http://www.kanzaki.com/docs/ical/vevent.html
|
|
||||||
case "BEGIN:VEVENT":
|
|
||||||
//echo "vevent gematcht";
|
|
||||||
$this->event_count++;
|
|
||||||
$type = "VEVENT";
|
|
||||||
break;
|
|
||||||
|
|
||||||
//all other special strings
|
|
||||||
case "BEGIN:VCALENDAR":
|
|
||||||
case "BEGIN:DAYLIGHT":
|
|
||||||
// http://www.kanzaki.com/docs/ical/vtimezone.html
|
|
||||||
case "BEGIN:VTIMEZONE":
|
|
||||||
case "BEGIN:STANDARD":
|
|
||||||
$type = $value;
|
|
||||||
break;
|
|
||||||
case "END:VTODO": // end special text - goto VCALENDAR key
|
|
||||||
case "END:VEVENT":
|
|
||||||
case "END:VCALENDAR":
|
|
||||||
case "END:DAYLIGHT":
|
|
||||||
case "END:VTIMEZONE":
|
|
||||||
case "END:STANDARD":
|
|
||||||
$type = "VCALENDAR";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->addCalendarComponentWithKeyAndValue($type,
|
|
||||||
$keyword,
|
|
||||||
$value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->cal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add to $this->ical array one value and key.
|
|
||||||
*
|
|
||||||
* @param {string} $component This could be VTODO, VEVENT, VCALENDAR, ...
|
|
||||||
* @param {string} $keyword The keyword, for example DTSTART
|
|
||||||
* @param {string} $value The value, for example 20110105T090000Z
|
|
||||||
*
|
|
||||||
* @return {None}
|
|
||||||
*/
|
|
||||||
public function addCalendarComponentWithKeyAndValue($component,
|
|
||||||
$keyword,
|
|
||||||
$value)
|
|
||||||
{
|
|
||||||
if ($keyword == false) {
|
|
||||||
$keyword = $this->last_keyword;
|
|
||||||
switch ($component) {
|
|
||||||
case 'VEVENT':
|
|
||||||
$value = $this->cal[$component][$this->event_count - 1]
|
|
||||||
[$keyword].$value;
|
|
||||||
break;
|
|
||||||
case 'VTODO' :
|
|
||||||
$value = $this->cal[$component][$this->todo_count - 1]
|
|
||||||
[$keyword].$value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stristr($keyword, "DTSTART") or stristr($keyword, "DTEND")) {
|
|
||||||
$keyword = explode(";", $keyword);
|
|
||||||
$keyword = $keyword[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($component) {
|
|
||||||
case "VTODO":
|
|
||||||
$this->cal[$component][$this->todo_count - 1][$keyword] = $value;
|
|
||||||
//$this->cal[$component][$this->todo_count]['Unix'] = $unixtime;
|
|
||||||
break;
|
|
||||||
case "VEVENT":
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword] = $value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->cal[$component][$keyword] = $value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$this->last_keyword = $keyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a key-value pair of a string.
|
|
||||||
*
|
|
||||||
* @param {string} $text which is like "VCALENDAR:Begin" or "LOCATION:"
|
|
||||||
*
|
|
||||||
* @return {array} array("VCALENDAR", "Begin")
|
|
||||||
*/
|
|
||||||
public function keyValueFromString($text)
|
|
||||||
{
|
|
||||||
preg_match("/([^:]+)[:]([\w\W]*)/", $text, $matches);
|
|
||||||
if (count($matches) == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$matches = array_splice($matches, 1, 2);
|
|
||||||
return $matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return Unix timestamp from ical date time format
|
|
||||||
*
|
|
||||||
* @param {string} $icalDate A Date in the format YYYYMMDD[T]HHMMSS[Z] or
|
|
||||||
* YYYYMMDD[T]HHMMSS
|
|
||||||
*
|
|
||||||
* @return {int}
|
|
||||||
*/
|
|
||||||
public function iCalDateToUnixTimestamp($icalDate)
|
|
||||||
{
|
|
||||||
$icalDate = str_replace('T', '', $icalDate);
|
|
||||||
$icalDate = str_replace('Z', '', $icalDate);
|
|
||||||
|
|
||||||
$pattern = '/([0-9]{4})'; // 1: YYYY
|
|
||||||
$pattern .= '([0-9]{2})'; // 2: MM
|
|
||||||
$pattern .= '([0-9]{2})'; // 3: DD
|
|
||||||
$pattern .= '([0-9]{0,2})'; // 4: HH
|
|
||||||
$pattern .= '([0-9]{0,2})'; // 5: MM
|
|
||||||
$pattern .= '([0-9]{0,2})/'; // 6: SS
|
|
||||||
preg_match($pattern, $icalDate, $date);
|
|
||||||
|
|
||||||
// Unix timestamp can't represent dates before 1970
|
|
||||||
if ($date[1] <= 1970) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Unix timestamps after 03:14:07 UTC 2038-01-19 might cause an overflow
|
|
||||||
// if 32 bit integers are used.
|
|
||||||
$timestamp = mktime((int)$date[4],
|
|
||||||
(int)$date[5],
|
|
||||||
(int)$date[6],
|
|
||||||
(int)$date[2],
|
|
||||||
(int)$date[3],
|
|
||||||
(int)$date[1]);
|
|
||||||
return $timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of arrays with all events. Every event is an associative
|
|
||||||
* array and each property is an element it.
|
|
||||||
*
|
|
||||||
* @return {array}
|
|
||||||
*/
|
|
||||||
public function events()
|
|
||||||
{
|
|
||||||
$array = $this->cal;
|
|
||||||
return $array['VEVENT'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a boolean value whether thr current calendar has events or not
|
|
||||||
*
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
public function hasEvents()
|
|
||||||
{
|
|
||||||
return ( count($this->events()) > 0 ? true : false );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns false when the current calendar has no events in range, else the
|
|
||||||
* events.
|
|
||||||
*
|
|
||||||
* Note that this function makes use of a UNIX timestamp. This might be a
|
|
||||||
* problem on January the 29th, 2038.
|
|
||||||
* See http://en.wikipedia.org/wiki/Unix_time#Representing_the_number
|
|
||||||
*
|
|
||||||
* @param {boolean} $rangeStart Either true or false
|
|
||||||
* @param {boolean} $rangeEnd Either true or false
|
|
||||||
*
|
|
||||||
* @return {mixed}
|
|
||||||
*/
|
|
||||||
public function eventsFromRange($rangeStart = false, $rangeEnd = false)
|
|
||||||
{
|
|
||||||
$events = $this->sortEventsWithOrder($this->events(), SORT_ASC);
|
|
||||||
|
|
||||||
if (!$events) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$extendedEvents = array();
|
|
||||||
|
|
||||||
if ($rangeStart !== false) {
|
|
||||||
$rangeStart = new DateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rangeEnd !== false or $rangeEnd <= 0) {
|
|
||||||
$rangeEnd = new DateTime('2038/01/18');
|
|
||||||
} else {
|
|
||||||
$rangeEnd = new DateTime($rangeEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
$rangeStart = $rangeStart->format('U');
|
|
||||||
$rangeEnd = $rangeEnd->format('U');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// loop through all events by adding two new elements
|
|
||||||
foreach ($events as $anEvent) {
|
|
||||||
$timestamp = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
|
||||||
if ($timestamp >= $rangeStart && $timestamp <= $rangeEnd) {
|
|
||||||
$extendedEvents[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $extendedEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a boolean value whether thr current calendar has events or not
|
|
||||||
*
|
|
||||||
* @param {array} $events An array with events.
|
|
||||||
* @param {array} $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR,
|
|
||||||
* SORT_NUMERIC, SORT_STRING
|
|
||||||
*
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
public function sortEventsWithOrder($events, $sortOrder = SORT_ASC)
|
|
||||||
{
|
|
||||||
$extendedEvents = array();
|
|
||||||
|
|
||||||
// loop through all events by adding two new elements
|
|
||||||
foreach ($events as $anEvent) {
|
|
||||||
if (!array_key_exists('UNIX_TIMESTAMP', $anEvent)) {
|
|
||||||
$anEvent['UNIX_TIMESTAMP'] =
|
|
||||||
$this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!array_key_exists('REAL_DATETIME', $anEvent)) {
|
|
||||||
$anEvent['REAL_DATETIME'] =
|
|
||||||
date("d.m.Y", $anEvent['UNIX_TIMESTAMP']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$extendedEvents[] = $anEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($extendedEvents as $key => $value) {
|
|
||||||
$timestamp[$key] = $value['UNIX_TIMESTAMP'];
|
|
||||||
}
|
|
||||||
array_multisort($timestamp, $sortOrder, $extendedEvents);
|
|
||||||
|
|
||||||
return $extendedEvents;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,8 +6,8 @@
|
|||||||
* The first PHP Library to support OAuth for Twitter's REST API.
|
* The first PHP Library to support OAuth for Twitter's REST API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Load OAuth lib. You can find it at http://oauth.net */
|
/* Load OAuth1 lib. You can find it at http://oauth.net */
|
||||||
if(!class_exists('OAuthException'))
|
if(!class_exists('OAuth1Exception'))
|
||||||
require_once('library/OAuth1.php');
|
require_once('library/OAuth1.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,10 +58,10 @@ class TwitterOAuth {
|
|||||||
* construct TwitterOAuth object
|
* construct TwitterOAuth object
|
||||||
*/
|
*/
|
||||||
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
|
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
|
||||||
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
|
$this->sha1_method = new OAuth1SignatureMethod_HMAC_SHA1();
|
||||||
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
|
$this->consumer = new OAuth1Consumer($consumer_key, $consumer_secret);
|
||||||
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
|
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
|
||||||
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
|
$this->token = new OAuth1Consumer($oauth_token, $oauth_token_secret);
|
||||||
} else {
|
} else {
|
||||||
$this->token = NULL;
|
$this->token = NULL;
|
||||||
}
|
}
|
||||||
@ -79,8 +79,8 @@ class TwitterOAuth {
|
|||||||
$parameters['oauth_callback'] = $oauth_callback;
|
$parameters['oauth_callback'] = $oauth_callback;
|
||||||
}
|
}
|
||||||
$request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
|
$request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
|
||||||
$token = OAuthUtil::parse_parameters($request);
|
$token = OAuth1Util::parse_parameters($request);
|
||||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
$this->token = new OAuth1Consumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +115,8 @@ class TwitterOAuth {
|
|||||||
$parameters['oauth_verifier'] = $oauth_verifier;
|
$parameters['oauth_verifier'] = $oauth_verifier;
|
||||||
}
|
}
|
||||||
$request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
|
$request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
|
||||||
$token = OAuthUtil::parse_parameters($request);
|
$token = OAuth1Util::parse_parameters($request);
|
||||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
$this->token = new OAuth1Consumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +135,8 @@ class TwitterOAuth {
|
|||||||
$parameters['x_auth_password'] = $password;
|
$parameters['x_auth_password'] = $password;
|
||||||
$parameters['x_auth_mode'] = 'client_auth';
|
$parameters['x_auth_mode'] = 'client_auth';
|
||||||
$request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters);
|
$request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters);
|
||||||
$token = OAuthUtil::parse_parameters($request);
|
$token = OAuth1Util::parse_parameters($request);
|
||||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
$this->token = new OAuth1Consumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||||
return $token;
|
return $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ class TwitterOAuth {
|
|||||||
if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
|
if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
|
||||||
$url = "{$this->host}{$url}.{$this->format}";
|
$url = "{$this->host}{$url}.{$this->format}";
|
||||||
}
|
}
|
||||||
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
|
$request = OAuth1Request::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
|
||||||
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
|
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
|
||||||
switch ($method) {
|
switch ($method) {
|
||||||
case 'GET':
|
case 'GET':
|
||||||
|
@ -243,7 +243,7 @@ function admin_page_site_post(&$a){
|
|||||||
$not_allowed_email = ((x($_POST,'not_allowed_email')) ? notags(trim($_POST['not_allowed_email'])) : '');
|
$not_allowed_email = ((x($_POST,'not_allowed_email')) ? notags(trim($_POST['not_allowed_email'])) : '');
|
||||||
$block_public = ((x($_POST,'block_public')) ? True : False);
|
$block_public = ((x($_POST,'block_public')) ? True : False);
|
||||||
$force_publish = ((x($_POST,'publish_all')) ? True : False);
|
$force_publish = ((x($_POST,'publish_all')) ? True : False);
|
||||||
$disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? True : False);
|
$disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? False : True);
|
||||||
$login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False);
|
$login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False);
|
||||||
$global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
|
$global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
|
||||||
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
|
$no_community_page = !((x($_POST,'no_community_page')) ? True : False);
|
||||||
@ -425,6 +425,13 @@ function admin_page_site(&$a) {
|
|||||||
// SSL_POLICY_FULL => t("Force all links to use SSL")
|
// SSL_POLICY_FULL => t("Force all links to use SSL")
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
$discover_tab = get_config('system','disable_discover_tab');
|
||||||
|
// $disable public streams by default
|
||||||
|
if($discover_tab === false)
|
||||||
|
$discover_tab = 1;
|
||||||
|
// now invert the logic for the setting.
|
||||||
|
$discover_tab = (1 - $discover_tab);
|
||||||
|
|
||||||
|
|
||||||
$homelogin = get_config('system','login_on_homepage');
|
$homelogin = get_config('system','login_on_homepage');
|
||||||
|
|
||||||
@ -461,7 +468,7 @@ function admin_page_site(&$a) {
|
|||||||
'$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")),
|
'$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")),
|
||||||
'$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")),
|
'$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")),
|
||||||
'$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
|
'$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
|
||||||
'$disable_discover_tab' => array('disable_discover_tab', t("Disable discovery tab"), get_config('system','disable_discover_tab'), t("Remove the tab in the network view with public content pulled from sources chosen for this site.")),
|
'$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')),
|
||||||
'$login_on_homepage' => array('login_on_homepage', t("login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.")),
|
'$login_on_homepage' => array('login_on_homepage', t("login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.")),
|
||||||
|
|
||||||
'$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null),
|
'$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null),
|
||||||
|
12
mod/api.php
12
mod/api.php
@ -36,16 +36,16 @@ function api_post(&$a) {
|
|||||||
|
|
||||||
function api_content(&$a) {
|
function api_content(&$a) {
|
||||||
if($a->cmd=='api/oauth/authorize'){
|
if($a->cmd=='api/oauth/authorize'){
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* api/oauth/authorize interact with the user. return a standard page
|
* api/oauth/authorize interact with the user. return a standard page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$a->page['template'] = "minimal";
|
$a->page['template'] = "minimal";
|
||||||
|
|
||||||
|
|
||||||
// get consumer/client from request token
|
// get consumer/client from request token
|
||||||
try {
|
try {
|
||||||
$request = OAuthRequest::from_request();
|
$request = OAuth1Request::from_request();
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
echo "<pre>"; var_dump($e); killme();
|
echo "<pre>"; var_dump($e); killme();
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ function api_content(&$a) {
|
|||||||
|
|
||||||
$app = oauth_get_client($request);
|
$app = oauth_get_client($request);
|
||||||
if (is_null($app)) return "Invalid request. Unknown token.";
|
if (is_null($app)) return "Invalid request. Unknown token.";
|
||||||
$consumer = new OAuthConsumer($app['client_id'], $app['pw'], $app['redirect_uri']);
|
$consumer = new OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']);
|
||||||
|
|
||||||
$verifier = md5($app['secret'].local_channel());
|
$verifier = md5($app['secret'].local_channel());
|
||||||
set_config("oauth", $verifier, local_channel());
|
set_config("oauth", $verifier, local_channel());
|
||||||
@ -65,12 +65,10 @@ function api_content(&$a) {
|
|||||||
$params = $request->get_parameters();
|
$params = $request->get_parameters();
|
||||||
$glue="?";
|
$glue="?";
|
||||||
if (strstr($consumer->callback_url,$glue)) $glue="?";
|
if (strstr($consumer->callback_url,$glue)) $glue="?";
|
||||||
goaway($consumer->callback_url.$glue."oauth_token=".OAuthUtil::urlencode_rfc3986($params['oauth_token'])."&oauth_verifier=".OAuthUtil::urlencode_rfc3986($verifier));
|
goaway($consumer->callback_url . $glue . "oauth_token=" . OAuth1Util::urlencode_rfc3986($params['oauth_token']) . "&oauth_verifier=" . OAuth1Util::urlencode_rfc3986($verifier));
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$tpl = get_markup_template("oauth_authorize_done.tpl");
|
$tpl = get_markup_template("oauth_authorize_done.tpl");
|
||||||
$o = replace_macros($tpl, array(
|
$o = replace_macros($tpl, array(
|
||||||
'$title' => t('Authorize application connection'),
|
'$title' => t('Authorize application connection'),
|
||||||
@ -79,8 +77,6 @@ function api_content(&$a) {
|
|||||||
));
|
));
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,36 +73,18 @@ function cloud_init(&$a) {
|
|||||||
|
|
||||||
$server->addPlugin($lockPlugin);
|
$server->addPlugin($lockPlugin);
|
||||||
|
|
||||||
/* This next bit should no longer be needed... */
|
$is_readable = false;
|
||||||
|
|
||||||
// The next section of code allows us to bypass prompting for http-auth if a
|
if($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||||
// FILE is being accessed anonymously and permissions allow this. This way
|
try {
|
||||||
// one can create hotlinks to public media files in their cloud and anonymous
|
$x = RedFileData('/' . $a->cmd, $auth);
|
||||||
// viewers won't get asked to login.
|
}
|
||||||
// If a DIRECTORY is accessed or there are permission issues accessing the
|
catch(\Exception $e) {
|
||||||
// file and we aren't previously authenticated via zot, prompt for HTTP-auth.
|
if($e instanceof Sabre\DAV\Exception\Forbidden) {
|
||||||
// This will be the default case for mounting a DAV directory.
|
http_status_exit(401, 'Permission denied.');
|
||||||
// In order to avoid prompting for passwords for viewing a DIRECTORY, add
|
}
|
||||||
// the URL query parameter 'davguest=1'.
|
}
|
||||||
|
}
|
||||||
// $isapublic_file = false;
|
|
||||||
// $davguest = ((x($_SESSION, 'davguest')) ? true : false);
|
|
||||||
|
|
||||||
// if ((! $auth->observer) && ($_SERVER['REQUEST_METHOD'] === 'GET')) {
|
|
||||||
// try {
|
|
||||||
// $x = RedFileData('/' . $a->cmd, $auth);
|
|
||||||
// if($x instanceof RedDAV\RedFile)
|
|
||||||
// $isapublic_file = true;
|
|
||||||
// }
|
|
||||||
// catch (Exception $e) {
|
|
||||||
// $isapublic_file = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if ((! $auth->observer) && (! $isapublic_file) && (! $davguest)) {
|
|
||||||
// logger('mod_cloud: auth exception');
|
|
||||||
// http_status_exit(401, 'Permission denied.');
|
|
||||||
// }
|
|
||||||
|
|
||||||
require_once('include/RedDAV/RedBrowser.php');
|
require_once('include/RedDAV/RedBrowser.php');
|
||||||
// provide a directory view for the cloud in Hubzilla
|
// provide a directory view for the cloud in Hubzilla
|
||||||
|
@ -57,12 +57,7 @@ function fbrowser_content($a){
|
|||||||
$types = $ph->supportedTypes();
|
$types = $ph->supportedTypes();
|
||||||
$ext = $types[$rr['type']];
|
$ext = $types[$rr['type']];
|
||||||
|
|
||||||
if($a->get_template_engine() === 'internal') {
|
|
||||||
$filename_e = template_escape($rr['filename']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$filename_e = $rr['filename'];
|
$filename_e = $rr['filename'];
|
||||||
}
|
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$a->get_baseurl() . '/photo/' . $rr['resource_id'] . '-' . $rr['hiq'] . '.' .$ext,
|
$a->get_baseurl() . '/photo/' . $rr['resource_id'] . '-' . $rr['hiq'] . '.' .$ext,
|
||||||
|
@ -72,7 +72,7 @@ function home_content(&$a, $update = 0, $load = false) {
|
|||||||
|
|
||||||
$sitename = get_config('system','sitename');
|
$sitename = get_config('system','sitename');
|
||||||
if($sitename)
|
if($sitename)
|
||||||
$o .= '<h1>' . sprintf( t("Welcome to %s") ,$sitename) . '</h1>';
|
$o .= '<h1 class="home-welcome">' . sprintf( t("Welcome to %s") ,$sitename) . '</h1>';
|
||||||
|
|
||||||
$loginbox = get_config('system','login_on_homepage');
|
$loginbox = get_config('system','login_on_homepage');
|
||||||
if(intval($loginbox) || $loginbox === false)
|
if(intval($loginbox) || $loginbox === false)
|
||||||
|
@ -50,23 +50,6 @@ function invite_post(&$a) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($invonly && ($x || is_site_admin())) {
|
|
||||||
$code = autoname(8) . rand(1000,9999);
|
|
||||||
$nmessage = str_replace('$invite_code',$code,$message);
|
|
||||||
|
|
||||||
$r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ",
|
|
||||||
dbesc($code),
|
|
||||||
dbesc(datetime_convert())
|
|
||||||
);
|
|
||||||
|
|
||||||
if(! is_site_admin()) {
|
|
||||||
$x --;
|
|
||||||
if($x >= 0)
|
|
||||||
set_pconfig(local_channel(),'system','invites_remaining',$x);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
$nmessage = $message;
|
$nmessage = $message;
|
||||||
|
|
||||||
@ -117,6 +100,23 @@ function invite_content(&$a) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($invonly && ($x || is_site_admin())) {
|
||||||
|
$invite_code = autoname(8) . rand(1000,9999);
|
||||||
|
$nmessage = str_replace('$invite_code',$invite_code,$message);
|
||||||
|
|
||||||
|
$r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ",
|
||||||
|
dbesc($invite_code),
|
||||||
|
dbesc(datetime_convert())
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! is_site_admin()) {
|
||||||
|
$x --;
|
||||||
|
if($x >= 0)
|
||||||
|
set_pconfig(local_channel(),'system','invites_remaining',$x);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$ob = $a->get_observer();
|
$ob = $a->get_observer();
|
||||||
if(! $ob)
|
if(! $ob)
|
||||||
|
@ -107,6 +107,7 @@ function item_post(&$a) {
|
|||||||
$layout_mid = ((x($_REQUEST,'layout_mid')) ? escape_tags($_REQUEST['layout_mid']): '');
|
$layout_mid = ((x($_REQUEST,'layout_mid')) ? escape_tags($_REQUEST['layout_mid']): '');
|
||||||
$plink = ((x($_REQUEST,'permalink')) ? escape_tags($_REQUEST['permalink']) : '');
|
$plink = ((x($_REQUEST,'permalink')) ? escape_tags($_REQUEST['permalink']) : '');
|
||||||
$obj_type = ((x($_REQUEST,'obj_type')) ? escape_tags($_REQUEST['obj_type']) : ACTIVITY_OBJ_NOTE);
|
$obj_type = ((x($_REQUEST,'obj_type')) ? escape_tags($_REQUEST['obj_type']) : ACTIVITY_OBJ_NOTE);
|
||||||
|
|
||||||
// allow API to bulk load a bunch of imported items with sending out a bunch of posts.
|
// allow API to bulk load a bunch of imported items with sending out a bunch of posts.
|
||||||
$nopush = ((x($_REQUEST,'nopush')) ? intval($_REQUEST['nopush']) : 0);
|
$nopush = ((x($_REQUEST,'nopush')) ? intval($_REQUEST['nopush']) : 0);
|
||||||
|
|
||||||
|
@ -698,12 +698,7 @@ function photos_content(&$a) {
|
|||||||
$album_edit = null;
|
$album_edit = null;
|
||||||
if(($album !== t('Profile Photos')) && ($album !== 'Profile Photos') && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) {
|
if(($album !== t('Profile Photos')) && ($album !== 'Profile Photos') && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) {
|
||||||
if($can_post) {
|
if($can_post) {
|
||||||
if($a->get_template_engine() === 'internal') {
|
|
||||||
$album_e = template_escape($album);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$album_e = $album;
|
$album_e = $album;
|
||||||
}
|
|
||||||
$albums = ((array_key_exists('albums', $a->data)) ? $a->data['albums'] : photos_albums_list($a->data['channel'],$a->data['observer']));
|
$albums = ((array_key_exists('albums', $a->data)) ? $a->data['albums'] : photos_albums_list($a->data['channel'],$a->data['observer']));
|
||||||
|
|
||||||
// @fixme - syncronise actions with DAV
|
// @fixme - syncronise actions with DAV
|
||||||
|
469
mod/post.php
469
mod/post.php
@ -9,479 +9,16 @@
|
|||||||
|
|
||||||
require_once('include/zot.php');
|
require_once('include/zot.php');
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief HTTP POST entry point for Zot.
|
|
||||||
*
|
|
||||||
* Most access to this endpoint is via the post method.
|
|
||||||
* Here we will pick out the magic auth params which arrive as a get request,
|
|
||||||
* and the only communications to arrive this way.
|
|
||||||
*
|
|
||||||
* Magic Auth
|
|
||||||
* ==========
|
|
||||||
*
|
|
||||||
* So-called "magic auth" takes place by a special exchange. On the site where the "channel to be authenticated" lives (e.g. $mysite),
|
|
||||||
* a redirection is made via $mysite/magic to the zot endpoint of the remote site ($remotesite) with special GET parameters.
|
|
||||||
*
|
|
||||||
* The endpoint is typically https://$remotesite/post - or whatever was specified as the callback url in prior communications
|
|
||||||
* (we will bootstrap an address and fetch a zot info packet if possible where no prior communications exist)
|
|
||||||
*
|
|
||||||
* Five GET parameters are supplied:
|
|
||||||
* * auth => the urlencoded webbie (channel@host.domain) of the channel requesting access
|
|
||||||
* * dest => the desired destination URL (urlencoded)
|
|
||||||
* * sec => a random string which is also stored on $mysite for use during the verification phase.
|
|
||||||
* * version => the zot revision
|
|
||||||
* * delegate => optional urlencoded webbie of a local channel to invoke delegation rights for
|
|
||||||
*
|
|
||||||
* When this packet is received, an "auth-check" zot message is sent to $mysite.
|
|
||||||
* (e.g. if $_GET['auth'] is foobar@podunk.edu, a zot packet is sent to the podunk.edu zot endpoint, which is typically /post)
|
|
||||||
* If no information has been recorded about the requesting identity a zot information packet will be retrieved before
|
|
||||||
* continuing.
|
|
||||||
*
|
|
||||||
* The sender of this packet is an arbitrary/random site channel. The recipients will be a single recipient corresponding
|
|
||||||
* to the guid and guid_sig we have associated with the requesting auth identity
|
|
||||||
*
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "type":"auth_check",
|
|
||||||
* "sender":{
|
|
||||||
* "guid":"kgVFf_...",
|
|
||||||
* "guid_sig":"PT9-TApz...",
|
|
||||||
* "url":"http:\/\/podunk.edu",
|
|
||||||
* "url_sig":"T8Bp7j..."
|
|
||||||
* },
|
|
||||||
* "recipients":{
|
|
||||||
* {
|
|
||||||
* "guid":"ZHSqb...",
|
|
||||||
* "guid_sig":"JsAAXi..."
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* "callback":"\/post",
|
|
||||||
* "version":1,
|
|
||||||
* "secret":"1eaa661",
|
|
||||||
* "secret_sig":"eKV968b1..."
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* auth_check messages MUST use encapsulated encryption. This message is sent to the origination site, which checks the 'secret' to see
|
|
||||||
* if it is the same as the 'sec' which it passed originally. It also checks the secret_sig which is the secret signed by the
|
|
||||||
* destination channel's private key and base64url encoded. If everything checks out, a json packet is returned:
|
|
||||||
*
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "success":1,
|
|
||||||
* "confirm":"q0Ysovd1u...",
|
|
||||||
* "service_class":(optional)
|
|
||||||
* "level":(optional)
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* 'confirm' in this case is the base64url encoded RSA signature of the concatenation of 'secret' with the
|
|
||||||
* base64url encoded whirlpool hash of the requestor's guid and guid_sig; signed with the source channel private key.
|
|
||||||
* This prevents a man-in-the-middle from inserting a rogue success packet. Upon receipt and successful
|
|
||||||
* verification of this packet, the destination site will redirect to the original destination URL and indicate a successful remote login.
|
|
||||||
* Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is
|
|
||||||
* a string whose contents are not defined by protocol. Example: "basic" or "gold".
|
|
||||||
*
|
|
||||||
* @param[in,out] App &$a
|
|
||||||
*/
|
|
||||||
function post_init(&$a) {
|
function post_init(&$a) {
|
||||||
|
|
||||||
if (array_key_exists('auth', $_REQUEST)) {
|
if (array_key_exists('auth', $_REQUEST)) {
|
||||||
|
require_once('Zotlabs/Zot/Auth.php');
|
||||||
$ret = array('success' => false, 'message' => '');
|
$x = new Zotlabs\Zot\Auth($_REQUEST);
|
||||||
|
exit;
|
||||||
logger('mod_zot: auth request received.');
|
|
||||||
$address = $_REQUEST['auth'];
|
|
||||||
$desturl = $_REQUEST['dest'];
|
|
||||||
$sec = $_REQUEST['sec'];
|
|
||||||
$version = $_REQUEST['version'];
|
|
||||||
$delegate = $_REQUEST['delegate'];
|
|
||||||
|
|
||||||
$test = ((x($_REQUEST, 'test')) ? intval($_REQUEST['test']) : 0);
|
|
||||||
|
|
||||||
// They are authenticating ultimately to the site and not to a particular channel.
|
|
||||||
// Any channel will do, providing it's currently active. We just need to have an
|
|
||||||
// identity to attach to the packet we send back. So find one.
|
|
||||||
|
|
||||||
$c = q("select * from channel where channel_removed = 0 limit 1");
|
|
||||||
|
|
||||||
if (! $c) {
|
|
||||||
// nobody here
|
|
||||||
logger('mod_zot: auth: unable to find a response channel');
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'no local channels found.' . EOL;
|
|
||||||
json_return_and_die($ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goaway($desturl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try and find a hubloc for the person attempting to auth
|
|
||||||
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc",
|
|
||||||
dbesc($address)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! $x) {
|
|
||||||
// finger them if they can't be found.
|
|
||||||
$ret = zot_finger($address, null);
|
|
||||||
if ($ret['success']) {
|
|
||||||
$j = json_decode($ret['body'], true);
|
|
||||||
if ($j)
|
|
||||||
import_xchan($j);
|
|
||||||
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc",
|
|
||||||
dbesc($address)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(! $x) {
|
|
||||||
logger('mod_zot: auth: unable to finger ' . $address);
|
|
||||||
|
|
||||||
if($test) {
|
|
||||||
$ret['message'] .= 'no hubloc found for ' . $address . ' and probing failed.' . EOL;
|
|
||||||
json_return_and_die($ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
goaway($desturl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
foreach($x as $xx) {
|
|
||||||
logger('mod_zot: auth request received from ' . $xx['hubloc_addr'] );
|
|
||||||
|
|
||||||
// check credentials and access
|
|
||||||
|
|
||||||
// If they are already authenticated and haven't changed credentials,
|
|
||||||
// we can save an expensive network round trip and improve performance.
|
|
||||||
|
|
||||||
$remote = remote_channel();
|
|
||||||
$result = null;
|
|
||||||
$remote_service_class = '';
|
|
||||||
$remote_level = 0;
|
|
||||||
$remote_hub = $xx['hubloc_url'];
|
|
||||||
$DNT = 0;
|
|
||||||
|
|
||||||
// Also check that they are coming from the same site as they authenticated with originally.
|
|
||||||
|
|
||||||
$already_authed = ((($remote) && ($xx['hubloc_hash'] == $remote) && ($xx['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false);
|
|
||||||
if($delegate && $delegate !== $_SESSION['delegate_channel'])
|
|
||||||
$already_authed = false;
|
|
||||||
|
|
||||||
$j = array();
|
|
||||||
|
|
||||||
if (! $already_authed) {
|
|
||||||
|
|
||||||
// Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the site private key
|
|
||||||
// The actual channel sending the packet ($c[0]) is not important, but this provides a generic zot packet with a sender
|
|
||||||
// which can be verified
|
|
||||||
|
|
||||||
$p = zot_build_packet($c[0],$type = 'auth_check', array(array('guid' => $xx['hubloc_guid'],'guid_sig' => $xx['hubloc_guid_sig'])), $xx['hubloc_sitekey'], $sec);
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'auth check packet created using sitekey ' . $xx['hubloc_sitekey'] . EOL;
|
|
||||||
$ret['message'] .= 'packet contents: ' . $p . EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = zot_zot($xx['hubloc_callback'],$p);
|
|
||||||
|
|
||||||
if (! $result['success']) {
|
|
||||||
logger('mod_zot: auth_check callback failed.');
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$j = json_decode($result['body'], true);
|
|
||||||
if (! $j) {
|
|
||||||
logger('mod_zot: auth_check json data malformed.');
|
|
||||||
if($test) {
|
|
||||||
$ret['message'] .= 'json malformed: ' . $result['body'] . EOL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'auth check request returned .' . print_r($j, true) . EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($already_authed || $j['success']) {
|
|
||||||
if ($j['success']) {
|
|
||||||
// legit response, but we do need to check that this wasn't answered by a man-in-middle
|
|
||||||
if (! rsa_verify($sec . $xx['xchan_hash'],base64url_decode($j['confirm']),$xx['xchan_pubkey'])) {
|
|
||||||
logger('mod_zot: auth: final confirmation failed.');
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j,true) . print_r($xx,true);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (array_key_exists('service_class',$j))
|
|
||||||
$remote_service_class = $j['service_class'];
|
|
||||||
if (array_key_exists('level',$j))
|
|
||||||
$remote_level = $j['level'];
|
|
||||||
if (array_key_exists('DNT',$j))
|
|
||||||
$DNT = $j['DNT'];
|
|
||||||
}
|
|
||||||
// everything is good... maybe
|
|
||||||
if(local_channel()) {
|
|
||||||
|
|
||||||
// tell them to logout if they're logged in locally as anything but the target remote account
|
|
||||||
// in which case just shut up because they don't need to be doing this at all.
|
|
||||||
|
|
||||||
if ($a->channel['channel_hash'] != $xx['xchan_hash']) {
|
|
||||||
logger('mod_zot: auth: already authenticated locally as somebody else.');
|
|
||||||
notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// log them in
|
|
||||||
|
|
||||||
if ($test) {
|
|
||||||
$ret['success'] = true;
|
|
||||||
$ret['message'] .= 'Authentication Success!' . EOL;
|
|
||||||
json_return_and_die($ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
$delegation_success = false;
|
|
||||||
if ($delegate) {
|
|
||||||
$r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1",
|
|
||||||
dbesc($delegate)
|
|
||||||
);
|
|
||||||
if ($r && intval($r[0]['channel_id'])) {
|
|
||||||
$allowed = perm_is_allowed($r[0]['channel_id'],$xx['xchan_hash'],'delegate');
|
|
||||||
if ($allowed) {
|
|
||||||
$_SESSION['delegate_channel'] = $r[0]['channel_id'];
|
|
||||||
$_SESSION['delegate'] = $xx['xchan_hash'];
|
|
||||||
$_SESSION['account_id'] = intval($r[0]['channel_account_id']);
|
|
||||||
require_once('include/security.php');
|
|
||||||
change_channel($r[0]['channel_id']);
|
|
||||||
$delegation_success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$_SESSION['authenticated'] = 1;
|
|
||||||
if (! $delegation_success) {
|
|
||||||
$_SESSION['visitor_id'] = $xx['xchan_hash'];
|
|
||||||
$_SESSION['my_url'] = $xx['xchan_url'];
|
|
||||||
$_SESSION['my_address'] = $address;
|
|
||||||
$_SESSION['remote_service_class'] = $remote_service_class;
|
|
||||||
$_SESSION['remote_level'] = $remote_level;
|
|
||||||
$_SESSION['remote_hub'] = $remote_hub;
|
|
||||||
$_SESSION['DNT'] = $DNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
$arr = array('xchan' => $xx, 'url' => $desturl, 'session' => $_SESSION);
|
|
||||||
call_hooks('magic_auth_success',$arr);
|
|
||||||
$a->set_observer($xx);
|
|
||||||
require_once('include/security.php');
|
|
||||||
$a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
|
||||||
info(sprintf( t('Welcome %s. Remote authentication successful.'),$xx['xchan_name']));
|
|
||||||
logger('mod_zot: auth success from ' . $xx['xchan_addr']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'auth failure. ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
logger('mod_zot: magic-auth failure - not authenticated: ' . $xx['xchan_addr']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($test) {
|
|
||||||
$ret['message'] .= 'auth failure fallthrough ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @FIXME we really want to save the return_url in the session before we
|
|
||||||
* visit rmagic. This does however prevent a recursion if you visit
|
|
||||||
* rmagic directly, as it would otherwise send you back here again.
|
|
||||||
* But z_root() probably isn't where you really want to go.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(strstr($desturl,z_root() . '/rmagic'))
|
|
||||||
goaway(z_root());
|
|
||||||
|
|
||||||
if ($test) {
|
|
||||||
json_return_and_die($ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
goaway($desturl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief zot communications and messaging.
|
|
||||||
*
|
|
||||||
* Sender HTTP posts to this endpoint ($site/post typically) with 'data' parameter set to json zot message packet.
|
|
||||||
* This packet is optionally encrypted, which we will discover if the json has an 'iv' element.
|
|
||||||
* $contents => array( 'alg' => 'aes256cbc', 'iv' => initialisation vector, 'key' => decryption key, 'data' => encrypted data);
|
|
||||||
* $contents->iv and $contents->key are random strings encrypted with this site's RSA public key and then base64url encoded.
|
|
||||||
* Currently only 'aes256cbc' is used, but this is extensible should that algorithm prove inadequate.
|
|
||||||
*
|
|
||||||
* Once decrypted, one will find the normal json_encoded zot message packet.
|
|
||||||
*
|
|
||||||
* Defined packet types are: notify, purge, refresh, force_refresh, auth_check, ping, and pickup
|
|
||||||
*
|
|
||||||
* Standard packet: (used by notify, purge, refresh, force_refresh, and auth_check)
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "type": "notify",
|
|
||||||
* "sender":{
|
|
||||||
* "guid":"kgVFf_1...",
|
|
||||||
* "guid_sig":"PT9-TApzp...",
|
|
||||||
* "url":"http:\/\/podunk.edu",
|
|
||||||
* "url_sig":"T8Bp7j5...",
|
|
||||||
* },
|
|
||||||
* "recipients": { optional recipient array },
|
|
||||||
* "callback":"\/post",
|
|
||||||
* "version":1,
|
|
||||||
* "secret":"1eaa...",
|
|
||||||
* "secret_sig": "df89025470fac8..."
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* Signature fields are all signed with the sender channel private key and base64url encoded.
|
|
||||||
* Recipients are arrays of guid and guid_sig, which were previously signed with the recipients private
|
|
||||||
* key and base64url encoded and later obtained via channel discovery. Absence of recipients indicates
|
|
||||||
* a public message or visible to all potential listeners on this site.
|
|
||||||
*
|
|
||||||
* "pickup" packet:
|
|
||||||
* The pickup packet is sent in response to a notify packet from another site
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "type":"pickup",
|
|
||||||
* "url":"http:\/\/example.com",
|
|
||||||
* "callback":"http:\/\/example.com\/post",
|
|
||||||
* "callback_sig":"teE1_fLI...",
|
|
||||||
* "secret":"1eaa...",
|
|
||||||
* "secret_sig":"O7nB4_..."
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* In the pickup packet, the sig fields correspond to the respective data
|
|
||||||
* element signed with this site's system private key and then base64url encoded.
|
|
||||||
* The "secret" is the same as the original secret from the notify packet.
|
|
||||||
*
|
|
||||||
* If verification is successful, a json structure is returned containing a
|
|
||||||
* success indicator and an array of type 'pickup'.
|
|
||||||
* Each pickup element contains the original notify request and a message field
|
|
||||||
* whose contents are dependent on the message type.
|
|
||||||
*
|
|
||||||
* This JSON array is AES encapsulated using the site public key of the site
|
|
||||||
* that sent the initial zot pickup packet.
|
|
||||||
* Using the above example, this would be example.com.
|
|
||||||
*
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "success":1,
|
|
||||||
* "pickup":{
|
|
||||||
* "notify":{
|
|
||||||
* "type":"notify",
|
|
||||||
* "sender":{
|
|
||||||
* "guid":"kgVFf_...",
|
|
||||||
* "guid_sig":"PT9-TApz...",
|
|
||||||
* "url":"http:\/\/z.podunk.edu",
|
|
||||||
* "url_sig":"T8Bp7j5D..."
|
|
||||||
* },
|
|
||||||
* "callback":"\/post",
|
|
||||||
* "version":1,
|
|
||||||
* "secret":"1eaa661..."
|
|
||||||
* },
|
|
||||||
* "message":{
|
|
||||||
* "type":"activity",
|
|
||||||
* "message_id":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
|
|
||||||
* "message_top":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
|
|
||||||
* "message_parent":"10b049ce384cbb2da9467319bc98169ab36290b8bbb403aa0c0accd9cb072e76@podunk.edu",
|
|
||||||
* "created":"2012-11-20 04:04:16",
|
|
||||||
* "edited":"2012-11-20 04:04:16",
|
|
||||||
* "title":"",
|
|
||||||
* "body":"Hi Nickordo",
|
|
||||||
* "app":"",
|
|
||||||
* "verb":"post",
|
|
||||||
* "object_type":"",
|
|
||||||
* "target_type":"",
|
|
||||||
* "permalink":"",
|
|
||||||
* "location":"",
|
|
||||||
* "longlat":"",
|
|
||||||
* "owner":{
|
|
||||||
* "name":"Indigo",
|
|
||||||
* "address":"indigo@podunk.edu",
|
|
||||||
* "url":"http:\/\/podunk.edu",
|
|
||||||
* "photo":{
|
|
||||||
* "mimetype":"image\/jpeg",
|
|
||||||
* "src":"http:\/\/podunk.edu\/photo\/profile\/m\/5"
|
|
||||||
* },
|
|
||||||
* "guid":"kgVFf_...",
|
|
||||||
* "guid_sig":"PT9-TAp...",
|
|
||||||
* },
|
|
||||||
* "author":{
|
|
||||||
* "name":"Indigo",
|
|
||||||
* "address":"indigo@podunk.edu",
|
|
||||||
* "url":"http:\/\/podunk.edu",
|
|
||||||
* "photo":{
|
|
||||||
* "mimetype":"image\/jpeg",
|
|
||||||
* "src":"http:\/\/podunk.edu\/photo\/profile\/m\/5"
|
|
||||||
* },
|
|
||||||
* "guid":"kgVFf_...",
|
|
||||||
* "guid_sig":"PT9-TAp..."
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* Currently defined message types are 'activity', 'mail', 'profile', 'location'
|
|
||||||
* and 'channel_sync', which each have different content schemas.
|
|
||||||
*
|
|
||||||
* Ping packet:
|
|
||||||
* A ping packet does not require any parameters except the type. It may or may
|
|
||||||
* not be encrypted.
|
|
||||||
*
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "type": "ping"
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* On receipt of a ping packet a ping response will be returned:
|
|
||||||
*
|
|
||||||
* \code{.json}
|
|
||||||
* {
|
|
||||||
* "success" : 1,
|
|
||||||
* "site" {
|
|
||||||
* "url": "http:\/\/podunk.edu",
|
|
||||||
* "url_sig": "T8Bp7j5...",
|
|
||||||
* "sitekey": "-----BEGIN PUBLIC KEY-----
|
|
||||||
* MIICIjANBgkqhkiG9w0BAQE..."
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* The ping packet can be used to verify that a site has not been re-installed, and to
|
|
||||||
* initiate corrective action if it has. The url_sig is signed with the site private key
|
|
||||||
* and base64url encoded - and this should verify with the enclosed sitekey. Failure to
|
|
||||||
* verify indicates the site is corrupt or otherwise unable to communicate using zot.
|
|
||||||
* This return packet is not otherwise verified, so should be compared with other
|
|
||||||
* results obtained from this site which were verified prior to taking action. For instance
|
|
||||||
* if you have one verified result with this signature and key, and other records for this
|
|
||||||
* url which have different signatures and keys, it indicates that the site was re-installed
|
|
||||||
* and corrective action may commence (remove or mark invalid any entries with different
|
|
||||||
* signatures).
|
|
||||||
* If you have no records which match this url_sig and key - no corrective action should
|
|
||||||
* be taken as this packet may have been returned by an imposter.
|
|
||||||
*
|
|
||||||
* @param[in,out] App &$a
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
function post_post(&$a) {
|
function post_post(&$a) {
|
||||||
|
|
||||||
|
@ -147,7 +147,6 @@ function subthread_content(&$a) {
|
|||||||
$arr['deny_cid'] = $item['deny_cid'];
|
$arr['deny_cid'] = $item['deny_cid'];
|
||||||
$arr['deny_gid'] = $item['deny_gid'];
|
$arr['deny_gid'] = $item['deny_gid'];
|
||||||
|
|
||||||
|
|
||||||
$post = item_store($arr);
|
$post = item_store($arr);
|
||||||
$post_id = $post['item_id'];
|
$post_id = $post['item_id'];
|
||||||
|
|
||||||
|
@ -6,14 +6,16 @@ require_once('include/photos.php');
|
|||||||
|
|
||||||
function wall_attach_post(&$a) {
|
function wall_attach_post(&$a) {
|
||||||
|
|
||||||
if(argc() > 1)
|
$using_api = false;
|
||||||
$channel = get_channel_by_nick(argv(1));
|
|
||||||
elseif($_FILES['media']) {
|
if($a->data['api_info'] && array_key_exists('media',$_FILES)) {
|
||||||
require_once('include/api.php');
|
$using_api = true;
|
||||||
$user_info = api_get_user($a);
|
$user_info = $a->data['api_info'];
|
||||||
$nick = $user_info['screen_name'];
|
$nick = $user_info['screen_name'];
|
||||||
$channel = get_channel_by_nick($user_info['screen_name']);
|
$channel = get_channel_by_nick($user_info['screen_name']);
|
||||||
}
|
}
|
||||||
|
elseif(argc() > 1)
|
||||||
|
$channel = get_channel_by_nick(argv(1));
|
||||||
|
|
||||||
if(! $channel)
|
if(! $channel)
|
||||||
killme();
|
killme();
|
||||||
@ -49,12 +51,16 @@ function wall_attach_post(&$a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(intval($r['data']['is_photo'])) {
|
if(intval($r['data']['is_photo'])) {
|
||||||
echo "\n\n" . $r['body'] . "\n\n";
|
$s = "\n\n" . $r['body'] . "\n\n";
|
||||||
if($using_api)
|
|
||||||
return;
|
|
||||||
killme();
|
|
||||||
}
|
}
|
||||||
echo "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
|
else {
|
||||||
|
$s = "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($using_api)
|
||||||
|
return $s;
|
||||||
|
|
||||||
|
echo $s;
|
||||||
killme();
|
killme();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
1284
util/hmessages.po
1284
util/hmessages.po
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
|||||||
2015-12-07.1239
|
2015-12-14.1246
|
||||||
|
15
view/css/mod_home.css
Normal file
15
view/css/mod_home.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.home-welcome {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generic-content-wrapper-styled {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-width: 420px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-main {
|
||||||
|
max-width: 400px;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
23
view/css/mod_login.css
Normal file
23
view/css/mod_login.css
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.generic-content-wrapper-styled {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-width: 420px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-main {
|
||||||
|
max-width: 400px;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) and (max-width: 991px) {
|
||||||
|
#region_1 {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) and (max-width: 1199px) {
|
||||||
|
#region_3 {
|
||||||
|
display: table-cell !important;
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +1,35 @@
|
|||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin-left: 5%;
|
margin: 20px 0 20px 5%;
|
||||||
margin-top: 5%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#register-form {
|
.generic-content-wrapper-styled {
|
||||||
font-size: 1.4em;
|
margin-left: auto;
|
||||||
margin-left: 10%;
|
margin-right: auto;
|
||||||
margin-top: 5%;
|
max-width: 820px;
|
||||||
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#register-desc, #register-text, #register-sites {
|
|
||||||
|
#register-desc, #register-invite-desc, #register-text, #register-sites {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-label {
|
@media (min-width: 560px) {
|
||||||
|
.register-label, .register-input {
|
||||||
float: left;
|
float: left;
|
||||||
width: 275px;
|
width: 50%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-input {
|
@media (max-width: 559px) {
|
||||||
|
.register-label, .register-input {
|
||||||
float: left;
|
float: left;
|
||||||
width: 275px;
|
max-width: 400px;
|
||||||
padding: 5px;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.register-feedback {
|
.register-feedback {
|
||||||
|
1340
view/es/hmessages.po
1340
view/es/hmessages.po
File diff suppressed because it is too large
Load Diff
@ -143,13 +143,6 @@ $a->strings["Collection is empty."] = "La colección está vacía.";
|
|||||||
$a->strings["Collection: %s"] = "Colección: %s";
|
$a->strings["Collection: %s"] = "Colección: %s";
|
||||||
$a->strings["Connection: %s"] = "Conexión: %s";
|
$a->strings["Connection: %s"] = "Conexión: %s";
|
||||||
$a->strings["Connection not found."] = "Conexión no encontrada";
|
$a->strings["Connection not found."] = "Conexión no encontrada";
|
||||||
$a->strings["view full size"] = "Ver en el tamaño original";
|
|
||||||
$a->strings["\$Projectname Notification"] = "Notificación de \$Projectname";
|
|
||||||
$a->strings["\$projectname"] = "\$projectname";
|
|
||||||
$a->strings["Thank You,"] = "Gracias,";
|
|
||||||
$a->strings["%s Administrator"] = "%s Administrador";
|
|
||||||
$a->strings["Administrator"] = "Administrador";
|
|
||||||
$a->strings["No Subject"] = "Sin asunto";
|
|
||||||
$a->strings["l F d, Y \\@ g:i A"] = "l d de F, Y \\@ G:i";
|
$a->strings["l F d, Y \\@ g:i A"] = "l d de F, Y \\@ G:i";
|
||||||
$a->strings["Starts:"] = "Comienza:";
|
$a->strings["Starts:"] = "Comienza:";
|
||||||
$a->strings["Finishes:"] = "Finaliza:";
|
$a->strings["Finishes:"] = "Finaliza:";
|
||||||
@ -232,9 +225,9 @@ $a->strings["has"] = "tiene";
|
|||||||
$a->strings["want"] = "quiero";
|
$a->strings["want"] = "quiero";
|
||||||
$a->strings["wants"] = "quiere";
|
$a->strings["wants"] = "quiere";
|
||||||
$a->strings["like"] = "me gusta";
|
$a->strings["like"] = "me gusta";
|
||||||
$a->strings["likes"] = "le gusta";
|
$a->strings["likes"] = "gusta de";
|
||||||
$a->strings["dislike"] = "no me gusta";
|
$a->strings["dislike"] = "no me gusta";
|
||||||
$a->strings["dislikes"] = "no le gusta";
|
$a->strings["dislikes"] = "no gusta de";
|
||||||
$a->strings["Visible to your default audience"] = "Visible para su público predeterminado.";
|
$a->strings["Visible to your default audience"] = "Visible para su público predeterminado.";
|
||||||
$a->strings["Show"] = "Mostrar";
|
$a->strings["Show"] = "Mostrar";
|
||||||
$a->strings["Don't show"] = "No mostrar";
|
$a->strings["Don't show"] = "No mostrar";
|
||||||
@ -395,7 +388,7 @@ $a->strings["Enable tab to display only Network posts that you've interacted on"
|
|||||||
$a->strings["Network New Tab"] = "Contenido nuevo";
|
$a->strings["Network New Tab"] = "Contenido nuevo";
|
||||||
$a->strings["Enable tab to display all new Network activity"] = "Habilitar una pestaña en la que se muestre solo el contenido nuevo";
|
$a->strings["Enable tab to display all new Network activity"] = "Habilitar una pestaña en la que se muestre solo el contenido nuevo";
|
||||||
$a->strings["Affinity Tool"] = "Herramienta de afinidad";
|
$a->strings["Affinity Tool"] = "Herramienta de afinidad";
|
||||||
$a->strings["Filter stream activity by depth of relationships"] = "Filtrar la actividad del flujo por profundidad de relaciones";
|
$a->strings["Filter stream activity by depth of relationships"] = "Filtrar el contenido según la profundidad de las relaciones";
|
||||||
$a->strings["Connection Filtering"] = "Filtrado de conexiones";
|
$a->strings["Connection Filtering"] = "Filtrado de conexiones";
|
||||||
$a->strings["Filter incoming posts from connections based on keywords/content"] = "Filtrar publicaciones entrantes de conexiones por palabras clave o contenido";
|
$a->strings["Filter incoming posts from connections based on keywords/content"] = "Filtrar publicaciones entrantes de conexiones por palabras clave o contenido";
|
||||||
$a->strings["Suggest Channels"] = "Sugerir canales";
|
$a->strings["Suggest Channels"] = "Sugerir canales";
|
||||||
@ -493,9 +486,9 @@ $a->strings["%1\$s's birthday"] = "Cumpleaños de %1\$s";
|
|||||||
$a->strings["Happy Birthday %1\$s"] = "Feliz cumpleaños %1\$s";
|
$a->strings["Happy Birthday %1\$s"] = "Feliz cumpleaños %1\$s";
|
||||||
$a->strings["Public Timeline"] = "Cronología pública";
|
$a->strings["Public Timeline"] = "Cronología pública";
|
||||||
$a->strings["photo"] = "foto";
|
$a->strings["photo"] = "foto";
|
||||||
$a->strings["channel"] = "canal";
|
$a->strings["channel"] = "el canal";
|
||||||
$a->strings["status"] = "el mensaje de estado";
|
$a->strings["status"] = "el mensaje de estado";
|
||||||
$a->strings["comment"] = "comentario";
|
$a->strings["comment"] = "el comentario";
|
||||||
$a->strings["%1\$s likes %2\$s's %3\$s"] = "a %1\$s le gusta %3\$s de %2\$s";
|
$a->strings["%1\$s likes %2\$s's %3\$s"] = "a %1\$s le gusta %3\$s de %2\$s";
|
||||||
$a->strings["%1\$s doesn't like %2\$s's %3\$s"] = "a %1\$s no le gusta %3\$s de %2\$s";
|
$a->strings["%1\$s doesn't like %2\$s's %3\$s"] = "a %1\$s no le gusta %3\$s de %2\$s";
|
||||||
$a->strings["%1\$s is now connected with %2\$s"] = "%1\$s ahora está conectado/a con %2\$s";
|
$a->strings["%1\$s is now connected with %2\$s"] = "%1\$s ahora está conectado/a con %2\$s";
|
||||||
@ -596,14 +589,14 @@ $a->strings["Encrypt text"] = "Cifrar texto";
|
|||||||
$a->strings["OK"] = "OK";
|
$a->strings["OK"] = "OK";
|
||||||
$a->strings["Cancel"] = "Cancelar";
|
$a->strings["Cancel"] = "Cancelar";
|
||||||
$a->strings["Discover"] = "Descubrir";
|
$a->strings["Discover"] = "Descubrir";
|
||||||
$a->strings["Imported public streams"] = "Flujos públicos importados";
|
$a->strings["Imported public streams"] = "Contenidos públicos importados";
|
||||||
$a->strings["Commented Order"] = "Comentarios recientes";
|
$a->strings["Commented Order"] = "Comentarios recientes";
|
||||||
$a->strings["Sort by Comment Date"] = "Ordenar por fecha de comentario";
|
$a->strings["Sort by Comment Date"] = "Ordenar por fecha de comentario";
|
||||||
$a->strings["Posted Order"] = "Publicaciones recientes";
|
$a->strings["Posted Order"] = "Publicaciones recientes";
|
||||||
$a->strings["Sort by Post Date"] = "Ordenar por fecha de publicación";
|
$a->strings["Sort by Post Date"] = "Ordenar por fecha de publicación";
|
||||||
$a->strings["Posts that mention or involve you"] = "Publicaciones que le mencionan o involucran";
|
$a->strings["Posts that mention or involve you"] = "Publicaciones que le mencionan o involucran";
|
||||||
$a->strings["New"] = "Nuevas";
|
$a->strings["New"] = "Nuevas";
|
||||||
$a->strings["Activity Stream - by date"] = "Flujo de actividad - por fecha";
|
$a->strings["Activity Stream - by date"] = "Contenido - por fecha";
|
||||||
$a->strings["Starred"] = "Preferidas";
|
$a->strings["Starred"] = "Preferidas";
|
||||||
$a->strings["Favourite Posts"] = "Publicaciones favoritas";
|
$a->strings["Favourite Posts"] = "Publicaciones favoritas";
|
||||||
$a->strings["Spam"] = "Correo basura";
|
$a->strings["Spam"] = "Correo basura";
|
||||||
@ -677,7 +670,7 @@ $a->strings["layout"] = "disposición";
|
|||||||
$a->strings["block"] = "bloque";
|
$a->strings["block"] = "bloque";
|
||||||
$a->strings["menu"] = "menú";
|
$a->strings["menu"] = "menú";
|
||||||
$a->strings["%1\$s wrote the following %2\$s %3\$s"] = "%1\$s escribió la siguiente %2\$s %3\$s";
|
$a->strings["%1\$s wrote the following %2\$s %3\$s"] = "%1\$s escribió la siguiente %2\$s %3\$s";
|
||||||
$a->strings["post"] = "entrada";
|
$a->strings["post"] = "la entrada";
|
||||||
$a->strings["Different viewers will see this text differently"] = "Visitantes diferentes verán este texto de forma distinta";
|
$a->strings["Different viewers will see this text differently"] = "Visitantes diferentes verán este texto de forma distinta";
|
||||||
$a->strings["$1 spoiler"] = "$1 spoiler";
|
$a->strings["$1 spoiler"] = "$1 spoiler";
|
||||||
$a->strings["$1 wrote:"] = "$1 escribió";
|
$a->strings["$1 wrote:"] = "$1 escribió";
|
||||||
@ -700,6 +693,10 @@ $a->strings["%d connection in common"] = array(
|
|||||||
1 => "%d conexiones en común",
|
1 => "%d conexiones en común",
|
||||||
);
|
);
|
||||||
$a->strings["show more"] = "mostrar más";
|
$a->strings["show more"] = "mostrar más";
|
||||||
|
$a->strings["\$Projectname Notification"] = "Notificación de \$Projectname";
|
||||||
|
$a->strings["\$projectname"] = "\$projectname";
|
||||||
|
$a->strings["Thank You,"] = "Gracias,";
|
||||||
|
$a->strings["%s Administrator"] = "%s Administrador";
|
||||||
$a->strings["%s <!item_type!>"] = "%s <!item_type!>";
|
$a->strings["%s <!item_type!>"] = "%s <!item_type!>";
|
||||||
$a->strings["[Hubzilla:Notify] New mail received at %s"] = "[Hubzilla:Aviso] Nuevo mensaje en %s";
|
$a->strings["[Hubzilla:Notify] New mail received at %s"] = "[Hubzilla:Aviso] Nuevo mensaje en %s";
|
||||||
$a->strings["%1\$s, %2\$s sent you a new private message at %3\$s."] = "%1\$s, %2\$s le ha enviado un nuevo mensaje privado en %3\$s.";
|
$a->strings["%1\$s, %2\$s sent you a new private message at %3\$s."] = "%1\$s, %2\$s le ha enviado un nuevo mensaje privado en %3\$s.";
|
||||||
@ -819,27 +816,27 @@ $a->strings["%d Connection"] = array(
|
|||||||
$a->strings["View Connections"] = "Ver conexiones";
|
$a->strings["View Connections"] = "Ver conexiones";
|
||||||
$a->strings["poke"] = "un toque";
|
$a->strings["poke"] = "un toque";
|
||||||
$a->strings["ping"] = "un \"ping\"";
|
$a->strings["ping"] = "un \"ping\"";
|
||||||
$a->strings["pinged"] = "avisado/a";
|
$a->strings["pinged"] = "ha enviado un \"ping\" a";
|
||||||
$a->strings["prod"] = "una incitación";
|
$a->strings["prod"] = "una incitación";
|
||||||
$a->strings["prodded"] = "ha recibido una incitación";
|
$a->strings["prodded"] = "ha incitado a";
|
||||||
$a->strings["slap"] = "una bofetada";
|
$a->strings["slap"] = "una bofetada";
|
||||||
$a->strings["slapped"] = "ha recibido una bofetada";
|
$a->strings["slapped"] = "ha enviado una bofetada a";
|
||||||
$a->strings["finger"] = "un \"finger\"";
|
$a->strings["finger"] = "un \"finger\"";
|
||||||
$a->strings["fingered"] = "ha recibido un \"finger\"";
|
$a->strings["fingered"] = "ha enviado un \"finger\" a";
|
||||||
$a->strings["rebuff"] = "un rechazo";
|
$a->strings["rebuff"] = "un rechazo";
|
||||||
$a->strings["rebuffed"] = "ha sido rechazado/a";
|
$a->strings["rebuffed"] = "ha enviado un rechazo a";
|
||||||
$a->strings["happy"] = "feliz";
|
$a->strings["happy"] = "feliz";
|
||||||
$a->strings["sad"] = "triste";
|
$a->strings["sad"] = "triste";
|
||||||
$a->strings["mellow"] = "amable";
|
$a->strings["mellow"] = "amable";
|
||||||
$a->strings["tired"] = "cansado/a";
|
$a->strings["tired"] = "cansado/a";
|
||||||
$a->strings["perky"] = "fresco/a";
|
$a->strings["perky"] = "vivaz";
|
||||||
$a->strings["angry"] = "enfadado/a";
|
$a->strings["angry"] = "enfadado/a";
|
||||||
$a->strings["stupified"] = "estupefacto/a";
|
$a->strings["stupified"] = "estupefacto/a";
|
||||||
$a->strings["puzzled"] = "perplejo/a";
|
$a->strings["puzzled"] = "perplejo/a";
|
||||||
$a->strings["interested"] = "interesado/a";
|
$a->strings["interested"] = "interesado/a";
|
||||||
$a->strings["bitter"] = "amargado/a";
|
$a->strings["bitter"] = "amargado/a";
|
||||||
$a->strings["cheerful"] = "alegre";
|
$a->strings["cheerful"] = "alegre";
|
||||||
$a->strings["alive"] = "vivo/a";
|
$a->strings["alive"] = "animado/a";
|
||||||
$a->strings["annoyed"] = "molesto/a";
|
$a->strings["annoyed"] = "molesto/a";
|
||||||
$a->strings["anxious"] = "ansioso/a";
|
$a->strings["anxious"] = "ansioso/a";
|
||||||
$a->strings["cranky"] = "de mal humor";
|
$a->strings["cranky"] = "de mal humor";
|
||||||
@ -892,6 +889,9 @@ $a->strings["Page Link"] = "Vínculo de la página";
|
|||||||
$a->strings["Title"] = "Título";
|
$a->strings["Title"] = "Título";
|
||||||
$a->strings["Created"] = "Creado";
|
$a->strings["Created"] = "Creado";
|
||||||
$a->strings["Edited"] = "Editado";
|
$a->strings["Edited"] = "Editado";
|
||||||
|
$a->strings["view full size"] = "Ver en el tamaño original";
|
||||||
|
$a->strings["Administrator"] = "Administrador";
|
||||||
|
$a->strings["No Subject"] = "Sin asunto";
|
||||||
$a->strings["Cannot locate DNS info for database server '%s'"] = "No se ha podido localizar información de DNS para el servidor de base de datos “%s”";
|
$a->strings["Cannot locate DNS info for database server '%s'"] = "No se ha podido localizar información de DNS para el servidor de base de datos “%s”";
|
||||||
$a->strings["Image exceeds website size limit of %lu bytes"] = "La imagen excede el límite de %lu bytes del sitio";
|
$a->strings["Image exceeds website size limit of %lu bytes"] = "La imagen excede el límite de %lu bytes del sitio";
|
||||||
$a->strings["Image file is empty."] = "El fichero de imagen está vacío. ";
|
$a->strings["Image file is empty."] = "El fichero de imagen está vacío. ";
|
||||||
@ -933,23 +933,6 @@ $a->strings["This is you"] = "Este es usted";
|
|||||||
$a->strings["Image"] = "Imagen";
|
$a->strings["Image"] = "Imagen";
|
||||||
$a->strings["Insert Link"] = "Insertar enlace";
|
$a->strings["Insert Link"] = "Insertar enlace";
|
||||||
$a->strings["Video"] = "Vídeo";
|
$a->strings["Video"] = "Vídeo";
|
||||||
$a->strings["Not a valid email address"] = "Dirección de correo no válida";
|
|
||||||
$a->strings["Your email domain is not among those allowed on this site"] = "Su dirección de correo no pertenece a ninguno de los dominios permitidos en este sitio.";
|
|
||||||
$a->strings["Your email address is already registered at this site."] = "Su dirección de correo está ya registrada en este sitio.";
|
|
||||||
$a->strings["An invitation is required."] = "Es obligatorio que le inviten.";
|
|
||||||
$a->strings["Invitation could not be verified."] = "No se ha podido verificar su invitación.";
|
|
||||||
$a->strings["Please enter the required information."] = "Por favor introduzca la información requerida.";
|
|
||||||
$a->strings["Failed to store account information."] = "La información de la cuenta no se ha podido guardar.";
|
|
||||||
$a->strings["Registration confirmation for %s"] = "Confirmación de registro para %s";
|
|
||||||
$a->strings["Registration request at %s"] = "Solicitud de registro en %s";
|
|
||||||
$a->strings["your registration password"] = "su contraseña de registro";
|
|
||||||
$a->strings["Registration details for %s"] = "Detalles del registro de %s";
|
|
||||||
$a->strings["Account approved."] = "Cuenta aprobada.";
|
|
||||||
$a->strings["Registration revoked for %s"] = "Registro revocado para %s";
|
|
||||||
$a->strings["Account verified. Please login."] = "Cuenta verificada. Por favor, inicie sesión.";
|
|
||||||
$a->strings["Click here to upgrade."] = "Pulse aquí para actualizar";
|
|
||||||
$a->strings["This action exceeds the limits set by your subscription plan."] = "Esta acción supera los límites establecidos por su plan de suscripción ";
|
|
||||||
$a->strings["This action is not available under your subscription plan."] = "Esta acción no está disponible en su plan de suscripción.";
|
|
||||||
$a->strings["Site Admin"] = "Adminstrador del sitio";
|
$a->strings["Site Admin"] = "Adminstrador del sitio";
|
||||||
$a->strings["Address Book"] = "Libreta de direcciones";
|
$a->strings["Address Book"] = "Libreta de direcciones";
|
||||||
$a->strings["Mood"] = "Estado de ánimo";
|
$a->strings["Mood"] = "Estado de ánimo";
|
||||||
@ -964,12 +947,12 @@ $a->strings["Profile Photo"] = "Foto del perfil";
|
|||||||
$a->strings["Update"] = "Actualizar";
|
$a->strings["Update"] = "Actualizar";
|
||||||
$a->strings["Install"] = "Instalar";
|
$a->strings["Install"] = "Instalar";
|
||||||
$a->strings["Purchase"] = "Comprar";
|
$a->strings["Purchase"] = "Comprar";
|
||||||
$a->strings["Can view my normal stream and posts"] = "Pueden verse mi flujo de actividad y publicaciones normales";
|
$a->strings["Can view my normal stream and posts"] = "Pueden verse mi actividad y publicaciones normales";
|
||||||
$a->strings["Can view my default channel profile"] = "Puede verse mi perfil de canal predeterminado.";
|
$a->strings["Can view my default channel profile"] = "Puede verse mi perfil de canal predeterminado.";
|
||||||
$a->strings["Can view my connections"] = "Pueden verse mis conexiones";
|
$a->strings["Can view my connections"] = "Pueden verse mis conexiones";
|
||||||
$a->strings["Can view my file storage and photos"] = "Pueden verse mi repositorio de ficheros y mis fotos";
|
$a->strings["Can view my file storage and photos"] = "Pueden verse mi repositorio de ficheros y mis fotos";
|
||||||
$a->strings["Can view my webpages"] = "Pueden verse mis páginas web";
|
$a->strings["Can view my webpages"] = "Pueden verse mis páginas web";
|
||||||
$a->strings["Can send me their channel stream and posts"] = "Me pueden enviar sus entradas y flujo de actividad del canal";
|
$a->strings["Can send me their channel stream and posts"] = "Me pueden enviar sus entradas y contenidos del canal";
|
||||||
$a->strings["Can post on my channel page (\"wall\")"] = "Pueden crearse entradas en mi página de inicio del canal (“muro”)";
|
$a->strings["Can post on my channel page (\"wall\")"] = "Pueden crearse entradas en mi página de inicio del canal (“muro”)";
|
||||||
$a->strings["Can comment on or like my posts"] = "Pueden publicarse comentarios en mis publicaciones o marcar mis entradas con 'me gusta'.";
|
$a->strings["Can comment on or like my posts"] = "Pueden publicarse comentarios en mis publicaciones o marcar mis entradas con 'me gusta'.";
|
||||||
$a->strings["Can send me private mail messages"] = "Se me pueden enviar mensajes privados";
|
$a->strings["Can send me private mail messages"] = "Se me pueden enviar mensajes privados";
|
||||||
@ -995,6 +978,23 @@ $a->strings["Celebrity/Soapbox"] = "Página para fans";
|
|||||||
$a->strings["Group Repository"] = "Repositorio de grupo";
|
$a->strings["Group Repository"] = "Repositorio de grupo";
|
||||||
$a->strings["Custom/Expert Mode"] = "Modo personalizado/experto";
|
$a->strings["Custom/Expert Mode"] = "Modo personalizado/experto";
|
||||||
$a->strings["Profile Photos"] = "Fotos del perfil";
|
$a->strings["Profile Photos"] = "Fotos del perfil";
|
||||||
|
$a->strings["Not a valid email address"] = "Dirección de correo no válida";
|
||||||
|
$a->strings["Your email domain is not among those allowed on this site"] = "Su dirección de correo no pertenece a ninguno de los dominios permitidos en este sitio.";
|
||||||
|
$a->strings["Your email address is already registered at this site."] = "Su dirección de correo está ya registrada en este sitio.";
|
||||||
|
$a->strings["An invitation is required."] = "Es obligatorio que le inviten.";
|
||||||
|
$a->strings["Invitation could not be verified."] = "No se ha podido verificar su invitación.";
|
||||||
|
$a->strings["Please enter the required information."] = "Por favor introduzca la información requerida.";
|
||||||
|
$a->strings["Failed to store account information."] = "La información de la cuenta no se ha podido guardar.";
|
||||||
|
$a->strings["Registration confirmation for %s"] = "Confirmación de registro para %s";
|
||||||
|
$a->strings["Registration request at %s"] = "Solicitud de registro en %s";
|
||||||
|
$a->strings["your registration password"] = "su contraseña de registro";
|
||||||
|
$a->strings["Registration details for %s"] = "Detalles del registro de %s";
|
||||||
|
$a->strings["Account approved."] = "Cuenta aprobada.";
|
||||||
|
$a->strings["Registration revoked for %s"] = "Registro revocado para %s";
|
||||||
|
$a->strings["Account verified. Please login."] = "Cuenta verificada. Por favor, inicie sesión.";
|
||||||
|
$a->strings["Click here to upgrade."] = "Pulse aquí para actualizar";
|
||||||
|
$a->strings["This action exceeds the limits set by your subscription plan."] = "Esta acción supera los límites establecidos por su plan de suscripción ";
|
||||||
|
$a->strings["This action is not available under your subscription plan."] = "Esta acción no está disponible en su plan de suscripción.";
|
||||||
$a->strings["Permission Denied."] = "Permiso denegado";
|
$a->strings["Permission Denied."] = "Permiso denegado";
|
||||||
$a->strings["File not found."] = "Fichero no encontrado.";
|
$a->strings["File not found."] = "Fichero no encontrado.";
|
||||||
$a->strings["Edit file permissions"] = "Modificar los permisos del fichero";
|
$a->strings["Edit file permissions"] = "Modificar los permisos del fichero";
|
||||||
@ -1214,8 +1214,6 @@ $a->strings["IMPORTANT: You will need to [manually] setup a scheduled task for t
|
|||||||
$a->strings["Bookmark added"] = "Marcador añadido";
|
$a->strings["Bookmark added"] = "Marcador añadido";
|
||||||
$a->strings["My Bookmarks"] = "Mis marcadores";
|
$a->strings["My Bookmarks"] = "Mis marcadores";
|
||||||
$a->strings["My Connections Bookmarks"] = "Marcadores de mis conexiones";
|
$a->strings["My Connections Bookmarks"] = "Marcadores de mis conexiones";
|
||||||
$a->strings["\$Projectname"] = "\$Projectname";
|
|
||||||
$a->strings["Welcome to %s"] = "Bienvenido a %s";
|
|
||||||
$a->strings["This setting requires special processing and editing has been blocked."] = "Este ajuste necesita de un proceso especial y la edición ha sido bloqueada.";
|
$a->strings["This setting requires special processing and editing has been blocked."] = "Este ajuste necesita de un proceso especial y la edición ha sido bloqueada.";
|
||||||
$a->strings["Configuration Editor"] = "Editor de configuración";
|
$a->strings["Configuration Editor"] = "Editor de configuración";
|
||||||
$a->strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Atención: El cambio de algunos ajustes puede volver inutilizable su canal. Por favor, abandone la página excepto que esté seguro y sepa cómo usar correctamente esta característica.";
|
$a->strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Atención: El cambio de algunos ajustes puede volver inutilizable su canal. Por favor, abandone la página excepto que esté seguro y sepa cómo usar correctamente esta característica.";
|
||||||
@ -1477,43 +1475,25 @@ $a->strings["For either option, please choose whether to make this hub your new
|
|||||||
$a->strings["Make this hub my primary location"] = "Convertir este servidor en mi ubicación primaria";
|
$a->strings["Make this hub my primary location"] = "Convertir este servidor en mi ubicación primaria";
|
||||||
$a->strings["Import existing posts if possible (experimental - limited by available memory"] = "Importar el contenido publicado si es posible (experimental - limitado por la memoria disponible";
|
$a->strings["Import existing posts if possible (experimental - limited by available memory"] = "Importar el contenido publicado si es posible (experimental - limitado por la memoria disponible";
|
||||||
$a->strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Este proceso puede tardar varios minutos en completarse. Por favor envíe el formulario una sola vez y mantenga esta página abierta hasta que termine.";
|
$a->strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Este proceso puede tardar varios minutos en completarse. Por favor envíe el formulario una sola vez y mantenga esta página abierta hasta que termine.";
|
||||||
$a->strings["Page owner information could not be retrieved."] = "La información del propietario de la página no pudo ser recuperada.";
|
$a->strings["Total invitation limit exceeded."] = "Se ha superado el límite máximo de invitaciones.";
|
||||||
$a->strings["Album not found."] = "Álbum no encontrado.";
|
$a->strings["%s : Not a valid email address."] = "%s : No es una dirección de correo electrónico válida. ";
|
||||||
$a->strings["Delete Album"] = "Borrar álbum";
|
$a->strings["Please join us on \$Projectname"] = "Únase a nosotros en \$Projectname";
|
||||||
$a->strings["Delete Photo"] = "Borrar foto";
|
$a->strings["Invitation limit exceeded. Please contact your site administrator."] = "Excedido el límite de invitaciones. Por favor, contacte con el Administrador de su sitio.";
|
||||||
$a->strings["No photos selected"] = "No hay fotos seleccionadas";
|
$a->strings["%s : Message delivery failed."] = "%s : Falló el envío del mensaje.";
|
||||||
$a->strings["Access to this item is restricted."] = "El acceso a este elemento está restringido.";
|
$a->strings["%d message sent."] = array(
|
||||||
$a->strings["%1$.2f MB of %2$.2f MB photo storage used."] = "%1$.2f MB de %2$.2f MB de almacenamiento de fotos utilizado.";
|
0 => "%d mensajes enviados.",
|
||||||
$a->strings["%1$.2f MB photo storage used."] = "%1$.2f MB de almacenamiento de fotos utilizado.";
|
1 => "%d mensajes enviados.",
|
||||||
$a->strings["Upload Photos"] = "Subir fotos";
|
);
|
||||||
$a->strings["Enter an album name"] = "Introducir un nombre de álbum";
|
$a->strings["You have no more invitations available"] = "No tiene más invitaciones disponibles";
|
||||||
$a->strings["or select an existing album (doubleclick)"] = "o seleccionar uno existente (doble click)";
|
$a->strings["Send invitations"] = "Enviar invitaciones";
|
||||||
$a->strings["Create a status post for this upload"] = "Crear una entrada de estado para esta subida";
|
$a->strings["Enter email addresses, one per line:"] = "Introduzca las direcciones de correo electrónico, una por línea:";
|
||||||
$a->strings["Caption (optional):"] = "Título (opcional):";
|
$a->strings["Your message:"] = "Su mensaje:";
|
||||||
$a->strings["Description (optional):"] = "Descripción (opcional):";
|
$a->strings["Please join my community on \$Projectname."] = "Por favor, únase a mi comunidad en \$Projectname.";
|
||||||
$a->strings["Album name could not be decoded"] = "El nombre del álbum no ha podido ser descifrado";
|
$a->strings["You will need to supply this invitation code: "] = "Debe proporcionar este código de invitación:";
|
||||||
$a->strings["Contact Photos"] = "Fotos de contacto";
|
$a->strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Regístrese en cualquier sitio de \$Projectname (están todos interconectados)";
|
||||||
$a->strings["Show Newest First"] = "Mostrar lo más reciente primero";
|
$a->strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Introduzca mi dirección \$Projectname en la caja de búsqueda del sitio.";
|
||||||
$a->strings["Show Oldest First"] = "Mostrar lo más antiguo primero";
|
$a->strings["or visit "] = "o visite ";
|
||||||
$a->strings["Permission denied. Access to this item may be restricted."] = "Permiso denegado. El acceso a este elemento puede estar restringido.";
|
$a->strings["3. Click [Connect]"] = "3. Pulse [conectar]";
|
||||||
$a->strings["Photo not available"] = "Foto no disponible";
|
|
||||||
$a->strings["Use as profile photo"] = "Usar como foto del perfil";
|
|
||||||
$a->strings["Private Photo"] = "Foto privada";
|
|
||||||
$a->strings["Previous"] = "Anterior";
|
|
||||||
$a->strings["View Full Size"] = "Ver tamaño completo";
|
|
||||||
$a->strings["Edit photo"] = "Editar foto";
|
|
||||||
$a->strings["Rotate CW (right)"] = "Girar CW (a la derecha)";
|
|
||||||
$a->strings["Rotate CCW (left)"] = "Girar CCW (a la izquierda)";
|
|
||||||
$a->strings["Enter a new album name"] = "Introducir un nuevo nombre de álbum";
|
|
||||||
$a->strings["or select an existing one (doubleclick)"] = "o seleccionar uno (doble click) existente";
|
|
||||||
$a->strings["Caption"] = "Título";
|
|
||||||
$a->strings["Add a Tag"] = "Añadir una etiqueta";
|
|
||||||
$a->strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Ejemplos: @eva, @Carmen_Osuna, @jaime@ejemplo.com";
|
|
||||||
$a->strings["Flag as adult in album view"] = "Marcar como \"solo para adultos\" en el álbum";
|
|
||||||
$a->strings["In This Photo:"] = "En esta foto:";
|
|
||||||
$a->strings["Map"] = "Mapa";
|
|
||||||
$a->strings["View Album"] = "Ver álbum";
|
|
||||||
$a->strings["Recent Photos"] = "Fotos recientes";
|
|
||||||
$a->strings["Fetching URL returns error: %1\$s"] = "Al intentar obtener la dirección, retorna el error: %1\$s";
|
$a->strings["Fetching URL returns error: %1\$s"] = "Al intentar obtener la dirección, retorna el error: %1\$s";
|
||||||
$a->strings["Image uploaded but image cropping failed."] = "Imagen actualizada, pero el recorte de la imagen ha fallado. ";
|
$a->strings["Image uploaded but image cropping failed."] = "Imagen actualizada, pero el recorte de la imagen ha fallado. ";
|
||||||
$a->strings["Image resize failed."] = "El ajuste del tamaño de la imagen ha fallado.";
|
$a->strings["Image resize failed."] = "El ajuste del tamaño de la imagen ha fallado.";
|
||||||
@ -1628,7 +1608,7 @@ $a->strings["System theme"] = "Tema gráfico del sistema";
|
|||||||
$a->strings["Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"] = "Tema del sistema por defecto - se puede cambiar por cada perfil de usuario - <a href='#' id='cnftheme'>modificar los ajustes del tema</a>";
|
$a->strings["Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"] = "Tema del sistema por defecto - se puede cambiar por cada perfil de usuario - <a href='#' id='cnftheme'>modificar los ajustes del tema</a>";
|
||||||
$a->strings["Mobile system theme"] = "Tema del sistema para móviles";
|
$a->strings["Mobile system theme"] = "Tema del sistema para móviles";
|
||||||
$a->strings["Theme for mobile devices"] = "Tema para dispositivos móviles";
|
$a->strings["Theme for mobile devices"] = "Tema para dispositivos móviles";
|
||||||
$a->strings["Allow Feeds as Connections"] = "Permitir flujos RSS como conexiones";
|
$a->strings["Allow Feeds as Connections"] = "Permitir contenidos RSS como conexiones";
|
||||||
$a->strings["(Heavy system resource usage)"] = "(Uso intenso de los recursos del sistema)";
|
$a->strings["(Heavy system resource usage)"] = "(Uso intenso de los recursos del sistema)";
|
||||||
$a->strings["Maximum image size"] = "Tamaño máximo de la imagen";
|
$a->strings["Maximum image size"] = "Tamaño máximo de la imagen";
|
||||||
$a->strings["Maximum size in bytes of uploaded images. Default is 0, which means no limits."] = "Tamaño máximo en bytes de la imagen subida. Por defecto, es 0, lo que significa que no hay límites.";
|
$a->strings["Maximum size in bytes of uploaded images. Default is 0, which means no limits."] = "Tamaño máximo en bytes de la imagen subida. Por defecto, es 0, lo que significa que no hay límites.";
|
||||||
@ -1654,8 +1634,8 @@ $a->strings["Verify Email Addresses"] = "Verificar las direcciones de correo ele
|
|||||||
$a->strings["Check to verify email addresses used in account registration (recommended)."] = "Activar para la verificación de la dirección de correo electrónico en el registro de una cuenta (recomendado).";
|
$a->strings["Check to verify email addresses used in account registration (recommended)."] = "Activar para la verificación de la dirección de correo electrónico en el registro de una cuenta (recomendado).";
|
||||||
$a->strings["Force publish"] = "Forzar la publicación";
|
$a->strings["Force publish"] = "Forzar la publicación";
|
||||||
$a->strings["Check to force all profiles on this site to be listed in the site directory."] = "Intentar forzar todos los perfiles para que sean listados en el directorio de este sitio.";
|
$a->strings["Check to force all profiles on this site to be listed in the site directory."] = "Intentar forzar todos los perfiles para que sean listados en el directorio de este sitio.";
|
||||||
$a->strings["Disable discovery tab"] = "Desactivar la pestaña \"Descubrir\"";
|
$a->strings["Import Public Streams"] = "Importar contenido público";
|
||||||
$a->strings["Remove the tab in the network view with public content pulled from sources chosen for this site."] = "Quitar la pestaña para ver contenido público extraído de las fuentes elegidas por este sitio.";
|
$a->strings["Import and allow access to public content pulled from other sites. Warning: this content is unmoderated."] = "Importar y permitir acceso al contenido público sacado de otros sitios. Advertencia: este contenido no está moderado, por lo que podría encontrar cosas inapropiadas u ofensivas.";
|
||||||
$a->strings["login on Homepage"] = "acceso a la página personal";
|
$a->strings["login on Homepage"] = "acceso a la página personal";
|
||||||
$a->strings["Present a login box to visitors on the home page if no other content has been configured."] = "Presentar a los visitantes una casilla de identificación en la página de inicio, si no se ha configurado otro tipo de contenido.";
|
$a->strings["Present a login box to visitors on the home page if no other content has been configured."] = "Presentar a los visitantes una casilla de identificación en la página de inicio, si no se ha configurado otro tipo de contenido.";
|
||||||
$a->strings["Directory Server URL"] = "URL del servidor de directorio";
|
$a->strings["Directory Server URL"] = "URL del servidor de directorio";
|
||||||
@ -1946,25 +1926,8 @@ $a->strings["Sync now"] = "Sincronizar ahora";
|
|||||||
$a->strings["Please wait several minutes between consecutive operations."] = "Por favor, espere algunos minutos entre operaciones consecutivas.";
|
$a->strings["Please wait several minutes between consecutive operations."] = "Por favor, espere algunos minutos entre operaciones consecutivas.";
|
||||||
$a->strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "Cuando sea posible, elimine una ubicación iniciando sesión en el sitio web o \"hub\" y borrando su canal.";
|
$a->strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "Cuando sea posible, elimine una ubicación iniciando sesión en el sitio web o \"hub\" y borrando su canal.";
|
||||||
$a->strings["Use this form to drop the location if the hub is no longer operating."] = "Utilice este formulario para eliminar la dirección si el \"hub\" no está funcionando desde hace tiempo.";
|
$a->strings["Use this form to drop the location if the hub is no longer operating."] = "Utilice este formulario para eliminar la dirección si el \"hub\" no está funcionando desde hace tiempo.";
|
||||||
$a->strings["Total invitation limit exceeded."] = "Se ha superado el límite máximo de invitaciones.";
|
$a->strings["\$Projectname"] = "\$Projectname";
|
||||||
$a->strings["%s : Not a valid email address."] = "%s : No es una dirección de correo electrónico válida. ";
|
$a->strings["Welcome to %s"] = "Bienvenido a %s";
|
||||||
$a->strings["Please join us on \$Projectname"] = "Únase a nosotros en \$Projectname";
|
|
||||||
$a->strings["Invitation limit exceeded. Please contact your site administrator."] = "Excedido el límite de invitaciones. Por favor, contacte con el Administrador de su sitio.";
|
|
||||||
$a->strings["%s : Message delivery failed."] = "%s : Falló el envío del mensaje.";
|
|
||||||
$a->strings["%d message sent."] = array(
|
|
||||||
0 => "%d mensajes enviados.",
|
|
||||||
1 => "%d mensajes enviados.",
|
|
||||||
);
|
|
||||||
$a->strings["You have no more invitations available"] = "No tiene más invitaciones disponibles";
|
|
||||||
$a->strings["Send invitations"] = "Enviar invitaciones";
|
|
||||||
$a->strings["Enter email addresses, one per line:"] = "Introduzca las direcciones de correo electrónico, una por línea:";
|
|
||||||
$a->strings["Your message:"] = "Su mensaje:";
|
|
||||||
$a->strings["Please join my community on \$Projectname."] = "Por favor, únase a mi comunidad en \$Projectname.";
|
|
||||||
$a->strings["You will need to supply this invitation code: "] = "Debe proporcionar este código de invitación:";
|
|
||||||
$a->strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Regístrese en cualquier sitio de \$Projectname (están todos interconectados)";
|
|
||||||
$a->strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Introduzca mi dirección \$Projectname en la caja de búsqueda del sitio.";
|
|
||||||
$a->strings["or visit "] = "o visite ";
|
|
||||||
$a->strings["3. Click [Connect]"] = "3. Pulse [conectar]";
|
|
||||||
$a->strings["Please login."] = "Por favor, inicie sesión.";
|
$a->strings["Please login."] = "Por favor, inicie sesión.";
|
||||||
$a->strings["Xchan Lookup"] = "Búsqueda de canales";
|
$a->strings["Xchan Lookup"] = "Búsqueda de canales";
|
||||||
$a->strings["Lookup xchan beginning with (or webbie): "] = "Buscar un canal (o un \"webbie\") que comience por:";
|
$a->strings["Lookup xchan beginning with (or webbie): "] = "Buscar un canal (o un \"webbie\") que comience por:";
|
||||||
@ -1972,6 +1935,43 @@ $a->strings["Not found."] = "No encontrado.";
|
|||||||
$a->strings["You must be logged in to see this page."] = "Debe haber iniciado sesión para poder ver esta página.";
|
$a->strings["You must be logged in to see this page."] = "Debe haber iniciado sesión para poder ver esta página.";
|
||||||
$a->strings["Insufficient permissions. Request redirected to profile page."] = "Permisos insuficientes. Petición redirigida a la página del perfil.";
|
$a->strings["Insufficient permissions. Request redirected to profile page."] = "Permisos insuficientes. Petición redirigida a la página del perfil.";
|
||||||
$a->strings["Item not available."] = "Elemento no disponible";
|
$a->strings["Item not available."] = "Elemento no disponible";
|
||||||
|
$a->strings["Page owner information could not be retrieved."] = "La información del propietario de la página no pudo ser recuperada.";
|
||||||
|
$a->strings["Album not found."] = "Álbum no encontrado.";
|
||||||
|
$a->strings["Delete Album"] = "Borrar álbum";
|
||||||
|
$a->strings["Delete Photo"] = "Borrar foto";
|
||||||
|
$a->strings["No photos selected"] = "No hay fotos seleccionadas";
|
||||||
|
$a->strings["Access to this item is restricted."] = "El acceso a este elemento está restringido.";
|
||||||
|
$a->strings["%1$.2f MB of %2$.2f MB photo storage used."] = "%1$.2f MB de %2$.2f MB de almacenamiento de fotos utilizado.";
|
||||||
|
$a->strings["%1$.2f MB photo storage used."] = "%1$.2f MB de almacenamiento de fotos utilizado.";
|
||||||
|
$a->strings["Upload Photos"] = "Subir fotos";
|
||||||
|
$a->strings["Enter an album name"] = "Introducir un nombre de álbum";
|
||||||
|
$a->strings["or select an existing album (doubleclick)"] = "o seleccionar uno existente (doble click)";
|
||||||
|
$a->strings["Create a status post for this upload"] = "Crear una entrada de estado para esta subida";
|
||||||
|
$a->strings["Caption (optional):"] = "Título (opcional):";
|
||||||
|
$a->strings["Description (optional):"] = "Descripción (opcional):";
|
||||||
|
$a->strings["Album name could not be decoded"] = "El nombre del álbum no ha podido ser descifrado";
|
||||||
|
$a->strings["Contact Photos"] = "Fotos de contacto";
|
||||||
|
$a->strings["Show Newest First"] = "Mostrar lo más reciente primero";
|
||||||
|
$a->strings["Show Oldest First"] = "Mostrar lo más antiguo primero";
|
||||||
|
$a->strings["Permission denied. Access to this item may be restricted."] = "Permiso denegado. El acceso a este elemento puede estar restringido.";
|
||||||
|
$a->strings["Photo not available"] = "Foto no disponible";
|
||||||
|
$a->strings["Use as profile photo"] = "Usar como foto del perfil";
|
||||||
|
$a->strings["Private Photo"] = "Foto privada";
|
||||||
|
$a->strings["Previous"] = "Anterior";
|
||||||
|
$a->strings["View Full Size"] = "Ver tamaño completo";
|
||||||
|
$a->strings["Edit photo"] = "Editar foto";
|
||||||
|
$a->strings["Rotate CW (right)"] = "Girar CW (a la derecha)";
|
||||||
|
$a->strings["Rotate CCW (left)"] = "Girar CCW (a la izquierda)";
|
||||||
|
$a->strings["Enter a new album name"] = "Introducir un nuevo nombre de álbum";
|
||||||
|
$a->strings["or select an existing one (doubleclick)"] = "o seleccionar uno (doble click) existente";
|
||||||
|
$a->strings["Caption"] = "Título";
|
||||||
|
$a->strings["Add a Tag"] = "Añadir una etiqueta";
|
||||||
|
$a->strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Ejemplos: @eva, @Carmen_Osuna, @jaime@ejemplo.com";
|
||||||
|
$a->strings["Flag as adult in album view"] = "Marcar como \"solo para adultos\" en el álbum";
|
||||||
|
$a->strings["In This Photo:"] = "En esta foto:";
|
||||||
|
$a->strings["Map"] = "Mapa";
|
||||||
|
$a->strings["View Album"] = "Ver álbum";
|
||||||
|
$a->strings["Recent Photos"] = "Fotos recientes";
|
||||||
$a->strings["Remote privacy information not available."] = "La información privada remota no está disponible.";
|
$a->strings["Remote privacy information not available."] = "La información privada remota no está disponible.";
|
||||||
$a->strings["Visible to:"] = "Visible para:";
|
$a->strings["Visible to:"] = "Visible para:";
|
||||||
$a->strings["Export Channel"] = "Exportar el canal";
|
$a->strings["Export Channel"] = "Exportar el canal";
|
||||||
@ -2082,7 +2082,6 @@ $a->strings["Delete Conversation"] = "Eliminar conversación";
|
|||||||
$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Comunicación segura no disponible. Pero <strong>puede</strong> responder desde la página del perfil del remitente.";
|
$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Comunicación segura no disponible. Pero <strong>puede</strong> responder desde la página del perfil del remitente.";
|
||||||
$a->strings["Send Reply"] = "Responder";
|
$a->strings["Send Reply"] = "Responder";
|
||||||
$a->strings["Your message for %s (%s):"] = "Su mensaje para %s (%s):";
|
$a->strings["Your message for %s (%s):"] = "Su mensaje para %s (%s):";
|
||||||
$a->strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "La autenticación desde su servidor está bloqueada. Ha iniciado sesión localmente. Por favor, salga de la sesión y vuelva a intentarlo.";
|
|
||||||
$a->strings["No service class restrictions found."] = "No se han encontrado restricciones sobre esta clase de servicio.";
|
$a->strings["No service class restrictions found."] = "No se han encontrado restricciones sobre esta clase de servicio.";
|
||||||
$a->strings["Version %s"] = "Versión %s";
|
$a->strings["Version %s"] = "Versión %s";
|
||||||
$a->strings["Installed plugins/addons/apps:"] = "Extensiones/Aplicaciones instaladas:";
|
$a->strings["Installed plugins/addons/apps:"] = "Extensiones/Aplicaciones instaladas:";
|
||||||
@ -2213,3 +2212,4 @@ $a->strings["Website SSL certificate is not valid. Please correct."] = "El certi
|
|||||||
$a->strings["[hubzilla] Website SSL error for %s"] = "[hubzilla] Error SSL del sitio web en %s";
|
$a->strings["[hubzilla] Website SSL error for %s"] = "[hubzilla] Error SSL del sitio web en %s";
|
||||||
$a->strings["Cron/Scheduled tasks not running."] = "Las tareas del Planificador/Cron no están funcionando.";
|
$a->strings["Cron/Scheduled tasks not running."] = "Las tareas del Planificador/Cron no están funcionando.";
|
||||||
$a->strings["[hubzilla] Cron tasks not running on %s"] = "[hubzilla] Las tareas de Cron no están funcionando en %s";
|
$a->strings["[hubzilla] Cron tasks not running on %s"] = "[hubzilla] Las tareas de Cron no están funcionando en %s";
|
||||||
|
$a->strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "La autenticación desde su servidor está bloqueada. Ha iniciado sesión localmente. Por favor, salga de la sesión y vuelva a intentarlo.";
|
||||||
|
@ -39,18 +39,18 @@ function ACL(backend_url, preset) {
|
|||||||
// no longer called only on submit - call to update whenever a change occurs to the acl list.
|
// no longer called only on submit - call to update whenever a change occurs to the acl list.
|
||||||
|
|
||||||
ACL.prototype.on_submit = function() {
|
ACL.prototype.on_submit = function() {
|
||||||
aclfileds = $("#acl-fields").html("");
|
aclfields = $("#acl-fields").html("");
|
||||||
$(that.allow_gid).each(function(i,v) {
|
$(that.allow_gid).each(function(i,v) {
|
||||||
aclfileds.append("<input type='hidden' name='group_allow[]' value='"+v+"'>");
|
aclfields.append("<input type='hidden' name='group_allow[]' value='"+v+"'>");
|
||||||
});
|
});
|
||||||
$(that.allow_cid).each(function(i,v) {
|
$(that.allow_cid).each(function(i,v) {
|
||||||
aclfileds.append("<input type='hidden' name='contact_allow[]' value='"+v+"'>");
|
aclfields.append("<input type='hidden' name='contact_allow[]' value='"+v+"'>");
|
||||||
});
|
});
|
||||||
$(that.deny_gid).each(function(i,v) {
|
$(that.deny_gid).each(function(i,v) {
|
||||||
aclfileds.append("<input type='hidden' name='group_deny[]' value='"+v+"'>");
|
aclfields.append("<input type='hidden' name='group_deny[]' value='"+v+"'>");
|
||||||
});
|
});
|
||||||
$(that.deny_cid).each(function(i,v) {
|
$(that.deny_cid).each(function(i,v) {
|
||||||
aclfileds.append("<input type='hidden' name='contact_deny[]' value='"+v+"'>");
|
aclfields.append("<input type='hidden' name='contact_deny[]' value='"+v+"'>");
|
||||||
});
|
});
|
||||||
|
|
||||||
//areYouSure jquery plugin: recheck the form here
|
//areYouSure jquery plugin: recheck the form here
|
||||||
|
1304
view/nl/hmessages.po
1304
view/nl/hmessages.po
File diff suppressed because it is too large
Load Diff
@ -143,13 +143,6 @@ $a->strings["Collection is empty."] = "Collectie is leeg";
|
|||||||
$a->strings["Collection: %s"] = "Collectie: %s";
|
$a->strings["Collection: %s"] = "Collectie: %s";
|
||||||
$a->strings["Connection: %s"] = "Connectie: %s";
|
$a->strings["Connection: %s"] = "Connectie: %s";
|
||||||
$a->strings["Connection not found."] = "Connectie niet gevonden.";
|
$a->strings["Connection not found."] = "Connectie niet gevonden.";
|
||||||
$a->strings["view full size"] = "volledige grootte tonen";
|
|
||||||
$a->strings["\$Projectname Notification"] = "\$Projectname-notificatie";
|
|
||||||
$a->strings["\$projectname"] = "\$projectname";
|
|
||||||
$a->strings["Thank You,"] = "Bedankt,";
|
|
||||||
$a->strings["%s Administrator"] = "Beheerder %s";
|
|
||||||
$a->strings["Administrator"] = "Beheerder";
|
|
||||||
$a->strings["No Subject"] = "Geen onderwerp";
|
|
||||||
$a->strings["l F d, Y \\@ g:i A"] = "l d F Y \\@ G:i";
|
$a->strings["l F d, Y \\@ g:i A"] = "l d F Y \\@ G:i";
|
||||||
$a->strings["Starts:"] = "Start:";
|
$a->strings["Starts:"] = "Start:";
|
||||||
$a->strings["Finishes:"] = "Einde:";
|
$a->strings["Finishes:"] = "Einde:";
|
||||||
@ -700,6 +693,10 @@ $a->strings["%d connection in common"] = array(
|
|||||||
1 => "%d gemeenschappelijke connecties",
|
1 => "%d gemeenschappelijke connecties",
|
||||||
);
|
);
|
||||||
$a->strings["show more"] = "meer connecties weergeven";
|
$a->strings["show more"] = "meer connecties weergeven";
|
||||||
|
$a->strings["\$Projectname Notification"] = "\$Projectname-notificatie";
|
||||||
|
$a->strings["\$projectname"] = "\$projectname";
|
||||||
|
$a->strings["Thank You,"] = "Bedankt,";
|
||||||
|
$a->strings["%s Administrator"] = "Beheerder %s";
|
||||||
$a->strings["%s <!item_type!>"] = "%s <!item_type!>";
|
$a->strings["%s <!item_type!>"] = "%s <!item_type!>";
|
||||||
$a->strings["[Hubzilla:Notify] New mail received at %s"] = "[Hubzilla:Notificatie] Nieuw privébericht ontvangen op %s";
|
$a->strings["[Hubzilla:Notify] New mail received at %s"] = "[Hubzilla:Notificatie] Nieuw privébericht ontvangen op %s";
|
||||||
$a->strings["%1\$s, %2\$s sent you a new private message at %3\$s."] = "%1\$s, %2\$s zond jou een nieuw privébericht om %3\$s.";
|
$a->strings["%1\$s, %2\$s sent you a new private message at %3\$s."] = "%1\$s, %2\$s zond jou een nieuw privébericht om %3\$s.";
|
||||||
@ -892,6 +889,9 @@ $a->strings["Page Link"] = "Paginalink";
|
|||||||
$a->strings["Title"] = "Titel";
|
$a->strings["Title"] = "Titel";
|
||||||
$a->strings["Created"] = "Aangemaakt";
|
$a->strings["Created"] = "Aangemaakt";
|
||||||
$a->strings["Edited"] = "Bewerkt";
|
$a->strings["Edited"] = "Bewerkt";
|
||||||
|
$a->strings["view full size"] = "volledige grootte tonen";
|
||||||
|
$a->strings["Administrator"] = "Beheerder";
|
||||||
|
$a->strings["No Subject"] = "Geen onderwerp";
|
||||||
$a->strings["Cannot locate DNS info for database server '%s'"] = "Kan DNS-informatie voor databaseserver '%s' niet vinden";
|
$a->strings["Cannot locate DNS info for database server '%s'"] = "Kan DNS-informatie voor databaseserver '%s' niet vinden";
|
||||||
$a->strings["Image exceeds website size limit of %lu bytes"] = "Afbeelding is groter dan op deze hub toegestane limiet van %lu bytes";
|
$a->strings["Image exceeds website size limit of %lu bytes"] = "Afbeelding is groter dan op deze hub toegestane limiet van %lu bytes";
|
||||||
$a->strings["Image file is empty."] = "Afbeeldingsbestand is leeg";
|
$a->strings["Image file is empty."] = "Afbeeldingsbestand is leeg";
|
||||||
@ -933,23 +933,6 @@ $a->strings["This is you"] = "Dit ben jij";
|
|||||||
$a->strings["Image"] = "Afbeelding";
|
$a->strings["Image"] = "Afbeelding";
|
||||||
$a->strings["Insert Link"] = "Link invoegen";
|
$a->strings["Insert Link"] = "Link invoegen";
|
||||||
$a->strings["Video"] = "Video";
|
$a->strings["Video"] = "Video";
|
||||||
$a->strings["Not a valid email address"] = "Geen geldig e-mailadres";
|
|
||||||
$a->strings["Your email domain is not among those allowed on this site"] = "Jouw e-maildomein is op deze hub niet toegestaan";
|
|
||||||
$a->strings["Your email address is already registered at this site."] = "Jouw e-mailadres is al op deze hub geregistreerd.";
|
|
||||||
$a->strings["An invitation is required."] = "Een uitnodiging is vereist";
|
|
||||||
$a->strings["Invitation could not be verified."] = "Uitnodiging kon niet geverifieerd worden";
|
|
||||||
$a->strings["Please enter the required information."] = "Vul de vereiste informatie in.";
|
|
||||||
$a->strings["Failed to store account information."] = "Account-informatie kon niet opgeslagen worden.";
|
|
||||||
$a->strings["Registration confirmation for %s"] = "Registratiebevestiging voor %s";
|
|
||||||
$a->strings["Registration request at %s"] = "Registratiebevestiging voor %s";
|
|
||||||
$a->strings["your registration password"] = "jouw registratiewachtwoord";
|
|
||||||
$a->strings["Registration details for %s"] = "Registratiegegevens voor %s";
|
|
||||||
$a->strings["Account approved."] = "Account goedgekeurd";
|
|
||||||
$a->strings["Registration revoked for %s"] = "Registratie ingetrokken voor %s";
|
|
||||||
$a->strings["Account verified. Please login."] = "Account is geverifieerd. Je kan inloggen.";
|
|
||||||
$a->strings["Click here to upgrade."] = "Klik hier om te upgraden.";
|
|
||||||
$a->strings["This action exceeds the limits set by your subscription plan."] = "Deze handeling overschrijdt de beperkingen die voor jouw abonnement gelden.";
|
|
||||||
$a->strings["This action is not available under your subscription plan."] = "Deze handeling is niet mogelijk met jouw abonnement.";
|
|
||||||
$a->strings["Site Admin"] = "Hubbeheerder";
|
$a->strings["Site Admin"] = "Hubbeheerder";
|
||||||
$a->strings["Address Book"] = "Connecties";
|
$a->strings["Address Book"] = "Connecties";
|
||||||
$a->strings["Mood"] = "Stemming";
|
$a->strings["Mood"] = "Stemming";
|
||||||
@ -995,6 +978,23 @@ $a->strings["Celebrity/Soapbox"] = "Beroemdheid/alleen volgen";
|
|||||||
$a->strings["Group Repository"] = "Groepsopslag";
|
$a->strings["Group Repository"] = "Groepsopslag";
|
||||||
$a->strings["Custom/Expert Mode"] = "Expertmodus/handmatig aanpassen";
|
$a->strings["Custom/Expert Mode"] = "Expertmodus/handmatig aanpassen";
|
||||||
$a->strings["Profile Photos"] = "Profielfoto's";
|
$a->strings["Profile Photos"] = "Profielfoto's";
|
||||||
|
$a->strings["Not a valid email address"] = "Geen geldig e-mailadres";
|
||||||
|
$a->strings["Your email domain is not among those allowed on this site"] = "Jouw e-maildomein is op deze hub niet toegestaan";
|
||||||
|
$a->strings["Your email address is already registered at this site."] = "Jouw e-mailadres is al op deze hub geregistreerd.";
|
||||||
|
$a->strings["An invitation is required."] = "Een uitnodiging is vereist";
|
||||||
|
$a->strings["Invitation could not be verified."] = "Uitnodiging kon niet geverifieerd worden";
|
||||||
|
$a->strings["Please enter the required information."] = "Vul de vereiste informatie in.";
|
||||||
|
$a->strings["Failed to store account information."] = "Account-informatie kon niet opgeslagen worden.";
|
||||||
|
$a->strings["Registration confirmation for %s"] = "Registratiebevestiging voor %s";
|
||||||
|
$a->strings["Registration request at %s"] = "Registratiebevestiging voor %s";
|
||||||
|
$a->strings["your registration password"] = "jouw registratiewachtwoord";
|
||||||
|
$a->strings["Registration details for %s"] = "Registratiegegevens voor %s";
|
||||||
|
$a->strings["Account approved."] = "Account goedgekeurd";
|
||||||
|
$a->strings["Registration revoked for %s"] = "Registratie ingetrokken voor %s";
|
||||||
|
$a->strings["Account verified. Please login."] = "Account is geverifieerd. Je kan inloggen.";
|
||||||
|
$a->strings["Click here to upgrade."] = "Klik hier om te upgraden.";
|
||||||
|
$a->strings["This action exceeds the limits set by your subscription plan."] = "Deze handeling overschrijdt de beperkingen die voor jouw abonnement gelden.";
|
||||||
|
$a->strings["This action is not available under your subscription plan."] = "Deze handeling is niet mogelijk met jouw abonnement.";
|
||||||
$a->strings["Permission Denied."] = "Toegang geweigerd";
|
$a->strings["Permission Denied."] = "Toegang geweigerd";
|
||||||
$a->strings["File not found."] = "Bestand niet gevonden.";
|
$a->strings["File not found."] = "Bestand niet gevonden.";
|
||||||
$a->strings["Edit file permissions"] = "Bestandsrechten bewerken";
|
$a->strings["Edit file permissions"] = "Bestandsrechten bewerken";
|
||||||
@ -1214,8 +1214,6 @@ $a->strings["IMPORTANT: You will need to [manually] setup a scheduled task for t
|
|||||||
$a->strings["Bookmark added"] = "Bladwijzer toegevoegd";
|
$a->strings["Bookmark added"] = "Bladwijzer toegevoegd";
|
||||||
$a->strings["My Bookmarks"] = "Mijn bladwijzers";
|
$a->strings["My Bookmarks"] = "Mijn bladwijzers";
|
||||||
$a->strings["My Connections Bookmarks"] = "Bladwijzers van mijn connecties";
|
$a->strings["My Connections Bookmarks"] = "Bladwijzers van mijn connecties";
|
||||||
$a->strings["\$Projectname"] = "\$Projectname";
|
|
||||||
$a->strings["Welcome to %s"] = "Welkom op %s";
|
|
||||||
$a->strings["This setting requires special processing and editing has been blocked."] = "Deze instelling vereist een speciaal proces en bewerken is geblokkeerd.";
|
$a->strings["This setting requires special processing and editing has been blocked."] = "Deze instelling vereist een speciaal proces en bewerken is geblokkeerd.";
|
||||||
$a->strings["Configuration Editor"] = "Configuratiebewerker";
|
$a->strings["Configuration Editor"] = "Configuratiebewerker";
|
||||||
$a->strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Waarschuwing: het veranderen van sommige instellingen kunnen jouw kanaal onklaar maken. Verlaat deze pagina, tenzij je weet waar je mee bezig bent en voldoende kennis bezit over hoe je deze functies moet gebruiken. ";
|
$a->strings["Warning: Changing some settings could render your channel inoperable. Please leave this page unless you are comfortable with and knowledgeable about how to correctly use this feature."] = "Waarschuwing: het veranderen van sommige instellingen kunnen jouw kanaal onklaar maken. Verlaat deze pagina, tenzij je weet waar je mee bezig bent en voldoende kennis bezit over hoe je deze functies moet gebruiken. ";
|
||||||
@ -1477,43 +1475,25 @@ $a->strings["For either option, please choose whether to make this hub your new
|
|||||||
$a->strings["Make this hub my primary location"] = "Stel deze hub als mijn primaire locatie in";
|
$a->strings["Make this hub my primary location"] = "Stel deze hub als mijn primaire locatie in";
|
||||||
$a->strings["Import existing posts if possible (experimental - limited by available memory"] = "Importeer bestaande berichten wanneer mogelijk (experimenteel - afhankelijk van beschikbaar servergeheugen)";
|
$a->strings["Import existing posts if possible (experimental - limited by available memory"] = "Importeer bestaande berichten wanneer mogelijk (experimenteel - afhankelijk van beschikbaar servergeheugen)";
|
||||||
$a->strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Dit proces kan enkele minuten in beslag nemen. Klik maar één keer op opslaan en verlaat deze pagina niet alvorens het proces is voltooid.";
|
$a->strings["This process may take several minutes to complete. Please submit the form only once and leave this page open until finished."] = "Dit proces kan enkele minuten in beslag nemen. Klik maar één keer op opslaan en verlaat deze pagina niet alvorens het proces is voltooid.";
|
||||||
$a->strings["Page owner information could not be retrieved."] = "Informatie over de pagina-eigenaar werd niet ontvangen.";
|
$a->strings["Total invitation limit exceeded."] = "Limiet voor aantal uitnodigingen overschreden.";
|
||||||
$a->strings["Album not found."] = "Album niet gevonden.";
|
$a->strings["%s : Not a valid email address."] = "%s : Geen geldig e-mailadres.";
|
||||||
$a->strings["Delete Album"] = "Verwijder album";
|
$a->strings["Please join us on \$Projectname"] = "Uitnodiging voor \$Projectname";
|
||||||
$a->strings["Delete Photo"] = "Verwijder foto";
|
$a->strings["Invitation limit exceeded. Please contact your site administrator."] = "Limiet voor aantal uitnodigingen overschreden. Neem contact op met je hub-beheerder.";
|
||||||
$a->strings["No photos selected"] = "Geen foto's geselecteerd";
|
$a->strings["%s : Message delivery failed."] = "%s: Aflevering bericht mislukt.";
|
||||||
$a->strings["Access to this item is restricted."] = "Toegang tot dit item is beperkt.";
|
$a->strings["%d message sent."] = array(
|
||||||
$a->strings["%1$.2f MB of %2$.2f MB photo storage used."] = "%1$.2f MB van %2$.2f MB aan foto-opslag gebruikt.";
|
0 => "%d bericht verzonden.",
|
||||||
$a->strings["%1$.2f MB photo storage used."] = "%1$.2f MB aan foto-opslag gebruikt.";
|
1 => "%d berichten verzonden.",
|
||||||
$a->strings["Upload Photos"] = "Foto's uploaden";
|
);
|
||||||
$a->strings["Enter an album name"] = "Vul een albumnaam in";
|
$a->strings["You have no more invitations available"] = "Je hebt geen uitnodigingen meer beschikbaar";
|
||||||
$a->strings["or select an existing album (doubleclick)"] = "of kies een bestaand album (dubbelklikken)";
|
$a->strings["Send invitations"] = "Uitnodigingen verzenden";
|
||||||
$a->strings["Create a status post for this upload"] = "Plaats een bericht voor deze upload.";
|
$a->strings["Enter email addresses, one per line:"] = "Voer e-mailadressen in, één per regel:";
|
||||||
$a->strings["Caption (optional):"] = "Bijschrift (optioneel):";
|
$a->strings["Your message:"] = "Jouw bericht:";
|
||||||
$a->strings["Description (optional):"] = "Omschrijving (optioneel):";
|
$a->strings["Please join my community on \$Projectname."] = "Hierbij nodig ik je uit om mij, en andere vrienden en kennissen, op \$Projectname te vergezellen. Lees meer over \$Projectname op https://redmatrix.me.";
|
||||||
$a->strings["Album name could not be decoded"] = "Albumnaam kon niet gedecodeerd worden";
|
$a->strings["You will need to supply this invitation code: "] = "Je moet deze uitnodigingscode opgeven: ";
|
||||||
$a->strings["Contact Photos"] = "Connectiefoto's";
|
$a->strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Registreer je op een willekeurige \$Projectname-hub (ze zijn allemaal onderling met elkaar verbonden):";
|
||||||
$a->strings["Show Newest First"] = "Nieuwste eerst weergeven";
|
$a->strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Nadat je bent ingelogd en een kanaal hebt aangemaakt kan je mijn \$Projectname-kanaaladres in het zoekveld invullen:";
|
||||||
$a->strings["Show Oldest First"] = "Oudste eerst weergeven";
|
$a->strings["or visit "] = "of bezoek ";
|
||||||
$a->strings["Permission denied. Access to this item may be restricted."] = "Toegang geweigerd. Toegang tot dit item kan zijn beperkt.";
|
$a->strings["3. Click [Connect]"] = "3. Klik op [+ Verbinden]";
|
||||||
$a->strings["Photo not available"] = "Foto niet aanwezig";
|
|
||||||
$a->strings["Use as profile photo"] = "Als profielfoto gebruiken";
|
|
||||||
$a->strings["Private Photo"] = "Privéfoto";
|
|
||||||
$a->strings["Previous"] = "Vorige";
|
|
||||||
$a->strings["View Full Size"] = "Volledige grootte weergeven";
|
|
||||||
$a->strings["Edit photo"] = "Foto bewerken";
|
|
||||||
$a->strings["Rotate CW (right)"] = "Draai met de klok mee (naar rechts)";
|
|
||||||
$a->strings["Rotate CCW (left)"] = "Draai tegen de klok in (naar links)";
|
|
||||||
$a->strings["Enter a new album name"] = "Vul een nieuwe albumnaam in";
|
|
||||||
$a->strings["or select an existing one (doubleclick)"] = "of kies een bestaand album (dubbelklikken)";
|
|
||||||
$a->strings["Caption"] = "Bijschrift";
|
|
||||||
$a->strings["Add a Tag"] = "Tag toevoegen";
|
|
||||||
$a->strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Voorbeeld: @bob, @Barbara_Jansen, @jan@voorbeeld.nl";
|
|
||||||
$a->strings["Flag as adult in album view"] = "Markeer als voor volwassenen in albumweergave";
|
|
||||||
$a->strings["In This Photo:"] = "Op deze foto:";
|
|
||||||
$a->strings["Map"] = "Kaart";
|
|
||||||
$a->strings["View Album"] = "Album weergeven";
|
|
||||||
$a->strings["Recent Photos"] = "Recente foto's";
|
|
||||||
$a->strings["Fetching URL returns error: %1\$s"] = "Ophalen URL gaf een foutmelding terug: %1\$s";
|
$a->strings["Fetching URL returns error: %1\$s"] = "Ophalen URL gaf een foutmelding terug: %1\$s";
|
||||||
$a->strings["Image uploaded but image cropping failed."] = "Afbeelding geüpload, maar afbeelding kon niet worden bijgesneden. ";
|
$a->strings["Image uploaded but image cropping failed."] = "Afbeelding geüpload, maar afbeelding kon niet worden bijgesneden. ";
|
||||||
$a->strings["Image resize failed."] = "Afbeelding kon niet van grootte veranderd worden.";
|
$a->strings["Image resize failed."] = "Afbeelding kon niet van grootte veranderd worden.";
|
||||||
@ -1654,8 +1634,8 @@ $a->strings["Verify Email Addresses"] = "E-mailadres verifieren";
|
|||||||
$a->strings["Check to verify email addresses used in account registration (recommended)."] = "Inschakelen om e-mailadressen te verifiëren die tijdens de accountregistratie worden gebruikt (aanbevolen).";
|
$a->strings["Check to verify email addresses used in account registration (recommended)."] = "Inschakelen om e-mailadressen te verifiëren die tijdens de accountregistratie worden gebruikt (aanbevolen).";
|
||||||
$a->strings["Force publish"] = "Dwing kanaalvermelding af";
|
$a->strings["Force publish"] = "Dwing kanaalvermelding af";
|
||||||
$a->strings["Check to force all profiles on this site to be listed in the site directory."] = "Vink dit aan om af te dwingen dat alle kanalen op deze hub in de kanalengids worden vermeld.";
|
$a->strings["Check to force all profiles on this site to be listed in the site directory."] = "Vink dit aan om af te dwingen dat alle kanalen op deze hub in de kanalengids worden vermeld.";
|
||||||
$a->strings["Disable discovery tab"] = "Ontdekkingstab";
|
$a->strings["Import Public Streams"] = "Openbare streams importeren";
|
||||||
$a->strings["Remove the tab in the network view with public content pulled from sources chosen for this site."] = "Verwijder de tab in de matrix-weergave waarin zich een selectie aan openbare berichten bevindt, die automatisch voor deze hub zijn uitgekozen.";
|
$a->strings["Import and allow access to public content pulled from other sites. Warning: this content is unmoderated."] = "Toegang verlenen tot openbare berichten die vanuit andere hubs worden geïmporteerd. Waarschuwing: de inhoud van deze berichten wordt niet gemodereerd.";
|
||||||
$a->strings["login on Homepage"] = "Inlogformulier op de homepagina";
|
$a->strings["login on Homepage"] = "Inlogformulier op de homepagina";
|
||||||
$a->strings["Present a login box to visitors on the home page if no other content has been configured."] = "Toon een inlogformulier voor bezoekers op de homepagina wanneer geen andere inhoud is geconfigureerd. ";
|
$a->strings["Present a login box to visitors on the home page if no other content has been configured."] = "Toon een inlogformulier voor bezoekers op de homepagina wanneer geen andere inhoud is geconfigureerd. ";
|
||||||
$a->strings["Directory Server URL"] = "Server-URL voor de kanalengids";
|
$a->strings["Directory Server URL"] = "Server-URL voor de kanalengids";
|
||||||
@ -1946,25 +1926,8 @@ $a->strings["Sync now"] = "Nu synchroniseren";
|
|||||||
$a->strings["Please wait several minutes between consecutive operations."] = "Wacht enkele minuten tussen opeenvolgende handelingen.";
|
$a->strings["Please wait several minutes between consecutive operations."] = "Wacht enkele minuten tussen opeenvolgende handelingen.";
|
||||||
$a->strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "Wij adviseren, wanneer dit (nog) mogelijk is, de locatie te verwijderen door op de hub van de kloon in te loggen en het kanaal daar te verwijderen.";
|
$a->strings["When possible, drop a location by logging into that website/hub and removing your channel."] = "Wij adviseren, wanneer dit (nog) mogelijk is, de locatie te verwijderen door op de hub van de kloon in te loggen en het kanaal daar te verwijderen.";
|
||||||
$a->strings["Use this form to drop the location if the hub is no longer operating."] = "Gebruik dit formulier om de locatie te verwijderen wanneer de hub van de kloon niet meer operationeel is.";
|
$a->strings["Use this form to drop the location if the hub is no longer operating."] = "Gebruik dit formulier om de locatie te verwijderen wanneer de hub van de kloon niet meer operationeel is.";
|
||||||
$a->strings["Total invitation limit exceeded."] = "Limiet voor aantal uitnodigingen overschreden.";
|
$a->strings["\$Projectname"] = "\$Projectname";
|
||||||
$a->strings["%s : Not a valid email address."] = "%s : Geen geldig e-mailadres.";
|
$a->strings["Welcome to %s"] = "Welkom op %s";
|
||||||
$a->strings["Please join us on \$Projectname"] = "Uitnodiging voor \$Projectname";
|
|
||||||
$a->strings["Invitation limit exceeded. Please contact your site administrator."] = "Limiet voor aantal uitnodigingen overschreden. Neem contact op met je hub-beheerder.";
|
|
||||||
$a->strings["%s : Message delivery failed."] = "%s: Aflevering bericht mislukt.";
|
|
||||||
$a->strings["%d message sent."] = array(
|
|
||||||
0 => "%d bericht verzonden.",
|
|
||||||
1 => "%d berichten verzonden.",
|
|
||||||
);
|
|
||||||
$a->strings["You have no more invitations available"] = "Je hebt geen uitnodigingen meer beschikbaar";
|
|
||||||
$a->strings["Send invitations"] = "Uitnodigingen verzenden";
|
|
||||||
$a->strings["Enter email addresses, one per line:"] = "Voer e-mailadressen in, één per regel:";
|
|
||||||
$a->strings["Your message:"] = "Jouw bericht:";
|
|
||||||
$a->strings["Please join my community on \$Projectname."] = "Hierbij nodig ik je uit om mij, en andere vrienden en kennissen, op \$Projectname te vergezellen. Lees meer over \$Projectname op https://redmatrix.me.";
|
|
||||||
$a->strings["You will need to supply this invitation code: "] = "Je moet deze uitnodigingscode opgeven:";
|
|
||||||
$a->strings["1. Register at any \$Projectname location (they are all inter-connected)"] = "1. Registreer je op een willekeurige \$Projectname-hub (ze zijn allemaal onderling met elkaar verbonden):";
|
|
||||||
$a->strings["2. Enter my \$Projectname network address into the site searchbar."] = "2. Nadat je bent ingelogd en een kanaal hebt aangemaakt kan je mijn \$Projectname-kanaaladres in het zoekveld invullen:";
|
|
||||||
$a->strings["or visit "] = "of bezoek ";
|
|
||||||
$a->strings["3. Click [Connect]"] = "3. Klik op [+ Verbinden]";
|
|
||||||
$a->strings["Please login."] = "Inloggen.";
|
$a->strings["Please login."] = "Inloggen.";
|
||||||
$a->strings["Xchan Lookup"] = "Xchan opzoeken";
|
$a->strings["Xchan Lookup"] = "Xchan opzoeken";
|
||||||
$a->strings["Lookup xchan beginning with (or webbie): "] = "Zoek een xchan (of webbie) die begint met:";
|
$a->strings["Lookup xchan beginning with (or webbie): "] = "Zoek een xchan (of webbie) die begint met:";
|
||||||
@ -1972,6 +1935,43 @@ $a->strings["Not found."] = "Niet gevonden.";
|
|||||||
$a->strings["You must be logged in to see this page."] = "Je moet zijn ingelogd om deze pagina te kunnen bekijken.";
|
$a->strings["You must be logged in to see this page."] = "Je moet zijn ingelogd om deze pagina te kunnen bekijken.";
|
||||||
$a->strings["Insufficient permissions. Request redirected to profile page."] = "Onvoldoende permissies. Doorgestuurd naar profielpagina.";
|
$a->strings["Insufficient permissions. Request redirected to profile page."] = "Onvoldoende permissies. Doorgestuurd naar profielpagina.";
|
||||||
$a->strings["Item not available."] = "Item is niet aanwezig.";
|
$a->strings["Item not available."] = "Item is niet aanwezig.";
|
||||||
|
$a->strings["Page owner information could not be retrieved."] = "Informatie over de pagina-eigenaar werd niet ontvangen.";
|
||||||
|
$a->strings["Album not found."] = "Album niet gevonden.";
|
||||||
|
$a->strings["Delete Album"] = "Verwijder album";
|
||||||
|
$a->strings["Delete Photo"] = "Verwijder foto";
|
||||||
|
$a->strings["No photos selected"] = "Geen foto's geselecteerd";
|
||||||
|
$a->strings["Access to this item is restricted."] = "Toegang tot dit item is beperkt.";
|
||||||
|
$a->strings["%1$.2f MB of %2$.2f MB photo storage used."] = "%1$.2f MB van %2$.2f MB aan foto-opslag gebruikt.";
|
||||||
|
$a->strings["%1$.2f MB photo storage used."] = "%1$.2f MB aan foto-opslag gebruikt.";
|
||||||
|
$a->strings["Upload Photos"] = "Foto's uploaden";
|
||||||
|
$a->strings["Enter an album name"] = "Vul een albumnaam in";
|
||||||
|
$a->strings["or select an existing album (doubleclick)"] = "of kies een bestaand album (dubbelklikken)";
|
||||||
|
$a->strings["Create a status post for this upload"] = "Plaats een bericht voor deze upload.";
|
||||||
|
$a->strings["Caption (optional):"] = "Bijschrift (optioneel):";
|
||||||
|
$a->strings["Description (optional):"] = "Omschrijving (optioneel):";
|
||||||
|
$a->strings["Album name could not be decoded"] = "Albumnaam kon niet gedecodeerd worden";
|
||||||
|
$a->strings["Contact Photos"] = "Connectiefoto's";
|
||||||
|
$a->strings["Show Newest First"] = "Nieuwste eerst weergeven";
|
||||||
|
$a->strings["Show Oldest First"] = "Oudste eerst weergeven";
|
||||||
|
$a->strings["Permission denied. Access to this item may be restricted."] = "Toegang geweigerd. Toegang tot dit item kan zijn beperkt.";
|
||||||
|
$a->strings["Photo not available"] = "Foto niet aanwezig";
|
||||||
|
$a->strings["Use as profile photo"] = "Als profielfoto gebruiken";
|
||||||
|
$a->strings["Private Photo"] = "Privéfoto";
|
||||||
|
$a->strings["Previous"] = "Vorige";
|
||||||
|
$a->strings["View Full Size"] = "Volledige grootte weergeven";
|
||||||
|
$a->strings["Edit photo"] = "Foto bewerken";
|
||||||
|
$a->strings["Rotate CW (right)"] = "Draai met de klok mee (naar rechts)";
|
||||||
|
$a->strings["Rotate CCW (left)"] = "Draai tegen de klok in (naar links)";
|
||||||
|
$a->strings["Enter a new album name"] = "Vul een nieuwe albumnaam in";
|
||||||
|
$a->strings["or select an existing one (doubleclick)"] = "of kies een bestaand album (dubbelklikken)";
|
||||||
|
$a->strings["Caption"] = "Bijschrift";
|
||||||
|
$a->strings["Add a Tag"] = "Tag toevoegen";
|
||||||
|
$a->strings["Example: @bob, @Barbara_Jensen, @jim@example.com"] = "Voorbeeld: @bob, @Barbara_Jansen, @jan@voorbeeld.nl";
|
||||||
|
$a->strings["Flag as adult in album view"] = "Markeer als voor volwassenen in albumweergave";
|
||||||
|
$a->strings["In This Photo:"] = "Op deze foto:";
|
||||||
|
$a->strings["Map"] = "Kaart";
|
||||||
|
$a->strings["View Album"] = "Album weergeven";
|
||||||
|
$a->strings["Recent Photos"] = "Recente foto's";
|
||||||
$a->strings["Remote privacy information not available."] = "Privacy-informatie op afstand niet beschikbaar.";
|
$a->strings["Remote privacy information not available."] = "Privacy-informatie op afstand niet beschikbaar.";
|
||||||
$a->strings["Visible to:"] = "Zichtbaar voor:";
|
$a->strings["Visible to:"] = "Zichtbaar voor:";
|
||||||
$a->strings["Export Channel"] = "Kanaal exporteren";
|
$a->strings["Export Channel"] = "Kanaal exporteren";
|
||||||
@ -2082,7 +2082,6 @@ $a->strings["Delete Conversation"] = "Verwijder conversatie";
|
|||||||
$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Geen veilige communicatie beschikbaar. <strong>Mogelijk</strong> kan je reageren op de kanaalpagina van de afzender.";
|
$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "Geen veilige communicatie beschikbaar. <strong>Mogelijk</strong> kan je reageren op de kanaalpagina van de afzender.";
|
||||||
$a->strings["Send Reply"] = "Antwoord versturen";
|
$a->strings["Send Reply"] = "Antwoord versturen";
|
||||||
$a->strings["Your message for %s (%s):"] = "Jouw privébericht aan %s (%s):";
|
$a->strings["Your message for %s (%s):"] = "Jouw privébericht aan %s (%s):";
|
||||||
$a->strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "Authenticatie op afstand geblokkeerd. Je bent lokaal op deze hub ingelogd. Uitloggen en opnieuw proberen.";
|
|
||||||
$a->strings["No service class restrictions found."] = "Geen abonnementsbeperkingen gevonden.";
|
$a->strings["No service class restrictions found."] = "Geen abonnementsbeperkingen gevonden.";
|
||||||
$a->strings["Version %s"] = "Versie %s";
|
$a->strings["Version %s"] = "Versie %s";
|
||||||
$a->strings["Installed plugins/addons/apps:"] = "Ingeschakelde plug-ins/add-ons/apps:";
|
$a->strings["Installed plugins/addons/apps:"] = "Ingeschakelde plug-ins/add-ons/apps:";
|
||||||
@ -2213,3 +2212,4 @@ $a->strings["Website SSL certificate is not valid. Please correct."] = "Het SSL-
|
|||||||
$a->strings["[hubzilla] Website SSL error for %s"] = "[hubzilla] Probleem met SSL-certificaat voor %s";
|
$a->strings["[hubzilla] Website SSL error for %s"] = "[hubzilla] Probleem met SSL-certificaat voor %s";
|
||||||
$a->strings["Cron/Scheduled tasks not running."] = "Cron is niet actief";
|
$a->strings["Cron/Scheduled tasks not running."] = "Cron is niet actief";
|
||||||
$a->strings["[hubzilla] Cron tasks not running on %s"] = "[hubzilla] Cron-taken zijn niet actief op %s";
|
$a->strings["[hubzilla] Cron tasks not running on %s"] = "[hubzilla] Cron-taken zijn niet actief op %s";
|
||||||
|
$a->strings["Remote authentication blocked. You are logged into this site locally. Please logout and retry."] = "Authenticatie op afstand geblokkeerd. Je bent lokaal op deze hub ingelogd. Uitloggen en opnieuw proberen.";
|
||||||
|
@ -11,7 +11,7 @@ bezoeken en een nieuwe wachtwoord aanvragen. Je kan daarna inloggen, een kanaal
|
|||||||
meteen via 'instellingen > account' (linksboven) het account verwijderen (onderaan).
|
meteen via 'instellingen > account' (linksboven) het account verwijderen (onderaan).
|
||||||
Excuses voor het eventuele ongemak.
|
Excuses voor het eventuele ongemak.
|
||||||
|
|
||||||
Wanneer dit account wel door jou is aangemaakt: Dank je en welkom op de {{$sitename}}.
|
Wanneer dit account wel door jou is aangemaakt: Dank je en welkom op {{$sitename}}.
|
||||||
|
|
||||||
Vriendelijke groet,
|
Vriendelijke groet,
|
||||||
Beheerder {{$sitename}} ({{$siteurl}})
|
Beheerder {{$sitename}} ({{$siteurl}})
|
||||||
|
@ -249,11 +249,6 @@ footer {
|
|||||||
color: $font_colour;
|
color: $font_colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
#login-main {
|
|
||||||
max-width: 300px;
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cropimage-wrapper, #cropimage-preview-wrapper {
|
#cropimage-wrapper, #cropimage-preview-wrapper {
|
||||||
float: left;
|
float: left;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
|
@ -284,8 +284,12 @@ input {
|
|||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.home-welcome {
|
||||||
|
color: #FFF;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
#login-main {
|
#login-main {
|
||||||
max-width: 100%;
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +345,7 @@ input {
|
|||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary, input#event-submit, input#rmagic-submit-button, input#lostpass-submit-button, input#side-follow-submit, .profile-edit-submit-wrapper > input.profile-edit-submit-button, input#profile-photo-submit, form#chat-form > input, div#adminpage > form > div.submit > input, input.sources-submit, input.contact-edit-submit, input#dbtn-submit, input#newchannel-submit-button, input#contacts-search-submit {
|
.btn-primary, input#event-submit, input#rmagic-submit-button, input#lostpass-submit-button, input#side-follow-submit, .profile-edit-submit-wrapper > input.profile-edit-submit-button, input#profile-photo-submit, form#chat-form > input, div#adminpage > form > div.submit > input, input.sources-submit, input.contact-edit-submit, input#dbtn-submit, input#newchannel-submit-button, input#contacts-search-submit, input#register-submit-button {
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
color: #43488A;
|
color: #43488A;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
@ -350,7 +354,7 @@ input {
|
|||||||
transition: all .3s ease-in-out;
|
transition: all .3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary:hover, .btn-primary:focus, input#event-submit:hover, input#event-submit:focus, input#rmagic-submit-button:hover, input#rmagic-submit-button:focus, input#lostpass-submit-button:hover, input#lostpass-submit-button:focus, input#side-follow-submit:hover, input#side-follow-submit:focus, .profile-edit-submit-wrapper > input.profile-edit-submit-button:hover, .profile-edit-submit-wrapper > input.profile-edit-submit-button:focus, input#profile-photo-submit:hover, input#profile-photo-submit:focus, form#chat-form > input:hover, form#chat-form > input:focus, div#adminpage > form > div.submit > input:hover, div#adminpage > form > div.submit > input:focus, input.sources-submit:hover, input.sources-submit:focus, input.contact-edit-submit:focus, input.contact-edit-submit:hover, input#dbtn-submit:hover, input#dbtn-submit:focus, input#newchannel-submit-button:hover, input#newchannel-submit-button:focus, input#contacts-search-submit:hover, input#contacts-search-submit:focus {
|
.btn-primary:hover, .btn-primary:focus, input#event-submit:hover, input#event-submit:focus, input#rmagic-submit-button:hover, input#rmagic-submit-button:focus, input#lostpass-submit-button:hover, input#lostpass-submit-button:focus, input#side-follow-submit:hover, input#side-follow-submit:focus, .profile-edit-submit-wrapper > input.profile-edit-submit-button:hover, .profile-edit-submit-wrapper > input.profile-edit-submit-button:focus, input#profile-photo-submit:hover, input#profile-photo-submit:focus, form#chat-form > input:hover, form#chat-form > input:focus, div#adminpage > form > div.submit > input:hover, div#adminpage > form > div.submit > input:focus, input.sources-submit:hover, input.sources-submit:focus, input.contact-edit-submit:focus, input.contact-edit-submit:hover, input#dbtn-submit:hover, input#dbtn-submit:focus, input#newchannel-submit-button:hover, input#newchannel-submit-button:focus, input#contacts-search-submit:hover, input#contacts-search-submit:focus, input#register-submit-button:hover, input#register-submit-button:focus {
|
||||||
border-color: #FFF;
|
border-color: #FFF;
|
||||||
background-color: #43488A;
|
background-color: #43488A;
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
|
@ -114,8 +114,6 @@
|
|||||||
<li class="divider visible-xs"></li>
|
<li class="divider visible-xs"></li>
|
||||||
{{if $writefiles}}<li class="visible-xs"><a id="wall-file-upload-sub" href="#" ><i class="icon-paper-clip"></i> {{$attach}}</a></li>{{/if}}
|
{{if $writefiles}}<li class="visible-xs"><a id="wall-file-upload-sub" href="#" ><i class="icon-paper-clip"></i> {{$attach}}</a></li>{{/if}}
|
||||||
<li class="visible-xs"><a href="#" onclick="jotGetLink(); return false;"><i class="icon-link"></i> {{$weblink}}</a></li>
|
<li class="visible-xs"><a href="#" onclick="jotGetLink(); return false;"><i class="icon-link"></i> {{$weblink}}</a></li>
|
||||||
<!--li class="visible-xs"><a href="#" onclick="jotVideoURL(); return false;"><i class="icon-facetime-video"></i> {{$video}}</a></li-->
|
|
||||||
<!--li class="visible-xs"><a href="#" onclick="jotAudioURL(); return false;"><i class="icon-volume-up"></i> {{$audio}}</a></li-->
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<li class="divider visible-xs"></li>
|
<li class="divider visible-xs"></li>
|
||||||
<li class="visible-xs visible-sm"><a href="#" onclick="jotGetLocation(); return false;"><i class="icon-globe"></i> {{$setloc}}</a></li>
|
<li class="visible-xs visible-sm"><a href="#" onclick="jotGetLocation(); return false;"><i class="icon-globe"></i> {{$setloc}}</a></li>
|
||||||
|
1
zot
1
zot
@ -1 +0,0 @@
|
|||||||
Subproject commit d94e61a7b627381715751fb6cb6c0cecf7ece3f9
|
|
Reference in New Issue
Block a user