';
- else
- return $s[0];
-}
-
-
-function diaspora_ol($s) {
- // A hack: Diaspora will create a properly-numbered ordered list even
- // if you use '1.' for each element of the list, like:
- // 1. First element
- // 1. Second element
- // 1. Third element
- if( strpos($s[0], "[list=1]") === 0 )
- return '
';
- else
- return $s[0];
-}
-*/
-
-//////////////////////
-// Non-Markdownify versions of "diaspora_ol" and "diaspora_ul"
-//////////////////////
-/**
- * @brief
- *
- * Replace "[\\*]" followed by any number (including zero) of
- * spaces by "* " to match Diaspora's list format.
- *
- * @param string $s
- * @return string
- */
-function diaspora_ul($s) {
- return preg_replace("/\[\\\\\*\]( *)/", "* ", $s[1]);
-}
-
-/**
- * @brief
- *
- * A hack: Diaspora will create a properly-numbered ordered list even
- * if you use '1.' for each element of the list, like:
- * \code
- * 1. First element
- * 1. Second element
- * 1. Third element
- * \endcode
- * @param string $s
- * @return string
- */
-function diaspora_ol($s) {
- return preg_replace("/\[\\\\\*\]( *)/", "1. ", $s[1]);
-}
-
-function bb2dmention_callback($match) {
-
- $r = q("select xchan_addr from xchan where xchan_url = '%s'",
- dbesc($match[2])
- );
-
- if($r)
- return '@{' . $match[3] . ' ; ' . $r[0]['xchan_addr'] . '}';
-
- return '@' . $match[3];
-}
-
-
-function bb2diaspora_itemwallwall(&$item,$uplink = false) {
-
- // We will provide wallwall (embedded author on the Diaspora side) if
- // 1. It is a wall-to-wall post
- // 2. A comment arrived which has no Diaspora signature info
- // 3. The channel allows us to send unsigned activities
-
- $dcv = get_pconfig($item['uid'],'system','diaspora_send_unsigned');
- if(! $dcv)
- return;
-
- $wallwall = false;
- $author_exists = true;
-
- if(! array_key_exists('author',$item)) {
- $author_exists = false;
- logger('bb2diaspora_itemwallwall: no author');
- $r = q("select * from xchan where xchan_hash = '%s' limit 1",
- dbesc($item['author_xchan'])
- );
- if($r)
- $item['author'] = $r[0];
- }
-
- $has_meta = false;
- if($item['diaspora_meta'] || get_iconfig($item,'diaspora','fields'))
- $has_meta = true;
-
- if($item['author_xchan'] != $item['owner_xchan']) {
- if($item['mid'] == $item['parent_mid'])
- $wallwall = true;
- else {
- if(! $has_meta) {
- $wallwall = true;
- }
- }
- }
-
- if($uplink)
- $wallwall = true;
-
- if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url']
- && $item['author']['xchan_name'] && $item['author']['xchan_photo_s']) {
- logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG);
- // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
- $item['body'] = "\n\n"
- . '[quote]'
- . '[img]' . $item['author']['xchan_photo_s'] . '[/img]'
- . ' '
- . '[url=' . $item['author']['xchan_url'] . '][b]' . $item['author']['xchan_name'] . '[/b][/url]' . "\n\n"
- . $item['body']
- . '[/quote]';
- }
-
- // $item['author'] might cause a surprise further down the line if it wasn't expected to be here.
-
- if(! $author_exists)
- unset($item['author']);
-}
-
-
-function bb2diaspora_itembody($item, $force_update = false, $have_channel = false, $uplink = false) {
-
- if(! get_iconfig($item,'diaspora','fields')) {
- $force_update = true;
- }
-
- $matches = array();
-
- create_export_photo_body($item);
-
- $newitem = $item;
-
- if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
- $key = get_config('system','prvkey');
- $b = json_decode($item['body'],true);
- // if called from diaspora_process_outbound, this decoding has already been done.
- // Everything else that calls us will not yet be decoded.
- if($b && is_array($b) && array_key_exists('iv',$b)) {
- $newitem['title'] = (($item['title']) ? crypto_unencapsulate(json_decode($item['title'],true),$key) : '');
- $newitem['body'] = (($item['body']) ? crypto_unencapsulate(json_decode($item['body'],true),$key) : '');
- }
- }
-
- if(! $have_channel)
- bb2diaspora_itemwallwall($newitem,$uplink);
-
- $title = $newitem['title'];
- $body = preg_replace('/\#\^http/i', 'http', $newitem['body']);
-
- // protect tags and mentions from hijacking
-
- if(intval(get_pconfig($item['uid'],'system','prevent_tag_hijacking'))) {
- $new_tag = html_entity_decode('⋕',ENT_COMPAT,'UTF-8');
- $new_mention = html_entity_decode('@',ENT_COMPAT,'UTF-8');
-
- // #-tags
- $body = preg_replace('/\#\[url/i', $new_tag . '[url', $body);
- $body = preg_replace('/\#\[zrl/i', $new_tag . '[zrl', $body);
- // @-mentions
- $body = preg_replace('/\@\!?\[url/i', $new_mention . '[url', $body);
- $body = preg_replace('/\@\!?\[zrl/i', $new_mention . '[zrl', $body);
- }
-
- // remove multiple newlines
- do {
- $oldbody = $body;
- $body = str_replace("\n\n\n", "\n\n", $body);
- } while ($oldbody != $body);
-
- $body = bb2diaspora($body);
-
- if(strlen($title))
- $body = "## " . $title . "\n\n" . $body;
-
- if($item['attach']) {
- $cnt = preg_match_all('/href=\"(.*?)\"(.*?)title=\"(.*?)\"/ism', $item['attach'], $matches, PREG_SET_ORDER);
- if($cnt) {
- $body .= "\n" . t('Attachments:') . "\n";
- foreach($matches as $mtch) {
- $body .= '[' . $mtch[3] . '](' . $mtch[1] . ')' . "\n";
- }
- }
- }
-
-// logger('bb2diaspora_itembody : ' . $body, LOGGER_DATA);
-
- return html_entity_decode($body);
-}
-
-function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
-
- // Re-enabling the converter again.
- // The bbcode parser now handles youtube-links (and the other stuff) correctly.
- // Additionally the html code is now fixed so that lists are now working.
-
- /*
- * Transform #tags, strip off the [url] and replace spaces with underscore
- */
- $Text = preg_replace_callback('/#\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/[(zu)]rl\]/i', create_function('$match',
- 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'
- ), $Text);
-
- $Text = preg_replace('/#\^\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text);
-
- $Text = preg_replace_callback('/\@\!?\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', 'bb2dmention_callback', $Text);
-
- // strip map tags, as the rendering is performed in bbcode() and the resulting output
- // is not compatible with Diaspora (at least in the case of openstreetmap and probably
- // due to the inclusion of an html iframe)
-
- $Text = preg_replace("/\[map\=(.*?)\]/ism", '$1', $Text);
- $Text = preg_replace("/\[map\](.*?)\[\/map\]/ism", '$1', $Text);
-
- // Converting images with size parameters to simple images. Markdown doesn't know it.
- $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
-
- // the following was added on 10-January-2012 due to an inability of Diaspora's
- // new javascript markdown processor to handle links with images as the link "text"
- // It is not optimal and may be removed if this ability is restored in the future
- //if ($fordiaspora)
- // $Text = preg_replace("/\[url\=([^\[\]]*)\]\s*\[img\](.*?)\[\/img\]\s*\[\/url\]/ism",
- // "[url]$1[/url]\n[img]$2[/img]", $Text);
-
- // Convert it to HTML - don't try oembed
- $Text = bbcode($Text, $preserve_nl, false);
-
- // Markdownify does not preserve previously escaped html entities such as <> and &.
-
- $Text = str_replace(array('<','>','&'),array('&_lt_;','&_gt_;','&_amp_;'),$Text);
-
- // Now convert HTML to Markdown
- $md = new Converter(Converter::LINK_AFTER_CONTENT, false, false);
- $Text = $md->parseString($Text);
-
-
- // It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason.
-
- $Text = str_replace(array('&\\_lt\\_;','&\\_gt\\_;','&\\_amp\\_;'),array('<','>','&'),$Text);
-
- // If the text going into bbcode() has a plain URL in it, i.e.
- // with no [url] tags around it, it will come out of parseString()
- // looking like: , which gets removed by strip_tags().
- // So take off the angle brackets of any such URL
- $Text = preg_replace("//is", "http$1", $Text);
-
- // Remove empty zrl links
- $Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
-
- // Remove all unconverted tags
- $Text = strip_tags($Text);
-
- // Remove any leading or trailing whitespace, as this will mess up
- // the Diaspora signature verification and cause the item to disappear
-
- $Text = trim($Text);
-
- call_hooks('bb2diaspora', $Text);
-
- return $Text;
-}
-
-function unescape_underscores_in_links($m) {
- $y = str_replace('\\_','_', $m[2]);
- return('[' . $m[1] . '](' . $y . ')');
-}
-
-function format_event_diaspora($ev) {
-
- if(! ((is_array($ev)) && count($ev)))
- return '';
-
- $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM
-
- $o = t('$Projectname event notification:') . "\n";
-
- $o .= '**' . (($ev['summary']) ? bb2diaspora($ev['summary']) : bb2diaspora($ev['desc'])) . '**' . "\n";
-
- $o .= t('Starts:') . ' ' . '['
- . (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
- $ev['start'] , $bd_format ))
- : day_translate(datetime_convert('UTC', 'UTC',
- $ev['start'] , $bd_format)))
- . '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
-
- if(! $ev['nofinish'])
- $o .= t('Finishes:') . ' ' . '['
- . (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
- $ev['finish'] , $bd_format ))
- : day_translate(datetime_convert('UTC', 'UTC',
- $ev['finish'] , $bd_format )))
- . '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
-
- if(strlen($ev['location']))
- $o .= t('Location:') . bb2diaspora($ev['location'])
- . "\n";
-
- $o .= "\n";
-
- return $o;
-}
--
cgit v1.2.3
From b6477cd38b532ebe69a480460e7b883964ec6627 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Thu, 9 Mar 2017 11:51:21 -0800
Subject: go back to where the problem started
---
include/items.php | 70 +------
include/network.php | 543 ++--------------------------------------------------
2 files changed, 13 insertions(+), 600 deletions(-)
diff --git a/include/items.php b/include/items.php
index 6d21953a9..8032f53c4 100755
--- a/include/items.php
+++ b/include/items.php
@@ -600,11 +600,6 @@ function get_item_elements($x,$allow_code = false) {
$arr['sig'] = (($x['signature']) ? htmlspecialchars($x['signature'], ENT_COMPAT,'UTF-8',false) : '');
- if(array_key_exists('diaspora_signature',$x) && is_array($x['diaspora_signature']))
- $x['diaspora_signature'] = json_encode($x['diaspora_signature']);
-
- $arr['diaspora_meta'] = (($x['diaspora_signature']) ? $x['diaspora_signature'] : '');
-
$arr['obj'] = activity_sanitise($x['object']);
$arr['target'] = activity_sanitise($x['target']);
@@ -1035,17 +1030,7 @@ function encode_item($item,$mirror = false) {
if($item['iconfig'])
$x['meta'] = encode_item_meta($item['iconfig'],$mirror);
- if($item['diaspora_meta']) {
- $z = json_decode($item['diaspora_meta'],true);
- if($z) {
- if(is_array($z) && array_key_exists('iv',$z))
- $x['diaspora_signature'] = crypto_unencapsulate($z,$key);
- else
- $x['diaspora_signature'] = $z;
- if(! is_array($z))
- logger('encode_item: diaspora meta is not an array: ' . print_r($z,true));
- }
- }
+
logger('encode_item: ' . print_r($x,true), LOGGER_DATA);
return $x;
@@ -1324,7 +1309,6 @@ function encode_mail($item,$extended = false) {
$x['message_parent'] = $item['parent_mid'];
$x['created'] = $item['created'];
$x['expires'] = $item['expires'];
- $x['diaspora_meta'] = $item['diaspora_meta'];
$x['title'] = $item['title'];
$x['body'] = $item['body'];
$x['from'] = encode_item_xchan($item['from']);
@@ -1517,7 +1501,6 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : '');
$arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : '');
- $arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : '');
$arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : '');
$arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : '');
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : '');
@@ -2027,7 +2010,7 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
$arr['changed'] = $orig[0]['changed'];
$arr['route'] = ((array_key_exists('route',$arr)) ? trim($arr['route']) : $orig[0]['route']);
- $arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : $orig[0]['diaspora_meta']);
+
$arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : $orig[0]['location']);
$arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']);
$arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']);
@@ -2186,55 +2169,6 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
-function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id, $walltowall = false) {
-
- // We won't be able to sign Diaspora comments for authenticated visitors
- // - we don't have their private key
-
- // since Diaspora doesn't handle edits we can only do this for the original text and not update it.
-
- require_once('include/markdown.php');
- $signed_body = bb2diaspora_itembody($datarray,$walltowall);
-
- if($walltowall) {
- logger('wall to wall comment',LOGGER_DEBUG);
- // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
- $signed_body = "\n\n"
- . '![' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_photo_m'] . ')'
- . '[' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_url'] . ')' . "\n\n"
- . $signed_body;
- }
-
- logger('storing diaspora comment signature',LOGGER_DEBUG);
-
- $diaspora_handle = channel_reddress($channel);
-
- $signed_text = $datarray['mid'] . ';' . $parent_item['mid'] . ';' . $signed_body . ';' . $diaspora_handle;
-
-
- if( $channel && $channel['channel_prvkey'] )
- $authorsig = base64_encode(rsa_sign($signed_text, $channel['channel_prvkey'], 'sha256'));
- else
- $authorsig = '';
-
- $x = array('signer' => $diaspora_handle, 'body' => $signed_body, 'signed_text' => $signed_text, 'signature' => $authorsig);
-
- $y = json_encode($x);
-
- $r = q("update item set diaspora_meta = '%s' where id = %d",
- dbesc($y),
- intval($post_id)
- );
-
-
- if(! $r)
- logger('store_diaspora_comment_sig: DB write failed');
-
- return;
-}
-
-
-
function send_status_notifications($post_id,$item) {
// only send notifications for comments
diff --git a/include/network.php b/include/network.php
index 6d1a05e9f..4d0bc6f0b 100644
--- a/include/network.php
+++ b/include/network.php
@@ -984,40 +984,6 @@ function email_header_encode($in_str, $charset = 'UTF-8') {
return $out_str;
}
-function email_send($addr, $subject, $headers, $item) {
- //$headers .= 'MIME-Version: 1.0' . "\n";
- //$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
- //$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
- //$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
-
- $part = uniqid("", true);
-
- $html = prepare_body($item);
-
- $headers .= "Mime-Version: 1.0\n";
- $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n";
-
- $body = "\n--=_".$part."\n";
- $body .= "Content-Transfer-Encoding: 8bit\n";
- $body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n";
-
- $body .= html2plain($html)."\n";
-
- $body .= "--=_".$part."\n";
- $body .= "Content-Transfer-Encoding: 8bit\n";
- $body .= "Content-Type: text/html; charset=utf-8\n\n";
-
- $body .= ''.$html."\n";
-
- $body .= "--=_".$part."--";
-
- //$message = '' . $html . '';
- //$message = html2plain($html);
- logger('notifier: email delivery to ' . $addr);
- mail($addr, $subject, $body, $headers);
-}
-
-
function discover_by_url($url,$arr = null) {
require_once('library/HTML5/Parser.php');
@@ -1027,10 +993,10 @@ function discover_by_url($url,$arr = null) {
if(! $arr)
return false;
$network = (($arr['network']) ? $arr['network'] : 'unknown');
- $name = (($arr['name']) ? $arr['name'] : 'unknown');
- $photo = (($arr['photo']) ? $arr['photo'] : '');
- $addr = (($arr['addr']) ? $arr['addr'] : '');
- $guid = $url;
+ $name = (($arr['name']) ? $arr['name'] : 'unknown');
+ $photo = (($arr['photo']) ? $arr['photo'] : '');
+ $addr = (($arr['addr']) ? $arr['addr'] : '');
+ $guid = $url;
}
$profile = $url;
@@ -1067,8 +1033,8 @@ function discover_by_url($url,$arr = null) {
if($feed->error())
logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error());
- $name = unxmlify(trim($feed->get_title()));
- $photo = $feed->get_image_url();
+ $name = unxmlify(trim($feed->get_title()));
+ $photo = $feed->get_image_url();
$author = $feed->get_author();
if($author) {
@@ -1172,23 +1138,11 @@ function discover_by_url($url,$arr = null) {
function discover_by_webbie($webbie) {
- require_once('library/HTML5/Parser.php');
- $result = array();
+ $result = [];
$network = null;
- $diaspora = false;
- $gnusoc = false;
- $dfrn = false;
-
- $has_salmon = false;
- $salmon_key = false;
- $atom_feed = false;
- $diaspora_base = '';
- $diaspora_guid = '';
- $diaspora_key = '';
-
$webbie = strtolower($webbie);
$x = webfinger_rfc7033($webbie,true);
@@ -1214,21 +1168,6 @@ function discover_by_webbie($webbie) {
}
}
}
- if($link['rel'] == NAMESPACE_DFRN) {
- $dfrn = $link['href'];
- }
- if($link['rel'] == 'magic-public-key') {
- if(substr($link['href'],0,5) === 'data:') {
- $salmon_key = convert_salmon_key($link['href']);
- }
- }
- if($link['rel'] == 'salmon') {
- $has_salmon = true;
- $salmon = $link['href'];
- }
- if($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
- $atom_feed = $link['href'];
- }
}
}
}
@@ -1240,287 +1179,9 @@ function discover_by_webbie($webbie) {
if($arr['success'])
return true;
- $aliases = array();
-
- // Now let's make some decisions on what we may need
- // to obtain further info
-
- $probe_atom = false;
- $probe_old = false;
- $probe_hcard = false;
-
- $address = '';
- $location = '';
- $nickname = '';
- $fullname = '';
- $avatar = '';
- $pubkey = '';
-
- if(is_array($x)) {
- if(array_key_exists('address',$x))
- $address = $x['address'];
- if(array_key_exists('location',$x))
- $location = $x['location'];
- if(array_key_exists('nickname',$x))
- $nickname = $x['nickname'];
- }
-
- if(! $x)
- $probe_old = true;
-
-
- if((! $dfrn) && (! $has_salmon))
- $probe_old = true;
-
- if($probe_old) {
- $y = old_webfinger($webbie);
- if($y) {
- logger('old_webfinger: ' . print_r($x,true));
- foreach($y as $link) {
- if($link['@attributes']['rel'] === NAMESPACE_DFRN)
- $dfrn = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'salmon')
- $notify = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === NAMESPACE_FEED)
- $poll = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
- $hcard = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
- $profile = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0')
- $poco = unamp($link['@attributes']['href']);
- if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
- $diaspora_base = unamp($link['@attributes']['href']);
- $diaspora = true;
- }
- if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
- $diaspora_guid = unamp($link['@attributes']['href']);
- $diaspora = true;
- }
- if($link['@attributes']['rel'] === 'diaspora-public-key') {
- $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
- if(strstr($diaspora_key,'RSA '))
- $pubkey = rsatopem($diaspora_key);
- else
- $pubkey = $diaspora_key;
- $diaspora = true;
- }
- if($link['@attributes']['rel'] == 'magic-public-key') {
- if(substr($link['@attributes']['href'],0,5) === 'data:') {
- $salmon_key = convert_salmon_key($link['@attributes']['href']);
- }
- }
- if($link['@attributes']['rel'] == 'salmon') {
- $has_salmon = true;
- $salmon = $link['@attributes']['href'];
- }
-
- if($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
- $atom_feed = $link['@attributes']['href'];
- }
- if($link['@attributes']['rel'] === 'alias') {
- $aliases[] = $link['@attributes']['href'];
- }
- if($link['@attributes']['rel'] === 'subject') {
- $subject = $link['@attributes']['href'];
- }
- }
- }
- }
-
- if($subject || $aliases) {
- if(strpos($webbie,'@')) {
- $rhs = substr($webbie,strpos($webbie,'@')+1);
- }
- else {
- $m = parse_url($webbie);
- if($m) {
- $rhs = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
- }
- }
-
- $v = array('subject' => $subject,'aliases' => $aliases);
- $address = find_webfinger_address($v,$rhs);
- $location = find_webfinger_location($v,$rhs);
- if($address)
- $nickname = substr($address,0,strpos($address,'@'));
-
- }
-
- if($salmon_key && $has_salmon && $atom_feed && (! $dfrn) && (! $diaspora)) {
- $gnusoc = true;
- $probe_atom = true;
- }
-
- if(! $pubkey)
- $pubkey = $salmon_key;
-
- if(($dfrn || $diaspora) && $hcard)
- $probe_hcard = true;
-
- if(! $fullname)
- $fullname = $nickname;
-
- if($probe_atom) {
- $k = z_fetch_url($atom_feed);
- if($k['success'])
- $feed_meta = feed_meta($k['body']);
- if($feed_meta) {
-
- // stash any discovered pubsubhubbub hubs in case we need to follow them
- // this will save an expensive lookup later
-
- if($feed_meta['hubs'] && $address) {
- set_xconfig($address,'system','push_hubs',$feed_meta['hubs']);
- set_xconfig($address,'system','feed_url',$atom_feed);
- }
- if($feed_meta['author']['author_name']) {
- $fullname = $feed_meta['author']['author_name'];
- }
- if(! $avatar) {
- if($feed_meta['author']['author_photo'])
- $avatar = $feed_meta['author']['author_photo'];
- }
-
- // for GNU-social over-ride any url aliases we may have picked up in webfinger
- // The author.uri element in the feed is likely to be more accurate
-
- if($gnusoc && $feed_meta['author']['author_uri'])
- $location = $feed_meta['author']['author_uri'];
- }
- }
- else {
- if($probe_hcard) {
- $vcard = scrape_vcard($hcard);
- if($vcard) {
- logger('vcard: ' . print_r($vcard,true), LOGGER_DATA);
- if($vcard['fn'])
- $fullname = $vcard['fn'];
- if($vcard['photo'] && (strpos($vcard['photo'],'http') !== 0))
- $vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
- if(($vcard['public_key']) && (! $pubkey)) {
- $diaspora_key = $vcard['public_key'];
- if(strstr($diaspora_key,'RSA '))
- $pubkey = rsatopem($diaspora_key);
- else
- $pubkey = $diaspora_key;
- }
- if(! $avatar)
- $avatar = $vcard['photo'];
- if($diaspora) {
- if(($vcard['uid']) && (! $diaspora_guid))
- $diaspora_guid = $vcard['uid'];
- if(($vcard['url']) && (! $diaspora_base))
- $diaspora_base = $vcard['url'];
-
-
-
-
- }
-
- }
- }
- }
-
- if(($profile) && (! $location))
- $location = $profile;
-
- if($location) {
- $m = parse_url($location);
- $base = $m['scheme'] . '://' . $m['host'];
- $host = $m['host'];
- }
-
-
- if($diaspora && $diaspora_base && $diaspora_guid) {
- if($dfrn)
- $network = 'friendica-over-diaspora';
- else
- $network = 'diaspora';
-
- $base = trim($diaspora_base,'/');
- $notify = $base . '/receive';
-
- }
- else {
- if($gnusoc) {
- $network = 'gnusoc';
- $notify = $salmon;
- }
- }
-
-
- logger('network: ' . $network);
- logger('address: ' . $address);
- logger('fullname: ' . $fullname);
- logger('pubkey: ' . $pubkey);
- logger('location: ' . $location);
-
-
-
- // if we have everything we need, let's create the records
-
- if($network && $address && $fullname && $pubkey && $location) {
- $r = q("select * from xchan where xchan_hash = '%s' limit 1",
- dbesc($address)
- );
- if($r) {
- $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
- dbesc($fullname),
- dbesc($network),
- dbesc(datetime_convert()),
- dbesc($address)
- );
- }
- else {
- $r = xchan_store_lowlevel(
- [
- 'xchan_hash' => $address,
- 'xchan_guid' => (($diaspora_guid) ? $diaspora_guid : $location),
- 'xchan_pubkey' => $pubkey,
- 'xchan_addr' => $address,
- 'xchan_url' => $location,
- 'xchan_name' => $fullname,
- 'xchan_name_date' => datetime_convert(),
- 'xchan_network' => $network
- ]
- );
- }
-
- $r = q("select * from hubloc where hubloc_hash = '%s' limit 1",
- dbesc($address)
- );
-
- if(! $r) {
- $r = hubloc_store_lowlevel(
- [
- 'hubloc_guid' => (($diaspora_guid) ? $diaspora_guid : $location),
- 'hubloc_hash' => $address,
- 'hubloc_addr' => $address,
- 'hubloc_network' => $network,
- 'hubloc_url' => $base,
- 'hubloc_host' => $host,
- 'hubloc_callback' => $notify,
- 'hubloc_updated' => datetime_convert(),
- 'hubloc_primary' => 1
- ]
- );
- }
- $photos = import_xchan_photo($avatar,$address);
- $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
- dbescdate(datetime_convert()),
- dbesc($photos[0]),
- dbesc($photos[1]),
- dbesc($photos[2]),
- dbesc($photos[3]),
- dbesc($address)
- );
- return true;
- }
return false;
-}
-
+}
function webfinger_rfc7033($webbie,$zot = false) {
@@ -1547,88 +1208,13 @@ function webfinger_rfc7033($webbie,$zot = false) {
if($s['success']) {
$j = json_decode($s['body'],true);
-
- // We could have a number of URL aliases and webbies
- // make an executive decision about the most likely "best" of each
- // by comparing against some examples from known networks we're likely to encounter.
- // Otherwise we have to store every alias that we may ever encounter and
- // validate every URL we ever find against every possible alias
-
- // @fixme pump.io is going to be a real bugger since it doesn't return subject or aliases
- // or provide lookup by url
-
- $j['address'] = find_webfinger_address($j,$rhs);
- $j['location'] = find_webfinger_location($j,$rhs);
- if($j['address'])
- $j['nickname'] = substr($j['address'],0,strpos($j['address'],'@'));
- }
- else
- return false;
-
- return($j);
-}
-
-function find_webfinger_address($j,$rhs) {
- if(is_array($j) && ($j)) {
- if(strpos($j['subject'],'acct:') !== false && strpos($j['subject'],'@' . $rhs))
- return str_replace('acct:','',$j['subject']);
- if($j['aliases']) {
- foreach($j['aliases'] as $alias) {
- if(strpos($alias,'acct:') !== false && strpos($alias,'@' . $rhs)) {
- return str_replace('acct:','',$alias);
- }
- }
- }
- }
- return '';
-}
-
-
-function find_webfinger_location($j,$rhs) {
- if(is_array($j) && ($j)) {
- if(strpos($j['subject'],'http') === 0) {
- $x = match_webfinger_location($j['subject'],$rhs);
- if($x)
- return $x;
- }
- if($j['aliases']) {
- foreach($j['aliases'] as $alias) {
- if(strpos($alias,'http') === 0) {
- $x = match_webfinger_location($alias,$rhs);
- if($x)
- return($x);
- }
- }
- }
+ return($j);
}
- return '';
-}
-
-function match_webfinger_location($s,$h) {
- // GNU-social and the older StatusNet - the $host/user/123 form doesn't work
- if(preg_match('|' . $h . '/index.php/user/([0-9]*?)$|',$s))
- return $s;
- // Redmatrix / hubzilla
- if(preg_match('|' . $h . '/channel/|',$s))
- return $s;
- // Friendica
- if(preg_match('|' . $h . '/profile/|',$s))
- return $s;
+ return false;
- $arr = array('test' => $s, 'host' => $h, 'success' => false);
- call_hooks('match_webfinger_location',$arr);
- if($arr['success'])
- return $s;
- return '';
}
-
-
-
-
-
-
function old_webfinger($webbie) {
$host = '';
@@ -1696,9 +1282,6 @@ function fetch_xrd_links($url) {
if ((! $xml) || (! stristr($xml,''),array('href="','"/>'),$xml);
-
$h = parse_xml_string($xml);
if(! $h)
return array();
@@ -1738,85 +1321,6 @@ function fetch_xrd_links($url) {
}
-function scrape_vcard($url) {
-
- $ret = array();
-
- logger('scrape_vcard: url=' . $url);
-
- $x = z_fetch_url($url);
- if(! $x['success'])
- return $ret;
-
- $s = $x['body'];
-
- if(! $s)
- return $ret;
-
- $headers = $x['header'];
- $lines = explode("\n",$headers);
- if(count($lines)) {
- foreach($lines as $line) {
- // don't try and run feeds through the html5 parser
- if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
- return ret;
- }
- }
-
- try {
- $dom = HTML5_Parser::parse($s);
- } catch (DOMException $e) {
- logger('scrape_vcard: parse error: ' . $e);
- }
-
- if(! $dom)
- return $ret;
-
- // Pull out hCard profile elements
-
- $largest_photo = 0;
-
- $items = $dom->getElementsByTagName('*');
- foreach($items as $item) {
- if(attribute_contains($item->getAttribute('class'), 'vcard')) {
- $level2 = $item->getElementsByTagName('*');
- foreach($level2 as $x) {
- if(attribute_contains($x->getAttribute('id'),'pod_location'))
- $ret['pod_location'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'fn'))
- $ret['fn'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'uid'))
- $ret['uid'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'nickname'))
- $ret['nick'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'searchable'))
- $ret['searchable'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'key'))
- $ret['public_key'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'given_name'))
- $ret['given_name'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'family_name'))
- $ret['family_name'] = $x->textContent;
- if(attribute_contains($x->getAttribute('class'),'url'))
- $ret['url'] = $x->textContent;
-
- if((attribute_contains($x->getAttribute('class'),'photo'))
- || (attribute_contains($x->getAttribute('class'),'avatar'))) {
- $size = intval($x->getAttribute('width'));
- if(($size > $largest_photo) || (! $largest_photo)) {
- $ret['photo'] = $x->getAttribute('src');
- $largest_photo = $size;
- }
- }
- }
- }
- }
-
- return $ret;
-}
-
-
-
function scrape_feed($url) {
$ret = array();
@@ -1910,31 +1414,6 @@ function scrape_feed($url) {
}
-
-function service_plink($contact, $guid) {
-
- $plink = '';
-
- $m = parse_url($contact['xchan_url']);
- if($m) {
- $url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
- }
- else
- $url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1);
-
- $handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@'));
-
- if($contact['xchan_network'] === 'diaspora')
- $plink = $url . '/posts/' . $guid;
- if($contact['xchan_network'] === 'friendica-over-diaspora')
- $plink = $url . '/display/' . $handle . '/' . $guid;
- if($contact['xchan_network'] === 'zot')
- $plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid;
-
- return $plink;
-}
-
-
function format_and_send_email($sender,$xchan,$item) {
$title = $item['title'];
@@ -1944,7 +1423,7 @@ function format_and_send_email($sender,$xchan,$item) {
$htmlversion = bbcode(str_replace(array("\\r","\\n"), array(""," \n"),$body));
- $banner = t('$Projectname Notification');
+ $banner = t('$Projectname Notification');
$product = t('$projectname'); // PLATFORM_NAME;
$siteurl = z_root();
$thanks = t('Thank You,');
--
cgit v1.2.3
From c93db2cd218d5a1e8ff6e5b243b99e7fcbae36ea Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Thu, 9 Mar 2017 14:31:54 -0800
Subject: more cleanup
---
boot.php | 4 ++--
include/items.php | 35 +----------------------------------
include/text.php | 6 ++----
3 files changed, 5 insertions(+), 40 deletions(-)
diff --git a/boot.php b/boot.php
index 36e08c77a..751bee9ec 100755
--- a/boot.php
+++ b/boot.php
@@ -635,11 +635,11 @@ function sys_boot() {
if(! defined('DEFAULT_PLATFORM_ICON')) {
- define( 'DEFAULT_PLATFORM_ICON', '/images/hz-32.png' );
+ define( 'DEFAULT_PLATFORM_ICON', '/images/rm-32.png' );
}
if(! defined('DEFAULT_NOTIFY_ICON')) {
- define( 'DEFAULT_NOTIFY_ICON', '/images/hz-white-32.png' );
+ define( 'DEFAULT_NOTIFY_ICON', '/images/rm-32.png' );
}
if(! defined('CRYPTO_ALGORITHM')) {
diff --git a/include/items.php b/include/items.php
index 033863c42..58305aa63 100755
--- a/include/items.php
+++ b/include/items.php
@@ -248,8 +248,6 @@ function can_comment_on_post($observer_xchan, $item) {
}
if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red'))
return true;
- if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'diaspora'))
- return true;
if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname()))
return true;
@@ -766,8 +764,6 @@ function import_author_xchan($x) {
if((! array_key_exists('network', $x)) || ($x['network'] === 'zot')) {
$y = import_author_zot($x);
}
- if(! $y)
- $y = import_author_diaspora($x);
if($x['network'] === 'rss') {
$y = import_author_rss($x);
@@ -780,36 +776,6 @@ function import_author_xchan($x) {
return(($y) ? $y : false);
}
-/**
- * @brief Imports an author from Diaspora.
- *
- * @param array $x an associative array with
- * * \e string \b address
- * @return boolean|string false on error, otherwise xchan_hash of the new entry
- */
-function import_author_diaspora($x) {
- if(! $x['address'])
- return false;
-
- $r = q("select * from xchan where xchan_addr = '%s' limit 1",
- dbesc($x['address'])
- );
- if($r) {
- logger('in_cache: ' . $x['address'], LOGGER_DATA);
- return $r[0]['xchan_hash'];
- }
-
- if(discover_by_webbie($x['address'])) {
- $r = q("select xchan_hash from xchan where xchan_addr = '%s' limit 1",
- dbesc($x['address'])
- );
- if($r)
- return $r[0]['xchan_hash'];
- }
-
- return false;
-}
-
/**
* @brief Imports an author from a RSS feed.
*
@@ -819,6 +785,7 @@ function import_author_diaspora($x) {
* * \e string \b guid
* @return boolean|string
*/
+
function import_author_rss($x) {
if(! $x['url'])
return false;
diff --git a/include/text.php b/include/text.php
index 9d76f9d78..fe3206b32 100644
--- a/include/text.php
+++ b/include/text.php
@@ -1183,8 +1183,7 @@ function list_smilies() {
':coffee',
':facepalm',
':like',
- ':dislike',
- ':hubzilla'
+ ':dislike'
);
$icons = array(
@@ -1219,8 +1218,7 @@ function list_smilies() {
'',
'',
'',
- '',
- '',
+ ''
);
--
cgit v1.2.3
From 1a49f0d164ce94bc3fce227a68aa3796e22347e1 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Thu, 9 Mar 2017 18:54:10 -0800
Subject: one role.
---
Zotlabs/Lib/System.php | 11 +++-------
Zotlabs/Module/Setup.php | 7 -------
boot.php | 47 ++-----------------------------------------
view/tpl/install_settings.tpl | 1 -
4 files changed, 5 insertions(+), 61 deletions(-)
diff --git a/Zotlabs/Lib/System.php b/Zotlabs/Lib/System.php
index 306c90f4a..865cb9a30 100644
--- a/Zotlabs/Lib/System.php
+++ b/Zotlabs/Lib/System.php
@@ -57,9 +57,7 @@ class System {
static public function get_server_role() {
- if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role'])
- return \App::$config['system']['server_role'];
- return 'standard';
+ return 'pro';
}
static public function get_std_version() {
@@ -72,11 +70,8 @@ class System {
if(get_directory_realm() != DIRECTORY_REALM)
return true;
-
- foreach(['hubzilla','zap'] as $t) {
- if(stristr($p,$t))
- return true;
- }
+ if(in_array(strtolower($p),['hubzilla','zap','red']))
+ return true;
return false;
}
}
diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php
index 9c688af01..e114dfc0b 100644
--- a/Zotlabs/Module/Setup.php
+++ b/Zotlabs/Module/Setup.php
@@ -324,11 +324,6 @@ class Setup extends \Zotlabs\Web\Controller {
$siteurl = trim($_POST['siteurl']);
$timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles');
- $server_roles = [
- 'basic' => t('Basic/Minimal Social Networking'),
- 'standard' => t('Standard Configuration (default)'),
- 'pro' => t('Professional')
- ];
$tpl = get_markup_template('install_settings.tpl');
$o .= replace_macros($tpl, array(
@@ -348,8 +343,6 @@ class Setup extends \Zotlabs\Web\Controller {
'$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')),
- '$server_role' => array('server_role', t("Server Configuration/Role"), 'standard','',$server_roles),
-
'$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()),
'$baseurl' => z_root(),
diff --git a/boot.php b/boot.php
index 751bee9ec..16d60f61e 100755
--- a/boot.php
+++ b/boot.php
@@ -49,7 +49,7 @@ require_once('include/xchan.php');
require_once('include/hubloc.php');
-define ( 'PLATFORM_NAME', 'hubzilla' );
+define ( 'PLATFORM_NAME', 'red' );
define ( 'STD_VERSION', '2.3' );
define ( 'ZOT_REVISION', '1.2' );
@@ -165,14 +165,6 @@ define ( 'LOGGER_DATA', 3 );
define ( 'LOGGER_ALL', 4 );
-/**
- * Server roles
- */
-
-define ( 'SERVER_ROLE_BASIC', 0x0001 );
-define ( 'SERVER_ROLE_STANDARD', 0x0002 );
-define ( 'SERVER_ROLE_PRO', 0x0004 );
-
/**
* registration policies
*/
@@ -620,15 +612,7 @@ function sys_boot() {
$a->convert();
- if(defined('UNO')) {
- if(UNO)
- App::$config['system']['server_role'] = 'basic';
- else
- App::$config['system']['server_role'] = 'standard';
- }
-
- if(! (array_key_exists('server_role',App::$config['system']) && App::$config['system']['server_role']))
- App::$config['system']['server_role'] = 'standard';
+ App::$config['system']['server_role'] = 'pro';
App::$timezone = ((App::$config['system']['timezone']) ? App::$config['system']['timezone'] : 'UTC');
date_default_timezone_set(App::$timezone);
@@ -755,7 +739,6 @@ class miniApp {
class App {
public static $install = false; // true if we are installing the software
- public static $role = 0; // server role (constant, not the string)
public static $account = null; // account record of the logged-in account
public static $channel = null; // channel record of the current channel of the logged-in account
public static $observer = null; // xchan record of the page observer
@@ -1030,36 +1013,10 @@ class App {
}
}
- public static function get_role() {
- if(! self::$role)
- return self::set_role();
- return self::$role;
- }
-
- public static function set_role() {
- $role_str = \Zotlabs\Lib\System::get_server_role();
- switch($role_str) {
- case 'basic':
- $role = SERVER_ROLE_BASIC;
- break;
- case 'pro':
- $role = SERVER_ROLE_PRO;
- break;
- case 'standard':
- default:
- $role = SERVER_ROLE_STANDARD;
- break;
- }
- self::$role = $role;
- return $role;
- }
-
-
public static function get_scheme() {
return self::$scheme;
}
-
public static function get_hostname() {
return self::$hostname;
}
diff --git a/view/tpl/install_settings.tpl b/view/tpl/install_settings.tpl
index f7a0108a8..62dcbb8b3 100755
--- a/view/tpl/install_settings.tpl
+++ b/view/tpl/install_settings.tpl
@@ -19,7 +19,6 @@
{{include file="field_input.tpl" field=$adminmail}}
{{include file="field_input.tpl" field=$siteurl}}
-{{include file="field_select.tpl" field=$server_role}}
{{include file="field_select_grouped.tpl" field=$timezone}}
--
cgit v1.2.3
From bbb83bea38c626aa59f28e3ed29e39488f2e9289 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Fri, 10 Mar 2017 12:44:57 -0800
Subject: strings
---
util/hmessages.po | 13246 ++++++++++++++++++++++++++--------------------------
1 file changed, 6616 insertions(+), 6630 deletions(-)
diff --git a/util/hmessages.po b/util/hmessages.po
index 135087b9e..796a53de2 100644
--- a/util/hmessages.po
+++ b/util/hmessages.po
@@ -1,6 +1,6 @@
-# hubzilla
-# Copyright (C) 2012-2016 hubzilla
-# This file is distributed under the same license as the hubzilla package.
+# red
+# Copyright (C) 2012-2016 red
+# This file is distributed under the same license as the red package.
# Mike Macgirvin, 2012
#
#, fuzzy
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-03-03 00:05-0800\n"
+"POT-Creation-Date: 2017-03-10 00:05-0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -88,16 +88,17 @@ msgid "Special - Group Repository"
msgstr ""
#: ../../Zotlabs/Access/PermissionRoles.php:270
-#: ../../Zotlabs/Module/Register.php:213 ../../Zotlabs/Module/Connedit.php:925
+#: ../../Zotlabs/Module/Register.php:213 ../../Zotlabs/Module/Profiles.php:798
+#: ../../Zotlabs/Module/Connedit.php:925
#: ../../Zotlabs/Module/New_channel.php:132
-#: ../../Zotlabs/Module/Profiles.php:798
#: ../../Zotlabs/Module/Settings/Channel.php:463
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1148
#: ../../extend/addon/addon/cdav/cdav.php:277
-#: ../../extend/addon/addon/cdav/cdav.php:284 ../../include/selectors.php:49
-#: ../../include/selectors.php:66 ../../include/selectors.php:104
-#: ../../include/selectors.php:140 ../../include/connections.php:675
-#: ../../include/connections.php:682 ../../include/permissions.php:949
+#: ../../extend/addon/addon/cdav/cdav.php:284
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1148
+#: ../../include/connections.php:675 ../../include/connections.php:682
+#: ../../include/selectors.php:49 ../../include/selectors.php:66
+#: ../../include/selectors.php:104 ../../include/selectors.php:140
+#: ../../include/permissions.php:949
msgid "Other"
msgstr ""
@@ -182,7 +183,7 @@ msgstr ""
msgid "parent"
msgstr ""
-#: ../../Zotlabs/Storage/Browser.php:130 ../../include/text.php:2700
+#: ../../Zotlabs/Storage/Browser.php:130 ../../include/text.php:2684
msgid "Collection"
msgstr ""
@@ -213,7 +214,7 @@ msgstr ""
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:745
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:746
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:753
-#: ../../include/widgets.php:1757 ../../include/conversation.php:1177
+#: ../../include/conversation.php:1177 ../../include/widgets.php:1757
msgid "Unknown"
msgstr ""
@@ -231,10 +232,10 @@ msgid "Shared"
msgstr ""
#: ../../Zotlabs/Storage/Browser.php:228 ../../Zotlabs/Storage/Browser.php:330
+#: ../../Zotlabs/Module/Profiles.php:801 ../../Zotlabs/Module/Webpages.php:243
#: ../../Zotlabs/Module/Menu.php:118 ../../Zotlabs/Module/Connedit.php:928
#: ../../Zotlabs/Module/New_channel.php:147
-#: ../../Zotlabs/Module/Webpages.php:243 ../../Zotlabs/Module/Blocks.php:159
-#: ../../Zotlabs/Module/Layouts.php:184 ../../Zotlabs/Module/Profiles.php:801
+#: ../../Zotlabs/Module/Blocks.php:159 ../../Zotlabs/Module/Layouts.php:184
#: ../../extend/addon/addon/cdav/include/widgets.php:127
#: ../../extend/addon/addon/cdav/include/widgets.php:164
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1151
@@ -243,8 +244,8 @@ msgstr ""
#: ../../Zotlabs/Storage/Browser.php:229 ../../Zotlabs/Storage/Browser.php:332
#: ../../Zotlabs/Module/Cover_photo.php:357
-#: ../../Zotlabs/Module/Photos.php:811 ../../Zotlabs/Module/Photos.php:1368
#: ../../Zotlabs/Module/Profile_photo.php:421
+#: ../../Zotlabs/Module/Photos.php:811 ../../Zotlabs/Module/Photos.php:1368
#: ../../Zotlabs/Module/Embedphotos.php:157
#: ../../extend/addon/addon/cdav/include/widgets.php:132
#: ../../extend/addon/addon/cdav/include/widgets.php:168
@@ -252,13 +253,12 @@ msgstr ""
msgid "Upload"
msgstr ""
-#: ../../Zotlabs/Storage/Browser.php:233
+#: ../../Zotlabs/Storage/Browser.php:233 ../../Zotlabs/Module/Chat.php:248
#: ../../Zotlabs/Module/Admin/Channels.php:159
-#: ../../Zotlabs/Module/Connedit.php:913
+#: ../../Zotlabs/Module/Connedit.php:913 ../../Zotlabs/Module/Wiki.php:171
#: ../../Zotlabs/Module/Sharedwithme.php:99
#: ../../Zotlabs/Module/Settings/Oauth.php:89
#: ../../Zotlabs/Module/Settings/Oauth.php:115
-#: ../../Zotlabs/Module/Wiki.php:171 ../../Zotlabs/Module/Chat.php:248
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1136
#: ../../extend/addon/addon/rendezvous/rendezvous.php:172
#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:156
@@ -272,7 +272,7 @@ msgid "Type"
msgstr ""
#: ../../Zotlabs/Storage/Browser.php:235
-#: ../../Zotlabs/Module/Sharedwithme.php:101 ../../include/text.php:1414
+#: ../../Zotlabs/Module/Sharedwithme.php:101 ../../include/text.php:1398
msgid "Size"
msgstr ""
@@ -286,39 +286,39 @@ msgstr ""
#: ../../Zotlabs/Module/Connections.php:300
#: ../../Zotlabs/Module/Connections.php:320
#: ../../Zotlabs/Module/Admin/Profs.php:154
+#: ../../Zotlabs/Module/Webpages.php:244
#: ../../Zotlabs/Module/Editlayout.php:114
#: ../../Zotlabs/Module/Editwebpage.php:145 ../../Zotlabs/Module/Menu.php:112
-#: ../../Zotlabs/Module/Editpost.php:85 ../../Zotlabs/Module/Webpages.php:244
-#: ../../Zotlabs/Module/Blocks.php:160 ../../Zotlabs/Module/Layouts.php:192
+#: ../../Zotlabs/Module/Editpost.php:85 ../../Zotlabs/Module/Wiki.php:164
+#: ../../Zotlabs/Module/Wiki.php:271 ../../Zotlabs/Module/Blocks.php:160
+#: ../../Zotlabs/Module/Layouts.php:192
#: ../../Zotlabs/Module/Settings/Oauth.php:149
-#: ../../Zotlabs/Module/Thing.php:260 ../../Zotlabs/Module/Wiki.php:164
-#: ../../Zotlabs/Module/Wiki.php:271 ../../Zotlabs/Lib/ThreadItem.php:106
+#: ../../Zotlabs/Module/Thing.php:260 ../../Zotlabs/Lib/ThreadItem.php:106
#: ../../Zotlabs/Lib/Apps.php:357
#: ../../extend/addon/addon/cdav/include/widgets.php:125
#: ../../extend/addon/addon/cdav/include/widgets.php:161
#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:149
#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:251
#: ../../include/page_widgets.php:9 ../../include/page_widgets.php:39
-#: ../../include/menu.php:113 ../../include/channel.php:1044
-#: ../../include/channel.php:1048
+#: ../../include/channel.php:1044 ../../include/channel.php:1048
+#: ../../include/menu.php:113
msgid "Edit"
msgstr ""
-#: ../../Zotlabs/Storage/Browser.php:239
+#: ../../Zotlabs/Storage/Browser.php:239 ../../Zotlabs/Module/Profiles.php:803
#: ../../Zotlabs/Module/Editblock.php:134
#: ../../Zotlabs/Module/Connections.php:271
#: ../../Zotlabs/Module/Admin/Profs.php:155
#: ../../Zotlabs/Module/Admin/Accounts.php:173
#: ../../Zotlabs/Module/Admin/Channels.php:149
+#: ../../Zotlabs/Module/Webpages.php:246
#: ../../Zotlabs/Module/Editlayout.php:137
-#: ../../Zotlabs/Module/Editwebpage.php:170
+#: ../../Zotlabs/Module/Editwebpage.php:170 ../../Zotlabs/Module/Group.php:177
#: ../../Zotlabs/Module/Connedit.php:661 ../../Zotlabs/Module/Connedit.php:930
-#: ../../Zotlabs/Module/Photos.php:1174 ../../Zotlabs/Module/Group.php:177
-#: ../../Zotlabs/Module/Webpages.php:246 ../../Zotlabs/Module/Blocks.php:162
-#: ../../Zotlabs/Module/Profiles.php:803
+#: ../../Zotlabs/Module/Blocks.php:162
#: ../../Zotlabs/Module/Settings/Oauth.php:150
-#: ../../Zotlabs/Module/Thing.php:261 ../../Zotlabs/Lib/ThreadItem.php:126
-#: ../../Zotlabs/Lib/Apps.php:358
+#: ../../Zotlabs/Module/Thing.php:261 ../../Zotlabs/Module/Photos.php:1174
+#: ../../Zotlabs/Lib/ThreadItem.php:126 ../../Zotlabs/Lib/Apps.php:358
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:864
#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1153
#: ../../include/conversation.php:656
@@ -360,24 +360,26 @@ msgstr ""
#: ../../Zotlabs/Web/WebServer.php:127 ../../Zotlabs/Module/Group.php:72
#: ../../Zotlabs/Module/Dreport.php:10 ../../Zotlabs/Module/Dreport.php:68
-#: ../../Zotlabs/Module/Import_items.php:114
-#: ../../Zotlabs/Module/Profperm.php:28 ../../Zotlabs/Module/Like.php:283
-#: ../../Zotlabs/Module/Subthread.php:62
+#: ../../Zotlabs/Module/Import_items.php:114 ../../Zotlabs/Module/Like.php:283
+#: ../../Zotlabs/Module/Subthread.php:62 ../../Zotlabs/Module/Profperm.php:28
#: ../../extend/addon/addon/frphotos/frphotos.php:81
#: ../../extend/addon/addon/redfiles/redfiles.php:109
#: ../../extend/addon/addon/redphotos/redphotos.php:119
-#: ../../include/items.php:327
+#: ../../include/items.php:325
msgid "Permission denied"
msgstr ""
#: ../../Zotlabs/Web/WebServer.php:128
-#: ../../Zotlabs/Module/Achievements.php:34 ../../Zotlabs/Module/Appman.php:82
-#: ../../Zotlabs/Module/Register.php:77 ../../Zotlabs/Module/Authtest.php:16
-#: ../../Zotlabs/Module/Bookmarks.php:61 ../../Zotlabs/Module/Editblock.php:67
-#: ../../Zotlabs/Module/Page.php:35 ../../Zotlabs/Module/Page.php:91
-#: ../../Zotlabs/Module/Connections.php:33
+#: ../../Zotlabs/Module/Achievements.php:34 ../../Zotlabs/Module/Chat.php:98
+#: ../../Zotlabs/Module/Chat.php:103 ../../Zotlabs/Module/Register.php:77
+#: ../../Zotlabs/Module/Setup.php:212 ../../Zotlabs/Module/Message.php:18
+#: ../../Zotlabs/Module/Profiles.php:198 ../../Zotlabs/Module/Profiles.php:635
+#: ../../Zotlabs/Module/Authtest.php:16 ../../Zotlabs/Module/Bookmarks.php:61
+#: ../../Zotlabs/Module/Editblock.php:67 ../../Zotlabs/Module/Page.php:35
+#: ../../Zotlabs/Module/Page.php:91 ../../Zotlabs/Module/Connections.php:33
#: ../../Zotlabs/Module/Cover_photo.php:277
#: ../../Zotlabs/Module/Cover_photo.php:290
+#: ../../Zotlabs/Module/Webpages.php:116
#: ../../Zotlabs/Module/Editlayout.php:67
#: ../../Zotlabs/Module/Editlayout.php:90
#: ../../Zotlabs/Module/Editwebpage.php:68
@@ -385,45 +387,42 @@ msgstr ""
#: ../../Zotlabs/Module/Editwebpage.php:104
#: ../../Zotlabs/Module/Editwebpage.php:126
#: ../../Zotlabs/Module/Network.php:15 ../../Zotlabs/Module/Menu.php:78
-#: ../../Zotlabs/Module/Locs.php:87 ../../Zotlabs/Module/Connedit.php:388
-#: ../../Zotlabs/Module/Events.php:271 ../../Zotlabs/Module/Filestorage.php:23
+#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Locs.php:87
+#: ../../Zotlabs/Module/Filestorage.php:23
#: ../../Zotlabs/Module/Filestorage.php:78
#: ../../Zotlabs/Module/Filestorage.php:93
-#: ../../Zotlabs/Module/Filestorage.php:120 ../../Zotlabs/Module/Photos.php:73
+#: ../../Zotlabs/Module/Filestorage.php:120
#: ../../Zotlabs/Module/Settings.php:59 ../../Zotlabs/Module/Group.php:13
-#: ../../Zotlabs/Module/Mail.php:164 ../../Zotlabs/Module/Block.php:26
-#: ../../Zotlabs/Module/Block.php:76 ../../Zotlabs/Module/Manage.php:10
-#: ../../Zotlabs/Module/Message.php:18 ../../Zotlabs/Module/Mitem.php:115
-#: ../../Zotlabs/Module/Editpost.php:17 ../../Zotlabs/Module/Api.php:24
-#: ../../Zotlabs/Module/Invite.php:17 ../../Zotlabs/Module/Invite.php:94
-#: ../../Zotlabs/Module/New_channel.php:77
+#: ../../Zotlabs/Module/Block.php:26 ../../Zotlabs/Module/Block.php:76
+#: ../../Zotlabs/Module/Manage.php:10 ../../Zotlabs/Module/Connedit.php:388
+#: ../../Zotlabs/Module/Mitem.php:115 ../../Zotlabs/Module/Item.php:220
+#: ../../Zotlabs/Module/Item.php:230 ../../Zotlabs/Module/Item.php:1067
+#: ../../Zotlabs/Module/Api.php:24 ../../Zotlabs/Module/Invite.php:17
+#: ../../Zotlabs/Module/Invite.php:94 ../../Zotlabs/Module/New_channel.php:77
#: ../../Zotlabs/Module/New_channel.php:104
-#: ../../Zotlabs/Module/Webpages.php:116
#: ../../Zotlabs/Module/Notifications.php:11 ../../Zotlabs/Module/Poke.php:137
-#: ../../Zotlabs/Module/Item.php:220 ../../Zotlabs/Module/Item.php:230
-#: ../../Zotlabs/Module/Item.php:1067 ../../Zotlabs/Module/Blocks.php:73
-#: ../../Zotlabs/Module/Blocks.php:80 ../../Zotlabs/Module/Layouts.php:71
-#: ../../Zotlabs/Module/Layouts.php:78 ../../Zotlabs/Module/Layouts.php:89
-#: ../../Zotlabs/Module/Rate.php:113
+#: ../../Zotlabs/Module/Wiki.php:50 ../../Zotlabs/Module/Wiki.php:215
+#: ../../Zotlabs/Module/Wiki.php:311 ../../Zotlabs/Module/Like.php:181
+#: ../../Zotlabs/Module/Mood.php:116 ../../Zotlabs/Module/Mail.php:164
+#: ../../Zotlabs/Module/Blocks.php:73 ../../Zotlabs/Module/Blocks.php:80
+#: ../../Zotlabs/Module/Layouts.php:71 ../../Zotlabs/Module/Layouts.php:78
+#: ../../Zotlabs/Module/Layouts.php:89 ../../Zotlabs/Module/Rate.php:113
#: ../../Zotlabs/Module/Profile_photo.php:278
#: ../../Zotlabs/Module/Profile_photo.php:291
-#: ../../Zotlabs/Module/Like.php:181 ../../Zotlabs/Module/Common.php:39
-#: ../../Zotlabs/Module/Channel.php:115 ../../Zotlabs/Module/Channel.php:245
-#: ../../Zotlabs/Module/Channel.php:285 ../../Zotlabs/Module/Mood.php:116
+#: ../../Zotlabs/Module/Appman.php:82 ../../Zotlabs/Module/Common.php:39
#: ../../Zotlabs/Module/Regmod.php:21 ../../Zotlabs/Module/Pdledit.php:29
-#: ../../Zotlabs/Module/Profile.php:83 ../../Zotlabs/Module/Profile.php:100
-#: ../../Zotlabs/Module/Viewsrc.php:18
+#: ../../Zotlabs/Module/Events.php:271
#: ../../Zotlabs/Module/Service_limits.php:11
#: ../../Zotlabs/Module/Sharedwithme.php:11
-#: ../../Zotlabs/Module/Sources.php:74 ../../Zotlabs/Module/Suggest.php:30
-#: ../../Zotlabs/Module/Profiles.php:198 ../../Zotlabs/Module/Profiles.php:635
+#: ../../Zotlabs/Module/Viewsrc.php:18 ../../Zotlabs/Module/Sources.php:74
+#: ../../Zotlabs/Module/Channel.php:115 ../../Zotlabs/Module/Channel.php:245
+#: ../../Zotlabs/Module/Channel.php:285 ../../Zotlabs/Module/Suggest.php:30
#: ../../Zotlabs/Module/Thing.php:274 ../../Zotlabs/Module/Thing.php:294
-#: ../../Zotlabs/Module/Thing.php:335 ../../Zotlabs/Module/Setup.php:212
+#: ../../Zotlabs/Module/Thing.php:335
#: ../../Zotlabs/Module/Viewconnections.php:28
#: ../../Zotlabs/Module/Viewconnections.php:33
-#: ../../Zotlabs/Module/Wiki.php:50 ../../Zotlabs/Module/Wiki.php:215
-#: ../../Zotlabs/Module/Wiki.php:311 ../../Zotlabs/Module/Chat.php:98
-#: ../../Zotlabs/Module/Chat.php:103 ../../Zotlabs/Lib/Chatroom.php:137
+#: ../../Zotlabs/Module/Photos.php:73 ../../Zotlabs/Module/Profile.php:83
+#: ../../Zotlabs/Module/Profile.php:100 ../../Zotlabs/Lib/Chatroom.php:137
#: ../../extend/addon/addon/friendica/dfrn_confirm.php:55
#: ../../extend/addon/addon/keepout/keepout.php:36
#: ../../extend/addon/addon/pumpio/pumpio.php:40
@@ -431,7 +430,7 @@ msgstr ""
#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:58
#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:194
#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:291
-#: ../../include/items.php:3447 ../../include/attach.php:144
+#: ../../include/items.php:3350 ../../include/attach.php:144
#: ../../include/attach.php:191 ../../include/attach.php:255
#: ../../include/attach.php:269 ../../include/attach.php:276
#: ../../include/attach.php:343 ../../include/attach.php:357
@@ -442,8 +441,8 @@ msgid "Permission denied."
msgstr ""
#: ../../Zotlabs/Web/Router.php:146 ../../Zotlabs/Module/Page.php:94
-#: ../../Zotlabs/Module/Display.php:122 ../../Zotlabs/Module/Block.php:79
-#: ../../Zotlabs/Lib/NativeWikiPage.php:518 ../../include/help.php:68
+#: ../../Zotlabs/Module/Block.php:79 ../../Zotlabs/Module/Display.php:122
+#: ../../Zotlabs/Lib/NativeWikiPage.php:522 ../../include/help.php:68
msgid "Page not found."
msgstr ""
@@ -462,11 +461,10 @@ msgstr ""
#: ../../Zotlabs/Module/Achievements.php:15
#: ../../Zotlabs/Module/Connect.php:17 ../../Zotlabs/Module/Editblock.php:31
-#: ../../Zotlabs/Module/Editlayout.php:31
+#: ../../Zotlabs/Module/Webpages.php:33 ../../Zotlabs/Module/Editlayout.php:31
#: ../../Zotlabs/Module/Editwebpage.php:32
-#: ../../Zotlabs/Module/Filestorage.php:59
-#: ../../Zotlabs/Module/Webpages.php:33 ../../Zotlabs/Module/Hcard.php:12
-#: ../../Zotlabs/Module/Blocks.php:33 ../../Zotlabs/Module/Layouts.php:31
+#: ../../Zotlabs/Module/Filestorage.php:59 ../../Zotlabs/Module/Blocks.php:33
+#: ../../Zotlabs/Module/Layouts.php:31 ../../Zotlabs/Module/Hcard.php:12
#: ../../Zotlabs/Module/Profile.php:20 ../../include/channel.php:945
msgid "Requested profile is not available."
msgstr ""
@@ -475,74 +473,19 @@ msgstr ""
msgid "Some blurb about what to do when you're new here"
msgstr ""
-#: ../../Zotlabs/Module/Appman.php:38 ../../Zotlabs/Module/Appman.php:55
-msgid "App installed."
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:48
-msgid "Malformed app."
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:111
-msgid "Embed code"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:117
-msgid "Edit App"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:117
-msgid "Create App"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:122
-msgid "Name of app"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:122 ../../Zotlabs/Module/Appman.php:123
-#: ../../Zotlabs/Module/Events.php:460 ../../Zotlabs/Module/Events.php:465
-#: ../../Zotlabs/Module/Profiles.php:748 ../../Zotlabs/Module/Profiles.php:752
-#: ../../include/datetime.php:259
-msgid "Required"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:123
-msgid "Location (URL) of app"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:124 ../../Zotlabs/Module/Events.php:473
-#: ../../Zotlabs/Module/Rbmark.php:101
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:838
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:173
-msgid "Description"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:125
-msgid "Photo icon URL"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:125
-msgid "80 x 80 pixels - optional"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:126
-msgid "Categories (optional, comma separated list)"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:127
-msgid "Version ID"
-msgstr ""
-
-#: ../../Zotlabs/Module/Appman.php:128
-msgid "Price of app"
+#: ../../Zotlabs/Module/Chat.php:25 ../../Zotlabs/Module/Channel.php:32
+#: ../../extend/addon/addon/chess/chess.php:403
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:26
+msgid "You must be logged in to see this page."
msgstr ""
-#: ../../Zotlabs/Module/Appman.php:129
-msgid "Location (URL) to purchase app"
+#: ../../Zotlabs/Module/Chat.php:179
+msgid "Room not found"
msgstr ""
-#: ../../Zotlabs/Module/Appman.php:134 ../../Zotlabs/Module/Import.php:507
-#: ../../Zotlabs/Module/Connect.php:98
+#: ../../Zotlabs/Module/Chat.php:194 ../../Zotlabs/Module/Chat.php:239
+#: ../../Zotlabs/Module/Setup.php:309 ../../Zotlabs/Module/Setup.php:350
+#: ../../Zotlabs/Module/Profiles.php:726 ../../Zotlabs/Module/Connect.php:98
#: ../../Zotlabs/Module/Admin/Features.php:66
#: ../../Zotlabs/Module/Admin/Logs.php:84
#: ../../Zotlabs/Module/Admin/Profs.php:157
@@ -553,30 +496,27 @@ msgstr ""
#: ../../Zotlabs/Module/Admin/Site.php:268
#: ../../Zotlabs/Module/Admin/Plugins.php:438
#: ../../Zotlabs/Module/Admin/Themes.php:158 ../../Zotlabs/Module/Locs.php:121
-#: ../../Zotlabs/Module/Connedit.php:893 ../../Zotlabs/Module/Events.php:493
-#: ../../Zotlabs/Module/Filestorage.php:165
-#: ../../Zotlabs/Module/Photos.php:667 ../../Zotlabs/Module/Photos.php:1053
-#: ../../Zotlabs/Module/Photos.php:1093 ../../Zotlabs/Module/Photos.php:1211
-#: ../../Zotlabs/Module/Group.php:85 ../../Zotlabs/Module/Mail.php:413
-#: ../../Zotlabs/Module/Import_items.php:122
-#: ../../Zotlabs/Module/Mitem.php:243 ../../Zotlabs/Module/Cal.php:342
+#: ../../Zotlabs/Module/Filestorage.php:165 ../../Zotlabs/Module/Group.php:85
+#: ../../Zotlabs/Module/Cal.php:342 ../../Zotlabs/Module/Import_items.php:122
+#: ../../Zotlabs/Module/Connedit.php:893 ../../Zotlabs/Module/Mitem.php:243
#: ../../Zotlabs/Module/Invite.php:149 ../../Zotlabs/Module/Poke.php:186
-#: ../../Zotlabs/Module/Pconfig.php:107 ../../Zotlabs/Module/Rate.php:166
-#: ../../Zotlabs/Module/Mood.php:139 ../../Zotlabs/Module/Pdledit.php:74
+#: ../../Zotlabs/Module/Wiki.php:168 ../../Zotlabs/Module/Pconfig.php:107
+#: ../../Zotlabs/Module/Mood.php:139 ../../Zotlabs/Module/Mail.php:413
+#: ../../Zotlabs/Module/Rate.php:166 ../../Zotlabs/Module/Appman.php:134
+#: ../../Zotlabs/Module/Pdledit.php:74 ../../Zotlabs/Module/Events.php:493
#: ../../Zotlabs/Module/Sources.php:114 ../../Zotlabs/Module/Sources.php:149
-#: ../../Zotlabs/Module/Profiles.php:726
#: ../../Zotlabs/Module/Settings/Features.php:47
#: ../../Zotlabs/Module/Settings/Oauth.php:87
#: ../../Zotlabs/Module/Settings/Account.php:118
-#: ../../Zotlabs/Module/Settings/Channel.php:476
+#: ../../Zotlabs/Module/Settings/Display.php:203
#: ../../Zotlabs/Module/Settings/Featured.php:50
#: ../../Zotlabs/Module/Settings/Permcats.php:112
#: ../../Zotlabs/Module/Settings/Tokens.php:168
-#: ../../Zotlabs/Module/Settings/Display.php:203
+#: ../../Zotlabs/Module/Settings/Channel.php:476
#: ../../Zotlabs/Module/Thing.php:320 ../../Zotlabs/Module/Thing.php:370
-#: ../../Zotlabs/Module/Setup.php:309 ../../Zotlabs/Module/Setup.php:357
-#: ../../Zotlabs/Module/Wiki.php:168 ../../Zotlabs/Module/Chat.php:194
-#: ../../Zotlabs/Module/Chat.php:239 ../../Zotlabs/Module/Xchan.php:15
+#: ../../Zotlabs/Module/Import.php:507 ../../Zotlabs/Module/Photos.php:667
+#: ../../Zotlabs/Module/Photos.php:1053 ../../Zotlabs/Module/Photos.php:1093
+#: ../../Zotlabs/Module/Photos.php:1211 ../../Zotlabs/Module/Xchan.php:15
#: ../../Zotlabs/Lib/ThreadItem.php:731
#: ../../extend/addon/addon/chords/Mod_Chords.php:60
#: ../../extend/addon/addon/diaspora/diaspora.php:714
@@ -629,6 +569,89 @@ msgstr ""
msgid "Submit"
msgstr ""
+#: ../../Zotlabs/Module/Chat.php:195
+msgid "Leave Room"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:196
+msgid "Delete Room"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:197
+msgid "I am away right now"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:198
+msgid "I am online"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:200
+msgid "Bookmark this room"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:203 ../../Zotlabs/Module/Mail.php:240
+#: ../../Zotlabs/Module/Mail.php:349 ../../include/conversation.php:1330
+msgid "Please enter a link URL:"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:204 ../../Zotlabs/Module/Mail.php:293
+#: ../../Zotlabs/Module/Mail.php:418 ../../Zotlabs/Lib/ThreadItem.php:743
+#: ../../include/conversation.php:1440
+msgid "Encrypt text"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:205 ../../Zotlabs/Module/Editblock.php:111
+#: ../../Zotlabs/Module/Editwebpage.php:146 ../../Zotlabs/Module/Mail.php:287
+#: ../../Zotlabs/Module/Mail.php:412 ../../include/conversation.php:1295
+msgid "Insert web link"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:216 ../../Zotlabs/Module/Pdledit.php:34
+msgid "Feature disabled."
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:229
+msgid "New Chatroom"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:230
+msgid "Chatroom name"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:231
+msgid "Expiration of chats (minutes)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:232 ../../Zotlabs/Module/Filestorage.php:152
+#: ../../Zotlabs/Module/Connedit.php:683 ../../Zotlabs/Module/Thing.php:313
+#: ../../Zotlabs/Module/Thing.php:363 ../../Zotlabs/Module/Photos.php:657
+#: ../../Zotlabs/Module/Photos.php:1042 ../../include/acl_selectors.php:218
+msgid "Permissions"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:247
+#, php-format
+msgid "%1$s's Chatrooms"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:252
+msgid "No chatrooms available"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:253 ../../Zotlabs/Module/Profiles.php:834
+#: ../../Zotlabs/Module/Manage.php:143 ../../Zotlabs/Module/Wiki.php:167
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:152
+msgid "Create New"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:256
+msgid "Expiration"
+msgstr ""
+
+#: ../../Zotlabs/Module/Chat.php:257
+msgid "min"
+msgstr ""
+
#: ../../Zotlabs/Module/Register.php:49
msgid "Maximum daily site registrations exceeded. Please try again tomorrow."
msgstr ""
@@ -761,7 +784,7 @@ msgid "Membership on this site is by invitation only."
msgstr ""
#: ../../Zotlabs/Module/Register.php:270 ../../include/nav.php:162
-#: ../../boot.php:1730
+#: ../../boot.php:1687
msgid "Register"
msgstr ""
@@ -776,2872 +799,2913 @@ msgstr ""
msgid "Fetching URL returns error: %1$s"
msgstr ""
-#: ../../Zotlabs/Module/Rmagic.php:35
-msgid "Authentication failed."
+#: ../../Zotlabs/Module/Setup.php:176
+msgid "$Projectname Server - Setup"
msgstr ""
-#: ../../Zotlabs/Module/Rmagic.php:75 ../../include/channel.php:1989
-msgid "Remote Authentication"
+#: ../../Zotlabs/Module/Setup.php:180
+msgid "Could not connect to database."
msgstr ""
-#: ../../Zotlabs/Module/Rmagic.php:76 ../../include/channel.php:1990
-msgid "Enter your channel address (e.g. channel@example.com)"
+#: ../../Zotlabs/Module/Setup.php:184
+msgid ""
+"Could not connect to specified site URL. Possible SSL certificate or DNS "
+"issue."
msgstr ""
-#: ../../Zotlabs/Module/Rmagic.php:77 ../../include/channel.php:1991
-msgid "Authenticate"
+#: ../../Zotlabs/Module/Setup.php:191
+msgid "Could not create table."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:57 ../../Zotlabs/Module/Import_items.php:42
-msgid "Nothing to import."
+#: ../../Zotlabs/Module/Setup.php:196
+msgid "Your site database has been installed."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:69 ../../Zotlabs/Module/Import.php:84
-#: ../../Zotlabs/Module/Import_items.php:66
-msgid "Unable to download data from old server"
+#: ../../Zotlabs/Module/Setup.php:200
+msgid ""
+"You may need to import the file \"install/schema_xxx.sql\" manually using a "
+"database client."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:91 ../../Zotlabs/Module/Import_items.php:72
-msgid "Imported file is empty."
+#: ../../Zotlabs/Module/Setup.php:201 ../../Zotlabs/Module/Setup.php:263
+#: ../../Zotlabs/Module/Setup.php:743
+msgid "Please see the file \"install/INSTALL.txt\"."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:111
-#: ../../Zotlabs/Module/Import_items.php:88
-#, php-format
-msgid "Warning: Database versions differ by %1$d updates."
+#: ../../Zotlabs/Module/Setup.php:260
+msgid "System check"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:134
-#, php-format
-msgid "Your service plan only allows %d channels."
+#: ../../Zotlabs/Module/Setup.php:264 ../../Zotlabs/Module/Cal.php:337
+#: ../../Zotlabs/Module/Cal.php:344 ../../Zotlabs/Module/Events.php:690
+#: ../../Zotlabs/Module/Events.php:699 ../../Zotlabs/Module/Photos.php:944
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:847
+msgid "Next"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:149
-msgid "No channel. Import failed."
+#: ../../Zotlabs/Module/Setup.php:265
+msgid "Check again"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:467
-#: ../../extend/addon/addon/diaspora/import_diaspora.php:142
-msgid "Import completed."
+#: ../../Zotlabs/Module/Setup.php:287
+msgid "Database connection"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:488
-msgid "You must be logged in to use this feature."
+#: ../../Zotlabs/Module/Setup.php:288
+msgid ""
+"In order to install $Projectname we need to know how to connect to your "
+"database."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:493
-msgid "Import Channel"
+#: ../../Zotlabs/Module/Setup.php:289
+msgid ""
+"Please contact your hosting provider or site administrator if you have "
+"questions about these settings."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:494
+#: ../../Zotlabs/Module/Setup.php:290
msgid ""
-"Use this form to import an existing channel from a different server/hub. You "
-"may retrieve the channel identity from the old server/hub via the network or "
-"provide an export file."
+"The database you specify below should already exist. If it does not, please "
+"create it before continuing."
msgstr ""
-#: ../../Zotlabs/Module/Import.php:495
-#: ../../Zotlabs/Module/Import_items.php:121
-msgid "File to Upload"
+#: ../../Zotlabs/Module/Setup.php:294
+msgid "Database Server Name"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:496
-msgid "Or provide the old server/hub details"
+#: ../../Zotlabs/Module/Setup.php:294
+msgid "Default is 127.0.0.1"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:497
-msgid "Your old identity address (xyz@example.com)"
+#: ../../Zotlabs/Module/Setup.php:295
+msgid "Database Port"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:498
-msgid "Your old login email address"
+#: ../../Zotlabs/Module/Setup.php:295
+msgid "Communication port number - use 0 for default"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:499
-msgid "Your old login password"
+#: ../../Zotlabs/Module/Setup.php:296
+msgid "Database Login Name"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:500
-msgid ""
-"For either option, please choose whether to make this hub your new primary "
-"address, or whether your old location should continue this role. You will be "
-"able to post from either location, but only one can be marked as the primary "
-"location for files, photos, and media."
+#: ../../Zotlabs/Module/Setup.php:297
+msgid "Database Login Password"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:501
-msgid "Make this hub my primary location"
+#: ../../Zotlabs/Module/Setup.php:298
+msgid "Database Name"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:502
-msgid "Move this channel (disable all previous locations)"
+#: ../../Zotlabs/Module/Setup.php:299
+msgid "Database Type"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:503
-msgid "Import a few months of posts if possible (limited by available memory"
+#: ../../Zotlabs/Module/Setup.php:301 ../../Zotlabs/Module/Setup.php:342
+msgid "Site administrator email address"
msgstr ""
-#: ../../Zotlabs/Module/Import.php:504
+#: ../../Zotlabs/Module/Setup.php:301 ../../Zotlabs/Module/Setup.php:342
msgid ""
-"This process may take several minutes to complete. Please submit the form "
-"only once and leave this page open until finished."
-msgstr ""
-
-#: ../../Zotlabs/Module/Chatsvc.php:131
-msgid "Away"
+"Your account email address must match this in order to use the web admin "
+"panel."
msgstr ""
-#: ../../Zotlabs/Module/Chatsvc.php:136
-msgid "Online"
+#: ../../Zotlabs/Module/Setup.php:302 ../../Zotlabs/Module/Setup.php:344
+msgid "Website URL"
msgstr ""
-#: ../../Zotlabs/Module/Help.php:23
-msgid "Documentation Search"
+#: ../../Zotlabs/Module/Setup.php:302 ../../Zotlabs/Module/Setup.php:344
+msgid "Please use SSL (https) URL if available."
msgstr ""
-#: ../../Zotlabs/Module/Help.php:80 ../../include/conversation.php:1827
-msgid "About"
+#: ../../Zotlabs/Module/Setup.php:303 ../../Zotlabs/Module/Setup.php:346
+msgid "Please select a default timezone for your website"
msgstr ""
-#: ../../Zotlabs/Module/Help.php:81 ../../Zotlabs/Module/Group.php:197
-msgid "Members"
+#: ../../Zotlabs/Module/Setup.php:331
+msgid "Site settings"
msgstr ""
-#: ../../Zotlabs/Module/Help.php:82
-msgid "Administrators"
+#: ../../Zotlabs/Module/Setup.php:385
+msgid "PHP version 5.5 or greater is required."
msgstr ""
-#: ../../Zotlabs/Module/Help.php:83
-msgid "Developers"
+#: ../../Zotlabs/Module/Setup.php:386
+msgid "PHP version"
msgstr ""
-#: ../../Zotlabs/Module/Help.php:84
-msgid "Tutorials"
+#: ../../Zotlabs/Module/Setup.php:402
+msgid "Could not find a command line version of PHP in the web server PATH."
msgstr ""
-#: ../../Zotlabs/Module/Help.php:93
-msgid "$Projectname Documentation"
+#: ../../Zotlabs/Module/Setup.php:403
+msgid ""
+"If you don't have a command line version of PHP installed on server, you "
+"will not be able to run background polling via cron."
msgstr ""
-#: ../../Zotlabs/Module/Help.php:94
-msgid "Contents"
+#: ../../Zotlabs/Module/Setup.php:407
+msgid "PHP executable path"
msgstr ""
-#: ../../Zotlabs/Module/Bookmarks.php:53
-msgid "Bookmark added"
+#: ../../Zotlabs/Module/Setup.php:407
+msgid ""
+"Enter full path to php executable. You can leave this blank to continue the "
+"installation."
msgstr ""
-#: ../../Zotlabs/Module/Bookmarks.php:75
-msgid "My Bookmarks"
+#: ../../Zotlabs/Module/Setup.php:412
+msgid "Command line PHP"
msgstr ""
-#: ../../Zotlabs/Module/Bookmarks.php:86
-msgid "My Connections Bookmarks"
+#: ../../Zotlabs/Module/Setup.php:422
+msgid ""
+"Unable to check command line PHP, as shell_exec() is disabled. This is "
+"required."
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:61 ../../Zotlabs/Module/Connect.php:109
-msgid "Continue"
+#: ../../Zotlabs/Module/Setup.php:425
+msgid ""
+"The command line version of PHP on your system does not have "
+"\"register_argc_argv\" enabled."
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:90
-msgid "Premium Channel Setup"
+#: ../../Zotlabs/Module/Setup.php:426
+msgid "This is required for message delivery to work."
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:92
-msgid "Enable premium channel connection restrictions"
+#: ../../Zotlabs/Module/Setup.php:429
+msgid "PHP register_argc_argv"
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:93
+#: ../../Zotlabs/Module/Setup.php:447
+#, php-format
msgid ""
-"Please enter your restrictions or conditions, such as paypal receipt, usage "
-"guidelines, etc."
+"Your max allowed total upload size is set to %s. Maximum size of one file to "
+"upload is set to %s. You are allowed to upload up to %d files at once."
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:95 ../../Zotlabs/Module/Connect.php:115
-msgid ""
-"This channel may require additional steps or acknowledgement of the "
-"following conditions prior to connecting:"
+#: ../../Zotlabs/Module/Setup.php:452
+msgid "You can adjust these settings in the server php.ini file."
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:96
-msgid ""
-"Potential connections will then see the following text before proceeding:"
+#: ../../Zotlabs/Module/Setup.php:454
+msgid "PHP upload limits"
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:97 ../../Zotlabs/Module/Connect.php:118
+#: ../../Zotlabs/Module/Setup.php:477
msgid ""
-"By continuing, I certify that I have complied with any instructions provided "
-"on this page."
+"Error: the \"openssl_pkey_new\" function on this system is not able to "
+"generate encryption keys"
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:106
-msgid "(No specific instructions have been provided by the channel owner.)"
+#: ../../Zotlabs/Module/Setup.php:478
+msgid ""
+"If running under Windows, please see \"http://www.php.net/manual/en/openssl."
+"installation.php\"."
msgstr ""
-#: ../../Zotlabs/Module/Connect.php:114
-msgid "Restricted or Premium Channel"
+#: ../../Zotlabs/Module/Setup.php:481
+msgid "Generate encryption keys"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:60
-#: ../../Zotlabs/Module/Admin/Plugins.php:259
-#: ../../Zotlabs/Module/Admin/Themes.php:72
-#: ../../Zotlabs/Module/Filestorage.php:32 ../../Zotlabs/Module/Display.php:35
-#: ../../Zotlabs/Module/Viewsrc.php:24 ../../Zotlabs/Module/Thing.php:89
-#: ../../include/items.php:3368
-msgid "Item not found."
+#: ../../Zotlabs/Module/Setup.php:498
+msgid "libCurl PHP module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:94
-msgid "# Accounts"
+#: ../../Zotlabs/Module/Setup.php:499
+msgid "GD graphics PHP module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:95
-msgid "# blocked accounts"
+#: ../../Zotlabs/Module/Setup.php:500
+msgid "OpenSSL PHP module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:96
-msgid "# expired accounts"
+#: ../../Zotlabs/Module/Setup.php:501
+msgid "PDO database PHP module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:97
-msgid "# expiring accounts"
+#: ../../Zotlabs/Module/Setup.php:502
+msgid "mb_string PHP module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:108
-msgid "# Channels"
+#: ../../Zotlabs/Module/Setup.php:503
+msgid "xml PHP module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:109
-msgid "# primary"
+#: ../../Zotlabs/Module/Setup.php:507 ../../Zotlabs/Module/Setup.php:509
+msgid "Apache mod_rewrite module"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:110
-msgid "# clones"
+#: ../../Zotlabs/Module/Setup.php:507
+msgid ""
+"Error: Apache webserver mod-rewrite module is required but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:116
-msgid "Message queues"
+#: ../../Zotlabs/Module/Setup.php:513 ../../Zotlabs/Module/Setup.php:516
+msgid "exec"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:133
-msgid "Your software should be updated"
+#: ../../Zotlabs/Module/Setup.php:513
+msgid ""
+"Error: exec is required but is either not installed or has been disabled in "
+"php.ini"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:137 ../../Zotlabs/Module/Admin/Logs.php:82
-#: ../../Zotlabs/Module/Admin/Security.php:86
-#: ../../Zotlabs/Module/Admin/Accounts.php:164
-#: ../../Zotlabs/Module/Admin/Channels.php:145
-#: ../../Zotlabs/Module/Admin/Site.php:266
-#: ../../Zotlabs/Module/Admin/Plugins.php:341
-#: ../../Zotlabs/Module/Admin/Plugins.php:436
-#: ../../Zotlabs/Module/Admin/Themes.php:122
-#: ../../Zotlabs/Module/Admin/Themes.php:156
-msgid "Administration"
+#: ../../Zotlabs/Module/Setup.php:519 ../../Zotlabs/Module/Setup.php:522
+msgid "shell_exec"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:138
-msgid "Summary"
+#: ../../Zotlabs/Module/Setup.php:519
+msgid ""
+"Error: shell_exec is required but is either not installed or has been "
+"disabled in php.ini"
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:141
-msgid "Registered accounts"
+#: ../../Zotlabs/Module/Setup.php:527
+msgid "Error: libCURL PHP module required but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:142
-msgid "Pending registrations"
+#: ../../Zotlabs/Module/Setup.php:531
+msgid ""
+"Error: GD graphics PHP module with JPEG support required but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:143
-msgid "Registered channels"
+#: ../../Zotlabs/Module/Setup.php:535
+msgid "Error: openssl PHP module required but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:144
-msgid "Active plugins"
+#: ../../Zotlabs/Module/Setup.php:539
+msgid "Error: PDO database PHP module required but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:145
-msgid "Version"
+#: ../../Zotlabs/Module/Setup.php:543
+msgid "Error: mb_string PHP module required but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:146
-msgid "Repository version (master)"
+#: ../../Zotlabs/Module/Setup.php:547
+msgid "Error: xml PHP module required for DAV but not installed."
msgstr ""
-#: ../../Zotlabs/Module/Admin.php:147
-msgid "Repository version (dev)"
+#: ../../Zotlabs/Module/Setup.php:565
+msgid ""
+"The web installer needs to be able to create a file called \".htconfig.php\" "
+"in the top folder of your web server and it is unable to do so."
msgstr ""
-#: ../../Zotlabs/Module/Editblock.php:79 ../../Zotlabs/Module/Editblock.php:95
-#: ../../Zotlabs/Module/Editlayout.php:79
-#: ../../Zotlabs/Module/Editwebpage.php:80
-#: ../../Zotlabs/Module/Editpost.php:24
-msgid "Item not found"
+#: ../../Zotlabs/Module/Setup.php:566
+msgid ""
+"This is most often a permission setting, as the web server may not be able "
+"to write files in your folder - even if you can."
msgstr ""
-#: ../../Zotlabs/Module/Editblock.php:108 ../../Zotlabs/Module/Blocks.php:97
-#: ../../Zotlabs/Module/Blocks.php:155
-msgid "Block Name"
+#: ../../Zotlabs/Module/Setup.php:567
+msgid ""
+"At the end of this procedure, we will give you a text to save in a file "
+"named .htconfig.php in your Red top folder."
msgstr ""
-#: ../../Zotlabs/Module/Editblock.php:111
-#: ../../Zotlabs/Module/Editwebpage.php:146 ../../Zotlabs/Module/Mail.php:287
-#: ../../Zotlabs/Module/Mail.php:412 ../../Zotlabs/Module/Chat.php:205
-#: ../../include/conversation.php:1295
-msgid "Insert web link"
+#: ../../Zotlabs/Module/Setup.php:568
+msgid ""
+"You can alternatively skip this procedure and perform a manual installation. "
+"Please see the file \"install/INSTALL.txt\" for instructions."
msgstr ""
-#: ../../Zotlabs/Module/Editblock.php:124 ../../include/conversation.php:1406
-msgid "Title (optional)"
+#: ../../Zotlabs/Module/Setup.php:571
+msgid ".htconfig.php is writable"
msgstr ""
-#: ../../Zotlabs/Module/Editblock.php:133
-msgid "Edit Block"
+#: ../../Zotlabs/Module/Setup.php:585
+msgid ""
+"This software uses the Smarty3 template engine to render its web views. "
+"Smarty3 compiles templates to PHP to speed up rendering."
msgstr ""
-#: ../../Zotlabs/Module/Page.php:40 ../../Zotlabs/Module/Block.php:31
-msgid "Invalid item."
+#: ../../Zotlabs/Module/Setup.php:586
+#, php-format
+msgid ""
+"In order to store these compiled templates, the web server needs to have "
+"write access to the directory %s under the top level web folder."
msgstr ""
-#: ../../Zotlabs/Module/Page.php:56 ../../Zotlabs/Module/Block.php:43
-#: ../../Zotlabs/Module/Cal.php:62 ../../Zotlabs/Module/Chanview.php:96
-#: ../../Zotlabs/Module/Wall_upload.php:31
-msgid "Channel not found."
+#: ../../Zotlabs/Module/Setup.php:587 ../../Zotlabs/Module/Setup.php:608
+msgid ""
+"Please ensure that the user that your web server runs as (e.g. www-data) has "
+"write access to this folder."
msgstr ""
-#: ../../Zotlabs/Module/Page.php:131
+#: ../../Zotlabs/Module/Setup.php:588
+#, php-format
msgid ""
-"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
-"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
-"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo "
-"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
-"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
-"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
+"Note: as a security measure, you should give the web server write access to "
+"%s only--not the template files (.tpl) that it contains."
msgstr ""
-#: ../../Zotlabs/Module/Filer.php:52
-msgid "Save to Folder:"
+#: ../../Zotlabs/Module/Setup.php:591
+#, php-format
+msgid "%s is writable"
msgstr ""
-#: ../../Zotlabs/Module/Filer.php:52
-msgid "- select -"
+#: ../../Zotlabs/Module/Setup.php:607
+msgid ""
+"This software uses the store directory to save uploaded files. The web "
+"server needs to have write access to the store directory under the top level "
+"web folder"
msgstr ""
-#: ../../Zotlabs/Module/Filer.php:53 ../../Zotlabs/Module/Admin/Profs.php:74
-#: ../../Zotlabs/Module/Admin/Profs.php:94 ../../Zotlabs/Module/Rbmark.php:32
-#: ../../Zotlabs/Module/Rbmark.php:104 ../../include/widgets.php:188
-#: ../../include/text.php:1011 ../../include/text.php:1023
-msgid "Save"
+#: ../../Zotlabs/Module/Setup.php:611
+msgid "store is writable"
msgstr ""
-#: ../../Zotlabs/Module/Ping.php:254
-msgid "sent you a private message"
+#: ../../Zotlabs/Module/Setup.php:644
+msgid ""
+"SSL certificate cannot be validated. Fix certificate or disable https access "
+"to this site."
msgstr ""
-#: ../../Zotlabs/Module/Ping.php:302
-msgid "added your channel"
+#: ../../Zotlabs/Module/Setup.php:645
+msgid ""
+"If you have https access to your website or allow connections to TCP port "
+"443 (the https: port), you MUST use a browser-valid certificate. You MUST "
+"NOT use self-signed certificates!"
msgstr ""
-#: ../../Zotlabs/Module/Ping.php:312
-msgid "g A l F d"
+#: ../../Zotlabs/Module/Setup.php:646
+msgid ""
+"This restriction is incorporated because public posts from you may for "
+"example contain references to images on your own hub."
msgstr ""
-#: ../../Zotlabs/Module/Ping.php:330
-msgid "[today]"
-msgstr ""
-
-#: ../../Zotlabs/Module/Ping.php:339
-msgid "posted an event"
-msgstr ""
-
-#: ../../Zotlabs/Module/Connections.php:56
-#: ../../Zotlabs/Module/Connections.php:161
-#: ../../Zotlabs/Module/Connections.php:250
-msgid "Blocked"
-msgstr ""
-
-#: ../../Zotlabs/Module/Connections.php:61
-#: ../../Zotlabs/Module/Connections.php:168
-#: ../../Zotlabs/Module/Connections.php:249
-msgid "Ignored"
-msgstr ""
-
-#: ../../Zotlabs/Module/Connections.php:66
-#: ../../Zotlabs/Module/Connections.php:182
-#: ../../Zotlabs/Module/Connections.php:248
-msgid "Hidden"
-msgstr ""
-
-#: ../../Zotlabs/Module/Connections.php:71
-#: ../../Zotlabs/Module/Connections.php:175
-#: ../../Zotlabs/Module/Connections.php:247
-msgid "Archived"
-msgstr ""
-
-#: ../../Zotlabs/Module/Connections.php:76
-#: ../../Zotlabs/Module/Connections.php:86 ../../Zotlabs/Module/Menu.php:116
-#: ../../include/conversation.php:1724
-msgid "New"
+#: ../../Zotlabs/Module/Setup.php:647
+msgid ""
+"If your certificate is not recognized, members of other sites (who may "
+"themselves have valid certificates) will get a warning message on their own "
+"site complaining about security issues."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:92
-#: ../../Zotlabs/Module/Connections.php:107
-#: ../../Zotlabs/Module/Connedit.php:720 ../../include/widgets.php:530
-msgid "All"
+#: ../../Zotlabs/Module/Setup.php:648
+msgid ""
+"This can cause usability issues elsewhere (not just on your own site) so we "
+"must insist on this requirement."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:138
-msgid "New Connections"
+#: ../../Zotlabs/Module/Setup.php:649
+msgid ""
+"Providers are available that issue free certificates which are browser-valid."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:141
-msgid "Show pending (new) connections"
+#: ../../Zotlabs/Module/Setup.php:651
+msgid ""
+"If you are confident that the certificate is valid and signed by a trusted "
+"authority, check to see if you have failed to install an intermediate cert. "
+"These are not normally required by browsers, but are required for server-to-"
+"server communications."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:145
-#: ../../Zotlabs/Module/Profperm.php:140
-msgid "All Connections"
+#: ../../Zotlabs/Module/Setup.php:653
+msgid "SSL certificate validation"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:148
-msgid "Show all connections"
+#: ../../Zotlabs/Module/Setup.php:659
+msgid ""
+"Url rewrite in .htaccess is not working. Check your server configuration."
+"Test: "
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:164
-msgid "Only show blocked connections"
+#: ../../Zotlabs/Module/Setup.php:662
+msgid "Url rewrite is working"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:171
-msgid "Only show ignored connections"
+#: ../../Zotlabs/Module/Setup.php:676
+msgid ""
+"The database configuration file \".htconfig.php\" could not be written. "
+"Please use the enclosed text to create a configuration file in your web "
+"server root."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:178
-msgid "Only show archived connections"
+#: ../../Zotlabs/Module/Setup.php:700
+#: ../../extend/addon/addon/cdav/cdav.php:41
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:401
+msgid "Errors encountered creating database tables."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:185
-msgid "Only show hidden connections"
+#: ../../Zotlabs/Module/Setup.php:741
+msgid "
What next
"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:246
-msgid "Pending approval"
+#: ../../Zotlabs/Module/Setup.php:742
+msgid ""
+"IMPORTANT: You will need to [manually] setup a scheduled task for the poller."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:262
-#, php-format
-msgid "%1$s [%2$s]"
+#: ../../Zotlabs/Module/Profiles.php:24 ../../Zotlabs/Module/Profiles.php:184
+#: ../../Zotlabs/Module/Profiles.php:241 ../../Zotlabs/Module/Profiles.php:659
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:62
+msgid "Profile not found."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:263
-msgid "Edit connection"
+#: ../../Zotlabs/Module/Profiles.php:44
+msgid "Profile deleted."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:264
-msgid "Delete connection"
+#: ../../Zotlabs/Module/Profiles.php:68 ../../Zotlabs/Module/Profiles.php:105
+msgid "Profile-"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:273
-msgid "Channel address"
+#: ../../Zotlabs/Module/Profiles.php:90 ../../Zotlabs/Module/Profiles.php:127
+msgid "New profile created."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:275
-msgid "Network"
+#: ../../Zotlabs/Module/Profiles.php:111
+msgid "Profile unavailable to clone."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:278
-msgid "Call"
+#: ../../Zotlabs/Module/Profiles.php:146
+msgid "Profile unavailable to export."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:280
-msgid "Status"
+#: ../../Zotlabs/Module/Profiles.php:252
+msgid "Profile Name is required."
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:282
-msgid "Connected"
+#: ../../Zotlabs/Module/Profiles.php:459
+msgid "Marital Status"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:284
-msgid "Approve connection"
+#: ../../Zotlabs/Module/Profiles.php:463
+msgid "Romantic Partner"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:285
-#: ../../Zotlabs/Module/Admin/Accounts.php:171
-msgid "Approve"
+#: ../../Zotlabs/Module/Profiles.php:467 ../../Zotlabs/Module/Profiles.php:775
+msgid "Likes"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:286
-msgid "Ignore connection"
+#: ../../Zotlabs/Module/Profiles.php:471 ../../Zotlabs/Module/Profiles.php:776
+msgid "Dislikes"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:287
-#: ../../Zotlabs/Module/Connedit.php:637
-msgid "Ignore"
+#: ../../Zotlabs/Module/Profiles.php:475 ../../Zotlabs/Module/Profiles.php:783
+msgid "Work/Employment"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:288
-msgid "Recent activity"
+#: ../../Zotlabs/Module/Profiles.php:478
+msgid "Religion"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:312 ../../Zotlabs/Lib/Apps.php:216
-#: ../../include/nav.php:203 ../../include/text.php:940
-msgid "Connections"
+#: ../../Zotlabs/Module/Profiles.php:482
+msgid "Political Views"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:316 ../../Zotlabs/Module/Search.php:44
-#: ../../Zotlabs/Lib/Apps.php:237 ../../include/widgets.php:302
-#: ../../include/acl_selectors.php:213 ../../include/nav.php:180
-#: ../../include/text.php:1010 ../../include/text.php:1022
-msgid "Search"
+#: ../../Zotlabs/Module/Profiles.php:486
+#: ../../extend/addon/addon/openid/MysqlProvider.php:74
+msgid "Gender"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:317
-msgid "Search your connections"
+#: ../../Zotlabs/Module/Profiles.php:490
+msgid "Sexual Preference"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:318
-msgid "Connections search"
+#: ../../Zotlabs/Module/Profiles.php:494
+msgid "Homepage"
msgstr ""
-#: ../../Zotlabs/Module/Connections.php:319
-#: ../../Zotlabs/Module/Directory.php:392
-#: ../../Zotlabs/Module/Directory.php:397 ../../include/contact_widgets.php:23
-msgid "Find"
+#: ../../Zotlabs/Module/Profiles.php:498
+msgid "Interests"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:58
-#: ../../Zotlabs/Module/Profile_photo.php:61
-msgid "Image uploaded but image cropping failed."
+#: ../../Zotlabs/Module/Profiles.php:502 ../../Zotlabs/Module/Profiles.php:793
+#: ../../Zotlabs/Module/Admin/Channels.php:160
+#: ../../Zotlabs/Module/Locs.php:118 ../../Zotlabs/Module/Connedit.php:920
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1143
+msgid "Address"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:134
-#: ../../Zotlabs/Module/Cover_photo.php:181
-msgid "Cover Photos"
+#: ../../Zotlabs/Module/Profiles.php:509 ../../Zotlabs/Module/Profiles.php:737
+#: ../../Zotlabs/Module/Locs.php:117 ../../Zotlabs/Module/Pubsites.php:51
+#: ../../Zotlabs/Module/Events.php:475
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:839
+#: ../../include/js_strings.php:25
+msgid "Location"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:154
-#: ../../Zotlabs/Module/Profile_photo.php:135
-msgid "Image resize failed."
+#: ../../Zotlabs/Module/Profiles.php:594
+msgid "Profile updated."
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:168
-#: ../../Zotlabs/Module/Profile_photo.php:201 ../../include/photos.php:149
-msgid "Unable to process image"
+#: ../../Zotlabs/Module/Profiles.php:678
+msgid "Hide your connections list from viewers of this profile"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:192
-#: ../../Zotlabs/Module/Profile_photo.php:236
-msgid "Image upload failed."
+#: ../../Zotlabs/Module/Profiles.php:681
+#: ../../Zotlabs/Module/Admin/Site.php:226 ../../Zotlabs/Module/Menu.php:100
+#: ../../Zotlabs/Module/Menu.php:157 ../../Zotlabs/Module/Filestorage.php:160
+#: ../../Zotlabs/Module/Filestorage.php:168
+#: ../../Zotlabs/Module/Connedit.php:402 ../../Zotlabs/Module/Connedit.php:786
+#: ../../Zotlabs/Module/Mitem.php:162 ../../Zotlabs/Module/Mitem.php:163
+#: ../../Zotlabs/Module/Mitem.php:240 ../../Zotlabs/Module/Mitem.php:241
+#: ../../Zotlabs/Module/Api.php:97 ../../Zotlabs/Module/Wiki.php:179
+#: ../../Zotlabs/Module/Events.php:470 ../../Zotlabs/Module/Events.php:471
+#: ../../Zotlabs/Module/Removeme.php:63
+#: ../../Zotlabs/Module/Settings/Display.php:103
+#: ../../Zotlabs/Module/Settings/Channel.php:294
+#: ../../Zotlabs/Module/Photos.php:652
+#: ../../extend/addon/addon/dwpost/dwpost.php:73
+#: ../../extend/addon/addon/dwpost/dwpost.php:85
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:120
+#: ../../extend/addon/addon/friendica/dfrn_request.php:865
+#: ../../extend/addon/addon/ijpost/ijpost.php:73
+#: ../../extend/addon/addon/ijpost/ijpost.php:85
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:309
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:313
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:343
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:351
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:355
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:359
+#: ../../extend/addon/addon/libertree/libertree.php:69
+#: ../../extend/addon/addon/libertree/libertree.php:81
+#: ../../extend/addon/addon/ljpost/ljpost.php:70
+#: ../../extend/addon/addon/ljpost/ljpost.php:82
+#: ../../extend/addon/addon/nofed/nofed.php:72
+#: ../../extend/addon/addon/nofed/nofed.php:76
+#: ../../extend/addon/addon/nsabait/nsabait.php:157
+#: ../../extend/addon/addon/nsfw/nsfw.php:84
+#: ../../extend/addon/addon/planets/planets.php:153
+#: ../../extend/addon/addon/pumpio/pumpio.php:219
+#: ../../extend/addon/addon/pumpio/pumpio.php:223
+#: ../../extend/addon/addon/pumpio/pumpio.php:227
+#: ../../extend/addon/addon/pumpio/pumpio.php:231
+#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:81
+#: ../../extend/addon/addon/redred/redred.php:95
+#: ../../extend/addon/addon/redred/redred.php:99
+#: ../../extend/addon/addon/rtof/rtof.php:81
+#: ../../extend/addon/addon/rtof/rtof.php:85
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:273
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:277
+#: ../../extend/addon/addon/statusnet/statusnet.php:389
+#: ../../extend/addon/addon/statusnet/statusnet.php:411
+#: ../../extend/addon/addon/statusnet/statusnet.php:415
+#: ../../extend/addon/addon/statusnet/statusnet.php:424
+#: ../../extend/addon/addon/twitter/twitter.php:242
+#: ../../extend/addon/addon/twitter/twitter.php:246
+#: ../../extend/addon/addon/twitter/twitter.php:255
+#: ../../extend/addon/addon/visage/visage.php:166
+#: ../../extend/addon/addon/wppost/wppost.php:82
+#: ../../extend/addon/addon/wppost/wppost.php:105
+#: ../../extend/addon/addon/wppost/wppost.php:109
+#: ../../extend/addon/addon/xmpp/xmpp.php:53
+#: ../../extend/addon/addon/cdav/cdav.php:234
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:164
+#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144
+#: ../../include/dir_fns.php:145 ../../view/theme/redbasic/php/config.php:111
+#: ../../view/theme/redbasic/php/config.php:136 ../../boot.php:1710
+msgid "No"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:210
-#: ../../Zotlabs/Module/Profile_photo.php:255
-msgid "Unable to process image."
+#: ../../Zotlabs/Module/Profiles.php:681
+#: ../../Zotlabs/Module/Admin/Site.php:228 ../../Zotlabs/Module/Menu.php:100
+#: ../../Zotlabs/Module/Menu.php:157 ../../Zotlabs/Module/Filestorage.php:160
+#: ../../Zotlabs/Module/Filestorage.php:168
+#: ../../Zotlabs/Module/Connedit.php:402 ../../Zotlabs/Module/Mitem.php:162
+#: ../../Zotlabs/Module/Mitem.php:163 ../../Zotlabs/Module/Mitem.php:240
+#: ../../Zotlabs/Module/Mitem.php:241 ../../Zotlabs/Module/Api.php:96
+#: ../../Zotlabs/Module/Wiki.php:179 ../../Zotlabs/Module/Events.php:470
+#: ../../Zotlabs/Module/Events.php:471 ../../Zotlabs/Module/Removeme.php:63
+#: ../../Zotlabs/Module/Settings/Display.php:103
+#: ../../Zotlabs/Module/Settings/Channel.php:294
+#: ../../Zotlabs/Module/Photos.php:652
+#: ../../extend/addon/addon/dwpost/dwpost.php:73
+#: ../../extend/addon/addon/dwpost/dwpost.php:85
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:120
+#: ../../extend/addon/addon/friendica/dfrn_request.php:865
+#: ../../extend/addon/addon/ijpost/ijpost.php:73
+#: ../../extend/addon/addon/ijpost/ijpost.php:85
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:309
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:313
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:343
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:351
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:355
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:359
+#: ../../extend/addon/addon/libertree/libertree.php:69
+#: ../../extend/addon/addon/libertree/libertree.php:81
+#: ../../extend/addon/addon/ljpost/ljpost.php:70
+#: ../../extend/addon/addon/ljpost/ljpost.php:82
+#: ../../extend/addon/addon/nofed/nofed.php:72
+#: ../../extend/addon/addon/nofed/nofed.php:76
+#: ../../extend/addon/addon/nsabait/nsabait.php:157
+#: ../../extend/addon/addon/nsfw/nsfw.php:84
+#: ../../extend/addon/addon/planets/planets.php:153
+#: ../../extend/addon/addon/pumpio/pumpio.php:219
+#: ../../extend/addon/addon/pumpio/pumpio.php:223
+#: ../../extend/addon/addon/pumpio/pumpio.php:227
+#: ../../extend/addon/addon/pumpio/pumpio.php:231
+#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:81
+#: ../../extend/addon/addon/redred/redred.php:95
+#: ../../extend/addon/addon/redred/redred.php:99
+#: ../../extend/addon/addon/rtof/rtof.php:81
+#: ../../extend/addon/addon/rtof/rtof.php:85
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:273
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:277
+#: ../../extend/addon/addon/statusnet/statusnet.php:389
+#: ../../extend/addon/addon/statusnet/statusnet.php:411
+#: ../../extend/addon/addon/statusnet/statusnet.php:415
+#: ../../extend/addon/addon/statusnet/statusnet.php:424
+#: ../../extend/addon/addon/twitter/twitter.php:242
+#: ../../extend/addon/addon/twitter/twitter.php:246
+#: ../../extend/addon/addon/twitter/twitter.php:255
+#: ../../extend/addon/addon/visage/visage.php:166
+#: ../../extend/addon/addon/wppost/wppost.php:82
+#: ../../extend/addon/addon/wppost/wppost.php:105
+#: ../../extend/addon/addon/wppost/wppost.php:109
+#: ../../extend/addon/addon/xmpp/xmpp.php:53
+#: ../../extend/addon/addon/cdav/cdav.php:234
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:164
+#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144
+#: ../../include/dir_fns.php:145 ../../view/theme/redbasic/php/config.php:111
+#: ../../view/theme/redbasic/php/config.php:136 ../../boot.php:1710
+msgid "Yes"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:233 ../../include/items.php:4278
-msgid "female"
+#: ../../Zotlabs/Module/Profiles.php:725
+msgid "Edit Profile Details"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:234 ../../include/items.php:4279
-#, php-format
-msgid "%1$s updated her %2$s"
+#: ../../Zotlabs/Module/Profiles.php:727
+msgid "View this profile"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:235 ../../include/items.php:4280
-msgid "male"
+#: ../../Zotlabs/Module/Profiles.php:728 ../../Zotlabs/Module/Profiles.php:827
+#: ../../include/channel.php:1066
+msgid "Edit visibility"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:236 ../../include/items.php:4281
-#, php-format
-msgid "%1$s updated his %2$s"
+#: ../../Zotlabs/Module/Profiles.php:729
+msgid "Profile Tools"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:238 ../../include/items.php:4283
-#, php-format
-msgid "%1$s updated their %2$s"
+#: ../../Zotlabs/Module/Profiles.php:730
+msgid "Change cover photo"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:240 ../../include/channel.php:1764
-msgid "cover photo"
+#: ../../Zotlabs/Module/Profiles.php:731 ../../include/channel.php:1037
+msgid "Change profile photo"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:303
-#: ../../Zotlabs/Module/Cover_photo.php:318
-#: ../../Zotlabs/Module/Profile_photo.php:316
-#: ../../Zotlabs/Module/Profile_photo.php:363
-msgid "Photo not available."
+#: ../../Zotlabs/Module/Profiles.php:732
+msgid "Create a new profile using these settings"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:354
-#: ../../Zotlabs/Module/Profile_photo.php:418
-msgid "Upload File:"
+#: ../../Zotlabs/Module/Profiles.php:733
+msgid "Clone this profile"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:355
-#: ../../Zotlabs/Module/Profile_photo.php:419
-msgid "Select a profile:"
+#: ../../Zotlabs/Module/Profiles.php:734
+msgid "Delete this profile"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:356
-msgid "Upload Cover Photo"
+#: ../../Zotlabs/Module/Profiles.php:735
+msgid "Add profile things"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:361
-#: ../../Zotlabs/Module/Profile_photo.php:427
-#: ../../Zotlabs/Module/Settings/Channel.php:404
-msgid "or"
+#: ../../Zotlabs/Module/Profiles.php:736 ../../include/conversation.php:1715
+msgid "Personal"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:361
-#: ../../Zotlabs/Module/Profile_photo.php:427
-msgid "skip this step"
+#: ../../Zotlabs/Module/Profiles.php:738
+msgid "Relation"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:361
-#: ../../Zotlabs/Module/Profile_photo.php:427
-msgid "select a photo from your photo albums"
+#: ../../Zotlabs/Module/Profiles.php:739 ../../include/datetime.php:55
+msgid "Miscellaneous"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:377
-#: ../../Zotlabs/Module/Profile_photo.php:446
-msgid "Crop Image"
+#: ../../Zotlabs/Module/Profiles.php:741
+msgid "Import profile from file"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:378
-#: ../../Zotlabs/Module/Profile_photo.php:447
-msgid "Please adjust the image cropping for optimum viewing."
+#: ../../Zotlabs/Module/Profiles.php:742
+msgid "Export profile to file"
msgstr ""
-#: ../../Zotlabs/Module/Cover_photo.php:380
-#: ../../Zotlabs/Module/Profile_photo.php:449
-msgid "Done Editing"
+#: ../../Zotlabs/Module/Profiles.php:743
+msgid "Your gender"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Features.php:55
-#: ../../Zotlabs/Module/Admin/Features.php:56
-#: ../../Zotlabs/Module/Settings/Features.php:38
-msgid "Off"
+#: ../../Zotlabs/Module/Profiles.php:744
+msgid "Marital status"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Features.php:55
-#: ../../Zotlabs/Module/Admin/Features.php:56
-#: ../../Zotlabs/Module/Settings/Features.php:38
-msgid "On"
+#: ../../Zotlabs/Module/Profiles.php:745
+msgid "Sexual preference"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Features.php:56
-#, php-format
-msgid "Lock feature %s"
+#: ../../Zotlabs/Module/Profiles.php:748
+msgid "Profile name"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Features.php:64
-msgid "Manage Additional Features"
+#: ../../Zotlabs/Module/Profiles.php:748 ../../Zotlabs/Module/Profiles.php:752
+#: ../../Zotlabs/Module/Appman.php:122 ../../Zotlabs/Module/Appman.php:123
+#: ../../Zotlabs/Module/Events.php:460 ../../Zotlabs/Module/Events.php:465
+#: ../../include/datetime.php:259
+msgid "Required"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:28
-msgid "Log settings updated."
+#: ../../Zotlabs/Module/Profiles.php:750
+msgid "This is your default profile."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:83 ../../include/widgets.php:1661
-#: ../../include/widgets.php:1671
-msgid "Logs"
+#: ../../Zotlabs/Module/Profiles.php:752
+msgid "Your full name"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:85
-msgid "Clear"
+#: ../../Zotlabs/Module/Profiles.php:753
+msgid "Title/Description"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:91
-msgid "Debugging"
+#: ../../Zotlabs/Module/Profiles.php:756
+msgid "Street address"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:92
-msgid "Log file"
+#: ../../Zotlabs/Module/Profiles.php:757
+msgid "Locality/City"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:92
-msgid ""
-"Must be writable by web server. Relative to your top-level webserver "
-"directory."
+#: ../../Zotlabs/Module/Profiles.php:758
+msgid "Region/State"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Logs.php:93
-msgid "Log level"
+#: ../../Zotlabs/Module/Profiles.php:759
+msgid "Postal/Zip code"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:69
-msgid "New Profile Field"
+#: ../../Zotlabs/Module/Profiles.php:760 ../../Zotlabs/Module/Connedit.php:938
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1161
+msgid "Country"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:70
-#: ../../Zotlabs/Module/Admin/Profs.php:90
-msgid "Field nickname"
+#: ../../Zotlabs/Module/Profiles.php:765
+msgid "Who (if applicable)"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:70
-#: ../../Zotlabs/Module/Admin/Profs.php:90
-msgid "System name of field"
+#: ../../Zotlabs/Module/Profiles.php:765
+msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:71
-#: ../../Zotlabs/Module/Admin/Profs.php:91
-msgid "Input type"
+#: ../../Zotlabs/Module/Profiles.php:766
+msgid "Since (date)"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:72
-#: ../../Zotlabs/Module/Admin/Profs.php:92
-msgid "Field Name"
+#: ../../Zotlabs/Module/Profiles.php:769
+msgid "Tell us about yourself"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:72
-#: ../../Zotlabs/Module/Admin/Profs.php:92
-msgid "Label on profile pages"
+#: ../../Zotlabs/Module/Profiles.php:770
+#: ../../extend/addon/addon/openid/MysqlProvider.php:68
+msgid "Homepage URL"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:73
-#: ../../Zotlabs/Module/Admin/Profs.php:93
-msgid "Help text"
+#: ../../Zotlabs/Module/Profiles.php:771
+msgid "Hometown"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:73
-#: ../../Zotlabs/Module/Admin/Profs.php:93
-msgid "Additional info (optional)"
+#: ../../Zotlabs/Module/Profiles.php:772
+msgid "Political views"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:83
-msgid "Field definition not found"
+#: ../../Zotlabs/Module/Profiles.php:773
+msgid "Religious views"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:89
-msgid "Edit Profile Field"
+#: ../../Zotlabs/Module/Profiles.php:774
+msgid "Keywords used in directory listings"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:147 ../../include/widgets.php:1642
-msgid "Profile Fields"
+#: ../../Zotlabs/Module/Profiles.php:774
+msgid "Example: fishing photography software"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:148
-msgid "Basic Profile Fields"
+#: ../../Zotlabs/Module/Profiles.php:777
+msgid "Musical interests"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:149
-msgid "Advanced Profile Fields"
+#: ../../Zotlabs/Module/Profiles.php:778
+msgid "Books, literature"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:149
-msgid "(In addition to basic fields)"
+#: ../../Zotlabs/Module/Profiles.php:779
+msgid "Television"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:151
-msgid "All available fields"
-msgstr ""
+#: ../../Zotlabs/Module/Profiles.php:780
+msgid "Film/Dance/Culture/Entertainment"
+msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:152
-msgid "Custom Fields"
+#: ../../Zotlabs/Module/Profiles.php:781
+msgid "Hobbies/Interests"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Profs.php:156
-msgid "Create Custom Field"
+#: ../../Zotlabs/Module/Profiles.php:782
+msgid "Love/Romance"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:77
-msgid ""
-"By default, unfiltered HTML is allowed in embedded media. This is inherently "
-"insecure."
+#: ../../Zotlabs/Module/Profiles.php:784
+msgid "School/Education"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:80
-msgid ""
-"The recommended setting is to only allow unfiltered HTML from the following "
-"sites:"
+#: ../../Zotlabs/Module/Profiles.php:785
+msgid "Contact information and social networks"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:81
-msgid ""
-"https://youtube.com/ https://www.youtube.com/ https://youtu.be/"
-" https://vimeo.com/ https://soundcloud.com/ "
+#: ../../Zotlabs/Module/Profiles.php:786
+msgid "My other channels"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:82
-msgid ""
-"All other embedded content will be filtered, unless "
-"embedded content from that site is explicitly blocked."
+#: ../../Zotlabs/Module/Profiles.php:788
+msgid "Communications"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:87 ../../include/widgets.php:1637
-msgid "Security"
+#: ../../Zotlabs/Module/Profiles.php:789 ../../Zotlabs/Module/Connedit.php:916
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1139
+msgid "Phone"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:89
-msgid "Block public"
+#: ../../Zotlabs/Module/Profiles.php:790
+#: ../../Zotlabs/Module/Admin/Accounts.php:169
+#: ../../Zotlabs/Module/Admin/Accounts.php:181
+#: ../../Zotlabs/Module/Connedit.php:917
+#: ../../extend/addon/addon/redred/redred.php:107
+#: ../../extend/addon/addon/rtof/rtof.php:93
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1140
+#: ../../extend/addon/addon/openid/MysqlProvider.php:56
+#: ../../extend/addon/addon/openid/MysqlProvider.php:57
+#: ../../include/network.php:1749
+msgid "Email"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:89
-msgid ""
-"Check to block public access to all otherwise public personal pages on this "
-"site unless you are currently authenticated."
+#: ../../Zotlabs/Module/Profiles.php:791 ../../Zotlabs/Module/Connedit.php:918
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1141
+msgid "Instant messenger"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:90
-msgid "Set \"Transport Security\" HTTP header"
+#: ../../Zotlabs/Module/Profiles.php:792 ../../Zotlabs/Module/Connedit.php:919
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1142
+msgid "Website"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:91
-msgid "Set \"Content Security Policy\" HTTP header"
+#: ../../Zotlabs/Module/Profiles.php:794 ../../Zotlabs/Module/Connedit.php:921
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1144
+msgid "Note"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:92
-msgid "Allowed email domains"
+#: ../../Zotlabs/Module/Profiles.php:795 ../../Zotlabs/Module/Connedit.php:922
+#: ../../extend/addon/addon/cdav/cdav.php:270
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1145
+#: ../../include/connections.php:668
+msgid "Mobile"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:92
-msgid ""
-"Comma separated list of domains which are allowed in email addresses for "
-"registrations to this site. Wildcards are accepted. Empty to allow any "
-"domains"
+#: ../../Zotlabs/Module/Profiles.php:796 ../../Zotlabs/Module/Connedit.php:923
+#: ../../extend/addon/addon/cdav/cdav.php:271
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1146
+#: ../../include/connections.php:669
+msgid "Home"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:93
-msgid "Not allowed email domains"
+#: ../../Zotlabs/Module/Profiles.php:797 ../../Zotlabs/Module/Connedit.php:924
+#: ../../extend/addon/addon/cdav/cdav.php:274
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1147
+#: ../../include/connections.php:672
+msgid "Work"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:93
-msgid ""
-"Comma separated list of domains which are not allowed in email addresses for "
-"registrations to this site. Wildcards are accepted. Empty to allow any "
-"domains, unless allowed domains have been defined."
+#: ../../Zotlabs/Module/Profiles.php:799 ../../Zotlabs/Module/Connedit.php:926
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:368
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1149
+msgid "Add Contact"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:94
-msgid "Allow communications only from these sites"
+#: ../../Zotlabs/Module/Profiles.php:800 ../../Zotlabs/Module/Connedit.php:927
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1150
+msgid "Add Field"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:94
-msgid ""
-"One site per line. Leave empty to allow communication from anywhere by "
-"default"
+#: ../../Zotlabs/Module/Profiles.php:802
+#: ../../Zotlabs/Module/Admin/Plugins.php:453
+#: ../../Zotlabs/Module/Connedit.php:929
+#: ../../Zotlabs/Module/Settings/Oauth.php:42
+#: ../../Zotlabs/Module/Settings/Oauth.php:113 ../../Zotlabs/Lib/Apps.php:348
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1152
+msgid "Update"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:95
-msgid "Block communications from these sites"
+#: ../../Zotlabs/Module/Profiles.php:804
+#: ../../Zotlabs/Module/Admin/Plugins.php:423
+#: ../../Zotlabs/Module/Fbrowser.php:66 ../../Zotlabs/Module/Fbrowser.php:88
+#: ../../Zotlabs/Module/Connedit.php:931 ../../Zotlabs/Module/Wiki.php:261
+#: ../../Zotlabs/Module/Wiki.php:286
+#: ../../Zotlabs/Module/Settings/Oauth.php:88
+#: ../../Zotlabs/Module/Settings/Oauth.php:114
+#: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138
+#: ../../extend/addon/addon/friendica/dfrn_request.php:879
+#: ../../extend/addon/addon/js_upload/js_upload.php:46
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:866
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1154
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:243
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:266
+#: ../../include/conversation.php:1394 ../../include/conversation.php:1443
+msgid "Cancel"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:96
-msgid "Allow communications only from these channels"
+#: ../../Zotlabs/Module/Profiles.php:823 ../../include/channel.php:1062
+msgid "Profile Image"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:96
-msgid ""
-"One channel (hash) per line. Leave empty to allow from any channel by default"
+#: ../../Zotlabs/Module/Profiles.php:833 ../../include/channel.php:1044
+#: ../../include/nav.php:105
+msgid "Edit Profiles"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:97
-msgid "Block communications from these channels"
+#: ../../Zotlabs/Module/Help.php:23
+msgid "Documentation Search"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:98
-msgid "Only allow embeds from secure (SSL) websites and links."
+#: ../../Zotlabs/Module/Help.php:80 ../../include/conversation.php:1827
+msgid "About"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:99
-msgid "Allow unfiltered embedded HTML content only from these domains"
+#: ../../Zotlabs/Module/Help.php:81 ../../Zotlabs/Module/Group.php:197
+msgid "Members"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:99
-msgid "One site per line. By default embedded content is filtered."
+#: ../../Zotlabs/Module/Help.php:82
+msgid "Administrators"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Security.php:100
-msgid "Block embedded HTML from these domains"
+#: ../../Zotlabs/Module/Help.php:83
+msgid "Developers"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:29
-#, php-format
-msgid "Password changed for account %d."
+#: ../../Zotlabs/Module/Help.php:84
+msgid "Tutorials"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:46
-msgid "Account settings updated."
+#: ../../Zotlabs/Module/Help.php:93
+msgid "$Projectname Documentation"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:61
-msgid "Account not found."
+#: ../../Zotlabs/Module/Help.php:94
+msgid "Contents"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:68
-msgid "Account Edit"
+#: ../../Zotlabs/Module/Bookmarks.php:53
+msgid "Bookmark added"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:69
-msgid "New Password"
+#: ../../Zotlabs/Module/Bookmarks.php:75
+msgid "My Bookmarks"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:70
-msgid "New Password again"
+#: ../../Zotlabs/Module/Bookmarks.php:86
+msgid "My Connections Bookmarks"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:71
-msgid "Technical skill level"
+#: ../../Zotlabs/Module/Connect.php:61 ../../Zotlabs/Module/Connect.php:109
+msgid "Continue"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:72
-msgid "Account language (for emails)"
+#: ../../Zotlabs/Module/Connect.php:90
+msgid "Premium Channel Setup"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Account_edit.php:73
-msgid "Service class"
+#: ../../Zotlabs/Module/Connect.php:92
+msgid "Enable premium channel connection restrictions"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:36
-#, php-format
-msgid "%s account blocked/unblocked"
-msgid_plural "%s account blocked/unblocked"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../Zotlabs/Module/Connect.php:93
+msgid ""
+"Please enter your restrictions or conditions, such as paypal receipt, usage "
+"guidelines, etc."
+msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:43
-#, php-format
-msgid "%s account deleted"
-msgid_plural "%s accounts deleted"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../Zotlabs/Module/Connect.php:95 ../../Zotlabs/Module/Connect.php:115
+msgid ""
+"This channel may require additional steps or acknowledgement of the "
+"following conditions prior to connecting:"
+msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:79
-msgid "Account not found"
+#: ../../Zotlabs/Module/Connect.php:96
+msgid ""
+"Potential connections will then see the following text before proceeding:"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:90
-#, php-format
-msgid "Account '%s' deleted"
+#: ../../Zotlabs/Module/Connect.php:97 ../../Zotlabs/Module/Connect.php:118
+msgid ""
+"By continuing, I certify that I have complied with any instructions provided "
+"on this page."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:98
-#, php-format
-msgid "Account '%s' blocked"
+#: ../../Zotlabs/Module/Connect.php:106
+msgid "(No specific instructions have been provided by the channel owner.)"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:106
-#, php-format
-msgid "Account '%s' unblocked"
+#: ../../Zotlabs/Module/Connect.php:114
+msgid "Restricted or Premium Channel"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:165
-#: ../../Zotlabs/Module/Admin/Accounts.php:178 ../../include/widgets.php:1635
-msgid "Accounts"
+#: ../../Zotlabs/Module/Admin.php:60
+#: ../../Zotlabs/Module/Admin/Plugins.php:259
+#: ../../Zotlabs/Module/Admin/Themes.php:72
+#: ../../Zotlabs/Module/Filestorage.php:32 ../../Zotlabs/Module/Display.php:35
+#: ../../Zotlabs/Module/Viewsrc.php:24 ../../Zotlabs/Module/Thing.php:89
+#: ../../include/items.php:3271
+msgid "Item not found."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:167
-#: ../../Zotlabs/Module/Admin/Channels.php:148
-msgid "select all"
+#: ../../Zotlabs/Module/Admin.php:94
+msgid "# Accounts"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:168
-msgid "Registrations waiting for confirm"
+#: ../../Zotlabs/Module/Admin.php:95
+msgid "# blocked accounts"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:169
-msgid "Request date"
+#: ../../Zotlabs/Module/Admin.php:96
+msgid "# expired accounts"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:169
-#: ../../Zotlabs/Module/Admin/Accounts.php:181
-#: ../../Zotlabs/Module/Connedit.php:917 ../../Zotlabs/Module/Profiles.php:790
-#: ../../extend/addon/addon/redred/redred.php:107
-#: ../../extend/addon/addon/rtof/rtof.php:93
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1140
-#: ../../extend/addon/addon/openid/MysqlProvider.php:56
-#: ../../extend/addon/addon/openid/MysqlProvider.php:57
-#: ../../include/network.php:2270
-msgid "Email"
+#: ../../Zotlabs/Module/Admin.php:97
+msgid "# expiring accounts"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:170
-msgid "No registrations."
+#: ../../Zotlabs/Module/Admin.php:108
+msgid "# Channels"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:172
-msgid "Deny"
+#: ../../Zotlabs/Module/Admin.php:109
+msgid "# primary"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:174
-#: ../../Zotlabs/Module/Connedit.php:629
-msgid "Block"
+#: ../../Zotlabs/Module/Admin.php:110
+msgid "# clones"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:175
-#: ../../Zotlabs/Module/Connedit.php:629
-msgid "Unblock"
+#: ../../Zotlabs/Module/Admin.php:116
+msgid "Message queues"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:180
-msgid "ID"
+#: ../../Zotlabs/Module/Admin.php:133
+msgid "Your software should be updated"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:182 ../../include/group.php:287
-msgid "All Channels"
+#: ../../Zotlabs/Module/Admin.php:137 ../../Zotlabs/Module/Admin/Logs.php:82
+#: ../../Zotlabs/Module/Admin/Security.php:86
+#: ../../Zotlabs/Module/Admin/Accounts.php:164
+#: ../../Zotlabs/Module/Admin/Channels.php:145
+#: ../../Zotlabs/Module/Admin/Site.php:266
+#: ../../Zotlabs/Module/Admin/Plugins.php:341
+#: ../../Zotlabs/Module/Admin/Plugins.php:436
+#: ../../Zotlabs/Module/Admin/Themes.php:122
+#: ../../Zotlabs/Module/Admin/Themes.php:156
+msgid "Administration"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:183
-msgid "Register date"
+#: ../../Zotlabs/Module/Admin.php:138
+msgid "Summary"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:184
-msgid "Last login"
+#: ../../Zotlabs/Module/Admin.php:141
+msgid "Registered accounts"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:185
-msgid "Expires"
+#: ../../Zotlabs/Module/Admin.php:142
+msgid "Pending registrations"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:186
-msgid "Service Class"
+#: ../../Zotlabs/Module/Admin.php:143
+msgid "Registered channels"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:188
-msgid ""
-"Selected accounts will be deleted!\\n\\nEverything these accounts had posted "
-"on this site will be permanently deleted!\\n\\nAre you sure?"
+#: ../../Zotlabs/Module/Admin.php:144
+msgid "Active plugins"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Accounts.php:189
-msgid ""
-"The account {0} will be deleted!\\n\\nEverything this account has posted on "
-"this site will be permanently deleted!\\n\\nAre you sure?"
+#: ../../Zotlabs/Module/Admin.php:145
+msgid "Version"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:31
-#, php-format
-msgid "%s channel censored/uncensored"
-msgid_plural "%s channels censored/uncensored"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../Zotlabs/Module/Admin.php:146
+msgid "Repository version (master)"
+msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:40
-#, php-format
-msgid "%s channel code allowed/disallowed"
-msgid_plural "%s channels code allowed/disallowed"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../Zotlabs/Module/Admin.php:147
+msgid "Repository version (dev)"
+msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:46
-#, php-format
-msgid "%s channel deleted"
-msgid_plural "%s channels deleted"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../Zotlabs/Module/Editblock.php:79 ../../Zotlabs/Module/Editblock.php:95
+#: ../../Zotlabs/Module/Editlayout.php:79
+#: ../../Zotlabs/Module/Editwebpage.php:80
+#: ../../Zotlabs/Module/Editpost.php:24
+msgid "Item not found"
+msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:65
-msgid "Channel not found"
+#: ../../Zotlabs/Module/Editblock.php:108 ../../Zotlabs/Module/Blocks.php:97
+#: ../../Zotlabs/Module/Blocks.php:155
+msgid "Block Name"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:75
-#, php-format
-msgid "Channel '%s' deleted"
+#: ../../Zotlabs/Module/Editblock.php:124 ../../include/conversation.php:1406
+msgid "Title (optional)"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:87
-#, php-format
-msgid "Channel '%s' censored"
+#: ../../Zotlabs/Module/Editblock.php:133
+msgid "Edit Block"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:87
-#, php-format
-msgid "Channel '%s' uncensored"
+#: ../../Zotlabs/Module/Page.php:40 ../../Zotlabs/Module/Block.php:31
+msgid "Invalid item."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:98
-#, php-format
-msgid "Channel '%s' code allowed"
+#: ../../Zotlabs/Module/Page.php:56 ../../Zotlabs/Module/Cal.php:62
+#: ../../Zotlabs/Module/Block.php:43 ../../Zotlabs/Module/Chanview.php:96
+#: ../../Zotlabs/Module/Wall_upload.php:31
+msgid "Channel not found."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:98
-#, php-format
-msgid "Channel '%s' code disallowed"
+#: ../../Zotlabs/Module/Page.php:131
+msgid ""
+"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
+"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
+"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo "
+"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse "
+"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat "
+"non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:146 ../../include/widgets.php:1636
-msgid "Channels"
+#: ../../Zotlabs/Module/Filer.php:52
+msgid "Save to Folder:"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:150
-msgid "Censor"
+#: ../../Zotlabs/Module/Filer.php:52
+msgid "- select -"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:151
-msgid "Uncensor"
+#: ../../Zotlabs/Module/Filer.php:53 ../../Zotlabs/Module/Admin/Profs.php:74
+#: ../../Zotlabs/Module/Admin/Profs.php:94 ../../Zotlabs/Module/Rbmark.php:32
+#: ../../Zotlabs/Module/Rbmark.php:104 ../../include/widgets.php:188
+#: ../../include/text.php:1011 ../../include/text.php:1023
+msgid "Save"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:152
-msgid "Allow Code"
+#: ../../Zotlabs/Module/Ping.php:254
+msgid "sent you a private message"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:153
-msgid "Disallow Code"
+#: ../../Zotlabs/Module/Ping.php:302
+msgid "added your channel"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:154
-#: ../../include/conversation.php:1815
-msgid "Channel"
+#: ../../Zotlabs/Module/Ping.php:312
+msgid "g A l F d"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:158
-msgid "UID"
+#: ../../Zotlabs/Module/Ping.php:330
+msgid "[today]"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:160
-#: ../../Zotlabs/Module/Locs.php:118 ../../Zotlabs/Module/Connedit.php:920
-#: ../../Zotlabs/Module/Profiles.php:502 ../../Zotlabs/Module/Profiles.php:793
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1143
-msgid "Address"
+#: ../../Zotlabs/Module/Ping.php:339
+msgid "posted an event"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:162
-msgid ""
-"Selected channels will be deleted!\\n\\nEverything that was posted in these "
-"channels on this site will be permanently deleted!\\n\\nAre you sure?"
+#: ../../Zotlabs/Module/Connections.php:56
+#: ../../Zotlabs/Module/Connections.php:161
+#: ../../Zotlabs/Module/Connections.php:250
+msgid "Blocked"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Channels.php:163
-msgid ""
-"The channel {0} will be deleted!\\n\\nEverything that was posted in this "
-"channel on this site will be permanently deleted!\\n\\nAre you sure?"
+#: ../../Zotlabs/Module/Connections.php:61
+#: ../../Zotlabs/Module/Connections.php:168
+#: ../../Zotlabs/Module/Connections.php:249
+msgid "Ignored"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:19
-msgid "Update has been marked successful"
+#: ../../Zotlabs/Module/Connections.php:66
+#: ../../Zotlabs/Module/Connections.php:182
+#: ../../Zotlabs/Module/Connections.php:248
+msgid "Hidden"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:29
-#, php-format
-msgid "Executing %s failed. Check system logs."
+#: ../../Zotlabs/Module/Connections.php:71
+#: ../../Zotlabs/Module/Connections.php:175
+#: ../../Zotlabs/Module/Connections.php:247
+msgid "Archived"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:32
-#, php-format
-msgid "Update %s was successfully applied."
+#: ../../Zotlabs/Module/Connections.php:76
+#: ../../Zotlabs/Module/Connections.php:86 ../../Zotlabs/Module/Menu.php:116
+#: ../../include/conversation.php:1724
+msgid "New"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:36
-#, php-format
-msgid "Update %s did not return a status. Unknown if it succeeded."
+#: ../../Zotlabs/Module/Connections.php:92
+#: ../../Zotlabs/Module/Connections.php:107
+#: ../../Zotlabs/Module/Connedit.php:720 ../../include/widgets.php:530
+msgid "All"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:39
-#, php-format
-msgid "Update function %s could not be found."
+#: ../../Zotlabs/Module/Connections.php:138
+msgid "New Connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:55
-msgid "No failed updates."
+#: ../../Zotlabs/Module/Connections.php:141
+msgid "Show pending (new) connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:59
-msgid "Failed Updates"
+#: ../../Zotlabs/Module/Connections.php:145
+#: ../../Zotlabs/Module/Profperm.php:140
+msgid "All Connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:61
-msgid "Mark success (if update was manually applied)"
+#: ../../Zotlabs/Module/Connections.php:148
+msgid "Show all connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Dbsync.php:62
-msgid "Attempt to execute this update step automatically"
+#: ../../Zotlabs/Module/Connections.php:164
+msgid "Only show blocked connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:35
-msgid "Queue Statistics"
+#: ../../Zotlabs/Module/Connections.php:171
+msgid "Only show ignored connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:36
-msgid "Total Entries"
+#: ../../Zotlabs/Module/Connections.php:178
+msgid "Only show archived connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:37
-msgid "Priority"
+#: ../../Zotlabs/Module/Connections.php:185
+msgid "Only show hidden connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:38
-msgid "Destination URL"
+#: ../../Zotlabs/Module/Connections.php:246
+msgid "Pending approval"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:39
-msgid "Mark hub permanently offline"
+#: ../../Zotlabs/Module/Connections.php:262
+#, php-format
+msgid "%1$s [%2$s]"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:40
-msgid "Empty queue for this hub"
+#: ../../Zotlabs/Module/Connections.php:263
+msgid "Edit connection"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Queue.php:41
-msgid "Last known contact"
+#: ../../Zotlabs/Module/Connections.php:264
+msgid "Delete connection"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:133
-msgid "Site settings updated."
+#: ../../Zotlabs/Module/Connections.php:273
+msgid "Channel address"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:159 ../../include/text.php:2936
-msgid "Default"
+#: ../../Zotlabs/Module/Connections.php:275
+msgid "Network"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:170
-#: ../../Zotlabs/Module/Settings/Display.php:137
-#, php-format
-msgid "%s - (Incompatible)"
+#: ../../Zotlabs/Module/Connections.php:278
+msgid "Call"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:177
-#: ../../Zotlabs/Module/Settings/Display.php:151
-msgid "mobile"
+#: ../../Zotlabs/Module/Connections.php:280
+msgid "Status"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:179
-msgid "experimental"
+#: ../../Zotlabs/Module/Connections.php:282
+msgid "Connected"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:181
-msgid "unsupported"
+#: ../../Zotlabs/Module/Connections.php:284
+msgid "Approve connection"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:226 ../../Zotlabs/Module/Menu.php:100
-#: ../../Zotlabs/Module/Menu.php:157 ../../Zotlabs/Module/Connedit.php:402
-#: ../../Zotlabs/Module/Connedit.php:786 ../../Zotlabs/Module/Events.php:470
-#: ../../Zotlabs/Module/Events.php:471
-#: ../../Zotlabs/Module/Filestorage.php:160
-#: ../../Zotlabs/Module/Filestorage.php:168
-#: ../../Zotlabs/Module/Photos.php:652 ../../Zotlabs/Module/Mitem.php:162
-#: ../../Zotlabs/Module/Mitem.php:163 ../../Zotlabs/Module/Mitem.php:240
-#: ../../Zotlabs/Module/Mitem.php:241 ../../Zotlabs/Module/Api.php:97
-#: ../../Zotlabs/Module/Removeme.php:63 ../../Zotlabs/Module/Profiles.php:681
-#: ../../Zotlabs/Module/Settings/Channel.php:294
-#: ../../Zotlabs/Module/Settings/Display.php:103
-#: ../../Zotlabs/Module/Wiki.php:179
-#: ../../extend/addon/addon/dwpost/dwpost.php:73
-#: ../../extend/addon/addon/dwpost/dwpost.php:85
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:120
-#: ../../extend/addon/addon/friendica/dfrn_request.php:865
-#: ../../extend/addon/addon/ijpost/ijpost.php:73
-#: ../../extend/addon/addon/ijpost/ijpost.php:85
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:309
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:313
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:343
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:351
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:355
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:359
-#: ../../extend/addon/addon/libertree/libertree.php:69
-#: ../../extend/addon/addon/libertree/libertree.php:81
-#: ../../extend/addon/addon/ljpost/ljpost.php:70
-#: ../../extend/addon/addon/ljpost/ljpost.php:82
-#: ../../extend/addon/addon/nofed/nofed.php:72
-#: ../../extend/addon/addon/nofed/nofed.php:76
-#: ../../extend/addon/addon/nsabait/nsabait.php:157
-#: ../../extend/addon/addon/nsfw/nsfw.php:84
-#: ../../extend/addon/addon/planets/planets.php:153
-#: ../../extend/addon/addon/pumpio/pumpio.php:219
-#: ../../extend/addon/addon/pumpio/pumpio.php:223
-#: ../../extend/addon/addon/pumpio/pumpio.php:227
-#: ../../extend/addon/addon/pumpio/pumpio.php:231
-#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:81
-#: ../../extend/addon/addon/redred/redred.php:95
-#: ../../extend/addon/addon/redred/redred.php:99
-#: ../../extend/addon/addon/rtof/rtof.php:81
-#: ../../extend/addon/addon/rtof/rtof.php:85
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:273
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:277
-#: ../../extend/addon/addon/statusnet/statusnet.php:389
-#: ../../extend/addon/addon/statusnet/statusnet.php:411
-#: ../../extend/addon/addon/statusnet/statusnet.php:415
-#: ../../extend/addon/addon/statusnet/statusnet.php:424
-#: ../../extend/addon/addon/twitter/twitter.php:242
-#: ../../extend/addon/addon/twitter/twitter.php:246
-#: ../../extend/addon/addon/twitter/twitter.php:255
-#: ../../extend/addon/addon/visage/visage.php:166
-#: ../../extend/addon/addon/wppost/wppost.php:82
-#: ../../extend/addon/addon/wppost/wppost.php:105
-#: ../../extend/addon/addon/wppost/wppost.php:109
-#: ../../extend/addon/addon/xmpp/xmpp.php:53
-#: ../../extend/addon/addon/cdav/cdav.php:234
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:164
-#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144
-#: ../../include/dir_fns.php:145 ../../view/theme/redbasic/php/config.php:111
-#: ../../view/theme/redbasic/php/config.php:136 ../../boot.php:1753
-msgid "No"
+#: ../../Zotlabs/Module/Connections.php:285
+#: ../../Zotlabs/Module/Admin/Accounts.php:171
+msgid "Approve"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:227
-msgid "Yes - with approval"
+#: ../../Zotlabs/Module/Connections.php:286
+msgid "Ignore connection"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:228 ../../Zotlabs/Module/Menu.php:100
-#: ../../Zotlabs/Module/Menu.php:157 ../../Zotlabs/Module/Connedit.php:402
-#: ../../Zotlabs/Module/Events.php:470 ../../Zotlabs/Module/Events.php:471
-#: ../../Zotlabs/Module/Filestorage.php:160
-#: ../../Zotlabs/Module/Filestorage.php:168
-#: ../../Zotlabs/Module/Photos.php:652 ../../Zotlabs/Module/Mitem.php:162
-#: ../../Zotlabs/Module/Mitem.php:163 ../../Zotlabs/Module/Mitem.php:240
-#: ../../Zotlabs/Module/Mitem.php:241 ../../Zotlabs/Module/Api.php:96
-#: ../../Zotlabs/Module/Removeme.php:63 ../../Zotlabs/Module/Profiles.php:681
-#: ../../Zotlabs/Module/Settings/Channel.php:294
-#: ../../Zotlabs/Module/Settings/Display.php:103
-#: ../../Zotlabs/Module/Wiki.php:179
-#: ../../extend/addon/addon/dwpost/dwpost.php:73
-#: ../../extend/addon/addon/dwpost/dwpost.php:85
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:120
-#: ../../extend/addon/addon/friendica/dfrn_request.php:865
-#: ../../extend/addon/addon/ijpost/ijpost.php:73
-#: ../../extend/addon/addon/ijpost/ijpost.php:85
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:309
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:313
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:343
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:351
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:355
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:359
-#: ../../extend/addon/addon/libertree/libertree.php:69
-#: ../../extend/addon/addon/libertree/libertree.php:81
-#: ../../extend/addon/addon/ljpost/ljpost.php:70
-#: ../../extend/addon/addon/ljpost/ljpost.php:82
-#: ../../extend/addon/addon/nofed/nofed.php:72
-#: ../../extend/addon/addon/nofed/nofed.php:76
-#: ../../extend/addon/addon/nsabait/nsabait.php:157
-#: ../../extend/addon/addon/nsfw/nsfw.php:84
-#: ../../extend/addon/addon/planets/planets.php:153
-#: ../../extend/addon/addon/pumpio/pumpio.php:219
-#: ../../extend/addon/addon/pumpio/pumpio.php:223
-#: ../../extend/addon/addon/pumpio/pumpio.php:227
-#: ../../extend/addon/addon/pumpio/pumpio.php:231
-#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:81
-#: ../../extend/addon/addon/redred/redred.php:95
-#: ../../extend/addon/addon/redred/redred.php:99
-#: ../../extend/addon/addon/rtof/rtof.php:81
-#: ../../extend/addon/addon/rtof/rtof.php:85
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:273
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:277
-#: ../../extend/addon/addon/statusnet/statusnet.php:389
-#: ../../extend/addon/addon/statusnet/statusnet.php:411
-#: ../../extend/addon/addon/statusnet/statusnet.php:415
-#: ../../extend/addon/addon/statusnet/statusnet.php:424
-#: ../../extend/addon/addon/twitter/twitter.php:242
-#: ../../extend/addon/addon/twitter/twitter.php:246
-#: ../../extend/addon/addon/twitter/twitter.php:255
-#: ../../extend/addon/addon/visage/visage.php:166
-#: ../../extend/addon/addon/wppost/wppost.php:82
-#: ../../extend/addon/addon/wppost/wppost.php:105
-#: ../../extend/addon/addon/wppost/wppost.php:109
-#: ../../extend/addon/addon/xmpp/xmpp.php:53
-#: ../../extend/addon/addon/cdav/cdav.php:234
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:164
-#: ../../include/dir_fns.php:143 ../../include/dir_fns.php:144
-#: ../../include/dir_fns.php:145 ../../view/theme/redbasic/php/config.php:111
-#: ../../view/theme/redbasic/php/config.php:136 ../../boot.php:1753
-msgid "Yes"
+#: ../../Zotlabs/Module/Connections.php:287
+#: ../../Zotlabs/Module/Connedit.php:637
+msgid "Ignore"
+msgstr ""
+
+#: ../../Zotlabs/Module/Connections.php:288
+msgid "Recent activity"
+msgstr ""
+
+#: ../../Zotlabs/Module/Connections.php:312 ../../Zotlabs/Lib/Apps.php:216
+#: ../../include/text.php:940 ../../include/nav.php:203
+msgid "Connections"
+msgstr ""
+
+#: ../../Zotlabs/Module/Connections.php:316 ../../Zotlabs/Module/Search.php:44
+#: ../../Zotlabs/Lib/Apps.php:237 ../../include/widgets.php:302
+#: ../../include/text.php:1010 ../../include/text.php:1022
+#: ../../include/nav.php:180 ../../include/acl_selectors.php:213
+msgid "Search"
+msgstr ""
+
+#: ../../Zotlabs/Module/Connections.php:317
+msgid "Search your connections"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:233
-msgid "My site is not a public server"
+#: ../../Zotlabs/Module/Connections.php:318
+msgid "Connections search"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:234
-msgid "My site has paid access only"
+#: ../../Zotlabs/Module/Connections.php:319
+#: ../../Zotlabs/Module/Directory.php:392
+#: ../../Zotlabs/Module/Directory.php:397 ../../include/contact_widgets.php:23
+msgid "Find"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:235
-msgid "My site has free access only"
+#: ../../Zotlabs/Module/Cover_photo.php:58
+#: ../../Zotlabs/Module/Profile_photo.php:61
+msgid "Image uploaded but image cropping failed."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:236
-msgid "My site offers free accounts with optional paid upgrades"
+#: ../../Zotlabs/Module/Cover_photo.php:134
+#: ../../Zotlabs/Module/Cover_photo.php:181
+msgid "Cover Photos"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:247 ../../Zotlabs/Module/Setup.php:328
-msgid "Basic/Minimal Social Networking"
+#: ../../Zotlabs/Module/Cover_photo.php:154
+#: ../../Zotlabs/Module/Profile_photo.php:135
+msgid "Image resize failed."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:248 ../../Zotlabs/Module/Setup.php:329
-msgid "Standard Configuration (default)"
+#: ../../Zotlabs/Module/Cover_photo.php:168
+#: ../../Zotlabs/Module/Profile_photo.php:201 ../../include/photos.php:149
+msgid "Unable to process image"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:249 ../../Zotlabs/Module/Setup.php:330
-msgid "Professional"
+#: ../../Zotlabs/Module/Cover_photo.php:192
+#: ../../Zotlabs/Module/Profile_photo.php:236
+msgid "Image upload failed."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:253 ../../Zotlabs/Lib/Techlevels.php:10
-msgid "Beginner/Basic"
+#: ../../Zotlabs/Module/Cover_photo.php:210
+#: ../../Zotlabs/Module/Profile_photo.php:255
+msgid "Unable to process image."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:254 ../../Zotlabs/Lib/Techlevels.php:11
-msgid "Novice - not skilled but willing to learn"
+#: ../../Zotlabs/Module/Cover_photo.php:233 ../../include/items.php:4181
+msgid "female"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:255 ../../Zotlabs/Lib/Techlevels.php:12
-msgid "Intermediate - somewhat comfortable"
+#: ../../Zotlabs/Module/Cover_photo.php:234 ../../include/items.php:4182
+#, php-format
+msgid "%1$s updated her %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:256 ../../Zotlabs/Lib/Techlevels.php:13
-msgid "Advanced - very comfortable"
+#: ../../Zotlabs/Module/Cover_photo.php:235 ../../include/items.php:4183
+msgid "male"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:257 ../../Zotlabs/Lib/Techlevels.php:14
-msgid "Expert - I can write computer code"
+#: ../../Zotlabs/Module/Cover_photo.php:236 ../../include/items.php:4184
+#, php-format
+msgid "%1$s updated his %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:258 ../../Zotlabs/Lib/Techlevels.php:15
-msgid "Wizard - I probably know more than you do"
+#: ../../Zotlabs/Module/Cover_photo.php:238 ../../include/items.php:4186
+#, php-format
+msgid "%1$s updated their %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:267 ../../include/widgets.php:1634
-msgid "Site"
+#: ../../Zotlabs/Module/Cover_photo.php:240 ../../include/channel.php:1764
+msgid "cover photo"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:270
-msgid "File upload"
+#: ../../Zotlabs/Module/Cover_photo.php:303
+#: ../../Zotlabs/Module/Cover_photo.php:318
+#: ../../Zotlabs/Module/Profile_photo.php:316
+#: ../../Zotlabs/Module/Profile_photo.php:363
+msgid "Photo not available."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:271
-msgid "Policies"
+#: ../../Zotlabs/Module/Cover_photo.php:354
+#: ../../Zotlabs/Module/Profile_photo.php:418
+msgid "Upload File:"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:272
-#: ../../include/contact_widgets.php:16
-msgid "Advanced"
+#: ../../Zotlabs/Module/Cover_photo.php:355
+#: ../../Zotlabs/Module/Profile_photo.php:419
+msgid "Select a profile:"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:276
-#: ../../extend/addon/addon/statusnet/statusnet.php:890
-msgid "Site name"
+#: ../../Zotlabs/Module/Cover_photo.php:356
+msgid "Upload Cover Photo"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:278 ../../Zotlabs/Module/Setup.php:351
-msgid "Server Configuration/Role"
+#: ../../Zotlabs/Module/Cover_photo.php:361
+#: ../../Zotlabs/Module/Profile_photo.php:427
+#: ../../Zotlabs/Module/Settings/Channel.php:404
+msgid "or"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:280
-msgid "Site default technical skill level"
+#: ../../Zotlabs/Module/Cover_photo.php:361
+#: ../../Zotlabs/Module/Profile_photo.php:427
+msgid "skip this step"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:280
-msgid "Used to provide a member experience matched to technical comfort level"
+#: ../../Zotlabs/Module/Cover_photo.php:361
+#: ../../Zotlabs/Module/Profile_photo.php:427
+msgid "select a photo from your photo albums"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:282
-msgid "Lock the technical skill level setting"
+#: ../../Zotlabs/Module/Cover_photo.php:377
+#: ../../Zotlabs/Module/Profile_photo.php:446
+msgid "Crop Image"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:282
-msgid "Members can set their own technical comfort level by default"
+#: ../../Zotlabs/Module/Cover_photo.php:378
+#: ../../Zotlabs/Module/Profile_photo.php:447
+msgid "Please adjust the image cropping for optimum viewing."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:284
-msgid "Banner/Logo"
+#: ../../Zotlabs/Module/Cover_photo.php:380
+#: ../../Zotlabs/Module/Profile_photo.php:449
+msgid "Done Editing"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:285
-msgid "Administrator Information"
+#: ../../Zotlabs/Module/Admin/Features.php:55
+#: ../../Zotlabs/Module/Admin/Features.php:56
+#: ../../Zotlabs/Module/Settings/Features.php:38
+msgid "Off"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:285
-msgid ""
-"Contact information for site administrators. Displayed on siteinfo page. "
-"BBCode can be used here"
+#: ../../Zotlabs/Module/Admin/Features.php:55
+#: ../../Zotlabs/Module/Admin/Features.php:56
+#: ../../Zotlabs/Module/Settings/Features.php:38
+msgid "On"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:286
-#: ../../Zotlabs/Module/Siteinfo.php:23
-msgid "Site Information"
+#: ../../Zotlabs/Module/Admin/Features.php:56
+#, php-format
+msgid "Lock feature %s"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:286
-msgid ""
-"Publicly visible description of this site. Displayed on siteinfo page. "
-"BBCode can be used here"
+#: ../../Zotlabs/Module/Admin/Features.php:64
+msgid "Manage Additional Features"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:287
-msgid "System language"
+#: ../../Zotlabs/Module/Admin/Logs.php:28
+msgid "Log settings updated."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:288
-msgid "System theme"
+#: ../../Zotlabs/Module/Admin/Logs.php:83 ../../include/widgets.php:1661
+#: ../../include/widgets.php:1671
+msgid "Logs"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:288
+#: ../../Zotlabs/Module/Admin/Logs.php:85
+msgid "Clear"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Logs.php:91
+msgid "Debugging"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Logs.php:92
+msgid "Log file"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Logs.php:92
msgid ""
-"Default system theme - may be over-ridden by user profiles - change theme settings"
+"Must be writable by web server. Relative to your top-level webserver "
+"directory."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:289
-msgid "Mobile system theme"
+#: ../../Zotlabs/Module/Admin/Logs.php:93
+msgid "Log level"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:289
-msgid "Theme for mobile devices"
+#: ../../Zotlabs/Module/Admin/Profs.php:69
+msgid "New Profile Field"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:291
-msgid "Allow Feeds as Connections"
+#: ../../Zotlabs/Module/Admin/Profs.php:70
+#: ../../Zotlabs/Module/Admin/Profs.php:90
+msgid "Field nickname"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:291
-msgid "(Heavy system resource usage)"
+#: ../../Zotlabs/Module/Admin/Profs.php:70
+#: ../../Zotlabs/Module/Admin/Profs.php:90
+msgid "System name of field"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:292
-msgid "Maximum image size"
+#: ../../Zotlabs/Module/Admin/Profs.php:71
+#: ../../Zotlabs/Module/Admin/Profs.php:91
+msgid "Input type"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:292
-msgid ""
-"Maximum size in bytes of uploaded images. Default is 0, which means no "
-"limits."
+#: ../../Zotlabs/Module/Admin/Profs.php:72
+#: ../../Zotlabs/Module/Admin/Profs.php:92
+msgid "Field Name"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:293
-msgid "Does this site allow new member registration?"
+#: ../../Zotlabs/Module/Admin/Profs.php:72
+#: ../../Zotlabs/Module/Admin/Profs.php:92
+msgid "Label on profile pages"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:294
-msgid "Invitation only"
+#: ../../Zotlabs/Module/Admin/Profs.php:73
+#: ../../Zotlabs/Module/Admin/Profs.php:93
+msgid "Help text"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:294
-msgid ""
-"Only allow new member registrations with an invitation code. Above register "
-"policy must be set to Yes."
+#: ../../Zotlabs/Module/Admin/Profs.php:73
+#: ../../Zotlabs/Module/Admin/Profs.php:93
+msgid "Additional info (optional)"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:295
-msgid "Which best describes the types of account offered by this hub?"
+#: ../../Zotlabs/Module/Admin/Profs.php:83
+msgid "Field definition not found"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:296
-msgid "Register text"
+#: ../../Zotlabs/Module/Admin/Profs.php:89
+msgid "Edit Profile Field"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:296
-msgid "Will be displayed prominently on the registration page."
+#: ../../Zotlabs/Module/Admin/Profs.php:147 ../../include/widgets.php:1642
+msgid "Profile Fields"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:297
-msgid "Site homepage to show visitors (default: login box)"
+#: ../../Zotlabs/Module/Admin/Profs.php:148
+msgid "Basic Profile Fields"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:297
-msgid ""
-"example: 'public' to show public stream, 'page/sys/home' to show a system "
-"webpage called 'home' or 'include:home.html' to include a file."
+#: ../../Zotlabs/Module/Admin/Profs.php:149
+msgid "Advanced Profile Fields"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:298
-msgid "Preserve site homepage URL"
+#: ../../Zotlabs/Module/Admin/Profs.php:149
+msgid "(In addition to basic fields)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Profs.php:151
+msgid "All available fields"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Profs.php:152
+msgid "Custom Fields"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Profs.php:156
+msgid "Create Custom Field"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Security.php:77
+msgid ""
+"By default, unfiltered HTML is allowed in embedded media. This is inherently "
+"insecure."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:298
+#: ../../Zotlabs/Module/Admin/Security.php:80
msgid ""
-"Present the site homepage in a frame at the original location instead of "
-"redirecting"
+"The recommended setting is to only allow unfiltered HTML from the following "
+"sites:"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:299
-msgid "Accounts abandoned after x days"
+#: ../../Zotlabs/Module/Admin/Security.php:81
+msgid ""
+"https://youtube.com/ https://www.youtube.com/ https://youtu.be/"
+" https://vimeo.com/ https://soundcloud.com/ "
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:299
+#: ../../Zotlabs/Module/Admin/Security.php:82
msgid ""
-"Will not waste system resources polling external sites for abandonded "
-"accounts. Enter 0 for no time limit."
+"All other embedded content will be filtered, unless "
+"embedded content from that site is explicitly blocked."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:300
-msgid "Allowed friend domains"
+#: ../../Zotlabs/Module/Admin/Security.php:87 ../../include/widgets.php:1637
+msgid "Security"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:300
+#: ../../Zotlabs/Module/Admin/Security.php:89
+msgid "Block public"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Security.php:89
msgid ""
-"Comma separated list of domains which are allowed to establish friendships "
-"with this site. Wildcards are accepted. Empty to allow any domains"
+"Check to block public access to all otherwise public personal pages on this "
+"site unless you are currently authenticated."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:301
-msgid "Verify Email Addresses"
+#: ../../Zotlabs/Module/Admin/Security.php:90
+msgid "Set \"Transport Security\" HTTP header"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:301
-msgid ""
-"Check to verify email addresses used in account registration (recommended)."
+#: ../../Zotlabs/Module/Admin/Security.php:91
+msgid "Set \"Content Security Policy\" HTTP header"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:302
-msgid "Force publish"
+#: ../../Zotlabs/Module/Admin/Security.php:92
+msgid "Allowed email domains"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:302
+#: ../../Zotlabs/Module/Admin/Security.php:92
msgid ""
-"Check to force all profiles on this site to be listed in the site directory."
+"Comma separated list of domains which are allowed in email addresses for "
+"registrations to this site. Wildcards are accepted. Empty to allow any "
+"domains"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:303
-msgid "Import Public Streams"
+#: ../../Zotlabs/Module/Admin/Security.php:93
+msgid "Not allowed email domains"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:303
+#: ../../Zotlabs/Module/Admin/Security.php:93
msgid ""
-"Import and allow access to public content pulled from other sites. Warning: "
-"this content is unmoderated."
+"Comma separated list of domains which are not allowed in email addresses for "
+"registrations to this site. Wildcards are accepted. Empty to allow any "
+"domains, unless allowed domains have been defined."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:304
-msgid "Login on Homepage"
+#: ../../Zotlabs/Module/Admin/Security.php:94
+msgid "Allow communications only from these sites"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:304
+#: ../../Zotlabs/Module/Admin/Security.php:94
msgid ""
-"Present a login box to visitors on the home page if no other content has "
-"been configured."
+"One site per line. Leave empty to allow communication from anywhere by "
+"default"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:305
-msgid "Enable context help"
+#: ../../Zotlabs/Module/Admin/Security.php:95
+msgid "Block communications from these sites"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:305
+#: ../../Zotlabs/Module/Admin/Security.php:96
+msgid "Allow communications only from these channels"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Security.php:96
msgid ""
-"Display contextual help for the current page when the help button is pressed."
+"One channel (hash) per line. Leave empty to allow from any channel by default"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:307
-msgid "Directory Server URL"
+#: ../../Zotlabs/Module/Admin/Security.php:97
+msgid "Block communications from these channels"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:307
-msgid "Default directory server"
+#: ../../Zotlabs/Module/Admin/Security.php:98
+msgid "Only allow embeds from secure (SSL) websites and links."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:309
-msgid "Proxy user"
+#: ../../Zotlabs/Module/Admin/Security.php:99
+msgid "Allow unfiltered embedded HTML content only from these domains"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:310
-msgid "Proxy URL"
+#: ../../Zotlabs/Module/Admin/Security.php:99
+msgid "One site per line. By default embedded content is filtered."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:311
-msgid "Network timeout"
+#: ../../Zotlabs/Module/Admin/Security.php:100
+msgid "Block embedded HTML from these domains"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:311
-msgid "Value is in seconds. Set to 0 for unlimited (not recommended)."
+#: ../../Zotlabs/Module/Admin/Account_edit.php:29
+#, php-format
+msgid "Password changed for account %d."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:312
-msgid "Delivery interval"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:46
+msgid "Account settings updated."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:312
-msgid ""
-"Delay background delivery processes by this many seconds to reduce system "
-"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 "
-"for large dedicated servers."
+#: ../../Zotlabs/Module/Admin/Account_edit.php:61
+msgid "Account not found."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:313
-msgid "Deliveries per process"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:68
+msgid "Account Edit"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:313
-msgid ""
-"Number of deliveries to attempt in a single operating system process. Adjust "
-"if necessary to tune system performance. Recommend: 1-5."
+#: ../../Zotlabs/Module/Admin/Account_edit.php:69
+msgid "New Password"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:314
-msgid "Poll interval"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:70
+msgid "New Password again"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:314
-msgid ""
-"Delay background polling processes by this many seconds to reduce system "
-"load. If 0, use delivery interval."
+#: ../../Zotlabs/Module/Admin/Account_edit.php:71
+msgid "Technical skill level"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:315
-msgid "Maximum Load Average"
+#: ../../Zotlabs/Module/Admin/Account_edit.php:72
+msgid "Account language (for emails)"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:315
-msgid ""
-"Maximum system load before delivery and poll processes are deferred - "
-"default 50."
+#: ../../Zotlabs/Module/Admin/Account_edit.php:73
+msgid "Service class"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:316
-msgid "Expiration period in days for imported (grid/network) content"
+#: ../../Zotlabs/Module/Admin/Accounts.php:36
+#, php-format
+msgid "%s account blocked/unblocked"
+msgid_plural "%s account blocked/unblocked"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../../Zotlabs/Module/Admin/Accounts.php:43
+#, php-format
+msgid "%s account deleted"
+msgid_plural "%s accounts deleted"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../../Zotlabs/Module/Admin/Accounts.php:79
+msgid "Account not found"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Site.php:316
-msgid "0 for no expiration of imported content"
+#: ../../Zotlabs/Module/Admin/Accounts.php:90
+#, php-format
+msgid "Account '%s' deleted"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:289
+#: ../../Zotlabs/Module/Admin/Accounts.php:98
#, php-format
-msgid "Plugin %s disabled."
+msgid "Account '%s' blocked"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:294
+#: ../../Zotlabs/Module/Admin/Accounts.php:106
#, php-format
-msgid "Plugin %s enabled."
+msgid "Account '%s' unblocked"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:310
-#: ../../Zotlabs/Module/Admin/Themes.php:95
-msgid "Disable"
+#: ../../Zotlabs/Module/Admin/Accounts.php:165
+#: ../../Zotlabs/Module/Admin/Accounts.php:178 ../../include/widgets.php:1635
+msgid "Accounts"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:313
-#: ../../Zotlabs/Module/Admin/Themes.php:97
-msgid "Enable"
+#: ../../Zotlabs/Module/Admin/Accounts.php:167
+#: ../../Zotlabs/Module/Admin/Channels.php:148
+msgid "select all"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:342
-#: ../../Zotlabs/Module/Admin/Plugins.php:437 ../../include/widgets.php:1639
-msgid "Plugins"
+#: ../../Zotlabs/Module/Admin/Accounts.php:168
+msgid "Registrations waiting for confirm"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:343
-#: ../../Zotlabs/Module/Admin/Themes.php:124
-msgid "Toggle"
+#: ../../Zotlabs/Module/Admin/Accounts.php:169
+msgid "Request date"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:344
-#: ../../Zotlabs/Module/Admin/Themes.php:125 ../../Zotlabs/Lib/Apps.php:223
-#: ../../include/widgets.php:685 ../../include/nav.php:225
-msgid "Settings"
+#: ../../Zotlabs/Module/Admin/Accounts.php:170
+msgid "No registrations."
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:351
-#: ../../Zotlabs/Module/Admin/Themes.php:134
-msgid "Author: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:172
+msgid "Deny"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:352
-#: ../../Zotlabs/Module/Admin/Themes.php:135
-msgid "Maintainer: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:174
+#: ../../Zotlabs/Module/Connedit.php:629
+msgid "Block"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:353
-msgid "Minimum project version: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:175
+#: ../../Zotlabs/Module/Connedit.php:629
+msgid "Unblock"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:354
-msgid "Maximum project version: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:180
+msgid "ID"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:355
-msgid "Minimum PHP version: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:182 ../../include/group.php:287
+msgid "All Channels"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:356
-msgid "Compatible Server Roles: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:183
+msgid "Register date"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:357
-msgid "Requires: "
+#: ../../Zotlabs/Module/Admin/Accounts.php:184
+msgid "Last login"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:358
-#: ../../Zotlabs/Module/Admin/Plugins.php:442
-msgid "Disabled - version incompatibility"
+#: ../../Zotlabs/Module/Admin/Accounts.php:185
+msgid "Expires"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:411
-msgid "Enter the public git repository URL of the plugin repo."
+#: ../../Zotlabs/Module/Admin/Accounts.php:186
+msgid "Service Class"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Accounts.php:188
+msgid ""
+"Selected accounts will be deleted!\\n\\nEverything these accounts had posted "
+"on this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:412
-msgid "Plugin repo git URL"
+#: ../../Zotlabs/Module/Admin/Accounts.php:189
+msgid ""
+"The account {0} will be deleted!\\n\\nEverything this account has posted on "
+"this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:413
-msgid "Custom repo name"
-msgstr ""
+#: ../../Zotlabs/Module/Admin/Channels.php:31
+#, php-format
+msgid "%s channel censored/uncensored"
+msgid_plural "%s channels censored/uncensored"
+msgstr[0] ""
+msgstr[1] ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:413
-msgid "(optional)"
+#: ../../Zotlabs/Module/Admin/Channels.php:40
+#, php-format
+msgid "%s channel code allowed/disallowed"
+msgid_plural "%s channels code allowed/disallowed"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../../Zotlabs/Module/Admin/Channels.php:46
+#, php-format
+msgid "%s channel deleted"
+msgid_plural "%s channels deleted"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../../Zotlabs/Module/Admin/Channels.php:65
+msgid "Channel not found"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:414
-msgid "Download Plugin Repo"
+#: ../../Zotlabs/Module/Admin/Channels.php:75
+#, php-format
+msgid "Channel '%s' deleted"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:421
-msgid "Install new repo"
+#: ../../Zotlabs/Module/Admin/Channels.php:87
+#, php-format
+msgid "Channel '%s' censored"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:422 ../../Zotlabs/Lib/Apps.php:348
-msgid "Install"
+#: ../../Zotlabs/Module/Admin/Channels.php:87
+#, php-format
+msgid "Channel '%s' uncensored"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:423
-#: ../../Zotlabs/Module/Connedit.php:931 ../../Zotlabs/Module/Fbrowser.php:66
-#: ../../Zotlabs/Module/Fbrowser.php:88 ../../Zotlabs/Module/Profiles.php:804
-#: ../../Zotlabs/Module/Settings/Oauth.php:88
-#: ../../Zotlabs/Module/Settings/Oauth.php:114
-#: ../../Zotlabs/Module/Tagrm.php:15 ../../Zotlabs/Module/Tagrm.php:138
-#: ../../Zotlabs/Module/Wiki.php:261 ../../Zotlabs/Module/Wiki.php:286
-#: ../../extend/addon/addon/friendica/dfrn_request.php:879
-#: ../../extend/addon/addon/js_upload/js_upload.php:46
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:866
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1154
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:243
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:266
-#: ../../include/conversation.php:1394 ../../include/conversation.php:1443
-msgid "Cancel"
+#: ../../Zotlabs/Module/Admin/Channels.php:98
+#, php-format
+msgid "Channel '%s' code allowed"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:445
-msgid "Manage Repos"
+#: ../../Zotlabs/Module/Admin/Channels.php:98
+#, php-format
+msgid "Channel '%s' code disallowed"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:446
-msgid "Installed Plugin Repositories"
+#: ../../Zotlabs/Module/Admin/Channels.php:146 ../../include/widgets.php:1636
+msgid "Channels"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:447
-msgid "Install a New Plugin Repository"
+#: ../../Zotlabs/Module/Admin/Channels.php:150
+msgid "Censor"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:453
-#: ../../Zotlabs/Module/Connedit.php:929 ../../Zotlabs/Module/Profiles.php:802
-#: ../../Zotlabs/Module/Settings/Oauth.php:42
-#: ../../Zotlabs/Module/Settings/Oauth.php:113 ../../Zotlabs/Lib/Apps.php:348
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1152
-msgid "Update"
+#: ../../Zotlabs/Module/Admin/Channels.php:151
+msgid "Uncensor"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:454
-msgid "Switch branch"
+#: ../../Zotlabs/Module/Admin/Channels.php:152
+msgid "Allow Code"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Plugins.php:455
-#: ../../Zotlabs/Module/Photos.php:984 ../../Zotlabs/Module/Tagrm.php:137
-#: ../../extend/addon/addon/superblock/superblock.php:116
-msgid "Remove"
+#: ../../Zotlabs/Module/Admin/Channels.php:153
+msgid "Disallow Code"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Themes.php:26
-msgid "Theme settings updated."
+#: ../../Zotlabs/Module/Admin/Channels.php:154
+#: ../../include/conversation.php:1815
+msgid "Channel"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Themes.php:61
-msgid "No themes found."
+#: ../../Zotlabs/Module/Admin/Channels.php:158
+msgid "UID"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Themes.php:116
-msgid "Screenshot"
+#: ../../Zotlabs/Module/Admin/Channels.php:162
+msgid ""
+"Selected channels will be deleted!\\n\\nEverything that was posted in these "
+"channels on this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Themes.php:123
-#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../include/widgets.php:1640
-msgid "Themes"
+#: ../../Zotlabs/Module/Admin/Channels.php:163
+msgid ""
+"The channel {0} will be deleted!\\n\\nEverything that was posted in this "
+"channel on this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Themes.php:162
-msgid "[Experimental]"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:19
+msgid "Update has been marked successful"
msgstr ""
-#: ../../Zotlabs/Module/Admin/Themes.php:163
-msgid "[Unsupported]"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:29
+#, php-format
+msgid "Executing %s failed. Check system logs."
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:57 ../../Zotlabs/Module/Uexport.php:58
-msgid "Export Channel"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:32
+#, php-format
+msgid "Update %s was successfully applied."
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:59
-msgid ""
-"Export your basic channel information to a file. This acts as a backup of "
-"your connections, permissions, profile and basic data, which can be used to "
-"import your data to a new server hub, but does not contain your content."
+#: ../../Zotlabs/Module/Admin/Dbsync.php:36
+#, php-format
+msgid "Update %s did not return a status. Unknown if it succeeded."
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:60
-msgid "Export Content"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:39
+#, php-format
+msgid "Update function %s could not be found."
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:61
-msgid ""
-"Export your channel information and recent content to a JSON backup that can "
-"be restored or imported to another server hub. This backs up all of your "
-"connections, permissions, profile data and several months of posts. This "
-"file may be VERY large. Please be patient - it may take several minutes for "
-"this download to begin."
+#: ../../Zotlabs/Module/Admin/Dbsync.php:55
+msgid "No failed updates."
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:63
-msgid "Export your posts from a given year."
+#: ../../Zotlabs/Module/Admin/Dbsync.php:59
+msgid "Failed Updates"
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:65
-msgid ""
-"You may also export your posts and conversations for a particular year or "
-"month. Adjust the date in your browser location bar to select other dates. "
-"If the export fails (possibly due to memory exhaustion on your server hub), "
-"please try again selecting a more limited date range."
+#: ../../Zotlabs/Module/Admin/Dbsync.php:61
+msgid "Mark success (if update was manually applied)"
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:66
-#, php-format
-msgid ""
-"To select all posts for a given year, such as this year, visit %2$s"
+#: ../../Zotlabs/Module/Admin/Dbsync.php:62
+msgid "Attempt to execute this update step automatically"
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:67
-#, php-format
-msgid ""
-"To select all posts for a given month, such as January of this year, visit "
-"%2$s"
+#: ../../Zotlabs/Module/Admin/Queue.php:35
+msgid "Queue Statistics"
msgstr ""
-#: ../../Zotlabs/Module/Uexport.php:68
-#, php-format
-msgid ""
-"These content files may be imported or restored by visiting "
-"%2$s on any site containing your channel. For best results please import "
-"or restore these in date order (oldest first)."
+#: ../../Zotlabs/Module/Admin/Queue.php:36
+msgid "Total Entries"
msgstr ""
-#: ../../Zotlabs/Module/Editlayout.php:127
-#: ../../Zotlabs/Module/Layouts.php:128 ../../Zotlabs/Module/Layouts.php:188
-msgid "Layout Name"
+#: ../../Zotlabs/Module/Admin/Queue.php:37
+msgid "Priority"
msgstr ""
-#: ../../Zotlabs/Module/Editlayout.php:128
-#: ../../Zotlabs/Module/Layouts.php:131
-msgid "Layout Description (Optional)"
+#: ../../Zotlabs/Module/Admin/Queue.php:38
+msgid "Destination URL"
msgstr ""
-#: ../../Zotlabs/Module/Editlayout.php:136
-msgid "Edit Layout"
+#: ../../Zotlabs/Module/Admin/Queue.php:39
+msgid "Mark hub permanently offline"
msgstr ""
-#: ../../Zotlabs/Module/Editwebpage.php:142
-msgid "Page link"
+#: ../../Zotlabs/Module/Admin/Queue.php:40
+msgid "Empty queue for this hub"
msgstr ""
-#: ../../Zotlabs/Module/Editwebpage.php:169
-msgid "Edit Webpage"
+#: ../../Zotlabs/Module/Admin/Queue.php:41
+msgid "Last known contact"
msgstr ""
-#: ../../Zotlabs/Module/Apps.php:45 ../../include/nav.php:178
-msgid "Apps"
+#: ../../Zotlabs/Module/Admin/Site.php:133
+msgid "Site settings updated."
msgstr ""
-#: ../../Zotlabs/Module/Apps.php:48
-msgid "Manage apps"
+#: ../../Zotlabs/Module/Admin/Site.php:159 ../../include/text.php:2920
+msgid "Default"
msgstr ""
-#: ../../Zotlabs/Module/Apps.php:49
-msgid "Create new app"
+#: ../../Zotlabs/Module/Admin/Site.php:170
+#: ../../Zotlabs/Module/Settings/Display.php:137
+#, php-format
+msgid "%s - (Incompatible)"
msgstr ""
-#: ../../Zotlabs/Module/Dirsearch.php:25 ../../Zotlabs/Module/Regdir.php:49
-msgid "This site is not a directory server"
+#: ../../Zotlabs/Module/Admin/Site.php:177
+#: ../../Zotlabs/Module/Settings/Display.php:151
+msgid "mobile"
msgstr ""
-#: ../../Zotlabs/Module/Dirsearch.php:33
-msgid "This directory server requires an access token"
+#: ../../Zotlabs/Module/Admin/Site.php:179
+msgid "experimental"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:96
-msgid "No such group"
+#: ../../Zotlabs/Module/Admin/Site.php:181
+msgid "unsupported"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:136
-msgid "No such channel"
+#: ../../Zotlabs/Module/Admin/Site.php:227
+msgid "Yes - with approval"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:141
-msgid "forum"
+#: ../../Zotlabs/Module/Admin/Site.php:233
+msgid "My site is not a public server"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:153
-msgid "Search Results For:"
+#: ../../Zotlabs/Module/Admin/Site.php:234
+msgid "My site has paid access only"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:221
-msgid "Privacy group is empty"
+#: ../../Zotlabs/Module/Admin/Site.php:235
+msgid "My site has free access only"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:230
-msgid "Privacy group: "
+#: ../../Zotlabs/Module/Admin/Site.php:236
+msgid "My site offers free accounts with optional paid upgrades"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:256
-msgid "Invalid connection."
+#: ../../Zotlabs/Module/Admin/Site.php:247
+msgid "Basic/Minimal Social Networking"
msgstr ""
-#: ../../Zotlabs/Module/Network.php:275
-#: ../../extend/addon/addon/redred/redred.php:65
-msgid "Invalid channel."
+#: ../../Zotlabs/Module/Admin/Site.php:248
+msgid "Standard Configuration (default)"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:49
-msgid "Unable to update menu."
+#: ../../Zotlabs/Module/Admin/Site.php:249
+msgid "Professional"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:60
-msgid "Unable to create menu."
+#: ../../Zotlabs/Module/Admin/Site.php:253 ../../Zotlabs/Lib/Techlevels.php:10
+msgid "Beginner/Basic"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:98 ../../Zotlabs/Module/Menu.php:110
-msgid "Menu Name"
+#: ../../Zotlabs/Module/Admin/Site.php:254 ../../Zotlabs/Lib/Techlevels.php:11
+msgid "Novice - not skilled but willing to learn"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:98
-msgid "Unique name (not visible on webpage) - required"
+#: ../../Zotlabs/Module/Admin/Site.php:255 ../../Zotlabs/Lib/Techlevels.php:12
+msgid "Intermediate - somewhat comfortable"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:99 ../../Zotlabs/Module/Menu.php:111
-msgid "Menu Title"
+#: ../../Zotlabs/Module/Admin/Site.php:256 ../../Zotlabs/Lib/Techlevels.php:13
+msgid "Advanced - very comfortable"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:99
-msgid "Visible on webpage - leave empty for no title"
+#: ../../Zotlabs/Module/Admin/Site.php:257 ../../Zotlabs/Lib/Techlevels.php:14
+msgid "Expert - I can write computer code"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:100
-msgid "Allow Bookmarks"
+#: ../../Zotlabs/Module/Admin/Site.php:258 ../../Zotlabs/Lib/Techlevels.php:15
+msgid "Wizard - I probably know more than you do"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:100 ../../Zotlabs/Module/Menu.php:157
-msgid "Menu may be used to store saved bookmarks"
+#: ../../Zotlabs/Module/Admin/Site.php:267 ../../include/widgets.php:1634
+msgid "Site"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:101 ../../Zotlabs/Module/Menu.php:159
-msgid "Submit and proceed"
+#: ../../Zotlabs/Module/Admin/Site.php:270
+msgid "File upload"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:107 ../../include/text.php:2289
-msgid "Menus"
+#: ../../Zotlabs/Module/Admin/Site.php:271
+msgid "Policies"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:113 ../../Zotlabs/Module/Locs.php:120
-msgid "Drop"
+#: ../../Zotlabs/Module/Admin/Site.php:272
+#: ../../include/contact_widgets.php:16
+msgid "Advanced"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:114 ../../Zotlabs/Module/Webpages.php:255
-#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Layouts.php:190
-#: ../../include/page_widgets.php:47
-msgid "Created"
+#: ../../Zotlabs/Module/Admin/Site.php:276
+#: ../../extend/addon/addon/statusnet/statusnet.php:890
+msgid "Site name"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:115 ../../Zotlabs/Module/Webpages.php:256
-#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Layouts.php:191
-#: ../../include/page_widgets.php:48
-msgid "Edited"
+#: ../../Zotlabs/Module/Admin/Site.php:278
+msgid "Server Configuration/Role"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:117
-msgid "Bookmarks allowed"
+#: ../../Zotlabs/Module/Admin/Site.php:280
+msgid "Site default technical skill level"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:119
-msgid "Delete this menu"
+#: ../../Zotlabs/Module/Admin/Site.php:280
+msgid "Used to provide a member experience matched to technical comfort level"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:120 ../../Zotlabs/Module/Menu.php:154
-msgid "Edit menu contents"
+#: ../../Zotlabs/Module/Admin/Site.php:282
+msgid "Lock the technical skill level setting"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:121
-msgid "Edit this menu"
+#: ../../Zotlabs/Module/Admin/Site.php:282
+msgid "Members can set their own technical comfort level by default"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:136
-msgid "Menu could not be deleted."
+#: ../../Zotlabs/Module/Admin/Site.php:284
+msgid "Banner/Logo"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:144 ../../Zotlabs/Module/Mitem.php:28
-msgid "Menu not found."
+#: ../../Zotlabs/Module/Admin/Site.php:285
+msgid "Administrator Information"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:149
-msgid "Edit Menu"
+#: ../../Zotlabs/Module/Admin/Site.php:285
+msgid ""
+"Contact information for site administrators. Displayed on siteinfo page. "
+"BBCode can be used here"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:153
-msgid "Add or remove entries to this menu"
+#: ../../Zotlabs/Module/Admin/Site.php:286
+#: ../../Zotlabs/Module/Siteinfo.php:23
+msgid "Site Information"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:155
-msgid "Menu name"
+#: ../../Zotlabs/Module/Admin/Site.php:286
+msgid ""
+"Publicly visible description of this site. Displayed on siteinfo page. "
+"BBCode can be used here"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:155
-msgid "Must be unique, only seen by you"
+#: ../../Zotlabs/Module/Admin/Site.php:287
+msgid "System language"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:156
-msgid "Menu title"
+#: ../../Zotlabs/Module/Admin/Site.php:288
+msgid "System theme"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:156
-msgid "Menu title as seen by others"
+#: ../../Zotlabs/Module/Admin/Site.php:288
+msgid ""
+"Default system theme - may be over-ridden by user profiles - change theme settings"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:157
-msgid "Allow bookmarks"
+#: ../../Zotlabs/Module/Admin/Site.php:289
+msgid "Mobile system theme"
msgstr ""
-#: ../../Zotlabs/Module/Menu.php:166 ../../Zotlabs/Module/Mitem.php:120
-#: ../../Zotlabs/Module/Xchan.php:41
-msgid "Not found."
+#: ../../Zotlabs/Module/Admin/Site.php:289
+msgid "Theme for mobile devices"
msgstr ""
-#: ../../Zotlabs/Module/Rpost.php:138 ../../Zotlabs/Module/Editpost.php:108
-msgid "Edit post"
+#: ../../Zotlabs/Module/Admin/Site.php:291
+msgid "Allow Feeds as Connections"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:25 ../../Zotlabs/Module/Locs.php:54
-msgid "Location not found."
+#: ../../Zotlabs/Module/Admin/Site.php:291
+msgid "(Heavy system resource usage)"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:62
-msgid "Location lookup failed."
+#: ../../Zotlabs/Module/Admin/Site.php:292
+msgid "Maximum image size"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:66
+#: ../../Zotlabs/Module/Admin/Site.php:292
msgid ""
-"Please select another location to become primary before removing the primary "
-"location."
+"Maximum size in bytes of uploaded images. Default is 0, which means no "
+"limits."
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:95
-msgid "Syncing locations"
+#: ../../Zotlabs/Module/Admin/Site.php:293
+msgid "Does this site allow new member registration?"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:105
-msgid "No locations found."
+#: ../../Zotlabs/Module/Admin/Site.php:294
+msgid "Invitation only"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:116
-msgid "Manage Channel Locations"
+#: ../../Zotlabs/Module/Admin/Site.php:294
+msgid ""
+"Only allow new member registrations with an invitation code. Above register "
+"policy must be set to Yes."
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:117 ../../Zotlabs/Module/Pubsites.php:51
-#: ../../Zotlabs/Module/Events.php:475 ../../Zotlabs/Module/Profiles.php:509
-#: ../../Zotlabs/Module/Profiles.php:737
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:839
-#: ../../include/js_strings.php:25
-msgid "Location"
+#: ../../Zotlabs/Module/Admin/Site.php:295
+msgid "Which best describes the types of account offered by this hub?"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:119
-msgid "Primary"
+#: ../../Zotlabs/Module/Admin/Site.php:296
+msgid "Register text"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:122
-msgid "Sync Now"
+#: ../../Zotlabs/Module/Admin/Site.php:296
+msgid "Will be displayed prominently on the registration page."
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:123
-msgid "Please wait several minutes between consecutive operations."
+#: ../../Zotlabs/Module/Admin/Site.php:297
+msgid "Site homepage to show visitors (default: login box)"
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:124
+#: ../../Zotlabs/Module/Admin/Site.php:297
msgid ""
-"When possible, drop a location by logging into that website/hub and removing "
-"your channel."
+"example: 'public' to show public stream, 'page/sys/home' to show a system "
+"webpage called 'home' or 'include:home.html' to include a file."
msgstr ""
-#: ../../Zotlabs/Module/Locs.php:125
-msgid "Use this form to drop the location if the hub is no longer operating."
+#: ../../Zotlabs/Module/Admin/Site.php:298
+msgid "Preserve site homepage URL"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:24 ../../include/widgets.php:1401
-msgid "Public Hubs"
+#: ../../Zotlabs/Module/Admin/Site.php:298
+msgid ""
+"Present the site homepage in a frame at the original location instead of "
+"redirecting"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:27
+#: ../../Zotlabs/Module/Admin/Site.php:299
+msgid "Accounts abandoned after x days"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Site.php:299
msgid ""
-"The listed hubs allow public registration for the $Projectname network. All "
-"hubs in the network are interlinked so membership on any of them conveys "
-"membership in the network as a whole. Some hubs may require subscription or "
-"provide tiered service plans. The hub itself may provide "
-"additional details."
+"Will not waste system resources polling external sites for abandonded "
+"accounts. Enter 0 for no time limit."
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Hub URL"
+#: ../../Zotlabs/Module/Admin/Site.php:300
+msgid "Allowed friend domains"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Access Type"
+#: ../../Zotlabs/Module/Admin/Site.php:300
+msgid ""
+"Comma separated list of domains which are allowed to establish friendships "
+"with this site. Wildcards are accepted. Empty to allow any domains"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Registration Policy"
+#: ../../Zotlabs/Module/Admin/Site.php:301
+msgid "Verify Email Addresses"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Stats"
+#: ../../Zotlabs/Module/Admin/Site.php:301
+msgid ""
+"Check to verify email addresses used in account registration (recommended)."
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:33
-msgid "Software"
+#: ../../Zotlabs/Module/Admin/Site.php:302
+msgid "Force publish"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:35 ../../Zotlabs/Module/Ratings.php:97
-#: ../../include/conversation.php:941 ../../include/conversation.php:1099
-msgid "Ratings"
+#: ../../Zotlabs/Module/Admin/Site.php:302
+msgid ""
+"Check to force all profiles on this site to be listed in the site directory."
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:48
-msgid "Rate"
+#: ../../Zotlabs/Module/Admin/Site.php:303
+msgid "Import Public Streams"
msgstr ""
-#: ../../Zotlabs/Module/Pubsites.php:59 ../../Zotlabs/Module/Events.php:694
-#: ../../Zotlabs/Module/Webpages.php:250 ../../Zotlabs/Module/Blocks.php:166
-#: ../../Zotlabs/Module/Layouts.php:197 ../../Zotlabs/Module/Wiki.php:166
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:151
-#: ../../include/page_widgets.php:42
-msgid "View"
+#: ../../Zotlabs/Module/Admin/Site.php:303
+msgid ""
+"Import and allow access to public content pulled from other sites. Warning: "
+"this content is unmoderated."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:82
-msgid "Could not access contact record."
+#: ../../Zotlabs/Module/Admin/Site.php:304
+msgid "Login on Homepage"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:112
-msgid "Could not locate selected profile."
+#: ../../Zotlabs/Module/Admin/Site.php:304
+msgid ""
+"Present a login box to visitors on the home page if no other content has "
+"been configured."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:249
-msgid "Connection updated."
+#: ../../Zotlabs/Module/Admin/Site.php:305
+msgid "Enable context help"
+msgstr ""
+
+#: ../../Zotlabs/Module/Admin/Site.php:305
+msgid ""
+"Display contextual help for the current page when the help button is pressed."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:251
-msgid "Failed to update connection record."
+#: ../../Zotlabs/Module/Admin/Site.php:307
+msgid "Directory Server URL"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:301
-msgid "is now connected to"
+#: ../../Zotlabs/Module/Admin/Site.php:307
+msgid "Default directory server"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:434
-msgid "Could not access address book record."
+#: ../../Zotlabs/Module/Admin/Site.php:309
+msgid "Proxy user"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:482
-msgid "Refresh failed - channel is currently unavailable."
+#: ../../Zotlabs/Module/Admin/Site.php:310
+msgid "Proxy URL"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:497 ../../Zotlabs/Module/Connedit.php:506
-#: ../../Zotlabs/Module/Connedit.php:515 ../../Zotlabs/Module/Connedit.php:524
-#: ../../Zotlabs/Module/Connedit.php:537
-msgid "Unable to set address book parameters."
+#: ../../Zotlabs/Module/Admin/Site.php:311
+msgid "Network timeout"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:561
-msgid "Connection has been removed."
+#: ../../Zotlabs/Module/Admin/Site.php:311
+msgid "Value is in seconds. Set to 0 for unlimited (not recommended)."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:601 ../../Zotlabs/Lib/Apps.php:228
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:57
-#: ../../include/conversation.php:936 ../../include/conversation.php:1049
-#: ../../include/nav.php:103
-msgid "View Profile"
+#: ../../Zotlabs/Module/Admin/Site.php:312
+msgid "Delivery interval"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:604
-#, php-format
-msgid "View %s's profile"
+#: ../../Zotlabs/Module/Admin/Site.php:312
+msgid ""
+"Delay background delivery processes by this many seconds to reduce system "
+"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 "
+"for large dedicated servers."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:608
-msgid "Refresh Permissions"
+#: ../../Zotlabs/Module/Admin/Site.php:313
+msgid "Deliveries per process"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:611
-msgid "Fetch updated permissions"
+#: ../../Zotlabs/Module/Admin/Site.php:313
+msgid ""
+"Number of deliveries to attempt in a single operating system process. Adjust "
+"if necessary to tune system performance. Recommend: 1-5."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:615
-msgid "Refresh Photo"
+#: ../../Zotlabs/Module/Admin/Site.php:314
+msgid "Poll interval"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:618
-msgid "Fetch updated photo"
+#: ../../Zotlabs/Module/Admin/Site.php:314
+msgid ""
+"Delay background polling processes by this many seconds to reduce system "
+"load. If 0, use delivery interval."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:622
-msgid "Recent Activity"
+#: ../../Zotlabs/Module/Admin/Site.php:315
+msgid "Maximum Load Average"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:625
-msgid "View recent posts and comments"
+#: ../../Zotlabs/Module/Admin/Site.php:315
+msgid ""
+"Maximum system load before delivery and poll processes are deferred - "
+"default 50."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:632
-msgid "Block (or Unblock) all communications with this connection"
+#: ../../Zotlabs/Module/Admin/Site.php:316
+msgid "Expiration period in days for imported (grid/network) content"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:633
-msgid "This connection is blocked!"
+#: ../../Zotlabs/Module/Admin/Site.php:316
+msgid "0 for no expiration of imported content"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:637
-msgid "Unignore"
+#: ../../Zotlabs/Module/Admin/Plugins.php:289
+#, php-format
+msgid "Plugin %s disabled."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:640
-msgid "Ignore (or Unignore) all inbound communications from this connection"
+#: ../../Zotlabs/Module/Admin/Plugins.php:294
+#, php-format
+msgid "Plugin %s enabled."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:641
-msgid "This connection is ignored!"
+#: ../../Zotlabs/Module/Admin/Plugins.php:310
+#: ../../Zotlabs/Module/Admin/Themes.php:95
+msgid "Disable"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:645
-msgid "Unarchive"
+#: ../../Zotlabs/Module/Admin/Plugins.php:313
+#: ../../Zotlabs/Module/Admin/Themes.php:97
+msgid "Enable"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:645
-msgid "Archive"
+#: ../../Zotlabs/Module/Admin/Plugins.php:342
+#: ../../Zotlabs/Module/Admin/Plugins.php:437 ../../include/widgets.php:1639
+msgid "Plugins"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:648
-msgid ""
-"Archive (or Unarchive) this connection - mark channel dead but keep content"
+#: ../../Zotlabs/Module/Admin/Plugins.php:343
+#: ../../Zotlabs/Module/Admin/Themes.php:124
+msgid "Toggle"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:649
-msgid "This connection is archived!"
+#: ../../Zotlabs/Module/Admin/Plugins.php:344
+#: ../../Zotlabs/Module/Admin/Themes.php:125 ../../Zotlabs/Lib/Apps.php:223
+#: ../../include/widgets.php:685 ../../include/nav.php:225
+msgid "Settings"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:653
-msgid "Unhide"
+#: ../../Zotlabs/Module/Admin/Plugins.php:351
+#: ../../Zotlabs/Module/Admin/Themes.php:134
+msgid "Author: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:653
-msgid "Hide"
+#: ../../Zotlabs/Module/Admin/Plugins.php:352
+#: ../../Zotlabs/Module/Admin/Themes.php:135
+msgid "Maintainer: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:656
-msgid "Hide or Unhide this connection from your other connections"
+#: ../../Zotlabs/Module/Admin/Plugins.php:353
+msgid "Minimum project version: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:657
-msgid "This connection is hidden!"
+#: ../../Zotlabs/Module/Admin/Plugins.php:354
+msgid "Maximum project version: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:664
-msgid "Delete this connection"
+#: ../../Zotlabs/Module/Admin/Plugins.php:355
+msgid "Minimum PHP version: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:672
-msgid "Fetch Vcard"
+#: ../../Zotlabs/Module/Admin/Plugins.php:356
+msgid "Compatible Server Roles: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:675
-msgid "Fetch electronic calling card for this connection"
+#: ../../Zotlabs/Module/Admin/Plugins.php:357
+msgid "Requires: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:683
-#: ../../Zotlabs/Module/Filestorage.php:152
-#: ../../Zotlabs/Module/Photos.php:657 ../../Zotlabs/Module/Photos.php:1042
-#: ../../Zotlabs/Module/Thing.php:313 ../../Zotlabs/Module/Thing.php:363
-#: ../../Zotlabs/Module/Chat.php:232 ../../include/acl_selectors.php:218
-msgid "Permissions"
+#: ../../Zotlabs/Module/Admin/Plugins.php:358
+#: ../../Zotlabs/Module/Admin/Plugins.php:442
+msgid "Disabled - version incompatibility"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:686
-msgid "Open Individual Permissions section by default"
+#: ../../Zotlabs/Module/Admin/Plugins.php:411
+msgid "Enter the public git repository URL of the plugin repo."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:709
-msgid "Affinity"
+#: ../../Zotlabs/Module/Admin/Plugins.php:412
+msgid "Plugin repo git URL"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:712
-msgid "Open Set Affinity section by default"
+#: ../../Zotlabs/Module/Admin/Plugins.php:413
+msgid "Custom repo name"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:716 ../../include/widgets.php:526
-msgid "Me"
+#: ../../Zotlabs/Module/Admin/Plugins.php:413
+msgid "(optional)"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:717 ../../include/widgets.php:527
-msgid "Family"
+#: ../../Zotlabs/Module/Admin/Plugins.php:414
+msgid "Download Plugin Repo"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:718
-#: ../../Zotlabs/Module/Settings/Channel.php:62
-#: ../../Zotlabs/Module/Settings/Channel.php:66
-#: ../../Zotlabs/Module/Settings/Channel.php:67
-#: ../../Zotlabs/Module/Settings/Channel.php:70
-#: ../../Zotlabs/Module/Settings/Channel.php:81 ../../include/widgets.php:528
-#: ../../include/selectors.php:123 ../../include/channel.php:408
-#: ../../include/channel.php:409 ../../include/channel.php:416
-msgid "Friends"
+#: ../../Zotlabs/Module/Admin/Plugins.php:421
+msgid "Install new repo"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:719 ../../include/widgets.php:529
-msgid "Acquaintances"
+#: ../../Zotlabs/Module/Admin/Plugins.php:422 ../../Zotlabs/Lib/Apps.php:348
+msgid "Install"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:746
-msgid "Filter"
+#: ../../Zotlabs/Module/Admin/Plugins.php:445
+msgid "Manage Repos"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:749
-msgid "Open Custom Filter section by default"
+#: ../../Zotlabs/Module/Admin/Plugins.php:446
+msgid "Installed Plugin Repositories"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:786
-msgid "Approve this connection"
+#: ../../Zotlabs/Module/Admin/Plugins.php:447
+msgid "Install a New Plugin Repository"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:786
-msgid "Accept connection to allow communication"
+#: ../../Zotlabs/Module/Admin/Plugins.php:454
+msgid "Switch branch"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:791
-msgid "Set Affinity"
+#: ../../Zotlabs/Module/Admin/Plugins.php:455
+#: ../../Zotlabs/Module/Tagrm.php:137 ../../Zotlabs/Module/Photos.php:984
+#: ../../extend/addon/addon/superblock/superblock.php:116
+msgid "Remove"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:794
-msgid "Set Profile"
+#: ../../Zotlabs/Module/Admin/Themes.php:26
+msgid "Theme settings updated."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:797
-msgid "Set Affinity & Profile"
+#: ../../Zotlabs/Module/Admin/Themes.php:61
+msgid "No themes found."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:855
-msgid "none"
+#: ../../Zotlabs/Module/Admin/Themes.php:116
+msgid "Screenshot"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:858 ../../include/widgets.php:661
-msgid "Connection Default Permissions"
+#: ../../Zotlabs/Module/Admin/Themes.php:123
+#: ../../Zotlabs/Module/Admin/Themes.php:157 ../../include/widgets.php:1640
+msgid "Themes"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:858 ../../include/items.php:3934
-#, php-format
-msgid "Connection: %s"
+#: ../../Zotlabs/Module/Admin/Themes.php:162
+msgid "[Experimental]"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:859
-msgid "Apply these permissions automatically"
+#: ../../Zotlabs/Module/Admin/Themes.php:163
+msgid "[Unsupported]"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:859
-msgid "Connection requests will be approved without your interaction"
+#: ../../Zotlabs/Module/Webpages.php:52
+msgid "Import Webpage Elements"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:860
-msgid "Permission role"
+#: ../../Zotlabs/Module/Webpages.php:53
+msgid "Import selected"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:861
-msgid "Add permission role"
+#: ../../Zotlabs/Module/Webpages.php:76
+msgid "Export Webpage Elements"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:867
-msgid "This connection's primary address is"
+#: ../../Zotlabs/Module/Webpages.php:77
+msgid "Export selected"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:868
-msgid "Available locations:"
+#: ../../Zotlabs/Module/Webpages.php:241 ../../Zotlabs/Lib/Apps.php:225
+#: ../../include/conversation.php:1889
+msgid "Webpages"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:872
-msgid ""
-"The permissions indicated on this page will be applied to all new "
-"connections."
+#: ../../Zotlabs/Module/Webpages.php:245 ../../Zotlabs/Module/Blocks.php:161
+#: ../../Zotlabs/Module/Layouts.php:193 ../../Zotlabs/Module/Photos.php:1073
+#: ../../extend/addon/addon/cdav/include/widgets.php:123
+#: ../../include/conversation.php:1378
+msgid "Share"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:873
-msgid "Connection Tools"
+#: ../../Zotlabs/Module/Webpages.php:250 ../../Zotlabs/Module/Pubsites.php:59
+#: ../../Zotlabs/Module/Wiki.php:166 ../../Zotlabs/Module/Blocks.php:166
+#: ../../Zotlabs/Module/Layouts.php:197 ../../Zotlabs/Module/Events.php:694
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:151
+#: ../../include/page_widgets.php:42
+msgid "View"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:875
-msgid "Slide to adjust your degree of friendship"
+#: ../../Zotlabs/Module/Webpages.php:251 ../../Zotlabs/Module/Events.php:478
+#: ../../Zotlabs/Module/Photos.php:1094 ../../Zotlabs/Lib/ThreadItem.php:740
+#: ../../include/conversation.php:1347 ../../include/page_widgets.php:43
+msgid "Preview"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:876 ../../Zotlabs/Module/Rate.php:155
-#: ../../include/js_strings.php:20
-msgid "Rating"
+#: ../../Zotlabs/Module/Webpages.php:252 ../../include/page_widgets.php:44
+msgid "Actions"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:877
-msgid "Slide to adjust your rating"
+#: ../../Zotlabs/Module/Webpages.php:253 ../../include/page_widgets.php:45
+msgid "Page Link"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:878 ../../Zotlabs/Module/Connedit.php:883
-msgid "Optionally explain your rating"
+#: ../../Zotlabs/Module/Webpages.php:254
+msgid "Page Title"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:880
-msgid "Custom Filter"
+#: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Menu.php:114
+#: ../../Zotlabs/Module/Blocks.php:157 ../../Zotlabs/Module/Layouts.php:190
+#: ../../include/page_widgets.php:47
+msgid "Created"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:881
-msgid "Only import posts with this text"
+#: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Module/Menu.php:115
+#: ../../Zotlabs/Module/Blocks.php:158 ../../Zotlabs/Module/Layouts.php:191
+#: ../../include/page_widgets.php:48
+msgid "Edited"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:881 ../../Zotlabs/Module/Connedit.php:882
-msgid ""
-"words one per line or #tags or /patterns/ or lang=xx, leave blank to import "
-"all posts"
+#: ../../Zotlabs/Module/Webpages.php:284
+msgid "Invalid file type."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:882
-msgid "Do not import posts with this text"
+#: ../../Zotlabs/Module/Webpages.php:296
+msgid "Error opening zip file"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:884
-msgid "This information is public!"
+#: ../../Zotlabs/Module/Webpages.php:307
+msgid "Invalid folder path."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:889
-msgid "Connection Pending Approval"
+#: ../../Zotlabs/Module/Webpages.php:334
+msgid "No webpage elements detected."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:892
-#: ../../Zotlabs/Module/Settings/Permcats.php:107
-#: ../../Zotlabs/Module/Settings/Tokens.php:163
-msgid "inherited"
+#: ../../Zotlabs/Module/Webpages.php:409
+msgid "Import complete."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:894
-#, php-format
-msgid ""
-"Please choose the profile you would like to display to %s when viewing your "
-"profile securely."
+#: ../../Zotlabs/Module/Editlayout.php:127
+#: ../../Zotlabs/Module/Layouts.php:128 ../../Zotlabs/Module/Layouts.php:188
+msgid "Layout Name"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:896
-#: ../../Zotlabs/Module/Settings/Tokens.php:160
-msgid "Their Settings"
+#: ../../Zotlabs/Module/Editlayout.php:128
+#: ../../Zotlabs/Module/Layouts.php:131
+msgid "Layout Description (Optional)"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:897
-#: ../../Zotlabs/Module/Settings/Permcats.php:105
-#: ../../Zotlabs/Module/Settings/Tokens.php:161
-msgid "My Settings"
+#: ../../Zotlabs/Module/Editlayout.php:136
+msgid "Edit Layout"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:899
-#: ../../Zotlabs/Module/Settings/Permcats.php:110
-#: ../../Zotlabs/Module/Settings/Tokens.php:166
-msgid "Individual Permissions"
+#: ../../Zotlabs/Module/Editwebpage.php:142
+msgid "Page link"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:900
-#: ../../Zotlabs/Module/Settings/Permcats.php:111
-#: ../../Zotlabs/Module/Settings/Tokens.php:167
-msgid ""
-"Some permissions may be inherited from your channel's privacy settings, which have higher priority than "
-"individual settings. You can not change those settings here."
+#: ../../Zotlabs/Module/Editwebpage.php:169
+msgid "Edit Webpage"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:901
-msgid ""
-"Some permissions may be inherited from your channel's privacy settings, which have higher priority than "
-"individual settings. You can change those settings here but they wont have "
-"any impact unless the inherited setting changes."
+#: ../../Zotlabs/Module/Chatsvc.php:131
+msgid "Away"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:902
-msgid "Last update:"
+#: ../../Zotlabs/Module/Chatsvc.php:136
+msgid "Online"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:911
-msgid "Details"
+#: ../../Zotlabs/Module/Dirsearch.php:25 ../../Zotlabs/Module/Regdir.php:49
+msgid "This site is not a directory server"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:914
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1137
-msgid "Organisation"
+#: ../../Zotlabs/Module/Dirsearch.php:33
+msgid "This directory server requires an access token"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:915
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1138
-#: ../../include/page_widgets.php:46
-msgid "Title"
+#: ../../Zotlabs/Module/Network.php:96
+msgid "No such group"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:916 ../../Zotlabs/Module/Profiles.php:789
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1139
-msgid "Phone"
+#: ../../Zotlabs/Module/Network.php:136
+msgid "No such channel"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:918 ../../Zotlabs/Module/Profiles.php:791
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1141
-msgid "Instant messenger"
+#: ../../Zotlabs/Module/Network.php:141
+msgid "forum"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:919 ../../Zotlabs/Module/Profiles.php:792
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1142
-msgid "Website"
+#: ../../Zotlabs/Module/Network.php:153
+msgid "Search Results For:"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:921 ../../Zotlabs/Module/Profiles.php:794
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1144
-msgid "Note"
+#: ../../Zotlabs/Module/Network.php:221
+msgid "Privacy group is empty"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:922 ../../Zotlabs/Module/Profiles.php:795
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1145
-#: ../../extend/addon/addon/cdav/cdav.php:270
-#: ../../include/connections.php:668
-msgid "Mobile"
+#: ../../Zotlabs/Module/Network.php:230
+msgid "Privacy group: "
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:923 ../../Zotlabs/Module/Profiles.php:796
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1146
-#: ../../extend/addon/addon/cdav/cdav.php:271
-#: ../../include/connections.php:669
-msgid "Home"
+#: ../../Zotlabs/Module/Network.php:256
+msgid "Invalid connection."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:924 ../../Zotlabs/Module/Profiles.php:797
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1147
-#: ../../extend/addon/addon/cdav/cdav.php:274
-#: ../../include/connections.php:672
-msgid "Work"
+#: ../../Zotlabs/Module/Network.php:275
+#: ../../extend/addon/addon/redred/redred.php:65
+msgid "Invalid channel."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:926 ../../Zotlabs/Module/Profiles.php:799
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:368
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1149
-msgid "Add Contact"
+#: ../../Zotlabs/Module/Menu.php:49
+msgid "Unable to update menu."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:927 ../../Zotlabs/Module/Profiles.php:800
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1150
-msgid "Add Field"
+#: ../../Zotlabs/Module/Menu.php:60
+msgid "Unable to create menu."
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:932
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1155
-msgid "P.O. Box"
+#: ../../Zotlabs/Module/Menu.php:98 ../../Zotlabs/Module/Menu.php:110
+msgid "Menu Name"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:933
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1156
-msgid "Additional"
+#: ../../Zotlabs/Module/Menu.php:98
+msgid "Unique name (not visible on webpage) - required"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:934
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1157
-msgid "Street"
+#: ../../Zotlabs/Module/Menu.php:99 ../../Zotlabs/Module/Menu.php:111
+msgid "Menu Title"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:935
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1158
-msgid "Locality"
+#: ../../Zotlabs/Module/Menu.php:99
+msgid "Visible on webpage - leave empty for no title"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:936
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1159
-msgid "Region"
+#: ../../Zotlabs/Module/Menu.php:100
+msgid "Allow Bookmarks"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:937
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1160
-msgid "ZIP Code"
+#: ../../Zotlabs/Module/Menu.php:100 ../../Zotlabs/Module/Menu.php:157
+msgid "Menu may be used to store saved bookmarks"
msgstr ""
-#: ../../Zotlabs/Module/Connedit.php:938 ../../Zotlabs/Module/Profiles.php:760
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1161
-msgid "Country"
+#: ../../Zotlabs/Module/Menu.php:101 ../../Zotlabs/Module/Menu.php:159
+msgid "Submit and proceed"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:25
-msgid "Calendar entries imported."
+#: ../../Zotlabs/Module/Menu.php:107 ../../include/text.php:2273
+msgid "Menus"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:27
-msgid "No calendar entries found."
+#: ../../Zotlabs/Module/Menu.php:113 ../../Zotlabs/Module/Locs.php:120
+msgid "Drop"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:110
-msgid "Event can not end before it has started."
+#: ../../Zotlabs/Module/Menu.php:117
+msgid "Bookmarks allowed"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:112 ../../Zotlabs/Module/Events.php:121
-#: ../../Zotlabs/Module/Events.php:143
-msgid "Unable to generate preview."
+#: ../../Zotlabs/Module/Menu.php:119
+msgid "Delete this menu"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:119
-msgid "Event title and start time are required."
+#: ../../Zotlabs/Module/Menu.php:120 ../../Zotlabs/Module/Menu.php:154
+msgid "Edit menu contents"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:141 ../../Zotlabs/Module/Events.php:265
-msgid "Event not found."
+#: ../../Zotlabs/Module/Menu.php:121
+msgid "Edit this menu"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:260 ../../Zotlabs/Module/Like.php:372
-#: ../../Zotlabs/Module/Tagger.php:51 ../../include/event.php:1141
-#: ../../include/conversation.php:123 ../../include/text.php:1961
-msgid "event"
+#: ../../Zotlabs/Module/Menu.php:136
+msgid "Menu could not be deleted."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:460
-msgid "Edit event title"
+#: ../../Zotlabs/Module/Menu.php:144 ../../Zotlabs/Module/Mitem.php:28
+msgid "Menu not found."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:460
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:835
-msgid "Event title"
+#: ../../Zotlabs/Module/Menu.php:149
+msgid "Edit Menu"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:462
-msgid "Categories (comma-separated list)"
+#: ../../Zotlabs/Module/Menu.php:153
+msgid "Add or remove entries to this menu"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:463
-msgid "Edit Category"
+#: ../../Zotlabs/Module/Menu.php:155
+msgid "Menu name"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:463
-msgid "Category"
+#: ../../Zotlabs/Module/Menu.php:155
+msgid "Must be unique, only seen by you"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:466
-msgid "Edit start date and time"
+#: ../../Zotlabs/Module/Menu.php:156
+msgid "Menu title"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:466
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:836
-msgid "Start date and time"
+#: ../../Zotlabs/Module/Menu.php:156
+msgid "Menu title as seen by others"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:467 ../../Zotlabs/Module/Events.php:470
-msgid "Finish date and time are not known or not relevant"
+#: ../../Zotlabs/Module/Menu.php:157
+msgid "Allow bookmarks"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:469
-msgid "Edit finish date and time"
+#: ../../Zotlabs/Module/Menu.php:166 ../../Zotlabs/Module/Mitem.php:120
+#: ../../Zotlabs/Module/Xchan.php:41
+msgid "Not found."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:469
-msgid "Finish date and time"
+#: ../../Zotlabs/Module/Editpost.php:35
+msgid "Item is not editable"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:471 ../../Zotlabs/Module/Events.php:472
-msgid "Adjust for viewer timezone"
+#: ../../Zotlabs/Module/Editpost.php:108 ../../Zotlabs/Module/Rpost.php:138
+msgid "Edit post"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:471
-msgid ""
-"Important for events that happen in a particular place. Not practical for "
-"global holidays."
+#: ../../Zotlabs/Module/Locs.php:25 ../../Zotlabs/Module/Locs.php:54
+msgid "Location not found."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:473
-msgid "Edit Description"
+#: ../../Zotlabs/Module/Locs.php:62
+msgid "Location lookup failed."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:475
-msgid "Edit Location"
+#: ../../Zotlabs/Module/Locs.php:66
+msgid ""
+"Please select another location to become primary before removing the primary "
+"location."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:478 ../../Zotlabs/Module/Photos.php:1094
-#: ../../Zotlabs/Module/Webpages.php:251 ../../Zotlabs/Lib/ThreadItem.php:740
-#: ../../include/page_widgets.php:43 ../../include/conversation.php:1347
-msgid "Preview"
+#: ../../Zotlabs/Module/Locs.php:95
+msgid "Syncing locations"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:479 ../../include/conversation.php:1410
-msgid "Permission settings"
+#: ../../Zotlabs/Module/Locs.php:105
+msgid "No locations found."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:489
-msgid "Timezone:"
+#: ../../Zotlabs/Module/Locs.php:116
+msgid "Manage Channel Locations"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:494
-msgid "Advanced Options"
+#: ../../Zotlabs/Module/Locs.php:119
+msgid "Primary"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:605 ../../Zotlabs/Module/Cal.php:263
-msgid "l, F j"
+#: ../../Zotlabs/Module/Locs.php:122
+msgid "Sync Now"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:633
-msgid "Edit event"
+#: ../../Zotlabs/Module/Locs.php:123
+msgid "Please wait several minutes between consecutive operations."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:635
-msgid "Delete event"
+#: ../../Zotlabs/Module/Locs.php:124
+msgid ""
+"When possible, drop a location by logging into that website/hub and removing "
+"your channel."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:660 ../../Zotlabs/Module/Cal.php:312
-#: ../../include/text.php:1766
-msgid "Link to Source"
+#: ../../Zotlabs/Module/Locs.php:125
+msgid "Use this form to drop the location if the hub is no longer operating."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:669
-msgid "calendar"
+#: ../../Zotlabs/Module/Pubsites.php:24 ../../include/widgets.php:1401
+msgid "Public Hubs"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:688 ../../Zotlabs/Module/Cal.php:335
-msgid "Edit Event"
+#: ../../Zotlabs/Module/Pubsites.php:27
+msgid ""
+"The listed hubs allow public registration for the $Projectname network. All "
+"hubs in the network are interlinked so membership on any of them conveys "
+"membership in the network as a whole. Some hubs may require subscription or "
+"provide tiered service plans. The hub itself may provide "
+"additional details."
msgstr ""
-#: ../../Zotlabs/Module/Events.php:688 ../../Zotlabs/Module/Cal.php:335
-msgid "Create Event"
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Hub URL"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:689 ../../Zotlabs/Module/Events.php:698
-#: ../../Zotlabs/Module/Photos.php:935 ../../Zotlabs/Module/Cal.php:336
-#: ../../Zotlabs/Module/Cal.php:343
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:846
-msgid "Previous"
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Access Type"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:690 ../../Zotlabs/Module/Events.php:699
-#: ../../Zotlabs/Module/Photos.php:944 ../../Zotlabs/Module/Cal.php:337
-#: ../../Zotlabs/Module/Cal.php:344 ../../Zotlabs/Module/Setup.php:264
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:847
-msgid "Next"
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Registration Policy"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:691 ../../Zotlabs/Module/Cal.php:338
-#: ../../include/channel.php:1370
-msgid "Export"
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Stats"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:695
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:849
-msgid "Month"
+#: ../../Zotlabs/Module/Pubsites.php:33
+msgid "Software"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:696
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:850
-msgid "Week"
+#: ../../Zotlabs/Module/Pubsites.php:35 ../../Zotlabs/Module/Ratings.php:97
+#: ../../include/conversation.php:941 ../../include/conversation.php:1099
+msgid "Ratings"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:697
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:851
-msgid "Day"
+#: ../../Zotlabs/Module/Pubsites.php:48
+msgid "Rate"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:700 ../../Zotlabs/Module/Cal.php:345
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:848
-msgid "Today"
+#: ../../Zotlabs/Module/Apps.php:45 ../../include/nav.php:178
+msgid "Apps"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:731
-msgid "Event removed"
+#: ../../Zotlabs/Module/Apps.php:48
+msgid "Manage apps"
msgstr ""
-#: ../../Zotlabs/Module/Events.php:734
-msgid "Failed to remove event"
+#: ../../Zotlabs/Module/Apps.php:49
+msgid "Create new app"
msgstr ""
#: ../../Zotlabs/Module/Home.php:74 ../../Zotlabs/Module/Home.php:82
@@ -3703,618 +3767,678 @@ msgstr ""
msgid "Photos"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:82
-msgid "Page owner information could not be retrieved."
+#: ../../Zotlabs/Module/Acl.php:117 ../../Zotlabs/Module/Lockview.php:117
+#: ../../Zotlabs/Module/Lockview.php:153 ../../include/acl_selectors.php:183
+msgctxt "acl"
+msgid "Profile"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:97 ../../Zotlabs/Module/Photos.php:729
-#: ../../Zotlabs/Module/Profile_photo.php:115
-#: ../../Zotlabs/Module/Profile_photo.php:224
-#: ../../include/photo/photo_driver.php:730
-msgid "Profile Photos"
+#: ../../Zotlabs/Module/Acl.php:344
+msgid "network"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:103 ../../Zotlabs/Module/Photos.php:129
-msgid "Album not found."
+#: ../../Zotlabs/Module/Acl.php:354
+msgid "RSS"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:112
-msgid "Delete Album"
+#: ../../Zotlabs/Module/Group.php:24
+msgid "Privacy group created."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:133
-msgid ""
-"Multiple storage folders exist with this album name, but within different "
-"directories. Please remove the desired folder or folders using the Files "
-"manager"
+#: ../../Zotlabs/Module/Group.php:30
+msgid "Could not create privacy group."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:190 ../../Zotlabs/Module/Photos.php:1054
-msgid "Delete Photo"
+#: ../../Zotlabs/Module/Group.php:42 ../../Zotlabs/Module/Group.php:141
+#: ../../include/items.php:3804
+msgid "Privacy group not found."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:508 ../../Zotlabs/Module/Display.php:22
-#: ../../Zotlabs/Module/Ratings.php:83 ../../Zotlabs/Module/Search.php:17
-#: ../../Zotlabs/Module/Directory.php:64
-#: ../../Zotlabs/Module/Viewconnections.php:23
-#: ../../extend/addon/addon/friendica/dfrn_request.php:794
-msgid "Public access denied."
+#: ../../Zotlabs/Module/Group.php:58
+msgid "Privacy group updated."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:519
-msgid "No photos selected"
+#: ../../Zotlabs/Module/Group.php:90
+msgid "Create a group of channels."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:568
-msgid "Access to this item is restricted."
+#: ../../Zotlabs/Module/Group.php:91 ../../Zotlabs/Module/Group.php:184
+msgid "Privacy group name: "
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:607
-#, php-format
-msgid "%1$.2f MB of %2$.2f MB photo storage used."
+#: ../../Zotlabs/Module/Group.php:93 ../../Zotlabs/Module/Group.php:187
+msgid "Members are visible to other channels"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:610
-#, php-format
-msgid "%1$.2f MB photo storage used."
+#: ../../Zotlabs/Module/Group.php:111
+msgid "Privacy group removed."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:646
-msgid "Upload Photos"
+#: ../../Zotlabs/Module/Group.php:113
+msgid "Unable to remove privacy group."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:650
-msgid "Enter an album name"
+#: ../../Zotlabs/Module/Group.php:183
+msgid "Privacy group editor"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:651
-msgid "or select an existing album (doubleclick)"
+#: ../../Zotlabs/Module/Group.php:199
+msgid "All Connected Channels"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:652
-msgid "Create a status post for this upload"
+#: ../../Zotlabs/Module/Group.php:231
+msgid "Click on a channel to add or remove."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:653
-msgid "Caption (optional):"
+#: ../../Zotlabs/Module/Dreport.php:45
+msgid "Invalid message"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:654
-msgid "Description (optional):"
+#: ../../Zotlabs/Module/Dreport.php:78
+msgid "no results"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:685
-msgid "Album name could not be decoded"
+#: ../../Zotlabs/Module/Dreport.php:93
+msgid "channel sync processed"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:97
+msgid "queued"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:101
+msgid "posted"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:105
+msgid "accepted for delivery"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:109
+msgid "updated"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:112
+msgid "update ignored"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:115
+msgid "permission denied"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:119
+msgid "recipient not found"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:122
+msgid "mail recalled"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:125
+msgid "duplicate mail received"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:128
+msgid "mail delivered"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:148
+#, php-format
+msgid "Delivery report for %1$s"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:151
+msgid "Options"
+msgstr ""
+
+#: ../../Zotlabs/Module/Dreport.php:152
+msgid "Redeliver"
+msgstr ""
+
+#: ../../Zotlabs/Module/Cal.php:69
+msgid "Permissions denied."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:729
-msgid "Contact Photos"
+#: ../../Zotlabs/Module/Cal.php:263 ../../Zotlabs/Module/Events.php:605
+msgid "l, F j"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:752
-msgid "Show Newest First"
+#: ../../Zotlabs/Module/Cal.php:312 ../../Zotlabs/Module/Events.php:660
+#: ../../include/text.php:1750
+msgid "Link to Source"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:754
-msgid "Show Oldest First"
+#: ../../Zotlabs/Module/Cal.php:335 ../../Zotlabs/Module/Events.php:688
+msgid "Edit Event"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:778 ../../Zotlabs/Module/Photos.php:1335
-#: ../../Zotlabs/Module/Embedphotos.php:139 ../../include/widgets.php:1751
-msgid "View Photo"
+#: ../../Zotlabs/Module/Cal.php:335 ../../Zotlabs/Module/Events.php:688
+msgid "Create Event"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:809
-#: ../../Zotlabs/Module/Embedphotos.php:155 ../../include/widgets.php:1768
-msgid "Edit Album"
+#: ../../Zotlabs/Module/Cal.php:336 ../../Zotlabs/Module/Cal.php:343
+#: ../../Zotlabs/Module/Events.php:689 ../../Zotlabs/Module/Events.php:698
+#: ../../Zotlabs/Module/Photos.php:935
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:846
+msgid "Previous"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:856
-msgid "Permission denied. Access to this item may be restricted."
+#: ../../Zotlabs/Module/Cal.php:338 ../../Zotlabs/Module/Events.php:691
+#: ../../include/channel.php:1370
+msgid "Export"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:858
-msgid "Photo not available"
+#: ../../Zotlabs/Module/Cal.php:341 ../../include/text.php:2296
+msgid "Import"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:916
-msgid "Use as profile photo"
+#: ../../Zotlabs/Module/Cal.php:345 ../../Zotlabs/Module/Events.php:700
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:848
+msgid "Today"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:917
-msgid "Use as cover photo"
+#: ../../Zotlabs/Module/Impel.php:41 ../../include/bbcode.php:203
+msgid "webpage"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:924
-msgid "Private Photo"
+#: ../../Zotlabs/Module/Impel.php:46 ../../include/bbcode.php:209
+msgid "block"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:939
-msgid "View Full Size"
+#: ../../Zotlabs/Module/Impel.php:51 ../../include/bbcode.php:206
+msgid "layout"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1028
-msgid "Edit photo"
+#: ../../Zotlabs/Module/Impel.php:58 ../../include/bbcode.php:212
+msgid "menu"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1030
-msgid "Rotate CW (right)"
+#: ../../Zotlabs/Module/Impel.php:191
+#, php-format
+msgid "%s element installed"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1031
-msgid "Rotate CCW (left)"
+#: ../../Zotlabs/Module/Impel.php:194
+#, php-format
+msgid "%s element installation failed"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1034
-msgid "Move photo to album"
+#: ../../Zotlabs/Module/Import_items.php:42 ../../Zotlabs/Module/Import.php:57
+msgid "Nothing to import."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1035
-msgid "Enter a new album name"
+#: ../../Zotlabs/Module/Import_items.php:66 ../../Zotlabs/Module/Import.php:69
+#: ../../Zotlabs/Module/Import.php:84
+msgid "Unable to download data from old server"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1036
-msgid "or select an existing one (doubleclick)"
+#: ../../Zotlabs/Module/Import_items.php:72 ../../Zotlabs/Module/Import.php:91
+msgid "Imported file is empty."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1039
-msgid "Caption"
+#: ../../Zotlabs/Module/Import_items.php:88
+#: ../../Zotlabs/Module/Import.php:111
+#, php-format
+msgid "Warning: Database versions differ by %1$d updates."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1041
-msgid "Add a Tag"
+#: ../../Zotlabs/Module/Import_items.php:104
+msgid "Import completed"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1049
-msgid "Example: @bob, @Barbara_Jensen, @jim@example.com"
+#: ../../Zotlabs/Module/Import_items.php:119
+msgid "Import Items"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1052
-msgid "Flag as adult in album view"
+#: ../../Zotlabs/Module/Import_items.php:120
+msgid "Use this form to import existing posts and content from an export file."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1071 ../../Zotlabs/Lib/ThreadItem.php:268
-msgid "I like this (toggle)"
+#: ../../Zotlabs/Module/Import_items.php:121
+#: ../../Zotlabs/Module/Import.php:495
+msgid "File to Upload"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1072 ../../Zotlabs/Lib/ThreadItem.php:269
-msgid "I don't like this (toggle)"
+#: ../../Zotlabs/Module/Manage.php:136
+#: ../../Zotlabs/Module/New_channel.php:121
+#, php-format
+msgid "You have created %1$.0f of %2$.0f allowed channels."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1073 ../../Zotlabs/Module/Webpages.php:245
-#: ../../Zotlabs/Module/Blocks.php:161 ../../Zotlabs/Module/Layouts.php:193
-#: ../../extend/addon/addon/cdav/include/widgets.php:123
-#: ../../include/conversation.php:1378
-msgid "Share"
+#: ../../Zotlabs/Module/Manage.php:143
+msgid "Create a new channel"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1074 ../../Zotlabs/Lib/ThreadItem.php:411
-#: ../../include/conversation.php:738
-msgid "Please wait"
+#: ../../Zotlabs/Module/Manage.php:164 ../../Zotlabs/Lib/Apps.php:221
+#: ../../include/nav.php:223
+msgid "Channel Manager"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1090 ../../Zotlabs/Module/Photos.php:1208
-#: ../../Zotlabs/Lib/ThreadItem.php:728
-msgid "This is you"
+#: ../../Zotlabs/Module/Manage.php:165
+msgid "Current Channel"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1092 ../../Zotlabs/Module/Photos.php:1210
-#: ../../Zotlabs/Lib/ThreadItem.php:730 ../../include/js_strings.php:6
-msgid "Comment"
+#: ../../Zotlabs/Module/Manage.php:167
+msgid "Switch to one of your channels by selecting it."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1108 ../../include/conversation.php:577
-msgctxt "title"
-msgid "Likes"
+#: ../../Zotlabs/Module/Manage.php:168
+msgid "Default Channel"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1108 ../../include/conversation.php:577
-msgctxt "title"
-msgid "Dislikes"
+#: ../../Zotlabs/Module/Manage.php:169
+msgid "Make Default"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1109 ../../include/conversation.php:578
-msgctxt "title"
-msgid "Agree"
+#: ../../Zotlabs/Module/Manage.php:172
+#, php-format
+msgid "%d new messages"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1109 ../../include/conversation.php:578
-msgctxt "title"
-msgid "Disagree"
+#: ../../Zotlabs/Module/Manage.php:173
+#, php-format
+msgid "%d new introductions"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1109 ../../include/conversation.php:578
-msgctxt "title"
-msgid "Abstain"
+#: ../../Zotlabs/Module/Manage.php:175
+msgid "Delegated Channel"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1110 ../../include/conversation.php:579
-msgctxt "title"
-msgid "Attending"
+#: ../../Zotlabs/Module/Oexchange.php:27
+msgid "Unable to find your hub."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1110 ../../include/conversation.php:579
-msgctxt "title"
-msgid "Not attending"
+#: ../../Zotlabs/Module/Oexchange.php:41
+msgid "Post successful."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1110 ../../include/conversation.php:579
-msgctxt "title"
-msgid "Might attend"
+#: ../../Zotlabs/Module/Connedit.php:82
+msgid "Could not access contact record."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1127 ../../Zotlabs/Module/Photos.php:1139
-#: ../../Zotlabs/Lib/ThreadItem.php:186 ../../Zotlabs/Lib/ThreadItem.php:198
-#: ../../include/conversation.php:1928
-msgid "View all"
+#: ../../Zotlabs/Module/Connedit.php:112
+msgid "Could not locate selected profile."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1131 ../../Zotlabs/Lib/ThreadItem.php:190
-#: ../../include/taxonomy.php:403 ../../include/conversation.php:1952
-#: ../../include/channel.php:1273
-msgctxt "noun"
-msgid "Like"
-msgid_plural "Likes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: ../../Zotlabs/Module/Photos.php:1136 ../../Zotlabs/Lib/ThreadItem.php:195
-#: ../../include/conversation.php:1955
-msgctxt "noun"
-msgid "Dislike"
-msgid_plural "Dislikes"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../Zotlabs/Module/Connedit.php:249
+msgid "Connection updated."
+msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1236
-msgid "Photo Tools"
+#: ../../Zotlabs/Module/Connedit.php:251
+msgid "Failed to update connection record."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1245
-msgid "In This Photo:"
+#: ../../Zotlabs/Module/Connedit.php:301
+msgid "is now connected to"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1250
-msgid "Map"
+#: ../../Zotlabs/Module/Connedit.php:434
+msgid "Could not access address book record."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1258 ../../Zotlabs/Lib/ThreadItem.php:400
-msgctxt "noun"
-msgid "Likes"
+#: ../../Zotlabs/Module/Connedit.php:482
+msgid "Refresh failed - channel is currently unavailable."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1259 ../../Zotlabs/Lib/ThreadItem.php:401
-msgctxt "noun"
-msgid "Dislikes"
+#: ../../Zotlabs/Module/Connedit.php:497 ../../Zotlabs/Module/Connedit.php:506
+#: ../../Zotlabs/Module/Connedit.php:515 ../../Zotlabs/Module/Connedit.php:524
+#: ../../Zotlabs/Module/Connedit.php:537
+msgid "Unable to set address book parameters."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1264 ../../Zotlabs/Lib/ThreadItem.php:406
-#: ../../include/acl_selectors.php:220
-msgid "Close"
+#: ../../Zotlabs/Module/Connedit.php:561
+msgid "Connection has been removed."
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1341
-msgid "View Album"
+#: ../../Zotlabs/Module/Connedit.php:601 ../../Zotlabs/Lib/Apps.php:228
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:57
+#: ../../include/conversation.php:936 ../../include/conversation.php:1049
+#: ../../include/nav.php:103
+msgid "View Profile"
msgstr ""
-#: ../../Zotlabs/Module/Photos.php:1352 ../../Zotlabs/Module/Photos.php:1365
-#: ../../Zotlabs/Module/Photos.php:1366
-msgid "Recent Photos"
+#: ../../Zotlabs/Module/Connedit.php:604
+#, php-format
+msgid "View %s's profile"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:24
-msgid "Privacy group created."
+#: ../../Zotlabs/Module/Connedit.php:608
+msgid "Refresh Permissions"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:30
-msgid "Could not create privacy group."
+#: ../../Zotlabs/Module/Connedit.php:611
+msgid "Fetch updated permissions"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:42 ../../Zotlabs/Module/Group.php:141
-#: ../../include/items.php:3901
-msgid "Privacy group not found."
+#: ../../Zotlabs/Module/Connedit.php:615
+msgid "Refresh Photo"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:58
-msgid "Privacy group updated."
+#: ../../Zotlabs/Module/Connedit.php:618
+msgid "Fetch updated photo"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:90
-msgid "Create a group of channels."
+#: ../../Zotlabs/Module/Connedit.php:622
+msgid "Recent Activity"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:91 ../../Zotlabs/Module/Group.php:184
-msgid "Privacy group name: "
+#: ../../Zotlabs/Module/Connedit.php:625
+msgid "View recent posts and comments"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:93 ../../Zotlabs/Module/Group.php:187
-msgid "Members are visible to other channels"
+#: ../../Zotlabs/Module/Connedit.php:632
+msgid "Block (or Unblock) all communications with this connection"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:111
-msgid "Privacy group removed."
+#: ../../Zotlabs/Module/Connedit.php:633
+msgid "This connection is blocked!"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:113
-msgid "Unable to remove privacy group."
+#: ../../Zotlabs/Module/Connedit.php:637
+msgid "Unignore"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:183
-msgid "Privacy group editor"
+#: ../../Zotlabs/Module/Connedit.php:640
+msgid "Ignore (or Unignore) all inbound communications from this connection"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:199
-msgid "All Connected Channels"
+#: ../../Zotlabs/Module/Connedit.php:641
+msgid "This connection is ignored!"
msgstr ""
-#: ../../Zotlabs/Module/Group.php:231
-msgid "Click on a channel to add or remove."
+#: ../../Zotlabs/Module/Connedit.php:645
+msgid "Unarchive"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:45
-msgid "Invalid message"
+#: ../../Zotlabs/Module/Connedit.php:645
+msgid "Archive"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:78
-msgid "no results"
+#: ../../Zotlabs/Module/Connedit.php:648
+msgid ""
+"Archive (or Unarchive) this connection - mark channel dead but keep content"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:93
-msgid "channel sync processed"
+#: ../../Zotlabs/Module/Connedit.php:649
+msgid "This connection is archived!"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:97
-msgid "queued"
+#: ../../Zotlabs/Module/Connedit.php:653
+msgid "Unhide"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:101
-msgid "posted"
+#: ../../Zotlabs/Module/Connedit.php:653
+msgid "Hide"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:105
-msgid "accepted for delivery"
+#: ../../Zotlabs/Module/Connedit.php:656
+msgid "Hide or Unhide this connection from your other connections"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:109
-msgid "updated"
+#: ../../Zotlabs/Module/Connedit.php:657
+msgid "This connection is hidden!"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:112
-msgid "update ignored"
+#: ../../Zotlabs/Module/Connedit.php:664
+msgid "Delete this connection"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:115
-msgid "permission denied"
+#: ../../Zotlabs/Module/Connedit.php:672
+msgid "Fetch Vcard"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:119
-msgid "recipient not found"
+#: ../../Zotlabs/Module/Connedit.php:675
+msgid "Fetch electronic calling card for this connection"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:122
-msgid "mail recalled"
+#: ../../Zotlabs/Module/Connedit.php:686
+msgid "Open Individual Permissions section by default"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:125
-msgid "duplicate mail received"
+#: ../../Zotlabs/Module/Connedit.php:709
+msgid "Affinity"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:128
-msgid "mail delivered"
+#: ../../Zotlabs/Module/Connedit.php:712
+msgid "Open Set Affinity section by default"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:148
-#, php-format
-msgid "Delivery report for %1$s"
+#: ../../Zotlabs/Module/Connedit.php:716 ../../include/widgets.php:526
+msgid "Me"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:151
-msgid "Options"
+#: ../../Zotlabs/Module/Connedit.php:717 ../../include/widgets.php:527
+msgid "Family"
msgstr ""
-#: ../../Zotlabs/Module/Dreport.php:152
-msgid "Redeliver"
+#: ../../Zotlabs/Module/Connedit.php:718
+#: ../../Zotlabs/Module/Settings/Channel.php:62
+#: ../../Zotlabs/Module/Settings/Channel.php:66
+#: ../../Zotlabs/Module/Settings/Channel.php:67
+#: ../../Zotlabs/Module/Settings/Channel.php:70
+#: ../../Zotlabs/Module/Settings/Channel.php:81
+#: ../../include/selectors.php:123 ../../include/widgets.php:528
+#: ../../include/channel.php:408 ../../include/channel.php:409
+#: ../../include/channel.php:416
+msgid "Friends"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:65
-msgid "Unable to lookup recipient."
+#: ../../Zotlabs/Module/Connedit.php:719 ../../include/widgets.php:529
+msgid "Acquaintances"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:72
-msgid "Unable to communicate with requested channel."
+#: ../../Zotlabs/Module/Connedit.php:746
+msgid "Filter"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:79
-msgid "Cannot verify requested channel."
+#: ../../Zotlabs/Module/Connedit.php:749
+msgid "Open Custom Filter section by default"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:97
-msgid "Selected channel has private message restrictions. Send failed."
+#: ../../Zotlabs/Module/Connedit.php:786
+msgid "Approve this connection"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:178
-msgid "Messages"
+#: ../../Zotlabs/Module/Connedit.php:786
+msgid "Accept connection to allow communication"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:213
-msgid "Message recalled."
+#: ../../Zotlabs/Module/Connedit.php:791
+msgid "Set Affinity"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:226
-msgid "Conversation removed."
+#: ../../Zotlabs/Module/Connedit.php:794
+msgid "Set Profile"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:240 ../../Zotlabs/Module/Mail.php:349
-#: ../../Zotlabs/Module/Chat.php:203 ../../include/conversation.php:1330
-msgid "Please enter a link URL:"
+#: ../../Zotlabs/Module/Connedit.php:797
+msgid "Set Affinity & Profile"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:241 ../../Zotlabs/Module/Mail.php:350
-msgid "Expires YYYY-MM-DD HH:MM"
+#: ../../Zotlabs/Module/Connedit.php:855
+msgid "none"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:269
-msgid "Requested channel is not in this network"
+#: ../../Zotlabs/Module/Connedit.php:858 ../../include/widgets.php:661
+msgid "Connection Default Permissions"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:277
-msgid "Send Private Message"
+#: ../../Zotlabs/Module/Connedit.php:858 ../../include/items.php:3837
+#, php-format
+msgid "Connection: %s"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:278 ../../Zotlabs/Module/Mail.php:403
-msgid "To:"
+#: ../../Zotlabs/Module/Connedit.php:859
+msgid "Apply these permissions automatically"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:281 ../../Zotlabs/Module/Mail.php:405
-msgid "Subject:"
+#: ../../Zotlabs/Module/Connedit.php:859
+msgid "Connection requests will be approved without your interaction"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:284 ../../Zotlabs/Module/Invite.php:138
-msgid "Your message:"
+#: ../../Zotlabs/Module/Connedit.php:860
+msgid "Permission role"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:286 ../../Zotlabs/Module/Mail.php:411
-#: ../../include/conversation.php:1390
-msgid "Attach file"
+#: ../../Zotlabs/Module/Connedit.php:861
+msgid "Add permission role"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:288
-msgid "Send"
+#: ../../Zotlabs/Module/Connedit.php:867
+msgid "This connection's primary address is"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:291 ../../Zotlabs/Module/Mail.php:416
-#: ../../include/conversation.php:1435
-msgid "Set expiration date"
+#: ../../Zotlabs/Module/Connedit.php:868
+msgid "Available locations:"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:293 ../../Zotlabs/Module/Mail.php:418
-#: ../../Zotlabs/Module/Chat.php:204 ../../Zotlabs/Lib/ThreadItem.php:743
-#: ../../include/conversation.php:1440
-msgid "Encrypt text"
+#: ../../Zotlabs/Module/Connedit.php:872
+msgid ""
+"The permissions indicated on this page will be applied to all new "
+"connections."
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:375
-msgid "Delete message"
+#: ../../Zotlabs/Module/Connedit.php:873
+msgid "Connection Tools"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:376
-msgid "Delivery report"
+#: ../../Zotlabs/Module/Connedit.php:875
+msgid "Slide to adjust your degree of friendship"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:377
-msgid "Recall message"
+#: ../../Zotlabs/Module/Connedit.php:876 ../../Zotlabs/Module/Rate.php:155
+#: ../../include/js_strings.php:20
+msgid "Rating"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:379
-msgid "Message has been recalled."
+#: ../../Zotlabs/Module/Connedit.php:877
+msgid "Slide to adjust your rating"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:396
-msgid "Delete Conversation"
+#: ../../Zotlabs/Module/Connedit.php:878 ../../Zotlabs/Module/Connedit.php:883
+msgid "Optionally explain your rating"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:398
-msgid ""
-"No secure communications available. You may be able to "
-"respond from the sender's profile page."
+#: ../../Zotlabs/Module/Connedit.php:880
+msgid "Custom Filter"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:402
-msgid "Send Reply"
+#: ../../Zotlabs/Module/Connedit.php:881
+msgid "Only import posts with this text"
msgstr ""
-#: ../../Zotlabs/Module/Mail.php:407
-#, php-format
-msgid "Your message for %s (%s):"
+#: ../../Zotlabs/Module/Connedit.php:881 ../../Zotlabs/Module/Connedit.php:882
+msgid ""
+"words one per line or #tags or /patterns/ or lang=xx, leave blank to import "
+"all posts"
msgstr ""
-#: ../../Zotlabs/Module/Impel.php:41 ../../include/bbcode.php:203
-msgid "webpage"
+#: ../../Zotlabs/Module/Connedit.php:882
+msgid "Do not import posts with this text"
msgstr ""
-#: ../../Zotlabs/Module/Impel.php:46 ../../include/bbcode.php:209
-msgid "block"
+#: ../../Zotlabs/Module/Connedit.php:884
+msgid "This information is public!"
msgstr ""
-#: ../../Zotlabs/Module/Impel.php:51 ../../include/bbcode.php:206
-msgid "layout"
+#: ../../Zotlabs/Module/Connedit.php:889
+msgid "Connection Pending Approval"
msgstr ""
-#: ../../Zotlabs/Module/Impel.php:58 ../../include/bbcode.php:212
-msgid "menu"
+#: ../../Zotlabs/Module/Connedit.php:892
+#: ../../Zotlabs/Module/Settings/Permcats.php:107
+#: ../../Zotlabs/Module/Settings/Tokens.php:163
+msgid "inherited"
msgstr ""
-#: ../../Zotlabs/Module/Impel.php:191
+#: ../../Zotlabs/Module/Connedit.php:894
#, php-format
-msgid "%s element installed"
+msgid ""
+"Please choose the profile you would like to display to %s when viewing your "
+"profile securely."
msgstr ""
-#: ../../Zotlabs/Module/Impel.php:194
-#, php-format
-msgid "%s element installation failed"
+#: ../../Zotlabs/Module/Connedit.php:896
+#: ../../Zotlabs/Module/Settings/Tokens.php:160
+msgid "Their Settings"
msgstr ""
-#: ../../Zotlabs/Module/Import_items.php:104
-msgid "Import completed"
+#: ../../Zotlabs/Module/Connedit.php:897
+#: ../../Zotlabs/Module/Settings/Permcats.php:105
+#: ../../Zotlabs/Module/Settings/Tokens.php:161
+msgid "My Settings"
msgstr ""
-#: ../../Zotlabs/Module/Import_items.php:119
-msgid "Import Items"
+#: ../../Zotlabs/Module/Connedit.php:899
+#: ../../Zotlabs/Module/Settings/Permcats.php:110
+#: ../../Zotlabs/Module/Settings/Tokens.php:166
+msgid "Individual Permissions"
msgstr ""
-#: ../../Zotlabs/Module/Import_items.php:120
-msgid "Use this form to import existing posts and content from an export file."
+#: ../../Zotlabs/Module/Connedit.php:900
+#: ../../Zotlabs/Module/Settings/Permcats.php:111
+#: ../../Zotlabs/Module/Settings/Tokens.php:167
+msgid ""
+"Some permissions may be inherited from your channel's privacy settings, which have higher priority than "
+"individual settings. You can not change those settings here."
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:136
-#: ../../Zotlabs/Module/New_channel.php:121
-#, php-format
-msgid "You have created %1$.0f of %2$.0f allowed channels."
+#: ../../Zotlabs/Module/Connedit.php:901
+msgid ""
+"Some permissions may be inherited from your channel's privacy settings, which have higher priority than "
+"individual settings. You can change those settings here but they wont have "
+"any impact unless the inherited setting changes."
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:143
-msgid "Create a new channel"
+#: ../../Zotlabs/Module/Connedit.php:902
+msgid "Last update:"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:143 ../../Zotlabs/Module/Profiles.php:834
-#: ../../Zotlabs/Module/Wiki.php:167 ../../Zotlabs/Module/Chat.php:253
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:152
-msgid "Create New"
+#: ../../Zotlabs/Module/Connedit.php:911
+msgid "Details"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:164 ../../Zotlabs/Lib/Apps.php:221
-#: ../../include/nav.php:223
-msgid "Channel Manager"
+#: ../../Zotlabs/Module/Connedit.php:914
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1137
+msgid "Organisation"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:165
-msgid "Current Channel"
+#: ../../Zotlabs/Module/Connedit.php:915
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1138
+#: ../../include/page_widgets.php:46
+msgid "Title"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:167
-msgid "Switch to one of your channels by selecting it."
+#: ../../Zotlabs/Module/Connedit.php:932
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1155
+msgid "P.O. Box"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:168
-msgid "Default Channel"
+#: ../../Zotlabs/Module/Connedit.php:933
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1156
+msgid "Additional"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:169
-msgid "Make Default"
+#: ../../Zotlabs/Module/Connedit.php:934
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1157
+msgid "Street"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:172
-#, php-format
-msgid "%d new messages"
+#: ../../Zotlabs/Module/Connedit.php:935
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1158
+msgid "Locality"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:173
-#, php-format
-msgid "%d new introductions"
+#: ../../Zotlabs/Module/Connedit.php:936
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1159
+msgid "Region"
msgstr ""
-#: ../../Zotlabs/Module/Manage.php:175
-msgid "Delegated Channel"
+#: ../../Zotlabs/Module/Connedit.php:937
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:1160
+msgid "ZIP Code"
msgstr ""
#: ../../Zotlabs/Module/Magic.php:71
@@ -4438,14 +4562,18 @@ msgstr ""
msgid "Link text"
msgstr ""
-#: ../../Zotlabs/Module/Editpost.php:35
-msgid "Item is not editable"
-msgstr ""
-
#: ../../Zotlabs/Module/Ratings.php:70
msgid "No ratings"
msgstr ""
+#: ../../Zotlabs/Module/Ratings.php:83 ../../Zotlabs/Module/Search.php:17
+#: ../../Zotlabs/Module/Directory.php:64 ../../Zotlabs/Module/Display.php:22
+#: ../../Zotlabs/Module/Viewconnections.php:23
+#: ../../Zotlabs/Module/Photos.php:508
+#: ../../extend/addon/addon/friendica/dfrn_request.php:794
+msgid "Public access denied."
+msgstr ""
+
#: ../../Zotlabs/Module/Ratings.php:98
msgid "Rating: "
msgstr ""
@@ -4462,14 +4590,6 @@ msgstr ""
msgid "Item not available."
msgstr ""
-#: ../../Zotlabs/Module/Cal.php:69
-msgid "Permissions denied."
-msgstr ""
-
-#: ../../Zotlabs/Module/Cal.php:341 ../../include/text.php:2312
-msgid "Import"
-msgstr ""
-
#: ../../Zotlabs/Module/Notify.php:57
#: ../../Zotlabs/Module/Notifications.php:38
msgid "No more system notifications."
@@ -4480,6 +4600,40 @@ msgstr ""
msgid "System Notifications"
msgstr ""
+#: ../../Zotlabs/Module/Item.php:184
+msgid "Unable to locate original post."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:450
+msgid "Empty post discarded."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:492
+msgid "Executable content type not permitted to this channel."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:842
+msgid "Duplicate post suppressed."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:984
+msgid "System error. Post not saved."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:1114
+msgid "Unable to obtain post information from database."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:1121
+#, php-format
+msgid "You have reached your limit of %1$.0f top level posts."
+msgstr ""
+
+#: ../../Zotlabs/Module/Item.php:1128
+#, php-format
+msgid "You have reached your limit of %1$.0f webpages."
+msgstr ""
+
#: ../../Zotlabs/Module/Api.php:72 ../../Zotlabs/Module/Api.php:93
msgid "Authorize application connection"
msgstr ""
@@ -4539,6 +4693,10 @@ msgstr ""
msgid "Enter email addresses, one per line:"
msgstr ""
+#: ../../Zotlabs/Module/Invite.php:138 ../../Zotlabs/Module/Mail.php:284
+msgid "Your message:"
+msgstr ""
+
#: ../../Zotlabs/Module/Invite.php:139
msgid "Please join my community on $Projectname."
msgstr ""
@@ -4571,7 +4729,7 @@ msgstr ""
msgid "Site Name"
msgstr ""
-#: ../../Zotlabs/Module/Siteinfo.php:25 ../../include/network.php:1995
+#: ../../Zotlabs/Module/Siteinfo.php:25 ../../include/network.php:1474
msgid "Administrator"
msgstr ""
@@ -4617,579 +4775,680 @@ msgid ""
"or import an existing channel from another location."
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:52
-msgid "Import Webpage Elements"
+#: ../../Zotlabs/Module/Notifications.php:43 ../../include/nav.php:208
+msgid "Mark all system notifications seen"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:53
-msgid "Import selected"
+#: ../../Zotlabs/Module/Poke.php:168 ../../Zotlabs/Lib/Apps.php:235
+#: ../../include/conversation.php:942 ../../include/conversation.php:1109
+msgid "Poke"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:76
-msgid "Export Webpage Elements"
+#: ../../Zotlabs/Module/Poke.php:169
+msgid "Poke somebody"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:77
-msgid "Export selected"
+#: ../../Zotlabs/Module/Poke.php:172
+msgid "Poke/Prod"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:241 ../../Zotlabs/Lib/Apps.php:225
-#: ../../include/conversation.php:1889
-msgid "Webpages"
+#: ../../Zotlabs/Module/Poke.php:173
+msgid "Poke, prod or do other things to somebody"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:252 ../../include/page_widgets.php:44
-msgid "Actions"
+#: ../../Zotlabs/Module/Poke.php:180
+msgid "Recipient"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:253 ../../include/page_widgets.php:45
-msgid "Page Link"
+#: ../../Zotlabs/Module/Poke.php:181
+msgid "Choose what you wish to do to recipient"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:254
-msgid "Page Title"
+#: ../../Zotlabs/Module/Poke.php:184 ../../Zotlabs/Module/Poke.php:185
+msgid "Make this post private"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:284
-msgid "Invalid file type."
+#: ../../Zotlabs/Module/Search.php:224
+#, php-format
+msgid "Items tagged with: %s"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:296
-msgid "Error opening zip file"
+#: ../../Zotlabs/Module/Search.php:226
+#, php-format
+msgid "Search results for: %s"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:307
-msgid "Invalid folder path."
+#: ../../Zotlabs/Module/Wiki.php:30
+msgid "Profile Unavailable."
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:334
-msgid "No webpage elements detected."
+#: ../../Zotlabs/Module/Wiki.php:44
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:40
+msgid "Not found"
msgstr ""
-#: ../../Zotlabs/Module/Webpages.php:409
-msgid "Import complete."
+#: ../../Zotlabs/Module/Wiki.php:68
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:60
+msgid "Invalid channel"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:159
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:144
+#: ../../include/conversation.php:1900
+msgid "Wikis"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:165
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:150
+msgid "Download"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:169
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:154
+msgid "Wiki name"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:170
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:155
+msgid "Content type"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:179
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:164
+msgid "Create a status post for this wiki"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:204
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:183
+msgid "Wiki not found"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:228
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:208
+msgid "Rename page"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:232
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:212
+msgid "Error retrieving page content"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:259
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:241
+msgid "Revision Comparison"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:260
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:242
+msgid "Revert"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:264
+msgid "Short description of your changes (optional)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:271
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:251
+msgid "Source"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:279
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:259
+msgid "New page name"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:284
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:264
+#: ../../include/conversation.php:1299
+msgid "Embed image from photo albums"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:285
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:265
+#: ../../include/conversation.php:1393
+msgid "Embed an image from your albums"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:287
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:267
+#: ../../include/conversation.php:1395 ../../include/conversation.php:1442
+msgid "OK"
+msgstr ""
+
+#: ../../Zotlabs/Module/Wiki.php:288
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:268
+#: ../../include/conversation.php:1335
+msgid "Choose images to embed"
msgstr ""
-#: ../../Zotlabs/Module/Notifications.php:43 ../../include/nav.php:208
-msgid "Mark all system notifications seen"
+#: ../../Zotlabs/Module/Wiki.php:289
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:269
+#: ../../include/conversation.php:1336
+msgid "Choose an album"
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:168 ../../Zotlabs/Lib/Apps.php:235
-#: ../../include/conversation.php:942 ../../include/conversation.php:1109
-msgid "Poke"
+#: ../../Zotlabs/Module/Wiki.php:290
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:270
+msgid "Choose a different album"
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:169
-msgid "Poke somebody"
+#: ../../Zotlabs/Module/Wiki.php:291
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:271
+#: ../../include/conversation.php:1338
+msgid "Error getting album list"
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:172
-msgid "Poke/Prod"
+#: ../../Zotlabs/Module/Wiki.php:292
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:272
+#: ../../include/conversation.php:1339
+msgid "Error getting photo link"
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:173
-msgid "Poke, prod or do other things to somebody"
+#: ../../Zotlabs/Module/Wiki.php:293
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:273
+#: ../../include/conversation.php:1340
+msgid "Error getting album"
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:180
-msgid "Recipient"
+#: ../../Zotlabs/Module/Wiki.php:357
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:337
+msgid "Error creating wiki. Invalid name."
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:181
-msgid "Choose what you wish to do to recipient"
+#: ../../Zotlabs/Module/Wiki.php:369
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:348
+msgid "Wiki created, but error creating Home page."
msgstr ""
-#: ../../Zotlabs/Module/Poke.php:184 ../../Zotlabs/Module/Poke.php:185
-msgid "Make this post private"
+#: ../../Zotlabs/Module/Wiki.php:376
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:353
+msgid "Error creating wiki"
msgstr ""
-#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63
-msgid "Invalid profile identifier."
+#: ../../Zotlabs/Module/Wiki.php:388
+msgid "Wiki delete permission denied."
msgstr ""
-#: ../../Zotlabs/Module/Profperm.php:111
-msgid "Profile Visibility Editor"
+#: ../../Zotlabs/Module/Wiki.php:398
+msgid "Error deleting wiki"
msgstr ""
-#: ../../Zotlabs/Module/Profperm.php:113 ../../include/channel.php:1367
-msgid "Profile"
+#: ../../Zotlabs/Module/Wiki.php:424
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:400
+msgid "New page created"
msgstr ""
-#: ../../Zotlabs/Module/Profperm.php:115
-msgid "Click on a contact to add or remove."
+#: ../../Zotlabs/Module/Wiki.php:539
+msgid "Cannot delete Home"
msgstr ""
-#: ../../Zotlabs/Module/Profperm.php:124
-msgid "Visible To"
+#: ../../Zotlabs/Module/Wiki.php:603
+msgid "Current Revision"
msgstr ""
-#: ../../Zotlabs/Module/Hcard.php:35 ../../Zotlabs/Module/Channel.php:47
-#: ../../Zotlabs/Module/Profile.php:43
-msgid "Posts and comments"
+#: ../../Zotlabs/Module/Wiki.php:603
+msgid "Selected Revision"
msgstr ""
-#: ../../Zotlabs/Module/Hcard.php:42 ../../Zotlabs/Module/Channel.php:54
-#: ../../Zotlabs/Module/Profile.php:50
-msgid "Only posts"
+#: ../../Zotlabs/Module/Wiki.php:653
+msgid "You must be authenticated."
msgstr ""
-#: ../../Zotlabs/Module/Item.php:184
-msgid "Unable to locate original post."
+#: ../../Zotlabs/Module/Like.php:19
+msgid "Like/Dislike"
msgstr ""
-#: ../../Zotlabs/Module/Item.php:450
-msgid "Empty post discarded."
+#: ../../Zotlabs/Module/Like.php:24
+msgid "This action is restricted to members."
msgstr ""
-#: ../../Zotlabs/Module/Item.php:492
-msgid "Executable content type not permitted to this channel."
+#: ../../Zotlabs/Module/Like.php:25
+msgid ""
+"Please login with your $Projectname ID or register as a new $Projectname member to continue."
msgstr ""
-#: ../../Zotlabs/Module/Item.php:842
-msgid "Duplicate post suppressed."
+#: ../../Zotlabs/Module/Like.php:105 ../../Zotlabs/Module/Like.php:131
+#: ../../Zotlabs/Module/Like.php:169
+msgid "Invalid request."
msgstr ""
-#: ../../Zotlabs/Module/Item.php:984
-msgid "System error. Post not saved."
+#: ../../Zotlabs/Module/Like.php:117 ../../include/conversation.php:126
+msgid "channel"
msgstr ""
-#: ../../Zotlabs/Module/Item.php:1114
-msgid "Unable to obtain post information from database."
+#: ../../Zotlabs/Module/Like.php:146
+msgid "thing"
msgstr ""
-#: ../../Zotlabs/Module/Item.php:1121
-#, php-format
-msgid "You have reached your limit of %1$.0f top level posts."
+#: ../../Zotlabs/Module/Like.php:192
+msgid "Channel unavailable."
msgstr ""
-#: ../../Zotlabs/Module/Item.php:1128
-#, php-format
-msgid "You have reached your limit of %1$.0f webpages."
+#: ../../Zotlabs/Module/Like.php:240
+msgid "Previous action reversed."
msgstr ""
-#: ../../Zotlabs/Module/Pconfig.php:26 ../../Zotlabs/Module/Pconfig.php:59
-msgid "This setting requires special processing and editing has been blocked."
+#: ../../Zotlabs/Module/Like.php:370 ../../Zotlabs/Module/Subthread.php:87
+#: ../../Zotlabs/Module/Tagger.php:47
+#: ../../extend/addon/addon/diaspora/inbound.php:1794
+#: ../../extend/addon/addon/redphotos/redphotohelper.php:74
+#: ../../include/conversation.php:120 ../../include/text.php:1942
+msgid "photo"
msgstr ""
-#: ../../Zotlabs/Module/Pconfig.php:48
-msgid "Configuration Editor"
+#: ../../Zotlabs/Module/Like.php:370 ../../Zotlabs/Module/Subthread.php:87
+#: ../../extend/addon/addon/diaspora/inbound.php:1794
+#: ../../include/conversation.php:148 ../../include/text.php:1948
+msgid "status"
msgstr ""
-#: ../../Zotlabs/Module/Pconfig.php:49
-msgid ""
-"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."
+#: ../../Zotlabs/Module/Like.php:372 ../../Zotlabs/Module/Events.php:260
+#: ../../Zotlabs/Module/Tagger.php:51 ../../include/event.php:1145
+#: ../../include/conversation.php:123 ../../include/text.php:1945
+msgid "event"
msgstr ""
-#: ../../Zotlabs/Module/Search.php:224
+#: ../../Zotlabs/Module/Like.php:419
+#: ../../extend/addon/addon/diaspora/inbound.php:1823
+#: ../../include/conversation.php:164
#, php-format
-msgid "Items tagged with: %s"
+msgid "%1$s likes %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Search.php:226
+#: ../../Zotlabs/Module/Like.php:421 ../../include/conversation.php:167
#, php-format
-msgid "Search results for: %s"
-msgstr ""
-
-#: ../../Zotlabs/Module/Lockview.php:75
-msgid "Remote privacy information not available."
-msgstr ""
-
-#: ../../Zotlabs/Module/Lockview.php:96
-msgid "Visible to:"
+msgid "%1$s doesn't like %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Lockview.php:117 ../../Zotlabs/Module/Lockview.php:153
-#: ../../Zotlabs/Module/Acl.php:117 ../../include/acl_selectors.php:183
-msgctxt "acl"
-msgid "Profile"
+#: ../../Zotlabs/Module/Like.php:423
+#, php-format
+msgid "%1$s agrees with %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2288
-msgid "Blocks"
+#: ../../Zotlabs/Module/Like.php:425
+#, php-format
+msgid "%1$s doesn't agree with %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Blocks.php:156
-msgid "Block Title"
+#: ../../Zotlabs/Module/Like.php:427
+#, php-format
+msgid "%1$s abstains from a decision on %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Layouts.php:183 ../../include/text.php:2290
-msgid "Layouts"
+#: ../../Zotlabs/Module/Like.php:429
+#, php-format
+msgid "%1$s is attending %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Layouts.php:185 ../../Zotlabs/Lib/Apps.php:232
-#: ../../include/help.php:55 ../../include/help.php:61
-#: ../../include/nav.php:174 ../../include/nav.php:288
-msgid "Help"
+#: ../../Zotlabs/Module/Like.php:431
+#, php-format
+msgid "%1$s is not attending %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Layouts.php:185
-msgid "Comanche page description language help"
+#: ../../Zotlabs/Module/Like.php:433
+#, php-format
+msgid "%1$s may attend %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Layouts.php:189
-msgid "Layout Description"
+#: ../../Zotlabs/Module/Like.php:538
+msgid "Action completed."
msgstr ""
-#: ../../Zotlabs/Module/Layouts.php:194
-msgid "Download PDL file"
+#: ../../Zotlabs/Module/Like.php:539
+msgid "Thank you."
msgstr ""
-#: ../../Zotlabs/Module/Rate.php:156
-msgid "Website:"
+#: ../../Zotlabs/Module/Lockview.php:75
+msgid "Remote privacy information not available."
msgstr ""
-#: ../../Zotlabs/Module/Rate.php:159
-#, php-format
-msgid "Remote Channel [%s] (not yet known on this site)"
+#: ../../Zotlabs/Module/Lockview.php:96
+msgid "Visible to:"
msgstr ""
-#: ../../Zotlabs/Module/Rate.php:160
-msgid "Rating (this information is public)"
+#: ../../Zotlabs/Module/Pconfig.php:26 ../../Zotlabs/Module/Pconfig.php:59
+msgid "This setting requires special processing and editing has been blocked."
msgstr ""
-#: ../../Zotlabs/Module/Rate.php:161
-msgid "Optionally explain your rating (this information is public)"
+#: ../../Zotlabs/Module/Pconfig.php:48
+msgid "Configuration Editor"
msgstr ""
-#: ../../Zotlabs/Module/Profile_photo.php:194
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:298
+#: ../../Zotlabs/Module/Pconfig.php:49
msgid ""
-"Shift-reload the page or clear browser cache if the new photo does not "
-"display immediately."
-msgstr ""
-
-#: ../../Zotlabs/Module/Profile_photo.php:420
-msgid "Use Photo for Profile"
+"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."
msgstr ""
-#: ../../Zotlabs/Module/Profile_photo.php:420
-msgid "Upload Profile Photo"
+#: ../../Zotlabs/Module/Subthread.php:118
+#, php-format
+msgid "%1$s is following %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Profile_photo.php:421
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:182
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:194
-msgid "Use"
+#: ../../Zotlabs/Module/Subthread.php:120
+#, php-format
+msgid "%1$s stopped following %2$s's %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:19
-msgid "Like/Dislike"
+#: ../../Zotlabs/Module/Mood.php:67 ../../include/conversation.php:260
+#, php-format
+msgctxt "mood"
+msgid "%1$s is %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:24
-msgid "This action is restricted to members."
+#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Lib/Apps.php:234
+msgid "Mood"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:25
-msgid ""
-"Please login with your $Projectname ID or register as a new $Projectname member to continue."
+#: ../../Zotlabs/Module/Mood.php:136
+msgid "Set your current mood and tell your friends"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:105 ../../Zotlabs/Module/Like.php:131
-#: ../../Zotlabs/Module/Like.php:169
-msgid "Invalid request."
+#: ../../Zotlabs/Module/Mail.php:65
+msgid "Unable to lookup recipient."
msgstr ""
-#: ../../Zotlabs/Module/Like.php:117 ../../include/conversation.php:126
-msgid "channel"
+#: ../../Zotlabs/Module/Mail.php:72
+msgid "Unable to communicate with requested channel."
msgstr ""
-
-#: ../../Zotlabs/Module/Like.php:146
-msgid "thing"
+
+#: ../../Zotlabs/Module/Mail.php:79
+msgid "Cannot verify requested channel."
msgstr ""
-#: ../../Zotlabs/Module/Like.php:192
-msgid "Channel unavailable."
+#: ../../Zotlabs/Module/Mail.php:97
+msgid "Selected channel has private message restrictions. Send failed."
msgstr ""
-#: ../../Zotlabs/Module/Like.php:240
-msgid "Previous action reversed."
+#: ../../Zotlabs/Module/Mail.php:178
+msgid "Messages"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:370 ../../Zotlabs/Module/Subthread.php:87
-#: ../../Zotlabs/Module/Tagger.php:47
-#: ../../extend/addon/addon/diaspora/inbound.php:1794
-#: ../../extend/addon/addon/redphotos/redphotohelper.php:74
-#: ../../include/conversation.php:120 ../../include/text.php:1958
-msgid "photo"
+#: ../../Zotlabs/Module/Mail.php:213
+msgid "Message recalled."
msgstr ""
-#: ../../Zotlabs/Module/Like.php:370 ../../Zotlabs/Module/Subthread.php:87
-#: ../../extend/addon/addon/diaspora/inbound.php:1794
-#: ../../include/conversation.php:148 ../../include/text.php:1964
-msgid "status"
+#: ../../Zotlabs/Module/Mail.php:226
+msgid "Conversation removed."
msgstr ""
-#: ../../Zotlabs/Module/Like.php:419
-#: ../../extend/addon/addon/diaspora/inbound.php:1823
-#: ../../include/conversation.php:164
-#, php-format
-msgid "%1$s likes %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:241 ../../Zotlabs/Module/Mail.php:350
+msgid "Expires YYYY-MM-DD HH:MM"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:421 ../../include/conversation.php:167
-#, php-format
-msgid "%1$s doesn't like %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:269
+msgid "Requested channel is not in this network"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:423
-#, php-format
-msgid "%1$s agrees with %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:277
+msgid "Send Private Message"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:425
-#, php-format
-msgid "%1$s doesn't agree with %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:278 ../../Zotlabs/Module/Mail.php:403
+msgid "To:"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:427
-#, php-format
-msgid "%1$s abstains from a decision on %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:281 ../../Zotlabs/Module/Mail.php:405
+msgid "Subject:"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:429
-#, php-format
-msgid "%1$s is attending %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:286 ../../Zotlabs/Module/Mail.php:411
+#: ../../include/conversation.php:1390
+msgid "Attach file"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:431
-#, php-format
-msgid "%1$s is not attending %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:288
+msgid "Send"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:433
-#, php-format
-msgid "%1$s may attend %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:291 ../../Zotlabs/Module/Mail.php:416
+#: ../../include/conversation.php:1435
+msgid "Set expiration date"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:538
-msgid "Action completed."
+#: ../../Zotlabs/Module/Mail.php:375
+msgid "Delete message"
msgstr ""
-#: ../../Zotlabs/Module/Like.php:539
-msgid "Thank you."
+#: ../../Zotlabs/Module/Mail.php:376
+msgid "Delivery report"
msgstr ""
-#: ../../Zotlabs/Module/Common.php:14
-msgid "No channel."
+#: ../../Zotlabs/Module/Mail.php:377
+msgid "Recall message"
msgstr ""
-#: ../../Zotlabs/Module/Common.php:43
-msgid "Common connections"
+#: ../../Zotlabs/Module/Mail.php:379
+msgid "Message has been recalled."
msgstr ""
-#: ../../Zotlabs/Module/Common.php:48
-msgid "No connections in common."
+#: ../../Zotlabs/Module/Mail.php:396
+msgid "Delete Conversation"
msgstr ""
-#: ../../Zotlabs/Module/Chanview.php:134
-msgid "toggle full screen mode"
+#: ../../Zotlabs/Module/Mail.php:398
+msgid ""
+"No secure communications available. You may be able to "
+"respond from the sender's profile page."
msgstr ""
-#: ../../Zotlabs/Module/Subthread.php:118
-#, php-format
-msgid "%1$s is following %2$s's %3$s"
+#: ../../Zotlabs/Module/Mail.php:402
+msgid "Send Reply"
msgstr ""
-#: ../../Zotlabs/Module/Subthread.php:120
+#: ../../Zotlabs/Module/Mail.php:407
#, php-format
-msgid "%1$s stopped following %2$s's %3$s"
+msgid "Your message for %s (%s):"
msgstr ""
-#: ../../Zotlabs/Module/Channel.php:32 ../../Zotlabs/Module/Chat.php:25
-#: ../../extend/addon/addon/chess/chess.php:403
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:26
-msgid "You must be logged in to see this page."
+#: ../../Zotlabs/Module/Blocks.php:154 ../../include/text.php:2272
+msgid "Blocks"
msgstr ""
-#: ../../Zotlabs/Module/Channel.php:112
-msgid "Insufficient permissions. Request redirected to profile page."
+#: ../../Zotlabs/Module/Blocks.php:156
+msgid "Block Title"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:19
-msgid "No valid account found."
+#: ../../Zotlabs/Module/Layouts.php:183 ../../include/text.php:2274
+msgid "Layouts"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:33
-msgid "Password reset request issued. Check your email."
+#: ../../Zotlabs/Module/Layouts.php:185 ../../Zotlabs/Lib/Apps.php:232
+#: ../../include/help.php:55 ../../include/help.php:61
+#: ../../include/nav.php:174 ../../include/nav.php:288
+msgid "Help"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108
-#, php-format
-msgid "Site Member (%s)"
+#: ../../Zotlabs/Module/Layouts.php:185
+msgid "Comanche page description language help"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49
-#, php-format
-msgid "Password reset requested at %s"
+#: ../../Zotlabs/Module/Layouts.php:189
+msgid "Layout Description"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:68
-msgid ""
-"Request could not be verified. (You may have previously submitted it.) "
-"Password reset failed."
+#: ../../Zotlabs/Module/Layouts.php:194
+msgid "Download PDL file"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1757
-msgid "Password Reset"
+#: ../../Zotlabs/Module/Rate.php:156
+msgid "Website:"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:92
-msgid "Your password has been reset as requested."
+#: ../../Zotlabs/Module/Rate.php:159
+#, php-format
+msgid "Remote Channel [%s] (not yet known on this site)"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:93
-msgid "Your new password is"
+#: ../../Zotlabs/Module/Rate.php:160
+msgid "Rating (this information is public)"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:94
-msgid "Save or copy your new password - and then"
+#: ../../Zotlabs/Module/Rate.php:161
+msgid "Optionally explain your rating (this information is public)"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:95
-msgid "click here to login"
+#: ../../Zotlabs/Module/Profile_photo.php:115
+#: ../../Zotlabs/Module/Profile_photo.php:224
+#: ../../Zotlabs/Module/Photos.php:97 ../../Zotlabs/Module/Photos.php:729
+#: ../../include/photo/photo_driver.php:730
+msgid "Profile Photos"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:96
+#: ../../Zotlabs/Module/Profile_photo.php:194
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:298
msgid ""
-"Your password may be changed from the Settings page after "
-"successful login."
+"Shift-reload the page or clear browser cache if the new photo does not "
+"display immediately."
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:117
-#, php-format
-msgid "Your password has changed at %s"
+#: ../../Zotlabs/Module/Profile_photo.php:420
+msgid "Use Photo for Profile"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:130
-msgid "Forgot your Password?"
+#: ../../Zotlabs/Module/Profile_photo.php:420
+msgid "Upload Profile Photo"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:131
-msgid ""
-"Enter your email address and submit to have your password reset. Then check "
-"your email for further instructions."
+#: ../../Zotlabs/Module/Profile_photo.php:421
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:182
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:194
+msgid "Use"
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:132
-msgid "Email Address"
+#: ../../Zotlabs/Module/Appman.php:38 ../../Zotlabs/Module/Appman.php:55
+msgid "App installed."
msgstr ""
-#: ../../Zotlabs/Module/Lostpass.php:133
-msgid "Reset"
+#: ../../Zotlabs/Module/Appman.php:48
+msgid "Malformed app."
msgstr ""
-#: ../../Zotlabs/Module/Rbmark.php:94
-msgid "Select a bookmark folder"
+#: ../../Zotlabs/Module/Appman.php:111
+msgid "Embed code"
msgstr ""
-#: ../../Zotlabs/Module/Rbmark.php:99
-msgid "Save Bookmark"
+#: ../../Zotlabs/Module/Appman.php:117
+msgid "Edit App"
msgstr ""
-#: ../../Zotlabs/Module/Rbmark.php:100
-msgid "URL of bookmark"
+#: ../../Zotlabs/Module/Appman.php:117
+msgid "Create App"
msgstr ""
-#: ../../Zotlabs/Module/Rbmark.php:105
-msgid "Or enter new bookmark folder name"
+#: ../../Zotlabs/Module/Appman.php:122
+msgid "Name of app"
msgstr ""
-#: ../../Zotlabs/Module/Follow.php:31
-msgid "Channel added."
+#: ../../Zotlabs/Module/Appman.php:123
+msgid "Location (URL) of app"
msgstr ""
-#: ../../Zotlabs/Module/Mood.php:67 ../../include/conversation.php:260
-#, php-format
-msgctxt "mood"
-msgid "%1$s is %2$s"
+#: ../../Zotlabs/Module/Appman.php:124 ../../Zotlabs/Module/Rbmark.php:101
+#: ../../Zotlabs/Module/Events.php:473
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:838
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:173
+msgid "Description"
msgstr ""
-#: ../../Zotlabs/Module/Mood.php:135 ../../Zotlabs/Lib/Apps.php:234
-msgid "Mood"
+#: ../../Zotlabs/Module/Appman.php:125
+msgid "Photo icon URL"
msgstr ""
-#: ../../Zotlabs/Module/Mood.php:136
-msgid "Set your current mood and tell your friends"
+#: ../../Zotlabs/Module/Appman.php:125
+msgid "80 x 80 pixels - optional"
msgstr ""
-#: ../../Zotlabs/Module/Regmod.php:15
-msgid "Please login."
+#: ../../Zotlabs/Module/Appman.php:126
+msgid "Categories (optional, comma separated list)"
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:35
-msgid ""
-"Account removals are not allowed within 48 hours of changing the account "
-"password."
+#: ../../Zotlabs/Module/Appman.php:127
+msgid "Version ID"
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:57
-msgid "Remove This Account"
+#: ../../Zotlabs/Module/Appman.php:128
+msgid "Price of app"
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:58
-#: ../../Zotlabs/Module/Removeme.php:61
-msgid "WARNING: "
+#: ../../Zotlabs/Module/Appman.php:129
+msgid "Location (URL) to purchase app"
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:58
-msgid ""
-"This account and all its channels will be completely removed from the "
-"network. "
+#: ../../Zotlabs/Module/Common.php:14
+msgid "No channel."
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:58
-#: ../../Zotlabs/Module/Removeme.php:61
-msgid "This action is permanent and can not be undone!"
+#: ../../Zotlabs/Module/Common.php:43
+msgid "Common connections"
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:59
-#: ../../Zotlabs/Module/Removeme.php:62
-msgid "Please enter your password for verification:"
+#: ../../Zotlabs/Module/Common.php:48
+msgid "No connections in common."
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:60
-msgid ""
-"Remove this account, all its channels and all its channel clones from the "
-"network"
+#: ../../Zotlabs/Module/Chanview.php:134
+msgid "toggle full screen mode"
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:60
+#: ../../Zotlabs/Module/Uexport.php:57 ../../Zotlabs/Module/Uexport.php:58
+msgid "Export Channel"
+msgstr ""
+
+#: ../../Zotlabs/Module/Uexport.php:59
msgid ""
-"By default only the instances of the channels located on this hub will be "
-"removed from the network"
+"Export your basic channel information to a file. This acts as a backup of "
+"your connections, permissions, profile and basic data, which can be used to "
+"import your data to a new server hub, but does not contain your content."
msgstr ""
-#: ../../Zotlabs/Module/Removeaccount.php:61
-#: ../../Zotlabs/Module/Settings/Account.php:120
-msgid "Remove Account"
+#: ../../Zotlabs/Module/Uexport.php:60
+msgid "Export Content"
msgstr ""
-#: ../../Zotlabs/Module/Pdledit.php:21
-msgid "Layout updated."
+#: ../../Zotlabs/Module/Uexport.php:61
+msgid ""
+"Export your channel information and recent content to a JSON backup that can "
+"be restored or imported to another server hub. This backs up all of your "
+"connections, permissions, profile data and several months of posts. This "
+"file may be VERY large. Please be patient - it may take several minutes for "
+"this download to begin."
msgstr ""
-#: ../../Zotlabs/Module/Pdledit.php:34 ../../Zotlabs/Module/Chat.php:216
-msgid "Feature disabled."
+#: ../../Zotlabs/Module/Uexport.php:63
+msgid "Export your posts from a given year."
msgstr ""
-#: ../../Zotlabs/Module/Pdledit.php:42 ../../Zotlabs/Module/Pdledit.php:69
-msgid "Edit System Page Description"
+#: ../../Zotlabs/Module/Uexport.php:65
+msgid ""
+"You may also export your posts and conversations for a particular year or "
+"month. Adjust the date in your browser location bar to select other dates. "
+"If the export fails (possibly due to memory exhaustion on your server hub), "
+"please try again selecting a more limited date range."
msgstr ""
-#: ../../Zotlabs/Module/Pdledit.php:64
-msgid "Layout not found."
+#: ../../Zotlabs/Module/Uexport.php:66
+#, php-format
+msgid ""
+"To select all posts for a given year, such as this year, visit %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Pdledit.php:70
-msgid "Module Name:"
+#: ../../Zotlabs/Module/Uexport.php:67
+#, php-format
+msgid ""
+"To select all posts for a given month, such as January of this year, visit "
+"%2$s"
msgstr ""
-#: ../../Zotlabs/Module/Pdledit.php:71
-msgid "Layout Help"
+#: ../../Zotlabs/Module/Uexport.php:68
+#, php-format
+msgid ""
+"These content files may be imported or restored by visiting "
+"%2$s on any site containing your channel. For best results please import "
+"or restore these in date order (oldest first)."
msgstr ""
#: ../../Zotlabs/Module/Directory.php:246
@@ -5216,8 +5475,7 @@ msgid "Age:"
msgstr ""
#: ../../Zotlabs/Module/Directory.php:315 ../../include/event.php:52
-#: ../../include/event.php:84 ../../include/markdown.php:562
-#: ../../include/channel.php:1134
+#: ../../include/event.php:84 ../../include/channel.php:1134
msgid "Location:"
msgstr ""
@@ -5234,9 +5492,9 @@ msgid "About:"
msgstr ""
#: ../../Zotlabs/Module/Directory.php:329 ../../Zotlabs/Module/Suggest.php:56
-#: ../../include/widgets.php:134 ../../include/widgets.php:171
#: ../../include/connections.php:110 ../../include/conversation.php:938
-#: ../../include/conversation.php:1069 ../../include/channel.php:1119
+#: ../../include/conversation.php:1069 ../../include/widgets.php:134
+#: ../../include/widgets.php:171 ../../include/channel.php:1119
msgid "Connect"
msgstr ""
@@ -5305,457 +5563,492 @@ msgstr ""
msgid "No entries (some entries may be hidden)."
msgstr ""
-#: ../../Zotlabs/Module/Profile.php:91
-msgid "vcard"
+#: ../../Zotlabs/Module/Lostpass.php:19
+msgid "No valid account found."
msgstr ""
-#: ../../Zotlabs/Module/Oexchange.php:27
-msgid "Unable to find your hub."
+#: ../../Zotlabs/Module/Lostpass.php:33
+msgid "Password reset request issued. Check your email."
msgstr ""
-#: ../../Zotlabs/Module/Oexchange.php:41
-msgid "Post successful."
+#: ../../Zotlabs/Module/Lostpass.php:39 ../../Zotlabs/Module/Lostpass.php:108
+#, php-format
+msgid "Site Member (%s)"
msgstr ""
-#: ../../Zotlabs/Module/Viewsrc.php:46
-msgid "Source of Item"
+#: ../../Zotlabs/Module/Lostpass.php:44 ../../Zotlabs/Module/Lostpass.php:49
+#, php-format
+msgid "Password reset requested at %s"
msgstr ""
-#: ../../Zotlabs/Module/Service_limits.php:23
-msgid "No service class restrictions found."
+#: ../../Zotlabs/Module/Lostpass.php:68
+msgid ""
+"Request could not be verified. (You may have previously submitted it.) "
+"Password reset failed."
msgstr ""
-#: ../../Zotlabs/Module/Acl.php:344
-msgid "network"
+#: ../../Zotlabs/Module/Lostpass.php:91 ../../boot.php:1714
+msgid "Password Reset"
msgstr ""
-#: ../../Zotlabs/Module/Acl.php:354
-msgid "RSS"
+#: ../../Zotlabs/Module/Lostpass.php:92
+msgid "Your password has been reset as requested."
msgstr ""
-#: ../../Zotlabs/Module/Removeme.php:35
-msgid ""
-"Channel removals are not allowed within 48 hours of changing the account "
-"password."
+#: ../../Zotlabs/Module/Lostpass.php:93
+msgid "Your new password is"
msgstr ""
-#: ../../Zotlabs/Module/Removeme.php:60
-msgid "Remove This Channel"
+#: ../../Zotlabs/Module/Lostpass.php:94
+msgid "Save or copy your new password - and then"
msgstr ""
-#: ../../Zotlabs/Module/Removeme.php:61
-msgid "This channel will be completely removed from the network. "
+#: ../../Zotlabs/Module/Lostpass.php:95
+msgid "click here to login"
msgstr ""
-#: ../../Zotlabs/Module/Removeme.php:63
-msgid "Remove this channel and all its clones from the network"
+#: ../../Zotlabs/Module/Lostpass.php:96
+msgid ""
+"Your password may be changed from the Settings page after "
+"successful login."
msgstr ""
-#: ../../Zotlabs/Module/Removeme.php:63
+#: ../../Zotlabs/Module/Lostpass.php:117
+#, php-format
+msgid "Your password has changed at %s"
+msgstr ""
+
+#: ../../Zotlabs/Module/Lostpass.php:130
+msgid "Forgot your Password?"
+msgstr ""
+
+#: ../../Zotlabs/Module/Lostpass.php:131
msgid ""
-"By default only the instance of the channel located on this hub will be "
-"removed from the network"
+"Enter your email address and submit to have your password reset. Then check "
+"your email for further instructions."
msgstr ""
-#: ../../Zotlabs/Module/Removeme.php:64
-#: ../../Zotlabs/Module/Settings/Channel.php:575
-msgid "Remove Channel"
+#: ../../Zotlabs/Module/Lostpass.php:132
+msgid "Email Address"
msgstr ""
-#: ../../Zotlabs/Module/Sharedwithme.php:98
-msgid "Files: shared with me"
+#: ../../Zotlabs/Module/Lostpass.php:133
+msgid "Reset"
msgstr ""
-#: ../../Zotlabs/Module/Sharedwithme.php:100
-msgid "NEW"
+#: ../../Zotlabs/Module/Rbmark.php:94
+msgid "Select a bookmark folder"
msgstr ""
-#: ../../Zotlabs/Module/Sharedwithme.php:103
-msgid "Remove all files"
+#: ../../Zotlabs/Module/Rbmark.php:99
+msgid "Save Bookmark"
msgstr ""
-#: ../../Zotlabs/Module/Sharedwithme.php:104
-msgid "Remove this file"
+#: ../../Zotlabs/Module/Rbmark.php:100
+msgid "URL of bookmark"
msgstr ""
-#: ../../Zotlabs/Module/Tagger.php:55 ../../include/bbcode.php:274
-msgid "post"
+#: ../../Zotlabs/Module/Rbmark.php:105
+msgid "Or enter new bookmark folder name"
msgstr ""
-#: ../../Zotlabs/Module/Tagger.php:57 ../../include/conversation.php:150
-#: ../../include/text.php:1966
-msgid "comment"
+#: ../../Zotlabs/Module/Follow.php:31
+msgid "Channel added."
msgstr ""
-#: ../../Zotlabs/Module/Tagger.php:95
-#, php-format
-msgid "%1$s tagged %2$s's %3$s with %4$s"
+#: ../../Zotlabs/Module/Regmod.php:15
+msgid "Please login."
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:37
-msgid "Failed to create source. No channel selected."
+#: ../../Zotlabs/Module/Removeaccount.php:35
+msgid ""
+"Account removals are not allowed within 48 hours of changing the account "
+"password."
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:51
-msgid "Source created."
+#: ../../Zotlabs/Module/Removeaccount.php:57
+msgid "Remove This Account"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:64
-msgid "Source updated."
+#: ../../Zotlabs/Module/Removeaccount.php:58
+#: ../../Zotlabs/Module/Removeme.php:61
+msgid "WARNING: "
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:90
-msgid "*"
+#: ../../Zotlabs/Module/Removeaccount.php:58
+msgid ""
+"This account and all its channels will be completely removed from the "
+"network. "
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:96 ../../include/widgets.php:677
-#: ../../include/features.php:213
-msgid "Channel Sources"
+#: ../../Zotlabs/Module/Removeaccount.php:58
+#: ../../Zotlabs/Module/Removeme.php:61
+msgid "This action is permanent and can not be undone!"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:97
-msgid "Manage remote sources of content for your channel."
+#: ../../Zotlabs/Module/Removeaccount.php:59
+#: ../../Zotlabs/Module/Removeme.php:62
+msgid "Please enter your password for verification:"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:98 ../../Zotlabs/Module/Sources.php:108
-msgid "New Source"
+#: ../../Zotlabs/Module/Removeaccount.php:60
+msgid ""
+"Remove this account, all its channels and all its channel clones from the "
+"network"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:143
+#: ../../Zotlabs/Module/Removeaccount.php:60
msgid ""
-"Import all or selected content from the following channel into this channel "
-"and distribute it according to your channel settings."
+"By default only the instances of the channels located on this hub will be "
+"removed from the network"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:110 ../../Zotlabs/Module/Sources.php:144
-msgid "Only import content with these words (one per line)"
+#: ../../Zotlabs/Module/Removeaccount.php:61
+#: ../../Zotlabs/Module/Settings/Account.php:120
+msgid "Remove Account"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:110 ../../Zotlabs/Module/Sources.php:144
-msgid "Leave blank to import all public content"
+#: ../../Zotlabs/Module/Pdledit.php:21
+msgid "Layout updated."
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:111 ../../Zotlabs/Module/Sources.php:148
-msgid "Channel Name"
+#: ../../Zotlabs/Module/Pdledit.php:42 ../../Zotlabs/Module/Pdledit.php:69
+msgid "Edit System Page Description"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:112 ../../Zotlabs/Module/Sources.php:147
-msgid ""
-"Add the following categories to posts imported from this source (comma "
-"separated)"
+#: ../../Zotlabs/Module/Pdledit.php:64
+msgid "Layout not found."
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:112 ../../Zotlabs/Module/Sources.php:147
-#: ../../Zotlabs/Module/Settings/Oauth.php:93
-msgid "Optional"
+#: ../../Zotlabs/Module/Pdledit.php:70
+msgid "Module Name:"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:133 ../../Zotlabs/Module/Sources.php:161
-msgid "Source not found."
+#: ../../Zotlabs/Module/Pdledit.php:71
+msgid "Layout Help"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:140
-msgid "Edit Source"
+#: ../../Zotlabs/Module/Profperm.php:34 ../../Zotlabs/Module/Profperm.php:63
+msgid "Invalid profile identifier."
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:141
-msgid "Delete Source"
+#: ../../Zotlabs/Module/Profperm.php:111
+msgid "Profile Visibility Editor"
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:169
-msgid "Source removed"
+#: ../../Zotlabs/Module/Profperm.php:113 ../../include/channel.php:1367
+msgid "Profile"
+msgstr ""
+
+#: ../../Zotlabs/Module/Profperm.php:115
+msgid "Click on a contact to add or remove."
msgstr ""
-#: ../../Zotlabs/Module/Sources.php:171
-msgid "Unable to remove source."
+#: ../../Zotlabs/Module/Profperm.php:124
+msgid "Visible To"
msgstr ""
-#: ../../Zotlabs/Module/Suggest.php:39
-msgid ""
-"No suggestions available. If this is a new site, please try again in 24 "
-"hours."
+#: ../../Zotlabs/Module/Events.php:25
+msgid "Calendar entries imported."
msgstr ""
-#: ../../Zotlabs/Module/Suggest.php:58 ../../include/widgets.php:136
-msgid "Ignore/Hide"
+#: ../../Zotlabs/Module/Events.php:27
+msgid "No calendar entries found."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:24 ../../Zotlabs/Module/Profiles.php:184
-#: ../../Zotlabs/Module/Profiles.php:241 ../../Zotlabs/Module/Profiles.php:659
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:62
-msgid "Profile not found."
+#: ../../Zotlabs/Module/Events.php:110
+msgid "Event can not end before it has started."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:44
-msgid "Profile deleted."
+#: ../../Zotlabs/Module/Events.php:112 ../../Zotlabs/Module/Events.php:121
+#: ../../Zotlabs/Module/Events.php:143
+msgid "Unable to generate preview."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:68 ../../Zotlabs/Module/Profiles.php:105
-msgid "Profile-"
+#: ../../Zotlabs/Module/Events.php:119
+msgid "Event title and start time are required."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:90 ../../Zotlabs/Module/Profiles.php:127
-msgid "New profile created."
+#: ../../Zotlabs/Module/Events.php:141 ../../Zotlabs/Module/Events.php:265
+msgid "Event not found."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:111
-msgid "Profile unavailable to clone."
+#: ../../Zotlabs/Module/Events.php:460
+msgid "Edit event title"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:146
-msgid "Profile unavailable to export."
+#: ../../Zotlabs/Module/Events.php:460
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:835
+msgid "Event title"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:252
-msgid "Profile Name is required."
+#: ../../Zotlabs/Module/Events.php:462
+msgid "Categories (comma-separated list)"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:459
-msgid "Marital Status"
+#: ../../Zotlabs/Module/Events.php:463
+msgid "Edit Category"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:463
-msgid "Romantic Partner"
+#: ../../Zotlabs/Module/Events.php:463
+msgid "Category"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:467 ../../Zotlabs/Module/Profiles.php:775
-msgid "Likes"
+#: ../../Zotlabs/Module/Events.php:466
+msgid "Edit start date and time"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:471 ../../Zotlabs/Module/Profiles.php:776
-msgid "Dislikes"
+#: ../../Zotlabs/Module/Events.php:466
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:836
+msgid "Start date and time"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:475 ../../Zotlabs/Module/Profiles.php:783
-msgid "Work/Employment"
+#: ../../Zotlabs/Module/Events.php:467 ../../Zotlabs/Module/Events.php:470
+msgid "Finish date and time are not known or not relevant"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:478
-msgid "Religion"
+#: ../../Zotlabs/Module/Events.php:469
+msgid "Edit finish date and time"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:482
-msgid "Political Views"
+#: ../../Zotlabs/Module/Events.php:469
+msgid "Finish date and time"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:486
-#: ../../extend/addon/addon/openid/MysqlProvider.php:74
-msgid "Gender"
+#: ../../Zotlabs/Module/Events.php:471 ../../Zotlabs/Module/Events.php:472
+msgid "Adjust for viewer timezone"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:490
-msgid "Sexual Preference"
+#: ../../Zotlabs/Module/Events.php:471
+msgid ""
+"Important for events that happen in a particular place. Not practical for "
+"global holidays."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:494
-msgid "Homepage"
+#: ../../Zotlabs/Module/Events.php:473
+msgid "Edit Description"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:498
-msgid "Interests"
+#: ../../Zotlabs/Module/Events.php:475
+msgid "Edit Location"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:594
-msgid "Profile updated."
+#: ../../Zotlabs/Module/Events.php:479 ../../include/conversation.php:1410
+msgid "Permission settings"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:678
-msgid "Hide your connections list from viewers of this profile"
+#: ../../Zotlabs/Module/Events.php:489
+msgid "Timezone:"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:725
-msgid "Edit Profile Details"
+#: ../../Zotlabs/Module/Events.php:494
+msgid "Advanced Options"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:727
-msgid "View this profile"
+#: ../../Zotlabs/Module/Events.php:633
+msgid "Edit event"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:728 ../../Zotlabs/Module/Profiles.php:827
-#: ../../include/channel.php:1066
-msgid "Edit visibility"
+#: ../../Zotlabs/Module/Events.php:635
+msgid "Delete event"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:729
-msgid "Profile Tools"
+#: ../../Zotlabs/Module/Events.php:669
+msgid "calendar"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:730
-msgid "Change cover photo"
+#: ../../Zotlabs/Module/Events.php:695
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:849
+msgid "Month"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:731 ../../include/channel.php:1037
-msgid "Change profile photo"
+#: ../../Zotlabs/Module/Events.php:696
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:850
+msgid "Week"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:732
-msgid "Create a new profile using these settings"
+#: ../../Zotlabs/Module/Events.php:697
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:851
+msgid "Day"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:733
-msgid "Clone this profile"
+#: ../../Zotlabs/Module/Events.php:731
+msgid "Event removed"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:734
-msgid "Delete this profile"
+#: ../../Zotlabs/Module/Events.php:734
+msgid "Failed to remove event"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:735
-msgid "Add profile things"
+#: ../../Zotlabs/Module/Service_limits.php:23
+msgid "No service class restrictions found."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:736 ../../include/conversation.php:1715
-msgid "Personal"
+#: ../../Zotlabs/Module/Hcard.php:35 ../../Zotlabs/Module/Channel.php:47
+#: ../../Zotlabs/Module/Profile.php:43
+msgid "Posts and comments"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:738
-msgid "Relation"
+#: ../../Zotlabs/Module/Hcard.php:42 ../../Zotlabs/Module/Channel.php:54
+#: ../../Zotlabs/Module/Profile.php:50
+msgid "Only posts"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:739 ../../include/datetime.php:55
-msgid "Miscellaneous"
+#: ../../Zotlabs/Module/Removeme.php:35
+msgid ""
+"Channel removals are not allowed within 48 hours of changing the account "
+"password."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:741
-msgid "Import profile from file"
+#: ../../Zotlabs/Module/Removeme.php:60
+msgid "Remove This Channel"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:742
-msgid "Export profile to file"
+#: ../../Zotlabs/Module/Removeme.php:61
+msgid "This channel will be completely removed from the network. "
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:743
-msgid "Your gender"
+#: ../../Zotlabs/Module/Removeme.php:63
+msgid "Remove this channel and all its clones from the network"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:744
-msgid "Marital status"
+#: ../../Zotlabs/Module/Removeme.php:63
+msgid ""
+"By default only the instance of the channel located on this hub will be "
+"removed from the network"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:745
-msgid "Sexual preference"
+#: ../../Zotlabs/Module/Removeme.php:64
+#: ../../Zotlabs/Module/Settings/Channel.php:575
+msgid "Remove Channel"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:748
-msgid "Profile name"
+#: ../../Zotlabs/Module/Sharedwithme.php:98
+msgid "Files: shared with me"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:750
-msgid "This is your default profile."
+#: ../../Zotlabs/Module/Sharedwithme.php:100
+msgid "NEW"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:752
-msgid "Your full name"
+#: ../../Zotlabs/Module/Sharedwithme.php:103
+msgid "Remove all files"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:753
-msgid "Title/Description"
+#: ../../Zotlabs/Module/Sharedwithme.php:104
+msgid "Remove this file"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:756
-msgid "Street address"
+#: ../../Zotlabs/Module/Viewsrc.php:46
+msgid "Source of Item"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:757
-msgid "Locality/City"
+#: ../../Zotlabs/Module/Sources.php:37
+msgid "Failed to create source. No channel selected."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:758
-msgid "Region/State"
+#: ../../Zotlabs/Module/Sources.php:51
+msgid "Source created."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:759
-msgid "Postal/Zip code"
+#: ../../Zotlabs/Module/Sources.php:64
+msgid "Source updated."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:765
-msgid "Who (if applicable)"
+#: ../../Zotlabs/Module/Sources.php:90
+msgid "*"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:765
-msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
+#: ../../Zotlabs/Module/Sources.php:96 ../../include/widgets.php:677
+#: ../../include/features.php:213
+msgid "Channel Sources"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:766
-msgid "Since (date)"
+#: ../../Zotlabs/Module/Sources.php:97
+msgid "Manage remote sources of content for your channel."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:769
-msgid "Tell us about yourself"
+#: ../../Zotlabs/Module/Sources.php:98 ../../Zotlabs/Module/Sources.php:108
+msgid "New Source"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:770
-#: ../../extend/addon/addon/openid/MysqlProvider.php:68
-msgid "Homepage URL"
+#: ../../Zotlabs/Module/Sources.php:109 ../../Zotlabs/Module/Sources.php:143
+msgid ""
+"Import all or selected content from the following channel into this channel "
+"and distribute it according to your channel settings."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:771
-msgid "Hometown"
+#: ../../Zotlabs/Module/Sources.php:110 ../../Zotlabs/Module/Sources.php:144
+msgid "Only import content with these words (one per line)"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:772
-msgid "Political views"
+#: ../../Zotlabs/Module/Sources.php:110 ../../Zotlabs/Module/Sources.php:144
+msgid "Leave blank to import all public content"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:773
-msgid "Religious views"
+#: ../../Zotlabs/Module/Sources.php:111 ../../Zotlabs/Module/Sources.php:148
+msgid "Channel Name"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:774
-msgid "Keywords used in directory listings"
+#: ../../Zotlabs/Module/Sources.php:112 ../../Zotlabs/Module/Sources.php:147
+msgid ""
+"Add the following categories to posts imported from this source (comma "
+"separated)"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:774
-msgid "Example: fishing photography software"
+#: ../../Zotlabs/Module/Sources.php:112 ../../Zotlabs/Module/Sources.php:147
+#: ../../Zotlabs/Module/Settings/Oauth.php:93
+msgid "Optional"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:777
-msgid "Musical interests"
+#: ../../Zotlabs/Module/Sources.php:133 ../../Zotlabs/Module/Sources.php:161
+msgid "Source not found."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:778
-msgid "Books, literature"
+#: ../../Zotlabs/Module/Sources.php:140
+msgid "Edit Source"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:779
-msgid "Television"
+#: ../../Zotlabs/Module/Sources.php:141
+msgid "Delete Source"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:780
-msgid "Film/Dance/Culture/Entertainment"
+#: ../../Zotlabs/Module/Sources.php:169
+msgid "Source removed"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:781
-msgid "Hobbies/Interests"
+#: ../../Zotlabs/Module/Sources.php:171
+msgid "Unable to remove source."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:782
-msgid "Love/Romance"
+#: ../../Zotlabs/Module/Channel.php:112
+msgid "Insufficient permissions. Request redirected to profile page."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:784
-msgid "School/Education"
+#: ../../Zotlabs/Module/Suggest.php:39
+msgid ""
+"No suggestions available. If this is a new site, please try again in 24 "
+"hours."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:785
-msgid "Contact information and social networks"
+#: ../../Zotlabs/Module/Suggest.php:58 ../../include/widgets.php:136
+msgid "Ignore/Hide"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:786
-msgid "My other channels"
+#: ../../Zotlabs/Module/Rmagic.php:35
+msgid "Authentication failed."
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:788
-msgid "Communications"
+#: ../../Zotlabs/Module/Rmagic.php:75 ../../include/channel.php:1989
+msgid "Remote Authentication"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:823 ../../include/channel.php:1062
-msgid "Profile Image"
+#: ../../Zotlabs/Module/Rmagic.php:76 ../../include/channel.php:1990
+msgid "Enter your channel address (e.g. channel@example.com)"
msgstr ""
-#: ../../Zotlabs/Module/Profiles.php:833 ../../include/nav.php:105
-#: ../../include/channel.php:1044
-msgid "Edit Profiles"
+#: ../../Zotlabs/Module/Rmagic.php:77 ../../include/channel.php:1991
+msgid "Authenticate"
msgstr ""
#: ../../Zotlabs/Module/Settings/Features.php:45
@@ -5898,13 +6191,211 @@ msgstr ""
msgid "Used to provide a member experience matched to your comfort level"
msgstr ""
-#: ../../Zotlabs/Module/Settings/Account.php:119
-#: ../../Zotlabs/Module/Settings/Channel.php:483
-msgid "Email Address:"
+#: ../../Zotlabs/Module/Settings/Account.php:119
+#: ../../Zotlabs/Module/Settings/Channel.php:483
+msgid "Email Address:"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Account.php:121
+msgid "Remove this account including all its channels"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:145
+msgid "No special theme for mobile devices"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:148
+#, php-format
+msgid "%s - (Experimental)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:198
+msgid "Display Settings"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:199
+msgid "Theme Settings"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:200
+msgid "Custom Theme Settings"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:201
+msgid "Content Settings"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:207
+msgid "Display Theme:"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:208
+msgid "Select scheme"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:210
+msgid "Mobile Theme:"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:211
+msgid "Preload images before rendering the page"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:211
+msgid ""
+"The subjective page load time will be longer but the page will be ready when "
+"displayed"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:212
+msgid "Enable user zoom on mobile devices"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:213
+msgid "Update browser every xx seconds"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:213
+msgid "Minimum of 10 seconds, no maximum"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:214
+msgid "Maximum number of conversations to load at any time:"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:214
+msgid "Maximum of 100 items"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:215
+msgid "Show emoticons (smilies) as images"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:216
+msgid "Manual conversation updates"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:216
+msgid "Default is on, turning this off may increase screen jumping"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:217
+msgid "Link post titles to source"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:218
+msgid "System Page Layout Editor - (advanced)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:221
+msgid "Use blog/list mode on channel page"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:221
+#: ../../Zotlabs/Module/Settings/Display.php:222
+msgid "(comments displayed separately)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:222
+msgid "Use blog/list mode on grid page"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:223
+msgid "Channel page max height of content (in pixels)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:223
+#: ../../Zotlabs/Module/Settings/Display.php:224
+msgid "click to expand content exceeding this height"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Display.php:224
+msgid "Grid page max height of content (in pixels)"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Featured.php:20
+msgid "Affinity Slider settings updated."
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Featured.php:34
+msgid "No feature settings configured"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Featured.php:41
+msgid "Default maximum affinity level"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Featured.php:46
+msgid "Default minimum affinity level"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Featured.php:50
+msgid "Affinity Slider Settings"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Featured.php:60
+msgid "Feature/Addon Settings"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Permcats.php:37
+msgid "Permission category saved."
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Permcats.php:63
+msgid ""
+"Use this form to create permission rules for various classes of people or "
+"connections."
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Permcats.php:96
+msgid "Permission Categories"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Permcats.php:104
+msgid "Permission Name"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:31
+#, php-format
+msgid "This channel is limited to %d tokens"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:37
+msgid "Name and Password are required."
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:77
+msgid "Token saved."
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:113
+msgid ""
+"Use this form to create temporary access identifiers to share things with "
+"non-members. These identities may be used in Access Control Lists and "
+"visitors may login using these credentials to access private content."
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:115
+msgid ""
+"You may also provide dropbox style access links to friends and "
+"associates by adding the Login Password to any specific site URL as shown. "
+"Examples:"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:150 ../../include/widgets.php:644
+msgid "Guest Access Tokens"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:157
+msgid "Login Name"
+msgstr ""
+
+#: ../../Zotlabs/Module/Settings/Tokens.php:158
+msgid "Login Password"
msgstr ""
-#: ../../Zotlabs/Module/Settings/Account.php:121
-msgid "Remove this account including all its channels"
+#: ../../Zotlabs/Module/Settings/Tokens.php:159
+msgid "Expires (yyyy-mm-dd)"
msgstr ""
#: ../../Zotlabs/Module/Settings/Channel.php:251
@@ -6284,204 +6775,6 @@ msgstr ""
msgid "Start calendar week on monday"
msgstr ""
-#: ../../Zotlabs/Module/Settings/Featured.php:20
-msgid "Affinity Slider settings updated."
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Featured.php:34
-msgid "No feature settings configured"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Featured.php:41
-msgid "Default maximum affinity level"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Featured.php:46
-msgid "Default minimum affinity level"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Featured.php:50
-msgid "Affinity Slider Settings"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Featured.php:60
-msgid "Feature/Addon Settings"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Permcats.php:37
-msgid "Permission category saved."
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Permcats.php:63
-msgid ""
-"Use this form to create permission rules for various classes of people or "
-"connections."
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Permcats.php:96
-msgid "Permission Categories"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Permcats.php:104
-msgid "Permission Name"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:31
-#, php-format
-msgid "This channel is limited to %d tokens"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:37
-msgid "Name and Password are required."
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:77
-msgid "Token saved."
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:113
-msgid ""
-"Use this form to create temporary access identifiers to share things with "
-"non-members. These identities may be used in Access Control Lists and "
-"visitors may login using these credentials to access private content."
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:115
-msgid ""
-"You may also provide dropbox style access links to friends and "
-"associates by adding the Login Password to any specific site URL as shown. "
-"Examples:"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:150 ../../include/widgets.php:644
-msgid "Guest Access Tokens"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:157
-msgid "Login Name"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:158
-msgid "Login Password"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Tokens.php:159
-msgid "Expires (yyyy-mm-dd)"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:145
-msgid "No special theme for mobile devices"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:148
-#, php-format
-msgid "%s - (Experimental)"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:198
-msgid "Display Settings"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:199
-msgid "Theme Settings"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:200
-msgid "Custom Theme Settings"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:201
-msgid "Content Settings"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:207
-msgid "Display Theme:"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:208
-msgid "Select scheme"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:210
-msgid "Mobile Theme:"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:211
-msgid "Preload images before rendering the page"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:211
-msgid ""
-"The subjective page load time will be longer but the page will be ready when "
-"displayed"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:212
-msgid "Enable user zoom on mobile devices"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:213
-msgid "Update browser every xx seconds"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:213
-msgid "Minimum of 10 seconds, no maximum"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:214
-msgid "Maximum number of conversations to load at any time:"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:214
-msgid "Maximum of 100 items"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:215
-msgid "Show emoticons (smilies) as images"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:216
-msgid "Manual conversation updates"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:216
-msgid "Default is on, turning this off may increase screen jumping"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:217
-msgid "Link post titles to source"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:218
-msgid "System Page Layout Editor - (advanced)"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:221
-msgid "Use blog/list mode on channel page"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:221
-#: ../../Zotlabs/Module/Settings/Display.php:222
-msgid "(comments displayed separately)"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:222
-msgid "Use blog/list mode on grid page"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:223
-msgid "Channel page max height of content (in pixels)"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:223
-#: ../../Zotlabs/Module/Settings/Display.php:224
-msgid "click to expand content exceeding this height"
-msgstr ""
-
-#: ../../Zotlabs/Module/Settings/Display.php:224
-msgid "Grid page max height of content (in pixels)"
-msgstr ""
-
#: ../../Zotlabs/Module/Tagrm.php:48 ../../Zotlabs/Module/Tagrm.php:98
msgid "Tag removed"
msgstr ""
@@ -6547,5128 +6840,5142 @@ msgstr ""
msgid "URL for photo of thing (optional)"
msgstr ""
-#: ../../Zotlabs/Module/Thing.php:353
-msgid "Add Thing to your Profile"
+#: ../../Zotlabs/Module/Thing.php:353
+msgid "Add Thing to your Profile"
+msgstr ""
+
+#: ../../Zotlabs/Module/Tagger.php:55 ../../include/bbcode.php:274
+msgid "post"
+msgstr ""
+
+#: ../../Zotlabs/Module/Tagger.php:57 ../../include/conversation.php:150
+#: ../../include/text.php:1950
+msgid "comment"
+msgstr ""
+
+#: ../../Zotlabs/Module/Tagger.php:95
+#, php-format
+msgid "%1$s tagged %2$s's %3$s with %4$s"
+msgstr ""
+
+#: ../../Zotlabs/Module/Viewconnections.php:65
+msgid "No connections."
+msgstr ""
+
+#: ../../Zotlabs/Module/Viewconnections.php:78
+#, php-format
+msgid "Visit %s's profile [%s]"
+msgstr ""
+
+#: ../../Zotlabs/Module/Viewconnections.php:107
+msgid "View Connections"
+msgstr ""
+
+#: ../../Zotlabs/Module/Import.php:134
+#, php-format
+msgid "Your service plan only allows %d channels."
+msgstr ""
+
+#: ../../Zotlabs/Module/Import.php:149
+msgid "No channel. Import failed."
+msgstr ""
+
+#: ../../Zotlabs/Module/Import.php:467
+#: ../../extend/addon/addon/diaspora/import_diaspora.php:142
+msgid "Import completed."
+msgstr ""
+
+#: ../../Zotlabs/Module/Import.php:488
+msgid "You must be logged in to use this feature."
+msgstr ""
+
+#: ../../Zotlabs/Module/Import.php:493
+msgid "Import Channel"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:176
-msgid "$Projectname Server - Setup"
+#: ../../Zotlabs/Module/Import.php:494
+msgid ""
+"Use this form to import an existing channel from a different server/hub. You "
+"may retrieve the channel identity from the old server/hub via the network or "
+"provide an export file."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:180
-msgid "Could not connect to database."
+#: ../../Zotlabs/Module/Import.php:496
+msgid "Or provide the old server/hub details"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:184
-msgid ""
-"Could not connect to specified site URL. Possible SSL certificate or DNS "
-"issue."
+#: ../../Zotlabs/Module/Import.php:497
+msgid "Your old identity address (xyz@example.com)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:191
-msgid "Could not create table."
+#: ../../Zotlabs/Module/Import.php:498
+msgid "Your old login email address"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:196
-msgid "Your site database has been installed."
+#: ../../Zotlabs/Module/Import.php:499
+msgid "Your old login password"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:200
+#: ../../Zotlabs/Module/Import.php:500
msgid ""
-"You may need to import the file \"install/schema_xxx.sql\" manually using a "
-"database client."
+"For either option, please choose whether to make this hub your new primary "
+"address, or whether your old location should continue this role. You will be "
+"able to post from either location, but only one can be marked as the primary "
+"location for files, photos, and media."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:201 ../../Zotlabs/Module/Setup.php:263
-#: ../../Zotlabs/Module/Setup.php:750
-msgid "Please see the file \"install/INSTALL.txt\"."
+#: ../../Zotlabs/Module/Import.php:501
+msgid "Make this hub my primary location"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:260
-msgid "System check"
+#: ../../Zotlabs/Module/Import.php:502
+msgid "Move this channel (disable all previous locations)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:265
-msgid "Check again"
+#: ../../Zotlabs/Module/Import.php:503
+msgid "Import a few months of posts if possible (limited by available memory"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:287
-msgid "Database connection"
+#: ../../Zotlabs/Module/Import.php:504
+msgid ""
+"This process may take several minutes to complete. Please submit the form "
+"only once and leave this page open until finished."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:288
-msgid ""
-"In order to install $Projectname we need to know how to connect to your "
-"database."
+#: ../../Zotlabs/Module/Photos.php:82
+msgid "Page owner information could not be retrieved."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:289
-msgid ""
-"Please contact your hosting provider or site administrator if you have "
-"questions about these settings."
+#: ../../Zotlabs/Module/Photos.php:103 ../../Zotlabs/Module/Photos.php:129
+msgid "Album not found."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:290
+#: ../../Zotlabs/Module/Photos.php:112
+msgid "Delete Album"
+msgstr ""
+
+#: ../../Zotlabs/Module/Photos.php:133
msgid ""
-"The database you specify below should already exist. If it does not, please "
-"create it before continuing."
+"Multiple storage folders exist with this album name, but within different "
+"directories. Please remove the desired folder or folders using the Files "
+"manager"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:294
-msgid "Database Server Name"
+#: ../../Zotlabs/Module/Photos.php:190 ../../Zotlabs/Module/Photos.php:1054
+msgid "Delete Photo"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:294
-msgid "Default is 127.0.0.1"
+#: ../../Zotlabs/Module/Photos.php:519
+msgid "No photos selected"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:295
-msgid "Database Port"
+#: ../../Zotlabs/Module/Photos.php:568
+msgid "Access to this item is restricted."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:295
-msgid "Communication port number - use 0 for default"
+#: ../../Zotlabs/Module/Photos.php:607
+#, php-format
+msgid "%1$.2f MB of %2$.2f MB photo storage used."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:296
-msgid "Database Login Name"
+#: ../../Zotlabs/Module/Photos.php:610
+#, php-format
+msgid "%1$.2f MB photo storage used."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:297
-msgid "Database Login Password"
+#: ../../Zotlabs/Module/Photos.php:646
+msgid "Upload Photos"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:298
-msgid "Database Name"
+#: ../../Zotlabs/Module/Photos.php:650
+msgid "Enter an album name"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:299
-msgid "Database Type"
+#: ../../Zotlabs/Module/Photos.php:651
+msgid "or select an existing album (doubleclick)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:301 ../../Zotlabs/Module/Setup.php:347
-msgid "Site administrator email address"
+#: ../../Zotlabs/Module/Photos.php:652
+msgid "Create a status post for this upload"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:301 ../../Zotlabs/Module/Setup.php:347
-msgid ""
-"Your account email address must match this in order to use the web admin "
-"panel."
+#: ../../Zotlabs/Module/Photos.php:653
+msgid "Caption (optional):"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:302 ../../Zotlabs/Module/Setup.php:349
-msgid "Website URL"
+#: ../../Zotlabs/Module/Photos.php:654
+msgid "Description (optional):"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:302 ../../Zotlabs/Module/Setup.php:349
-msgid "Please use SSL (https) URL if available."
+#: ../../Zotlabs/Module/Photos.php:685
+msgid "Album name could not be decoded"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:303 ../../Zotlabs/Module/Setup.php:353
-msgid "Please select a default timezone for your website"
+#: ../../Zotlabs/Module/Photos.php:729
+msgid "Contact Photos"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:336
-msgid "Site settings"
+#: ../../Zotlabs/Module/Photos.php:752
+msgid "Show Newest First"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:392
-msgid "PHP version 5.5 or greater is required."
+#: ../../Zotlabs/Module/Photos.php:754
+msgid "Show Oldest First"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:393
-msgid "PHP version"
+#: ../../Zotlabs/Module/Photos.php:778 ../../Zotlabs/Module/Photos.php:1335
+#: ../../Zotlabs/Module/Embedphotos.php:139 ../../include/widgets.php:1751
+msgid "View Photo"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:409
-msgid "Could not find a command line version of PHP in the web server PATH."
+#: ../../Zotlabs/Module/Photos.php:809
+#: ../../Zotlabs/Module/Embedphotos.php:155 ../../include/widgets.php:1768
+msgid "Edit Album"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:410
-msgid ""
-"If you don't have a command line version of PHP installed on server, you "
-"will not be able to run background polling via cron."
+#: ../../Zotlabs/Module/Photos.php:856
+msgid "Permission denied. Access to this item may be restricted."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:414
-msgid "PHP executable path"
+#: ../../Zotlabs/Module/Photos.php:858
+msgid "Photo not available"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:414
-msgid ""
-"Enter full path to php executable. You can leave this blank to continue the "
-"installation."
+#: ../../Zotlabs/Module/Photos.php:916
+msgid "Use as profile photo"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:419
-msgid "Command line PHP"
+#: ../../Zotlabs/Module/Photos.php:917
+msgid "Use as cover photo"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:429
-msgid ""
-"Unable to check command line PHP, as shell_exec() is disabled. This is "
-"required."
+#: ../../Zotlabs/Module/Photos.php:924
+msgid "Private Photo"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:432
-msgid ""
-"The command line version of PHP on your system does not have "
-"\"register_argc_argv\" enabled."
+#: ../../Zotlabs/Module/Photos.php:939
+msgid "View Full Size"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:433
-msgid "This is required for message delivery to work."
+#: ../../Zotlabs/Module/Photos.php:1028
+msgid "Edit photo"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:436
-msgid "PHP register_argc_argv"
+#: ../../Zotlabs/Module/Photos.php:1030
+msgid "Rotate CW (right)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:454
-#, php-format
-msgid ""
-"Your max allowed total upload size is set to %s. Maximum size of one file to "
-"upload is set to %s. You are allowed to upload up to %d files at once."
+#: ../../Zotlabs/Module/Photos.php:1031
+msgid "Rotate CCW (left)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:459
-msgid "You can adjust these settings in the server php.ini file."
+#: ../../Zotlabs/Module/Photos.php:1034
+msgid "Move photo to album"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:461
-msgid "PHP upload limits"
+#: ../../Zotlabs/Module/Photos.php:1035
+msgid "Enter a new album name"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:484
-msgid ""
-"Error: the \"openssl_pkey_new\" function on this system is not able to "
-"generate encryption keys"
+#: ../../Zotlabs/Module/Photos.php:1036
+msgid "or select an existing one (doubleclick)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:485
-msgid ""
-"If running under Windows, please see \"http://www.php.net/manual/en/openssl."
-"installation.php\"."
+#: ../../Zotlabs/Module/Photos.php:1039
+msgid "Caption"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:488
-msgid "Generate encryption keys"
+#: ../../Zotlabs/Module/Photos.php:1041
+msgid "Add a Tag"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:505
-msgid "libCurl PHP module"
+#: ../../Zotlabs/Module/Photos.php:1049
+msgid "Example: @bob, @Barbara_Jensen, @jim@example.com"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:506
-msgid "GD graphics PHP module"
+#: ../../Zotlabs/Module/Photos.php:1052
+msgid "Flag as adult in album view"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:507
-msgid "OpenSSL PHP module"
+#: ../../Zotlabs/Module/Photos.php:1071 ../../Zotlabs/Lib/ThreadItem.php:268
+msgid "I like this (toggle)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:508
-msgid "PDO database PHP module"
+#: ../../Zotlabs/Module/Photos.php:1072 ../../Zotlabs/Lib/ThreadItem.php:269
+msgid "I don't like this (toggle)"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:509
-msgid "mb_string PHP module"
+#: ../../Zotlabs/Module/Photos.php:1074 ../../Zotlabs/Lib/ThreadItem.php:411
+#: ../../include/conversation.php:738
+msgid "Please wait"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:510
-msgid "xml PHP module"
+#: ../../Zotlabs/Module/Photos.php:1090 ../../Zotlabs/Module/Photos.php:1208
+#: ../../Zotlabs/Lib/ThreadItem.php:728
+msgid "This is you"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:514 ../../Zotlabs/Module/Setup.php:516
-msgid "Apache mod_rewrite module"
+#: ../../Zotlabs/Module/Photos.php:1092 ../../Zotlabs/Module/Photos.php:1210
+#: ../../Zotlabs/Lib/ThreadItem.php:730 ../../include/js_strings.php:6
+msgid "Comment"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:514
-msgid ""
-"Error: Apache webserver mod-rewrite module is required but not installed."
+#: ../../Zotlabs/Module/Photos.php:1108 ../../include/conversation.php:577
+msgctxt "title"
+msgid "Likes"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:520 ../../Zotlabs/Module/Setup.php:523
-msgid "exec"
+#: ../../Zotlabs/Module/Photos.php:1108 ../../include/conversation.php:577
+msgctxt "title"
+msgid "Dislikes"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:520
-msgid ""
-"Error: exec is required but is either not installed or has been disabled in "
-"php.ini"
+#: ../../Zotlabs/Module/Photos.php:1109 ../../include/conversation.php:578
+msgctxt "title"
+msgid "Agree"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:526 ../../Zotlabs/Module/Setup.php:529
-msgid "shell_exec"
+#: ../../Zotlabs/Module/Photos.php:1109 ../../include/conversation.php:578
+msgctxt "title"
+msgid "Disagree"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:526
-msgid ""
-"Error: shell_exec is required but is either not installed or has been "
-"disabled in php.ini"
+#: ../../Zotlabs/Module/Photos.php:1109 ../../include/conversation.php:578
+msgctxt "title"
+msgid "Abstain"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:534
-msgid "Error: libCURL PHP module required but not installed."
+#: ../../Zotlabs/Module/Photos.php:1110 ../../include/conversation.php:579
+msgctxt "title"
+msgid "Attending"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:538
-msgid ""
-"Error: GD graphics PHP module with JPEG support required but not installed."
+#: ../../Zotlabs/Module/Photos.php:1110 ../../include/conversation.php:579
+msgctxt "title"
+msgid "Not attending"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:542
-msgid "Error: openssl PHP module required but not installed."
+#: ../../Zotlabs/Module/Photos.php:1110 ../../include/conversation.php:579
+msgctxt "title"
+msgid "Might attend"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:546
-msgid "Error: PDO database PHP module required but not installed."
+#: ../../Zotlabs/Module/Photos.php:1127 ../../Zotlabs/Module/Photos.php:1139
+#: ../../Zotlabs/Lib/ThreadItem.php:186 ../../Zotlabs/Lib/ThreadItem.php:198
+#: ../../include/conversation.php:1928
+msgid "View all"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:550
-msgid "Error: mb_string PHP module required but not installed."
-msgstr ""
+#: ../../Zotlabs/Module/Photos.php:1131 ../../Zotlabs/Lib/ThreadItem.php:190
+#: ../../include/taxonomy.php:403 ../../include/conversation.php:1952
+#: ../../include/channel.php:1273
+msgctxt "noun"
+msgid "Like"
+msgid_plural "Likes"
+msgstr[0] ""
+msgstr[1] ""
-#: ../../Zotlabs/Module/Setup.php:554
-msgid "Error: xml PHP module required for DAV but not installed."
-msgstr ""
+#: ../../Zotlabs/Module/Photos.php:1136 ../../Zotlabs/Lib/ThreadItem.php:195
+#: ../../include/conversation.php:1955
+msgctxt "noun"
+msgid "Dislike"
+msgid_plural "Dislikes"
+msgstr[0] ""
+msgstr[1] ""
-#: ../../Zotlabs/Module/Setup.php:572
-msgid ""
-"The web installer needs to be able to create a file called \".htconfig.php\" "
-"in the top folder of your web server and it is unable to do so."
+#: ../../Zotlabs/Module/Photos.php:1236
+msgid "Photo Tools"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:573
-msgid ""
-"This is most often a permission setting, as the web server may not be able "
-"to write files in your folder - even if you can."
+#: ../../Zotlabs/Module/Photos.php:1245
+msgid "In This Photo:"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:574
-msgid ""
-"At the end of this procedure, we will give you a text to save in a file "
-"named .htconfig.php in your Red top folder."
+#: ../../Zotlabs/Module/Photos.php:1250
+msgid "Map"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:575
-msgid ""
-"You can alternatively skip this procedure and perform a manual installation. "
-"Please see the file \"install/INSTALL.txt\" for instructions."
+#: ../../Zotlabs/Module/Photos.php:1258 ../../Zotlabs/Lib/ThreadItem.php:400
+msgctxt "noun"
+msgid "Likes"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:578
-msgid ".htconfig.php is writable"
+#: ../../Zotlabs/Module/Photos.php:1259 ../../Zotlabs/Lib/ThreadItem.php:401
+msgctxt "noun"
+msgid "Dislikes"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:592
-msgid ""
-"This software uses the Smarty3 template engine to render its web views. "
-"Smarty3 compiles templates to PHP to speed up rendering."
+#: ../../Zotlabs/Module/Photos.php:1264 ../../Zotlabs/Lib/ThreadItem.php:406
+#: ../../include/acl_selectors.php:220
+msgid "Close"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:593
-#, php-format
-msgid ""
-"In order to store these compiled templates, the web server needs to have "
-"write access to the directory %s under the top level web folder."
+#: ../../Zotlabs/Module/Photos.php:1341
+msgid "View Album"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:594 ../../Zotlabs/Module/Setup.php:615
-msgid ""
-"Please ensure that the user that your web server runs as (e.g. www-data) has "
-"write access to this folder."
+#: ../../Zotlabs/Module/Photos.php:1352 ../../Zotlabs/Module/Photos.php:1365
+#: ../../Zotlabs/Module/Photos.php:1366
+msgid "Recent Photos"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:595
-#, php-format
-msgid ""
-"Note: as a security measure, you should give the web server write access to "
-"%s only--not the template files (.tpl) that it contains."
+#: ../../Zotlabs/Module/Xchan.php:10
+msgid "Xchan Lookup"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:598
-#, php-format
-msgid "%s is writable"
+#: ../../Zotlabs/Module/Xchan.php:13
+msgid "Lookup xchan beginning with (or webbie): "
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:614
-msgid ""
-"This software uses the store directory to save uploaded files. The web "
-"server needs to have write access to the store directory under the top level "
-"web folder"
+#: ../../Zotlabs/Module/Profile.php:91
+msgid "vcard"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:618
-msgid "store is writable"
+#: ../../Zotlabs/Lib/Chatroom.php:27
+msgid "Missing room name"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:651
-msgid ""
-"SSL certificate cannot be validated. Fix certificate or disable https access "
-"to this site."
+#: ../../Zotlabs/Lib/Chatroom.php:36
+msgid "Duplicate room name"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:652
-msgid ""
-"If you have https access to your website or allow connections to TCP port "
-"443 (the https: port), you MUST use a browser-valid certificate. You MUST "
-"NOT use self-signed certificates!"
+#: ../../Zotlabs/Lib/Chatroom.php:86 ../../Zotlabs/Lib/Chatroom.php:94
+msgid "Invalid room specifier."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:653
-msgid ""
-"This restriction is incorporated because public posts from you may for "
-"example contain references to images on your own hub."
+#: ../../Zotlabs/Lib/Chatroom.php:126
+msgid "Room not found."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:654
-msgid ""
-"If your certificate is not recognized, members of other sites (who may "
-"themselves have valid certificates) will get a warning message on their own "
-"site complaining about security issues."
+#: ../../Zotlabs/Lib/Chatroom.php:147
+msgid "Room is full"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:655
-msgid ""
-"This can cause usability issues elsewhere (not just on your own site) so we "
-"must insist on this requirement."
+#: ../../Zotlabs/Lib/Enotify.php:60 ../../include/network.php:1426
+msgid "$Projectname Notification"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:656
-msgid ""
-"Providers are available that issue free certificates which are browser-valid."
+#: ../../Zotlabs/Lib/Enotify.php:61
+#: ../../extend/addon/addon/diaspora/util.php:218
+#: ../../extend/addon/addon/diaspora/util.php:231
+#: ../../extend/addon/addon/diaspora/p.php:46 ../../include/network.php:1427
+msgid "$projectname"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:658
-msgid ""
-"If you are confident that the certificate is valid and signed by a trusted "
-"authority, check to see if you have failed to install an intermediate cert. "
-"These are not normally required by browsers, but are required for server-to-"
-"server communications."
+#: ../../Zotlabs/Lib/Enotify.php:63 ../../include/network.php:1429
+msgid "Thank You,"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:660
-msgid "SSL certificate validation"
+#: ../../Zotlabs/Lib/Enotify.php:65 ../../include/network.php:1431
+#, php-format
+msgid "%s Administrator"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:666
-msgid ""
-"Url rewrite in .htaccess is not working. Check your server configuration."
-"Test: "
+#: ../../Zotlabs/Lib/Enotify.php:116
+#, php-format
+msgid "%s "
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:669
-msgid "Url rewrite is working"
+#: ../../Zotlabs/Lib/Enotify.php:120
+#, php-format
+msgid "[$Projectname:Notify] New mail received at %s"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:683
-msgid ""
-"The database configuration file \".htconfig.php\" could not be written. "
-"Please use the enclosed text to create a configuration file in your web "
-"server root."
+#: ../../Zotlabs/Lib/Enotify.php:122
+#, php-format
+msgid "%1$s, %2$s sent you a new private message at %3$s."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:707
-#: ../../extend/addon/addon/cdav/cdav.php:41
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:401
-msgid "Errors encountered creating database tables."
+#: ../../Zotlabs/Lib/Enotify.php:123
+#, php-format
+msgid "%1$s sent you %2$s."
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:748
-msgid "
What next
"
+#: ../../Zotlabs/Lib/Enotify.php:123
+msgid "a private message"
msgstr ""
-#: ../../Zotlabs/Module/Setup.php:749
-msgid ""
-"IMPORTANT: You will need to [manually] setup a scheduled task for the poller."
+#: ../../Zotlabs/Lib/Enotify.php:124
+#, php-format
+msgid "Please visit %s to view and/or reply to your private messages."
msgstr ""
-#: ../../Zotlabs/Module/Viewconnections.php:65
-msgid "No connections."
+#: ../../Zotlabs/Lib/Enotify.php:183
+#, php-format
+msgid "%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]"
msgstr ""
-#: ../../Zotlabs/Module/Viewconnections.php:78
+#: ../../Zotlabs/Lib/Enotify.php:191
#, php-format
-msgid "Visit %s's profile [%s]"
+msgid "%1$s, %2$s commented on [zrl=%3$s]%4$s's %5$s[/zrl]"
msgstr ""
-#: ../../Zotlabs/Module/Viewconnections.php:107
-msgid "View Connections"
+#: ../../Zotlabs/Lib/Enotify.php:200
+#, php-format
+msgid "%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:30
-msgid "Profile Unavailable."
+#: ../../Zotlabs/Lib/Enotify.php:211
+#, php-format
+msgid "[$Projectname:Notify] Comment to conversation #%1$d by %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:44
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:40
-msgid "Not found"
+#: ../../Zotlabs/Lib/Enotify.php:212
+#, php-format
+msgid "%1$s, %2$s commented on an item/conversation you have been following."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:68
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:60
-msgid "Invalid channel"
+#: ../../Zotlabs/Lib/Enotify.php:215 ../../Zotlabs/Lib/Enotify.php:292
+#: ../../Zotlabs/Lib/Enotify.php:309 ../../Zotlabs/Lib/Enotify.php:335
+#: ../../Zotlabs/Lib/Enotify.php:353 ../../Zotlabs/Lib/Enotify.php:367
+#, php-format
+msgid "Please visit %s to view and/or reply to the conversation."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:159
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:144
-#: ../../include/conversation.php:1900
-msgid "Wikis"
+#: ../../Zotlabs/Lib/Enotify.php:273
+#, php-format
+msgid "%1$s, %2$s liked [zrl=%3$s]your %4$s[/zrl]"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:165
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:150
-msgid "Download"
+#: ../../Zotlabs/Lib/Enotify.php:288
+#, php-format
+msgid "[$Projectname:Notify] Like received to conversation #%1$d by %2$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:169
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:154
-msgid "Wiki name"
+#: ../../Zotlabs/Lib/Enotify.php:289
+#, php-format
+msgid "%1$s, %2$s liked an item/conversation you created."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:170
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:155
-msgid "Content type"
+#: ../../Zotlabs/Lib/Enotify.php:300
+#, php-format
+msgid "[$Projectname:Notify] %s posted to your profile wall"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:179
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:164
-msgid "Create a status post for this wiki"
+#: ../../Zotlabs/Lib/Enotify.php:302
+#, php-format
+msgid "%1$s, %2$s posted to your profile wall at %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:204
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:183
-msgid "Wiki not found"
+#: ../../Zotlabs/Lib/Enotify.php:304
+#, php-format
+msgid "%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:228
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:208
-msgid "Rename page"
+#: ../../Zotlabs/Lib/Enotify.php:328
+#, php-format
+msgid "[$Projectname:Notify] %s tagged you"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:232
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:212
-msgid "Error retrieving page content"
+#: ../../Zotlabs/Lib/Enotify.php:329
+#, php-format
+msgid "%1$s, %2$s tagged you at %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:259
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:241
-msgid "Revision Comparison"
+#: ../../Zotlabs/Lib/Enotify.php:330
+#, php-format
+msgid "%1$s, %2$s [zrl=%3$s]tagged you[/zrl]."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:260
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:242
-msgid "Revert"
+#: ../../Zotlabs/Lib/Enotify.php:342
+#, php-format
+msgid "[$Projectname:Notify] %1$s poked you"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:264
-msgid "Short description of your changes (optional)"
+#: ../../Zotlabs/Lib/Enotify.php:343
+#, php-format
+msgid "%1$s, %2$s poked you at %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:271
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:251
-msgid "Source"
+#: ../../Zotlabs/Lib/Enotify.php:344
+#, php-format
+msgid "%1$s, %2$s [zrl=%2$s]poked you[/zrl]."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:279
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:259
-msgid "New page name"
+#: ../../Zotlabs/Lib/Enotify.php:360
+#, php-format
+msgid "[$Projectname:Notify] %s tagged your post"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:284
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:264
-#: ../../include/conversation.php:1299
-msgid "Embed image from photo albums"
+#: ../../Zotlabs/Lib/Enotify.php:361
+#, php-format
+msgid "%1$s, %2$s tagged your post at %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:285
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:265
-#: ../../include/conversation.php:1393
-msgid "Embed an image from your albums"
+#: ../../Zotlabs/Lib/Enotify.php:362
+#, php-format
+msgid "%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:287
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:267
-#: ../../include/conversation.php:1395 ../../include/conversation.php:1442
-msgid "OK"
+#: ../../Zotlabs/Lib/Enotify.php:374
+msgid "[$Projectname:Notify] Introduction received"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:288
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:268
-#: ../../include/conversation.php:1335
-msgid "Choose images to embed"
+#: ../../Zotlabs/Lib/Enotify.php:375
+#, php-format
+msgid "%1$s, you've received an new connection request from '%2$s' at %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:289
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:269
-#: ../../include/conversation.php:1336
-msgid "Choose an album"
+#: ../../Zotlabs/Lib/Enotify.php:376
+#, php-format
+msgid ""
+"%1$s, you've received [zrl=%2$s]a new connection request[/zrl] from %3$s."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:290
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:270
-msgid "Choose a different album"
+#: ../../Zotlabs/Lib/Enotify.php:380 ../../Zotlabs/Lib/Enotify.php:399
+#, php-format
+msgid "You may visit their profile at %s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:291
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:271
-#: ../../include/conversation.php:1338
-msgid "Error getting album list"
+#: ../../Zotlabs/Lib/Enotify.php:382
+#, php-format
+msgid "Please visit %s to approve or reject the connection request."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:292
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:272
-#: ../../include/conversation.php:1339
-msgid "Error getting photo link"
+#: ../../Zotlabs/Lib/Enotify.php:389
+msgid "[$Projectname:Notify] Friend suggestion received"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:293
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:273
-#: ../../include/conversation.php:1340
-msgid "Error getting album"
+#: ../../Zotlabs/Lib/Enotify.php:390
+#, php-format
+msgid "%1$s, you've received a friend suggestion from '%2$s' at %3$s"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:357
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:337
-msgid "Error creating wiki. Invalid name."
+#: ../../Zotlabs/Lib/Enotify.php:391
+#, php-format
+msgid ""
+"%1$s, you've received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:369
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:348
-msgid "Wiki created, but error creating Home page."
+#: ../../Zotlabs/Lib/Enotify.php:397
+msgid "Name:"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:376
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:353
-msgid "Error creating wiki"
+#: ../../Zotlabs/Lib/Enotify.php:398
+msgid "Photo:"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:388
-msgid "Wiki delete permission denied."
+#: ../../Zotlabs/Lib/Enotify.php:401
+#, php-format
+msgid "Please visit %s to approve or reject the suggestion."
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:398
-msgid "Error deleting wiki"
+#: ../../Zotlabs/Lib/Enotify.php:619
+msgid "[$Projectname:Notify]"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:424
-#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:400
-msgid "New page created"
+#: ../../Zotlabs/Lib/Enotify.php:779
+msgid "created a new post"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:539
-msgid "Cannot delete Home"
+#: ../../Zotlabs/Lib/Enotify.php:780
+#, php-format
+msgid "commented on %s's post"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:603
-msgid "Current Revision"
+#: ../../Zotlabs/Lib/PermissionDescription.php:34
+#: ../../include/acl_selectors.php:128
+msgid "Visible to your default audience"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:603
-msgid "Selected Revision"
+#: ../../Zotlabs/Lib/PermissionDescription.php:107
+#: ../../include/acl_selectors.php:201
+msgid "Only me"
msgstr ""
-#: ../../Zotlabs/Module/Wiki.php:653
-msgid "You must be authenticated."
+#: ../../Zotlabs/Lib/PermissionDescription.php:108
+msgid "Public"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:179
-msgid "Room not found"
+#: ../../Zotlabs/Lib/PermissionDescription.php:109
+msgid "Anybody in the $Projectname network"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:195
-msgid "Leave Room"
+#: ../../Zotlabs/Lib/PermissionDescription.php:110
+#, php-format
+msgid "Any account on %s"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:196
-msgid "Delete Room"
+#: ../../Zotlabs/Lib/PermissionDescription.php:111
+msgid "Any of my connections"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:197
-msgid "I am away right now"
+#: ../../Zotlabs/Lib/PermissionDescription.php:112
+msgid "Only connections I specifically allow"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:198
-msgid "I am online"
+#: ../../Zotlabs/Lib/PermissionDescription.php:113
+msgid "Anybody authenticated (could include visitors from other networks)"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:200
-msgid "Bookmark this room"
+#: ../../Zotlabs/Lib/PermissionDescription.php:114
+msgid "Any connections including those who haven't yet been approved"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:229
-msgid "New Chatroom"
+#: ../../Zotlabs/Lib/PermissionDescription.php:150
+msgid ""
+"This is your default setting for the audience of your normal stream, and "
+"posts."
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:230
-msgid "Chatroom name"
+#: ../../Zotlabs/Lib/PermissionDescription.php:151
+msgid ""
+"This is your default setting for who can view your default channel profile"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:231
-msgid "Expiration of chats (minutes)"
+#: ../../Zotlabs/Lib/PermissionDescription.php:152
+msgid "This is your default setting for who can view your connections"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:247
-#, php-format
-msgid "%1$s's Chatrooms"
+#: ../../Zotlabs/Lib/PermissionDescription.php:153
+msgid ""
+"This is your default setting for who can view your file storage and photos"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:252
-msgid "No chatrooms available"
+#: ../../Zotlabs/Lib/PermissionDescription.php:154
+msgid "This is your default setting for the audience of your webpages"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:256
-msgid "Expiration"
+#: ../../Zotlabs/Lib/ThreadItem.php:95 ../../include/conversation.php:663
+msgid "Private Message"
msgstr ""
-#: ../../Zotlabs/Module/Chat.php:257
-msgid "min"
+#: ../../Zotlabs/Lib/ThreadItem.php:132 ../../include/conversation.php:655
+msgid "Select"
msgstr ""
-#: ../../Zotlabs/Module/Xchan.php:10
-msgid "Xchan Lookup"
+#: ../../Zotlabs/Lib/ThreadItem.php:136
+msgid "Save to Folder"
msgstr ""
-#: ../../Zotlabs/Module/Xchan.php:13
-msgid "Lookup xchan beginning with (or webbie): "
+#: ../../Zotlabs/Lib/ThreadItem.php:157
+msgid "I will attend"
msgstr ""
-#: ../../Zotlabs/Lib/Chatroom.php:27
-msgid "Missing room name"
+#: ../../Zotlabs/Lib/ThreadItem.php:157
+msgid "I will not attend"
msgstr ""
-#: ../../Zotlabs/Lib/Chatroom.php:36
-msgid "Duplicate room name"
+#: ../../Zotlabs/Lib/ThreadItem.php:157
+msgid "I might attend"
msgstr ""
-#: ../../Zotlabs/Lib/Chatroom.php:86 ../../Zotlabs/Lib/Chatroom.php:94
-msgid "Invalid room specifier."
+#: ../../Zotlabs/Lib/ThreadItem.php:167
+msgid "I agree"
msgstr ""
-#: ../../Zotlabs/Lib/Chatroom.php:126
-msgid "Room not found."
+#: ../../Zotlabs/Lib/ThreadItem.php:167
+msgid "I disagree"
msgstr ""
-#: ../../Zotlabs/Lib/Chatroom.php:147
-msgid "Room is full"
+#: ../../Zotlabs/Lib/ThreadItem.php:167
+msgid "I abstain"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:60 ../../include/network.php:1947
-msgid "$Projectname Notification"
+#: ../../Zotlabs/Lib/ThreadItem.php:223
+msgid "Add Star"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:61 ../../extend/addon/addon/diaspora/p.php:46
-#: ../../extend/addon/addon/diaspora/util.php:218
-#: ../../extend/addon/addon/diaspora/util.php:231
-#: ../../include/network.php:1948
-msgid "$projectname"
+#: ../../Zotlabs/Lib/ThreadItem.php:224
+msgid "Remove Star"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:63 ../../include/network.php:1950
-msgid "Thank You,"
+#: ../../Zotlabs/Lib/ThreadItem.php:225
+msgid "Toggle Star Status"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:65 ../../include/network.php:1952
-#, php-format
-msgid "%s Administrator"
+#: ../../Zotlabs/Lib/ThreadItem.php:229
+msgid "starred"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:116
-#, php-format
-msgid "%s "
+#: ../../Zotlabs/Lib/ThreadItem.php:239 ../../include/conversation.php:670
+msgid "Message signature validated"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:120
-#, php-format
-msgid "[$Projectname:Notify] New mail received at %s"
+#: ../../Zotlabs/Lib/ThreadItem.php:240 ../../include/conversation.php:671
+msgid "Message signature incorrect"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:122
-#, php-format
-msgid "%1$s, %2$s sent you a new private message at %3$s."
+#: ../../Zotlabs/Lib/ThreadItem.php:248
+msgid "Add Tag"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:123
-#, php-format
-msgid "%1$s sent you %2$s."
+#: ../../Zotlabs/Lib/ThreadItem.php:268 ../../include/taxonomy.php:316
+msgid "like"
+msgstr ""
+
+#: ../../Zotlabs/Lib/ThreadItem.php:269 ../../include/taxonomy.php:317
+msgid "dislike"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:123
-msgid "a private message"
+#: ../../Zotlabs/Lib/ThreadItem.php:273
+msgid "Share This"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:124
-#, php-format
-msgid "Please visit %s to view and/or reply to your private messages."
+#: ../../Zotlabs/Lib/ThreadItem.php:273
+msgid "share"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:183
-#, php-format
-msgid "%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]"
+#: ../../Zotlabs/Lib/ThreadItem.php:282
+msgid "Delivery Report"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:191
+#: ../../Zotlabs/Lib/ThreadItem.php:300
#, php-format
-msgid "%1$s, %2$s commented on [zrl=%3$s]%4$s's %5$s[/zrl]"
-msgstr ""
+msgid "%d comment"
+msgid_plural "%d comments"
+msgstr[0] ""
+msgstr[1] ""
-#: ../../Zotlabs/Lib/Enotify.php:200
+#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Lib/ThreadItem.php:330
#, php-format
-msgid "%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]"
+msgid "View %s's profile - %s"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:211
-#, php-format
-msgid "[$Projectname:Notify] Comment to conversation #%1$d by %2$s"
+#: ../../Zotlabs/Lib/ThreadItem.php:333
+msgid "to"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:212
-#, php-format
-msgid "%1$s, %2$s commented on an item/conversation you have been following."
+#: ../../Zotlabs/Lib/ThreadItem.php:334
+msgid "via"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:215 ../../Zotlabs/Lib/Enotify.php:292
-#: ../../Zotlabs/Lib/Enotify.php:309 ../../Zotlabs/Lib/Enotify.php:335
-#: ../../Zotlabs/Lib/Enotify.php:353 ../../Zotlabs/Lib/Enotify.php:367
-#, php-format
-msgid "Please visit %s to view and/or reply to the conversation."
+#: ../../Zotlabs/Lib/ThreadItem.php:335
+msgid "Wall-to-Wall"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:273
-#, php-format
-msgid "%1$s, %2$s liked [zrl=%3$s]your %4$s[/zrl]"
+#: ../../Zotlabs/Lib/ThreadItem.php:336
+msgid "via Wall-To-Wall:"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:288
+#: ../../Zotlabs/Lib/ThreadItem.php:350 ../../include/conversation.php:717
#, php-format
-msgid "[$Projectname:Notify] Like received to conversation #%1$d by %2$s"
+msgid "from %s"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:289
+#: ../../Zotlabs/Lib/ThreadItem.php:353 ../../include/conversation.php:720
#, php-format
-msgid "%1$s, %2$s liked an item/conversation you created."
+msgid "last edited: %s"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:300
+#: ../../Zotlabs/Lib/ThreadItem.php:354 ../../include/conversation.php:721
#, php-format
-msgid "[$Projectname:Notify] %s posted to your profile wall"
+msgid "Expires: %s"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:302
-#, php-format
-msgid "%1$s, %2$s posted to your profile wall at %3$s"
+#: ../../Zotlabs/Lib/ThreadItem.php:360
+msgid "Attend"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:304
-#, php-format
-msgid "%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]"
+#: ../../Zotlabs/Lib/ThreadItem.php:361
+msgid "Attendance Options"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:328
-#, php-format
-msgid "[$Projectname:Notify] %s tagged you"
+#: ../../Zotlabs/Lib/ThreadItem.php:362
+msgid "Vote"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:329
-#, php-format
-msgid "%1$s, %2$s tagged you at %3$s"
+#: ../../Zotlabs/Lib/ThreadItem.php:363
+msgid "Voting Options"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:330
-#, php-format
-msgid "%1$s, %2$s [zrl=%3$s]tagged you[/zrl]."
+#: ../../Zotlabs/Lib/ThreadItem.php:383
+#: ../../extend/addon/addon/bookmarker/bookmarker.php:38
+msgid "Save Bookmarks"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:342
-#, php-format
-msgid "[$Projectname:Notify] %1$s poked you"
+#: ../../Zotlabs/Lib/ThreadItem.php:384
+msgid "Add to Calendar"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:343
-#, php-format
-msgid "%1$s, %2$s poked you at %3$s"
+#: ../../Zotlabs/Lib/ThreadItem.php:393
+msgid "Mark all seen"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:344
+#: ../../Zotlabs/Lib/ThreadItem.php:442 ../../include/js_strings.php:7
#, php-format
-msgid "%1$s, %2$s [zrl=%2$s]poked you[/zrl]."
+msgid "%s show all"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:360
-#, php-format
-msgid "[$Projectname:Notify] %s tagged your post"
+#: ../../Zotlabs/Lib/ThreadItem.php:732 ../../include/conversation.php:1385
+msgid "Bold"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:361
-#, php-format
-msgid "%1$s, %2$s tagged your post at %3$s"
+#: ../../Zotlabs/Lib/ThreadItem.php:733 ../../include/conversation.php:1386
+msgid "Italic"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:362
-#, php-format
-msgid "%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]"
+#: ../../Zotlabs/Lib/ThreadItem.php:734 ../../include/conversation.php:1387
+msgid "Underline"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:374
-msgid "[$Projectname:Notify] Introduction received"
+#: ../../Zotlabs/Lib/ThreadItem.php:735 ../../include/conversation.php:1388
+msgid "Quote"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:375
-#, php-format
-msgid "%1$s, you've received an new connection request from '%2$s' at %3$s"
+#: ../../Zotlabs/Lib/ThreadItem.php:736 ../../include/conversation.php:1389
+msgid "Code"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:376
-#, php-format
-msgid ""
-"%1$s, you've received [zrl=%2$s]a new connection request[/zrl] from %3$s."
+#: ../../Zotlabs/Lib/ThreadItem.php:737
+msgid "Image"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:380 ../../Zotlabs/Lib/Enotify.php:399
-#, php-format
-msgid "You may visit their profile at %s"
+#: ../../Zotlabs/Lib/ThreadItem.php:738
+msgid "Insert Link"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:382
-#, php-format
-msgid "Please visit %s to approve or reject the connection request."
+#: ../../Zotlabs/Lib/ThreadItem.php:739
+msgid "Video"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:389
-msgid "[$Projectname:Notify] Friend suggestion received"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:31
+#: ../../Zotlabs/Lib/NativeWikiPage.php:72
+msgid "(No Title)"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:390
-#, php-format
-msgid "%1$s, you've received a friend suggestion from '%2$s' at %3$s"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:86
+msgid "Wiki page create failed."
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:391
-#, php-format
-msgid ""
-"%1$s, you've received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s."
+#: ../../Zotlabs/Lib/NativeWikiPage.php:99
+msgid "Wiki not found."
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:397
-msgid "Name:"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:110
+msgid "Destination name already exists"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:398
-msgid "Photo:"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:136
+#: ../../Zotlabs/Lib/NativeWikiPage.php:365
+msgid "Page not found"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:401
-#, php-format
-msgid "Please visit %s to approve or reject the suggestion."
+#: ../../Zotlabs/Lib/NativeWikiPage.php:166
+msgid "Error reading page content"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:619
-msgid "[$Projectname:Notify]"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:350
+#: ../../Zotlabs/Lib/NativeWikiPage.php:403
+#: ../../Zotlabs/Lib/NativeWikiPage.php:470
+#: ../../Zotlabs/Lib/NativeWikiPage.php:511
+msgid "Error reading wiki"
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:779
-msgid "created a new post"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:391
+msgid "Page update failed."
msgstr ""
-#: ../../Zotlabs/Lib/Enotify.php:780
-#, php-format
-msgid "commented on %s's post"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:425
+msgid "Nothing deleted"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:34
-#: ../../include/acl_selectors.php:128
-msgid "Visible to your default audience"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:491
+msgid "Compare: object not found."
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:107
-#: ../../include/acl_selectors.php:201
-msgid "Only me"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:497
+msgid "Page updated"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:108
-msgid "Public"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:500
+msgid "Untitled"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:109
-msgid "Anybody in the $Projectname network"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:506
+msgid "Wiki resource_id required for git commit"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:110
-#, php-format
-msgid "Any account on %s"
+#: ../../Zotlabs/Lib/NativeWikiPage.php:577
+#: ../../extend/addon/addon/gitwiki/gitwiki_backend.php:579
+#: ../../include/bbcode.php:610 ../../include/bbcode.php:756
+msgid "Different viewers will see this text differently"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:111
-msgid "Any of my connections"
+#: ../../Zotlabs/Lib/Permcat.php:58
+msgctxt "permcat"
+msgid "default"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:112
-msgid "Only connections I specifically allow"
+#: ../../Zotlabs/Lib/Permcat.php:96
+msgctxt "permcat"
+msgid "follower"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:113
-msgid "Anybody authenticated (could include visitors from other networks)"
+#: ../../Zotlabs/Lib/Permcat.php:100
+msgctxt "permcat"
+msgid "contributor"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:114
-msgid "Any connections including those who haven't yet been approved"
+#: ../../Zotlabs/Lib/Permcat.php:104
+msgctxt "permcat"
+msgid "publisher"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:150
-msgid ""
-"This is your default setting for the audience of your normal stream, and "
-"posts."
+#: ../../Zotlabs/Lib/Apps.php:212
+msgid "Site Admin"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:151
-msgid ""
-"This is your default setting for who can view your default channel profile"
+#: ../../Zotlabs/Lib/Apps.php:213
+#: ../../extend/addon/addon/buglink/buglink.php:16
+msgid "Report Bug"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:152
-msgid "This is your default setting for who can view your connections"
+#: ../../Zotlabs/Lib/Apps.php:214
+msgid "View Bookmarks"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:153
-msgid ""
-"This is your default setting for who can view your file storage and photos"
+#: ../../Zotlabs/Lib/Apps.php:215
+msgid "My Chatrooms"
msgstr ""
-#: ../../Zotlabs/Lib/PermissionDescription.php:154
-msgid "This is your default setting for the audience of your webpages"
+#: ../../Zotlabs/Lib/Apps.php:217
+msgid "Firefox Share"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:31
-#: ../../Zotlabs/Lib/NativeWikiPage.php:70
-msgid "(No Title)"
+#: ../../Zotlabs/Lib/Apps.php:218
+msgid "Remote Diagnostics"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:84
-msgid "Wiki page create failed."
+#: ../../Zotlabs/Lib/Apps.php:219 ../../include/features.php:337
+msgid "Suggest Channels"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:97
-msgid "Wiki not found."
+#: ../../Zotlabs/Lib/Apps.php:220 ../../include/nav.php:130
+#: ../../boot.php:1706
+msgid "Login"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:108
-msgid "Destination name already exists"
+#: ../../Zotlabs/Lib/Apps.php:222 ../../include/nav.php:194
+msgid "Grid"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:134
-#: ../../Zotlabs/Lib/NativeWikiPage.php:361
-msgid "Page not found"
+#: ../../Zotlabs/Lib/Apps.php:226 ../../include/conversation.php:1903
+#: ../../include/features.php:99
+msgid "Wiki"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:164
-msgid "Error reading page content"
+#: ../../Zotlabs/Lib/Apps.php:227 ../../include/nav.php:198
+msgid "Channel Home"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:346
-#: ../../Zotlabs/Lib/NativeWikiPage.php:399
-#: ../../Zotlabs/Lib/NativeWikiPage.php:466
-#: ../../Zotlabs/Lib/NativeWikiPage.php:507
-msgid "Error reading wiki"
+#: ../../Zotlabs/Lib/Apps.php:230 ../../include/conversation.php:1853
+#: ../../include/conversation.php:1856 ../../include/nav.php:218
+msgid "Events"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:387
-msgid "Page update failed."
+#: ../../Zotlabs/Lib/Apps.php:231 ../../include/nav.php:182
+msgid "Directory"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:421
-msgid "Nothing deleted"
+#: ../../Zotlabs/Lib/Apps.php:233 ../../include/nav.php:210
+msgid "Mail"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:487
-msgid "Compare: object not found."
+#: ../../Zotlabs/Lib/Apps.php:236
+msgid "Chat"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:493
-msgid "Page updated"
+#: ../../Zotlabs/Lib/Apps.php:238
+msgid "Probe"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:496
-msgid "Untitled"
+#: ../../Zotlabs/Lib/Apps.php:239
+msgid "Suggest"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:502
-msgid "Wiki resource_id required for git commit"
+#: ../../Zotlabs/Lib/Apps.php:240
+msgid "Random Channel"
msgstr ""
-#: ../../Zotlabs/Lib/NativeWikiPage.php:573
-#: ../../extend/addon/addon/gitwiki/gitwiki_backend.php:579
-#: ../../include/bbcode.php:610 ../../include/bbcode.php:756
-msgid "Different viewers will see this text differently"
+#: ../../Zotlabs/Lib/Apps.php:241
+msgid "Invite"
msgstr ""
-#: ../../Zotlabs/Lib/Permcat.php:58
-msgctxt "permcat"
-msgid "default"
+#: ../../Zotlabs/Lib/Apps.php:242 ../../include/widgets.php:1638
+msgid "Features"
msgstr ""
-#: ../../Zotlabs/Lib/Permcat.php:96
-msgctxt "permcat"
-msgid "follower"
+#: ../../Zotlabs/Lib/Apps.php:243
+#: ../../extend/addon/addon/openid/MysqlProvider.php:69
+msgid "Language"
msgstr ""
-#: ../../Zotlabs/Lib/Permcat.php:100
-msgctxt "permcat"
-msgid "contributor"
+#: ../../Zotlabs/Lib/Apps.php:244
+msgid "Post"
msgstr ""
-#: ../../Zotlabs/Lib/Permcat.php:104
-msgctxt "permcat"
-msgid "publisher"
+#: ../../Zotlabs/Lib/Apps.php:245
+#: ../../extend/addon/addon/openid/MysqlProvider.php:58
+#: ../../extend/addon/addon/openid/MysqlProvider.php:59
+#: ../../extend/addon/addon/openid/MysqlProvider.php:60
+msgid "Profile Photo"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:95 ../../include/conversation.php:663
-msgid "Private Message"
+#: ../../Zotlabs/Lib/Apps.php:355
+msgid "Purchase"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:132 ../../include/conversation.php:655
-msgid "Select"
+#: ../../Zotlabs/Lib/Apps.php:359
+msgid "Undelete"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:136
-msgid "Save to Folder"
+#: ../../Zotlabs/Lib/Apps.php:364
+msgid "Add to app-tray"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:157
-msgid "I will attend"
+#: ../../Zotlabs/Lib/Apps.php:365
+msgid "Remove from app-tray"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:157
-msgid "I will not attend"
+#: ../../Zotlabs/Lib/NativeWiki.php:128
+msgid "Wiki files deleted successfully"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:157
-msgid "I might attend"
+#: ../../extend/addon/addon/adultphotoflag/adultphotoflag.php:24
+msgid "Flag Adult Photos"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:167
-msgid "I agree"
+#: ../../extend/addon/addon/adultphotoflag/adultphotoflag.php:25
+msgid ""
+"Provide photo edit option to hide inappropriate photos from default album "
+"view"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:167
-msgid "I disagree"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:44
+msgid ""
+"This is a fairly comprehensive and complete guitar chord dictionary which "
+"will list most of the available ways to play a certain chord, starting from "
+"the base of the fingerboard up to a few frets beyond the twelfth fret "
+"(beyond which everything repeats). A couple of non-standard tunings are "
+"provided for the benefit of slide players, etc."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:167
-msgid "I abstain"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:46
+msgid ""
+"Chord names start with a root note (A-G) and may include sharps (#) and "
+"flats (b). This software will parse most of the standard naming conventions "
+"such as maj, min, dim, sus(2 or 4), aug, with optional repeating elements."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:223
-msgid "Add Star"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:48
+msgid ""
+"Valid examples include A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, "
+"E7b13b11 ..."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:224
-msgid "Remove Star"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:51
+msgid "Guitar Chords"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:225
-msgid "Toggle Star Status"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:52
+msgid "The complete online chord dictionary"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:229
-msgid "starred"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:57
+msgid "Tuning"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:239 ../../include/conversation.php:670
-msgid "Message signature validated"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:58
+msgid "Chord name: example: Em7"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:240 ../../include/conversation.php:671
-msgid "Message signature incorrect"
+#: ../../extend/addon/addon/chords/Mod_Chords.php:59
+msgid "Show for left handed stringing"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:248
-msgid "Add Tag"
+#: ../../extend/addon/addon/chords/chords.php:33
+msgid "Quick Reference"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:268 ../../include/taxonomy.php:316
-msgid "like"
+#: ../../extend/addon/addon/diaspora/diaspora.php:677
+msgid "Diaspora Protocol Settings updated."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:269 ../../include/taxonomy.php:317
-msgid "dislike"
+#: ../../extend/addon/addon/diaspora/diaspora.php:696
+msgid "Enable the Diaspora protocol for this channel"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:273
-msgid "Share This"
+#: ../../extend/addon/addon/diaspora/diaspora.php:700
+msgid "Allow any Diaspora member to comment on your public posts"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:273
-msgid "share"
+#: ../../extend/addon/addon/diaspora/diaspora.php:704
+msgid "Prevent your hashtags from being redirected to other sites"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:282
-msgid "Delivery Report"
+#: ../../extend/addon/addon/diaspora/diaspora.php:709
+msgid "Followed hashtags (comma separated, do not include the #)"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:300
-#, php-format
-msgid "%d comment"
-msgid_plural "%d comments"
-msgstr[0] ""
-msgstr[1] ""
-
-#: ../../Zotlabs/Lib/ThreadItem.php:329 ../../Zotlabs/Lib/ThreadItem.php:330
-#, php-format
-msgid "View %s's profile - %s"
+#: ../../extend/addon/addon/diaspora/diaspora.php:714
+msgid "Diaspora Protocol Settings"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:333
-msgid "to"
+#: ../../extend/addon/addon/diaspora/import_diaspora.php:16
+msgid "No username found in import file."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:334
-msgid "via"
+#: ../../extend/addon/addon/diaspora/import_diaspora.php:41
+#: ../../include/import.php:51
+msgid "Unable to create a unique channel address. Import failed."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:335
-msgid "Wall-to-Wall"
+#: ../../extend/addon/addon/dirstats/dirstats.php:94
+msgid "Hubzilla Directory Stats"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:336
-msgid "via Wall-To-Wall:"
+#: ../../extend/addon/addon/dirstats/dirstats.php:95
+msgid "Total Hubs"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:350 ../../include/conversation.php:717
-#, php-format
-msgid "from %s"
+#: ../../extend/addon/addon/dirstats/dirstats.php:97
+msgid "Hubzilla Hubs"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:353 ../../include/conversation.php:720
-#, php-format
-msgid "last edited: %s"
+#: ../../extend/addon/addon/dirstats/dirstats.php:99
+msgid "Friendica Hubs"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:354 ../../include/conversation.php:721
-#, php-format
-msgid "Expires: %s"
+#: ../../extend/addon/addon/dirstats/dirstats.php:101
+msgid "Diaspora Pods"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:360
-msgid "Attend"
+#: ../../extend/addon/addon/dirstats/dirstats.php:103
+msgid "Hubzilla Channels"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:361
-msgid "Attendance Options"
+#: ../../extend/addon/addon/dirstats/dirstats.php:105
+msgid "Friendica Channels"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:362
-msgid "Vote"
+#: ../../extend/addon/addon/dirstats/dirstats.php:107
+msgid "Diaspora Channels"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:363
-msgid "Voting Options"
+#: ../../extend/addon/addon/dirstats/dirstats.php:109
+msgid "Aged 35 and above"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:383
-#: ../../extend/addon/addon/bookmarker/bookmarker.php:38
-msgid "Save Bookmarks"
+#: ../../extend/addon/addon/dirstats/dirstats.php:111
+msgid "Aged 34 and under"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:384
-msgid "Add to Calendar"
+#: ../../extend/addon/addon/dirstats/dirstats.php:113
+msgid "Average Age"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:393
-msgid "Mark all seen"
+#: ../../extend/addon/addon/dirstats/dirstats.php:115
+msgid "Known Chatrooms"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:442 ../../include/js_strings.php:7
-#, php-format
-msgid "%s show all"
+#: ../../extend/addon/addon/dirstats/dirstats.php:117
+msgid "Known Tags"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:732 ../../include/conversation.php:1385
-msgid "Bold"
+#: ../../extend/addon/addon/dirstats/dirstats.php:119
+msgid ""
+"Please note Diaspora and Friendica statistics are merely those **this "
+"directory** is aware of, and not all those known in the network. This also "
+"applies to chatrooms,"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:733 ../../include/conversation.php:1386
-msgid "Italic"
+#: ../../extend/addon/addon/donate/donate.php:21
+msgid "Project Servers and Resources"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:734 ../../include/conversation.php:1387
-msgid "Underline"
+#: ../../extend/addon/addon/donate/donate.php:22
+msgid "Project Creator and Tech Lead"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:735 ../../include/conversation.php:1388
-msgid "Quote"
+#: ../../extend/addon/addon/donate/donate.php:23
+msgid "Admin, developer, directorymin, support bloke"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:736 ../../include/conversation.php:1389
-msgid "Code"
+#: ../../extend/addon/addon/donate/donate.php:50
+msgid ""
+"And the hundreds of other people and organisations who helped make the "
+"Hubzilla possible."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:737
-msgid "Image"
+#: ../../extend/addon/addon/donate/donate.php:53
+msgid ""
+"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving "
+"their time and expertise - and often paying out of pocket for services they "
+"share with others."
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:738
-msgid "Insert Link"
+#: ../../extend/addon/addon/donate/donate.php:54
+msgid ""
+"There is no corporate funding and no ads, and we do not collect and sell "
+"your personal information. (We don't control your personal information - "
+"you do.)"
msgstr ""
-#: ../../Zotlabs/Lib/ThreadItem.php:739
-msgid "Video"
+#: ../../extend/addon/addon/donate/donate.php:55
+msgid ""
+"Help support our ground-breaking work in decentralisation, web identity, and "
+"privacy."
msgstr ""
-#: ../../Zotlabs/Lib/NativeWiki.php:126
-msgid "Wiki files deleted successfully"
+#: ../../extend/addon/addon/donate/donate.php:57
+msgid ""
+"Your donations keep servers and services running and also helps us to "
+"provide innovative new features and continued development."
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:212
-msgid "Site Admin"
+#: ../../extend/addon/addon/donate/donate.php:60
+msgid "Donate"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:213
-#: ../../extend/addon/addon/buglink/buglink.php:16
-msgid "Report Bug"
+#: ../../extend/addon/addon/donate/donate.php:62
+msgid ""
+"Choose a project, developer, or public hub to support with a one-time "
+"donation"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:214
-msgid "View Bookmarks"
+#: ../../extend/addon/addon/donate/donate.php:63
+msgid "Donate Now"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:215
-msgid "My Chatrooms"
+#: ../../extend/addon/addon/donate/donate.php:64
+msgid ""
+"Or become a project sponsor (Hubzilla Project only)"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:217
-msgid "Firefox Share"
+#: ../../extend/addon/addon/donate/donate.php:65
+msgid ""
+"Please indicate if you would like your first name or full name (or nothing) "
+"to appear in our sponsor listing"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:218
-msgid "Remote Diagnostics"
+#: ../../extend/addon/addon/donate/donate.php:66
+msgid "Sponsor"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:219 ../../include/features.php:337
-msgid "Suggest Channels"
+#: ../../extend/addon/addon/donate/donate.php:69
+msgid "Special thanks to: "
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:220 ../../include/nav.php:130
-#: ../../boot.php:1749
-msgid "Login"
+#: ../../extend/addon/addon/dwpost/dwpost.php:42
+msgid "Post to Dreamwidth"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:222 ../../include/nav.php:194
-msgid "Grid"
+#: ../../extend/addon/addon/dwpost/dwpost.php:73
+msgid "Enable Dreamwidth Post Plugin"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:226 ../../include/conversation.php:1903
-#: ../../include/features.php:99
-msgid "Wiki"
+#: ../../extend/addon/addon/dwpost/dwpost.php:77
+msgid "Dreamwidth username"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:227 ../../include/nav.php:198
-msgid "Channel Home"
+#: ../../extend/addon/addon/dwpost/dwpost.php:81
+msgid "Dreamwidth password"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:230 ../../include/conversation.php:1853
-#: ../../include/conversation.php:1856 ../../include/nav.php:218
-msgid "Events"
+#: ../../extend/addon/addon/dwpost/dwpost.php:85
+msgid "Post to Dreamwidth by default"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:231 ../../include/nav.php:182
-msgid "Directory"
+#: ../../extend/addon/addon/dwpost/dwpost.php:89
+msgid "Dreamwidth Post Settings"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:233 ../../include/nav.php:210
-msgid "Mail"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:45
+msgid "Flattr this!"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:236
-msgid "Chat"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:83
+msgid "Flattr widget settings updated."
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:238
-msgid "Probe"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:100
+msgid "Flattr user"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:239
-msgid "Suggest"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:104
+msgid "URL of the Thing to flattr"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:240
-msgid "Random Channel"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:104
+msgid "If empty channel URL is used"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:241
-msgid "Invite"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:108
+msgid "Title of the Thing to flattr"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:242 ../../include/widgets.php:1638
-msgid "Features"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:108
+msgid "If empty \"channel name on The Hubzilla\" will be used"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:243
-#: ../../extend/addon/addon/openid/MysqlProvider.php:69
-msgid "Language"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:112
+msgid "Static or dynamic flattr button"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:244
-msgid "Post"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:112
+msgid "static"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:245
-#: ../../extend/addon/addon/openid/MysqlProvider.php:58
-#: ../../extend/addon/addon/openid/MysqlProvider.php:59
-#: ../../extend/addon/addon/openid/MysqlProvider.php:60
-msgid "Profile Photo"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:112
+msgid "dynamic"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:355
-msgid "Purchase"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:116
+msgid "Alignment of the widget"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:359
-msgid "Undelete"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:116
+msgid "left"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:364
-msgid "Add to app-tray"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:116
+msgid "right"
msgstr ""
-#: ../../Zotlabs/Lib/Apps.php:365
-msgid "Remove from app-tray"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:120
+msgid "Enable Flattr widget"
msgstr ""
-#: ../../extend/addon/addon/adultphotoflag/adultphotoflag.php:24
-msgid "Flag Adult Photos"
+#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:124
+msgid "Flattr Widget Settings"
msgstr ""
-#: ../../extend/addon/addon/adultphotoflag/adultphotoflag.php:25
-msgid ""
-"Provide photo edit option to hide inappropriate photos from default album "
-"view"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:118
+msgid "Contact not found."
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:44
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:119
msgid ""
-"This is a fairly comprehensive and complete guitar chord dictionary which "
-"will list most of the available ways to play a certain chord, starting from "
-"the base of the fingerboard up to a few frets beyond the twelfth fret "
-"(beyond which everything repeats). A couple of non-standard tunings are "
-"provided for the benefit of slide players, etc."
+"This may occasionally happen if contact was requested by both persons and it "
+"has already been approved."
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:46
-msgid ""
-"Chord names start with a root note (A-G) and may include sharps (#) and "
-"flats (b). This software will parse most of the standard naming conventions "
-"such as maj, min, dim, sus(2 or 4), aug, with optional repeating elements."
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:238
+msgid "Response from remote site was not understood."
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:48
-msgid ""
-"Valid examples include A, A7, Am7, Amaj7, Amaj9, Ammaj7, Aadd4, Asus2Add4, "
-"E7b13b11 ..."
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:247
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:252
+msgid "Unexpected response from remote site: "
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:51
-msgid "Guitar Chords"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:261
+msgid "Confirmation completed successfully."
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:52
-msgid "The complete online chord dictionary"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:263
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:277
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:284
+msgid "Remote site reported: "
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:57
-msgid "Tuning"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:275
+msgid "Temporary failure. Please wait and try again."
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:58
-msgid "Chord name: example: Em7"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:282
+msgid "Introduction failed or was revoked."
msgstr ""
-#: ../../extend/addon/addon/chords/Mod_Chords.php:59
-msgid "Show for left handed stringing"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:428
+msgid "Unable to set contact photo."
msgstr ""
-#: ../../extend/addon/addon/chords/chords.php:33
-msgid "Quick Reference"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:485
+#, php-format
+msgid "%1$s is now friends with %2$s"
msgstr ""
-#: ../../extend/addon/addon/diaspora/import_diaspora.php:16
-msgid "No username found in import file."
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:570
+#, php-format
+msgid "No user record found for '%s' "
msgstr ""
-#: ../../extend/addon/addon/diaspora/import_diaspora.php:41
-#: ../../include/import.php:51
-msgid "Unable to create a unique channel address. Import failed."
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:580
+msgid "Our site encryption key is apparently messed up."
msgstr ""
-#: ../../extend/addon/addon/diaspora/diaspora.php:677
-msgid "Diaspora Protocol Settings updated."
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:591
+msgid "Empty site URL was provided or URL could not be decrypted by us."
msgstr ""
-#: ../../extend/addon/addon/diaspora/diaspora.php:696
-msgid "Enable the Diaspora protocol for this channel"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:612
+msgid "Contact record was not found for you on our site."
msgstr ""
-#: ../../extend/addon/addon/diaspora/diaspora.php:700
-msgid "Allow any Diaspora member to comment on your public posts"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:626
+#, php-format
+msgid "Site public key not available in contact record for URL %s."
msgstr ""
-#: ../../extend/addon/addon/diaspora/diaspora.php:704
-msgid "Prevent your hashtags from being redirected to other sites"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:646
+msgid ""
+"The ID provided by your system is a duplicate on our system. It should work "
+"if you try again."
msgstr ""
-#: ../../extend/addon/addon/diaspora/diaspora.php:709
-msgid "Followed hashtags (comma separated, do not include the #)"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:657
+msgid "Unable to set your contact credentials on our system."
msgstr ""
-#: ../../extend/addon/addon/diaspora/diaspora.php:714
-msgid "Diaspora Protocol Settings"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:724
+msgid "Unable to update your contact profile details on our system"
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:94
-msgid "Hubzilla Directory Stats"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:751
+#: ../../extend/addon/addon/friendica/dfrn_request.php:749
+msgid "[Name Withheld]"
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:95
-msgid "Total Hubs"
+#: ../../extend/addon/addon/friendica/dfrn_confirm.php:796
+#, php-format
+msgid "%1$s has joined %2$s"
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:97
-msgid "Hubzilla Hubs"
+#: ../../extend/addon/addon/friendica/dfrn_poll.php:103
+#: ../../extend/addon/addon/friendica/dfrn_poll.php:536
+#, php-format
+msgid "%1$s welcomes %2$s"
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:99
-msgid "Friendica Hubs"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:102
+msgid "This introduction has already been accepted."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:101
-msgid "Diaspora Pods"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:123
+#: ../../extend/addon/addon/friendica/dfrn_request.php:528
+msgid "Profile location is not valid or does not contain profile information."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:103
-msgid "Hubzilla Channels"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:128
+#: ../../extend/addon/addon/friendica/dfrn_request.php:533
+msgid "Warning: profile location has no identifiable owner name."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:105
-msgid "Friendica Channels"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:130
+#: ../../extend/addon/addon/friendica/dfrn_request.php:535
+msgid "Warning: profile location has no profile photo."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:107
-msgid "Diaspora Channels"
-msgstr ""
+#: ../../extend/addon/addon/friendica/dfrn_request.php:133
+#: ../../extend/addon/addon/friendica/dfrn_request.php:538
+#, php-format
+msgid "%d required parameter was not found at the given location"
+msgid_plural "%d required parameters were not found at the given location"
+msgstr[0] ""
+msgstr[1] ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:109
-msgid "Aged 35 and above"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:180
+msgid "Introduction complete."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:111
-msgid "Aged 34 and under"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:224
+msgid "Unrecoverable protocol error."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:113
-msgid "Average Age"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:252
+msgid "Profile unavailable."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:115
-msgid "Known Chatrooms"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:277
+#, php-format
+msgid "%s has received too many connection requests today."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:117
-msgid "Known Tags"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:278
+msgid "Spam protection measures have been invoked."
msgstr ""
-#: ../../extend/addon/addon/dirstats/dirstats.php:119
-msgid ""
-"Please note Diaspora and Friendica statistics are merely those **this "
-"directory** is aware of, and not all those known in the network. This also "
-"applies to chatrooms,"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:279
+msgid "Friends are advised to please try again in 24 hours."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:21
-msgid "Project Servers and Resources"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:341
+msgid "Invalid locator"
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:22
-msgid "Project Creator and Tech Lead"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:350
+msgid "Invalid email address."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:23
-msgid "Admin, developer, directorymin, support bloke"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:377
+msgid "This account has not been configured for email. Request failed."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:50
-msgid ""
-"And the hundreds of other people and organisations who helped make the "
-"Hubzilla possible."
+#: ../../extend/addon/addon/friendica/dfrn_request.php:473
+msgid "Unable to resolve your name at the provided location."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:53
-msgid ""
-"The Redmatrix/Hubzilla projects are provided primarily by volunteers giving "
-"their time and expertise - and often paying out of pocket for services they "
-"share with others."
+#: ../../extend/addon/addon/friendica/dfrn_request.php:486
+msgid "You have already introduced yourself here."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:54
-msgid ""
-"There is no corporate funding and no ads, and we do not collect and sell "
-"your personal information. (We don't control your personal information - "
-"you do.)"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:490
+#, php-format
+msgid "Apparently you are already friends with %s."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:55
-msgid ""
-"Help support our ground-breaking work in decentralisation, web identity, and "
-"privacy."
+#: ../../extend/addon/addon/friendica/dfrn_request.php:511
+msgid "Invalid profile URL."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:57
-msgid ""
-"Your donations keep servers and services running and also helps us to "
-"provide innovative new features and continued development."
+#: ../../extend/addon/addon/friendica/dfrn_request.php:517
+msgid "Disallowed profile URL."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:60
-msgid "Donate"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:587
+msgid "Failed to update contact record."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:62
-msgid ""
-"Choose a project, developer, or public hub to support with a one-time "
-"donation"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:608
+msgid "Your introduction has been sent."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:63
-msgid "Donate Now"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:662
+msgid "Please login to confirm introduction."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:64
+#: ../../extend/addon/addon/friendica/dfrn_request.php:676
msgid ""
-"Or become a project sponsor (Hubzilla Project only)"
+"Incorrect identity currently logged in. Please login to this"
+"strong> profile."
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:65
-msgid ""
-"Please indicate if you would like your first name or full name (or nothing) "
-"to appear in our sponsor listing"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:690
+#: ../../extend/addon/addon/friendica/dfrn_request.php:707
+msgid "Confirm"
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:66
-msgid "Sponsor"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:702
+msgid "Hide this contact"
msgstr ""
-#: ../../extend/addon/addon/donate/donate.php:69
-msgid "Special thanks to: "
+#: ../../extend/addon/addon/friendica/dfrn_request.php:705
+#, php-format
+msgid "Welcome home %s."
msgstr ""
-#: ../../extend/addon/addon/dwpost/dwpost.php:42
-msgid "Post to Dreamwidth"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:706
+#, php-format
+msgid "Please confirm your introduction/connection request to %s."
msgstr ""
-#: ../../extend/addon/addon/dwpost/dwpost.php:73
-msgid "Enable Dreamwidth Post Plugin"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:836
+msgid ""
+"Please enter your 'Identity Address' from one of the following supported "
+"communications networks:"
msgstr ""
-#: ../../extend/addon/addon/dwpost/dwpost.php:77
-msgid "Dreamwidth username"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:857
+#, php-format
+msgid ""
+"If you are not yet a member of the free social web, follow this link to find a public Friendica site and join us today."
msgstr ""
-#: ../../extend/addon/addon/dwpost/dwpost.php:81
-msgid "Dreamwidth password"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:862
+msgid "Friend/Connection Request"
msgstr ""
-#: ../../extend/addon/addon/dwpost/dwpost.php:85
-msgid "Post to Dreamwidth by default"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:863
+msgid ""
+"Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, "
+"testuser@identi.ca"
msgstr ""
-#: ../../extend/addon/addon/dwpost/dwpost.php:89
-msgid "Dreamwidth Post Settings"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:864
+msgid "Please answer the following:"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:45
-msgid "Flattr this!"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:865
+#, php-format
+msgid "Does %s know you?"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:83
-msgid "Flattr widget settings updated."
+#: ../../extend/addon/addon/friendica/dfrn_request.php:869
+msgid "Add a personal note:"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:100
-msgid "Flattr user"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:871
+#: ../../include/network.php:1744 ../../include/network.php:1745
+msgid "Friendica"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:104
-msgid "URL of the Thing to flattr"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:872
+msgid "StatusNet/Federated Social Web"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:104
-msgid "If empty channel URL is used"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:873
+#: ../../include/network.php:1750
+msgid "Diaspora"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:108
-msgid "Title of the Thing to flattr"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:874
+#, php-format
+msgid ""
+" - please do not use this form. Instead, enter %s into your Diaspora search "
+"bar."
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:108
-msgid "If empty \"channel name on The Hubzilla\" will be used"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:875
+msgid "Your Identity Address:"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:112
-msgid "Static or dynamic flattr button"
+#: ../../extend/addon/addon/friendica/dfrn_request.php:878
+msgid "Submit Request"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:112
-msgid "static"
+#: ../../extend/addon/addon/friendica/friendica.php:113
+#: ../../extend/addon/addon/gnusoc/gnusoc.php:118
+msgid "GNU-Social Protocol Settings updated."
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:112
-msgid "dynamic"
+#: ../../extend/addon/addon/friendica/friendica.php:124
+msgid "Enable the (experimental) GNU-Social protocol for this channel"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:116
-msgid "Alignment of the widget"
+#: ../../extend/addon/addon/friendica/friendica.php:128
+#: ../../extend/addon/addon/gnusoc/gnusoc.php:133
+msgid "GNU-Social Protocol Settings"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:116
-msgid "left"
+#: ../../extend/addon/addon/friendica/friendica.php:185
+#: ../../extend/addon/addon/gnusoc/gnusoc.php:323
+msgid "Follow"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:116
-msgid "right"
+#: ../../extend/addon/addon/friendica/friendica.php:188
+#: ../../extend/addon/addon/gnusoc/gnusoc.php:326
+#, php-format
+msgid "%1$s is now following %2$s"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:120
-msgid "Enable Flattr widget"
+#: ../../extend/addon/addon/frphotos/frphotos.php:91
+msgid "Friendica Photo Album Import"
msgstr ""
-#: ../../extend/addon/addon/flattrwidget/flattrwidget.php:124
-msgid "Flattr Widget Settings"
+#: ../../extend/addon/addon/frphotos/frphotos.php:92
+msgid "This will import all your Friendica photo albums to this Red channel."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:118
-msgid "Contact not found."
+#: ../../extend/addon/addon/frphotos/frphotos.php:93
+msgid "Friendica Server base URL"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:119
-msgid ""
-"This may occasionally happen if contact was requested by both persons and it "
-"has already been approved."
+#: ../../extend/addon/addon/frphotos/frphotos.php:94
+msgid "Friendica Login Username"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:238
-msgid "Response from remote site was not understood."
+#: ../../extend/addon/addon/frphotos/frphotos.php:95
+msgid "Friendica Login Password"
+msgstr ""
+
+#: ../../extend/addon/addon/hubwall/hubwall.php:19
+msgid "Send email to all members"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:247
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:252
-msgid "Unexpected response from remote site: "
+#: ../../extend/addon/addon/hubwall/hubwall.php:33
+#, php-format
+msgid "$1%s Administrator"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:261
-msgid "Confirmation completed successfully."
+#: ../../extend/addon/addon/hubwall/hubwall.php:50
+#: ../../extend/addon/addon/mailtest/mailtest.php:50
+msgid "No recipients found."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:263
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:277
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:284
-msgid "Remote site reported: "
+#: ../../extend/addon/addon/hubwall/hubwall.php:73
+#, php-format
+msgid "%1$d of %2$d messages sent."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:275
-msgid "Temporary failure. Please wait and try again."
+#: ../../extend/addon/addon/hubwall/hubwall.php:81
+msgid "Send email to all hub members."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:282
-msgid "Introduction failed or was revoked."
+#: ../../extend/addon/addon/hubwall/hubwall.php:92
+#: ../../extend/addon/addon/mailtest/mailtest.php:96
+msgid "Message subject"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:428
-msgid "Unable to set contact photo."
+#: ../../extend/addon/addon/hubwall/hubwall.php:93
+msgid "Sender Email address"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:485
-#, php-format
-msgid "%1$s is now friends with %2$s"
+#: ../../extend/addon/addon/hubwall/hubwall.php:94
+msgid "Test mode (only send to hub administrator)"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:570
-#, php-format
-msgid "No user record found for '%s' "
+#: ../../extend/addon/addon/ijpost/ijpost.php:42
+msgid "Post to Insanejournal"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:580
-msgid "Our site encryption key is apparently messed up."
+#: ../../extend/addon/addon/ijpost/ijpost.php:73
+msgid "Enable InsaneJournal Post Plugin"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:591
-msgid "Empty site URL was provided or URL could not be decrypted by us."
+#: ../../extend/addon/addon/ijpost/ijpost.php:77
+msgid "InsaneJournal username"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:612
-msgid "Contact record was not found for you on our site."
+#: ../../extend/addon/addon/ijpost/ijpost.php:81
+msgid "InsaneJournal password"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:626
-#, php-format
-msgid "Site public key not available in contact record for URL %s."
+#: ../../extend/addon/addon/ijpost/ijpost.php:85
+msgid "Post to InsaneJournal by default"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:646
-msgid ""
-"The ID provided by your system is a duplicate on our system. It should work "
-"if you try again."
+#: ../../extend/addon/addon/ijpost/ijpost.php:89
+msgid "InsaneJournal Post Settings"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:657
-msgid "Unable to set your contact credentials on our system."
+#: ../../extend/addon/addon/ijpost/ijpost.php:104
+msgid "Insane Journal Settings saved."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:724
-msgid "Unable to update your contact profile details on our system"
+#: ../../extend/addon/addon/irc/irc.php:45
+msgid "Channels to auto connect"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:751
-#: ../../extend/addon/addon/friendica/dfrn_request.php:749
-msgid "[Name Withheld]"
+#: ../../extend/addon/addon/irc/irc.php:45
+#: ../../extend/addon/addon/irc/irc.php:49
+msgid "Comma separated list"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_confirm.php:796
-#, php-format
-msgid "%1$s has joined %2$s"
+#: ../../extend/addon/addon/irc/irc.php:49
+#: ../../extend/addon/addon/irc/irc.php:96
+msgid "Popular Channels"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_poll.php:103
-#: ../../extend/addon/addon/friendica/dfrn_poll.php:536
-#, php-format
-msgid "%1$s welcomes %2$s"
+#: ../../extend/addon/addon/irc/irc.php:53
+msgid "IRC Settings"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:102
-msgid "This introduction has already been accepted."
+#: ../../extend/addon/addon/irc/irc.php:69
+msgid "IRC settings saved."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:123
-#: ../../extend/addon/addon/friendica/dfrn_request.php:528
-msgid "Profile location is not valid or does not contain profile information."
+#: ../../extend/addon/addon/irc/irc.php:74
+msgid "IRC Chatroom"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:128
-#: ../../extend/addon/addon/friendica/dfrn_request.php:533
-msgid "Warning: profile location has no identifiable owner name."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:305
+#: ../../include/channel.php:1139 ../../include/channel.php:1301
+msgid "Status:"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:130
-#: ../../extend/addon/addon/friendica/dfrn_request.php:535
-msgid "Warning: profile location has no profile photo."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:309
+msgid "Activate addon"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:133
-#: ../../extend/addon/addon/friendica/dfrn_request.php:538
-#, php-format
-msgid "%d required parameter was not found at the given location"
-msgid_plural "%d required parameters were not found at the given location"
-msgstr[0] ""
-msgstr[1] ""
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:313
+msgid "Hide Jappixmini Chat-Widget from the webinterface"
+msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:180
-msgid "Introduction complete."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:318
+msgid "Jabber username"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:224
-msgid "Unrecoverable protocol error."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:324
+msgid "Jabber server"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:252
-msgid "Profile unavailable."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:330
+msgid "Jabber BOSH host URL"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:277
-#, php-format
-msgid "%s has received too many connection requests today."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:337
+msgid "Jabber password"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:278
-msgid "Spam protection measures have been invoked."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:343
+msgid "Encrypt Jabber password with Hubzilla password"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:279
-msgid "Friends are advised to please try again in 24 hours."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:347
+#: ../../extend/addon/addon/redred/redred.php:115
+msgid "Hubzilla password"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:341
-msgid "Invalid locator"
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:351
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:355
+msgid "Approve subscription requests from Hubzilla contacts automatically"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:350
-msgid "Invalid email address."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:359
+msgid "Purge internal list of jabber addresses of contacts"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:377
-msgid "This account has not been configured for email. Request failed."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:364
+msgid "Configuration Help"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:473
-msgid "Unable to resolve your name at the provided location."
+#: ../../extend/addon/addon/jappixmini/jappixmini.php:371
+msgid "Jappix Mini Settings"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:486
-msgid "You have already introduced yourself here."
+#: ../../extend/addon/addon/js_upload/js_upload.php:44
+msgid "Upload a file"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:490
-#, php-format
-msgid "Apparently you are already friends with %s."
+#: ../../extend/addon/addon/js_upload/js_upload.php:45
+msgid "Drop files here to upload"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:511
-msgid "Invalid profile URL."
+#: ../../extend/addon/addon/js_upload/js_upload.php:47
+msgid "Failed"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:517
-msgid "Disallowed profile URL."
+#: ../../extend/addon/addon/js_upload/js_upload.php:315
+msgid "No files were uploaded."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:587
-msgid "Failed to update contact record."
+#: ../../extend/addon/addon/js_upload/js_upload.php:322
+msgid "Uploaded file is empty"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:608
-msgid "Your introduction has been sent."
+#: ../../extend/addon/addon/js_upload/js_upload.php:335
+msgid "Image exceeds size limit of "
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:662
-msgid "Please login to confirm introduction."
+#: ../../extend/addon/addon/js_upload/js_upload.php:347
+msgid "File has an invalid extension, it should be one of "
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:676
-msgid ""
-"Incorrect identity currently logged in. Please login to this"
-"strong> profile."
+#: ../../extend/addon/addon/js_upload/js_upload.php:359
+msgid "Upload was cancelled, or server error encountered"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:690
-#: ../../extend/addon/addon/friendica/dfrn_request.php:707
-msgid "Confirm"
+#: ../../extend/addon/addon/ldapauth/ldapauth.php:61
+msgid "An account has been created for you."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:702
-msgid "Hide this contact"
+#: ../../extend/addon/addon/ldapauth/ldapauth.php:68
+msgid "Authentication successful but rejected: account creation is disabled."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:705
-#, php-format
-msgid "Welcome home %s."
+#: ../../extend/addon/addon/libertree/libertree.php:38
+msgid "Post to Libertree"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:706
-#, php-format
-msgid "Please confirm your introduction/connection request to %s."
+#: ../../extend/addon/addon/libertree/libertree.php:69
+msgid "Enable Libertree Post Plugin"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:836
-msgid ""
-"Please enter your 'Identity Address' from one of the following supported "
-"communications networks:"
+#: ../../extend/addon/addon/libertree/libertree.php:73
+msgid "Libertree API token"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:857
-#, php-format
-msgid ""
-"If you are not yet a member of the free social web, follow this link to find a public Friendica site and join us today."
+#: ../../extend/addon/addon/libertree/libertree.php:77
+msgid "Libertree site URL"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:862
-msgid "Friend/Connection Request"
+#: ../../extend/addon/addon/libertree/libertree.php:81
+msgid "Post to Libertree by default"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:863
-msgid ""
-"Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, "
-"testuser@identi.ca"
+#: ../../extend/addon/addon/libertree/libertree.php:85
+msgid "Libertree Post Settings"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:864
-msgid "Please answer the following:"
+#: ../../extend/addon/addon/libertree/libertree.php:99
+msgid "Libertree Settings saved."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:865
-#, php-format
-msgid "Does %s know you?"
+#: ../../extend/addon/addon/ljpost/ljpost.php:42
+msgid "Post to LiveJournal"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:869
-msgid "Add a personal note:"
+#: ../../extend/addon/addon/ljpost/ljpost.php:70
+msgid "Enable LiveJournal Post Plugin"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:871
-#: ../../include/network.php:2265 ../../include/network.php:2266
-msgid "Friendica"
+#: ../../extend/addon/addon/ljpost/ljpost.php:74
+msgid "LiveJournal username"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:872
-msgid "StatusNet/Federated Social Web"
+#: ../../extend/addon/addon/ljpost/ljpost.php:78
+msgid "LiveJournal password"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:873
-#: ../../include/network.php:2271
-msgid "Diaspora"
+#: ../../extend/addon/addon/ljpost/ljpost.php:82
+msgid "Post to LiveJournal by default"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:874
-#, php-format
-msgid ""
-" - please do not use this form. Instead, enter %s into your Diaspora search "
-"bar."
+#: ../../extend/addon/addon/ljpost/ljpost.php:86
+msgid "LiveJournal Post Settings"
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:875
-msgid "Your Identity Address:"
+#: ../../extend/addon/addon/ljpost/ljpost.php:101
+msgid "LiveJournal Settings saved."
msgstr ""
-#: ../../extend/addon/addon/friendica/dfrn_request.php:878
-msgid "Submit Request"
+#: ../../extend/addon/addon/logrot/logrot.php:36
+msgid "Logfile archive directory"
msgstr ""
-#: ../../extend/addon/addon/friendica/friendica.php:113
-#: ../../extend/addon/addon/gnusoc/gnusoc.php:118
-msgid "GNU-Social Protocol Settings updated."
+#: ../../extend/addon/addon/logrot/logrot.php:36
+msgid "Directory to store rotated logs"
msgstr ""
-#: ../../extend/addon/addon/friendica/friendica.php:124
-msgid "Enable the (experimental) GNU-Social protocol for this channel"
+#: ../../extend/addon/addon/logrot/logrot.php:37
+msgid "Logfile size in bytes before rotating"
msgstr ""
-#: ../../extend/addon/addon/friendica/friendica.php:128
-#: ../../extend/addon/addon/gnusoc/gnusoc.php:133
-msgid "GNU-Social Protocol Settings"
+#: ../../extend/addon/addon/logrot/logrot.php:38
+msgid "Number of logfiles to retain"
msgstr ""
-#: ../../extend/addon/addon/friendica/friendica.php:185
-#: ../../extend/addon/addon/gnusoc/gnusoc.php:323
-msgid "Follow"
+#: ../../extend/addon/addon/mailhost/mailhost.php:36
+msgid "Email notification hub"
msgstr ""
-#: ../../extend/addon/addon/friendica/friendica.php:188
-#: ../../extend/addon/addon/gnusoc/gnusoc.php:326
-#, php-format
-msgid "%1$s is now following %2$s"
+#: ../../extend/addon/addon/mailhost/mailhost.php:36
+msgid "Hostname"
msgstr ""
-#: ../../extend/addon/addon/frphotos/frphotos.php:91
-msgid "Friendica Photo Album Import"
+#: ../../extend/addon/addon/mailhost/mailhost.php:40
+msgid "Mailhost Settings"
msgstr ""
-#: ../../extend/addon/addon/frphotos/frphotos.php:92
-msgid "This will import all your Friendica photo albums to this Red channel."
+#: ../../extend/addon/addon/mailhost/mailhost.php:54
+msgid "MAILHOST Settings saved."
msgstr ""
-#: ../../extend/addon/addon/frphotos/frphotos.php:93
-msgid "Friendica Server base URL"
+#: ../../extend/addon/addon/moremoods/moremoods.php:19
+msgid "lonely"
msgstr ""
-#: ../../extend/addon/addon/frphotos/frphotos.php:94
-msgid "Friendica Login Username"
+#: ../../extend/addon/addon/moremoods/moremoods.php:20
+msgid "drunk"
msgstr ""
-#: ../../extend/addon/addon/frphotos/frphotos.php:95
-msgid "Friendica Login Password"
+#: ../../extend/addon/addon/moremoods/moremoods.php:21
+msgid "horny"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:19
-msgid "Send email to all members"
+#: ../../extend/addon/addon/moremoods/moremoods.php:22
+msgid "stoned"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:33
-#, php-format
-msgid "$1%s Administrator"
+#: ../../extend/addon/addon/moremoods/moremoods.php:23
+msgid "fucked up"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:50
-#: ../../extend/addon/addon/mailtest/mailtest.php:50
-msgid "No recipients found."
+#: ../../extend/addon/addon/moremoods/moremoods.php:24
+msgid "clusterfucked"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:73
-#, php-format
-msgid "%1$d of %2$d messages sent."
+#: ../../extend/addon/addon/moremoods/moremoods.php:25
+msgid "crazy"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:81
-msgid "Send email to all hub members."
+#: ../../extend/addon/addon/moremoods/moremoods.php:26
+msgid "hurt"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:92
-#: ../../extend/addon/addon/mailtest/mailtest.php:96
-msgid "Message subject"
+#: ../../extend/addon/addon/moremoods/moremoods.php:27
+msgid "sleepy"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:93
-msgid "Sender Email address"
+#: ../../extend/addon/addon/moremoods/moremoods.php:28
+msgid "grumpy"
msgstr ""
-#: ../../extend/addon/addon/hubwall/hubwall.php:94
-msgid "Test mode (only send to hub administrator)"
+#: ../../extend/addon/addon/moremoods/moremoods.php:29
+msgid "high"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:42
-msgid "Post to Insanejournal"
+#: ../../extend/addon/addon/moremoods/moremoods.php:30
+msgid "semi-conscious"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:73
-msgid "Enable InsaneJournal Post Plugin"
+#: ../../extend/addon/addon/moremoods/moremoods.php:31
+msgid "in love"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:77
-msgid "InsaneJournal username"
+#: ../../extend/addon/addon/moremoods/moremoods.php:32
+msgid "in lust"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:81
-msgid "InsaneJournal password"
+#: ../../extend/addon/addon/moremoods/moremoods.php:33
+msgid "naked"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:85
-msgid "Post to InsaneJournal by default"
+#: ../../extend/addon/addon/moremoods/moremoods.php:34
+msgid "stinky"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:89
-msgid "InsaneJournal Post Settings"
+#: ../../extend/addon/addon/moremoods/moremoods.php:35
+msgid "sweaty"
msgstr ""
-#: ../../extend/addon/addon/ijpost/ijpost.php:104
-msgid "Insane Journal Settings saved."
+#: ../../extend/addon/addon/moremoods/moremoods.php:36
+msgid "bleeding out"
msgstr ""
-#: ../../extend/addon/addon/irc/irc.php:45
-msgid "Channels to auto connect"
+#: ../../extend/addon/addon/moremoods/moremoods.php:37
+msgid "victorious"
msgstr ""
-#: ../../extend/addon/addon/irc/irc.php:45
-#: ../../extend/addon/addon/irc/irc.php:49
-msgid "Comma separated list"
+#: ../../extend/addon/addon/moremoods/moremoods.php:38
+msgid "defeated"
msgstr ""
-#: ../../extend/addon/addon/irc/irc.php:49
-#: ../../extend/addon/addon/irc/irc.php:96
-msgid "Popular Channels"
+#: ../../extend/addon/addon/moremoods/moremoods.php:39
+msgid "envious"
msgstr ""
-#: ../../extend/addon/addon/irc/irc.php:53
-msgid "IRC Settings"
+#: ../../extend/addon/addon/moremoods/moremoods.php:40
+msgid "jealous"
msgstr ""
-#: ../../extend/addon/addon/irc/irc.php:69
-msgid "IRC settings saved."
+#: ../../extend/addon/addon/morepokes/morepokes.php:19
+msgid "bitchslap"
msgstr ""
-#: ../../extend/addon/addon/irc/irc.php:74
-msgid "IRC Chatroom"
+#: ../../extend/addon/addon/morepokes/morepokes.php:19
+msgid "bitchslapped"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:305
-#: ../../include/channel.php:1139 ../../include/channel.php:1301
-msgid "Status:"
+#: ../../extend/addon/addon/morepokes/morepokes.php:20
+msgid "shag"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:309
-msgid "Activate addon"
+#: ../../extend/addon/addon/morepokes/morepokes.php:20
+msgid "shagged"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:313
-msgid "Hide Jappixmini Chat-Widget from the webinterface"
+#: ../../extend/addon/addon/morepokes/morepokes.php:21
+msgid "patent"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:318
-msgid "Jabber username"
+#: ../../extend/addon/addon/morepokes/morepokes.php:21
+msgid "patented"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:324
-msgid "Jabber server"
+#: ../../extend/addon/addon/morepokes/morepokes.php:22
+msgid "hug"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:330
-msgid "Jabber BOSH host URL"
+#: ../../extend/addon/addon/morepokes/morepokes.php:22
+msgid "hugged"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:337
-msgid "Jabber password"
+#: ../../extend/addon/addon/morepokes/morepokes.php:23
+msgid "murder"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:343
-msgid "Encrypt Jabber password with Hubzilla password"
+#: ../../extend/addon/addon/morepokes/morepokes.php:23
+msgid "murdered"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:347
-#: ../../extend/addon/addon/redred/redred.php:115
-msgid "Hubzilla password"
+#: ../../extend/addon/addon/morepokes/morepokes.php:24
+msgid "worship"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:351
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:355
-msgid "Approve subscription requests from Hubzilla contacts automatically"
+#: ../../extend/addon/addon/morepokes/morepokes.php:24
+msgid "worshipped"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:359
-msgid "Purge internal list of jabber addresses of contacts"
+#: ../../extend/addon/addon/morepokes/morepokes.php:25
+msgid "kiss"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:364
-msgid "Configuration Help"
+#: ../../extend/addon/addon/morepokes/morepokes.php:25
+msgid "kissed"
msgstr ""
-#: ../../extend/addon/addon/jappixmini/jappixmini.php:371
-msgid "Jappix Mini Settings"
+#: ../../extend/addon/addon/morepokes/morepokes.php:26
+msgid "tempt"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:44
-msgid "Upload a file"
+#: ../../extend/addon/addon/morepokes/morepokes.php:26
+msgid "tempted"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:45
-msgid "Drop files here to upload"
+#: ../../extend/addon/addon/morepokes/morepokes.php:27
+msgid "raise eyebrows at"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:47
-msgid "Failed"
+#: ../../extend/addon/addon/morepokes/morepokes.php:27
+msgid "raised their eyebrows at"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:315
-msgid "No files were uploaded."
+#: ../../extend/addon/addon/morepokes/morepokes.php:28
+msgid "insult"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:322
-msgid "Uploaded file is empty"
+#: ../../extend/addon/addon/morepokes/morepokes.php:28
+msgid "insulted"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:335
-msgid "Image exceeds size limit of "
+#: ../../extend/addon/addon/morepokes/morepokes.php:29
+msgid "praise"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:347
-msgid "File has an invalid extension, it should be one of "
+#: ../../extend/addon/addon/morepokes/morepokes.php:29
+msgid "praised"
msgstr ""
-#: ../../extend/addon/addon/js_upload/js_upload.php:359
-msgid "Upload was cancelled, or server error encountered"
+#: ../../extend/addon/addon/morepokes/morepokes.php:30
+msgid "be dubious of"
msgstr ""
-#: ../../extend/addon/addon/ldapauth/ldapauth.php:61
-msgid "An account has been created for you."
+#: ../../extend/addon/addon/morepokes/morepokes.php:30
+msgid "was dubious of"
msgstr ""
-#: ../../extend/addon/addon/ldapauth/ldapauth.php:68
-msgid "Authentication successful but rejected: account creation is disabled."
+#: ../../extend/addon/addon/morepokes/morepokes.php:31
+msgid "eat"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:38
-msgid "Post to Libertree"
+#: ../../extend/addon/addon/morepokes/morepokes.php:31
+msgid "ate"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:69
-msgid "Enable Libertree Post Plugin"
+#: ../../extend/addon/addon/morepokes/morepokes.php:32
+msgid "giggle and fawn at"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:73
-msgid "Libertree API token"
+#: ../../extend/addon/addon/morepokes/morepokes.php:32
+msgid "giggled and fawned at"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:77
-msgid "Libertree site URL"
+#: ../../extend/addon/addon/morepokes/morepokes.php:33
+msgid "doubt"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:81
-msgid "Post to Libertree by default"
+#: ../../extend/addon/addon/morepokes/morepokes.php:33
+msgid "doubted"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:85
-msgid "Libertree Post Settings"
+#: ../../extend/addon/addon/morepokes/morepokes.php:34
+msgid "glare"
msgstr ""
-#: ../../extend/addon/addon/libertree/libertree.php:99
-msgid "Libertree Settings saved."
+#: ../../extend/addon/addon/morepokes/morepokes.php:34
+msgid "glared at"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:42
-msgid "Post to LiveJournal"
+#: ../../extend/addon/addon/morepokes/morepokes.php:35
+msgid "fuck"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:70
-msgid "Enable LiveJournal Post Plugin"
+#: ../../extend/addon/addon/morepokes/morepokes.php:35
+msgid "fucked"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:74
-msgid "LiveJournal username"
+#: ../../extend/addon/addon/morepokes/morepokes.php:36
+msgid "bonk"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:78
-msgid "LiveJournal password"
+#: ../../extend/addon/addon/morepokes/morepokes.php:36
+msgid "bonked"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:82
-msgid "Post to LiveJournal by default"
+#: ../../extend/addon/addon/morepokes/morepokes.php:37
+msgid "declare undying love for"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:86
-msgid "LiveJournal Post Settings"
+#: ../../extend/addon/addon/morepokes/morepokes.php:37
+msgid "declared undying love for"
msgstr ""
-#: ../../extend/addon/addon/ljpost/ljpost.php:101
-msgid "LiveJournal Settings saved."
+#: ../../extend/addon/addon/msgfooter/msgfooter.php:46
+#: ../../extend/addon/addon/xmpp/xmpp.php:91
+msgid "Save Settings"
msgstr ""
-#: ../../extend/addon/addon/logrot/logrot.php:36
-msgid "Logfile archive directory"
+#: ../../extend/addon/addon/msgfooter/msgfooter.php:47
+msgid "text to include in all outgoing posts from this site"
msgstr ""
-#: ../../extend/addon/addon/logrot/logrot.php:36
-msgid "Directory to store rotated logs"
+#: ../../extend/addon/addon/nofed/nofed.php:42
+msgid "Federate"
msgstr ""
-#: ../../extend/addon/addon/logrot/logrot.php:37
-msgid "Logfile size in bytes before rotating"
+#: ../../extend/addon/addon/nofed/nofed.php:56
+msgid "nofed Settings saved."
msgstr ""
-#: ../../extend/addon/addon/logrot/logrot.php:38
-msgid "Number of logfiles to retain"
+#: ../../extend/addon/addon/nofed/nofed.php:72
+msgid "Allow Federation Toggle"
msgstr ""
-#: ../../extend/addon/addon/mailhost/mailhost.php:36
-msgid "Email notification hub"
+#: ../../extend/addon/addon/nofed/nofed.php:76
+msgid "Federate posts by default"
msgstr ""
-#: ../../extend/addon/addon/mailhost/mailhost.php:36
-msgid "Hostname"
+#: ../../extend/addon/addon/nofed/nofed.php:80
+msgid "NoFed Settings"
msgstr ""
-#: ../../extend/addon/addon/mailhost/mailhost.php:40
-msgid "Mailhost Settings"
+#: ../../extend/addon/addon/nsabait/nsabait.php:125
+msgid "Nsabait Settings updated."
msgstr ""
-#: ../../extend/addon/addon/mailhost/mailhost.php:54
-msgid "MAILHOST Settings saved."
+#: ../../extend/addon/addon/nsabait/nsabait.php:157
+msgid "Enable NSAbait Plugin"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:19
-msgid "lonely"
+#: ../../extend/addon/addon/nsabait/nsabait.php:161
+msgid "NSAbait Settings"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:20
-msgid "drunk"
+#: ../../extend/addon/addon/nsfw/nsfw.php:80
+msgid ""
+"This plugin looks in posts for the words/text you specify below, and "
+"collapses any content containing those keywords so it is not displayed at "
+"inappropriate times, such as sexual innuendo that may be improper in a work "
+"setting. It is polite and recommended to tag any content containing nudity "
+"with #NSFW. This filter can also match any other word/text you specify, and "
+"can thereby be used as a general purpose content filter."
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:21
-msgid "horny"
+#: ../../extend/addon/addon/nsfw/nsfw.php:84
+msgid "Enable Content filter"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:22
-msgid "stoned"
+#: ../../extend/addon/addon/nsfw/nsfw.php:88
+msgid "Comma separated list of keywords to hide"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:23
-msgid "fucked up"
+#: ../../extend/addon/addon/nsfw/nsfw.php:88
+msgid "Word, /regular-expression/, lang=xx, lang!=xx"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:24
-msgid "clusterfucked"
+#: ../../extend/addon/addon/nsfw/nsfw.php:92
+msgid "Not Safe For Work Settings"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:25
-msgid "crazy"
+#: ../../extend/addon/addon/nsfw/nsfw.php:92
+msgid "General Purpose Content Filter"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:26
-msgid "hurt"
+#: ../../extend/addon/addon/nsfw/nsfw.php:110
+msgid "NSFW Settings saved."
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:27
-msgid "sleepy"
+#: ../../extend/addon/addon/nsfw/nsfw.php:207
+msgid "Possible adult content"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:28
-msgid "grumpy"
+#: ../../extend/addon/addon/nsfw/nsfw.php:211
+#, php-format
+msgid "%s - view"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:29
-msgid "high"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:50
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:128
+msgid "System defaults:"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:30
-msgid "semi-conscious"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:54
+msgid "Preferred Clipart IDs"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:31
-msgid "in love"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:54
+msgid "List of preferred clipart ids. These will be shown first."
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:32
-msgid "in lust"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:55
+msgid "Default Search Term"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:33
-msgid "naked"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:55
+msgid "The default search term. These will be shown second."
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:34
-msgid "stinky"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:56
+msgid "Return After"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:35
-msgid "sweaty"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:56
+msgid "Page to load after image selection."
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:36
-msgid "bleeding out"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:58
+#: ../../include/channel.php:1048 ../../include/nav.php:107
+msgid "Edit Profile"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:37
-msgid "victorious"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:59
+msgid "Profile List"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:38
-msgid "defeated"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:61
+msgid "Order of Preferred"
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:39
-msgid "envious"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:61
+msgid "Sort order of preferred clipart ids."
msgstr ""
-#: ../../extend/addon/addon/moremoods/moremoods.php:40
-msgid "jealous"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:62
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:68
+msgid "Newest first"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:19
-msgid "bitchslap"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:65
+msgid "As entered"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:19
-msgid "bitchslapped"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:67
+msgid "Order of other"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:20
-msgid "shag"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:67
+msgid "Sort order of other clipart ids."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:20
-msgid "shagged"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:69
+msgid "Most downloaded first"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:21
-msgid "patent"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:70
+msgid "Most liked first"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:21
-msgid "patented"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:72
+msgid "Preferred IDs Message"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:22
-msgid "hug"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:72
+msgid "Message to display above preferred results."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:22
-msgid "hugged"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:78
+msgid "Uploaded by: "
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:23
-msgid "murder"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:78
+msgid "Drawn by: "
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:23
-msgid "murdered"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:192
+msgid "Or select from a free OpenClipart.org image:"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:24
-msgid "worship"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:195
+msgid "Search Term"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:24
-msgid "worshipped"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:232
+msgid "Unknown error. Please try again later."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:25
-msgid "kiss"
+#: ../../extend/addon/addon/openclipatar/openclipatar.php:308
+msgid "Profile photo updated successfully."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:25
-msgid "kissed"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:146
+msgid "View Larger"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:26
-msgid "tempt"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:169
+msgid "Tile Server URL"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:26
-msgid "tempted"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:169
+msgid ""
+"A list of public tile servers"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:27
-msgid "raise eyebrows at"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:170
+msgid "Nominatim (reverse geocoding) Server URL"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:27
-msgid "raised their eyebrows at"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:170
+msgid ""
+"A list of Nominatim servers"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:28
-msgid "insult"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:171
+msgid "Default zoom"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:28
-msgid "insulted"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:171
+msgid ""
+"The default zoom level. (1:world, 18:highest, also depends on tile server)"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:29
-msgid "praise"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:172
+msgid "Include marker on map"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:29
-msgid "praised"
+#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:172
+msgid "Include a marker on the map."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:30
-msgid "be dubious of"
+#: ../../extend/addon/addon/pageheader/pageheader.php:43
+msgid "Message to display on every page on this server"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:30
-msgid "was dubious of"
+#: ../../extend/addon/addon/pageheader/pageheader.php:48
+msgid "Pageheader Settings"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:31
-msgid "eat"
+#: ../../extend/addon/addon/pageheader/pageheader.php:64
+msgid "pageheader Settings saved."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:31
-msgid "ate"
+#: ../../extend/addon/addon/piwik/piwik.php:85
+msgid ""
+"This website is tracked using the Piwik "
+"analytics tool."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:32
-msgid "giggle and fawn at"
+#: ../../extend/addon/addon/piwik/piwik.php:88
+#, php-format
+msgid ""
+"If you do not want that your visits are logged this way you can "
+"set a cookie to prevent Piwik from tracking further visits of the site "
+"(opt-out)."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:32
-msgid "giggled and fawned at"
+#: ../../extend/addon/addon/piwik/piwik.php:96
+msgid "Piwik Base URL"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:33
-msgid "doubt"
+#: ../../extend/addon/addon/piwik/piwik.php:96
+msgid ""
+"Absolute path to your Piwik installation. (without protocol (http/s), with "
+"trailing slash)"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:33
-msgid "doubted"
+#: ../../extend/addon/addon/piwik/piwik.php:97
+msgid "Site ID"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:34
-msgid "glare"
+#: ../../extend/addon/addon/piwik/piwik.php:98
+msgid "Show opt-out cookie link?"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:34
-msgid "glared at"
+#: ../../extend/addon/addon/piwik/piwik.php:99
+msgid "Asynchronous tracking"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:35
-msgid "fuck"
+#: ../../extend/addon/addon/piwik/piwik.php:100
+msgid "Enable frontend JavaScript error tracking"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:35
-msgid "fucked"
+#: ../../extend/addon/addon/piwik/piwik.php:100
+msgid "This feature requires Piwik >= 2.2.0"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:36
-msgid "bonk"
+#: ../../extend/addon/addon/planets/planets.php:121
+msgid "Planets Settings updated."
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:36
-msgid "bonked"
+#: ../../extend/addon/addon/planets/planets.php:153
+msgid "Enable Planets Plugin"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:37
-msgid "declare undying love for"
+#: ../../extend/addon/addon/planets/planets.php:157
+msgid "Planets Settings"
msgstr ""
-#: ../../extend/addon/addon/morepokes/morepokes.php:37
-msgid "declared undying love for"
+#: ../../extend/addon/addon/pumpio/pumpio.php:148
+msgid "You are now authenticated to pumpio."
msgstr ""
-#: ../../extend/addon/addon/msgfooter/msgfooter.php:46
-#: ../../extend/addon/addon/xmpp/xmpp.php:91
-msgid "Save Settings"
+#: ../../extend/addon/addon/pumpio/pumpio.php:149
+msgid "return to the featured settings page"
msgstr ""
-#: ../../extend/addon/addon/msgfooter/msgfooter.php:47
-msgid "text to include in all outgoing posts from this site"
+#: ../../extend/addon/addon/pumpio/pumpio.php:163
+msgid "Post to Pump.io"
msgstr ""
-#: ../../extend/addon/addon/nofed/nofed.php:42
-msgid "Federate"
+#: ../../extend/addon/addon/pumpio/pumpio.php:198
+msgid "Pump.io servername"
msgstr ""
-#: ../../extend/addon/addon/nofed/nofed.php:56
-msgid "nofed Settings saved."
+#: ../../extend/addon/addon/pumpio/pumpio.php:198
+msgid "Without \"http://\" or \"https://\""
msgstr ""
-#: ../../extend/addon/addon/nofed/nofed.php:72
-msgid "Allow Federation Toggle"
+#: ../../extend/addon/addon/pumpio/pumpio.php:202
+msgid "Pump.io username"
msgstr ""
-#: ../../extend/addon/addon/nofed/nofed.php:76
-msgid "Federate posts by default"
+#: ../../extend/addon/addon/pumpio/pumpio.php:202
+msgid "Without the servername"
msgstr ""
-#: ../../extend/addon/addon/nofed/nofed.php:80
-msgid "NoFed Settings"
+#: ../../extend/addon/addon/pumpio/pumpio.php:213
+msgid "You are not authenticated to pumpio"
msgstr ""
-#: ../../extend/addon/addon/nsabait/nsabait.php:125
-msgid "Nsabait Settings updated."
+#: ../../extend/addon/addon/pumpio/pumpio.php:215
+msgid "(Re-)Authenticate your pump.io connection"
msgstr ""
-#: ../../extend/addon/addon/nsabait/nsabait.php:157
-msgid "Enable NSAbait Plugin"
+#: ../../extend/addon/addon/pumpio/pumpio.php:219
+msgid "Enable pump.io Post Plugin"
msgstr ""
-#: ../../extend/addon/addon/nsabait/nsabait.php:161
-msgid "NSAbait Settings"
+#: ../../extend/addon/addon/pumpio/pumpio.php:223
+msgid "Post to pump.io by default"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:80
-msgid ""
-"This plugin looks in posts for the words/text you specify below, and "
-"collapses any content containing those keywords so it is not displayed at "
-"inappropriate times, such as sexual innuendo that may be improper in a work "
-"setting. It is polite and recommended to tag any content containing nudity "
-"with #NSFW. This filter can also match any other word/text you specify, and "
-"can thereby be used as a general purpose content filter."
+#: ../../extend/addon/addon/pumpio/pumpio.php:227
+msgid "Should posts be public"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:84
-msgid "Enable Content filter"
+#: ../../extend/addon/addon/pumpio/pumpio.php:231
+msgid "Mirror all public posts"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:88
-msgid "Comma separated list of keywords to hide"
+#: ../../extend/addon/addon/pumpio/pumpio.php:237
+msgid "Pump.io Post Settings"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:88
-msgid "Word, /regular-expression/, lang=xx, lang!=xx"
+#: ../../extend/addon/addon/pumpio/pumpio.php:266
+msgid "PumpIO Settings saved."
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:92
-msgid "Not Safe For Work Settings"
+#: ../../extend/addon/addon/qrator/qrator.php:48
+msgid "QR code"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:92
-msgid "General Purpose Content Filter"
+#: ../../extend/addon/addon/qrator/qrator.php:63
+msgid "QR Generator"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:110
-msgid "NSFW Settings saved."
+#: ../../extend/addon/addon/qrator/qrator.php:64
+msgid "Enter some text"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:207
-msgid "Possible adult content"
+#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:81
+msgid "Enable Rainbowtag"
msgstr ""
-#: ../../extend/addon/addon/nsfw/nsfw.php:211
-#, php-format
-msgid "%s - view"
+#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:85
+msgid "Rainbowtag Settings"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:50
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:128
-msgid "System defaults:"
+#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:101
+msgid "Rainbowtag Settings saved."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:54
-msgid "Preferred Clipart IDs"
+#: ../../extend/addon/addon/randpost/randpost.php:97
+msgid "You're welcome."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:54
-msgid "List of preferred clipart ids. These will be shown first."
+#: ../../extend/addon/addon/randpost/randpost.php:98
+msgid "Ah shucks..."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:55
-msgid "Default Search Term"
+#: ../../extend/addon/addon/randpost/randpost.php:99
+msgid "Don't mention it."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:55
-msgid "The default search term. These will be shown second."
+#: ../../extend/addon/addon/randpost/randpost.php:100
+msgid "<blush>"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:56
-msgid "Return After"
+#: ../../extend/addon/addon/redfiles/redfiles.php:119
+msgid "Redmatrix File Storage Import"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:56
-msgid "Page to load after image selection."
+#: ../../extend/addon/addon/redfiles/redfiles.php:120
+msgid "This will import all your Redmatrix cloud files to this channel."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:58
-#: ../../include/nav.php:107 ../../include/channel.php:1048
-msgid "Edit Profile"
+#: ../../extend/addon/addon/redfiles/redfiles.php:121
+#: ../../extend/addon/addon/redphotos/redphotos.php:131
+msgid "Redmatrix Server base URL"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:59
-msgid "Profile List"
+#: ../../extend/addon/addon/redfiles/redfiles.php:122
+#: ../../extend/addon/addon/redphotos/redphotos.php:132
+msgid "Redmatrix Login Username"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:61
-msgid "Order of Preferred"
+#: ../../extend/addon/addon/redfiles/redfiles.php:123
+#: ../../extend/addon/addon/redphotos/redphotos.php:133
+msgid "Redmatrix Login Password"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:61
-msgid "Sort order of preferred clipart ids."
+#: ../../extend/addon/addon/redfiles/redfilehelper.php:67
+msgid "file"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:62
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:68
-msgid "Newest first"
+#: ../../extend/addon/addon/redphotos/redphotos.php:106
+msgid "Photos imported"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:65
-msgid "As entered"
+#: ../../extend/addon/addon/redphotos/redphotos.php:129
+msgid "Redmatrix Photo Album Import"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:67
-msgid "Order of other"
+#: ../../extend/addon/addon/redphotos/redphotos.php:130
+msgid "This will import all your Redmatrix photo albums to this channel."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:67
-msgid "Sort order of other clipart ids."
+#: ../../extend/addon/addon/redphotos/redphotos.php:134
+msgid "Import just this album"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:69
-msgid "Most downloaded first"
+#: ../../extend/addon/addon/redphotos/redphotos.php:134
+msgid "Leave blank to import all albums"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:70
-msgid "Most liked first"
+#: ../../extend/addon/addon/redphotos/redphotos.php:135
+msgid "Maximum count to import"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:72
-msgid "Preferred IDs Message"
+#: ../../extend/addon/addon/redphotos/redphotos.php:135
+msgid "0 or blank to import all available"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:72
-msgid "Message to display above preferred results."
+#: ../../extend/addon/addon/redred/redred.php:45
+msgid "Post to Red"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:78
-msgid "Uploaded by: "
+#: ../../extend/addon/addon/redred/redred.php:60
+msgid "Channel is required."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:78
-msgid "Drawn by: "
+#: ../../extend/addon/addon/redred/redred.php:76
+msgid "redred Settings saved."
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:192
-msgid "Or select from a free OpenClipart.org image:"
+#: ../../extend/addon/addon/redred/redred.php:95
+msgid "Allow posting to another Hubzilla Channel"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:195
-msgid "Search Term"
+#: ../../extend/addon/addon/redred/redred.php:99
+msgid "Send public postings to Hubzilla channel by default"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:232
-msgid "Unknown error. Please try again later."
+#: ../../extend/addon/addon/redred/redred.php:103
+msgid "Hubzilla API Path"
msgstr ""
-#: ../../extend/addon/addon/openclipatar/openclipatar.php:308
-msgid "Profile photo updated successfully."
+#: ../../extend/addon/addon/redred/redred.php:103
+#: ../../extend/addon/addon/rtof/rtof.php:89
+msgid "https://{sitename}/api"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:146
-msgid "View Larger"
+#: ../../extend/addon/addon/redred/redred.php:107
+msgid "Hubzilla login name"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:169
-msgid "Tile Server URL"
+#: ../../extend/addon/addon/redred/redred.php:111
+msgid "Hubzilla channel name"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:169
-msgid ""
-"A list of public tile servers"
+#: ../../extend/addon/addon/redred/redred.php:111
+#: ../../extend/addon/addon/openid/MysqlProvider.php:54
+msgid "Nickname"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:170
-msgid "Nominatim (reverse geocoding) Server URL"
+#: ../../extend/addon/addon/redred/redred.php:119
+msgid "Hubzilla Crosspost Settings"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:170
-msgid ""
-"A list of Nominatim servers"
+#: ../../extend/addon/addon/rtof/rtof.php:45
+msgid "Post to Friendica"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:171
-msgid "Default zoom"
+#: ../../extend/addon/addon/rtof/rtof.php:62
+msgid "rtof Settings saved."
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:171
-msgid ""
-"The default zoom level. (1:world, 18:highest, also depends on tile server)"
+#: ../../extend/addon/addon/rtof/rtof.php:81
+msgid "Allow posting to Friendica"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:172
-msgid "Include marker on map"
+#: ../../extend/addon/addon/rtof/rtof.php:85
+msgid "Send public postings to Friendica by default"
msgstr ""
-#: ../../extend/addon/addon/openstreetmap/openstreetmap.php:172
-msgid "Include a marker on the map."
+#: ../../extend/addon/addon/rtof/rtof.php:89
+msgid "Friendica API Path"
msgstr ""
-#: ../../extend/addon/addon/pageheader/pageheader.php:43
-msgid "Message to display on every page on this server"
+#: ../../extend/addon/addon/rtof/rtof.php:93
+msgid "Friendica login name"
msgstr ""
-#: ../../extend/addon/addon/pageheader/pageheader.php:48
-msgid "Pageheader Settings"
+#: ../../extend/addon/addon/rtof/rtof.php:97
+msgid "Friendica password"
msgstr ""
-#: ../../extend/addon/addon/pageheader/pageheader.php:64
-msgid "pageheader Settings saved."
+#: ../../extend/addon/addon/rtof/rtof.php:101
+msgid "Hubzilla to Friendica Post Settings"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:85
-msgid ""
-"This website is tracked using the Piwik "
-"analytics tool."
+#: ../../extend/addon/addon/sendzid/sendzid.php:25
+msgid "Extended Identity Sharing"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:88
-#, php-format
+#: ../../extend/addon/addon/sendzid/sendzid.php:26
msgid ""
-"If you do not want that your visits are logged this way you can "
-"set a cookie to prevent Piwik from tracking further visits of the site "
-"(opt-out)."
+"Share your identity with all websites on the internet. When disabled, "
+"identity is only shared with sites in the matrix."
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:96
-msgid "Piwik Base URL"
+#: ../../extend/addon/addon/skeleton/skeleton.php:59
+msgid "Some setting"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:96
-msgid ""
-"Absolute path to your Piwik installation. (without protocol (http/s), with "
-"trailing slash)"
+#: ../../extend/addon/addon/skeleton/skeleton.php:61
+msgid "A setting"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:97
-msgid "Site ID"
+#: ../../extend/addon/addon/skeleton/skeleton.php:64
+msgid "Skeleton Settings"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:98
-msgid "Show opt-out cookie link?"
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:273
+msgid "Deactivate the feature"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:99
-msgid "Asynchronous tracking"
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:277
+msgid "Hide the button and show the smilies directly."
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:100
-msgid "Enable frontend JavaScript error tracking"
+#: ../../extend/addon/addon/smileybutton/smileybutton.php:281
+msgid "Smileybutton Settings"
msgstr ""
-#: ../../extend/addon/addon/piwik/piwik.php:100
-msgid "This feature requires Piwik >= 2.2.0"
+#: ../../extend/addon/addon/startpage/startpage.php:109
+msgid "Page to load after login"
msgstr ""
-#: ../../extend/addon/addon/planets/planets.php:121
-msgid "Planets Settings updated."
+#: ../../extend/addon/addon/startpage/startpage.php:109
+msgid ""
+"Examples: "apps", "network?f=&gid=37" (privacy "
+"collection), "channel" or "notifications/system" (leave "
+"blank for default network page (grid)."
msgstr ""
-#: ../../extend/addon/addon/planets/planets.php:153
-msgid "Enable Planets Plugin"
+#: ../../extend/addon/addon/startpage/startpage.php:113
+msgid "Startpage Settings"
msgstr ""
-#: ../../extend/addon/addon/planets/planets.php:157
-msgid "Planets Settings"
+#: ../../extend/addon/addon/statusnet/statusnet.php:143
+msgid "Post to GNU social"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:148
-msgid "You are now authenticated to pumpio."
+#: ../../extend/addon/addon/statusnet/statusnet.php:195
+msgid ""
+"Please contact your site administrator. The provided API URL is not "
+"valid."
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:149
-msgid "return to the featured settings page"
+#: ../../extend/addon/addon/statusnet/statusnet.php:232
+msgid "We could not contact the GNU social API with the Path you entered."
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:163
-msgid "Post to Pump.io"
+#: ../../extend/addon/addon/statusnet/statusnet.php:266
+msgid "GNU social settings updated."
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:198
-msgid "Pump.io servername"
+#: ../../extend/addon/addon/statusnet/statusnet.php:310
+msgid "Globally Available GNU social OAuthKeys"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:198
-msgid "Without \"http://\" or \"https://\""
+#: ../../extend/addon/addon/statusnet/statusnet.php:312
+msgid ""
+"There are preconfigured OAuth key pairs for some GNU social servers "
+"available. If you are using one of them, please use these credentials. If not feel free to connect to any other GNU social instance (see below)."
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:202
-msgid "Pump.io username"
+#: ../../extend/addon/addon/statusnet/statusnet.php:327
+msgid "Provide your own OAuth Credentials"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:202
-msgid "Without the servername"
+#: ../../extend/addon/addon/statusnet/statusnet.php:329
+msgid ""
+"No consumer key pair for GNU social found. Register your Hubzilla Account as "
+"an desktop client on your GNU social account, copy the consumer key pair "
+"here and enter the API base root. Before you register your own OAuth "
+"key pair ask the administrator if there is already a key pair for this "
+"Hubzilla installation at your favourite GNU social installation."
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:213
-msgid "You are not authenticated to pumpio"
+#: ../../extend/addon/addon/statusnet/statusnet.php:333
+msgid "OAuth Consumer Key"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:215
-msgid "(Re-)Authenticate your pump.io connection"
+#: ../../extend/addon/addon/statusnet/statusnet.php:337
+msgid "OAuth Consumer Secret"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:219
-msgid "Enable pump.io Post Plugin"
+#: ../../extend/addon/addon/statusnet/statusnet.php:341
+msgid "Base API Path"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:223
-msgid "Post to pump.io by default"
+#: ../../extend/addon/addon/statusnet/statusnet.php:341
+msgid "Remember the trailing /"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:227
-msgid "Should posts be public"
+#: ../../extend/addon/addon/statusnet/statusnet.php:345
+msgid "GNU social application name"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:231
-msgid "Mirror all public posts"
+#: ../../extend/addon/addon/statusnet/statusnet.php:368
+msgid ""
+"To connect to your GNU social account click the button below to get a "
+"security code from GNU social which you have to copy into the input box "
+"below and submit the form. Only your public posts will be "
+"posted to GNU social."
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:237
-msgid "Pump.io Post Settings"
+#: ../../extend/addon/addon/statusnet/statusnet.php:370
+msgid "Log in with GNU social"
msgstr ""
-#: ../../extend/addon/addon/pumpio/pumpio.php:266
-msgid "PumpIO Settings saved."
+#: ../../extend/addon/addon/statusnet/statusnet.php:373
+msgid "Copy the security code from GNU social here"
msgstr ""
-#: ../../extend/addon/addon/qrator/qrator.php:48
-msgid "QR code"
+#: ../../extend/addon/addon/statusnet/statusnet.php:383
+msgid "Cancel Connection Process"
msgstr ""
-#: ../../extend/addon/addon/qrator/qrator.php:63
-msgid "QR Generator"
+#: ../../extend/addon/addon/statusnet/statusnet.php:385
+msgid "Current GNU social API is"
msgstr ""
-#: ../../extend/addon/addon/qrator/qrator.php:64
-msgid "Enter some text"
+#: ../../extend/addon/addon/statusnet/statusnet.php:389
+msgid "Cancel GNU social Connection"
msgstr ""
-#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:81
-msgid "Enable Rainbowtag"
+#: ../../extend/addon/addon/statusnet/statusnet.php:401
+#: ../../extend/addon/addon/twitter/twitter.php:232
+msgid "Currently connected to: "
msgstr ""
-#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:85
-msgid "Rainbowtag Settings"
+#: ../../extend/addon/addon/statusnet/statusnet.php:406
+msgid ""
+"Note: Due your privacy settings (Hide your profile "
+"details from unknown viewers?) the link potentially included in public "
+"postings relayed to GNU social will lead the visitor to a blank page "
+"informing the visitor that the access to your profile has been restricted."
msgstr ""
-#: ../../extend/addon/addon/rainbowtag/rainbowtag.php:101
-msgid "Rainbowtag Settings saved."
+#: ../../extend/addon/addon/statusnet/statusnet.php:411
+msgid "Allow posting to GNU social"
msgstr ""
-#: ../../extend/addon/addon/randpost/randpost.php:97
-msgid "You're welcome."
+#: ../../extend/addon/addon/statusnet/statusnet.php:411
+msgid ""
+"If enabled your public postings can be posted to the associated GNU-social "
+"account"
msgstr ""
-#: ../../extend/addon/addon/randpost/randpost.php:98
-msgid "Ah shucks..."
+#: ../../extend/addon/addon/statusnet/statusnet.php:415
+msgid "Post to GNU social by default"
msgstr ""
-#: ../../extend/addon/addon/randpost/randpost.php:99
-msgid "Don't mention it."
+#: ../../extend/addon/addon/statusnet/statusnet.php:415
+msgid ""
+"If enabled your public postings will be posted to the associated GNU-social "
+"account by default"
msgstr ""
-#: ../../extend/addon/addon/randpost/randpost.php:100
-msgid "<blush>"
+#: ../../extend/addon/addon/statusnet/statusnet.php:424
+#: ../../extend/addon/addon/twitter/twitter.php:255
+msgid "Clear OAuth configuration"
msgstr ""
-#: ../../extend/addon/addon/redfiles/redfiles.php:119
-msgid "Redmatrix File Storage Import"
+#: ../../extend/addon/addon/statusnet/statusnet.php:432
+msgid "GNU social Post Settings"
msgstr ""
-#: ../../extend/addon/addon/redfiles/redfiles.php:120
-msgid "This will import all your Redmatrix cloud files to this channel."
+#: ../../extend/addon/addon/statusnet/statusnet.php:891
+msgid "API URL"
msgstr ""
-#: ../../extend/addon/addon/redfiles/redfiles.php:121
-#: ../../extend/addon/addon/redphotos/redphotos.php:131
-msgid "Redmatrix Server base URL"
+#: ../../extend/addon/addon/statusnet/statusnet.php:894
+msgid "Application name"
msgstr ""
-#: ../../extend/addon/addon/redfiles/redfiles.php:122
-#: ../../extend/addon/addon/redphotos/redphotos.php:132
-msgid "Redmatrix Login Username"
+#: ../../extend/addon/addon/superblock/superblock.php:112
+msgid "Currently blocked"
msgstr ""
-#: ../../extend/addon/addon/redfiles/redfiles.php:123
-#: ../../extend/addon/addon/redphotos/redphotos.php:133
-msgid "Redmatrix Login Password"
+#: ../../extend/addon/addon/superblock/superblock.php:114
+msgid "No channels currently blocked"
msgstr ""
-#: ../../extend/addon/addon/redfiles/redfilehelper.php:67
-msgid "file"
+#: ../../extend/addon/addon/superblock/superblock.php:120
+msgid "\"Superblock\" Settings"
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:106
-msgid "Photos imported"
+#: ../../extend/addon/addon/superblock/superblock.php:345
+msgid "Block Completely"
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:129
-msgid "Redmatrix Photo Album Import"
+#: ../../extend/addon/addon/superblock/superblock.php:394
+msgid "superblock settings updated"
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:130
-msgid "This will import all your Redmatrix photo albums to this channel."
+#: ../../extend/addon/addon/testdrive/testdrive.php:104
+#, php-format
+msgid "Your account on %s will expire in a few days."
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:134
-msgid "Import just this album"
+#: ../../extend/addon/addon/testdrive/testdrive.php:105
+msgid "Your $Productname test account is about to expire."
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:134
-msgid "Leave blank to import all albums"
+#: ../../extend/addon/addon/tictac/tictac.php:21
+msgid "Three Dimensional Tic-Tac-Toe"
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:135
-msgid "Maximum count to import"
+#: ../../extend/addon/addon/tictac/tictac.php:54
+msgid "3D Tic-Tac-Toe"
msgstr ""
-#: ../../extend/addon/addon/redphotos/redphotos.php:135
-msgid "0 or blank to import all available"
+#: ../../extend/addon/addon/tictac/tictac.php:59
+msgid "New game"
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:45
-msgid "Post to Red"
+#: ../../extend/addon/addon/tictac/tictac.php:60
+msgid "New game with handicap"
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:60
-msgid "Channel is required."
+#: ../../extend/addon/addon/tictac/tictac.php:61
+msgid ""
+"Three dimensional tic-tac-toe is just like the traditional game except that "
+"it is played on multiple levels simultaneously. "
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:76
-msgid "redred Settings saved."
+#: ../../extend/addon/addon/tictac/tictac.php:62
+msgid ""
+"In this case there are three levels. You win by getting three in a row on "
+"any level, as well as up, down, and diagonally across the different levels."
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:95
-msgid "Allow posting to another Hubzilla Channel"
+#: ../../extend/addon/addon/tictac/tictac.php:64
+msgid ""
+"The handicap game disables the center position on the middle level because "
+"the player claiming this square often has an unfair advantage."
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:99
-msgid "Send public postings to Hubzilla channel by default"
+#: ../../extend/addon/addon/tictac/tictac.php:183
+msgid "You go first..."
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:103
-msgid "Hubzilla API Path"
+#: ../../extend/addon/addon/tictac/tictac.php:188
+msgid "I'm going first this time..."
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:103
-#: ../../extend/addon/addon/rtof/rtof.php:89
-msgid "https://{sitename}/api"
+#: ../../extend/addon/addon/tictac/tictac.php:194
+msgid "You won!"
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:107
-msgid "Hubzilla login name"
+#: ../../extend/addon/addon/tictac/tictac.php:200
+#: ../../extend/addon/addon/tictac/tictac.php:225
+msgid "\"Cat\" game!"
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:111
-msgid "Hubzilla channel name"
+#: ../../extend/addon/addon/tictac/tictac.php:223
+msgid "I won!"
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:111
-#: ../../extend/addon/addon/openid/MysqlProvider.php:54
-msgid "Nickname"
+#: ../../extend/addon/addon/tour/tour.php:75
+msgid "Edit your profile and change settings."
msgstr ""
-#: ../../extend/addon/addon/redred/redred.php:119
-msgid "Hubzilla Crosspost Settings"
+#: ../../extend/addon/addon/tour/tour.php:76
+msgid "Click here to see activity from your connections."
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:45
-msgid "Post to Friendica"
+#: ../../extend/addon/addon/tour/tour.php:77
+msgid "Click here to see your channel home."
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:62
-msgid "rtof Settings saved."
+#: ../../extend/addon/addon/tour/tour.php:78
+msgid "You can access your private messages from here."
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:81
-msgid "Allow posting to Friendica"
+#: ../../extend/addon/addon/tour/tour.php:79
+msgid "Create new events here."
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:85
-msgid "Send public postings to Friendica by default"
+#: ../../extend/addon/addon/tour/tour.php:80
+msgid ""
+"You can accept new connections and change permissions for existing ones "
+"here. You can also e.g. create groups of contacts."
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:89
-msgid "Friendica API Path"
+#: ../../extend/addon/addon/tour/tour.php:81
+msgid "System notifications will arrive here"
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:93
-msgid "Friendica login name"
+#: ../../extend/addon/addon/tour/tour.php:82
+msgid "Search for content and users"
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:97
-msgid "Friendica password"
+#: ../../extend/addon/addon/tour/tour.php:83
+msgid "Browse for new contacts"
msgstr ""
-#: ../../extend/addon/addon/rtof/rtof.php:101
-msgid "Hubzilla to Friendica Post Settings"
+#: ../../extend/addon/addon/tour/tour.php:84
+msgid "Launch installed apps"
msgstr ""
-#: ../../extend/addon/addon/sendzid/sendzid.php:25
-msgid "Extended Identity Sharing"
+#: ../../extend/addon/addon/tour/tour.php:85
+msgid "Looking for help? Click here."
msgstr ""
-#: ../../extend/addon/addon/sendzid/sendzid.php:26
+#: ../../extend/addon/addon/tour/tour.php:86
msgid ""
-"Share your identity with all websites on the internet. When disabled, "
-"identity is only shared with sites in the matrix."
+"New events have occurred in your network. Click here to see what has "
+"happened!"
msgstr ""
-#: ../../extend/addon/addon/skeleton/skeleton.php:59
-msgid "Some setting"
+#: ../../extend/addon/addon/tour/tour.php:87
+msgid "You have received a new private message. Click here to see from who!"
msgstr ""
-#: ../../extend/addon/addon/skeleton/skeleton.php:61
-msgid "A setting"
+#: ../../extend/addon/addon/tour/tour.php:88
+msgid "There are events this week. Click here too see which!"
msgstr ""
-#: ../../extend/addon/addon/skeleton/skeleton.php:64
-msgid "Skeleton Settings"
+#: ../../extend/addon/addon/tour/tour.php:89
+msgid "You have received a new introduction. Click here to see who!"
msgstr ""
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:273
-msgid "Deactivate the feature"
+#: ../../extend/addon/addon/tour/tour.php:90
+msgid ""
+"There is a new system notification. Click here to see what has happened!"
msgstr ""
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:277
-msgid "Hide the button and show the smilies directly."
+#: ../../extend/addon/addon/tour/tour.php:93
+msgid "Click here to share text, images, videos and sound."
msgstr ""
-#: ../../extend/addon/addon/smileybutton/smileybutton.php:281
-msgid "Smileybutton Settings"
+#: ../../extend/addon/addon/tour/tour.php:94
+msgid "You can write an optional title for your update (good for long posts)."
msgstr ""
-#: ../../extend/addon/addon/startpage/startpage.php:109
-msgid "Page to load after login"
+#: ../../extend/addon/addon/tour/tour.php:95
+msgid "Entering some categories here makes it easier to find your post later."
msgstr ""
-#: ../../extend/addon/addon/startpage/startpage.php:109
-msgid ""
-"Examples: "apps", "network?f=&gid=37" (privacy "
-"collection), "channel" or "notifications/system" (leave "
-"blank for default network page (grid)."
+#: ../../extend/addon/addon/tour/tour.php:96
+msgid "Share photos, links, location, etc."
msgstr ""
-#: ../../extend/addon/addon/startpage/startpage.php:113
-msgid "Startpage Settings"
+#: ../../extend/addon/addon/tour/tour.php:97
+msgid ""
+"Only want to share content for a while? Make it expire at a certain date."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:143
-msgid "Post to GNU social"
+#: ../../extend/addon/addon/tour/tour.php:98
+msgid "You can password protect content."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:195
-msgid ""
-"Please contact your site administrator. The provided API URL is not "
-"valid."
+#: ../../extend/addon/addon/tour/tour.php:99
+msgid "Choose who you share with."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:232
-msgid "We could not contact the GNU social API with the Path you entered."
+#: ../../extend/addon/addon/tour/tour.php:101
+msgid "Click here when you are done."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:266
-msgid "GNU social settings updated."
+#: ../../extend/addon/addon/tour/tour.php:104
+msgid "Adjust from which channels posts should be displayed."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:310
-msgid "Globally Available GNU social OAuthKeys"
+#: ../../extend/addon/addon/tour/tour.php:105
+msgid "Only show posts from channels in the specified privacy group."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:312
+#: ../../extend/addon/addon/tour/tour.php:109
msgid ""
-"There are preconfigured OAuth key pairs for some GNU social servers "
-"available. If you are using one of them, please use these credentials. If not feel free to connect to any other GNU social instance (see below)."
+"Easily find posts containing tags (keywords preceded by the \"#\" symbol)."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:327
-msgid "Provide your own OAuth Credentials"
+#: ../../extend/addon/addon/tour/tour.php:110
+msgid "Easily find posts in given category."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:329
-msgid ""
-"No consumer key pair for GNU social found. Register your Hubzilla Account as "
-"an desktop client on your GNU social account, copy the consumer key pair "
-"here and enter the API base root. Before you register your own OAuth "
-"key pair ask the administrator if there is already a key pair for this "
-"Hubzilla installation at your favourite GNU social installation."
+#: ../../extend/addon/addon/tour/tour.php:111
+msgid "Easily find posts by date."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:333
-msgid "OAuth Consumer Key"
+#: ../../extend/addon/addon/tour/tour.php:112
+msgid ""
+"Suggested users who have volounteered to be shown as suggestions, and who we "
+"think you might find interesting."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:337
-msgid "OAuth Consumer Secret"
+#: ../../extend/addon/addon/tour/tour.php:113
+msgid "Here you see channels you have connected to."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:341
-msgid "Base API Path"
+#: ../../extend/addon/addon/tour/tour.php:114
+msgid "Save your search so you can repeat it at a later date."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:341
-msgid "Remember the trailing /"
+#: ../../extend/addon/addon/tour/tour.php:117
+msgid ""
+"If you see this icon you can be sure that the sender is who it say it is. It "
+"is normal that it is not always possible to verify the sender, so the icon "
+"will be missing sometimes. There is usually no need to worry about that."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:345
-msgid "GNU social application name"
+#: ../../extend/addon/addon/tour/tour.php:118
+msgid ""
+"Danger! It seems someone tried to forge a message! This message is not "
+"necessarily from who it says it is from!"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:368
+#: ../../extend/addon/addon/tour/tour.php:125
msgid ""
-"To connect to your GNU social account click the button below to get a "
-"security code from GNU social which you have to copy into the input box "
-"below and submit the form. Only your public posts will be "
-"posted to GNU social."
+"Welcome to Hubzilla! Would you like to see a tour of the UI?
You can "
+"pause it at any time and continue where you left off by reloading the page, "
+"or navigting to another page.
You can also advance by pressing the "
+"return key"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:370
-msgid "Log in with GNU social"
+#: ../../extend/addon/addon/twitter/twitter.php:99
+msgid "Post to Twitter"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:373
-msgid "Copy the security code from GNU social here"
+#: ../../extend/addon/addon/twitter/twitter.php:154
+msgid "Twitter settings updated."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:383
-msgid "Cancel Connection Process"
+#: ../../extend/addon/addon/twitter/twitter.php:183
+msgid ""
+"No consumer key pair for Twitter found. Please contact your site "
+"administrator."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:385
-msgid "Current GNU social API is"
+#: ../../extend/addon/addon/twitter/twitter.php:205
+msgid ""
+"At this Hubzilla instance the Twitter plugin was enabled but you have not "
+"yet connected your account to your Twitter account. To do so click the "
+"button below to get a PIN from Twitter which you have to copy into the input "
+"box below and submit the form. Only your public posts will "
+"be posted to Twitter."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:389
-msgid "Cancel GNU social Connection"
+#: ../../extend/addon/addon/twitter/twitter.php:207
+msgid "Log in with Twitter"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:401
-#: ../../extend/addon/addon/twitter/twitter.php:232
-msgid "Currently connected to: "
+#: ../../extend/addon/addon/twitter/twitter.php:210
+msgid "Copy the PIN from Twitter here"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:406
+#: ../../extend/addon/addon/twitter/twitter.php:237
msgid ""
-"Note: Due your privacy settings (Hide your profile "
+"Note: Due your privacy settings (Hide your profile "
"details from unknown viewers?) the link potentially included in public "
-"postings relayed to GNU social will lead the visitor to a blank page "
-"informing the visitor that the access to your profile has been restricted."
+"postings relayed to Twitter will lead the visitor to a blank page informing "
+"the visitor that the access to your profile has been restricted."
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:411
-msgid "Allow posting to GNU social"
+#: ../../extend/addon/addon/twitter/twitter.php:242
+msgid "Allow posting to Twitter"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:411
+#: ../../extend/addon/addon/twitter/twitter.php:242
msgid ""
-"If enabled your public postings can be posted to the associated GNU-social "
+"If enabled your public postings can be posted to the associated Twitter "
"account"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:415
-msgid "Post to GNU social by default"
+#: ../../extend/addon/addon/twitter/twitter.php:246
+msgid "Send public postings to Twitter by default"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:415
+#: ../../extend/addon/addon/twitter/twitter.php:246
msgid ""
-"If enabled your public postings will be posted to the associated GNU-social "
+"If enabled your public postings will be posted to the associated Twitter "
"account by default"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:424
-#: ../../extend/addon/addon/twitter/twitter.php:255
-msgid "Clear OAuth configuration"
-msgstr ""
-
-#: ../../extend/addon/addon/statusnet/statusnet.php:432
-msgid "GNU social Post Settings"
+#: ../../extend/addon/addon/twitter/twitter.php:264
+msgid "Twitter Post Settings"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:891
-msgid "API URL"
+#: ../../extend/addon/addon/twitter/twitter.php:773
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:95
+msgid "Submit Settings"
msgstr ""
-#: ../../extend/addon/addon/statusnet/statusnet.php:894
-msgid "Application name"
+#: ../../extend/addon/addon/upload_limits/upload_limits.php:25
+msgid "Show Upload Limits"
msgstr ""
-#: ../../extend/addon/addon/superblock/superblock.php:112
-msgid "Currently blocked"
+#: ../../extend/addon/addon/upload_limits/upload_limits.php:27
+msgid "Hubzilla configured maximum size: "
msgstr ""
-#: ../../extend/addon/addon/superblock/superblock.php:114
-msgid "No channels currently blocked"
+#: ../../extend/addon/addon/upload_limits/upload_limits.php:28
+msgid "PHP upload_max_filesize: "
msgstr ""
-#: ../../extend/addon/addon/superblock/superblock.php:120
-msgid "\"Superblock\" Settings"
+#: ../../extend/addon/addon/upload_limits/upload_limits.php:29
+msgid "PHP post_max_size (must be larger than upload_max_filesize): "
msgstr ""
-#: ../../extend/addon/addon/superblock/superblock.php:345
-msgid "Block Completely"
+#: ../../extend/addon/addon/visage/visage.php:93
+msgid "Recent Channel/Profile Viewers"
msgstr ""
-#: ../../extend/addon/addon/superblock/superblock.php:394
-msgid "superblock settings updated"
+#: ../../extend/addon/addon/visage/visage.php:98
+msgid "This plugin/addon has not been configured."
msgstr ""
-#: ../../extend/addon/addon/testdrive/testdrive.php:104
+#: ../../extend/addon/addon/visage/visage.php:99
#, php-format
-msgid "Your account on %s will expire in a few days."
+msgid "Please visit the Visage settings on %s"
msgstr ""
-#: ../../extend/addon/addon/testdrive/testdrive.php:105
-msgid "Your $Productname test account is about to expire."
+#: ../../extend/addon/addon/visage/visage.php:99
+msgid "your feature settings page"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:21
-msgid "Three Dimensional Tic-Tac-Toe"
+#: ../../extend/addon/addon/visage/visage.php:112
+msgid "No entries."
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:54
-msgid "3D Tic-Tac-Toe"
+#: ../../extend/addon/addon/visage/visage.php:166
+msgid "Enable Visage Visitor Logging"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:59
-msgid "New game"
+#: ../../extend/addon/addon/visage/visage.php:170
+msgid "Visage Settings"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:60
-msgid "New game with handicap"
+#: ../../extend/addon/addon/wholikesme/wholikesme.php:29
+msgid "Who likes me?"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:61
-msgid ""
-"Three dimensional tic-tac-toe is just like the traditional game except that "
-"it is played on multiple levels simultaneously. "
+#: ../../extend/addon/addon/wppost/wppost.php:45
+msgid "Post to WordPress"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:62
-msgid ""
-"In this case there are three levels. You win by getting three in a row on "
-"any level, as well as up, down, and diagonally across the different levels."
+#: ../../extend/addon/addon/wppost/wppost.php:82
+msgid "Enable WordPress Post Plugin"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:64
-msgid ""
-"The handicap game disables the center position on the middle level because "
-"the player claiming this square often has an unfair advantage."
+#: ../../extend/addon/addon/wppost/wppost.php:86
+msgid "WordPress username"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:183
-msgid "You go first..."
+#: ../../extend/addon/addon/wppost/wppost.php:90
+msgid "WordPress password"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:188
-msgid "I'm going first this time..."
+#: ../../extend/addon/addon/wppost/wppost.php:94
+msgid "WordPress API URL"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:194
-msgid "You won!"
+#: ../../extend/addon/addon/wppost/wppost.php:95
+msgid "Typically https://your-blog.tld/xmlrpc.php"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:200
-#: ../../extend/addon/addon/tictac/tictac.php:225
-msgid "\"Cat\" game!"
+#: ../../extend/addon/addon/wppost/wppost.php:98
+msgid "WordPress blogid"
msgstr ""
-#: ../../extend/addon/addon/tictac/tictac.php:223
-msgid "I won!"
+#: ../../extend/addon/addon/wppost/wppost.php:99
+msgid "For multi-user sites such as wordpress.com, otherwise leave blank"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:75
-msgid "Edit your profile and change settings."
+#: ../../extend/addon/addon/wppost/wppost.php:105
+msgid "Post to WordPress by default"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:76
-msgid "Click here to see activity from your connections."
+#: ../../extend/addon/addon/wppost/wppost.php:109
+msgid "Forward comments (requires hubzilla_wp plugin)"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:77
-msgid "Click here to see your channel home."
+#: ../../extend/addon/addon/wppost/wppost.php:113
+msgid "WordPress Post Settings"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:78
-msgid "You can access your private messages from here."
+#: ../../extend/addon/addon/wppost/wppost.php:129
+msgid "Wordpress Settings saved."
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:79
-msgid "Create new events here."
+#: ../../extend/addon/addon/xmpp/xmpp.php:31
+msgid "XMPP settings updated."
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:80
-msgid ""
-"You can accept new connections and change permissions for existing ones "
-"here. You can also e.g. create groups of contacts."
+#: ../../extend/addon/addon/xmpp/xmpp.php:53
+msgid "Enable Chat"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:81
-msgid "System notifications will arrive here"
+#: ../../extend/addon/addon/xmpp/xmpp.php:58
+msgid "Individual credentials"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:82
-msgid "Search for content and users"
+#: ../../extend/addon/addon/xmpp/xmpp.php:64
+msgid "Jabber BOSH server"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:83
-msgid "Browse for new contacts"
+#: ../../extend/addon/addon/xmpp/xmpp.php:69
+msgid "XMPP Settings"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:84
-msgid "Launch installed apps"
+#: ../../extend/addon/addon/xmpp/xmpp.php:92
+msgid "Jabber BOSH host"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:85
-msgid "Looking for help? Click here."
+#: ../../extend/addon/addon/xmpp/xmpp.php:93
+msgid "Use central userbase"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:86
+#: ../../extend/addon/addon/xmpp/xmpp.php:93
msgid ""
-"New events have occurred in your network. Click here to see what has "
-"happened!"
+"If enabled, members will automatically login to an ejabberd server that has "
+"to be installed on this machine with synchronized credentials via the "
+"\"auth_ejabberd.php\" script."
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:87
-msgid "You have received a new private message. Click here to see from who!"
+#: ../../extend/addon/addon/cdav/include/widgets.php:37
+msgid "Select Channel"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:88
-msgid "There are events this week. Click here too see which!"
+#: ../../extend/addon/addon/cdav/include/widgets.php:42
+msgid "Read-write"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:89
-msgid "You have received a new introduction. Click here to see who!"
+#: ../../extend/addon/addon/cdav/include/widgets.php:43
+msgid "Read-only"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:90
-msgid ""
-"There is a new system notification. Click here to see what has happened!"
+#: ../../extend/addon/addon/cdav/include/widgets.php:116
+msgid "My Calendars"
+msgstr ""
+
+#: ../../extend/addon/addon/cdav/include/widgets.php:118
+msgid "Shared Calendars"
+msgstr ""
+
+#: ../../extend/addon/addon/cdav/include/widgets.php:122
+msgid "Share this calendar"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:93
-msgid "Click here to share text, images, videos and sound."
+#: ../../extend/addon/addon/cdav/include/widgets.php:124
+msgid "Calendar name and color"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:94
-msgid "You can write an optional title for your update (good for long posts)."
+#: ../../extend/addon/addon/cdav/include/widgets.php:126
+msgid "Create new calendar"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:95
-msgid "Entering some categories here makes it easier to find your post later."
+#: ../../extend/addon/addon/cdav/include/widgets.php:128
+msgid "Calendar Name"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:96
-msgid "Share photos, links, location, etc."
+#: ../../extend/addon/addon/cdav/include/widgets.php:129
+msgid "Calendar Tools"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:97
-msgid ""
-"Only want to share content for a while? Make it expire at a certain date."
+#: ../../extend/addon/addon/cdav/include/widgets.php:130
+msgid "Import calendar"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:98
-msgid "You can password protect content."
+#: ../../extend/addon/addon/cdav/include/widgets.php:131
+msgid "Select a calendar to import to"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:99
-msgid "Choose who you share with."
+#: ../../extend/addon/addon/cdav/include/widgets.php:158
+msgid "Addressbooks"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:101
-msgid "Click here when you are done."
+#: ../../extend/addon/addon/cdav/include/widgets.php:160
+msgid "Addressbook name"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:104
-msgid "Adjust from which channels posts should be displayed."
+#: ../../extend/addon/addon/cdav/include/widgets.php:162
+msgid "Create new addressbook"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:105
-msgid "Only show posts from channels in the specified privacy group."
+#: ../../extend/addon/addon/cdav/include/widgets.php:163
+msgid "Addressbook Name"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:109
-msgid ""
-"Easily find posts containing tags (keywords preceded by the \"#\" symbol)."
+#: ../../extend/addon/addon/cdav/include/widgets.php:165
+msgid "Addressbook Tools"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:110
-msgid "Easily find posts in given category."
+#: ../../extend/addon/addon/cdav/include/widgets.php:166
+msgid "Import addressbook"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:111
-msgid "Easily find posts by date."
+#: ../../extend/addon/addon/cdav/include/widgets.php:167
+msgid "Select an addressbook to import to"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:112
-msgid ""
-"Suggested users who have volounteered to be shown as suggestions, and who we "
-"think you might find interesting."
+#: ../../extend/addon/addon/cdav/cdav.php:36
+msgid "Errors encountered creating database table: "
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:113
-msgid "Here you see channels you have connected to."
+#: ../../extend/addon/addon/cdav/cdav.php:197
+msgid "Default Calendar"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:114
-msgid "Save your search so you can repeat it at a later date."
+#: ../../extend/addon/addon/cdav/cdav.php:206
+msgid "Default Addressbook"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:117
-msgid ""
-"If you see this icon you can be sure that the sender is who it say it is. It "
-"is normal that it is not always possible to verify the sender, so the icon "
-"will be missing sometimes. There is usually no need to worry about that."
+#: ../../extend/addon/addon/cdav/cdav.php:215
+msgid "CalDAV/CardDAV Settings saved."
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:118
-msgid ""
-"Danger! It seems someone tried to forge a message! This message is not "
-"necessarily from who it says it is from!"
+#: ../../extend/addon/addon/cdav/cdav.php:234
+msgid "Enable CalDAV/CardDAV Server for this channel"
msgstr ""
-#: ../../extend/addon/addon/tour/tour.php:125
-msgid ""
-"Welcome to Hubzilla! Would you like to see a tour of the UI?
You can "
-"pause it at any time and continue where you left off by reloading the page, "
-"or navigting to another page.
You can also advance by pressing the "
-"return key"
+#: ../../extend/addon/addon/cdav/cdav.php:237
+#, php-format
+msgid "Your CalDAV resources are located at %s "
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:99
-msgid "Post to Twitter"
+#: ../../extend/addon/addon/cdav/cdav.php:240
+#, php-format
+msgid "Your CardDAV resources are located at %s "
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:154
-msgid "Twitter settings updated."
+#: ../../extend/addon/addon/cdav/cdav.php:246
+msgid "CalDAV/CardDAV Settings"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:183
-msgid ""
-"No consumer key pair for Twitter found. Please contact your site "
-"administrator."
+#: ../../extend/addon/addon/cdav/cdav.php:272
+#: ../../include/connections.php:670
+msgid "Home, Voice"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:205
-msgid ""
-"At this Hubzilla instance the Twitter plugin was enabled but you have not "
-"yet connected your account to your Twitter account. To do so click the "
-"button below to get a PIN from Twitter which you have to copy into the input "
-"box below and submit the form. Only your public posts will "
-"be posted to Twitter."
+#: ../../extend/addon/addon/cdav/cdav.php:273
+#: ../../include/connections.php:671
+msgid "Home, Fax"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:207
-msgid "Log in with Twitter"
+#: ../../extend/addon/addon/cdav/cdav.php:275
+#: ../../include/connections.php:673
+msgid "Work, Voice"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:210
-msgid "Copy the PIN from Twitter here"
+#: ../../extend/addon/addon/cdav/cdav.php:276
+#: ../../include/connections.php:674
+msgid "Work, Fax"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:237
-msgid ""
-"Note: Due your privacy settings (Hide your profile "
-"details from unknown viewers?) the link potentially included in public "
-"postings relayed to Twitter will lead the visitor to a blank page informing "
-"the visitor that the access to your profile has been restricted."
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:744
+msgid "INVALID EVENT DISMISSED!"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:242
-msgid "Allow posting to Twitter"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:745
+msgid "Summary: "
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:242
-msgid ""
-"If enabled your public postings can be posted to the associated Twitter "
-"account"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:746
+msgid "Date: "
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:246
-msgid "Send public postings to Twitter by default"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:747
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:754
+msgid "Reason: "
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:246
-msgid ""
-"If enabled your public postings will be posted to the associated Twitter "
-"account by default"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:752
+msgid "INVALID CARD DISMISSED!"
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:264
-msgid "Twitter Post Settings"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:753
+msgid "Name: "
msgstr ""
-#: ../../extend/addon/addon/twitter/twitter.php:773
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:95
-msgid "Submit Settings"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:770
+msgid ""
+"You have to enable this plugin in Feature/Addon Settings > CalDAV/CardDAV "
+"Settings before you can use it."
msgstr ""
-#: ../../extend/addon/addon/upload_limits/upload_limits.php:25
-msgid "Show Upload Limits"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:836
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:837
+msgid "Example: YYYY-MM-DD HH:mm"
msgstr ""
-#: ../../extend/addon/addon/upload_limits/upload_limits.php:27
-msgid "Hubzilla configured maximum size: "
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:837
+msgid "End date and time"
msgstr ""
-#: ../../extend/addon/addon/upload_limits/upload_limits.php:28
-msgid "PHP upload_max_filesize: "
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:852
+msgid "List month"
msgstr ""
-#: ../../extend/addon/addon/upload_limits/upload_limits.php:29
-msgid "PHP post_max_size (must be larger than upload_max_filesize): "
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:853
+msgid "List week"
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:93
-msgid "Recent Channel/Profile Viewers"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:854
+msgid "List day"
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:98
-msgid "This plugin/addon has not been configured."
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:861
+msgid "More"
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:99
-#, php-format
-msgid "Please visit the Visage settings on %s"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:862
+msgid "Less"
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:99
-msgid "your feature settings page"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:863
+msgid "Select calendar"
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:112
-msgid "No entries."
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:865
+msgid "Delete all"
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:166
-msgid "Enable Visage Visitor Logging"
+#: ../../extend/addon/addon/cdav/Mod_Cdav.php:867
+msgid "Sorry! Editing of recurrent events is not yet implemented."
msgstr ""
-#: ../../extend/addon/addon/visage/visage.php:170
-msgid "Visage Settings"
+#: ../../extend/addon/addon/chess/chess.php:276
+#: ../../extend/addon/addon/chess/chess.php:433
+msgid "Invalid game."
msgstr ""
-#: ../../extend/addon/addon/wholikesme/wholikesme.php:29
-msgid "Who likes me?"
+#: ../../extend/addon/addon/chess/chess.php:282
+#: ../../extend/addon/addon/chess/chess.php:439
+msgid "You are not a player in this game."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:45
-msgid "Post to WordPress"
+#: ../../extend/addon/addon/chess/chess.php:315
+msgid "You must be a local channel to create a game."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:82
-msgid "Enable WordPress Post Plugin"
+#: ../../extend/addon/addon/chess/chess.php:333
+msgid "You must select one opponent that is not yourself."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:86
-msgid "WordPress username"
+#: ../../extend/addon/addon/chess/chess.php:336
+msgid "Creating new game..."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:90
-msgid "WordPress password"
+#: ../../extend/addon/addon/chess/chess.php:342
+msgid "You must select white or black."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:94
-msgid "WordPress API URL"
+#: ../../extend/addon/addon/chess/chess.php:349
+msgid "Error creating new game."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:95
-msgid "Typically https://your-blog.tld/xmlrpc.php"
+#: ../../extend/addon/addon/chess/chess.php:381 ../../include/channel.php:899
+msgid "Requested channel is not available."
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:98
-msgid "WordPress blogid"
+#: ../../extend/addon/addon/chess/chess.php:395
+msgid "You must select a local channel /chess/channelname"
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:99
-msgid "For multi-user sites such as wordpress.com, otherwise leave blank"
+#: ../../extend/addon/addon/chess/chess.php:923
+msgid "Enable notifications"
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:105
-msgid "Post to WordPress by default"
+#: ../../extend/addon/addon/likebanner/likebanner.php:51
+msgid "Your Webbie:"
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:109
-msgid "Forward comments (requires hubzilla_wp plugin)"
+#: ../../extend/addon/addon/likebanner/likebanner.php:54
+msgid "Fontsize (px):"
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:113
-msgid "WordPress Post Settings"
+#: ../../extend/addon/addon/likebanner/likebanner.php:68
+msgid "Link:"
msgstr ""
-#: ../../extend/addon/addon/wppost/wppost.php:129
-msgid "Wordpress Settings saved."
+#: ../../extend/addon/addon/likebanner/likebanner.php:70
+msgid "Like us on Hubzilla"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:31
-msgid "XMPP settings updated."
+#: ../../extend/addon/addon/likebanner/likebanner.php:72
+msgid "Embed:"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:53
-msgid "Enable Chat"
+#: ../../extend/addon/addon/openid/Mod_Id.php:85
+#: ../../include/selectors.php:49 ../../include/selectors.php:66
+msgid "Male"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:58
-msgid "Individual credentials"
+#: ../../extend/addon/addon/openid/Mod_Id.php:87
+#: ../../include/selectors.php:49 ../../include/selectors.php:66
+msgid "Female"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:64
-msgid "Jabber BOSH server"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:52
+msgid "First Name"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:69
-msgid "XMPP Settings"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:53
+msgid "Last Name"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:92
-msgid "Jabber BOSH host"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:55
+msgid "Full Name"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:93
-msgid "Use central userbase"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:61
+msgid "Profile Photo 16px"
msgstr ""
-#: ../../extend/addon/addon/xmpp/xmpp.php:93
-msgid ""
-"If enabled, members will automatically login to an ejabberd server that has "
-"to be installed on this machine with synchronized credentials via the "
-"\"auth_ejabberd.php\" script."
+#: ../../extend/addon/addon/openid/MysqlProvider.php:62
+msgid "Profile Photo 32px"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:37
-msgid "Select Channel"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:63
+msgid "Profile Photo 48px"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:42
-msgid "Read-write"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:64
+msgid "Profile Photo 64px"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:43
-msgid "Read-only"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:65
+msgid "Profile Photo 80px"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:116
-msgid "My Calendars"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:66
+msgid "Profile Photo 128px"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:118
-msgid "Shared Calendars"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:67
+msgid "Timezone"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:122
-msgid "Share this calendar"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:70
+msgid "Birth Year"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:124
-msgid "Calendar name and color"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:71
+msgid "Birth Month"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:126
-msgid "Create new calendar"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:72
+msgid "Birth Day"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:128
-msgid "Calendar Name"
+#: ../../extend/addon/addon/openid/MysqlProvider.php:73
+msgid "Birthdate"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:129
-msgid "Calendar Tools"
+#: ../../extend/addon/addon/openid/openid.php:49
+msgid ""
+"We encountered a problem while logging in with the OpenID you provided. "
+"Please check the correct spelling of the ID."
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:130
-msgid "Import calendar"
+#: ../../extend/addon/addon/openid/openid.php:49
+msgid "The error message was:"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:131
-msgid "Select a calendar to import to"
+#: ../../extend/addon/addon/openid/Mod_Openid.php:30
+msgid "OpenID protocol error. No ID returned."
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:158
-msgid "Addressbooks"
+#: ../../extend/addon/addon/openid/Mod_Openid.php:188
+#: ../../include/auth.php:286
+msgid "Login failed."
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:160
-msgid "Addressbook name"
+#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:44
+#, php-format
+msgid "Reconnecting %d connections"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:162
-msgid "Create new addressbook"
+#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:63
+msgid "Diaspora Reconnect"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:163
-msgid "Addressbook Name"
+#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:65
+msgid ""
+"Use this form to re-establish Diaspora connections which were initially made "
+"from a different hub."
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:165
-msgid "Addressbook Tools"
+#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:70
+msgid "Reconnect"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:166
-msgid "Import addressbook"
+#: ../../extend/addon/addon/mailtest/mailtest.php:19
+msgid "Send test email"
msgstr ""
-#: ../../extend/addon/addon/cdav/include/widgets.php:167
-msgid "Select an addressbook to import to"
+#: ../../extend/addon/addon/mailtest/mailtest.php:66
+msgid "Mail sent."
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:744
-msgid "INVALID EVENT DISMISSED!"
+#: ../../extend/addon/addon/mailtest/mailtest.php:68
+msgid "Sending of mail failed."
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:745
-msgid "Summary: "
+#: ../../extend/addon/addon/mailtest/mailtest.php:77
+msgid "Mail Test"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:746
-msgid "Date: "
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:57
+msgid "Errors encountered deleting database table "
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:747
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:754
-msgid "Reason: "
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:96
+msgid "Drop tables when uninstalling?"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:752
-msgid "INVALID CARD DISMISSED!"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:96
+msgid ""
+"If checked, the Rendezvous database tables will be deleted when the plugin "
+"is uninstalled."
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:753
-msgid "Name: "
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:97
+msgid "Mapbox Access Token"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:770
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:97
msgid ""
-"You have to enable this plugin in Feature/Addon Settings > CalDAV/CardDAV "
-"Settings before you can use it."
+"If you enter a Mapbox access token, it will be used to retrieve map tiles "
+"from Mapbox instead of the default OpenStreetMap tile server."
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:836
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:837
-msgid "Example: YYYY-MM-DD HH:mm"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:162
+msgid "Rendezvous"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:837
-msgid "End date and time"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:167
+msgid ""
+"This identity has been deleted by another member due to inactivity. Please "
+"press the \"New identity\" button or refresh the page to register a new "
+"identity. You may use the same name."
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:852
-msgid "List month"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:168
+msgid "Welcome to Rendezvous!"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:853
-msgid "List week"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:169
+msgid ""
+"Enter your name to join this rendezvous. To begin sharing your location with "
+"the other members, tap the GPS control. When your location is discovered, a "
+"red dot will appear and others will be able to see you on the map."
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:854
-msgid "List day"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:171
+msgid "Let's meet here"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:861
-msgid "More"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:174
+msgid "New marker"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:862
-msgid "Less"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:175
+msgid "Edit marker"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:863
-msgid "Select calendar"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:176
+msgid "New identity"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:865
-msgid "Delete all"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:177
+msgid "Delete marker"
msgstr ""
-#: ../../extend/addon/addon/cdav/Mod_Cdav.php:867
-msgid "Sorry! Editing of recurrent events is not yet implemented."
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:178
+msgid "Delete member"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:36
-msgid "Errors encountered creating database table: "
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:179
+msgid "Edit proximity alert"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:197
-msgid "Default Calendar"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:180
+msgid ""
+"A proximity alert will be issued when this member is within a certain radius "
+"of you.
Enter a radius in meters (0 to disable):"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:206
-msgid "Default Addressbook"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:180
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:185
+msgid "distance"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:215
-msgid "CalDAV/CardDAV Settings saved."
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:181
+msgid "Proximity alert distance (meters)"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:234
-msgid "Enable CalDAV/CardDAV Server for this channel"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:182
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:184
+msgid ""
+"A proximity alert will be issued when you are within a certain radius of the "
+"marker location.
Enter a radius in meters (0 to disable):"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:237
-#, php-format
-msgid "Your CalDAV resources are located at %s "
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:183
+msgid "Marker proximity alert"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:240
-#, php-format
-msgid "Your CardDAV resources are located at %s "
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:186
+msgid "Reminder note"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:246
-msgid "CalDAV/CardDAV Settings"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:187
+msgid ""
+"Enter a note to be displayed when you are within the specified proximity..."
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:272
-#: ../../include/connections.php:670
-msgid "Home, Voice"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:199
+msgid "Add new rendezvous"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:273
-#: ../../include/connections.php:671
-msgid "Home, Fax"
+#: ../../extend/addon/addon/rendezvous/rendezvous.php:200
+msgid ""
+"Create a new rendezvous and share the access link with those you wish to "
+"invite to the group. Those who open the link become members of the "
+"rendezvous. They can view other member locations, add markers to the map, or "
+"share their own locations with the group."
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:275
-#: ../../include/connections.php:673
-msgid "Work, Voice"
+#: ../../extend/addon/addon/firefox/firefox.php:23
+msgid "Install Firefox Sharing Tools"
msgstr ""
-#: ../../extend/addon/addon/cdav/cdav.php:276
-#: ../../include/connections.php:674
-msgid "Work, Fax"
+#: ../../extend/addon/addon/firefox/firefox.php:34
+msgid "Share content from Firefox to $Projectname"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:276
-#: ../../extend/addon/addon/chess/chess.php:433
-msgid "Invalid game."
+#: ../../extend/addon/addon/firefox/firefox.php:37
+msgid "Install Firefox Sharing Tools to this web browser"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:282
-#: ../../extend/addon/addon/chess/chess.php:439
-msgid "You are not a player in this game."
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:105
+msgid "Error retrieving wiki"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:315
-msgid "You must be a local channel to create a game."
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:112
+msgid "Error creating zip file export folder"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:333
-msgid "You must select one opponent that is not yourself."
+#: ../../extend/addon/addon/gitwiki/Mod_Gitwiki.php:130
+msgid "Error downloading wiki: "
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:336
-msgid "Creating new game..."
+#: ../../extend/addon/addon/gitwiki/gitwiki.php:76
+#: ../../include/widgets.php:956
+msgid "Wiki Pages"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:342
-msgid "You must select white or black."
+#: ../../extend/addon/addon/gitwiki/gitwiki.php:81
+#: ../../include/widgets.php:962
+msgid "Add new page"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:349
-msgid "Error creating new game."
+#: ../../extend/addon/addon/gitwiki/gitwiki.php:82
+#: ../../include/widgets.php:963
+msgid "Page name"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:381 ../../include/channel.php:899
-msgid "Requested channel is not available."
+#: ../../extend/addon/addon/gitwiki/gitwiki.php:95
+#: ../../include/widgets.php:913
+msgid "Wiki List"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:395
-msgid "You must select a local channel /chess/channelname"
+#: ../../extend/addon/addon/gnusoc/gnusoc.php:129
+msgid "Enable the GNU-Social protocol for this channel"
msgstr ""
-#: ../../extend/addon/addon/chess/chess.php:923
-msgid "Enable notifications"
+#: ../../extend/addon/addon/opensearch/opensearch.php:26 ../../boot.php:1143
+#, php-format
+msgctxt "opensearch"
+msgid "Search %1$s (%2$s)"
msgstr ""
-#: ../../extend/addon/addon/likebanner/likebanner.php:51
-msgid "Your Webbie:"
+#: ../../extend/addon/addon/opensearch/opensearch.php:28 ../../boot.php:1143
+msgctxt "opensearch"
+msgid "$Projectname"
msgstr ""
-#: ../../extend/addon/addon/likebanner/likebanner.php:54
-msgid "Fontsize (px):"
+#: ../../extend/addon/addon/opensearch/opensearch.php:43
+msgid "Search $Projectname"
msgstr ""
-#: ../../extend/addon/addon/likebanner/likebanner.php:68
-msgid "Link:"
+#: ../../include/dba/dba_driver.php:187
+#, php-format
+msgid "Cannot locate DNS info for database server '%s'"
msgstr ""
-#: ../../extend/addon/addon/likebanner/likebanner.php:70
-msgid "Like us on Hubzilla"
+#: ../../include/language.php:367 ../../include/text.php:1772
+msgid "default"
msgstr ""
-#: ../../extend/addon/addon/likebanner/likebanner.php:72
-msgid "Embed:"
+#: ../../include/language.php:380
+msgid "Select an alternate language"
msgstr ""
-#: ../../extend/addon/addon/openid/Mod_Id.php:85
-#: ../../include/selectors.php:49 ../../include/selectors.php:66
-msgid "Male"
+#: ../../include/account.php:35
+msgid "Not a valid email address"
msgstr ""
-#: ../../extend/addon/addon/openid/Mod_Id.php:87
-#: ../../include/selectors.php:49 ../../include/selectors.php:66
-msgid "Female"
+#: ../../include/account.php:37
+msgid "Your email domain is not among those allowed on this site"
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:52
-msgid "First Name"
+#: ../../include/account.php:43
+msgid "Your email address is already registered at this site."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:53
-msgid "Last Name"
+#: ../../include/account.php:75
+msgid "An invitation is required."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:55
-msgid "Full Name"
+#: ../../include/account.php:79
+msgid "Invitation could not be verified."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:61
-msgid "Profile Photo 16px"
+#: ../../include/account.php:130
+msgid "Please enter the required information."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:62
-msgid "Profile Photo 32px"
+#: ../../include/account.php:198
+msgid "Failed to store account information."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:63
-msgid "Profile Photo 48px"
+#: ../../include/account.php:263
+#, php-format
+msgid "Registration confirmation for %s"
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:64
-msgid "Profile Photo 64px"
+#: ../../include/account.php:330
+#, php-format
+msgid "Registration request at %s"
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:65
-msgid "Profile Photo 80px"
+#: ../../include/account.php:352
+msgid "your registration password"
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:66
-msgid "Profile Photo 128px"
+#: ../../include/account.php:358 ../../include/account.php:420
+#, php-format
+msgid "Registration details for %s"
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:67
-msgid "Timezone"
+#: ../../include/account.php:431
+msgid "Account approved."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:70
-msgid "Birth Year"
+#: ../../include/account.php:471
+#, php-format
+msgid "Registration revoked for %s"
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:71
-msgid "Birth Month"
+#: ../../include/account.php:756 ../../include/account.php:758
+msgid "Click here to upgrade."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:72
-msgid "Birth Day"
+#: ../../include/account.php:764
+msgid "This action exceeds the limits set by your subscription plan."
msgstr ""
-#: ../../extend/addon/addon/openid/MysqlProvider.php:73
-msgid "Birthdate"
+#: ../../include/account.php:769
+msgid "This action is not available under your subscription plan."
msgstr ""
-#: ../../extend/addon/addon/openid/openid.php:49
-msgid ""
-"We encountered a problem while logging in with the OpenID you provided. "
-"Please check the correct spelling of the ID."
+#: ../../include/help.php:33
+msgid "Help:"
msgstr ""
-#: ../../extend/addon/addon/openid/openid.php:49
-msgid "The error message was:"
+#: ../../include/help.php:65
+msgid "Not Found"
msgstr ""
-#: ../../extend/addon/addon/openid/Mod_Openid.php:30
-msgid "OpenID protocol error. No ID returned."
+#: ../../include/zot.php:649
+msgid "Invalid data packet"
msgstr ""
-#: ../../extend/addon/addon/openid/Mod_Openid.php:188
-#: ../../include/auth.php:286
-msgid "Login failed."
+#: ../../include/zot.php:665
+msgid "Unable to verify channel signature"
msgstr ""
-#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:44
+#: ../../include/zot.php:2316
#, php-format
-msgid "Reconnecting %d connections"
+msgid "Unable to verify site signature for %s"
msgstr ""
-#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:63
-msgid "Diaspora Reconnect"
+#: ../../include/zot.php:3722
+msgid "invalid target signature"
msgstr ""
-#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:65
-msgid ""
-"Use this form to re-establish Diaspora connections which were initially made "
-"from a different hub."
+#: ../../include/taxonomy.php:188 ../../include/taxonomy.php:270
+#: ../../include/contact_widgets.php:91 ../../include/widgets.php:46
+#: ../../include/widgets.php:455
+msgid "Categories"
msgstr ""
-#: ../../extend/addon/addon/diaspora_reconnect/diaspora_reconnect.php:70
-msgid "Reconnect"
+#: ../../include/taxonomy.php:228 ../../include/taxonomy.php:249
+msgid "Tags"
msgstr ""
-#: ../../extend/addon/addon/mailtest/mailtest.php:19
-msgid "Send test email"
+#: ../../include/taxonomy.php:293
+msgid "Keywords"
msgstr ""
-#: ../../extend/addon/addon/mailtest/mailtest.php:66
-msgid "Mail sent."
+#: ../../include/taxonomy.php:314
+msgid "have"
msgstr ""
-#: ../../extend/addon/addon/mailtest/mailtest.php:68
-msgid "Sending of mail failed."
+#: ../../include/taxonomy.php:314
+msgid "has"
msgstr ""
-#: ../../extend/addon/addon/mailtest/mailtest.php:77
-msgid "Mail Test"
+#: ../../include/taxonomy.php:315
+msgid "want"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:57
-msgid "Errors encountered deleting database table "
+#: ../../include/taxonomy.php:315
+msgid "wants"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:96
-msgid "Drop tables when uninstalling?"
+#: ../../include/taxonomy.php:316
+msgid "likes"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:96
-msgid ""
-"If checked, the Rendezvous database tables will be deleted when the plugin "
-"is uninstalled."
+#: ../../include/taxonomy.php:317
+msgid "dislikes"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:97
-msgid "Mapbox Access Token"
+#: ../../include/connections.php:127
+msgid "New window"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:97
-msgid ""
-"If you enter a Mapbox access token, it will be used to retrieve map tiles "
-"from Mapbox instead of the default OpenStreetMap tile server."
+#: ../../include/connections.php:128
+msgid "Open the selected location in a different window or browser tab"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:162
-msgid "Rendezvous"
+#: ../../include/event.php:22 ../../include/event.php:69
+msgid "l F d, Y \\@ g:i A"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:167
-msgid ""
-"This identity has been deleted by another member due to inactivity. Please "
-"press the \"New identity\" button or refresh the page to register a new "
-"identity. You may use the same name."
+#: ../../include/event.php:30 ../../include/event.php:73
+msgid "Starts:"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:168
-msgid "Welcome to Rendezvous!"
+#: ../../include/event.php:40 ../../include/event.php:77
+msgid "Finishes:"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:169
-msgid ""
-"Enter your name to join this rendezvous. To begin sharing your location with "
-"the other members, tap the GPS control. When your location is discovered, a "
-"red dot will appear and others will be able to see you on the map."
+#: ../../include/event.php:1008
+msgid "This event has been added to your calendar."
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:171
-msgid "Let's meet here"
+#: ../../include/event.php:1208
+msgid "Not specified"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:174
-msgid "New marker"
+#: ../../include/event.php:1209
+msgid "Needs Action"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:175
-msgid "Edit marker"
+#: ../../include/event.php:1210
+msgid "Completed"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:176
-msgid "New identity"
+#: ../../include/event.php:1211
+msgid "In Process"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:177
-msgid "Delete marker"
+#: ../../include/event.php:1212
+msgid "Cancelled"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:178
-msgid "Delete member"
+#: ../../include/datetime.php:147
+msgid "Birthday"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:179
-msgid "Edit proximity alert"
+#: ../../include/datetime.php:149
+msgid "Age: "
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:180
-msgid ""
-"A proximity alert will be issued when this member is within a certain radius "
-"of you.
Enter a radius in meters (0 to disable):"
+#: ../../include/datetime.php:151
+msgid "YYYY-MM-DD or MM-DD"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:180
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:185
-msgid "distance"
+#: ../../include/datetime.php:286 ../../boot.php:2555
+msgid "never"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:181
-msgid "Proximity alert distance (meters)"
+#: ../../include/datetime.php:292
+msgid "less than a second ago"
msgstr ""
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:182
-#: ../../extend/addon/addon/rendezvous/rendezvous.php:184
-msgid ""
-"A proximity alert will be issued when you are within a certain radius of the "
-"marker location.
{{foreach $navapps as $navapp}}
--
cgit v1.2.3
From 2a1f6e3df26bf641bbf977deaf3c5f3ac3c64449 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Sun, 12 Mar 2017 15:57:56 -0700
Subject: update std_version
---
boot.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/boot.php b/boot.php
index 16d60f61e..83826fd0c 100755
--- a/boot.php
+++ b/boot.php
@@ -50,7 +50,7 @@ require_once('include/hubloc.php');
define ( 'PLATFORM_NAME', 'red' );
-define ( 'STD_VERSION', '2.3' );
+define ( 'STD_VERSION', '5.2' );
define ( 'ZOT_REVISION', '1.2' );
define ( 'DB_UPDATE_VERSION', 1188 );
--
cgit v1.2.3
From b1fc29be117cd95ad175a9899d1102ee56471d5b Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Sun, 12 Mar 2017 16:30:05 -0700
Subject: more cleanup
---
boot.php | 64 +++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 35 insertions(+), 29 deletions(-)
diff --git a/boot.php b/boot.php
index 83826fd0c..a80bfbed3 100755
--- a/boot.php
+++ b/boot.php
@@ -1130,24 +1130,25 @@ class App {
* since the code added by the modules frequently depends on it
* being first
*/
- $tpl = get_markup_template('head.tpl');
- self::$page['htmlhead'] = replace_macros($tpl, array(
- '$preload_images' => $preload_images,
- '$user_scalable' => $user_scalable,
- '$query' => urlencode(self::$query_string),
- '$baseurl' => self::get_baseurl(),
- '$local_channel' => local_channel(),
- '$metas' => self::$meta->get(),
- '$plugins' => $x['header'],
- '$update_interval' => $interval,
- 'osearch' => sprintf( t('Search %1$s (%2$s)','opensearch'), Zotlabs\Lib\System::get_site_name(), t('$Projectname','opensearch')),
- '$head_css' => head_get_css(),
- '$head_js' => head_get_js(),
- '$linkrel' => head_get_links(),
- '$js_strings' => js_strings(),
- '$zid' => get_my_address(),
- '$channel_id' => self::$profile['uid'],
- )) . self::$page['htmlhead'];
+
+ self::$page['htmlhead'] = replace_macros(get_markup_template('head.tpl'),
+ [
+ '$preload_images' => $preload_images,
+ '$user_scalable' => $user_scalable,
+ '$query' => urlencode(self::$query_string),
+ '$baseurl' => self::get_baseurl(),
+ '$local_channel' => local_channel(),
+ '$metas' => self::$meta->get(),
+ '$plugins' => $x['header'],
+ '$update_interval' => $interval,
+ '$head_css' => head_get_css(),
+ '$head_js' => head_get_js(),
+ '$linkrel' => head_get_links(),
+ '$js_strings' => js_strings(),
+ '$zid' => get_my_address(),
+ '$channel_id' => self::$profile['uid']
+ ]
+ ) . self::$page['htmlhead'];
// always put main.js at the end
self::$page['htmlhead'] .= head_get_main_js();
@@ -1160,11 +1161,13 @@ class App {
* @param string $name
*/
public static function register_template_engine($class, $name = '') {
- if ($name === ""){
- $v = get_class_vars( $class );
- if(x($v, "name")) $name = $v['name'];
+ if(! $name) {
+ $v = get_class_vars($class);
+ if(x($v, "name")) {
+ $name = $v['name'];
+ }
}
- if ($name === ""){
+ if (! $name) {
echo "template engine $class cannot be registered without a name.\n";
killme();
}
@@ -1180,19 +1183,21 @@ class App {
* @return object Template Engine instance
*/
public static function template_engine($name = ''){
- if ($name !== "") {
+ if($name !== '') {
$template_engine = $name;
- } else {
+ }
+ else {
$template_engine = 'smarty3';
- if (x(self::$theme, 'template_engine')) {
+ if(x(self::$theme, 'template_engine')) {
$template_engine = self::$theme['template_engine'];
}
}
- if (isset(self::$template_engines[$template_engine])){
+ if(isset(self::$template_engines[$template_engine])){
if(isset(self::$template_engine_instance[$template_engine])){
return self::$template_engine_instance[$template_engine];
- } else {
+ }
+ else {
$class = self::$template_engines[$template_engine];
$obj = new $class;
self::$template_engine_instance[$template_engine] = $obj;
@@ -1200,7 +1205,8 @@ class App {
}
}
- echo "template engine $template_engine is not registered!\n"; killme();
+ echo "template engine $template_engine is not registered!\n";
+ killme();
}
/**
@@ -2555,7 +2561,7 @@ function check_cron_broken() {
'$lastdate' => (($d)? $d : t('never'))
));
- $subject = email_header_encode(sprintf(t('[hubzilla] Cron tasks not running on %s'), App::get_hostname()));
+ $subject = email_header_encode(sprintf(t('[$Projectname] Cron tasks not running on %s'), App::get_hostname()));
mail(App::$config['system']['admin_email'], $subject, $email_msg,
'From: Administrator' . '@' . App::get_hostname() . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
--
cgit v1.2.3
From c39c925d8db1fd6a62033c1ece71cc4424899935 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Sun, 12 Mar 2017 17:32:45 -0700
Subject: grrr. stop making branding assumptions.
---
Zotlabs/Lib/Config.php | 2 +-
Zotlabs/Lib/PConfig.php | 2 +-
doc/about/about.bb | 204 +++++++++++++++++++++++++++++++++++++++++
doc/about/about_hubzilla.bb | 209 ------------------------------------------
doc/about/hubzilla_project.bb | 185 -------------------------------------
doc/about/project.bb | 185 +++++++++++++++++++++++++++++++++++++
doc/toc.html | 4 +-
include/help.php | 2 +-
8 files changed, 394 insertions(+), 399 deletions(-)
create mode 100644 doc/about/about.bb
delete mode 100644 doc/about/about_hubzilla.bb
delete mode 100644 doc/about/hubzilla_project.bb
create mode 100644 doc/about/project.bb
diff --git a/Zotlabs/Lib/Config.php b/Zotlabs/Lib/Config.php
index 5625a3f79..6e042feba 100644
--- a/Zotlabs/Lib/Config.php
+++ b/Zotlabs/Lib/Config.php
@@ -53,7 +53,7 @@ class Config {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
- if(get_config($family, $key) === false || (! self::get_from_storage($family, $key))) {
+ if(self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) {
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($family),
dbesc($key),
diff --git a/Zotlabs/Lib/PConfig.php b/Zotlabs/Lib/PConfig.php
index d70697fbc..25478e764 100644
--- a/Zotlabs/Lib/PConfig.php
+++ b/Zotlabs/Lib/PConfig.php
@@ -119,7 +119,7 @@ class PConfig {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
- if(get_pconfig($uid, $family, $key) === false) {
+ if(self::Get($uid, $family, $key) === false) {
if(! array_key_exists($uid, \App::$config))
\App::$config[$uid] = array();
if(! array_key_exists($family, \App::$config[$uid]))
diff --git a/doc/about/about.bb b/doc/about/about.bb
new file mode 100644
index 000000000..2affe2cba
--- /dev/null
+++ b/doc/about/about.bb
@@ -0,0 +1,204 @@
+[h3]What is $Projectname?[/h3]
+$Projectname is a [b]free and open source[/b] set of web applications and services running on a special kind of web server, called a "hub", that can connect to other hubs in a decentralised network we like to call "the grid", providing sophisticated communications, identity, and access control services which work together seamlessly across domains and independent websites. It allows anybody to publicly or [b]privately[/b] publish content via "channels", which are the fundamental, cryptographically secured identities that provide authentication independently of the hubs which host them. This revolutionary liberation of online identity from individual servers and domains is called "nomadic identity", and it is powered by the Zot protocol, a new framework for decentralised access control with fine-grained, extensible permissions.
+
+[h3]Right... so what is $Projectname?[/h3]
+From the practical perspective of hub members who use the software, $Projectname offers a variety of familiar, integrated web apps and services, including:
+[ul]
+[li]social networking discussion threads[/li]
+[li]cloud file storage[/li]
+[li]calendar and contacts (with CalDAV and CardDAV support)[/li]
+[li]webpage hosting with a content management system[/li]
+[li]wiki[/li]
+[li]and more...[/li][/ul]
+While all of these apps and services can be found in other software packages, only $Projectname allows you to set permissions for groups and individuals who may not even have accounts on your hub! In typical web apps, if you want to share things privately on the internet, the people you share with must have accounts on the server hosting your data; otherwise, there is no robust way for your server to [i]authenticate[/i] visitors to the site to know whether to grant them access. $Projectname solves this problem with an advanced system of [i]remote authentication[/i] that validates the identity of visitors by employing techniques that include public key cryptography.
+
+[h3]Software Stack[/h3]
+The $Projectname software stack is a relatively standard webserver application written primarily in PHP/MySQL and [url=https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt]requiring little more than a web server, a MySQL-compatible database, and the PHP scripting language[/url]. It is designed to be easily installable by those with basic website administration skills on typical shared hosting platforms with a broad range of computing hardware. It is also easily extended via plugins and themes and other third-party tools.
+
+[h3]Glossary[/h3]
+[dl terms="b"]
+[*= hub] An instance of this software running on a standard web server
+
+[*= grid] The global network of hubs that exchange information with each other using the Zot protocol.
+
+[*= channel] The fundamental identity on the grid. A channel can represent a person, a blog, or a forum to name a few. Channels can make connections with other channels to share information with highly detailed permissions.
+
+[*= clone] Channels can have clones associated with separate and otherwise unrelated accounts on independent hubs. Communications shared with a channel are synchronized among the channel clones, allowing a channel to send and receive messages and access shared content from multiple hubs. This provides resilience against network and hardware failures, which can be a significant problem for self-hosted or limited-resource web servers. Cloning allows you to completely move a channel from one hub to another, taking your data and connections with you. See nomadic identity.
+
+[*= nomadic identity] The ability to authenticate and easily migrate an identity across independent hubs and web domains. Nomadic identity provides true ownership of an online identity, because the identities of the channels controlled by an account on a hub are not tied to the hub itself. A hub is more like a "host" for channels. With Hubzilla, you don't have an "account" on a server like you do on typical websites; you own an identity that you can take with you across the grid by using clones.
+
+[*= [url=[baseurl]/help/developer/zot_protocol]Zot[/url]] The novel JSON-based protocol for implementing secure decentralised communications and services. It differs from many other communication protocols by building communications on top of a decentralised identity and authentication framework. The authentication component is similar to OpenID conceptually but is insulated from DNS-based identities. Where possible remote authentication is silent and invisible. This provides a mechanism for internet-scale distributed access control which is unobtrusive.
+[/dl]
+
+[h3]Features[/h3]
+This page lists some of the core features of $Projectname that are bundled with the official release. $Projectname is a highly extensible platform, so more features and capabilities can be added via additional themes and plugins.
+
+[h4]Affinity Slider[/h4]
+
+When adding connnections in $Projectname, members have the option of assigning "affinity" levels (how close your friendship is) to the new connection. For example, when adding someone who happens to be a person whose blog you follow, you could assign their channel an affinity level of "Acquaintances".
+
+On the other hand, when adding a friend's channel, they could be placed under the affinity level of "Friends".
+
+At this point, $Projectname [i]Affinity Slider[/i] tool, which usually appears at the top of your "Matrix" page, adjusts the content on the page to include those within the desired affinity range. Channels outside that range will not be displayed, unless you adjust the slider to include them.
+
+The Affinity Slider allows instantaneous filtering of large amounts of content, grouped by levels of closeness.
+
+[h4]Connection Filtering[/h4]
+
+You have the ability to control precisely what appears in your stream using the optional "Connection Filter". When enabled, the Connection Editor provides inputs for selecting criteria which needs to be matched in order to include or exclude a specific post from a specific channel. Once a post has been allowed, all comments to that post are allowed regardless of whether they match the selection criteria. You may select words that if present block the post or ensure it is included in your stream. Regular expressions may be used for even finer control, as well as hashtags or even the detected language of the post.
+
+[h4]Access Control Lists[/h4]
+
+When sharing content, members have the option of restricting who sees the content. By clicking on the padlock underneath the sharing box, one may choose desired recipients of the post, by clicking on their names.
+
+Once sent, the message will be viewable only by the sender and the selected recipients. In other words, the message will not appear on any public walls.
+
+Access Control Lists may be applied to content and posts, photos, events, webpages, chatrooms and files.
+
+[h4]Single Sign-on[/h4]
+
+Access Control Lists work for all channels in the grid due to our unique single sign-on technology. Most internal links provide an identity token which can be verified on other $Projectname sites and used to control access to private resources. You login once to your home hub. After that, authentication to all $Projectname resources is "magic".
+
+
+[h4]WebDAV enabled File Storage[/h4]
+
+Files may be uploaded to your personal storage area using your operating system utilities (drag and drop in most cases). You may protect these files with Access Control Lists to any combination of $Projectname members (including some third party network members) or make them public.
+
+[h4]Photo Albums[/h4]
+
+Store photos in albums. All your photos may be protected by Access Control Lists.
+
+[h4]Events Calendar[/h4]
+
+Create and manage events and tasks, which may also be protected with Access Control Lists. Events can be imported/exported to other software using the industry standard vcalendar/iCal format and shared in posts with others. Birthday events are automatically added from your friends and converted to your correct timezone so that you will know precisely when the birthday occurs - no matter where you are located in the world in relation to the birthday person. Events are normally created with attendance counters so your friends and connections can RSVP instantly.
+
+[h4]Chatrooms[/h4]
+
+You may create any number of personal chatrooms and allow access via Access Control Lists. These are typically more secure than XMPP, IRC, and other Instant Messaging transports, though we also allow using these other services via plugins.
+
+[h4]Webpage Building[/h4]
+
+$Projectname has many "Content Management" creation tools for building webpages, including layout editing, menus, blocks, widgets, and page/content regions. All of these may be access controlled so that the resulting pages are private to their intended audience.
+
+[h4]Apps[/h4]
+
+Apps may be built and distributed by members. These are different from traditional "vendor lockin" apps because they are controlled completely by the author - who can provide access control on the destination app pages and charge accordingly for this access. Most apps in $Projectname are free and can be created easily by those with no programming skills.
+
+[h4]Layout[/h4]
+
+Page layout is based on a description language called Comanche. $Projectname is itself written in Comanche layouts which you can change. This allows a level of customisation you won't typically find in so-called "multi-user environments".
+
+[h4]Bookmarks[/h4]
+
+Share and save/manage bookmarks from links provided in conversations.
+
+
+[h4]Private Message Encryption and Privacy Concerns[/h4]
+
+Private mail is stored in an obscured format. While this is not bullet-proof it typically prevents casual snooping by the site administrator or ISP.
+
+Each $Projectname channel has it's own unique set of private and associated public RSA 4096-bit keys, generated when the channels is first created. This is used to protect private messages and posts in transit.
+
+Additionally, messages may be created utilising "end-to-end encryption" which cannot be read by $Projectname operators or ISPs or anybody who does not know the passcode.
+
+Public messages are generally not encrypted in transit or in storage.
+
+Private messages may be retracted (unsent) although there is no guarantee the recipient hasn't read it yet.
+
+Posts and messages may be created with an expiration date, at which time they will be deleted/removed on the recipient's site.
+
+
+[h4]Service Federation[/h4]
+
+In addition to addon "cross-post connectors" to a variety of alternate networks, there is native support for importation of content from RSS/Atom feeds and using this to create special channels. Also, an experimental but working implementation of the Diaspora protocol allows communication with people on the Friendica and Diaspora decentralised social networks. This is currently marked experimental because these networks do not have the same level of privacy and encryption features and abilities as $Projectname and may present privacy risks.
+
+There is also experimental support for OpenID authentication which may be used in Access Control Lists. This is a work in progress. Your $Projectname hub may be used as an OpenID provider to authenticate you to external services which use this technology.
+
+Channels may have permissions to become "derivative channels" where two or more existing channels combine to create a new topical channel.
+
+[h4]Privacy Groups[/h4]
+
+Our implementation of privacy groups is similar to Google "Circles" and Diaspora "Aspects". This allows you to filter your incoming stream by selected groups, and automatically set the outbound Access Control List to only those in that privacy group when you post. You may over-ride this at any time (prior to sending the post).
+
+
+[h4]Directory Services[/h4]
+
+We provide easy access to a directory of members and provide decentralised tools capable of providing friend "suggestions". The directories are normal $Projectname sites which have chosen to accept the directory server role. This requires more resources than most typical sites so is not the default. Directories are synchronised and mirrored so that they all contain up-to-date information on the entire network (subject to normal propagation delays).
+
+
+[h4]TLS/SSL[/h4]
+
+For $Projectname hubs that use TLS/SSL, client to server communications are encrypted via TLS/SSL. Given recent disclosures in the media regarding widespread, global surveillance and encryption circumvention by the NSA and GCHQ, it is reasonable to assume that HTTPS-protected communications may be compromised in various ways. Private communications are consequently encrypted at a higher level before sending offsite.
+
+[h4]Channel Settings[/h4]
+
+When a channel is created, a role is chosen which applies a number of pre-configured security and privacy settings. These are chosen for best practives to maintain privacy at the requested levels.
+
+If you choose a "custom" privacy role, each channel allows fine-grained permissions to be set for various aspects of communication. For example, under the "Security and Privacy Settings" heading, each aspect on the left side of the page, has six (6) possible viewing/access options, that can be selected by clicking on the dropdown menu. There are also a number of other privacy settings you may edit.
+
+The options are:
+
+ - Nobody except yourself.
+ - Only those you specifically allow.
+ - Anybody in your address book.
+ - Anybody on this website.
+ - Anybody in this network.
+ - Anybody authenticated.
+ - Anybody on the Internet.
+
+
+[h4]Public and Private Forums[/h4]
+
+Forums are typically channels which may be open to participation from multiple authors. There are currently two mechanisms to post to forums: 1) "wall-to-wall" posts and 2) via forum @mention tags. Forums can be created by anybody and used for any purpose. The directory contains an option to search for public forums. Private forums can only be posted to and often only seen by members.
+
+
+[h4]Account Cloning[/h4]
+
+Accounts in $Projectname are referred to as [i]nomadic identities[/i], because a member's identity is not bound to the hub where the identity was originally created. For example, when you create a Facebook or Gmail account, it is tied to those services. They cannot function without Facebook.com or Gmail.com.
+
+By contrast, say you've created a $Projectname identity called [b]tina@$Projectnamehub.com[/b]. You can clone it to another $Projectname hub by choosing the same, or a different name: [b]liveForever@Some$ProjectnameHub.info[/b]
+
+Both channels are now synchronized, which means all your contacts and preferences will be duplicated on your clone. It doesn't matter whether you send a post from your original hub, or the new hub. Posts will be mirrored on both accounts.
+
+This is a rather revolutionary feature, if we consider some scenarios:
+
+ - What happens if the hub where an identity is based suddenly goes offline? Without cloning, a member will not be able to communicate until that hub comes back online (no doubt many of you have seen and cursed the Twitter "Fail Whale"). With cloning, you just log into your cloned account, and life goes on happily ever after.
+
+ - The administrator of your hub can no longer afford to pay for his free and public $Projectname hub. He announces that the hub will be shutting down in two weeks. This gives you ample time to clone your identity(ies) and preserve your$Projectname relationships, friends and content.
+
+ - What if your identity is subject to government censorship? Your hub provider may be compelled to delete your account, along with any identities and associated data. With cloning, $Projectname offers [b]censorship resistance[/b]. You can have hundreds of clones, if you wanted to, all named different, and existing on many different hubs, strewn around the internet.
+
+$Projectname offers interesting new possibilities for privacy. You can read more at the <<Private Communications Best Practices>> page.
+
+Some caveats apply. For a full explanation of identity cloning, read the <HOW TO CLONE MY IDENTITY>.
+
+[h4]Multiple Profiles[/h4]
+
+Any number of profiles may be created containing different information and these may be made visible to certain of your connections/friends. A "default" profile can be seen by anybody and may contain limited information, with more information available to select groups or people. This means that the profile (and site content) your beer-drinking buddies see may be different than what your co-workers see, and also completely different from what is visible to the general public.
+
+[h4]Account Backup[/h4]
+
+$Projectname offers a simple, one-click account backup, where you can download a complete backup of your profile(s). Backups can then be used to clone or restore a profile.
+
+[h4]Account Deletion[/h4]
+Accounts can be immediately deleted by clicking on a link. That's it. All associated content is then deleted from the grid (this includes posts and any other content produced by the deleted profile). Depending on the number of connections you have, the process of deleting remote content could take some time but it is scheduled to happen as quickly as is practical.
+
+[h4]Deletion of content[/h4]
+Any content created in $Projectname remains under the control of the member (or channel) that originally created it. At any time, a member can delete a message, or a range of messages. The deletion process ensures that the content is deleted, regardless of whether it was posted on a channel's primary (home) hub, or on another hub, where the channel was remotely authenticated via Zot ($Projectname communication and authentication protocol).
+
+[h4]Media[/h4]
+Similar to any other modern blogging system, social network, or a micro-blogging service, $Projectname supports the uploading of files, embedding of videos, linking web pages.
+
+[h4]Previewing/Editing[/h4]
+Post can be previewed prior to sending and edited after sending.
+
+[h4]Voting/Consensus[/h4]
+Posts can be turned into "consensus" items which allows readers to offer feedback, which is collated into "agree", "disagree", and "abstain" counters. This lets you gauge interest for ideas and create informal surveys.
+
+[h4]Extending $Projectname[/h4]
+
+$Projectname can be extended in a number of ways, through site customisation, personal customisation, option setting, themes, and addons/plugins.
+
+[h4]API[/h4]
+
+An API is available for use by third-party services. This is based originally on the early Twitter API (for which hundreds of third-party tools exist). It is currently being extended to provide access to facilities and abilities which are specific to $Projectname. Access may be provided by login/password or OAuth and client registration of OAuth applications is provided.
diff --git a/doc/about/about_hubzilla.bb b/doc/about/about_hubzilla.bb
deleted file mode 100644
index e9485ffa6..000000000
--- a/doc/about/about_hubzilla.bb
+++ /dev/null
@@ -1,209 +0,0 @@
-[h3]What is Hubzilla?[/h3]
-$Projectname is a [b]free and open source[/b] set of web applications and services running on a special kind of web server, called a "hub", that can connect to other hubs in a decentralised network we like to call "the grid", providing sophisticated communications, identity, and access control services which work together seamlessly across domains and independent websites. It allows anybody to publicly or [b]privately[/b] publish content via "channels", which are the fundamental, cryptographically secured identities that provide authentication independently of the hubs which host them. This revolutionary liberation of online identity from individual servers and domains is called "nomadic identity", and it is powered by the Zot protocol, a new framework for decentralised access control with fine-grained, extensible permissions.
-
-[h3]Right... so what is Hubzilla?[/h3]
-From the practical perspective of hub members who use the software, $Projectname offers a variety of familiar, integrated web apps and services, including:
-[ul]
-[li]social networking discussion threads[/li]
-[li]cloud file storage[/li]
-[li]calendar and contacts (with CalDAV and CardDAV support)[/li]
-[li]webpage hosting with a content management system[/li]
-[li]wiki[/li]
-[li]and more...[/li][/ul]
-While all of these apps and services can be found in other software packages, only $Projectname allows you to set permissions for groups and individuals who may not even have accounts on your hub! In typical web apps, if you want to share things privately on the internet, the people you share with must have accounts on the server hosting your data; otherwise, there is no robust way for your server to [i]authenticate[/i] visitors to the site to know whether to grant them access. $Projectname solves this problem with an advanced system of [i]remote authentication[/i] that validates the identity of visitors by employing techniques that include public key cryptography.
-
-[h3]Software Stack[/h3]
-The $Projectname software stack is a relatively standard webserver application written primarily in PHP/MySQL and [url=https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt]requiring little more than a web server, a MySQL-compatible database, and the PHP scripting language[/url]. It is designed to be easily installable by those with basic website administration skills on typical shared hosting platforms with a broad range of computing hardware. It is also easily extended via plugins and themes and other third-party tools.
-
-[h3]Additional Resources and Links[/h3]
-[list][*][url=http://hubzilla.org]Hubzilla project website[/url]
-[*][url=https://github.com/redmatrix/hubzilla]Hubzilla core code repository[/url]
-[*][url=https://github.com/redmatrix/hubzilla-addons]Hubzilla official addons repository[/url][/list]
-
-[h3]Glossary[/h3]
-[dl terms="b"]
-[*= hub] An instance of the Hubzilla software running on a standard web server
-
-[*= grid] The global network of hubs that exchange information with each other using the Zot protocol.
-
-[*= channel] The fundamental identity on the grid. A channel can represent a person, a blog, or a forum to name a few. Channels can make connections with other channels to share information with highly detailed permissions.
-
-[*= clone] Channels can have clones associated with separate and otherwise unrelated accounts on independent hubs. Communications shared with a channel are synchronized among the channel clones, allowing a channel to send and receive messages and access shared content from multiple hubs. This provides resilience against network and hardware failures, which can be a significant problem for self-hosted or limited-resource web servers. Cloning allows you to completely move a channel from one hub to another, taking your data and connections with you. See nomadic identity.
-
-[*= nomadic identity] The ability to authenticate and easily migrate an identity across independent hubs and web domains. Nomadic identity provides true ownership of an online identity, because the identities of the channels controlled by an account on a hub are not tied to the hub itself. A hub is more like a "host" for channels. With Hubzilla, you don't have an "account" on a server like you do on typical websites; you own an identity that you can take with you across the grid by using clones.
-
-[*= [url=[baseurl]/help/developer/zot_protocol]Zot[/url]] The novel JSON-based protocol for implementing secure decentralised communications and services. It differs from many other communication protocols by building communications on top of a decentralised identity and authentication framework. The authentication component is similar to OpenID conceptually but is insulated from DNS-based identities. Where possible remote authentication is silent and invisible. This provides a mechanism for internet-scale distributed access control which is unobtrusive.
-[/dl]
-
-[h3]Features[/h3]
-This page lists some of the core features of $Projectname that are bundled with the official release. $Projectname is a highly extensible platform, so more features and capabilities can be added via additional themes and plugins.
-
-[h4]Affinity Slider[/h4]
-
-When adding connnections in $Projectname, members have the option of assigning "affinity" levels (how close your friendship is) to the new connection. For example, when adding someone who happens to be a person whose blog you follow, you could assign their channel an affinity level of "Acquaintances".
-
-On the other hand, when adding a friend's channel, they could be placed under the affinity level of "Friends".
-
-At this point, $Projectname [i]Affinity Slider[/i] tool, which usually appears at the top of your "Matrix" page, adjusts the content on the page to include those within the desired affinity range. Channels outside that range will not be displayed, unless you adjust the slider to include them.
-
-The Affinity Slider allows instantaneous filtering of large amounts of content, grouped by levels of closeness.
-
-[h4]Connection Filtering[/h4]
-
-You have the ability to control precisely what appears in your stream using the optional "Connection Filter". When enabled, the Connection Editor provides inputs for selecting criteria which needs to be matched in order to include or exclude a specific post from a specific channel. Once a post has been allowed, all comments to that post are allowed regardless of whether they match the selection criteria. You may select words that if present block the post or ensure it is included in your stream. Regular expressions may be used for even finer control, as well as hashtags or even the detected language of the post.
-
-[h4]Access Control Lists[/h4]
-
-When sharing content, members have the option of restricting who sees the content. By clicking on the padlock underneath the sharing box, one may choose desired recipients of the post, by clicking on their names.
-
-Once sent, the message will be viewable only by the sender and the selected recipients. In other words, the message will not appear on any public walls.
-
-Access Control Lists may be applied to content and posts, photos, events, webpages, chatrooms and files.
-
-[h4]Single Sign-on[/h4]
-
-Access Control Lists work for all channels in the grid due to our unique single sign-on technology. Most internal links provide an identity token which can be verified on other $Projectname sites and used to control access to private resources. You login once to your home hub. After that, authentication to all $Projectname resources is "magic".
-
-
-[h4]WebDAV enabled File Storage[/h4]
-
-Files may be uploaded to your personal storage area using your operating system utilities (drag and drop in most cases). You may protect these files with Access Control Lists to any combination of $Projectname members (including some third party network members) or make them public.
-
-[h4]Photo Albums[/h4]
-
-Store photos in albums. All your photos may be protected by Access Control Lists.
-
-[h4]Events Calendar[/h4]
-
-Create and manage events and tasks, which may also be protected with Access Control Lists. Events can be imported/exported to other software using the industry standard vcalendar/iCal format and shared in posts with others. Birthday events are automatically added from your friends and converted to your correct timezone so that you will know precisely when the birthday occurs - no matter where you are located in the world in relation to the birthday person. Events are normally created with attendance counters so your friends and connections can RSVP instantly.
-
-[h4]Chatrooms[/h4]
-
-You may create any number of personal chatrooms and allow access via Access Control Lists. These are typically more secure than XMPP, IRC, and other Instant Messaging transports, though we also allow using these other services via plugins.
-
-[h4]Webpage Building[/h4]
-
-$Projectname has many "Content Management" creation tools for building webpages, including layout editing, menus, blocks, widgets, and page/content regions. All of these may be access controlled so that the resulting pages are private to their intended audience.
-
-[h4]Apps[/h4]
-
-Apps may be built and distributed by members. These are different from traditional "vendor lockin" apps because they are controlled completely by the author - who can provide access control on the destination app pages and charge accordingly for this access. Most apps in $Projectname are free and can be created easily by those with no programming skills.
-
-[h4]Layout[/h4]
-
-Page layout is based on a description language called Comanche. $Projectname is itself written in Comanche layouts which you can change. This allows a level of customisation you won't typically find in so-called "multi-user environments".
-
-[h4]Bookmarks[/h4]
-
-Share and save/manage bookmarks from links provided in conversations.
-
-
-[h4]Private Message Encryption and Privacy Concerns[/h4]
-
-Private mail is stored in an obscured format. While this is not bullet-proof it typically prevents casual snooping by the site administrator or ISP.
-
-Each $Projectname channel has it's own unique set of private and associated public RSA 4096-bit keys, generated when the channels is first created. This is used to protect private messages and posts in transit.
-
-Additionally, messages may be created utilising "end-to-end encryption" which cannot be read by $Projectname operators or ISPs or anybody who does not know the passcode.
-
-Public messages are generally not encrypted in transit or in storage.
-
-Private messages may be retracted (unsent) although there is no guarantee the recipient hasn't read it yet.
-
-Posts and messages may be created with an expiration date, at which time they will be deleted/removed on the recipient's site.
-
-
-[h4]Service Federation[/h4]
-
-In addition to addon "cross-post connectors" to a variety of alternate networks, there is native support for importation of content from RSS/Atom feeds and using this to create special channels. Also, an experimental but working implementation of the Diaspora protocol allows communication with people on the Friendica and Diaspora decentralised social networks. This is currently marked experimental because these networks do not have the same level of privacy and encryption features and abilities as $Projectname and may present privacy risks.
-
-There is also experimental support for OpenID authentication which may be used in Access Control Lists. This is a work in progress. Your $Projectname hub may be used as an OpenID provider to authenticate you to external services which use this technology.
-
-Channels may have permissions to become "derivative channels" where two or more existing channels combine to create a new topical channel.
-
-[h4]Privacy Groups[/h4]
-
-Our implementation of privacy groups is similar to Google "Circles" and Diaspora "Aspects". This allows you to filter your incoming stream by selected groups, and automatically set the outbound Access Control List to only those in that privacy group when you post. You may over-ride this at any time (prior to sending the post).
-
-
-[h4]Directory Services[/h4]
-
-We provide easy access to a directory of members and provide decentralised tools capable of providing friend "suggestions". The directories are normal $Projectname sites which have chosen to accept the directory server role. This requires more resources than most typical sites so is not the default. Directories are synchronised and mirrored so that they all contain up-to-date information on the entire network (subject to normal propagation delays).
-
-
-[h4]TLS/SSL[/h4]
-
-For $Projectname hubs that use TLS/SSL, client to server communications are encrypted via TLS/SSL. Given recent disclosures in the media regarding widespread, global surveillance and encryption circumvention by the NSA and GCHQ, it is reasonable to assume that HTTPS-protected communications may be compromised in various ways. Private communications are consequently encrypted at a higher level before sending offsite.
-
-[h4]Channel Settings[/h4]
-
-When a channel is created, a role is chosen which applies a number of pre-configured security and privacy settings. These are chosen for best practives to maintain privacy at the requested levels.
-
-If you choose a "custom" privacy role, each channel allows fine-grained permissions to be set for various aspects of communication. For example, under the "Security and Privacy Settings" heading, each aspect on the left side of the page, has six (6) possible viewing/access options, that can be selected by clicking on the dropdown menu. There are also a number of other privacy settings you may edit.
-
-The options are:
-
- - Nobody except yourself.
- - Only those you specifically allow.
- - Anybody in your address book.
- - Anybody on this website.
- - Anybody in this network.
- - Anybody authenticated.
- - Anybody on the Internet.
-
-
-[h4]Public and Private Forums[/h4]
-
-Forums are typically channels which may be open to participation from multiple authors. There are currently two mechanisms to post to forums: 1) "wall-to-wall" posts and 2) via forum @mention tags. Forums can be created by anybody and used for any purpose. The directory contains an option to search for public forums. Private forums can only be posted to and often only seen by members.
-
-
-[h4]Account Cloning[/h4]
-
-Accounts in $Projectname are referred to as [i]nomadic identities[/i], because a member's identity is not bound to the hub where the identity was originally created. For example, when you create a Facebook or Gmail account, it is tied to those services. They cannot function without Facebook.com or Gmail.com.
-
-By contrast, say you've created a $Projectname identity called [b]tina@$Projectnamehub.com[/b]. You can clone it to another $Projectname hub by choosing the same, or a different name: [b]liveForever@Some$ProjectnameHub.info[/b]
-
-Both channels are now synchronized, which means all your contacts and preferences will be duplicated on your clone. It doesn't matter whether you send a post from your original hub, or the new hub. Posts will be mirrored on both accounts.
-
-This is a rather revolutionary feature, if we consider some scenarios:
-
- - What happens if the hub where an identity is based suddenly goes offline? Without cloning, a member will not be able to communicate until that hub comes back online (no doubt many of you have seen and cursed the Twitter "Fail Whale"). With cloning, you just log into your cloned account, and life goes on happily ever after.
-
- - The administrator of your hub can no longer afford to pay for his free and public $Projectname hub. He announces that the hub will be shutting down in two weeks. This gives you ample time to clone your identity(ies) and preserve your$Projectname relationships, friends and content.
-
- - What if your identity is subject to government censorship? Your hub provider may be compelled to delete your account, along with any identities and associated data. With cloning, $Projectname offers [b]censorship resistance[/b]. You can have hundreds of clones, if you wanted to, all named different, and existing on many different hubs, strewn around the internet.
-
-$Projectname offers interesting new possibilities for privacy. You can read more at the <<Private Communications Best Practices>> page.
-
-Some caveats apply. For a full explanation of identity cloning, read the <HOW TO CLONE MY IDENTITY>.
-
-[h4]Multiple Profiles[/h4]
-
-Any number of profiles may be created containing different information and these may be made visible to certain of your connections/friends. A "default" profile can be seen by anybody and may contain limited information, with more information available to select groups or people. This means that the profile (and site content) your beer-drinking buddies see may be different than what your co-workers see, and also completely different from what is visible to the general public.
-
-[h4]Account Backup[/h4]
-
-$Projectname offers a simple, one-click account backup, where you can download a complete backup of your profile(s). Backups can then be used to clone or restore a profile.
-
-[h4]Account Deletion[/h4]
-Accounts can be immediately deleted by clicking on a link. That's it. All associated content is then deleted from the grid (this includes posts and any other content produced by the deleted profile). Depending on the number of connections you have, the process of deleting remote content could take some time but it is scheduled to happen as quickly as is practical.
-
-[h4]Deletion of content[/h4]
-Any content created in $Projectname remains under the control of the member (or channel) that originally created it. At any time, a member can delete a message, or a range of messages. The deletion process ensures that the content is deleted, regardless of whether it was posted on a channel's primary (home) hub, or on another hub, where the channel was remotely authenticated via Zot ($Projectname communication and authentication protocol).
-
-[h4]Media[/h4]
-Similar to any other modern blogging system, social network, or a micro-blogging service, $Projectname supports the uploading of files, embedding of videos, linking web pages.
-
-[h4]Previewing/Editing[/h4]
-Post can be previewed prior to sending and edited after sending.
-
-[h4]Voting/Consensus[/h4]
-Posts can be turned into "consensus" items which allows readers to offer feedback, which is collated into "agree", "disagree", and "abstain" counters. This lets you gauge interest for ideas and create informal surveys.
-
-[h4]Extending $Projectname[/h4]
-
-$Projectname can be extended in a number of ways, through site customisation, personal customisation, option setting, themes, and addons/plugins.
-
-[h4]API[/h4]
-
-An API is available for use by third-party services. This is based originally on the early Twitter API (for which hundreds of third-party tools exist). It is currently being extended to provide access to facilities and abilities which are specific to $Projectname. Access may be provided by login/password or OAuth and client registration of OAuth applications is provided.
diff --git a/doc/about/hubzilla_project.bb b/doc/about/hubzilla_project.bb
deleted file mode 100644
index 7a584687d..000000000
--- a/doc/about/hubzilla_project.bb
+++ /dev/null
@@ -1,185 +0,0 @@
-[h3]$Projectname Governance[/h3]
-Governance relates to the management of a project and particularly how this relates to conflict resolution.
-
-[h4]Community Governance[/h4]
-The project is maintained and decisions made by the 'community'. The governance structure is still evolving. Until the structure is finalised, decisions are made in the following order:
-
-[ol]
-[*] Lazy Consensus
-
-If a project proposal is made to one of the community governance forums and there are no serious objections in a "reasonable" amount of time from date of proposal (we usually provide 2-3 days for all interested parties to weigh in), no vote needs to be taken and the proposal will be considered approved. Some concerns may be raised at this time, but if these are addressed during discussion and work-arounds provided, it will still be considered approved.
-
-
-[*] Veto
-
-Senior developers with a significant history of project commits may veto any decision. The decision may not proceed until the veto is removed or an alternative proposal is presented.
-
-
-[*] Community Vote
-
-A decision which does not have a clear mandate or clear consensus, but is not vetoed, can be taken to a community vote. At present this is a simple popular vote in one of the applicable community forums. At this time, popular vote decides the outcome. This may change in the future if the community adopts a 'council' governance model. This document will be updated at that time with the updated governance rules.
-[/ol]
-
-Community Voting does not always provide a pleasant outcome and can generate polarised factions in the community (hence the reason why other models are under consideration). If the proposal is 'down voted' there are still several things which can be done and the proposal re-submitted with slightly different parameters (convert to an addon, convert to an optional feature which is disabled by default, etc.). If interest in the feature is high and the vote is "close", it can generate lots of bad feelings amongst the losing voters. On such close votes, it is [b]strongly recommended[/b] that the proposer take steps to address any concerns that were raised and re-submit.
-
-
-
-[h4]Privacy Policy[/h4]
-
-Q: Who can see my content?
-
-A: By default ANYBODY on the internet, UNLESS you restrict it. $Projectname allows you to choose the privacy level you desire. Restricted content will NOT be visible to "spy networks" and advertisers. It will be protected against eavesdropping by outsiders - to the best of our ability. Hub administrators with sufficient skills and patience MAY be able to eavesdrop on some private communications but they must expend effort to do so. Privacy modes exist within $Projectname which are even resistant to eavesdropping by skilled and determined hub administrators.
-
-Q: Can my content be censored?
-
-A: $Projectname (the network) CANNOT censor your content. Server and hub administrators are subject to local laws and MAY remove objectionable content from their site/hub. Anybody MAY become a hub administrator, including you; and therefore publish content which might otherwise be censored. You still MAY be subject to local laws.
-
-
-[h5]Definitions[/h5]
-
-**$Projectname**
-
-Otherwise referred to as "the network", $Projectname is a collection of individual computers/servers (aka **hubs**) which connect together to form a larger cooperative network.
-
-**hub**
-
-An individual computer or server connected to $Projectname. These are provided by a **hub administrator** and may be public or private, paid or free.
-
-**hub administrator**
-
-The system operator of an individual hub.
-
-[h5]Policies[/h5]
-
-**Public Information**
-
-Any information or anything posted by you within $Projectname MAY be public or visible to anybody on the internet. To the extent possible, $Projectname allows you to protect content and restrict who can view it.
-
-Your profile photo, your channel name, and the location (URL or network address) of your channel are visible to anybody on the internet and privacy controls will not affect the display of these items.
-
-You MAY additionally provide other profile information. Any information which you provide in your "default" or **public profile** MAY be transmitted to other hubs in $Projectname and additionally MAY be displayed in the channel directory. You can restrict the viewing of this profile information. It may be restricted only to members of your hub, or only connections (friends), or other limited sets of viewers as you desire. If you wish for your profile to be restricted, you must set the appropriate privacy setting, or simply DO NOT provide additional information.
-
-**Content**
-
-Content you provide (status posts, photos, files, etc.) belongs to you. $Projectname default is to publish content openly and visible to anybody on the internet (PUBLIC). You MAY control this in your channel settings and restrict the default permissions or you MAY restrict the visibility of any single published item separately (PRIVATE). $Projectname developers will ensure that restricted content is ONLY visible to those in the restriction list - to the best of their ability.
-
-Content (especially status posts) that you share with other networks or that you have made visible to anybody on the internet (PUBLIC) cannot easily be taken back once it has been published. It MAY be shared with other networks and made available through RSS/Atom feeds. It may also be syndicated on other $Projectname sites. It MAY appear on other networks and websites and be visible in internet searches. If you do not wish this default behaviour please adjust your channel settings and restrict who can see your content.
-
-**Comments and Forum posts**
-
-Comments to posts that were created by others and posts which are designated as forum posts belong to you as the creator/author, but the distribution of these posts is not under your direct control, and you relinquish SOME rights to these items. These posts/comments MAY be re-distributed to others, and MAY be visible to anybody on the internet. In the case of comments, the creator of the "first message" in the thread (conversation) to which you are replying controls the distribution of all comments and replies to that message. They "own" and therefore have certain rights with regard to the entire conversation (including all comments contained within it). You can still edit or delete the comment, but the conversation owner also has rights to edit, delete, re-distribute, and backup/restore any or all the content from the conversation.
-
-**Private Information**
-
-$Projectname developers will ensure that any content you provide which is designated as PRIVATE will be protected against eavesdropping - to the best of their ability. Private channel content CAN be seen in the database of every involved hub administrator, but private messages are obscured in the database. The latter means that it is very difficult, but NOT impossible for this content to be seen by a hub administrator. Private channel content and private messages are also stripped from email notifications. End to end encryption is provided as an optional feature and this CANNOT be seen, even by a determined administrator.
-
-[h5]Identity Privacy[/h5]
-
-Privacy for your identity is another aspect. Because you have a decentralized identity in $Projectname, your privacy extends beyond your home hub. If you want to have complete control of your privacy and security you should run your own hub on a dedicated server. For many people, this is complicated and may stretch their technical abilities. So let's list a few precautions you can make to assure your privacy as much as possible.
-
-A decentralized identity has a lot of advantages and gives you al lot of interesting features, but you should be aware of the fact that your identity is known by other hubs in $Projectname network. One of those advantages is that other channels can serve you customized content and allow you to see private things (such as private photos which others wish to share with you). Because of this those channels need to know who you are. But we understand that sometimes those other channels know more from you than you might desire. For instance the plug-in Visage that can tell a channel owner the last time you visit their profile. You can easily OPT-OUT of this low level and we think, harmless tracking.
-
-* You can enable [Do Not Track (DNT)](http://donottrack.us/) in your web browser. We respect this new privacy policy proposal. All modern browsers support DNT. You will find it in the privacy settings of your browsers or else you can consult the web browser's manual. This will not affect the functionality of $Projectname. This setting is probably enough for most people.
-
-*You can [disable publication](settings) of your channel in our channel directory. If you want people to find your channel, you should give your channel address directly to them. We think this is a good indication that you prefer extra privacy and automatically enable "Do Not Track" if this is the case.
-
-* You can have a blocked hub. That means that all channels and content on that hub is not public, and not visible to the outside world. This is something only your hub administrator can do. We also respect this and automatically enable "Do Not Track" if it is set.
-
-[h5]Censorship[/h5]
-
-$Projectname is a global network which is inclusive of all religions and cultures. This does not imply that every member of the network feels the same way you do on contentious issues, and some people may be STRONGLY opposed to the content you post. In general, if you wish to post something that you know may nor be universally acceptable, the best approach is to restrict the audience using privacy controls to a small circle of friends.
-
-$Projectname as a network provider is unable to censor content. However, hub administrators MAY censor any content which appears on their hub to comply with local laws or even personal judgement. Their decision is final. If you have issues with any hub administrator, you may move your account and postings to another site which is more in line with your expectations. Please check (periodically) the [Terms of Service](help/TermsOfService) of your hub to learn about any rules or guidelines. If your content consists of material which is illegal or may cause issues, you are STRONGLY encouraged to host your own (become a hub administrator). You may still find that your content is blocked on some hubs, but $Projectname as a network cannot block it from being posted.
-
-$Projectname RECOMMENDS that hub administrators provide a grace period of 1-2 days between warning an account holder of content that needs to be removed and physically removing or disabling the account. This will give the content owner an opportunity to export their channel meta-data and import it to another site. In rare cases the content may be of such a nature to justify the immediate termination of the account. This is a hub decision, not a $Projectname decision.
-
-If you typically and regularly post content of an adult or offensive nature, you are STRONGLY encouraged to mark your account "NSFW" (Not Safe For Work). This will prevent the display of your profile photo in the directory except to viewers that have chosen to disable "safe mode". If your profile photo is found by directory administrators to be adult or offensive, the directory administrator MAY flag your profile photo as NSFW. There is currently no official mechanism to contest or reverse this decision, which is why you SHOULD mark your own account NSFW if it is likely to be inappropriate for general audiences.
-
-[h3]Credits[/h3]
-
-Thanks to all who have helped and contributed to the project and its predecessors over the years.
-It is possible we missed in your name but this is unintentional. We also thank the community and
-its members for providing valuable input and without whom this entire effort would be meaningless.
-
-It is also worth acknowledging the contributions and solutions to problems which arose from
-discussions amongst members and developers of other somewhat related and competing projects;
-even if we have had our occasional disagreements.
-
-[list]
-[li]Mike Macgirvin[/li]
-[li]Fabio Comuni[/li]
-[li]Simon L'nu[/li]
-[li]marijus[/li]
-[li]Tobias Diekershoff[/li]
-[li]fabrixxm[/li]
-[li]tommy tomson[/li]
-[li]Simon[/li]
-[li]zottel[/li]
-[li]Christian Vogeley[/li]
-[li]Jeroen van Riet Paap (jeroenpraat)[/li]
-[li]Michael Vogel[/li]
-[li]erik[/li]
-[li]Zach Prezkuta[/li]
-[li]Paolo T[/li]
-[li]Michael Meer[/li]
-[li]Michael[/li]
-[li]Abinoam P. Marques Jr[/li]
-[li]Tobias Hößl[/li]
-[li]Alexander Kampmann[/li]
-[li]Olaf Conradi[/li]
-[li]Paolo Tacconi[/li]
-[li]tobiasd[/li]
-[li]Devlon Duthie[/li]
-[li]Zvi ben Yaakov (a.k.a rdc)[/li]
-[li]Alexandre Hannud Abdo[/li]
-[li]Olivier Migeot[/li]
-[li]Chris Case[/li]
-[li]Klaus Weidenbach[/li]
-[li]Michael Johnston[/li]
-[li]olivierm[/li]
-[li]Vasudev Kamath[/li]
-[li]pixelroot[/li]
-[li]Max Weller[/li]
-[li]duthied[/li]
-[li]Martin Schmitt[/li]
-[li]Sebastian Egbers[/li]
-[li]Erkan Yilmaz[/li]
-[li]sasiflo[/li]
-[li]Stefan Parviainen[/li]
-[li]Haakon Meland Eriksen[/li]
-[li]Oliver Hartmann (23n)[/li]
-[li]Erik Lundin[/li]
-[li]habeascodice[/li]
-[li]sirius[/li]
-[li]Charles[/li]
-[li]Tony Baldwin[/li]
-[li]Hauke Zuehl[/li]
-[li]Keith Fernie[/li]
-[li]Anne Walk[/li]
-[li]toclimb[/li]
-[li]Daniel Frank[/li]
-[li]Matthew Exon[/li]
-[li]Michal Supler[/li]
-[li]Tobias Luther[/li]
-[li]U-SOUND\mike[/li]
-[li]mrjive[/li]
-[li]nostupidzone[/li]
-[li]tonnerkiller[/li]
-[li]Antoine G[/li]
-[li]Christian Drechsler[/li]
-[li]Ludovic Grossard[/li]
-[li]RedmatrixCanada[/li]
-[li]Stanislav Lechev [0xAF][/li]
-[li]aweiher[/li]
-[li]bufalo1973[/li]
-[li]dsp1986[/li]
-[li]felixgilles[/li]
-[li]ike[/li]
-[li]maase2[/li]
-[li]mycocham[/li]
-[li]ndurchx[/li]
-[li]pafcu[/li]
-[li]Simó Albert i Beltran[/li]
-[li]Manuel Reva[/li]
-[li]Manuel Jiménez Friaza[/li]
-[/list]
\ No newline at end of file
diff --git a/doc/about/project.bb b/doc/about/project.bb
new file mode 100644
index 000000000..7a584687d
--- /dev/null
+++ b/doc/about/project.bb
@@ -0,0 +1,185 @@
+[h3]$Projectname Governance[/h3]
+Governance relates to the management of a project and particularly how this relates to conflict resolution.
+
+[h4]Community Governance[/h4]
+The project is maintained and decisions made by the 'community'. The governance structure is still evolving. Until the structure is finalised, decisions are made in the following order:
+
+[ol]
+[*] Lazy Consensus
+
+If a project proposal is made to one of the community governance forums and there are no serious objections in a "reasonable" amount of time from date of proposal (we usually provide 2-3 days for all interested parties to weigh in), no vote needs to be taken and the proposal will be considered approved. Some concerns may be raised at this time, but if these are addressed during discussion and work-arounds provided, it will still be considered approved.
+
+
+[*] Veto
+
+Senior developers with a significant history of project commits may veto any decision. The decision may not proceed until the veto is removed or an alternative proposal is presented.
+
+
+[*] Community Vote
+
+A decision which does not have a clear mandate or clear consensus, but is not vetoed, can be taken to a community vote. At present this is a simple popular vote in one of the applicable community forums. At this time, popular vote decides the outcome. This may change in the future if the community adopts a 'council' governance model. This document will be updated at that time with the updated governance rules.
+[/ol]
+
+Community Voting does not always provide a pleasant outcome and can generate polarised factions in the community (hence the reason why other models are under consideration). If the proposal is 'down voted' there are still several things which can be done and the proposal re-submitted with slightly different parameters (convert to an addon, convert to an optional feature which is disabled by default, etc.). If interest in the feature is high and the vote is "close", it can generate lots of bad feelings amongst the losing voters. On such close votes, it is [b]strongly recommended[/b] that the proposer take steps to address any concerns that were raised and re-submit.
+
+
+
+[h4]Privacy Policy[/h4]
+
+Q: Who can see my content?
+
+A: By default ANYBODY on the internet, UNLESS you restrict it. $Projectname allows you to choose the privacy level you desire. Restricted content will NOT be visible to "spy networks" and advertisers. It will be protected against eavesdropping by outsiders - to the best of our ability. Hub administrators with sufficient skills and patience MAY be able to eavesdrop on some private communications but they must expend effort to do so. Privacy modes exist within $Projectname which are even resistant to eavesdropping by skilled and determined hub administrators.
+
+Q: Can my content be censored?
+
+A: $Projectname (the network) CANNOT censor your content. Server and hub administrators are subject to local laws and MAY remove objectionable content from their site/hub. Anybody MAY become a hub administrator, including you; and therefore publish content which might otherwise be censored. You still MAY be subject to local laws.
+
+
+[h5]Definitions[/h5]
+
+**$Projectname**
+
+Otherwise referred to as "the network", $Projectname is a collection of individual computers/servers (aka **hubs**) which connect together to form a larger cooperative network.
+
+**hub**
+
+An individual computer or server connected to $Projectname. These are provided by a **hub administrator** and may be public or private, paid or free.
+
+**hub administrator**
+
+The system operator of an individual hub.
+
+[h5]Policies[/h5]
+
+**Public Information**
+
+Any information or anything posted by you within $Projectname MAY be public or visible to anybody on the internet. To the extent possible, $Projectname allows you to protect content and restrict who can view it.
+
+Your profile photo, your channel name, and the location (URL or network address) of your channel are visible to anybody on the internet and privacy controls will not affect the display of these items.
+
+You MAY additionally provide other profile information. Any information which you provide in your "default" or **public profile** MAY be transmitted to other hubs in $Projectname and additionally MAY be displayed in the channel directory. You can restrict the viewing of this profile information. It may be restricted only to members of your hub, or only connections (friends), or other limited sets of viewers as you desire. If you wish for your profile to be restricted, you must set the appropriate privacy setting, or simply DO NOT provide additional information.
+
+**Content**
+
+Content you provide (status posts, photos, files, etc.) belongs to you. $Projectname default is to publish content openly and visible to anybody on the internet (PUBLIC). You MAY control this in your channel settings and restrict the default permissions or you MAY restrict the visibility of any single published item separately (PRIVATE). $Projectname developers will ensure that restricted content is ONLY visible to those in the restriction list - to the best of their ability.
+
+Content (especially status posts) that you share with other networks or that you have made visible to anybody on the internet (PUBLIC) cannot easily be taken back once it has been published. It MAY be shared with other networks and made available through RSS/Atom feeds. It may also be syndicated on other $Projectname sites. It MAY appear on other networks and websites and be visible in internet searches. If you do not wish this default behaviour please adjust your channel settings and restrict who can see your content.
+
+**Comments and Forum posts**
+
+Comments to posts that were created by others and posts which are designated as forum posts belong to you as the creator/author, but the distribution of these posts is not under your direct control, and you relinquish SOME rights to these items. These posts/comments MAY be re-distributed to others, and MAY be visible to anybody on the internet. In the case of comments, the creator of the "first message" in the thread (conversation) to which you are replying controls the distribution of all comments and replies to that message. They "own" and therefore have certain rights with regard to the entire conversation (including all comments contained within it). You can still edit or delete the comment, but the conversation owner also has rights to edit, delete, re-distribute, and backup/restore any or all the content from the conversation.
+
+**Private Information**
+
+$Projectname developers will ensure that any content you provide which is designated as PRIVATE will be protected against eavesdropping - to the best of their ability. Private channel content CAN be seen in the database of every involved hub administrator, but private messages are obscured in the database. The latter means that it is very difficult, but NOT impossible for this content to be seen by a hub administrator. Private channel content and private messages are also stripped from email notifications. End to end encryption is provided as an optional feature and this CANNOT be seen, even by a determined administrator.
+
+[h5]Identity Privacy[/h5]
+
+Privacy for your identity is another aspect. Because you have a decentralized identity in $Projectname, your privacy extends beyond your home hub. If you want to have complete control of your privacy and security you should run your own hub on a dedicated server. For many people, this is complicated and may stretch their technical abilities. So let's list a few precautions you can make to assure your privacy as much as possible.
+
+A decentralized identity has a lot of advantages and gives you al lot of interesting features, but you should be aware of the fact that your identity is known by other hubs in $Projectname network. One of those advantages is that other channels can serve you customized content and allow you to see private things (such as private photos which others wish to share with you). Because of this those channels need to know who you are. But we understand that sometimes those other channels know more from you than you might desire. For instance the plug-in Visage that can tell a channel owner the last time you visit their profile. You can easily OPT-OUT of this low level and we think, harmless tracking.
+
+* You can enable [Do Not Track (DNT)](http://donottrack.us/) in your web browser. We respect this new privacy policy proposal. All modern browsers support DNT. You will find it in the privacy settings of your browsers or else you can consult the web browser's manual. This will not affect the functionality of $Projectname. This setting is probably enough for most people.
+
+*You can [disable publication](settings) of your channel in our channel directory. If you want people to find your channel, you should give your channel address directly to them. We think this is a good indication that you prefer extra privacy and automatically enable "Do Not Track" if this is the case.
+
+* You can have a blocked hub. That means that all channels and content on that hub is not public, and not visible to the outside world. This is something only your hub administrator can do. We also respect this and automatically enable "Do Not Track" if it is set.
+
+[h5]Censorship[/h5]
+
+$Projectname is a global network which is inclusive of all religions and cultures. This does not imply that every member of the network feels the same way you do on contentious issues, and some people may be STRONGLY opposed to the content you post. In general, if you wish to post something that you know may nor be universally acceptable, the best approach is to restrict the audience using privacy controls to a small circle of friends.
+
+$Projectname as a network provider is unable to censor content. However, hub administrators MAY censor any content which appears on their hub to comply with local laws or even personal judgement. Their decision is final. If you have issues with any hub administrator, you may move your account and postings to another site which is more in line with your expectations. Please check (periodically) the [Terms of Service](help/TermsOfService) of your hub to learn about any rules or guidelines. If your content consists of material which is illegal or may cause issues, you are STRONGLY encouraged to host your own (become a hub administrator). You may still find that your content is blocked on some hubs, but $Projectname as a network cannot block it from being posted.
+
+$Projectname RECOMMENDS that hub administrators provide a grace period of 1-2 days between warning an account holder of content that needs to be removed and physically removing or disabling the account. This will give the content owner an opportunity to export their channel meta-data and import it to another site. In rare cases the content may be of such a nature to justify the immediate termination of the account. This is a hub decision, not a $Projectname decision.
+
+If you typically and regularly post content of an adult or offensive nature, you are STRONGLY encouraged to mark your account "NSFW" (Not Safe For Work). This will prevent the display of your profile photo in the directory except to viewers that have chosen to disable "safe mode". If your profile photo is found by directory administrators to be adult or offensive, the directory administrator MAY flag your profile photo as NSFW. There is currently no official mechanism to contest or reverse this decision, which is why you SHOULD mark your own account NSFW if it is likely to be inappropriate for general audiences.
+
+[h3]Credits[/h3]
+
+Thanks to all who have helped and contributed to the project and its predecessors over the years.
+It is possible we missed in your name but this is unintentional. We also thank the community and
+its members for providing valuable input and without whom this entire effort would be meaningless.
+
+It is also worth acknowledging the contributions and solutions to problems which arose from
+discussions amongst members and developers of other somewhat related and competing projects;
+even if we have had our occasional disagreements.
+
+[list]
+[li]Mike Macgirvin[/li]
+[li]Fabio Comuni[/li]
+[li]Simon L'nu[/li]
+[li]marijus[/li]
+[li]Tobias Diekershoff[/li]
+[li]fabrixxm[/li]
+[li]tommy tomson[/li]
+[li]Simon[/li]
+[li]zottel[/li]
+[li]Christian Vogeley[/li]
+[li]Jeroen van Riet Paap (jeroenpraat)[/li]
+[li]Michael Vogel[/li]
+[li]erik[/li]
+[li]Zach Prezkuta[/li]
+[li]Paolo T[/li]
+[li]Michael Meer[/li]
+[li]Michael[/li]
+[li]Abinoam P. Marques Jr[/li]
+[li]Tobias Hößl[/li]
+[li]Alexander Kampmann[/li]
+[li]Olaf Conradi[/li]
+[li]Paolo Tacconi[/li]
+[li]tobiasd[/li]
+[li]Devlon Duthie[/li]
+[li]Zvi ben Yaakov (a.k.a rdc)[/li]
+[li]Alexandre Hannud Abdo[/li]
+[li]Olivier Migeot[/li]
+[li]Chris Case[/li]
+[li]Klaus Weidenbach[/li]
+[li]Michael Johnston[/li]
+[li]olivierm[/li]
+[li]Vasudev Kamath[/li]
+[li]pixelroot[/li]
+[li]Max Weller[/li]
+[li]duthied[/li]
+[li]Martin Schmitt[/li]
+[li]Sebastian Egbers[/li]
+[li]Erkan Yilmaz[/li]
+[li]sasiflo[/li]
+[li]Stefan Parviainen[/li]
+[li]Haakon Meland Eriksen[/li]
+[li]Oliver Hartmann (23n)[/li]
+[li]Erik Lundin[/li]
+[li]habeascodice[/li]
+[li]sirius[/li]
+[li]Charles[/li]
+[li]Tony Baldwin[/li]
+[li]Hauke Zuehl[/li]
+[li]Keith Fernie[/li]
+[li]Anne Walk[/li]
+[li]toclimb[/li]
+[li]Daniel Frank[/li]
+[li]Matthew Exon[/li]
+[li]Michal Supler[/li]
+[li]Tobias Luther[/li]
+[li]U-SOUND\mike[/li]
+[li]mrjive[/li]
+[li]nostupidzone[/li]
+[li]tonnerkiller[/li]
+[li]Antoine G[/li]
+[li]Christian Drechsler[/li]
+[li]Ludovic Grossard[/li]
+[li]RedmatrixCanada[/li]
+[li]Stanislav Lechev [0xAF][/li]
+[li]aweiher[/li]
+[li]bufalo1973[/li]
+[li]dsp1986[/li]
+[li]felixgilles[/li]
+[li]ike[/li]
+[li]maase2[/li]
+[li]mycocham[/li]
+[li]ndurchx[/li]
+[li]pafcu[/li]
+[li]Simó Albert i Beltran[/li]
+[li]Manuel Reva[/li]
+[li]Manuel Jiménez Friaza[/li]
+[/list]
\ No newline at end of file
diff --git a/doc/toc.html b/doc/toc.html
index 3c9c5c299..285794689 100644
--- a/doc/toc.html
+++ b/doc/toc.html
@@ -7,8 +7,8 @@
-
-
-**What is Hubzilla?**
-
-Hubzilla is a general purpose communication server integrated with a web publishing system and a decentralised permission system. If this sounds like a bunch of technical mumbo-jumbo to you, just think of it as an independent platform for sharing stuff online.
-
-Hubzilla contains some social network bits, some cloud storage bits, some blog and forum bits, and some content management bits. These are all integrated within a common privacy framework - and it is all decentralised.
-
-Everything you publish or share can be restricted to those channels and people you wish to share them with; and these permissions work completely invisibly - even with channels on different servers or other communications services.
-
-Migration and live backups of your connections, settings, and everything you publish are built-in, so you never need worry about server failure.
-
-Hubzilla is completely decentralised and open source, for you modify or adapt to your needs and desires. Plugins, themes, and numerous configuration options extend the overall capabilities to do anything you can imagine.
-
-
-**Who Are We?**
-
-The Hubzilla community consists of passionate volunteers creating an open source commons of decentralised services which are highly integrated and can rival the feature set of large centralised providers. We do our best to provide ethical software which places you in control of your online communications and privacy expectations.
-
-
-[![Build Status](https://travis-ci.org/redmatrix/hubzilla.svg)](https://travis-ci.org/redmatrix/hubzilla)
+This is red.
\ No newline at end of file
--
cgit v1.2.3
From 4bb90dffc13f8c2252a55ea26466088d70379130 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Sun, 12 Mar 2017 17:45:51 -0700
Subject: update license
---
LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/LICENSE b/LICENSE
index 25c4bf1a3..bb0e40327 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010-2017 the Hubzilla Community
+Copyright (c) 2010-2017 Mike Macgirvin
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
--
cgit v1.2.3
From 1ee76cb5066870db9ea427e00e5c18edfb292496 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Sun, 12 Mar 2017 20:54:48 -0700
Subject: remove more hardwired branding
---
doc/tutorials/personal_channel.html | 10 +++---
include/network.php | 52 +++++++++++++--------------
include/photos.php | 70 +++++++++++++++++++------------------
3 files changed, 67 insertions(+), 65 deletions(-)
diff --git a/doc/tutorials/personal_channel.html b/doc/tutorials/personal_channel.html
index f2ad87077..9dbc2aaec 100644
--- a/doc/tutorials/personal_channel.html
+++ b/doc/tutorials/personal_channel.html
@@ -6,7 +6,7 @@ to a personal channel in a natural way.
Create a new channel
When you log in for the first time after registering, you must create a channel.
-(Alternatively you can load https://grid.reticu.li/new_channel)
+(Alternatively you can visit https://your_website/new_channel)
@@ -76,7 +76,7 @@ so you can specify exactly who can access this post.
Use an uploaded image as a channel cover photo
One way to add some pizzazz your channel is to add a cover photo that visitors will
-see when they load your channel page. Hubzilla's integrated cloud file system
+see when they load your channel page. The integrated cloud file system
allows you to choose an existing photo for this purpose.
Visit your photos in the Photos app
@@ -99,9 +99,9 @@ channel page will fade in as you scroll down.
Make a connection
-
Making connections between channels to share things is what Hubzilla is all about.
+
Making connections between channels to share things is what social communications are all about.
Making a connection is simple. If you do not already know how to reach a channel's home
-page, you might try a directory search by opening the Directory link on the right
+page, you might try a directory search by opening the Directory link from the menu on the right
side of the top navbar.
@@ -160,4 +160,4 @@ editor by pressing the edit button beside the Delete button.
-
\ No newline at end of file
+
diff --git a/include/network.php b/include/network.php
index 4d0bc6f0b..bce59d38c 100644
--- a/include/network.php
+++ b/include/network.php
@@ -1611,33 +1611,33 @@ function get_site_info() {
- $data = Array(
- 'version' => $version,
- 'version_tag' => $tag,
- 'server_role' => Zotlabs\Lib\System::get_server_role(),
- 'commit' => $commit,
- 'url' => z_root(),
- 'plugins' => $visible_plugins,
- 'register_policy' => $register_policy[get_config('system','register_policy')],
- 'invitation_only' => intval(get_config('system','invitation_only')),
- 'directory_mode' => $directory_mode[get_config('system','directory_mode')],
- 'language' => get_config('system','language'),
- 'rss_connections' => intval(get_config('system','feed_contacts')),
- 'expiration' => $site_expire,
+ $data = [
+ 'url' => z_root(),
+ 'platform' => Zotlabs\Lib\System::get_platform_name(),
+ 'site_name' => (($site_name) ? $site_name : ''),
+ 'version' => $version,
+ 'version_tag' => $tag,
+ 'server_role' => Zotlabs\Lib\System::get_server_role(),
+ 'commit' => $commit,
+ 'plugins' => $visible_plugins,
+ 'register_policy' => $register_policy[get_config('system','register_policy')],
+ 'invitation_only' => intval(get_config('system','invitation_only')),
+ 'directory_mode' => $directory_mode[get_config('system','directory_mode')],
+ 'language' => get_config('system','language'),
+ 'rss_connections' => intval(get_config('system','feed_contacts')),
+ 'expiration' => $site_expire,
'default_service_restrictions' => $service_class,
- 'locked_features' => $locked_features,
- 'admin' => $admin,
- 'site_name' => (($site_name) ? $site_name : ''),
- 'platform' => Zotlabs\Lib\System::get_platform_name(),
- 'dbdriver' => DBA::$dba->getdriver(),
- 'lastpoll' => get_config('system','lastpoll'),
- 'info' => (($site_info) ? $site_info : ''),
- 'channels_total' => $channels_total_stat,
- 'channels_active_halfyear' => $channels_active_halfyear_stat,
- 'channels_active_monthly' => $channels_active_monthly_stat,
- 'local_posts' => $local_posts_stat,
- 'hide_in_statistics' => $hide_in_statistics
- );
+ 'locked_features' => $locked_features,
+ 'admin' => $admin,
+ 'dbdriver' => DBA::$dba->getdriver(),
+ 'lastpoll' => get_config('system','lastpoll'),
+ 'info' => (($site_info) ? $site_info : ''),
+ 'channels_total' => $channels_total_stat,
+ 'channels_active_halfyear' => $channels_active_halfyear_stat,
+ 'channels_active_monthly' => $channels_active_monthly_stat,
+ 'local_posts' => $local_posts_stat,
+ 'hide_in_statistics' => $hide_in_statistics
+ ];
return $data;
}
diff --git a/include/photos.php b/include/photos.php
index c0f7dc8c4..68ff32924 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -17,6 +17,7 @@ require_once('include/text.php');
* @param array $args
* @return array
*/
+
function photo_upload($channel, $observer, $args) {
$ret = array('success' => false);
@@ -28,9 +29,6 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
-
-//call_hooks('photo_upload_begin', $args);
-
/*
* Determine the album to use
*/
@@ -90,8 +88,6 @@ function photo_upload($channel, $observer, $args) {
} else {
$f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
-// call_hooks('photo_upload_file',$f);
-
if (x($f,'src') && x($f,'filesize')) {
$src = $f['src'];
$filename = $f['filename'];
@@ -374,37 +370,37 @@ function photo_upload($channel, $observer, $args) {
else {
$mid = item_message_id();
- $arr = array();
-
- if($lat && $lon)
- $arr['coord'] = $lat . ' ' . $lon;
+ $arr = [
+ 'aid' => $account_id,
+ 'uid' => $channel_id,
+ 'mid' => $mid,
+ 'parent_mid' => $mid,
+ 'item_hidden' => $item_hidden,
+ 'resource_type' => 'photo',
+ 'resource_id' => $photo_hash,
+ 'owner_xchan' => $channel['channel_hash'],
+ 'author_xchan' => $observer['xchan_hash'],
+ 'title' => $title,
+ 'allow_cid' => $ac['allow_cid'],
+ 'allow_gid' => $ac['allow_gid'],
+ 'deny_cid' => $ac['deny_cid'],
+ 'deny_gid' => $ac['deny_gid'],
+ 'verb' => ACTIVITY_POST,
+ 'obj_type' => ACTIVITY_OBJ_PHOTO,
+ 'obj' => json_encode($object),
+ 'tgt_type' => ACTIVITY_OBJ_ALBUM,
+ 'target' => json_encode($target),
+ 'item_wall' => $visible,
+ 'item_origin' => 1,
+ 'item_thread_top' => 1,
+ 'item_private' => intval($acl->is_private()),
+ 'body' => $summary
+ ];
- $arr['aid'] = $account_id;
- $arr['uid'] = $channel_id;
- $arr['mid'] = $mid;
- $arr['parent_mid'] = $mid;
- $arr['item_hidden'] = $item_hidden;
- $arr['resource_type'] = 'photo';
- $arr['resource_id'] = $photo_hash;
- $arr['owner_xchan'] = $channel['channel_hash'];
- $arr['author_xchan'] = $observer['xchan_hash'];
- $arr['title'] = $title;
- $arr['allow_cid'] = $ac['allow_cid'];
- $arr['allow_gid'] = $ac['allow_gid'];
- $arr['deny_cid'] = $ac['deny_cid'];
- $arr['deny_gid'] = $ac['deny_gid'];
- $arr['verb'] = ACTIVITY_POST;
- $arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
- $arr['obj'] = json_encode($object);
- $arr['tgt_type'] = ACTIVITY_OBJ_ALBUM;
- $arr['target'] = json_encode($target);
- $arr['item_wall'] = 1;
- $arr['item_origin'] = 1;
- $arr['item_thread_top'] = 1;
- $arr['item_private'] = intval($acl->is_private());
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
- $arr['body'] = $summary;
+ if($lat && $lon)
+ $arr['coord'] = $lat . ' ' . $lon;
// this one is tricky because the item and the photo have the same permissions, those of the photo.
// Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
@@ -451,6 +447,7 @@ function photo_upload($channel, $observer, $args) {
* * \e boolean \b success
* * \e array \b albums
*/
+
function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') {
$channel_id = $channel['channel_id'];
@@ -531,6 +528,7 @@ function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction =
* @param string $album default empty
* @return boolean|array
*/
+
function photos_list_photos($channel, $observer, $album = '') {
$channel_id = $channel['channel_id'];
@@ -570,6 +568,7 @@ function photos_list_photos($channel, $observer, $album = '') {
* @param string $album name of the album
* @return boolean
*/
+
function photos_album_exists($channel_id, $album) {
$r = q("SELECT id FROM photo WHERE album = '%s' AND uid = %d limit 1",
dbesc($album),
@@ -589,6 +588,7 @@ function photos_album_exists($channel_id, $album) {
* @param string $newname The new name of the album
* @return bool|array
*/
+
function photos_album_rename($channel_id, $oldname, $newname) {
return q("UPDATE photo SET album = '%s' WHERE album = '%s' AND uid = %d",
dbesc($newname),
@@ -607,6 +607,7 @@ function photos_album_rename($channel_id, $oldname, $newname) {
* @param string $remote_xchan
* @return string|boolean
*/
+
function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') {
if ($remote_xchan) {
@@ -642,6 +643,7 @@ function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') {
* @param boolean $visible default false
* @return int item_id
*/
+
function photos_create_item($channel, $creator_hash, $photo, $visible = false) {
// Create item container
@@ -697,7 +699,7 @@ function getGps($exifCoord, $hemi) {
function getGpstimestamp($exifCoord) {
- $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
+ $hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
$minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
$seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;
--
cgit v1.2.3
From fc533107ed49735aad5ba39bf02b87ed7ac870b6 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Sun, 12 Mar 2017 21:55:24 -0700
Subject: better handling of mimetype security
---
Zotlabs/Lib/System.php | 2 --
Zotlabs/Module/Editwebpage.php | 2 --
Zotlabs/Module/Item.php | 23 +++++++----------------
3 files changed, 7 insertions(+), 20 deletions(-)
diff --git a/Zotlabs/Lib/System.php b/Zotlabs/Lib/System.php
index 865cb9a30..3d5b18506 100644
--- a/Zotlabs/Lib/System.php
+++ b/Zotlabs/Lib/System.php
@@ -54,8 +54,6 @@ class System {
return 'https://github.com/redmatrix/hubzilla';
}
-
-
static public function get_server_role() {
return 'pro';
}
diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php
index 3d4af107d..97f4a32ff 100644
--- a/Zotlabs/Module/Editwebpage.php
+++ b/Zotlabs/Module/Editwebpage.php
@@ -130,8 +130,6 @@ class Editwebpage extends \Zotlabs\Web\Controller {
$layout = $itm[0]['layout_mid'];
- $tpl = get_markup_template("jot.tpl");
-
$rp = 'webpages/' . $which;
$x = array(
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 4725ecb38..afac1542d 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -480,22 +480,13 @@ class Item extends \Zotlabs\Web\Controller {
$execflag = false;
- if($mimetype !== 'text/bbcode') {
- $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1",
- intval($profile_uid)
- );
- if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
- if($uid && (get_account_id() == $z[0]['account_id'])) {
- $execflag = true;
- }
- else {
- notice( t('Executable content type not permitted to this channel.') . EOL);
- if($api_source)
- return ( [ 'success' => false, 'message' => 'forbidden content type' ] );
- if(x($_REQUEST,'return'))
- goaway(z_root() . "/" . $return_path );
- killme();
- }
+ $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id
+ where channel_id = %d limit 1",
+ intval($profile_uid)
+ );
+ if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
+ if($uid && (intval(get_account_id()) == intval($z[0]['account_id']))) {
+ $execflag = true;
}
}
--
cgit v1.2.3
From 6c641b1834539c65edb35dd43a6afa7620e73e1c Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 09:09:05 +1100
Subject: move oauth2 to vendor
---
composer.json | 3 +-
composer.lock | 2851 +-------------------
library/oauth2/.gitignore | 5 -
library/oauth2/.travis.yml | 30 -
library/oauth2/CHANGELOG.md | 152 --
library/oauth2/LICENSE | 21 -
library/oauth2/README.md | 8 -
library/oauth2/phpunit.xml | 25 -
library/oauth2/src/OAuth2/Autoloader.php | 48 -
.../ClientAssertionTypeInterface.php | 15 -
.../src/OAuth2/ClientAssertionType/HttpBasic.php | 123 -
.../src/OAuth2/Controller/AuthorizeController.php | 388 ---
.../Controller/AuthorizeControllerInterface.php | 43 -
.../src/OAuth2/Controller/ResourceController.php | 111 -
.../Controller/ResourceControllerInterface.php | 26 -
.../src/OAuth2/Controller/TokenController.php | 278 --
.../OAuth2/Controller/TokenControllerInterface.php | 32 -
.../src/OAuth2/Encryption/EncryptionInterface.php | 11 -
.../oauth2/src/OAuth2/Encryption/FirebaseJwt.php | 47 -
library/oauth2/src/OAuth2/Encryption/Jwt.php | 173 --
.../src/OAuth2/GrantType/AuthorizationCode.php | 100 -
.../src/OAuth2/GrantType/ClientCredentials.php | 67 -
.../src/OAuth2/GrantType/GrantTypeInterface.php | 20 -
library/oauth2/src/OAuth2/GrantType/JwtBearer.php | 226 --
.../oauth2/src/OAuth2/GrantType/RefreshToken.php | 111 -
.../src/OAuth2/GrantType/UserCredentials.php | 83 -
.../OpenID/Controller/AuthorizeController.php | 106 -
.../Controller/AuthorizeControllerInterface.php | 10 -
.../OpenID/Controller/UserInfoController.php | 58 -
.../Controller/UserInfoControllerInterface.php | 23 -
.../OAuth2/OpenID/GrantType/AuthorizationCode.php | 33 -
.../OpenID/ResponseType/AuthorizationCode.php | 60 -
.../ResponseType/AuthorizationCodeInterface.php | 27 -
.../src/OAuth2/OpenID/ResponseType/CodeIdToken.php | 24 -
.../OpenID/ResponseType/CodeIdTokenInterface.php | 9 -
.../src/OAuth2/OpenID/ResponseType/IdToken.php | 124 -
.../OpenID/ResponseType/IdTokenInterface.php | 29 -
.../OAuth2/OpenID/ResponseType/IdTokenToken.php | 27 -
.../OpenID/ResponseType/IdTokenTokenInterface.php | 9 -
.../OpenID/Storage/AuthorizationCodeInterface.php | 37 -
.../OAuth2/OpenID/Storage/UserClaimsInterface.php | 38 -
library/oauth2/src/OAuth2/Request.php | 213 --
library/oauth2/src/OAuth2/RequestInterface.php | 16 -
library/oauth2/src/OAuth2/Response.php | 369 ---
library/oauth2/src/OAuth2/ResponseInterface.php | 24 -
.../oauth2/src/OAuth2/ResponseType/AccessToken.php | 194 --
.../OAuth2/ResponseType/AccessTokenInterface.php | 34 -
.../src/OAuth2/ResponseType/AuthorizationCode.php | 100 -
.../ResponseType/AuthorizationCodeInterface.php | 30 -
.../src/OAuth2/ResponseType/JwtAccessToken.php | 124 -
.../OAuth2/ResponseType/ResponseTypeInterface.php | 8 -
library/oauth2/src/OAuth2/Scope.php | 103 -
library/oauth2/src/OAuth2/ScopeInterface.php | 40 -
library/oauth2/src/OAuth2/Server.php | 832 ------
.../src/OAuth2/Storage/AccessTokenInterface.php | 64 -
.../OAuth2/Storage/AuthorizationCodeInterface.php | 86 -
library/oauth2/src/OAuth2/Storage/Cassandra.php | 480 ----
.../OAuth2/Storage/ClientCredentialsInterface.php | 49 -
.../oauth2/src/OAuth2/Storage/ClientInterface.php | 66 -
library/oauth2/src/OAuth2/Storage/CouchbaseDB.php | 331 ---
library/oauth2/src/OAuth2/Storage/DynamoDB.php | 540 ----
.../oauth2/src/OAuth2/Storage/JwtAccessToken.php | 88 -
.../src/OAuth2/Storage/JwtAccessTokenInterface.php | 14 -
.../src/OAuth2/Storage/JwtBearerInterface.php | 74 -
library/oauth2/src/OAuth2/Storage/Memory.php | 381 ---
library/oauth2/src/OAuth2/Storage/Mongo.php | 339 ---
library/oauth2/src/OAuth2/Storage/Pdo.php | 553 ----
.../src/OAuth2/Storage/PublicKeyInterface.php | 16 -
library/oauth2/src/OAuth2/Storage/Redis.php | 321 ---
.../src/OAuth2/Storage/RefreshTokenInterface.php | 82 -
.../oauth2/src/OAuth2/Storage/ScopeInterface.php | 46 -
.../OAuth2/Storage/UserCredentialsInterface.php | 52 -
library/oauth2/src/OAuth2/TokenType/Bearer.php | 130 -
library/oauth2/src/OAuth2/TokenType/Mac.php | 22 -
.../src/OAuth2/TokenType/TokenTypeInterface.php | 21 -
library/oauth2/test/OAuth2/AutoloadTest.php | 16 -
.../OAuth2/Controller/AuthorizeControllerTest.php | 492 ----
.../OAuth2/Controller/ResourceControllerTest.php | 175 --
.../test/OAuth2/Controller/TokenControllerTest.php | 289 --
.../test/OAuth2/Encryption/FirebaseJwtTest.php | 102 -
library/oauth2/test/OAuth2/Encryption/JwtTest.php | 102 -
.../OAuth2/GrantType/AuthorizationCodeTest.php | 207 --
.../OAuth2/GrantType/ClientCredentialsTest.php | 159 --
.../oauth2/test/OAuth2/GrantType/ImplicitTest.php | 143 -
.../oauth2/test/OAuth2/GrantType/JwtBearerTest.php | 360 ---
.../test/OAuth2/GrantType/RefreshTokenTest.php | 204 --
.../test/OAuth2/GrantType/UserCredentialsTest.php | 172 --
.../OpenID/Controller/AuthorizeControllerTest.php | 182 --
.../OpenID/Controller/UserInfoControllerTest.php | 44 -
.../OpenID/GrantType/AuthorizationCodeTest.php | 57 -
.../OAuth2/OpenID/ResponseType/CodeIdTokenTest.php | 182 --
.../OAuth2/OpenID/ResponseType/IdTokenTest.php | 184 --
.../OpenID/ResponseType/IdTokenTokenTest.php | 91 -
.../OpenID/Storage/AuthorizationCodeTest.php | 95 -
.../test/OAuth2/OpenID/Storage/UserClaimsTest.php | 41 -
library/oauth2/test/OAuth2/RequestTest.php | 98 -
library/oauth2/test/OAuth2/ResponseTest.php | 17 -
.../test/OAuth2/ResponseType/AccessTokenTest.php | 107 -
.../OAuth2/ResponseType/JwtAccessTokenTest.php | 160 --
library/oauth2/test/OAuth2/ScopeTest.php | 42 -
library/oauth2/test/OAuth2/ServerTest.php | 684 -----
.../oauth2/test/OAuth2/Storage/AccessTokenTest.php | 102 -
.../test/OAuth2/Storage/AuthorizationCodeTest.php | 106 -
.../test/OAuth2/Storage/ClientCredentialsTest.php | 28 -
library/oauth2/test/OAuth2/Storage/ClientTest.php | 110 -
.../oauth2/test/OAuth2/Storage/DynamoDBTest.php | 40 -
.../test/OAuth2/Storage/JwtAccessTokenTest.php | 41 -
.../oauth2/test/OAuth2/Storage/JwtBearerTest.php | 25 -
library/oauth2/test/OAuth2/Storage/PdoTest.php | 39 -
.../oauth2/test/OAuth2/Storage/PublicKeyTest.php | 29 -
.../test/OAuth2/Storage/RefreshTokenTest.php | 41 -
library/oauth2/test/OAuth2/Storage/ScopeTest.php | 53 -
.../test/OAuth2/Storage/UserCredentialsTest.php | 40 -
.../oauth2/test/OAuth2/TokenType/BearerTest.php | 58 -
library/oauth2/test/bootstrap.php | 12 -
library/oauth2/test/cleanup.php | 15 -
library/oauth2/test/config/keys/id_rsa | 15 -
library/oauth2/test/config/keys/id_rsa.pub | 16 -
library/oauth2/test/config/storage.json | 181 --
.../oauth2/test/lib/OAuth2/Request/TestRequest.php | 61 -
.../oauth2/test/lib/OAuth2/Storage/BaseTest.php | 34 -
.../oauth2/test/lib/OAuth2/Storage/Bootstrap.php | 888 ------
.../oauth2/test/lib/OAuth2/Storage/NullStorage.php | 32 -
vendor/autoload.php | 2 +-
vendor/bshaffer/oauth2-server-php/CHANGELOG.md | 182 ++
vendor/bshaffer/oauth2-server-php/LICENSE | 21 +
vendor/bshaffer/oauth2-server-php/README.md | 8 +
vendor/bshaffer/oauth2-server-php/composer.json | 34 +
.../oauth2-server-php/src/OAuth2/Autoloader.php | 48 +
.../ClientAssertionTypeInterface.php | 15 +
.../src/OAuth2/ClientAssertionType/HttpBasic.php | 123 +
.../src/OAuth2/Controller/AuthorizeController.php | 393 +++
.../Controller/AuthorizeControllerInterface.php | 43 +
.../src/OAuth2/Controller/ResourceController.php | 111 +
.../Controller/ResourceControllerInterface.php | 26 +
.../src/OAuth2/Controller/TokenController.php | 295 ++
.../OAuth2/Controller/TokenControllerInterface.php | 32 +
.../src/OAuth2/Encryption/EncryptionInterface.php | 11 +
.../src/OAuth2/Encryption/FirebaseJwt.php | 47 +
.../src/OAuth2/Encryption/Jwt.php | 173 ++
.../src/OAuth2/GrantType/AuthorizationCode.php | 100 +
.../src/OAuth2/GrantType/ClientCredentials.php | 67 +
.../src/OAuth2/GrantType/GrantTypeInterface.php | 20 +
.../src/OAuth2/GrantType/JwtBearer.php | 226 ++
.../src/OAuth2/GrantType/RefreshToken.php | 111 +
.../src/OAuth2/GrantType/UserCredentials.php | 83 +
.../OpenID/Controller/AuthorizeController.php | 106 +
.../Controller/AuthorizeControllerInterface.php | 10 +
.../OpenID/Controller/UserInfoController.php | 58 +
.../Controller/UserInfoControllerInterface.php | 23 +
.../OAuth2/OpenID/GrantType/AuthorizationCode.php | 33 +
.../OpenID/ResponseType/AuthorizationCode.php | 60 +
.../ResponseType/AuthorizationCodeInterface.php | 27 +
.../src/OAuth2/OpenID/ResponseType/CodeIdToken.php | 24 +
.../OpenID/ResponseType/CodeIdTokenInterface.php | 9 +
.../src/OAuth2/OpenID/ResponseType/IdToken.php | 124 +
.../OpenID/ResponseType/IdTokenInterface.php | 29 +
.../OAuth2/OpenID/ResponseType/IdTokenToken.php | 27 +
.../OpenID/ResponseType/IdTokenTokenInterface.php | 9 +
.../OpenID/Storage/AuthorizationCodeInterface.php | 37 +
.../OAuth2/OpenID/Storage/UserClaimsInterface.php | 38 +
.../oauth2-server-php/src/OAuth2/Request.php | 213 ++
.../src/OAuth2/RequestInterface.php | 16 +
.../oauth2-server-php/src/OAuth2/Response.php | 369 +++
.../src/OAuth2/ResponseInterface.php | 24 +
.../src/OAuth2/ResponseType/AccessToken.php | 194 ++
.../OAuth2/ResponseType/AccessTokenInterface.php | 34 +
.../src/OAuth2/ResponseType/AuthorizationCode.php | 100 +
.../ResponseType/AuthorizationCodeInterface.php | 30 +
.../src/OAuth2/ResponseType/JwtAccessToken.php | 124 +
.../OAuth2/ResponseType/ResponseTypeInterface.php | 8 +
.../oauth2-server-php/src/OAuth2/Scope.php | 103 +
.../src/OAuth2/ScopeInterface.php | 40 +
.../oauth2-server-php/src/OAuth2/Server.php | 879 ++++++
.../src/OAuth2/Storage/AccessTokenInterface.php | 64 +
.../OAuth2/Storage/AuthorizationCodeInterface.php | 86 +
.../src/OAuth2/Storage/Cassandra.php | 480 ++++
.../OAuth2/Storage/ClientCredentialsInterface.php | 49 +
.../src/OAuth2/Storage/ClientInterface.php | 66 +
.../src/OAuth2/Storage/CouchbaseDB.php | 331 +++
.../src/OAuth2/Storage/DynamoDB.php | 540 ++++
.../src/OAuth2/Storage/JwtAccessToken.php | 88 +
.../src/OAuth2/Storage/JwtAccessTokenInterface.php | 14 +
.../src/OAuth2/Storage/JwtBearerInterface.php | 74 +
.../src/OAuth2/Storage/Memory.php | 381 +++
.../oauth2-server-php/src/OAuth2/Storage/Mongo.php | 392 +++
.../src/OAuth2/Storage/MongoDB.php | 380 +++
.../oauth2-server-php/src/OAuth2/Storage/Pdo.php | 553 ++++
.../src/OAuth2/Storage/PublicKeyInterface.php | 16 +
.../oauth2-server-php/src/OAuth2/Storage/Redis.php | 321 +++
.../src/OAuth2/Storage/RefreshTokenInterface.php | 82 +
.../src/OAuth2/Storage/ScopeInterface.php | 46 +
.../OAuth2/Storage/UserCredentialsInterface.php | 52 +
.../src/OAuth2/TokenType/Bearer.php | 130 +
.../oauth2-server-php/src/OAuth2/TokenType/Mac.php | 22 +
.../src/OAuth2/TokenType/TokenTypeInterface.php | 21 +
.../oauth2-server-php/test/OAuth2/AutoloadTest.php | 16 +
.../OAuth2/Controller/AuthorizeControllerTest.php | 492 ++++
.../OAuth2/Controller/ResourceControllerTest.php | 176 ++
.../test/OAuth2/Controller/TokenControllerTest.php | 289 ++
.../test/OAuth2/Encryption/FirebaseJwtTest.php | 102 +
.../test/OAuth2/Encryption/JwtTest.php | 102 +
.../OAuth2/GrantType/AuthorizationCodeTest.php | 223 ++
.../OAuth2/GrantType/ClientCredentialsTest.php | 159 ++
.../test/OAuth2/GrantType/ImplicitTest.php | 143 +
.../test/OAuth2/GrantType/JwtBearerTest.php | 360 +++
.../test/OAuth2/GrantType/RefreshTokenTest.php | 204 ++
.../test/OAuth2/GrantType/UserCredentialsTest.php | 172 ++
.../OpenID/Controller/AuthorizeControllerTest.php | 182 ++
.../OpenID/Controller/UserInfoControllerTest.php | 44 +
.../OpenID/GrantType/AuthorizationCodeTest.php | 57 +
.../OAuth2/OpenID/ResponseType/CodeIdTokenTest.php | 182 ++
.../OAuth2/OpenID/ResponseType/IdTokenTest.php | 184 ++
.../OpenID/ResponseType/IdTokenTokenTest.php | 91 +
.../OpenID/Storage/AuthorizationCodeTest.php | 95 +
.../test/OAuth2/OpenID/Storage/UserClaimsTest.php | 41 +
.../oauth2-server-php/test/OAuth2/RequestTest.php | 98 +
.../oauth2-server-php/test/OAuth2/ResponseTest.php | 17 +
.../test/OAuth2/ResponseType/AccessTokenTest.php | 107 +
.../OAuth2/ResponseType/JwtAccessTokenTest.php | 160 ++
.../oauth2-server-php/test/OAuth2/ScopeTest.php | 42 +
.../oauth2-server-php/test/OAuth2/ServerTest.php | 684 +++++
.../test/OAuth2/Storage/AccessTokenTest.php | 102 +
.../test/OAuth2/Storage/AuthorizationCodeTest.php | 106 +
.../test/OAuth2/Storage/ClientCredentialsTest.php | 28 +
.../test/OAuth2/Storage/ClientTest.php | 110 +
.../test/OAuth2/Storage/DynamoDBTest.php | 40 +
.../test/OAuth2/Storage/JwtAccessTokenTest.php | 41 +
.../test/OAuth2/Storage/JwtBearerTest.php | 25 +
.../test/OAuth2/Storage/PdoTest.php | 39 +
.../test/OAuth2/Storage/PublicKeyTest.php | 29 +
.../test/OAuth2/Storage/RefreshTokenTest.php | 41 +
.../test/OAuth2/Storage/ScopeTest.php | 53 +
.../test/OAuth2/Storage/UserCredentialsTest.php | 40 +
.../test/OAuth2/TokenType/BearerTest.php | 58 +
.../bshaffer/oauth2-server-php/test/bootstrap.php | 12 +
vendor/bshaffer/oauth2-server-php/test/cleanup.php | 15 +
.../oauth2-server-php/test/config/keys/id_rsa | 15 +
.../oauth2-server-php/test/config/keys/id_rsa.pub | 16 +
.../oauth2-server-php/test/config/storage.json | 188 ++
.../test/lib/OAuth2/Request/TestRequest.php | 61 +
.../test/lib/OAuth2/Storage/BaseTest.php | 36 +
.../test/lib/OAuth2/Storage/Bootstrap.php | 967 +++++++
.../test/lib/OAuth2/Storage/NullStorage.php | 32 +
vendor/composer/ClassLoader.php | 48 +-
vendor/composer/LICENSE | 444 ++-
vendor/composer/autoload_classmap.php | 619 -----
vendor/composer/autoload_namespaces.php | 1 +
vendor/composer/autoload_real.php | 35 +-
vendor/composer/installed.json | 76 +-
250 files changed, 16171 insertions(+), 18459 deletions(-)
delete mode 100644 library/oauth2/.gitignore
delete mode 100644 library/oauth2/.travis.yml
delete mode 100644 library/oauth2/CHANGELOG.md
delete mode 100644 library/oauth2/LICENSE
delete mode 100644 library/oauth2/README.md
delete mode 100644 library/oauth2/phpunit.xml
delete mode 100644 library/oauth2/src/OAuth2/Autoloader.php
delete mode 100644 library/oauth2/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/ClientAssertionType/HttpBasic.php
delete mode 100644 library/oauth2/src/OAuth2/Controller/AuthorizeController.php
delete mode 100644 library/oauth2/src/OAuth2/Controller/AuthorizeControllerInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Controller/ResourceController.php
delete mode 100644 library/oauth2/src/OAuth2/Controller/ResourceControllerInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Controller/TokenController.php
delete mode 100644 library/oauth2/src/OAuth2/Controller/TokenControllerInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Encryption/EncryptionInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Encryption/FirebaseJwt.php
delete mode 100644 library/oauth2/src/OAuth2/Encryption/Jwt.php
delete mode 100644 library/oauth2/src/OAuth2/GrantType/AuthorizationCode.php
delete mode 100644 library/oauth2/src/OAuth2/GrantType/ClientCredentials.php
delete mode 100644 library/oauth2/src/OAuth2/GrantType/GrantTypeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/GrantType/JwtBearer.php
delete mode 100644 library/oauth2/src/OAuth2/GrantType/RefreshToken.php
delete mode 100644 library/oauth2/src/OAuth2/GrantType/UserCredentials.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeController.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/Controller/UserInfoController.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/GrantType/AuthorizationCode.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdToken.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/IdToken.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenToken.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/Storage/AuthorizationCodeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/OpenID/Storage/UserClaimsInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Request.php
delete mode 100644 library/oauth2/src/OAuth2/RequestInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Response.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseInterface.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseType/AccessToken.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseType/AccessTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseType/AuthorizationCode.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseType/JwtAccessToken.php
delete mode 100644 library/oauth2/src/OAuth2/ResponseType/ResponseTypeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Scope.php
delete mode 100644 library/oauth2/src/OAuth2/ScopeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Server.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/AccessTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/AuthorizationCodeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/Cassandra.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/ClientCredentialsInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/ClientInterface.php
delete mode 100755 library/oauth2/src/OAuth2/Storage/CouchbaseDB.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/DynamoDB.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/JwtAccessToken.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/JwtAccessTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/JwtBearerInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/Memory.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/Mongo.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/Pdo.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/PublicKeyInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/Redis.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/RefreshTokenInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/ScopeInterface.php
delete mode 100644 library/oauth2/src/OAuth2/Storage/UserCredentialsInterface.php
delete mode 100644 library/oauth2/src/OAuth2/TokenType/Bearer.php
delete mode 100644 library/oauth2/src/OAuth2/TokenType/Mac.php
delete mode 100644 library/oauth2/src/OAuth2/TokenType/TokenTypeInterface.php
delete mode 100644 library/oauth2/test/OAuth2/AutoloadTest.php
delete mode 100644 library/oauth2/test/OAuth2/Controller/AuthorizeControllerTest.php
delete mode 100644 library/oauth2/test/OAuth2/Controller/ResourceControllerTest.php
delete mode 100644 library/oauth2/test/OAuth2/Controller/TokenControllerTest.php
delete mode 100644 library/oauth2/test/OAuth2/Encryption/FirebaseJwtTest.php
delete mode 100644 library/oauth2/test/OAuth2/Encryption/JwtTest.php
delete mode 100644 library/oauth2/test/OAuth2/GrantType/AuthorizationCodeTest.php
delete mode 100644 library/oauth2/test/OAuth2/GrantType/ClientCredentialsTest.php
delete mode 100644 library/oauth2/test/OAuth2/GrantType/ImplicitTest.php
delete mode 100644 library/oauth2/test/OAuth2/GrantType/JwtBearerTest.php
delete mode 100644 library/oauth2/test/OAuth2/GrantType/RefreshTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/GrantType/UserCredentialsTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php
delete mode 100644 library/oauth2/test/OAuth2/OpenID/Storage/UserClaimsTest.php
delete mode 100644 library/oauth2/test/OAuth2/RequestTest.php
delete mode 100644 library/oauth2/test/OAuth2/ResponseTest.php
delete mode 100644 library/oauth2/test/OAuth2/ResponseType/AccessTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/ResponseType/JwtAccessTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/ScopeTest.php
delete mode 100644 library/oauth2/test/OAuth2/ServerTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/AccessTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/AuthorizationCodeTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/ClientCredentialsTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/ClientTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/DynamoDBTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/JwtAccessTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/JwtBearerTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/PdoTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/PublicKeyTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/RefreshTokenTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/ScopeTest.php
delete mode 100644 library/oauth2/test/OAuth2/Storage/UserCredentialsTest.php
delete mode 100644 library/oauth2/test/OAuth2/TokenType/BearerTest.php
delete mode 100644 library/oauth2/test/bootstrap.php
delete mode 100644 library/oauth2/test/cleanup.php
delete mode 100644 library/oauth2/test/config/keys/id_rsa
delete mode 100644 library/oauth2/test/config/keys/id_rsa.pub
delete mode 100644 library/oauth2/test/config/storage.json
delete mode 100644 library/oauth2/test/lib/OAuth2/Request/TestRequest.php
delete mode 100755 library/oauth2/test/lib/OAuth2/Storage/BaseTest.php
delete mode 100755 library/oauth2/test/lib/OAuth2/Storage/Bootstrap.php
delete mode 100644 library/oauth2/test/lib/OAuth2/Storage/NullStorage.php
create mode 100644 vendor/bshaffer/oauth2-server-php/CHANGELOG.md
create mode 100644 vendor/bshaffer/oauth2-server-php/LICENSE
create mode 100644 vendor/bshaffer/oauth2-server-php/README.md
create mode 100644 vendor/bshaffer/oauth2-server-php/composer.json
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Autoloader.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ClientAssertionType/HttpBasic.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeController.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeControllerInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceController.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceControllerInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenController.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenControllerInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/EncryptionInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/FirebaseJwt.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/Jwt.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/AuthorizationCode.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/ClientCredentials.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/GrantTypeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/JwtBearer.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/RefreshToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/UserCredentials.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeController.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/UserInfoController.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/GrantType/AuthorizationCode.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Storage/AuthorizationCodeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Storage/UserClaimsInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Request.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/RequestInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Response.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCode.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/JwtAccessToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/ResponseTypeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Scope.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/ScopeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Server.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AccessTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AuthorizationCodeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Cassandra.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientCredentialsInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientInterface.php
create mode 100755 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/DynamoDB.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessToken.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtBearerInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Memory.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Mongo.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/MongoDB.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/PublicKeyInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Redis.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/RefreshTokenInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/UserCredentialsInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php
create mode 100644 vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/AutoloadTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/AuthorizeControllerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/ResourceControllerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/TokenControllerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/FirebaseJwtTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/JwtTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/AuthorizationCodeTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ClientCredentialsTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ImplicitTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/JwtBearerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/RefreshTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/UserCredentialsTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/UserClaimsTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/RequestTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/AccessTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/JwtAccessTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/ScopeTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/ServerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AccessTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AuthorizationCodeTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientCredentialsTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/DynamoDBTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtAccessTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtBearerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PdoTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PublicKeyTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/RefreshTokenTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ScopeTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/UserCredentialsTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/OAuth2/TokenType/BearerTest.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/bootstrap.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/cleanup.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa
create mode 100644 vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa.pub
create mode 100644 vendor/bshaffer/oauth2-server-php/test/config/storage.json
create mode 100644 vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Request/TestRequest.php
create mode 100755 vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/BaseTest.php
create mode 100755 vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/Bootstrap.php
create mode 100644 vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/NullStorage.php
diff --git a/composer.json b/composer.json
index b59c81bba..e7577c41c 100644
--- a/composer.json
+++ b/composer.json
@@ -30,7 +30,8 @@
"ext-openssl" : "*",
"sabre/dav" : "~3.2",
"michelf/php-markdown" : "^1.7",
- "pixel418/markdownify": "^2.2"
+ "pixel418/markdownify": "^2.2",
+ "bshaffer/oauth2-server-php": "~1.8"
},
"require-dev" : {
"php" : ">=5.6",
diff --git a/composer.lock b/composer.lock
index 06fb17410..9f19b6f15 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,65 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "c0cafbf9fd702be588f6b392b9742cb6",
+ "hash": "85f6331e3e91b178ea0072065780747b",
+ "content-hash": "5aca7c342f023e1c3377a67c1812f5ff",
"packages": [
+ {
+ "name": "bshaffer/oauth2-server-php",
+ "version": "v1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bshaffer/oauth2-server-php.git",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bshaffer/oauth2-server-php/zipball/8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "~2.8",
+ "firebase/php-jwt": "~2.2",
+ "mongodb/mongodb": "^1.1",
+ "predis/predis": "dev-master",
+ "thobbs/phpcassa": "dev-master"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
+ "firebase/php-jwt": "~1.1 is required to use MondoDB storage",
+ "predis/predis": "Required to use Redis storage",
+ "thobbs/phpcassa": "Required to use Cassandra storage"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "OAuth2": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brent Shaffer",
+ "email": "bshafs@gmail.com",
+ "homepage": "http://brentertainment.com"
+ }
+ ],
+ "description": "OAuth2 Server for PHP",
+ "homepage": "http://github.com/bshaffer/oauth2-server-php",
+ "keywords": [
+ "auth",
+ "oauth",
+ "oauth2"
+ ],
+ "time": "2017-01-06 23:20:00"
+ },
{
"name": "michelf/php-markdown",
"version": "1.7.0",
@@ -55,7 +112,7 @@
"keywords": [
"markdown"
],
- "time": "2016-10-29T18:58:20+00:00"
+ "time": "2016-10-29 18:58:20"
},
{
"name": "pixel418/markdownify",
@@ -111,7 +168,7 @@
"markdown",
"markdownify"
],
- "time": "2016-09-21T13:01:43+00:00"
+ "time": "2016-09-21 13:01:43"
},
{
"name": "psr/log",
@@ -158,7 +215,7 @@
"psr",
"psr-3"
],
- "time": "2016-10-10T12:19:37+00:00"
+ "time": "2016-10-10 12:19:37"
},
{
"name": "sabre/dav",
@@ -241,7 +298,7 @@
"framework",
"iCalendar"
],
- "time": "2016-06-28T02:44:05+00:00"
+ "time": "2016-06-28 02:44:05"
},
{
"name": "sabre/event",
@@ -298,7 +355,7 @@
"promise",
"signal"
],
- "time": "2015-11-05T20:14:39+00:00"
+ "time": "2015-11-05 20:14:39"
},
{
"name": "sabre/http",
@@ -353,7 +410,7 @@
"keywords": [
"http"
],
- "time": "2016-01-06T23:00:08+00:00"
+ "time": "2016-01-06 23:00:08"
},
{
"name": "sabre/uri",
@@ -404,7 +461,7 @@
"uri",
"url"
],
- "time": "2016-03-08T02:29:27+00:00"
+ "time": "2016-03-08 02:29:27"
},
{
"name": "sabre/vobject",
@@ -501,7 +558,7 @@
"xCal",
"xCard"
],
- "time": "2016-07-15T19:52:17+00:00"
+ "time": "2016-07-15 19:52:17"
},
{
"name": "sabre/xml",
@@ -564,2778 +621,10 @@
"dom",
"xml"
],
- "time": "2016-10-09T22:57:52+00:00"
- }
- ],
- "packages-dev": [
- {
- "name": "behat/behat",
- "version": "v3.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Behat/Behat.git",
- "reference": "15a3a1857457eaa29cdf41564a5e421effb09526"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Behat/Behat/zipball/15a3a1857457eaa29cdf41564a5e421effb09526",
- "reference": "15a3a1857457eaa29cdf41564a5e421effb09526",
- "shasum": ""
- },
- "require": {
- "behat/gherkin": "^4.4.4",
- "behat/transliterator": "~1.0",
- "container-interop/container-interop": "^1.1",
- "ext-mbstring": "*",
- "php": ">=5.3.3",
- "symfony/class-loader": "~2.1||~3.0",
- "symfony/config": "~2.3||~3.0",
- "symfony/console": "~2.5||~3.0",
- "symfony/dependency-injection": "~2.1||~3.0",
- "symfony/event-dispatcher": "~2.1||~3.0",
- "symfony/translation": "~2.3||~3.0",
- "symfony/yaml": "~2.1||~3.0"
- },
- "require-dev": {
- "herrera-io/box": "~1.6.1",
- "phpunit/phpunit": "~4.5",
- "symfony/process": "~2.5|~3.0"
- },
- "suggest": {
- "behat/mink-extension": "for integration with Mink testing framework",
- "behat/symfony2-extension": "for integration with Symfony2 web framework",
- "behat/yii-extension": "for integration with Yii web framework"
- },
- "bin": [
- "bin/behat"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Behat\\Behat": "src/",
- "Behat\\Testwork": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- }
- ],
- "description": "Scenario-oriented BDD framework for PHP 5.3",
- "homepage": "http://behat.org/",
- "keywords": [
- "Agile",
- "BDD",
- "ScenarioBDD",
- "Scrum",
- "StoryBDD",
- "User story",
- "business",
- "development",
- "documentation",
- "examples",
- "symfony",
- "testing"
- ],
- "time": "2016-12-25T13:43:52+00:00"
- },
- {
- "name": "behat/gherkin",
- "version": "v4.4.5",
- "source": {
- "type": "git",
- "url": "https://github.com/Behat/Gherkin.git",
- "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74",
- "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.1"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.5|~5",
- "symfony/phpunit-bridge": "~2.7|~3",
- "symfony/yaml": "~2.3|~3"
- },
- "suggest": {
- "symfony/yaml": "If you want to parse features, represented in YAML files"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.4-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Behat\\Gherkin": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- }
- ],
- "description": "Gherkin DSL parser for PHP 5.3",
- "homepage": "http://behat.org/",
- "keywords": [
- "BDD",
- "Behat",
- "Cucumber",
- "DSL",
- "gherkin",
- "parser"
- ],
- "time": "2016-10-30T11:50:56+00:00"
- },
- {
- "name": "behat/mink",
- "version": "v1.7.1",
- "source": {
- "type": "git",
- "url": "https://github.com/minkphp/Mink.git",
- "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9",
- "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.1",
- "symfony/css-selector": "~2.1|~3.0"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0"
- },
- "suggest": {
- "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
- "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
- "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
- "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.7.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Behat\\Mink\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- }
- ],
- "description": "Browser controller/emulator abstraction for PHP",
- "homepage": "http://mink.behat.org/",
- "keywords": [
- "browser",
- "testing",
- "web"
- ],
- "time": "2016-03-05T08:26:18+00:00"
- },
- {
- "name": "behat/mink-browserkit-driver",
- "version": "v1.3.2",
- "source": {
- "type": "git",
- "url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
- "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb",
- "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb",
- "shasum": ""
- },
- "require": {
- "behat/mink": "^1.7.1@dev",
- "php": ">=5.3.6",
- "symfony/browser-kit": "~2.3|~3.0",
- "symfony/dom-crawler": "~2.3|~3.0"
- },
- "require-dev": {
- "silex/silex": "~1.2",
- "symfony/phpunit-bridge": "~2.7|~3.0"
- },
- "type": "mink-driver",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Behat\\Mink\\Driver\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- }
- ],
- "description": "Symfony2 BrowserKit driver for Mink framework",
- "homepage": "http://mink.behat.org/",
- "keywords": [
- "Mink",
- "Symfony2",
- "browser",
- "testing"
- ],
- "time": "2016-03-05T08:59:47+00:00"
- },
- {
- "name": "behat/mink-extension",
- "version": "v2.2",
- "source": {
- "type": "git",
- "url": "https://github.com/Behat/MinkExtension.git",
- "reference": "5b4bda64ff456104564317e212c823e45cad9d59"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/5b4bda64ff456104564317e212c823e45cad9d59",
- "reference": "5b4bda64ff456104564317e212c823e45cad9d59",
- "shasum": ""
- },
- "require": {
- "behat/behat": "~3.0,>=3.0.5",
- "behat/mink": "~1.5",
- "php": ">=5.3.2",
- "symfony/config": "~2.2|~3.0"
- },
- "require-dev": {
- "behat/mink-goutte-driver": "~1.1",
- "phpspec/phpspec": "~2.0"
- },
- "type": "behat-extension",
- "extra": {
- "branch-alias": {
- "dev-master": "2.1.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Behat\\MinkExtension": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Christophe Coevoet",
- "email": "stof@notk.org"
- },
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com"
- }
- ],
- "description": "Mink extension for Behat",
- "homepage": "http://extensions.behat.org/mink",
- "keywords": [
- "browser",
- "gui",
- "test",
- "web"
- ],
- "time": "2016-02-15T07:55:18+00:00"
- },
- {
- "name": "behat/mink-goutte-driver",
- "version": "v1.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/minkphp/MinkGoutteDriver.git",
- "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
- "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
- "shasum": ""
- },
- "require": {
- "behat/mink": "~1.6@dev",
- "behat/mink-browserkit-driver": "~1.2@dev",
- "fabpot/goutte": "~1.0.4|~2.0|~3.1",
- "php": ">=5.3.1"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0"
- },
- "type": "mink-driver",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Behat\\Mink\\Driver\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- }
- ],
- "description": "Goutte driver for Mink framework",
- "homepage": "http://mink.behat.org/",
- "keywords": [
- "browser",
- "goutte",
- "headless",
- "testing"
- ],
- "time": "2016-03-05T09:04:22+00:00"
- },
- {
- "name": "behat/transliterator",
- "version": "v1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Behat/Transliterator.git",
- "reference": "868e05be3a9f25ba6424c2dd4849567f50715003"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Behat/Transliterator/zipball/868e05be3a9f25ba6424c2dd4849567f50715003",
- "reference": "868e05be3a9f25ba6424c2dd4849567f50715003",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Behat\\Transliterator": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Artistic-1.0"
- ],
- "description": "String transliterator",
- "keywords": [
- "i18n",
- "slug",
- "transliterator"
- ],
- "time": "2015-09-28T16:26:35+00:00"
- },
- {
- "name": "container-interop/container-interop",
- "version": "1.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/container-interop/container-interop.git",
- "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
- "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
- "shasum": ""
- },
- "require": {
- "psr/container": "^1.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Interop\\Container\\": "src/Interop/Container/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
- "homepage": "https://github.com/container-interop/container-interop",
- "time": "2017-02-14T19:40:03+00:00"
- },
- {
- "name": "doctrine/instantiator",
- "version": "1.0.5",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/instantiator.git",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3,<8.0-DEV"
- },
- "require-dev": {
- "athletic/athletic": "~0.1.8",
- "ext-pdo": "*",
- "ext-phar": "*",
- "phpunit/phpunit": "~4.0",
- "squizlabs/php_codesniffer": "~2.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
- }
- ],
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://github.com/doctrine/instantiator",
- "keywords": [
- "constructor",
- "instantiate"
- ],
- "time": "2015-06-14T21:17:01+00:00"
- },
- {
- "name": "fabpot/goutte",
- "version": "v3.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/FriendsOfPHP/Goutte.git",
- "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638",
- "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/guzzle": "^6.0",
- "php": ">=5.5.0",
- "symfony/browser-kit": "~2.1|~3.0",
- "symfony/css-selector": "~2.1|~3.0",
- "symfony/dom-crawler": "~2.1|~3.0"
- },
- "type": "application",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Goutte\\": "Goutte"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- }
- ],
- "description": "A simple PHP Web Scraper",
- "homepage": "https://github.com/FriendsOfPHP/Goutte",
- "keywords": [
- "scraper"
- ],
- "time": "2017-01-03T13:21:43+00:00"
- },
- {
- "name": "guzzlehttp/guzzle",
- "version": "6.2.2",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ebf29dee597f02f09f4d5bbecc68230ea9b08f60",
- "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/promises": "^1.0",
- "guzzlehttp/psr7": "^1.3.1",
- "php": ">=5.5"
- },
- "require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "^4.0",
- "psr/log": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "6.2-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "GuzzleHttp\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- }
- ],
- "description": "Guzzle is a PHP HTTP client library",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "rest",
- "web service"
- ],
- "time": "2016-10-08T15:01:37+00:00"
- },
- {
- "name": "guzzlehttp/promises",
- "version": "v1.3.1",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- }
- ],
- "description": "Guzzle promises library",
- "keywords": [
- "promise"
- ],
- "time": "2016-12-20T10:07:11+00:00"
- },
- {
- "name": "guzzlehttp/psr7",
- "version": "1.4.0",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "04a6d1a00ea5da0727ee94309a9f0d3dbaecb569"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/04a6d1a00ea5da0727ee94309a9f0d3dbaecb569",
- "reference": "04a6d1a00ea5da0727ee94309a9f0d3dbaecb569",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4.0",
- "psr/http-message": "~1.0"
- },
- "provide": {
- "psr/http-message-implementation": "1.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Tobias Schultze",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "PSR-7 message implementation that also provides common utility methods",
- "keywords": [
- "http",
- "message",
- "request",
- "response",
- "stream",
- "uri",
- "url"
- ],
- "time": "2017-02-21T01:20:32+00:00"
- },
- {
- "name": "myclabs/deep-copy",
- "version": "1.6.0",
- "source": {
- "type": "git",
- "url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
- "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4.0"
- },
- "require-dev": {
- "doctrine/collections": "1.*",
- "phpunit/phpunit": "~4.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "DeepCopy\\": "src/DeepCopy/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Create deep copies (clones) of your objects",
- "homepage": "https://github.com/myclabs/DeepCopy",
- "keywords": [
- "clone",
- "copy",
- "duplicate",
- "object",
- "object graph"
- ],
- "time": "2017-01-26T22:05:40+00:00"
- },
- {
- "name": "phpdocumentor/reflection-common",
- "version": "1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.6"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src"
- ]
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
- }
- ],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
- "keywords": [
- "FQSEN",
- "phpDocumentor",
- "phpdoc",
- "reflection",
- "static analysis"
- ],
- "time": "2015-12-27T11:43:31+00:00"
- },
- {
- "name": "phpdocumentor/reflection-docblock",
- "version": "3.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
- "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5",
- "phpdocumentor/reflection-common": "^1.0@dev",
- "phpdocumentor/type-resolver": "^0.2.0",
- "webmozart/assert": "^1.0"
- },
- "require-dev": {
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.4"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src/"
- ]
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- }
- ],
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2016-09-30T07:12:33+00:00"
- },
- {
- "name": "phpdocumentor/type-resolver",
- "version": "0.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
- "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5",
- "phpdocumentor/reflection-common": "^1.0"
- },
- "require-dev": {
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^5.2||^4.8.24"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src/"
- ]
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- }
- ],
- "time": "2016-11-25T06:54:22+00:00"
- },
- {
- "name": "phpspec/prophecy",
- "version": "v1.6.2",
- "source": {
- "type": "git",
- "url": "https://github.com/phpspec/prophecy.git",
- "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
- "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.0.2",
- "php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
- "sebastian/comparator": "^1.1",
- "sebastian/recursion-context": "^1.0|^2.0"
- },
- "require-dev": {
- "phpspec/phpspec": "^2.0",
- "phpunit/phpunit": "^4.8 || ^5.6.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.6.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Prophecy\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- },
- {
- "name": "Marcello Duarte",
- "email": "marcello.duarte@gmail.com"
- }
- ],
- "description": "Highly opinionated mocking framework for PHP 5.3+",
- "homepage": "https://github.com/phpspec/prophecy",
- "keywords": [
- "Double",
- "Dummy",
- "fake",
- "mock",
- "spy",
- "stub"
- ],
- "time": "2016-11-21T14:58:47+00:00"
- },
- {
- "name": "phpunit/php-code-coverage",
- "version": "4.0.6",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "ca060f645beeddebedb1885c97bf163e93264c35"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca060f645beeddebedb1885c97bf163e93264c35",
- "reference": "ca060f645beeddebedb1885c97bf163e93264c35",
- "shasum": ""
- },
- "require": {
- "php": "^5.6 || ^7.0",
- "phpunit/php-file-iterator": "~1.3",
- "phpunit/php-text-template": "~1.2",
- "phpunit/php-token-stream": "^1.4.2 || ^2.0",
- "sebastian/code-unit-reverse-lookup": "~1.0",
- "sebastian/environment": "^1.3.2 || ^2.0",
- "sebastian/version": "~1.0|~2.0"
- },
- "require-dev": {
- "ext-xdebug": ">=2.1.4",
- "phpunit/phpunit": "^5.4"
- },
- "suggest": {
- "ext-dom": "*",
- "ext-xdebug": ">=2.4.0",
- "ext-xmlwriter": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
- "role": "lead"
- }
- ],
- "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
- "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
- "keywords": [
- "coverage",
- "testing",
- "xunit"
- ],
- "time": "2017-02-23T07:38:02+00:00"
- },
- {
- "name": "phpunit/php-file-iterator",
- "version": "1.4.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
- "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
- "role": "lead"
- }
- ],
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
- "keywords": [
- "filesystem",
- "iterator"
- ],
- "time": "2016-10-03T07:40:28+00:00"
- },
- {
- "name": "phpunit/php-text-template",
- "version": "1.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Simple template engine.",
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
- "keywords": [
- "template"
- ],
- "time": "2015-06-21T13:50:34+00:00"
- },
- {
- "name": "phpunit/php-timer",
- "version": "1.0.8",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~4|~5"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
- "role": "lead"
- }
- ],
- "description": "Utility class for timing",
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
- "keywords": [
- "timer"
- ],
- "time": "2016-05-12T18:03:57+00:00"
- },
- {
- "name": "phpunit/php-token-stream",
- "version": "1.4.10",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "284fb0679dd25fb5ffb56dad92c72860c0a22f1b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/284fb0679dd25fb5ffb56dad92c72860c0a22f1b",
- "reference": "284fb0679dd25fb5ffb56dad92c72860c0a22f1b",
- "shasum": ""
- },
- "require": {
- "ext-tokenizer": "*",
- "php": ">=5.3.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.2"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Wrapper around PHP's tokenizer extension.",
- "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
- "keywords": [
- "tokenizer"
- ],
- "time": "2017-02-23T06:14:45+00:00"
- },
- {
- "name": "phpunit/phpunit",
- "version": "5.7.14",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "4906b8faf23e42612182fd212eb6f4c0f2954b57"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4906b8faf23e42612182fd212eb6f4c0f2954b57",
- "reference": "4906b8faf23e42612182fd212eb6f4c0f2954b57",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-xml": "*",
- "myclabs/deep-copy": "~1.3",
- "php": "^5.6 || ^7.0",
- "phpspec/prophecy": "^1.6.2",
- "phpunit/php-code-coverage": "^4.0.4",
- "phpunit/php-file-iterator": "~1.4",
- "phpunit/php-text-template": "~1.2",
- "phpunit/php-timer": "^1.0.6",
- "phpunit/phpunit-mock-objects": "^3.2",
- "sebastian/comparator": "^1.2.4",
- "sebastian/diff": "~1.2",
- "sebastian/environment": "^1.3.4 || ^2.0",
- "sebastian/exporter": "~2.0",
- "sebastian/global-state": "^1.1",
- "sebastian/object-enumerator": "~2.0",
- "sebastian/resource-operations": "~1.0",
- "sebastian/version": "~1.0.3|~2.0",
- "symfony/yaml": "~2.1|~3.0"
- },
- "conflict": {
- "phpdocumentor/reflection-docblock": "3.0.2"
- },
- "require-dev": {
- "ext-pdo": "*"
- },
- "suggest": {
- "ext-xdebug": "*",
- "phpunit/php-invoker": "~1.1"
- },
- "bin": [
- "phpunit"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.7.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "The PHP Unit Testing framework.",
- "homepage": "https://phpunit.de/",
- "keywords": [
- "phpunit",
- "testing",
- "xunit"
- ],
- "time": "2017-02-19T07:22:16+00:00"
- },
- {
- "name": "phpunit/phpunit-mock-objects",
- "version": "3.4.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
- "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.0.2",
- "php": "^5.6 || ^7.0",
- "phpunit/php-text-template": "^1.2",
- "sebastian/exporter": "^1.2 || ^2.0"
- },
- "conflict": {
- "phpunit/phpunit": "<5.4.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^5.4"
- },
- "suggest": {
- "ext-soap": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
- "role": "lead"
- }
- ],
- "description": "Mock Object library for PHPUnit",
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
- "keywords": [
- "mock",
- "xunit"
- ],
- "time": "2016-12-08T20:27:08+00:00"
- },
- {
- "name": "psr/container",
- "version": "1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/container.git",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Container\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common Container Interface (PHP FIG PSR-11)",
- "homepage": "https://github.com/php-fig/container",
- "keywords": [
- "PSR-11",
- "container",
- "container-interface",
- "container-interop",
- "psr"
- ],
- "time": "2017-02-14T16:28:37+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "time": "2016-08-06T14:39:51+00:00"
- },
- {
- "name": "sebastian/code-unit-reverse-lookup",
- "version": "1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
- "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "require-dev": {
- "phpunit/phpunit": "~5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Looks up which function or method a line of code belongs to",
- "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "time": "2016-02-13T06:45:14+00:00"
- },
- {
- "name": "sebastian/comparator",
- "version": "1.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
- "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3",
- "sebastian/diff": "~1.2",
- "sebastian/exporter": "~1.2 || ~2.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides the functionality to compare PHP values for equality",
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
- "keywords": [
- "comparator",
- "compare",
- "equality"
- ],
- "time": "2017-01-29T09:50:25+00:00"
- },
- {
- "name": "sebastian/diff",
- "version": "1.4.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
- "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.8"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Diff implementation",
- "homepage": "https://github.com/sebastianbergmann/diff",
- "keywords": [
- "diff"
- ],
- "time": "2015-12-08T07:14:41+00:00"
- },
- {
- "name": "sebastian/environment",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
- "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
- "shasum": ""
- },
- "require": {
- "php": "^5.6 || ^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^5.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides functionality to handle HHVM/PHP environments",
- "homepage": "http://www.github.com/sebastianbergmann/environment",
- "keywords": [
- "Xdebug",
- "environment",
- "hhvm"
- ],
- "time": "2016-11-26T07:53:53+00:00"
- },
- {
- "name": "sebastian/exporter",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
- "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3",
- "sebastian/recursion-context": "~2.0"
- },
- "require-dev": {
- "ext-mbstring": "*",
- "phpunit/phpunit": "~4.4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- }
- ],
- "description": "Provides the functionality to export PHP variables for visualization",
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
- "keywords": [
- "export",
- "exporter"
- ],
- "time": "2016-11-19T08:54:04+00:00"
- },
- {
- "name": "sebastian/global-state",
- "version": "1.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.2"
- },
- "suggest": {
- "ext-uopz": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Snapshotting of global state",
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
- "keywords": [
- "global state"
- ],
- "time": "2015-10-12T03:26:01+00:00"
- },
- {
- "name": "sebastian/object-enumerator",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
- "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6",
- "sebastian/recursion-context": "~2.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Traverses array structures and object graphs to enumerate all referenced objects",
- "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "time": "2017-02-18T15:18:39+00:00"
- },
- {
- "name": "sebastian/recursion-context",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
- "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- }
- ],
- "description": "Provides functionality to recursively process PHP variables",
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2016-11-19T07:33:16+00:00"
- },
- {
- "name": "sebastian/resource-operations",
- "version": "1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
- "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides a list of PHP built-in functions that operate on resources",
- "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "time": "2015-07-28T20:34:47+00:00"
- },
- {
- "name": "sebastian/version",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/version.git",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
- "homepage": "https://github.com/sebastianbergmann/version",
- "time": "2016-10-03T07:35:21+00:00"
- },
- {
- "name": "symfony/browser-kit",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/browser-kit.git",
- "reference": "394a2475a3a89089353fde5714a7f402fbb83880"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/394a2475a3a89089353fde5714a7f402fbb83880",
- "reference": "394a2475a3a89089353fde5714a7f402fbb83880",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9",
- "symfony/dom-crawler": "~2.8|~3.0"
- },
- "require-dev": {
- "symfony/css-selector": "~2.8|~3.0",
- "symfony/process": "~2.8|~3.0"
- },
- "suggest": {
- "symfony/process": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\BrowserKit\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony BrowserKit Component",
- "homepage": "https://symfony.com",
- "time": "2017-01-31T21:49:23+00:00"
- },
- {
- "name": "symfony/class-loader",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/class-loader.git",
- "reference": "2847d56f518ad5721bf85aa9174b3aa3fd12aa03"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/class-loader/zipball/2847d56f518ad5721bf85aa9174b3aa3fd12aa03",
- "reference": "2847d56f518ad5721bf85aa9174b3aa3fd12aa03",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "require-dev": {
- "symfony/finder": "~2.8|~3.0",
- "symfony/polyfill-apcu": "~1.1"
- },
- "suggest": {
- "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\ClassLoader\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony ClassLoader Component",
- "homepage": "https://symfony.com",
- "time": "2017-01-21T17:06:35+00:00"
- },
- {
- "name": "symfony/config",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/config.git",
- "reference": "9f99453e77771e629af8a25eeb0a6c4ed1e19da2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/9f99453e77771e629af8a25eeb0a6c4ed1e19da2",
- "reference": "9f99453e77771e629af8a25eeb0a6c4ed1e19da2",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9",
- "symfony/filesystem": "~2.8|~3.0"
- },
- "require-dev": {
- "symfony/yaml": "~3.0"
- },
- "suggest": {
- "symfony/yaml": "To use the yaml reference dumper"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Config\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Config Component",
- "homepage": "https://symfony.com",
- "time": "2017-02-14T16:27:43+00:00"
- },
- {
- "name": "symfony/console",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/console.git",
- "reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
- "reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9",
- "symfony/debug": "~2.8|~3.0",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/event-dispatcher": "~2.8|~3.0",
- "symfony/filesystem": "~2.8|~3.0",
- "symfony/process": "~2.8|~3.0"
- },
- "suggest": {
- "psr/log": "For using the console logger",
- "symfony/event-dispatcher": "",
- "symfony/filesystem": "",
- "symfony/process": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Console\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Console Component",
- "homepage": "https://symfony.com",
- "time": "2017-02-16T14:07:22+00:00"
- },
- {
- "name": "symfony/css-selector",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/css-selector.git",
- "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
- "reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\CssSelector\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jean-François Simon",
- "email": "jeanfrancois.simon@sensiolabs.com"
- },
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony CssSelector Component",
- "homepage": "https://symfony.com",
- "time": "2017-01-02T20:32:22+00:00"
- },
- {
- "name": "symfony/debug",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/debug.git",
- "reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
- "reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9",
- "psr/log": "~1.0"
- },
- "conflict": {
- "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
- },
- "require-dev": {
- "symfony/class-loader": "~2.8|~3.0",
- "symfony/http-kernel": "~2.8|~3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Debug\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Debug Component",
- "homepage": "https://symfony.com",
- "time": "2017-02-16T16:34:18+00:00"
- },
- {
- "name": "symfony/dependency-injection",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/dependency-injection.git",
- "reference": "130aa55b8ed7e6d0d75b0ed37256cec687a22f41"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/130aa55b8ed7e6d0d75b0ed37256cec687a22f41",
- "reference": "130aa55b8ed7e6d0d75b0ed37256cec687a22f41",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "conflict": {
- "symfony/yaml": "<3.2"
- },
- "require-dev": {
- "symfony/config": "~2.8|~3.0",
- "symfony/expression-language": "~2.8|~3.0",
- "symfony/yaml": "~3.2"
- },
- "suggest": {
- "symfony/config": "",
- "symfony/expression-language": "For using expressions in service container configuration",
- "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
- "symfony/yaml": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\DependencyInjection\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony DependencyInjection Component",
- "homepage": "https://symfony.com",
- "time": "2017-02-16T22:46:52+00:00"
- },
- {
- "name": "symfony/dom-crawler",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/dom-crawler.git",
- "reference": "b814b41373fc4e535aff8c765abe39545216f391"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b814b41373fc4e535aff8c765abe39545216f391",
- "reference": "b814b41373fc4e535aff8c765abe39545216f391",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "require-dev": {
- "symfony/css-selector": "~2.8|~3.0"
- },
- "suggest": {
- "symfony/css-selector": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\DomCrawler\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony DomCrawler Component",
- "homepage": "https://symfony.com",
- "time": "2017-01-21T17:14:11+00:00"
- },
- {
- "name": "symfony/event-dispatcher",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6",
- "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~2.8|~3.0",
- "symfony/dependency-injection": "~2.8|~3.0",
- "symfony/expression-language": "~2.8|~3.0",
- "symfony/stopwatch": "~2.8|~3.0"
- },
- "suggest": {
- "symfony/dependency-injection": "",
- "symfony/http-kernel": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\EventDispatcher\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony EventDispatcher Component",
- "homepage": "https://symfony.com",
- "time": "2017-01-02T20:32:22+00:00"
- },
- {
- "name": "symfony/filesystem",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/a0c6ef2dc78d33b58d91d3a49f49797a184d06f4",
- "reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Filesystem Component",
- "homepage": "https://symfony.com",
- "time": "2017-01-08T20:47:33+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "v1.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
- "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2016-11-14T01:06:16+00:00"
- },
- {
- "name": "symfony/translation",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/translation.git",
- "reference": "d6825c6bb2f1da13f564678f9f236fe8242c0029"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/d6825c6bb2f1da13f564678f9f236fe8242c0029",
- "reference": "d6825c6bb2f1da13f564678f9f236fe8242c0029",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "conflict": {
- "symfony/config": "<2.8"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~2.8|~3.0",
- "symfony/intl": "~2.8|~3.0",
- "symfony/yaml": "~2.8|~3.0"
- },
- "suggest": {
- "psr/log": "To use logging capability in translator",
- "symfony/config": "",
- "symfony/yaml": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Translation\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Translation Component",
- "homepage": "https://symfony.com",
- "time": "2017-02-16T22:46:52+00:00"
- },
- {
- "name": "symfony/yaml",
- "version": "v3.2.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/yaml.git",
- "reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
- "reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5.9"
- },
- "require-dev": {
- "symfony/console": "~2.8|~3.0"
- },
- "suggest": {
- "symfony/console": "For validating YAML files using the lint command"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Yaml\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Yaml Component",
- "homepage": "https://symfony.com",
- "time": "2017-02-16T22:46:52+00:00"
- },
- {
- "name": "webmozart/assert",
- "version": "1.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/webmozart/assert.git",
- "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
- "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.3 || ^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.6",
- "sebastian/version": "^1.0.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Webmozart\\Assert\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Assertions to validate method input/output with nice error messages.",
- "keywords": [
- "assert",
- "check",
- "validate"
- ],
- "time": "2016-11-23T20:04:58+00:00"
+ "time": "2016-10-09 22:57:52"
}
],
+ "packages-dev": null,
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
@@ -3353,7 +642,5 @@
"ext-xml": "*",
"ext-openssl": "*"
},
- "platform-dev": {
- "php": ">=5.6"
- }
+ "platform-dev": []
}
diff --git a/library/oauth2/.gitignore b/library/oauth2/.gitignore
deleted file mode 100644
index c43a667d4..000000000
--- a/library/oauth2/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Test Files #
-test/config/test.sqlite
-vendor
-composer.lock
-.idea
diff --git a/library/oauth2/.travis.yml b/library/oauth2/.travis.yml
deleted file mode 100644
index dd4aae4a6..000000000
--- a/library/oauth2/.travis.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-language: php
-sudo: false
-cache:
- directories:
- - $HOME/.composer/cache
- - vendor
-php:
-- 5.3
-- 5.4
-- 5.5
-- 5.6
-- 7
-- hhvm
-env:
- global:
- - SKIP_MONGO_TESTS=1
- - secure: Bc5ZqvZ1YYpoPZNNuU2eCB8DS6vBYrAdfBtTenBs5NSxzb+Vjven4kWakbzaMvZjb/Ib7Uph7DGuOtJXpmxnvBXPLd707LZ89oFWN/yqQlZKCcm8iErvJCB5XL+/ONHj2iPdR242HJweMcat6bMCwbVWoNDidjtWMH0U2mYFy3M=
- - secure: R3bXlymyFiY2k2jf7+fv/J8i34wtXTkmD4mCr5Ps/U+vn9axm2VtvR2Nj+r7LbRjn61gzFE/xIVjYft/wOyBOYwysrfriydrnRVS0owh6y+7EyOyQWbRX11vVQMf8o31QCQE5BY58V5AJZW3MjoOL0FVlTgySJiJvdw6Pv18v+E=
-services:
-- mongodb
-- redis-server
-- cassandra
-before_install:
-- phpenv config-rm xdebug.ini || return 0
-install:
-- composer install --no-interaction
-before_script:
-- psql -c 'create database oauth2_server_php;' -U postgres
-after_script:
-- php test/cleanup.php
diff --git a/library/oauth2/CHANGELOG.md b/library/oauth2/CHANGELOG.md
deleted file mode 100644
index 03d925e06..000000000
--- a/library/oauth2/CHANGELOG.md
+++ /dev/null
@@ -1,152 +0,0 @@
-CHANGELOG for 1.x
-=================
-
-This changelog references the relevant changes (bug and security fixes) done
-in 1.x minor versions.
-
-To see the files changed for a given bug, go to https://github.com/bshaffer/oauth2-server-php/issues/### where ### is the bug number
-To get the diff between two versions, go to https://github.com/bshaffer/oauth2-server-php/compare/v1.0...v1.1
-To get the diff for a specific change, go to https://github.com/bshaffer/oauth2-server-php/commit/XXX where XXX is the change hash
-
-* 1.8.0 (2015-09-18)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/643
-
- * bug #594 - adds jti
- * bug #598 - fixes lifetime configurations for JWTs
- * bug #634 - fixes travis builds, upgrade to containers
- * bug #586 - support for revoking tokens
- * bug #636 - Adds FirebaseJWT bridge
- * bug #639 - Mongo HHVM compatibility
-
-* 1.7.0 (2015-04-23)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/572
-
- * bug #500 - PDO fetch mode changed from FETCH_BOTH to FETCH_ASSOC
- * bug #508 - Case insensitive for Bearer token header name ba716d4
- * bug #512 - validateRedirectUri is now public
- * bug #530 - Add PublicKeyInterface, UserClaimsInterface to Cassandra Storage
- * bug #505 - DynamoDB storage fixes
- * bug #556 - adds "code id_token" return type to openid connect
- * bug #563 - Include "issuer" config key for JwtAccessToken
- * bug #564 - Fixes JWT vulnerability
- * bug #571 - Added unset_refresh_token_after_use option
-
-* 1.6 (2015-01-16)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/496
-
- * bug 437 - renames CryptoToken to JwtAccessToken / use_crypto_tokens to use_jwt_access_tokens
- * bug 447 - Adds a Couchbase storage implementation
- * bug 460 - Rename JWT claims to match spec
- * bug 470 - order does not matter for multi-valued response types
- * bug 471 - Make validateAuthorizeRequest available for POST in addition to GET
- * bug 475 - Adds JTI table definitiion
- * bug 481 - better randomness for generating access tokens
- * bug 480 - Use hash_equals() for signature verification (prevents remote timing attacks)
- * bugs 489, 491, 498 - misc other fixes
-
-* 1.5 (2014-08-27)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/446
-
- * bug #399 - Add DynamoDB Support
- * bug #404 - renamed error name for malformed/expired tokens
- * bug #412 - Openid connect: fixes for claims with more than one scope / Add support for the prompt parameter ('consent' and 'none')
- * bug #411 - fixes xml output
- * bug #413 - fixes invalid format error
- * bug #401 - fixes code standards / whitespace
- * bug #354 - bundles PDO SQL with the library
- * [BC] bug #397 - refresh tokens should not be encrypted
- * bug #423 - makes "scope" optional for refresh token storage
-
-* 1.4 (2014-06-12)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/392
-
- * bug #189 Storage\PDO - allows DSN string in constructor
- * bug #233 Bearer Tokens - allows token in request body for PUT requests
- * bug #346 Fixes open_basedir warning
- * bug #351 Adds OpenID Connect support
- * bug #355 Adds php 5.6 and HHVM to travis.ci testing
- * [BC] bug #358 Adds `getQuerystringIdentifier()` to the GrantType interface
- * bug #363 Encryption\JWT - Allows for subclassing JWT Headers
- * bug #349 Bearer Tokens - adds requestHasToken method for when access tokens are optional
- * bug #301 Encryption\JWT - fixes urlSafeB64Encode(): ensures newlines are replaced as expected
- * bug #323 ResourceController - client_id is no longer required to be returned when calling getAccessToken
- * bug #367 Storage\PDO - adds Postgres support
- * bug #368 Access Tokens - use mcrypt_create_iv or openssl_random_pseudo_bytes to create token string
- * bug #376 Request - allows case insensitive headers
- * bug #384 Storage\PDO - can pass in PDO options in constructor of PDO storage
- * misc fixes #361, #292, #373, #374, #379, #396
-* 1.3 (2014-02-27)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/325
-
- * bug #311 adds cassandra storage
- * bug #298 fixes response code for user credentials grant type
- * bug #318 adds 'use_crypto_tokens' config to Server class for better DX
- * [BC] bug #320 pass client_id to getDefaultScope
- * bug #324 better feedback when running tests
- * bug #335 adds support for non-expiring refresh tokens
- * bug #333 fixes Pdo storage for getClientKey
- * bug #336 fixes Redis storage for expireAuthorizationCode
-
-* 1.2 (2014-01-03)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/288
-
- * bug #285 changed response header from 200 to 401 when empty token received
- * bug #286 adds documentation and links to spec for not including error messages when no token is supplied
- * bug #280 ensures PHP warnings do not get thrown as a result of an invalid argument to $jwt->decode()
- * bug #279 predis wrong number of arguments
- * bug #277 Securing JS WebApp client secret w/ password grant type
-
-* 1.1 (2013-12-17)
-
- PR: https://github.com/bshaffer/oauth2-server-php/pull/276
-
- * bug #278 adds refresh token configuration to Server class
- * bug #274 Supplying a null client_id and client_secret grants API access
- * bug #244 [MongoStorage] More detailed implementation info
- * bug #268 Implement jti for JWT Bearer tokens to prevent replay attacks.
- * bug #266 Removing unused argument to getAccessTokenData
- * bug #247 Make Bearer token type consistent
- * bug #253 Fixing CryptoToken refresh token lifetime
- * bug #246 refactors public key logic to be more intuitive
- * bug #245 adds support for JSON crypto tokens
- * bug #230 Remove unused columns in oauth_clients
- * bug #215 makes Redis Scope Storage obey the same paradigm as PDO
- * bug #228 removes scope group
- * bug #227 squelches open basedir restriction error
- * bug #223 Updated docblocks for RefreshTokenInterface.php
- * bug #224 Adds protected properties
- * bug #217 Implement ScopeInterface for PDO, Redis
-
-* 1.0 (2013-08-12)
-
- * bug #203 Add redirect\_status_code config param for AuthorizeController
- * bug #205 ensures unnecessary ? is not set when ** bug
- * bug #204 Fixed call to LogicException
- * bug #202 Add explode to checkRestrictedGrant in PDO Storage
- * bug #197 adds support for 'false' default scope ** bug
- * bug #192 reference errors and adds tests
- * bug #194 makes some appropriate properties ** bug
- * bug #191 passes config to HttpBasic
- * bug #190 validates client credentials before ** bug
- * bug #171 Fix wrong redirect following authorization step
- * bug #187 client_id is now passed to getDefaultScope().
- * bug #176 Require refresh_token in getRefreshToken response
- * bug #174 make user\_id not required for refresh_token grant
- * bug #173 Duplication in JwtBearer Grant
- * bug #168 user\_id not required for authorization_code grant
- * bug #133 hardens default security for user object
- * bug #163 allows redirect\_uri on authorization_code to be NULL in docs example
- * bug #162 adds getToken on ResourceController for convenience
- * bug #161 fixes fatal error
- * bug #163 Invalid redirect_uri handling
- * bug #156 user\_id in OAuth2\_Storage_AuthorizationCodeInterface::getAuthorizationCode() response
- * bug #157 Fix for extending access and refresh tokens
- * bug #154 ResponseInterface: getParameter method is used in the library but not defined in the interface
- * bug #148 Add more detail to examples in Readme.md
diff --git a/library/oauth2/LICENSE b/library/oauth2/LICENSE
deleted file mode 100644
index d7ece8467..000000000
--- a/library/oauth2/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2014 Brent Shaffer
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/library/oauth2/README.md b/library/oauth2/README.md
deleted file mode 100644
index 4ceda6cf9..000000000
--- a/library/oauth2/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-oauth2-server-php
-=================
-
-[![Build Status](https://travis-ci.org/bshaffer/oauth2-server-php.svg?branch=develop)](https://travis-ci.org/bshaffer/oauth2-server-php)
-
-[![Total Downloads](https://poser.pugx.org/bshaffer/oauth2-server-php/downloads.png)](https://packagist.org/packages/bshaffer/oauth2-server-php)
-
-View the [complete documentation](http://bshaffer.github.io/oauth2-server-php-docs/)
\ No newline at end of file
diff --git a/library/oauth2/phpunit.xml b/library/oauth2/phpunit.xml
deleted file mode 100644
index e36403f0a..000000000
--- a/library/oauth2/phpunit.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
- ./test/OAuth2/
-
-
-
-
-
- ./src/OAuth2/
-
-
-
diff --git a/library/oauth2/src/OAuth2/Autoloader.php b/library/oauth2/src/OAuth2/Autoloader.php
deleted file mode 100644
index ecfb6ba75..000000000
--- a/library/oauth2/src/OAuth2/Autoloader.php
+++ /dev/null
@@ -1,48 +0,0 @@
-
- * @license MIT License
- */
-class Autoloader
-{
- private $dir;
-
- public function __construct($dir = null)
- {
- if (is_null($dir)) {
- $dir = dirname(__FILE__).'/..';
- }
- $this->dir = $dir;
- }
- /**
- * Registers OAuth2\Autoloader as an SPL autoloader.
- */
- public static function register($dir = null)
- {
- ini_set('unserialize_callback_func', 'spl_autoload_call');
- spl_autoload_register(array(new self($dir), 'autoload'));
- }
-
- /**
- * Handles autoloading of classes.
- *
- * @param string $class A class name.
- *
- * @return boolean Returns true if the class has been loaded
- */
- public function autoload($class)
- {
- if (0 !== strpos($class, 'OAuth2')) {
- return;
- }
-
- if (file_exists($file = $this->dir.'/'.str_replace('\\', '/', $class).'.php')) {
- require $file;
- }
- }
-}
diff --git a/library/oauth2/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php b/library/oauth2/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
deleted file mode 100644
index 29c7171b5..000000000
--- a/library/oauth2/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
+++ /dev/null
@@ -1,15 +0,0 @@
-
- */
-class HttpBasic implements ClientAssertionTypeInterface
-{
- private $clientData;
-
- protected $storage;
- protected $config;
-
- /**
- * @param OAuth2\Storage\ClientCredentialsInterface $clientStorage REQUIRED Storage class for retrieving client credentials information
- * @param array $config OPTIONAL Configuration options for the server
- *
- * $config = array(
- * 'allow_credentials_in_request_body' => true, // whether to look for credentials in the POST body in addition to the Authorize HTTP Header
- * 'allow_public_clients' => true // if true, "public clients" (clients without a secret) may be authenticated
- * );
- *
- */
- public function __construct(ClientCredentialsInterface $storage, array $config = array())
- {
- $this->storage = $storage;
- $this->config = array_merge(array(
- 'allow_credentials_in_request_body' => true,
- 'allow_public_clients' => true,
- ), $config);
- }
-
- public function validateRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!$clientData = $this->getClientCredentials($request, $response)) {
- return false;
- }
-
- if (!isset($clientData['client_id'])) {
- throw new \LogicException('the clientData array must have "client_id" set');
- }
-
- if (!isset($clientData['client_secret']) || $clientData['client_secret'] == '') {
- if (!$this->config['allow_public_clients']) {
- $response->setError(400, 'invalid_client', 'client credentials are required');
-
- return false;
- }
-
- if (!$this->storage->isPublicClient($clientData['client_id'])) {
- $response->setError(400, 'invalid_client', 'This client is invalid or must authenticate using a client secret');
-
- return false;
- }
- } elseif ($this->storage->checkClientCredentials($clientData['client_id'], $clientData['client_secret']) === false) {
- $response->setError(400, 'invalid_client', 'The client credentials are invalid');
-
- return false;
- }
-
- $this->clientData = $clientData;
-
- return true;
- }
-
- public function getClientId()
- {
- return $this->clientData['client_id'];
- }
-
- /**
- * Internal function used to get the client credentials from HTTP basic
- * auth or POST data.
- *
- * According to the spec (draft 20), the client_id can be provided in
- * the Basic Authorization header (recommended) or via GET/POST.
- *
- * @return
- * A list containing the client identifier and password, for example
- * @code
- * return array(
- * "client_id" => CLIENT_ID, // REQUIRED the client id
- * "client_secret" => CLIENT_SECRET, // OPTIONAL the client secret (may be omitted for public clients)
- * );
- * @endcode
- *
- * @see http://tools.ietf.org/html/rfc6749#section-2.3.1
- *
- * @ingroup oauth2_section_2
- */
- public function getClientCredentials(RequestInterface $request, ResponseInterface $response = null)
- {
- if (!is_null($request->headers('PHP_AUTH_USER')) && !is_null($request->headers('PHP_AUTH_PW'))) {
- return array('client_id' => $request->headers('PHP_AUTH_USER'), 'client_secret' => $request->headers('PHP_AUTH_PW'));
- }
-
- if ($this->config['allow_credentials_in_request_body']) {
- // Using POST for HttpBasic authorization is not recommended, but is supported by specification
- if (!is_null($request->request('client_id'))) {
- /**
- * client_secret can be null if the client's password is an empty string
- * @see http://tools.ietf.org/html/rfc6749#section-2.3.1
- */
-
- return array('client_id' => $request->request('client_id'), 'client_secret' => $request->request('client_secret'));
- }
- }
-
- if ($response) {
- $message = $this->config['allow_credentials_in_request_body'] ? ' or body' : '';
- $response->setError(400, 'invalid_client', 'Client credentials were not found in the headers'.$message);
- }
-
- return null;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Controller/AuthorizeController.php b/library/oauth2/src/OAuth2/Controller/AuthorizeController.php
deleted file mode 100644
index a9a722587..000000000
--- a/library/oauth2/src/OAuth2/Controller/AuthorizeController.php
+++ /dev/null
@@ -1,388 +0,0 @@
-
- * $config = array(
- * 'allow_implicit' => false, // if the controller should allow the "implicit" grant type
- * 'enforce_state' => true // if the controller should require the "state" parameter
- * 'require_exact_redirect_uri' => true, // if the controller should require an exact match on the "redirect_uri" parameter
- * 'redirect_status_code' => 302, // HTTP status code to use for redirect responses
- * );
- *
- * @param OAuth2\ScopeInterface $scopeUtil OPTIONAL Instance of OAuth2\ScopeInterface to validate the requested scope
- */
- public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ScopeInterface $scopeUtil = null)
- {
- $this->clientStorage = $clientStorage;
- $this->responseTypes = $responseTypes;
- $this->config = array_merge(array(
- 'allow_implicit' => false,
- 'enforce_state' => true,
- 'require_exact_redirect_uri' => true,
- 'redirect_status_code' => 302,
- ), $config);
-
- if (is_null($scopeUtil)) {
- $scopeUtil = new Scope();
- }
- $this->scopeUtil = $scopeUtil;
- }
-
- public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null)
- {
- if (!is_bool($is_authorized)) {
- throw new \InvalidArgumentException('Argument "is_authorized" must be a boolean. This method must know if the user has granted access to the client.');
- }
-
- // We repeat this, because we need to re-validate. The request could be POSTed
- // by a 3rd-party (because we are not internally enforcing NONCEs, etc)
- if (!$this->validateAuthorizeRequest($request, $response)) {
- return;
- }
-
- // If no redirect_uri is passed in the request, use client's registered one
- if (empty($this->redirect_uri)) {
- $clientData = $this->clientStorage->getClientDetails($this->client_id);
- $registered_redirect_uri = $clientData['redirect_uri'];
- }
-
- // the user declined access to the client's application
- if ($is_authorized === false) {
- $redirect_uri = $this->redirect_uri ?: $registered_redirect_uri;
- $this->setNotAuthorizedResponse($request, $response, $redirect_uri, $user_id);
-
- return;
- }
-
- // build the parameters to set in the redirect URI
- if (!$params = $this->buildAuthorizeParameters($request, $response, $user_id)) {
- return;
- }
-
- $authResult = $this->responseTypes[$this->response_type]->getAuthorizeResponse($params, $user_id);
-
- list($redirect_uri, $uri_params) = $authResult;
-
- if (empty($redirect_uri) && !empty($registered_redirect_uri)) {
- $redirect_uri = $registered_redirect_uri;
- }
-
- $uri = $this->buildUri($redirect_uri, $uri_params);
-
- // return redirect response
- $response->setRedirect($this->config['redirect_status_code'], $uri);
- }
-
- protected function setNotAuthorizedResponse(RequestInterface $request, ResponseInterface $response, $redirect_uri, $user_id = null)
- {
- $error = 'access_denied';
- $error_message = 'The user denied access to your application';
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->state, $error, $error_message);
- }
-
- /*
- * We have made this protected so this class can be extended to add/modify
- * these parameters
- */
- protected function buildAuthorizeParameters($request, $response, $user_id)
- {
- // @TODO: we should be explicit with this in the future
- $params = array(
- 'scope' => $this->scope,
- 'state' => $this->state,
- 'client_id' => $this->client_id,
- 'redirect_uri' => $this->redirect_uri,
- 'response_type' => $this->response_type,
- );
-
- return $params;
- }
-
- public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
- {
- // Make sure a valid client id was supplied (we can not redirect because we were unable to verify the URI)
- if (!$client_id = $request->query('client_id', $request->request('client_id'))) {
- // We don't have a good URI to use
- $response->setError(400, 'invalid_client', "No client id supplied");
-
- return false;
- }
-
- // Get client details
- if (!$clientData = $this->clientStorage->getClientDetails($client_id)) {
- $response->setError(400, 'invalid_client', 'The client id supplied is invalid');
-
- return false;
- }
-
- $registered_redirect_uri = isset($clientData['redirect_uri']) ? $clientData['redirect_uri'] : '';
-
- // Make sure a valid redirect_uri was supplied. If specified, it must match the clientData URI.
- // @see http://tools.ietf.org/html/rfc6749#section-3.1.2
- // @see http://tools.ietf.org/html/rfc6749#section-4.1.2.1
- // @see http://tools.ietf.org/html/rfc6749#section-4.2.2.1
- if ($supplied_redirect_uri = $request->query('redirect_uri', $request->request('redirect_uri'))) {
- // validate there is no fragment supplied
- $parts = parse_url($supplied_redirect_uri);
- if (isset($parts['fragment']) && $parts['fragment']) {
- $response->setError(400, 'invalid_uri', 'The redirect URI must not contain a fragment');
-
- return false;
- }
-
- // validate against the registered redirect uri(s) if available
- if ($registered_redirect_uri && !$this->validateRedirectUri($supplied_redirect_uri, $registered_redirect_uri)) {
- $response->setError(400, 'redirect_uri_mismatch', 'The redirect URI provided is missing or does not match', '#section-3.1.2');
-
- return false;
- }
- $redirect_uri = $supplied_redirect_uri;
- } else {
- // use the registered redirect_uri if none has been supplied, if possible
- if (!$registered_redirect_uri) {
- $response->setError(400, 'invalid_uri', 'No redirect URI was supplied or stored');
-
- return false;
- }
-
- if (count(explode(' ', $registered_redirect_uri)) > 1) {
- $response->setError(400, 'invalid_uri', 'A redirect URI must be supplied when multiple redirect URIs are registered', '#section-3.1.2.3');
-
- return false;
- }
- $redirect_uri = $registered_redirect_uri;
- }
-
- // Select the redirect URI
- $response_type = $request->query('response_type', $request->request('response_type'));
-
- // for multiple-valued response types - make them alphabetical
- if (false !== strpos($response_type, ' ')) {
- $types = explode(' ', $response_type);
- sort($types);
- $response_type = ltrim(implode(' ', $types));
- }
-
- $state = $request->query('state', $request->request('state'));
-
- // type and client_id are required
- if (!$response_type || !in_array($response_type, $this->getValidResponseTypes())) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'invalid_request', 'Invalid or missing response type', null);
-
- return false;
- }
-
- if ($response_type == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
- if (!isset($this->responseTypes['code'])) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unsupported_response_type', 'authorization code grant type not supported', null);
-
- return false;
- }
- if (!$this->clientStorage->checkRestrictedGrantType($client_id, 'authorization_code')) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unauthorized_client', 'The grant type is unauthorized for this client_id', null);
-
- return false;
- }
- if ($this->responseTypes['code']->enforceRedirect() && !$redirect_uri) {
- $response->setError(400, 'redirect_uri_mismatch', 'The redirect URI is mandatory and was not supplied');
-
- return false;
- }
- } else {
- if (!$this->config['allow_implicit']) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unsupported_response_type', 'implicit grant type not supported', null);
-
- return false;
- }
- if (!$this->clientStorage->checkRestrictedGrantType($client_id, 'implicit')) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unauthorized_client', 'The grant type is unauthorized for this client_id', null);
-
- return false;
- }
- }
-
- // validate requested scope if it exists
- $requestedScope = $this->scopeUtil->getScopeFromRequest($request);
-
- if ($requestedScope) {
- // restrict scope by client specific scope if applicable,
- // otherwise verify the scope exists
- $clientScope = $this->clientStorage->getClientScope($client_id);
- if ((empty($clientScope) && !$this->scopeUtil->scopeExists($requestedScope))
- || (!empty($clientScope) && !$this->scopeUtil->checkScope($requestedScope, $clientScope))) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'invalid_scope', 'An unsupported scope was requested', null);
-
- return false;
- }
- } else {
- // use a globally-defined default scope
- $defaultScope = $this->scopeUtil->getDefaultScope($client_id);
-
- if (false === $defaultScope) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'invalid_client', 'This application requires you specify a scope parameter', null);
-
- return false;
- }
-
- $requestedScope = $defaultScope;
- }
-
- // Validate state parameter exists (if configured to enforce this)
- if ($this->config['enforce_state'] && !$state) {
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, null, 'invalid_request', 'The state parameter is required');
-
- return false;
- }
-
- // save the input data and return true
- $this->scope = $requestedScope;
- $this->state = $state;
- $this->client_id = $client_id;
- // Only save the SUPPLIED redirect URI (@see http://tools.ietf.org/html/rfc6749#section-4.1.3)
- $this->redirect_uri = $supplied_redirect_uri;
- $this->response_type = $response_type;
-
- return true;
- }
-
- /**
- * Build the absolute URI based on supplied URI and parameters.
- *
- * @param $uri An absolute URI.
- * @param $params Parameters to be append as GET.
- *
- * @return
- * An absolute URI with supplied parameters.
- *
- * @ingroup oauth2_section_4
- */
- private function buildUri($uri, $params)
- {
- $parse_url = parse_url($uri);
-
- // Add our params to the parsed uri
- foreach ($params as $k => $v) {
- if (isset($parse_url[$k])) {
- $parse_url[$k] .= "&" . http_build_query($v, '', '&');
- } else {
- $parse_url[$k] = http_build_query($v, '', '&');
- }
- }
-
- // Put humpty dumpty back together
- return
- ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
- . ((isset($parse_url["user"])) ? $parse_url["user"]
- . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "")
- . ((isset($parse_url["host"])) ? $parse_url["host"] : "")
- . ((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "")
- . ((isset($parse_url["path"])) ? $parse_url["path"] : "")
- . ((isset($parse_url["query"]) && !empty($parse_url['query'])) ? "?" . $parse_url["query"] : "")
- . ((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "")
- ;
- }
-
- protected function getValidResponseTypes()
- {
- return array(
- self::RESPONSE_TYPE_ACCESS_TOKEN,
- self::RESPONSE_TYPE_AUTHORIZATION_CODE,
- );
- }
-
- /**
- * Internal method for validating redirect URI supplied
- *
- * @param string $inputUri The submitted URI to be validated
- * @param string $registeredUriString The allowed URI(s) to validate against. Can be a space-delimited string of URIs to
- * allow for multiple URIs
- *
- * @see http://tools.ietf.org/html/rfc6749#section-3.1.2
- */
- protected function validateRedirectUri($inputUri, $registeredUriString)
- {
- if (!$inputUri || !$registeredUriString) {
- return false; // if either one is missing, assume INVALID
- }
-
- $registered_uris = explode(' ', $registeredUriString);
- foreach ($registered_uris as $registered_uri) {
- if ($this->config['require_exact_redirect_uri']) {
- // the input uri is validated against the registered uri using exact match
- if (strcmp($inputUri, $registered_uri) === 0) {
- return true;
- }
- } else {
- $registered_uri_length = strlen($registered_uri);
- if ($registered_uri_length === 0) {
- return false;
- }
-
- // the input uri is validated against the registered uri using case-insensitive match of the initial string
- // i.e. additional query parameters may be applied
- if (strcasecmp(substr($inputUri, 0, $registered_uri_length), $registered_uri) === 0) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Convenience methods to access the parameters derived from the validated request
- */
-
- public function getScope()
- {
- return $this->scope;
- }
-
- public function getState()
- {
- return $this->state;
- }
-
- public function getClientId()
- {
- return $this->client_id;
- }
-
- public function getRedirectUri()
- {
- return $this->redirect_uri;
- }
-
- public function getResponseType()
- {
- return $this->response_type;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Controller/AuthorizeControllerInterface.php b/library/oauth2/src/OAuth2/Controller/AuthorizeControllerInterface.php
deleted file mode 100644
index fa07ae8d2..000000000
--- a/library/oauth2/src/OAuth2/Controller/AuthorizeControllerInterface.php
+++ /dev/null
@@ -1,43 +0,0 @@
- $user_id = $this->somehowDetermineUserId();
- * > $is_authorized = $this->somehowDetermineUserAuthorization();
- * > $response = new OAuth2\Response();
- * > $authorizeController->handleAuthorizeRequest(
- * > OAuth2\Request::createFromGlobals(),
- * > $response,
- * > $is_authorized,
- * > $user_id);
- * > $response->send();
- *
- */
-interface AuthorizeControllerInterface
-{
- /**
- * List of possible authentication response types.
- * The "authorization_code" mechanism exclusively supports 'code'
- * and the "implicit" mechanism exclusively supports 'token'.
- *
- * @var string
- * @see http://tools.ietf.org/html/rfc6749#section-4.1.1
- * @see http://tools.ietf.org/html/rfc6749#section-4.2.1
- */
- const RESPONSE_TYPE_AUTHORIZATION_CODE = 'code';
- const RESPONSE_TYPE_ACCESS_TOKEN = 'token';
-
- public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null);
-
- public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response);
-}
diff --git a/library/oauth2/src/OAuth2/Controller/ResourceController.php b/library/oauth2/src/OAuth2/Controller/ResourceController.php
deleted file mode 100644
index e8588188f..000000000
--- a/library/oauth2/src/OAuth2/Controller/ResourceController.php
+++ /dev/null
@@ -1,111 +0,0 @@
-tokenType = $tokenType;
- $this->tokenStorage = $tokenStorage;
-
- $this->config = array_merge(array(
- 'www_realm' => 'Service',
- ), $config);
-
- if (is_null($scopeUtil)) {
- $scopeUtil = new Scope();
- }
- $this->scopeUtil = $scopeUtil;
- }
-
- public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null)
- {
- $token = $this->getAccessTokenData($request, $response);
-
- // Check if we have token data
- if (is_null($token)) {
- return false;
- }
-
- /**
- * Check scope, if provided
- * If token doesn't have a scope, it's null/empty, or it's insufficient, then throw 403
- * @see http://tools.ietf.org/html/rfc6750#section-3.1
- */
- if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->scopeUtil->checkScope($scope, $token["scope"]))) {
- $response->setError(403, 'insufficient_scope', 'The request requires higher privileges than provided by the access token');
- $response->addHttpHeaders(array(
- 'WWW-Authenticate' => sprintf('%s realm="%s", scope="%s", error="%s", error_description="%s"',
- $this->tokenType->getTokenType(),
- $this->config['www_realm'],
- $scope,
- $response->getParameter('error'),
- $response->getParameter('error_description')
- )
- ));
-
- return false;
- }
-
- // allow retrieval of the token
- $this->token = $token;
-
- return (bool) $token;
- }
-
- public function getAccessTokenData(RequestInterface $request, ResponseInterface $response)
- {
- // Get the token parameter
- if ($token_param = $this->tokenType->getAccessTokenParameter($request, $response)) {
- // Get the stored token data (from the implementing subclass)
- // Check we have a well formed token
- // Check token expiration (expires is a mandatory paramter)
- if (!$token = $this->tokenStorage->getAccessToken($token_param)) {
- $response->setError(401, 'invalid_token', 'The access token provided is invalid');
- } elseif (!isset($token["expires"]) || !isset($token["client_id"])) {
- $response->setError(401, 'malformed_token', 'Malformed token (missing "expires")');
- } elseif (time() > $token["expires"]) {
- $response->setError(401, 'expired_token', 'The access token provided has expired');
- } else {
- return $token;
- }
- }
-
- $authHeader = sprintf('%s realm="%s"', $this->tokenType->getTokenType(), $this->config['www_realm']);
-
- if ($error = $response->getParameter('error')) {
- $authHeader = sprintf('%s, error="%s"', $authHeader, $error);
- if ($error_description = $response->getParameter('error_description')) {
- $authHeader = sprintf('%s, error_description="%s"', $authHeader, $error_description);
- }
- }
-
- $response->addHttpHeaders(array('WWW-Authenticate' => $authHeader));
-
- return null;
- }
-
- // convenience method to allow retrieval of the token
- public function getToken()
- {
- return $this->token;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Controller/ResourceControllerInterface.php b/library/oauth2/src/OAuth2/Controller/ResourceControllerInterface.php
deleted file mode 100644
index 611421935..000000000
--- a/library/oauth2/src/OAuth2/Controller/ResourceControllerInterface.php
+++ /dev/null
@@ -1,26 +0,0 @@
- if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
- * > $response->send(); // authorization failed
- * > die();
- * > }
- * > return json_encode($resource); // valid token! Send the stuff!
- *
- */
-interface ResourceControllerInterface
-{
- public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null);
-
- public function getAccessTokenData(RequestInterface $request, ResponseInterface $response);
-}
diff --git a/library/oauth2/src/OAuth2/Controller/TokenController.php b/library/oauth2/src/OAuth2/Controller/TokenController.php
deleted file mode 100644
index 42dab892f..000000000
--- a/library/oauth2/src/OAuth2/Controller/TokenController.php
+++ /dev/null
@@ -1,278 +0,0 @@
-clientAssertionType = $clientAssertionType;
- $this->accessToken = $accessToken;
- $this->clientStorage = $clientStorage;
- foreach ($grantTypes as $grantType) {
- $this->addGrantType($grantType);
- }
-
- if (is_null($scopeUtil)) {
- $scopeUtil = new Scope();
- }
- $this->scopeUtil = $scopeUtil;
- }
-
- public function handleTokenRequest(RequestInterface $request, ResponseInterface $response)
- {
- if ($token = $this->grantAccessToken($request, $response)) {
- // @see http://tools.ietf.org/html/rfc6749#section-5.1
- // server MUST disable caching in headers when tokens are involved
- $response->setStatusCode(200);
- $response->addParameters($token);
- $response->addHttpHeaders(array(
- 'Cache-Control' => 'no-store',
- 'Pragma' => 'no-cache',
- 'Content-Type' => 'application/json'
- ));
- }
- }
-
- /**
- * Grant or deny a requested access token.
- * This would be called from the "/token" endpoint as defined in the spec.
- * You can call your endpoint whatever you want.
- *
- * @param $request - RequestInterface
- * Request object to grant access token
- *
- * @throws InvalidArgumentException
- * @throws LogicException
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- * @see http://tools.ietf.org/html/rfc6749#section-10.6
- * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
- *
- * @ingroup oauth2_section_4
- */
- public function grantAccessToken(RequestInterface $request, ResponseInterface $response)
- {
- if (strtolower($request->server('REQUEST_METHOD')) != 'post') {
- $response->setError(405, 'invalid_request', 'The request method must be POST when requesting an access token', '#section-3.2');
- $response->addHttpHeaders(array('Allow' => 'POST'));
-
- return null;
- }
-
- /**
- * Determine grant type from request
- * and validate the request for that grant type
- */
- if (!$grantTypeIdentifier = $request->request('grant_type')) {
- $response->setError(400, 'invalid_request', 'The grant type was not specified in the request');
-
- return null;
- }
-
- if (!isset($this->grantTypes[$grantTypeIdentifier])) {
- /* TODO: If this is an OAuth2 supported grant type that we have chosen not to implement, throw a 501 Not Implemented instead */
- $response->setError(400, 'unsupported_grant_type', sprintf('Grant type "%s" not supported', $grantTypeIdentifier));
-
- return null;
- }
-
- $grantType = $this->grantTypes[$grantTypeIdentifier];
-
- /**
- * Retrieve the client information from the request
- * ClientAssertionTypes allow for grant types which also assert the client data
- * in which case ClientAssertion is handled in the validateRequest method
- *
- * @see OAuth2\GrantType\JWTBearer
- * @see OAuth2\GrantType\ClientCredentials
- */
- if (!$grantType instanceof ClientAssertionTypeInterface) {
- if (!$this->clientAssertionType->validateRequest($request, $response)) {
- return null;
- }
- $clientId = $this->clientAssertionType->getClientId();
- }
-
- /**
- * Retrieve the grant type information from the request
- * The GrantTypeInterface object handles all validation
- * If the object is an instance of ClientAssertionTypeInterface,
- * That logic is handled here as well
- */
- if (!$grantType->validateRequest($request, $response)) {
- return null;
- }
-
- if ($grantType instanceof ClientAssertionTypeInterface) {
- $clientId = $grantType->getClientId();
- } else {
- // validate the Client ID (if applicable)
- if (!is_null($storedClientId = $grantType->getClientId()) && $storedClientId != $clientId) {
- $response->setError(400, 'invalid_grant', sprintf('%s doesn\'t exist or is invalid for the client', $grantTypeIdentifier));
-
- return null;
- }
- }
-
- /**
- * Validate the client can use the requested grant type
- */
- if (!$this->clientStorage->checkRestrictedGrantType($clientId, $grantTypeIdentifier)) {
- $response->setError(400, 'unauthorized_client', 'The grant type is unauthorized for this client_id');
-
- return false;
- }
-
- /**
- * Validate the scope of the token
- *
- * requestedScope - the scope specified in the token request
- * availableScope - the scope associated with the grant type
- * ex: in the case of the "Authorization Code" grant type,
- * the scope is specified in the authorize request
- *
- * @see http://tools.ietf.org/html/rfc6749#section-3.3
- */
-
- $requestedScope = $this->scopeUtil->getScopeFromRequest($request);
- $availableScope = $grantType->getScope();
-
- if ($requestedScope) {
- // validate the requested scope
- if ($availableScope) {
- if (!$this->scopeUtil->checkScope($requestedScope, $availableScope)) {
- $response->setError(400, 'invalid_scope', 'The scope requested is invalid for this request');
-
- return null;
- }
- } else {
- // validate the client has access to this scope
- if ($clientScope = $this->clientStorage->getClientScope($clientId)) {
- if (!$this->scopeUtil->checkScope($requestedScope, $clientScope)) {
- $response->setError(400, 'invalid_scope', 'The scope requested is invalid for this client');
-
- return false;
- }
- } elseif (!$this->scopeUtil->scopeExists($requestedScope)) {
- $response->setError(400, 'invalid_scope', 'An unsupported scope was requested');
-
- return null;
- }
- }
- } elseif ($availableScope) {
- // use the scope associated with this grant type
- $requestedScope = $availableScope;
- } else {
- // use a globally-defined default scope
- $defaultScope = $this->scopeUtil->getDefaultScope($clientId);
-
- // "false" means default scopes are not allowed
- if (false === $defaultScope) {
- $response->setError(400, 'invalid_scope', 'This application requires you specify a scope parameter');
-
- return null;
- }
-
- $requestedScope = $defaultScope;
- }
-
- return $grantType->createAccessToken($this->accessToken, $clientId, $grantType->getUserId(), $requestedScope);
- }
-
- /**
- * addGrantType
- *
- * @param grantType - OAuth2\GrantTypeInterface
- * the grant type to add for the specified identifier
- * @param identifier - string
- * a string passed in as "grant_type" in the response that will call this grantType
- */
- public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
- {
- if (is_null($identifier) || is_numeric($identifier)) {
- $identifier = $grantType->getQuerystringIdentifier();
- }
-
- $this->grantTypes[$identifier] = $grantType;
- }
-
- public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response)
- {
- if ($this->revokeToken($request, $response)) {
- $response->setStatusCode(200);
- $response->addParameters(array('revoked' => true));
- }
- }
-
- /**
- * Revoke a refresh or access token. Returns true on success and when tokens are invalid
- *
- * Note: invalid tokens do not cause an error response since the client
- * cannot handle such an error in a reasonable way. Moreover, the
- * purpose of the revocation request, invalidating the particular token,
- * is already achieved.
- *
- * @param RequestInterface $request
- * @param ResponseInterface $response
- * @return bool|null
- */
- public function revokeToken(RequestInterface $request, ResponseInterface $response)
- {
- if (strtolower($request->server('REQUEST_METHOD')) != 'post') {
- $response->setError(405, 'invalid_request', 'The request method must be POST when revoking an access token', '#section-3.2');
- $response->addHttpHeaders(array('Allow' => 'POST'));
-
- return null;
- }
-
- $token_type_hint = $request->request('token_type_hint');
- if (!in_array($token_type_hint, array(null, 'access_token', 'refresh_token'), true)) {
- $response->setError(400, 'invalid_request', 'Token type hint must be either \'access_token\' or \'refresh_token\'');
-
- return null;
- }
-
- $token = $request->request('token');
- if ($token === null) {
- $response->setError(400, 'invalid_request', 'Missing token parameter to revoke');
-
- return null;
- }
-
- // @todo remove this check for v2.0
- if (!method_exists($this->accessToken, 'revokeToken')) {
- $class = get_class($this->accessToken);
- throw new \RuntimeException("AccessToken {$class} does not implement required revokeToken method");
- }
-
- $this->accessToken->revokeToken($token, $token_type_hint);
-
- return true;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Controller/TokenControllerInterface.php b/library/oauth2/src/OAuth2/Controller/TokenControllerInterface.php
deleted file mode 100644
index 72d72570f..000000000
--- a/library/oauth2/src/OAuth2/Controller/TokenControllerInterface.php
+++ /dev/null
@@ -1,32 +0,0 @@
- $tokenController->handleTokenRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response());
- * > $response->send();
- *
- */
-interface TokenControllerInterface
-{
- /**
- * handleTokenRequest
- *
- * @param $request
- * OAuth2\RequestInterface - The current http request
- * @param $response
- * OAuth2\ResponseInterface - An instance of OAuth2\ResponseInterface to contain the response data
- *
- */
- public function handleTokenRequest(RequestInterface $request, ResponseInterface $response);
-
- public function grantAccessToken(RequestInterface $request, ResponseInterface $response);
-}
diff --git a/library/oauth2/src/OAuth2/Encryption/EncryptionInterface.php b/library/oauth2/src/OAuth2/Encryption/EncryptionInterface.php
deleted file mode 100644
index 2d336c664..000000000
--- a/library/oauth2/src/OAuth2/Encryption/EncryptionInterface.php
+++ /dev/null
@@ -1,11 +0,0 @@
-
- */
-class FirebaseJwt implements EncryptionInterface
-{
- public function __construct()
- {
- if (!class_exists('\JWT')) {
- throw new \ErrorException('firebase/php-jwt must be installed to use this feature. You can do this by running "composer require firebase/php-jwt"');
- }
- }
-
- public function encode($payload, $key, $alg = 'HS256', $keyId = null)
- {
- return \JWT::encode($payload, $key, $alg, $keyId);
- }
-
- public function decode($jwt, $key = null, $allowedAlgorithms = null)
- {
- try {
-
- //Maintain BC: Do not verify if no algorithms are passed in.
- if (!$allowedAlgorithms) {
- $key = null;
- }
-
- return (array)\JWT::decode($jwt, $key, $allowedAlgorithms);
- } catch (\Exception $e) {
- return false;
- }
- }
-
- public function urlSafeB64Encode($data)
- {
- return \JWT::urlsafeB64Encode($data);
- }
-
- public function urlSafeB64Decode($b64)
- {
- return \JWT::urlsafeB64Decode($b64);
- }
-}
diff --git a/library/oauth2/src/OAuth2/Encryption/Jwt.php b/library/oauth2/src/OAuth2/Encryption/Jwt.php
deleted file mode 100644
index ee576e643..000000000
--- a/library/oauth2/src/OAuth2/Encryption/Jwt.php
+++ /dev/null
@@ -1,173 +0,0 @@
-generateJwtHeader($payload, $algo);
-
- $segments = array(
- $this->urlSafeB64Encode(json_encode($header)),
- $this->urlSafeB64Encode(json_encode($payload))
- );
-
- $signing_input = implode('.', $segments);
-
- $signature = $this->sign($signing_input, $key, $algo);
- $segments[] = $this->urlsafeB64Encode($signature);
-
- return implode('.', $segments);
- }
-
- public function decode($jwt, $key = null, $allowedAlgorithms = true)
- {
- if (!strpos($jwt, '.')) {
- return false;
- }
-
- $tks = explode('.', $jwt);
-
- if (count($tks) != 3) {
- return false;
- }
-
- list($headb64, $payloadb64, $cryptob64) = $tks;
-
- if (null === ($header = json_decode($this->urlSafeB64Decode($headb64), true))) {
- return false;
- }
-
- if (null === $payload = json_decode($this->urlSafeB64Decode($payloadb64), true)) {
- return false;
- }
-
- $sig = $this->urlSafeB64Decode($cryptob64);
-
- if ((bool) $allowedAlgorithms) {
- if (!isset($header['alg'])) {
- return false;
- }
-
- // check if bool arg supplied here to maintain BC
- if (is_array($allowedAlgorithms) && !in_array($header['alg'], $allowedAlgorithms)) {
- return false;
- }
-
- if (!$this->verifySignature($sig, "$headb64.$payloadb64", $key, $header['alg'])) {
- return false;
- }
- }
-
- return $payload;
- }
-
- private function verifySignature($signature, $input, $key, $algo = 'HS256')
- {
- // use constants when possible, for HipHop support
- switch ($algo) {
- case'HS256':
- case'HS384':
- case'HS512':
- return $this->hash_equals(
- $this->sign($input, $key, $algo),
- $signature
- );
-
- case 'RS256':
- return openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA256') ? OPENSSL_ALGO_SHA256 : 'sha256') === 1;
-
- case 'RS384':
- return @openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'sha384') === 1;
-
- case 'RS512':
- return @openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA512') ? OPENSSL_ALGO_SHA512 : 'sha512') === 1;
-
- default:
- throw new \InvalidArgumentException("Unsupported or invalid signing algorithm.");
- }
- }
-
- private function sign($input, $key, $algo = 'HS256')
- {
- switch ($algo) {
- case 'HS256':
- return hash_hmac('sha256', $input, $key, true);
-
- case 'HS384':
- return hash_hmac('sha384', $input, $key, true);
-
- case 'HS512':
- return hash_hmac('sha512', $input, $key, true);
-
- case 'RS256':
- return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA256') ? OPENSSL_ALGO_SHA256 : 'sha256');
-
- case 'RS384':
- return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'sha384');
-
- case 'RS512':
- return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA512') ? OPENSSL_ALGO_SHA512 : 'sha512');
-
- default:
- throw new \Exception("Unsupported or invalid signing algorithm.");
- }
- }
-
- private function generateRSASignature($input, $key, $algo)
- {
- if (!openssl_sign($input, $signature, $key, $algo)) {
- throw new \Exception("Unable to sign data.");
- }
-
- return $signature;
- }
-
- public function urlSafeB64Encode($data)
- {
- $b64 = base64_encode($data);
- $b64 = str_replace(array('+', '/', "\r", "\n", '='),
- array('-', '_'),
- $b64);
-
- return $b64;
- }
-
- public function urlSafeB64Decode($b64)
- {
- $b64 = str_replace(array('-', '_'),
- array('+', '/'),
- $b64);
-
- return base64_decode($b64);
- }
-
- /**
- * Override to create a custom header
- */
- protected function generateJwtHeader($payload, $algorithm)
- {
- return array(
- 'typ' => 'JWT',
- 'alg' => $algorithm,
- );
- }
-
- protected function hash_equals($a, $b)
- {
- if (function_exists('hash_equals')) {
- return hash_equals($a, $b);
- }
- $diff = strlen($a) ^ strlen($b);
- for ($i = 0; $i < strlen($a) && $i < strlen($b); $i++) {
- $diff |= ord($a[$i]) ^ ord($b[$i]);
- }
-
- return $diff === 0;
- }
-}
diff --git a/library/oauth2/src/OAuth2/GrantType/AuthorizationCode.php b/library/oauth2/src/OAuth2/GrantType/AuthorizationCode.php
deleted file mode 100644
index e8995204c..000000000
--- a/library/oauth2/src/OAuth2/GrantType/AuthorizationCode.php
+++ /dev/null
@@ -1,100 +0,0 @@
-
- */
-class AuthorizationCode implements GrantTypeInterface
-{
- protected $storage;
- protected $authCode;
-
- /**
- * @param OAuth2\Storage\AuthorizationCodeInterface $storage REQUIRED Storage class for retrieving authorization code information
- */
- public function __construct(AuthorizationCodeInterface $storage)
- {
- $this->storage = $storage;
- }
-
- public function getQuerystringIdentifier()
- {
- return 'authorization_code';
- }
-
- public function validateRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!$request->request('code')) {
- $response->setError(400, 'invalid_request', 'Missing parameter: "code" is required');
-
- return false;
- }
-
- $code = $request->request('code');
- if (!$authCode = $this->storage->getAuthorizationCode($code)) {
- $response->setError(400, 'invalid_grant', 'Authorization code doesn\'t exist or is invalid for the client');
-
- return false;
- }
-
- /*
- * 4.1.3 - ensure that the "redirect_uri" parameter is present if the "redirect_uri" parameter was included in the initial authorization request
- * @uri - http://tools.ietf.org/html/rfc6749#section-4.1.3
- */
- if (isset($authCode['redirect_uri']) && $authCode['redirect_uri']) {
- if (!$request->request('redirect_uri') || urldecode($request->request('redirect_uri')) != $authCode['redirect_uri']) {
- $response->setError(400, 'redirect_uri_mismatch', "The redirect URI is missing or do not match", "#section-4.1.3");
-
- return false;
- }
- }
-
- if (!isset($authCode['expires'])) {
- throw new \Exception('Storage must return authcode with a value for "expires"');
- }
-
- if ($authCode["expires"] < time()) {
- $response->setError(400, 'invalid_grant', "The authorization code has expired");
-
- return false;
- }
-
- if (!isset($authCode['code'])) {
- $authCode['code'] = $code; // used to expire the code after the access token is granted
- }
-
- $this->authCode = $authCode;
-
- return true;
- }
-
- public function getClientId()
- {
- return $this->authCode['client_id'];
- }
-
- public function getScope()
- {
- return isset($this->authCode['scope']) ? $this->authCode['scope'] : null;
- }
-
- public function getUserId()
- {
- return isset($this->authCode['user_id']) ? $this->authCode['user_id'] : null;
- }
-
- public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
- {
- $token = $accessToken->createAccessToken($client_id, $user_id, $scope);
- $this->storage->expireAuthorizationCode($this->authCode['code']);
-
- return $token;
- }
-}
diff --git a/library/oauth2/src/OAuth2/GrantType/ClientCredentials.php b/library/oauth2/src/OAuth2/GrantType/ClientCredentials.php
deleted file mode 100644
index f953e4e8d..000000000
--- a/library/oauth2/src/OAuth2/GrantType/ClientCredentials.php
+++ /dev/null
@@ -1,67 +0,0 @@
-
- *
- * @see OAuth2\ClientAssertionType_HttpBasic
- */
-class ClientCredentials extends HttpBasic implements GrantTypeInterface
-{
- private $clientData;
-
- public function __construct(ClientCredentialsInterface $storage, array $config = array())
- {
- /**
- * The client credentials grant type MUST only be used by confidential clients
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.4
- */
- $config['allow_public_clients'] = false;
-
- parent::__construct($storage, $config);
- }
-
- public function getQuerystringIdentifier()
- {
- return 'client_credentials';
- }
-
- public function getScope()
- {
- $this->loadClientData();
-
- return isset($this->clientData['scope']) ? $this->clientData['scope'] : null;
- }
-
- public function getUserId()
- {
- $this->loadClientData();
-
- return isset($this->clientData['user_id']) ? $this->clientData['user_id'] : null;
- }
-
- public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
- {
- /**
- * Client Credentials Grant does NOT include a refresh token
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.4.3
- */
- $includeRefreshToken = false;
-
- return $accessToken->createAccessToken($client_id, $user_id, $scope, $includeRefreshToken);
- }
-
- private function loadClientData()
- {
- if (!$this->clientData) {
- $this->clientData = $this->storage->getClientDetails($this->getClientId());
- }
- }
-}
diff --git a/library/oauth2/src/OAuth2/GrantType/GrantTypeInterface.php b/library/oauth2/src/OAuth2/GrantType/GrantTypeInterface.php
deleted file mode 100644
index 98489e9c1..000000000
--- a/library/oauth2/src/OAuth2/GrantType/GrantTypeInterface.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
- */
-class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
-{
- private $jwt;
-
- protected $storage;
- protected $audience;
- protected $jwtUtil;
- protected $allowedAlgorithms;
-
- /**
- * Creates an instance of the JWT bearer grant type.
- *
- * @param OAuth2\Storage\JWTBearerInterface|JwtBearerInterface $storage A valid storage interface that implements storage hooks for the JWT bearer grant type.
- * @param string $audience The audience to validate the token against. This is usually the full URI of the OAuth token requests endpoint.
- * @param EncryptionInterface|OAuth2\Encryption\JWT $jwtUtil OPTONAL The class used to decode, encode and verify JWTs.
- * @param array $config
- */
- public function __construct(JwtBearerInterface $storage, $audience, EncryptionInterface $jwtUtil = null, array $config = array())
- {
- $this->storage = $storage;
- $this->audience = $audience;
-
- if (is_null($jwtUtil)) {
- $jwtUtil = new Jwt();
- }
-
- $this->config = array_merge(array(
- 'allowed_algorithms' => array('RS256', 'RS384', 'RS512')
- ), $config);
-
- $this->jwtUtil = $jwtUtil;
-
- $this->allowedAlgorithms = $this->config['allowed_algorithms'];
- }
-
- /**
- * Returns the grant_type get parameter to identify the grant type request as JWT bearer authorization grant.
- *
- * @return
- * The string identifier for grant_type.
- *
- * @see OAuth2\GrantType\GrantTypeInterface::getQuerystringIdentifier()
- */
- public function getQuerystringIdentifier()
- {
- return 'urn:ietf:params:oauth:grant-type:jwt-bearer';
- }
-
- /**
- * Validates the data from the decoded JWT.
- *
- * @return
- * TRUE if the JWT request is valid and can be decoded. Otherwise, FALSE is returned.
- *
- * @see OAuth2\GrantType\GrantTypeInterface::getTokenData()
- */
- public function validateRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!$request->request("assertion")) {
- $response->setError(400, 'invalid_request', 'Missing parameters: "assertion" required');
-
- return null;
- }
-
- // Store the undecoded JWT for later use
- $undecodedJWT = $request->request('assertion');
-
- // Decode the JWT
- $jwt = $this->jwtUtil->decode($request->request('assertion'), null, false);
-
- if (!$jwt) {
- $response->setError(400, 'invalid_request', "JWT is malformed");
-
- return null;
- }
-
- // ensure these properties contain a value
- // @todo: throw malformed error for missing properties
- $jwt = array_merge(array(
- 'scope' => null,
- 'iss' => null,
- 'sub' => null,
- 'aud' => null,
- 'exp' => null,
- 'nbf' => null,
- 'iat' => null,
- 'jti' => null,
- 'typ' => null,
- ), $jwt);
-
- if (!isset($jwt['iss'])) {
- $response->setError(400, 'invalid_grant', "Invalid issuer (iss) provided");
-
- return null;
- }
-
- if (!isset($jwt['sub'])) {
- $response->setError(400, 'invalid_grant', "Invalid subject (sub) provided");
-
- return null;
- }
-
- if (!isset($jwt['exp'])) {
- $response->setError(400, 'invalid_grant', "Expiration (exp) time must be present");
-
- return null;
- }
-
- // Check expiration
- if (ctype_digit($jwt['exp'])) {
- if ($jwt['exp'] <= time()) {
- $response->setError(400, 'invalid_grant', "JWT has expired");
-
- return null;
- }
- } else {
- $response->setError(400, 'invalid_grant', "Expiration (exp) time must be a unix time stamp");
-
- return null;
- }
-
- // Check the not before time
- if ($notBefore = $jwt['nbf']) {
- if (ctype_digit($notBefore)) {
- if ($notBefore > time()) {
- $response->setError(400, 'invalid_grant', "JWT cannot be used before the Not Before (nbf) time");
-
- return null;
- }
- } else {
- $response->setError(400, 'invalid_grant', "Not Before (nbf) time must be a unix time stamp");
-
- return null;
- }
- }
-
- // Check the audience if required to match
- if (!isset($jwt['aud']) || ($jwt['aud'] != $this->audience)) {
- $response->setError(400, 'invalid_grant', "Invalid audience (aud)");
-
- return null;
- }
-
- // Check the jti (nonce)
- // @see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1.7
- if (isset($jwt['jti'])) {
- $jti = $this->storage->getJti($jwt['iss'], $jwt['sub'], $jwt['aud'], $jwt['exp'], $jwt['jti']);
-
- //Reject if jti is used and jwt is still valid (exp parameter has not expired).
- if ($jti && $jti['expires'] > time()) {
- $response->setError(400, 'invalid_grant', "JSON Token Identifier (jti) has already been used");
-
- return null;
- } else {
- $this->storage->setJti($jwt['iss'], $jwt['sub'], $jwt['aud'], $jwt['exp'], $jwt['jti']);
- }
- }
-
- // Get the iss's public key
- // @see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06#section-4.1.1
- if (!$key = $this->storage->getClientKey($jwt['iss'], $jwt['sub'])) {
- $response->setError(400, 'invalid_grant', "Invalid issuer (iss) or subject (sub) provided");
-
- return null;
- }
-
- // Verify the JWT
- if (!$this->jwtUtil->decode($undecodedJWT, $key, $this->allowedAlgorithms)) {
- $response->setError(400, 'invalid_grant', "JWT failed signature verification");
-
- return null;
- }
-
- $this->jwt = $jwt;
-
- return true;
- }
-
- public function getClientId()
- {
- return $this->jwt['iss'];
- }
-
- public function getUserId()
- {
- return $this->jwt['sub'];
- }
-
- public function getScope()
- {
- return null;
- }
-
- /**
- * Creates an access token that is NOT associated with a refresh token.
- * If a subject (sub) the name of the user/account we are accessing data on behalf of.
- *
- * @see OAuth2\GrantType\GrantTypeInterface::createAccessToken()
- */
- public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
- {
- $includeRefreshToken = false;
-
- return $accessToken->createAccessToken($client_id, $user_id, $scope, $includeRefreshToken);
- }
-}
diff --git a/library/oauth2/src/OAuth2/GrantType/RefreshToken.php b/library/oauth2/src/OAuth2/GrantType/RefreshToken.php
deleted file mode 100644
index e55385222..000000000
--- a/library/oauth2/src/OAuth2/GrantType/RefreshToken.php
+++ /dev/null
@@ -1,111 +0,0 @@
-
- */
-class RefreshToken implements GrantTypeInterface
-{
- private $refreshToken;
-
- protected $storage;
- protected $config;
-
- /**
- * @param OAuth2\Storage\RefreshTokenInterface $storage REQUIRED Storage class for retrieving refresh token information
- * @param array $config OPTIONAL Configuration options for the server
- *
- * $config = array(
- * 'always_issue_new_refresh_token' => true, // whether to issue a new refresh token upon successful token request
- * 'unset_refresh_token_after_use' => true // whether to unset the refresh token after after using
- * );
- *
- */
- public function __construct(RefreshTokenInterface $storage, $config = array())
- {
- $this->config = array_merge(array(
- 'always_issue_new_refresh_token' => false,
- 'unset_refresh_token_after_use' => true
- ), $config);
-
- // to preserve B.C. with v1.6
- // @see https://github.com/bshaffer/oauth2-server-php/pull/580
- // @todo - remove in v2.0
- if (isset($config['always_issue_new_refresh_token']) && !isset($config['unset_refresh_token_after_use'])) {
- $this->config['unset_refresh_token_after_use'] = $config['always_issue_new_refresh_token'];
- }
-
- $this->storage = $storage;
- }
-
- public function getQuerystringIdentifier()
- {
- return 'refresh_token';
- }
-
- public function validateRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!$request->request("refresh_token")) {
- $response->setError(400, 'invalid_request', 'Missing parameter: "refresh_token" is required');
-
- return null;
- }
-
- if (!$refreshToken = $this->storage->getRefreshToken($request->request("refresh_token"))) {
- $response->setError(400, 'invalid_grant', 'Invalid refresh token');
-
- return null;
- }
-
- if ($refreshToken['expires'] > 0 && $refreshToken["expires"] < time()) {
- $response->setError(400, 'invalid_grant', 'Refresh token has expired');
-
- return null;
- }
-
- // store the refresh token locally so we can delete it when a new refresh token is generated
- $this->refreshToken = $refreshToken;
-
- return true;
- }
-
- public function getClientId()
- {
- return $this->refreshToken['client_id'];
- }
-
- public function getUserId()
- {
- return isset($this->refreshToken['user_id']) ? $this->refreshToken['user_id'] : null;
- }
-
- public function getScope()
- {
- return isset($this->refreshToken['scope']) ? $this->refreshToken['scope'] : null;
- }
-
- public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
- {
- /*
- * It is optional to force a new refresh token when a refresh token is used.
- * However, if a new refresh token is issued, the old one MUST be expired
- * @see http://tools.ietf.org/html/rfc6749#section-6
- */
- $issueNewRefreshToken = $this->config['always_issue_new_refresh_token'];
- $unsetRefreshToken = $this->config['unset_refresh_token_after_use'];
- $token = $accessToken->createAccessToken($client_id, $user_id, $scope, $issueNewRefreshToken);
-
- if ($unsetRefreshToken) {
- $this->storage->unsetRefreshToken($this->refreshToken['refresh_token']);
- }
-
- return $token;
- }
-}
diff --git a/library/oauth2/src/OAuth2/GrantType/UserCredentials.php b/library/oauth2/src/OAuth2/GrantType/UserCredentials.php
deleted file mode 100644
index f165538ba..000000000
--- a/library/oauth2/src/OAuth2/GrantType/UserCredentials.php
+++ /dev/null
@@ -1,83 +0,0 @@
-
- */
-class UserCredentials implements GrantTypeInterface
-{
- private $userInfo;
-
- protected $storage;
-
- /**
- * @param OAuth2\Storage\UserCredentialsInterface $storage REQUIRED Storage class for retrieving user credentials information
- */
- public function __construct(UserCredentialsInterface $storage)
- {
- $this->storage = $storage;
- }
-
- public function getQuerystringIdentifier()
- {
- return 'password';
- }
-
- public function validateRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!$request->request("password") || !$request->request("username")) {
- $response->setError(400, 'invalid_request', 'Missing parameters: "username" and "password" required');
-
- return null;
- }
-
- if (!$this->storage->checkUserCredentials($request->request("username"), $request->request("password"))) {
- $response->setError(401, 'invalid_grant', 'Invalid username and password combination');
-
- return null;
- }
-
- $userInfo = $this->storage->getUserDetails($request->request("username"));
-
- if (empty($userInfo)) {
- $response->setError(400, 'invalid_grant', 'Unable to retrieve user information');
-
- return null;
- }
-
- if (!isset($userInfo['user_id'])) {
- throw new \LogicException("you must set the user_id on the array returned by getUserDetails");
- }
-
- $this->userInfo = $userInfo;
-
- return true;
- }
-
- public function getClientId()
- {
- return null;
- }
-
- public function getUserId()
- {
- return $this->userInfo['user_id'];
- }
-
- public function getScope()
- {
- return isset($this->userInfo['scope']) ? $this->userInfo['scope'] : null;
- }
-
- public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
- {
- return $accessToken->createAccessToken($client_id, $user_id, $scope);
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeController.php b/library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeController.php
deleted file mode 100644
index c9b5c6af7..000000000
--- a/library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeController.php
+++ /dev/null
@@ -1,106 +0,0 @@
-query('prompt', 'consent');
- if ($prompt == 'none') {
- if (is_null($user_id)) {
- $error = 'login_required';
- $error_message = 'The user must log in';
- } else {
- $error = 'interaction_required';
- $error_message = 'The user must grant access to your application';
- }
- } else {
- $error = 'consent_required';
- $error_message = 'The user denied access to your application';
- }
-
- $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->getState(), $error, $error_message);
- }
-
- protected function buildAuthorizeParameters($request, $response, $user_id)
- {
- if (!$params = parent::buildAuthorizeParameters($request, $response, $user_id)) {
- return;
- }
-
- // Generate an id token if needed.
- if ($this->needsIdToken($this->getScope()) && $this->getResponseType() == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
- $params['id_token'] = $this->responseTypes['id_token']->createIdToken($this->getClientId(), $user_id, $this->nonce);
- }
-
- // add the nonce to return with the redirect URI
- $params['nonce'] = $this->nonce;
-
- return $params;
- }
-
- public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!parent::validateAuthorizeRequest($request, $response)) {
- return false;
- }
-
- $nonce = $request->query('nonce');
-
- // Validate required nonce for "id_token" and "id_token token"
- if (!$nonce && in_array($this->getResponseType(), array(self::RESPONSE_TYPE_ID_TOKEN, self::RESPONSE_TYPE_ID_TOKEN_TOKEN))) {
- $response->setError(400, 'invalid_nonce', 'This application requires you specify a nonce parameter');
-
- return false;
- }
-
- $this->nonce = $nonce;
-
- return true;
- }
-
- protected function getValidResponseTypes()
- {
- return array(
- self::RESPONSE_TYPE_ACCESS_TOKEN,
- self::RESPONSE_TYPE_AUTHORIZATION_CODE,
- self::RESPONSE_TYPE_ID_TOKEN,
- self::RESPONSE_TYPE_ID_TOKEN_TOKEN,
- self::RESPONSE_TYPE_CODE_ID_TOKEN,
- );
- }
-
- /**
- * Returns whether the current request needs to generate an id token.
- *
- * ID Tokens are a part of the OpenID Connect specification, so this
- * method checks whether OpenID Connect is enabled in the server settings
- * and whether the openid scope was requested.
- *
- * @param $request_scope
- * A space-separated string of scopes.
- *
- * @return
- * TRUE if an id token is needed, FALSE otherwise.
- */
- public function needsIdToken($request_scope)
- {
- // see if the "openid" scope exists in the requested scope
- return $this->scopeUtil->checkScope('openid', $request_scope);
- }
-
- public function getNonce()
- {
- return $this->nonce;
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php b/library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
deleted file mode 100644
index 1e231d844..000000000
--- a/library/oauth2/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
+++ /dev/null
@@ -1,10 +0,0 @@
-tokenType = $tokenType;
- $this->tokenStorage = $tokenStorage;
- $this->userClaimsStorage = $userClaimsStorage;
-
- $this->config = array_merge(array(
- 'www_realm' => 'Service',
- ), $config);
-
- if (is_null($scopeUtil)) {
- $scopeUtil = new Scope();
- }
- $this->scopeUtil = $scopeUtil;
- }
-
- public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response)
- {
- if (!$this->verifyResourceRequest($request, $response, 'openid')) {
- return;
- }
-
- $token = $this->getToken();
- $claims = $this->userClaimsStorage->getUserClaims($token['user_id'], $token['scope']);
- // The sub Claim MUST always be returned in the UserInfo Response.
- // http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
- $claims += array(
- 'sub' => $token['user_id'],
- );
- $response->addParameters($claims);
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php b/library/oauth2/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
deleted file mode 100644
index a89049d49..000000000
--- a/library/oauth2/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
+++ /dev/null
@@ -1,23 +0,0 @@
- $response = new OAuth2\Response();
- * > $userInfoController->handleUserInfoRequest(
- * > OAuth2\Request::createFromGlobals(),
- * > $response;
- * > $response->send();
- *
- */
-interface UserInfoControllerInterface
-{
- public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response);
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/GrantType/AuthorizationCode.php b/library/oauth2/src/OAuth2/OpenID/GrantType/AuthorizationCode.php
deleted file mode 100644
index 8ed1edc26..000000000
--- a/library/oauth2/src/OAuth2/OpenID/GrantType/AuthorizationCode.php
+++ /dev/null
@@ -1,33 +0,0 @@
-
- */
-class AuthorizationCode extends BaseAuthorizationCode
-{
- public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
- {
- $includeRefreshToken = true;
- if (isset($this->authCode['id_token'])) {
- // OpenID Connect requests include the refresh token only if the
- // offline_access scope has been requested and granted.
- $scopes = explode(' ', trim($scope));
- $includeRefreshToken = in_array('offline_access', $scopes);
- }
-
- $token = $accessToken->createAccessToken($client_id, $user_id, $scope, $includeRefreshToken);
- if (isset($this->authCode['id_token'])) {
- $token['id_token'] = $this->authCode['id_token'];
- }
-
- $this->storage->expireAuthorizationCode($this->authCode['code']);
-
- return $token;
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php b/library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php
deleted file mode 100644
index 8971954c5..000000000
--- a/library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php
+++ /dev/null
@@ -1,60 +0,0 @@
-
- */
-class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCodeInterface
-{
- public function __construct(AuthorizationCodeStorageInterface $storage, array $config = array())
- {
- parent::__construct($storage, $config);
- }
-
- public function getAuthorizeResponse($params, $user_id = null)
- {
- // build the URL to redirect to
- $result = array('query' => array());
-
- $params += array('scope' => null, 'state' => null, 'id_token' => null);
-
- $result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['id_token']);
-
- if (isset($params['state'])) {
- $result['query']['state'] = $params['state'];
- }
-
- return array($params['redirect_uri'], $result);
- }
-
- /**
- * Handle the creation of the authorization code.
- *
- * @param $client_id
- * Client identifier related to the authorization code
- * @param $user_id
- * User ID associated with the authorization code
- * @param $redirect_uri
- * An absolute URI to which the authorization server will redirect the
- * user-agent to when the end-user authorization step is completed.
- * @param $scope
- * (optional) Scopes to be stored in space-separated string.
- * @param $id_token
- * (optional) The OpenID Connect id_token.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- * @ingroup oauth2_section_4
- */
- public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null)
- {
- $code = $this->generateAuthorizationCode();
- $this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, $id_token);
-
- return $code;
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php b/library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
deleted file mode 100644
index ea4779255..000000000
--- a/library/oauth2/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
+++ /dev/null
@@ -1,27 +0,0 @@
-
- */
-interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
-{
- /**
- * Handle the creation of the authorization code.
- *
- * @param $client_id Client identifier related to the authorization code
- * @param $user_id User ID associated with the authorization code
- * @param $redirect_uri An absolute URI to which the authorization server will redirect the
- * user-agent to when the end-user authorization step is completed.
- * @param $scope OPTIONAL Scopes to be stored in space-separated string.
- * @param $id_token OPTIONAL The OpenID Connect id_token.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- * @ingroup oauth2_section_4
- */
- public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null);
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdToken.php b/library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdToken.php
deleted file mode 100644
index ac7764d6c..000000000
--- a/library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdToken.php
+++ /dev/null
@@ -1,24 +0,0 @@
-authCode = $authCode;
- $this->idToken = $idToken;
- }
-
- public function getAuthorizeResponse($params, $user_id = null)
- {
- $result = $this->authCode->getAuthorizeResponse($params, $user_id);
- $resultIdToken = $this->idToken->getAuthorizeResponse($params, $user_id);
- $result[1]['query']['id_token'] = $resultIdToken[1]['fragment']['id_token'];
-
- return $result;
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php b/library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php
deleted file mode 100644
index 629adcca8..000000000
--- a/library/oauth2/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php
+++ /dev/null
@@ -1,9 +0,0 @@
-userClaimsStorage = $userClaimsStorage;
- $this->publicKeyStorage = $publicKeyStorage;
- if (is_null($encryptionUtil)) {
- $encryptionUtil = new Jwt();
- }
- $this->encryptionUtil = $encryptionUtil;
-
- if (!isset($config['issuer'])) {
- throw new \LogicException('config parameter "issuer" must be set');
- }
- $this->config = array_merge(array(
- 'id_lifetime' => 3600,
- ), $config);
- }
-
- public function getAuthorizeResponse($params, $userInfo = null)
- {
- // build the URL to redirect to
- $result = array('query' => array());
- $params += array('scope' => null, 'state' => null, 'nonce' => null);
-
- // create the id token.
- list($user_id, $auth_time) = $this->getUserIdAndAuthTime($userInfo);
- $userClaims = $this->userClaimsStorage->getUserClaims($user_id, $params['scope']);
-
- $id_token = $this->createIdToken($params['client_id'], $userInfo, $params['nonce'], $userClaims, null);
- $result["fragment"] = array('id_token' => $id_token);
- if (isset($params['state'])) {
- $result["fragment"]["state"] = $params['state'];
- }
-
- return array($params['redirect_uri'], $result);
- }
-
- public function createIdToken($client_id, $userInfo, $nonce = null, $userClaims = null, $access_token = null)
- {
- // pull auth_time from user info if supplied
- list($user_id, $auth_time) = $this->getUserIdAndAuthTime($userInfo);
-
- $token = array(
- 'iss' => $this->config['issuer'],
- 'sub' => $user_id,
- 'aud' => $client_id,
- 'iat' => time(),
- 'exp' => time() + $this->config['id_lifetime'],
- 'auth_time' => $auth_time,
- );
-
- if ($nonce) {
- $token['nonce'] = $nonce;
- }
-
- if ($userClaims) {
- $token += $userClaims;
- }
-
- if ($access_token) {
- $token['at_hash'] = $this->createAtHash($access_token, $client_id);
- }
-
- return $this->encodeToken($token, $client_id);
- }
-
- protected function createAtHash($access_token, $client_id = null)
- {
- // maps HS256 and RS256 to sha256, etc.
- $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
- $hash_algorithm = 'sha' . substr($algorithm, 2);
- $hash = hash($hash_algorithm, $access_token, true);
- $at_hash = substr($hash, 0, strlen($hash) / 2);
-
- return $this->encryptionUtil->urlSafeB64Encode($at_hash);
- }
-
- protected function encodeToken(array $token, $client_id = null)
- {
- $private_key = $this->publicKeyStorage->getPrivateKey($client_id);
- $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
-
- return $this->encryptionUtil->encode($token, $private_key, $algorithm);
- }
-
- private function getUserIdAndAuthTime($userInfo)
- {
- $auth_time = null;
-
- // support an array for user_id / auth_time
- if (is_array($userInfo)) {
- if (!isset($userInfo['user_id'])) {
- throw new \LogicException('if $user_id argument is an array, user_id index must be set');
- }
-
- $auth_time = isset($userInfo['auth_time']) ? $userInfo['auth_time'] : null;
- $user_id = $userInfo['user_id'];
- } else {
- $user_id = $userInfo;
- }
-
- if (is_null($auth_time)) {
- $auth_time = time();
- }
-
- // userInfo is a scalar, and so this is the $user_id. Auth Time is null
- return array($user_id, $auth_time);
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php b/library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php
deleted file mode 100644
index 0bd2f8391..000000000
--- a/library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-accessToken = $accessToken;
- $this->idToken = $idToken;
- }
-
- public function getAuthorizeResponse($params, $user_id = null)
- {
- $result = $this->accessToken->getAuthorizeResponse($params, $user_id);
- $access_token = $result[1]['fragment']['access_token'];
- $id_token = $this->idToken->createIdToken($params['client_id'], $user_id, $params['nonce'], null, $access_token);
- $result[1]['fragment']['id_token'] = $id_token;
-
- return $result;
- }
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php b/library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php
deleted file mode 100644
index ac13e2032..000000000
--- a/library/oauth2/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php
+++ /dev/null
@@ -1,9 +0,0 @@
-
- */
-interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
-{
- /**
- * Take the provided authorization code values and store them somewhere.
- *
- * This function should be the storage counterpart to getAuthCode().
- *
- * If storage fails for some reason, we're not currently checking for
- * any sort of success/failure, so you should bail out of the script
- * and provide a descriptive fail message.
- *
- * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
- *
- * @param $code authorization code to be stored.
- * @param $client_id client identifier to be stored.
- * @param $user_id user identifier to be stored.
- * @param string $redirect_uri redirect URI(s) to be stored in a space-separated string.
- * @param int $expires expiration to be stored as a Unix timestamp.
- * @param string $scope OPTIONAL scopes to be stored in space-separated string.
- * @param string $id_token OPTIONAL the OpenID Connect id_token.
- *
- * @ingroup oauth2_section_4
- */
- public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null);
-}
diff --git a/library/oauth2/src/OAuth2/OpenID/Storage/UserClaimsInterface.php b/library/oauth2/src/OAuth2/OpenID/Storage/UserClaimsInterface.php
deleted file mode 100644
index f230bef9e..000000000
--- a/library/oauth2/src/OAuth2/OpenID/Storage/UserClaimsInterface.php
+++ /dev/null
@@ -1,38 +0,0 @@
- value format.
- *
- * @see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
- */
- public function getUserClaims($user_id, $scope);
-}
diff --git a/library/oauth2/src/OAuth2/Request.php b/library/oauth2/src/OAuth2/Request.php
deleted file mode 100644
index c92cee821..000000000
--- a/library/oauth2/src/OAuth2/Request.php
+++ /dev/null
@@ -1,213 +0,0 @@
-initialize($query, $request, $attributes, $cookies, $files, $server, $content, $headers);
- }
-
- /**
- * Sets the parameters for this request.
- *
- * This method also re-initializes all properties.
- *
- * @param array $query The GET parameters
- * @param array $request The POST parameters
- * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
- * @param array $cookies The COOKIE parameters
- * @param array $files The FILES parameters
- * @param array $server The SERVER parameters
- * @param string $content The raw body data
- *
- * @api
- */
- public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, array $headers = null)
- {
- $this->request = $request;
- $this->query = $query;
- $this->attributes = $attributes;
- $this->cookies = $cookies;
- $this->files = $files;
- $this->server = $server;
- $this->content = $content;
- $this->headers = is_null($headers) ? $this->getHeadersFromServer($this->server) : $headers;
- }
-
- public function query($name, $default = null)
- {
- return isset($this->query[$name]) ? $this->query[$name] : $default;
- }
-
- public function request($name, $default = null)
- {
- return isset($this->request[$name]) ? $this->request[$name] : $default;
- }
-
- public function server($name, $default = null)
- {
- return isset($this->server[$name]) ? $this->server[$name] : $default;
- }
-
- public function headers($name, $default = null)
- {
- $headers = array_change_key_case($this->headers);
- $name = strtolower($name);
-
- return isset($headers[$name]) ? $headers[$name] : $default;
- }
-
- public function getAllQueryParameters()
- {
- return $this->query;
- }
-
- /**
- * Returns the request body content.
- *
- * @param Boolean $asResource If true, a resource will be returned
- *
- * @return string|resource The request body content or a resource to read the body stream.
- */
- public function getContent($asResource = false)
- {
- if (false === $this->content || (true === $asResource && null !== $this->content)) {
- throw new \LogicException('getContent() can only be called once when using the resource return type.');
- }
-
- if (true === $asResource) {
- $this->content = false;
-
- return fopen('php://input', 'rb');
- }
-
- if (null === $this->content) {
- $this->content = file_get_contents('php://input');
- }
-
- return $this->content;
- }
-
- private function getHeadersFromServer($server)
- {
- $headers = array();
- foreach ($server as $key => $value) {
- if (0 === strpos($key, 'HTTP_')) {
- $headers[substr($key, 5)] = $value;
- }
- // CONTENT_* are not prefixed with HTTP_
- elseif (in_array($key, array('CONTENT_LENGTH', 'CONTENT_MD5', 'CONTENT_TYPE'))) {
- $headers[$key] = $value;
- }
- }
-
- if (isset($server['PHP_AUTH_USER'])) {
- $headers['PHP_AUTH_USER'] = $server['PHP_AUTH_USER'];
- $headers['PHP_AUTH_PW'] = isset($server['PHP_AUTH_PW']) ? $server['PHP_AUTH_PW'] : '';
- } else {
- /*
- * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
- * For this workaround to work, add this line to your .htaccess file:
- * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
- *
- * A sample .htaccess file:
- * RewriteEngine On
- * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
- * RewriteCond %{REQUEST_FILENAME} !-f
- * RewriteRule ^(.*)$ app.php [QSA,L]
- */
-
- $authorizationHeader = null;
- if (isset($server['HTTP_AUTHORIZATION'])) {
- $authorizationHeader = $server['HTTP_AUTHORIZATION'];
- } elseif (isset($server['REDIRECT_HTTP_AUTHORIZATION'])) {
- $authorizationHeader = $server['REDIRECT_HTTP_AUTHORIZATION'];
- } elseif (function_exists('apache_request_headers')) {
- $requestHeaders = (array) apache_request_headers();
-
- // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
- $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
-
- if (isset($requestHeaders['Authorization'])) {
- $authorizationHeader = trim($requestHeaders['Authorization']);
- }
- }
-
- if (null !== $authorizationHeader) {
- $headers['AUTHORIZATION'] = $authorizationHeader;
- // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
- if (0 === stripos($authorizationHeader, 'basic')) {
- $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)));
- if (count($exploded) == 2) {
- list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
- }
- }
- }
- }
-
- // PHP_AUTH_USER/PHP_AUTH_PW
- if (isset($headers['PHP_AUTH_USER'])) {
- $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
- }
-
- return $headers;
- }
-
- /**
- * Creates a new request with values from PHP's super globals.
- *
- * @return Request A new request
- *
- * @api
- */
- public static function createFromGlobals()
- {
- $class = get_called_class();
- $request = new $class($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
-
- $contentType = $request->server('CONTENT_TYPE', '');
- $requestMethod = $request->server('REQUEST_METHOD', 'GET');
- if (0 === strpos($contentType, 'application/x-www-form-urlencoded')
- && in_array(strtoupper($requestMethod), array('PUT', 'DELETE'))
- ) {
- parse_str($request->getContent(), $data);
- $request->request = $data;
- } elseif (0 === strpos($contentType, 'application/json')
- && in_array(strtoupper($requestMethod), array('POST', 'PUT', 'DELETE'))
- ) {
- $data = json_decode($request->getContent(), true);
- $request->request = $data;
- }
-
- return $request;
- }
-}
diff --git a/library/oauth2/src/OAuth2/RequestInterface.php b/library/oauth2/src/OAuth2/RequestInterface.php
deleted file mode 100644
index 8a70d5fad..000000000
--- a/library/oauth2/src/OAuth2/RequestInterface.php
+++ /dev/null
@@ -1,16 +0,0 @@
- 'Continue',
- 101 => 'Switching Protocols',
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 303 => 'See Other',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested Range Not Satisfiable',
- 417 => 'Expectation Failed',
- 418 => 'I\'m a teapot',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported',
- );
-
- public function __construct($parameters = array(), $statusCode = 200, $headers = array())
- {
- $this->setParameters($parameters);
- $this->setStatusCode($statusCode);
- $this->setHttpHeaders($headers);
- $this->version = '1.1';
- }
-
- /**
- * Converts the response object to string containing all headers and the response content.
- *
- * @return string The response with headers and content
- */
- public function __toString()
- {
- $headers = array();
- foreach ($this->httpHeaders as $name => $value) {
- $headers[$name] = (array) $value;
- }
-
- return
- sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
- $this->getHttpHeadersAsString($headers)."\r\n".
- $this->getResponseBody();
- }
-
- /**
- * Returns the build header line.
- *
- * @param string $name The header name
- * @param string $value The header value
- *
- * @return string The built header line
- */
- protected function buildHeader($name, $value)
- {
- return sprintf("%s: %s\n", $name, $value);
- }
-
- public function getStatusCode()
- {
- return $this->statusCode;
- }
-
- public function setStatusCode($statusCode, $text = null)
- {
- $this->statusCode = (int) $statusCode;
- if ($this->isInvalid()) {
- throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $statusCode));
- }
-
- $this->statusText = false === $text ? '' : (null === $text ? self::$statusTexts[$this->statusCode] : $text);
- }
-
- public function getStatusText()
- {
- return $this->statusText;
- }
-
- public function getParameters()
- {
- return $this->parameters;
- }
-
- public function setParameters(array $parameters)
- {
- $this->parameters = $parameters;
- }
-
- public function addParameters(array $parameters)
- {
- $this->parameters = array_merge($this->parameters, $parameters);
- }
-
- public function getParameter($name, $default = null)
- {
- return isset($this->parameters[$name]) ? $this->parameters[$name] : $default;
- }
-
- public function setParameter($name, $value)
- {
- $this->parameters[$name] = $value;
- }
-
- public function setHttpHeaders(array $httpHeaders)
- {
- $this->httpHeaders = $httpHeaders;
- }
-
- public function setHttpHeader($name, $value)
- {
- $this->httpHeaders[$name] = $value;
- }
-
- public function addHttpHeaders(array $httpHeaders)
- {
- $this->httpHeaders = array_merge($this->httpHeaders, $httpHeaders);
- }
-
- public function getHttpHeaders()
- {
- return $this->httpHeaders;
- }
-
- public function getHttpHeader($name, $default = null)
- {
- return isset($this->httpHeaders[$name]) ? $this->httpHeaders[$name] : $default;
- }
-
- public function getResponseBody($format = 'json')
- {
- switch ($format) {
- case 'json':
- return json_encode($this->parameters);
- case 'xml':
- // this only works for single-level arrays
- $xml = new \SimpleXMLElement('');
- foreach ($this->parameters as $key => $param) {
- $xml->addChild($key, $param);
- }
-
- return $xml->asXML();
- }
-
- throw new \InvalidArgumentException(sprintf('The format %s is not supported', $format));
-
- }
-
- public function send($format = 'json')
- {
- // headers have already been sent by the developer
- if (headers_sent()) {
- return;
- }
-
- switch ($format) {
- case 'json':
- $this->setHttpHeader('Content-Type', 'application/json');
- break;
- case 'xml':
- $this->setHttpHeader('Content-Type', 'text/xml');
- break;
- }
- // status
- header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
-
- foreach ($this->getHttpHeaders() as $name => $header) {
- header(sprintf('%s: %s', $name, $header));
- }
- echo $this->getResponseBody($format);
- }
-
- public function setError($statusCode, $error, $errorDescription = null, $errorUri = null)
- {
- $parameters = array(
- 'error' => $error,
- 'error_description' => $errorDescription,
- );
-
- if (!is_null($errorUri)) {
- if (strlen($errorUri) > 0 && $errorUri[0] == '#') {
- // we are referencing an oauth bookmark (for brevity)
- $errorUri = 'http://tools.ietf.org/html/rfc6749' . $errorUri;
- }
- $parameters['error_uri'] = $errorUri;
- }
-
- $httpHeaders = array(
- 'Cache-Control' => 'no-store'
- );
-
- $this->setStatusCode($statusCode);
- $this->addParameters($parameters);
- $this->addHttpHeaders($httpHeaders);
-
- if (!$this->isClientError() && !$this->isServerError()) {
- throw new \InvalidArgumentException(sprintf('The HTTP status code is not an error ("%s" given).', $statusCode));
- }
- }
-
- public function setRedirect($statusCode, $url, $state = null, $error = null, $errorDescription = null, $errorUri = null)
- {
- if (empty($url)) {
- throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
- }
-
- $parameters = array();
-
- if (!is_null($state)) {
- $parameters['state'] = $state;
- }
-
- if (!is_null($error)) {
- $this->setError(400, $error, $errorDescription, $errorUri);
- }
- $this->setStatusCode($statusCode);
- $this->addParameters($parameters);
-
- if (count($this->parameters) > 0) {
- // add parameters to URL redirection
- $parts = parse_url($url);
- $sep = isset($parts['query']) && count($parts['query']) > 0 ? '&' : '?';
- $url .= $sep . http_build_query($this->parameters);
- }
-
- $this->addHttpHeaders(array('Location' => $url));
-
- if (!$this->isRedirection()) {
- throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $statusCode));
- }
- }
-
- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
- /**
- * @return Boolean
- *
- * @api
- */
- public function isInvalid()
- {
- return $this->statusCode < 100 || $this->statusCode >= 600;
- }
-
- /**
- * @return Boolean
- *
- * @api
- */
- public function isInformational()
- {
- return $this->statusCode >= 100 && $this->statusCode < 200;
- }
-
- /**
- * @return Boolean
- *
- * @api
- */
- public function isSuccessful()
- {
- return $this->statusCode >= 200 && $this->statusCode < 300;
- }
-
- /**
- * @return Boolean
- *
- * @api
- */
- public function isRedirection()
- {
- return $this->statusCode >= 300 && $this->statusCode < 400;
- }
-
- /**
- * @return Boolean
- *
- * @api
- */
- public function isClientError()
- {
- return $this->statusCode >= 400 && $this->statusCode < 500;
- }
-
- /**
- * @return Boolean
- *
- * @api
- */
- public function isServerError()
- {
- return $this->statusCode >= 500 && $this->statusCode < 600;
- }
-
- /*
- * Functions from Symfony2 HttpFoundation - output pretty header
- */
- private function getHttpHeadersAsString($headers)
- {
- if (count($headers) == 0) {
- return '';
- }
-
- $max = max(array_map('strlen', array_keys($headers))) + 1;
- $content = '';
- ksort($headers);
- foreach ($headers as $name => $values) {
- foreach ($values as $value) {
- $content .= sprintf("%-{$max}s %s\r\n", $this->beautifyHeaderName($name).':', $value);
- }
- }
-
- return $content;
- }
-
- private function beautifyHeaderName($name)
- {
- return preg_replace_callback('/\-(.)/', array($this, 'beautifyCallback'), ucfirst($name));
- }
-
- private function beautifyCallback($match)
- {
- return '-'.strtoupper($match[1]);
- }
-}
diff --git a/library/oauth2/src/OAuth2/ResponseInterface.php b/library/oauth2/src/OAuth2/ResponseInterface.php
deleted file mode 100644
index c99b5f7d1..000000000
--- a/library/oauth2/src/OAuth2/ResponseInterface.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- */
-class AccessToken implements AccessTokenInterface
-{
- protected $tokenStorage;
- protected $refreshStorage;
- protected $config;
-
- /**
- * @param OAuth2\Storage\AccessTokenInterface $tokenStorage REQUIRED Storage class for saving access token information
- * @param OAuth2\Storage\RefreshTokenInterface $refreshStorage OPTIONAL Storage class for saving refresh token information
- * @param array $config OPTIONAL Configuration options for the server
- *
- * $config = array(
- * 'token_type' => 'bearer', // token type identifier
- * 'access_lifetime' => 3600, // time before access token expires
- * 'refresh_token_lifetime' => 1209600, // time before refresh token expires
- * );
- *
- */
- public function __construct(AccessTokenStorageInterface $tokenStorage, RefreshTokenInterface $refreshStorage = null, array $config = array())
- {
- $this->tokenStorage = $tokenStorage;
- $this->refreshStorage = $refreshStorage;
-
- $this->config = array_merge(array(
- 'token_type' => 'bearer',
- 'access_lifetime' => 3600,
- 'refresh_token_lifetime' => 1209600,
- ), $config);
- }
-
- public function getAuthorizeResponse($params, $user_id = null)
- {
- // build the URL to redirect to
- $result = array('query' => array());
-
- $params += array('scope' => null, 'state' => null);
-
- /*
- * a refresh token MUST NOT be included in the fragment
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.2.2
- */
- $includeRefreshToken = false;
- $result["fragment"] = $this->createAccessToken($params['client_id'], $user_id, $params['scope'], $includeRefreshToken);
-
- if (isset($params['state'])) {
- $result["fragment"]["state"] = $params['state'];
- }
-
- return array($params['redirect_uri'], $result);
- }
-
- /**
- * Handle the creation of access token, also issue refresh token if supported / desirable.
- *
- * @param $client_id client identifier related to the access token.
- * @param $user_id user ID associated with the access token
- * @param $scope OPTIONAL scopes to be stored in space-separated string.
- * @param bool $includeRefreshToken if true, a new refresh_token will be added to the response
- *
- * @see http://tools.ietf.org/html/rfc6749#section-5
- * @ingroup oauth2_section_5
- */
- public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
- {
- $token = array(
- "access_token" => $this->generateAccessToken(),
- "expires_in" => $this->config['access_lifetime'],
- "token_type" => $this->config['token_type'],
- "scope" => $scope
- );
-
- $this->tokenStorage->setAccessToken($token["access_token"], $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
-
- /*
- * Issue a refresh token also, if we support them
- *
- * Refresh Tokens are considered supported if an instance of OAuth2\Storage\RefreshTokenInterface
- * is supplied in the constructor
- */
- if ($includeRefreshToken && $this->refreshStorage) {
- $token["refresh_token"] = $this->generateRefreshToken();
- $expires = 0;
- if ($this->config['refresh_token_lifetime'] > 0) {
- $expires = time() + $this->config['refresh_token_lifetime'];
- }
- $this->refreshStorage->setRefreshToken($token['refresh_token'], $client_id, $user_id, $expires, $scope);
- }
-
- return $token;
- }
-
- /**
- * Generates an unique access token.
- *
- * Implementing classes may want to override this function to implement
- * other access token generation schemes.
- *
- * @return
- * An unique access token.
- *
- * @ingroup oauth2_section_4
- */
- protected function generateAccessToken()
- {
- if (function_exists('mcrypt_create_iv')) {
- $randomData = mcrypt_create_iv(20, MCRYPT_DEV_URANDOM);
- if ($randomData !== false && strlen($randomData) === 20) {
- return bin2hex($randomData);
- }
- }
- if (function_exists('openssl_random_pseudo_bytes')) {
- $randomData = openssl_random_pseudo_bytes(20);
- if ($randomData !== false && strlen($randomData) === 20) {
- return bin2hex($randomData);
- }
- }
- if (@file_exists('/dev/urandom')) { // Get 100 bytes of random data
- $randomData = file_get_contents('/dev/urandom', false, null, 0, 20);
- if ($randomData !== false && strlen($randomData) === 20) {
- return bin2hex($randomData);
- }
- }
- // Last resort which you probably should just get rid of:
- $randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);
-
- return substr(hash('sha512', $randomData), 0, 40);
- }
-
- /**
- * Generates an unique refresh token
- *
- * Implementing classes may want to override this function to implement
- * other refresh token generation schemes.
- *
- * @return
- * An unique refresh.
- *
- * @ingroup oauth2_section_4
- * @see OAuth2::generateAccessToken()
- */
- protected function generateRefreshToken()
- {
- return $this->generateAccessToken(); // let's reuse the same scheme for token generation
- }
-
- /**
- * Handle the revoking of refresh tokens, and access tokens if supported / desirable
- * RFC7009 specifies that "If the server is unable to locate the token using
- * the given hint, it MUST extend its search across all of its supported token types"
- *
- * @param $token
- * @param null $tokenTypeHint
- * @return boolean
- */
- public function revokeToken($token, $tokenTypeHint = null)
- {
- if ($tokenTypeHint == 'refresh_token') {
- if ($this->refreshStorage && $revoked = $this->refreshStorage->unsetRefreshToken($token)) {
- return true;
- }
- }
-
- /** @TODO remove in v2 */
- if (!method_exists($this->tokenStorage, 'unsetAccessToken')) {
- throw new \RuntimeException(
- sprintf('Token storage %s must implement unsetAccessToken method', get_class($this->tokenStorage)
- ));
- }
-
- $revoked = $this->tokenStorage->unsetAccessToken($token);
-
- // if a typehint is supplied and fails, try other storages
- // @see https://tools.ietf.org/html/rfc7009#section-2.1
- if (!$revoked && $tokenTypeHint != 'refresh_token') {
- if ($this->refreshStorage) {
- $revoked = $this->refreshStorage->unsetRefreshToken($token);
- }
- }
-
- return $revoked;
- }
-}
diff --git a/library/oauth2/src/OAuth2/ResponseType/AccessTokenInterface.php b/library/oauth2/src/OAuth2/ResponseType/AccessTokenInterface.php
deleted file mode 100644
index 4bd3928d8..000000000
--- a/library/oauth2/src/OAuth2/ResponseType/AccessTokenInterface.php
+++ /dev/null
@@ -1,34 +0,0 @@
-
- */
-interface AccessTokenInterface extends ResponseTypeInterface
-{
- /**
- * Handle the creation of access token, also issue refresh token if supported / desirable.
- *
- * @param $client_id client identifier related to the access token.
- * @param $user_id user ID associated with the access token
- * @param $scope OPTONAL scopes to be stored in space-separated string.
- * @param bool $includeRefreshToken if true, a new refresh_token will be added to the response
- *
- * @see http://tools.ietf.org/html/rfc6749#section-5
- * @ingroup oauth2_section_5
- */
- public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true);
-
- /**
- * Handle the revoking of refresh tokens, and access tokens if supported / desirable
- *
- * @param $token
- * @param $tokenTypeHint
- * @return mixed
- *
- * @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
- */
- //public function revokeToken($token, $tokenTypeHint);
-}
diff --git a/library/oauth2/src/OAuth2/ResponseType/AuthorizationCode.php b/library/oauth2/src/OAuth2/ResponseType/AuthorizationCode.php
deleted file mode 100644
index 6a305fd75..000000000
--- a/library/oauth2/src/OAuth2/ResponseType/AuthorizationCode.php
+++ /dev/null
@@ -1,100 +0,0 @@
-
- */
-class AuthorizationCode implements AuthorizationCodeInterface
-{
- protected $storage;
- protected $config;
-
- public function __construct(AuthorizationCodeStorageInterface $storage, array $config = array())
- {
- $this->storage = $storage;
- $this->config = array_merge(array(
- 'enforce_redirect' => false,
- 'auth_code_lifetime' => 30,
- ), $config);
- }
-
- public function getAuthorizeResponse($params, $user_id = null)
- {
- // build the URL to redirect to
- $result = array('query' => array());
-
- $params += array('scope' => null, 'state' => null);
-
- $result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope']);
-
- if (isset($params['state'])) {
- $result['query']['state'] = $params['state'];
- }
-
- return array($params['redirect_uri'], $result);
- }
-
- /**
- * Handle the creation of the authorization code.
- *
- * @param $client_id
- * Client identifier related to the authorization code
- * @param $user_id
- * User ID associated with the authorization code
- * @param $redirect_uri
- * An absolute URI to which the authorization server will redirect the
- * user-agent to when the end-user authorization step is completed.
- * @param $scope
- * (optional) Scopes to be stored in space-separated string.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- * @ingroup oauth2_section_4
- */
- public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null)
- {
- $code = $this->generateAuthorizationCode();
- $this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope);
-
- return $code;
- }
-
- /**
- * @return
- * TRUE if the grant type requires a redirect_uri, FALSE if not
- */
- public function enforceRedirect()
- {
- return $this->config['enforce_redirect'];
- }
-
- /**
- * Generates an unique auth code.
- *
- * Implementing classes may want to override this function to implement
- * other auth code generation schemes.
- *
- * @return
- * An unique auth code.
- *
- * @ingroup oauth2_section_4
- */
- protected function generateAuthorizationCode()
- {
- $tokenLen = 40;
- if (function_exists('mcrypt_create_iv')) {
- $randomData = mcrypt_create_iv(100, MCRYPT_DEV_URANDOM);
- } elseif (function_exists('openssl_random_pseudo_bytes')) {
- $randomData = openssl_random_pseudo_bytes(100);
- } elseif (@file_exists('/dev/urandom')) { // Get 100 bytes of random data
- $randomData = file_get_contents('/dev/urandom', false, null, 0, 100) . uniqid(mt_rand(), true);
- } else {
- $randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);
- }
-
- return substr(hash('sha512', $randomData), 0, $tokenLen);
- }
-}
diff --git a/library/oauth2/src/OAuth2/ResponseType/AuthorizationCodeInterface.php b/library/oauth2/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
deleted file mode 100644
index df777e221..000000000
--- a/library/oauth2/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
- */
-interface AuthorizationCodeInterface extends ResponseTypeInterface
-{
- /**
- * @return
- * TRUE if the grant type requires a redirect_uri, FALSE if not
- */
- public function enforceRedirect();
-
- /**
- * Handle the creation of the authorization code.
- *
- * @param $client_id client identifier related to the authorization code
- * @param $user_id user id associated with the authorization code
- * @param $redirect_uri an absolute URI to which the authorization server will redirect the
- * user-agent to when the end-user authorization step is completed.
- * @param $scope OPTIONAL scopes to be stored in space-separated string.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- * @ingroup oauth2_section_4
- */
- public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null);
-}
diff --git a/library/oauth2/src/OAuth2/ResponseType/JwtAccessToken.php b/library/oauth2/src/OAuth2/ResponseType/JwtAccessToken.php
deleted file mode 100644
index 3942fe41e..000000000
--- a/library/oauth2/src/OAuth2/ResponseType/JwtAccessToken.php
+++ /dev/null
@@ -1,124 +0,0 @@
-
- */
-class JwtAccessToken extends AccessToken
-{
- protected $publicKeyStorage;
- protected $encryptionUtil;
-
- /**
- * @param $config
- * - store_encrypted_token_string (bool true)
- * whether the entire encrypted string is stored,
- * or just the token ID is stored
- */
- public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
- {
- $this->publicKeyStorage = $publicKeyStorage;
- $config = array_merge(array(
- 'store_encrypted_token_string' => true,
- 'issuer' => ''
- ), $config);
- if (is_null($tokenStorage)) {
- // a pass-thru, so we can call the parent constructor
- $tokenStorage = new Memory();
- }
- if (is_null($encryptionUtil)) {
- $encryptionUtil = new Jwt();
- }
- $this->encryptionUtil = $encryptionUtil;
- parent::__construct($tokenStorage, $refreshStorage, $config);
- }
-
- /**
- * Handle the creation of access token, also issue refresh token if supported / desirable.
- *
- * @param $client_id
- * Client identifier related to the access token.
- * @param $user_id
- * User ID associated with the access token
- * @param $scope
- * (optional) Scopes to be stored in space-separated string.
- * @param bool $includeRefreshToken
- * If true, a new refresh_token will be added to the response
- *
- * @see http://tools.ietf.org/html/rfc6749#section-5
- * @ingroup oauth2_section_5
- */
- public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
- {
- // token to encrypt
- $expires = time() + $this->config['access_lifetime'];
- $id = $this->generateAccessToken();
- $jwtAccessToken = array(
- 'id' => $id, // for BC (see #591)
- 'jti' => $id,
- 'iss' => $this->config['issuer'],
- 'aud' => $client_id,
- 'sub' => $user_id,
- 'exp' => $expires,
- 'iat' => time(),
- 'token_type' => $this->config['token_type'],
- 'scope' => $scope
- );
-
- /*
- * Encode the token data into a single access_token string
- */
- $access_token = $this->encodeToken($jwtAccessToken, $client_id);
-
- /*
- * Save the token to a secondary storage. This is implemented on the
- * OAuth2\Storage\JwtAccessToken side, and will not actually store anything,
- * if no secondary storage has been supplied
- */
- $token_to_store = $this->config['store_encrypted_token_string'] ? $access_token : $jwtAccessToken['id'];
- $this->tokenStorage->setAccessToken($token_to_store, $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
-
- // token to return to the client
- $token = array(
- 'access_token' => $access_token,
- 'expires_in' => $this->config['access_lifetime'],
- 'token_type' => $this->config['token_type'],
- 'scope' => $scope
- );
-
- /*
- * Issue a refresh token also, if we support them
- *
- * Refresh Tokens are considered supported if an instance of OAuth2\Storage\RefreshTokenInterface
- * is supplied in the constructor
- */
- if ($includeRefreshToken && $this->refreshStorage) {
- $refresh_token = $this->generateRefreshToken();
- $expires = 0;
- if ($this->config['refresh_token_lifetime'] > 0) {
- $expires = time() + $this->config['refresh_token_lifetime'];
- }
- $this->refreshStorage->setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope);
- $token['refresh_token'] = $refresh_token;
- }
-
- return $token;
- }
-
- protected function encodeToken(array $token, $client_id = null)
- {
- $private_key = $this->publicKeyStorage->getPrivateKey($client_id);
- $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
-
- return $this->encryptionUtil->encode($token, $private_key, $algorithm);
- }
-}
diff --git a/library/oauth2/src/OAuth2/ResponseType/ResponseTypeInterface.php b/library/oauth2/src/OAuth2/ResponseType/ResponseTypeInterface.php
deleted file mode 100644
index f8e26a5b0..000000000
--- a/library/oauth2/src/OAuth2/ResponseType/ResponseTypeInterface.php
+++ /dev/null
@@ -1,8 +0,0 @@
-storage = $storage;
- }
-
- /**
- * Check if everything in required scope is contained in available scope.
- *
- * @param $required_scope
- * A space-separated string of scopes.
- *
- * @return
- * TRUE if everything in required scope is contained in available scope,
- * and FALSE if it isn't.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-7
- *
- * @ingroup oauth2_section_7
- */
- public function checkScope($required_scope, $available_scope)
- {
- $required_scope = explode(' ', trim($required_scope));
- $available_scope = explode(' ', trim($available_scope));
-
- return (count(array_diff($required_scope, $available_scope)) == 0);
- }
-
- /**
- * Check if the provided scope exists in storage.
- *
- * @param $scope
- * A space-separated string of scopes.
- *
- * @return
- * TRUE if it exists, FALSE otherwise.
- */
- public function scopeExists($scope)
- {
- // Check reserved scopes first.
- $scope = explode(' ', trim($scope));
- $reservedScope = $this->getReservedScopes();
- $nonReservedScopes = array_diff($scope, $reservedScope);
- if (count($nonReservedScopes) == 0) {
- return true;
- } else {
- // Check the storage for non-reserved scopes.
- $nonReservedScopes = implode(' ', $nonReservedScopes);
-
- return $this->storage->scopeExists($nonReservedScopes);
- }
- }
-
- public function getScopeFromRequest(RequestInterface $request)
- {
- // "scope" is valid if passed in either POST or QUERY
- return $request->request('scope', $request->query('scope'));
- }
-
- public function getDefaultScope($client_id = null)
- {
- return $this->storage->getDefaultScope($client_id);
- }
-
- /**
- * Get reserved scopes needed by the server.
- *
- * In case OpenID Connect is used, these scopes must include:
- * 'openid', offline_access'.
- *
- * @return
- * An array of reserved scopes.
- */
- public function getReservedScopes()
- {
- return array('openid', 'offline_access');
- }
-}
diff --git a/library/oauth2/src/OAuth2/ScopeInterface.php b/library/oauth2/src/OAuth2/ScopeInterface.php
deleted file mode 100644
index 5b60f9aee..000000000
--- a/library/oauth2/src/OAuth2/ScopeInterface.php
+++ /dev/null
@@ -1,40 +0,0 @@
- 'OAuth2\Storage\AccessTokenInterface',
- 'authorization_code' => 'OAuth2\Storage\AuthorizationCodeInterface',
- 'client_credentials' => 'OAuth2\Storage\ClientCredentialsInterface',
- 'client' => 'OAuth2\Storage\ClientInterface',
- 'refresh_token' => 'OAuth2\Storage\RefreshTokenInterface',
- 'user_credentials' => 'OAuth2\Storage\UserCredentialsInterface',
- 'user_claims' => 'OAuth2\OpenID\Storage\UserClaimsInterface',
- 'public_key' => 'OAuth2\Storage\PublicKeyInterface',
- 'jwt_bearer' => 'OAuth2\Storage\JWTBearerInterface',
- 'scope' => 'OAuth2\Storage\ScopeInterface',
- );
-
- protected $responseTypeMap = array(
- 'token' => 'OAuth2\ResponseType\AccessTokenInterface',
- 'code' => 'OAuth2\ResponseType\AuthorizationCodeInterface',
- 'id_token' => 'OAuth2\OpenID\ResponseType\IdTokenInterface',
- 'id_token token' => 'OAuth2\OpenID\ResponseType\IdTokenTokenInterface',
- 'code id_token' => 'OAuth2\OpenID\ResponseType\CodeIdTokenInterface',
- );
-
- /**
- * @param mixed $storage (array or OAuth2\Storage) - single object or array of objects implementing the
- * required storage types (ClientCredentialsInterface and AccessTokenInterface as a minimum)
- * @param array $config specify a different token lifetime, token header name, etc
- * @param array $grantTypes An array of OAuth2\GrantType\GrantTypeInterface to use for granting access tokens
- * @param array $responseTypes Response types to use. array keys should be "code" and and "token" for
- * Access Token and Authorization Code response types
- * @param OAuth2\TokenType\TokenTypeInterface $tokenType The token type object to use. Valid token types are "bearer" and "mac"
- * @param OAuth2\ScopeInterface $scopeUtil The scope utility class to use to validate scope
- * @param OAuth2\ClientAssertionType\ClientAssertionTypeInterface $clientAssertionType The method in which to verify the client identity. Default is HttpBasic
- *
- * @ingroup oauth2_section_7
- */
- public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), TokenTypeInterface $tokenType = null, ScopeInterface $scopeUtil = null, ClientAssertionTypeInterface $clientAssertionType = null)
- {
- $storage = is_array($storage) ? $storage : array($storage);
- $this->storages = array();
- foreach ($storage as $key => $service) {
- $this->addStorage($service, $key);
- }
-
- // merge all config values. These get passed to our controller objects
- $this->config = array_merge(array(
- 'use_jwt_access_tokens' => false,
- 'store_encrypted_token_string' => true,
- 'use_openid_connect' => false,
- 'id_lifetime' => 3600,
- 'access_lifetime' => 3600,
- 'www_realm' => 'Service',
- 'token_param_name' => 'access_token',
- 'token_bearer_header_name' => 'Bearer',
- 'enforce_state' => true,
- 'require_exact_redirect_uri' => true,
- 'allow_implicit' => false,
- 'allow_credentials_in_request_body' => true,
- 'allow_public_clients' => true,
- 'always_issue_new_refresh_token' => false,
- 'unset_refresh_token_after_use' => true,
- ), $config);
-
- foreach ($grantTypes as $key => $grantType) {
- $this->addGrantType($grantType, $key);
- }
-
- foreach ($responseTypes as $key => $responseType) {
- $this->addResponseType($responseType, $key);
- }
-
- $this->tokenType = $tokenType;
- $this->scopeUtil = $scopeUtil;
- $this->clientAssertionType = $clientAssertionType;
-
- if ($this->config['use_openid_connect']) {
- $this->validateOpenIdConnect();
- }
- }
-
- public function getAuthorizeController()
- {
- if (is_null($this->authorizeController)) {
- $this->authorizeController = $this->createDefaultAuthorizeController();
- }
-
- return $this->authorizeController;
- }
-
- public function getTokenController()
- {
- if (is_null($this->tokenController)) {
- $this->tokenController = $this->createDefaultTokenController();
- }
-
- return $this->tokenController;
- }
-
- public function getResourceController()
- {
- if (is_null($this->resourceController)) {
- $this->resourceController = $this->createDefaultResourceController();
- }
-
- return $this->resourceController;
- }
-
- public function getUserInfoController()
- {
- if (is_null($this->userInfoController)) {
- $this->userInfoController = $this->createDefaultUserInfoController();
- }
-
- return $this->userInfoController;
- }
-
- /**
- * every getter deserves a setter
- */
- public function setAuthorizeController(AuthorizeControllerInterface $authorizeController)
- {
- $this->authorizeController = $authorizeController;
- }
-
- /**
- * every getter deserves a setter
- */
- public function setTokenController(TokenControllerInterface $tokenController)
- {
- $this->tokenController = $tokenController;
- }
-
- /**
- * every getter deserves a setter
- */
- public function setResourceController(ResourceControllerInterface $resourceController)
- {
- $this->resourceController = $resourceController;
- }
-
- /**
- * every getter deserves a setter
- */
- public function setUserInfoController(UserInfoControllerInterface $userInfoController)
- {
- $this->userInfoController = $userInfoController;
- }
-
- /**
- * Return claims about the authenticated end-user.
- * This would be called from the "/UserInfo" endpoint as defined in the spec.
- *
- * @param $request - OAuth2\RequestInterface
- * Request object to grant access token
- *
- * @param $response - OAuth2\ResponseInterface
- * Response object containing error messages (failure) or user claims (success)
- *
- * @throws InvalidArgumentException
- * @throws LogicException
- *
- * @see http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
- */
- public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $this->getUserInfoController()->handleUserInfoRequest($request, $this->response);
-
- return $this->response;
- }
-
- /**
- * Grant or deny a requested access token.
- * This would be called from the "/token" endpoint as defined in the spec.
- * Obviously, you can call your endpoint whatever you want.
- *
- * @param $request - OAuth2\RequestInterface
- * Request object to grant access token
- *
- * @param $response - OAuth2\ResponseInterface
- * Response object containing error messages (failure) or access token (success)
- *
- * @throws InvalidArgumentException
- * @throws LogicException
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- * @see http://tools.ietf.org/html/rfc6749#section-10.6
- * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
- *
- * @ingroup oauth2_section_4
- */
- public function handleTokenRequest(RequestInterface $request, ResponseInterface $response = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $this->getTokenController()->handleTokenRequest($request, $this->response);
-
- return $this->response;
- }
-
- public function grantAccessToken(RequestInterface $request, ResponseInterface $response = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $value = $this->getTokenController()->grantAccessToken($request, $this->response);
-
- return $value;
- }
-
- /**
- * Handle a revoke token request
- * This would be called from the "/revoke" endpoint as defined in the draft Token Revocation spec
- *
- * @see https://tools.ietf.org/html/rfc7009#section-2
- *
- * @param RequestInterface $request
- * @param ResponseInterface $response
- * @return Response|ResponseInterface
- */
- public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $this->getTokenController()->handleRevokeRequest($request, $this->response);
-
- return $this->response;
- }
-
- /**
- * Redirect the user appropriately after approval.
- *
- * After the user has approved or denied the resource request the
- * authorization server should call this function to redirect the user
- * appropriately.
- *
- * @param $request
- * The request should have the follow parameters set in the querystring:
- * - response_type: The requested response: an access token, an
- * authorization code, or both.
- * - client_id: The client identifier as described in Section 2.
- * - redirect_uri: An absolute URI to which the authorization server
- * will redirect the user-agent to when the end-user authorization
- * step is completed.
- * - scope: (optional) The scope of the resource request expressed as a
- * list of space-delimited strings.
- * - state: (optional) An opaque value used by the client to maintain
- * state between the request and callback.
- * @param $is_authorized
- * TRUE or FALSE depending on whether the user authorized the access.
- * @param $user_id
- * Identifier of user who authorized the client
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4
- *
- * @ingroup oauth2_section_4
- */
- public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null)
- {
- $this->response = $response;
- $this->getAuthorizeController()->handleAuthorizeRequest($request, $this->response, $is_authorized, $user_id);
-
- return $this->response;
- }
-
- /**
- * Pull the authorization request data out of the HTTP request.
- * - The redirect_uri is OPTIONAL as per draft 20. But your implementation can enforce it
- * by setting $config['enforce_redirect'] to true.
- * - The state is OPTIONAL but recommended to enforce CSRF. Draft 21 states, however, that
- * CSRF protection is MANDATORY. You can enforce this by setting the $config['enforce_state'] to true.
- *
- * The draft specifies that the parameters should be retrieved from GET, override the Response
- * object to change this
- *
- * @return
- * The authorization parameters so the authorization server can prompt
- * the user for approval if valid.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.1.1
- * @see http://tools.ietf.org/html/rfc6749#section-10.12
- *
- * @ingroup oauth2_section_3
- */
- public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $value = $this->getAuthorizeController()->validateAuthorizeRequest($request, $this->response);
-
- return $value;
- }
-
- public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response = null, $scope = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $value = $this->getResourceController()->verifyResourceRequest($request, $this->response, $scope);
-
- return $value;
- }
-
- public function getAccessTokenData(RequestInterface $request, ResponseInterface $response = null)
- {
- $this->response = is_null($response) ? new Response() : $response;
- $value = $this->getResourceController()->getAccessTokenData($request, $this->response);
-
- return $value;
- }
-
- public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
- {
- if (!is_string($identifier)) {
- $identifier = $grantType->getQuerystringIdentifier();
- }
-
- $this->grantTypes[$identifier] = $grantType;
-
- // persist added grant type down to TokenController
- if (!is_null($this->tokenController)) {
- $this->getTokenController()->addGrantType($grantType, $identifier);
- }
- }
-
- /**
- * Set a storage object for the server
- *
- * @param $storage
- * An object implementing one of the Storage interfaces
- * @param $key
- * If null, the storage is set to the key of each storage interface it implements
- *
- * @see storageMap
- */
- public function addStorage($storage, $key = null)
- {
- // if explicitly set to a valid key, do not "magically" set below
- if (isset($this->storageMap[$key])) {
- if (!is_null($storage) && !$storage instanceof $this->storageMap[$key]) {
- throw new \InvalidArgumentException(sprintf('storage of type "%s" must implement interface "%s"', $key, $this->storageMap[$key]));
- }
- $this->storages[$key] = $storage;
-
- // special logic to handle "client" and "client_credentials" strangeness
- if ($key === 'client' && !isset($this->storages['client_credentials'])) {
- if ($storage instanceof \OAuth2\Storage\ClientCredentialsInterface) {
- $this->storages['client_credentials'] = $storage;
- }
- } elseif ($key === 'client_credentials' && !isset($this->storages['client'])) {
- if ($storage instanceof \OAuth2\Storage\ClientInterface) {
- $this->storages['client'] = $storage;
- }
- }
- } elseif (!is_null($key) && !is_numeric($key)) {
- throw new \InvalidArgumentException(sprintf('unknown storage key "%s", must be one of [%s]', $key, implode(', ', array_keys($this->storageMap))));
- } else {
- $set = false;
- foreach ($this->storageMap as $type => $interface) {
- if ($storage instanceof $interface) {
- $this->storages[$type] = $storage;
- $set = true;
- }
- }
-
- if (!$set) {
- throw new \InvalidArgumentException(sprintf('storage of class "%s" must implement one of [%s]', get_class($storage), implode(', ', $this->storageMap)));
- }
- }
- }
-
- public function addResponseType(ResponseTypeInterface $responseType, $key = null)
- {
- $key = $this->normalizeResponseType($key);
-
- if (isset($this->responseTypeMap[$key])) {
- if (!$responseType instanceof $this->responseTypeMap[$key]) {
- throw new \InvalidArgumentException(sprintf('responseType of type "%s" must implement interface "%s"', $key, $this->responseTypeMap[$key]));
- }
- $this->responseTypes[$key] = $responseType;
- } elseif (!is_null($key) && !is_numeric($key)) {
- throw new \InvalidArgumentException(sprintf('unknown responseType key "%s", must be one of [%s]', $key, implode(', ', array_keys($this->responseTypeMap))));
- } else {
- $set = false;
- foreach ($this->responseTypeMap as $type => $interface) {
- if ($responseType instanceof $interface) {
- $this->responseTypes[$type] = $responseType;
- $set = true;
- }
- }
-
- if (!$set) {
- throw new \InvalidArgumentException(sprintf('Unknown response type %s. Please implement one of [%s]', get_class($responseType), implode(', ', $this->responseTypeMap)));
- }
- }
- }
-
- public function getScopeUtil()
- {
- if (!$this->scopeUtil) {
- $storage = isset($this->storages['scope']) ? $this->storages['scope'] : null;
- $this->scopeUtil = new Scope($storage);
- }
-
- return $this->scopeUtil;
- }
-
- /**
- * every getter deserves a setter
- */
- public function setScopeUtil($scopeUtil)
- {
- $this->scopeUtil = $scopeUtil;
- }
-
- protected function createDefaultAuthorizeController()
- {
- if (!isset($this->storages['client'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the authorize server");
- }
- if (0 == count($this->responseTypes)) {
- $this->responseTypes = $this->getDefaultResponseTypes();
- }
- if ($this->config['use_openid_connect'] && !isset($this->responseTypes['id_token'])) {
- $this->responseTypes['id_token'] = $this->createDefaultIdTokenResponseType();
- if ($this->config['allow_implicit']) {
- $this->responseTypes['id_token token'] = $this->createDefaultIdTokenTokenResponseType();
- }
- }
-
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_implicit enforce_state require_exact_redirect_uri')));
-
- if ($this->config['use_openid_connect']) {
- return new OpenIDAuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
- }
-
- return new AuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
- }
-
- protected function createDefaultTokenController()
- {
- if (0 == count($this->grantTypes)) {
- $this->grantTypes = $this->getDefaultGrantTypes();
- }
-
- if (is_null($this->clientAssertionType)) {
- // see if HttpBasic assertion type is requred. If so, then create it from storage classes.
- foreach ($this->grantTypes as $grantType) {
- if (!$grantType instanceof ClientAssertionTypeInterface) {
- if (!isset($this->storages['client_credentials'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\ClientCredentialsInterface to use the token server");
- }
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_credentials_in_request_body allow_public_clients')));
- $this->clientAssertionType = new HttpBasic($this->storages['client_credentials'], $config);
- break;
- }
- }
- }
-
- if (!isset($this->storages['client'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the token server");
- }
-
- $accessTokenResponseType = $this->getAccessTokenResponseType();
-
- return new TokenController($accessTokenResponseType, $this->storages['client'], $this->grantTypes, $this->clientAssertionType, $this->getScopeUtil());
- }
-
- protected function createDefaultResourceController()
- {
- if ($this->config['use_jwt_access_tokens']) {
- // overwrites access token storage with crypto token storage if "use_jwt_access_tokens" is set
- if (!isset($this->storages['access_token']) || !$this->storages['access_token'] instanceof JwtAccessTokenInterface) {
- $this->storages['access_token'] = $this->createDefaultJwtAccessTokenStorage();
- }
- } elseif (!isset($this->storages['access_token'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface or use JwtAccessTokens to use the resource server");
- }
-
- if (!$this->tokenType) {
- $this->tokenType = $this->getDefaultTokenType();
- }
-
- $config = array_intersect_key($this->config, array('www_realm' => ''));
-
- return new ResourceController($this->tokenType, $this->storages['access_token'], $config, $this->getScopeUtil());
- }
-
- protected function createDefaultUserInfoController()
- {
- if ($this->config['use_jwt_access_tokens']) {
- // overwrites access token storage with crypto token storage if "use_jwt_access_tokens" is set
- if (!isset($this->storages['access_token']) || !$this->storages['access_token'] instanceof JwtAccessTokenInterface) {
- $this->storages['access_token'] = $this->createDefaultJwtAccessTokenStorage();
- }
- } elseif (!isset($this->storages['access_token'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface or use JwtAccessTokens to use the UserInfo server");
- }
-
- if (!isset($this->storages['user_claims'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use the UserInfo server");
- }
-
- if (!$this->tokenType) {
- $this->tokenType = $this->getDefaultTokenType();
- }
-
- $config = array_intersect_key($this->config, array('www_realm' => ''));
-
- return new UserInfoController($this->tokenType, $this->storages['access_token'], $this->storages['user_claims'], $config, $this->getScopeUtil());
- }
-
- protected function getDefaultTokenType()
- {
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'token_param_name token_bearer_header_name')));
-
- return new Bearer($config);
- }
-
- protected function getDefaultResponseTypes()
- {
- $responseTypes = array();
-
- if ($this->config['allow_implicit']) {
- $responseTypes['token'] = $this->getAccessTokenResponseType();
- }
-
- if ($this->config['use_openid_connect']) {
- $responseTypes['id_token'] = $this->getIdTokenResponseType();
- if ($this->config['allow_implicit']) {
- $responseTypes['id_token token'] = $this->getIdTokenTokenResponseType();
- }
- }
-
- if (isset($this->storages['authorization_code'])) {
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'enforce_redirect auth_code_lifetime')));
- if ($this->config['use_openid_connect']) {
- if (!$this->storages['authorization_code'] instanceof OpenIDAuthorizationCodeInterface) {
- throw new \LogicException("Your authorization_code storage must implement OAuth2\OpenID\Storage\AuthorizationCodeInterface to work when 'use_openid_connect' is true");
- }
- $responseTypes['code'] = new OpenIDAuthorizationCodeResponseType($this->storages['authorization_code'], $config);
- $responseTypes['code id_token'] = new CodeIdToken($responseTypes['code'], $responseTypes['id_token']);
- } else {
- $responseTypes['code'] = new AuthorizationCodeResponseType($this->storages['authorization_code'], $config);
- }
- }
-
- if (count($responseTypes) == 0) {
- throw new \LogicException("You must supply an array of response_types in the constructor or implement a OAuth2\Storage\AuthorizationCodeInterface storage object or set 'allow_implicit' to true and implement a OAuth2\Storage\AccessTokenInterface storage object");
- }
-
- return $responseTypes;
- }
-
- protected function getDefaultGrantTypes()
- {
- $grantTypes = array();
-
- if (isset($this->storages['user_credentials'])) {
- $grantTypes['password'] = new UserCredentials($this->storages['user_credentials']);
- }
-
- if (isset($this->storages['client_credentials'])) {
- $config = array_intersect_key($this->config, array('allow_credentials_in_request_body' => ''));
- $grantTypes['client_credentials'] = new ClientCredentials($this->storages['client_credentials'], $config);
- }
-
- if (isset($this->storages['refresh_token'])) {
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'always_issue_new_refresh_token unset_refresh_token_after_use')));
- $grantTypes['refresh_token'] = new RefreshToken($this->storages['refresh_token'], $config);
- }
-
- if (isset($this->storages['authorization_code'])) {
- if ($this->config['use_openid_connect']) {
- if (!$this->storages['authorization_code'] instanceof OpenIDAuthorizationCodeInterface) {
- throw new \LogicException("Your authorization_code storage must implement OAuth2\OpenID\Storage\AuthorizationCodeInterface to work when 'use_openid_connect' is true");
- }
- $grantTypes['authorization_code'] = new OpenIDAuthorizationCodeGrantType($this->storages['authorization_code']);
- } else {
- $grantTypes['authorization_code'] = new AuthorizationCode($this->storages['authorization_code']);
- }
- }
-
- if (count($grantTypes) == 0) {
- throw new \LogicException("Unable to build default grant types - You must supply an array of grant_types in the constructor");
- }
-
- return $grantTypes;
- }
-
- protected function getAccessTokenResponseType()
- {
- if (isset($this->responseTypes['token'])) {
- return $this->responseTypes['token'];
- }
-
- if ($this->config['use_jwt_access_tokens']) {
- return $this->createDefaultJwtAccessTokenResponseType();
- }
-
- return $this->createDefaultAccessTokenResponseType();
- }
-
- protected function getIdTokenResponseType()
- {
- if (isset($this->responseTypes['id_token'])) {
- return $this->responseTypes['id_token'];
- }
-
- return $this->createDefaultIdTokenResponseType();
- }
-
- protected function getIdTokenTokenResponseType()
- {
- if (isset($this->responseTypes['id_token token'])) {
- return $this->responseTypes['id_token token'];
- }
-
- return $this->createDefaultIdTokenTokenResponseType();
- }
-
- /**
- * For Resource Controller
- */
- protected function createDefaultJwtAccessTokenStorage()
- {
- if (!isset($this->storages['public_key'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
- }
- $tokenStorage = null;
- if (!empty($this->config['store_encrypted_token_string']) && isset($this->storages['access_token'])) {
- $tokenStorage = $this->storages['access_token'];
- }
- // wrap the access token storage as required.
- return new JwtAccessTokenStorage($this->storages['public_key'], $tokenStorage);
- }
-
- /**
- * For Authorize and Token Controllers
- */
- protected function createDefaultJwtAccessTokenResponseType()
- {
- if (!isset($this->storages['public_key'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens");
- }
-
- $tokenStorage = null;
- if (isset($this->storages['access_token'])) {
- $tokenStorage = $this->storages['access_token'];
- }
-
- $refreshStorage = null;
- if (isset($this->storages['refresh_token'])) {
- $refreshStorage = $this->storages['refresh_token'];
- }
-
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'store_encrypted_token_string issuer access_lifetime refresh_token_lifetime')));
-
- return new JwtAccessToken($this->storages['public_key'], $tokenStorage, $refreshStorage, $config);
- }
-
- protected function createDefaultAccessTokenResponseType()
- {
- if (!isset($this->storages['access_token'])) {
- throw new \LogicException("You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server");
- }
-
- $refreshStorage = null;
- if (isset($this->storages['refresh_token'])) {
- $refreshStorage = $this->storages['refresh_token'];
- }
-
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'access_lifetime refresh_token_lifetime')));
- $config['token_type'] = $this->tokenType ? $this->tokenType->getTokenType() : $this->getDefaultTokenType()->getTokenType();
-
- return new AccessToken($this->storages['access_token'], $refreshStorage, $config);
- }
-
- protected function createDefaultIdTokenResponseType()
- {
- if (!isset($this->storages['user_claims'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use openid connect");
- }
- if (!isset($this->storages['public_key'])) {
- throw new \LogicException("You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use openid connect");
- }
-
- $config = array_intersect_key($this->config, array_flip(explode(' ', 'issuer id_lifetime')));
-
- return new IdToken($this->storages['user_claims'], $this->storages['public_key'], $config);
- }
-
- protected function createDefaultIdTokenTokenResponseType()
- {
- return new IdTokenToken($this->getAccessTokenResponseType(), $this->getIdTokenResponseType());
- }
-
- protected function validateOpenIdConnect()
- {
- $authCodeGrant = $this->getGrantType('authorization_code');
- if (!empty($authCodeGrant) && !$authCodeGrant instanceof OpenIDAuthorizationCodeGrantType) {
- throw new \InvalidArgumentException('You have enabled OpenID Connect, but supplied a grant type that does not support it.');
- }
- }
-
- protected function normalizeResponseType($name)
- {
- // for multiple-valued response types - make them alphabetical
- if (!empty($name) && false !== strpos($name, ' ')) {
- $types = explode(' ', $name);
- sort($types);
- $name = implode(' ', $types);
- }
-
- return $name;
- }
-
- public function getResponse()
- {
- return $this->response;
- }
-
- public function getStorages()
- {
- return $this->storages;
- }
-
- public function getStorage($name)
- {
- return isset($this->storages[$name]) ? $this->storages[$name] : null;
- }
-
- public function getGrantTypes()
- {
- return $this->grantTypes;
- }
-
- public function getGrantType($name)
- {
- return isset($this->grantTypes[$name]) ? $this->grantTypes[$name] : null;
- }
-
- public function getResponseTypes()
- {
- return $this->responseTypes;
- }
-
- public function getResponseType($name)
- {
- // for multiple-valued response types - make them alphabetical
- $name = $this->normalizeResponseType($name);
-
- return isset($this->responseTypes[$name]) ? $this->responseTypes[$name] : null;
- }
-
- public function getTokenType()
- {
- return $this->tokenType;
- }
-
- public function getClientAssertionType()
- {
- return $this->clientAssertionType;
- }
-
- public function setConfig($name, $value)
- {
- $this->config[$name] = $value;
- }
-
- public function getConfig($name, $default = null)
- {
- return isset($this->config[$name]) ? $this->config[$name] : $default;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/AccessTokenInterface.php b/library/oauth2/src/OAuth2/Storage/AccessTokenInterface.php
deleted file mode 100644
index 1819158af..000000000
--- a/library/oauth2/src/OAuth2/Storage/AccessTokenInterface.php
+++ /dev/null
@@ -1,64 +0,0 @@
-
- */
-interface AccessTokenInterface
-{
- /**
- * Look up the supplied oauth_token from storage.
- *
- * We need to retrieve access token data as we create and verify tokens.
- *
- * @param $oauth_token
- * oauth_token to be check with.
- *
- * @return
- * An associative array as below, and return NULL if the supplied oauth_token
- * is invalid:
- * - expires: Stored expiration in unix timestamp.
- * - client_id: (optional) Stored client identifier.
- * - user_id: (optional) Stored user identifier.
- * - scope: (optional) Stored scope values in space-separated string.
- * - id_token: (optional) Stored id_token (if "use_openid_connect" is true).
- *
- * @ingroup oauth2_section_7
- */
- public function getAccessToken($oauth_token);
-
- /**
- * Store the supplied access token values to storage.
- *
- * We need to store access token data as we create and verify tokens.
- *
- * @param $oauth_token oauth_token to be stored.
- * @param $client_id client identifier to be stored.
- * @param $user_id user identifier to be stored.
- * @param int $expires expiration to be stored as a Unix timestamp.
- * @param string $scope OPTIONAL Scopes to be stored in space-separated string.
- *
- * @ingroup oauth2_section_4
- */
- public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null);
-
- /**
- * Expire an access token.
- *
- * This is not explicitly required in the spec, but if defined in a draft RFC for token
- * revoking (RFC 7009) https://tools.ietf.org/html/rfc7009
- *
- * @param $access_token
- * Access token to be expired.
- *
- * @return BOOL true if an access token was unset, false if not
- * @ingroup oauth2_section_6
- *
- * @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
- */
- //public function unsetAccessToken($access_token);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/AuthorizationCodeInterface.php b/library/oauth2/src/OAuth2/Storage/AuthorizationCodeInterface.php
deleted file mode 100644
index 3beb0e437..000000000
--- a/library/oauth2/src/OAuth2/Storage/AuthorizationCodeInterface.php
+++ /dev/null
@@ -1,86 +0,0 @@
-
- */
-interface AuthorizationCodeInterface
-{
- /**
- * The Authorization Code grant type supports a response type of "code".
- *
- * @var string
- * @see http://tools.ietf.org/html/rfc6749#section-1.4.1
- * @see http://tools.ietf.org/html/rfc6749#section-4.2
- */
- const RESPONSE_TYPE_CODE = "code";
-
- /**
- * Fetch authorization code data (probably the most common grant type).
- *
- * Retrieve the stored data for the given authorization code.
- *
- * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
- *
- * @param $code
- * Authorization code to be check with.
- *
- * @return
- * An associative array as below, and NULL if the code is invalid
- * @code
- * return array(
- * "client_id" => CLIENT_ID, // REQUIRED Stored client identifier
- * "user_id" => USER_ID, // REQUIRED Stored user identifier
- * "expires" => EXPIRES, // REQUIRED Stored expiration in unix timestamp
- * "redirect_uri" => REDIRECT_URI, // REQUIRED Stored redirect URI
- * "scope" => SCOPE, // OPTIONAL Stored scope values in space-separated string
- * );
- * @endcode
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.1
- *
- * @ingroup oauth2_section_4
- */
- public function getAuthorizationCode($code);
-
- /**
- * Take the provided authorization code values and store them somewhere.
- *
- * This function should be the storage counterpart to getAuthCode().
- *
- * If storage fails for some reason, we're not currently checking for
- * any sort of success/failure, so you should bail out of the script
- * and provide a descriptive fail message.
- *
- * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
- *
- * @param string $code Authorization code to be stored.
- * @param mixed $client_id Client identifier to be stored.
- * @param mixed $user_id User identifier to be stored.
- * @param string $redirect_uri Redirect URI(s) to be stored in a space-separated string.
- * @param int $expires Expiration to be stored as a Unix timestamp.
- * @param string $scope OPTIONAL Scopes to be stored in space-separated string.
- *
- * @ingroup oauth2_section_4
- */
- public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null);
-
- /**
- * once an Authorization Code is used, it must be exipired
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.1.2
- *
- * The client MUST NOT use the authorization code
- * more than once. If an authorization code is used more than
- * once, the authorization server MUST deny the request and SHOULD
- * revoke (when possible) all tokens previously issued based on
- * that authorization code
- *
- */
- public function expireAuthorizationCode($code);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/Cassandra.php b/library/oauth2/src/OAuth2/Storage/Cassandra.php
deleted file mode 100644
index 602e8a058..000000000
--- a/library/oauth2/src/OAuth2/Storage/Cassandra.php
+++ /dev/null
@@ -1,480 +0,0 @@
-
- * composer require thobbs/phpcassa:dev-master
- *
- *
- * Once this is done, instantiate the
- *
- * $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_server', array('127.0.0.1:9160'));
- *
- *
- * Then, register the storage client:
- *
- * $storage = new OAuth2\Storage\Cassandra($cassandra);
- * $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
- *
- *
- * @see test/lib/OAuth2/Storage/Bootstrap::getCassandraStorage
- */
-class Cassandra implements AuthorizationCodeInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- UserCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- ScopeInterface,
- PublicKeyInterface,
- UserClaimsInterface,
- OpenIDAuthorizationCodeInterface
-{
-
- private $cache;
-
- /* The cassandra client */
- protected $cassandra;
-
- /* Configuration array */
- protected $config;
-
- /**
- * Cassandra Storage! uses phpCassa
- *
- * @param \phpcassa\ConnectionPool $cassandra
- * @param array $config
- */
- public function __construct($connection = array(), array $config = array())
- {
- if ($connection instanceof ConnectionPool) {
- $this->cassandra = $connection;
- } else {
- if (!is_array($connection)) {
- throw new \InvalidArgumentException('First argument to OAuth2\Storage\Cassandra must be an instance of phpcassa\Connection\ConnectionPool or a configuration array');
- }
- $connection = array_merge(array(
- 'keyspace' => 'oauth2',
- 'servers' => null,
- ), $connection);
-
- $this->cassandra = new ConnectionPool($connection['keyspace'], $connection['servers']);
- }
-
- $this->config = array_merge(array(
- // cassandra config
- 'column_family' => 'auth',
-
- // key names
- 'client_key' => 'oauth_clients:',
- 'access_token_key' => 'oauth_access_tokens:',
- 'refresh_token_key' => 'oauth_refresh_tokens:',
- 'code_key' => 'oauth_authorization_codes:',
- 'user_key' => 'oauth_users:',
- 'jwt_key' => 'oauth_jwt:',
- 'scope_key' => 'oauth_scopes:',
- 'public_key_key' => 'oauth_public_keys:',
- ), $config);
- }
-
- protected function getValue($key)
- {
- if (isset($this->cache[$key])) {
- return $this->cache[$key];
- }
- $cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
-
- try {
- $value = $cf->get($key, new ColumnSlice("", ""));
- $value = array_shift($value);
- } catch (\cassandra\NotFoundException $e) {
- return false;
- }
-
- return json_decode($value, true);
- }
-
- protected function setValue($key, $value, $expire = 0)
- {
- $this->cache[$key] = $value;
-
- $cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
-
- $str = json_encode($value);
- if ($expire > 0) {
- try {
- $seconds = $expire - time();
- // __data key set as C* requires a field, note: max TTL can only be 630720000 seconds
- $cf->insert($key, array('__data' => $str), null, $seconds);
- } catch (\Exception $e) {
- return false;
- }
- } else {
- try {
- // __data key set as C* requires a field
- $cf->insert($key, array('__data' => $str));
- } catch (\Exception $e) {
- return false;
- }
- }
-
- return true;
- }
-
- protected function expireValue($key)
- {
- unset($this->cache[$key]);
-
- $cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
-
- if ($cf->get_count($key) > 0) {
- try {
- // __data key set as C* requires a field
- $cf->remove($key, array('__data'));
- } catch (\Exception $e) {
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- /* AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- return $this->getValue($this->config['code_key'] . $code);
- }
-
- public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- return $this->setValue(
- $this->config['code_key'] . $authorization_code,
- compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
- $expires
- );
- }
-
- public function expireAuthorizationCode($code)
- {
- $key = $this->config['code_key'] . $code;
- unset($this->cache[$key]);
-
- return $this->expireValue($key);
- }
-
- /* UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- if ($user = $this->getUser($username)) {
- return $this->checkPassword($user, $password);
- }
-
- return false;
- }
-
- // plaintext passwords are bad! Override this for your application
- protected function checkPassword($user, $password)
- {
- return $user['password'] == $this->hashPassword($password);
- }
-
- // use a secure hashing algorithm when storing passwords. Override this for your application
- protected function hashPassword($password)
- {
- return sha1($password);
- }
-
- public function getUserDetails($username)
- {
- return $this->getUser($username);
- }
-
- public function getUser($username)
- {
- if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
- return false;
- }
-
- // the default behavior is to use "username" as the user_id
- return array_merge(array(
- 'user_id' => $username,
- ), $userInfo);
- }
-
- public function setUser($username, $password, $first_name = null, $last_name = null)
- {
- $password = $this->hashPassword($password);
-
- return $this->setValue(
- $this->config['user_key'] . $username,
- compact('username', 'password', 'first_name', 'last_name')
- );
- }
-
- /* ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- if (!$client = $this->getClientDetails($client_id)) {
- return false;
- }
-
- return isset($client['client_secret'])
- && $client['client_secret'] == $client_secret;
- }
-
- public function isPublicClient($client_id)
- {
- if (!$client = $this->getClientDetails($client_id)) {
- return false;
- }
-
- return empty($client['client_secret']);;
- }
-
- /* ClientInterface */
- public function getClientDetails($client_id)
- {
- return $this->getValue($this->config['client_key'] . $client_id);
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- return $this->setValue(
- $this->config['client_key'] . $client_id,
- compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
- );
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- $details = $this->getClientDetails($client_id);
- if (isset($details['grant_types'])) {
- $grant_types = explode(' ', $details['grant_types']);
-
- return in_array($grant_type, (array) $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- /* RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- return $this->setValue(
- $this->config['refresh_token_key'] . $refresh_token,
- compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'),
- $expires
- );
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- return $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
- }
-
- /* AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- return $this->getValue($this->config['access_token_key'].$access_token);
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
- {
- return $this->setValue(
- $this->config['access_token_key'].$access_token,
- compact('access_token', 'client_id', 'user_id', 'expires', 'scope'),
- $expires
- );
- }
-
- public function unsetAccessToken($access_token)
- {
- return $this->expireValue($this->config['access_token_key'] . $access_token);
- }
-
- /* ScopeInterface */
- public function scopeExists($scope)
- {
- $scope = explode(' ', $scope);
-
- $result = $this->getValue($this->config['scope_key'].'supported:global');
-
- $supportedScope = explode(' ', (string) $result);
-
- return (count(array_diff($scope, $supportedScope)) == 0);
- }
-
- public function getDefaultScope($client_id = null)
- {
- if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
- $result = $this->getValue($this->config['scope_key'].'default:global');
- }
-
- return $result;
- }
-
- public function setScope($scope, $client_id = null, $type = 'supported')
- {
- if (!in_array($type, array('default', 'supported'))) {
- throw new \InvalidArgumentException('"$type" must be one of "default", "supported"');
- }
-
- if (is_null($client_id)) {
- $key = $this->config['scope_key'].$type.':global';
- } else {
- $key = $this->config['scope_key'].$type.':'.$client_id;
- }
-
- return $this->setValue($key, $scope);
- }
-
- /*JWTBearerInterface */
- public function getClientKey($client_id, $subject)
- {
- if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
- return false;
- }
-
- if (isset($jwt['subject']) && $jwt['subject'] == $subject ) {
- return $jwt['key'];
- }
-
- return null;
- }
-
- public function setClientKey($client_id, $key, $subject = null)
- {
- return $this->setValue($this->config['jwt_key'] . $client_id, array(
- 'key' => $key,
- 'subject' => $subject
- ));
- }
-
- /*ScopeInterface */
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs cassandra implementation.
- throw new \Exception('getJti() for the Cassandra driver is currently unimplemented.');
- }
-
- public function setJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs cassandra implementation.
- throw new \Exception('setJti() for the Cassandra driver is currently unimplemented.');
- }
-
- /* PublicKeyInterface */
- public function getPublicKey($client_id = '')
- {
- $public_key = $this->getValue($this->config['public_key_key'] . $client_id);
- if (is_array($public_key)) {
- return $public_key['public_key'];
- }
- $public_key = $this->getValue($this->config['public_key_key']);
- if (is_array($public_key)) {
- return $public_key['public_key'];
- }
- }
-
- public function getPrivateKey($client_id = '')
- {
- $public_key = $this->getValue($this->config['public_key_key'] . $client_id);
- if (is_array($public_key)) {
- return $public_key['private_key'];
- }
- $public_key = $this->getValue($this->config['public_key_key']);
- if (is_array($public_key)) {
- return $public_key['private_key'];
- }
- }
-
- public function getEncryptionAlgorithm($client_id = null)
- {
- $public_key = $this->getValue($this->config['public_key_key'] . $client_id);
- if (is_array($public_key)) {
- return $public_key['encryption_algorithm'];
- }
- $public_key = $this->getValue($this->config['public_key_key']);
- if (is_array($public_key)) {
- return $public_key['encryption_algorithm'];
- }
-
- return 'RS256';
- }
-
- /* UserClaimsInterface */
- public function getUserClaims($user_id, $claims)
- {
- $userDetails = $this->getUserDetails($user_id);
- if (!is_array($userDetails)) {
- return false;
- }
-
- $claims = explode(' ', trim($claims));
- $userClaims = array();
-
- // for each requested claim, if the user has the claim, set it in the response
- $validClaims = explode(' ', self::VALID_CLAIMS);
- foreach ($validClaims as $validClaim) {
- if (in_array($validClaim, $claims)) {
- if ($validClaim == 'address') {
- // address is an object with subfields
- $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
- } else {
- $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
- }
- }
- }
-
- return $userClaims;
- }
-
- protected function getUserClaim($claim, $userDetails)
- {
- $userClaims = array();
- $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
- $claimValues = explode(' ', $claimValuesString);
-
- foreach ($claimValues as $value) {
- if ($value == 'email_verified') {
- $userClaims[$value] = $userDetails[$value]=='true' ? true : false;
- } else {
- $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
- }
- }
-
- return $userClaims;
- }
-
-}
diff --git a/library/oauth2/src/OAuth2/Storage/ClientCredentialsInterface.php b/library/oauth2/src/OAuth2/Storage/ClientCredentialsInterface.php
deleted file mode 100644
index 3318c6966..000000000
--- a/library/oauth2/src/OAuth2/Storage/ClientCredentialsInterface.php
+++ /dev/null
@@ -1,49 +0,0 @@
-
- */
-interface ClientCredentialsInterface extends ClientInterface
-{
-
- /**
- * Make sure that the client credentials is valid.
- *
- * @param $client_id
- * Client identifier to be check with.
- * @param $client_secret
- * (optional) If a secret is required, check that they've given the right one.
- *
- * @return
- * TRUE if the client credentials are valid, and MUST return FALSE if it isn't.
- * @endcode
- *
- * @see http://tools.ietf.org/html/rfc6749#section-3.1
- *
- * @ingroup oauth2_section_3
- */
- public function checkClientCredentials($client_id, $client_secret = null);
-
- /**
- * Determine if the client is a "public" client, and therefore
- * does not require passing credentials for certain grant types
- *
- * @param $client_id
- * Client identifier to be check with.
- *
- * @return
- * TRUE if the client is public, and FALSE if it isn't.
- * @endcode
- *
- * @see http://tools.ietf.org/html/rfc6749#section-2.3
- * @see https://github.com/bshaffer/oauth2-server-php/issues/257
- *
- * @ingroup oauth2_section_2
- */
- public function isPublicClient($client_id);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/ClientInterface.php b/library/oauth2/src/OAuth2/Storage/ClientInterface.php
deleted file mode 100644
index 09a5bffc1..000000000
--- a/library/oauth2/src/OAuth2/Storage/ClientInterface.php
+++ /dev/null
@@ -1,66 +0,0 @@
-
- */
-interface ClientInterface
-{
- /**
- * Get client details corresponding client_id.
- *
- * OAuth says we should store request URIs for each registered client.
- * Implement this function to grab the stored URI for a given client id.
- *
- * @param $client_id
- * Client identifier to be check with.
- *
- * @return array
- * Client details. The only mandatory key in the array is "redirect_uri".
- * This function MUST return FALSE if the given client does not exist or is
- * invalid. "redirect_uri" can be space-delimited to allow for multiple valid uris.
- *
- * return array(
- * "redirect_uri" => REDIRECT_URI, // REQUIRED redirect_uri registered for the client
- * "client_id" => CLIENT_ID, // OPTIONAL the client id
- * "grant_types" => GRANT_TYPES, // OPTIONAL an array of restricted grant types
- * "user_id" => USER_ID, // OPTIONAL the user identifier associated with this client
- * "scope" => SCOPE, // OPTIONAL the scopes allowed for this client
- * );
- *
- *
- * @ingroup oauth2_section_4
- */
- public function getClientDetails($client_id);
-
- /**
- * Get the scope associated with this client
- *
- * @return
- * STRING the space-delineated scope list for the specified client_id
- */
- public function getClientScope($client_id);
-
- /**
- * Check restricted grant types of corresponding client identifier.
- *
- * If you want to restrict clients to certain grant types, override this
- * function.
- *
- * @param $client_id
- * Client identifier to be check with.
- * @param $grant_type
- * Grant type to be check with
- *
- * @return
- * TRUE if the grant type is supported by this client identifier, and
- * FALSE if it isn't.
- *
- * @ingroup oauth2_section_4
- */
- public function checkRestrictedGrantType($client_id, $grant_type);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/CouchbaseDB.php b/library/oauth2/src/OAuth2/Storage/CouchbaseDB.php
deleted file mode 100755
index 1eb55f027..000000000
--- a/library/oauth2/src/OAuth2/Storage/CouchbaseDB.php
+++ /dev/null
@@ -1,331 +0,0 @@
-
- */
-class CouchbaseDB implements AuthorizationCodeInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- UserCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- OpenIDAuthorizationCodeInterface
-{
- protected $db;
- protected $config;
-
- public function __construct($connection, $config = array())
- {
- if ($connection instanceof \Couchbase) {
- $this->db = $connection;
- } else {
- if (!is_array($connection) || !is_array($connection['servers'])) {
- throw new \InvalidArgumentException('First argument to OAuth2\Storage\CouchbaseDB must be an instance of Couchbase or a configuration array containing a server array');
- }
-
- $this->db = new \Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
- }
-
- $this->config = array_merge(array(
- 'client_table' => 'oauth_clients',
- 'access_token_table' => 'oauth_access_tokens',
- 'refresh_token_table' => 'oauth_refresh_tokens',
- 'code_table' => 'oauth_authorization_codes',
- 'user_table' => 'oauth_users',
- 'jwt_table' => 'oauth_jwt',
- ), $config);
- }
-
- // Helper function to access couchbase item by type:
- protected function getObjectByType($name,$id)
- {
- return json_decode($this->db->get($this->config[$name].'-'.$id),true);
- }
-
- // Helper function to set couchbase item by type:
- protected function setObjectByType($name,$id,$array)
- {
- $array['type'] = $name;
-
- return $this->db->set($this->config[$name].'-'.$id,json_encode($array));
- }
-
- // Helper function to delete couchbase item by type, wait for persist to at least 1 node
- protected function deleteObjectByType($name,$id)
- {
- $this->db->delete($this->config[$name].'-'.$id,"",1);
- }
-
- /* ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- if ($result = $this->getObjectByType('client_table',$client_id)) {
- return $result['client_secret'] == $client_secret;
- }
-
- return false;
- }
-
- public function isPublicClient($client_id)
- {
- if (!$result = $this->getObjectByType('client_table',$client_id)) {
- return false;
- }
-
- return empty($result['client_secret']);
- }
-
- /* ClientInterface */
- public function getClientDetails($client_id)
- {
- $result = $this->getObjectByType('client_table',$client_id);
-
- return is_null($result) ? false : $result;
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- if ($this->getClientDetails($client_id)) {
-
- $this->setObjectByType('client_table',$client_id, array(
- 'client_id' => $client_id,
- 'client_secret' => $client_secret,
- 'redirect_uri' => $redirect_uri,
- 'grant_types' => $grant_types,
- 'scope' => $scope,
- 'user_id' => $user_id,
- ));
- } else {
- $this->setObjectByType('client_table',$client_id, array(
- 'client_id' => $client_id,
- 'client_secret' => $client_secret,
- 'redirect_uri' => $redirect_uri,
- 'grant_types' => $grant_types,
- 'scope' => $scope,
- 'user_id' => $user_id,
- ));
- }
-
- return true;
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- $details = $this->getClientDetails($client_id);
- if (isset($details['grant_types'])) {
- $grant_types = explode(' ', $details['grant_types']);
-
- return in_array($grant_type, $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- /* AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- $token = $this->getObjectByType('access_token_table',$access_token);
-
- return is_null($token) ? false : $token;
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
- {
- // if it exists, update it.
- if ($this->getAccessToken($access_token)) {
- $this->setObjectByType('access_token_table',$access_token, array(
- 'access_token' => $access_token,
- 'client_id' => $client_id,
- 'expires' => $expires,
- 'user_id' => $user_id,
- 'scope' => $scope
- ));
- } else {
- $this->setObjectByType('access_token_table',$access_token, array(
- 'access_token' => $access_token,
- 'client_id' => $client_id,
- 'expires' => $expires,
- 'user_id' => $user_id,
- 'scope' => $scope
- ));
- }
-
- return true;
- }
-
- /* AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- $code = $this->getObjectByType('code_table',$code);
-
- return is_null($code) ? false : $code;
- }
-
- public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- // if it exists, update it.
- if ($this->getAuthorizationCode($code)) {
- $this->setObjectByType('code_table',$code, array(
- 'authorization_code' => $code,
- 'client_id' => $client_id,
- 'user_id' => $user_id,
- 'redirect_uri' => $redirect_uri,
- 'expires' => $expires,
- 'scope' => $scope,
- 'id_token' => $id_token,
- ));
- } else {
- $this->setObjectByType('code_table',$code,array(
- 'authorization_code' => $code,
- 'client_id' => $client_id,
- 'user_id' => $user_id,
- 'redirect_uri' => $redirect_uri,
- 'expires' => $expires,
- 'scope' => $scope,
- 'id_token' => $id_token,
- ));
- }
-
- return true;
- }
-
- public function expireAuthorizationCode($code)
- {
- $this->deleteObjectByType('code_table',$code);
-
- return true;
- }
-
- /* UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- if ($user = $this->getUser($username)) {
- return $this->checkPassword($user, $password);
- }
-
- return false;
- }
-
- public function getUserDetails($username)
- {
- if ($user = $this->getUser($username)) {
- $user['user_id'] = $user['username'];
- }
-
- return $user;
- }
-
- /* RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- $token = $this->getObjectByType('refresh_token_table',$refresh_token);
-
- return is_null($token) ? false : $token;
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- $this->setObjectByType('refresh_token_table',$refresh_token, array(
- 'refresh_token' => $refresh_token,
- 'client_id' => $client_id,
- 'user_id' => $user_id,
- 'expires' => $expires,
- 'scope' => $scope
- ));
-
- return true;
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- $this->deleteObjectByType('refresh_token_table',$refresh_token);
-
- return true;
- }
-
- // plaintext passwords are bad! Override this for your application
- protected function checkPassword($user, $password)
- {
- return $user['password'] == $password;
- }
-
- public function getUser($username)
- {
- $result = $this->getObjectByType('user_table',$username);
-
- return is_null($result) ? false : $result;
- }
-
- public function setUser($username, $password, $firstName = null, $lastName = null)
- {
- if ($this->getUser($username)) {
- $this->setObjectByType('user_table',$username, array(
- 'username' => $username,
- 'password' => $password,
- 'first_name' => $firstName,
- 'last_name' => $lastName
- ));
-
- } else {
- $this->setObjectByType('user_table',$username, array(
- 'username' => $username,
- 'password' => $password,
- 'first_name' => $firstName,
- 'last_name' => $lastName
- ));
-
- }
-
- return true;
- }
-
- public function getClientKey($client_id, $subject)
- {
- if (!$jwt = $this->getObjectByType('jwt_table',$client_id)) {
- return false;
- }
-
- if (isset($jwt['subject']) && $jwt['subject'] == $subject) {
- return $jwt['key'];
- }
-
- return false;
- }
-
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs couchbase implementation.
- throw new \Exception('getJti() for the Couchbase driver is currently unimplemented.');
- }
-
- public function setJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs couchbase implementation.
- throw new \Exception('setJti() for the Couchbase driver is currently unimplemented.');
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/DynamoDB.php b/library/oauth2/src/OAuth2/Storage/DynamoDB.php
deleted file mode 100644
index 8347ab258..000000000
--- a/library/oauth2/src/OAuth2/Storage/DynamoDB.php
+++ /dev/null
@@ -1,540 +0,0 @@
-
- * composer require aws/aws-sdk-php:dev-master
- *
- *
- * Once this is done, instantiate the DynamoDB client
- *
- * $storage = new OAuth2\Storage\Dynamodb(array("key" => "YOURKEY", "secret" => "YOURSECRET", "region" => "YOURREGION"));
- *
- *
- * Table :
- * - oauth_access_tokens (primary hash key : access_token)
- * - oauth_authorization_codes (primary hash key : authorization_code)
- * - oauth_clients (primary hash key : client_id)
- * - oauth_jwt (primary hash key : client_id, primary range key : subject)
- * - oauth_public_keys (primary hash key : client_id)
- * - oauth_refresh_tokens (primary hash key : refresh_token)
- * - oauth_scopes (primary hash key : scope, secondary index : is_default-index hash key is_default)
- * - oauth_users (primary hash key : username)
- *
- * @author Frederic AUGUSTE
- */
-class DynamoDB implements
- AuthorizationCodeInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- UserCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- ScopeInterface,
- PublicKeyInterface,
- UserClaimsInterface,
- OpenIDAuthorizationCodeInterface
-{
- protected $client;
- protected $config;
-
- public function __construct($connection, $config = array())
- {
- if (!($connection instanceof DynamoDbClient)) {
- if (!is_array($connection)) {
- throw new \InvalidArgumentException('First argument to OAuth2\Storage\Dynamodb must be an instance a configuration array containt key, secret, region');
- }
- if (!array_key_exists("key",$connection) || !array_key_exists("secret",$connection) || !array_key_exists("region",$connection) ) {
- throw new \InvalidArgumentException('First argument to OAuth2\Storage\Dynamodb must be an instance a configuration array containt key, secret, region');
- }
- $this->client = DynamoDbClient::factory(array(
- 'key' => $connection["key"],
- 'secret' => $connection["secret"],
- 'region' =>$connection["region"]
- ));
- } else {
- $this->client = $connection;
- }
-
- $this->config = array_merge(array(
- 'client_table' => 'oauth_clients',
- 'access_token_table' => 'oauth_access_tokens',
- 'refresh_token_table' => 'oauth_refresh_tokens',
- 'code_table' => 'oauth_authorization_codes',
- 'user_table' => 'oauth_users',
- 'jwt_table' => 'oauth_jwt',
- 'scope_table' => 'oauth_scopes',
- 'public_key_table' => 'oauth_public_keys',
- ), $config);
- }
-
- /* OAuth2\Storage\ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['client_table'],
- "Key" => array('client_id' => array('S' => $client_id))
- ));
-
- return $result->count()==1 && $result["Item"]["client_secret"]["S"] == $client_secret;
- }
-
- public function isPublicClient($client_id)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['client_table'],
- "Key" => array('client_id' => array('S' => $client_id))
- ));
-
- if ($result->count()==0) {
- return false ;
- }
-
- return empty($result["Item"]["client_secret"]);
- }
-
- /* OAuth2\Storage\ClientInterface */
- public function getClientDetails($client_id)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['client_table'],
- "Key" => array('client_id' => array('S' => $client_id))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $result = $this->dynamo2array($result);
- foreach (array('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id') as $key => $val) {
- if (!array_key_exists ($val, $result)) {
- $result[$val] = null;
- }
- }
-
- return $result;
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- $clientData = compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id');
- $clientData = array_filter($clientData, 'self::isNotEmpty');
-
- $result = $this->client->putItem(array(
- 'TableName' => $this->config['client_table'],
- 'Item' => $this->client->formatAttributes($clientData)
- ));
-
- return true;
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- $details = $this->getClientDetails($client_id);
- if (isset($details['grant_types'])) {
- $grant_types = explode(' ', $details['grant_types']);
-
- return in_array($grant_type, (array) $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- /* OAuth2\Storage\AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['access_token_table'],
- "Key" => array('access_token' => array('S' => $access_token))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
- if (array_key_exists ('expires', $token)) {
- $token['expires'] = strtotime($token['expires']);
- }
-
- return $token;
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
- {
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- $clientData = compact('access_token', 'client_id', 'user_id', 'expires', 'scope');
- $clientData = array_filter($clientData, 'self::isNotEmpty');
-
- $result = $this->client->putItem(array(
- 'TableName' => $this->config['access_token_table'],
- 'Item' => $this->client->formatAttributes($clientData)
- ));
-
- return true;
-
- }
-
- public function unsetAccessToken($access_token)
- {
- $result = $this->client->deleteItem(array(
- 'TableName' => $this->config['access_token_table'],
- 'Key' => $this->client->formatAttributes(array("access_token" => $access_token)),
- 'ReturnValues' => 'ALL_OLD',
- ));
-
- return null !== $result->get('Attributes');
- }
-
- /* OAuth2\Storage\AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['code_table'],
- "Key" => array('authorization_code' => array('S' => $code))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
- if (!array_key_exists("id_token", $token )) {
- $token['id_token'] = null;
- }
- $token['expires'] = strtotime($token['expires']);
-
- return $token;
-
- }
-
- public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- $clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'id_token', 'scope');
- $clientData = array_filter($clientData, 'self::isNotEmpty');
-
- $result = $this->client->putItem(array(
- 'TableName' => $this->config['code_table'],
- 'Item' => $this->client->formatAttributes($clientData)
- ));
-
- return true;
- }
-
- public function expireAuthorizationCode($code)
- {
-
- $result = $this->client->deleteItem(array(
- 'TableName' => $this->config['code_table'],
- 'Key' => $this->client->formatAttributes(array("authorization_code" => $code))
- ));
-
- return true;
- }
-
- /* OAuth2\Storage\UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- if ($user = $this->getUser($username)) {
- return $this->checkPassword($user, $password);
- }
-
- return false;
- }
-
- public function getUserDetails($username)
- {
- return $this->getUser($username);
- }
-
- /* UserClaimsInterface */
- public function getUserClaims($user_id, $claims)
- {
- if (!$userDetails = $this->getUserDetails($user_id)) {
- return false;
- }
-
- $claims = explode(' ', trim($claims));
- $userClaims = array();
-
- // for each requested claim, if the user has the claim, set it in the response
- $validClaims = explode(' ', self::VALID_CLAIMS);
- foreach ($validClaims as $validClaim) {
- if (in_array($validClaim, $claims)) {
- if ($validClaim == 'address') {
- // address is an object with subfields
- $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
- } else {
- $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
- }
- }
- }
-
- return $userClaims;
- }
-
- protected function getUserClaim($claim, $userDetails)
- {
- $userClaims = array();
- $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
- $claimValues = explode(' ', $claimValuesString);
-
- foreach ($claimValues as $value) {
- if ($value == 'email_verified') {
- $userClaims[$value] = $userDetails[$value]=='true' ? true : false;
- } else {
- $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
- }
- }
-
- return $userClaims;
- }
-
- /* OAuth2\Storage\RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['refresh_token_table'],
- "Key" => array('refresh_token' => array('S' => $refresh_token))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
- $token['expires'] = strtotime($token['expires']);
-
- return $token;
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- $clientData = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
- $clientData = array_filter($clientData, 'self::isNotEmpty');
-
- $result = $this->client->putItem(array(
- 'TableName' => $this->config['refresh_token_table'],
- 'Item' => $this->client->formatAttributes($clientData)
- ));
-
- return true;
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- $result = $this->client->deleteItem(array(
- 'TableName' => $this->config['refresh_token_table'],
- 'Key' => $this->client->formatAttributes(array("refresh_token" => $refresh_token))
- ));
-
- return true;
- }
-
- // plaintext passwords are bad! Override this for your application
- protected function checkPassword($user, $password)
- {
- return $user['password'] == $this->hashPassword($password);
- }
-
- // use a secure hashing algorithm when storing passwords. Override this for your application
- protected function hashPassword($password)
- {
- return sha1($password);
- }
-
- public function getUser($username)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['user_table'],
- "Key" => array('username' => array('S' => $username))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
- $token['user_id'] = $username;
-
- return $token;
- }
-
- public function setUser($username, $password, $first_name = null, $last_name = null)
- {
- // do not store in plaintext
- $password = $this->hashPassword($password);
-
- $clientData = compact('username', 'password', 'first_name', 'last_name');
- $clientData = array_filter($clientData, 'self::isNotEmpty');
-
- $result = $this->client->putItem(array(
- 'TableName' => $this->config['user_table'],
- 'Item' => $this->client->formatAttributes($clientData)
- ));
-
- return true;
-
- }
-
- /* ScopeInterface */
- public function scopeExists($scope)
- {
- $scope = explode(' ', $scope);
- $scope_query = array();
- $count = 0;
- foreach ($scope as $key => $val) {
- $result = $this->client->query(array(
- 'TableName' => $this->config['scope_table'],
- 'Select' => 'COUNT',
- 'KeyConditions' => array(
- 'scope' => array(
- 'AttributeValueList' => array(array('S' => $val)),
- 'ComparisonOperator' => 'EQ'
- )
- )
- ));
- $count += $result['Count'];
- }
-
- return $count == count($scope);
- }
-
- public function getDefaultScope($client_id = null)
- {
-
- $result = $this->client->query(array(
- 'TableName' => $this->config['scope_table'],
- 'IndexName' => 'is_default-index',
- 'Select' => 'ALL_ATTRIBUTES',
- 'KeyConditions' => array(
- 'is_default' => array(
- 'AttributeValueList' => array(array('S' => 'true')),
- 'ComparisonOperator' => 'EQ',
- ),
- )
- ));
- $defaultScope = array();
- if ($result->count() > 0) {
- $array = $result->toArray();
- foreach ($array["Items"] as $item) {
- $defaultScope[] = $item['scope']['S'];
- }
-
- return empty($defaultScope) ? null : implode(' ', $defaultScope);
- }
-
- return null;
- }
-
- /* JWTBearerInterface */
- public function getClientKey($client_id, $subject)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['jwt_table'],
- "Key" => array('client_id' => array('S' => $client_id), 'subject' => array('S' => $subject))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
-
- return $token['public_key'];
- }
-
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expires, $jti)
- {
- //TODO not use.
- }
-
- public function setJti($client_id, $subject, $audience, $expires, $jti)
- {
- //TODO not use.
- }
-
- /* PublicKeyInterface */
- public function getPublicKey($client_id = '0')
- {
-
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['public_key_table'],
- "Key" => array('client_id' => array('S' => $client_id))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
-
- return $token['public_key'];
-
- }
-
- public function getPrivateKey($client_id = '0')
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['public_key_table'],
- "Key" => array('client_id' => array('S' => $client_id))
- ));
- if ($result->count()==0) {
- return false ;
- }
- $token = $this->dynamo2array($result);
-
- return $token['private_key'];
- }
-
- public function getEncryptionAlgorithm($client_id = null)
- {
- $result = $this->client->getItem(array(
- "TableName"=> $this->config['public_key_table'],
- "Key" => array('client_id' => array('S' => $client_id))
- ));
- if ($result->count()==0) {
- return 'RS256' ;
- }
- $token = $this->dynamo2array($result);
-
- return $token['encryption_algorithm'];
- }
-
- /**
- * Transform dynamodb resultset to an array.
- * @param $dynamodbResult
- * @return $array
- */
- private function dynamo2array($dynamodbResult)
- {
- $result = array();
- foreach ($dynamodbResult["Item"] as $key => $val) {
- $result[$key] = $val["S"];
- $result[] = $val["S"];
- }
-
- return $result;
- }
-
- private static function isNotEmpty($value)
- {
- return null !== $value && '' !== $value;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/JwtAccessToken.php b/library/oauth2/src/OAuth2/Storage/JwtAccessToken.php
deleted file mode 100644
index 75b49d301..000000000
--- a/library/oauth2/src/OAuth2/Storage/JwtAccessToken.php
+++ /dev/null
@@ -1,88 +0,0 @@
-
- */
-class JwtAccessToken implements JwtAccessTokenInterface
-{
- protected $publicKeyStorage;
- protected $tokenStorage;
- protected $encryptionUtil;
-
- /**
- * @param OAuth2\Encryption\PublicKeyInterface $publicKeyStorage the public key encryption to use
- * @param OAuth2\Storage\AccessTokenInterface $tokenStorage OPTIONAL persist the access token to another storage. This is useful if
- * you want to retain access token grant information somewhere, but
- * is not necessary when using this grant type.
- * @param OAuth2\Encryption\EncryptionInterface $encryptionUtil OPTIONAL class to use for "encode" and "decode" functions.
- */
- public function __construct(PublicKeyInterface $publicKeyStorage, AccessTokenInterface $tokenStorage = null, EncryptionInterface $encryptionUtil = null)
- {
- $this->publicKeyStorage = $publicKeyStorage;
- $this->tokenStorage = $tokenStorage;
- if (is_null($encryptionUtil)) {
- $encryptionUtil = new Jwt;
- }
- $this->encryptionUtil = $encryptionUtil;
- }
-
- public function getAccessToken($oauth_token)
- {
- // just decode the token, don't verify
- if (!$tokenData = $this->encryptionUtil->decode($oauth_token, null, false)) {
- return false;
- }
-
- $client_id = isset($tokenData['aud']) ? $tokenData['aud'] : null;
- $public_key = $this->publicKeyStorage->getPublicKey($client_id);
- $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
-
- // now that we have the client_id, verify the token
- if (false === $this->encryptionUtil->decode($oauth_token, $public_key, array($algorithm))) {
- return false;
- }
-
- // normalize the JWT claims to the format expected by other components in this library
- return $this->convertJwtToOAuth2($tokenData);
- }
-
- public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null)
- {
- if ($this->tokenStorage) {
- return $this->tokenStorage->setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope);
- }
- }
-
- public function unsetAccessToken($access_token)
- {
- if ($this->tokenStorage) {
- return $this->tokenStorage->unsetAccessToken($access_token);
- }
- }
-
-
- // converts a JWT access token into an OAuth2-friendly format
- protected function convertJwtToOAuth2($tokenData)
- {
- $keyMapping = array(
- 'aud' => 'client_id',
- 'exp' => 'expires',
- 'sub' => 'user_id'
- );
-
- foreach ($keyMapping as $jwtKey => $oauth2Key) {
- if (isset($tokenData[$jwtKey])) {
- $tokenData[$oauth2Key] = $tokenData[$jwtKey];
- unset($tokenData[$jwtKey]);
- }
- }
-
- return $tokenData;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/JwtAccessTokenInterface.php b/library/oauth2/src/OAuth2/Storage/JwtAccessTokenInterface.php
deleted file mode 100644
index 3abb2aa2d..000000000
--- a/library/oauth2/src/OAuth2/Storage/JwtAccessTokenInterface.php
+++ /dev/null
@@ -1,14 +0,0 @@
-
- */
-interface JwtAccessTokenInterface extends AccessTokenInterface
-{
-
-}
diff --git a/library/oauth2/src/OAuth2/Storage/JwtBearerInterface.php b/library/oauth2/src/OAuth2/Storage/JwtBearerInterface.php
deleted file mode 100644
index c83aa72ea..000000000
--- a/library/oauth2/src/OAuth2/Storage/JwtBearerInterface.php
+++ /dev/null
@@ -1,74 +0,0 @@
-
- */
-interface JwtBearerInterface
-{
- /**
- * Get the public key associated with a client_id
- *
- * @param $client_id
- * Client identifier to be checked with.
- *
- * @return
- * STRING Return the public key for the client_id if it exists, and MUST return FALSE if it doesn't.
- */
- public function getClientKey($client_id, $subject);
-
- /**
- * Get a jti (JSON token identifier) by matching against the client_id, subject, audience and expiration.
- *
- * @param $client_id
- * Client identifier to match.
- *
- * @param $subject
- * The subject to match.
- *
- * @param $audience
- * The audience to match.
- *
- * @param $expiration
- * The expiration of the jti.
- *
- * @param $jti
- * The jti to match.
- *
- * @return
- * An associative array as below, and return NULL if the jti does not exist.
- * - issuer: Stored client identifier.
- * - subject: Stored subject.
- * - audience: Stored audience.
- * - expires: Stored expiration in unix timestamp.
- * - jti: The stored jti.
- */
- public function getJti($client_id, $subject, $audience, $expiration, $jti);
-
- /**
- * Store a used jti so that we can check against it to prevent replay attacks.
- * @param $client_id
- * Client identifier to insert.
- *
- * @param $subject
- * The subject to insert.
- *
- * @param $audience
- * The audience to insert.
- *
- * @param $expiration
- * The expiration of the jti.
- *
- * @param $jti
- * The jti to insert.
- */
- public function setJti($client_id, $subject, $audience, $expiration, $jti);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/Memory.php b/library/oauth2/src/OAuth2/Storage/Memory.php
deleted file mode 100644
index 42d833ccb..000000000
--- a/library/oauth2/src/OAuth2/Storage/Memory.php
+++ /dev/null
@@ -1,381 +0,0 @@
-
- */
-class Memory implements AuthorizationCodeInterface,
- UserCredentialsInterface,
- UserClaimsInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- ScopeInterface,
- PublicKeyInterface,
- OpenIDAuthorizationCodeInterface
-{
- public $authorizationCodes;
- public $userCredentials;
- public $clientCredentials;
- public $refreshTokens;
- public $accessTokens;
- public $jwt;
- public $jti;
- public $supportedScopes;
- public $defaultScope;
- public $keys;
-
- public function __construct($params = array())
- {
- $params = array_merge(array(
- 'authorization_codes' => array(),
- 'user_credentials' => array(),
- 'client_credentials' => array(),
- 'refresh_tokens' => array(),
- 'access_tokens' => array(),
- 'jwt' => array(),
- 'jti' => array(),
- 'default_scope' => null,
- 'supported_scopes' => array(),
- 'keys' => array(),
- ), $params);
-
- $this->authorizationCodes = $params['authorization_codes'];
- $this->userCredentials = $params['user_credentials'];
- $this->clientCredentials = $params['client_credentials'];
- $this->refreshTokens = $params['refresh_tokens'];
- $this->accessTokens = $params['access_tokens'];
- $this->jwt = $params['jwt'];
- $this->jti = $params['jti'];
- $this->supportedScopes = $params['supported_scopes'];
- $this->defaultScope = $params['default_scope'];
- $this->keys = $params['keys'];
- }
-
- /* AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- if (!isset($this->authorizationCodes[$code])) {
- return false;
- }
-
- return array_merge(array(
- 'authorization_code' => $code,
- ), $this->authorizationCodes[$code]);
- }
-
- public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- $this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token');
-
- return true;
- }
-
- public function setAuthorizationCodes($authorization_codes)
- {
- $this->authorizationCodes = $authorization_codes;
- }
-
- public function expireAuthorizationCode($code)
- {
- unset($this->authorizationCodes[$code]);
- }
-
- /* UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- $userDetails = $this->getUserDetails($username);
-
- return $userDetails && $userDetails['password'] && $userDetails['password'] === $password;
- }
-
- public function setUser($username, $password, $firstName = null, $lastName = null)
- {
- $this->userCredentials[$username] = array(
- 'password' => $password,
- 'first_name' => $firstName,
- 'last_name' => $lastName,
- );
-
- return true;
- }
-
- public function getUserDetails($username)
- {
- if (!isset($this->userCredentials[$username])) {
- return false;
- }
-
- return array_merge(array(
- 'user_id' => $username,
- 'password' => null,
- 'first_name' => null,
- 'last_name' => null,
- ), $this->userCredentials[$username]);
- }
-
- /* UserClaimsInterface */
- public function getUserClaims($user_id, $claims)
- {
- if (!$userDetails = $this->getUserDetails($user_id)) {
- return false;
- }
-
- $claims = explode(' ', trim($claims));
- $userClaims = array();
-
- // for each requested claim, if the user has the claim, set it in the response
- $validClaims = explode(' ', self::VALID_CLAIMS);
- foreach ($validClaims as $validClaim) {
- if (in_array($validClaim, $claims)) {
- if ($validClaim == 'address') {
- // address is an object with subfields
- $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
- } else {
- $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
- }
- }
- }
-
- return $userClaims;
- }
-
- protected function getUserClaim($claim, $userDetails)
- {
- $userClaims = array();
- $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
- $claimValues = explode(' ', $claimValuesString);
-
- foreach ($claimValues as $value) {
- $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
- }
-
- return $userClaims;
- }
-
- /* ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- return isset($this->clientCredentials[$client_id]['client_secret']) && $this->clientCredentials[$client_id]['client_secret'] === $client_secret;
- }
-
- public function isPublicClient($client_id)
- {
- if (!isset($this->clientCredentials[$client_id])) {
- return false;
- }
-
- return empty($this->clientCredentials[$client_id]['client_secret']);
- }
-
- /* ClientInterface */
- public function getClientDetails($client_id)
- {
- if (!isset($this->clientCredentials[$client_id])) {
- return false;
- }
-
- $clientDetails = array_merge(array(
- 'client_id' => $client_id,
- 'client_secret' => null,
- 'redirect_uri' => null,
- 'scope' => null,
- ), $this->clientCredentials[$client_id]);
-
- return $clientDetails;
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- if (isset($this->clientCredentials[$client_id]['grant_types'])) {
- $grant_types = explode(' ', $this->clientCredentials[$client_id]['grant_types']);
-
- return in_array($grant_type, $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- $this->clientCredentials[$client_id] = array(
- 'client_id' => $client_id,
- 'client_secret' => $client_secret,
- 'redirect_uri' => $redirect_uri,
- 'grant_types' => $grant_types,
- 'scope' => $scope,
- 'user_id' => $user_id,
- );
-
- return true;
- }
-
- /* RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- return isset($this->refreshTokens[$refresh_token]) ? $this->refreshTokens[$refresh_token] : false;
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- $this->refreshTokens[$refresh_token] = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
-
- return true;
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- if (isset($this->refreshTokens[$refresh_token])) {
- unset($this->refreshTokens[$refresh_token]);
-
- return true;
- }
-
- return false;
- }
-
- public function setRefreshTokens($refresh_tokens)
- {
- $this->refreshTokens = $refresh_tokens;
- }
-
- /* AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- return isset($this->accessTokens[$access_token]) ? $this->accessTokens[$access_token] : false;
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null, $id_token = null)
- {
- $this->accessTokens[$access_token] = compact('access_token', 'client_id', 'user_id', 'expires', 'scope', 'id_token');
-
- return true;
- }
-
- public function unsetAccessToken($access_token)
- {
- if (isset($this->accessTokens[$access_token])) {
- unset($this->accessTokens[$access_token]);
-
- return true;
- }
-
- return false;
- }
-
- public function scopeExists($scope)
- {
- $scope = explode(' ', trim($scope));
-
- return (count(array_diff($scope, $this->supportedScopes)) == 0);
- }
-
- public function getDefaultScope($client_id = null)
- {
- return $this->defaultScope;
- }
-
- /*JWTBearerInterface */
- public function getClientKey($client_id, $subject)
- {
- if (isset($this->jwt[$client_id])) {
- $jwt = $this->jwt[$client_id];
- if ($jwt) {
- if ($jwt["subject"] == $subject) {
- return $jwt["key"];
- }
- }
- }
-
- return false;
- }
-
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expires, $jti)
- {
- foreach ($this->jti as $storedJti) {
- if ($storedJti['issuer'] == $client_id && $storedJti['subject'] == $subject && $storedJti['audience'] == $audience && $storedJti['expires'] == $expires && $storedJti['jti'] == $jti) {
- return array(
- 'issuer' => $storedJti['issuer'],
- 'subject' => $storedJti['subject'],
- 'audience' => $storedJti['audience'],
- 'expires' => $storedJti['expires'],
- 'jti' => $storedJti['jti']
- );
- }
- }
-
- return null;
- }
-
- public function setJti($client_id, $subject, $audience, $expires, $jti)
- {
- $this->jti[] = array('issuer' => $client_id, 'subject' => $subject, 'audience' => $audience, 'expires' => $expires, 'jti' => $jti);
- }
-
- /*PublicKeyInterface */
- public function getPublicKey($client_id = null)
- {
- if (isset($this->keys[$client_id])) {
- return $this->keys[$client_id]['public_key'];
- }
-
- // use a global encryption pair
- if (isset($this->keys['public_key'])) {
- return $this->keys['public_key'];
- }
-
- return false;
- }
-
- public function getPrivateKey($client_id = null)
- {
- if (isset($this->keys[$client_id])) {
- return $this->keys[$client_id]['private_key'];
- }
-
- // use a global encryption pair
- if (isset($this->keys['private_key'])) {
- return $this->keys['private_key'];
- }
-
- return false;
- }
-
- public function getEncryptionAlgorithm($client_id = null)
- {
- if (isset($this->keys[$client_id]['encryption_algorithm'])) {
- return $this->keys[$client_id]['encryption_algorithm'];
- }
-
- // use a global encryption algorithm
- if (isset($this->keys['encryption_algorithm'])) {
- return $this->keys['encryption_algorithm'];
- }
-
- return 'RS256';
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/Mongo.php b/library/oauth2/src/OAuth2/Storage/Mongo.php
deleted file mode 100644
index cef35e5e9..000000000
--- a/library/oauth2/src/OAuth2/Storage/Mongo.php
+++ /dev/null
@@ -1,339 +0,0 @@
-
- */
-class Mongo implements AuthorizationCodeInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- UserCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- OpenIDAuthorizationCodeInterface
-{
- protected $db;
- protected $config;
-
- public function __construct($connection, $config = array())
- {
- if ($connection instanceof \MongoDB) {
- $this->db = $connection;
- } else {
- if (!is_array($connection)) {
- throw new \InvalidArgumentException('First argument to OAuth2\Storage\Mongo must be an instance of MongoDB or a configuration array');
- }
- $server = sprintf('mongodb://%s:%d', $connection['host'], $connection['port']);
- $m = new \MongoClient($server);
- $this->db = $m->{$connection['database']};
- }
-
- $this->config = array_merge(array(
- 'client_table' => 'oauth_clients',
- 'access_token_table' => 'oauth_access_tokens',
- 'refresh_token_table' => 'oauth_refresh_tokens',
- 'code_table' => 'oauth_authorization_codes',
- 'user_table' => 'oauth_users',
- 'jwt_table' => 'oauth_jwt',
- ), $config);
- }
-
- // Helper function to access a MongoDB collection by `type`:
- protected function collection($name)
- {
- return $this->db->{$this->config[$name]};
- }
-
- /* ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- if ($result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
- return $result['client_secret'] == $client_secret;
- }
-
- return false;
- }
-
- public function isPublicClient($client_id)
- {
- if (!$result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
- return false;
- }
-
- return empty($result['client_secret']);
- }
-
- /* ClientInterface */
- public function getClientDetails($client_id)
- {
- $result = $this->collection('client_table')->findOne(array('client_id' => $client_id));
-
- return is_null($result) ? false : $result;
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- if ($this->getClientDetails($client_id)) {
- $this->collection('client_table')->update(
- array('client_id' => $client_id),
- array('$set' => array(
- 'client_secret' => $client_secret,
- 'redirect_uri' => $redirect_uri,
- 'grant_types' => $grant_types,
- 'scope' => $scope,
- 'user_id' => $user_id,
- ))
- );
- } else {
- $client = array(
- 'client_id' => $client_id,
- 'client_secret' => $client_secret,
- 'redirect_uri' => $redirect_uri,
- 'grant_types' => $grant_types,
- 'scope' => $scope,
- 'user_id' => $user_id,
- );
- $this->collection('client_table')->insert($client);
- }
-
- return true;
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- $details = $this->getClientDetails($client_id);
- if (isset($details['grant_types'])) {
- $grant_types = explode(' ', $details['grant_types']);
-
- return in_array($grant_type, $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- /* AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- $token = $this->collection('access_token_table')->findOne(array('access_token' => $access_token));
-
- return is_null($token) ? false : $token;
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
- {
- // if it exists, update it.
- if ($this->getAccessToken($access_token)) {
- $this->collection('access_token_table')->update(
- array('access_token' => $access_token),
- array('$set' => array(
- 'client_id' => $client_id,
- 'expires' => $expires,
- 'user_id' => $user_id,
- 'scope' => $scope
- ))
- );
- } else {
- $token = array(
- 'access_token' => $access_token,
- 'client_id' => $client_id,
- 'expires' => $expires,
- 'user_id' => $user_id,
- 'scope' => $scope
- );
- $this->collection('access_token_table')->insert($token);
- }
-
- return true;
- }
-
- public function unsetAccessToken($access_token)
- {
- $result = $this->collection('access_token_table')->remove(array(
- 'access_token' => $access_token
- ), array('w' => 1));
-
- return $result['n'] > 0;
- }
-
-
- /* AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- $code = $this->collection('code_table')->findOne(array('authorization_code' => $code));
-
- return is_null($code) ? false : $code;
- }
-
- public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- // if it exists, update it.
- if ($this->getAuthorizationCode($code)) {
- $this->collection('code_table')->update(
- array('authorization_code' => $code),
- array('$set' => array(
- 'client_id' => $client_id,
- 'user_id' => $user_id,
- 'redirect_uri' => $redirect_uri,
- 'expires' => $expires,
- 'scope' => $scope,
- 'id_token' => $id_token,
- ))
- );
- } else {
- $token = array(
- 'authorization_code' => $code,
- 'client_id' => $client_id,
- 'user_id' => $user_id,
- 'redirect_uri' => $redirect_uri,
- 'expires' => $expires,
- 'scope' => $scope,
- 'id_token' => $id_token,
- );
- $this->collection('code_table')->insert($token);
- }
-
- return true;
- }
-
- public function expireAuthorizationCode($code)
- {
- $this->collection('code_table')->remove(array('authorization_code' => $code));
-
- return true;
- }
-
- /* UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- if ($user = $this->getUser($username)) {
- return $this->checkPassword($user, $password);
- }
-
- return false;
- }
-
- public function getUserDetails($username)
- {
- if ($user = $this->getUser($username)) {
- $user['user_id'] = $user['username'];
- }
-
- return $user;
- }
-
- /* RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- $token = $this->collection('refresh_token_table')->findOne(array('refresh_token' => $refresh_token));
-
- return is_null($token) ? false : $token;
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- $token = array(
- 'refresh_token' => $refresh_token,
- 'client_id' => $client_id,
- 'user_id' => $user_id,
- 'expires' => $expires,
- 'scope' => $scope
- );
- $this->collection('refresh_token_table')->insert($token);
-
- return true;
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- $result = $this->collection('refresh_token_table')->remove(array(
- 'refresh_token' => $refresh_token
- ), array('w' => 1));
-
- return $result['n'] > 0;
- }
-
- // plaintext passwords are bad! Override this for your application
- protected function checkPassword($user, $password)
- {
- return $user['password'] == $password;
- }
-
- public function getUser($username)
- {
- $result = $this->collection('user_table')->findOne(array('username' => $username));
-
- return is_null($result) ? false : $result;
- }
-
- public function setUser($username, $password, $firstName = null, $lastName = null)
- {
- if ($this->getUser($username)) {
- $this->collection('user_table')->update(
- array('username' => $username),
- array('$set' => array(
- 'password' => $password,
- 'first_name' => $firstName,
- 'last_name' => $lastName
- ))
- );
- } else {
- $user = array(
- 'username' => $username,
- 'password' => $password,
- 'first_name' => $firstName,
- 'last_name' => $lastName
- );
- $this->collection('user_table')->insert($user);
- }
-
- return true;
- }
-
- public function getClientKey($client_id, $subject)
- {
- $result = $this->collection('jwt_table')->findOne(array(
- 'client_id' => $client_id,
- 'subject' => $subject
- ));
-
- return is_null($result) ? false : $result['key'];
- }
-
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs mongodb implementation.
- throw new \Exception('getJti() for the MongoDB driver is currently unimplemented.');
- }
-
- public function setJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs mongodb implementation.
- throw new \Exception('setJti() for the MongoDB driver is currently unimplemented.');
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/Pdo.php b/library/oauth2/src/OAuth2/Storage/Pdo.php
deleted file mode 100644
index ae5107e29..000000000
--- a/library/oauth2/src/OAuth2/Storage/Pdo.php
+++ /dev/null
@@ -1,553 +0,0 @@
-
- */
-class Pdo implements
- AuthorizationCodeInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- UserCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- ScopeInterface,
- PublicKeyInterface,
- UserClaimsInterface,
- OpenIDAuthorizationCodeInterface
-{
- protected $db;
- protected $config;
-
- public function __construct($connection, $config = array())
- {
- if (!$connection instanceof \PDO) {
- if (is_string($connection)) {
- $connection = array('dsn' => $connection);
- }
- if (!is_array($connection)) {
- throw new \InvalidArgumentException('First argument to OAuth2\Storage\Pdo must be an instance of PDO, a DSN string, or a configuration array');
- }
- if (!isset($connection['dsn'])) {
- throw new \InvalidArgumentException('configuration array must contain "dsn"');
- }
- // merge optional parameters
- $connection = array_merge(array(
- 'username' => null,
- 'password' => null,
- 'options' => array(),
- ), $connection);
- $connection = new \PDO($connection['dsn'], $connection['username'], $connection['password'], $connection['options']);
- }
- $this->db = $connection;
-
- // debugging
- $connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
-
- $this->config = array_merge(array(
- 'client_table' => 'oauth_clients',
- 'access_token_table' => 'oauth_access_tokens',
- 'refresh_token_table' => 'oauth_refresh_tokens',
- 'code_table' => 'oauth_authorization_codes',
- 'user_table' => 'oauth_users',
- 'jwt_table' => 'oauth_jwt',
- 'jti_table' => 'oauth_jti',
- 'scope_table' => 'oauth_scopes',
- 'public_key_table' => 'oauth_public_keys',
- ), $config);
- }
-
- /* OAuth2\Storage\ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
- $stmt->execute(compact('client_id'));
- $result = $stmt->fetch(\PDO::FETCH_ASSOC);
-
- // make this extensible
- return $result && $result['client_secret'] == $client_secret;
- }
-
- public function isPublicClient($client_id)
- {
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
- $stmt->execute(compact('client_id'));
-
- if (!$result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return false;
- }
-
- return empty($result['client_secret']);
- }
-
- /* OAuth2\Storage\ClientInterface */
- public function getClientDetails($client_id)
- {
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
- $stmt->execute(compact('client_id'));
-
- return $stmt->fetch(\PDO::FETCH_ASSOC);
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- // if it exists, update it.
- if ($this->getClientDetails($client_id)) {
- $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_secret=:client_secret, redirect_uri=:redirect_uri, grant_types=:grant_types, scope=:scope, user_id=:user_id where client_id=:client_id', $this->config['client_table']));
- } else {
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (client_id, client_secret, redirect_uri, grant_types, scope, user_id) VALUES (:client_id, :client_secret, :redirect_uri, :grant_types, :scope, :user_id)', $this->config['client_table']));
- }
-
- return $stmt->execute(compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id'));
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- $details = $this->getClientDetails($client_id);
- if (isset($details['grant_types'])) {
- $grant_types = explode(' ', $details['grant_types']);
-
- return in_array($grant_type, (array) $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- /* OAuth2\Storage\AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = :access_token', $this->config['access_token_table']));
-
- $token = $stmt->execute(compact('access_token'));
- if ($token = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- // convert date string back to timestamp
- $token['expires'] = strtotime($token['expires']);
- }
-
- return $token;
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
- {
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- // if it exists, update it.
- if ($this->getAccessToken($access_token)) {
- $stmt = $this->db->prepare(sprintf('UPDATE %s SET client_id=:client_id, expires=:expires, user_id=:user_id, scope=:scope where access_token=:access_token', $this->config['access_token_table']));
- } else {
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (access_token, client_id, expires, user_id, scope) VALUES (:access_token, :client_id, :expires, :user_id, :scope)', $this->config['access_token_table']));
- }
-
- return $stmt->execute(compact('access_token', 'client_id', 'user_id', 'expires', 'scope'));
- }
-
- public function unsetAccessToken($access_token)
- {
- $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE access_token = :access_token', $this->config['access_token_table']));
-
- $stmt->execute(compact('access_token'));
-
- return $stmt->rowCount() > 0;
- }
-
- /* OAuth2\Storage\AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = :code', $this->config['code_table']));
- $stmt->execute(compact('code'));
-
- if ($code = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- // convert date string back to timestamp
- $code['expires'] = strtotime($code['expires']);
- }
-
- return $code;
- }
-
- public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- if (func_num_args() > 6) {
- // we are calling with an id token
- return call_user_func_array(array($this, 'setAuthorizationCodeWithIdToken'), func_get_args());
- }
-
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- // if it exists, update it.
- if ($this->getAuthorizationCode($code)) {
- $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope where authorization_code=:code', $this->config['code_table']));
- } else {
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope)', $this->config['code_table']));
- }
-
- return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
- }
-
- private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- // if it exists, update it.
- if ($this->getAuthorizationCode($code)) {
- $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token where authorization_code=:code', $this->config['code_table']));
- } else {
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token)', $this->config['code_table']));
- }
-
- return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'));
- }
-
- public function expireAuthorizationCode($code)
- {
- $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE authorization_code = :code', $this->config['code_table']));
-
- return $stmt->execute(compact('code'));
- }
-
- /* OAuth2\Storage\UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- if ($user = $this->getUser($username)) {
- return $this->checkPassword($user, $password);
- }
-
- return false;
- }
-
- public function getUserDetails($username)
- {
- return $this->getUser($username);
- }
-
- /* UserClaimsInterface */
- public function getUserClaims($user_id, $claims)
- {
- if (!$userDetails = $this->getUserDetails($user_id)) {
- return false;
- }
-
- $claims = explode(' ', trim($claims));
- $userClaims = array();
-
- // for each requested claim, if the user has the claim, set it in the response
- $validClaims = explode(' ', self::VALID_CLAIMS);
- foreach ($validClaims as $validClaim) {
- if (in_array($validClaim, $claims)) {
- if ($validClaim == 'address') {
- // address is an object with subfields
- $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
- } else {
- $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
- }
- }
- }
-
- return $userClaims;
- }
-
- protected function getUserClaim($claim, $userDetails)
- {
- $userClaims = array();
- $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
- $claimValues = explode(' ', $claimValuesString);
-
- foreach ($claimValues as $value) {
- $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
- }
-
- return $userClaims;
- }
-
- /* OAuth2\Storage\RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- $stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
-
- $token = $stmt->execute(compact('refresh_token'));
- if ($token = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- // convert expires to epoch time
- $token['expires'] = strtotime($token['expires']);
- }
-
- return $token;
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- // convert expires to datestring
- $expires = date('Y-m-d H:i:s', $expires);
-
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (refresh_token, client_id, user_id, expires, scope) VALUES (:refresh_token, :client_id, :user_id, :expires, :scope)', $this->config['refresh_token_table']));
-
- return $stmt->execute(compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'));
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
-
- $stmt->execute(compact('refresh_token'));
-
- return $stmt->rowCount() > 0;
- }
-
- // plaintext passwords are bad! Override this for your application
- protected function checkPassword($user, $password)
- {
- return $user['password'] == $this->hashPassword($password);
- }
-
- // use a secure hashing algorithm when storing passwords. Override this for your application
- protected function hashPassword($password)
- {
- return sha1($password);
- }
-
- public function getUser($username)
- {
- $stmt = $this->db->prepare($sql = sprintf('SELECT * from %s where username=:username', $this->config['user_table']));
- $stmt->execute(array('username' => $username));
-
- if (!$userInfo = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return false;
- }
-
- // the default behavior is to use "username" as the user_id
- return array_merge(array(
- 'user_id' => $username
- ), $userInfo);
- }
-
- public function setUser($username, $password, $firstName = null, $lastName = null)
- {
- // do not store in plaintext
- $password = $this->hashPassword($password);
-
- // if it exists, update it.
- if ($this->getUser($username)) {
- $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET password=:password, first_name=:firstName, last_name=:lastName where username=:username', $this->config['user_table']));
- } else {
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (username, password, first_name, last_name) VALUES (:username, :password, :firstName, :lastName)', $this->config['user_table']));
- }
-
- return $stmt->execute(compact('username', 'password', 'firstName', 'lastName'));
- }
-
- /* ScopeInterface */
- public function scopeExists($scope)
- {
- $scope = explode(' ', $scope);
- $whereIn = implode(',', array_fill(0, count($scope), '?'));
- $stmt = $this->db->prepare(sprintf('SELECT count(scope) as count FROM %s WHERE scope IN (%s)', $this->config['scope_table'], $whereIn));
- $stmt->execute($scope);
-
- if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return $result['count'] == count($scope);
- }
-
- return false;
- }
-
- public function getDefaultScope($client_id = null)
- {
- $stmt = $this->db->prepare(sprintf('SELECT scope FROM %s WHERE is_default=:is_default', $this->config['scope_table']));
- $stmt->execute(array('is_default' => true));
-
- if ($result = $stmt->fetchAll(\PDO::FETCH_ASSOC)) {
- $defaultScope = array_map(function ($row) {
- return $row['scope'];
- }, $result);
-
- return implode(' ', $defaultScope);
- }
-
- return null;
- }
-
- /* JWTBearerInterface */
- public function getClientKey($client_id, $subject)
- {
- $stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id AND subject=:subject', $this->config['jwt_table']));
-
- $stmt->execute(array('client_id' => $client_id, 'subject' => $subject));
-
- return $stmt->fetchColumn();
- }
-
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expires, $jti)
- {
- $stmt = $this->db->prepare($sql = sprintf('SELECT * FROM %s WHERE issuer=:client_id AND subject=:subject AND audience=:audience AND expires=:expires AND jti=:jti', $this->config['jti_table']));
-
- $stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
-
- if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return array(
- 'issuer' => $result['issuer'],
- 'subject' => $result['subject'],
- 'audience' => $result['audience'],
- 'expires' => $result['expires'],
- 'jti' => $result['jti'],
- );
- }
-
- return null;
- }
-
- public function setJti($client_id, $subject, $audience, $expires, $jti)
- {
- $stmt = $this->db->prepare(sprintf('INSERT INTO %s (issuer, subject, audience, expires, jti) VALUES (:client_id, :subject, :audience, :expires, :jti)', $this->config['jti_table']));
-
- return $stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
- }
-
- /* PublicKeyInterface */
- public function getPublicKey($client_id = null)
- {
- $stmt = $this->db->prepare($sql = sprintf('SELECT public_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
-
- $stmt->execute(compact('client_id'));
- if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return $result['public_key'];
- }
- }
-
- public function getPrivateKey($client_id = null)
- {
- $stmt = $this->db->prepare($sql = sprintf('SELECT private_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
-
- $stmt->execute(compact('client_id'));
- if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return $result['private_key'];
- }
- }
-
- public function getEncryptionAlgorithm($client_id = null)
- {
- $stmt = $this->db->prepare($sql = sprintf('SELECT encryption_algorithm FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
-
- $stmt->execute(compact('client_id'));
- if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- return $result['encryption_algorithm'];
- }
-
- return 'RS256';
- }
-
- /**
- * DDL to create OAuth2 database and tables for PDO storage
- *
- * @see https://github.com/dsquier/oauth2-server-php-mysql
- */
- public function getBuildSql($dbName = 'oauth2_server_php')
- {
- $sql = "
- CREATE TABLE {$this->config['client_table']} (
- client_id VARCHAR(80) NOT NULL,
- client_secret VARCHAR(80),
- redirect_uri VARCHAR(2000),
- grant_types VARCHAR(80),
- scope VARCHAR(4000),
- user_id VARCHAR(80),
- PRIMARY KEY (client_id)
- );
-
- CREATE TABLE {$this->config['access_token_table']} (
- access_token VARCHAR(40) NOT NULL,
- client_id VARCHAR(80) NOT NULL,
- user_id VARCHAR(80),
- expires TIMESTAMP NOT NULL,
- scope VARCHAR(4000),
- PRIMARY KEY (access_token)
- );
-
- CREATE TABLE {$this->config['code_table']} (
- authorization_code VARCHAR(40) NOT NULL,
- client_id VARCHAR(80) NOT NULL,
- user_id VARCHAR(80),
- redirect_uri VARCHAR(2000),
- expires TIMESTAMP NOT NULL,
- scope VARCHAR(4000),
- id_token VARCHAR(1000),
- PRIMARY KEY (authorization_code)
- );
-
- CREATE TABLE {$this->config['refresh_token_table']} (
- refresh_token VARCHAR(40) NOT NULL,
- client_id VARCHAR(80) NOT NULL,
- user_id VARCHAR(80),
- expires TIMESTAMP NOT NULL,
- scope VARCHAR(4000),
- PRIMARY KEY (refresh_token)
- );
-
- CREATE TABLE {$this->config['user_table']} (
- username VARCHAR(80),
- password VARCHAR(80),
- first_name VARCHAR(80),
- last_name VARCHAR(80),
- email VARCHAR(80),
- email_verified BOOLEAN,
- scope VARCHAR(4000)
- );
-
- CREATE TABLE {$this->config['scope_table']} (
- scope VARCHAR(80) NOT NULL,
- is_default BOOLEAN,
- PRIMARY KEY (scope)
- );
-
- CREATE TABLE {$this->config['jwt_table']} (
- client_id VARCHAR(80) NOT NULL,
- subject VARCHAR(80),
- public_key VARCHAR(2000) NOT NULL
- );
-
- CREATE TABLE {$this->config['jti_table']} (
- issuer VARCHAR(80) NOT NULL,
- subject VARCHAR(80),
- audience VARCHAR(80),
- expires TIMESTAMP NOT NULL,
- jti VARCHAR(2000) NOT NULL
- );
-
- CREATE TABLE {$this->config['public_key_table']} (
- client_id VARCHAR(80),
- public_key VARCHAR(2000),
- private_key VARCHAR(2000),
- encryption_algorithm VARCHAR(100) DEFAULT 'RS256'
- )
-";
-
- return $sql;
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/PublicKeyInterface.php b/library/oauth2/src/OAuth2/Storage/PublicKeyInterface.php
deleted file mode 100644
index 108418d3a..000000000
--- a/library/oauth2/src/OAuth2/Storage/PublicKeyInterface.php
+++ /dev/null
@@ -1,16 +0,0 @@
-
- */
-interface PublicKeyInterface
-{
- public function getPublicKey($client_id = null);
- public function getPrivateKey($client_id = null);
- public function getEncryptionAlgorithm($client_id = null);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/Redis.php b/library/oauth2/src/OAuth2/Storage/Redis.php
deleted file mode 100644
index e6294e22d..000000000
--- a/library/oauth2/src/OAuth2/Storage/Redis.php
+++ /dev/null
@@ -1,321 +0,0 @@
-
- * $storage = new OAuth2\Storage\Redis($redis);
- * $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
- *
- */
-class Redis implements AuthorizationCodeInterface,
- AccessTokenInterface,
- ClientCredentialsInterface,
- UserCredentialsInterface,
- RefreshTokenInterface,
- JwtBearerInterface,
- ScopeInterface,
- OpenIDAuthorizationCodeInterface
-{
-
- private $cache;
-
- /* The redis client */
- protected $redis;
-
- /* Configuration array */
- protected $config;
-
- /**
- * Redis Storage!
- *
- * @param \Predis\Client $redis
- * @param array $config
- */
- public function __construct($redis, $config=array())
- {
- $this->redis = $redis;
- $this->config = array_merge(array(
- 'client_key' => 'oauth_clients:',
- 'access_token_key' => 'oauth_access_tokens:',
- 'refresh_token_key' => 'oauth_refresh_tokens:',
- 'code_key' => 'oauth_authorization_codes:',
- 'user_key' => 'oauth_users:',
- 'jwt_key' => 'oauth_jwt:',
- 'scope_key' => 'oauth_scopes:',
- ), $config);
- }
-
- protected function getValue($key)
- {
- if ( isset($this->cache[$key]) ) {
- return $this->cache[$key];
- }
- $value = $this->redis->get($key);
- if ( isset($value) ) {
- return json_decode($value, true);
- } else {
- return false;
- }
- }
-
- protected function setValue($key, $value, $expire=0)
- {
- $this->cache[$key] = $value;
- $str = json_encode($value);
- if ($expire > 0) {
- $seconds = $expire - time();
- $ret = $this->redis->setex($key, $seconds, $str);
- } else {
- $ret = $this->redis->set($key, $str);
- }
-
- // check that the key was set properly
- // if this fails, an exception will usually thrown, so this step isn't strictly necessary
- return is_bool($ret) ? $ret : $ret->getPayload() == 'OK';
- }
-
- protected function expireValue($key)
- {
- unset($this->cache[$key]);
-
- return $this->redis->del($key);
- }
-
- /* AuthorizationCodeInterface */
- public function getAuthorizationCode($code)
- {
- return $this->getValue($this->config['code_key'] . $code);
- }
-
- public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
- {
- return $this->setValue(
- $this->config['code_key'] . $authorization_code,
- compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
- $expires
- );
- }
-
- public function expireAuthorizationCode($code)
- {
- $key = $this->config['code_key'] . $code;
- unset($this->cache[$key]);
-
- return $this->expireValue($key);
- }
-
- /* UserCredentialsInterface */
- public function checkUserCredentials($username, $password)
- {
- $user = $this->getUserDetails($username);
-
- return $user && $user['password'] === $password;
- }
-
- public function getUserDetails($username)
- {
- return $this->getUser($username);
- }
-
- public function getUser($username)
- {
- if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
- return false;
- }
-
- // the default behavior is to use "username" as the user_id
- return array_merge(array(
- 'user_id' => $username,
- ), $userInfo);
- }
-
- public function setUser($username, $password, $first_name = null, $last_name = null)
- {
- return $this->setValue(
- $this->config['user_key'] . $username,
- compact('username', 'password', 'first_name', 'last_name')
- );
- }
-
- /* ClientCredentialsInterface */
- public function checkClientCredentials($client_id, $client_secret = null)
- {
- if (!$client = $this->getClientDetails($client_id)) {
- return false;
- }
-
- return isset($client['client_secret'])
- && $client['client_secret'] == $client_secret;
- }
-
- public function isPublicClient($client_id)
- {
- if (!$client = $this->getClientDetails($client_id)) {
- return false;
- }
-
- return empty($client['client_secret']);
- }
-
- /* ClientInterface */
- public function getClientDetails($client_id)
- {
- return $this->getValue($this->config['client_key'] . $client_id);
- }
-
- public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
- {
- return $this->setValue(
- $this->config['client_key'] . $client_id,
- compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
- );
- }
-
- public function checkRestrictedGrantType($client_id, $grant_type)
- {
- $details = $this->getClientDetails($client_id);
- if (isset($details['grant_types'])) {
- $grant_types = explode(' ', $details['grant_types']);
-
- return in_array($grant_type, (array) $grant_types);
- }
-
- // if grant_types are not defined, then none are restricted
- return true;
- }
-
- /* RefreshTokenInterface */
- public function getRefreshToken($refresh_token)
- {
- return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
- }
-
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
- {
- return $this->setValue(
- $this->config['refresh_token_key'] . $refresh_token,
- compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'),
- $expires
- );
- }
-
- public function unsetRefreshToken($refresh_token)
- {
- $result = $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
-
- return $result > 0;
- }
-
- /* AccessTokenInterface */
- public function getAccessToken($access_token)
- {
- return $this->getValue($this->config['access_token_key'].$access_token);
- }
-
- public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
- {
- return $this->setValue(
- $this->config['access_token_key'].$access_token,
- compact('access_token', 'client_id', 'user_id', 'expires', 'scope'),
- $expires
- );
- }
-
- public function unsetAccessToken($access_token)
- {
- $result = $this->expireValue($this->config['access_token_key'] . $access_token);
-
- return $result > 0;
- }
-
- /* ScopeInterface */
- public function scopeExists($scope)
- {
- $scope = explode(' ', $scope);
-
- $result = $this->getValue($this->config['scope_key'].'supported:global');
-
- $supportedScope = explode(' ', (string) $result);
-
- return (count(array_diff($scope, $supportedScope)) == 0);
- }
-
- public function getDefaultScope($client_id = null)
- {
- if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
- $result = $this->getValue($this->config['scope_key'].'default:global');
- }
-
- return $result;
- }
-
- public function setScope($scope, $client_id = null, $type = 'supported')
- {
- if (!in_array($type, array('default', 'supported'))) {
- throw new \InvalidArgumentException('"$type" must be one of "default", "supported"');
- }
-
- if (is_null($client_id)) {
- $key = $this->config['scope_key'].$type.':global';
- } else {
- $key = $this->config['scope_key'].$type.':'.$client_id;
- }
-
- return $this->setValue($key, $scope);
- }
-
- /*JWTBearerInterface */
- public function getClientKey($client_id, $subject)
- {
- if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
- return false;
- }
-
- if (isset($jwt['subject']) && $jwt['subject'] == $subject) {
- return $jwt['key'];
- }
-
- return null;
- }
-
- public function setClientKey($client_id, $key, $subject = null)
- {
- return $this->setValue($this->config['jwt_key'] . $client_id, array(
- 'key' => $key,
- 'subject' => $subject
- ));
- }
-
- public function getClientScope($client_id)
- {
- if (!$clientDetails = $this->getClientDetails($client_id)) {
- return false;
- }
-
- if (isset($clientDetails['scope'])) {
- return $clientDetails['scope'];
- }
-
- return null;
- }
-
- public function getJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs redis implementation.
- throw new \Exception('getJti() for the Redis driver is currently unimplemented.');
- }
-
- public function setJti($client_id, $subject, $audience, $expiration, $jti)
- {
- //TODO: Needs redis implementation.
- throw new \Exception('setJti() for the Redis driver is currently unimplemented.');
- }
-}
diff --git a/library/oauth2/src/OAuth2/Storage/RefreshTokenInterface.php b/library/oauth2/src/OAuth2/Storage/RefreshTokenInterface.php
deleted file mode 100644
index 0273f2125..000000000
--- a/library/oauth2/src/OAuth2/Storage/RefreshTokenInterface.php
+++ /dev/null
@@ -1,82 +0,0 @@
-
- */
-interface RefreshTokenInterface
-{
- /**
- * Grant refresh access tokens.
- *
- * Retrieve the stored data for the given refresh token.
- *
- * Required for OAuth2::GRANT_TYPE_REFRESH_TOKEN.
- *
- * @param $refresh_token
- * Refresh token to be check with.
- *
- * @return
- * An associative array as below, and NULL if the refresh_token is
- * invalid:
- * - refresh_token: Refresh token identifier.
- * - client_id: Client identifier.
- * - user_id: User identifier.
- * - expires: Expiration unix timestamp, or 0 if the token doesn't expire.
- * - scope: (optional) Scope values in space-separated string.
- *
- * @see http://tools.ietf.org/html/rfc6749#section-6
- *
- * @ingroup oauth2_section_6
- */
- public function getRefreshToken($refresh_token);
-
- /**
- * Take the provided refresh token values and store them somewhere.
- *
- * This function should be the storage counterpart to getRefreshToken().
- *
- * If storage fails for some reason, we're not currently checking for
- * any sort of success/failure, so you should bail out of the script
- * and provide a descriptive fail message.
- *
- * Required for OAuth2::GRANT_TYPE_REFRESH_TOKEN.
- *
- * @param $refresh_token
- * Refresh token to be stored.
- * @param $client_id
- * Client identifier to be stored.
- * @param $user_id
- * User identifier to be stored.
- * @param $expires
- * Expiration timestamp to be stored. 0 if the token doesn't expire.
- * @param $scope
- * (optional) Scopes to be stored in space-separated string.
- *
- * @ingroup oauth2_section_6
- */
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null);
-
- /**
- * Expire a used refresh token.
- *
- * This is not explicitly required in the spec, but is almost implied.
- * After granting a new refresh token, the old one is no longer useful and
- * so should be forcibly expired in the data store so it can't be used again.
- *
- * If storage fails for some reason, we're not currently checking for
- * any sort of success/failure, so you should bail out of the script
- * and provide a descriptive fail message.
- *
- * @param $refresh_token
- * Refresh token to be expirse.
- *
- * @ingroup oauth2_section_6
- */
- public function unsetRefreshToken($refresh_token);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/ScopeInterface.php b/library/oauth2/src/OAuth2/Storage/ScopeInterface.php
deleted file mode 100644
index a8292269b..000000000
--- a/library/oauth2/src/OAuth2/Storage/ScopeInterface.php
+++ /dev/null
@@ -1,46 +0,0 @@
-
- */
-interface ScopeInterface
-{
- /**
- * Check if the provided scope exists.
- *
- * @param $scope
- * A space-separated string of scopes.
- *
- * @return
- * TRUE if it exists, FALSE otherwise.
- */
- public function scopeExists($scope);
-
- /**
- * The default scope to use in the event the client
- * does not request one. By returning "false", a
- * request_error is returned by the server to force a
- * scope request by the client. By returning "null",
- * opt out of requiring scopes
- *
- * @param $client_id
- * An optional client id that can be used to return customized default scopes.
- *
- * @return
- * string representation of default scope, null if
- * scopes are not defined, or false to force scope
- * request by the client
- *
- * ex:
- * 'default'
- * ex:
- * null
- */
- public function getDefaultScope($client_id = null);
-}
diff --git a/library/oauth2/src/OAuth2/Storage/UserCredentialsInterface.php b/library/oauth2/src/OAuth2/Storage/UserCredentialsInterface.php
deleted file mode 100644
index 6e0fd7bad..000000000
--- a/library/oauth2/src/OAuth2/Storage/UserCredentialsInterface.php
+++ /dev/null
@@ -1,52 +0,0 @@
-
- */
-interface UserCredentialsInterface
-{
- /**
- * Grant access tokens for basic user credentials.
- *
- * Check the supplied username and password for validity.
- *
- * You can also use the $client_id param to do any checks required based
- * on a client, if you need that.
- *
- * Required for OAuth2::GRANT_TYPE_USER_CREDENTIALS.
- *
- * @param $username
- * Username to be check with.
- * @param $password
- * Password to be check with.
- *
- * @return
- * TRUE if the username and password are valid, and FALSE if it isn't.
- * Moreover, if the username and password are valid, and you want to
- *
- * @see http://tools.ietf.org/html/rfc6749#section-4.3
- *
- * @ingroup oauth2_section_4
- */
- public function checkUserCredentials($username, $password);
-
- /**
- * @return
- * ARRAY the associated "user_id" and optional "scope" values
- * This function MUST return FALSE if the requested user does not exist or is
- * invalid. "scope" is a space-separated list of restricted scopes.
- * @code
- * return array(
- * "user_id" => USER_ID, // REQUIRED user_id to be stored with the authorization code or access token
- * "scope" => SCOPE // OPTIONAL space-separated list of restricted scopes
- * );
- * @endcode
- */
- public function getUserDetails($username);
-}
diff --git a/library/oauth2/src/OAuth2/TokenType/Bearer.php b/library/oauth2/src/OAuth2/TokenType/Bearer.php
deleted file mode 100644
index 8ac8596ac..000000000
--- a/library/oauth2/src/OAuth2/TokenType/Bearer.php
+++ /dev/null
@@ -1,130 +0,0 @@
-config = array_merge(array(
- 'token_param_name' => 'access_token',
- 'token_bearer_header_name' => 'Bearer',
- ), $config);
- }
-
- public function getTokenType()
- {
- return 'Bearer';
- }
-
- /**
- * Check if the request has supplied token
- *
- * @see https://github.com/bshaffer/oauth2-server-php/issues/349#issuecomment-37993588
- */
- public function requestHasToken(RequestInterface $request)
- {
- $headers = $request->headers('AUTHORIZATION');
-
- // check the header, then the querystring, then the request body
- return !empty($headers) || (bool) ($request->request($this->config['token_param_name'])) || (bool) ($request->query($this->config['token_param_name']));
- }
-
- /**
- * This is a convenience function that can be used to get the token, which can then
- * be passed to getAccessTokenData(). The constraints specified by the draft are
- * attempted to be adheared to in this method.
- *
- * As per the Bearer spec (draft 8, section 2) - there are three ways for a client
- * to specify the bearer token, in order of preference: Authorization Header,
- * POST and GET.
- *
- * NB: Resource servers MUST accept tokens via the Authorization scheme
- * (http://tools.ietf.org/html/rfc6750#section-2).
- *
- * @todo Should we enforce TLS/SSL in this function?
- *
- * @see http://tools.ietf.org/html/rfc6750#section-2.1
- * @see http://tools.ietf.org/html/rfc6750#section-2.2
- * @see http://tools.ietf.org/html/rfc6750#section-2.3
- *
- * Old Android version bug (at least with version 2.2)
- * @see http://code.google.com/p/android/issues/detail?id=6684
- *
- */
- public function getAccessTokenParameter(RequestInterface $request, ResponseInterface $response)
- {
- $headers = $request->headers('AUTHORIZATION');
-
- /**
- * Ensure more than one method is not used for including an
- * access token
- *
- * @see http://tools.ietf.org/html/rfc6750#section-3.1
- */
- $methodsUsed = !empty($headers) + (bool) ($request->query($this->config['token_param_name'])) + (bool) ($request->request($this->config['token_param_name']));
- if ($methodsUsed > 1) {
- $response->setError(400, 'invalid_request', 'Only one method may be used to authenticate at a time (Auth header, GET or POST)');
-
- return null;
- }
-
- /**
- * If no authentication is provided, set the status code
- * to 401 and return no other error information
- *
- * @see http://tools.ietf.org/html/rfc6750#section-3.1
- */
- if ($methodsUsed == 0) {
- $response->setStatusCode(401);
-
- return null;
- }
-
- // HEADER: Get the access token from the header
- if (!empty($headers)) {
- if (!preg_match('/' . $this->config['token_bearer_header_name'] . '\s(\S+)/i', $headers, $matches)) {
- $response->setError(400, 'invalid_request', 'Malformed auth header');
-
- return null;
- }
-
- return $matches[1];
- }
-
- if ($request->request($this->config['token_param_name'])) {
- // // POST: Get the token from POST data
- if (!in_array(strtolower($request->server('REQUEST_METHOD')), array('post', 'put'))) {
- $response->setError(400, 'invalid_request', 'When putting the token in the body, the method must be POST or PUT', '#section-2.2');
-
- return null;
- }
-
- $contentType = $request->server('CONTENT_TYPE');
- if (false !== $pos = strpos($contentType, ';')) {
- $contentType = substr($contentType, 0, $pos);
- }
-
- if ($contentType !== null && $contentType != 'application/x-www-form-urlencoded') {
- // IETF specifies content-type. NB: Not all webservers populate this _SERVER variable
- // @see http://tools.ietf.org/html/rfc6750#section-2.2
- $response->setError(400, 'invalid_request', 'The content type for POST requests must be "application/x-www-form-urlencoded"');
-
- return null;
- }
-
- return $request->request($this->config['token_param_name']);
- }
-
- // GET method
- return $request->query($this->config['token_param_name']);
- }
-}
diff --git a/library/oauth2/src/OAuth2/TokenType/Mac.php b/library/oauth2/src/OAuth2/TokenType/Mac.php
deleted file mode 100644
index fe6a86aa6..000000000
--- a/library/oauth2/src/OAuth2/TokenType/Mac.php
+++ /dev/null
@@ -1,22 +0,0 @@
-assertTrue(class_exists('OAuth2\Server'));
- $this->assertTrue(class_exists('OAuth2\Request'));
- $this->assertTrue(class_exists('OAuth2\Response'));
- $this->assertTrue(class_exists('OAuth2\GrantType\UserCredentials'));
- $this->assertTrue(interface_exists('OAuth2\Storage\AccessTokenInterface'));
- }
-}
diff --git a/library/oauth2/test/OAuth2/Controller/AuthorizeControllerTest.php b/library/oauth2/test/OAuth2/Controller/AuthorizeControllerTest.php
deleted file mode 100644
index 3bfc760e4..000000000
--- a/library/oauth2/test/OAuth2/Controller/AuthorizeControllerTest.php
+++ /dev/null
@@ -1,492 +0,0 @@
-getTestServer();
- $request = new Request();
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'No client id supplied');
- }
-
- public function testInvalidClientIdResponse()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Fake Client ID', // invalid client id
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'The client id supplied is invalid');
- }
-
- public function testNoRedirectUriSuppliedOrStoredResponse()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_uri');
- $this->assertEquals($response->getParameter('error_description'), 'No redirect URI was supplied or stored');
- }
-
- public function testNoResponseTypeResponse()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'invalid_request');
- $this->assertEquals($query['error_description'], 'Invalid or missing response type');
- }
-
- public function testInvalidResponseTypeResponse()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'invalid', // invalid response type
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'invalid_request');
- $this->assertEquals($query['error_description'], 'Invalid or missing response type');
- }
-
- public function testRedirectUriFragmentResponse()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com#fragment', // valid redirect URI
- 'response_type' => 'code', // invalid response type
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_uri');
- $this->assertEquals($response->getParameter('error_description'), 'The redirect URI must not contain a fragment');
- }
-
- public function testEnforceState()
- {
- $server = $this->getTestServer(array('enforce_state' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'invalid_request');
- $this->assertEquals($query['error_description'], 'The state parameter is required');
- }
-
- public function testDoNotEnforceState()
- {
- $server = $this->getTestServer(array('enforce_state' => false));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertNotContains('error', $response->getHttpHeader('Location'));
- }
-
- public function testEnforceScope()
- {
- $server = $this->getTestServer();
- $scopeStorage = new Memory(array('default_scope' => false, 'supported_scopes' => array('testscope')));
- $server->setScopeUtil(new Scope($scopeStorage));
-
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- 'state' => 'xyz',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'invalid_client');
- $this->assertEquals($query['error_description'], 'This application requires you specify a scope parameter');
-
- $request->query['scope'] = 'testscope';
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertNotContains('error', $response->getHttpHeader('Location'));
- }
-
- public function testInvalidRedirectUri()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
- 'redirect_uri' => 'http://adobe.com', // invalid redirect URI
- 'response_type' => 'code',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
- $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
- }
-
- public function testInvalidRedirectUriApprovedByBuggyRegisteredUri()
- {
- $server = $this->getTestServer();
- $server->setConfig('require_exact_redirect_uri', false);
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Buggy Redirect Uri', // valid client id
- 'redirect_uri' => 'http://adobe.com', // invalid redirect URI
- 'response_type' => 'code',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
- $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
- }
-
- public function testNoRedirectUriWithMultipleRedirectUris()
- {
- $server = $this->getTestServer();
-
- // create a request with no "redirect_uri" in querystring
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
- 'response_type' => 'code',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_uri');
- $this->assertEquals($response->getParameter('error_description'), 'A redirect URI must be supplied when multiple redirect URIs are registered');
- }
-
- public function testRedirectUriWithValidRedirectUri()
- {
- $server = $this->getTestServer();
-
- // create a request with no "redirect_uri" in querystring
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
- 'response_type' => 'code',
- 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true',
- 'state' => 'xyz',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertContains('code', $response->getHttpHeader('Location'));
- }
-
- public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
- {
- $server = $this->getTestServer(array('require_exact_redirect_uri' => true));
-
- // create a request with no "redirect_uri" in querystring
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
- 'response_type' => 'code',
- 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
- $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
- }
-
- public function testRedirectUriWithDifferentQueryAndExactMatchNotRequired()
- {
- $server = $this->getTestServer(array('require_exact_redirect_uri' => false));
-
- // create a request with no "redirect_uri" in querystring
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
- 'response_type' => 'code',
- 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
- 'state' => 'xyz',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertContains('code', $response->getHttpHeader('Location'));
- }
-
- public function testMultipleRedirectUris()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
- 'redirect_uri' => 'http://brentertainment.com', // valid redirect URI
- 'response_type' => 'code',
- 'state' => 'xyz'
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertContains('code', $response->getHttpHeader('Location'));
-
- // call again with different (but still valid) redirect URI
- $request->query['redirect_uri'] = 'http://morehazards.com';
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertContains('code', $response->getHttpHeader('Location'));
- }
-
- /**
- * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
- * @see https://github.com/bshaffer/oauth2-server-php/issues/163
- */
- public function testNoRedirectUriSuppliedDoesNotRequireTokenRedirectUri()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
- 'response_type' => 'code',
- 'state' => 'xyz',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertContains('state', $response->getHttpHeader('Location'));
- $this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
-
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['query'], $query);
-
- // call token endpoint with no redirect_uri supplied
- $request = TestRequest::createPost(array(
- 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
- 'client_secret' => 'TestSecret2',
- 'grant_type' => 'authorization_code',
- 'code' => $query['code'],
- ));
-
- $server->handleTokenRequest($request, $response = new Response(), true);
- $this->assertEquals($response->getStatusCode(), 200);
- $this->assertNotNull($response->getParameter('access_token'));
- }
-
- public function testUserDeniesAccessResponse()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- 'state' => 'xyz',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'access_denied');
- $this->assertEquals($query['error_description'], 'The user denied access to your application');
- }
-
- public function testCodeQueryParamIsSet()
- {
- $server = $this->getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- 'state' => 'xyz',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
-
- $this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
- $this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
- $this->assertArrayHasKey('query', $parts);
- $this->assertFalse(isset($parts['fragment']));
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['query'], $query);
- $this->assertNotNull($query);
- $this->assertArrayHasKey('code', $query);
-
- // ensure no id_token was saved, since the openid scope wasn't requested
- $storage = $server->getStorage('authorization_code');
- $code = $storage->getAuthorizationCode($query['code']);
- $this->assertTrue(empty($code['id_token']));
-
- // ensure no error was returned
- $this->assertFalse(isset($query['error']));
- $this->assertFalse(isset($query['error_description']));
- }
-
- public function testSuccessfulRequestReturnsStateParameter()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- 'state' => 'test', // valid state string (just needs to be passed back to us)
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
-
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- $this->assertArrayHasKey('query', $parts);
- parse_str($parts['query'], $query);
-
- $this->assertArrayHasKey('state', $query);
- $this->assertEquals($query['state'], 'test');
-
- // ensure no error was returned
- $this->assertFalse(isset($query['error']));
- $this->assertFalse(isset($query['error_description']));
- }
-
- public function testSuccessfulRequestStripsExtraParameters()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'code',
- 'state' => 'test', // valid state string (just needs to be passed back to us)
- 'fake' => 'something', // extra query param
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertFalse(isset($parts['fake']));
- $this->assertArrayHasKey('query', $parts);
- parse_str($parts['query'], $query);
-
- $this->assertFalse(isset($parmas['fake']));
- $this->assertArrayHasKey('state', $query);
- $this->assertEquals($query['state'], 'test');
- }
-
- public function testSuccessfulOpenidConnectRequest()
- {
- $server = $this->getTestServer(array(
- 'use_openid_connect' => true,
- 'issuer' => 'bojanz',
- ));
-
- $request = new Request(array(
- 'client_id' => 'Test Client ID',
- 'redirect_uri' => 'http://adobe.com',
- 'response_type' => 'code',
- 'state' => 'xyz',
- 'scope' => 'openid',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- $this->assertArrayHasKey('query', $parts);
- $this->assertFalse(isset($parts['fragment']));
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['query'], $query);
- $this->assertNotNull($query);
- $this->assertArrayHasKey('code', $query);
-
- // ensure no error was returned
- $this->assertFalse(isset($query['error']));
- $this->assertFalse(isset($query['error_description']));
-
- // confirm that the id_token has been created.
- $storage = $server->getStorage('authorization_code');
- $code = $storage->getAuthorizationCode($query['code']);
- $this->assertTrue(!empty($code['id_token']));
- }
-
- public function testCreateController()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $controller = new AuthorizeController($storage);
- }
-
- private function getTestServer($config = array())
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, $config);
-
- // Add the two types supported for authorization grant
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/Controller/ResourceControllerTest.php b/library/oauth2/test/OAuth2/Controller/ResourceControllerTest.php
deleted file mode 100644
index ee6d96ff8..000000000
--- a/library/oauth2/test/OAuth2/Controller/ResourceControllerTest.php
+++ /dev/null
@@ -1,175 +0,0 @@
-getTestServer();
- $request = Request::createFromGlobals();
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 401);
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
- }
-
- public function testMalformedHeader()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'tH1s i5 B0gU5';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Malformed auth header');
- }
-
- public function testMultipleTokensSubmitted()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->request['access_token'] = 'TEST';
- $request->query['access_token'] = 'TEST';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Only one method may be used to authenticate at a time (Auth header, GET or POST)');
- }
-
- public function testInvalidRequestMethod()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->server['REQUEST_METHOD'] = 'GET';
- $request->request['access_token'] = 'TEST';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'When putting the token in the body, the method must be POST or PUT');
- }
-
- public function testInvalidContentType()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->server['REQUEST_METHOD'] = 'POST';
- $request->server['CONTENT_TYPE'] = 'application/json';
- $request->request['access_token'] = 'TEST';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
- }
-
- public function testInvalidToken()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer TESTTOKEN';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'invalid_token');
- $this->assertEquals($response->getParameter('error_description'), 'The access token provided is invalid');
- }
-
- public function testExpiredToken()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-expired';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'expired_token');
- $this->assertEquals($response->getParameter('error_description'), 'The access token provided has expired');
- }
-
- public function testOutOfScopeToken()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
- $scope = 'outofscope';
- $allow = $server->verifyResourceRequest($request, $response = new Response(), $scope);
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 403);
- $this->assertEquals($response->getParameter('error'), 'insufficient_scope');
- $this->assertEquals($response->getParameter('error_description'), 'The request requires higher privileges than provided by the access token');
-
- // verify the "scope" has been set in the "WWW-Authenticate" header
- preg_match('/scope="(.*?)"/', $response->getHttpHeader('WWW-Authenticate'), $matches);
- $this->assertEquals(2, count($matches));
- $this->assertEquals($matches[1], 'outofscope');
- }
-
- public function testMalformedToken()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-malformed';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertFalse($allow);
-
- $this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'malformed_token');
- $this->assertEquals($response->getParameter('error_description'), 'Malformed token (missing "expires")');
- }
-
- public function testValidToken()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertTrue($allow);
- }
-
- public function testValidTokenWithScopeParam()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
- $request->query['scope'] = 'testscope';
- $allow = $server->verifyResourceRequest($request, $response = new Response());
- $this->assertTrue($allow);
- }
-
- public function testCreateController()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $tokenType = new \OAuth2\TokenType\Bearer();
- $controller = new ResourceController($tokenType, $storage);
- }
-
- private function getTestServer($config = array())
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, $config);
-
- // Add the two types supported for authorization grant
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/Controller/TokenControllerTest.php b/library/oauth2/test/OAuth2/Controller/TokenControllerTest.php
deleted file mode 100644
index 4a217bd55..000000000
--- a/library/oauth2/test/OAuth2/Controller/TokenControllerTest.php
+++ /dev/null
@@ -1,289 +0,0 @@
-getTestServer();
- $server->handleTokenRequest(TestRequest::createPost(), $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'The grant type was not specified in the request');
- }
-
- public function testInvalidGrantType()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'invalid_grant_type', // invalid grant type
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'unsupported_grant_type');
- $this->assertEquals($response->getParameter('error_description'), 'Grant type "invalid_grant_type" not supported');
- }
-
- public function testNoClientId()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode',
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'Client credentials were not found in the headers or body');
- }
-
- public function testNoClientSecretWithConfidentialClient()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode',
- 'client_id' => 'Test Client ID', // valid client id
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'This client is invalid or must authenticate using a client secret');
- }
-
- public function testNoClientSecretWithEmptySecret()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode-empty-secret',
- 'client_id' => 'Test Client ID Empty Secret', // valid client id
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 200);
- }
-
- public function testInvalidClientId()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode',
- 'client_id' => 'Fake Client ID', // invalid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
- }
-
- public function testInvalidClientSecret()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode',
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'Fake Client Secret', // invalid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
- }
-
- public function testValidTokenResponse()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode', // valid authorization code
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertTrue($response instanceof Response);
- $this->assertEquals($response->getStatusCode(), 200);
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
- $this->assertNotNull($response->getParameter('access_token'));
- $this->assertNotNull($response->getParameter('expires_in'));
- $this->assertNotNull($response->getParameter('token_type'));
- }
-
- public function testValidClientIdScope()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode',
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'scope' => 'clientscope1 clientscope2'
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 200);
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
- $this->assertEquals('clientscope1 clientscope2', $response->getParameter('scope'));
- }
-
- public function testInvalidClientIdScope()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'code' => 'testcode-with-scope',
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'scope' => 'clientscope3'
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
- }
-
- public function testEnforceScope()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new ClientCredentials($storage));
-
- $scope = new Scope(array(
- 'default_scope' => false,
- 'supported_scopes' => array('testscope')
- ));
- $server->setScopeUtil($scope);
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $response = $server->handleTokenRequest($request);
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'This application requires you specify a scope parameter');
- }
-
- public function testCanReceiveAccessTokenUsingPasswordGrantTypeWithoutClientSecret()
- {
- // add the test parameters in memory
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new UserCredentials($storage));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID For Password Grant', // valid client id
- 'username' => 'johndoe', // valid username
- 'password' => 'password', // valid password for username
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertTrue($response instanceof Response);
- $this->assertEquals(200, $response->getStatusCode(), var_export($response, 1));
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
- $this->assertNotNull($response->getParameter('access_token'));
- $this->assertNotNull($response->getParameter('expires_in'));
- $this->assertNotNull($response->getParameter('token_type'));
- }
-
- public function testInvalidTokenTypeHintForRevoke()
- {
- $server = $this->getTestServer();
-
- $request = TestRequest::createPost(array(
- 'token_type_hint' => 'foo',
- 'token' => 'sometoken'
- ));
-
- $server->handleRevokeRequest($request, $response = new Response());
-
- $this->assertTrue($response instanceof Response);
- $this->assertEquals(400, $response->getStatusCode(), var_export($response, 1));
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Token type hint must be either \'access_token\' or \'refresh_token\'');
- }
-
- public function testMissingTokenForRevoke()
- {
- $server = $this->getTestServer();
-
- $request = TestRequest::createPost(array(
- 'token_type_hint' => 'access_token'
- ));
-
- $server->handleRevokeRequest($request, $response = new Response());
- $this->assertTrue($response instanceof Response);
- $this->assertEquals(400, $response->getStatusCode(), var_export($response, 1));
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Missing token parameter to revoke');
- }
-
- public function testInvalidRequestMethodForRevoke()
- {
- $server = $this->getTestServer();
-
- $request = new TestRequest();
- $request->setQuery(array(
- 'token_type_hint' => 'access_token'
- ));
-
- $server->handleRevokeRequest($request, $response = new Response());
- $this->assertTrue($response instanceof Response);
- $this->assertEquals(405, $response->getStatusCode(), var_export($response, 1));
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'The request method must be POST when revoking an access token');
- }
-
- public function testCreateController()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $accessToken = new \OAuth2\ResponseType\AccessToken($storage);
- $controller = new TokenController($accessToken, $storage);
- }
-
- private function getTestServer()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/Encryption/FirebaseJwtTest.php b/library/oauth2/test/OAuth2/Encryption/FirebaseJwtTest.php
deleted file mode 100644
index d34136767..000000000
--- a/library/oauth2/test/OAuth2/Encryption/FirebaseJwtTest.php
+++ /dev/null
@@ -1,102 +0,0 @@
-privateKey = << $client_id,
- 'exp' => time() + 1000,
- 'iat' => time(),
- 'sub' => 'testuser@ourdomain.com',
- 'aud' => 'http://myapp.com/oauth/auth',
- 'scope' => null,
- );
-
- $encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256');
-
- // test BC behaviour of trusting the algorithm in the header
- $payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
- $this->assertEquals($params, $payload);
-
- // test BC behaviour of not verifying by passing false
- $payload = $jwtUtil->decode($encoded, $client_key, false);
- $this->assertEquals($params, $payload);
-
- // test the new restricted algorithms header
- $payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
- $this->assertEquals($params, $payload);
- }
-
- public function testInvalidJwt()
- {
- $jwtUtil = new FirebaseJwt();
-
- $this->assertFalse($jwtUtil->decode('goob'));
- $this->assertFalse($jwtUtil->decode('go.o.b'));
- }
-
- /** @dataProvider provideClientCredentials */
- public function testInvalidJwtHeader($client_id, $client_key)
- {
- $jwtUtil = new FirebaseJwt();
-
- $params = array(
- 'iss' => $client_id,
- 'exp' => time() + 1000,
- 'iat' => time(),
- 'sub' => 'testuser@ourdomain.com',
- 'aud' => 'http://myapp.com/oauth/auth',
- 'scope' => null,
- );
-
- // testing for algorithm tampering when only RSA256 signing is allowed
- // @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
- $tampered = $jwtUtil->encode($params, $client_key, 'HS256');
-
- $payload = $jwtUtil->decode($tampered, $client_key, array('RS256'));
-
- $this->assertFalse($payload);
- }
-
- public function provideClientCredentials()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $client_id = 'Test Client ID';
- $client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com");
-
- return array(
- array($client_id, $client_key),
- );
- }
-}
diff --git a/library/oauth2/test/OAuth2/Encryption/JwtTest.php b/library/oauth2/test/OAuth2/Encryption/JwtTest.php
deleted file mode 100644
index 214eebac8..000000000
--- a/library/oauth2/test/OAuth2/Encryption/JwtTest.php
+++ /dev/null
@@ -1,102 +0,0 @@
-privateKey = << $client_id,
- 'exp' => time() + 1000,
- 'iat' => time(),
- 'sub' => 'testuser@ourdomain.com',
- 'aud' => 'http://myapp.com/oauth/auth',
- 'scope' => null,
- );
-
- $encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256');
-
- // test BC behaviour of trusting the algorithm in the header
- $payload = $jwtUtil->decode($encoded, $client_key);
- $this->assertEquals($params, $payload);
-
- // test BC behaviour of not verifying by passing false
- $payload = $jwtUtil->decode($encoded, $client_key, false);
- $this->assertEquals($params, $payload);
-
- // test the new restricted algorithms header
- $payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
- $this->assertEquals($params, $payload);
- }
-
- public function testInvalidJwt()
- {
- $jwtUtil = new Jwt();
-
- $this->assertFalse($jwtUtil->decode('goob'));
- $this->assertFalse($jwtUtil->decode('go.o.b'));
- }
-
- /** @dataProvider provideClientCredentials */
- public function testInvalidJwtHeader($client_id, $client_key)
- {
- $jwtUtil = new Jwt();
-
- $params = array(
- 'iss' => $client_id,
- 'exp' => time() + 1000,
- 'iat' => time(),
- 'sub' => 'testuser@ourdomain.com',
- 'aud' => 'http://myapp.com/oauth/auth',
- 'scope' => null,
- );
-
- // testing for algorithm tampering when only RSA256 signing is allowed
- // @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
- $tampered = $jwtUtil->encode($params, $client_key, 'HS256');
-
- $payload = $jwtUtil->decode($tampered, $client_key, array('RS256'));
-
- $this->assertFalse($payload);
- }
-
- public function provideClientCredentials()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $client_id = 'Test Client ID';
- $client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com");
-
- return array(
- array($client_id, $client_key),
- );
- }
-}
diff --git a/library/oauth2/test/OAuth2/GrantType/AuthorizationCodeTest.php b/library/oauth2/test/OAuth2/GrantType/AuthorizationCodeTest.php
deleted file mode 100644
index 740989635..000000000
--- a/library/oauth2/test/OAuth2/GrantType/AuthorizationCodeTest.php
+++ /dev/null
@@ -1,207 +0,0 @@
-getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Missing parameter: "code" is required');
- }
-
- public function testInvalidCode()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'InvalidCode', // invalid authorization code
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
- }
-
- public function testCodeCannotBeUsedTwice()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode', // valid code
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 200);
- $this->assertNotNull($response->getParameter('access_token'));
-
- // try to use the same code again
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
- }
-
- public function testExpiredCode()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-expired', // expired authorization code
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'The authorization code has expired');
- }
-
- public function testValidCode()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode', // valid code
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- }
-
- public function testValidCodeNoScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-with-scope', // valid code
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope1 scope2');
- }
-
- public function testValidCodeSameScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-with-scope', // valid code
- 'scope' => 'scope2 scope1',
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope2 scope1');
- }
-
- public function testValidCodeLessScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-with-scope', // valid code
- 'scope' => 'scope1',
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope1');
- }
-
- public function testValidCodeDifferentScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-with-scope', // valid code
- 'scope' => 'scope3',
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
- }
-
- public function testValidCodeInvalidScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-with-scope', // valid code
- 'scope' => 'invalid-scope',
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
- }
-
- public function testValidClientDifferentCode()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Some Other Client', // valid client id
- 'client_secret' => 'TestSecret3', // valid client secret
- 'code' => 'testcode', // valid code
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'authorization_code doesn\'t exist or is invalid for the client');
- }
-
- private function getTestServer()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/GrantType/ClientCredentialsTest.php b/library/oauth2/test/OAuth2/GrantType/ClientCredentialsTest.php
deleted file mode 100644
index f0d46ccb3..000000000
--- a/library/oauth2/test/OAuth2/GrantType/ClientCredentialsTest.php
+++ /dev/null
@@ -1,159 +0,0 @@
-getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'FakeSecret', // valid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
- }
-
- public function testValidCredentials()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertNull($token['scope']);
- }
-
- public function testValidCredentialsWithScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'scope' => 'scope1',
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope1');
- }
-
- public function testValidCredentialsInvalidScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'scope' => 'invalid-scope',
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
- }
-
- public function testValidCredentialsInHeader()
- {
- // create with HTTP_AUTHORIZATION in header
- $server = $this->getTestServer();
- $headers = array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('Test Client ID:TestSecret'), 'REQUEST_METHOD' => 'POST');
- $params = array('grant_type' => 'client_credentials');
- $request = new Request(array(), $params, array(), array(), array(), $headers);
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertNotNull($token['access_token']);
-
- // create using PHP Authorization Globals
- $headers = array('PHP_AUTH_USER' => 'Test Client ID', 'PHP_AUTH_PW' => 'TestSecret', 'REQUEST_METHOD' => 'POST');
- $params = array('grant_type' => 'client_credentials');
- $request = new Request(array(), $params, array(), array(), array(), $headers);
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertNotNull($token['access_token']);
- }
-
- public function testValidCredentialsInRequest()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertNotNull($token['access_token']);
- }
-
- public function testValidCredentialsInQuerystring()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertNotNull($token['access_token']);
- }
-
- public function testClientUserIdIsSetInAccessToken()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Client ID With User ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
-
- // verify the user_id was associated with the token
- $storage = $server->getStorage('client');
- $token = $storage->getAccessToken($token['access_token']);
- $this->assertNotNull($token);
- $this->assertArrayHasKey('user_id', $token);
- $this->assertEquals($token['user_id'], 'brent@brentertainment.com');
- }
-
- private function getTestServer()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new ClientCredentials($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/GrantType/ImplicitTest.php b/library/oauth2/test/OAuth2/GrantType/ImplicitTest.php
deleted file mode 100644
index a47aae3e8..000000000
--- a/library/oauth2/test/OAuth2/GrantType/ImplicitTest.php
+++ /dev/null
@@ -1,143 +0,0 @@
-getTestServer();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'token', // invalid response type
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'unsupported_response_type');
- $this->assertEquals($query['error_description'], 'implicit grant type not supported');
- }
-
- public function testUserDeniesAccessResponse()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'token', // valid response type
- 'state' => 'xyz',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), false);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- parse_str($parts['query'], $query);
-
- $this->assertEquals($query['error'], 'access_denied');
- $this->assertEquals($query['error_description'], 'The user denied access to your application');
- }
-
- public function testSuccessfulRequestFragmentParameter()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'token', // valid response type
- 'state' => 'xyz',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
-
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
-
- $this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
- $this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
- $this->assertArrayHasKey('fragment', $parts);
- $this->assertFalse(isset($parts['query']));
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['fragment'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('access_token', $params);
- $this->assertArrayHasKey('expires_in', $params);
- $this->assertArrayHasKey('token_type', $params);
- }
-
- public function testSuccessfulRequestReturnsStateParameter()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'token', // valid response type
- 'state' => 'test', // valid state string (just needs to be passed back to us)
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
-
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- $this->assertArrayHasKey('fragment', $parts);
- parse_str($parts['fragment'], $params);
-
- $this->assertArrayHasKey('state', $params);
- $this->assertEquals($params['state'], 'test');
- }
-
- public function testSuccessfulRequestStripsExtraParameters()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com?fake=something', // valid redirect URI
- 'response_type' => 'token', // valid response type
- 'state' => 'test', // valid state string (just needs to be passed back to us)
- 'fake' => 'something', // add extra param to querystring
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $this->assertNull($response->getParameter('error'));
- $this->assertNull($response->getParameter('error_description'));
-
- $location = $response->getHttpHeader('Location');
- $parts = parse_url($location);
- $this->assertFalse(isset($parts['fake']));
- $this->assertArrayHasKey('fragment', $parts);
- parse_str($parts['fragment'], $params);
-
- $this->assertFalse(isset($params['fake']));
- $this->assertArrayHasKey('state', $params);
- $this->assertEquals($params['state'], 'test');
- }
-
- private function getTestServer($config = array())
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, $config);
-
- // Add the two types supported for authorization grant
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/GrantType/JwtBearerTest.php b/library/oauth2/test/OAuth2/GrantType/JwtBearerTest.php
deleted file mode 100644
index 0a6c4b827..000000000
--- a/library/oauth2/test/OAuth2/GrantType/JwtBearerTest.php
+++ /dev/null
@@ -1,360 +0,0 @@
-privateKey = <<getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Get the jwt and break it
- $jwt = $this->getJWT();
- $jwt = substr_replace($jwt, 'broken', 3, 6);
-
- $request->request['assertion'] = $jwt;
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'JWT is malformed');
- }
-
- public function testBrokenSignature()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Get the jwt and break signature
- $jwt = $this->getJWT() . 'notSupposeToBeHere';
- $request->request['assertion'] = $jwt;
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'JWT failed signature verification');
- }
-
- public function testExpiredJWT()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Get an expired JWT
- $jwt = $this->getJWT(1234);
- $request->request['assertion'] = $jwt;
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'JWT has expired');
- }
-
- public function testBadExp()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Get an expired JWT
- $jwt = $this->getJWT('badtimestamp');
- $request->request['assertion'] = $jwt;
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Expiration (exp) time must be a unix time stamp');
- }
-
- public function testNoAssert()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Do not pass the assert (JWT)
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "assertion" required');
- }
-
- public function testNotBefore()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Get a future NBF
- $jwt = $this->getJWT(null, time() + 10000);
- $request->request['assertion'] = $jwt;
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'JWT cannot be used before the Not Before (nbf) time');
- }
-
- public function testBadNotBefore()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- ));
-
- //Get a non timestamp nbf
- $jwt = $this->getJWT(null, 'notatimestamp');
- $request->request['assertion'] = $jwt;
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Not Before (nbf) time must be a unix time stamp');
- }
-
- public function testNonMatchingAudience()
- {
- $server = $this->getTestServer('http://google.com/oauth/o/auth');
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(),
- ));
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid audience (aud)');
- }
-
- public function testBadClientID()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(null, null, null, 'bad_client_id'),
- ));
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
- }
-
- public function testBadSubject()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(null, null, 'anotheruser@ourdomain,com'),
- ));
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
- }
-
- public function testMissingKey()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(null, null, null, 'Missing Key Cli,nt'),
- ));
-
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
- }
-
- public function testValidJwt()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(), // valid assertion
- ));
-
- $token = $server->grantAccessToken($request, new Response());
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- }
-
- public function testValidJwtWithScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(null, null, null, 'Test Client ID'), // valid assertion
- 'scope' => 'scope1', // valid scope
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope1');
- }
-
- public function testValidJwtInvalidScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(null, null, null, 'Test Client ID'), // valid assertion
- 'scope' => 'invalid-scope', // invalid scope
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
- }
-
- public function testValidJti()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(null, null, 'testuser@ourdomain.com', 'Test Client ID', 'unused_jti'), // valid assertion with invalid scope
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- }
-
- public function testInvalidJti()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(99999999900, null, 'testuser@ourdomain.com', 'Test Client ID', 'used_jti'), // valid assertion with invalid scope
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'JSON Token Identifier (jti) has already been used');
- }
-
- public function testJtiReplayAttack()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
- 'assertion' => $this->getJWT(99999999900, null, 'testuser@ourdomain.com', 'Test Client ID', 'totally_new_jti'), // valid assertion with invalid scope
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
-
- //Replay the same request
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'JSON Token Identifier (jti) has already been used');
- }
-
- /**
- * Generates a JWT
- * @param $exp The expiration date. If the current time is greater than the exp, the JWT is invalid.
- * @param $nbf The "not before" time. If the current time is less than the nbf, the JWT is invalid.
- * @param $sub The subject we are acting on behalf of. This could be the email address of the user in the system.
- * @param $iss The issuer, usually the client_id.
- * @return string
- */
- private function getJWT($exp = null, $nbf = null, $sub = null, $iss = 'Test Client ID', $jti = null)
- {
- if (!$exp) {
- $exp = time() + 1000;
- }
-
- if (!$sub) {
- $sub = "testuser@ourdomain.com";
- }
-
- $params = array(
- 'iss' => $iss,
- 'exp' => $exp,
- 'iat' => time(),
- 'sub' => $sub,
- 'aud' => 'http://myapp.com/oauth/auth',
- );
-
- if ($nbf) {
- $params['nbf'] = $nbf;
- }
-
- if ($jti) {
- $params['jti'] = $jti;
- }
-
- $jwtUtil = new Jwt();
-
- return $jwtUtil->encode($params, $this->privateKey, 'RS256');
- }
-
- private function getTestServer($audience = 'http://myapp.com/oauth/auth')
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new JwtBearer($storage, $audience, new Jwt()));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/GrantType/RefreshTokenTest.php b/library/oauth2/test/OAuth2/GrantType/RefreshTokenTest.php
deleted file mode 100644
index a458aad8a..000000000
--- a/library/oauth2/test/OAuth2/GrantType/RefreshTokenTest.php
+++ /dev/null
@@ -1,204 +0,0 @@
-getTestServer();
- $server->addGrantType(new RefreshToken($this->storage));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Missing parameter: "refresh_token" is required');
- }
-
- public function testInvalidRefreshToken()
- {
- $server = $this->getTestServer();
- $server->addGrantType(new RefreshToken($this->storage));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'fake-token', // invalid refresh token
- ));
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid refresh token');
- }
-
- public function testValidRefreshTokenWithNewRefreshTokenInResponse()
- {
- $server = $this->getTestServer();
- $server->addGrantType(new RefreshToken($this->storage, array('always_issue_new_refresh_token' => true)));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken', // valid refresh token
- ));
- $token = $server->grantAccessToken($request, new Response());
- $this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
-
- $refresh_token = $this->storage->getRefreshToken($token['refresh_token']);
- $this->assertNotNull($refresh_token);
- $this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
- $this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
- $this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
- $used_token = $this->storage->getRefreshToken('test-refreshtoken');
- $this->assertFalse($used_token, 'the refresh token used is no longer valid');
- }
-
- public function testValidRefreshTokenDoesNotUnsetToken()
- {
- $server = $this->getTestServer();
- $server->addGrantType(new RefreshToken($this->storage, array(
- 'always_issue_new_refresh_token' => true,
- 'unset_refresh_token_after_use' => false,
- )));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken', // valid refresh token
- ));
- $token = $server->grantAccessToken($request, new Response());
- $this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
-
- $used_token = $this->storage->getRefreshToken('test-refreshtoken');
- $this->assertNotNull($used_token, 'the refresh token used is still valid');
- }
-
- public function testValidRefreshTokenWithNoRefreshTokenInResponse()
- {
- $server = $this->getTestServer();
- $server->addGrantType(new RefreshToken($this->storage, array('always_issue_new_refresh_token' => false)));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken', // valid refresh token
- ));
- $token = $server->grantAccessToken($request, new Response());
- $this->assertFalse(isset($token['refresh_token']), 'refresh token should not be returned');
-
- $used_token = $this->storage->getRefreshToken('test-refreshtoken');
- $this->assertNotNull($used_token, 'the refresh token used is still valid');
- }
-
- public function testValidRefreshTokenSameScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
- 'scope' => 'scope2 scope1',
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope2 scope1');
- }
-
- public function testValidRefreshTokenLessScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
- 'scope' => 'scope1',
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope1');
- }
-
- public function testValidRefreshTokenDifferentScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
- 'scope' => 'scope3',
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
- }
-
- public function testValidRefreshTokenInvalidScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
- 'scope' => 'invalid-scope',
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
- }
-
- public function testValidClientDifferentRefreshToken()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Some Other Client', // valid client id
- 'client_secret' => 'TestSecret3', // valid client secret
- 'refresh_token' => 'test-refreshtoken', // valid refresh token
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'refresh_token doesn\'t exist or is invalid for the client');
- }
-
- private function getTestServer()
- {
- $this->storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($this->storage);
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/GrantType/UserCredentialsTest.php b/library/oauth2/test/OAuth2/GrantType/UserCredentialsTest.php
deleted file mode 100644
index 18943d055..000000000
--- a/library/oauth2/test/OAuth2/GrantType/UserCredentialsTest.php
+++ /dev/null
@@ -1,172 +0,0 @@
-getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'password' => 'testpass', // valid password
- ));
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "username" and "password" required');
- }
-
- public function testNoPassword()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'test-username', // valid username
- ));
- $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "username" and "password" required');
- }
-
- public function testInvalidUsername()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'fake-username', // valid username
- 'password' => 'testpass', // valid password
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid username and password combination');
- }
-
- public function testInvalidPassword()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'test-username', // valid username
- 'password' => 'fakepass', // invalid password
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 401);
- $this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid username and password combination');
- }
-
- public function testValidCredentials()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'test-username', // valid username
- 'password' => 'testpass', // valid password
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- }
-
- public function testValidCredentialsWithScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'test-username', // valid username
- 'password' => 'testpass', // valid password
- 'scope' => 'scope1', // valid scope
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('scope', $token);
- $this->assertEquals($token['scope'], 'scope1');
- }
-
- public function testValidCredentialsInvalidScope()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'test-username', // valid username
- 'password' => 'testpass', // valid password
- 'scope' => 'invalid-scope',
- ));
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_scope');
- $this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
- }
-
- public function testNoSecretWithPublicClient()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID Empty Secret', // valid public client
- 'username' => 'test-username', // valid username
- 'password' => 'testpass', // valid password
- ));
-
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- }
-
- public function testNoSecretWithConfidentialClient()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid public client
- 'username' => 'test-username', // valid username
- 'password' => 'testpass', // valid password
- ));
-
- $token = $server->grantAccessToken($request, $response = new Response());
-
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_client');
- $this->assertEquals($response->getParameter('error_description'), 'This client is invalid or must authenticate using a client secret');
- }
-
- private function getTestServer()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage);
- $server->addGrantType(new UserCredentials($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php b/library/oauth2/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
deleted file mode 100644
index 46de936d8..000000000
--- a/library/oauth2/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
+++ /dev/null
@@ -1,182 +0,0 @@
-getTestServer();
-
- $response = new Response();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'id_token',
- 'state' => 'af0ifjsldkj',
- 'nonce' => 'n-0S6_WzA2Mj',
- ));
-
- // Test valid id_token request
- $server->handleAuthorizeRequest($request, $response, true);
-
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['fragment'], $query);
-
- $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
- $this->assertEquals($query['state'], 'af0ifjsldkj');
-
- $this->assertArrayHasKey('id_token', $query);
- $this->assertArrayHasKey('state', $query);
- $this->assertArrayNotHasKey('access_token', $query);
- $this->assertArrayNotHasKey('expires_in', $query);
- $this->assertArrayNotHasKey('token_type', $query);
-
- // Test valid token id_token request
- $request->query['response_type'] = 'id_token token';
- $server->handleAuthorizeRequest($request, $response, true);
-
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['fragment'], $query);
-
- $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
- $this->assertEquals($query['state'], 'af0ifjsldkj');
-
- $this->assertArrayHasKey('access_token', $query);
- $this->assertArrayHasKey('expires_in', $query);
- $this->assertArrayHasKey('token_type', $query);
- $this->assertArrayHasKey('state', $query);
- $this->assertArrayHasKey('id_token', $query);
-
- // assert that with multiple-valued response types, order does not matter
- $request->query['response_type'] = 'token id_token';
- $server->handleAuthorizeRequest($request, $response, true);
-
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['fragment'], $query);
-
- $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
- $this->assertEquals($query['state'], 'af0ifjsldkj');
-
- $this->assertArrayHasKey('access_token', $query);
- $this->assertArrayHasKey('expires_in', $query);
- $this->assertArrayHasKey('token_type', $query);
- $this->assertArrayHasKey('state', $query);
- $this->assertArrayHasKey('id_token', $query);
-
- // assert that with multiple-valued response types with extra spaces do not matter
- $request->query['response_type'] = ' token id_token ';
- $server->handleAuthorizeRequest($request, $response, true);
-
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['fragment'], $query);
-
- $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
- $this->assertEquals($query['state'], 'af0ifjsldkj');
-
- $this->assertArrayHasKey('access_token', $query);
- $this->assertArrayHasKey('expires_in', $query);
- $this->assertArrayHasKey('token_type', $query);
- $this->assertArrayHasKey('state', $query);
- $this->assertArrayHasKey('id_token', $query);
- }
-
- public function testMissingNonce()
- {
- $server = $this->getTestServer();
- $authorize = $server->getAuthorizeController();
-
- $response = new Response();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'id_token',
- 'state' => 'xyz',
- ));
-
- // Test missing nonce for 'id_token' response type
- $server->handleAuthorizeRequest($request, $response, true);
- $params = $response->getParameters();
-
- $this->assertEquals($params['error'], 'invalid_nonce');
- $this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
-
- // Test missing nonce for 'id_token token' response type
- $request->query['response_type'] = 'id_token token';
- $server->handleAuthorizeRequest($request, $response, true);
- $params = $response->getParameters();
-
- $this->assertEquals($params['error'], 'invalid_nonce');
- $this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
- }
-
- public function testNotGrantedApplication()
- {
- $server = $this->getTestServer();
-
- $response = new Response();
- $request = new Request(array(
- 'client_id' => 'Test Client ID', // valid client id
- 'redirect_uri' => 'http://adobe.com', // valid redirect URI
- 'response_type' => 'id_token',
- 'state' => 'af0ifjsldkj',
- 'nonce' => 'n-0S6_WzA2Mj',
- ));
-
- // Test not approved application
- $server->handleAuthorizeRequest($request, $response, false);
-
- $params = $response->getParameters();
-
- $this->assertEquals($params['error'], 'consent_required');
- $this->assertEquals($params['error_description'], 'The user denied access to your application');
-
- // Test not approved application with prompt parameter
- $request->query['prompt'] = 'none';
- $server->handleAuthorizeRequest($request, $response, false);
-
- $params = $response->getParameters();
-
- $this->assertEquals($params['error'], 'login_required');
- $this->assertEquals($params['error_description'], 'The user must log in');
-
- // Test not approved application with user_id set
- $request->query['prompt'] = 'none';
- $server->handleAuthorizeRequest($request, $response, false, 'some-user-id');
-
- $params = $response->getParameters();
-
- $this->assertEquals($params['error'], 'interaction_required');
- $this->assertEquals($params['error_description'], 'The user must grant access to your application');
- }
-
- public function testNeedsIdToken()
- {
- $server = $this->getTestServer();
- $authorize = $server->getAuthorizeController();
-
- $this->assertTrue($authorize->needsIdToken('openid'));
- $this->assertTrue($authorize->needsIdToken('openid profile'));
- $this->assertFalse($authorize->needsIdToken(''));
- $this->assertFalse($authorize->needsIdToken('some-scope'));
- }
-
- private function getTestServer($config = array())
- {
- $config += array(
- 'use_openid_connect' => true,
- 'issuer' => 'phpunit',
- 'allow_implicit' => true
- );
-
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, $config);
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php b/library/oauth2/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
deleted file mode 100644
index b1b687077..000000000
--- a/library/oauth2/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
+++ /dev/null
@@ -1,44 +0,0 @@
-handleUserInfoRequest(new Request(), $response);
- $this->assertEquals(401, $response->getStatusCode());
- }
-
- public function testValidToken()
- {
- $server = $this->getTestServer();
- $request = Request::createFromGlobals();
- $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-openid-connect';
- $response = new Response();
-
- $server->handleUserInfoRequest($request, $response);
- $parameters = $response->getParameters();
- $this->assertEquals($parameters['sub'], 'testuser');
- $this->assertEquals($parameters['email'], 'testuser@test.com');
- $this->assertEquals($parameters['email_verified'], true);
- }
-
- private function getTestServer($config = array())
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, $config);
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php b/library/oauth2/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php
deleted file mode 100644
index 776002d1e..000000000
--- a/library/oauth2/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php
+++ /dev/null
@@ -1,57 +0,0 @@
-getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-openid', // valid code
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('id_token', $token);
- $this->assertEquals('test_id_token', $token['id_token']);
-
- // this is only true if "offline_access" was requested
- $this->assertFalse(isset($token['refresh_token']));
- }
-
- public function testOfflineAccess()
- {
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'code' => 'testcode-openid', // valid code
- 'scope' => 'offline_access', // valid code
- ));
- $token = $server->grantAccessToken($request, new Response());
-
- $this->assertNotNull($token);
- $this->assertArrayHasKey('id_token', $token);
- $this->assertEquals('test_id_token', $token['id_token']);
- $this->assertTrue(isset($token['refresh_token']));
- }
-
- private function getTestServer()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, array('use_openid_connect' => true));
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php b/library/oauth2/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php
deleted file mode 100644
index b0311434a..000000000
--- a/library/oauth2/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php
+++ /dev/null
@@ -1,182 +0,0 @@
-getTestServer();
-
- $request = new Request(array(
- 'response_type' => 'code id_token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid',
- 'state' => 'test',
- 'nonce' => 'test',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertArrayHasKey('query', $parts);
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['query'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('id_token', $params);
- $this->assertArrayHasKey('code', $params);
-
- // validate ID Token
- $parts = explode('.', $params['id_token']);
- foreach ($parts as &$part) {
- // Each part is a base64url encoded json string.
- $part = str_replace(array('-', '_'), array('+', '/'), $part);
- $part = base64_decode($part);
- $part = json_decode($part, true);
- }
- list($header, $claims, $signature) = $parts;
-
- $this->assertArrayHasKey('iss', $claims);
- $this->assertArrayHasKey('sub', $claims);
- $this->assertArrayHasKey('aud', $claims);
- $this->assertArrayHasKey('iat', $claims);
- $this->assertArrayHasKey('exp', $claims);
- $this->assertArrayHasKey('auth_time', $claims);
- $this->assertArrayHasKey('nonce', $claims);
-
- // only exists if an access token was granted along with the id_token
- $this->assertArrayNotHasKey('at_hash', $claims);
-
- $this->assertEquals($claims['iss'], 'test');
- $this->assertEquals($claims['aud'], 'Test Client ID');
- $this->assertEquals($claims['nonce'], 'test');
- $duration = $claims['exp'] - $claims['iat'];
- $this->assertEquals($duration, 3600);
- }
-
- public function testUserClaimsWithUserId()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
-
- $request = new Request(array(
- 'response_type' => 'code id_token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid email',
- 'state' => 'test',
- 'nonce' => 'test',
- ));
-
- $userId = 'testuser';
- $server->handleAuthorizeRequest($request, $response = new Response(), true, $userId);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertArrayHasKey('query', $parts);
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['query'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('id_token', $params);
- $this->assertArrayHasKey('code', $params);
-
- // validate ID Token
- $parts = explode('.', $params['id_token']);
- foreach ($parts as &$part) {
- // Each part is a base64url encoded json string.
- $part = str_replace(array('-', '_'), array('+', '/'), $part);
- $part = base64_decode($part);
- $part = json_decode($part, true);
- }
- list($header, $claims, $signature) = $parts;
-
- $this->assertArrayHasKey('email', $claims);
- $this->assertArrayHasKey('email_verified', $claims);
- $this->assertNotNull($claims['email']);
- $this->assertNotNull($claims['email_verified']);
- }
-
- public function testUserClaimsWithoutUserId()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
-
- $request = new Request(array(
- 'response_type' => 'code id_token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid email',
- 'state' => 'test',
- 'nonce' => 'test',
- ));
-
- $userId = null;
- $server->handleAuthorizeRequest($request, $response = new Response(), true, $userId);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertArrayHasKey('query', $parts);
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['query'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('id_token', $params);
- $this->assertArrayHasKey('code', $params);
-
- // validate ID Token
- $parts = explode('.', $params['id_token']);
- foreach ($parts as &$part) {
- // Each part is a base64url encoded json string.
- $part = str_replace(array('-', '_'), array('+', '/'), $part);
- $part = base64_decode($part);
- $part = json_decode($part, true);
- }
- list($header, $claims, $signature) = $parts;
-
- $this->assertArrayNotHasKey('email', $claims);
- $this->assertArrayNotHasKey('email_verified', $claims);
- }
-
- private function getTestServer($config = array())
- {
- $config += array(
- 'use_openid_connect' => true,
- 'issuer' => 'test',
- 'id_lifetime' => 3600,
- 'allow_implicit' => true,
- );
-
- $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
- $memoryStorage->supportedScopes[] = 'email';
- $responseTypes = array(
- 'code' => $code = new AuthorizationCode($memoryStorage),
- 'id_token' => $idToken = new IdToken($memoryStorage, $memoryStorage, $config),
- 'code id_token' => new CodeIdToken($code, $idToken),
- );
-
- $server = new Server($memoryStorage, $config, array(), $responseTypes);
- $server->addGrantType(new ClientCredentials($memoryStorage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTest.php b/library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTest.php
deleted file mode 100644
index e772f6be4..000000000
--- a/library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTest.php
+++ /dev/null
@@ -1,184 +0,0 @@
- 'id_token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid',
- 'state' => 'test',
- );
-
- // attempt to do the request without a nonce.
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request($query);
- $valid = $server->validateAuthorizeRequest($request, $response = new Response());
-
- // Add a nonce and retry.
- $query['nonce'] = 'test';
- $request = new Request($query);
- $valid = $server->validateAuthorizeRequest($request, $response = new Response());
- $this->assertTrue($valid);
- }
-
- public function testHandleAuthorizeRequest()
- {
- // add the test parameters in memory
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'response_type' => 'id_token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid email',
- 'state' => 'test',
- 'nonce' => 'test',
- ));
-
- $user_id = 'testuser';
- $server->handleAuthorizeRequest($request, $response = new Response(), true, $user_id);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertArrayHasKey('fragment', $parts);
- $this->assertFalse(isset($parts['query']));
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['fragment'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('id_token', $params);
- $this->assertArrayNotHasKey('access_token', $params);
- $this->validateIdToken($params['id_token']);
- }
-
- public function testPassInAuthTime()
- {
- $server = $this->getTestServer(array('allow_implicit' => true));
- $request = new Request(array(
- 'response_type' => 'id_token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid email',
- 'state' => 'test',
- 'nonce' => 'test',
- ));
-
- // test with a scalar user id
- $user_id = 'testuser123';
- $server->handleAuthorizeRequest($request, $response = new Response(), true, $user_id);
-
- list($header, $payload, $signature) = $this->extractTokenDataFromResponse($response);
-
- $this->assertTrue(is_array($payload));
- $this->assertArrayHasKey('sub', $payload);
- $this->assertEquals($user_id, $payload['sub']);
- $this->assertArrayHasKey('auth_time', $payload);
-
- // test with an array of user info
- $userInfo = array(
- 'user_id' => 'testuser1234',
- 'auth_time' => date('Y-m-d H:i:s', strtotime('20 minutes ago')
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true, $userInfo);
-
- list($header, $payload, $signature) = $this->extractTokenDataFromResponse($response);
-
- $this->assertTrue(is_array($payload));
- $this->assertArrayHasKey('sub', $payload);
- $this->assertEquals($userInfo['user_id'], $payload['sub']);
- $this->assertArrayHasKey('auth_time', $payload);
- $this->assertEquals($userInfo['auth_time'], $payload['auth_time']);
- }
-
- private function extractTokenDataFromResponse(Response $response)
- {
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertArrayHasKey('fragment', $parts);
- $this->assertFalse(isset($parts['query']));
-
- parse_str($parts['fragment'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('id_token', $params);
- $this->assertArrayNotHasKey('access_token', $params);
-
- list($headb64, $payloadb64, $signature) = explode('.', $params['id_token']);
-
- $jwt = new Jwt();
- $header = json_decode($jwt->urlSafeB64Decode($headb64), true);
- $payload = json_decode($jwt->urlSafeB64Decode($payloadb64), true);
-
- return array($header, $payload, $signature);
- }
-
- private function validateIdToken($id_token)
- {
- $parts = explode('.', $id_token);
- foreach ($parts as &$part) {
- // Each part is a base64url encoded json string.
- $part = str_replace(array('-', '_'), array('+', '/'), $part);
- $part = base64_decode($part);
- $part = json_decode($part, true);
- }
- list($header, $claims, $signature) = $parts;
-
- $this->assertArrayHasKey('iss', $claims);
- $this->assertArrayHasKey('sub', $claims);
- $this->assertArrayHasKey('aud', $claims);
- $this->assertArrayHasKey('iat', $claims);
- $this->assertArrayHasKey('exp', $claims);
- $this->assertArrayHasKey('auth_time', $claims);
- $this->assertArrayHasKey('nonce', $claims);
- $this->assertArrayHasKey('email', $claims);
- $this->assertArrayHasKey('email_verified', $claims);
-
- $this->assertEquals($claims['iss'], 'test');
- $this->assertEquals($claims['aud'], 'Test Client ID');
- $this->assertEquals($claims['nonce'], 'test');
- $this->assertEquals($claims['email'], 'testuser@test.com');
- $duration = $claims['exp'] - $claims['iat'];
- $this->assertEquals($duration, 3600);
- }
-
- private function getTestServer($config = array())
- {
- $config += array(
- 'use_openid_connect' => true,
- 'issuer' => 'test',
- 'id_lifetime' => 3600,
- );
-
- $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
- $memoryStorage->supportedScopes[] = 'email';
- $storage = array(
- 'client' => $memoryStorage,
- 'scope' => $memoryStorage,
- );
- $responseTypes = array(
- 'id_token' => new IdToken($memoryStorage, $memoryStorage, $config),
- );
-
- $server = new Server($storage, $config, array(), $responseTypes);
- $server->addGrantType(new ClientCredentials($memoryStorage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php b/library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php
deleted file mode 100644
index bc564d37b..000000000
--- a/library/oauth2/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php
+++ /dev/null
@@ -1,91 +0,0 @@
-getTestServer(array('allow_implicit' => true));
-
- $request = new Request(array(
- 'response_type' => 'id_token token',
- 'redirect_uri' => 'http://adobe.com',
- 'client_id' => 'Test Client ID',
- 'scope' => 'openid',
- 'state' => 'test',
- 'nonce' => 'test',
- ));
-
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- $this->assertEquals($response->getStatusCode(), 302);
- $location = $response->getHttpHeader('Location');
- $this->assertNotContains('error', $location);
-
- $parts = parse_url($location);
- $this->assertArrayHasKey('fragment', $parts);
- $this->assertFalse(isset($parts['query']));
-
- // assert fragment is in "application/x-www-form-urlencoded" format
- parse_str($parts['fragment'], $params);
- $this->assertNotNull($params);
- $this->assertArrayHasKey('id_token', $params);
- $this->assertArrayHasKey('access_token', $params);
-
- // validate ID Token
- $parts = explode('.', $params['id_token']);
- foreach ($parts as &$part) {
- // Each part is a base64url encoded json string.
- $part = str_replace(array('-', '_'), array('+', '/'), $part);
- $part = base64_decode($part);
- $part = json_decode($part, true);
- }
- list($header, $claims, $signature) = $parts;
-
- $this->assertArrayHasKey('iss', $claims);
- $this->assertArrayHasKey('sub', $claims);
- $this->assertArrayHasKey('aud', $claims);
- $this->assertArrayHasKey('iat', $claims);
- $this->assertArrayHasKey('exp', $claims);
- $this->assertArrayHasKey('auth_time', $claims);
- $this->assertArrayHasKey('nonce', $claims);
- $this->assertArrayHasKey('at_hash', $claims);
-
- $this->assertEquals($claims['iss'], 'test');
- $this->assertEquals($claims['aud'], 'Test Client ID');
- $this->assertEquals($claims['nonce'], 'test');
- $duration = $claims['exp'] - $claims['iat'];
- $this->assertEquals($duration, 3600);
- }
-
- private function getTestServer($config = array())
- {
- $config += array(
- 'use_openid_connect' => true,
- 'issuer' => 'test',
- 'id_lifetime' => 3600,
- );
-
- $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
- $responseTypes = array(
- 'token' => $token = new AccessToken($memoryStorage, $memoryStorage),
- 'id_token' => $idToken = new IdToken($memoryStorage, $memoryStorage, $config),
- 'id_token token' => new IdTokenToken($token, $idToken),
- );
-
- $server = new Server($memoryStorage, $config, array(), $responseTypes);
- $server->addGrantType(new ClientCredentials($memoryStorage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php b/library/oauth2/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php
deleted file mode 100644
index bdfb085e3..000000000
--- a/library/oauth2/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- if (!$storage instanceof AuthorizationCodeInterface) {
- return;
- }
-
- // assert code we are about to add does not exist
- $code = $storage->getAuthorizationCode('new-openid-code');
- $this->assertFalse($code);
-
- // add new code
- $expires = time() + 20;
- $scope = null;
- $id_token = 'fake_id_token';
- $success = $storage->setAuthorizationCode('new-openid-code', 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, $id_token);
- $this->assertTrue($success);
-
- $code = $storage->getAuthorizationCode('new-openid-code');
- $this->assertNotNull($code);
- $this->assertArrayHasKey('authorization_code', $code);
- $this->assertArrayHasKey('client_id', $code);
- $this->assertArrayHasKey('user_id', $code);
- $this->assertArrayHasKey('redirect_uri', $code);
- $this->assertArrayHasKey('expires', $code);
- $this->assertEquals($code['authorization_code'], 'new-openid-code');
- $this->assertEquals($code['client_id'], 'client ID');
- $this->assertEquals($code['user_id'], 'SOMEUSERID');
- $this->assertEquals($code['redirect_uri'], 'http://example.com');
- $this->assertEquals($code['expires'], $expires);
- $this->assertEquals($code['id_token'], $id_token);
-
- // change existing code
- $expires = time() + 42;
- $new_id_token = 'fake_id_token-2';
- $success = $storage->setAuthorizationCode('new-openid-code', 'client ID2', 'SOMEOTHERID', 'http://example.org', $expires, $scope, $new_id_token);
- $this->assertTrue($success);
-
- $code = $storage->getAuthorizationCode('new-openid-code');
- $this->assertNotNull($code);
- $this->assertArrayHasKey('authorization_code', $code);
- $this->assertArrayHasKey('client_id', $code);
- $this->assertArrayHasKey('user_id', $code);
- $this->assertArrayHasKey('redirect_uri', $code);
- $this->assertArrayHasKey('expires', $code);
- $this->assertEquals($code['authorization_code'], 'new-openid-code');
- $this->assertEquals($code['client_id'], 'client ID2');
- $this->assertEquals($code['user_id'], 'SOMEOTHERID');
- $this->assertEquals($code['redirect_uri'], 'http://example.org');
- $this->assertEquals($code['expires'], $expires);
- $this->assertEquals($code['id_token'], $new_id_token);
- }
-
- /** @dataProvider provideStorage */
- public function testRemoveIdTokenFromAuthorizationCode($storage)
- {
- // add new code
- $expires = time() + 20;
- $scope = null;
- $id_token = 'fake_id_token_to_remove';
- $authcode = 'new-openid-code-'.rand();
- $success = $storage->setAuthorizationCode($authcode, 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, $id_token);
- $this->assertTrue($success);
-
- // verify params were set
- $code = $storage->getAuthorizationCode($authcode);
- $this->assertNotNull($code);
- $this->assertArrayHasKey('id_token', $code);
- $this->assertEquals($code['id_token'], $id_token);
-
- // remove the id_token
- $success = $storage->setAuthorizationCode($authcode, 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, null);
-
- // verify the "id_token" is now null
- $code = $storage->getAuthorizationCode($authcode);
- $this->assertNotNull($code);
- $this->assertArrayHasKey('id_token', $code);
- $this->assertEquals($code['id_token'], null);
- }
-}
diff --git a/library/oauth2/test/OAuth2/OpenID/Storage/UserClaimsTest.php b/library/oauth2/test/OAuth2/OpenID/Storage/UserClaimsTest.php
deleted file mode 100644
index 840f6c566..000000000
--- a/library/oauth2/test/OAuth2/OpenID/Storage/UserClaimsTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- if (!$storage instanceof UserClaimsInterface) {
- // incompatible storage
- return;
- }
-
- // invalid user
- $claims = $storage->getUserClaims('fake-user', '');
- $this->assertFalse($claims);
-
- // valid user (no scope)
- $claims = $storage->getUserClaims('testuser', '');
-
- /* assert the decoded token is the same */
- $this->assertFalse(isset($claims['email']));
-
- // valid user
- $claims = $storage->getUserClaims('testuser', 'email');
-
- /* assert the decoded token is the same */
- $this->assertEquals($claims['email'], "testuser@test.com");
- $this->assertEquals($claims['email_verified'], true);
- }
-}
diff --git a/library/oauth2/test/OAuth2/RequestTest.php b/library/oauth2/test/OAuth2/RequestTest.php
deleted file mode 100644
index 10db3215c..000000000
--- a/library/oauth2/test/OAuth2/RequestTest.php
+++ /dev/null
@@ -1,98 +0,0 @@
-getTestServer();
-
- // Smoke test for override request class
- // $server->handleTokenRequest($request, $response = new Response());
- // $this->assertInstanceOf('Response', $response);
- // $server->handleAuthorizeRequest($request, $response = new Response(), true);
- // $this->assertInstanceOf('Response', $response);
- // $response = $server->verifyResourceRequest($request, $response = new Response());
- // $this->assertTrue(is_bool($response));
-
- /*** make some valid requests ***/
-
- // Valid Token Request
- $request->setPost(array(
- 'grant_type' => 'authorization_code',
- 'client_id' => 'Test Client ID',
- 'client_secret' => 'TestSecret',
- 'code' => 'testcode',
- ));
- $server->handleTokenRequest($request, $response = new Response());
- $this->assertEquals($response->getStatusCode(), 200);
- $this->assertNull($response->getParameter('error'));
- $this->assertNotNUll($response->getParameter('access_token'));
- }
-
- public function testHeadersReturnsValueByKey()
- {
- $request = new Request(
- array(),
- array(),
- array(),
- array(),
- array(),
- array(),
- array(),
- array('AUTHORIZATION' => 'Basic secret')
- );
-
- $this->assertEquals('Basic secret', $request->headers('AUTHORIZATION'));
- }
-
- public function testHeadersReturnsDefaultIfHeaderNotPresent()
- {
- $request = new Request();
-
- $this->assertEquals('Bearer', $request->headers('AUTHORIZATION', 'Bearer'));
- }
-
- public function testHeadersIsCaseInsensitive()
- {
- $request = new Request(
- array(),
- array(),
- array(),
- array(),
- array(),
- array(),
- array(),
- array('AUTHORIZATION' => 'Basic secret')
- );
-
- $this->assertEquals('Basic secret', $request->headers('Authorization'));
- }
-
- public function testRequestReturnsPostParamIfNoQueryParamAvailable()
- {
- $request = new Request(
- array(),
- array('client_id' => 'correct')
- );
-
- $this->assertEquals('correct', $request->query('client_id', $request->request('client_id')));
- }
-
- private function getTestServer($config = array())
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, $config);
-
- // Add the two types supported for authorization grant
- $server->addGrantType(new AuthorizationCode($storage));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/ResponseTest.php b/library/oauth2/test/OAuth2/ResponseTest.php
deleted file mode 100644
index b8149005d..000000000
--- a/library/oauth2/test/OAuth2/ResponseTest.php
+++ /dev/null
@@ -1,17 +0,0 @@
- 'bar',
- 'halland' => 'oates',
- ));
-
- $string = $response->getResponseBody('xml');
- $this->assertContains('baroates', $string);
- }
-}
diff --git a/library/oauth2/test/OAuth2/ResponseType/AccessTokenTest.php b/library/oauth2/test/OAuth2/ResponseType/AccessTokenTest.php
deleted file mode 100644
index 0ed1c82fc..000000000
--- a/library/oauth2/test/OAuth2/ResponseType/AccessTokenTest.php
+++ /dev/null
@@ -1,107 +0,0 @@
- array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
- $accessToken = new AccessToken($tokenStorage);
- $accessToken->revokeToken('revoke', 'access_token');
- $this->assertFalse($tokenStorage->getAccessToken('revoke'));
- }
-
- public function testRevokeAccessTokenWithoutTypeHint()
- {
- $tokenStorage = new Memory(array(
- 'access_tokens' => array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
- $accessToken = new AccessToken($tokenStorage);
- $accessToken->revokeToken('revoke');
- $this->assertFalse($tokenStorage->getAccessToken('revoke'));
- }
-
- public function testRevokeRefreshTokenWithTypeHint()
- {
- $tokenStorage = new Memory(array(
- 'refresh_tokens' => array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
- $accessToken = new AccessToken(new Memory, $tokenStorage);
- $accessToken->revokeToken('revoke', 'refresh_token');
- $this->assertFalse($tokenStorage->getRefreshToken('revoke'));
- }
-
- public function testRevokeRefreshTokenWithoutTypeHint()
- {
- $tokenStorage = new Memory(array(
- 'refresh_tokens' => array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
- $accessToken = new AccessToken(new Memory, $tokenStorage);
- $accessToken->revokeToken('revoke');
- $this->assertFalse($tokenStorage->getRefreshToken('revoke'));
- }
-
- public function testRevokeAccessTokenWithRefreshTokenTypeHint()
- {
- $tokenStorage = new Memory(array(
- 'access_tokens' => array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
- $accessToken = new AccessToken($tokenStorage);
- $accessToken->revokeToken('revoke', 'refresh_token');
- $this->assertFalse($tokenStorage->getAccessToken('revoke'));
- }
-
- public function testRevokeAccessTokenWithBogusTypeHint()
- {
- $tokenStorage = new Memory(array(
- 'access_tokens' => array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
- $accessToken = new AccessToken($tokenStorage);
- $accessToken->revokeToken('revoke', 'foo');
- $this->assertFalse($tokenStorage->getAccessToken('revoke'));
- }
-
- public function testRevokeRefreshTokenWithBogusTypeHint()
- {
- $tokenStorage = new Memory(array(
- 'refresh_tokens' => array(
- 'revoke' => array('mytoken'),
- ),
- ));
-
- $this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
- $accessToken = new AccessToken(new Memory, $tokenStorage);
- $accessToken->revokeToken('revoke', 'foo');
- $this->assertFalse($tokenStorage->getRefreshToken('revoke'));
- }
-}
diff --git a/library/oauth2/test/OAuth2/ResponseType/JwtAccessTokenTest.php b/library/oauth2/test/OAuth2/ResponseType/JwtAccessTokenTest.php
deleted file mode 100644
index 51b01a927..000000000
--- a/library/oauth2/test/OAuth2/ResponseType/JwtAccessTokenTest.php
+++ /dev/null
@@ -1,160 +0,0 @@
-getTestServer();
- $jwtResponseType = $server->getResponseType('token');
-
- $accessToken = $jwtResponseType->createAccessToken('Test Client ID', 123, 'test', false);
- $jwt = new Jwt;
- $decodedAccessToken = $jwt->decode($accessToken['access_token'], null, false);
-
- $this->assertArrayHasKey('id', $decodedAccessToken);
- $this->assertArrayHasKey('jti', $decodedAccessToken);
- $this->assertArrayHasKey('iss', $decodedAccessToken);
- $this->assertArrayHasKey('aud', $decodedAccessToken);
- $this->assertArrayHasKey('exp', $decodedAccessToken);
- $this->assertArrayHasKey('iat', $decodedAccessToken);
- $this->assertArrayHasKey('token_type', $decodedAccessToken);
- $this->assertArrayHasKey('scope', $decodedAccessToken);
-
- $this->assertEquals('https://api.example.com', $decodedAccessToken['iss']);
- $this->assertEquals('Test Client ID', $decodedAccessToken['aud']);
- $this->assertEquals(123, $decodedAccessToken['sub']);
- $delta = $decodedAccessToken['exp'] - $decodedAccessToken['iat'];
- $this->assertEquals(3600, $delta);
- $this->assertEquals($decodedAccessToken['id'], $decodedAccessToken['jti']);
- }
-
- public function testGrantJwtAccessToken()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
-
- $this->assertNotNull($response->getParameter('access_token'));
- $this->assertEquals(2, substr_count($response->getParameter('access_token'), '.'));
- }
-
- public function testAccessResourceWithJwtAccessToken()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
- $this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
-
- // make a call to the resource server using the crypto token
- $request = TestRequest::createPost(array(
- 'access_token' => $JwtAccessToken,
- ));
-
- $this->assertTrue($server->verifyResourceRequest($request));
- }
-
- public function testAccessResourceWithJwtAccessTokenUsingSecondaryStorage()
- {
- // add the test parameters in memory
- $server = $this->getTestServer();
- $request = TestRequest::createPost(array(
- 'grant_type' => 'client_credentials', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- ));
- $server->handleTokenRequest($request, $response = new Response());
- $this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
-
- // make a call to the resource server using the crypto token
- $request = TestRequest::createPost(array(
- 'access_token' => $JwtAccessToken,
- ));
-
- // create a resource server with the "memory" storage from the grant server
- $resourceServer = new Server($server->getStorage('client_credentials'));
-
- $this->assertTrue($resourceServer->verifyResourceRequest($request));
- }
-
- public function testJwtAccessTokenWithRefreshToken()
- {
- $server = $this->getTestServer();
-
- // add "UserCredentials" grant type and "JwtAccessToken" response type
- // and ensure "JwtAccessToken" response type has "RefreshToken" storage
- $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
- $server->addGrantType(new UserCredentials($memoryStorage));
- $server->addGrantType(new RefreshToken($memoryStorage));
- $server->addResponseType(new JwtAccessToken($memoryStorage, $memoryStorage, $memoryStorage), 'token');
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'password', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'username' => 'test-username', // valid username
- 'password' => 'testpass', // valid password
- ));
-
- // make the call to grant a crypto token
- $server->handleTokenRequest($request, $response = new Response());
- $this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
- $this->assertNotNull($refreshToken = $response->getParameter('refresh_token'));
-
- // decode token and make sure refresh_token isn't set
- list($header, $payload, $signature) = explode('.', $JwtAccessToken);
- $decodedToken = json_decode(base64_decode($payload), true);
- $this->assertFalse(array_key_exists('refresh_token', $decodedToken));
-
- // use the refresh token to get another access token
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token',
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => $refreshToken,
- ));
-
- $server->handleTokenRequest($request, $response = new Response());
- $this->assertNotNull($response->getParameter('access_token'));
- }
-
- private function getTestServer()
- {
- $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
-
- $storage = array(
- 'access_token' => new JwtAccessTokenStorage($memoryStorage),
- 'client' => $memoryStorage,
- 'client_credentials' => $memoryStorage,
- );
- $server = new Server($storage);
- $server->addGrantType(new ClientCredentials($memoryStorage));
-
- // make the "token" response type a JwtAccessToken
- $config = array('issuer' => 'https://api.example.com');
- $server->addResponseType(new JwtAccessToken($memoryStorage, $memoryStorage, null, $config));
-
- return $server;
- }
-}
diff --git a/library/oauth2/test/OAuth2/ScopeTest.php b/library/oauth2/test/OAuth2/ScopeTest.php
deleted file mode 100644
index 99f9cf6eb..000000000
--- a/library/oauth2/test/OAuth2/ScopeTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-assertFalse($scopeUtil->checkScope('invalid', 'list of scopes'));
- $this->assertTrue($scopeUtil->checkScope('valid', 'valid and-some other-scopes'));
- $this->assertTrue($scopeUtil->checkScope('valid another-valid', 'valid another-valid and-some other-scopes'));
- // all scopes must match
- $this->assertFalse($scopeUtil->checkScope('valid invalid', 'valid and-some other-scopes'));
- $this->assertFalse($scopeUtil->checkScope('valid valid2 invalid', 'valid valid2 and-some other-scopes'));
- }
-
- public function testScopeStorage()
- {
- $scopeUtil = new Scope();
- $this->assertEquals($scopeUtil->getDefaultScope(), null);
-
- $scopeUtil = new Scope(array(
- 'default_scope' => 'default',
- 'supported_scopes' => array('this', 'that', 'another'),
- ));
- $this->assertEquals($scopeUtil->getDefaultScope(), 'default');
- $this->assertTrue($scopeUtil->scopeExists('this that another', 'client_id'));
-
- $memoryStorage = new Memory(array(
- 'default_scope' => 'base',
- 'supported_scopes' => array('only-this-one'),
- ));
- $scopeUtil = new Scope($memoryStorage);
-
- $this->assertEquals($scopeUtil->getDefaultScope(), 'base');
- $this->assertTrue($scopeUtil->scopeExists('only-this-one', 'client_id'));
- }
-}
diff --git a/library/oauth2/test/OAuth2/ServerTest.php b/library/oauth2/test/OAuth2/ServerTest.php
deleted file mode 100644
index 747e120f5..000000000
--- a/library/oauth2/test/OAuth2/ServerTest.php
+++ /dev/null
@@ -1,684 +0,0 @@
-getAuthorizeController();
- }
-
- /**
- * @expectedException LogicException OAuth2\Storage\AccessTokenInterface
- **/
- public function testGetAuthorizeControllerWithNoAccessTokenStorageThrowsException()
- {
- // must set AccessToken or AuthorizationCode
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
- $server->getAuthorizeController();
- }
-
- public function testGetAuthorizeControllerWithClientStorageAndAccessTokenResponseType()
- {
- // must set AccessToken or AuthorizationCode
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
- $server->addResponseType($this->getMock('OAuth2\ResponseType\AccessTokenInterface'));
-
- $this->assertNotNull($server->getAuthorizeController());
- }
-
- public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeResponseType()
- {
- // must set AccessToken or AuthorizationCode
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
- $server->addResponseType($this->getMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
-
- $this->assertNotNull($server->getAuthorizeController());
- }
-
- /**
- * @expectedException LogicException allow_implicit
- **/
- public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
- {
- // must set AuthorizationCode or AccessToken / implicit
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
-
- $this->assertNotNull($server->getAuthorizeController());
- }
-
- public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorage()
- {
- // must set AuthorizationCode or AccessToken / implicit
- $server = new Server(array(), array('allow_implicit' => true));
- $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
-
- $this->assertNotNull($server->getAuthorizeController());
- }
-
- public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeStorage()
- {
- // must set AccessToken or AuthorizationCode
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\AuthorizationCodeInterface'));
-
- $this->assertNotNull($server->getAuthorizeController());
- }
-
- /**
- * @expectedException LogicException grant_types
- **/
- public function testGetTokenControllerWithGrantTypeStorageThrowsException()
- {
- $server = new Server();
- $server->getTokenController();
- }
-
- /**
- * @expectedException LogicException OAuth2\Storage\ClientCredentialsInterface
- **/
- public function testGetTokenControllerWithNoClientCredentialsStorageThrowsException()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\UserCredentialsInterface'));
- $server->getTokenController();
- }
-
- /**
- * @expectedException LogicException OAuth2\Storage\AccessTokenInterface
- **/
- public function testGetTokenControllerWithNoAccessTokenStorageThrowsException()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
- $server->getTokenController();
- }
-
- public function testGetTokenControllerWithAccessTokenAndClientCredentialsStorage()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
- $server->getTokenController();
- }
-
- public function testGetTokenControllerAccessTokenStorageAndClientCredentialsStorageAndGrantTypes()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
- $server->addGrantType($this->getMockBuilder('OAuth2\GrantType\AuthorizationCode')->disableOriginalConstructor()->getMock());
- $server->getTokenController();
- }
-
- /**
- * @expectedException LogicException OAuth2\Storage\AccessTokenInterface
- **/
- public function testGetResourceControllerWithNoAccessTokenStorageThrowsException()
- {
- $server = new Server();
- $server->getResourceController();
- }
-
- public function testGetResourceControllerWithAccessTokenStorage()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
- $server->getResourceController();
- }
-
- /**
- * @expectedException InvalidArgumentException OAuth2\Storage\AccessTokenInterface
- **/
- public function testAddingStorageWithInvalidClass()
- {
- $server = new Server();
- $server->addStorage(new \StdClass());
- }
-
- /**
- * @expectedException InvalidArgumentException access_token
- **/
- public function testAddingStorageWithInvalidKey()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
- }
-
- /**
- * @expectedException InvalidArgumentException OAuth2\Storage\AuthorizationCodeInterface
- **/
- public function testAddingStorageWithInvalidKeyStorageCombination()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
- }
-
- public function testAddingStorageWithValidKeyOnlySetsThatKey()
- {
- $server = new Server();
- $server->addStorage($this->getMock('OAuth2\Storage\Memory'), 'access_token');
-
- $reflection = new \ReflectionClass($server);
- $prop = $reflection->getProperty('storages');
- $prop->setAccessible(true);
-
- $storages = $prop->getValue($server); // get the private "storages" property
-
- $this->assertEquals(1, count($storages));
- $this->assertTrue(isset($storages['access_token']));
- $this->assertFalse(isset($storages['authorization_code']));
- }
-
- public function testAddingClientStorageSetsClientCredentialsStorageByDefault()
- {
- $server = new Server();
- $memory = $this->getMock('OAuth2\Storage\Memory');
- $server->addStorage($memory, 'client');
-
- $client_credentials = $server->getStorage('client_credentials');
-
- $this->assertNotNull($client_credentials);
- $this->assertEquals($client_credentials, $memory);
- }
-
- public function testAddStorageWithNullValue()
- {
- $memory = $this->getMock('OAuth2\Storage\Memory');
- $server = new Server($memory);
- $server->addStorage(null, 'refresh_token');
-
- $client_credentials = $server->getStorage('client_credentials');
-
- $this->assertNotNull($client_credentials);
- $this->assertEquals($client_credentials, $memory);
-
- $refresh_token = $server->getStorage('refresh_token');
-
- $this->assertNull($refresh_token);
- }
-
- public function testNewServerWithNullStorageValue()
- {
- $memory = $this->getMock('OAuth2\Storage\Memory');
- $server = new Server(array(
- 'client_credentials' => $memory,
- 'refresh_token' => null,
- ));
-
- $client_credentials = $server->getStorage('client_credentials');
-
- $this->assertNotNull($client_credentials);
- $this->assertEquals($client_credentials, $memory);
-
- $refresh_token = $server->getStorage('refresh_token');
-
- $this->assertNull($refresh_token);
- }
-
- public function testAddingClientCredentialsStorageSetsClientStorageByDefault()
- {
- $server = new Server();
- $memory = $this->getMock('OAuth2\Storage\Memory');
- $server->addStorage($memory, 'client_credentials');
-
- $client = $server->getStorage('client');
-
- $this->assertNotNull($client);
- $this->assertEquals($client, $memory);
- }
-
- public function testSettingClientStorageByDefaultDoesNotOverrideSetStorage()
- {
- $server = new Server();
- $pdo = $this->getMockBuilder('OAuth2\Storage\Pdo')
- ->disableOriginalConstructor()->getMock();
-
- $memory = $this->getMock('OAuth2\Storage\Memory');
-
- $server->addStorage($pdo, 'client');
- $server->addStorage($memory, 'client_credentials');
-
- $client = $server->getStorage('client');
- $client_credentials = $server->getStorage('client_credentials');
-
- $this->assertEquals($client, $pdo);
- $this->assertEquals($client_credentials, $memory);
- }
-
- public function testAddingResponseType()
- {
- $storage = $this->getMock('OAuth2\Storage\Memory');
- $storage
- ->expects($this->any())
- ->method('getClientDetails')
- ->will($this->returnValue(array('client_id' => 'some_client')));
- $storage
- ->expects($this->any())
- ->method('checkRestrictedGrantType')
- ->will($this->returnValue(true));
-
- // add with the "code" key explicitly set
- $codeType = new AuthorizationCode($storage);
- $server = new Server();
- $server->addStorage($storage);
- $server->addResponseType($codeType);
- $request = new Request(array(
- 'response_type' => 'code',
- 'client_id' => 'some_client',
- 'redirect_uri' => 'http://example.com',
- 'state' => 'xyx',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- // the response is successful
- $this->assertEquals($response->getStatusCode(), 302);
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['query'], $query);
- $this->assertTrue(isset($query['code']));
- $this->assertFalse(isset($query['error']));
-
- // add with the "code" key not set
- $codeType = new AuthorizationCode($storage);
- $server = new Server(array($storage), array(), array(), array($codeType));
- $request = new Request(array(
- 'response_type' => 'code',
- 'client_id' => 'some_client',
- 'redirect_uri' => 'http://example.com',
- 'state' => 'xyx',
- ));
- $server->handleAuthorizeRequest($request, $response = new Response(), true);
-
- // the response is successful
- $this->assertEquals($response->getStatusCode(), 302);
- $parts = parse_url($response->getHttpHeader('Location'));
- parse_str($parts['query'], $query);
- $this->assertTrue(isset($query['code']));
- $this->assertFalse(isset($query['error']));
- }
-
- public function testCustomClientAssertionType()
- {
- $request = TestRequest::createPost(array(
- 'grant_type' => 'authorization_code',
- 'client_id' =>'Test Client ID',
- 'code' => 'testcode',
- ));
- // verify the mock clientAssertionType was called as expected
- $clientAssertionType = $this->getMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface', array('validateRequest', 'getClientId'));
- $clientAssertionType
- ->expects($this->once())
- ->method('validateRequest')
- ->will($this->returnValue(true));
- $clientAssertionType
- ->expects($this->once())
- ->method('getClientId')
- ->will($this->returnValue('Test Client ID'));
-
- // create mock storage
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server(array($storage), array(), array(), array(), null, null, $clientAssertionType);
- $server->handleTokenRequest($request, $response = new Response());
- }
-
- public function testHttpBasicConfig()
- {
- // create mock storage
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server(array($storage), array(
- 'allow_credentials_in_request_body' => false,
- 'allow_public_clients' => false
- ));
- $server->getTokenController();
- $httpBasic = $server->getClientAssertionType();
-
- $reflection = new \ReflectionClass($httpBasic);
- $prop = $reflection->getProperty('config');
- $prop->setAccessible(true);
-
- $config = $prop->getValue($httpBasic); // get the private "config" property
-
- $this->assertEquals($config['allow_credentials_in_request_body'], false);
- $this->assertEquals($config['allow_public_clients'], false);
- }
-
- public function testRefreshTokenConfig()
- {
- // create mock storage
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server1 = new Server(array($storage));
- $server2 = new Server(array($storage), array('always_issue_new_refresh_token' => true, 'unset_refresh_token_after_use' => false));
-
- $server1->getTokenController();
- $refreshToken1 = $server1->getGrantType('refresh_token');
-
- $server2->getTokenController();
- $refreshToken2 = $server2->getGrantType('refresh_token');
-
- $reflection1 = new \ReflectionClass($refreshToken1);
- $prop1 = $reflection1->getProperty('config');
- $prop1->setAccessible(true);
-
- $reflection2 = new \ReflectionClass($refreshToken2);
- $prop2 = $reflection2->getProperty('config');
- $prop2->setAccessible(true);
-
- // get the private "config" property
- $config1 = $prop1->getValue($refreshToken1);
- $config2 = $prop2->getValue($refreshToken2);
-
- $this->assertEquals($config1['always_issue_new_refresh_token'], false);
- $this->assertEquals($config2['always_issue_new_refresh_token'], true);
-
- $this->assertEquals($config1['unset_refresh_token_after_use'], true);
- $this->assertEquals($config2['unset_refresh_token_after_use'], false);
- }
-
- /**
- * Test setting "always_issue_new_refresh_token" on a server level
- *
- * @see test/OAuth2/GrantType/RefreshTokenTest::testValidRefreshTokenWithNewRefreshTokenInResponse
- **/
- public function testValidRefreshTokenWithNewRefreshTokenInResponse()
- {
- $storage = Bootstrap::getInstance()->getMemoryStorage();
- $server = new Server($storage, array('always_issue_new_refresh_token' => true));
-
- $request = TestRequest::createPost(array(
- 'grant_type' => 'refresh_token', // valid grant type
- 'client_id' => 'Test Client ID', // valid client id
- 'client_secret' => 'TestSecret', // valid client secret
- 'refresh_token' => 'test-refreshtoken', // valid refresh token
- ));
- $token = $server->grantAccessToken($request, new Response());
- $this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
-
- $refresh_token = $storage->getRefreshToken($token['refresh_token']);
- $this->assertNotNull($refresh_token);
- $this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
- $this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
- $this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
- $used_token = $storage->getRefreshToken('test-refreshtoken');
- $this->assertFalse($used_token, 'the refresh token used is no longer valid');
- }
-
- /**
- * @expectedException InvalidArgumentException OAuth2\ResponseType\AuthorizationCodeInterface
- **/
- public function testAddingUnknownResponseTypeThrowsException()
- {
- $server = new Server();
- $server->addResponseType($this->getMock('OAuth2\ResponseType\ResponseTypeInterface'));
- }
-
- /**
- * @expectedException LogicException OAuth2\Storage\PublicKeyInterface
- **/
- public function testUsingJwtAccessTokensWithoutPublicKeyStorageThrowsException()
- {
- $server = new Server(array(), array('use_jwt_access_tokens' => true));
- $server->addGrantType($this->getMock('OAuth2\GrantType\GrantTypeInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
- $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
-
- $server->getTokenController();
- }
-
- public function testUsingJustJwtAccessTokenStorageWithResourceControllerIsOkay()
- {
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
-
- $this->assertNotNull($server->getResourceController());
- $this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
- }
-
- /**
- * @expectedException LogicException OAuth2\Storage\ClientInterface
- **/
- public function testUsingJustJwtAccessTokenStorageWithAuthorizeControllerThrowsException()
- {
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
- $this->assertNotNull($server->getAuthorizeController());
- }
-
- /**
- * @expectedException LogicException grant_types
- **/
- public function testUsingJustJwtAccessTokenStorageWithTokenControllerThrowsException()
- {
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
- $server->getTokenController();
- }
-
- public function testUsingJwtAccessTokenAndClientStorageWithAuthorizeControllerIsOkay()
- {
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $server = new Server(array($pubkey, $client), array('use_jwt_access_tokens' => true, 'allow_implicit' => true));
- $this->assertNotNull($server->getAuthorizeController());
-
- $this->assertInstanceOf('OAuth2\ResponseType\JwtAccessToken', $server->getResponseType('token'));
- }
-
- /**
- * @expectedException LogicException UserClaims
- **/
- public function testUsingOpenIDConnectWithoutUserClaimsThrowsException()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $server = new Server($client, array('use_openid_connect' => true));
-
- $server->getAuthorizeController();
- }
-
- /**
- * @expectedException LogicException PublicKeyInterface
- **/
- public function testUsingOpenIDConnectWithoutPublicKeyThrowsException()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OPenID\Storage\UserClaimsInterface');
- $server = new Server(array($client, $userclaims), array('use_openid_connect' => true));
-
- $server->getAuthorizeController();
- }
-
- /**
- * @expectedException LogicException issuer
- **/
- public function testUsingOpenIDConnectWithoutIssuerThrowsException()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($client, $userclaims, $pubkey), array('use_openid_connect' => true));
-
- $server->getAuthorizeController();
- }
-
- public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($client, $userclaims, $pubkey), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy',
- ));
-
- $server->getAuthorizeController();
-
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
- $this->assertNull($server->getResponseType('id_token token'));
- }
-
- /**
- * @expectedException LogicException OAuth2\ResponseType\AccessTokenInterface
- **/
- public function testUsingOpenIDConnectWithAllowImplicitWithoutTokenStorageThrowsException()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($client, $userclaims, $pubkey), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy',
- 'allow_implicit' => true,
- ));
-
- $server->getAuthorizeController();
- }
-
- public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOkay()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $server = new Server(array($client, $userclaims, $pubkey), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy',
- 'allow_implicit' => true,
- 'use_jwt_access_tokens' => true,
- ));
-
- $server->getAuthorizeController();
-
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
- }
-
- public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
- $server = new Server(array($client, $userclaims, $pubkey, $token), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy',
- 'allow_implicit' => true,
- ));
-
- $server->getAuthorizeController();
-
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
- }
-
- public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
- {
- $client = $this->getMock('OAuth2\Storage\ClientInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- // $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
- $server = new Server(array($client, $userclaims, $pubkey), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy',
- 'allow_implicit' => true,
- ));
-
- $token = $this->getMock('OAuth2\ResponseType\AccessTokenInterface');
- $server->addResponseType($token, 'token');
-
- $server->getAuthorizeController();
-
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
- $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
- }
-
- /**
- * @expectedException LogicException OAuth2\OpenID\Storage\AuthorizationCodeInterface
- **/
- public function testUsingOpenIDConnectWithAuthorizationCodeStorageThrowsException()
- {
- $client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
- $authcode = $this->getMock('OAuth2\Storage\AuthorizationCodeInterface');
-
- $server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy'
- ));
-
- $server->getTokenController();
-
- $this->assertInstanceOf('OAuth2\OpenID\GrantType\AuthorizationCode', $server->getGrantType('authorization_code'));
- }
-
- public function testUsingOpenIDConnectWithOpenIDAuthorizationCodeStorageCreatesOpenIDAuthorizationCodeGrantType()
- {
- $client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
- $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
- $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
- $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
- $authcode = $this->getMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
-
- $server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
- 'use_openid_connect' => true,
- 'issuer' => 'someguy'
- ));
-
- $server->getTokenController();
-
- $this->assertInstanceOf('OAuth2\OpenID\GrantType\AuthorizationCode', $server->getGrantType('authorization_code'));
- }
-
- public function testMultipleValuedResponseTypeOrderDoesntMatter()
- {
- $responseType = $this->getMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
- $server = new Server(array(), array(), array(), array(
- 'token id_token' => $responseType,
- ));
-
- $this->assertEquals($responseType, $server->getResponseType('id_token token'));
- }
-
- public function testAddGrantTypeWithoutKey()
- {
- $server = new Server();
- $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')));
-
- $grantTypes = $server->getGrantTypes();
- $this->assertEquals('authorization_code', key($grantTypes));
- }
-
- public function testAddGrantTypeWithKey()
- {
- $server = new Server();
- $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
-
- $grantTypes = $server->getGrantTypes();
- $this->assertEquals('ac', key($grantTypes));
- }
-
- public function testAddGrantTypeWithKeyNotString()
- {
- $server = new Server();
- $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
-
- $grantTypes = $server->getGrantTypes();
- $this->assertEquals('authorization_code', key($grantTypes));
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/AccessTokenTest.php b/library/oauth2/test/OAuth2/Storage/AccessTokenTest.php
deleted file mode 100644
index b34e0bfc0..000000000
--- a/library/oauth2/test/OAuth2/Storage/AccessTokenTest.php
+++ /dev/null
@@ -1,102 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // assert token we are about to add does not exist
- $token = $storage->getAccessToken('newtoken');
- $this->assertFalse($token);
-
- // add new token
- $expires = time() + 20;
- $success = $storage->setAccessToken('newtoken', 'client ID', 'SOMEUSERID', $expires);
- $this->assertTrue($success);
-
- $token = $storage->getAccessToken('newtoken');
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('client_id', $token);
- $this->assertArrayHasKey('user_id', $token);
- $this->assertArrayHasKey('expires', $token);
- $this->assertEquals($token['access_token'], 'newtoken');
- $this->assertEquals($token['client_id'], 'client ID');
- $this->assertEquals($token['user_id'], 'SOMEUSERID');
- $this->assertEquals($token['expires'], $expires);
-
- // change existing token
- $expires = time() + 42;
- $success = $storage->setAccessToken('newtoken', 'client ID2', 'SOMEOTHERID', $expires);
- $this->assertTrue($success);
-
- $token = $storage->getAccessToken('newtoken');
- $this->assertNotNull($token);
- $this->assertArrayHasKey('access_token', $token);
- $this->assertArrayHasKey('client_id', $token);
- $this->assertArrayHasKey('user_id', $token);
- $this->assertArrayHasKey('expires', $token);
- $this->assertEquals($token['access_token'], 'newtoken');
- $this->assertEquals($token['client_id'], 'client ID2');
- $this->assertEquals($token['user_id'], 'SOMEOTHERID');
- $this->assertEquals($token['expires'], $expires);
-
- // add token with scope having an empty string value
- $expires = time() + 42;
- $success = $storage->setAccessToken('newtoken', 'client ID', 'SOMEOTHERID', $expires, '');
- $this->assertTrue($success);
- }
-
- /** @dataProvider provideStorage */
- public function testUnsetAccessToken(AccessTokenInterface $storage)
- {
- if ($storage instanceof NullStorage || !method_exists($storage, 'unsetAccessToken')) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // assert token we are about to unset does not exist
- $token = $storage->getAccessToken('revokabletoken');
- $this->assertFalse($token);
-
- // add new token
- $expires = time() + 20;
- $success = $storage->setAccessToken('revokabletoken', 'client ID', 'SOMEUSERID', $expires);
- $this->assertTrue($success);
-
- // assert unsetAccessToken returns true
- $result = $storage->unsetAccessToken('revokabletoken');
- $this->assertTrue($result);
-
- // assert token we unset does not exist
- $token = $storage->getAccessToken('revokabletoken');
- $this->assertFalse($token);
- }
-
- /** @dataProvider provideStorage */
- public function testUnsetAccessTokenReturnsFalse(AccessTokenInterface $storage)
- {
- if ($storage instanceof NullStorage || !method_exists($storage, 'unsetAccessToken')) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // assert token we are about to unset does not exist
- $token = $storage->getAccessToken('nonexistanttoken');
- $this->assertFalse($token);
-
- // assert unsetAccessToken returns false
- $result = $storage->unsetAccessToken('nonexistanttoken');
- $this->assertFalse($result);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/AuthorizationCodeTest.php b/library/oauth2/test/OAuth2/Storage/AuthorizationCodeTest.php
deleted file mode 100644
index 2d901b501..000000000
--- a/library/oauth2/test/OAuth2/Storage/AuthorizationCodeTest.php
+++ /dev/null
@@ -1,106 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // nonexistant client_id
- $details = $storage->getAuthorizationCode('faketoken');
- $this->assertFalse($details);
-
- // valid client_id
- $details = $storage->getAuthorizationCode('testtoken');
- $this->assertNotNull($details);
- }
-
- /** @dataProvider provideStorage */
- public function testSetAuthorizationCode(AuthorizationCodeInterface $storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // assert code we are about to add does not exist
- $code = $storage->getAuthorizationCode('newcode');
- $this->assertFalse($code);
-
- // add new code
- $expires = time() + 20;
- $success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://example.com', $expires);
- $this->assertTrue($success);
-
- $code = $storage->getAuthorizationCode('newcode');
- $this->assertNotNull($code);
- $this->assertArrayHasKey('authorization_code', $code);
- $this->assertArrayHasKey('client_id', $code);
- $this->assertArrayHasKey('user_id', $code);
- $this->assertArrayHasKey('redirect_uri', $code);
- $this->assertArrayHasKey('expires', $code);
- $this->assertEquals($code['authorization_code'], 'newcode');
- $this->assertEquals($code['client_id'], 'client ID');
- $this->assertEquals($code['user_id'], 'SOMEUSERID');
- $this->assertEquals($code['redirect_uri'], 'http://example.com');
- $this->assertEquals($code['expires'], $expires);
-
- // change existing code
- $expires = time() + 42;
- $success = $storage->setAuthorizationCode('newcode', 'client ID2', 'SOMEOTHERID', 'http://example.org', $expires);
- $this->assertTrue($success);
-
- $code = $storage->getAuthorizationCode('newcode');
- $this->assertNotNull($code);
- $this->assertArrayHasKey('authorization_code', $code);
- $this->assertArrayHasKey('client_id', $code);
- $this->assertArrayHasKey('user_id', $code);
- $this->assertArrayHasKey('redirect_uri', $code);
- $this->assertArrayHasKey('expires', $code);
- $this->assertEquals($code['authorization_code'], 'newcode');
- $this->assertEquals($code['client_id'], 'client ID2');
- $this->assertEquals($code['user_id'], 'SOMEOTHERID');
- $this->assertEquals($code['redirect_uri'], 'http://example.org');
- $this->assertEquals($code['expires'], $expires);
-
- // add new code with scope having an empty string value
- $expires = time() + 20;
- $success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://example.com', $expires, '');
- $this->assertTrue($success);
- }
-
- /** @dataProvider provideStorage */
- public function testExpireAccessToken(AccessTokenInterface $storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // create a valid code
- $expires = time() + 20;
- $success = $storage->setAuthorizationCode('code-to-expire', 'client ID', 'SOMEUSERID', 'http://example.com', time() + 20);
- $this->assertTrue($success);
-
- // verify the new code exists
- $code = $storage->getAuthorizationCode('code-to-expire');
- $this->assertNotNull($code);
-
- $this->assertArrayHasKey('authorization_code', $code);
- $this->assertEquals($code['authorization_code'], 'code-to-expire');
-
- // now expire the code and ensure it's no longer available
- $storage->expireAuthorizationCode('code-to-expire');
- $code = $storage->getAuthorizationCode('code-to-expire');
- $this->assertFalse($code);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/ClientCredentialsTest.php b/library/oauth2/test/OAuth2/Storage/ClientCredentialsTest.php
deleted file mode 100644
index 15289af30..000000000
--- a/library/oauth2/test/OAuth2/Storage/ClientCredentialsTest.php
+++ /dev/null
@@ -1,28 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // nonexistant client_id
- $pass = $storage->checkClientCredentials('fakeclient', 'testpass');
- $this->assertFalse($pass);
-
- // invalid password
- $pass = $storage->checkClientCredentials('oauth_test_client', 'invalidcredentials');
- $this->assertFalse($pass);
-
- // valid credentials
- $pass = $storage->checkClientCredentials('oauth_test_client', 'testpass');
- $this->assertTrue($pass);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/ClientTest.php b/library/oauth2/test/OAuth2/Storage/ClientTest.php
deleted file mode 100644
index 6a5cc0b49..000000000
--- a/library/oauth2/test/OAuth2/Storage/ClientTest.php
+++ /dev/null
@@ -1,110 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // nonexistant client_id
- $details = $storage->getClientDetails('fakeclient');
- $this->assertFalse($details);
-
- // valid client_id
- $details = $storage->getClientDetails('oauth_test_client');
- $this->assertNotNull($details);
- $this->assertArrayHasKey('client_id', $details);
- $this->assertArrayHasKey('client_secret', $details);
- $this->assertArrayHasKey('redirect_uri', $details);
- }
-
- /** @dataProvider provideStorage */
- public function testCheckRestrictedGrantType(ClientInterface $storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // Check invalid
- $pass = $storage->checkRestrictedGrantType('oauth_test_client', 'authorization_code');
- $this->assertFalse($pass);
-
- // Check valid
- $pass = $storage->checkRestrictedGrantType('oauth_test_client', 'implicit');
- $this->assertTrue($pass);
- }
-
- /** @dataProvider provideStorage */
- public function testGetAccessToken(ClientInterface $storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // nonexistant client_id
- $details = $storage->getAccessToken('faketoken');
- $this->assertFalse($details);
-
- // valid client_id
- $details = $storage->getAccessToken('testtoken');
- $this->assertNotNull($details);
- }
-
- /** @dataProvider provideStorage */
- public function testIsPublicClient(ClientInterface $storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- $publicClientId = 'public-client-'.rand();
- $confidentialClientId = 'confidential-client-'.rand();
-
- // create a new client
- $success1 = $storage->setClientDetails($publicClientId, '');
- $success2 = $storage->setClientDetails($confidentialClientId, 'some-secret');
- $this->assertTrue($success1);
- $this->assertTrue($success2);
-
- // assert isPublicClient for both
- $this->assertTrue($storage->isPublicClient($publicClientId));
- $this->assertFalse($storage->isPublicClient($confidentialClientId));
- }
-
- /** @dataProvider provideStorage */
- public function testSaveClient(ClientInterface $storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- $clientId = 'some-client-'.rand();
-
- // create a new client
- $success = $storage->setClientDetails($clientId, 'somesecret', 'http://test.com', 'client_credentials', 'clientscope1', 'brent@brentertainment.com');
- $this->assertTrue($success);
-
- // valid client_id
- $details = $storage->getClientDetails($clientId);
- $this->assertEquals($details['client_secret'], 'somesecret');
- $this->assertEquals($details['redirect_uri'], 'http://test.com');
- $this->assertEquals($details['grant_types'], 'client_credentials');
- $this->assertEquals($details['scope'], 'clientscope1');
- $this->assertEquals($details['user_id'], 'brent@brentertainment.com');
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/DynamoDBTest.php b/library/oauth2/test/OAuth2/Storage/DynamoDBTest.php
deleted file mode 100644
index 2147f0914..000000000
--- a/library/oauth2/test/OAuth2/Storage/DynamoDBTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-getMockBuilder('\Aws\DynamoDb\DynamoDbClient')
- ->disableOriginalConstructor()
- ->setMethods(array('query'))
- ->getMock();
-
- $return = $this->getMockBuilder('\Guzzle\Service\Resource\Model')
- ->setMethods(array('count', 'toArray'))
- ->getMock();
-
- $data = array(
- 'Items' => array(),
- 'Count' => 0,
- 'ScannedCount'=> 0
- );
-
- $return->expects($this->once())
- ->method('count')
- ->will($this->returnValue(count($data)));
-
- $return->expects($this->once())
- ->method('toArray')
- ->will($this->returnValue($data));
-
- // should return null default scope if none is set in database
- $client->expects($this->once())
- ->method('query')
- ->will($this->returnValue($return));
-
- $storage = new DynamoDB($client);
- $this->assertNull($storage->getDefaultScope());
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/JwtAccessTokenTest.php b/library/oauth2/test/OAuth2/Storage/JwtAccessTokenTest.php
deleted file mode 100644
index a6acbea1f..000000000
--- a/library/oauth2/test/OAuth2/Storage/JwtAccessTokenTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-getMemoryStorage();
- $encryptionUtil = new Jwt();
-
- $jwtAccessToken = array(
- 'access_token' => rand(),
- 'expires' => time() + 100,
- 'scope' => 'foo',
- );
-
- $token = $encryptionUtil->encode($jwtAccessToken, $storage->getPrivateKey(), $storage->getEncryptionAlgorithm());
-
- $this->assertNotNull($token);
-
- $tokenData = $crypto->getAccessToken($token);
-
- $this->assertTrue(is_array($tokenData));
-
- /* assert the decoded token is the same */
- $this->assertEquals($tokenData['access_token'], $jwtAccessToken['access_token']);
- $this->assertEquals($tokenData['expires'], $jwtAccessToken['expires']);
- $this->assertEquals($tokenData['scope'], $jwtAccessToken['scope']);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/JwtBearerTest.php b/library/oauth2/test/OAuth2/Storage/JwtBearerTest.php
deleted file mode 100644
index d0ab9b899..000000000
--- a/library/oauth2/test/OAuth2/Storage/JwtBearerTest.php
+++ /dev/null
@@ -1,25 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // nonexistant client_id
- $key = $storage->getClientKey('this-is-not-real', 'nor-is-this');
- $this->assertFalse($key);
-
- // valid client_id and subject
- $key = $storage->getClientKey('oauth_test_client', 'test_subject');
- $this->assertNotNull($key);
- $this->assertEquals($key, Bootstrap::getInstance()->getTestPublicKey());
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/PdoTest.php b/library/oauth2/test/OAuth2/Storage/PdoTest.php
deleted file mode 100644
index 57eb39072..000000000
--- a/library/oauth2/test/OAuth2/Storage/PdoTest.php
+++ /dev/null
@@ -1,39 +0,0 @@
-getSqliteDir()));
- $storage = new Pdo($pdo);
-
- $this->assertNotNull($storage->getClientDetails('oauth_test_client'));
- }
-
- public function testCreatePdoStorageUsingDSN()
- {
- $dsn = sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir());
- $storage = new Pdo($dsn);
-
- $this->assertNotNull($storage->getClientDetails('oauth_test_client'));
- }
-
- public function testCreatePdoStorageUsingConfig()
- {
- $config = array('dsn' => sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir()));
- $storage = new Pdo($config);
-
- $this->assertNotNull($storage->getClientDetails('oauth_test_client'));
- }
-
- /**
- * @expectedException InvalidArgumentException dsn
- */
- public function testCreatePdoStorageWithoutDSNThrowsException()
- {
- $config = array('username' => 'brent', 'password' => 'brentisaballer');
- $storage = new Pdo($config);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/PublicKeyTest.php b/library/oauth2/test/OAuth2/Storage/PublicKeyTest.php
deleted file mode 100644
index f85195870..000000000
--- a/library/oauth2/test/OAuth2/Storage/PublicKeyTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- if (!$storage instanceof PublicKeyInterface) {
- // incompatible storage
- return;
- }
-
- $configDir = Bootstrap::getInstance()->getConfigDir();
- $globalPublicKey = file_get_contents($configDir.'/keys/id_rsa.pub');
- $globalPrivateKey = file_get_contents($configDir.'/keys/id_rsa');
-
- /* assert values from storage */
- $this->assertEquals($storage->getPublicKey(), $globalPublicKey);
- $this->assertEquals($storage->getPrivateKey(), $globalPrivateKey);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/RefreshTokenTest.php b/library/oauth2/test/OAuth2/Storage/RefreshTokenTest.php
deleted file mode 100644
index 314c93195..000000000
--- a/library/oauth2/test/OAuth2/Storage/RefreshTokenTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // assert token we are about to add does not exist
- $token = $storage->getRefreshToken('refreshtoken');
- $this->assertFalse($token);
-
- // add new token
- $expires = time() + 20;
- $success = $storage->setRefreshToken('refreshtoken', 'client ID', 'SOMEUSERID', $expires);
- $this->assertTrue($success);
-
- $token = $storage->getRefreshToken('refreshtoken');
- $this->assertNotNull($token);
- $this->assertArrayHasKey('refresh_token', $token);
- $this->assertArrayHasKey('client_id', $token);
- $this->assertArrayHasKey('user_id', $token);
- $this->assertArrayHasKey('expires', $token);
- $this->assertEquals($token['refresh_token'], 'refreshtoken');
- $this->assertEquals($token['client_id'], 'client ID');
- $this->assertEquals($token['user_id'], 'SOMEUSERID');
- $this->assertEquals($token['expires'], $expires);
-
- // add token with scope having an empty string value
- $expires = time() + 20;
- $success = $storage->setRefreshToken('refreshtoken2', 'client ID', 'SOMEUSERID', $expires, '');
- $this->assertTrue($success);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/ScopeTest.php b/library/oauth2/test/OAuth2/Storage/ScopeTest.php
deleted file mode 100644
index fd1edeb93..000000000
--- a/library/oauth2/test/OAuth2/Storage/ScopeTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- if (!$storage instanceof ScopeInterface) {
- // incompatible storage
- return;
- }
-
- //Test getting scopes
- $scopeUtil = new Scope($storage);
- $this->assertTrue($scopeUtil->scopeExists('supportedscope1'));
- $this->assertTrue($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3'));
- $this->assertFalse($scopeUtil->scopeExists('fakescope'));
- $this->assertFalse($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3 fakescope'));
- }
-
- /** @dataProvider provideStorage */
- public function testGetDefaultScope($storage)
- {
- if ($storage instanceof NullStorage) {
- $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- if (!$storage instanceof ScopeInterface) {
- // incompatible storage
- return;
- }
-
- // test getting default scope
- $scopeUtil = new Scope($storage);
- $expected = explode(' ', $scopeUtil->getDefaultScope());
- $actual = explode(' ', 'defaultscope1 defaultscope2');
- sort($expected);
- sort($actual);
- $this->assertEquals($expected, $actual);
- }
-}
diff --git a/library/oauth2/test/OAuth2/Storage/UserCredentialsTest.php b/library/oauth2/test/OAuth2/Storage/UserCredentialsTest.php
deleted file mode 100644
index 65655a6b2..000000000
--- a/library/oauth2/test/OAuth2/Storage/UserCredentialsTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-markTestSkipped('Skipped Storage: ' . $storage->getMessage());
-
- return;
- }
-
- // create a new user for testing
- $success = $storage->setUser('testusername', 'testpass', 'Test', 'User');
- $this->assertTrue($success);
-
- // correct credentials
- $this->assertTrue($storage->checkUserCredentials('testusername', 'testpass'));
- // invalid password
- $this->assertFalse($storage->checkUserCredentials('testusername', 'fakepass'));
- // invalid username
- $this->assertFalse($storage->checkUserCredentials('fakeusername', 'testpass'));
-
- // invalid username
- $this->assertFalse($storage->getUserDetails('fakeusername'));
-
- // ensure all properties are set
- $user = $storage->getUserDetails('testusername');
- $this->assertTrue($user !== false);
- $this->assertArrayHasKey('user_id', $user);
- $this->assertArrayHasKey('first_name', $user);
- $this->assertArrayHasKey('last_name', $user);
- $this->assertEquals($user['user_id'], 'testusername');
- $this->assertEquals($user['first_name'], 'Test');
- $this->assertEquals($user['last_name'], 'User');
- }
-}
diff --git a/library/oauth2/test/OAuth2/TokenType/BearerTest.php b/library/oauth2/test/OAuth2/TokenType/BearerTest.php
deleted file mode 100644
index a2e000e22..000000000
--- a/library/oauth2/test/OAuth2/TokenType/BearerTest.php
+++ /dev/null
@@ -1,58 +0,0 @@
- 'ThisIsMyAccessToken'
- ));
- $request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
-
- $param = $bearer->getAccessTokenParameter($request, $response = new Response());
- $this->assertEquals($param, 'ThisIsMyAccessToken');
- }
-
- public function testInvalidContentType()
- {
- $bearer = new Bearer();
- $request = TestRequest::createPost(array(
- 'access_token' => 'ThisIsMyAccessToken'
- ));
- $request->server['CONTENT_TYPE'] = 'application/json; charset=UTF-8';
-
- $param = $bearer->getAccessTokenParameter($request, $response = new Response());
- $this->assertNull($param);
- $this->assertEquals($response->getStatusCode(), 400);
- $this->assertEquals($response->getParameter('error'), 'invalid_request');
- $this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
- }
-
- public function testValidRequestUsingAuthorizationHeader()
- {
- $bearer = new Bearer();
- $request = new TestRequest();
- $request->headers['AUTHORIZATION'] = 'Bearer MyToken';
- $request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
-
- $param = $bearer->getAccessTokenParameter($request, $response = new Response());
- $this->assertEquals('MyToken', $param);
- }
-
- public function testValidRequestUsingAuthorizationHeaderCaseInsensitive()
- {
- $bearer = new Bearer();
- $request = new TestRequest();
- $request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
- $request->headers['Authorization'] = 'Bearer MyToken';
-
- $param = $bearer->getAccessTokenParameter($request, $response = new Response());
- $this->assertEquals('MyToken', $param);
- }
-}
diff --git a/library/oauth2/test/bootstrap.php b/library/oauth2/test/bootstrap.php
deleted file mode 100644
index 0a4af0716..000000000
--- a/library/oauth2/test/bootstrap.php
+++ /dev/null
@@ -1,12 +0,0 @@
-cleanupTravisDynamoDb();
diff --git a/library/oauth2/test/config/keys/id_rsa b/library/oauth2/test/config/keys/id_rsa
deleted file mode 100644
index e8b9eff2d..000000000
--- a/library/oauth2/test/config/keys/id_rsa
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLsNjP+uAt2eO0cc5J9H5XV
-8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdwizIum8j0KzpsGYH5qReN
-QDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJuBe+FQpZTs8DewwIDAQAB
-AoGARfNxNknmtx/n1bskZ/01iZRzAge6BLEE0LV6Q4gS7mkRZu/Oyiv39Sl5vUlA
-+WdGxLjkBwKNjxGN8Vxw9/ASd8rSsqeAUYIwAeifXrHhj5DBPQT/pDPkeFnp9B1w
-C6jo+3AbBQ4/b0ONSIEnCL2xGGglSIAxO17T1ViXp7lzXPECQQDe63nkRdWM0OCb
-oaHQPT3E26224maIstrGFUdt9yw3yJf4bOF7TtiPLlLuHsTTge3z+fG6ntC0xG56
-1cl37C3ZAkEA2HdVcRGugNp/qmVz4LJTpD+WZKi73PLAO47wDOrYh9Pn2I6fcEH0
-CPnggt1ko4ujvGzFTvRH64HXa6aPCv1j+wJBAMQMah3VQPNf/DlDVFEUmw9XeBZg
-VHaifX851aEjgXLp6qVj9IYCmLiLsAmVa9rr6P7p8asD418nZlaHUHE0eDkCQQCr
-uxis6GMx1Ka971jcJX2X696LoxXPd0KsvXySMupv79yagKPa8mgBiwPjrnK+EPVo
-cj6iochA/bSCshP/mwFrAkBHEKPi6V6gb94JinCT7x3weahbdp6bJ6/nzBH/p9VA
-HoT1JtwNFhGv9BCjmDydshQHfSWpY9NxlccBKL7ITm8R
------END RSA PRIVATE KEY-----
\ No newline at end of file
diff --git a/library/oauth2/test/config/keys/id_rsa.pub b/library/oauth2/test/config/keys/id_rsa.pub
deleted file mode 100644
index 1ac15f5eb..000000000
--- a/library/oauth2/test/config/keys/id_rsa.pub
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgIBADANBgkqhkiG9w0BAQQFADA9MQswCQYDVQQGEwJVUzEL
-MAkGA1UECBMCVVQxITAfBgNVBAoTGFZpZ25ldHRlIENvcnBvcmF0aW9uIFNCWDAe
-Fw0xMTEwMTUwMzE4MjdaFw0zMTEwMTAwMzE4MjdaMD0xCzAJBgNVBAYTAlVTMQsw
-CQYDVQQIEwJVVDEhMB8GA1UEChMYVmlnbmV0dGUgQ29ycG9yYXRpb24gU0JYMIGf
-MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLs
-NjP+uAt2eO0cc5J9H5XV8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdw
-izIum8j0KzpsGYH5qReNQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJu
-Be+FQpZTs8DewwIDAQABo4GXMIGUMB0GA1UdDgQWBBRe8hrEXm+Yim4YlD5Nx+1K
-vCYs9DBlBgNVHSMEXjBcgBRe8hrEXm+Yim4YlD5Nx+1KvCYs9KFBpD8wPTELMAkG
-A1UEBhMCVVMxCzAJBgNVBAgTAlVUMSEwHwYDVQQKExhWaWduZXR0ZSBDb3Jwb3Jh
-dGlvbiBTQliCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBjhyRD
-lM7vnLn6drgQVftW5V9nDFAyPAuiGvMIKFSbiAf1PxXCRn5sfJquwWKsJUi4ZGNl
-aViXdFmN6/F13PSM+yg63tpKy0fYqMbTM+Oe5WuSHkSW1VuYNHV+24adgNk/FRDL
-FRrlM1f6s9VTLWvwGItjfrof0Ba8Uq7ZDSb9Xg==
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/library/oauth2/test/config/storage.json b/library/oauth2/test/config/storage.json
deleted file mode 100644
index a31d3bca2..000000000
--- a/library/oauth2/test/config/storage.json
+++ /dev/null
@@ -1,181 +0,0 @@
-{
- "authorization_codes": {
- "testcode": {
- "client_id": "Test Client ID",
- "user_id": "",
- "redirect_uri": "",
- "expires": "9999999999",
- "id_token": "IDTOKEN"
- },
- "testcode-with-scope": {
- "client_id": "Test Client ID",
- "user_id": "",
- "redirect_uri": "",
- "expires": "9999999999",
- "scope": "scope1 scope2"
- },
- "testcode-expired": {
- "client_id": "Test Client ID",
- "user_id": "",
- "redirect_uri": "",
- "expires": "1356998400"
- },
- "testcode-empty-secret": {
- "client_id": "Test Client ID Empty Secret",
- "user_id": "",
- "redirect_uri": "",
- "expires": "9999999999"
- },
- "testcode-openid": {
- "client_id": "Test Client ID",
- "user_id": "",
- "redirect_uri": "",
- "expires": "9999999999",
- "id_token": "test_id_token"
- }
- },
- "client_credentials" : {
- "Test Client ID": {
- "client_secret": "TestSecret"
- },
- "Test Client ID with Redirect Uri": {
- "client_secret": "TestSecret2",
- "redirect_uri": "http://brentertainment.com"
- },
- "Test Client ID with Buggy Redirect Uri": {
- "client_secret": "TestSecret2",
- "redirect_uri": " http://brentertainment.com"
- },
- "Test Client ID with Multiple Redirect Uris": {
- "client_secret": "TestSecret3",
- "redirect_uri": "http://brentertainment.com http://morehazards.com"
- },
- "Test Client ID with Redirect Uri Parts": {
- "client_secret": "TestSecret4",
- "redirect_uri": "http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true"
- },
- "Test Some Other Client": {
- "client_secret": "TestSecret3"
- },
- "Test Client ID Empty Secret": {
- "client_secret": ""
- },
- "Test Client ID For Password Grant": {
- "grant_types": "password",
- "client_secret": ""
- },
- "Client ID With User ID": {
- "client_secret": "TestSecret",
- "user_id": "brent@brentertainment.com"
- },
- "oauth_test_client": {
- "client_secret": "testpass",
- "grant_types": "implicit password"
- }
- },
- "user_credentials" : {
- "test-username": {
- "password": "testpass"
- },
- "testusername": {
- "password": "testpass"
- },
- "testuser": {
- "password": "password",
- "email": "testuser@test.com",
- "email_verified": true
- },
- "johndoe": {
- "password": "password"
- }
- },
- "refresh_tokens" : {
- "test-refreshtoken": {
- "refresh_token": "test-refreshtoken",
- "client_id": "Test Client ID",
- "user_id": "test-username",
- "expires": 0,
- "scope": null
- },
- "test-refreshtoken-with-scope": {
- "refresh_token": "test-refreshtoken",
- "client_id": "Test Client ID",
- "user_id": "test-username",
- "expires": 0,
- "scope": "scope1 scope2"
- }
- },
- "access_tokens" : {
- "accesstoken-expired": {
- "access_token": "accesstoken-expired",
- "client_id": "Test Client ID",
- "expires": 1234567,
- "scope": null
- },
- "accesstoken-scope": {
- "access_token": "accesstoken-scope",
- "client_id": "Test Client ID",
- "expires": 99999999900,
- "scope": "testscope"
- },
- "accesstoken-openid-connect": {
- "access_token": "accesstoken-openid-connect",
- "client_id": "Test Client ID",
- "user_id": "testuser",
- "expires": 99999999900,
- "scope": "openid email"
- },
- "accesstoken-malformed": {
- "access_token": "accesstoken-mallformed",
- "expires": 99999999900,
- "scope": "testscope"
- }
- },
- "jwt": {
- "Test Client ID": {
- "key": "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5/SxVlE8gnpFqCxgl2wjhzY7u\ncEi00s0kUg3xp7lVEvgLgYcAnHiWp+gtSjOFfH2zsvpiWm6Lz5f743j/FEzHIO1o\nwR0p4d9pOaJK07d01+RzoQLOIQAgXrr4T1CCWUesncwwPBVCyy2Mw3Nmhmr9MrF8\nUlvdRKBxriRnlP3qJQIDAQAB\n-----END PUBLIC KEY-----",
- "subject": "testuser@ourdomain.com"
- },
- "Test Client ID PHP-5.2": {
- "key": "mysecretkey",
- "subject": "testuser@ourdomain.com"
- },
- "Missing Key Client": {
- "key": null,
- "subject": "testuser@ourdomain.com"
- },
- "Missing Key Client PHP-5.2": {
- "key": null,
- "subject": "testuser@ourdomain.com"
- },
- "oauth_test_client": {
- "key": "-----BEGIN CERTIFICATE-----\nMIICiDCCAfGgAwIBAgIBADANBgkqhkiG9w0BAQQFADA9MQswCQYDVQQGEwJVUzEL\nMAkGA1UECBMCVVQxITAfBgNVBAoTGFZpZ25ldHRlIENvcnBvcmF0aW9uIFNCWDAe\nFw0xMTEwMTUwMzE4MjdaFw0zMTEwMTAwMzE4MjdaMD0xCzAJBgNVBAYTAlVTMQsw\nCQYDVQQIEwJVVDEhMB8GA1UEChMYVmlnbmV0dGUgQ29ycG9yYXRpb24gU0JYMIGf\nMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLs\nNjP+uAt2eO0cc5J9H5XV8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdw\nizIum8j0KzpsGYH5qReNQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJu\nBe+FQpZTs8DewwIDAQABo4GXMIGUMB0GA1UdDgQWBBRe8hrEXm+Yim4YlD5Nx+1K\nvCYs9DBlBgNVHSMEXjBcgBRe8hrEXm+Yim4YlD5Nx+1KvCYs9KFBpD8wPTELMAkG\nA1UEBhMCVVMxCzAJBgNVBAgTAlVUMSEwHwYDVQQKExhWaWduZXR0ZSBDb3Jwb3Jh\ndGlvbiBTQliCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBjhyRD\nlM7vnLn6drgQVftW5V9nDFAyPAuiGvMIKFSbiAf1PxXCRn5sfJquwWKsJUi4ZGNl\naViXdFmN6/F13PSM+yg63tpKy0fYqMbTM+Oe5WuSHkSW1VuYNHV+24adgNk/FRDL\nFRrlM1f6s9VTLWvwGItjfrof0Ba8Uq7ZDSb9Xg==\n-----END CERTIFICATE-----",
- "subject": "test_subject"
- }
- },
- "jti": [
- {
- "issuer": "Test Client ID",
- "subject": "testuser@ourdomain.com",
- "audience": "http://myapp.com/oauth/auth",
- "expires": 99999999900,
- "jti": "used_jti"
- }
- ],
- "supported_scopes" : [
- "scope1",
- "scope2",
- "scope3",
- "clientscope1",
- "clientscope2",
- "clientscope3",
- "supportedscope1",
- "supportedscope2",
- "supportedscope3",
- "supportedscope4"
- ],
- "keys": {
- "public_key": "-----BEGIN CERTIFICATE-----\nMIICiDCCAfGgAwIBAgIBADANBgkqhkiG9w0BAQQFADA9MQswCQYDVQQGEwJVUzEL\nMAkGA1UECBMCVVQxITAfBgNVBAoTGFZpZ25ldHRlIENvcnBvcmF0aW9uIFNCWDAe\nFw0xMTEwMTUwMzE4MjdaFw0zMTEwMTAwMzE4MjdaMD0xCzAJBgNVBAYTAlVTMQsw\nCQYDVQQIEwJVVDEhMB8GA1UEChMYVmlnbmV0dGUgQ29ycG9yYXRpb24gU0JYMIGf\nMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLs\nNjP+uAt2eO0cc5J9H5XV8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdw\nizIum8j0KzpsGYH5qReNQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJu\nBe+FQpZTs8DewwIDAQABo4GXMIGUMB0GA1UdDgQWBBRe8hrEXm+Yim4YlD5Nx+1K\nvCYs9DBlBgNVHSMEXjBcgBRe8hrEXm+Yim4YlD5Nx+1KvCYs9KFBpD8wPTELMAkG\nA1UEBhMCVVMxCzAJBgNVBAgTAlVUMSEwHwYDVQQKExhWaWduZXR0ZSBDb3Jwb3Jh\ndGlvbiBTQliCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBjhyRD\nlM7vnLn6drgQVftW5V9nDFAyPAuiGvMIKFSbiAf1PxXCRn5sfJquwWKsJUi4ZGNl\naViXdFmN6/F13PSM+yg63tpKy0fYqMbTM+Oe5WuSHkSW1VuYNHV+24adgNk/FRDL\nFRrlM1f6s9VTLWvwGItjfrof0Ba8Uq7ZDSb9Xg==\n-----END CERTIFICATE-----",
- "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLsNjP+uAt2eO0cc5J9H5XV\n8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdwizIum8j0KzpsGYH5qReN\nQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJuBe+FQpZTs8DewwIDAQAB\nAoGARfNxNknmtx/n1bskZ/01iZRzAge6BLEE0LV6Q4gS7mkRZu/Oyiv39Sl5vUlA\n+WdGxLjkBwKNjxGN8Vxw9/ASd8rSsqeAUYIwAeifXrHhj5DBPQT/pDPkeFnp9B1w\nC6jo+3AbBQ4/b0ONSIEnCL2xGGglSIAxO17T1ViXp7lzXPECQQDe63nkRdWM0OCb\noaHQPT3E26224maIstrGFUdt9yw3yJf4bOF7TtiPLlLuHsTTge3z+fG6ntC0xG56\n1cl37C3ZAkEA2HdVcRGugNp/qmVz4LJTpD+WZKi73PLAO47wDOrYh9Pn2I6fcEH0\nCPnggt1ko4ujvGzFTvRH64HXa6aPCv1j+wJBAMQMah3VQPNf/DlDVFEUmw9XeBZg\nVHaifX851aEjgXLp6qVj9IYCmLiLsAmVa9rr6P7p8asD418nZlaHUHE0eDkCQQCr\nuxis6GMx1Ka971jcJX2X696LoxXPd0KsvXySMupv79yagKPa8mgBiwPjrnK+EPVo\ncj6iochA/bSCshP/mwFrAkBHEKPi6V6gb94JinCT7x3weahbdp6bJ6/nzBH/p9VA\nHoT1JtwNFhGv9BCjmDydshQHfSWpY9NxlccBKL7ITm8R\n-----END RSA PRIVATE KEY-----"
- }
-}
diff --git a/library/oauth2/test/lib/OAuth2/Request/TestRequest.php b/library/oauth2/test/lib/OAuth2/Request/TestRequest.php
deleted file mode 100644
index 7bbce28a4..000000000
--- a/library/oauth2/test/lib/OAuth2/Request/TestRequest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-query = $_GET;
- $this->request = $_POST;
- $this->server = $_SERVER;
- $this->headers = array();
- }
-
- public function query($name, $default = null)
- {
- return isset($this->query[$name]) ? $this->query[$name] : $default;
- }
-
- public function request($name, $default = null)
- {
- return isset($this->request[$name]) ? $this->request[$name] : $default;
- }
-
- public function server($name, $default = null)
- {
- return isset($this->server[$name]) ? $this->server[$name] : $default;
- }
-
- public function getAllQueryParameters()
- {
- return $this->query;
- }
-
- public function setQuery(array $query)
- {
- $this->query = $query;
- }
-
- public function setPost(array $params)
- {
- $this->server['REQUEST_METHOD'] = 'POST';
- $this->request = $params;
- }
-
- public static function createPost(array $params = array())
- {
- $request = new self();
- $request->setPost($params);
-
- return $request;
- }
-}
diff --git a/library/oauth2/test/lib/OAuth2/Storage/BaseTest.php b/library/oauth2/test/lib/OAuth2/Storage/BaseTest.php
deleted file mode 100755
index 921d52500..000000000
--- a/library/oauth2/test/lib/OAuth2/Storage/BaseTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-getMemoryStorage();
- $sqlite = Bootstrap::getInstance()->getSqlitePdo();
- $mysql = Bootstrap::getInstance()->getMysqlPdo();
- $postgres = Bootstrap::getInstance()->getPostgresPdo();
- $mongo = Bootstrap::getInstance()->getMongo();
- $redis = Bootstrap::getInstance()->getRedisStorage();
- $cassandra = Bootstrap::getInstance()->getCassandraStorage();
- $dynamodb = Bootstrap::getInstance()->getDynamoDbStorage();
- $couchbase = Bootstrap::getInstance()->getCouchbase();
-
- /* hack until we can fix "default_scope" dependencies in other tests */
- $memory->defaultScope = 'defaultscope1 defaultscope2';
-
- return array(
- array($memory),
- array($sqlite),
- array($mysql),
- array($postgres),
- array($mongo),
- array($redis),
- array($cassandra),
- array($dynamodb),
- array($couchbase),
- );
- }
-}
diff --git a/library/oauth2/test/lib/OAuth2/Storage/Bootstrap.php b/library/oauth2/test/lib/OAuth2/Storage/Bootstrap.php
deleted file mode 100755
index 4ac9022b1..000000000
--- a/library/oauth2/test/lib/OAuth2/Storage/Bootstrap.php
+++ /dev/null
@@ -1,888 +0,0 @@
-configDir = __DIR__.'/../../../config';
- }
-
- public static function getInstance()
- {
- if (!self::$instance) {
- self::$instance = new self();
- }
-
- return self::$instance;
- }
-
- public function getSqlitePdo()
- {
- if (!$this->sqlite) {
- $this->removeSqliteDb();
- $pdo = new \PDO(sprintf('sqlite://%s', $this->getSqliteDir()));
- $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
- $this->createSqliteDb($pdo);
-
- $this->sqlite = new Pdo($pdo);
- }
-
- return $this->sqlite;
- }
-
- public function getPostgresPdo()
- {
- if (!$this->postgres) {
- if (in_array('pgsql', \PDO::getAvailableDrivers())) {
- $this->removePostgresDb();
- $this->createPostgresDb();
- if ($pdo = $this->getPostgresDriver()) {
- $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
- $this->populatePostgresDb($pdo);
- $this->postgres = new Pdo($pdo);
- }
- } else {
- $this->postgres = new NullStorage('Postgres', 'Missing postgres PDO extension.');
- }
- }
-
- return $this->postgres;
- }
-
- public function getPostgresDriver()
- {
- try {
- $pdo = new \PDO('pgsql:host=localhost;dbname=oauth2_server_php', 'postgres');
-
- return $pdo;
- } catch (\PDOException $e) {
- $this->postgres = new NullStorage('Postgres', $e->getMessage());
- }
- }
-
- public function getMemoryStorage()
- {
- return new Memory(json_decode(file_get_contents($this->configDir. '/storage.json'), true));
- }
-
- public function getRedisStorage()
- {
- if (!$this->redis) {
- if (class_exists('Predis\Client')) {
- $redis = new \Predis\Client();
- if ($this->testRedisConnection($redis)) {
- $redis->flushdb();
- $this->redis = new Redis($redis);
- $this->createRedisDb($this->redis);
- } else {
- $this->redis = new NullStorage('Redis', 'Unable to connect to redis server on port 6379');
- }
- } else {
- $this->redis = new NullStorage('Redis', 'Missing redis library. Please run "composer.phar require predis/predis:dev-master"');
- }
- }
-
- return $this->redis;
- }
-
- private function testRedisConnection(\Predis\Client $redis)
- {
- try {
- $redis->connect();
- } catch (\Predis\CommunicationException $exception) {
- // we were unable to connect to the redis server
- return false;
- }
-
- return true;
- }
-
- public function getMysqlPdo()
- {
- if (!$this->mysql) {
- $pdo = null;
- try {
- $pdo = new \PDO('mysql:host=localhost;', 'root');
- } catch (\PDOException $e) {
- $this->mysql = new NullStorage('MySQL', 'Unable to connect to MySQL on root@localhost');
- }
-
- if ($pdo) {
- $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
- $this->removeMysqlDb($pdo);
- $this->createMysqlDb($pdo);
-
- $this->mysql = new Pdo($pdo);
- }
- }
-
- return $this->mysql;
- }
-
- public function getMongo()
- {
- if (!$this->mongo) {
- $skipMongo = $this->getEnvVar('SKIP_MONGO_TESTS');
- if (!$skipMongo && class_exists('MongoClient')) {
- $mongo = new \MongoClient('mongodb://localhost:27017', array('connect' => false));
- if ($this->testMongoConnection($mongo)) {
- $db = $mongo->oauth2_server_php;
- $this->removeMongoDb($db);
- $this->createMongoDb($db);
-
- $this->mongo = new Mongo($db);
- } else {
- $this->mongo = new NullStorage('Mongo', 'Unable to connect to mongo server on "localhost:27017"');
- }
- } else {
- $this->mongo = new NullStorage('Mongo', 'Missing mongo php extension. Please install mongo.so');
- }
- }
-
- return $this->mongo;
- }
-
- private function testMongoConnection(\MongoClient $mongo)
- {
- try {
- $mongo->connect();
- } catch (\MongoConnectionException $e) {
- return false;
- }
-
- return true;
- }
-
- public function getCouchbase()
- {
- if (!$this->couchbase) {
- if ($this->getEnvVar('SKIP_COUCHBASE_TESTS')) {
- $this->couchbase = new NullStorage('Couchbase', 'Skipping Couchbase tests');
- } elseif (!class_exists('Couchbase')) {
- $this->couchbase = new NullStorage('Couchbase', 'Missing Couchbase php extension. Please install couchbase.so');
- } else {
- // round-about way to make sure couchbase is working
- // this is required because it throws a "floating point exception" otherwise
- $code = "new \Couchbase(array('localhost:8091'), '', '', 'auth', false);";
- $exec = sprintf('php -r "%s"', $code);
- $ret = exec($exec, $test, $var);
- if ($ret != 0) {
- $couchbase = new \Couchbase(array('localhost:8091'), '', '', 'auth', false);
- if ($this->testCouchbaseConnection($couchbase)) {
- $this->clearCouchbase($couchbase);
- $this->createCouchbaseDB($couchbase);
-
- $this->couchbase = new CouchbaseDB($couchbase);
- } else {
- $this->couchbase = new NullStorage('Couchbase', 'Unable to connect to Couchbase server on "localhost:8091"');
- }
- } else {
- $this->couchbase = new NullStorage('Couchbase', 'Error while trying to connect to Couchbase');
- }
- }
- }
-
- return $this->couchbase;
- }
-
- private function testCouchbaseConnection(\Couchbase $couchbase)
- {
- try {
- if (count($couchbase->getServers()) > 0) {
- return true;
- }
- } catch (\CouchbaseException $e) {
- return false;
- }
-
- return true;
- }
-
- public function getCassandraStorage()
- {
- if (!$this->cassandra) {
- if (class_exists('phpcassa\ColumnFamily')) {
- $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_test', array('127.0.0.1:9160'));
- if ($this->testCassandraConnection($cassandra)) {
- $this->removeCassandraDb();
- $this->cassandra = new Cassandra($cassandra);
- $this->createCassandraDb($this->cassandra);
- } else {
- $this->cassandra = new NullStorage('Cassandra', 'Unable to connect to cassandra server on "127.0.0.1:9160"');
- }
- } else {
- $this->cassandra = new NullStorage('Cassandra', 'Missing cassandra library. Please run "composer.phar require thobbs/phpcassa:dev-master"');
- }
- }
-
- return $this->cassandra;
- }
-
- private function testCassandraConnection(\phpcassa\Connection\ConnectionPool $cassandra)
- {
- try {
- new \phpcassa\SystemManager('localhost:9160');
- } catch (\Exception $e) {
- return false;
- }
-
- return true;
- }
-
- private function removeCassandraDb()
- {
- $sys = new \phpcassa\SystemManager('localhost:9160');
-
- try {
- $sys->drop_keyspace('oauth2_test');
- } catch (\cassandra\InvalidRequestException $e) {
-
- }
- }
-
- private function createCassandraDb(Cassandra $storage)
- {
- // create the cassandra keyspace and column family
- $sys = new \phpcassa\SystemManager('localhost:9160');
-
- $sys->create_keyspace('oauth2_test', array(
- "strategy_class" => \phpcassa\Schema\StrategyClass::SIMPLE_STRATEGY,
- "strategy_options" => array('replication_factor' => '1')
- ));
-
- $sys->create_column_family('oauth2_test', 'auth');
- $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_test', array('127.0.0.1:9160'));
- $cf = new \phpcassa\ColumnFamily($cassandra, 'auth');
-
- // populate the data
- $storage->setClientDetails("oauth_test_client", "testpass", "http://example.com", 'implicit password');
- $storage->setAccessToken("testtoken", "Some Client", '', time() + 1000);
- $storage->setAuthorizationCode("testcode", "Some Client", '', '', time() + 1000);
-
- $storage->setScope('supportedscope1 supportedscope2 supportedscope3 supportedscope4');
- $storage->setScope('defaultscope1 defaultscope2', null, 'default');
-
- $storage->setScope('clientscope1 clientscope2', 'Test Client ID');
- $storage->setScope('clientscope1 clientscope2', 'Test Client ID', 'default');
-
- $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Client ID 2');
- $storage->setScope('clientscope1 clientscope2', 'Test Client ID 2', 'default');
-
- $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID');
- $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID', 'default');
-
- $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Default Scope Client ID 2');
- $storage->setScope('clientscope3', 'Test Default Scope Client ID 2', 'default');
-
- $storage->setClientKey('oauth_test_client', $this->getTestPublicKey(), 'test_subject');
-
- $cf->insert("oauth_public_keys:ClientID_One", array('__data' => json_encode(array("public_key" => "client_1_public", "private_key" => "client_1_private", "encryption_algorithm" => "RS256"))));
- $cf->insert("oauth_public_keys:ClientID_Two", array('__data' => json_encode(array("public_key" => "client_2_public", "private_key" => "client_2_private", "encryption_algorithm" => "RS256"))));
- $cf->insert("oauth_public_keys:", array('__data' => json_encode(array("public_key" => $this->getTestPublicKey(), "private_key" => $this->getTestPrivateKey(), "encryption_algorithm" => "RS256"))));
-
- $cf->insert("oauth_users:testuser", array('__data' =>json_encode(array("password" => "password", "email" => "testuser@test.com", "email_verified" => true))));
-
- }
-
- private function createSqliteDb(\PDO $pdo)
- {
- $this->runPdoSql($pdo);
- }
-
- private function removeSqliteDb()
- {
- if (file_exists($this->getSqliteDir())) {
- unlink($this->getSqliteDir());
- }
- }
-
- private function createMysqlDb(\PDO $pdo)
- {
- $pdo->exec('CREATE DATABASE oauth2_server_php');
- $pdo->exec('USE oauth2_server_php');
- $this->runPdoSql($pdo);
- }
-
- private function removeMysqlDb(\PDO $pdo)
- {
- $pdo->exec('DROP DATABASE IF EXISTS oauth2_server_php');
- }
-
- private function createPostgresDb()
- {
- if (!`psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'"`) {
- `createuser -s -r postgres`;
- }
-
- `createdb -O postgres oauth2_server_php`;
- }
-
- private function populatePostgresDb(\PDO $pdo)
- {
- $this->runPdoSql($pdo);
- }
-
- private function removePostgresDb()
- {
- if (trim(`psql -l | grep oauth2_server_php | wc -l`)) {
- `dropdb oauth2_server_php`;
- }
- }
-
- public function runPdoSql(\PDO $pdo)
- {
- $storage = new Pdo($pdo);
- foreach (explode(';', $storage->getBuildSql()) as $statement) {
- $result = $pdo->exec($statement);
- }
-
- // set up scopes
- $sql = 'INSERT INTO oauth_scopes (scope) VALUES (?)';
- foreach (explode(' ', 'supportedscope1 supportedscope2 supportedscope3 supportedscope4 clientscope1 clientscope2 clientscope3') as $supportedScope) {
- $pdo->prepare($sql)->execute(array($supportedScope));
- }
-
- $sql = 'INSERT INTO oauth_scopes (scope, is_default) VALUES (?, ?)';
- foreach (array('defaultscope1', 'defaultscope2') as $defaultScope) {
- $pdo->prepare($sql)->execute(array($defaultScope, true));
- }
-
- // set up clients
- $sql = 'INSERT INTO oauth_clients (client_id, client_secret, scope, grant_types) VALUES (?, ?, ?, ?)';
- $pdo->prepare($sql)->execute(array('Test Client ID', 'TestSecret', 'clientscope1 clientscope2', null));
- $pdo->prepare($sql)->execute(array('Test Client ID 2', 'TestSecret', 'clientscope1 clientscope2 clientscope3', null));
- $pdo->prepare($sql)->execute(array('Test Default Scope Client ID', 'TestSecret', 'clientscope1 clientscope2', null));
- $pdo->prepare($sql)->execute(array('oauth_test_client', 'testpass', null, 'implicit password'));
-
- // set up misc
- $sql = 'INSERT INTO oauth_access_tokens (access_token, client_id, expires, user_id) VALUES (?, ?, ?, ?)';
- $pdo->prepare($sql)->execute(array('testtoken', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour')), null));
- $pdo->prepare($sql)->execute(array('accesstoken-openid-connect', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour')), 'testuser'));
-
- $sql = 'INSERT INTO oauth_authorization_codes (authorization_code, client_id, expires) VALUES (?, ?, ?)';
- $pdo->prepare($sql)->execute(array('testcode', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour'))));
-
- $sql = 'INSERT INTO oauth_users (username, password, email, email_verified) VALUES (?, ?, ?, ?)';
- $pdo->prepare($sql)->execute(array('testuser', 'password', 'testuser@test.com', true));
-
- $sql = 'INSERT INTO oauth_public_keys (client_id, public_key, private_key, encryption_algorithm) VALUES (?, ?, ?, ?)';
- $pdo->prepare($sql)->execute(array('ClientID_One', 'client_1_public', 'client_1_private', 'RS256'));
- $pdo->prepare($sql)->execute(array('ClientID_Two', 'client_2_public', 'client_2_private', 'RS256'));
-
- $sql = 'INSERT INTO oauth_public_keys (client_id, public_key, private_key, encryption_algorithm) VALUES (?, ?, ?, ?)';
- $pdo->prepare($sql)->execute(array(null, $this->getTestPublicKey(), $this->getTestPrivateKey(), 'RS256'));
-
- $sql = 'INSERT INTO oauth_jwt (client_id, subject, public_key) VALUES (?, ?, ?)';
- $pdo->prepare($sql)->execute(array('oauth_test_client', 'test_subject', $this->getTestPublicKey()));
- }
-
- public function getSqliteDir()
- {
- return $this->configDir. '/test.sqlite';
- }
-
- public function getConfigDir()
- {
- return $this->configDir;
- }
-
- private function createCouchbaseDB(\Couchbase $db)
- {
- $db->set('oauth_clients-oauth_test_client',json_encode(array(
- 'client_id' => "oauth_test_client",
- 'client_secret' => "testpass",
- 'redirect_uri' => "http://example.com",
- 'grant_types' => 'implicit password'
- )));
-
- $db->set('oauth_access_tokens-testtoken',json_encode(array(
- 'access_token' => "testtoken",
- 'client_id' => "Some Client"
- )));
-
- $db->set('oauth_authorization_codes-testcode',json_encode(array(
- 'access_token' => "testcode",
- 'client_id' => "Some Client"
- )));
-
- $db->set('oauth_users-testuser',json_encode(array(
- 'username' => 'testuser',
- 'password' => 'password',
- 'email' => 'testuser@test.com',
- 'email_verified' => true,
- )));
-
- $db->set('oauth_jwt-oauth_test_client',json_encode(array(
- 'client_id' => 'oauth_test_client',
- 'key' => $this->getTestPublicKey(),
- 'subject' => 'test_subject',
- )));
- }
-
- private function clearCouchbase(\Couchbase $cb)
- {
- $cb->delete('oauth_authorization_codes-new-openid-code');
- $cb->delete('oauth_access_tokens-newtoken');
- $cb->delete('oauth_authorization_codes-newcode');
- $cb->delete('oauth_refresh_tokens-refreshtoken');
- }
-
- private function createMongoDb(\MongoDB $db)
- {
- $db->oauth_clients->insert(array(
- 'client_id' => "oauth_test_client",
- 'client_secret' => "testpass",
- 'redirect_uri' => "http://example.com",
- 'grant_types' => 'implicit password'
- ));
-
- $db->oauth_access_tokens->insert(array(
- 'access_token' => "testtoken",
- 'client_id' => "Some Client"
- ));
-
- $db->oauth_authorization_codes->insert(array(
- 'authorization_code' => "testcode",
- 'client_id' => "Some Client"
- ));
-
- $db->oauth_users->insert(array(
- 'username' => 'testuser',
- 'password' => 'password',
- 'email' => 'testuser@test.com',
- 'email_verified' => true,
- ));
-
- $db->oauth_jwt->insert(array(
- 'client_id' => 'oauth_test_client',
- 'key' => $this->getTestPublicKey(),
- 'subject' => 'test_subject',
- ));
- }
-
- private function createRedisDb(Redis $storage)
- {
- $storage->setClientDetails("oauth_test_client", "testpass", "http://example.com", 'implicit password');
- $storage->setAccessToken("testtoken", "Some Client", '', time() + 1000);
- $storage->setAuthorizationCode("testcode", "Some Client", '', '', time() + 1000);
- $storage->setUser("testuser", "password");
-
- $storage->setScope('supportedscope1 supportedscope2 supportedscope3 supportedscope4');
- $storage->setScope('defaultscope1 defaultscope2', null, 'default');
-
- $storage->setScope('clientscope1 clientscope2', 'Test Client ID');
- $storage->setScope('clientscope1 clientscope2', 'Test Client ID', 'default');
-
- $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Client ID 2');
- $storage->setScope('clientscope1 clientscope2', 'Test Client ID 2', 'default');
-
- $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID');
- $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID', 'default');
-
- $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Default Scope Client ID 2');
- $storage->setScope('clientscope3', 'Test Default Scope Client ID 2', 'default');
-
- $storage->setClientKey('oauth_test_client', $this->getTestPublicKey(), 'test_subject');
- }
-
- public function removeMongoDb(\MongoDB $db)
- {
- $db->drop();
- }
-
- public function getTestPublicKey()
- {
- return file_get_contents(__DIR__.'/../../../config/keys/id_rsa.pub');
- }
-
- private function getTestPrivateKey()
- {
- return file_get_contents(__DIR__.'/../../../config/keys/id_rsa');
- }
-
- public function getDynamoDbStorage()
- {
- if (!$this->dynamodb) {
- // only run once per travis build
- if (true == $this->getEnvVar('TRAVIS')) {
- if (self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
- $this->dynamodb = new NullStorage('DynamoDb', 'Skipping for travis.ci - only run once per build');
-
- return;
- }
- }
- if (class_exists('\Aws\DynamoDb\DynamoDbClient')) {
- if ($client = $this->getDynamoDbClient()) {
- // travis runs a unique set of tables per build, to avoid conflict
- $prefix = '';
- if ($build_id = $this->getEnvVar('TRAVIS_JOB_NUMBER')) {
- $prefix = sprintf('build_%s_', $build_id);
- } else {
- if (!$this->deleteDynamoDb($client, $prefix, true)) {
- return $this->dynamodb = new NullStorage('DynamoDb', 'Timed out while waiting for DynamoDB deletion (30 seconds)');
- }
- }
- $this->createDynamoDb($client, $prefix);
- $this->populateDynamoDb($client, $prefix);
- $config = array(
- 'client_table' => $prefix.'oauth_clients',
- 'access_token_table' => $prefix.'oauth_access_tokens',
- 'refresh_token_table' => $prefix.'oauth_refresh_tokens',
- 'code_table' => $prefix.'oauth_authorization_codes',
- 'user_table' => $prefix.'oauth_users',
- 'jwt_table' => $prefix.'oauth_jwt',
- 'scope_table' => $prefix.'oauth_scopes',
- 'public_key_table' => $prefix.'oauth_public_keys',
- );
- $this->dynamodb = new DynamoDB($client, $config);
- } elseif (!$this->dynamodb) {
- $this->dynamodb = new NullStorage('DynamoDb', 'unable to connect to DynamoDB');
- }
- } else {
- $this->dynamodb = new NullStorage('DynamoDb', 'Missing DynamoDB library. Please run "composer.phar require aws/aws-sdk-php:dev-master');
- }
- }
-
- return $this->dynamodb;
- }
-
- private function getDynamoDbClient()
- {
- $config = array();
- // check for environment variables
- if (($key = $this->getEnvVar('AWS_ACCESS_KEY_ID')) && ($secret = $this->getEnvVar('AWS_SECRET_KEY'))) {
- $config['key'] = $key;
- $config['secret'] = $secret;
- } else {
- // fall back on ~/.aws/credentials file
- // @see http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html#credential-profiles
- if (!file_exists($this->getEnvVar('HOME') . '/.aws/credentials')) {
- $this->dynamodb = new NullStorage('DynamoDb', 'No aws credentials file found, and no AWS_ACCESS_KEY_ID or AWS_SECRET_KEY environment variable set');
-
- return;
- }
-
- // set profile in AWS_PROFILE environment variable, defaults to "default"
- $config['profile'] = $this->getEnvVar('AWS_PROFILE', 'default');
- }
-
- // set region in AWS_REGION environment variable, defaults to "us-east-1"
- $config['region'] = $this->getEnvVar('AWS_REGION', \Aws\Common\Enum\Region::US_EAST_1);
-
- return \Aws\DynamoDb\DynamoDbClient::factory($config);
- }
-
- private function deleteDynamoDb(\Aws\DynamoDb\DynamoDbClient $client, $prefix = null, $waitForDeletion = false)
- {
- $tablesList = explode(' ', 'oauth_access_tokens oauth_authorization_codes oauth_clients oauth_jwt oauth_public_keys oauth_refresh_tokens oauth_scopes oauth_users');
- $nbTables = count($tablesList);
-
- // Delete all table.
- foreach ($tablesList as $key => $table) {
- try {
- $client->deleteTable(array('TableName' => $prefix.$table));
- } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
- // Table does not exist : nothing to do
- }
- }
-
- // Wait for deleting
- if ($waitForDeletion) {
- $retries = 5;
- $nbTableDeleted = 0;
- while ($nbTableDeleted != $nbTables) {
- $nbTableDeleted = 0;
- foreach ($tablesList as $key => $table) {
- try {
- $result = $client->describeTable(array('TableName' => $prefix.$table));
- } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
- // Table does not exist : nothing to do
- $nbTableDeleted++;
- }
- }
- if ($nbTableDeleted != $nbTables) {
- if ($retries < 0) {
- // we are tired of waiting
- return false;
- }
- sleep(5);
- echo "Sleeping 5 seconds for DynamoDB ($retries more retries)...\n";
- $retries--;
- }
- }
- }
-
- return true;
- }
-
- private function createDynamoDb(\Aws\DynamoDb\DynamoDbClient $client, $prefix = null)
- {
- $tablesList = explode(' ', 'oauth_access_tokens oauth_authorization_codes oauth_clients oauth_jwt oauth_public_keys oauth_refresh_tokens oauth_scopes oauth_users');
- $nbTables = count($tablesList);
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_access_tokens',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'access_token','AttributeType' => 'S')
- ),
- 'KeySchema' => array(array('AttributeName' => 'access_token','KeyType' => 'HASH')),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_authorization_codes',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'authorization_code','AttributeType' => 'S')
- ),
- 'KeySchema' => array(array('AttributeName' => 'authorization_code','KeyType' => 'HASH')),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_clients',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'client_id','AttributeType' => 'S')
- ),
- 'KeySchema' => array(array('AttributeName' => 'client_id','KeyType' => 'HASH')),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_jwt',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'client_id','AttributeType' => 'S'),
- array('AttributeName' => 'subject','AttributeType' => 'S')
- ),
- 'KeySchema' => array(
- array('AttributeName' => 'client_id','KeyType' => 'HASH'),
- array('AttributeName' => 'subject','KeyType' => 'RANGE')
- ),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_public_keys',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'client_id','AttributeType' => 'S')
- ),
- 'KeySchema' => array(array('AttributeName' => 'client_id','KeyType' => 'HASH')),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_refresh_tokens',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'refresh_token','AttributeType' => 'S')
- ),
- 'KeySchema' => array(array('AttributeName' => 'refresh_token','KeyType' => 'HASH')),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_scopes',
- 'AttributeDefinitions' => array(
- array('AttributeName' => 'scope','AttributeType' => 'S'),
- array('AttributeName' => 'is_default','AttributeType' => 'S')
- ),
- 'KeySchema' => array(array('AttributeName' => 'scope','KeyType' => 'HASH')),
- 'GlobalSecondaryIndexes' => array(
- array(
- 'IndexName' => 'is_default-index',
- 'KeySchema' => array(array('AttributeName' => 'is_default', 'KeyType' => 'HASH')),
- 'Projection' => array('ProjectionType' => 'ALL'),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ),
- ),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- $client->createTable(array(
- 'TableName' => $prefix.'oauth_users',
- 'AttributeDefinitions' => array(array('AttributeName' => 'username','AttributeType' => 'S')),
- 'KeySchema' => array(array('AttributeName' => 'username','KeyType' => 'HASH')),
- 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
- ));
-
- // Wait for creation
- $nbTableCreated = 0;
- while ($nbTableCreated != $nbTables) {
- $nbTableCreated = 0;
- foreach ($tablesList as $key => $table) {
- try {
- $result = $client->describeTable(array('TableName' => $prefix.$table));
- if ($result['Table']['TableStatus'] == 'ACTIVE') {
- $nbTableCreated++;
- }
- } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
- // Table does not exist : nothing to do
- $nbTableCreated++;
- }
- }
- if ($nbTableCreated != $nbTables) {
- sleep(1);
- }
- }
- }
-
- private function populateDynamoDb($client, $prefix = null)
- {
- // set up scopes
- foreach (explode(' ', 'supportedscope1 supportedscope2 supportedscope3 supportedscope4 clientscope1 clientscope2 clientscope3') as $supportedScope) {
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_scopes',
- 'Item' => array('scope' => array('S' => $supportedScope))
- ));
- }
-
- foreach (array('defaultscope1', 'defaultscope2') as $defaultScope) {
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_scopes',
- 'Item' => array('scope' => array('S' => $defaultScope), 'is_default' => array('S' => "true"))
- ));
- }
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_clients',
- 'Item' => array(
- 'client_id' => array('S' => 'Test Client ID'),
- 'client_secret' => array('S' => 'TestSecret'),
- 'scope' => array('S' => 'clientscope1 clientscope2')
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_clients',
- 'Item' => array(
- 'client_id' => array('S' => 'Test Client ID 2'),
- 'client_secret' => array('S' => 'TestSecret'),
- 'scope' => array('S' => 'clientscope1 clientscope2 clientscope3')
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_clients',
- 'Item' => array(
- 'client_id' => array('S' => 'Test Default Scope Client ID'),
- 'client_secret' => array('S' => 'TestSecret'),
- 'scope' => array('S' => 'clientscope1 clientscope2')
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_clients',
- 'Item' => array(
- 'client_id' => array('S' => 'oauth_test_client'),
- 'client_secret' => array('S' => 'testpass'),
- 'grant_types' => array('S' => 'implicit password')
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_access_tokens',
- 'Item' => array(
- 'access_token' => array('S' => 'testtoken'),
- 'client_id' => array('S' => 'Some Client'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_access_tokens',
- 'Item' => array(
- 'access_token' => array('S' => 'accesstoken-openid-connect'),
- 'client_id' => array('S' => 'Some Client'),
- 'user_id' => array('S' => 'testuser'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_authorization_codes',
- 'Item' => array(
- 'authorization_code' => array('S' => 'testcode'),
- 'client_id' => array('S' => 'Some Client'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_users',
- 'Item' => array(
- 'username' => array('S' => 'testuser'),
- 'password' => array('S' => 'password'),
- 'email' => array('S' => 'testuser@test.com'),
- 'email_verified' => array('S' => 'true'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_public_keys',
- 'Item' => array(
- 'client_id' => array('S' => 'ClientID_One'),
- 'public_key' => array('S' => 'client_1_public'),
- 'private_key' => array('S' => 'client_1_private'),
- 'encryption_algorithm' => array('S' => 'RS256'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_public_keys',
- 'Item' => array(
- 'client_id' => array('S' => 'ClientID_Two'),
- 'public_key' => array('S' => 'client_2_public'),
- 'private_key' => array('S' => 'client_2_private'),
- 'encryption_algorithm' => array('S' => 'RS256'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_public_keys',
- 'Item' => array(
- 'client_id' => array('S' => '0'),
- 'public_key' => array('S' => $this->getTestPublicKey()),
- 'private_key' => array('S' => $this->getTestPrivateKey()),
- 'encryption_algorithm' => array('S' => 'RS256'),
- )
- ));
-
- $client->putItem(array(
- 'TableName' => $prefix.'oauth_jwt',
- 'Item' => array(
- 'client_id' => array('S' => 'oauth_test_client'),
- 'subject' => array('S' => 'test_subject'),
- 'public_key' => array('S' => $this->getTestPublicKey()),
- )
- ));
- }
-
- public function cleanupTravisDynamoDb($prefix = null)
- {
- if (is_null($prefix)) {
- // skip this when not applicable
- if (!$this->getEnvVar('TRAVIS') || self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
- return;
- }
-
- $prefix = sprintf('build_%s_', $this->getEnvVar('TRAVIS_JOB_NUMBER'));
- }
-
- $client = $this->getDynamoDbClient();
- $this->deleteDynamoDb($client, $prefix);
- }
-
- private function getEnvVar($var, $default = null)
- {
- return isset($_SERVER[$var]) ? $_SERVER[$var] : (getenv($var) ?: $default);
- }
-}
diff --git a/library/oauth2/test/lib/OAuth2/Storage/NullStorage.php b/library/oauth2/test/lib/OAuth2/Storage/NullStorage.php
deleted file mode 100644
index 6caa62068..000000000
--- a/library/oauth2/test/lib/OAuth2/Storage/NullStorage.php
+++ /dev/null
@@ -1,32 +0,0 @@
-name = $name;
- $this->description = $description;
- }
-
- public function __toString()
- {
- return $this->name;
- }
-
- public function getMessage()
- {
- if ($this->description) {
- return $this->description;
- }
-
- return $this->name;
- }
-}
diff --git a/vendor/autoload.php b/vendor/autoload.php
index 8b4926c3d..063a1b7e1 100644
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -2,6 +2,6 @@
// autoload.php @generated by Composer
-require_once __DIR__ . '/composer/autoload_real.php';
+require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d::getLoader();
diff --git a/vendor/bshaffer/oauth2-server-php/CHANGELOG.md b/vendor/bshaffer/oauth2-server-php/CHANGELOG.md
new file mode 100644
index 000000000..4fddd72c9
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/CHANGELOG.md
@@ -0,0 +1,182 @@
+CHANGELOG for 1.x
+=================
+
+This changelog references the relevant changes (bug and security fixes) done
+in 1.x minor versions.
+
+To see the files changed for a given bug, go to https://github.com/bshaffer/oauth2-server-php/issues/### where ### is the bug number
+To get the diff between two versions, go to https://github.com/bshaffer/oauth2-server-php/compare/v1.0...v1.1
+To get the diff for a specific change, go to https://github.com/bshaffer/oauth2-server-php/commit/XXX where XXX is the change hash
+
+* 1.9.0 (2016-01-06)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/788
+
+ * bug #645 - Allow null for client_secret
+ * bug #651 - Fix bug in isPublicClient of Cassandra Storage
+ * bug #670 - Bug in client's scope restriction
+ * bug #672 - Implemented method to override the password hashing algorithm
+ * bug #698 - Fix Token Response's Content-Type to application/json
+ * bug #729 - Ensures unsetAccessToken and unsetRefreshToken return a bool
+ * bug #749 - Fix UserClaims for CodeIdToken
+ * bug #784 - RFC6750 compatibility
+ * bug #776 - Fix "redirect_uri_mismatch" for URIs with encoded characters
+ * bug #759 - no access token supplied to resource controller results in empty request body
+ * bug #773 - Use OpenSSL random method before attempting Mcrypt's.
+ * bug #790 - Add mongo db
+
+* 1.8.0 (2015-09-18)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/643
+
+ * bug #594 - adds jti
+ * bug #598 - fixes lifetime configurations for JWTs
+ * bug #634 - fixes travis builds, upgrade to containers
+ * bug #586 - support for revoking tokens
+ * bug #636 - Adds FirebaseJWT bridge
+ * bug #639 - Mongo HHVM compatibility
+
+* 1.7.0 (2015-04-23)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/572
+
+ * bug #500 - PDO fetch mode changed from FETCH_BOTH to FETCH_ASSOC
+ * bug #508 - Case insensitive for Bearer token header name ba716d4
+ * bug #512 - validateRedirectUri is now public
+ * bug #530 - Add PublicKeyInterface, UserClaimsInterface to Cassandra Storage
+ * bug #505 - DynamoDB storage fixes
+ * bug #556 - adds "code id_token" return type to openid connect
+ * bug #563 - Include "issuer" config key for JwtAccessToken
+ * bug #564 - Fixes JWT vulnerability
+ * bug #571 - Added unset_refresh_token_after_use option
+
+* 1.6 (2015-01-16)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/496
+
+ * bug 437 - renames CryptoToken to JwtAccessToken / use_crypto_tokens to use_jwt_access_tokens
+ * bug 447 - Adds a Couchbase storage implementation
+ * bug 460 - Rename JWT claims to match spec
+ * bug 470 - order does not matter for multi-valued response types
+ * bug 471 - Make validateAuthorizeRequest available for POST in addition to GET
+ * bug 475 - Adds JTI table definitiion
+ * bug 481 - better randomness for generating access tokens
+ * bug 480 - Use hash_equals() for signature verification (prevents remote timing attacks)
+ * bugs 489, 491, 498 - misc other fixes
+
+* 1.5 (2014-08-27)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/446
+
+ * bug #399 - Add DynamoDB Support
+ * bug #404 - renamed error name for malformed/expired tokens
+ * bug #412 - Openid connect: fixes for claims with more than one scope / Add support for the prompt parameter ('consent' and 'none')
+ * bug #411 - fixes xml output
+ * bug #413 - fixes invalid format error
+ * bug #401 - fixes code standards / whitespace
+ * bug #354 - bundles PDO SQL with the library
+ * [BC] bug #397 - refresh tokens should not be encrypted
+ * bug #423 - makes "scope" optional for refresh token storage
+
+* 1.4 (2014-06-12)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/392
+
+ * bug #189 Storage\PDO - allows DSN string in constructor
+ * bug #233 Bearer Tokens - allows token in request body for PUT requests
+ * bug #346 Fixes open_basedir warning
+ * bug #351 Adds OpenID Connect support
+ * bug #355 Adds php 5.6 and HHVM to travis.ci testing
+ * [BC] bug #358 Adds `getQuerystringIdentifier()` to the GrantType interface
+ * bug #363 Encryption\JWT - Allows for subclassing JWT Headers
+ * bug #349 Bearer Tokens - adds requestHasToken method for when access tokens are optional
+ * bug #301 Encryption\JWT - fixes urlSafeB64Encode(): ensures newlines are replaced as expected
+ * bug #323 ResourceController - client_id is no longer required to be returned when calling getAccessToken
+ * bug #367 Storage\PDO - adds Postgres support
+ * bug #368 Access Tokens - use mcrypt_create_iv or openssl_random_pseudo_bytes to create token string
+ * bug #376 Request - allows case insensitive headers
+ * bug #384 Storage\PDO - can pass in PDO options in constructor of PDO storage
+ * misc fixes #361, #292, #373, #374, #379, #396
+* 1.3 (2014-02-27)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/325
+
+ * bug #311 adds cassandra storage
+ * bug #298 fixes response code for user credentials grant type
+ * bug #318 adds 'use_crypto_tokens' config to Server class for better DX
+ * [BC] bug #320 pass client_id to getDefaultScope
+ * bug #324 better feedback when running tests
+ * bug #335 adds support for non-expiring refresh tokens
+ * bug #333 fixes Pdo storage for getClientKey
+ * bug #336 fixes Redis storage for expireAuthorizationCode
+
+* 1.3 (2014-02-27)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/325
+
+ * bug #311 adds cassandra storage
+ * bug #298 fixes response code for user credentials grant type
+ * bug #318 adds 'use_crypto_tokens' config to Server class for better DX
+ * bug #320 pass client_id to getDefaultScope
+ * bug #324 better feedback when running tests
+ * bug #335 adds support for non-expiring refresh tokens
+ * bug #333 fixes Pdo storage for getClientKey
+ * bug #336 fixes Redis storage for expireAuthorizationCode
+
+* 1.2 (2014-01-03)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/288
+
+ * bug #285 changed response header from 200 to 401 when empty token received
+ * bug #286 adds documentation and links to spec for not including error messages when no token is supplied
+ * bug #280 ensures PHP warnings do not get thrown as a result of an invalid argument to $jwt->decode()
+ * bug #279 predis wrong number of arguments
+ * bug #277 Securing JS WebApp client secret w/ password grant type
+
+* 1.1 (2013-12-17)
+
+ PR: https://github.com/bshaffer/oauth2-server-php/pull/276
+
+ * bug #278 adds refresh token configuration to Server class
+ * bug #274 Supplying a null client_id and client_secret grants API access
+ * bug #244 [MongoStorage] More detailed implementation info
+ * bug #268 Implement jti for JWT Bearer tokens to prevent replay attacks.
+ * bug #266 Removing unused argument to getAccessTokenData
+ * bug #247 Make Bearer token type consistent
+ * bug #253 Fixing CryptoToken refresh token lifetime
+ * bug #246 refactors public key logic to be more intuitive
+ * bug #245 adds support for JSON crypto tokens
+ * bug #230 Remove unused columns in oauth_clients
+ * bug #215 makes Redis Scope Storage obey the same paradigm as PDO
+ * bug #228 removes scope group
+ * bug #227 squelches open basedir restriction error
+ * bug #223 Updated docblocks for RefreshTokenInterface.php
+ * bug #224 Adds protected properties
+ * bug #217 Implement ScopeInterface for PDO, Redis
+
+* 1.0 (2013-08-12)
+
+ * bug #203 Add redirect\_status_code config param for AuthorizeController
+ * bug #205 ensures unnecessary ? is not set when ** bug
+ * bug #204 Fixed call to LogicException
+ * bug #202 Add explode to checkRestrictedGrant in PDO Storage
+ * bug #197 adds support for 'false' default scope ** bug
+ * bug #192 reference errors and adds tests
+ * bug #194 makes some appropriate properties ** bug
+ * bug #191 passes config to HttpBasic
+ * bug #190 validates client credentials before ** bug
+ * bug #171 Fix wrong redirect following authorization step
+ * bug #187 client_id is now passed to getDefaultScope().
+ * bug #176 Require refresh_token in getRefreshToken response
+ * bug #174 make user\_id not required for refresh_token grant
+ * bug #173 Duplication in JwtBearer Grant
+ * bug #168 user\_id not required for authorization_code grant
+ * bug #133 hardens default security for user object
+ * bug #163 allows redirect\_uri on authorization_code to be NULL in docs example
+ * bug #162 adds getToken on ResourceController for convenience
+ * bug #161 fixes fatal error
+ * bug #163 Invalid redirect_uri handling
+ * bug #156 user\_id in OAuth2\_Storage_AuthorizationCodeInterface::getAuthorizationCode() response
+ * bug #157 Fix for extending access and refresh tokens
+ * bug #154 ResponseInterface: getParameter method is used in the library but not defined in the interface
+ * bug #148 Add more detail to examples in Readme.md
diff --git a/vendor/bshaffer/oauth2-server-php/LICENSE b/vendor/bshaffer/oauth2-server-php/LICENSE
new file mode 100644
index 000000000..d7ece8467
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2014 Brent Shaffer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/bshaffer/oauth2-server-php/README.md b/vendor/bshaffer/oauth2-server-php/README.md
new file mode 100644
index 000000000..4ceda6cf9
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/README.md
@@ -0,0 +1,8 @@
+oauth2-server-php
+=================
+
+[![Build Status](https://travis-ci.org/bshaffer/oauth2-server-php.svg?branch=develop)](https://travis-ci.org/bshaffer/oauth2-server-php)
+
+[![Total Downloads](https://poser.pugx.org/bshaffer/oauth2-server-php/downloads.png)](https://packagist.org/packages/bshaffer/oauth2-server-php)
+
+View the [complete documentation](http://bshaffer.github.io/oauth2-server-php-docs/)
\ No newline at end of file
diff --git a/vendor/bshaffer/oauth2-server-php/composer.json b/vendor/bshaffer/oauth2-server-php/composer.json
new file mode 100644
index 000000000..561699f5e
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "bshaffer/oauth2-server-php",
+ "description":"OAuth2 Server for PHP",
+ "keywords":["oauth","oauth2","auth"],
+ "type":"library",
+ "license":"MIT",
+ "authors":[
+ {
+ "name":"Brent Shaffer",
+ "email": "bshafs@gmail.com",
+ "homepage":"http://brentertainment.com"
+ }
+ ],
+ "homepage": "http://github.com/bshaffer/oauth2-server-php",
+ "autoload": {
+ "psr-0": { "OAuth2": "src/" }
+ },
+ "require":{
+ "php":">=5.3.9"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "~2.8",
+ "firebase/php-jwt": "~2.2",
+ "predis/predis": "dev-master",
+ "thobbs/phpcassa": "dev-master",
+ "mongodb/mongodb": "^1.1"
+ },
+ "suggest": {
+ "predis/predis": "Required to use Redis storage",
+ "thobbs/phpcassa": "Required to use Cassandra storage",
+ "aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
+ "firebase/php-jwt": "~1.1 is required to use MondoDB storage"
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Autoloader.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Autoloader.php
new file mode 100644
index 000000000..ecfb6ba75
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Autoloader.php
@@ -0,0 +1,48 @@
+
+ * @license MIT License
+ */
+class Autoloader
+{
+ private $dir;
+
+ public function __construct($dir = null)
+ {
+ if (is_null($dir)) {
+ $dir = dirname(__FILE__).'/..';
+ }
+ $this->dir = $dir;
+ }
+ /**
+ * Registers OAuth2\Autoloader as an SPL autoloader.
+ */
+ public static function register($dir = null)
+ {
+ ini_set('unserialize_callback_func', 'spl_autoload_call');
+ spl_autoload_register(array(new self($dir), 'autoload'));
+ }
+
+ /**
+ * Handles autoloading of classes.
+ *
+ * @param string $class A class name.
+ *
+ * @return boolean Returns true if the class has been loaded
+ */
+ public function autoload($class)
+ {
+ if (0 !== strpos($class, 'OAuth2')) {
+ return;
+ }
+
+ if (file_exists($file = $this->dir.'/'.str_replace('\\', '/', $class).'.php')) {
+ require $file;
+ }
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
new file mode 100644
index 000000000..29c7171b5
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ClientAssertionType/ClientAssertionTypeInterface.php
@@ -0,0 +1,15 @@
+
+ */
+class HttpBasic implements ClientAssertionTypeInterface
+{
+ private $clientData;
+
+ protected $storage;
+ protected $config;
+
+ /**
+ * @param OAuth2\Storage\ClientCredentialsInterface $clientStorage REQUIRED Storage class for retrieving client credentials information
+ * @param array $config OPTIONAL Configuration options for the server
+ *
+ * $config = array(
+ * 'allow_credentials_in_request_body' => true, // whether to look for credentials in the POST body in addition to the Authorize HTTP Header
+ * 'allow_public_clients' => true // if true, "public clients" (clients without a secret) may be authenticated
+ * );
+ *
+ */
+ public function __construct(ClientCredentialsInterface $storage, array $config = array())
+ {
+ $this->storage = $storage;
+ $this->config = array_merge(array(
+ 'allow_credentials_in_request_body' => true,
+ 'allow_public_clients' => true,
+ ), $config);
+ }
+
+ public function validateRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!$clientData = $this->getClientCredentials($request, $response)) {
+ return false;
+ }
+
+ if (!isset($clientData['client_id'])) {
+ throw new \LogicException('the clientData array must have "client_id" set');
+ }
+
+ if (!isset($clientData['client_secret']) || $clientData['client_secret'] == '') {
+ if (!$this->config['allow_public_clients']) {
+ $response->setError(400, 'invalid_client', 'client credentials are required');
+
+ return false;
+ }
+
+ if (!$this->storage->isPublicClient($clientData['client_id'])) {
+ $response->setError(400, 'invalid_client', 'This client is invalid or must authenticate using a client secret');
+
+ return false;
+ }
+ } elseif ($this->storage->checkClientCredentials($clientData['client_id'], $clientData['client_secret']) === false) {
+ $response->setError(400, 'invalid_client', 'The client credentials are invalid');
+
+ return false;
+ }
+
+ $this->clientData = $clientData;
+
+ return true;
+ }
+
+ public function getClientId()
+ {
+ return $this->clientData['client_id'];
+ }
+
+ /**
+ * Internal function used to get the client credentials from HTTP basic
+ * auth or POST data.
+ *
+ * According to the spec (draft 20), the client_id can be provided in
+ * the Basic Authorization header (recommended) or via GET/POST.
+ *
+ * @return
+ * A list containing the client identifier and password, for example
+ * @code
+ * return array(
+ * "client_id" => CLIENT_ID, // REQUIRED the client id
+ * "client_secret" => CLIENT_SECRET, // OPTIONAL the client secret (may be omitted for public clients)
+ * );
+ * @endcode
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-2.3.1
+ *
+ * @ingroup oauth2_section_2
+ */
+ public function getClientCredentials(RequestInterface $request, ResponseInterface $response = null)
+ {
+ if (!is_null($request->headers('PHP_AUTH_USER')) && !is_null($request->headers('PHP_AUTH_PW'))) {
+ return array('client_id' => $request->headers('PHP_AUTH_USER'), 'client_secret' => $request->headers('PHP_AUTH_PW'));
+ }
+
+ if ($this->config['allow_credentials_in_request_body']) {
+ // Using POST for HttpBasic authorization is not recommended, but is supported by specification
+ if (!is_null($request->request('client_id'))) {
+ /**
+ * client_secret can be null if the client's password is an empty string
+ * @see http://tools.ietf.org/html/rfc6749#section-2.3.1
+ */
+
+ return array('client_id' => $request->request('client_id'), 'client_secret' => $request->request('client_secret'));
+ }
+ }
+
+ if ($response) {
+ $message = $this->config['allow_credentials_in_request_body'] ? ' or body' : '';
+ $response->setError(400, 'invalid_client', 'Client credentials were not found in the headers'.$message);
+ }
+
+ return null;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeController.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeController.php
new file mode 100644
index 000000000..ea7f54a87
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeController.php
@@ -0,0 +1,393 @@
+
+ * $config = array(
+ * 'allow_implicit' => false, // if the controller should allow the "implicit" grant type
+ * 'enforce_state' => true // if the controller should require the "state" parameter
+ * 'require_exact_redirect_uri' => true, // if the controller should require an exact match on the "redirect_uri" parameter
+ * 'redirect_status_code' => 302, // HTTP status code to use for redirect responses
+ * );
+ *
+ * @param OAuth2\ScopeInterface $scopeUtil OPTIONAL Instance of OAuth2\ScopeInterface to validate the requested scope
+ */
+ public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ScopeInterface $scopeUtil = null)
+ {
+ $this->clientStorage = $clientStorage;
+ $this->responseTypes = $responseTypes;
+ $this->config = array_merge(array(
+ 'allow_implicit' => false,
+ 'enforce_state' => true,
+ 'require_exact_redirect_uri' => true,
+ 'redirect_status_code' => 302,
+ ), $config);
+
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new Scope();
+ }
+ $this->scopeUtil = $scopeUtil;
+ }
+
+ public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null)
+ {
+ if (!is_bool($is_authorized)) {
+ throw new \InvalidArgumentException('Argument "is_authorized" must be a boolean. This method must know if the user has granted access to the client.');
+ }
+
+ // We repeat this, because we need to re-validate. The request could be POSTed
+ // by a 3rd-party (because we are not internally enforcing NONCEs, etc)
+ if (!$this->validateAuthorizeRequest($request, $response)) {
+ return;
+ }
+
+ // If no redirect_uri is passed in the request, use client's registered one
+ if (empty($this->redirect_uri)) {
+ $clientData = $this->clientStorage->getClientDetails($this->client_id);
+ $registered_redirect_uri = $clientData['redirect_uri'];
+ }
+
+ // the user declined access to the client's application
+ if ($is_authorized === false) {
+ $redirect_uri = $this->redirect_uri ?: $registered_redirect_uri;
+ $this->setNotAuthorizedResponse($request, $response, $redirect_uri, $user_id);
+
+ return;
+ }
+
+ // build the parameters to set in the redirect URI
+ if (!$params = $this->buildAuthorizeParameters($request, $response, $user_id)) {
+ return;
+ }
+
+ $authResult = $this->responseTypes[$this->response_type]->getAuthorizeResponse($params, $user_id);
+
+ list($redirect_uri, $uri_params) = $authResult;
+
+ if (empty($redirect_uri) && !empty($registered_redirect_uri)) {
+ $redirect_uri = $registered_redirect_uri;
+ }
+
+ $uri = $this->buildUri($redirect_uri, $uri_params);
+
+ // return redirect response
+ $response->setRedirect($this->config['redirect_status_code'], $uri);
+ }
+
+ protected function setNotAuthorizedResponse(RequestInterface $request, ResponseInterface $response, $redirect_uri, $user_id = null)
+ {
+ $error = 'access_denied';
+ $error_message = 'The user denied access to your application';
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->state, $error, $error_message);
+ }
+
+ /*
+ * We have made this protected so this class can be extended to add/modify
+ * these parameters
+ */
+ protected function buildAuthorizeParameters($request, $response, $user_id)
+ {
+ // @TODO: we should be explicit with this in the future
+ $params = array(
+ 'scope' => $this->scope,
+ 'state' => $this->state,
+ 'client_id' => $this->client_id,
+ 'redirect_uri' => $this->redirect_uri,
+ 'response_type' => $this->response_type,
+ );
+
+ return $params;
+ }
+
+ /**
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return bool
+ */
+ public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ // Make sure a valid client id was supplied (we can not redirect because we were unable to verify the URI)
+ if (!$client_id = $request->query('client_id', $request->request('client_id'))) {
+ // We don't have a good URI to use
+ $response->setError(400, 'invalid_client', "No client id supplied");
+
+ return false;
+ }
+
+ // Get client details
+ if (!$clientData = $this->clientStorage->getClientDetails($client_id)) {
+ $response->setError(400, 'invalid_client', 'The client id supplied is invalid');
+
+ return false;
+ }
+
+ $registered_redirect_uri = isset($clientData['redirect_uri']) ? $clientData['redirect_uri'] : '';
+
+ // Make sure a valid redirect_uri was supplied. If specified, it must match the clientData URI.
+ // @see http://tools.ietf.org/html/rfc6749#section-3.1.2
+ // @see http://tools.ietf.org/html/rfc6749#section-4.1.2.1
+ // @see http://tools.ietf.org/html/rfc6749#section-4.2.2.1
+ if ($supplied_redirect_uri = $request->query('redirect_uri', $request->request('redirect_uri'))) {
+ // validate there is no fragment supplied
+ $parts = parse_url($supplied_redirect_uri);
+ if (isset($parts['fragment']) && $parts['fragment']) {
+ $response->setError(400, 'invalid_uri', 'The redirect URI must not contain a fragment');
+
+ return false;
+ }
+
+ // validate against the registered redirect uri(s) if available
+ if ($registered_redirect_uri && !$this->validateRedirectUri($supplied_redirect_uri, $registered_redirect_uri)) {
+ $response->setError(400, 'redirect_uri_mismatch', 'The redirect URI provided is missing or does not match', '#section-3.1.2');
+
+ return false;
+ }
+ $redirect_uri = $supplied_redirect_uri;
+ } else {
+ // use the registered redirect_uri if none has been supplied, if possible
+ if (!$registered_redirect_uri) {
+ $response->setError(400, 'invalid_uri', 'No redirect URI was supplied or stored');
+
+ return false;
+ }
+
+ if (count(explode(' ', $registered_redirect_uri)) > 1) {
+ $response->setError(400, 'invalid_uri', 'A redirect URI must be supplied when multiple redirect URIs are registered', '#section-3.1.2.3');
+
+ return false;
+ }
+ $redirect_uri = $registered_redirect_uri;
+ }
+
+ // Select the redirect URI
+ $response_type = $request->query('response_type', $request->request('response_type'));
+
+ // for multiple-valued response types - make them alphabetical
+ if (false !== strpos($response_type, ' ')) {
+ $types = explode(' ', $response_type);
+ sort($types);
+ $response_type = ltrim(implode(' ', $types));
+ }
+
+ $state = $request->query('state', $request->request('state'));
+
+ // type and client_id are required
+ if (!$response_type || !in_array($response_type, $this->getValidResponseTypes())) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'invalid_request', 'Invalid or missing response type', null);
+
+ return false;
+ }
+
+ if ($response_type == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
+ if (!isset($this->responseTypes['code'])) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unsupported_response_type', 'authorization code grant type not supported', null);
+
+ return false;
+ }
+ if (!$this->clientStorage->checkRestrictedGrantType($client_id, 'authorization_code')) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unauthorized_client', 'The grant type is unauthorized for this client_id', null);
+
+ return false;
+ }
+ if ($this->responseTypes['code']->enforceRedirect() && !$redirect_uri) {
+ $response->setError(400, 'redirect_uri_mismatch', 'The redirect URI is mandatory and was not supplied');
+
+ return false;
+ }
+ } else {
+ if (!$this->config['allow_implicit']) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unsupported_response_type', 'implicit grant type not supported', null);
+
+ return false;
+ }
+ if (!$this->clientStorage->checkRestrictedGrantType($client_id, 'implicit')) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'unauthorized_client', 'The grant type is unauthorized for this client_id', null);
+
+ return false;
+ }
+ }
+
+ // validate requested scope if it exists
+ $requestedScope = $this->scopeUtil->getScopeFromRequest($request);
+
+ if ($requestedScope) {
+ // restrict scope by client specific scope if applicable,
+ // otherwise verify the scope exists
+ $clientScope = $this->clientStorage->getClientScope($client_id);
+ if ((empty($clientScope) && !$this->scopeUtil->scopeExists($requestedScope))
+ || (!empty($clientScope) && !$this->scopeUtil->checkScope($requestedScope, $clientScope))) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'invalid_scope', 'An unsupported scope was requested', null);
+
+ return false;
+ }
+ } else {
+ // use a globally-defined default scope
+ $defaultScope = $this->scopeUtil->getDefaultScope($client_id);
+
+ if (false === $defaultScope) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $state, 'invalid_client', 'This application requires you specify a scope parameter', null);
+
+ return false;
+ }
+
+ $requestedScope = $defaultScope;
+ }
+
+ // Validate state parameter exists (if configured to enforce this)
+ if ($this->config['enforce_state'] && !$state) {
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, null, 'invalid_request', 'The state parameter is required');
+
+ return false;
+ }
+
+ // save the input data and return true
+ $this->scope = $requestedScope;
+ $this->state = $state;
+ $this->client_id = $client_id;
+ // Only save the SUPPLIED redirect URI (@see http://tools.ietf.org/html/rfc6749#section-4.1.3)
+ $this->redirect_uri = $supplied_redirect_uri;
+ $this->response_type = $response_type;
+
+ return true;
+ }
+
+ /**
+ * Build the absolute URI based on supplied URI and parameters.
+ *
+ * @param $uri An absolute URI.
+ * @param $params Parameters to be append as GET.
+ *
+ * @return
+ * An absolute URI with supplied parameters.
+ *
+ * @ingroup oauth2_section_4
+ */
+ private function buildUri($uri, $params)
+ {
+ $parse_url = parse_url($uri);
+
+ // Add our params to the parsed uri
+ foreach ($params as $k => $v) {
+ if (isset($parse_url[$k])) {
+ $parse_url[$k] .= "&" . http_build_query($v, '', '&');
+ } else {
+ $parse_url[$k] = http_build_query($v, '', '&');
+ }
+ }
+
+ // Put humpty dumpty back together
+ return
+ ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
+ . ((isset($parse_url["user"])) ? $parse_url["user"]
+ . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "")
+ . ((isset($parse_url["host"])) ? $parse_url["host"] : "")
+ . ((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "")
+ . ((isset($parse_url["path"])) ? $parse_url["path"] : "")
+ . ((isset($parse_url["query"]) && !empty($parse_url['query'])) ? "?" . $parse_url["query"] : "")
+ . ((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "")
+ ;
+ }
+
+ protected function getValidResponseTypes()
+ {
+ return array(
+ self::RESPONSE_TYPE_ACCESS_TOKEN,
+ self::RESPONSE_TYPE_AUTHORIZATION_CODE,
+ );
+ }
+
+ /**
+ * Internal method for validating redirect URI supplied
+ *
+ * @param string $inputUri The submitted URI to be validated
+ * @param string $registeredUriString The allowed URI(s) to validate against. Can be a space-delimited string of URIs to
+ * allow for multiple URIs
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-3.1.2
+ */
+ protected function validateRedirectUri($inputUri, $registeredUriString)
+ {
+ if (!$inputUri || !$registeredUriString) {
+ return false; // if either one is missing, assume INVALID
+ }
+
+ $registered_uris = preg_split('/\s+/', $registeredUriString);
+ foreach ($registered_uris as $registered_uri) {
+ if ($this->config['require_exact_redirect_uri']) {
+ // the input uri is validated against the registered uri using exact match
+ if (strcmp($inputUri, $registered_uri) === 0) {
+ return true;
+ }
+ } else {
+ $registered_uri_length = strlen($registered_uri);
+ if ($registered_uri_length === 0) {
+ return false;
+ }
+
+ // the input uri is validated against the registered uri using case-insensitive match of the initial string
+ // i.e. additional query parameters may be applied
+ if (strcasecmp(substr($inputUri, 0, $registered_uri_length), $registered_uri) === 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convenience methods to access the parameters derived from the validated request
+ */
+
+ public function getScope()
+ {
+ return $this->scope;
+ }
+
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ public function getRedirectUri()
+ {
+ return $this->redirect_uri;
+ }
+
+ public function getResponseType()
+ {
+ return $this->response_type;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeControllerInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeControllerInterface.php
new file mode 100644
index 000000000..fa07ae8d2
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/AuthorizeControllerInterface.php
@@ -0,0 +1,43 @@
+ $user_id = $this->somehowDetermineUserId();
+ * > $is_authorized = $this->somehowDetermineUserAuthorization();
+ * > $response = new OAuth2\Response();
+ * > $authorizeController->handleAuthorizeRequest(
+ * > OAuth2\Request::createFromGlobals(),
+ * > $response,
+ * > $is_authorized,
+ * > $user_id);
+ * > $response->send();
+ *
+ */
+interface AuthorizeControllerInterface
+{
+ /**
+ * List of possible authentication response types.
+ * The "authorization_code" mechanism exclusively supports 'code'
+ * and the "implicit" mechanism exclusively supports 'token'.
+ *
+ * @var string
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1.1
+ * @see http://tools.ietf.org/html/rfc6749#section-4.2.1
+ */
+ const RESPONSE_TYPE_AUTHORIZATION_CODE = 'code';
+ const RESPONSE_TYPE_ACCESS_TOKEN = 'token';
+
+ public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null);
+
+ public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceController.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceController.php
new file mode 100644
index 000000000..3cfaaaf12
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceController.php
@@ -0,0 +1,111 @@
+tokenType = $tokenType;
+ $this->tokenStorage = $tokenStorage;
+
+ $this->config = array_merge(array(
+ 'www_realm' => 'Service',
+ ), $config);
+
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new Scope();
+ }
+ $this->scopeUtil = $scopeUtil;
+ }
+
+ public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null)
+ {
+ $token = $this->getAccessTokenData($request, $response);
+
+ // Check if we have token data
+ if (is_null($token)) {
+ return false;
+ }
+
+ /**
+ * Check scope, if provided
+ * If token doesn't have a scope, it's null/empty, or it's insufficient, then throw 403
+ * @see http://tools.ietf.org/html/rfc6750#section-3.1
+ */
+ if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->scopeUtil->checkScope($scope, $token["scope"]))) {
+ $response->setError(403, 'insufficient_scope', 'The request requires higher privileges than provided by the access token');
+ $response->addHttpHeaders(array(
+ 'WWW-Authenticate' => sprintf('%s realm="%s", scope="%s", error="%s", error_description="%s"',
+ $this->tokenType->getTokenType(),
+ $this->config['www_realm'],
+ $scope,
+ $response->getParameter('error'),
+ $response->getParameter('error_description')
+ )
+ ));
+
+ return false;
+ }
+
+ // allow retrieval of the token
+ $this->token = $token;
+
+ return (bool) $token;
+ }
+
+ public function getAccessTokenData(RequestInterface $request, ResponseInterface $response)
+ {
+ // Get the token parameter
+ if ($token_param = $this->tokenType->getAccessTokenParameter($request, $response)) {
+ // Get the stored token data (from the implementing subclass)
+ // Check we have a well formed token
+ // Check token expiration (expires is a mandatory paramter)
+ if (!$token = $this->tokenStorage->getAccessToken($token_param)) {
+ $response->setError(401, 'invalid_token', 'The access token provided is invalid');
+ } elseif (!isset($token["expires"]) || !isset($token["client_id"])) {
+ $response->setError(401, 'malformed_token', 'Malformed token (missing "expires")');
+ } elseif (time() > $token["expires"]) {
+ $response->setError(401, 'invalid_token', 'The access token provided has expired');
+ } else {
+ return $token;
+ }
+ }
+
+ $authHeader = sprintf('%s realm="%s"', $this->tokenType->getTokenType(), $this->config['www_realm']);
+
+ if ($error = $response->getParameter('error')) {
+ $authHeader = sprintf('%s, error="%s"', $authHeader, $error);
+ if ($error_description = $response->getParameter('error_description')) {
+ $authHeader = sprintf('%s, error_description="%s"', $authHeader, $error_description);
+ }
+ }
+
+ $response->addHttpHeaders(array('WWW-Authenticate' => $authHeader));
+
+ return null;
+ }
+
+ // convenience method to allow retrieval of the token
+ public function getToken()
+ {
+ return $this->token;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceControllerInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceControllerInterface.php
new file mode 100644
index 000000000..611421935
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/ResourceControllerInterface.php
@@ -0,0 +1,26 @@
+ if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
+ * > $response->send(); // authorization failed
+ * > die();
+ * > }
+ * > return json_encode($resource); // valid token! Send the stuff!
+ *
+ */
+interface ResourceControllerInterface
+{
+ public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null);
+
+ public function getAccessTokenData(RequestInterface $request, ResponseInterface $response);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenController.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenController.php
new file mode 100644
index 000000000..5d2d731fe
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenController.php
@@ -0,0 +1,295 @@
+clientAssertionType = $clientAssertionType;
+ $this->accessToken = $accessToken;
+ $this->clientStorage = $clientStorage;
+ foreach ($grantTypes as $grantType) {
+ $this->addGrantType($grantType);
+ }
+
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new Scope();
+ }
+ $this->scopeUtil = $scopeUtil;
+ }
+
+ public function handleTokenRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if ($token = $this->grantAccessToken($request, $response)) {
+ // @see http://tools.ietf.org/html/rfc6749#section-5.1
+ // server MUST disable caching in headers when tokens are involved
+ $response->setStatusCode(200);
+ $response->addParameters($token);
+ $response->addHttpHeaders(array(
+ 'Cache-Control' => 'no-store',
+ 'Pragma' => 'no-cache',
+ 'Content-Type' => 'application/json'
+ ));
+ }
+ }
+
+ /**
+ * Grant or deny a requested access token.
+ * This would be called from the "/token" endpoint as defined in the spec.
+ * You can call your endpoint whatever you want.
+ *
+ * @param RequestInterface $request Request object to grant access token
+ * @param ResponseInterface $response
+ *
+ * @throws \InvalidArgumentException
+ * @throws \LogicException
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ * @see http://tools.ietf.org/html/rfc6749#section-10.6
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function grantAccessToken(RequestInterface $request, ResponseInterface $response)
+ {
+ if (strtolower($request->server('REQUEST_METHOD')) != 'post') {
+ $response->setError(405, 'invalid_request', 'The request method must be POST when requesting an access token', '#section-3.2');
+ $response->addHttpHeaders(array('Allow' => 'POST'));
+
+ return null;
+ }
+
+ /**
+ * Determine grant type from request
+ * and validate the request for that grant type
+ */
+ if (!$grantTypeIdentifier = $request->request('grant_type')) {
+ $response->setError(400, 'invalid_request', 'The grant type was not specified in the request');
+
+ return null;
+ }
+
+ if (!isset($this->grantTypes[$grantTypeIdentifier])) {
+ /* TODO: If this is an OAuth2 supported grant type that we have chosen not to implement, throw a 501 Not Implemented instead */
+ $response->setError(400, 'unsupported_grant_type', sprintf('Grant type "%s" not supported', $grantTypeIdentifier));
+
+ return null;
+ }
+
+ $grantType = $this->grantTypes[$grantTypeIdentifier];
+
+ /**
+ * Retrieve the client information from the request
+ * ClientAssertionTypes allow for grant types which also assert the client data
+ * in which case ClientAssertion is handled in the validateRequest method
+ *
+ * @see OAuth2\GrantType\JWTBearer
+ * @see OAuth2\GrantType\ClientCredentials
+ */
+ if (!$grantType instanceof ClientAssertionTypeInterface) {
+ if (!$this->clientAssertionType->validateRequest($request, $response)) {
+ return null;
+ }
+ $clientId = $this->clientAssertionType->getClientId();
+ }
+
+ /**
+ * Retrieve the grant type information from the request
+ * The GrantTypeInterface object handles all validation
+ * If the object is an instance of ClientAssertionTypeInterface,
+ * That logic is handled here as well
+ */
+ if (!$grantType->validateRequest($request, $response)) {
+ return null;
+ }
+
+ if ($grantType instanceof ClientAssertionTypeInterface) {
+ $clientId = $grantType->getClientId();
+ } else {
+ // validate the Client ID (if applicable)
+ if (!is_null($storedClientId = $grantType->getClientId()) && $storedClientId != $clientId) {
+ $response->setError(400, 'invalid_grant', sprintf('%s doesn\'t exist or is invalid for the client', $grantTypeIdentifier));
+
+ return null;
+ }
+ }
+
+ /**
+ * Validate the client can use the requested grant type
+ */
+ if (!$this->clientStorage->checkRestrictedGrantType($clientId, $grantTypeIdentifier)) {
+ $response->setError(400, 'unauthorized_client', 'The grant type is unauthorized for this client_id');
+
+ return false;
+ }
+
+ /**
+ * Validate the scope of the token
+ *
+ * requestedScope - the scope specified in the token request
+ * availableScope - the scope associated with the grant type
+ * ex: in the case of the "Authorization Code" grant type,
+ * the scope is specified in the authorize request
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-3.3
+ */
+
+ $requestedScope = $this->scopeUtil->getScopeFromRequest($request);
+ $availableScope = $grantType->getScope();
+
+ if ($requestedScope) {
+ // validate the requested scope
+ if ($availableScope) {
+ if (!$this->scopeUtil->checkScope($requestedScope, $availableScope)) {
+ $response->setError(400, 'invalid_scope', 'The scope requested is invalid for this request');
+
+ return null;
+ }
+ } else {
+ // validate the client has access to this scope
+ if ($clientScope = $this->clientStorage->getClientScope($clientId)) {
+ if (!$this->scopeUtil->checkScope($requestedScope, $clientScope)) {
+ $response->setError(400, 'invalid_scope', 'The scope requested is invalid for this client');
+
+ return false;
+ }
+ } elseif (!$this->scopeUtil->scopeExists($requestedScope)) {
+ $response->setError(400, 'invalid_scope', 'An unsupported scope was requested');
+
+ return null;
+ }
+ }
+ } elseif ($availableScope) {
+ // use the scope associated with this grant type
+ $requestedScope = $availableScope;
+ } else {
+ // use a globally-defined default scope
+ $defaultScope = $this->scopeUtil->getDefaultScope($clientId);
+
+ // "false" means default scopes are not allowed
+ if (false === $defaultScope) {
+ $response->setError(400, 'invalid_scope', 'This application requires you specify a scope parameter');
+
+ return null;
+ }
+
+ $requestedScope = $defaultScope;
+ }
+
+ return $grantType->createAccessToken($this->accessToken, $clientId, $grantType->getUserId(), $requestedScope);
+ }
+
+ /**
+ * addGrantType
+ *
+ * @param GrantTypeInterface $grantType the grant type to add for the specified identifier
+ * @param string $identifier a string passed in as "grant_type" in the response that will call this grantType
+ */
+ public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
+ {
+ if (is_null($identifier) || is_numeric($identifier)) {
+ $identifier = $grantType->getQuerystringIdentifier();
+ }
+
+ $this->grantTypes[$identifier] = $grantType;
+ }
+
+ public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if ($this->revokeToken($request, $response)) {
+ $response->setStatusCode(200);
+ $response->addParameters(array('revoked' => true));
+ }
+ }
+
+ /**
+ * Revoke a refresh or access token. Returns true on success and when tokens are invalid
+ *
+ * Note: invalid tokens do not cause an error response since the client
+ * cannot handle such an error in a reasonable way. Moreover, the
+ * purpose of the revocation request, invalidating the particular token,
+ * is already achieved.
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return bool|null
+ */
+ public function revokeToken(RequestInterface $request, ResponseInterface $response)
+ {
+ if (strtolower($request->server('REQUEST_METHOD')) != 'post') {
+ $response->setError(405, 'invalid_request', 'The request method must be POST when revoking an access token', '#section-3.2');
+ $response->addHttpHeaders(array('Allow' => 'POST'));
+
+ return null;
+ }
+
+ $token_type_hint = $request->request('token_type_hint');
+ if (!in_array($token_type_hint, array(null, 'access_token', 'refresh_token'), true)) {
+ $response->setError(400, 'invalid_request', 'Token type hint must be either \'access_token\' or \'refresh_token\'');
+
+ return null;
+ }
+
+ $token = $request->request('token');
+ if ($token === null) {
+ $response->setError(400, 'invalid_request', 'Missing token parameter to revoke');
+
+ return null;
+ }
+
+ // @todo remove this check for v2.0
+ if (!method_exists($this->accessToken, 'revokeToken')) {
+ $class = get_class($this->accessToken);
+ throw new \RuntimeException("AccessToken {$class} does not implement required revokeToken method");
+ }
+
+ $this->accessToken->revokeToken($token, $token_type_hint);
+
+ return true;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenControllerInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenControllerInterface.php
new file mode 100644
index 000000000..72d72570f
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Controller/TokenControllerInterface.php
@@ -0,0 +1,32 @@
+ $tokenController->handleTokenRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response());
+ * > $response->send();
+ *
+ */
+interface TokenControllerInterface
+{
+ /**
+ * handleTokenRequest
+ *
+ * @param $request
+ * OAuth2\RequestInterface - The current http request
+ * @param $response
+ * OAuth2\ResponseInterface - An instance of OAuth2\ResponseInterface to contain the response data
+ *
+ */
+ public function handleTokenRequest(RequestInterface $request, ResponseInterface $response);
+
+ public function grantAccessToken(RequestInterface $request, ResponseInterface $response);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/EncryptionInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/EncryptionInterface.php
new file mode 100644
index 000000000..2d336c664
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/EncryptionInterface.php
@@ -0,0 +1,11 @@
+
+ */
+class FirebaseJwt implements EncryptionInterface
+{
+ public function __construct()
+ {
+ if (!class_exists('\JWT')) {
+ throw new \ErrorException('firebase/php-jwt must be installed to use this feature. You can do this by running "composer require firebase/php-jwt"');
+ }
+ }
+
+ public function encode($payload, $key, $alg = 'HS256', $keyId = null)
+ {
+ return \JWT::encode($payload, $key, $alg, $keyId);
+ }
+
+ public function decode($jwt, $key = null, $allowedAlgorithms = null)
+ {
+ try {
+
+ //Maintain BC: Do not verify if no algorithms are passed in.
+ if (!$allowedAlgorithms) {
+ $key = null;
+ }
+
+ return (array)\JWT::decode($jwt, $key, $allowedAlgorithms);
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ public function urlSafeB64Encode($data)
+ {
+ return \JWT::urlsafeB64Encode($data);
+ }
+
+ public function urlSafeB64Decode($b64)
+ {
+ return \JWT::urlsafeB64Decode($b64);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/Jwt.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/Jwt.php
new file mode 100644
index 000000000..ee576e643
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Encryption/Jwt.php
@@ -0,0 +1,173 @@
+generateJwtHeader($payload, $algo);
+
+ $segments = array(
+ $this->urlSafeB64Encode(json_encode($header)),
+ $this->urlSafeB64Encode(json_encode($payload))
+ );
+
+ $signing_input = implode('.', $segments);
+
+ $signature = $this->sign($signing_input, $key, $algo);
+ $segments[] = $this->urlsafeB64Encode($signature);
+
+ return implode('.', $segments);
+ }
+
+ public function decode($jwt, $key = null, $allowedAlgorithms = true)
+ {
+ if (!strpos($jwt, '.')) {
+ return false;
+ }
+
+ $tks = explode('.', $jwt);
+
+ if (count($tks) != 3) {
+ return false;
+ }
+
+ list($headb64, $payloadb64, $cryptob64) = $tks;
+
+ if (null === ($header = json_decode($this->urlSafeB64Decode($headb64), true))) {
+ return false;
+ }
+
+ if (null === $payload = json_decode($this->urlSafeB64Decode($payloadb64), true)) {
+ return false;
+ }
+
+ $sig = $this->urlSafeB64Decode($cryptob64);
+
+ if ((bool) $allowedAlgorithms) {
+ if (!isset($header['alg'])) {
+ return false;
+ }
+
+ // check if bool arg supplied here to maintain BC
+ if (is_array($allowedAlgorithms) && !in_array($header['alg'], $allowedAlgorithms)) {
+ return false;
+ }
+
+ if (!$this->verifySignature($sig, "$headb64.$payloadb64", $key, $header['alg'])) {
+ return false;
+ }
+ }
+
+ return $payload;
+ }
+
+ private function verifySignature($signature, $input, $key, $algo = 'HS256')
+ {
+ // use constants when possible, for HipHop support
+ switch ($algo) {
+ case'HS256':
+ case'HS384':
+ case'HS512':
+ return $this->hash_equals(
+ $this->sign($input, $key, $algo),
+ $signature
+ );
+
+ case 'RS256':
+ return openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA256') ? OPENSSL_ALGO_SHA256 : 'sha256') === 1;
+
+ case 'RS384':
+ return @openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'sha384') === 1;
+
+ case 'RS512':
+ return @openssl_verify($input, $signature, $key, defined('OPENSSL_ALGO_SHA512') ? OPENSSL_ALGO_SHA512 : 'sha512') === 1;
+
+ default:
+ throw new \InvalidArgumentException("Unsupported or invalid signing algorithm.");
+ }
+ }
+
+ private function sign($input, $key, $algo = 'HS256')
+ {
+ switch ($algo) {
+ case 'HS256':
+ return hash_hmac('sha256', $input, $key, true);
+
+ case 'HS384':
+ return hash_hmac('sha384', $input, $key, true);
+
+ case 'HS512':
+ return hash_hmac('sha512', $input, $key, true);
+
+ case 'RS256':
+ return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA256') ? OPENSSL_ALGO_SHA256 : 'sha256');
+
+ case 'RS384':
+ return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'sha384');
+
+ case 'RS512':
+ return $this->generateRSASignature($input, $key, defined('OPENSSL_ALGO_SHA512') ? OPENSSL_ALGO_SHA512 : 'sha512');
+
+ default:
+ throw new \Exception("Unsupported or invalid signing algorithm.");
+ }
+ }
+
+ private function generateRSASignature($input, $key, $algo)
+ {
+ if (!openssl_sign($input, $signature, $key, $algo)) {
+ throw new \Exception("Unable to sign data.");
+ }
+
+ return $signature;
+ }
+
+ public function urlSafeB64Encode($data)
+ {
+ $b64 = base64_encode($data);
+ $b64 = str_replace(array('+', '/', "\r", "\n", '='),
+ array('-', '_'),
+ $b64);
+
+ return $b64;
+ }
+
+ public function urlSafeB64Decode($b64)
+ {
+ $b64 = str_replace(array('-', '_'),
+ array('+', '/'),
+ $b64);
+
+ return base64_decode($b64);
+ }
+
+ /**
+ * Override to create a custom header
+ */
+ protected function generateJwtHeader($payload, $algorithm)
+ {
+ return array(
+ 'typ' => 'JWT',
+ 'alg' => $algorithm,
+ );
+ }
+
+ protected function hash_equals($a, $b)
+ {
+ if (function_exists('hash_equals')) {
+ return hash_equals($a, $b);
+ }
+ $diff = strlen($a) ^ strlen($b);
+ for ($i = 0; $i < strlen($a) && $i < strlen($b); $i++) {
+ $diff |= ord($a[$i]) ^ ord($b[$i]);
+ }
+
+ return $diff === 0;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/AuthorizationCode.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/AuthorizationCode.php
new file mode 100644
index 000000000..cae9f787d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/AuthorizationCode.php
@@ -0,0 +1,100 @@
+
+ */
+class AuthorizationCode implements GrantTypeInterface
+{
+ protected $storage;
+ protected $authCode;
+
+ /**
+ * @param \OAuth2\Storage\AuthorizationCodeInterface $storage REQUIRED Storage class for retrieving authorization code information
+ */
+ public function __construct(AuthorizationCodeInterface $storage)
+ {
+ $this->storage = $storage;
+ }
+
+ public function getQuerystringIdentifier()
+ {
+ return 'authorization_code';
+ }
+
+ public function validateRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!$request->request('code')) {
+ $response->setError(400, 'invalid_request', 'Missing parameter: "code" is required');
+
+ return false;
+ }
+
+ $code = $request->request('code');
+ if (!$authCode = $this->storage->getAuthorizationCode($code)) {
+ $response->setError(400, 'invalid_grant', 'Authorization code doesn\'t exist or is invalid for the client');
+
+ return false;
+ }
+
+ /*
+ * 4.1.3 - ensure that the "redirect_uri" parameter is present if the "redirect_uri" parameter was included in the initial authorization request
+ * @uri - http://tools.ietf.org/html/rfc6749#section-4.1.3
+ */
+ if (isset($authCode['redirect_uri']) && $authCode['redirect_uri']) {
+ if (!$request->request('redirect_uri') || urldecode($request->request('redirect_uri')) != urldecode($authCode['redirect_uri'])) {
+ $response->setError(400, 'redirect_uri_mismatch', "The redirect URI is missing or do not match", "#section-4.1.3");
+
+ return false;
+ }
+ }
+
+ if (!isset($authCode['expires'])) {
+ throw new \Exception('Storage must return authcode with a value for "expires"');
+ }
+
+ if ($authCode["expires"] < time()) {
+ $response->setError(400, 'invalid_grant', "The authorization code has expired");
+
+ return false;
+ }
+
+ if (!isset($authCode['code'])) {
+ $authCode['code'] = $code; // used to expire the code after the access token is granted
+ }
+
+ $this->authCode = $authCode;
+
+ return true;
+ }
+
+ public function getClientId()
+ {
+ return $this->authCode['client_id'];
+ }
+
+ public function getScope()
+ {
+ return isset($this->authCode['scope']) ? $this->authCode['scope'] : null;
+ }
+
+ public function getUserId()
+ {
+ return isset($this->authCode['user_id']) ? $this->authCode['user_id'] : null;
+ }
+
+ public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
+ {
+ $token = $accessToken->createAccessToken($client_id, $user_id, $scope);
+ $this->storage->expireAuthorizationCode($this->authCode['code']);
+
+ return $token;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/ClientCredentials.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/ClientCredentials.php
new file mode 100644
index 000000000..f953e4e8d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/ClientCredentials.php
@@ -0,0 +1,67 @@
+
+ *
+ * @see OAuth2\ClientAssertionType_HttpBasic
+ */
+class ClientCredentials extends HttpBasic implements GrantTypeInterface
+{
+ private $clientData;
+
+ public function __construct(ClientCredentialsInterface $storage, array $config = array())
+ {
+ /**
+ * The client credentials grant type MUST only be used by confidential clients
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.4
+ */
+ $config['allow_public_clients'] = false;
+
+ parent::__construct($storage, $config);
+ }
+
+ public function getQuerystringIdentifier()
+ {
+ return 'client_credentials';
+ }
+
+ public function getScope()
+ {
+ $this->loadClientData();
+
+ return isset($this->clientData['scope']) ? $this->clientData['scope'] : null;
+ }
+
+ public function getUserId()
+ {
+ $this->loadClientData();
+
+ return isset($this->clientData['user_id']) ? $this->clientData['user_id'] : null;
+ }
+
+ public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
+ {
+ /**
+ * Client Credentials Grant does NOT include a refresh token
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.4.3
+ */
+ $includeRefreshToken = false;
+
+ return $accessToken->createAccessToken($client_id, $user_id, $scope, $includeRefreshToken);
+ }
+
+ private function loadClientData()
+ {
+ if (!$this->clientData) {
+ $this->clientData = $this->storage->getClientDetails($this->getClientId());
+ }
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/GrantTypeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/GrantTypeInterface.php
new file mode 100644
index 000000000..98489e9c1
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/GrantTypeInterface.php
@@ -0,0 +1,20 @@
+
+ */
+class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
+{
+ private $jwt;
+
+ protected $storage;
+ protected $audience;
+ protected $jwtUtil;
+ protected $allowedAlgorithms;
+
+ /**
+ * Creates an instance of the JWT bearer grant type.
+ *
+ * @param OAuth2\Storage\JWTBearerInterface|JwtBearerInterface $storage A valid storage interface that implements storage hooks for the JWT bearer grant type.
+ * @param string $audience The audience to validate the token against. This is usually the full URI of the OAuth token requests endpoint.
+ * @param EncryptionInterface|OAuth2\Encryption\JWT $jwtUtil OPTONAL The class used to decode, encode and verify JWTs.
+ * @param array $config
+ */
+ public function __construct(JwtBearerInterface $storage, $audience, EncryptionInterface $jwtUtil = null, array $config = array())
+ {
+ $this->storage = $storage;
+ $this->audience = $audience;
+
+ if (is_null($jwtUtil)) {
+ $jwtUtil = new Jwt();
+ }
+
+ $this->config = array_merge(array(
+ 'allowed_algorithms' => array('RS256', 'RS384', 'RS512')
+ ), $config);
+
+ $this->jwtUtil = $jwtUtil;
+
+ $this->allowedAlgorithms = $this->config['allowed_algorithms'];
+ }
+
+ /**
+ * Returns the grant_type get parameter to identify the grant type request as JWT bearer authorization grant.
+ *
+ * @return
+ * The string identifier for grant_type.
+ *
+ * @see OAuth2\GrantType\GrantTypeInterface::getQuerystringIdentifier()
+ */
+ public function getQuerystringIdentifier()
+ {
+ return 'urn:ietf:params:oauth:grant-type:jwt-bearer';
+ }
+
+ /**
+ * Validates the data from the decoded JWT.
+ *
+ * @return
+ * TRUE if the JWT request is valid and can be decoded. Otherwise, FALSE is returned.
+ *
+ * @see OAuth2\GrantType\GrantTypeInterface::getTokenData()
+ */
+ public function validateRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!$request->request("assertion")) {
+ $response->setError(400, 'invalid_request', 'Missing parameters: "assertion" required');
+
+ return null;
+ }
+
+ // Store the undecoded JWT for later use
+ $undecodedJWT = $request->request('assertion');
+
+ // Decode the JWT
+ $jwt = $this->jwtUtil->decode($request->request('assertion'), null, false);
+
+ if (!$jwt) {
+ $response->setError(400, 'invalid_request', "JWT is malformed");
+
+ return null;
+ }
+
+ // ensure these properties contain a value
+ // @todo: throw malformed error for missing properties
+ $jwt = array_merge(array(
+ 'scope' => null,
+ 'iss' => null,
+ 'sub' => null,
+ 'aud' => null,
+ 'exp' => null,
+ 'nbf' => null,
+ 'iat' => null,
+ 'jti' => null,
+ 'typ' => null,
+ ), $jwt);
+
+ if (!isset($jwt['iss'])) {
+ $response->setError(400, 'invalid_grant', "Invalid issuer (iss) provided");
+
+ return null;
+ }
+
+ if (!isset($jwt['sub'])) {
+ $response->setError(400, 'invalid_grant', "Invalid subject (sub) provided");
+
+ return null;
+ }
+
+ if (!isset($jwt['exp'])) {
+ $response->setError(400, 'invalid_grant', "Expiration (exp) time must be present");
+
+ return null;
+ }
+
+ // Check expiration
+ if (ctype_digit($jwt['exp'])) {
+ if ($jwt['exp'] <= time()) {
+ $response->setError(400, 'invalid_grant', "JWT has expired");
+
+ return null;
+ }
+ } else {
+ $response->setError(400, 'invalid_grant', "Expiration (exp) time must be a unix time stamp");
+
+ return null;
+ }
+
+ // Check the not before time
+ if ($notBefore = $jwt['nbf']) {
+ if (ctype_digit($notBefore)) {
+ if ($notBefore > time()) {
+ $response->setError(400, 'invalid_grant', "JWT cannot be used before the Not Before (nbf) time");
+
+ return null;
+ }
+ } else {
+ $response->setError(400, 'invalid_grant', "Not Before (nbf) time must be a unix time stamp");
+
+ return null;
+ }
+ }
+
+ // Check the audience if required to match
+ if (!isset($jwt['aud']) || ($jwt['aud'] != $this->audience)) {
+ $response->setError(400, 'invalid_grant', "Invalid audience (aud)");
+
+ return null;
+ }
+
+ // Check the jti (nonce)
+ // @see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1.7
+ if (isset($jwt['jti'])) {
+ $jti = $this->storage->getJti($jwt['iss'], $jwt['sub'], $jwt['aud'], $jwt['exp'], $jwt['jti']);
+
+ //Reject if jti is used and jwt is still valid (exp parameter has not expired).
+ if ($jti && $jti['expires'] > time()) {
+ $response->setError(400, 'invalid_grant', "JSON Token Identifier (jti) has already been used");
+
+ return null;
+ } else {
+ $this->storage->setJti($jwt['iss'], $jwt['sub'], $jwt['aud'], $jwt['exp'], $jwt['jti']);
+ }
+ }
+
+ // Get the iss's public key
+ // @see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06#section-4.1.1
+ if (!$key = $this->storage->getClientKey($jwt['iss'], $jwt['sub'])) {
+ $response->setError(400, 'invalid_grant', "Invalid issuer (iss) or subject (sub) provided");
+
+ return null;
+ }
+
+ // Verify the JWT
+ if (!$this->jwtUtil->decode($undecodedJWT, $key, $this->allowedAlgorithms)) {
+ $response->setError(400, 'invalid_grant', "JWT failed signature verification");
+
+ return null;
+ }
+
+ $this->jwt = $jwt;
+
+ return true;
+ }
+
+ public function getClientId()
+ {
+ return $this->jwt['iss'];
+ }
+
+ public function getUserId()
+ {
+ return $this->jwt['sub'];
+ }
+
+ public function getScope()
+ {
+ return null;
+ }
+
+ /**
+ * Creates an access token that is NOT associated with a refresh token.
+ * If a subject (sub) the name of the user/account we are accessing data on behalf of.
+ *
+ * @see OAuth2\GrantType\GrantTypeInterface::createAccessToken()
+ */
+ public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
+ {
+ $includeRefreshToken = false;
+
+ return $accessToken->createAccessToken($client_id, $user_id, $scope, $includeRefreshToken);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/RefreshToken.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/RefreshToken.php
new file mode 100644
index 000000000..e55385222
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/RefreshToken.php
@@ -0,0 +1,111 @@
+
+ */
+class RefreshToken implements GrantTypeInterface
+{
+ private $refreshToken;
+
+ protected $storage;
+ protected $config;
+
+ /**
+ * @param OAuth2\Storage\RefreshTokenInterface $storage REQUIRED Storage class for retrieving refresh token information
+ * @param array $config OPTIONAL Configuration options for the server
+ *
+ * $config = array(
+ * 'always_issue_new_refresh_token' => true, // whether to issue a new refresh token upon successful token request
+ * 'unset_refresh_token_after_use' => true // whether to unset the refresh token after after using
+ * );
+ *
+ */
+ public function __construct(RefreshTokenInterface $storage, $config = array())
+ {
+ $this->config = array_merge(array(
+ 'always_issue_new_refresh_token' => false,
+ 'unset_refresh_token_after_use' => true
+ ), $config);
+
+ // to preserve B.C. with v1.6
+ // @see https://github.com/bshaffer/oauth2-server-php/pull/580
+ // @todo - remove in v2.0
+ if (isset($config['always_issue_new_refresh_token']) && !isset($config['unset_refresh_token_after_use'])) {
+ $this->config['unset_refresh_token_after_use'] = $config['always_issue_new_refresh_token'];
+ }
+
+ $this->storage = $storage;
+ }
+
+ public function getQuerystringIdentifier()
+ {
+ return 'refresh_token';
+ }
+
+ public function validateRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!$request->request("refresh_token")) {
+ $response->setError(400, 'invalid_request', 'Missing parameter: "refresh_token" is required');
+
+ return null;
+ }
+
+ if (!$refreshToken = $this->storage->getRefreshToken($request->request("refresh_token"))) {
+ $response->setError(400, 'invalid_grant', 'Invalid refresh token');
+
+ return null;
+ }
+
+ if ($refreshToken['expires'] > 0 && $refreshToken["expires"] < time()) {
+ $response->setError(400, 'invalid_grant', 'Refresh token has expired');
+
+ return null;
+ }
+
+ // store the refresh token locally so we can delete it when a new refresh token is generated
+ $this->refreshToken = $refreshToken;
+
+ return true;
+ }
+
+ public function getClientId()
+ {
+ return $this->refreshToken['client_id'];
+ }
+
+ public function getUserId()
+ {
+ return isset($this->refreshToken['user_id']) ? $this->refreshToken['user_id'] : null;
+ }
+
+ public function getScope()
+ {
+ return isset($this->refreshToken['scope']) ? $this->refreshToken['scope'] : null;
+ }
+
+ public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
+ {
+ /*
+ * It is optional to force a new refresh token when a refresh token is used.
+ * However, if a new refresh token is issued, the old one MUST be expired
+ * @see http://tools.ietf.org/html/rfc6749#section-6
+ */
+ $issueNewRefreshToken = $this->config['always_issue_new_refresh_token'];
+ $unsetRefreshToken = $this->config['unset_refresh_token_after_use'];
+ $token = $accessToken->createAccessToken($client_id, $user_id, $scope, $issueNewRefreshToken);
+
+ if ($unsetRefreshToken) {
+ $this->storage->unsetRefreshToken($this->refreshToken['refresh_token']);
+ }
+
+ return $token;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/UserCredentials.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/UserCredentials.php
new file mode 100644
index 000000000..f165538ba
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/GrantType/UserCredentials.php
@@ -0,0 +1,83 @@
+
+ */
+class UserCredentials implements GrantTypeInterface
+{
+ private $userInfo;
+
+ protected $storage;
+
+ /**
+ * @param OAuth2\Storage\UserCredentialsInterface $storage REQUIRED Storage class for retrieving user credentials information
+ */
+ public function __construct(UserCredentialsInterface $storage)
+ {
+ $this->storage = $storage;
+ }
+
+ public function getQuerystringIdentifier()
+ {
+ return 'password';
+ }
+
+ public function validateRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!$request->request("password") || !$request->request("username")) {
+ $response->setError(400, 'invalid_request', 'Missing parameters: "username" and "password" required');
+
+ return null;
+ }
+
+ if (!$this->storage->checkUserCredentials($request->request("username"), $request->request("password"))) {
+ $response->setError(401, 'invalid_grant', 'Invalid username and password combination');
+
+ return null;
+ }
+
+ $userInfo = $this->storage->getUserDetails($request->request("username"));
+
+ if (empty($userInfo)) {
+ $response->setError(400, 'invalid_grant', 'Unable to retrieve user information');
+
+ return null;
+ }
+
+ if (!isset($userInfo['user_id'])) {
+ throw new \LogicException("you must set the user_id on the array returned by getUserDetails");
+ }
+
+ $this->userInfo = $userInfo;
+
+ return true;
+ }
+
+ public function getClientId()
+ {
+ return null;
+ }
+
+ public function getUserId()
+ {
+ return $this->userInfo['user_id'];
+ }
+
+ public function getScope()
+ {
+ return isset($this->userInfo['scope']) ? $this->userInfo['scope'] : null;
+ }
+
+ public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
+ {
+ return $accessToken->createAccessToken($client_id, $user_id, $scope);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeController.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeController.php
new file mode 100644
index 000000000..c9b5c6af7
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeController.php
@@ -0,0 +1,106 @@
+query('prompt', 'consent');
+ if ($prompt == 'none') {
+ if (is_null($user_id)) {
+ $error = 'login_required';
+ $error_message = 'The user must log in';
+ } else {
+ $error = 'interaction_required';
+ $error_message = 'The user must grant access to your application';
+ }
+ } else {
+ $error = 'consent_required';
+ $error_message = 'The user denied access to your application';
+ }
+
+ $response->setRedirect($this->config['redirect_status_code'], $redirect_uri, $this->getState(), $error, $error_message);
+ }
+
+ protected function buildAuthorizeParameters($request, $response, $user_id)
+ {
+ if (!$params = parent::buildAuthorizeParameters($request, $response, $user_id)) {
+ return;
+ }
+
+ // Generate an id token if needed.
+ if ($this->needsIdToken($this->getScope()) && $this->getResponseType() == self::RESPONSE_TYPE_AUTHORIZATION_CODE) {
+ $params['id_token'] = $this->responseTypes['id_token']->createIdToken($this->getClientId(), $user_id, $this->nonce);
+ }
+
+ // add the nonce to return with the redirect URI
+ $params['nonce'] = $this->nonce;
+
+ return $params;
+ }
+
+ public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!parent::validateAuthorizeRequest($request, $response)) {
+ return false;
+ }
+
+ $nonce = $request->query('nonce');
+
+ // Validate required nonce for "id_token" and "id_token token"
+ if (!$nonce && in_array($this->getResponseType(), array(self::RESPONSE_TYPE_ID_TOKEN, self::RESPONSE_TYPE_ID_TOKEN_TOKEN))) {
+ $response->setError(400, 'invalid_nonce', 'This application requires you specify a nonce parameter');
+
+ return false;
+ }
+
+ $this->nonce = $nonce;
+
+ return true;
+ }
+
+ protected function getValidResponseTypes()
+ {
+ return array(
+ self::RESPONSE_TYPE_ACCESS_TOKEN,
+ self::RESPONSE_TYPE_AUTHORIZATION_CODE,
+ self::RESPONSE_TYPE_ID_TOKEN,
+ self::RESPONSE_TYPE_ID_TOKEN_TOKEN,
+ self::RESPONSE_TYPE_CODE_ID_TOKEN,
+ );
+ }
+
+ /**
+ * Returns whether the current request needs to generate an id token.
+ *
+ * ID Tokens are a part of the OpenID Connect specification, so this
+ * method checks whether OpenID Connect is enabled in the server settings
+ * and whether the openid scope was requested.
+ *
+ * @param $request_scope
+ * A space-separated string of scopes.
+ *
+ * @return
+ * TRUE if an id token is needed, FALSE otherwise.
+ */
+ public function needsIdToken($request_scope)
+ {
+ // see if the "openid" scope exists in the requested scope
+ return $this->scopeUtil->checkScope('openid', $request_scope);
+ }
+
+ public function getNonce()
+ {
+ return $this->nonce;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
new file mode 100644
index 000000000..1e231d844
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/AuthorizeControllerInterface.php
@@ -0,0 +1,10 @@
+tokenType = $tokenType;
+ $this->tokenStorage = $tokenStorage;
+ $this->userClaimsStorage = $userClaimsStorage;
+
+ $this->config = array_merge(array(
+ 'www_realm' => 'Service',
+ ), $config);
+
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new Scope();
+ }
+ $this->scopeUtil = $scopeUtil;
+ }
+
+ public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response)
+ {
+ if (!$this->verifyResourceRequest($request, $response, 'openid')) {
+ return;
+ }
+
+ $token = $this->getToken();
+ $claims = $this->userClaimsStorage->getUserClaims($token['user_id'], $token['scope']);
+ // The sub Claim MUST always be returned in the UserInfo Response.
+ // http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
+ $claims += array(
+ 'sub' => $token['user_id'],
+ );
+ $response->addParameters($claims);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
new file mode 100644
index 000000000..a89049d49
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Controller/UserInfoControllerInterface.php
@@ -0,0 +1,23 @@
+ $response = new OAuth2\Response();
+ * > $userInfoController->handleUserInfoRequest(
+ * > OAuth2\Request::createFromGlobals(),
+ * > $response;
+ * > $response->send();
+ *
+ */
+interface UserInfoControllerInterface
+{
+ public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/GrantType/AuthorizationCode.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/GrantType/AuthorizationCode.php
new file mode 100644
index 000000000..8ed1edc26
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/GrantType/AuthorizationCode.php
@@ -0,0 +1,33 @@
+
+ */
+class AuthorizationCode extends BaseAuthorizationCode
+{
+ public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
+ {
+ $includeRefreshToken = true;
+ if (isset($this->authCode['id_token'])) {
+ // OpenID Connect requests include the refresh token only if the
+ // offline_access scope has been requested and granted.
+ $scopes = explode(' ', trim($scope));
+ $includeRefreshToken = in_array('offline_access', $scopes);
+ }
+
+ $token = $accessToken->createAccessToken($client_id, $user_id, $scope, $includeRefreshToken);
+ if (isset($this->authCode['id_token'])) {
+ $token['id_token'] = $this->authCode['id_token'];
+ }
+
+ $this->storage->expireAuthorizationCode($this->authCode['code']);
+
+ return $token;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php
new file mode 100644
index 000000000..8971954c5
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCode.php
@@ -0,0 +1,60 @@
+
+ */
+class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCodeInterface
+{
+ public function __construct(AuthorizationCodeStorageInterface $storage, array $config = array())
+ {
+ parent::__construct($storage, $config);
+ }
+
+ public function getAuthorizeResponse($params, $user_id = null)
+ {
+ // build the URL to redirect to
+ $result = array('query' => array());
+
+ $params += array('scope' => null, 'state' => null, 'id_token' => null);
+
+ $result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['id_token']);
+
+ if (isset($params['state'])) {
+ $result['query']['state'] = $params['state'];
+ }
+
+ return array($params['redirect_uri'], $result);
+ }
+
+ /**
+ * Handle the creation of the authorization code.
+ *
+ * @param $client_id
+ * Client identifier related to the authorization code
+ * @param $user_id
+ * User ID associated with the authorization code
+ * @param $redirect_uri
+ * An absolute URI to which the authorization server will redirect the
+ * user-agent to when the end-user authorization step is completed.
+ * @param $scope
+ * (optional) Scopes to be stored in space-separated string.
+ * @param $id_token
+ * (optional) The OpenID Connect id_token.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ * @ingroup oauth2_section_4
+ */
+ public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null)
+ {
+ $code = $this->generateAuthorizationCode();
+ $this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, $id_token);
+
+ return $code;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
new file mode 100644
index 000000000..ea4779255
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/AuthorizationCodeInterface.php
@@ -0,0 +1,27 @@
+
+ */
+interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
+{
+ /**
+ * Handle the creation of the authorization code.
+ *
+ * @param $client_id Client identifier related to the authorization code
+ * @param $user_id User ID associated with the authorization code
+ * @param $redirect_uri An absolute URI to which the authorization server will redirect the
+ * user-agent to when the end-user authorization step is completed.
+ * @param $scope OPTIONAL Scopes to be stored in space-separated string.
+ * @param $id_token OPTIONAL The OpenID Connect id_token.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ * @ingroup oauth2_section_4
+ */
+ public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdToken.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdToken.php
new file mode 100644
index 000000000..ac7764d6c
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdToken.php
@@ -0,0 +1,24 @@
+authCode = $authCode;
+ $this->idToken = $idToken;
+ }
+
+ public function getAuthorizeResponse($params, $user_id = null)
+ {
+ $result = $this->authCode->getAuthorizeResponse($params, $user_id);
+ $resultIdToken = $this->idToken->getAuthorizeResponse($params, $user_id);
+ $result[1]['query']['id_token'] = $resultIdToken[1]['fragment']['id_token'];
+
+ return $result;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php
new file mode 100644
index 000000000..629adcca8
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/CodeIdTokenInterface.php
@@ -0,0 +1,9 @@
+userClaimsStorage = $userClaimsStorage;
+ $this->publicKeyStorage = $publicKeyStorage;
+ if (is_null($encryptionUtil)) {
+ $encryptionUtil = new Jwt();
+ }
+ $this->encryptionUtil = $encryptionUtil;
+
+ if (!isset($config['issuer'])) {
+ throw new \LogicException('config parameter "issuer" must be set');
+ }
+ $this->config = array_merge(array(
+ 'id_lifetime' => 3600,
+ ), $config);
+ }
+
+ public function getAuthorizeResponse($params, $userInfo = null)
+ {
+ // build the URL to redirect to
+ $result = array('query' => array());
+ $params += array('scope' => null, 'state' => null, 'nonce' => null);
+
+ // create the id token.
+ list($user_id, $auth_time) = $this->getUserIdAndAuthTime($userInfo);
+ $userClaims = $this->userClaimsStorage->getUserClaims($user_id, $params['scope']);
+
+ $id_token = $this->createIdToken($params['client_id'], $userInfo, $params['nonce'], $userClaims, null);
+ $result["fragment"] = array('id_token' => $id_token);
+ if (isset($params['state'])) {
+ $result["fragment"]["state"] = $params['state'];
+ }
+
+ return array($params['redirect_uri'], $result);
+ }
+
+ public function createIdToken($client_id, $userInfo, $nonce = null, $userClaims = null, $access_token = null)
+ {
+ // pull auth_time from user info if supplied
+ list($user_id, $auth_time) = $this->getUserIdAndAuthTime($userInfo);
+
+ $token = array(
+ 'iss' => $this->config['issuer'],
+ 'sub' => $user_id,
+ 'aud' => $client_id,
+ 'iat' => time(),
+ 'exp' => time() + $this->config['id_lifetime'],
+ 'auth_time' => $auth_time,
+ );
+
+ if ($nonce) {
+ $token['nonce'] = $nonce;
+ }
+
+ if ($userClaims) {
+ $token += $userClaims;
+ }
+
+ if ($access_token) {
+ $token['at_hash'] = $this->createAtHash($access_token, $client_id);
+ }
+
+ return $this->encodeToken($token, $client_id);
+ }
+
+ protected function createAtHash($access_token, $client_id = null)
+ {
+ // maps HS256 and RS256 to sha256, etc.
+ $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
+ $hash_algorithm = 'sha' . substr($algorithm, 2);
+ $hash = hash($hash_algorithm, $access_token, true);
+ $at_hash = substr($hash, 0, strlen($hash) / 2);
+
+ return $this->encryptionUtil->urlSafeB64Encode($at_hash);
+ }
+
+ protected function encodeToken(array $token, $client_id = null)
+ {
+ $private_key = $this->publicKeyStorage->getPrivateKey($client_id);
+ $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
+
+ return $this->encryptionUtil->encode($token, $private_key, $algorithm);
+ }
+
+ private function getUserIdAndAuthTime($userInfo)
+ {
+ $auth_time = null;
+
+ // support an array for user_id / auth_time
+ if (is_array($userInfo)) {
+ if (!isset($userInfo['user_id'])) {
+ throw new \LogicException('if $user_id argument is an array, user_id index must be set');
+ }
+
+ $auth_time = isset($userInfo['auth_time']) ? $userInfo['auth_time'] : null;
+ $user_id = $userInfo['user_id'];
+ } else {
+ $user_id = $userInfo;
+ }
+
+ if (is_null($auth_time)) {
+ $auth_time = time();
+ }
+
+ // userInfo is a scalar, and so this is the $user_id. Auth Time is null
+ return array($user_id, $auth_time);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php
new file mode 100644
index 000000000..0bd2f8391
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenInterface.php
@@ -0,0 +1,29 @@
+accessToken = $accessToken;
+ $this->idToken = $idToken;
+ }
+
+ public function getAuthorizeResponse($params, $user_id = null)
+ {
+ $result = $this->accessToken->getAuthorizeResponse($params, $user_id);
+ $access_token = $result[1]['fragment']['access_token'];
+ $id_token = $this->idToken->createIdToken($params['client_id'], $user_id, $params['nonce'], null, $access_token);
+ $result[1]['fragment']['id_token'] = $id_token;
+
+ return $result;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php
new file mode 100644
index 000000000..ac13e2032
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/ResponseType/IdTokenTokenInterface.php
@@ -0,0 +1,9 @@
+
+ */
+interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
+{
+ /**
+ * Take the provided authorization code values and store them somewhere.
+ *
+ * This function should be the storage counterpart to getAuthCode().
+ *
+ * If storage fails for some reason, we're not currently checking for
+ * any sort of success/failure, so you should bail out of the script
+ * and provide a descriptive fail message.
+ *
+ * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
+ *
+ * @param $code authorization code to be stored.
+ * @param $client_id client identifier to be stored.
+ * @param $user_id user identifier to be stored.
+ * @param string $redirect_uri redirect URI(s) to be stored in a space-separated string.
+ * @param int $expires expiration to be stored as a Unix timestamp.
+ * @param string $scope OPTIONAL scopes to be stored in space-separated string.
+ * @param string $id_token OPTIONAL the OpenID Connect id_token.
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Storage/UserClaimsInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Storage/UserClaimsInterface.php
new file mode 100644
index 000000000..f230bef9e
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/OpenID/Storage/UserClaimsInterface.php
@@ -0,0 +1,38 @@
+ value format.
+ *
+ * @see http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
+ */
+ public function getUserClaims($user_id, $scope);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Request.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Request.php
new file mode 100644
index 000000000..c92cee821
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Request.php
@@ -0,0 +1,213 @@
+initialize($query, $request, $attributes, $cookies, $files, $server, $content, $headers);
+ }
+
+ /**
+ * Sets the parameters for this request.
+ *
+ * This method also re-initializes all properties.
+ *
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ * @param string $content The raw body data
+ *
+ * @api
+ */
+ public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, array $headers = null)
+ {
+ $this->request = $request;
+ $this->query = $query;
+ $this->attributes = $attributes;
+ $this->cookies = $cookies;
+ $this->files = $files;
+ $this->server = $server;
+ $this->content = $content;
+ $this->headers = is_null($headers) ? $this->getHeadersFromServer($this->server) : $headers;
+ }
+
+ public function query($name, $default = null)
+ {
+ return isset($this->query[$name]) ? $this->query[$name] : $default;
+ }
+
+ public function request($name, $default = null)
+ {
+ return isset($this->request[$name]) ? $this->request[$name] : $default;
+ }
+
+ public function server($name, $default = null)
+ {
+ return isset($this->server[$name]) ? $this->server[$name] : $default;
+ }
+
+ public function headers($name, $default = null)
+ {
+ $headers = array_change_key_case($this->headers);
+ $name = strtolower($name);
+
+ return isset($headers[$name]) ? $headers[$name] : $default;
+ }
+
+ public function getAllQueryParameters()
+ {
+ return $this->query;
+ }
+
+ /**
+ * Returns the request body content.
+ *
+ * @param Boolean $asResource If true, a resource will be returned
+ *
+ * @return string|resource The request body content or a resource to read the body stream.
+ */
+ public function getContent($asResource = false)
+ {
+ if (false === $this->content || (true === $asResource && null !== $this->content)) {
+ throw new \LogicException('getContent() can only be called once when using the resource return type.');
+ }
+
+ if (true === $asResource) {
+ $this->content = false;
+
+ return fopen('php://input', 'rb');
+ }
+
+ if (null === $this->content) {
+ $this->content = file_get_contents('php://input');
+ }
+
+ return $this->content;
+ }
+
+ private function getHeadersFromServer($server)
+ {
+ $headers = array();
+ foreach ($server as $key => $value) {
+ if (0 === strpos($key, 'HTTP_')) {
+ $headers[substr($key, 5)] = $value;
+ }
+ // CONTENT_* are not prefixed with HTTP_
+ elseif (in_array($key, array('CONTENT_LENGTH', 'CONTENT_MD5', 'CONTENT_TYPE'))) {
+ $headers[$key] = $value;
+ }
+ }
+
+ if (isset($server['PHP_AUTH_USER'])) {
+ $headers['PHP_AUTH_USER'] = $server['PHP_AUTH_USER'];
+ $headers['PHP_AUTH_PW'] = isset($server['PHP_AUTH_PW']) ? $server['PHP_AUTH_PW'] : '';
+ } else {
+ /*
+ * php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
+ * For this workaround to work, add this line to your .htaccess file:
+ * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+ *
+ * A sample .htaccess file:
+ * RewriteEngine On
+ * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+ * RewriteCond %{REQUEST_FILENAME} !-f
+ * RewriteRule ^(.*)$ app.php [QSA,L]
+ */
+
+ $authorizationHeader = null;
+ if (isset($server['HTTP_AUTHORIZATION'])) {
+ $authorizationHeader = $server['HTTP_AUTHORIZATION'];
+ } elseif (isset($server['REDIRECT_HTTP_AUTHORIZATION'])) {
+ $authorizationHeader = $server['REDIRECT_HTTP_AUTHORIZATION'];
+ } elseif (function_exists('apache_request_headers')) {
+ $requestHeaders = (array) apache_request_headers();
+
+ // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
+ $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
+
+ if (isset($requestHeaders['Authorization'])) {
+ $authorizationHeader = trim($requestHeaders['Authorization']);
+ }
+ }
+
+ if (null !== $authorizationHeader) {
+ $headers['AUTHORIZATION'] = $authorizationHeader;
+ // Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
+ if (0 === stripos($authorizationHeader, 'basic')) {
+ $exploded = explode(':', base64_decode(substr($authorizationHeader, 6)));
+ if (count($exploded) == 2) {
+ list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
+ }
+ }
+ }
+ }
+
+ // PHP_AUTH_USER/PHP_AUTH_PW
+ if (isset($headers['PHP_AUTH_USER'])) {
+ $headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
+ }
+
+ return $headers;
+ }
+
+ /**
+ * Creates a new request with values from PHP's super globals.
+ *
+ * @return Request A new request
+ *
+ * @api
+ */
+ public static function createFromGlobals()
+ {
+ $class = get_called_class();
+ $request = new $class($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
+
+ $contentType = $request->server('CONTENT_TYPE', '');
+ $requestMethod = $request->server('REQUEST_METHOD', 'GET');
+ if (0 === strpos($contentType, 'application/x-www-form-urlencoded')
+ && in_array(strtoupper($requestMethod), array('PUT', 'DELETE'))
+ ) {
+ parse_str($request->getContent(), $data);
+ $request->request = $data;
+ } elseif (0 === strpos($contentType, 'application/json')
+ && in_array(strtoupper($requestMethod), array('POST', 'PUT', 'DELETE'))
+ ) {
+ $data = json_decode($request->getContent(), true);
+ $request->request = $data;
+ }
+
+ return $request;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/RequestInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/RequestInterface.php
new file mode 100644
index 000000000..8a70d5fad
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/RequestInterface.php
@@ -0,0 +1,16 @@
+ 'Continue',
+ 101 => 'Switching Protocols',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+ 418 => 'I\'m a teapot',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ );
+
+ public function __construct($parameters = array(), $statusCode = 200, $headers = array())
+ {
+ $this->setParameters($parameters);
+ $this->setStatusCode($statusCode);
+ $this->setHttpHeaders($headers);
+ $this->version = '1.1';
+ }
+
+ /**
+ * Converts the response object to string containing all headers and the response content.
+ *
+ * @return string The response with headers and content
+ */
+ public function __toString()
+ {
+ $headers = array();
+ foreach ($this->httpHeaders as $name => $value) {
+ $headers[$name] = (array) $value;
+ }
+
+ return
+ sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
+ $this->getHttpHeadersAsString($headers)."\r\n".
+ $this->getResponseBody();
+ }
+
+ /**
+ * Returns the build header line.
+ *
+ * @param string $name The header name
+ * @param string $value The header value
+ *
+ * @return string The built header line
+ */
+ protected function buildHeader($name, $value)
+ {
+ return sprintf("%s: %s\n", $name, $value);
+ }
+
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+
+ public function setStatusCode($statusCode, $text = null)
+ {
+ $this->statusCode = (int) $statusCode;
+ if ($this->isInvalid()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $statusCode));
+ }
+
+ $this->statusText = false === $text ? '' : (null === $text ? self::$statusTexts[$this->statusCode] : $text);
+ }
+
+ public function getStatusText()
+ {
+ return $this->statusText;
+ }
+
+ public function getParameters()
+ {
+ return $this->parameters;
+ }
+
+ public function setParameters(array $parameters)
+ {
+ $this->parameters = $parameters;
+ }
+
+ public function addParameters(array $parameters)
+ {
+ $this->parameters = array_merge($this->parameters, $parameters);
+ }
+
+ public function getParameter($name, $default = null)
+ {
+ return isset($this->parameters[$name]) ? $this->parameters[$name] : $default;
+ }
+
+ public function setParameter($name, $value)
+ {
+ $this->parameters[$name] = $value;
+ }
+
+ public function setHttpHeaders(array $httpHeaders)
+ {
+ $this->httpHeaders = $httpHeaders;
+ }
+
+ public function setHttpHeader($name, $value)
+ {
+ $this->httpHeaders[$name] = $value;
+ }
+
+ public function addHttpHeaders(array $httpHeaders)
+ {
+ $this->httpHeaders = array_merge($this->httpHeaders, $httpHeaders);
+ }
+
+ public function getHttpHeaders()
+ {
+ return $this->httpHeaders;
+ }
+
+ public function getHttpHeader($name, $default = null)
+ {
+ return isset($this->httpHeaders[$name]) ? $this->httpHeaders[$name] : $default;
+ }
+
+ public function getResponseBody($format = 'json')
+ {
+ switch ($format) {
+ case 'json':
+ return $this->parameters ? json_encode($this->parameters) : '';
+ case 'xml':
+ // this only works for single-level arrays
+ $xml = new \SimpleXMLElement('');
+ foreach ($this->parameters as $key => $param) {
+ $xml->addChild($key, $param);
+ }
+
+ return $xml->asXML();
+ }
+
+ throw new \InvalidArgumentException(sprintf('The format %s is not supported', $format));
+
+ }
+
+ public function send($format = 'json')
+ {
+ // headers have already been sent by the developer
+ if (headers_sent()) {
+ return;
+ }
+
+ switch ($format) {
+ case 'json':
+ $this->setHttpHeader('Content-Type', 'application/json');
+ break;
+ case 'xml':
+ $this->setHttpHeader('Content-Type', 'text/xml');
+ break;
+ }
+ // status
+ header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
+
+ foreach ($this->getHttpHeaders() as $name => $header) {
+ header(sprintf('%s: %s', $name, $header));
+ }
+ echo $this->getResponseBody($format);
+ }
+
+ public function setError($statusCode, $error, $errorDescription = null, $errorUri = null)
+ {
+ $parameters = array(
+ 'error' => $error,
+ 'error_description' => $errorDescription,
+ );
+
+ if (!is_null($errorUri)) {
+ if (strlen($errorUri) > 0 && $errorUri[0] == '#') {
+ // we are referencing an oauth bookmark (for brevity)
+ $errorUri = 'http://tools.ietf.org/html/rfc6749' . $errorUri;
+ }
+ $parameters['error_uri'] = $errorUri;
+ }
+
+ $httpHeaders = array(
+ 'Cache-Control' => 'no-store'
+ );
+
+ $this->setStatusCode($statusCode);
+ $this->addParameters($parameters);
+ $this->addHttpHeaders($httpHeaders);
+
+ if (!$this->isClientError() && !$this->isServerError()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code is not an error ("%s" given).', $statusCode));
+ }
+ }
+
+ public function setRedirect($statusCode, $url, $state = null, $error = null, $errorDescription = null, $errorUri = null)
+ {
+ if (empty($url)) {
+ throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
+ }
+
+ $parameters = array();
+
+ if (!is_null($state)) {
+ $parameters['state'] = $state;
+ }
+
+ if (!is_null($error)) {
+ $this->setError(400, $error, $errorDescription, $errorUri);
+ }
+ $this->setStatusCode($statusCode);
+ $this->addParameters($parameters);
+
+ if (count($this->parameters) > 0) {
+ // add parameters to URL redirection
+ $parts = parse_url($url);
+ $sep = isset($parts['query']) && count($parts['query']) > 0 ? '&' : '?';
+ $url .= $sep . http_build_query($this->parameters);
+ }
+
+ $this->addHttpHeaders(array('Location' => $url));
+
+ if (!$this->isRedirection()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $statusCode));
+ }
+ }
+
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+ /**
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isInvalid()
+ {
+ return $this->statusCode < 100 || $this->statusCode >= 600;
+ }
+
+ /**
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isInformational()
+ {
+ return $this->statusCode >= 100 && $this->statusCode < 200;
+ }
+
+ /**
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isSuccessful()
+ {
+ return $this->statusCode >= 200 && $this->statusCode < 300;
+ }
+
+ /**
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isRedirection()
+ {
+ return $this->statusCode >= 300 && $this->statusCode < 400;
+ }
+
+ /**
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isClientError()
+ {
+ return $this->statusCode >= 400 && $this->statusCode < 500;
+ }
+
+ /**
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isServerError()
+ {
+ return $this->statusCode >= 500 && $this->statusCode < 600;
+ }
+
+ /*
+ * Functions from Symfony2 HttpFoundation - output pretty header
+ */
+ private function getHttpHeadersAsString($headers)
+ {
+ if (count($headers) == 0) {
+ return '';
+ }
+
+ $max = max(array_map('strlen', array_keys($headers))) + 1;
+ $content = '';
+ ksort($headers);
+ foreach ($headers as $name => $values) {
+ foreach ($values as $value) {
+ $content .= sprintf("%-{$max}s %s\r\n", $this->beautifyHeaderName($name).':', $value);
+ }
+ }
+
+ return $content;
+ }
+
+ private function beautifyHeaderName($name)
+ {
+ return preg_replace_callback('/\-(.)/', array($this, 'beautifyCallback'), ucfirst($name));
+ }
+
+ private function beautifyCallback($match)
+ {
+ return '-'.strtoupper($match[1]);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseInterface.php
new file mode 100644
index 000000000..c99b5f7d1
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseInterface.php
@@ -0,0 +1,24 @@
+
+ */
+class AccessToken implements AccessTokenInterface
+{
+ protected $tokenStorage;
+ protected $refreshStorage;
+ protected $config;
+
+ /**
+ * @param OAuth2\Storage\AccessTokenInterface $tokenStorage REQUIRED Storage class for saving access token information
+ * @param OAuth2\Storage\RefreshTokenInterface $refreshStorage OPTIONAL Storage class for saving refresh token information
+ * @param array $config OPTIONAL Configuration options for the server
+ *
+ * $config = array(
+ * 'token_type' => 'bearer', // token type identifier
+ * 'access_lifetime' => 3600, // time before access token expires
+ * 'refresh_token_lifetime' => 1209600, // time before refresh token expires
+ * );
+ *
+ */
+ public function __construct(AccessTokenStorageInterface $tokenStorage, RefreshTokenInterface $refreshStorage = null, array $config = array())
+ {
+ $this->tokenStorage = $tokenStorage;
+ $this->refreshStorage = $refreshStorage;
+
+ $this->config = array_merge(array(
+ 'token_type' => 'bearer',
+ 'access_lifetime' => 3600,
+ 'refresh_token_lifetime' => 1209600,
+ ), $config);
+ }
+
+ public function getAuthorizeResponse($params, $user_id = null)
+ {
+ // build the URL to redirect to
+ $result = array('query' => array());
+
+ $params += array('scope' => null, 'state' => null);
+
+ /*
+ * a refresh token MUST NOT be included in the fragment
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.2.2
+ */
+ $includeRefreshToken = false;
+ $result["fragment"] = $this->createAccessToken($params['client_id'], $user_id, $params['scope'], $includeRefreshToken);
+
+ if (isset($params['state'])) {
+ $result["fragment"]["state"] = $params['state'];
+ }
+
+ return array($params['redirect_uri'], $result);
+ }
+
+ /**
+ * Handle the creation of access token, also issue refresh token if supported / desirable.
+ *
+ * @param $client_id client identifier related to the access token.
+ * @param $user_id user ID associated with the access token
+ * @param $scope OPTIONAL scopes to be stored in space-separated string.
+ * @param bool $includeRefreshToken if true, a new refresh_token will be added to the response
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-5
+ * @ingroup oauth2_section_5
+ */
+ public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
+ {
+ $token = array(
+ "access_token" => $this->generateAccessToken(),
+ "expires_in" => $this->config['access_lifetime'],
+ "token_type" => $this->config['token_type'],
+ "scope" => $scope
+ );
+
+ $this->tokenStorage->setAccessToken($token["access_token"], $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
+
+ /*
+ * Issue a refresh token also, if we support them
+ *
+ * Refresh Tokens are considered supported if an instance of OAuth2\Storage\RefreshTokenInterface
+ * is supplied in the constructor
+ */
+ if ($includeRefreshToken && $this->refreshStorage) {
+ $token["refresh_token"] = $this->generateRefreshToken();
+ $expires = 0;
+ if ($this->config['refresh_token_lifetime'] > 0) {
+ $expires = time() + $this->config['refresh_token_lifetime'];
+ }
+ $this->refreshStorage->setRefreshToken($token['refresh_token'], $client_id, $user_id, $expires, $scope);
+ }
+
+ return $token;
+ }
+
+ /**
+ * Generates an unique access token.
+ *
+ * Implementing classes may want to override this function to implement
+ * other access token generation schemes.
+ *
+ * @return
+ * An unique access token.
+ *
+ * @ingroup oauth2_section_4
+ */
+ protected function generateAccessToken()
+ {
+ if (function_exists('openssl_random_pseudo_bytes')) {
+ $randomData = openssl_random_pseudo_bytes(20);
+ if ($randomData !== false && strlen($randomData) === 20) {
+ return bin2hex($randomData);
+ }
+ }
+ if (function_exists('mcrypt_create_iv')) {
+ $randomData = mcrypt_create_iv(20, MCRYPT_DEV_URANDOM);
+ if ($randomData !== false && strlen($randomData) === 20) {
+ return bin2hex($randomData);
+ }
+ }
+ if (@file_exists('/dev/urandom')) { // Get 100 bytes of random data
+ $randomData = file_get_contents('/dev/urandom', false, null, 0, 20);
+ if ($randomData !== false && strlen($randomData) === 20) {
+ return bin2hex($randomData);
+ }
+ }
+ // Last resort which you probably should just get rid of:
+ $randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);
+
+ return substr(hash('sha512', $randomData), 0, 40);
+ }
+
+ /**
+ * Generates an unique refresh token
+ *
+ * Implementing classes may want to override this function to implement
+ * other refresh token generation schemes.
+ *
+ * @return
+ * An unique refresh.
+ *
+ * @ingroup oauth2_section_4
+ * @see OAuth2::generateAccessToken()
+ */
+ protected function generateRefreshToken()
+ {
+ return $this->generateAccessToken(); // let's reuse the same scheme for token generation
+ }
+
+ /**
+ * Handle the revoking of refresh tokens, and access tokens if supported / desirable
+ * RFC7009 specifies that "If the server is unable to locate the token using
+ * the given hint, it MUST extend its search across all of its supported token types"
+ *
+ * @param $token
+ * @param null $tokenTypeHint
+ * @return boolean
+ */
+ public function revokeToken($token, $tokenTypeHint = null)
+ {
+ if ($tokenTypeHint == 'refresh_token') {
+ if ($this->refreshStorage && $revoked = $this->refreshStorage->unsetRefreshToken($token)) {
+ return true;
+ }
+ }
+
+ /** @TODO remove in v2 */
+ if (!method_exists($this->tokenStorage, 'unsetAccessToken')) {
+ throw new \RuntimeException(
+ sprintf('Token storage %s must implement unsetAccessToken method', get_class($this->tokenStorage)
+ ));
+ }
+
+ $revoked = $this->tokenStorage->unsetAccessToken($token);
+
+ // if a typehint is supplied and fails, try other storages
+ // @see https://tools.ietf.org/html/rfc7009#section-2.1
+ if (!$revoked && $tokenTypeHint != 'refresh_token') {
+ if ($this->refreshStorage) {
+ $revoked = $this->refreshStorage->unsetRefreshToken($token);
+ }
+ }
+
+ return $revoked;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessTokenInterface.php
new file mode 100644
index 000000000..4bd3928d8
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AccessTokenInterface.php
@@ -0,0 +1,34 @@
+
+ */
+interface AccessTokenInterface extends ResponseTypeInterface
+{
+ /**
+ * Handle the creation of access token, also issue refresh token if supported / desirable.
+ *
+ * @param $client_id client identifier related to the access token.
+ * @param $user_id user ID associated with the access token
+ * @param $scope OPTONAL scopes to be stored in space-separated string.
+ * @param bool $includeRefreshToken if true, a new refresh_token will be added to the response
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-5
+ * @ingroup oauth2_section_5
+ */
+ public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true);
+
+ /**
+ * Handle the revoking of refresh tokens, and access tokens if supported / desirable
+ *
+ * @param $token
+ * @param $tokenTypeHint
+ * @return mixed
+ *
+ * @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
+ */
+ //public function revokeToken($token, $tokenTypeHint);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCode.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCode.php
new file mode 100644
index 000000000..52aeb4be5
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCode.php
@@ -0,0 +1,100 @@
+
+ */
+class AuthorizationCode implements AuthorizationCodeInterface
+{
+ protected $storage;
+ protected $config;
+
+ public function __construct(AuthorizationCodeStorageInterface $storage, array $config = array())
+ {
+ $this->storage = $storage;
+ $this->config = array_merge(array(
+ 'enforce_redirect' => false,
+ 'auth_code_lifetime' => 30,
+ ), $config);
+ }
+
+ public function getAuthorizeResponse($params, $user_id = null)
+ {
+ // build the URL to redirect to
+ $result = array('query' => array());
+
+ $params += array('scope' => null, 'state' => null);
+
+ $result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope']);
+
+ if (isset($params['state'])) {
+ $result['query']['state'] = $params['state'];
+ }
+
+ return array($params['redirect_uri'], $result);
+ }
+
+ /**
+ * Handle the creation of the authorization code.
+ *
+ * @param $client_id
+ * Client identifier related to the authorization code
+ * @param $user_id
+ * User ID associated with the authorization code
+ * @param $redirect_uri
+ * An absolute URI to which the authorization server will redirect the
+ * user-agent to when the end-user authorization step is completed.
+ * @param $scope
+ * (optional) Scopes to be stored in space-separated string.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ * @ingroup oauth2_section_4
+ */
+ public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null)
+ {
+ $code = $this->generateAuthorizationCode();
+ $this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope);
+
+ return $code;
+ }
+
+ /**
+ * @return
+ * TRUE if the grant type requires a redirect_uri, FALSE if not
+ */
+ public function enforceRedirect()
+ {
+ return $this->config['enforce_redirect'];
+ }
+
+ /**
+ * Generates an unique auth code.
+ *
+ * Implementing classes may want to override this function to implement
+ * other auth code generation schemes.
+ *
+ * @return
+ * An unique auth code.
+ *
+ * @ingroup oauth2_section_4
+ */
+ protected function generateAuthorizationCode()
+ {
+ $tokenLen = 40;
+ if (function_exists('openssl_random_pseudo_bytes')) {
+ $randomData = openssl_random_pseudo_bytes(100);
+ } elseif (function_exists('mcrypt_create_iv')) {
+ $randomData = mcrypt_create_iv(100, MCRYPT_DEV_URANDOM);
+ } elseif (@file_exists('/dev/urandom')) { // Get 100 bytes of random data
+ $randomData = file_get_contents('/dev/urandom', false, null, 0, 100) . uniqid(mt_rand(), true);
+ } else {
+ $randomData = mt_rand() . mt_rand() . mt_rand() . mt_rand() . microtime(true) . uniqid(mt_rand(), true);
+ }
+
+ return substr(hash('sha512', $randomData), 0, $tokenLen);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCodeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
new file mode 100644
index 000000000..df777e221
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
@@ -0,0 +1,30 @@
+
+ */
+interface AuthorizationCodeInterface extends ResponseTypeInterface
+{
+ /**
+ * @return
+ * TRUE if the grant type requires a redirect_uri, FALSE if not
+ */
+ public function enforceRedirect();
+
+ /**
+ * Handle the creation of the authorization code.
+ *
+ * @param $client_id client identifier related to the authorization code
+ * @param $user_id user id associated with the authorization code
+ * @param $redirect_uri an absolute URI to which the authorization server will redirect the
+ * user-agent to when the end-user authorization step is completed.
+ * @param $scope OPTIONAL scopes to be stored in space-separated string.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ * @ingroup oauth2_section_4
+ */
+ public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/JwtAccessToken.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/JwtAccessToken.php
new file mode 100644
index 000000000..3942fe41e
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/JwtAccessToken.php
@@ -0,0 +1,124 @@
+
+ */
+class JwtAccessToken extends AccessToken
+{
+ protected $publicKeyStorage;
+ protected $encryptionUtil;
+
+ /**
+ * @param $config
+ * - store_encrypted_token_string (bool true)
+ * whether the entire encrypted string is stored,
+ * or just the token ID is stored
+ */
+ public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
+ {
+ $this->publicKeyStorage = $publicKeyStorage;
+ $config = array_merge(array(
+ 'store_encrypted_token_string' => true,
+ 'issuer' => ''
+ ), $config);
+ if (is_null($tokenStorage)) {
+ // a pass-thru, so we can call the parent constructor
+ $tokenStorage = new Memory();
+ }
+ if (is_null($encryptionUtil)) {
+ $encryptionUtil = new Jwt();
+ }
+ $this->encryptionUtil = $encryptionUtil;
+ parent::__construct($tokenStorage, $refreshStorage, $config);
+ }
+
+ /**
+ * Handle the creation of access token, also issue refresh token if supported / desirable.
+ *
+ * @param $client_id
+ * Client identifier related to the access token.
+ * @param $user_id
+ * User ID associated with the access token
+ * @param $scope
+ * (optional) Scopes to be stored in space-separated string.
+ * @param bool $includeRefreshToken
+ * If true, a new refresh_token will be added to the response
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-5
+ * @ingroup oauth2_section_5
+ */
+ public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true)
+ {
+ // token to encrypt
+ $expires = time() + $this->config['access_lifetime'];
+ $id = $this->generateAccessToken();
+ $jwtAccessToken = array(
+ 'id' => $id, // for BC (see #591)
+ 'jti' => $id,
+ 'iss' => $this->config['issuer'],
+ 'aud' => $client_id,
+ 'sub' => $user_id,
+ 'exp' => $expires,
+ 'iat' => time(),
+ 'token_type' => $this->config['token_type'],
+ 'scope' => $scope
+ );
+
+ /*
+ * Encode the token data into a single access_token string
+ */
+ $access_token = $this->encodeToken($jwtAccessToken, $client_id);
+
+ /*
+ * Save the token to a secondary storage. This is implemented on the
+ * OAuth2\Storage\JwtAccessToken side, and will not actually store anything,
+ * if no secondary storage has been supplied
+ */
+ $token_to_store = $this->config['store_encrypted_token_string'] ? $access_token : $jwtAccessToken['id'];
+ $this->tokenStorage->setAccessToken($token_to_store, $client_id, $user_id, $this->config['access_lifetime'] ? time() + $this->config['access_lifetime'] : null, $scope);
+
+ // token to return to the client
+ $token = array(
+ 'access_token' => $access_token,
+ 'expires_in' => $this->config['access_lifetime'],
+ 'token_type' => $this->config['token_type'],
+ 'scope' => $scope
+ );
+
+ /*
+ * Issue a refresh token also, if we support them
+ *
+ * Refresh Tokens are considered supported if an instance of OAuth2\Storage\RefreshTokenInterface
+ * is supplied in the constructor
+ */
+ if ($includeRefreshToken && $this->refreshStorage) {
+ $refresh_token = $this->generateRefreshToken();
+ $expires = 0;
+ if ($this->config['refresh_token_lifetime'] > 0) {
+ $expires = time() + $this->config['refresh_token_lifetime'];
+ }
+ $this->refreshStorage->setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope);
+ $token['refresh_token'] = $refresh_token;
+ }
+
+ return $token;
+ }
+
+ protected function encodeToken(array $token, $client_id = null)
+ {
+ $private_key = $this->publicKeyStorage->getPrivateKey($client_id);
+ $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
+
+ return $this->encryptionUtil->encode($token, $private_key, $algorithm);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/ResponseTypeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/ResponseTypeInterface.php
new file mode 100644
index 000000000..f8e26a5b0
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ResponseType/ResponseTypeInterface.php
@@ -0,0 +1,8 @@
+storage = $storage;
+ }
+
+ /**
+ * Check if everything in required scope is contained in available scope.
+ *
+ * @param $required_scope
+ * A space-separated string of scopes.
+ *
+ * @return
+ * TRUE if everything in required scope is contained in available scope,
+ * and FALSE if it isn't.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-7
+ *
+ * @ingroup oauth2_section_7
+ */
+ public function checkScope($required_scope, $available_scope)
+ {
+ $required_scope = explode(' ', trim($required_scope));
+ $available_scope = explode(' ', trim($available_scope));
+
+ return (count(array_diff($required_scope, $available_scope)) == 0);
+ }
+
+ /**
+ * Check if the provided scope exists in storage.
+ *
+ * @param $scope
+ * A space-separated string of scopes.
+ *
+ * @return
+ * TRUE if it exists, FALSE otherwise.
+ */
+ public function scopeExists($scope)
+ {
+ // Check reserved scopes first.
+ $scope = explode(' ', trim($scope));
+ $reservedScope = $this->getReservedScopes();
+ $nonReservedScopes = array_diff($scope, $reservedScope);
+ if (count($nonReservedScopes) == 0) {
+ return true;
+ } else {
+ // Check the storage for non-reserved scopes.
+ $nonReservedScopes = implode(' ', $nonReservedScopes);
+
+ return $this->storage->scopeExists($nonReservedScopes);
+ }
+ }
+
+ public function getScopeFromRequest(RequestInterface $request)
+ {
+ // "scope" is valid if passed in either POST or QUERY
+ return $request->request('scope', $request->query('scope'));
+ }
+
+ public function getDefaultScope($client_id = null)
+ {
+ return $this->storage->getDefaultScope($client_id);
+ }
+
+ /**
+ * Get reserved scopes needed by the server.
+ *
+ * In case OpenID Connect is used, these scopes must include:
+ * 'openid', offline_access'.
+ *
+ * @return
+ * An array of reserved scopes.
+ */
+ public function getReservedScopes()
+ {
+ return array('openid', 'offline_access');
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/ScopeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ScopeInterface.php
new file mode 100644
index 000000000..5b60f9aee
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/ScopeInterface.php
@@ -0,0 +1,40 @@
+ 'OAuth2\Storage\AccessTokenInterface',
+ 'authorization_code' => 'OAuth2\Storage\AuthorizationCodeInterface',
+ 'client_credentials' => 'OAuth2\Storage\ClientCredentialsInterface',
+ 'client' => 'OAuth2\Storage\ClientInterface',
+ 'refresh_token' => 'OAuth2\Storage\RefreshTokenInterface',
+ 'user_credentials' => 'OAuth2\Storage\UserCredentialsInterface',
+ 'user_claims' => 'OAuth2\OpenID\Storage\UserClaimsInterface',
+ 'public_key' => 'OAuth2\Storage\PublicKeyInterface',
+ 'jwt_bearer' => 'OAuth2\Storage\JWTBearerInterface',
+ 'scope' => 'OAuth2\Storage\ScopeInterface',
+ );
+
+ protected $responseTypeMap = array(
+ 'token' => 'OAuth2\ResponseType\AccessTokenInterface',
+ 'code' => 'OAuth2\ResponseType\AuthorizationCodeInterface',
+ 'id_token' => 'OAuth2\OpenID\ResponseType\IdTokenInterface',
+ 'id_token token' => 'OAuth2\OpenID\ResponseType\IdTokenTokenInterface',
+ 'code id_token' => 'OAuth2\OpenID\ResponseType\CodeIdTokenInterface',
+ );
+
+ /**
+ * @param mixed $storage (array or OAuth2\Storage) - single object or array of objects implementing the
+ * required storage types (ClientCredentialsInterface and AccessTokenInterface as a minimum)
+ * @param array $config specify a different token lifetime, token header name, etc
+ * @param array $grantTypes An array of OAuth2\GrantType\GrantTypeInterface to use for granting access tokens
+ * @param array $responseTypes Response types to use. array keys should be "code" and and "token" for
+ * Access Token and Authorization Code response types
+ * @param \OAuth2\TokenType\TokenTypeInterface $tokenType The token type object to use. Valid token types are "bearer" and "mac"
+ * @param \OAuth2\ScopeInterface $scopeUtil The scope utility class to use to validate scope
+ * @param \OAuth2\ClientAssertionType\ClientAssertionTypeInterface $clientAssertionType The method in which to verify the client identity. Default is HttpBasic
+ *
+ * @ingroup oauth2_section_7
+ */
+ public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), TokenTypeInterface $tokenType = null, ScopeInterface $scopeUtil = null, ClientAssertionTypeInterface $clientAssertionType = null)
+ {
+ $storage = is_array($storage) ? $storage : array($storage);
+ $this->storages = array();
+ foreach ($storage as $key => $service) {
+ $this->addStorage($service, $key);
+ }
+
+ // merge all config values. These get passed to our controller objects
+ $this->config = array_merge(array(
+ 'use_jwt_access_tokens' => false,
+ 'store_encrypted_token_string' => true,
+ 'use_openid_connect' => false,
+ 'id_lifetime' => 3600,
+ 'access_lifetime' => 3600,
+ 'www_realm' => 'Service',
+ 'token_param_name' => 'access_token',
+ 'token_bearer_header_name' => 'Bearer',
+ 'enforce_state' => true,
+ 'require_exact_redirect_uri' => true,
+ 'allow_implicit' => false,
+ 'allow_credentials_in_request_body' => true,
+ 'allow_public_clients' => true,
+ 'always_issue_new_refresh_token' => false,
+ 'unset_refresh_token_after_use' => true,
+ ), $config);
+
+ foreach ($grantTypes as $key => $grantType) {
+ $this->addGrantType($grantType, $key);
+ }
+
+ foreach ($responseTypes as $key => $responseType) {
+ $this->addResponseType($responseType, $key);
+ }
+
+ $this->tokenType = $tokenType;
+ $this->scopeUtil = $scopeUtil;
+ $this->clientAssertionType = $clientAssertionType;
+
+ if ($this->config['use_openid_connect']) {
+ $this->validateOpenIdConnect();
+ }
+ }
+
+ public function getAuthorizeController()
+ {
+ if (is_null($this->authorizeController)) {
+ $this->authorizeController = $this->createDefaultAuthorizeController();
+ }
+
+ return $this->authorizeController;
+ }
+
+ public function getTokenController()
+ {
+ if (is_null($this->tokenController)) {
+ $this->tokenController = $this->createDefaultTokenController();
+ }
+
+ return $this->tokenController;
+ }
+
+ public function getResourceController()
+ {
+ if (is_null($this->resourceController)) {
+ $this->resourceController = $this->createDefaultResourceController();
+ }
+
+ return $this->resourceController;
+ }
+
+ public function getUserInfoController()
+ {
+ if (is_null($this->userInfoController)) {
+ $this->userInfoController = $this->createDefaultUserInfoController();
+ }
+
+ return $this->userInfoController;
+ }
+
+ /**
+ * every getter deserves a setter
+ *
+ * @param AuthorizeControllerInterface $authorizeController
+ */
+ public function setAuthorizeController(AuthorizeControllerInterface $authorizeController)
+ {
+ $this->authorizeController = $authorizeController;
+ }
+
+ /**
+ * every getter deserves a setter
+ *
+ * @param TokenControllerInterface $tokenController
+ */
+ public function setTokenController(TokenControllerInterface $tokenController)
+ {
+ $this->tokenController = $tokenController;
+ }
+
+ /**
+ * every getter deserves a setter
+ *
+ * @param ResourceControllerInterface $resourceController
+ */
+ public function setResourceController(ResourceControllerInterface $resourceController)
+ {
+ $this->resourceController = $resourceController;
+ }
+
+ /**
+ * every getter deserves a setter
+ *
+ * @param UserInfoControllerInterface $userInfoController
+ */
+ public function setUserInfoController(UserInfoControllerInterface $userInfoController)
+ {
+ $this->userInfoController = $userInfoController;
+ }
+
+ /**
+ * Return claims about the authenticated end-user.
+ * This would be called from the "/UserInfo" endpoint as defined in the spec.
+ *
+ * @param $request - \OAuth2\RequestInterface
+ * Request object to grant access token
+ *
+ * @param $response - \OAuth2\ResponseInterface
+ * Response object containing error messages (failure) or user claims (success)
+ *
+ * @return ResponseInterface
+ *
+ * @throws \InvalidArgumentException
+ * @throws \LogicException
+ *
+ * @see http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
+ */
+ public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $this->getUserInfoController()->handleUserInfoRequest($request, $this->response);
+
+ return $this->response;
+ }
+
+ /**
+ * Grant or deny a requested access token.
+ * This would be called from the "/token" endpoint as defined in the spec.
+ * Obviously, you can call your endpoint whatever you want.
+ *
+ * @param $request - \OAuth2\RequestInterface
+ * Request object to grant access token
+ *
+ * @param $response - \OAuth2\ResponseInterface
+ * Response object containing error messages (failure) or access token (success)
+ *
+ * @return ResponseInterface
+ *
+ * @throws \InvalidArgumentException
+ * @throws \LogicException
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ * @see http://tools.ietf.org/html/rfc6749#section-10.6
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function handleTokenRequest(RequestInterface $request, ResponseInterface $response = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $this->getTokenController()->handleTokenRequest($request, $this->response);
+
+ return $this->response;
+ }
+
+ public function grantAccessToken(RequestInterface $request, ResponseInterface $response = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $value = $this->getTokenController()->grantAccessToken($request, $this->response);
+
+ return $value;
+ }
+
+ /**
+ * Handle a revoke token request
+ * This would be called from the "/revoke" endpoint as defined in the draft Token Revocation spec
+ *
+ * @see https://tools.ietf.org/html/rfc7009#section-2
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return Response|ResponseInterface
+ */
+ public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $this->getTokenController()->handleRevokeRequest($request, $this->response);
+
+ return $this->response;
+ }
+
+ /**
+ * Redirect the user appropriately after approval.
+ *
+ * After the user has approved or denied the resource request the
+ * authorization server should call this function to redirect the user
+ * appropriately.
+ *
+ * @param $request
+ * The request should have the follow parameters set in the querystring:
+ * - response_type: The requested response: an access token, an
+ * authorization code, or both.
+ * - client_id: The client identifier as described in Section 2.
+ * - redirect_uri: An absolute URI to which the authorization server
+ * will redirect the user-agent to when the end-user authorization
+ * step is completed.
+ * - scope: (optional) The scope of the resource request expressed as a
+ * list of space-delimited strings.
+ * - state: (optional) An opaque value used by the client to maintain
+ * state between the request and callback.
+ * @param ResponseInterface $response
+ * @param $is_authorized
+ * TRUE or FALSE depending on whether the user authorized the access.
+ * @param $user_id
+ * Identifier of user who authorized the client
+ *
+ * @return Response
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function handleAuthorizeRequest(RequestInterface $request, ResponseInterface $response, $is_authorized, $user_id = null)
+ {
+ $this->response = $response;
+ $this->getAuthorizeController()->handleAuthorizeRequest($request, $this->response, $is_authorized, $user_id);
+
+ return $this->response;
+ }
+
+ /**
+ * Pull the authorization request data out of the HTTP request.
+ * - The redirect_uri is OPTIONAL as per draft 20. But your implementation can enforce it
+ * by setting $config['enforce_redirect'] to true.
+ * - The state is OPTIONAL but recommended to enforce CSRF. Draft 21 states, however, that
+ * CSRF protection is MANDATORY. You can enforce this by setting the $config['enforce_state'] to true.
+ *
+ * The draft specifies that the parameters should be retrieved from GET, override the Response
+ * object to change this
+ *
+ * @return
+ * The authorization parameters so the authorization server can prompt
+ * the user for approval if valid.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1.1
+ * @see http://tools.ietf.org/html/rfc6749#section-10.12
+ *
+ * @ingroup oauth2_section_3
+ */
+ public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $value = $this->getAuthorizeController()->validateAuthorizeRequest($request, $this->response);
+
+ return $value;
+ }
+
+ public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response = null, $scope = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $value = $this->getResourceController()->verifyResourceRequest($request, $this->response, $scope);
+
+ return $value;
+ }
+
+ public function getAccessTokenData(RequestInterface $request, ResponseInterface $response = null)
+ {
+ $this->response = is_null($response) ? new Response() : $response;
+ $value = $this->getResourceController()->getAccessTokenData($request, $this->response);
+
+ return $value;
+ }
+
+ public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
+ {
+ if (!is_string($identifier)) {
+ $identifier = $grantType->getQuerystringIdentifier();
+ }
+
+ $this->grantTypes[$identifier] = $grantType;
+
+ // persist added grant type down to TokenController
+ if (!is_null($this->tokenController)) {
+ $this->getTokenController()->addGrantType($grantType, $identifier);
+ }
+ }
+
+ /**
+ * Set a storage object for the server
+ *
+ * @param $storage
+ * An object implementing one of the Storage interfaces
+ * @param $key
+ * If null, the storage is set to the key of each storage interface it implements
+ *
+ * @see storageMap
+ */
+ public function addStorage($storage, $key = null)
+ {
+ // if explicitly set to a valid key, do not "magically" set below
+ if (isset($this->storageMap[$key])) {
+ if (!is_null($storage) && !$storage instanceof $this->storageMap[$key]) {
+ throw new \InvalidArgumentException(sprintf('storage of type "%s" must implement interface "%s"', $key, $this->storageMap[$key]));
+ }
+ $this->storages[$key] = $storage;
+
+ // special logic to handle "client" and "client_credentials" strangeness
+ if ($key === 'client' && !isset($this->storages['client_credentials'])) {
+ if ($storage instanceof \OAuth2\Storage\ClientCredentialsInterface) {
+ $this->storages['client_credentials'] = $storage;
+ }
+ } elseif ($key === 'client_credentials' && !isset($this->storages['client'])) {
+ if ($storage instanceof \OAuth2\Storage\ClientInterface) {
+ $this->storages['client'] = $storage;
+ }
+ }
+ } elseif (!is_null($key) && !is_numeric($key)) {
+ throw new \InvalidArgumentException(sprintf('unknown storage key "%s", must be one of [%s]', $key, implode(', ', array_keys($this->storageMap))));
+ } else {
+ $set = false;
+ foreach ($this->storageMap as $type => $interface) {
+ if ($storage instanceof $interface) {
+ $this->storages[$type] = $storage;
+ $set = true;
+ }
+ }
+
+ if (!$set) {
+ throw new \InvalidArgumentException(sprintf('storage of class "%s" must implement one of [%s]', get_class($storage), implode(', ', $this->storageMap)));
+ }
+ }
+ }
+
+ public function addResponseType(ResponseTypeInterface $responseType, $key = null)
+ {
+ $key = $this->normalizeResponseType($key);
+
+ if (isset($this->responseTypeMap[$key])) {
+ if (!$responseType instanceof $this->responseTypeMap[$key]) {
+ throw new \InvalidArgumentException(sprintf('responseType of type "%s" must implement interface "%s"', $key, $this->responseTypeMap[$key]));
+ }
+ $this->responseTypes[$key] = $responseType;
+ } elseif (!is_null($key) && !is_numeric($key)) {
+ throw new \InvalidArgumentException(sprintf('unknown responseType key "%s", must be one of [%s]', $key, implode(', ', array_keys($this->responseTypeMap))));
+ } else {
+ $set = false;
+ foreach ($this->responseTypeMap as $type => $interface) {
+ if ($responseType instanceof $interface) {
+ $this->responseTypes[$type] = $responseType;
+ $set = true;
+ }
+ }
+
+ if (!$set) {
+ throw new \InvalidArgumentException(sprintf('Unknown response type %s. Please implement one of [%s]', get_class($responseType), implode(', ', $this->responseTypeMap)));
+ }
+ }
+ }
+
+ public function getScopeUtil()
+ {
+ if (!$this->scopeUtil) {
+ $storage = isset($this->storages['scope']) ? $this->storages['scope'] : null;
+ $this->scopeUtil = new Scope($storage);
+ }
+
+ return $this->scopeUtil;
+ }
+
+ /**
+ * every getter deserves a setter
+ *
+ * @param ScopeInterface $scopeUtil
+ */
+ public function setScopeUtil($scopeUtil)
+ {
+ $this->scopeUtil = $scopeUtil;
+ }
+
+ protected function createDefaultAuthorizeController()
+ {
+ if (!isset($this->storages['client'])) {
+ throw new \LogicException('You must supply a storage object implementing \OAuth2\Storage\ClientInterface to use the authorize server');
+ }
+ if (0 == count($this->responseTypes)) {
+ $this->responseTypes = $this->getDefaultResponseTypes();
+ }
+ if ($this->config['use_openid_connect'] && !isset($this->responseTypes['id_token'])) {
+ $this->responseTypes['id_token'] = $this->createDefaultIdTokenResponseType();
+ if ($this->config['allow_implicit']) {
+ $this->responseTypes['id_token token'] = $this->createDefaultIdTokenTokenResponseType();
+ }
+ }
+
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_implicit enforce_state require_exact_redirect_uri')));
+
+ if ($this->config['use_openid_connect']) {
+ return new OpenIDAuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
+ }
+
+ return new AuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
+ }
+
+ protected function createDefaultTokenController()
+ {
+ if (0 == count($this->grantTypes)) {
+ $this->grantTypes = $this->getDefaultGrantTypes();
+ }
+
+ if (is_null($this->clientAssertionType)) {
+ // see if HttpBasic assertion type is requred. If so, then create it from storage classes.
+ foreach ($this->grantTypes as $grantType) {
+ if (!$grantType instanceof ClientAssertionTypeInterface) {
+ if (!isset($this->storages['client_credentials'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\ClientCredentialsInterface to use the token server');
+ }
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_credentials_in_request_body allow_public_clients')));
+ $this->clientAssertionType = new HttpBasic($this->storages['client_credentials'], $config);
+ break;
+ }
+ }
+ }
+
+ if (!isset($this->storages['client'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\ClientInterface to use the token server');
+ }
+
+ $accessTokenResponseType = $this->getAccessTokenResponseType();
+
+ return new TokenController($accessTokenResponseType, $this->storages['client'], $this->grantTypes, $this->clientAssertionType, $this->getScopeUtil());
+ }
+
+ protected function createDefaultResourceController()
+ {
+ if ($this->config['use_jwt_access_tokens']) {
+ // overwrites access token storage with crypto token storage if "use_jwt_access_tokens" is set
+ if (!isset($this->storages['access_token']) || !$this->storages['access_token'] instanceof JwtAccessTokenInterface) {
+ $this->storages['access_token'] = $this->createDefaultJwtAccessTokenStorage();
+ }
+ } elseif (!isset($this->storages['access_token'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface or use JwtAccessTokens to use the resource server');
+ }
+
+ if (!$this->tokenType) {
+ $this->tokenType = $this->getDefaultTokenType();
+ }
+
+ $config = array_intersect_key($this->config, array('www_realm' => ''));
+
+ return new ResourceController($this->tokenType, $this->storages['access_token'], $config, $this->getScopeUtil());
+ }
+
+ protected function createDefaultUserInfoController()
+ {
+ if ($this->config['use_jwt_access_tokens']) {
+ // overwrites access token storage with crypto token storage if "use_jwt_access_tokens" is set
+ if (!isset($this->storages['access_token']) || !$this->storages['access_token'] instanceof JwtAccessTokenInterface) {
+ $this->storages['access_token'] = $this->createDefaultJwtAccessTokenStorage();
+ }
+ } elseif (!isset($this->storages['access_token'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\AccessTokenInterface or use JwtAccessTokens to use the UserInfo server');
+ }
+
+ if (!isset($this->storages['user_claims'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use the UserInfo server');
+ }
+
+ if (!$this->tokenType) {
+ $this->tokenType = $this->getDefaultTokenType();
+ }
+
+ $config = array_intersect_key($this->config, array('www_realm' => ''));
+
+ return new UserInfoController($this->tokenType, $this->storages['access_token'], $this->storages['user_claims'], $config, $this->getScopeUtil());
+ }
+
+ protected function getDefaultTokenType()
+ {
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'token_param_name token_bearer_header_name')));
+
+ return new Bearer($config);
+ }
+
+ protected function getDefaultResponseTypes()
+ {
+ $responseTypes = array();
+
+ if ($this->config['allow_implicit']) {
+ $responseTypes['token'] = $this->getAccessTokenResponseType();
+ }
+
+ if ($this->config['use_openid_connect']) {
+ $responseTypes['id_token'] = $this->getIdTokenResponseType();
+ if ($this->config['allow_implicit']) {
+ $responseTypes['id_token token'] = $this->getIdTokenTokenResponseType();
+ }
+ }
+
+ if (isset($this->storages['authorization_code'])) {
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'enforce_redirect auth_code_lifetime')));
+ if ($this->config['use_openid_connect']) {
+ if (!$this->storages['authorization_code'] instanceof OpenIDAuthorizationCodeInterface) {
+ throw new \LogicException('Your authorization_code storage must implement OAuth2\OpenID\Storage\AuthorizationCodeInterface to work when "use_openid_connect" is true');
+ }
+ $responseTypes['code'] = new OpenIDAuthorizationCodeResponseType($this->storages['authorization_code'], $config);
+ $responseTypes['code id_token'] = new CodeIdToken($responseTypes['code'], $responseTypes['id_token']);
+ } else {
+ $responseTypes['code'] = new AuthorizationCodeResponseType($this->storages['authorization_code'], $config);
+ }
+ }
+
+ if (count($responseTypes) == 0) {
+ throw new \LogicException('You must supply an array of response_types in the constructor or implement a OAuth2\Storage\AuthorizationCodeInterface storage object or set "allow_implicit" to true and implement a OAuth2\Storage\AccessTokenInterface storage object');
+ }
+
+ return $responseTypes;
+ }
+
+ protected function getDefaultGrantTypes()
+ {
+ $grantTypes = array();
+
+ if (isset($this->storages['user_credentials'])) {
+ $grantTypes['password'] = new UserCredentials($this->storages['user_credentials']);
+ }
+
+ if (isset($this->storages['client_credentials'])) {
+ $config = array_intersect_key($this->config, array('allow_credentials_in_request_body' => ''));
+ $grantTypes['client_credentials'] = new ClientCredentials($this->storages['client_credentials'], $config);
+ }
+
+ if (isset($this->storages['refresh_token'])) {
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'always_issue_new_refresh_token unset_refresh_token_after_use')));
+ $grantTypes['refresh_token'] = new RefreshToken($this->storages['refresh_token'], $config);
+ }
+
+ if (isset($this->storages['authorization_code'])) {
+ if ($this->config['use_openid_connect']) {
+ if (!$this->storages['authorization_code'] instanceof OpenIDAuthorizationCodeInterface) {
+ throw new \LogicException('Your authorization_code storage must implement OAuth2\OpenID\Storage\AuthorizationCodeInterface to work when "use_openid_connect" is true');
+ }
+ $grantTypes['authorization_code'] = new OpenIDAuthorizationCodeGrantType($this->storages['authorization_code']);
+ } else {
+ $grantTypes['authorization_code'] = new AuthorizationCode($this->storages['authorization_code']);
+ }
+ }
+
+ if (count($grantTypes) == 0) {
+ throw new \LogicException('Unable to build default grant types - You must supply an array of grant_types in the constructor');
+ }
+
+ return $grantTypes;
+ }
+
+ protected function getAccessTokenResponseType()
+ {
+ if (isset($this->responseTypes['token'])) {
+ return $this->responseTypes['token'];
+ }
+
+ if ($this->config['use_jwt_access_tokens']) {
+ return $this->createDefaultJwtAccessTokenResponseType();
+ }
+
+ return $this->createDefaultAccessTokenResponseType();
+ }
+
+ protected function getIdTokenResponseType()
+ {
+ if (isset($this->responseTypes['id_token'])) {
+ return $this->responseTypes['id_token'];
+ }
+
+ return $this->createDefaultIdTokenResponseType();
+ }
+
+ protected function getIdTokenTokenResponseType()
+ {
+ if (isset($this->responseTypes['id_token token'])) {
+ return $this->responseTypes['id_token token'];
+ }
+
+ return $this->createDefaultIdTokenTokenResponseType();
+ }
+
+ /**
+ * For Resource Controller
+ */
+ protected function createDefaultJwtAccessTokenStorage()
+ {
+ if (!isset($this->storages['public_key'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens');
+ }
+ $tokenStorage = null;
+ if (!empty($this->config['store_encrypted_token_string']) && isset($this->storages['access_token'])) {
+ $tokenStorage = $this->storages['access_token'];
+ }
+ // wrap the access token storage as required.
+ return new JwtAccessTokenStorage($this->storages['public_key'], $tokenStorage);
+ }
+
+ /**
+ * For Authorize and Token Controllers
+ */
+ protected function createDefaultJwtAccessTokenResponseType()
+ {
+ if (!isset($this->storages['public_key'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use crypto tokens');
+ }
+
+ $tokenStorage = null;
+ if (isset($this->storages['access_token'])) {
+ $tokenStorage = $this->storages['access_token'];
+ }
+
+ $refreshStorage = null;
+ if (isset($this->storages['refresh_token'])) {
+ $refreshStorage = $this->storages['refresh_token'];
+ }
+
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'store_encrypted_token_string issuer access_lifetime refresh_token_lifetime')));
+
+ return new JwtAccessToken($this->storages['public_key'], $tokenStorage, $refreshStorage, $config);
+ }
+
+ protected function createDefaultAccessTokenResponseType()
+ {
+ if (!isset($this->storages['access_token'])) {
+ throw new \LogicException('You must supply a response type implementing OAuth2\ResponseType\AccessTokenInterface, or a storage object implementing OAuth2\Storage\AccessTokenInterface to use the token server');
+ }
+
+ $refreshStorage = null;
+ if (isset($this->storages['refresh_token'])) {
+ $refreshStorage = $this->storages['refresh_token'];
+ }
+
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'access_lifetime refresh_token_lifetime')));
+ $config['token_type'] = $this->tokenType ? $this->tokenType->getTokenType() : $this->getDefaultTokenType()->getTokenType();
+
+ return new AccessToken($this->storages['access_token'], $refreshStorage, $config);
+ }
+
+ protected function createDefaultIdTokenResponseType()
+ {
+ if (!isset($this->storages['user_claims'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\OpenID\Storage\UserClaimsInterface to use openid connect');
+ }
+ if (!isset($this->storages['public_key'])) {
+ throw new \LogicException('You must supply a storage object implementing OAuth2\Storage\PublicKeyInterface to use openid connect');
+ }
+
+ $config = array_intersect_key($this->config, array_flip(explode(' ', 'issuer id_lifetime')));
+
+ return new IdToken($this->storages['user_claims'], $this->storages['public_key'], $config);
+ }
+
+ protected function createDefaultIdTokenTokenResponseType()
+ {
+ return new IdTokenToken($this->getAccessTokenResponseType(), $this->getIdTokenResponseType());
+ }
+
+ protected function validateOpenIdConnect()
+ {
+ $authCodeGrant = $this->getGrantType('authorization_code');
+ if (!empty($authCodeGrant) && !$authCodeGrant instanceof OpenIDAuthorizationCodeGrantType) {
+ throw new \InvalidArgumentException('You have enabled OpenID Connect, but supplied a grant type that does not support it.');
+ }
+ }
+
+ protected function normalizeResponseType($name)
+ {
+ // for multiple-valued response types - make them alphabetical
+ if (!empty($name) && false !== strpos($name, ' ')) {
+ $types = explode(' ', $name);
+ sort($types);
+ $name = implode(' ', $types);
+ }
+
+ return $name;
+ }
+
+ public function getResponse()
+ {
+ return $this->response;
+ }
+
+ public function getStorages()
+ {
+ return $this->storages;
+ }
+
+ public function getStorage($name)
+ {
+ return isset($this->storages[$name]) ? $this->storages[$name] : null;
+ }
+
+ public function getGrantTypes()
+ {
+ return $this->grantTypes;
+ }
+
+ public function getGrantType($name)
+ {
+ return isset($this->grantTypes[$name]) ? $this->grantTypes[$name] : null;
+ }
+
+ public function getResponseTypes()
+ {
+ return $this->responseTypes;
+ }
+
+ public function getResponseType($name)
+ {
+ // for multiple-valued response types - make them alphabetical
+ $name = $this->normalizeResponseType($name);
+
+ return isset($this->responseTypes[$name]) ? $this->responseTypes[$name] : null;
+ }
+
+ public function getTokenType()
+ {
+ return $this->tokenType;
+ }
+
+ public function getClientAssertionType()
+ {
+ return $this->clientAssertionType;
+ }
+
+ public function setConfig($name, $value)
+ {
+ $this->config[$name] = $value;
+ }
+
+ public function getConfig($name, $default = null)
+ {
+ return isset($this->config[$name]) ? $this->config[$name] : $default;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AccessTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AccessTokenInterface.php
new file mode 100644
index 000000000..1819158af
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AccessTokenInterface.php
@@ -0,0 +1,64 @@
+
+ */
+interface AccessTokenInterface
+{
+ /**
+ * Look up the supplied oauth_token from storage.
+ *
+ * We need to retrieve access token data as we create and verify tokens.
+ *
+ * @param $oauth_token
+ * oauth_token to be check with.
+ *
+ * @return
+ * An associative array as below, and return NULL if the supplied oauth_token
+ * is invalid:
+ * - expires: Stored expiration in unix timestamp.
+ * - client_id: (optional) Stored client identifier.
+ * - user_id: (optional) Stored user identifier.
+ * - scope: (optional) Stored scope values in space-separated string.
+ * - id_token: (optional) Stored id_token (if "use_openid_connect" is true).
+ *
+ * @ingroup oauth2_section_7
+ */
+ public function getAccessToken($oauth_token);
+
+ /**
+ * Store the supplied access token values to storage.
+ *
+ * We need to store access token data as we create and verify tokens.
+ *
+ * @param $oauth_token oauth_token to be stored.
+ * @param $client_id client identifier to be stored.
+ * @param $user_id user identifier to be stored.
+ * @param int $expires expiration to be stored as a Unix timestamp.
+ * @param string $scope OPTIONAL Scopes to be stored in space-separated string.
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null);
+
+ /**
+ * Expire an access token.
+ *
+ * This is not explicitly required in the spec, but if defined in a draft RFC for token
+ * revoking (RFC 7009) https://tools.ietf.org/html/rfc7009
+ *
+ * @param $access_token
+ * Access token to be expired.
+ *
+ * @return BOOL true if an access token was unset, false if not
+ * @ingroup oauth2_section_6
+ *
+ * @todo v2.0 include this method in interface. Omitted to maintain BC in v1.x
+ */
+ //public function unsetAccessToken($access_token);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AuthorizationCodeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AuthorizationCodeInterface.php
new file mode 100644
index 000000000..edc7c70e5
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/AuthorizationCodeInterface.php
@@ -0,0 +1,86 @@
+
+ */
+interface AuthorizationCodeInterface
+{
+ /**
+ * The Authorization Code grant type supports a response type of "code".
+ *
+ * @var string
+ * @see http://tools.ietf.org/html/rfc6749#section-1.4.1
+ * @see http://tools.ietf.org/html/rfc6749#section-4.2
+ */
+ const RESPONSE_TYPE_CODE = "code";
+
+ /**
+ * Fetch authorization code data (probably the most common grant type).
+ *
+ * Retrieve the stored data for the given authorization code.
+ *
+ * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
+ *
+ * @param $code
+ * Authorization code to be check with.
+ *
+ * @return
+ * An associative array as below, and NULL if the code is invalid
+ * @code
+ * return array(
+ * "client_id" => CLIENT_ID, // REQUIRED Stored client identifier
+ * "user_id" => USER_ID, // REQUIRED Stored user identifier
+ * "expires" => EXPIRES, // REQUIRED Stored expiration in unix timestamp
+ * "redirect_uri" => REDIRECT_URI, // REQUIRED Stored redirect URI
+ * "scope" => SCOPE, // OPTIONAL Stored scope values in space-separated string
+ * );
+ * @endcode
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function getAuthorizationCode($code);
+
+ /**
+ * Take the provided authorization code values and store them somewhere.
+ *
+ * This function should be the storage counterpart to getAuthCode().
+ *
+ * If storage fails for some reason, we're not currently checking for
+ * any sort of success/failure, so you should bail out of the script
+ * and provide a descriptive fail message.
+ *
+ * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
+ *
+ * @param string $code Authorization code to be stored.
+ * @param mixed $client_id Client identifier to be stored.
+ * @param mixed $user_id User identifier to be stored.
+ * @param string $redirect_uri Redirect URI(s) to be stored in a space-separated string.
+ * @param int $expires Expiration to be stored as a Unix timestamp.
+ * @param string $scope OPTIONAL Scopes to be stored in space-separated string.
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null);
+
+ /**
+ * once an Authorization Code is used, it must be expired
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1.2
+ *
+ * The client MUST NOT use the authorization code
+ * more than once. If an authorization code is used more than
+ * once, the authorization server MUST deny the request and SHOULD
+ * revoke (when possible) all tokens previously issued based on
+ * that authorization code
+ *
+ */
+ public function expireAuthorizationCode($code);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Cassandra.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Cassandra.php
new file mode 100644
index 000000000..c5048c08d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Cassandra.php
@@ -0,0 +1,480 @@
+
+ * composer require thobbs/phpcassa:dev-master
+ *
+ *
+ * Once this is done, instantiate the
+ *
+ * $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_server', array('127.0.0.1:9160'));
+ *
+ *
+ * Then, register the storage client:
+ *
+ * $storage = new OAuth2\Storage\Cassandra($cassandra);
+ * $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
+ *
+ *
+ * @see test/lib/OAuth2/Storage/Bootstrap::getCassandraStorage
+ */
+class Cassandra implements AuthorizationCodeInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ UserCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ ScopeInterface,
+ PublicKeyInterface,
+ UserClaimsInterface,
+ OpenIDAuthorizationCodeInterface
+{
+
+ private $cache;
+
+ /* The cassandra client */
+ protected $cassandra;
+
+ /* Configuration array */
+ protected $config;
+
+ /**
+ * Cassandra Storage! uses phpCassa
+ *
+ * @param \phpcassa\ConnectionPool $cassandra
+ * @param array $config
+ */
+ public function __construct($connection = array(), array $config = array())
+ {
+ if ($connection instanceof ConnectionPool) {
+ $this->cassandra = $connection;
+ } else {
+ if (!is_array($connection)) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\Cassandra must be an instance of phpcassa\Connection\ConnectionPool or a configuration array');
+ }
+ $connection = array_merge(array(
+ 'keyspace' => 'oauth2',
+ 'servers' => null,
+ ), $connection);
+
+ $this->cassandra = new ConnectionPool($connection['keyspace'], $connection['servers']);
+ }
+
+ $this->config = array_merge(array(
+ // cassandra config
+ 'column_family' => 'auth',
+
+ // key names
+ 'client_key' => 'oauth_clients:',
+ 'access_token_key' => 'oauth_access_tokens:',
+ 'refresh_token_key' => 'oauth_refresh_tokens:',
+ 'code_key' => 'oauth_authorization_codes:',
+ 'user_key' => 'oauth_users:',
+ 'jwt_key' => 'oauth_jwt:',
+ 'scope_key' => 'oauth_scopes:',
+ 'public_key_key' => 'oauth_public_keys:',
+ ), $config);
+ }
+
+ protected function getValue($key)
+ {
+ if (isset($this->cache[$key])) {
+ return $this->cache[$key];
+ }
+ $cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
+
+ try {
+ $value = $cf->get($key, new ColumnSlice("", ""));
+ $value = array_shift($value);
+ } catch (\cassandra\NotFoundException $e) {
+ return false;
+ }
+
+ return json_decode($value, true);
+ }
+
+ protected function setValue($key, $value, $expire = 0)
+ {
+ $this->cache[$key] = $value;
+
+ $cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
+
+ $str = json_encode($value);
+ if ($expire > 0) {
+ try {
+ $seconds = $expire - time();
+ // __data key set as C* requires a field, note: max TTL can only be 630720000 seconds
+ $cf->insert($key, array('__data' => $str), null, $seconds);
+ } catch (\Exception $e) {
+ return false;
+ }
+ } else {
+ try {
+ // __data key set as C* requires a field
+ $cf->insert($key, array('__data' => $str));
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected function expireValue($key)
+ {
+ unset($this->cache[$key]);
+
+ $cf = new ColumnFamily($this->cassandra, $this->config['column_family']);
+
+ if ($cf->get_count($key) > 0) {
+ try {
+ // __data key set as C* requires a field
+ $cf->remove($key, array('__data'));
+ } catch (\Exception $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /* AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ return $this->getValue($this->config['code_key'] . $code);
+ }
+
+ public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ return $this->setValue(
+ $this->config['code_key'] . $authorization_code,
+ compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
+ $expires
+ );
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ $key = $this->config['code_key'] . $code;
+ unset($this->cache[$key]);
+
+ return $this->expireValue($key);
+ }
+
+ /* UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ if ($user = $this->getUser($username)) {
+ return $this->checkPassword($user, $password);
+ }
+
+ return false;
+ }
+
+ // plaintext passwords are bad! Override this for your application
+ protected function checkPassword($user, $password)
+ {
+ return $user['password'] == $this->hashPassword($password);
+ }
+
+ // use a secure hashing algorithm when storing passwords. Override this for your application
+ protected function hashPassword($password)
+ {
+ return sha1($password);
+ }
+
+ public function getUserDetails($username)
+ {
+ return $this->getUser($username);
+ }
+
+ public function getUser($username)
+ {
+ if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
+ return false;
+ }
+
+ // the default behavior is to use "username" as the user_id
+ return array_merge(array(
+ 'user_id' => $username,
+ ), $userInfo);
+ }
+
+ public function setUser($username, $password, $first_name = null, $last_name = null)
+ {
+ $password = $this->hashPassword($password);
+
+ return $this->setValue(
+ $this->config['user_key'] . $username,
+ compact('username', 'password', 'first_name', 'last_name')
+ );
+ }
+
+ /* ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ if (!$client = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ return isset($client['client_secret'])
+ && $client['client_secret'] == $client_secret;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ if (!$client = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ return empty($client['client_secret']);
+ }
+
+ /* ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ return $this->getValue($this->config['client_key'] . $client_id);
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ return $this->setValue(
+ $this->config['client_key'] . $client_id,
+ compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
+ );
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+
+ return in_array($grant_type, (array) $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ return $this->setValue(
+ $this->config['refresh_token_key'] . $refresh_token,
+ compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'),
+ $expires
+ );
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ return $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
+ }
+
+ /* AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ return $this->getValue($this->config['access_token_key'].$access_token);
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ return $this->setValue(
+ $this->config['access_token_key'].$access_token,
+ compact('access_token', 'client_id', 'user_id', 'expires', 'scope'),
+ $expires
+ );
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ return $this->expireValue($this->config['access_token_key'] . $access_token);
+ }
+
+ /* ScopeInterface */
+ public function scopeExists($scope)
+ {
+ $scope = explode(' ', $scope);
+
+ $result = $this->getValue($this->config['scope_key'].'supported:global');
+
+ $supportedScope = explode(' ', (string) $result);
+
+ return (count(array_diff($scope, $supportedScope)) == 0);
+ }
+
+ public function getDefaultScope($client_id = null)
+ {
+ if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
+ $result = $this->getValue($this->config['scope_key'].'default:global');
+ }
+
+ return $result;
+ }
+
+ public function setScope($scope, $client_id = null, $type = 'supported')
+ {
+ if (!in_array($type, array('default', 'supported'))) {
+ throw new \InvalidArgumentException('"$type" must be one of "default", "supported"');
+ }
+
+ if (is_null($client_id)) {
+ $key = $this->config['scope_key'].$type.':global';
+ } else {
+ $key = $this->config['scope_key'].$type.':'.$client_id;
+ }
+
+ return $this->setValue($key, $scope);
+ }
+
+ /*JWTBearerInterface */
+ public function getClientKey($client_id, $subject)
+ {
+ if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
+ return false;
+ }
+
+ if (isset($jwt['subject']) && $jwt['subject'] == $subject ) {
+ return $jwt['key'];
+ }
+
+ return null;
+ }
+
+ public function setClientKey($client_id, $key, $subject = null)
+ {
+ return $this->setValue($this->config['jwt_key'] . $client_id, array(
+ 'key' => $key,
+ 'subject' => $subject
+ ));
+ }
+
+ /*ScopeInterface */
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs cassandra implementation.
+ throw new \Exception('getJti() for the Cassandra driver is currently unimplemented.');
+ }
+
+ public function setJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs cassandra implementation.
+ throw new \Exception('setJti() for the Cassandra driver is currently unimplemented.');
+ }
+
+ /* PublicKeyInterface */
+ public function getPublicKey($client_id = '')
+ {
+ $public_key = $this->getValue($this->config['public_key_key'] . $client_id);
+ if (is_array($public_key)) {
+ return $public_key['public_key'];
+ }
+ $public_key = $this->getValue($this->config['public_key_key']);
+ if (is_array($public_key)) {
+ return $public_key['public_key'];
+ }
+ }
+
+ public function getPrivateKey($client_id = '')
+ {
+ $public_key = $this->getValue($this->config['public_key_key'] . $client_id);
+ if (is_array($public_key)) {
+ return $public_key['private_key'];
+ }
+ $public_key = $this->getValue($this->config['public_key_key']);
+ if (is_array($public_key)) {
+ return $public_key['private_key'];
+ }
+ }
+
+ public function getEncryptionAlgorithm($client_id = null)
+ {
+ $public_key = $this->getValue($this->config['public_key_key'] . $client_id);
+ if (is_array($public_key)) {
+ return $public_key['encryption_algorithm'];
+ }
+ $public_key = $this->getValue($this->config['public_key_key']);
+ if (is_array($public_key)) {
+ return $public_key['encryption_algorithm'];
+ }
+
+ return 'RS256';
+ }
+
+ /* UserClaimsInterface */
+ public function getUserClaims($user_id, $claims)
+ {
+ $userDetails = $this->getUserDetails($user_id);
+ if (!is_array($userDetails)) {
+ return false;
+ }
+
+ $claims = explode(' ', trim($claims));
+ $userClaims = array();
+
+ // for each requested claim, if the user has the claim, set it in the response
+ $validClaims = explode(' ', self::VALID_CLAIMS);
+ foreach ($validClaims as $validClaim) {
+ if (in_array($validClaim, $claims)) {
+ if ($validClaim == 'address') {
+ // address is an object with subfields
+ $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
+ } else {
+ $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
+ }
+ }
+ }
+
+ return $userClaims;
+ }
+
+ protected function getUserClaim($claim, $userDetails)
+ {
+ $userClaims = array();
+ $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
+ $claimValues = explode(' ', $claimValuesString);
+
+ foreach ($claimValues as $value) {
+ if ($value == 'email_verified') {
+ $userClaims[$value] = $userDetails[$value]=='true' ? true : false;
+ } else {
+ $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
+ }
+ }
+
+ return $userClaims;
+ }
+
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientCredentialsInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientCredentialsInterface.php
new file mode 100644
index 000000000..3318c6966
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientCredentialsInterface.php
@@ -0,0 +1,49 @@
+
+ */
+interface ClientCredentialsInterface extends ClientInterface
+{
+
+ /**
+ * Make sure that the client credentials is valid.
+ *
+ * @param $client_id
+ * Client identifier to be check with.
+ * @param $client_secret
+ * (optional) If a secret is required, check that they've given the right one.
+ *
+ * @return
+ * TRUE if the client credentials are valid, and MUST return FALSE if it isn't.
+ * @endcode
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-3.1
+ *
+ * @ingroup oauth2_section_3
+ */
+ public function checkClientCredentials($client_id, $client_secret = null);
+
+ /**
+ * Determine if the client is a "public" client, and therefore
+ * does not require passing credentials for certain grant types
+ *
+ * @param $client_id
+ * Client identifier to be check with.
+ *
+ * @return
+ * TRUE if the client is public, and FALSE if it isn't.
+ * @endcode
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-2.3
+ * @see https://github.com/bshaffer/oauth2-server-php/issues/257
+ *
+ * @ingroup oauth2_section_2
+ */
+ public function isPublicClient($client_id);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientInterface.php
new file mode 100644
index 000000000..09a5bffc1
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ClientInterface.php
@@ -0,0 +1,66 @@
+
+ */
+interface ClientInterface
+{
+ /**
+ * Get client details corresponding client_id.
+ *
+ * OAuth says we should store request URIs for each registered client.
+ * Implement this function to grab the stored URI for a given client id.
+ *
+ * @param $client_id
+ * Client identifier to be check with.
+ *
+ * @return array
+ * Client details. The only mandatory key in the array is "redirect_uri".
+ * This function MUST return FALSE if the given client does not exist or is
+ * invalid. "redirect_uri" can be space-delimited to allow for multiple valid uris.
+ *
+ * return array(
+ * "redirect_uri" => REDIRECT_URI, // REQUIRED redirect_uri registered for the client
+ * "client_id" => CLIENT_ID, // OPTIONAL the client id
+ * "grant_types" => GRANT_TYPES, // OPTIONAL an array of restricted grant types
+ * "user_id" => USER_ID, // OPTIONAL the user identifier associated with this client
+ * "scope" => SCOPE, // OPTIONAL the scopes allowed for this client
+ * );
+ *
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function getClientDetails($client_id);
+
+ /**
+ * Get the scope associated with this client
+ *
+ * @return
+ * STRING the space-delineated scope list for the specified client_id
+ */
+ public function getClientScope($client_id);
+
+ /**
+ * Check restricted grant types of corresponding client identifier.
+ *
+ * If you want to restrict clients to certain grant types, override this
+ * function.
+ *
+ * @param $client_id
+ * Client identifier to be check with.
+ * @param $grant_type
+ * Grant type to be check with
+ *
+ * @return
+ * TRUE if the grant type is supported by this client identifier, and
+ * FALSE if it isn't.
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function checkRestrictedGrantType($client_id, $grant_type);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
new file mode 100755
index 000000000..1eb55f027
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/CouchbaseDB.php
@@ -0,0 +1,331 @@
+
+ */
+class CouchbaseDB implements AuthorizationCodeInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ UserCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ OpenIDAuthorizationCodeInterface
+{
+ protected $db;
+ protected $config;
+
+ public function __construct($connection, $config = array())
+ {
+ if ($connection instanceof \Couchbase) {
+ $this->db = $connection;
+ } else {
+ if (!is_array($connection) || !is_array($connection['servers'])) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\CouchbaseDB must be an instance of Couchbase or a configuration array containing a server array');
+ }
+
+ $this->db = new \Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
+ }
+
+ $this->config = array_merge(array(
+ 'client_table' => 'oauth_clients',
+ 'access_token_table' => 'oauth_access_tokens',
+ 'refresh_token_table' => 'oauth_refresh_tokens',
+ 'code_table' => 'oauth_authorization_codes',
+ 'user_table' => 'oauth_users',
+ 'jwt_table' => 'oauth_jwt',
+ ), $config);
+ }
+
+ // Helper function to access couchbase item by type:
+ protected function getObjectByType($name,$id)
+ {
+ return json_decode($this->db->get($this->config[$name].'-'.$id),true);
+ }
+
+ // Helper function to set couchbase item by type:
+ protected function setObjectByType($name,$id,$array)
+ {
+ $array['type'] = $name;
+
+ return $this->db->set($this->config[$name].'-'.$id,json_encode($array));
+ }
+
+ // Helper function to delete couchbase item by type, wait for persist to at least 1 node
+ protected function deleteObjectByType($name,$id)
+ {
+ $this->db->delete($this->config[$name].'-'.$id,"",1);
+ }
+
+ /* ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ if ($result = $this->getObjectByType('client_table',$client_id)) {
+ return $result['client_secret'] == $client_secret;
+ }
+
+ return false;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ if (!$result = $this->getObjectByType('client_table',$client_id)) {
+ return false;
+ }
+
+ return empty($result['client_secret']);
+ }
+
+ /* ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ $result = $this->getObjectByType('client_table',$client_id);
+
+ return is_null($result) ? false : $result;
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ if ($this->getClientDetails($client_id)) {
+
+ $this->setObjectByType('client_table',$client_id, array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ ));
+ } else {
+ $this->setObjectByType('client_table',$client_id, array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ ));
+ }
+
+ return true;
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+
+ return in_array($grant_type, $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ $token = $this->getObjectByType('access_token_table',$access_token);
+
+ return is_null($token) ? false : $token;
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // if it exists, update it.
+ if ($this->getAccessToken($access_token)) {
+ $this->setObjectByType('access_token_table',$access_token, array(
+ 'access_token' => $access_token,
+ 'client_id' => $client_id,
+ 'expires' => $expires,
+ 'user_id' => $user_id,
+ 'scope' => $scope
+ ));
+ } else {
+ $this->setObjectByType('access_token_table',$access_token, array(
+ 'access_token' => $access_token,
+ 'client_id' => $client_id,
+ 'expires' => $expires,
+ 'user_id' => $user_id,
+ 'scope' => $scope
+ ));
+ }
+
+ return true;
+ }
+
+ /* AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ $code = $this->getObjectByType('code_table',$code);
+
+ return is_null($code) ? false : $code;
+ }
+
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ // if it exists, update it.
+ if ($this->getAuthorizationCode($code)) {
+ $this->setObjectByType('code_table',$code, array(
+ 'authorization_code' => $code,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'redirect_uri' => $redirect_uri,
+ 'expires' => $expires,
+ 'scope' => $scope,
+ 'id_token' => $id_token,
+ ));
+ } else {
+ $this->setObjectByType('code_table',$code,array(
+ 'authorization_code' => $code,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'redirect_uri' => $redirect_uri,
+ 'expires' => $expires,
+ 'scope' => $scope,
+ 'id_token' => $id_token,
+ ));
+ }
+
+ return true;
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ $this->deleteObjectByType('code_table',$code);
+
+ return true;
+ }
+
+ /* UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ if ($user = $this->getUser($username)) {
+ return $this->checkPassword($user, $password);
+ }
+
+ return false;
+ }
+
+ public function getUserDetails($username)
+ {
+ if ($user = $this->getUser($username)) {
+ $user['user_id'] = $user['username'];
+ }
+
+ return $user;
+ }
+
+ /* RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ $token = $this->getObjectByType('refresh_token_table',$refresh_token);
+
+ return is_null($token) ? false : $token;
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ $this->setObjectByType('refresh_token_table',$refresh_token, array(
+ 'refresh_token' => $refresh_token,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'expires' => $expires,
+ 'scope' => $scope
+ ));
+
+ return true;
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ $this->deleteObjectByType('refresh_token_table',$refresh_token);
+
+ return true;
+ }
+
+ // plaintext passwords are bad! Override this for your application
+ protected function checkPassword($user, $password)
+ {
+ return $user['password'] == $password;
+ }
+
+ public function getUser($username)
+ {
+ $result = $this->getObjectByType('user_table',$username);
+
+ return is_null($result) ? false : $result;
+ }
+
+ public function setUser($username, $password, $firstName = null, $lastName = null)
+ {
+ if ($this->getUser($username)) {
+ $this->setObjectByType('user_table',$username, array(
+ 'username' => $username,
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName
+ ));
+
+ } else {
+ $this->setObjectByType('user_table',$username, array(
+ 'username' => $username,
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName
+ ));
+
+ }
+
+ return true;
+ }
+
+ public function getClientKey($client_id, $subject)
+ {
+ if (!$jwt = $this->getObjectByType('jwt_table',$client_id)) {
+ return false;
+ }
+
+ if (isset($jwt['subject']) && $jwt['subject'] == $subject) {
+ return $jwt['key'];
+ }
+
+ return false;
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs couchbase implementation.
+ throw new \Exception('getJti() for the Couchbase driver is currently unimplemented.');
+ }
+
+ public function setJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs couchbase implementation.
+ throw new \Exception('setJti() for the Couchbase driver is currently unimplemented.');
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/DynamoDB.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/DynamoDB.php
new file mode 100644
index 000000000..8347ab258
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/DynamoDB.php
@@ -0,0 +1,540 @@
+
+ * composer require aws/aws-sdk-php:dev-master
+ *
+ *
+ * Once this is done, instantiate the DynamoDB client
+ *
+ * $storage = new OAuth2\Storage\Dynamodb(array("key" => "YOURKEY", "secret" => "YOURSECRET", "region" => "YOURREGION"));
+ *
+ *
+ * Table :
+ * - oauth_access_tokens (primary hash key : access_token)
+ * - oauth_authorization_codes (primary hash key : authorization_code)
+ * - oauth_clients (primary hash key : client_id)
+ * - oauth_jwt (primary hash key : client_id, primary range key : subject)
+ * - oauth_public_keys (primary hash key : client_id)
+ * - oauth_refresh_tokens (primary hash key : refresh_token)
+ * - oauth_scopes (primary hash key : scope, secondary index : is_default-index hash key is_default)
+ * - oauth_users (primary hash key : username)
+ *
+ * @author Frederic AUGUSTE
+ */
+class DynamoDB implements
+ AuthorizationCodeInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ UserCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ ScopeInterface,
+ PublicKeyInterface,
+ UserClaimsInterface,
+ OpenIDAuthorizationCodeInterface
+{
+ protected $client;
+ protected $config;
+
+ public function __construct($connection, $config = array())
+ {
+ if (!($connection instanceof DynamoDbClient)) {
+ if (!is_array($connection)) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\Dynamodb must be an instance a configuration array containt key, secret, region');
+ }
+ if (!array_key_exists("key",$connection) || !array_key_exists("secret",$connection) || !array_key_exists("region",$connection) ) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\Dynamodb must be an instance a configuration array containt key, secret, region');
+ }
+ $this->client = DynamoDbClient::factory(array(
+ 'key' => $connection["key"],
+ 'secret' => $connection["secret"],
+ 'region' =>$connection["region"]
+ ));
+ } else {
+ $this->client = $connection;
+ }
+
+ $this->config = array_merge(array(
+ 'client_table' => 'oauth_clients',
+ 'access_token_table' => 'oauth_access_tokens',
+ 'refresh_token_table' => 'oauth_refresh_tokens',
+ 'code_table' => 'oauth_authorization_codes',
+ 'user_table' => 'oauth_users',
+ 'jwt_table' => 'oauth_jwt',
+ 'scope_table' => 'oauth_scopes',
+ 'public_key_table' => 'oauth_public_keys',
+ ), $config);
+ }
+
+ /* OAuth2\Storage\ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['client_table'],
+ "Key" => array('client_id' => array('S' => $client_id))
+ ));
+
+ return $result->count()==1 && $result["Item"]["client_secret"]["S"] == $client_secret;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['client_table'],
+ "Key" => array('client_id' => array('S' => $client_id))
+ ));
+
+ if ($result->count()==0) {
+ return false ;
+ }
+
+ return empty($result["Item"]["client_secret"]);
+ }
+
+ /* OAuth2\Storage\ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['client_table'],
+ "Key" => array('client_id' => array('S' => $client_id))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $result = $this->dynamo2array($result);
+ foreach (array('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id') as $key => $val) {
+ if (!array_key_exists ($val, $result)) {
+ $result[$val] = null;
+ }
+ }
+
+ return $result;
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ $clientData = compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id');
+ $clientData = array_filter($clientData, 'self::isNotEmpty');
+
+ $result = $this->client->putItem(array(
+ 'TableName' => $this->config['client_table'],
+ 'Item' => $this->client->formatAttributes($clientData)
+ ));
+
+ return true;
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+
+ return in_array($grant_type, (array) $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* OAuth2\Storage\AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['access_token_table'],
+ "Key" => array('access_token' => array('S' => $access_token))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+ if (array_key_exists ('expires', $token)) {
+ $token['expires'] = strtotime($token['expires']);
+ }
+
+ return $token;
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ $clientData = compact('access_token', 'client_id', 'user_id', 'expires', 'scope');
+ $clientData = array_filter($clientData, 'self::isNotEmpty');
+
+ $result = $this->client->putItem(array(
+ 'TableName' => $this->config['access_token_table'],
+ 'Item' => $this->client->formatAttributes($clientData)
+ ));
+
+ return true;
+
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ $result = $this->client->deleteItem(array(
+ 'TableName' => $this->config['access_token_table'],
+ 'Key' => $this->client->formatAttributes(array("access_token" => $access_token)),
+ 'ReturnValues' => 'ALL_OLD',
+ ));
+
+ return null !== $result->get('Attributes');
+ }
+
+ /* OAuth2\Storage\AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['code_table'],
+ "Key" => array('authorization_code' => array('S' => $code))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+ if (!array_key_exists("id_token", $token )) {
+ $token['id_token'] = null;
+ }
+ $token['expires'] = strtotime($token['expires']);
+
+ return $token;
+
+ }
+
+ public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ $clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'id_token', 'scope');
+ $clientData = array_filter($clientData, 'self::isNotEmpty');
+
+ $result = $this->client->putItem(array(
+ 'TableName' => $this->config['code_table'],
+ 'Item' => $this->client->formatAttributes($clientData)
+ ));
+
+ return true;
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+
+ $result = $this->client->deleteItem(array(
+ 'TableName' => $this->config['code_table'],
+ 'Key' => $this->client->formatAttributes(array("authorization_code" => $code))
+ ));
+
+ return true;
+ }
+
+ /* OAuth2\Storage\UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ if ($user = $this->getUser($username)) {
+ return $this->checkPassword($user, $password);
+ }
+
+ return false;
+ }
+
+ public function getUserDetails($username)
+ {
+ return $this->getUser($username);
+ }
+
+ /* UserClaimsInterface */
+ public function getUserClaims($user_id, $claims)
+ {
+ if (!$userDetails = $this->getUserDetails($user_id)) {
+ return false;
+ }
+
+ $claims = explode(' ', trim($claims));
+ $userClaims = array();
+
+ // for each requested claim, if the user has the claim, set it in the response
+ $validClaims = explode(' ', self::VALID_CLAIMS);
+ foreach ($validClaims as $validClaim) {
+ if (in_array($validClaim, $claims)) {
+ if ($validClaim == 'address') {
+ // address is an object with subfields
+ $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
+ } else {
+ $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
+ }
+ }
+ }
+
+ return $userClaims;
+ }
+
+ protected function getUserClaim($claim, $userDetails)
+ {
+ $userClaims = array();
+ $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
+ $claimValues = explode(' ', $claimValuesString);
+
+ foreach ($claimValues as $value) {
+ if ($value == 'email_verified') {
+ $userClaims[$value] = $userDetails[$value]=='true' ? true : false;
+ } else {
+ $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
+ }
+ }
+
+ return $userClaims;
+ }
+
+ /* OAuth2\Storage\RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['refresh_token_table'],
+ "Key" => array('refresh_token' => array('S' => $refresh_token))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+ $token['expires'] = strtotime($token['expires']);
+
+ return $token;
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ $clientData = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
+ $clientData = array_filter($clientData, 'self::isNotEmpty');
+
+ $result = $this->client->putItem(array(
+ 'TableName' => $this->config['refresh_token_table'],
+ 'Item' => $this->client->formatAttributes($clientData)
+ ));
+
+ return true;
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ $result = $this->client->deleteItem(array(
+ 'TableName' => $this->config['refresh_token_table'],
+ 'Key' => $this->client->formatAttributes(array("refresh_token" => $refresh_token))
+ ));
+
+ return true;
+ }
+
+ // plaintext passwords are bad! Override this for your application
+ protected function checkPassword($user, $password)
+ {
+ return $user['password'] == $this->hashPassword($password);
+ }
+
+ // use a secure hashing algorithm when storing passwords. Override this for your application
+ protected function hashPassword($password)
+ {
+ return sha1($password);
+ }
+
+ public function getUser($username)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['user_table'],
+ "Key" => array('username' => array('S' => $username))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+ $token['user_id'] = $username;
+
+ return $token;
+ }
+
+ public function setUser($username, $password, $first_name = null, $last_name = null)
+ {
+ // do not store in plaintext
+ $password = $this->hashPassword($password);
+
+ $clientData = compact('username', 'password', 'first_name', 'last_name');
+ $clientData = array_filter($clientData, 'self::isNotEmpty');
+
+ $result = $this->client->putItem(array(
+ 'TableName' => $this->config['user_table'],
+ 'Item' => $this->client->formatAttributes($clientData)
+ ));
+
+ return true;
+
+ }
+
+ /* ScopeInterface */
+ public function scopeExists($scope)
+ {
+ $scope = explode(' ', $scope);
+ $scope_query = array();
+ $count = 0;
+ foreach ($scope as $key => $val) {
+ $result = $this->client->query(array(
+ 'TableName' => $this->config['scope_table'],
+ 'Select' => 'COUNT',
+ 'KeyConditions' => array(
+ 'scope' => array(
+ 'AttributeValueList' => array(array('S' => $val)),
+ 'ComparisonOperator' => 'EQ'
+ )
+ )
+ ));
+ $count += $result['Count'];
+ }
+
+ return $count == count($scope);
+ }
+
+ public function getDefaultScope($client_id = null)
+ {
+
+ $result = $this->client->query(array(
+ 'TableName' => $this->config['scope_table'],
+ 'IndexName' => 'is_default-index',
+ 'Select' => 'ALL_ATTRIBUTES',
+ 'KeyConditions' => array(
+ 'is_default' => array(
+ 'AttributeValueList' => array(array('S' => 'true')),
+ 'ComparisonOperator' => 'EQ',
+ ),
+ )
+ ));
+ $defaultScope = array();
+ if ($result->count() > 0) {
+ $array = $result->toArray();
+ foreach ($array["Items"] as $item) {
+ $defaultScope[] = $item['scope']['S'];
+ }
+
+ return empty($defaultScope) ? null : implode(' ', $defaultScope);
+ }
+
+ return null;
+ }
+
+ /* JWTBearerInterface */
+ public function getClientKey($client_id, $subject)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['jwt_table'],
+ "Key" => array('client_id' => array('S' => $client_id), 'subject' => array('S' => $subject))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+
+ return $token['public_key'];
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ //TODO not use.
+ }
+
+ public function setJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ //TODO not use.
+ }
+
+ /* PublicKeyInterface */
+ public function getPublicKey($client_id = '0')
+ {
+
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['public_key_table'],
+ "Key" => array('client_id' => array('S' => $client_id))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+
+ return $token['public_key'];
+
+ }
+
+ public function getPrivateKey($client_id = '0')
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['public_key_table'],
+ "Key" => array('client_id' => array('S' => $client_id))
+ ));
+ if ($result->count()==0) {
+ return false ;
+ }
+ $token = $this->dynamo2array($result);
+
+ return $token['private_key'];
+ }
+
+ public function getEncryptionAlgorithm($client_id = null)
+ {
+ $result = $this->client->getItem(array(
+ "TableName"=> $this->config['public_key_table'],
+ "Key" => array('client_id' => array('S' => $client_id))
+ ));
+ if ($result->count()==0) {
+ return 'RS256' ;
+ }
+ $token = $this->dynamo2array($result);
+
+ return $token['encryption_algorithm'];
+ }
+
+ /**
+ * Transform dynamodb resultset to an array.
+ * @param $dynamodbResult
+ * @return $array
+ */
+ private function dynamo2array($dynamodbResult)
+ {
+ $result = array();
+ foreach ($dynamodbResult["Item"] as $key => $val) {
+ $result[$key] = $val["S"];
+ $result[] = $val["S"];
+ }
+
+ return $result;
+ }
+
+ private static function isNotEmpty($value)
+ {
+ return null !== $value && '' !== $value;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessToken.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessToken.php
new file mode 100644
index 000000000..75b49d301
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessToken.php
@@ -0,0 +1,88 @@
+
+ */
+class JwtAccessToken implements JwtAccessTokenInterface
+{
+ protected $publicKeyStorage;
+ protected $tokenStorage;
+ protected $encryptionUtil;
+
+ /**
+ * @param OAuth2\Encryption\PublicKeyInterface $publicKeyStorage the public key encryption to use
+ * @param OAuth2\Storage\AccessTokenInterface $tokenStorage OPTIONAL persist the access token to another storage. This is useful if
+ * you want to retain access token grant information somewhere, but
+ * is not necessary when using this grant type.
+ * @param OAuth2\Encryption\EncryptionInterface $encryptionUtil OPTIONAL class to use for "encode" and "decode" functions.
+ */
+ public function __construct(PublicKeyInterface $publicKeyStorage, AccessTokenInterface $tokenStorage = null, EncryptionInterface $encryptionUtil = null)
+ {
+ $this->publicKeyStorage = $publicKeyStorage;
+ $this->tokenStorage = $tokenStorage;
+ if (is_null($encryptionUtil)) {
+ $encryptionUtil = new Jwt;
+ }
+ $this->encryptionUtil = $encryptionUtil;
+ }
+
+ public function getAccessToken($oauth_token)
+ {
+ // just decode the token, don't verify
+ if (!$tokenData = $this->encryptionUtil->decode($oauth_token, null, false)) {
+ return false;
+ }
+
+ $client_id = isset($tokenData['aud']) ? $tokenData['aud'] : null;
+ $public_key = $this->publicKeyStorage->getPublicKey($client_id);
+ $algorithm = $this->publicKeyStorage->getEncryptionAlgorithm($client_id);
+
+ // now that we have the client_id, verify the token
+ if (false === $this->encryptionUtil->decode($oauth_token, $public_key, array($algorithm))) {
+ return false;
+ }
+
+ // normalize the JWT claims to the format expected by other components in this library
+ return $this->convertJwtToOAuth2($tokenData);
+ }
+
+ public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ if ($this->tokenStorage) {
+ return $this->tokenStorage->setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope);
+ }
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ if ($this->tokenStorage) {
+ return $this->tokenStorage->unsetAccessToken($access_token);
+ }
+ }
+
+
+ // converts a JWT access token into an OAuth2-friendly format
+ protected function convertJwtToOAuth2($tokenData)
+ {
+ $keyMapping = array(
+ 'aud' => 'client_id',
+ 'exp' => 'expires',
+ 'sub' => 'user_id'
+ );
+
+ foreach ($keyMapping as $jwtKey => $oauth2Key) {
+ if (isset($tokenData[$jwtKey])) {
+ $tokenData[$oauth2Key] = $tokenData[$jwtKey];
+ unset($tokenData[$jwtKey]);
+ }
+ }
+
+ return $tokenData;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessTokenInterface.php
new file mode 100644
index 000000000..3abb2aa2d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtAccessTokenInterface.php
@@ -0,0 +1,14 @@
+
+ */
+interface JwtAccessTokenInterface extends AccessTokenInterface
+{
+
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtBearerInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtBearerInterface.php
new file mode 100644
index 000000000..c83aa72ea
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/JwtBearerInterface.php
@@ -0,0 +1,74 @@
+
+ */
+interface JwtBearerInterface
+{
+ /**
+ * Get the public key associated with a client_id
+ *
+ * @param $client_id
+ * Client identifier to be checked with.
+ *
+ * @return
+ * STRING Return the public key for the client_id if it exists, and MUST return FALSE if it doesn't.
+ */
+ public function getClientKey($client_id, $subject);
+
+ /**
+ * Get a jti (JSON token identifier) by matching against the client_id, subject, audience and expiration.
+ *
+ * @param $client_id
+ * Client identifier to match.
+ *
+ * @param $subject
+ * The subject to match.
+ *
+ * @param $audience
+ * The audience to match.
+ *
+ * @param $expiration
+ * The expiration of the jti.
+ *
+ * @param $jti
+ * The jti to match.
+ *
+ * @return
+ * An associative array as below, and return NULL if the jti does not exist.
+ * - issuer: Stored client identifier.
+ * - subject: Stored subject.
+ * - audience: Stored audience.
+ * - expires: Stored expiration in unix timestamp.
+ * - jti: The stored jti.
+ */
+ public function getJti($client_id, $subject, $audience, $expiration, $jti);
+
+ /**
+ * Store a used jti so that we can check against it to prevent replay attacks.
+ * @param $client_id
+ * Client identifier to insert.
+ *
+ * @param $subject
+ * The subject to insert.
+ *
+ * @param $audience
+ * The audience to insert.
+ *
+ * @param $expiration
+ * The expiration of the jti.
+ *
+ * @param $jti
+ * The jti to insert.
+ */
+ public function setJti($client_id, $subject, $audience, $expiration, $jti);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Memory.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Memory.php
new file mode 100644
index 000000000..42d833ccb
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Memory.php
@@ -0,0 +1,381 @@
+
+ */
+class Memory implements AuthorizationCodeInterface,
+ UserCredentialsInterface,
+ UserClaimsInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ ScopeInterface,
+ PublicKeyInterface,
+ OpenIDAuthorizationCodeInterface
+{
+ public $authorizationCodes;
+ public $userCredentials;
+ public $clientCredentials;
+ public $refreshTokens;
+ public $accessTokens;
+ public $jwt;
+ public $jti;
+ public $supportedScopes;
+ public $defaultScope;
+ public $keys;
+
+ public function __construct($params = array())
+ {
+ $params = array_merge(array(
+ 'authorization_codes' => array(),
+ 'user_credentials' => array(),
+ 'client_credentials' => array(),
+ 'refresh_tokens' => array(),
+ 'access_tokens' => array(),
+ 'jwt' => array(),
+ 'jti' => array(),
+ 'default_scope' => null,
+ 'supported_scopes' => array(),
+ 'keys' => array(),
+ ), $params);
+
+ $this->authorizationCodes = $params['authorization_codes'];
+ $this->userCredentials = $params['user_credentials'];
+ $this->clientCredentials = $params['client_credentials'];
+ $this->refreshTokens = $params['refresh_tokens'];
+ $this->accessTokens = $params['access_tokens'];
+ $this->jwt = $params['jwt'];
+ $this->jti = $params['jti'];
+ $this->supportedScopes = $params['supported_scopes'];
+ $this->defaultScope = $params['default_scope'];
+ $this->keys = $params['keys'];
+ }
+
+ /* AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ if (!isset($this->authorizationCodes[$code])) {
+ return false;
+ }
+
+ return array_merge(array(
+ 'authorization_code' => $code,
+ ), $this->authorizationCodes[$code]);
+ }
+
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ $this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token');
+
+ return true;
+ }
+
+ public function setAuthorizationCodes($authorization_codes)
+ {
+ $this->authorizationCodes = $authorization_codes;
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ unset($this->authorizationCodes[$code]);
+ }
+
+ /* UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ $userDetails = $this->getUserDetails($username);
+
+ return $userDetails && $userDetails['password'] && $userDetails['password'] === $password;
+ }
+
+ public function setUser($username, $password, $firstName = null, $lastName = null)
+ {
+ $this->userCredentials[$username] = array(
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName,
+ );
+
+ return true;
+ }
+
+ public function getUserDetails($username)
+ {
+ if (!isset($this->userCredentials[$username])) {
+ return false;
+ }
+
+ return array_merge(array(
+ 'user_id' => $username,
+ 'password' => null,
+ 'first_name' => null,
+ 'last_name' => null,
+ ), $this->userCredentials[$username]);
+ }
+
+ /* UserClaimsInterface */
+ public function getUserClaims($user_id, $claims)
+ {
+ if (!$userDetails = $this->getUserDetails($user_id)) {
+ return false;
+ }
+
+ $claims = explode(' ', trim($claims));
+ $userClaims = array();
+
+ // for each requested claim, if the user has the claim, set it in the response
+ $validClaims = explode(' ', self::VALID_CLAIMS);
+ foreach ($validClaims as $validClaim) {
+ if (in_array($validClaim, $claims)) {
+ if ($validClaim == 'address') {
+ // address is an object with subfields
+ $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
+ } else {
+ $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
+ }
+ }
+ }
+
+ return $userClaims;
+ }
+
+ protected function getUserClaim($claim, $userDetails)
+ {
+ $userClaims = array();
+ $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
+ $claimValues = explode(' ', $claimValuesString);
+
+ foreach ($claimValues as $value) {
+ $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
+ }
+
+ return $userClaims;
+ }
+
+ /* ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ return isset($this->clientCredentials[$client_id]['client_secret']) && $this->clientCredentials[$client_id]['client_secret'] === $client_secret;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ if (!isset($this->clientCredentials[$client_id])) {
+ return false;
+ }
+
+ return empty($this->clientCredentials[$client_id]['client_secret']);
+ }
+
+ /* ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ if (!isset($this->clientCredentials[$client_id])) {
+ return false;
+ }
+
+ $clientDetails = array_merge(array(
+ 'client_id' => $client_id,
+ 'client_secret' => null,
+ 'redirect_uri' => null,
+ 'scope' => null,
+ ), $this->clientCredentials[$client_id]);
+
+ return $clientDetails;
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ if (isset($this->clientCredentials[$client_id]['grant_types'])) {
+ $grant_types = explode(' ', $this->clientCredentials[$client_id]['grant_types']);
+
+ return in_array($grant_type, $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ $this->clientCredentials[$client_id] = array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ );
+
+ return true;
+ }
+
+ /* RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ return isset($this->refreshTokens[$refresh_token]) ? $this->refreshTokens[$refresh_token] : false;
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ $this->refreshTokens[$refresh_token] = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
+
+ return true;
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ if (isset($this->refreshTokens[$refresh_token])) {
+ unset($this->refreshTokens[$refresh_token]);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public function setRefreshTokens($refresh_tokens)
+ {
+ $this->refreshTokens = $refresh_tokens;
+ }
+
+ /* AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ return isset($this->accessTokens[$access_token]) ? $this->accessTokens[$access_token] : false;
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null, $id_token = null)
+ {
+ $this->accessTokens[$access_token] = compact('access_token', 'client_id', 'user_id', 'expires', 'scope', 'id_token');
+
+ return true;
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ if (isset($this->accessTokens[$access_token])) {
+ unset($this->accessTokens[$access_token]);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public function scopeExists($scope)
+ {
+ $scope = explode(' ', trim($scope));
+
+ return (count(array_diff($scope, $this->supportedScopes)) == 0);
+ }
+
+ public function getDefaultScope($client_id = null)
+ {
+ return $this->defaultScope;
+ }
+
+ /*JWTBearerInterface */
+ public function getClientKey($client_id, $subject)
+ {
+ if (isset($this->jwt[$client_id])) {
+ $jwt = $this->jwt[$client_id];
+ if ($jwt) {
+ if ($jwt["subject"] == $subject) {
+ return $jwt["key"];
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ foreach ($this->jti as $storedJti) {
+ if ($storedJti['issuer'] == $client_id && $storedJti['subject'] == $subject && $storedJti['audience'] == $audience && $storedJti['expires'] == $expires && $storedJti['jti'] == $jti) {
+ return array(
+ 'issuer' => $storedJti['issuer'],
+ 'subject' => $storedJti['subject'],
+ 'audience' => $storedJti['audience'],
+ 'expires' => $storedJti['expires'],
+ 'jti' => $storedJti['jti']
+ );
+ }
+ }
+
+ return null;
+ }
+
+ public function setJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ $this->jti[] = array('issuer' => $client_id, 'subject' => $subject, 'audience' => $audience, 'expires' => $expires, 'jti' => $jti);
+ }
+
+ /*PublicKeyInterface */
+ public function getPublicKey($client_id = null)
+ {
+ if (isset($this->keys[$client_id])) {
+ return $this->keys[$client_id]['public_key'];
+ }
+
+ // use a global encryption pair
+ if (isset($this->keys['public_key'])) {
+ return $this->keys['public_key'];
+ }
+
+ return false;
+ }
+
+ public function getPrivateKey($client_id = null)
+ {
+ if (isset($this->keys[$client_id])) {
+ return $this->keys[$client_id]['private_key'];
+ }
+
+ // use a global encryption pair
+ if (isset($this->keys['private_key'])) {
+ return $this->keys['private_key'];
+ }
+
+ return false;
+ }
+
+ public function getEncryptionAlgorithm($client_id = null)
+ {
+ if (isset($this->keys[$client_id]['encryption_algorithm'])) {
+ return $this->keys[$client_id]['encryption_algorithm'];
+ }
+
+ // use a global encryption algorithm
+ if (isset($this->keys['encryption_algorithm'])) {
+ return $this->keys['encryption_algorithm'];
+ }
+
+ return 'RS256';
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Mongo.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Mongo.php
new file mode 100644
index 000000000..eea06e315
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Mongo.php
@@ -0,0 +1,392 @@
+
+ */
+class Mongo implements AuthorizationCodeInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ UserCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ PublicKeyInterface,
+ OpenIDAuthorizationCodeInterface
+{
+ protected $db;
+ protected $config;
+
+ public function __construct($connection, $config = array())
+ {
+ if ($connection instanceof \MongoDB) {
+ $this->db = $connection;
+ } else {
+ if (!is_array($connection)) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\Mongo must be an instance of MongoDB or a configuration array');
+ }
+ $server = sprintf('mongodb://%s:%d', $connection['host'], $connection['port']);
+ $m = new \MongoClient($server);
+ $this->db = $m->{$connection['database']};
+ }
+
+ $this->config = array_merge(array(
+ 'client_table' => 'oauth_clients',
+ 'access_token_table' => 'oauth_access_tokens',
+ 'refresh_token_table' => 'oauth_refresh_tokens',
+ 'code_table' => 'oauth_authorization_codes',
+ 'user_table' => 'oauth_users',
+ 'key_table' => 'oauth_keys',
+ 'jwt_table' => 'oauth_jwt',
+ ), $config);
+ }
+
+ // Helper function to access a MongoDB collection by `type`:
+ protected function collection($name)
+ {
+ return $this->db->{$this->config[$name]};
+ }
+
+ /* ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ if ($result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
+ return $result['client_secret'] == $client_secret;
+ }
+
+ return false;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ if (!$result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
+ return false;
+ }
+
+ return empty($result['client_secret']);
+ }
+
+ /* ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ $result = $this->collection('client_table')->findOne(array('client_id' => $client_id));
+
+ return is_null($result) ? false : $result;
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ if ($this->getClientDetails($client_id)) {
+ $this->collection('client_table')->update(
+ array('client_id' => $client_id),
+ array('$set' => array(
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ ))
+ );
+ } else {
+ $client = array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ );
+ $this->collection('client_table')->insert($client);
+ }
+
+ return true;
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+
+ return in_array($grant_type, $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ $token = $this->collection('access_token_table')->findOne(array('access_token' => $access_token));
+
+ return is_null($token) ? false : $token;
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // if it exists, update it.
+ if ($this->getAccessToken($access_token)) {
+ $this->collection('access_token_table')->update(
+ array('access_token' => $access_token),
+ array('$set' => array(
+ 'client_id' => $client_id,
+ 'expires' => $expires,
+ 'user_id' => $user_id,
+ 'scope' => $scope
+ ))
+ );
+ } else {
+ $token = array(
+ 'access_token' => $access_token,
+ 'client_id' => $client_id,
+ 'expires' => $expires,
+ 'user_id' => $user_id,
+ 'scope' => $scope
+ );
+ $this->collection('access_token_table')->insert($token);
+ }
+
+ return true;
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ $result = $this->collection('access_token_table')->remove(array(
+ 'access_token' => $access_token
+ ), array('w' => 1));
+
+ return $result['n'] > 0;
+ }
+
+
+ /* AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ $code = $this->collection('code_table')->findOne(array('authorization_code' => $code));
+
+ return is_null($code) ? false : $code;
+ }
+
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ // if it exists, update it.
+ if ($this->getAuthorizationCode($code)) {
+ $this->collection('code_table')->update(
+ array('authorization_code' => $code),
+ array('$set' => array(
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'redirect_uri' => $redirect_uri,
+ 'expires' => $expires,
+ 'scope' => $scope,
+ 'id_token' => $id_token,
+ ))
+ );
+ } else {
+ $token = array(
+ 'authorization_code' => $code,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'redirect_uri' => $redirect_uri,
+ 'expires' => $expires,
+ 'scope' => $scope,
+ 'id_token' => $id_token,
+ );
+ $this->collection('code_table')->insert($token);
+ }
+
+ return true;
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ $this->collection('code_table')->remove(array('authorization_code' => $code));
+
+ return true;
+ }
+
+ /* UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ if ($user = $this->getUser($username)) {
+ return $this->checkPassword($user, $password);
+ }
+
+ return false;
+ }
+
+ public function getUserDetails($username)
+ {
+ if ($user = $this->getUser($username)) {
+ $user['user_id'] = $user['username'];
+ }
+
+ return $user;
+ }
+
+ /* RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ $token = $this->collection('refresh_token_table')->findOne(array('refresh_token' => $refresh_token));
+
+ return is_null($token) ? false : $token;
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ $token = array(
+ 'refresh_token' => $refresh_token,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'expires' => $expires,
+ 'scope' => $scope
+ );
+ $this->collection('refresh_token_table')->insert($token);
+
+ return true;
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ $result = $this->collection('refresh_token_table')->remove(array(
+ 'refresh_token' => $refresh_token
+ ), array('w' => 1));
+
+ return $result['n'] > 0;
+ }
+
+ // plaintext passwords are bad! Override this for your application
+ protected function checkPassword($user, $password)
+ {
+ return $user['password'] == $password;
+ }
+
+ public function getUser($username)
+ {
+ $result = $this->collection('user_table')->findOne(array('username' => $username));
+
+ return is_null($result) ? false : $result;
+ }
+
+ public function setUser($username, $password, $firstName = null, $lastName = null)
+ {
+ if ($this->getUser($username)) {
+ $this->collection('user_table')->update(
+ array('username' => $username),
+ array('$set' => array(
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName
+ ))
+ );
+ } else {
+ $user = array(
+ 'username' => $username,
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName
+ );
+ $this->collection('user_table')->insert($user);
+ }
+
+ return true;
+ }
+
+ public function getClientKey($client_id, $subject)
+ {
+ $result = $this->collection('jwt_table')->findOne(array(
+ 'client_id' => $client_id,
+ 'subject' => $subject
+ ));
+
+ return is_null($result) ? false : $result['key'];
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs mongodb implementation.
+ throw new \Exception('getJti() for the MongoDB driver is currently unimplemented.');
+ }
+
+ public function setJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs mongodb implementation.
+ throw new \Exception('setJti() for the MongoDB driver is currently unimplemented.');
+ }
+
+ public function getPublicKey($client_id = null)
+ {
+ if ($client_id) {
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => $client_id
+ ));
+ if ($result) {
+ return $result['public_key'];
+ }
+ }
+
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => null
+ ));
+ return is_null($result) ? false : $result['public_key'];
+ }
+
+ public function getPrivateKey($client_id = null)
+ {
+ if ($client_id) {
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => $client_id
+ ));
+ if ($result) {
+ return $result['private_key'];
+ }
+ }
+
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => null
+ ));
+ return is_null($result) ? false : $result['private_key'];
+ }
+
+ public function getEncryptionAlgorithm($client_id = null)
+ {
+ if ($client_id) {
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => $client_id
+ ));
+ if ($result) {
+ return $result['encryption_algorithm'];
+ }
+ }
+
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => null
+ ));
+ return is_null($result) ? 'RS256' : $result['encryption_algorithm'];
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/MongoDB.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/MongoDB.php
new file mode 100644
index 000000000..64f740fc1
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/MongoDB.php
@@ -0,0 +1,380 @@
+
+ */
+class MongoDB implements AuthorizationCodeInterface,
+ UserCredentialsInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ PublicKeyInterface,
+ OpenIDAuthorizationCodeInterface
+{
+ protected $db;
+ protected $config;
+
+ public function __construct($connection, $config = array())
+ {
+ if ($connection instanceof Database) {
+ $this->db = $connection;
+ } else {
+ if (!is_array($connection)) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\Mongo must be an instance of MongoDB\Database or a configuration array');
+ }
+ $server = sprintf('mongodb://%s:%d', $connection['host'], $connection['port']);
+ $m = new Client($server);
+ $this->db = $m->selectDatabase($connection['database']);
+ }
+ $this->config = array_merge(array(
+ 'client_table' => 'oauth_clients',
+ 'access_token_table' => 'oauth_access_tokens',
+ 'refresh_token_table' => 'oauth_refresh_tokens',
+ 'code_table' => 'oauth_authorization_codes',
+ 'user_table' => 'oauth_users',
+ 'jwt_table' => 'oauth_jwt',
+ 'jti_table' => 'oauth_jti',
+ 'scope_table' => 'oauth_scopes',
+ 'key_table' => 'oauth_keys',
+ ), $config);
+ }
+
+ /* ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ if ($result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
+ return $result['client_secret'] == $client_secret;
+ }
+ return false;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ if (!$result = $this->collection('client_table')->findOne(array('client_id' => $client_id))) {
+ return false;
+ }
+ return empty($result['client_secret']);
+ }
+
+ /* ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ $result = $this->collection('client_table')->findOne(array('client_id' => $client_id));
+ return is_null($result) ? false : $result;
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ if ($this->getClientDetails($client_id)) {
+ $result = $this->collection('client_table')->updateOne(
+ array('client_id' => $client_id),
+ array('$set' => array(
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ ))
+ );
+ return $result->getMatchedCount() > 0;
+ }
+ $client = array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'redirect_uri' => $redirect_uri,
+ 'grant_types' => $grant_types,
+ 'scope' => $scope,
+ 'user_id' => $user_id,
+ );
+ $result = $this->collection('client_table')->insertOne($client);
+ return $result->getInsertedCount() > 0;
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+ return in_array($grant_type, $grant_types);
+ }
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ $token = $this->collection('access_token_table')->findOne(array('access_token' => $access_token));
+ return is_null($token) ? false : $token;
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // if it exists, update it.
+ if ($this->getAccessToken($access_token)) {
+ $result = $this->collection('access_token_table')->updateOne(
+ array('access_token' => $access_token),
+ array('$set' => array(
+ 'client_id' => $client_id,
+ 'expires' => $expires,
+ 'user_id' => $user_id,
+ 'scope' => $scope
+ ))
+ );
+ return $result->getMatchedCount() > 0;
+ }
+ $token = array(
+ 'access_token' => $access_token,
+ 'client_id' => $client_id,
+ 'expires' => $expires,
+ 'user_id' => $user_id,
+ 'scope' => $scope
+ );
+ $result = $this->collection('access_token_table')->insertOne($token);
+ return $result->getInsertedCount() > 0;
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ $result = $this->collection('access_token_table')->deleteOne(array(
+ 'access_token' => $access_token
+ ));
+ return $result->getDeletedCount() > 0;
+ }
+
+ /* AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ $code = $this->collection('code_table')->findOne(array(
+ 'authorization_code' => $code
+ ));
+ return is_null($code) ? false : $code;
+ }
+
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ // if it exists, update it.
+ if ($this->getAuthorizationCode($code)) {
+ $result = $this->collection('code_table')->updateOne(
+ array('authorization_code' => $code),
+ array('$set' => array(
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'redirect_uri' => $redirect_uri,
+ 'expires' => $expires,
+ 'scope' => $scope,
+ 'id_token' => $id_token,
+ ))
+ );
+ return $result->getMatchedCount() > 0;
+ }
+ $token = array(
+ 'authorization_code' => $code,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'redirect_uri' => $redirect_uri,
+ 'expires' => $expires,
+ 'scope' => $scope,
+ 'id_token' => $id_token,
+ );
+ $result = $this->collection('code_table')->insertOne($token);
+ return $result->getInsertedCount() > 0;
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ $result = $this->collection('code_table')->deleteOne(array(
+ 'authorization_code' => $code
+ ));
+ return $result->getDeletedCount() > 0;
+ }
+
+ /* UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ if ($user = $this->getUser($username)) {
+ return $this->checkPassword($user, $password);
+ }
+ return false;
+ }
+
+ public function getUserDetails($username)
+ {
+ if ($user = $this->getUser($username)) {
+ $user['user_id'] = $user['username'];
+ }
+ return $user;
+ }
+
+ /* RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ $token = $this->collection('refresh_token_table')->findOne(array(
+ 'refresh_token' => $refresh_token
+ ));
+ return is_null($token) ? false : $token;
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ $token = array(
+ 'refresh_token' => $refresh_token,
+ 'client_id' => $client_id,
+ 'user_id' => $user_id,
+ 'expires' => $expires,
+ 'scope' => $scope
+ );
+ $result = $this->collection('refresh_token_table')->insertOne($token);
+ return $result->getInsertedCount() > 0;
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ $result = $this->collection('refresh_token_table')->deleteOne(array(
+ 'refresh_token' => $refresh_token
+ ));
+ return $result->getDeletedCount() > 0;
+ }
+
+ // plaintext passwords are bad! Override this for your application
+ protected function checkPassword($user, $password)
+ {
+ return $user['password'] == $password;
+ }
+
+ public function getUser($username)
+ {
+ $result = $this->collection('user_table')->findOne(array('username' => $username));
+ return is_null($result) ? false : $result;
+ }
+
+ public function setUser($username, $password, $firstName = null, $lastName = null)
+ {
+ if ($this->getUser($username)) {
+ $result = $this->collection('user_table')->updateOne(
+ array('username' => $username),
+ array('$set' => array(
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName
+ ))
+ );
+
+ return $result->getMatchedCount() > 0;
+ }
+
+ $user = array(
+ 'username' => $username,
+ 'password' => $password,
+ 'first_name' => $firstName,
+ 'last_name' => $lastName
+ );
+ $result = $this->collection('user_table')->insertOne($user);
+ return $result->getInsertedCount() > 0;
+ }
+
+ public function getClientKey($client_id, $subject)
+ {
+ $result = $this->collection('jwt_table')->findOne(array(
+ 'client_id' => $client_id,
+ 'subject' => $subject
+ ));
+ return is_null($result) ? false : $result['key'];
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ //TODO: Needs mongodb implementation.
+ throw new \Exception('getJti() for the MongoDB driver is currently unimplemented.');
+ }
+
+ public function setJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ //TODO: Needs mongodb implementation.
+ throw new \Exception('setJti() for the MongoDB driver is currently unimplemented.');
+ }
+
+ public function getPublicKey($client_id = null)
+ {
+ if ($client_id) {
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => $client_id
+ ));
+ if ($result) {
+ return $result['public_key'];
+ }
+ }
+
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => null
+ ));
+ return is_null($result) ? false : $result['public_key'];
+ }
+
+ public function getPrivateKey($client_id = null)
+ {
+ if ($client_id) {
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => $client_id
+ ));
+ if ($result) {
+ return $result['private_key'];
+ }
+ }
+
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => null
+ ));
+ return is_null($result) ? false : $result['private_key'];
+ }
+
+ public function getEncryptionAlgorithm($client_id = null)
+ {
+ if ($client_id) {
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => $client_id
+ ));
+ if ($result) {
+ return $result['encryption_algorithm'];
+ }
+ }
+
+ $result = $this->collection('key_table')->findOne(array(
+ 'client_id' => null
+ ));
+ return is_null($result) ? 'RS256' : $result['encryption_algorithm'];
+ }
+
+ // Helper function to access a MongoDB collection by `type`:
+ protected function collection($name)
+ {
+ return $this->db->{$this->config[$name]};
+ }
+}
\ No newline at end of file
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
new file mode 100644
index 000000000..ae5107e29
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
@@ -0,0 +1,553 @@
+
+ */
+class Pdo implements
+ AuthorizationCodeInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ UserCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ ScopeInterface,
+ PublicKeyInterface,
+ UserClaimsInterface,
+ OpenIDAuthorizationCodeInterface
+{
+ protected $db;
+ protected $config;
+
+ public function __construct($connection, $config = array())
+ {
+ if (!$connection instanceof \PDO) {
+ if (is_string($connection)) {
+ $connection = array('dsn' => $connection);
+ }
+ if (!is_array($connection)) {
+ throw new \InvalidArgumentException('First argument to OAuth2\Storage\Pdo must be an instance of PDO, a DSN string, or a configuration array');
+ }
+ if (!isset($connection['dsn'])) {
+ throw new \InvalidArgumentException('configuration array must contain "dsn"');
+ }
+ // merge optional parameters
+ $connection = array_merge(array(
+ 'username' => null,
+ 'password' => null,
+ 'options' => array(),
+ ), $connection);
+ $connection = new \PDO($connection['dsn'], $connection['username'], $connection['password'], $connection['options']);
+ }
+ $this->db = $connection;
+
+ // debugging
+ $connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+ $this->config = array_merge(array(
+ 'client_table' => 'oauth_clients',
+ 'access_token_table' => 'oauth_access_tokens',
+ 'refresh_token_table' => 'oauth_refresh_tokens',
+ 'code_table' => 'oauth_authorization_codes',
+ 'user_table' => 'oauth_users',
+ 'jwt_table' => 'oauth_jwt',
+ 'jti_table' => 'oauth_jti',
+ 'scope_table' => 'oauth_scopes',
+ 'public_key_table' => 'oauth_public_keys',
+ ), $config);
+ }
+
+ /* OAuth2\Storage\ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
+ $stmt->execute(compact('client_id'));
+ $result = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+ // make this extensible
+ return $result && $result['client_secret'] == $client_secret;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
+ $stmt->execute(compact('client_id'));
+
+ if (!$result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return false;
+ }
+
+ return empty($result['client_secret']);
+ }
+
+ /* OAuth2\Storage\ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
+ $stmt->execute(compact('client_id'));
+
+ return $stmt->fetch(\PDO::FETCH_ASSOC);
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ // if it exists, update it.
+ if ($this->getClientDetails($client_id)) {
+ $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_secret=:client_secret, redirect_uri=:redirect_uri, grant_types=:grant_types, scope=:scope, user_id=:user_id where client_id=:client_id', $this->config['client_table']));
+ } else {
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (client_id, client_secret, redirect_uri, grant_types, scope, user_id) VALUES (:client_id, :client_secret, :redirect_uri, :grant_types, :scope, :user_id)', $this->config['client_table']));
+ }
+
+ return $stmt->execute(compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id'));
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+
+ return in_array($grant_type, (array) $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* OAuth2\Storage\AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = :access_token', $this->config['access_token_table']));
+
+ $token = $stmt->execute(compact('access_token'));
+ if ($token = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ // convert date string back to timestamp
+ $token['expires'] = strtotime($token['expires']);
+ }
+
+ return $token;
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ // if it exists, update it.
+ if ($this->getAccessToken($access_token)) {
+ $stmt = $this->db->prepare(sprintf('UPDATE %s SET client_id=:client_id, expires=:expires, user_id=:user_id, scope=:scope where access_token=:access_token', $this->config['access_token_table']));
+ } else {
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (access_token, client_id, expires, user_id, scope) VALUES (:access_token, :client_id, :expires, :user_id, :scope)', $this->config['access_token_table']));
+ }
+
+ return $stmt->execute(compact('access_token', 'client_id', 'user_id', 'expires', 'scope'));
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE access_token = :access_token', $this->config['access_token_table']));
+
+ $stmt->execute(compact('access_token'));
+
+ return $stmt->rowCount() > 0;
+ }
+
+ /* OAuth2\Storage\AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = :code', $this->config['code_table']));
+ $stmt->execute(compact('code'));
+
+ if ($code = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ // convert date string back to timestamp
+ $code['expires'] = strtotime($code['expires']);
+ }
+
+ return $code;
+ }
+
+ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ if (func_num_args() > 6) {
+ // we are calling with an id token
+ return call_user_func_array(array($this, 'setAuthorizationCodeWithIdToken'), func_get_args());
+ }
+
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ // if it exists, update it.
+ if ($this->getAuthorizationCode($code)) {
+ $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope where authorization_code=:code', $this->config['code_table']));
+ } else {
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope)', $this->config['code_table']));
+ }
+
+ return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
+ }
+
+ private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ // if it exists, update it.
+ if ($this->getAuthorizationCode($code)) {
+ $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token where authorization_code=:code', $this->config['code_table']));
+ } else {
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token)', $this->config['code_table']));
+ }
+
+ return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'));
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE authorization_code = :code', $this->config['code_table']));
+
+ return $stmt->execute(compact('code'));
+ }
+
+ /* OAuth2\Storage\UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ if ($user = $this->getUser($username)) {
+ return $this->checkPassword($user, $password);
+ }
+
+ return false;
+ }
+
+ public function getUserDetails($username)
+ {
+ return $this->getUser($username);
+ }
+
+ /* UserClaimsInterface */
+ public function getUserClaims($user_id, $claims)
+ {
+ if (!$userDetails = $this->getUserDetails($user_id)) {
+ return false;
+ }
+
+ $claims = explode(' ', trim($claims));
+ $userClaims = array();
+
+ // for each requested claim, if the user has the claim, set it in the response
+ $validClaims = explode(' ', self::VALID_CLAIMS);
+ foreach ($validClaims as $validClaim) {
+ if (in_array($validClaim, $claims)) {
+ if ($validClaim == 'address') {
+ // address is an object with subfields
+ $userClaims['address'] = $this->getUserClaim($validClaim, $userDetails['address'] ?: $userDetails);
+ } else {
+ $userClaims = array_merge($userClaims, $this->getUserClaim($validClaim, $userDetails));
+ }
+ }
+ }
+
+ return $userClaims;
+ }
+
+ protected function getUserClaim($claim, $userDetails)
+ {
+ $userClaims = array();
+ $claimValuesString = constant(sprintf('self::%s_CLAIM_VALUES', strtoupper($claim)));
+ $claimValues = explode(' ', $claimValuesString);
+
+ foreach ($claimValues as $value) {
+ $userClaims[$value] = isset($userDetails[$value]) ? $userDetails[$value] : null;
+ }
+
+ return $userClaims;
+ }
+
+ /* OAuth2\Storage\RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
+
+ $token = $stmt->execute(compact('refresh_token'));
+ if ($token = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ // convert expires to epoch time
+ $token['expires'] = strtotime($token['expires']);
+ }
+
+ return $token;
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ // convert expires to datestring
+ $expires = date('Y-m-d H:i:s', $expires);
+
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (refresh_token, client_id, user_id, expires, scope) VALUES (:refresh_token, :client_id, :user_id, :expires, :scope)', $this->config['refresh_token_table']));
+
+ return $stmt->execute(compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'));
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
+
+ $stmt->execute(compact('refresh_token'));
+
+ return $stmt->rowCount() > 0;
+ }
+
+ // plaintext passwords are bad! Override this for your application
+ protected function checkPassword($user, $password)
+ {
+ return $user['password'] == $this->hashPassword($password);
+ }
+
+ // use a secure hashing algorithm when storing passwords. Override this for your application
+ protected function hashPassword($password)
+ {
+ return sha1($password);
+ }
+
+ public function getUser($username)
+ {
+ $stmt = $this->db->prepare($sql = sprintf('SELECT * from %s where username=:username', $this->config['user_table']));
+ $stmt->execute(array('username' => $username));
+
+ if (!$userInfo = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return false;
+ }
+
+ // the default behavior is to use "username" as the user_id
+ return array_merge(array(
+ 'user_id' => $username
+ ), $userInfo);
+ }
+
+ public function setUser($username, $password, $firstName = null, $lastName = null)
+ {
+ // do not store in plaintext
+ $password = $this->hashPassword($password);
+
+ // if it exists, update it.
+ if ($this->getUser($username)) {
+ $stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET password=:password, first_name=:firstName, last_name=:lastName where username=:username', $this->config['user_table']));
+ } else {
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (username, password, first_name, last_name) VALUES (:username, :password, :firstName, :lastName)', $this->config['user_table']));
+ }
+
+ return $stmt->execute(compact('username', 'password', 'firstName', 'lastName'));
+ }
+
+ /* ScopeInterface */
+ public function scopeExists($scope)
+ {
+ $scope = explode(' ', $scope);
+ $whereIn = implode(',', array_fill(0, count($scope), '?'));
+ $stmt = $this->db->prepare(sprintf('SELECT count(scope) as count FROM %s WHERE scope IN (%s)', $this->config['scope_table'], $whereIn));
+ $stmt->execute($scope);
+
+ if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return $result['count'] == count($scope);
+ }
+
+ return false;
+ }
+
+ public function getDefaultScope($client_id = null)
+ {
+ $stmt = $this->db->prepare(sprintf('SELECT scope FROM %s WHERE is_default=:is_default', $this->config['scope_table']));
+ $stmt->execute(array('is_default' => true));
+
+ if ($result = $stmt->fetchAll(\PDO::FETCH_ASSOC)) {
+ $defaultScope = array_map(function ($row) {
+ return $row['scope'];
+ }, $result);
+
+ return implode(' ', $defaultScope);
+ }
+
+ return null;
+ }
+
+ /* JWTBearerInterface */
+ public function getClientKey($client_id, $subject)
+ {
+ $stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id AND subject=:subject', $this->config['jwt_table']));
+
+ $stmt->execute(array('client_id' => $client_id, 'subject' => $subject));
+
+ return $stmt->fetchColumn();
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ $stmt = $this->db->prepare($sql = sprintf('SELECT * FROM %s WHERE issuer=:client_id AND subject=:subject AND audience=:audience AND expires=:expires AND jti=:jti', $this->config['jti_table']));
+
+ $stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
+
+ if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return array(
+ 'issuer' => $result['issuer'],
+ 'subject' => $result['subject'],
+ 'audience' => $result['audience'],
+ 'expires' => $result['expires'],
+ 'jti' => $result['jti'],
+ );
+ }
+
+ return null;
+ }
+
+ public function setJti($client_id, $subject, $audience, $expires, $jti)
+ {
+ $stmt = $this->db->prepare(sprintf('INSERT INTO %s (issuer, subject, audience, expires, jti) VALUES (:client_id, :subject, :audience, :expires, :jti)', $this->config['jti_table']));
+
+ return $stmt->execute(compact('client_id', 'subject', 'audience', 'expires', 'jti'));
+ }
+
+ /* PublicKeyInterface */
+ public function getPublicKey($client_id = null)
+ {
+ $stmt = $this->db->prepare($sql = sprintf('SELECT public_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
+
+ $stmt->execute(compact('client_id'));
+ if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return $result['public_key'];
+ }
+ }
+
+ public function getPrivateKey($client_id = null)
+ {
+ $stmt = $this->db->prepare($sql = sprintf('SELECT private_key FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
+
+ $stmt->execute(compact('client_id'));
+ if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return $result['private_key'];
+ }
+ }
+
+ public function getEncryptionAlgorithm($client_id = null)
+ {
+ $stmt = $this->db->prepare($sql = sprintf('SELECT encryption_algorithm FROM %s WHERE client_id=:client_id OR client_id IS NULL ORDER BY client_id IS NOT NULL DESC', $this->config['public_key_table']));
+
+ $stmt->execute(compact('client_id'));
+ if ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return $result['encryption_algorithm'];
+ }
+
+ return 'RS256';
+ }
+
+ /**
+ * DDL to create OAuth2 database and tables for PDO storage
+ *
+ * @see https://github.com/dsquier/oauth2-server-php-mysql
+ */
+ public function getBuildSql($dbName = 'oauth2_server_php')
+ {
+ $sql = "
+ CREATE TABLE {$this->config['client_table']} (
+ client_id VARCHAR(80) NOT NULL,
+ client_secret VARCHAR(80),
+ redirect_uri VARCHAR(2000),
+ grant_types VARCHAR(80),
+ scope VARCHAR(4000),
+ user_id VARCHAR(80),
+ PRIMARY KEY (client_id)
+ );
+
+ CREATE TABLE {$this->config['access_token_table']} (
+ access_token VARCHAR(40) NOT NULL,
+ client_id VARCHAR(80) NOT NULL,
+ user_id VARCHAR(80),
+ expires TIMESTAMP NOT NULL,
+ scope VARCHAR(4000),
+ PRIMARY KEY (access_token)
+ );
+
+ CREATE TABLE {$this->config['code_table']} (
+ authorization_code VARCHAR(40) NOT NULL,
+ client_id VARCHAR(80) NOT NULL,
+ user_id VARCHAR(80),
+ redirect_uri VARCHAR(2000),
+ expires TIMESTAMP NOT NULL,
+ scope VARCHAR(4000),
+ id_token VARCHAR(1000),
+ PRIMARY KEY (authorization_code)
+ );
+
+ CREATE TABLE {$this->config['refresh_token_table']} (
+ refresh_token VARCHAR(40) NOT NULL,
+ client_id VARCHAR(80) NOT NULL,
+ user_id VARCHAR(80),
+ expires TIMESTAMP NOT NULL,
+ scope VARCHAR(4000),
+ PRIMARY KEY (refresh_token)
+ );
+
+ CREATE TABLE {$this->config['user_table']} (
+ username VARCHAR(80),
+ password VARCHAR(80),
+ first_name VARCHAR(80),
+ last_name VARCHAR(80),
+ email VARCHAR(80),
+ email_verified BOOLEAN,
+ scope VARCHAR(4000)
+ );
+
+ CREATE TABLE {$this->config['scope_table']} (
+ scope VARCHAR(80) NOT NULL,
+ is_default BOOLEAN,
+ PRIMARY KEY (scope)
+ );
+
+ CREATE TABLE {$this->config['jwt_table']} (
+ client_id VARCHAR(80) NOT NULL,
+ subject VARCHAR(80),
+ public_key VARCHAR(2000) NOT NULL
+ );
+
+ CREATE TABLE {$this->config['jti_table']} (
+ issuer VARCHAR(80) NOT NULL,
+ subject VARCHAR(80),
+ audience VARCHAR(80),
+ expires TIMESTAMP NOT NULL,
+ jti VARCHAR(2000) NOT NULL
+ );
+
+ CREATE TABLE {$this->config['public_key_table']} (
+ client_id VARCHAR(80),
+ public_key VARCHAR(2000),
+ private_key VARCHAR(2000),
+ encryption_algorithm VARCHAR(100) DEFAULT 'RS256'
+ )
+";
+
+ return $sql;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/PublicKeyInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/PublicKeyInterface.php
new file mode 100644
index 000000000..108418d3a
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/PublicKeyInterface.php
@@ -0,0 +1,16 @@
+
+ */
+interface PublicKeyInterface
+{
+ public function getPublicKey($client_id = null);
+ public function getPrivateKey($client_id = null);
+ public function getEncryptionAlgorithm($client_id = null);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Redis.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Redis.php
new file mode 100644
index 000000000..e6294e22d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Redis.php
@@ -0,0 +1,321 @@
+
+ * $storage = new OAuth2\Storage\Redis($redis);
+ * $storage->setClientDetails($client_id, $client_secret, $redirect_uri);
+ *
+ */
+class Redis implements AuthorizationCodeInterface,
+ AccessTokenInterface,
+ ClientCredentialsInterface,
+ UserCredentialsInterface,
+ RefreshTokenInterface,
+ JwtBearerInterface,
+ ScopeInterface,
+ OpenIDAuthorizationCodeInterface
+{
+
+ private $cache;
+
+ /* The redis client */
+ protected $redis;
+
+ /* Configuration array */
+ protected $config;
+
+ /**
+ * Redis Storage!
+ *
+ * @param \Predis\Client $redis
+ * @param array $config
+ */
+ public function __construct($redis, $config=array())
+ {
+ $this->redis = $redis;
+ $this->config = array_merge(array(
+ 'client_key' => 'oauth_clients:',
+ 'access_token_key' => 'oauth_access_tokens:',
+ 'refresh_token_key' => 'oauth_refresh_tokens:',
+ 'code_key' => 'oauth_authorization_codes:',
+ 'user_key' => 'oauth_users:',
+ 'jwt_key' => 'oauth_jwt:',
+ 'scope_key' => 'oauth_scopes:',
+ ), $config);
+ }
+
+ protected function getValue($key)
+ {
+ if ( isset($this->cache[$key]) ) {
+ return $this->cache[$key];
+ }
+ $value = $this->redis->get($key);
+ if ( isset($value) ) {
+ return json_decode($value, true);
+ } else {
+ return false;
+ }
+ }
+
+ protected function setValue($key, $value, $expire=0)
+ {
+ $this->cache[$key] = $value;
+ $str = json_encode($value);
+ if ($expire > 0) {
+ $seconds = $expire - time();
+ $ret = $this->redis->setex($key, $seconds, $str);
+ } else {
+ $ret = $this->redis->set($key, $str);
+ }
+
+ // check that the key was set properly
+ // if this fails, an exception will usually thrown, so this step isn't strictly necessary
+ return is_bool($ret) ? $ret : $ret->getPayload() == 'OK';
+ }
+
+ protected function expireValue($key)
+ {
+ unset($this->cache[$key]);
+
+ return $this->redis->del($key);
+ }
+
+ /* AuthorizationCodeInterface */
+ public function getAuthorizationCode($code)
+ {
+ return $this->getValue($this->config['code_key'] . $code);
+ }
+
+ public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
+ {
+ return $this->setValue(
+ $this->config['code_key'] . $authorization_code,
+ compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
+ $expires
+ );
+ }
+
+ public function expireAuthorizationCode($code)
+ {
+ $key = $this->config['code_key'] . $code;
+ unset($this->cache[$key]);
+
+ return $this->expireValue($key);
+ }
+
+ /* UserCredentialsInterface */
+ public function checkUserCredentials($username, $password)
+ {
+ $user = $this->getUserDetails($username);
+
+ return $user && $user['password'] === $password;
+ }
+
+ public function getUserDetails($username)
+ {
+ return $this->getUser($username);
+ }
+
+ public function getUser($username)
+ {
+ if (!$userInfo = $this->getValue($this->config['user_key'] . $username)) {
+ return false;
+ }
+
+ // the default behavior is to use "username" as the user_id
+ return array_merge(array(
+ 'user_id' => $username,
+ ), $userInfo);
+ }
+
+ public function setUser($username, $password, $first_name = null, $last_name = null)
+ {
+ return $this->setValue(
+ $this->config['user_key'] . $username,
+ compact('username', 'password', 'first_name', 'last_name')
+ );
+ }
+
+ /* ClientCredentialsInterface */
+ public function checkClientCredentials($client_id, $client_secret = null)
+ {
+ if (!$client = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ return isset($client['client_secret'])
+ && $client['client_secret'] == $client_secret;
+ }
+
+ public function isPublicClient($client_id)
+ {
+ if (!$client = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ return empty($client['client_secret']);
+ }
+
+ /* ClientInterface */
+ public function getClientDetails($client_id)
+ {
+ return $this->getValue($this->config['client_key'] . $client_id);
+ }
+
+ public function setClientDetails($client_id, $client_secret = null, $redirect_uri = null, $grant_types = null, $scope = null, $user_id = null)
+ {
+ return $this->setValue(
+ $this->config['client_key'] . $client_id,
+ compact('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
+ );
+ }
+
+ public function checkRestrictedGrantType($client_id, $grant_type)
+ {
+ $details = $this->getClientDetails($client_id);
+ if (isset($details['grant_types'])) {
+ $grant_types = explode(' ', $details['grant_types']);
+
+ return in_array($grant_type, (array) $grant_types);
+ }
+
+ // if grant_types are not defined, then none are restricted
+ return true;
+ }
+
+ /* RefreshTokenInterface */
+ public function getRefreshToken($refresh_token)
+ {
+ return $this->getValue($this->config['refresh_token_key'] . $refresh_token);
+ }
+
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ return $this->setValue(
+ $this->config['refresh_token_key'] . $refresh_token,
+ compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'),
+ $expires
+ );
+ }
+
+ public function unsetRefreshToken($refresh_token)
+ {
+ $result = $this->expireValue($this->config['refresh_token_key'] . $refresh_token);
+
+ return $result > 0;
+ }
+
+ /* AccessTokenInterface */
+ public function getAccessToken($access_token)
+ {
+ return $this->getValue($this->config['access_token_key'].$access_token);
+ }
+
+ public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
+ {
+ return $this->setValue(
+ $this->config['access_token_key'].$access_token,
+ compact('access_token', 'client_id', 'user_id', 'expires', 'scope'),
+ $expires
+ );
+ }
+
+ public function unsetAccessToken($access_token)
+ {
+ $result = $this->expireValue($this->config['access_token_key'] . $access_token);
+
+ return $result > 0;
+ }
+
+ /* ScopeInterface */
+ public function scopeExists($scope)
+ {
+ $scope = explode(' ', $scope);
+
+ $result = $this->getValue($this->config['scope_key'].'supported:global');
+
+ $supportedScope = explode(' ', (string) $result);
+
+ return (count(array_diff($scope, $supportedScope)) == 0);
+ }
+
+ public function getDefaultScope($client_id = null)
+ {
+ if (is_null($client_id) || !$result = $this->getValue($this->config['scope_key'].'default:'.$client_id)) {
+ $result = $this->getValue($this->config['scope_key'].'default:global');
+ }
+
+ return $result;
+ }
+
+ public function setScope($scope, $client_id = null, $type = 'supported')
+ {
+ if (!in_array($type, array('default', 'supported'))) {
+ throw new \InvalidArgumentException('"$type" must be one of "default", "supported"');
+ }
+
+ if (is_null($client_id)) {
+ $key = $this->config['scope_key'].$type.':global';
+ } else {
+ $key = $this->config['scope_key'].$type.':'.$client_id;
+ }
+
+ return $this->setValue($key, $scope);
+ }
+
+ /*JWTBearerInterface */
+ public function getClientKey($client_id, $subject)
+ {
+ if (!$jwt = $this->getValue($this->config['jwt_key'] . $client_id)) {
+ return false;
+ }
+
+ if (isset($jwt['subject']) && $jwt['subject'] == $subject) {
+ return $jwt['key'];
+ }
+
+ return null;
+ }
+
+ public function setClientKey($client_id, $key, $subject = null)
+ {
+ return $this->setValue($this->config['jwt_key'] . $client_id, array(
+ 'key' => $key,
+ 'subject' => $subject
+ ));
+ }
+
+ public function getClientScope($client_id)
+ {
+ if (!$clientDetails = $this->getClientDetails($client_id)) {
+ return false;
+ }
+
+ if (isset($clientDetails['scope'])) {
+ return $clientDetails['scope'];
+ }
+
+ return null;
+ }
+
+ public function getJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs redis implementation.
+ throw new \Exception('getJti() for the Redis driver is currently unimplemented.');
+ }
+
+ public function setJti($client_id, $subject, $audience, $expiration, $jti)
+ {
+ //TODO: Needs redis implementation.
+ throw new \Exception('setJti() for the Redis driver is currently unimplemented.');
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/RefreshTokenInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/RefreshTokenInterface.php
new file mode 100644
index 000000000..e6407e440
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/RefreshTokenInterface.php
@@ -0,0 +1,82 @@
+
+ */
+interface RefreshTokenInterface
+{
+ /**
+ * Grant refresh access tokens.
+ *
+ * Retrieve the stored data for the given refresh token.
+ *
+ * Required for OAuth2::GRANT_TYPE_REFRESH_TOKEN.
+ *
+ * @param $refresh_token
+ * Refresh token to be check with.
+ *
+ * @return
+ * An associative array as below, and NULL if the refresh_token is
+ * invalid:
+ * - refresh_token: Refresh token identifier.
+ * - client_id: Client identifier.
+ * - user_id: User identifier.
+ * - expires: Expiration unix timestamp, or 0 if the token doesn't expire.
+ * - scope: (optional) Scope values in space-separated string.
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-6
+ *
+ * @ingroup oauth2_section_6
+ */
+ public function getRefreshToken($refresh_token);
+
+ /**
+ * Take the provided refresh token values and store them somewhere.
+ *
+ * This function should be the storage counterpart to getRefreshToken().
+ *
+ * If storage fails for some reason, we're not currently checking for
+ * any sort of success/failure, so you should bail out of the script
+ * and provide a descriptive fail message.
+ *
+ * Required for OAuth2::GRANT_TYPE_REFRESH_TOKEN.
+ *
+ * @param $refresh_token
+ * Refresh token to be stored.
+ * @param $client_id
+ * Client identifier to be stored.
+ * @param $user_id
+ * User identifier to be stored.
+ * @param $expires
+ * Expiration timestamp to be stored. 0 if the token doesn't expire.
+ * @param $scope
+ * (optional) Scopes to be stored in space-separated string.
+ *
+ * @ingroup oauth2_section_6
+ */
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null);
+
+ /**
+ * Expire a used refresh token.
+ *
+ * This is not explicitly required in the spec, but is almost implied.
+ * After granting a new refresh token, the old one is no longer useful and
+ * so should be forcibly expired in the data store so it can't be used again.
+ *
+ * If storage fails for some reason, we're not currently checking for
+ * any sort of success/failure, so you should bail out of the script
+ * and provide a descriptive fail message.
+ *
+ * @param $refresh_token
+ * Refresh token to be expired.
+ *
+ * @ingroup oauth2_section_6
+ */
+ public function unsetRefreshToken($refresh_token);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php
new file mode 100644
index 000000000..a8292269b
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php
@@ -0,0 +1,46 @@
+
+ */
+interface ScopeInterface
+{
+ /**
+ * Check if the provided scope exists.
+ *
+ * @param $scope
+ * A space-separated string of scopes.
+ *
+ * @return
+ * TRUE if it exists, FALSE otherwise.
+ */
+ public function scopeExists($scope);
+
+ /**
+ * The default scope to use in the event the client
+ * does not request one. By returning "false", a
+ * request_error is returned by the server to force a
+ * scope request by the client. By returning "null",
+ * opt out of requiring scopes
+ *
+ * @param $client_id
+ * An optional client id that can be used to return customized default scopes.
+ *
+ * @return
+ * string representation of default scope, null if
+ * scopes are not defined, or false to force scope
+ * request by the client
+ *
+ * ex:
+ * 'default'
+ * ex:
+ * null
+ */
+ public function getDefaultScope($client_id = null);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/UserCredentialsInterface.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/UserCredentialsInterface.php
new file mode 100644
index 000000000..6e0fd7bad
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/UserCredentialsInterface.php
@@ -0,0 +1,52 @@
+
+ */
+interface UserCredentialsInterface
+{
+ /**
+ * Grant access tokens for basic user credentials.
+ *
+ * Check the supplied username and password for validity.
+ *
+ * You can also use the $client_id param to do any checks required based
+ * on a client, if you need that.
+ *
+ * Required for OAuth2::GRANT_TYPE_USER_CREDENTIALS.
+ *
+ * @param $username
+ * Username to be check with.
+ * @param $password
+ * Password to be check with.
+ *
+ * @return
+ * TRUE if the username and password are valid, and FALSE if it isn't.
+ * Moreover, if the username and password are valid, and you want to
+ *
+ * @see http://tools.ietf.org/html/rfc6749#section-4.3
+ *
+ * @ingroup oauth2_section_4
+ */
+ public function checkUserCredentials($username, $password);
+
+ /**
+ * @return
+ * ARRAY the associated "user_id" and optional "scope" values
+ * This function MUST return FALSE if the requested user does not exist or is
+ * invalid. "scope" is a space-separated list of restricted scopes.
+ * @code
+ * return array(
+ * "user_id" => USER_ID, // REQUIRED user_id to be stored with the authorization code or access token
+ * "scope" => SCOPE // OPTIONAL space-separated list of restricted scopes
+ * );
+ * @endcode
+ */
+ public function getUserDetails($username);
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php
new file mode 100644
index 000000000..8ac8596ac
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php
@@ -0,0 +1,130 @@
+config = array_merge(array(
+ 'token_param_name' => 'access_token',
+ 'token_bearer_header_name' => 'Bearer',
+ ), $config);
+ }
+
+ public function getTokenType()
+ {
+ return 'Bearer';
+ }
+
+ /**
+ * Check if the request has supplied token
+ *
+ * @see https://github.com/bshaffer/oauth2-server-php/issues/349#issuecomment-37993588
+ */
+ public function requestHasToken(RequestInterface $request)
+ {
+ $headers = $request->headers('AUTHORIZATION');
+
+ // check the header, then the querystring, then the request body
+ return !empty($headers) || (bool) ($request->request($this->config['token_param_name'])) || (bool) ($request->query($this->config['token_param_name']));
+ }
+
+ /**
+ * This is a convenience function that can be used to get the token, which can then
+ * be passed to getAccessTokenData(). The constraints specified by the draft are
+ * attempted to be adheared to in this method.
+ *
+ * As per the Bearer spec (draft 8, section 2) - there are three ways for a client
+ * to specify the bearer token, in order of preference: Authorization Header,
+ * POST and GET.
+ *
+ * NB: Resource servers MUST accept tokens via the Authorization scheme
+ * (http://tools.ietf.org/html/rfc6750#section-2).
+ *
+ * @todo Should we enforce TLS/SSL in this function?
+ *
+ * @see http://tools.ietf.org/html/rfc6750#section-2.1
+ * @see http://tools.ietf.org/html/rfc6750#section-2.2
+ * @see http://tools.ietf.org/html/rfc6750#section-2.3
+ *
+ * Old Android version bug (at least with version 2.2)
+ * @see http://code.google.com/p/android/issues/detail?id=6684
+ *
+ */
+ public function getAccessTokenParameter(RequestInterface $request, ResponseInterface $response)
+ {
+ $headers = $request->headers('AUTHORIZATION');
+
+ /**
+ * Ensure more than one method is not used for including an
+ * access token
+ *
+ * @see http://tools.ietf.org/html/rfc6750#section-3.1
+ */
+ $methodsUsed = !empty($headers) + (bool) ($request->query($this->config['token_param_name'])) + (bool) ($request->request($this->config['token_param_name']));
+ if ($methodsUsed > 1) {
+ $response->setError(400, 'invalid_request', 'Only one method may be used to authenticate at a time (Auth header, GET or POST)');
+
+ return null;
+ }
+
+ /**
+ * If no authentication is provided, set the status code
+ * to 401 and return no other error information
+ *
+ * @see http://tools.ietf.org/html/rfc6750#section-3.1
+ */
+ if ($methodsUsed == 0) {
+ $response->setStatusCode(401);
+
+ return null;
+ }
+
+ // HEADER: Get the access token from the header
+ if (!empty($headers)) {
+ if (!preg_match('/' . $this->config['token_bearer_header_name'] . '\s(\S+)/i', $headers, $matches)) {
+ $response->setError(400, 'invalid_request', 'Malformed auth header');
+
+ return null;
+ }
+
+ return $matches[1];
+ }
+
+ if ($request->request($this->config['token_param_name'])) {
+ // // POST: Get the token from POST data
+ if (!in_array(strtolower($request->server('REQUEST_METHOD')), array('post', 'put'))) {
+ $response->setError(400, 'invalid_request', 'When putting the token in the body, the method must be POST or PUT', '#section-2.2');
+
+ return null;
+ }
+
+ $contentType = $request->server('CONTENT_TYPE');
+ if (false !== $pos = strpos($contentType, ';')) {
+ $contentType = substr($contentType, 0, $pos);
+ }
+
+ if ($contentType !== null && $contentType != 'application/x-www-form-urlencoded') {
+ // IETF specifies content-type. NB: Not all webservers populate this _SERVER variable
+ // @see http://tools.ietf.org/html/rfc6750#section-2.2
+ $response->setError(400, 'invalid_request', 'The content type for POST requests must be "application/x-www-form-urlencoded"');
+
+ return null;
+ }
+
+ return $request->request($this->config['token_param_name']);
+ }
+
+ // GET method
+ return $request->query($this->config['token_param_name']);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php b/vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php
new file mode 100644
index 000000000..fe6a86aa6
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php
@@ -0,0 +1,22 @@
+assertTrue(class_exists('OAuth2\Server'));
+ $this->assertTrue(class_exists('OAuth2\Request'));
+ $this->assertTrue(class_exists('OAuth2\Response'));
+ $this->assertTrue(class_exists('OAuth2\GrantType\UserCredentials'));
+ $this->assertTrue(interface_exists('OAuth2\Storage\AccessTokenInterface'));
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/AuthorizeControllerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/AuthorizeControllerTest.php
new file mode 100644
index 000000000..3bfc760e4
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/AuthorizeControllerTest.php
@@ -0,0 +1,492 @@
+getTestServer();
+ $request = new Request();
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'No client id supplied');
+ }
+
+ public function testInvalidClientIdResponse()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Fake Client ID', // invalid client id
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'The client id supplied is invalid');
+ }
+
+ public function testNoRedirectUriSuppliedOrStoredResponse()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_uri');
+ $this->assertEquals($response->getParameter('error_description'), 'No redirect URI was supplied or stored');
+ }
+
+ public function testNoResponseTypeResponse()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'invalid_request');
+ $this->assertEquals($query['error_description'], 'Invalid or missing response type');
+ }
+
+ public function testInvalidResponseTypeResponse()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'invalid', // invalid response type
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'invalid_request');
+ $this->assertEquals($query['error_description'], 'Invalid or missing response type');
+ }
+
+ public function testRedirectUriFragmentResponse()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com#fragment', // valid redirect URI
+ 'response_type' => 'code', // invalid response type
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_uri');
+ $this->assertEquals($response->getParameter('error_description'), 'The redirect URI must not contain a fragment');
+ }
+
+ public function testEnforceState()
+ {
+ $server = $this->getTestServer(array('enforce_state' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'invalid_request');
+ $this->assertEquals($query['error_description'], 'The state parameter is required');
+ }
+
+ public function testDoNotEnforceState()
+ {
+ $server = $this->getTestServer(array('enforce_state' => false));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertNotContains('error', $response->getHttpHeader('Location'));
+ }
+
+ public function testEnforceScope()
+ {
+ $server = $this->getTestServer();
+ $scopeStorage = new Memory(array('default_scope' => false, 'supported_scopes' => array('testscope')));
+ $server->setScopeUtil(new Scope($scopeStorage));
+
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ 'state' => 'xyz',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'invalid_client');
+ $this->assertEquals($query['error_description'], 'This application requires you specify a scope parameter');
+
+ $request->query['scope'] = 'testscope';
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertNotContains('error', $response->getHttpHeader('Location'));
+ }
+
+ public function testInvalidRedirectUri()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // invalid redirect URI
+ 'response_type' => 'code',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
+ $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
+ }
+
+ public function testInvalidRedirectUriApprovedByBuggyRegisteredUri()
+ {
+ $server = $this->getTestServer();
+ $server->setConfig('require_exact_redirect_uri', false);
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Buggy Redirect Uri', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // invalid redirect URI
+ 'response_type' => 'code',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
+ $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
+ }
+
+ public function testNoRedirectUriWithMultipleRedirectUris()
+ {
+ $server = $this->getTestServer();
+
+ // create a request with no "redirect_uri" in querystring
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
+ 'response_type' => 'code',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_uri');
+ $this->assertEquals($response->getParameter('error_description'), 'A redirect URI must be supplied when multiple redirect URIs are registered');
+ }
+
+ public function testRedirectUriWithValidRedirectUri()
+ {
+ $server = $this->getTestServer();
+
+ // create a request with no "redirect_uri" in querystring
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
+ 'response_type' => 'code',
+ 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true',
+ 'state' => 'xyz',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertContains('code', $response->getHttpHeader('Location'));
+ }
+
+ public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
+ {
+ $server = $this->getTestServer(array('require_exact_redirect_uri' => true));
+
+ // create a request with no "redirect_uri" in querystring
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
+ 'response_type' => 'code',
+ 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
+ $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
+ }
+
+ public function testRedirectUriWithDifferentQueryAndExactMatchNotRequired()
+ {
+ $server = $this->getTestServer(array('require_exact_redirect_uri' => false));
+
+ // create a request with no "redirect_uri" in querystring
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
+ 'response_type' => 'code',
+ 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true&hereisa=querystring',
+ 'state' => 'xyz',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertContains('code', $response->getHttpHeader('Location'));
+ }
+
+ public function testMultipleRedirectUris()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
+ 'redirect_uri' => 'http://brentertainment.com', // valid redirect URI
+ 'response_type' => 'code',
+ 'state' => 'xyz'
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertContains('code', $response->getHttpHeader('Location'));
+
+ // call again with different (but still valid) redirect URI
+ $request->query['redirect_uri'] = 'http://morehazards.com';
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertContains('code', $response->getHttpHeader('Location'));
+ }
+
+ /**
+ * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
+ * @see https://github.com/bshaffer/oauth2-server-php/issues/163
+ */
+ public function testNoRedirectUriSuppliedDoesNotRequireTokenRedirectUri()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
+ 'response_type' => 'code',
+ 'state' => 'xyz',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertContains('state', $response->getHttpHeader('Location'));
+ $this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
+
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['query'], $query);
+
+ // call token endpoint with no redirect_uri supplied
+ $request = TestRequest::createPost(array(
+ 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
+ 'client_secret' => 'TestSecret2',
+ 'grant_type' => 'authorization_code',
+ 'code' => $query['code'],
+ ));
+
+ $server->handleTokenRequest($request, $response = new Response(), true);
+ $this->assertEquals($response->getStatusCode(), 200);
+ $this->assertNotNull($response->getParameter('access_token'));
+ }
+
+ public function testUserDeniesAccessResponse()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ 'state' => 'xyz',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'access_denied');
+ $this->assertEquals($query['error_description'], 'The user denied access to your application');
+ }
+
+ public function testCodeQueryParamIsSet()
+ {
+ $server = $this->getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ 'state' => 'xyz',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+
+ $this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
+ $this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
+ $this->assertArrayHasKey('query', $parts);
+ $this->assertFalse(isset($parts['fragment']));
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['query'], $query);
+ $this->assertNotNull($query);
+ $this->assertArrayHasKey('code', $query);
+
+ // ensure no id_token was saved, since the openid scope wasn't requested
+ $storage = $server->getStorage('authorization_code');
+ $code = $storage->getAuthorizationCode($query['code']);
+ $this->assertTrue(empty($code['id_token']));
+
+ // ensure no error was returned
+ $this->assertFalse(isset($query['error']));
+ $this->assertFalse(isset($query['error_description']));
+ }
+
+ public function testSuccessfulRequestReturnsStateParameter()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ 'state' => 'test', // valid state string (just needs to be passed back to us)
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('query', $parts);
+ parse_str($parts['query'], $query);
+
+ $this->assertArrayHasKey('state', $query);
+ $this->assertEquals($query['state'], 'test');
+
+ // ensure no error was returned
+ $this->assertFalse(isset($query['error']));
+ $this->assertFalse(isset($query['error_description']));
+ }
+
+ public function testSuccessfulRequestStripsExtraParameters()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'code',
+ 'state' => 'test', // valid state string (just needs to be passed back to us)
+ 'fake' => 'something', // extra query param
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertFalse(isset($parts['fake']));
+ $this->assertArrayHasKey('query', $parts);
+ parse_str($parts['query'], $query);
+
+ $this->assertFalse(isset($parmas['fake']));
+ $this->assertArrayHasKey('state', $query);
+ $this->assertEquals($query['state'], 'test');
+ }
+
+ public function testSuccessfulOpenidConnectRequest()
+ {
+ $server = $this->getTestServer(array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'bojanz',
+ ));
+
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID',
+ 'redirect_uri' => 'http://adobe.com',
+ 'response_type' => 'code',
+ 'state' => 'xyz',
+ 'scope' => 'openid',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('query', $parts);
+ $this->assertFalse(isset($parts['fragment']));
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['query'], $query);
+ $this->assertNotNull($query);
+ $this->assertArrayHasKey('code', $query);
+
+ // ensure no error was returned
+ $this->assertFalse(isset($query['error']));
+ $this->assertFalse(isset($query['error_description']));
+
+ // confirm that the id_token has been created.
+ $storage = $server->getStorage('authorization_code');
+ $code = $storage->getAuthorizationCode($query['code']);
+ $this->assertTrue(!empty($code['id_token']));
+ }
+
+ public function testCreateController()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $controller = new AuthorizeController($storage);
+ }
+
+ private function getTestServer($config = array())
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ // Add the two types supported for authorization grant
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/ResourceControllerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/ResourceControllerTest.php
new file mode 100644
index 000000000..b277514a5
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/ResourceControllerTest.php
@@ -0,0 +1,176 @@
+getTestServer();
+ $request = Request::createFromGlobals();
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 401);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+ $this->assertEquals('', $response->getResponseBody());
+ }
+
+ public function testMalformedHeader()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'tH1s i5 B0gU5';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Malformed auth header');
+ }
+
+ public function testMultipleTokensSubmitted()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->request['access_token'] = 'TEST';
+ $request->query['access_token'] = 'TEST';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Only one method may be used to authenticate at a time (Auth header, GET or POST)');
+ }
+
+ public function testInvalidRequestMethod()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->server['REQUEST_METHOD'] = 'GET';
+ $request->request['access_token'] = 'TEST';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'When putting the token in the body, the method must be POST or PUT');
+ }
+
+ public function testInvalidContentType()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->server['REQUEST_METHOD'] = 'POST';
+ $request->server['CONTENT_TYPE'] = 'application/json';
+ $request->request['access_token'] = 'TEST';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
+ }
+
+ public function testInvalidToken()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer TESTTOKEN';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 401);
+ $this->assertEquals($response->getParameter('error'), 'invalid_token');
+ $this->assertEquals($response->getParameter('error_description'), 'The access token provided is invalid');
+ }
+
+ public function testExpiredToken()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-expired';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 401);
+ $this->assertEquals($response->getParameter('error'), 'invalid_token');
+ $this->assertEquals($response->getParameter('error_description'), 'The access token provided has expired');
+ }
+
+ public function testOutOfScopeToken()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
+ $scope = 'outofscope';
+ $allow = $server->verifyResourceRequest($request, $response = new Response(), $scope);
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 403);
+ $this->assertEquals($response->getParameter('error'), 'insufficient_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'The request requires higher privileges than provided by the access token');
+
+ // verify the "scope" has been set in the "WWW-Authenticate" header
+ preg_match('/scope="(.*?)"/', $response->getHttpHeader('WWW-Authenticate'), $matches);
+ $this->assertEquals(2, count($matches));
+ $this->assertEquals($matches[1], 'outofscope');
+ }
+
+ public function testMalformedToken()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-malformed';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertFalse($allow);
+
+ $this->assertEquals($response->getStatusCode(), 401);
+ $this->assertEquals($response->getParameter('error'), 'malformed_token');
+ $this->assertEquals($response->getParameter('error_description'), 'Malformed token (missing "expires")');
+ }
+
+ public function testValidToken()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertTrue($allow);
+ }
+
+ public function testValidTokenWithScopeParam()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-scope';
+ $request->query['scope'] = 'testscope';
+ $allow = $server->verifyResourceRequest($request, $response = new Response());
+ $this->assertTrue($allow);
+ }
+
+ public function testCreateController()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $tokenType = new \OAuth2\TokenType\Bearer();
+ $controller = new ResourceController($tokenType, $storage);
+ }
+
+ private function getTestServer($config = array())
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ // Add the two types supported for authorization grant
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/TokenControllerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/TokenControllerTest.php
new file mode 100644
index 000000000..4a217bd55
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Controller/TokenControllerTest.php
@@ -0,0 +1,289 @@
+getTestServer();
+ $server->handleTokenRequest(TestRequest::createPost(), $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'The grant type was not specified in the request');
+ }
+
+ public function testInvalidGrantType()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'invalid_grant_type', // invalid grant type
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'unsupported_grant_type');
+ $this->assertEquals($response->getParameter('error_description'), 'Grant type "invalid_grant_type" not supported');
+ }
+
+ public function testNoClientId()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode',
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'Client credentials were not found in the headers or body');
+ }
+
+ public function testNoClientSecretWithConfidentialClient()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode',
+ 'client_id' => 'Test Client ID', // valid client id
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'This client is invalid or must authenticate using a client secret');
+ }
+
+ public function testNoClientSecretWithEmptySecret()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode-empty-secret',
+ 'client_id' => 'Test Client ID Empty Secret', // valid client id
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 200);
+ }
+
+ public function testInvalidClientId()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode',
+ 'client_id' => 'Fake Client ID', // invalid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
+ }
+
+ public function testInvalidClientSecret()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode',
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'Fake Client Secret', // invalid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
+ }
+
+ public function testValidTokenResponse()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode', // valid authorization code
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertTrue($response instanceof Response);
+ $this->assertEquals($response->getStatusCode(), 200);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+ $this->assertNotNull($response->getParameter('access_token'));
+ $this->assertNotNull($response->getParameter('expires_in'));
+ $this->assertNotNull($response->getParameter('token_type'));
+ }
+
+ public function testValidClientIdScope()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode',
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'scope' => 'clientscope1 clientscope2'
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 200);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+ $this->assertEquals('clientscope1 clientscope2', $response->getParameter('scope'));
+ }
+
+ public function testInvalidClientIdScope()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'code' => 'testcode-with-scope',
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'scope' => 'clientscope3'
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
+ }
+
+ public function testEnforceScope()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new ClientCredentials($storage));
+
+ $scope = new Scope(array(
+ 'default_scope' => false,
+ 'supported_scopes' => array('testscope')
+ ));
+ $server->setScopeUtil($scope);
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $response = $server->handleTokenRequest($request);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'This application requires you specify a scope parameter');
+ }
+
+ public function testCanReceiveAccessTokenUsingPasswordGrantTypeWithoutClientSecret()
+ {
+ // add the test parameters in memory
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new UserCredentials($storage));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID For Password Grant', // valid client id
+ 'username' => 'johndoe', // valid username
+ 'password' => 'password', // valid password for username
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertTrue($response instanceof Response);
+ $this->assertEquals(200, $response->getStatusCode(), var_export($response, 1));
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+ $this->assertNotNull($response->getParameter('access_token'));
+ $this->assertNotNull($response->getParameter('expires_in'));
+ $this->assertNotNull($response->getParameter('token_type'));
+ }
+
+ public function testInvalidTokenTypeHintForRevoke()
+ {
+ $server = $this->getTestServer();
+
+ $request = TestRequest::createPost(array(
+ 'token_type_hint' => 'foo',
+ 'token' => 'sometoken'
+ ));
+
+ $server->handleRevokeRequest($request, $response = new Response());
+
+ $this->assertTrue($response instanceof Response);
+ $this->assertEquals(400, $response->getStatusCode(), var_export($response, 1));
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Token type hint must be either \'access_token\' or \'refresh_token\'');
+ }
+
+ public function testMissingTokenForRevoke()
+ {
+ $server = $this->getTestServer();
+
+ $request = TestRequest::createPost(array(
+ 'token_type_hint' => 'access_token'
+ ));
+
+ $server->handleRevokeRequest($request, $response = new Response());
+ $this->assertTrue($response instanceof Response);
+ $this->assertEquals(400, $response->getStatusCode(), var_export($response, 1));
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Missing token parameter to revoke');
+ }
+
+ public function testInvalidRequestMethodForRevoke()
+ {
+ $server = $this->getTestServer();
+
+ $request = new TestRequest();
+ $request->setQuery(array(
+ 'token_type_hint' => 'access_token'
+ ));
+
+ $server->handleRevokeRequest($request, $response = new Response());
+ $this->assertTrue($response instanceof Response);
+ $this->assertEquals(405, $response->getStatusCode(), var_export($response, 1));
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'The request method must be POST when revoking an access token');
+ }
+
+ public function testCreateController()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $accessToken = new \OAuth2\ResponseType\AccessToken($storage);
+ $controller = new TokenController($accessToken, $storage);
+ }
+
+ private function getTestServer()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/FirebaseJwtTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/FirebaseJwtTest.php
new file mode 100644
index 000000000..d34136767
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/FirebaseJwtTest.php
@@ -0,0 +1,102 @@
+privateKey = << $client_id,
+ 'exp' => time() + 1000,
+ 'iat' => time(),
+ 'sub' => 'testuser@ourdomain.com',
+ 'aud' => 'http://myapp.com/oauth/auth',
+ 'scope' => null,
+ );
+
+ $encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256');
+
+ // test BC behaviour of trusting the algorithm in the header
+ $payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
+ $this->assertEquals($params, $payload);
+
+ // test BC behaviour of not verifying by passing false
+ $payload = $jwtUtil->decode($encoded, $client_key, false);
+ $this->assertEquals($params, $payload);
+
+ // test the new restricted algorithms header
+ $payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
+ $this->assertEquals($params, $payload);
+ }
+
+ public function testInvalidJwt()
+ {
+ $jwtUtil = new FirebaseJwt();
+
+ $this->assertFalse($jwtUtil->decode('goob'));
+ $this->assertFalse($jwtUtil->decode('go.o.b'));
+ }
+
+ /** @dataProvider provideClientCredentials */
+ public function testInvalidJwtHeader($client_id, $client_key)
+ {
+ $jwtUtil = new FirebaseJwt();
+
+ $params = array(
+ 'iss' => $client_id,
+ 'exp' => time() + 1000,
+ 'iat' => time(),
+ 'sub' => 'testuser@ourdomain.com',
+ 'aud' => 'http://myapp.com/oauth/auth',
+ 'scope' => null,
+ );
+
+ // testing for algorithm tampering when only RSA256 signing is allowed
+ // @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
+ $tampered = $jwtUtil->encode($params, $client_key, 'HS256');
+
+ $payload = $jwtUtil->decode($tampered, $client_key, array('RS256'));
+
+ $this->assertFalse($payload);
+ }
+
+ public function provideClientCredentials()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $client_id = 'Test Client ID';
+ $client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com");
+
+ return array(
+ array($client_id, $client_key),
+ );
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/JwtTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/JwtTest.php
new file mode 100644
index 000000000..214eebac8
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Encryption/JwtTest.php
@@ -0,0 +1,102 @@
+privateKey = << $client_id,
+ 'exp' => time() + 1000,
+ 'iat' => time(),
+ 'sub' => 'testuser@ourdomain.com',
+ 'aud' => 'http://myapp.com/oauth/auth',
+ 'scope' => null,
+ );
+
+ $encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256');
+
+ // test BC behaviour of trusting the algorithm in the header
+ $payload = $jwtUtil->decode($encoded, $client_key);
+ $this->assertEquals($params, $payload);
+
+ // test BC behaviour of not verifying by passing false
+ $payload = $jwtUtil->decode($encoded, $client_key, false);
+ $this->assertEquals($params, $payload);
+
+ // test the new restricted algorithms header
+ $payload = $jwtUtil->decode($encoded, $client_key, array('RS256'));
+ $this->assertEquals($params, $payload);
+ }
+
+ public function testInvalidJwt()
+ {
+ $jwtUtil = new Jwt();
+
+ $this->assertFalse($jwtUtil->decode('goob'));
+ $this->assertFalse($jwtUtil->decode('go.o.b'));
+ }
+
+ /** @dataProvider provideClientCredentials */
+ public function testInvalidJwtHeader($client_id, $client_key)
+ {
+ $jwtUtil = new Jwt();
+
+ $params = array(
+ 'iss' => $client_id,
+ 'exp' => time() + 1000,
+ 'iat' => time(),
+ 'sub' => 'testuser@ourdomain.com',
+ 'aud' => 'http://myapp.com/oauth/auth',
+ 'scope' => null,
+ );
+
+ // testing for algorithm tampering when only RSA256 signing is allowed
+ // @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
+ $tampered = $jwtUtil->encode($params, $client_key, 'HS256');
+
+ $payload = $jwtUtil->decode($tampered, $client_key, array('RS256'));
+
+ $this->assertFalse($payload);
+ }
+
+ public function provideClientCredentials()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $client_id = 'Test Client ID';
+ $client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com");
+
+ return array(
+ array($client_id, $client_key),
+ );
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/AuthorizationCodeTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/AuthorizationCodeTest.php
new file mode 100644
index 000000000..356b8e53c
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/AuthorizationCodeTest.php
@@ -0,0 +1,223 @@
+getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Missing parameter: "code" is required');
+ }
+
+ public function testInvalidCode()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'InvalidCode', // invalid authorization code
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
+ }
+
+ public function testCodeCannotBeUsedTwice()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode', // valid code
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 200);
+ $this->assertNotNull($response->getParameter('access_token'));
+
+ // try to use the same code again
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
+ }
+
+ public function testExpiredCode()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-expired', // expired authorization code
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'The authorization code has expired');
+ }
+
+ public function testValidCode()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode', // valid code
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ }
+
+ public function testValidRedirectUri()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://brentertainment.com/voil%C3%A0', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-redirect-uri', // valid code
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ }
+
+ public function testValidCodeNoScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-with-scope', // valid code
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope1 scope2');
+ }
+
+ public function testValidCodeSameScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-with-scope', // valid code
+ 'scope' => 'scope2 scope1',
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope2 scope1');
+ }
+
+ public function testValidCodeLessScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-with-scope', // valid code
+ 'scope' => 'scope1',
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope1');
+ }
+
+ public function testValidCodeDifferentScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-with-scope', // valid code
+ 'scope' => 'scope3',
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
+ }
+
+ public function testValidCodeInvalidScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-with-scope', // valid code
+ 'scope' => 'invalid-scope',
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
+ }
+
+ public function testValidClientDifferentCode()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Some Other Client', // valid client id
+ 'client_secret' => 'TestSecret3', // valid client secret
+ 'code' => 'testcode', // valid code
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'authorization_code doesn\'t exist or is invalid for the client');
+ }
+
+ private function getTestServer()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ClientCredentialsTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ClientCredentialsTest.php
new file mode 100644
index 000000000..f0d46ccb3
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ClientCredentialsTest.php
@@ -0,0 +1,159 @@
+getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'FakeSecret', // valid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
+ }
+
+ public function testValidCredentials()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertNull($token['scope']);
+ }
+
+ public function testValidCredentialsWithScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'scope' => 'scope1',
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope1');
+ }
+
+ public function testValidCredentialsInvalidScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'scope' => 'invalid-scope',
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
+ }
+
+ public function testValidCredentialsInHeader()
+ {
+ // create with HTTP_AUTHORIZATION in header
+ $server = $this->getTestServer();
+ $headers = array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('Test Client ID:TestSecret'), 'REQUEST_METHOD' => 'POST');
+ $params = array('grant_type' => 'client_credentials');
+ $request = new Request(array(), $params, array(), array(), array(), $headers);
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertNotNull($token['access_token']);
+
+ // create using PHP Authorization Globals
+ $headers = array('PHP_AUTH_USER' => 'Test Client ID', 'PHP_AUTH_PW' => 'TestSecret', 'REQUEST_METHOD' => 'POST');
+ $params = array('grant_type' => 'client_credentials');
+ $request = new Request(array(), $params, array(), array(), array(), $headers);
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertNotNull($token['access_token']);
+ }
+
+ public function testValidCredentialsInRequest()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertNotNull($token['access_token']);
+ }
+
+ public function testValidCredentialsInQuerystring()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertNotNull($token['access_token']);
+ }
+
+ public function testClientUserIdIsSetInAccessToken()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Client ID With User ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+
+ // verify the user_id was associated with the token
+ $storage = $server->getStorage('client');
+ $token = $storage->getAccessToken($token['access_token']);
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('user_id', $token);
+ $this->assertEquals($token['user_id'], 'brent@brentertainment.com');
+ }
+
+ private function getTestServer()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new ClientCredentials($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ImplicitTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ImplicitTest.php
new file mode 100644
index 000000000..a47aae3e8
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/ImplicitTest.php
@@ -0,0 +1,143 @@
+getTestServer();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'token', // invalid response type
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'unsupported_response_type');
+ $this->assertEquals($query['error_description'], 'implicit grant type not supported');
+ }
+
+ public function testUserDeniesAccessResponse()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'token', // valid response type
+ 'state' => 'xyz',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), false);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ parse_str($parts['query'], $query);
+
+ $this->assertEquals($query['error'], 'access_denied');
+ $this->assertEquals($query['error_description'], 'The user denied access to your application');
+ }
+
+ public function testSuccessfulRequestFragmentParameter()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'token', // valid response type
+ 'state' => 'xyz',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+
+ $this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
+ $this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
+ $this->assertArrayHasKey('fragment', $parts);
+ $this->assertFalse(isset($parts['query']));
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['fragment'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('access_token', $params);
+ $this->assertArrayHasKey('expires_in', $params);
+ $this->assertArrayHasKey('token_type', $params);
+ }
+
+ public function testSuccessfulRequestReturnsStateParameter()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'token', // valid response type
+ 'state' => 'test', // valid state string (just needs to be passed back to us)
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('fragment', $parts);
+ parse_str($parts['fragment'], $params);
+
+ $this->assertArrayHasKey('state', $params);
+ $this->assertEquals($params['state'], 'test');
+ }
+
+ public function testSuccessfulRequestStripsExtraParameters()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com?fake=something', // valid redirect URI
+ 'response_type' => 'token', // valid response type
+ 'state' => 'test', // valid state string (just needs to be passed back to us)
+ 'fake' => 'something', // add extra param to querystring
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNull($response->getParameter('error_description'));
+
+ $location = $response->getHttpHeader('Location');
+ $parts = parse_url($location);
+ $this->assertFalse(isset($parts['fake']));
+ $this->assertArrayHasKey('fragment', $parts);
+ parse_str($parts['fragment'], $params);
+
+ $this->assertFalse(isset($params['fake']));
+ $this->assertArrayHasKey('state', $params);
+ $this->assertEquals($params['state'], 'test');
+ }
+
+ private function getTestServer($config = array())
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ // Add the two types supported for authorization grant
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/JwtBearerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/JwtBearerTest.php
new file mode 100644
index 000000000..0a6c4b827
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/JwtBearerTest.php
@@ -0,0 +1,360 @@
+privateKey = <<getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Get the jwt and break it
+ $jwt = $this->getJWT();
+ $jwt = substr_replace($jwt, 'broken', 3, 6);
+
+ $request->request['assertion'] = $jwt;
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'JWT is malformed');
+ }
+
+ public function testBrokenSignature()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Get the jwt and break signature
+ $jwt = $this->getJWT() . 'notSupposeToBeHere';
+ $request->request['assertion'] = $jwt;
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'JWT failed signature verification');
+ }
+
+ public function testExpiredJWT()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Get an expired JWT
+ $jwt = $this->getJWT(1234);
+ $request->request['assertion'] = $jwt;
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'JWT has expired');
+ }
+
+ public function testBadExp()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Get an expired JWT
+ $jwt = $this->getJWT('badtimestamp');
+ $request->request['assertion'] = $jwt;
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Expiration (exp) time must be a unix time stamp');
+ }
+
+ public function testNoAssert()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Do not pass the assert (JWT)
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "assertion" required');
+ }
+
+ public function testNotBefore()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Get a future NBF
+ $jwt = $this->getJWT(null, time() + 10000);
+ $request->request['assertion'] = $jwt;
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'JWT cannot be used before the Not Before (nbf) time');
+ }
+
+ public function testBadNotBefore()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ ));
+
+ //Get a non timestamp nbf
+ $jwt = $this->getJWT(null, 'notatimestamp');
+ $request->request['assertion'] = $jwt;
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Not Before (nbf) time must be a unix time stamp');
+ }
+
+ public function testNonMatchingAudience()
+ {
+ $server = $this->getTestServer('http://google.com/oauth/o/auth');
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(),
+ ));
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid audience (aud)');
+ }
+
+ public function testBadClientID()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(null, null, null, 'bad_client_id'),
+ ));
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
+ }
+
+ public function testBadSubject()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(null, null, 'anotheruser@ourdomain,com'),
+ ));
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
+ }
+
+ public function testMissingKey()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(null, null, null, 'Missing Key Cli,nt'),
+ ));
+
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
+ }
+
+ public function testValidJwt()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(), // valid assertion
+ ));
+
+ $token = $server->grantAccessToken($request, new Response());
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ }
+
+ public function testValidJwtWithScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(null, null, null, 'Test Client ID'), // valid assertion
+ 'scope' => 'scope1', // valid scope
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope1');
+ }
+
+ public function testValidJwtInvalidScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(null, null, null, 'Test Client ID'), // valid assertion
+ 'scope' => 'invalid-scope', // invalid scope
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
+ }
+
+ public function testValidJti()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(null, null, 'testuser@ourdomain.com', 'Test Client ID', 'unused_jti'), // valid assertion with invalid scope
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ }
+
+ public function testInvalidJti()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(99999999900, null, 'testuser@ourdomain.com', 'Test Client ID', 'used_jti'), // valid assertion with invalid scope
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'JSON Token Identifier (jti) has already been used');
+ }
+
+ public function testJtiReplayAttack()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', // valid grant type
+ 'assertion' => $this->getJWT(99999999900, null, 'testuser@ourdomain.com', 'Test Client ID', 'totally_new_jti'), // valid assertion with invalid scope
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+
+ //Replay the same request
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'JSON Token Identifier (jti) has already been used');
+ }
+
+ /**
+ * Generates a JWT
+ * @param $exp The expiration date. If the current time is greater than the exp, the JWT is invalid.
+ * @param $nbf The "not before" time. If the current time is less than the nbf, the JWT is invalid.
+ * @param $sub The subject we are acting on behalf of. This could be the email address of the user in the system.
+ * @param $iss The issuer, usually the client_id.
+ * @return string
+ */
+ private function getJWT($exp = null, $nbf = null, $sub = null, $iss = 'Test Client ID', $jti = null)
+ {
+ if (!$exp) {
+ $exp = time() + 1000;
+ }
+
+ if (!$sub) {
+ $sub = "testuser@ourdomain.com";
+ }
+
+ $params = array(
+ 'iss' => $iss,
+ 'exp' => $exp,
+ 'iat' => time(),
+ 'sub' => $sub,
+ 'aud' => 'http://myapp.com/oauth/auth',
+ );
+
+ if ($nbf) {
+ $params['nbf'] = $nbf;
+ }
+
+ if ($jti) {
+ $params['jti'] = $jti;
+ }
+
+ $jwtUtil = new Jwt();
+
+ return $jwtUtil->encode($params, $this->privateKey, 'RS256');
+ }
+
+ private function getTestServer($audience = 'http://myapp.com/oauth/auth')
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new JwtBearer($storage, $audience, new Jwt()));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/RefreshTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/RefreshTokenTest.php
new file mode 100644
index 000000000..a458aad8a
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/RefreshTokenTest.php
@@ -0,0 +1,204 @@
+getTestServer();
+ $server->addGrantType(new RefreshToken($this->storage));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Missing parameter: "refresh_token" is required');
+ }
+
+ public function testInvalidRefreshToken()
+ {
+ $server = $this->getTestServer();
+ $server->addGrantType(new RefreshToken($this->storage));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'fake-token', // invalid refresh token
+ ));
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid refresh token');
+ }
+
+ public function testValidRefreshTokenWithNewRefreshTokenInResponse()
+ {
+ $server = $this->getTestServer();
+ $server->addGrantType(new RefreshToken($this->storage, array('always_issue_new_refresh_token' => true)));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken', // valid refresh token
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+ $this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
+
+ $refresh_token = $this->storage->getRefreshToken($token['refresh_token']);
+ $this->assertNotNull($refresh_token);
+ $this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
+ $this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
+ $this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
+ $used_token = $this->storage->getRefreshToken('test-refreshtoken');
+ $this->assertFalse($used_token, 'the refresh token used is no longer valid');
+ }
+
+ public function testValidRefreshTokenDoesNotUnsetToken()
+ {
+ $server = $this->getTestServer();
+ $server->addGrantType(new RefreshToken($this->storage, array(
+ 'always_issue_new_refresh_token' => true,
+ 'unset_refresh_token_after_use' => false,
+ )));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken', // valid refresh token
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+ $this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
+
+ $used_token = $this->storage->getRefreshToken('test-refreshtoken');
+ $this->assertNotNull($used_token, 'the refresh token used is still valid');
+ }
+
+ public function testValidRefreshTokenWithNoRefreshTokenInResponse()
+ {
+ $server = $this->getTestServer();
+ $server->addGrantType(new RefreshToken($this->storage, array('always_issue_new_refresh_token' => false)));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken', // valid refresh token
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+ $this->assertFalse(isset($token['refresh_token']), 'refresh token should not be returned');
+
+ $used_token = $this->storage->getRefreshToken('test-refreshtoken');
+ $this->assertNotNull($used_token, 'the refresh token used is still valid');
+ }
+
+ public function testValidRefreshTokenSameScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
+ 'scope' => 'scope2 scope1',
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope2 scope1');
+ }
+
+ public function testValidRefreshTokenLessScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
+ 'scope' => 'scope1',
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope1');
+ }
+
+ public function testValidRefreshTokenDifferentScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
+ 'scope' => 'scope3',
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
+ }
+
+ public function testValidRefreshTokenInvalidScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken-with-scope', // valid refresh token (with scope)
+ 'scope' => 'invalid-scope',
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'The scope requested is invalid for this request');
+ }
+
+ public function testValidClientDifferentRefreshToken()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Some Other Client', // valid client id
+ 'client_secret' => 'TestSecret3', // valid client secret
+ 'refresh_token' => 'test-refreshtoken', // valid refresh token
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'refresh_token doesn\'t exist or is invalid for the client');
+ }
+
+ private function getTestServer()
+ {
+ $this->storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($this->storage);
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/UserCredentialsTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/UserCredentialsTest.php
new file mode 100644
index 000000000..18943d055
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/GrantType/UserCredentialsTest.php
@@ -0,0 +1,172 @@
+getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'password' => 'testpass', // valid password
+ ));
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "username" and "password" required');
+ }
+
+ public function testNoPassword()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'test-username', // valid username
+ ));
+ $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'Missing parameters: "username" and "password" required');
+ }
+
+ public function testInvalidUsername()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'fake-username', // valid username
+ 'password' => 'testpass', // valid password
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 401);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid username and password combination');
+ }
+
+ public function testInvalidPassword()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'test-username', // valid username
+ 'password' => 'fakepass', // invalid password
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 401);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid username and password combination');
+ }
+
+ public function testValidCredentials()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'test-username', // valid username
+ 'password' => 'testpass', // valid password
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ }
+
+ public function testValidCredentialsWithScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'test-username', // valid username
+ 'password' => 'testpass', // valid password
+ 'scope' => 'scope1', // valid scope
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('scope', $token);
+ $this->assertEquals($token['scope'], 'scope1');
+ }
+
+ public function testValidCredentialsInvalidScope()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'test-username', // valid username
+ 'password' => 'testpass', // valid password
+ 'scope' => 'invalid-scope',
+ ));
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_scope');
+ $this->assertEquals($response->getParameter('error_description'), 'An unsupported scope was requested');
+ }
+
+ public function testNoSecretWithPublicClient()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID Empty Secret', // valid public client
+ 'username' => 'test-username', // valid username
+ 'password' => 'testpass', // valid password
+ ));
+
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ }
+
+ public function testNoSecretWithConfidentialClient()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid public client
+ 'username' => 'test-username', // valid username
+ 'password' => 'testpass', // valid password
+ ));
+
+ $token = $server->grantAccessToken($request, $response = new Response());
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_client');
+ $this->assertEquals($response->getParameter('error_description'), 'This client is invalid or must authenticate using a client secret');
+ }
+
+ private function getTestServer()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage);
+ $server->addGrantType(new UserCredentials($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
new file mode 100644
index 000000000..46de936d8
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/AuthorizeControllerTest.php
@@ -0,0 +1,182 @@
+getTestServer();
+
+ $response = new Response();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'id_token',
+ 'state' => 'af0ifjsldkj',
+ 'nonce' => 'n-0S6_WzA2Mj',
+ ));
+
+ // Test valid id_token request
+ $server->handleAuthorizeRequest($request, $response, true);
+
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['fragment'], $query);
+
+ $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
+ $this->assertEquals($query['state'], 'af0ifjsldkj');
+
+ $this->assertArrayHasKey('id_token', $query);
+ $this->assertArrayHasKey('state', $query);
+ $this->assertArrayNotHasKey('access_token', $query);
+ $this->assertArrayNotHasKey('expires_in', $query);
+ $this->assertArrayNotHasKey('token_type', $query);
+
+ // Test valid token id_token request
+ $request->query['response_type'] = 'id_token token';
+ $server->handleAuthorizeRequest($request, $response, true);
+
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['fragment'], $query);
+
+ $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
+ $this->assertEquals($query['state'], 'af0ifjsldkj');
+
+ $this->assertArrayHasKey('access_token', $query);
+ $this->assertArrayHasKey('expires_in', $query);
+ $this->assertArrayHasKey('token_type', $query);
+ $this->assertArrayHasKey('state', $query);
+ $this->assertArrayHasKey('id_token', $query);
+
+ // assert that with multiple-valued response types, order does not matter
+ $request->query['response_type'] = 'token id_token';
+ $server->handleAuthorizeRequest($request, $response, true);
+
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['fragment'], $query);
+
+ $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
+ $this->assertEquals($query['state'], 'af0ifjsldkj');
+
+ $this->assertArrayHasKey('access_token', $query);
+ $this->assertArrayHasKey('expires_in', $query);
+ $this->assertArrayHasKey('token_type', $query);
+ $this->assertArrayHasKey('state', $query);
+ $this->assertArrayHasKey('id_token', $query);
+
+ // assert that with multiple-valued response types with extra spaces do not matter
+ $request->query['response_type'] = ' token id_token ';
+ $server->handleAuthorizeRequest($request, $response, true);
+
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['fragment'], $query);
+
+ $this->assertEquals('n-0S6_WzA2Mj', $server->getAuthorizeController()->getNonce());
+ $this->assertEquals($query['state'], 'af0ifjsldkj');
+
+ $this->assertArrayHasKey('access_token', $query);
+ $this->assertArrayHasKey('expires_in', $query);
+ $this->assertArrayHasKey('token_type', $query);
+ $this->assertArrayHasKey('state', $query);
+ $this->assertArrayHasKey('id_token', $query);
+ }
+
+ public function testMissingNonce()
+ {
+ $server = $this->getTestServer();
+ $authorize = $server->getAuthorizeController();
+
+ $response = new Response();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'id_token',
+ 'state' => 'xyz',
+ ));
+
+ // Test missing nonce for 'id_token' response type
+ $server->handleAuthorizeRequest($request, $response, true);
+ $params = $response->getParameters();
+
+ $this->assertEquals($params['error'], 'invalid_nonce');
+ $this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
+
+ // Test missing nonce for 'id_token token' response type
+ $request->query['response_type'] = 'id_token token';
+ $server->handleAuthorizeRequest($request, $response, true);
+ $params = $response->getParameters();
+
+ $this->assertEquals($params['error'], 'invalid_nonce');
+ $this->assertEquals($params['error_description'], 'This application requires you specify a nonce parameter');
+ }
+
+ public function testNotGrantedApplication()
+ {
+ $server = $this->getTestServer();
+
+ $response = new Response();
+ $request = new Request(array(
+ 'client_id' => 'Test Client ID', // valid client id
+ 'redirect_uri' => 'http://adobe.com', // valid redirect URI
+ 'response_type' => 'id_token',
+ 'state' => 'af0ifjsldkj',
+ 'nonce' => 'n-0S6_WzA2Mj',
+ ));
+
+ // Test not approved application
+ $server->handleAuthorizeRequest($request, $response, false);
+
+ $params = $response->getParameters();
+
+ $this->assertEquals($params['error'], 'consent_required');
+ $this->assertEquals($params['error_description'], 'The user denied access to your application');
+
+ // Test not approved application with prompt parameter
+ $request->query['prompt'] = 'none';
+ $server->handleAuthorizeRequest($request, $response, false);
+
+ $params = $response->getParameters();
+
+ $this->assertEquals($params['error'], 'login_required');
+ $this->assertEquals($params['error_description'], 'The user must log in');
+
+ // Test not approved application with user_id set
+ $request->query['prompt'] = 'none';
+ $server->handleAuthorizeRequest($request, $response, false, 'some-user-id');
+
+ $params = $response->getParameters();
+
+ $this->assertEquals($params['error'], 'interaction_required');
+ $this->assertEquals($params['error_description'], 'The user must grant access to your application');
+ }
+
+ public function testNeedsIdToken()
+ {
+ $server = $this->getTestServer();
+ $authorize = $server->getAuthorizeController();
+
+ $this->assertTrue($authorize->needsIdToken('openid'));
+ $this->assertTrue($authorize->needsIdToken('openid profile'));
+ $this->assertFalse($authorize->needsIdToken(''));
+ $this->assertFalse($authorize->needsIdToken('some-scope'));
+ }
+
+ private function getTestServer($config = array())
+ {
+ $config += array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'phpunit',
+ 'allow_implicit' => true
+ );
+
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
new file mode 100644
index 000000000..b1b687077
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Controller/UserInfoControllerTest.php
@@ -0,0 +1,44 @@
+handleUserInfoRequest(new Request(), $response);
+ $this->assertEquals(401, $response->getStatusCode());
+ }
+
+ public function testValidToken()
+ {
+ $server = $this->getTestServer();
+ $request = Request::createFromGlobals();
+ $request->headers['AUTHORIZATION'] = 'Bearer accesstoken-openid-connect';
+ $response = new Response();
+
+ $server->handleUserInfoRequest($request, $response);
+ $parameters = $response->getParameters();
+ $this->assertEquals($parameters['sub'], 'testuser');
+ $this->assertEquals($parameters['email'], 'testuser@test.com');
+ $this->assertEquals($parameters['email_verified'], true);
+ }
+
+ private function getTestServer($config = array())
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php
new file mode 100644
index 000000000..776002d1e
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/GrantType/AuthorizationCodeTest.php
@@ -0,0 +1,57 @@
+getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-openid', // valid code
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('id_token', $token);
+ $this->assertEquals('test_id_token', $token['id_token']);
+
+ // this is only true if "offline_access" was requested
+ $this->assertFalse(isset($token['refresh_token']));
+ }
+
+ public function testOfflineAccess()
+ {
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'code' => 'testcode-openid', // valid code
+ 'scope' => 'offline_access', // valid code
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('id_token', $token);
+ $this->assertEquals('test_id_token', $token['id_token']);
+ $this->assertTrue(isset($token['refresh_token']));
+ }
+
+ private function getTestServer()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, array('use_openid_connect' => true));
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php
new file mode 100644
index 000000000..b0311434a
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/CodeIdTokenTest.php
@@ -0,0 +1,182 @@
+getTestServer();
+
+ $request = new Request(array(
+ 'response_type' => 'code id_token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid',
+ 'state' => 'test',
+ 'nonce' => 'test',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('query', $parts);
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['query'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('id_token', $params);
+ $this->assertArrayHasKey('code', $params);
+
+ // validate ID Token
+ $parts = explode('.', $params['id_token']);
+ foreach ($parts as &$part) {
+ // Each part is a base64url encoded json string.
+ $part = str_replace(array('-', '_'), array('+', '/'), $part);
+ $part = base64_decode($part);
+ $part = json_decode($part, true);
+ }
+ list($header, $claims, $signature) = $parts;
+
+ $this->assertArrayHasKey('iss', $claims);
+ $this->assertArrayHasKey('sub', $claims);
+ $this->assertArrayHasKey('aud', $claims);
+ $this->assertArrayHasKey('iat', $claims);
+ $this->assertArrayHasKey('exp', $claims);
+ $this->assertArrayHasKey('auth_time', $claims);
+ $this->assertArrayHasKey('nonce', $claims);
+
+ // only exists if an access token was granted along with the id_token
+ $this->assertArrayNotHasKey('at_hash', $claims);
+
+ $this->assertEquals($claims['iss'], 'test');
+ $this->assertEquals($claims['aud'], 'Test Client ID');
+ $this->assertEquals($claims['nonce'], 'test');
+ $duration = $claims['exp'] - $claims['iat'];
+ $this->assertEquals($duration, 3600);
+ }
+
+ public function testUserClaimsWithUserId()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+
+ $request = new Request(array(
+ 'response_type' => 'code id_token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid email',
+ 'state' => 'test',
+ 'nonce' => 'test',
+ ));
+
+ $userId = 'testuser';
+ $server->handleAuthorizeRequest($request, $response = new Response(), true, $userId);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('query', $parts);
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['query'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('id_token', $params);
+ $this->assertArrayHasKey('code', $params);
+
+ // validate ID Token
+ $parts = explode('.', $params['id_token']);
+ foreach ($parts as &$part) {
+ // Each part is a base64url encoded json string.
+ $part = str_replace(array('-', '_'), array('+', '/'), $part);
+ $part = base64_decode($part);
+ $part = json_decode($part, true);
+ }
+ list($header, $claims, $signature) = $parts;
+
+ $this->assertArrayHasKey('email', $claims);
+ $this->assertArrayHasKey('email_verified', $claims);
+ $this->assertNotNull($claims['email']);
+ $this->assertNotNull($claims['email_verified']);
+ }
+
+ public function testUserClaimsWithoutUserId()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+
+ $request = new Request(array(
+ 'response_type' => 'code id_token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid email',
+ 'state' => 'test',
+ 'nonce' => 'test',
+ ));
+
+ $userId = null;
+ $server->handleAuthorizeRequest($request, $response = new Response(), true, $userId);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('query', $parts);
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['query'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('id_token', $params);
+ $this->assertArrayHasKey('code', $params);
+
+ // validate ID Token
+ $parts = explode('.', $params['id_token']);
+ foreach ($parts as &$part) {
+ // Each part is a base64url encoded json string.
+ $part = str_replace(array('-', '_'), array('+', '/'), $part);
+ $part = base64_decode($part);
+ $part = json_decode($part, true);
+ }
+ list($header, $claims, $signature) = $parts;
+
+ $this->assertArrayNotHasKey('email', $claims);
+ $this->assertArrayNotHasKey('email_verified', $claims);
+ }
+
+ private function getTestServer($config = array())
+ {
+ $config += array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'test',
+ 'id_lifetime' => 3600,
+ 'allow_implicit' => true,
+ );
+
+ $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
+ $memoryStorage->supportedScopes[] = 'email';
+ $responseTypes = array(
+ 'code' => $code = new AuthorizationCode($memoryStorage),
+ 'id_token' => $idToken = new IdToken($memoryStorage, $memoryStorage, $config),
+ 'code id_token' => new CodeIdToken($code, $idToken),
+ );
+
+ $server = new Server($memoryStorage, $config, array(), $responseTypes);
+ $server->addGrantType(new ClientCredentials($memoryStorage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTest.php
new file mode 100644
index 000000000..e772f6be4
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTest.php
@@ -0,0 +1,184 @@
+ 'id_token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid',
+ 'state' => 'test',
+ );
+
+ // attempt to do the request without a nonce.
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request($query);
+ $valid = $server->validateAuthorizeRequest($request, $response = new Response());
+
+ // Add a nonce and retry.
+ $query['nonce'] = 'test';
+ $request = new Request($query);
+ $valid = $server->validateAuthorizeRequest($request, $response = new Response());
+ $this->assertTrue($valid);
+ }
+
+ public function testHandleAuthorizeRequest()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'response_type' => 'id_token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid email',
+ 'state' => 'test',
+ 'nonce' => 'test',
+ ));
+
+ $user_id = 'testuser';
+ $server->handleAuthorizeRequest($request, $response = new Response(), true, $user_id);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('fragment', $parts);
+ $this->assertFalse(isset($parts['query']));
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['fragment'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('id_token', $params);
+ $this->assertArrayNotHasKey('access_token', $params);
+ $this->validateIdToken($params['id_token']);
+ }
+
+ public function testPassInAuthTime()
+ {
+ $server = $this->getTestServer(array('allow_implicit' => true));
+ $request = new Request(array(
+ 'response_type' => 'id_token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid email',
+ 'state' => 'test',
+ 'nonce' => 'test',
+ ));
+
+ // test with a scalar user id
+ $user_id = 'testuser123';
+ $server->handleAuthorizeRequest($request, $response = new Response(), true, $user_id);
+
+ list($header, $payload, $signature) = $this->extractTokenDataFromResponse($response);
+
+ $this->assertTrue(is_array($payload));
+ $this->assertArrayHasKey('sub', $payload);
+ $this->assertEquals($user_id, $payload['sub']);
+ $this->assertArrayHasKey('auth_time', $payload);
+
+ // test with an array of user info
+ $userInfo = array(
+ 'user_id' => 'testuser1234',
+ 'auth_time' => date('Y-m-d H:i:s', strtotime('20 minutes ago')
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true, $userInfo);
+
+ list($header, $payload, $signature) = $this->extractTokenDataFromResponse($response);
+
+ $this->assertTrue(is_array($payload));
+ $this->assertArrayHasKey('sub', $payload);
+ $this->assertEquals($userInfo['user_id'], $payload['sub']);
+ $this->assertArrayHasKey('auth_time', $payload);
+ $this->assertEquals($userInfo['auth_time'], $payload['auth_time']);
+ }
+
+ private function extractTokenDataFromResponse(Response $response)
+ {
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('fragment', $parts);
+ $this->assertFalse(isset($parts['query']));
+
+ parse_str($parts['fragment'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('id_token', $params);
+ $this->assertArrayNotHasKey('access_token', $params);
+
+ list($headb64, $payloadb64, $signature) = explode('.', $params['id_token']);
+
+ $jwt = new Jwt();
+ $header = json_decode($jwt->urlSafeB64Decode($headb64), true);
+ $payload = json_decode($jwt->urlSafeB64Decode($payloadb64), true);
+
+ return array($header, $payload, $signature);
+ }
+
+ private function validateIdToken($id_token)
+ {
+ $parts = explode('.', $id_token);
+ foreach ($parts as &$part) {
+ // Each part is a base64url encoded json string.
+ $part = str_replace(array('-', '_'), array('+', '/'), $part);
+ $part = base64_decode($part);
+ $part = json_decode($part, true);
+ }
+ list($header, $claims, $signature) = $parts;
+
+ $this->assertArrayHasKey('iss', $claims);
+ $this->assertArrayHasKey('sub', $claims);
+ $this->assertArrayHasKey('aud', $claims);
+ $this->assertArrayHasKey('iat', $claims);
+ $this->assertArrayHasKey('exp', $claims);
+ $this->assertArrayHasKey('auth_time', $claims);
+ $this->assertArrayHasKey('nonce', $claims);
+ $this->assertArrayHasKey('email', $claims);
+ $this->assertArrayHasKey('email_verified', $claims);
+
+ $this->assertEquals($claims['iss'], 'test');
+ $this->assertEquals($claims['aud'], 'Test Client ID');
+ $this->assertEquals($claims['nonce'], 'test');
+ $this->assertEquals($claims['email'], 'testuser@test.com');
+ $duration = $claims['exp'] - $claims['iat'];
+ $this->assertEquals($duration, 3600);
+ }
+
+ private function getTestServer($config = array())
+ {
+ $config += array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'test',
+ 'id_lifetime' => 3600,
+ );
+
+ $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
+ $memoryStorage->supportedScopes[] = 'email';
+ $storage = array(
+ 'client' => $memoryStorage,
+ 'scope' => $memoryStorage,
+ );
+ $responseTypes = array(
+ 'id_token' => new IdToken($memoryStorage, $memoryStorage, $config),
+ );
+
+ $server = new Server($storage, $config, array(), $responseTypes);
+ $server->addGrantType(new ClientCredentials($memoryStorage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php
new file mode 100644
index 000000000..bc564d37b
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/ResponseType/IdTokenTokenTest.php
@@ -0,0 +1,91 @@
+getTestServer(array('allow_implicit' => true));
+
+ $request = new Request(array(
+ 'response_type' => 'id_token token',
+ 'redirect_uri' => 'http://adobe.com',
+ 'client_id' => 'Test Client ID',
+ 'scope' => 'openid',
+ 'state' => 'test',
+ 'nonce' => 'test',
+ ));
+
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ $this->assertEquals($response->getStatusCode(), 302);
+ $location = $response->getHttpHeader('Location');
+ $this->assertNotContains('error', $location);
+
+ $parts = parse_url($location);
+ $this->assertArrayHasKey('fragment', $parts);
+ $this->assertFalse(isset($parts['query']));
+
+ // assert fragment is in "application/x-www-form-urlencoded" format
+ parse_str($parts['fragment'], $params);
+ $this->assertNotNull($params);
+ $this->assertArrayHasKey('id_token', $params);
+ $this->assertArrayHasKey('access_token', $params);
+
+ // validate ID Token
+ $parts = explode('.', $params['id_token']);
+ foreach ($parts as &$part) {
+ // Each part is a base64url encoded json string.
+ $part = str_replace(array('-', '_'), array('+', '/'), $part);
+ $part = base64_decode($part);
+ $part = json_decode($part, true);
+ }
+ list($header, $claims, $signature) = $parts;
+
+ $this->assertArrayHasKey('iss', $claims);
+ $this->assertArrayHasKey('sub', $claims);
+ $this->assertArrayHasKey('aud', $claims);
+ $this->assertArrayHasKey('iat', $claims);
+ $this->assertArrayHasKey('exp', $claims);
+ $this->assertArrayHasKey('auth_time', $claims);
+ $this->assertArrayHasKey('nonce', $claims);
+ $this->assertArrayHasKey('at_hash', $claims);
+
+ $this->assertEquals($claims['iss'], 'test');
+ $this->assertEquals($claims['aud'], 'Test Client ID');
+ $this->assertEquals($claims['nonce'], 'test');
+ $duration = $claims['exp'] - $claims['iat'];
+ $this->assertEquals($duration, 3600);
+ }
+
+ private function getTestServer($config = array())
+ {
+ $config += array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'test',
+ 'id_lifetime' => 3600,
+ );
+
+ $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
+ $responseTypes = array(
+ 'token' => $token = new AccessToken($memoryStorage, $memoryStorage),
+ 'id_token' => $idToken = new IdToken($memoryStorage, $memoryStorage, $config),
+ 'id_token token' => new IdTokenToken($token, $idToken),
+ );
+
+ $server = new Server($memoryStorage, $config, array(), $responseTypes);
+ $server->addGrantType(new ClientCredentials($memoryStorage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php
new file mode 100644
index 000000000..bdfb085e3
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/AuthorizationCodeTest.php
@@ -0,0 +1,95 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ if (!$storage instanceof AuthorizationCodeInterface) {
+ return;
+ }
+
+ // assert code we are about to add does not exist
+ $code = $storage->getAuthorizationCode('new-openid-code');
+ $this->assertFalse($code);
+
+ // add new code
+ $expires = time() + 20;
+ $scope = null;
+ $id_token = 'fake_id_token';
+ $success = $storage->setAuthorizationCode('new-openid-code', 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, $id_token);
+ $this->assertTrue($success);
+
+ $code = $storage->getAuthorizationCode('new-openid-code');
+ $this->assertNotNull($code);
+ $this->assertArrayHasKey('authorization_code', $code);
+ $this->assertArrayHasKey('client_id', $code);
+ $this->assertArrayHasKey('user_id', $code);
+ $this->assertArrayHasKey('redirect_uri', $code);
+ $this->assertArrayHasKey('expires', $code);
+ $this->assertEquals($code['authorization_code'], 'new-openid-code');
+ $this->assertEquals($code['client_id'], 'client ID');
+ $this->assertEquals($code['user_id'], 'SOMEUSERID');
+ $this->assertEquals($code['redirect_uri'], 'http://example.com');
+ $this->assertEquals($code['expires'], $expires);
+ $this->assertEquals($code['id_token'], $id_token);
+
+ // change existing code
+ $expires = time() + 42;
+ $new_id_token = 'fake_id_token-2';
+ $success = $storage->setAuthorizationCode('new-openid-code', 'client ID2', 'SOMEOTHERID', 'http://example.org', $expires, $scope, $new_id_token);
+ $this->assertTrue($success);
+
+ $code = $storage->getAuthorizationCode('new-openid-code');
+ $this->assertNotNull($code);
+ $this->assertArrayHasKey('authorization_code', $code);
+ $this->assertArrayHasKey('client_id', $code);
+ $this->assertArrayHasKey('user_id', $code);
+ $this->assertArrayHasKey('redirect_uri', $code);
+ $this->assertArrayHasKey('expires', $code);
+ $this->assertEquals($code['authorization_code'], 'new-openid-code');
+ $this->assertEquals($code['client_id'], 'client ID2');
+ $this->assertEquals($code['user_id'], 'SOMEOTHERID');
+ $this->assertEquals($code['redirect_uri'], 'http://example.org');
+ $this->assertEquals($code['expires'], $expires);
+ $this->assertEquals($code['id_token'], $new_id_token);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testRemoveIdTokenFromAuthorizationCode($storage)
+ {
+ // add new code
+ $expires = time() + 20;
+ $scope = null;
+ $id_token = 'fake_id_token_to_remove';
+ $authcode = 'new-openid-code-'.rand();
+ $success = $storage->setAuthorizationCode($authcode, 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, $id_token);
+ $this->assertTrue($success);
+
+ // verify params were set
+ $code = $storage->getAuthorizationCode($authcode);
+ $this->assertNotNull($code);
+ $this->assertArrayHasKey('id_token', $code);
+ $this->assertEquals($code['id_token'], $id_token);
+
+ // remove the id_token
+ $success = $storage->setAuthorizationCode($authcode, 'client ID', 'SOMEUSERID', 'http://example.com', $expires, $scope, null);
+
+ // verify the "id_token" is now null
+ $code = $storage->getAuthorizationCode($authcode);
+ $this->assertNotNull($code);
+ $this->assertArrayHasKey('id_token', $code);
+ $this->assertEquals($code['id_token'], null);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/UserClaimsTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/UserClaimsTest.php
new file mode 100644
index 000000000..840f6c566
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/OpenID/Storage/UserClaimsTest.php
@@ -0,0 +1,41 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ if (!$storage instanceof UserClaimsInterface) {
+ // incompatible storage
+ return;
+ }
+
+ // invalid user
+ $claims = $storage->getUserClaims('fake-user', '');
+ $this->assertFalse($claims);
+
+ // valid user (no scope)
+ $claims = $storage->getUserClaims('testuser', '');
+
+ /* assert the decoded token is the same */
+ $this->assertFalse(isset($claims['email']));
+
+ // valid user
+ $claims = $storage->getUserClaims('testuser', 'email');
+
+ /* assert the decoded token is the same */
+ $this->assertEquals($claims['email'], "testuser@test.com");
+ $this->assertEquals($claims['email_verified'], true);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/RequestTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/RequestTest.php
new file mode 100644
index 000000000..10db3215c
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/RequestTest.php
@@ -0,0 +1,98 @@
+getTestServer();
+
+ // Smoke test for override request class
+ // $server->handleTokenRequest($request, $response = new Response());
+ // $this->assertInstanceOf('Response', $response);
+ // $server->handleAuthorizeRequest($request, $response = new Response(), true);
+ // $this->assertInstanceOf('Response', $response);
+ // $response = $server->verifyResourceRequest($request, $response = new Response());
+ // $this->assertTrue(is_bool($response));
+
+ /*** make some valid requests ***/
+
+ // Valid Token Request
+ $request->setPost(array(
+ 'grant_type' => 'authorization_code',
+ 'client_id' => 'Test Client ID',
+ 'client_secret' => 'TestSecret',
+ 'code' => 'testcode',
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+ $this->assertEquals($response->getStatusCode(), 200);
+ $this->assertNull($response->getParameter('error'));
+ $this->assertNotNUll($response->getParameter('access_token'));
+ }
+
+ public function testHeadersReturnsValueByKey()
+ {
+ $request = new Request(
+ array(),
+ array(),
+ array(),
+ array(),
+ array(),
+ array(),
+ array(),
+ array('AUTHORIZATION' => 'Basic secret')
+ );
+
+ $this->assertEquals('Basic secret', $request->headers('AUTHORIZATION'));
+ }
+
+ public function testHeadersReturnsDefaultIfHeaderNotPresent()
+ {
+ $request = new Request();
+
+ $this->assertEquals('Bearer', $request->headers('AUTHORIZATION', 'Bearer'));
+ }
+
+ public function testHeadersIsCaseInsensitive()
+ {
+ $request = new Request(
+ array(),
+ array(),
+ array(),
+ array(),
+ array(),
+ array(),
+ array(),
+ array('AUTHORIZATION' => 'Basic secret')
+ );
+
+ $this->assertEquals('Basic secret', $request->headers('Authorization'));
+ }
+
+ public function testRequestReturnsPostParamIfNoQueryParamAvailable()
+ {
+ $request = new Request(
+ array(),
+ array('client_id' => 'correct')
+ );
+
+ $this->assertEquals('correct', $request->query('client_id', $request->request('client_id')));
+ }
+
+ private function getTestServer($config = array())
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, $config);
+
+ // Add the two types supported for authorization grant
+ $server->addGrantType(new AuthorizationCode($storage));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseTest.php
new file mode 100644
index 000000000..b8149005d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseTest.php
@@ -0,0 +1,17 @@
+ 'bar',
+ 'halland' => 'oates',
+ ));
+
+ $string = $response->getResponseBody('xml');
+ $this->assertContains('baroates', $string);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/AccessTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/AccessTokenTest.php
new file mode 100644
index 000000000..0ed1c82fc
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/AccessTokenTest.php
@@ -0,0 +1,107 @@
+ array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
+ $accessToken = new AccessToken($tokenStorage);
+ $accessToken->revokeToken('revoke', 'access_token');
+ $this->assertFalse($tokenStorage->getAccessToken('revoke'));
+ }
+
+ public function testRevokeAccessTokenWithoutTypeHint()
+ {
+ $tokenStorage = new Memory(array(
+ 'access_tokens' => array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
+ $accessToken = new AccessToken($tokenStorage);
+ $accessToken->revokeToken('revoke');
+ $this->assertFalse($tokenStorage->getAccessToken('revoke'));
+ }
+
+ public function testRevokeRefreshTokenWithTypeHint()
+ {
+ $tokenStorage = new Memory(array(
+ 'refresh_tokens' => array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
+ $accessToken = new AccessToken(new Memory, $tokenStorage);
+ $accessToken->revokeToken('revoke', 'refresh_token');
+ $this->assertFalse($tokenStorage->getRefreshToken('revoke'));
+ }
+
+ public function testRevokeRefreshTokenWithoutTypeHint()
+ {
+ $tokenStorage = new Memory(array(
+ 'refresh_tokens' => array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
+ $accessToken = new AccessToken(new Memory, $tokenStorage);
+ $accessToken->revokeToken('revoke');
+ $this->assertFalse($tokenStorage->getRefreshToken('revoke'));
+ }
+
+ public function testRevokeAccessTokenWithRefreshTokenTypeHint()
+ {
+ $tokenStorage = new Memory(array(
+ 'access_tokens' => array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
+ $accessToken = new AccessToken($tokenStorage);
+ $accessToken->revokeToken('revoke', 'refresh_token');
+ $this->assertFalse($tokenStorage->getAccessToken('revoke'));
+ }
+
+ public function testRevokeAccessTokenWithBogusTypeHint()
+ {
+ $tokenStorage = new Memory(array(
+ 'access_tokens' => array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getAccessToken('revoke'));
+ $accessToken = new AccessToken($tokenStorage);
+ $accessToken->revokeToken('revoke', 'foo');
+ $this->assertFalse($tokenStorage->getAccessToken('revoke'));
+ }
+
+ public function testRevokeRefreshTokenWithBogusTypeHint()
+ {
+ $tokenStorage = new Memory(array(
+ 'refresh_tokens' => array(
+ 'revoke' => array('mytoken'),
+ ),
+ ));
+
+ $this->assertEquals(array('mytoken'), $tokenStorage->getRefreshToken('revoke'));
+ $accessToken = new AccessToken(new Memory, $tokenStorage);
+ $accessToken->revokeToken('revoke', 'foo');
+ $this->assertFalse($tokenStorage->getRefreshToken('revoke'));
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/JwtAccessTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/JwtAccessTokenTest.php
new file mode 100644
index 000000000..51b01a927
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ResponseType/JwtAccessTokenTest.php
@@ -0,0 +1,160 @@
+getTestServer();
+ $jwtResponseType = $server->getResponseType('token');
+
+ $accessToken = $jwtResponseType->createAccessToken('Test Client ID', 123, 'test', false);
+ $jwt = new Jwt;
+ $decodedAccessToken = $jwt->decode($accessToken['access_token'], null, false);
+
+ $this->assertArrayHasKey('id', $decodedAccessToken);
+ $this->assertArrayHasKey('jti', $decodedAccessToken);
+ $this->assertArrayHasKey('iss', $decodedAccessToken);
+ $this->assertArrayHasKey('aud', $decodedAccessToken);
+ $this->assertArrayHasKey('exp', $decodedAccessToken);
+ $this->assertArrayHasKey('iat', $decodedAccessToken);
+ $this->assertArrayHasKey('token_type', $decodedAccessToken);
+ $this->assertArrayHasKey('scope', $decodedAccessToken);
+
+ $this->assertEquals('https://api.example.com', $decodedAccessToken['iss']);
+ $this->assertEquals('Test Client ID', $decodedAccessToken['aud']);
+ $this->assertEquals(123, $decodedAccessToken['sub']);
+ $delta = $decodedAccessToken['exp'] - $decodedAccessToken['iat'];
+ $this->assertEquals(3600, $delta);
+ $this->assertEquals($decodedAccessToken['id'], $decodedAccessToken['jti']);
+ }
+
+ public function testGrantJwtAccessToken()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+
+ $this->assertNotNull($response->getParameter('access_token'));
+ $this->assertEquals(2, substr_count($response->getParameter('access_token'), '.'));
+ }
+
+ public function testAccessResourceWithJwtAccessToken()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+ $this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
+
+ // make a call to the resource server using the crypto token
+ $request = TestRequest::createPost(array(
+ 'access_token' => $JwtAccessToken,
+ ));
+
+ $this->assertTrue($server->verifyResourceRequest($request));
+ }
+
+ public function testAccessResourceWithJwtAccessTokenUsingSecondaryStorage()
+ {
+ // add the test parameters in memory
+ $server = $this->getTestServer();
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'client_credentials', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ ));
+ $server->handleTokenRequest($request, $response = new Response());
+ $this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
+
+ // make a call to the resource server using the crypto token
+ $request = TestRequest::createPost(array(
+ 'access_token' => $JwtAccessToken,
+ ));
+
+ // create a resource server with the "memory" storage from the grant server
+ $resourceServer = new Server($server->getStorage('client_credentials'));
+
+ $this->assertTrue($resourceServer->verifyResourceRequest($request));
+ }
+
+ public function testJwtAccessTokenWithRefreshToken()
+ {
+ $server = $this->getTestServer();
+
+ // add "UserCredentials" grant type and "JwtAccessToken" response type
+ // and ensure "JwtAccessToken" response type has "RefreshToken" storage
+ $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
+ $server->addGrantType(new UserCredentials($memoryStorage));
+ $server->addGrantType(new RefreshToken($memoryStorage));
+ $server->addResponseType(new JwtAccessToken($memoryStorage, $memoryStorage, $memoryStorage), 'token');
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'password', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'username' => 'test-username', // valid username
+ 'password' => 'testpass', // valid password
+ ));
+
+ // make the call to grant a crypto token
+ $server->handleTokenRequest($request, $response = new Response());
+ $this->assertNotNull($JwtAccessToken = $response->getParameter('access_token'));
+ $this->assertNotNull($refreshToken = $response->getParameter('refresh_token'));
+
+ // decode token and make sure refresh_token isn't set
+ list($header, $payload, $signature) = explode('.', $JwtAccessToken);
+ $decodedToken = json_decode(base64_decode($payload), true);
+ $this->assertFalse(array_key_exists('refresh_token', $decodedToken));
+
+ // use the refresh token to get another access token
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token',
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => $refreshToken,
+ ));
+
+ $server->handleTokenRequest($request, $response = new Response());
+ $this->assertNotNull($response->getParameter('access_token'));
+ }
+
+ private function getTestServer()
+ {
+ $memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
+
+ $storage = array(
+ 'access_token' => new JwtAccessTokenStorage($memoryStorage),
+ 'client' => $memoryStorage,
+ 'client_credentials' => $memoryStorage,
+ );
+ $server = new Server($storage);
+ $server->addGrantType(new ClientCredentials($memoryStorage));
+
+ // make the "token" response type a JwtAccessToken
+ $config = array('issuer' => 'https://api.example.com');
+ $server->addResponseType(new JwtAccessToken($memoryStorage, $memoryStorage, null, $config));
+
+ return $server;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/ScopeTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ScopeTest.php
new file mode 100644
index 000000000..99f9cf6eb
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ScopeTest.php
@@ -0,0 +1,42 @@
+assertFalse($scopeUtil->checkScope('invalid', 'list of scopes'));
+ $this->assertTrue($scopeUtil->checkScope('valid', 'valid and-some other-scopes'));
+ $this->assertTrue($scopeUtil->checkScope('valid another-valid', 'valid another-valid and-some other-scopes'));
+ // all scopes must match
+ $this->assertFalse($scopeUtil->checkScope('valid invalid', 'valid and-some other-scopes'));
+ $this->assertFalse($scopeUtil->checkScope('valid valid2 invalid', 'valid valid2 and-some other-scopes'));
+ }
+
+ public function testScopeStorage()
+ {
+ $scopeUtil = new Scope();
+ $this->assertEquals($scopeUtil->getDefaultScope(), null);
+
+ $scopeUtil = new Scope(array(
+ 'default_scope' => 'default',
+ 'supported_scopes' => array('this', 'that', 'another'),
+ ));
+ $this->assertEquals($scopeUtil->getDefaultScope(), 'default');
+ $this->assertTrue($scopeUtil->scopeExists('this that another', 'client_id'));
+
+ $memoryStorage = new Memory(array(
+ 'default_scope' => 'base',
+ 'supported_scopes' => array('only-this-one'),
+ ));
+ $scopeUtil = new Scope($memoryStorage);
+
+ $this->assertEquals($scopeUtil->getDefaultScope(), 'base');
+ $this->assertTrue($scopeUtil->scopeExists('only-this-one', 'client_id'));
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/ServerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ServerTest.php
new file mode 100644
index 000000000..747e120f5
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/ServerTest.php
@@ -0,0 +1,684 @@
+getAuthorizeController();
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\Storage\AccessTokenInterface
+ **/
+ public function testGetAuthorizeControllerWithNoAccessTokenStorageThrowsException()
+ {
+ // must set AccessToken or AuthorizationCode
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
+ $server->getAuthorizeController();
+ }
+
+ public function testGetAuthorizeControllerWithClientStorageAndAccessTokenResponseType()
+ {
+ // must set AccessToken or AuthorizationCode
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
+ $server->addResponseType($this->getMock('OAuth2\ResponseType\AccessTokenInterface'));
+
+ $this->assertNotNull($server->getAuthorizeController());
+ }
+
+ public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeResponseType()
+ {
+ // must set AccessToken or AuthorizationCode
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
+ $server->addResponseType($this->getMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
+
+ $this->assertNotNull($server->getAuthorizeController());
+ }
+
+ /**
+ * @expectedException LogicException allow_implicit
+ **/
+ public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
+ {
+ // must set AuthorizationCode or AccessToken / implicit
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
+
+ $this->assertNotNull($server->getAuthorizeController());
+ }
+
+ public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorage()
+ {
+ // must set AuthorizationCode or AccessToken / implicit
+ $server = new Server(array(), array('allow_implicit' => true));
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
+
+ $this->assertNotNull($server->getAuthorizeController());
+ }
+
+ public function testGetAuthorizeControllerWithClientStorageAndAuthorizationCodeStorage()
+ {
+ // must set AccessToken or AuthorizationCode
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\AuthorizationCodeInterface'));
+
+ $this->assertNotNull($server->getAuthorizeController());
+ }
+
+ /**
+ * @expectedException LogicException grant_types
+ **/
+ public function testGetTokenControllerWithGrantTypeStorageThrowsException()
+ {
+ $server = new Server();
+ $server->getTokenController();
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\Storage\ClientCredentialsInterface
+ **/
+ public function testGetTokenControllerWithNoClientCredentialsStorageThrowsException()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\UserCredentialsInterface'));
+ $server->getTokenController();
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\Storage\AccessTokenInterface
+ **/
+ public function testGetTokenControllerWithNoAccessTokenStorageThrowsException()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
+ $server->getTokenController();
+ }
+
+ public function testGetTokenControllerWithAccessTokenAndClientCredentialsStorage()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
+ $server->getTokenController();
+ }
+
+ public function testGetTokenControllerAccessTokenStorageAndClientCredentialsStorageAndGrantTypes()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
+ $server->addGrantType($this->getMockBuilder('OAuth2\GrantType\AuthorizationCode')->disableOriginalConstructor()->getMock());
+ $server->getTokenController();
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\Storage\AccessTokenInterface
+ **/
+ public function testGetResourceControllerWithNoAccessTokenStorageThrowsException()
+ {
+ $server = new Server();
+ $server->getResourceController();
+ }
+
+ public function testGetResourceControllerWithAccessTokenStorage()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
+ $server->getResourceController();
+ }
+
+ /**
+ * @expectedException InvalidArgumentException OAuth2\Storage\AccessTokenInterface
+ **/
+ public function testAddingStorageWithInvalidClass()
+ {
+ $server = new Server();
+ $server->addStorage(new \StdClass());
+ }
+
+ /**
+ * @expectedException InvalidArgumentException access_token
+ **/
+ public function testAddingStorageWithInvalidKey()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
+ }
+
+ /**
+ * @expectedException InvalidArgumentException OAuth2\Storage\AuthorizationCodeInterface
+ **/
+ public function testAddingStorageWithInvalidKeyStorageCombination()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
+ }
+
+ public function testAddingStorageWithValidKeyOnlySetsThatKey()
+ {
+ $server = new Server();
+ $server->addStorage($this->getMock('OAuth2\Storage\Memory'), 'access_token');
+
+ $reflection = new \ReflectionClass($server);
+ $prop = $reflection->getProperty('storages');
+ $prop->setAccessible(true);
+
+ $storages = $prop->getValue($server); // get the private "storages" property
+
+ $this->assertEquals(1, count($storages));
+ $this->assertTrue(isset($storages['access_token']));
+ $this->assertFalse(isset($storages['authorization_code']));
+ }
+
+ public function testAddingClientStorageSetsClientCredentialsStorageByDefault()
+ {
+ $server = new Server();
+ $memory = $this->getMock('OAuth2\Storage\Memory');
+ $server->addStorage($memory, 'client');
+
+ $client_credentials = $server->getStorage('client_credentials');
+
+ $this->assertNotNull($client_credentials);
+ $this->assertEquals($client_credentials, $memory);
+ }
+
+ public function testAddStorageWithNullValue()
+ {
+ $memory = $this->getMock('OAuth2\Storage\Memory');
+ $server = new Server($memory);
+ $server->addStorage(null, 'refresh_token');
+
+ $client_credentials = $server->getStorage('client_credentials');
+
+ $this->assertNotNull($client_credentials);
+ $this->assertEquals($client_credentials, $memory);
+
+ $refresh_token = $server->getStorage('refresh_token');
+
+ $this->assertNull($refresh_token);
+ }
+
+ public function testNewServerWithNullStorageValue()
+ {
+ $memory = $this->getMock('OAuth2\Storage\Memory');
+ $server = new Server(array(
+ 'client_credentials' => $memory,
+ 'refresh_token' => null,
+ ));
+
+ $client_credentials = $server->getStorage('client_credentials');
+
+ $this->assertNotNull($client_credentials);
+ $this->assertEquals($client_credentials, $memory);
+
+ $refresh_token = $server->getStorage('refresh_token');
+
+ $this->assertNull($refresh_token);
+ }
+
+ public function testAddingClientCredentialsStorageSetsClientStorageByDefault()
+ {
+ $server = new Server();
+ $memory = $this->getMock('OAuth2\Storage\Memory');
+ $server->addStorage($memory, 'client_credentials');
+
+ $client = $server->getStorage('client');
+
+ $this->assertNotNull($client);
+ $this->assertEquals($client, $memory);
+ }
+
+ public function testSettingClientStorageByDefaultDoesNotOverrideSetStorage()
+ {
+ $server = new Server();
+ $pdo = $this->getMockBuilder('OAuth2\Storage\Pdo')
+ ->disableOriginalConstructor()->getMock();
+
+ $memory = $this->getMock('OAuth2\Storage\Memory');
+
+ $server->addStorage($pdo, 'client');
+ $server->addStorage($memory, 'client_credentials');
+
+ $client = $server->getStorage('client');
+ $client_credentials = $server->getStorage('client_credentials');
+
+ $this->assertEquals($client, $pdo);
+ $this->assertEquals($client_credentials, $memory);
+ }
+
+ public function testAddingResponseType()
+ {
+ $storage = $this->getMock('OAuth2\Storage\Memory');
+ $storage
+ ->expects($this->any())
+ ->method('getClientDetails')
+ ->will($this->returnValue(array('client_id' => 'some_client')));
+ $storage
+ ->expects($this->any())
+ ->method('checkRestrictedGrantType')
+ ->will($this->returnValue(true));
+
+ // add with the "code" key explicitly set
+ $codeType = new AuthorizationCode($storage);
+ $server = new Server();
+ $server->addStorage($storage);
+ $server->addResponseType($codeType);
+ $request = new Request(array(
+ 'response_type' => 'code',
+ 'client_id' => 'some_client',
+ 'redirect_uri' => 'http://example.com',
+ 'state' => 'xyx',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ // the response is successful
+ $this->assertEquals($response->getStatusCode(), 302);
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['query'], $query);
+ $this->assertTrue(isset($query['code']));
+ $this->assertFalse(isset($query['error']));
+
+ // add with the "code" key not set
+ $codeType = new AuthorizationCode($storage);
+ $server = new Server(array($storage), array(), array(), array($codeType));
+ $request = new Request(array(
+ 'response_type' => 'code',
+ 'client_id' => 'some_client',
+ 'redirect_uri' => 'http://example.com',
+ 'state' => 'xyx',
+ ));
+ $server->handleAuthorizeRequest($request, $response = new Response(), true);
+
+ // the response is successful
+ $this->assertEquals($response->getStatusCode(), 302);
+ $parts = parse_url($response->getHttpHeader('Location'));
+ parse_str($parts['query'], $query);
+ $this->assertTrue(isset($query['code']));
+ $this->assertFalse(isset($query['error']));
+ }
+
+ public function testCustomClientAssertionType()
+ {
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'authorization_code',
+ 'client_id' =>'Test Client ID',
+ 'code' => 'testcode',
+ ));
+ // verify the mock clientAssertionType was called as expected
+ $clientAssertionType = $this->getMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface', array('validateRequest', 'getClientId'));
+ $clientAssertionType
+ ->expects($this->once())
+ ->method('validateRequest')
+ ->will($this->returnValue(true));
+ $clientAssertionType
+ ->expects($this->once())
+ ->method('getClientId')
+ ->will($this->returnValue('Test Client ID'));
+
+ // create mock storage
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server(array($storage), array(), array(), array(), null, null, $clientAssertionType);
+ $server->handleTokenRequest($request, $response = new Response());
+ }
+
+ public function testHttpBasicConfig()
+ {
+ // create mock storage
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server(array($storage), array(
+ 'allow_credentials_in_request_body' => false,
+ 'allow_public_clients' => false
+ ));
+ $server->getTokenController();
+ $httpBasic = $server->getClientAssertionType();
+
+ $reflection = new \ReflectionClass($httpBasic);
+ $prop = $reflection->getProperty('config');
+ $prop->setAccessible(true);
+
+ $config = $prop->getValue($httpBasic); // get the private "config" property
+
+ $this->assertEquals($config['allow_credentials_in_request_body'], false);
+ $this->assertEquals($config['allow_public_clients'], false);
+ }
+
+ public function testRefreshTokenConfig()
+ {
+ // create mock storage
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server1 = new Server(array($storage));
+ $server2 = new Server(array($storage), array('always_issue_new_refresh_token' => true, 'unset_refresh_token_after_use' => false));
+
+ $server1->getTokenController();
+ $refreshToken1 = $server1->getGrantType('refresh_token');
+
+ $server2->getTokenController();
+ $refreshToken2 = $server2->getGrantType('refresh_token');
+
+ $reflection1 = new \ReflectionClass($refreshToken1);
+ $prop1 = $reflection1->getProperty('config');
+ $prop1->setAccessible(true);
+
+ $reflection2 = new \ReflectionClass($refreshToken2);
+ $prop2 = $reflection2->getProperty('config');
+ $prop2->setAccessible(true);
+
+ // get the private "config" property
+ $config1 = $prop1->getValue($refreshToken1);
+ $config2 = $prop2->getValue($refreshToken2);
+
+ $this->assertEquals($config1['always_issue_new_refresh_token'], false);
+ $this->assertEquals($config2['always_issue_new_refresh_token'], true);
+
+ $this->assertEquals($config1['unset_refresh_token_after_use'], true);
+ $this->assertEquals($config2['unset_refresh_token_after_use'], false);
+ }
+
+ /**
+ * Test setting "always_issue_new_refresh_token" on a server level
+ *
+ * @see test/OAuth2/GrantType/RefreshTokenTest::testValidRefreshTokenWithNewRefreshTokenInResponse
+ **/
+ public function testValidRefreshTokenWithNewRefreshTokenInResponse()
+ {
+ $storage = Bootstrap::getInstance()->getMemoryStorage();
+ $server = new Server($storage, array('always_issue_new_refresh_token' => true));
+
+ $request = TestRequest::createPost(array(
+ 'grant_type' => 'refresh_token', // valid grant type
+ 'client_id' => 'Test Client ID', // valid client id
+ 'client_secret' => 'TestSecret', // valid client secret
+ 'refresh_token' => 'test-refreshtoken', // valid refresh token
+ ));
+ $token = $server->grantAccessToken($request, new Response());
+ $this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
+
+ $refresh_token = $storage->getRefreshToken($token['refresh_token']);
+ $this->assertNotNull($refresh_token);
+ $this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
+ $this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
+ $this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
+ $used_token = $storage->getRefreshToken('test-refreshtoken');
+ $this->assertFalse($used_token, 'the refresh token used is no longer valid');
+ }
+
+ /**
+ * @expectedException InvalidArgumentException OAuth2\ResponseType\AuthorizationCodeInterface
+ **/
+ public function testAddingUnknownResponseTypeThrowsException()
+ {
+ $server = new Server();
+ $server->addResponseType($this->getMock('OAuth2\ResponseType\ResponseTypeInterface'));
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\Storage\PublicKeyInterface
+ **/
+ public function testUsingJwtAccessTokensWithoutPublicKeyStorageThrowsException()
+ {
+ $server = new Server(array(), array('use_jwt_access_tokens' => true));
+ $server->addGrantType($this->getMock('OAuth2\GrantType\GrantTypeInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
+ $server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
+
+ $server->getTokenController();
+ }
+
+ public function testUsingJustJwtAccessTokenStorageWithResourceControllerIsOkay()
+ {
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
+
+ $this->assertNotNull($server->getResourceController());
+ $this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\Storage\ClientInterface
+ **/
+ public function testUsingJustJwtAccessTokenStorageWithAuthorizeControllerThrowsException()
+ {
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
+ $this->assertNotNull($server->getAuthorizeController());
+ }
+
+ /**
+ * @expectedException LogicException grant_types
+ **/
+ public function testUsingJustJwtAccessTokenStorageWithTokenControllerThrowsException()
+ {
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
+ $server->getTokenController();
+ }
+
+ public function testUsingJwtAccessTokenAndClientStorageWithAuthorizeControllerIsOkay()
+ {
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $server = new Server(array($pubkey, $client), array('use_jwt_access_tokens' => true, 'allow_implicit' => true));
+ $this->assertNotNull($server->getAuthorizeController());
+
+ $this->assertInstanceOf('OAuth2\ResponseType\JwtAccessToken', $server->getResponseType('token'));
+ }
+
+ /**
+ * @expectedException LogicException UserClaims
+ **/
+ public function testUsingOpenIDConnectWithoutUserClaimsThrowsException()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $server = new Server($client, array('use_openid_connect' => true));
+
+ $server->getAuthorizeController();
+ }
+
+ /**
+ * @expectedException LogicException PublicKeyInterface
+ **/
+ public function testUsingOpenIDConnectWithoutPublicKeyThrowsException()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OPenID\Storage\UserClaimsInterface');
+ $server = new Server(array($client, $userclaims), array('use_openid_connect' => true));
+
+ $server->getAuthorizeController();
+ }
+
+ /**
+ * @expectedException LogicException issuer
+ **/
+ public function testUsingOpenIDConnectWithoutIssuerThrowsException()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($client, $userclaims, $pubkey), array('use_openid_connect' => true));
+
+ $server->getAuthorizeController();
+ }
+
+ public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($client, $userclaims, $pubkey), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy',
+ ));
+
+ $server->getAuthorizeController();
+
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
+ $this->assertNull($server->getResponseType('id_token token'));
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\ResponseType\AccessTokenInterface
+ **/
+ public function testUsingOpenIDConnectWithAllowImplicitWithoutTokenStorageThrowsException()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($client, $userclaims, $pubkey), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy',
+ 'allow_implicit' => true,
+ ));
+
+ $server->getAuthorizeController();
+ }
+
+ public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOkay()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $server = new Server(array($client, $userclaims, $pubkey), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy',
+ 'allow_implicit' => true,
+ 'use_jwt_access_tokens' => true,
+ ));
+
+ $server->getAuthorizeController();
+
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
+ }
+
+ public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
+ $server = new Server(array($client, $userclaims, $pubkey, $token), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy',
+ 'allow_implicit' => true,
+ ));
+
+ $server->getAuthorizeController();
+
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
+ }
+
+ public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ // $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
+ $server = new Server(array($client, $userclaims, $pubkey), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy',
+ 'allow_implicit' => true,
+ ));
+
+ $token = $this->getMock('OAuth2\ResponseType\AccessTokenInterface');
+ $server->addResponseType($token, 'token');
+
+ $server->getAuthorizeController();
+
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenInterface', $server->getResponseType('id_token'));
+ $this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
+ }
+
+ /**
+ * @expectedException LogicException OAuth2\OpenID\Storage\AuthorizationCodeInterface
+ **/
+ public function testUsingOpenIDConnectWithAuthorizationCodeStorageThrowsException()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
+ $authcode = $this->getMock('OAuth2\Storage\AuthorizationCodeInterface');
+
+ $server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy'
+ ));
+
+ $server->getTokenController();
+
+ $this->assertInstanceOf('OAuth2\OpenID\GrantType\AuthorizationCode', $server->getGrantType('authorization_code'));
+ }
+
+ public function testUsingOpenIDConnectWithOpenIDAuthorizationCodeStorageCreatesOpenIDAuthorizationCodeGrantType()
+ {
+ $client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
+ $userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
+ $pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
+ $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
+ $authcode = $this->getMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
+
+ $server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
+ 'use_openid_connect' => true,
+ 'issuer' => 'someguy'
+ ));
+
+ $server->getTokenController();
+
+ $this->assertInstanceOf('OAuth2\OpenID\GrantType\AuthorizationCode', $server->getGrantType('authorization_code'));
+ }
+
+ public function testMultipleValuedResponseTypeOrderDoesntMatter()
+ {
+ $responseType = $this->getMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
+ $server = new Server(array(), array(), array(), array(
+ 'token id_token' => $responseType,
+ ));
+
+ $this->assertEquals($responseType, $server->getResponseType('id_token token'));
+ }
+
+ public function testAddGrantTypeWithoutKey()
+ {
+ $server = new Server();
+ $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')));
+
+ $grantTypes = $server->getGrantTypes();
+ $this->assertEquals('authorization_code', key($grantTypes));
+ }
+
+ public function testAddGrantTypeWithKey()
+ {
+ $server = new Server();
+ $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
+
+ $grantTypes = $server->getGrantTypes();
+ $this->assertEquals('ac', key($grantTypes));
+ }
+
+ public function testAddGrantTypeWithKeyNotString()
+ {
+ $server = new Server();
+ $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
+
+ $grantTypes = $server->getGrantTypes();
+ $this->assertEquals('authorization_code', key($grantTypes));
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AccessTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AccessTokenTest.php
new file mode 100644
index 000000000..b34e0bfc0
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AccessTokenTest.php
@@ -0,0 +1,102 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // assert token we are about to add does not exist
+ $token = $storage->getAccessToken('newtoken');
+ $this->assertFalse($token);
+
+ // add new token
+ $expires = time() + 20;
+ $success = $storage->setAccessToken('newtoken', 'client ID', 'SOMEUSERID', $expires);
+ $this->assertTrue($success);
+
+ $token = $storage->getAccessToken('newtoken');
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('client_id', $token);
+ $this->assertArrayHasKey('user_id', $token);
+ $this->assertArrayHasKey('expires', $token);
+ $this->assertEquals($token['access_token'], 'newtoken');
+ $this->assertEquals($token['client_id'], 'client ID');
+ $this->assertEquals($token['user_id'], 'SOMEUSERID');
+ $this->assertEquals($token['expires'], $expires);
+
+ // change existing token
+ $expires = time() + 42;
+ $success = $storage->setAccessToken('newtoken', 'client ID2', 'SOMEOTHERID', $expires);
+ $this->assertTrue($success);
+
+ $token = $storage->getAccessToken('newtoken');
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('access_token', $token);
+ $this->assertArrayHasKey('client_id', $token);
+ $this->assertArrayHasKey('user_id', $token);
+ $this->assertArrayHasKey('expires', $token);
+ $this->assertEquals($token['access_token'], 'newtoken');
+ $this->assertEquals($token['client_id'], 'client ID2');
+ $this->assertEquals($token['user_id'], 'SOMEOTHERID');
+ $this->assertEquals($token['expires'], $expires);
+
+ // add token with scope having an empty string value
+ $expires = time() + 42;
+ $success = $storage->setAccessToken('newtoken', 'client ID', 'SOMEOTHERID', $expires, '');
+ $this->assertTrue($success);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testUnsetAccessToken(AccessTokenInterface $storage)
+ {
+ if ($storage instanceof NullStorage || !method_exists($storage, 'unsetAccessToken')) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // assert token we are about to unset does not exist
+ $token = $storage->getAccessToken('revokabletoken');
+ $this->assertFalse($token);
+
+ // add new token
+ $expires = time() + 20;
+ $success = $storage->setAccessToken('revokabletoken', 'client ID', 'SOMEUSERID', $expires);
+ $this->assertTrue($success);
+
+ // assert unsetAccessToken returns true
+ $result = $storage->unsetAccessToken('revokabletoken');
+ $this->assertTrue($result);
+
+ // assert token we unset does not exist
+ $token = $storage->getAccessToken('revokabletoken');
+ $this->assertFalse($token);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testUnsetAccessTokenReturnsFalse(AccessTokenInterface $storage)
+ {
+ if ($storage instanceof NullStorage || !method_exists($storage, 'unsetAccessToken')) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // assert token we are about to unset does not exist
+ $token = $storage->getAccessToken('nonexistanttoken');
+ $this->assertFalse($token);
+
+ // assert unsetAccessToken returns false
+ $result = $storage->unsetAccessToken('nonexistanttoken');
+ $this->assertFalse($result);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AuthorizationCodeTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AuthorizationCodeTest.php
new file mode 100644
index 000000000..2d901b501
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/AuthorizationCodeTest.php
@@ -0,0 +1,106 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // nonexistant client_id
+ $details = $storage->getAuthorizationCode('faketoken');
+ $this->assertFalse($details);
+
+ // valid client_id
+ $details = $storage->getAuthorizationCode('testtoken');
+ $this->assertNotNull($details);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testSetAuthorizationCode(AuthorizationCodeInterface $storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // assert code we are about to add does not exist
+ $code = $storage->getAuthorizationCode('newcode');
+ $this->assertFalse($code);
+
+ // add new code
+ $expires = time() + 20;
+ $success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://example.com', $expires);
+ $this->assertTrue($success);
+
+ $code = $storage->getAuthorizationCode('newcode');
+ $this->assertNotNull($code);
+ $this->assertArrayHasKey('authorization_code', $code);
+ $this->assertArrayHasKey('client_id', $code);
+ $this->assertArrayHasKey('user_id', $code);
+ $this->assertArrayHasKey('redirect_uri', $code);
+ $this->assertArrayHasKey('expires', $code);
+ $this->assertEquals($code['authorization_code'], 'newcode');
+ $this->assertEquals($code['client_id'], 'client ID');
+ $this->assertEquals($code['user_id'], 'SOMEUSERID');
+ $this->assertEquals($code['redirect_uri'], 'http://example.com');
+ $this->assertEquals($code['expires'], $expires);
+
+ // change existing code
+ $expires = time() + 42;
+ $success = $storage->setAuthorizationCode('newcode', 'client ID2', 'SOMEOTHERID', 'http://example.org', $expires);
+ $this->assertTrue($success);
+
+ $code = $storage->getAuthorizationCode('newcode');
+ $this->assertNotNull($code);
+ $this->assertArrayHasKey('authorization_code', $code);
+ $this->assertArrayHasKey('client_id', $code);
+ $this->assertArrayHasKey('user_id', $code);
+ $this->assertArrayHasKey('redirect_uri', $code);
+ $this->assertArrayHasKey('expires', $code);
+ $this->assertEquals($code['authorization_code'], 'newcode');
+ $this->assertEquals($code['client_id'], 'client ID2');
+ $this->assertEquals($code['user_id'], 'SOMEOTHERID');
+ $this->assertEquals($code['redirect_uri'], 'http://example.org');
+ $this->assertEquals($code['expires'], $expires);
+
+ // add new code with scope having an empty string value
+ $expires = time() + 20;
+ $success = $storage->setAuthorizationCode('newcode', 'client ID', 'SOMEUSERID', 'http://example.com', $expires, '');
+ $this->assertTrue($success);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testExpireAccessToken(AccessTokenInterface $storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // create a valid code
+ $expires = time() + 20;
+ $success = $storage->setAuthorizationCode('code-to-expire', 'client ID', 'SOMEUSERID', 'http://example.com', time() + 20);
+ $this->assertTrue($success);
+
+ // verify the new code exists
+ $code = $storage->getAuthorizationCode('code-to-expire');
+ $this->assertNotNull($code);
+
+ $this->assertArrayHasKey('authorization_code', $code);
+ $this->assertEquals($code['authorization_code'], 'code-to-expire');
+
+ // now expire the code and ensure it's no longer available
+ $storage->expireAuthorizationCode('code-to-expire');
+ $code = $storage->getAuthorizationCode('code-to-expire');
+ $this->assertFalse($code);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientCredentialsTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientCredentialsTest.php
new file mode 100644
index 000000000..15289af30
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientCredentialsTest.php
@@ -0,0 +1,28 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // nonexistant client_id
+ $pass = $storage->checkClientCredentials('fakeclient', 'testpass');
+ $this->assertFalse($pass);
+
+ // invalid password
+ $pass = $storage->checkClientCredentials('oauth_test_client', 'invalidcredentials');
+ $this->assertFalse($pass);
+
+ // valid credentials
+ $pass = $storage->checkClientCredentials('oauth_test_client', 'testpass');
+ $this->assertTrue($pass);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientTest.php
new file mode 100644
index 000000000..6a5cc0b49
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ClientTest.php
@@ -0,0 +1,110 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // nonexistant client_id
+ $details = $storage->getClientDetails('fakeclient');
+ $this->assertFalse($details);
+
+ // valid client_id
+ $details = $storage->getClientDetails('oauth_test_client');
+ $this->assertNotNull($details);
+ $this->assertArrayHasKey('client_id', $details);
+ $this->assertArrayHasKey('client_secret', $details);
+ $this->assertArrayHasKey('redirect_uri', $details);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testCheckRestrictedGrantType(ClientInterface $storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // Check invalid
+ $pass = $storage->checkRestrictedGrantType('oauth_test_client', 'authorization_code');
+ $this->assertFalse($pass);
+
+ // Check valid
+ $pass = $storage->checkRestrictedGrantType('oauth_test_client', 'implicit');
+ $this->assertTrue($pass);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testGetAccessToken(ClientInterface $storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // nonexistant client_id
+ $details = $storage->getAccessToken('faketoken');
+ $this->assertFalse($details);
+
+ // valid client_id
+ $details = $storage->getAccessToken('testtoken');
+ $this->assertNotNull($details);
+ }
+
+ /** @dataProvider provideStorage */
+ public function testIsPublicClient(ClientInterface $storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ $publicClientId = 'public-client-'.rand();
+ $confidentialClientId = 'confidential-client-'.rand();
+
+ // create a new client
+ $success1 = $storage->setClientDetails($publicClientId, '');
+ $success2 = $storage->setClientDetails($confidentialClientId, 'some-secret');
+ $this->assertTrue($success1);
+ $this->assertTrue($success2);
+
+ // assert isPublicClient for both
+ $this->assertTrue($storage->isPublicClient($publicClientId));
+ $this->assertFalse($storage->isPublicClient($confidentialClientId));
+ }
+
+ /** @dataProvider provideStorage */
+ public function testSaveClient(ClientInterface $storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ $clientId = 'some-client-'.rand();
+
+ // create a new client
+ $success = $storage->setClientDetails($clientId, 'somesecret', 'http://test.com', 'client_credentials', 'clientscope1', 'brent@brentertainment.com');
+ $this->assertTrue($success);
+
+ // valid client_id
+ $details = $storage->getClientDetails($clientId);
+ $this->assertEquals($details['client_secret'], 'somesecret');
+ $this->assertEquals($details['redirect_uri'], 'http://test.com');
+ $this->assertEquals($details['grant_types'], 'client_credentials');
+ $this->assertEquals($details['scope'], 'clientscope1');
+ $this->assertEquals($details['user_id'], 'brent@brentertainment.com');
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/DynamoDBTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/DynamoDBTest.php
new file mode 100644
index 000000000..2147f0914
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/DynamoDBTest.php
@@ -0,0 +1,40 @@
+getMockBuilder('\Aws\DynamoDb\DynamoDbClient')
+ ->disableOriginalConstructor()
+ ->setMethods(array('query'))
+ ->getMock();
+
+ $return = $this->getMockBuilder('\Guzzle\Service\Resource\Model')
+ ->setMethods(array('count', 'toArray'))
+ ->getMock();
+
+ $data = array(
+ 'Items' => array(),
+ 'Count' => 0,
+ 'ScannedCount'=> 0
+ );
+
+ $return->expects($this->once())
+ ->method('count')
+ ->will($this->returnValue(count($data)));
+
+ $return->expects($this->once())
+ ->method('toArray')
+ ->will($this->returnValue($data));
+
+ // should return null default scope if none is set in database
+ $client->expects($this->once())
+ ->method('query')
+ ->will($this->returnValue($return));
+
+ $storage = new DynamoDB($client);
+ $this->assertNull($storage->getDefaultScope());
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtAccessTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtAccessTokenTest.php
new file mode 100644
index 000000000..a6acbea1f
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtAccessTokenTest.php
@@ -0,0 +1,41 @@
+getMemoryStorage();
+ $encryptionUtil = new Jwt();
+
+ $jwtAccessToken = array(
+ 'access_token' => rand(),
+ 'expires' => time() + 100,
+ 'scope' => 'foo',
+ );
+
+ $token = $encryptionUtil->encode($jwtAccessToken, $storage->getPrivateKey(), $storage->getEncryptionAlgorithm());
+
+ $this->assertNotNull($token);
+
+ $tokenData = $crypto->getAccessToken($token);
+
+ $this->assertTrue(is_array($tokenData));
+
+ /* assert the decoded token is the same */
+ $this->assertEquals($tokenData['access_token'], $jwtAccessToken['access_token']);
+ $this->assertEquals($tokenData['expires'], $jwtAccessToken['expires']);
+ $this->assertEquals($tokenData['scope'], $jwtAccessToken['scope']);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtBearerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtBearerTest.php
new file mode 100644
index 000000000..d0ab9b899
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/JwtBearerTest.php
@@ -0,0 +1,25 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // nonexistant client_id
+ $key = $storage->getClientKey('this-is-not-real', 'nor-is-this');
+ $this->assertFalse($key);
+
+ // valid client_id and subject
+ $key = $storage->getClientKey('oauth_test_client', 'test_subject');
+ $this->assertNotNull($key);
+ $this->assertEquals($key, Bootstrap::getInstance()->getTestPublicKey());
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PdoTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PdoTest.php
new file mode 100644
index 000000000..57eb39072
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PdoTest.php
@@ -0,0 +1,39 @@
+getSqliteDir()));
+ $storage = new Pdo($pdo);
+
+ $this->assertNotNull($storage->getClientDetails('oauth_test_client'));
+ }
+
+ public function testCreatePdoStorageUsingDSN()
+ {
+ $dsn = sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir());
+ $storage = new Pdo($dsn);
+
+ $this->assertNotNull($storage->getClientDetails('oauth_test_client'));
+ }
+
+ public function testCreatePdoStorageUsingConfig()
+ {
+ $config = array('dsn' => sprintf('sqlite://%s', Bootstrap::getInstance()->getSqliteDir()));
+ $storage = new Pdo($config);
+
+ $this->assertNotNull($storage->getClientDetails('oauth_test_client'));
+ }
+
+ /**
+ * @expectedException InvalidArgumentException dsn
+ */
+ public function testCreatePdoStorageWithoutDSNThrowsException()
+ {
+ $config = array('username' => 'brent', 'password' => 'brentisaballer');
+ $storage = new Pdo($config);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PublicKeyTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PublicKeyTest.php
new file mode 100644
index 000000000..f85195870
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/PublicKeyTest.php
@@ -0,0 +1,29 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ if (!$storage instanceof PublicKeyInterface) {
+ // incompatible storage
+ return;
+ }
+
+ $configDir = Bootstrap::getInstance()->getConfigDir();
+ $globalPublicKey = file_get_contents($configDir.'/keys/id_rsa.pub');
+ $globalPrivateKey = file_get_contents($configDir.'/keys/id_rsa');
+
+ /* assert values from storage */
+ $this->assertEquals($storage->getPublicKey(), $globalPublicKey);
+ $this->assertEquals($storage->getPrivateKey(), $globalPrivateKey);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/RefreshTokenTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/RefreshTokenTest.php
new file mode 100644
index 000000000..314c93195
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/RefreshTokenTest.php
@@ -0,0 +1,41 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // assert token we are about to add does not exist
+ $token = $storage->getRefreshToken('refreshtoken');
+ $this->assertFalse($token);
+
+ // add new token
+ $expires = time() + 20;
+ $success = $storage->setRefreshToken('refreshtoken', 'client ID', 'SOMEUSERID', $expires);
+ $this->assertTrue($success);
+
+ $token = $storage->getRefreshToken('refreshtoken');
+ $this->assertNotNull($token);
+ $this->assertArrayHasKey('refresh_token', $token);
+ $this->assertArrayHasKey('client_id', $token);
+ $this->assertArrayHasKey('user_id', $token);
+ $this->assertArrayHasKey('expires', $token);
+ $this->assertEquals($token['refresh_token'], 'refreshtoken');
+ $this->assertEquals($token['client_id'], 'client ID');
+ $this->assertEquals($token['user_id'], 'SOMEUSERID');
+ $this->assertEquals($token['expires'], $expires);
+
+ // add token with scope having an empty string value
+ $expires = time() + 20;
+ $success = $storage->setRefreshToken('refreshtoken2', 'client ID', 'SOMEUSERID', $expires, '');
+ $this->assertTrue($success);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ScopeTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ScopeTest.php
new file mode 100644
index 000000000..fd1edeb93
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/ScopeTest.php
@@ -0,0 +1,53 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ if (!$storage instanceof ScopeInterface) {
+ // incompatible storage
+ return;
+ }
+
+ //Test getting scopes
+ $scopeUtil = new Scope($storage);
+ $this->assertTrue($scopeUtil->scopeExists('supportedscope1'));
+ $this->assertTrue($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3'));
+ $this->assertFalse($scopeUtil->scopeExists('fakescope'));
+ $this->assertFalse($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3 fakescope'));
+ }
+
+ /** @dataProvider provideStorage */
+ public function testGetDefaultScope($storage)
+ {
+ if ($storage instanceof NullStorage) {
+ $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ if (!$storage instanceof ScopeInterface) {
+ // incompatible storage
+ return;
+ }
+
+ // test getting default scope
+ $scopeUtil = new Scope($storage);
+ $expected = explode(' ', $scopeUtil->getDefaultScope());
+ $actual = explode(' ', 'defaultscope1 defaultscope2');
+ sort($expected);
+ sort($actual);
+ $this->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/UserCredentialsTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/UserCredentialsTest.php
new file mode 100644
index 000000000..65655a6b2
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/Storage/UserCredentialsTest.php
@@ -0,0 +1,40 @@
+markTestSkipped('Skipped Storage: ' . $storage->getMessage());
+
+ return;
+ }
+
+ // create a new user for testing
+ $success = $storage->setUser('testusername', 'testpass', 'Test', 'User');
+ $this->assertTrue($success);
+
+ // correct credentials
+ $this->assertTrue($storage->checkUserCredentials('testusername', 'testpass'));
+ // invalid password
+ $this->assertFalse($storage->checkUserCredentials('testusername', 'fakepass'));
+ // invalid username
+ $this->assertFalse($storage->checkUserCredentials('fakeusername', 'testpass'));
+
+ // invalid username
+ $this->assertFalse($storage->getUserDetails('fakeusername'));
+
+ // ensure all properties are set
+ $user = $storage->getUserDetails('testusername');
+ $this->assertTrue($user !== false);
+ $this->assertArrayHasKey('user_id', $user);
+ $this->assertArrayHasKey('first_name', $user);
+ $this->assertArrayHasKey('last_name', $user);
+ $this->assertEquals($user['user_id'], 'testusername');
+ $this->assertEquals($user['first_name'], 'Test');
+ $this->assertEquals($user['last_name'], 'User');
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/OAuth2/TokenType/BearerTest.php b/vendor/bshaffer/oauth2-server-php/test/OAuth2/TokenType/BearerTest.php
new file mode 100644
index 000000000..a2e000e22
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/OAuth2/TokenType/BearerTest.php
@@ -0,0 +1,58 @@
+ 'ThisIsMyAccessToken'
+ ));
+ $request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
+
+ $param = $bearer->getAccessTokenParameter($request, $response = new Response());
+ $this->assertEquals($param, 'ThisIsMyAccessToken');
+ }
+
+ public function testInvalidContentType()
+ {
+ $bearer = new Bearer();
+ $request = TestRequest::createPost(array(
+ 'access_token' => 'ThisIsMyAccessToken'
+ ));
+ $request->server['CONTENT_TYPE'] = 'application/json; charset=UTF-8';
+
+ $param = $bearer->getAccessTokenParameter($request, $response = new Response());
+ $this->assertNull($param);
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_request');
+ $this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
+ }
+
+ public function testValidRequestUsingAuthorizationHeader()
+ {
+ $bearer = new Bearer();
+ $request = new TestRequest();
+ $request->headers['AUTHORIZATION'] = 'Bearer MyToken';
+ $request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
+
+ $param = $bearer->getAccessTokenParameter($request, $response = new Response());
+ $this->assertEquals('MyToken', $param);
+ }
+
+ public function testValidRequestUsingAuthorizationHeaderCaseInsensitive()
+ {
+ $bearer = new Bearer();
+ $request = new TestRequest();
+ $request->server['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=UTF-8';
+ $request->headers['Authorization'] = 'Bearer MyToken';
+
+ $param = $bearer->getAccessTokenParameter($request, $response = new Response());
+ $this->assertEquals('MyToken', $param);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/bootstrap.php b/vendor/bshaffer/oauth2-server-php/test/bootstrap.php
new file mode 100644
index 000000000..0a4af0716
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/bootstrap.php
@@ -0,0 +1,12 @@
+cleanupTravisDynamoDb();
diff --git a/vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa b/vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa
new file mode 100644
index 000000000..e8b9eff2d
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLsNjP+uAt2eO0cc5J9H5XV
+8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdwizIum8j0KzpsGYH5qReN
+QDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJuBe+FQpZTs8DewwIDAQAB
+AoGARfNxNknmtx/n1bskZ/01iZRzAge6BLEE0LV6Q4gS7mkRZu/Oyiv39Sl5vUlA
++WdGxLjkBwKNjxGN8Vxw9/ASd8rSsqeAUYIwAeifXrHhj5DBPQT/pDPkeFnp9B1w
+C6jo+3AbBQ4/b0ONSIEnCL2xGGglSIAxO17T1ViXp7lzXPECQQDe63nkRdWM0OCb
+oaHQPT3E26224maIstrGFUdt9yw3yJf4bOF7TtiPLlLuHsTTge3z+fG6ntC0xG56
+1cl37C3ZAkEA2HdVcRGugNp/qmVz4LJTpD+WZKi73PLAO47wDOrYh9Pn2I6fcEH0
+CPnggt1ko4ujvGzFTvRH64HXa6aPCv1j+wJBAMQMah3VQPNf/DlDVFEUmw9XeBZg
+VHaifX851aEjgXLp6qVj9IYCmLiLsAmVa9rr6P7p8asD418nZlaHUHE0eDkCQQCr
+uxis6GMx1Ka971jcJX2X696LoxXPd0KsvXySMupv79yagKPa8mgBiwPjrnK+EPVo
+cj6iochA/bSCshP/mwFrAkBHEKPi6V6gb94JinCT7x3weahbdp6bJ6/nzBH/p9VA
+HoT1JtwNFhGv9BCjmDydshQHfSWpY9NxlccBKL7ITm8R
+-----END RSA PRIVATE KEY-----
\ No newline at end of file
diff --git a/vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa.pub b/vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa.pub
new file mode 100644
index 000000000..1ac15f5eb
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/config/keys/id_rsa.pub
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICiDCCAfGgAwIBAgIBADANBgkqhkiG9w0BAQQFADA9MQswCQYDVQQGEwJVUzEL
+MAkGA1UECBMCVVQxITAfBgNVBAoTGFZpZ25ldHRlIENvcnBvcmF0aW9uIFNCWDAe
+Fw0xMTEwMTUwMzE4MjdaFw0zMTEwMTAwMzE4MjdaMD0xCzAJBgNVBAYTAlVTMQsw
+CQYDVQQIEwJVVDEhMB8GA1UEChMYVmlnbmV0dGUgQ29ycG9yYXRpb24gU0JYMIGf
+MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLs
+NjP+uAt2eO0cc5J9H5XV8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdw
+izIum8j0KzpsGYH5qReNQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJu
+Be+FQpZTs8DewwIDAQABo4GXMIGUMB0GA1UdDgQWBBRe8hrEXm+Yim4YlD5Nx+1K
+vCYs9DBlBgNVHSMEXjBcgBRe8hrEXm+Yim4YlD5Nx+1KvCYs9KFBpD8wPTELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMSEwHwYDVQQKExhWaWduZXR0ZSBDb3Jwb3Jh
+dGlvbiBTQliCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBjhyRD
+lM7vnLn6drgQVftW5V9nDFAyPAuiGvMIKFSbiAf1PxXCRn5sfJquwWKsJUi4ZGNl
+aViXdFmN6/F13PSM+yg63tpKy0fYqMbTM+Oe5WuSHkSW1VuYNHV+24adgNk/FRDL
+FRrlM1f6s9VTLWvwGItjfrof0Ba8Uq7ZDSb9Xg==
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/vendor/bshaffer/oauth2-server-php/test/config/storage.json b/vendor/bshaffer/oauth2-server-php/test/config/storage.json
new file mode 100644
index 000000000..52d3f2399
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/config/storage.json
@@ -0,0 +1,188 @@
+{
+ "authorization_codes": {
+ "testcode": {
+ "client_id": "Test Client ID",
+ "user_id": "",
+ "redirect_uri": "",
+ "expires": "9999999999",
+ "id_token": "IDTOKEN"
+ },
+ "testcode-with-scope": {
+ "client_id": "Test Client ID",
+ "user_id": "",
+ "redirect_uri": "",
+ "expires": "9999999999",
+ "scope": "scope1 scope2"
+ },
+ "testcode-expired": {
+ "client_id": "Test Client ID",
+ "user_id": "",
+ "redirect_uri": "",
+ "expires": "1356998400"
+ },
+ "testcode-empty-secret": {
+ "client_id": "Test Client ID Empty Secret",
+ "user_id": "",
+ "redirect_uri": "",
+ "expires": "9999999999"
+ },
+ "testcode-openid": {
+ "client_id": "Test Client ID",
+ "user_id": "",
+ "redirect_uri": "",
+ "expires": "9999999999",
+ "id_token": "test_id_token"
+ },
+ "testcode-redirect-uri": {
+ "client_id": "Test Client ID",
+ "user_id": "",
+ "redirect_uri": "http://brentertainment.com/voil%C3%A0",
+ "expires": "9999999999",
+ "id_token": "IDTOKEN"
+ }
+ },
+ "client_credentials" : {
+ "Test Client ID": {
+ "client_secret": "TestSecret"
+ },
+ "Test Client ID with Redirect Uri": {
+ "client_secret": "TestSecret2",
+ "redirect_uri": "http://brentertainment.com"
+ },
+ "Test Client ID with Buggy Redirect Uri": {
+ "client_secret": "TestSecret2",
+ "redirect_uri": " http://brentertainment.com"
+ },
+ "Test Client ID with Multiple Redirect Uris": {
+ "client_secret": "TestSecret3",
+ "redirect_uri": "http://brentertainment.com http://morehazards.com"
+ },
+ "Test Client ID with Redirect Uri Parts": {
+ "client_secret": "TestSecret4",
+ "redirect_uri": "http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&test=true"
+ },
+ "Test Some Other Client": {
+ "client_secret": "TestSecret3"
+ },
+ "Test Client ID Empty Secret": {
+ "client_secret": ""
+ },
+ "Test Client ID For Password Grant": {
+ "grant_types": "password",
+ "client_secret": ""
+ },
+ "Client ID With User ID": {
+ "client_secret": "TestSecret",
+ "user_id": "brent@brentertainment.com"
+ },
+ "oauth_test_client": {
+ "client_secret": "testpass",
+ "grant_types": "implicit password"
+ }
+ },
+ "user_credentials" : {
+ "test-username": {
+ "password": "testpass"
+ },
+ "testusername": {
+ "password": "testpass"
+ },
+ "testuser": {
+ "password": "password",
+ "email": "testuser@test.com",
+ "email_verified": true
+ },
+ "johndoe": {
+ "password": "password"
+ }
+ },
+ "refresh_tokens" : {
+ "test-refreshtoken": {
+ "refresh_token": "test-refreshtoken",
+ "client_id": "Test Client ID",
+ "user_id": "test-username",
+ "expires": 0,
+ "scope": null
+ },
+ "test-refreshtoken-with-scope": {
+ "refresh_token": "test-refreshtoken",
+ "client_id": "Test Client ID",
+ "user_id": "test-username",
+ "expires": 0,
+ "scope": "scope1 scope2"
+ }
+ },
+ "access_tokens" : {
+ "accesstoken-expired": {
+ "access_token": "accesstoken-expired",
+ "client_id": "Test Client ID",
+ "expires": 1234567,
+ "scope": null
+ },
+ "accesstoken-scope": {
+ "access_token": "accesstoken-scope",
+ "client_id": "Test Client ID",
+ "expires": 99999999900,
+ "scope": "testscope"
+ },
+ "accesstoken-openid-connect": {
+ "access_token": "accesstoken-openid-connect",
+ "client_id": "Test Client ID",
+ "user_id": "testuser",
+ "expires": 99999999900,
+ "scope": "openid email"
+ },
+ "accesstoken-malformed": {
+ "access_token": "accesstoken-mallformed",
+ "expires": 99999999900,
+ "scope": "testscope"
+ }
+ },
+ "jwt": {
+ "Test Client ID": {
+ "key": "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5/SxVlE8gnpFqCxgl2wjhzY7u\ncEi00s0kUg3xp7lVEvgLgYcAnHiWp+gtSjOFfH2zsvpiWm6Lz5f743j/FEzHIO1o\nwR0p4d9pOaJK07d01+RzoQLOIQAgXrr4T1CCWUesncwwPBVCyy2Mw3Nmhmr9MrF8\nUlvdRKBxriRnlP3qJQIDAQAB\n-----END PUBLIC KEY-----",
+ "subject": "testuser@ourdomain.com"
+ },
+ "Test Client ID PHP-5.2": {
+ "key": "mysecretkey",
+ "subject": "testuser@ourdomain.com"
+ },
+ "Missing Key Client": {
+ "key": null,
+ "subject": "testuser@ourdomain.com"
+ },
+ "Missing Key Client PHP-5.2": {
+ "key": null,
+ "subject": "testuser@ourdomain.com"
+ },
+ "oauth_test_client": {
+ "key": "-----BEGIN CERTIFICATE-----\nMIICiDCCAfGgAwIBAgIBADANBgkqhkiG9w0BAQQFADA9MQswCQYDVQQGEwJVUzEL\nMAkGA1UECBMCVVQxITAfBgNVBAoTGFZpZ25ldHRlIENvcnBvcmF0aW9uIFNCWDAe\nFw0xMTEwMTUwMzE4MjdaFw0zMTEwMTAwMzE4MjdaMD0xCzAJBgNVBAYTAlVTMQsw\nCQYDVQQIEwJVVDEhMB8GA1UEChMYVmlnbmV0dGUgQ29ycG9yYXRpb24gU0JYMIGf\nMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLs\nNjP+uAt2eO0cc5J9H5XV8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdw\nizIum8j0KzpsGYH5qReNQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJu\nBe+FQpZTs8DewwIDAQABo4GXMIGUMB0GA1UdDgQWBBRe8hrEXm+Yim4YlD5Nx+1K\nvCYs9DBlBgNVHSMEXjBcgBRe8hrEXm+Yim4YlD5Nx+1KvCYs9KFBpD8wPTELMAkG\nA1UEBhMCVVMxCzAJBgNVBAgTAlVUMSEwHwYDVQQKExhWaWduZXR0ZSBDb3Jwb3Jh\ndGlvbiBTQliCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBjhyRD\nlM7vnLn6drgQVftW5V9nDFAyPAuiGvMIKFSbiAf1PxXCRn5sfJquwWKsJUi4ZGNl\naViXdFmN6/F13PSM+yg63tpKy0fYqMbTM+Oe5WuSHkSW1VuYNHV+24adgNk/FRDL\nFRrlM1f6s9VTLWvwGItjfrof0Ba8Uq7ZDSb9Xg==\n-----END CERTIFICATE-----",
+ "subject": "test_subject"
+ }
+ },
+ "jti": [
+ {
+ "issuer": "Test Client ID",
+ "subject": "testuser@ourdomain.com",
+ "audience": "http://myapp.com/oauth/auth",
+ "expires": 99999999900,
+ "jti": "used_jti"
+ }
+ ],
+ "supported_scopes" : [
+ "scope1",
+ "scope2",
+ "scope3",
+ "clientscope1",
+ "clientscope2",
+ "clientscope3",
+ "supportedscope1",
+ "supportedscope2",
+ "supportedscope3",
+ "supportedscope4"
+ ],
+ "keys": {
+ "public_key": "-----BEGIN CERTIFICATE-----\nMIICiDCCAfGgAwIBAgIBADANBgkqhkiG9w0BAQQFADA9MQswCQYDVQQGEwJVUzEL\nMAkGA1UECBMCVVQxITAfBgNVBAoTGFZpZ25ldHRlIENvcnBvcmF0aW9uIFNCWDAe\nFw0xMTEwMTUwMzE4MjdaFw0zMTEwMTAwMzE4MjdaMD0xCzAJBgNVBAYTAlVTMQsw\nCQYDVQQIEwJVVDEhMB8GA1UEChMYVmlnbmV0dGUgQ29ycG9yYXRpb24gU0JYMIGf\nMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLs\nNjP+uAt2eO0cc5J9H5XV8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdw\nizIum8j0KzpsGYH5qReNQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJu\nBe+FQpZTs8DewwIDAQABo4GXMIGUMB0GA1UdDgQWBBRe8hrEXm+Yim4YlD5Nx+1K\nvCYs9DBlBgNVHSMEXjBcgBRe8hrEXm+Yim4YlD5Nx+1KvCYs9KFBpD8wPTELMAkG\nA1UEBhMCVVMxCzAJBgNVBAgTAlVUMSEwHwYDVQQKExhWaWduZXR0ZSBDb3Jwb3Jh\ndGlvbiBTQliCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBjhyRD\nlM7vnLn6drgQVftW5V9nDFAyPAuiGvMIKFSbiAf1PxXCRn5sfJquwWKsJUi4ZGNl\naViXdFmN6/F13PSM+yg63tpKy0fYqMbTM+Oe5WuSHkSW1VuYNHV+24adgNk/FRDL\nFRrlM1f6s9VTLWvwGItjfrof0Ba8Uq7ZDSb9Xg==\n-----END CERTIFICATE-----",
+ "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQC8fpi06NfVYHAOAnxNMVnTXr/ptsLsNjP+uAt2eO0cc5J9H5XV\n8lFVujOrRu/JWi1TDmAvOaf/6A3BphIA1Pwp0AAqlZdwizIum8j0KzpsGYH5qReN\nQDwF3oUSKMsQCCGCDHrDYifG/pRi9bN1ZVjEXPr35HJuBe+FQpZTs8DewwIDAQAB\nAoGARfNxNknmtx/n1bskZ/01iZRzAge6BLEE0LV6Q4gS7mkRZu/Oyiv39Sl5vUlA\n+WdGxLjkBwKNjxGN8Vxw9/ASd8rSsqeAUYIwAeifXrHhj5DBPQT/pDPkeFnp9B1w\nC6jo+3AbBQ4/b0ONSIEnCL2xGGglSIAxO17T1ViXp7lzXPECQQDe63nkRdWM0OCb\noaHQPT3E26224maIstrGFUdt9yw3yJf4bOF7TtiPLlLuHsTTge3z+fG6ntC0xG56\n1cl37C3ZAkEA2HdVcRGugNp/qmVz4LJTpD+WZKi73PLAO47wDOrYh9Pn2I6fcEH0\nCPnggt1ko4ujvGzFTvRH64HXa6aPCv1j+wJBAMQMah3VQPNf/DlDVFEUmw9XeBZg\nVHaifX851aEjgXLp6qVj9IYCmLiLsAmVa9rr6P7p8asD418nZlaHUHE0eDkCQQCr\nuxis6GMx1Ka971jcJX2X696LoxXPd0KsvXySMupv79yagKPa8mgBiwPjrnK+EPVo\ncj6iochA/bSCshP/mwFrAkBHEKPi6V6gb94JinCT7x3weahbdp6bJ6/nzBH/p9VA\nHoT1JtwNFhGv9BCjmDydshQHfSWpY9NxlccBKL7ITm8R\n-----END RSA PRIVATE KEY-----"
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Request/TestRequest.php b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Request/TestRequest.php
new file mode 100644
index 000000000..7bbce28a4
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Request/TestRequest.php
@@ -0,0 +1,61 @@
+query = $_GET;
+ $this->request = $_POST;
+ $this->server = $_SERVER;
+ $this->headers = array();
+ }
+
+ public function query($name, $default = null)
+ {
+ return isset($this->query[$name]) ? $this->query[$name] : $default;
+ }
+
+ public function request($name, $default = null)
+ {
+ return isset($this->request[$name]) ? $this->request[$name] : $default;
+ }
+
+ public function server($name, $default = null)
+ {
+ return isset($this->server[$name]) ? $this->server[$name] : $default;
+ }
+
+ public function getAllQueryParameters()
+ {
+ return $this->query;
+ }
+
+ public function setQuery(array $query)
+ {
+ $this->query = $query;
+ }
+
+ public function setPost(array $params)
+ {
+ $this->server['REQUEST_METHOD'] = 'POST';
+ $this->request = $params;
+ }
+
+ public static function createPost(array $params = array())
+ {
+ $request = new self();
+ $request->setPost($params);
+
+ return $request;
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/BaseTest.php b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/BaseTest.php
new file mode 100755
index 000000000..f0b1274a2
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/BaseTest.php
@@ -0,0 +1,36 @@
+getMemoryStorage();
+ $sqlite = Bootstrap::getInstance()->getSqlitePdo();
+ $mysql = Bootstrap::getInstance()->getMysqlPdo();
+ $postgres = Bootstrap::getInstance()->getPostgresPdo();
+ $mongo = Bootstrap::getInstance()->getMongo();
+ $mongoDb = Bootstrap::getInstance()->getMongoDB();
+ $redis = Bootstrap::getInstance()->getRedisStorage();
+ $cassandra = Bootstrap::getInstance()->getCassandraStorage();
+ $dynamodb = Bootstrap::getInstance()->getDynamoDbStorage();
+ $couchbase = Bootstrap::getInstance()->getCouchbase();
+
+ /* hack until we can fix "default_scope" dependencies in other tests */
+ $memory->defaultScope = 'defaultscope1 defaultscope2';
+
+ return array(
+ array($memory),
+ array($sqlite),
+ array($mysql),
+ array($postgres),
+ array($mongo),
+ array($mongoDb),
+ array($redis),
+ array($cassandra),
+ array($dynamodb),
+ array($couchbase),
+ );
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/Bootstrap.php b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/Bootstrap.php
new file mode 100755
index 000000000..3d7bdd4e9
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/Bootstrap.php
@@ -0,0 +1,967 @@
+configDir = __DIR__.'/../../../config';
+ }
+
+ public static function getInstance()
+ {
+ if (!self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ public function getSqlitePdo()
+ {
+ if (!$this->sqlite) {
+ $this->removeSqliteDb();
+ $pdo = new \PDO(sprintf('sqlite://%s', $this->getSqliteDir()));
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $this->createSqliteDb($pdo);
+
+ $this->sqlite = new Pdo($pdo);
+ }
+
+ return $this->sqlite;
+ }
+
+ public function getPostgresPdo()
+ {
+ if (!$this->postgres) {
+ if (in_array('pgsql', \PDO::getAvailableDrivers())) {
+ $this->removePostgresDb();
+ $this->createPostgresDb();
+ if ($pdo = $this->getPostgresDriver()) {
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $this->populatePostgresDb($pdo);
+ $this->postgres = new Pdo($pdo);
+ }
+ } else {
+ $this->postgres = new NullStorage('Postgres', 'Missing postgres PDO extension.');
+ }
+ }
+
+ return $this->postgres;
+ }
+
+ public function getPostgresDriver()
+ {
+ try {
+ $pdo = new \PDO('pgsql:host=localhost;dbname=oauth2_server_php', 'postgres');
+
+ return $pdo;
+ } catch (\PDOException $e) {
+ $this->postgres = new NullStorage('Postgres', $e->getMessage());
+ }
+ }
+
+ public function getMemoryStorage()
+ {
+ return new Memory(json_decode(file_get_contents($this->configDir. '/storage.json'), true));
+ }
+
+ public function getRedisStorage()
+ {
+ if (!$this->redis) {
+ if (class_exists('Predis\Client')) {
+ $redis = new \Predis\Client();
+ if ($this->testRedisConnection($redis)) {
+ $redis->flushdb();
+ $this->redis = new Redis($redis);
+ $this->createRedisDb($this->redis);
+ } else {
+ $this->redis = new NullStorage('Redis', 'Unable to connect to redis server on port 6379');
+ }
+ } else {
+ $this->redis = new NullStorage('Redis', 'Missing redis library. Please run "composer.phar require predis/predis:dev-master"');
+ }
+ }
+
+ return $this->redis;
+ }
+
+ private function testRedisConnection(\Predis\Client $redis)
+ {
+ try {
+ $redis->connect();
+ } catch (\Predis\CommunicationException $exception) {
+ // we were unable to connect to the redis server
+ return false;
+ }
+
+ return true;
+ }
+
+ public function getMysqlPdo()
+ {
+ if (!$this->mysql) {
+ $pdo = null;
+ try {
+ $pdo = new \PDO('mysql:host=localhost;', 'root');
+ } catch (\PDOException $e) {
+ $this->mysql = new NullStorage('MySQL', 'Unable to connect to MySQL on root@localhost');
+ }
+
+ if ($pdo) {
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ $this->removeMysqlDb($pdo);
+ $this->createMysqlDb($pdo);
+
+ $this->mysql = new Pdo($pdo);
+ }
+ }
+
+ return $this->mysql;
+ }
+
+ public function getMongo()
+ {
+ if (!$this->mongo) {
+ if (class_exists('MongoClient')) {
+ $mongo = new \MongoClient('mongodb://localhost:27017', array('connect' => false));
+ if ($this->testMongoConnection($mongo)) {
+ $db = $mongo->oauth2_server_php_legacy;
+ $this->removeMongo($db);
+ $this->createMongo($db);
+
+ $this->mongo = new Mongo($db);
+ } else {
+ $this->mongo = new NullStorage('Mongo', 'Unable to connect to mongo server on "localhost:27017"');
+ }
+ } else {
+ $this->mongo = new NullStorage('Mongo', 'Missing mongo php extension. Please install mongo.so');
+ }
+ }
+
+ return $this->mongo;
+ }
+
+ public function getMongoDb()
+ {
+ if (!$this->mongoDb) {
+ if (class_exists('MongoDB\Client')) {
+ $mongoDb = new \MongoDB\Client('mongodb://localhost:27017');
+ if ($this->testMongoDBConnection($mongoDb)) {
+ $db = $mongoDb->oauth2_server_php;
+ $this->removeMongoDb($db);
+ $this->createMongoDb($db);
+
+ $this->mongoDb = new MongoDB($db);
+ } else {
+ $this->mongoDb = new NullStorage('MongoDB', 'Unable to connect to mongo server on "localhost:27017"');
+ }
+ } else {
+ $this->mongoDb = new NullStorage('MongoDB', 'Missing MongoDB php extension. Please install mongodb.so');
+ }
+ }
+
+ return $this->mongoDb;
+ }
+
+ private function testMongoConnection(\MongoClient $mongo)
+ {
+ try {
+ $mongo->connect();
+ } catch (\MongoConnectionException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private function testMongoDBConnection(\MongoDB\Client $mongo)
+ {
+ return true;
+ }
+
+ public function getCouchbase()
+ {
+ if (!$this->couchbase) {
+ if ($this->getEnvVar('SKIP_COUCHBASE_TESTS')) {
+ $this->couchbase = new NullStorage('Couchbase', 'Skipping Couchbase tests');
+ } elseif (!class_exists('Couchbase')) {
+ $this->couchbase = new NullStorage('Couchbase', 'Missing Couchbase php extension. Please install couchbase.so');
+ } else {
+ // round-about way to make sure couchbase is working
+ // this is required because it throws a "floating point exception" otherwise
+ $code = "new \Couchbase(array('localhost:8091'), '', '', 'auth', false);";
+ $exec = sprintf('php -r "%s"', $code);
+ $ret = exec($exec, $test, $var);
+ if ($ret != 0) {
+ $couchbase = new \Couchbase(array('localhost:8091'), '', '', 'auth', false);
+ if ($this->testCouchbaseConnection($couchbase)) {
+ $this->clearCouchbase($couchbase);
+ $this->createCouchbaseDB($couchbase);
+
+ $this->couchbase = new CouchbaseDB($couchbase);
+ } else {
+ $this->couchbase = new NullStorage('Couchbase', 'Unable to connect to Couchbase server on "localhost:8091"');
+ }
+ } else {
+ $this->couchbase = new NullStorage('Couchbase', 'Error while trying to connect to Couchbase');
+ }
+ }
+ }
+
+ return $this->couchbase;
+ }
+
+ private function testCouchbaseConnection(\Couchbase $couchbase)
+ {
+ try {
+ if (count($couchbase->getServers()) > 0) {
+ return true;
+ }
+ } catch (\CouchbaseException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function getCassandraStorage()
+ {
+ if (!$this->cassandra) {
+ if (class_exists('phpcassa\ColumnFamily')) {
+ $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_test', array('127.0.0.1:9160'));
+ if ($this->testCassandraConnection($cassandra)) {
+ $this->removeCassandraDb();
+ $this->cassandra = new Cassandra($cassandra);
+ $this->createCassandraDb($this->cassandra);
+ } else {
+ $this->cassandra = new NullStorage('Cassandra', 'Unable to connect to cassandra server on "127.0.0.1:9160"');
+ }
+ } else {
+ $this->cassandra = new NullStorage('Cassandra', 'Missing cassandra library. Please run "composer.phar require thobbs/phpcassa:dev-master"');
+ }
+ }
+
+ return $this->cassandra;
+ }
+
+ private function testCassandraConnection(\phpcassa\Connection\ConnectionPool $cassandra)
+ {
+ try {
+ new \phpcassa\SystemManager('localhost:9160');
+ } catch (\Exception $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private function removeCassandraDb()
+ {
+ $sys = new \phpcassa\SystemManager('localhost:9160');
+
+ try {
+ $sys->drop_keyspace('oauth2_test');
+ } catch (\cassandra\InvalidRequestException $e) {
+
+ }
+ }
+
+ private function createCassandraDb(Cassandra $storage)
+ {
+ // create the cassandra keyspace and column family
+ $sys = new \phpcassa\SystemManager('localhost:9160');
+
+ $sys->create_keyspace('oauth2_test', array(
+ "strategy_class" => \phpcassa\Schema\StrategyClass::SIMPLE_STRATEGY,
+ "strategy_options" => array('replication_factor' => '1')
+ ));
+
+ $sys->create_column_family('oauth2_test', 'auth');
+ $cassandra = new \phpcassa\Connection\ConnectionPool('oauth2_test', array('127.0.0.1:9160'));
+ $cf = new \phpcassa\ColumnFamily($cassandra, 'auth');
+
+ // populate the data
+ $storage->setClientDetails("oauth_test_client", "testpass", "http://example.com", 'implicit password');
+ $storage->setAccessToken("testtoken", "Some Client", '', time() + 1000);
+ $storage->setAuthorizationCode("testcode", "Some Client", '', '', time() + 1000);
+
+ $storage->setScope('supportedscope1 supportedscope2 supportedscope3 supportedscope4');
+ $storage->setScope('defaultscope1 defaultscope2', null, 'default');
+
+ $storage->setScope('clientscope1 clientscope2', 'Test Client ID');
+ $storage->setScope('clientscope1 clientscope2', 'Test Client ID', 'default');
+
+ $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Client ID 2');
+ $storage->setScope('clientscope1 clientscope2', 'Test Client ID 2', 'default');
+
+ $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID');
+ $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID', 'default');
+
+ $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Default Scope Client ID 2');
+ $storage->setScope('clientscope3', 'Test Default Scope Client ID 2', 'default');
+
+ $storage->setClientKey('oauth_test_client', $this->getTestPublicKey(), 'test_subject');
+
+ $cf->insert("oauth_public_keys:ClientID_One", array('__data' => json_encode(array("public_key" => "client_1_public", "private_key" => "client_1_private", "encryption_algorithm" => "RS256"))));
+ $cf->insert("oauth_public_keys:ClientID_Two", array('__data' => json_encode(array("public_key" => "client_2_public", "private_key" => "client_2_private", "encryption_algorithm" => "RS256"))));
+ $cf->insert("oauth_public_keys:", array('__data' => json_encode(array("public_key" => $this->getTestPublicKey(), "private_key" => $this->getTestPrivateKey(), "encryption_algorithm" => "RS256"))));
+
+ $cf->insert("oauth_users:testuser", array('__data' =>json_encode(array("password" => "password", "email" => "testuser@test.com", "email_verified" => true))));
+
+ }
+
+ private function createSqliteDb(\PDO $pdo)
+ {
+ $this->runPdoSql($pdo);
+ }
+
+ private function removeSqliteDb()
+ {
+ if (file_exists($this->getSqliteDir())) {
+ unlink($this->getSqliteDir());
+ }
+ }
+
+ private function createMysqlDb(\PDO $pdo)
+ {
+ $pdo->exec('CREATE DATABASE oauth2_server_php');
+ $pdo->exec('USE oauth2_server_php');
+ $this->runPdoSql($pdo);
+ }
+
+ private function removeMysqlDb(\PDO $pdo)
+ {
+ $pdo->exec('DROP DATABASE IF EXISTS oauth2_server_php');
+ }
+
+ private function createPostgresDb()
+ {
+ if (!`psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'"`) {
+ `createuser -s -r postgres`;
+ }
+
+ `createdb -O postgres oauth2_server_php`;
+ }
+
+ private function populatePostgresDb(\PDO $pdo)
+ {
+ $this->runPdoSql($pdo);
+ }
+
+ private function removePostgresDb()
+ {
+ if (trim(`psql -l | grep oauth2_server_php | wc -l`)) {
+ `dropdb oauth2_server_php`;
+ }
+ }
+
+ public function runPdoSql(\PDO $pdo)
+ {
+ $storage = new Pdo($pdo);
+ foreach (explode(';', $storage->getBuildSql()) as $statement) {
+ $result = $pdo->exec($statement);
+ }
+
+ // set up scopes
+ $sql = 'INSERT INTO oauth_scopes (scope) VALUES (?)';
+ foreach (explode(' ', 'supportedscope1 supportedscope2 supportedscope3 supportedscope4 clientscope1 clientscope2 clientscope3') as $supportedScope) {
+ $pdo->prepare($sql)->execute(array($supportedScope));
+ }
+
+ $sql = 'INSERT INTO oauth_scopes (scope, is_default) VALUES (?, ?)';
+ foreach (array('defaultscope1', 'defaultscope2') as $defaultScope) {
+ $pdo->prepare($sql)->execute(array($defaultScope, true));
+ }
+
+ // set up clients
+ $sql = 'INSERT INTO oauth_clients (client_id, client_secret, scope, grant_types) VALUES (?, ?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('Test Client ID', 'TestSecret', 'clientscope1 clientscope2', null));
+ $pdo->prepare($sql)->execute(array('Test Client ID 2', 'TestSecret', 'clientscope1 clientscope2 clientscope3', null));
+ $pdo->prepare($sql)->execute(array('Test Default Scope Client ID', 'TestSecret', 'clientscope1 clientscope2', null));
+ $pdo->prepare($sql)->execute(array('oauth_test_client', 'testpass', null, 'implicit password'));
+
+ // set up misc
+ $sql = 'INSERT INTO oauth_access_tokens (access_token, client_id, expires, user_id) VALUES (?, ?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('testtoken', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour')), null));
+ $pdo->prepare($sql)->execute(array('accesstoken-openid-connect', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour')), 'testuser'));
+
+ $sql = 'INSERT INTO oauth_authorization_codes (authorization_code, client_id, expires) VALUES (?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('testcode', 'Some Client', date('Y-m-d H:i:s', strtotime('+1 hour'))));
+
+ $sql = 'INSERT INTO oauth_users (username, password, email, email_verified) VALUES (?, ?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('testuser', 'password', 'testuser@test.com', true));
+
+ $sql = 'INSERT INTO oauth_public_keys (client_id, public_key, private_key, encryption_algorithm) VALUES (?, ?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('ClientID_One', 'client_1_public', 'client_1_private', 'RS256'));
+ $pdo->prepare($sql)->execute(array('ClientID_Two', 'client_2_public', 'client_2_private', 'RS256'));
+
+ $sql = 'INSERT INTO oauth_public_keys (client_id, public_key, private_key, encryption_algorithm) VALUES (?, ?, ?, ?)';
+ $pdo->prepare($sql)->execute(array(null, $this->getTestPublicKey(), $this->getTestPrivateKey(), 'RS256'));
+
+ $sql = 'INSERT INTO oauth_jwt (client_id, subject, public_key) VALUES (?, ?, ?)';
+ $pdo->prepare($sql)->execute(array('oauth_test_client', 'test_subject', $this->getTestPublicKey()));
+ }
+
+ public function getSqliteDir()
+ {
+ return $this->configDir. '/test.sqlite';
+ }
+
+ public function getConfigDir()
+ {
+ return $this->configDir;
+ }
+
+ private function createCouchbaseDB(\Couchbase $db)
+ {
+ $db->set('oauth_clients-oauth_test_client',json_encode(array(
+ 'client_id' => "oauth_test_client",
+ 'client_secret' => "testpass",
+ 'redirect_uri' => "http://example.com",
+ 'grant_types' => 'implicit password'
+ )));
+
+ $db->set('oauth_access_tokens-testtoken',json_encode(array(
+ 'access_token' => "testtoken",
+ 'client_id' => "Some Client"
+ )));
+
+ $db->set('oauth_authorization_codes-testcode',json_encode(array(
+ 'access_token' => "testcode",
+ 'client_id' => "Some Client"
+ )));
+
+ $db->set('oauth_users-testuser',json_encode(array(
+ 'username' => 'testuser',
+ 'password' => 'password',
+ 'email' => 'testuser@test.com',
+ 'email_verified' => true,
+ )));
+
+ $db->set('oauth_jwt-oauth_test_client',json_encode(array(
+ 'client_id' => 'oauth_test_client',
+ 'key' => $this->getTestPublicKey(),
+ 'subject' => 'test_subject',
+ )));
+ }
+
+ private function clearCouchbase(\Couchbase $cb)
+ {
+ $cb->delete('oauth_authorization_codes-new-openid-code');
+ $cb->delete('oauth_access_tokens-newtoken');
+ $cb->delete('oauth_authorization_codes-newcode');
+ $cb->delete('oauth_refresh_tokens-refreshtoken');
+ }
+
+ private function createMongo(\MongoDB $db)
+ {
+ $db->oauth_clients->insert(array(
+ 'client_id' => "oauth_test_client",
+ 'client_secret' => "testpass",
+ 'redirect_uri' => "http://example.com",
+ 'grant_types' => 'implicit password'
+ ));
+
+ $db->oauth_access_tokens->insert(array(
+ 'access_token' => "testtoken",
+ 'client_id' => "Some Client"
+ ));
+
+ $db->oauth_authorization_codes->insert(array(
+ 'authorization_code' => "testcode",
+ 'client_id' => "Some Client"
+ ));
+
+ $db->oauth_users->insert(array(
+ 'username' => 'testuser',
+ 'password' => 'password',
+ 'email' => 'testuser@test.com',
+ 'email_verified' => true,
+ ));
+
+ $db->oauth_keys->insert(array(
+ 'client_id' => null,
+ 'public_key' => $this->getTestPublicKey(),
+ 'private_key' => $this->getTestPrivateKey(),
+ 'encryption_algorithm' => 'RS256'
+ ));
+
+ $db->oauth_jwt->insert(array(
+ 'client_id' => 'oauth_test_client',
+ 'key' => $this->getTestPublicKey(),
+ 'subject' => 'test_subject',
+ ));
+ }
+
+ public function removeMongo(\MongoDB $db)
+ {
+ $db->drop();
+ }
+
+ private function createMongoDB(\MongoDB\Database $db)
+ {
+ $db->oauth_clients->insertOne(array(
+ 'client_id' => "oauth_test_client",
+ 'client_secret' => "testpass",
+ 'redirect_uri' => "http://example.com",
+ 'grant_types' => 'implicit password'
+ ));
+
+ $db->oauth_access_tokens->insertOne(array(
+ 'access_token' => "testtoken",
+ 'client_id' => "Some Client"
+ ));
+
+ $db->oauth_authorization_codes->insertOne(array(
+ 'authorization_code' => "testcode",
+ 'client_id' => "Some Client"
+ ));
+
+ $db->oauth_users->insertOne(array(
+ 'username' => 'testuser',
+ 'password' => 'password',
+ 'email' => 'testuser@test.com',
+ 'email_verified' => true,
+ ));
+
+ $db->oauth_keys->insertOne(array(
+ 'client_id' => null,
+ 'public_key' => $this->getTestPublicKey(),
+ 'private_key' => $this->getTestPrivateKey(),
+ 'encryption_algorithm' => 'RS256'
+ ));
+
+ $db->oauth_jwt->insertOne(array(
+ 'client_id' => 'oauth_test_client',
+ 'key' => $this->getTestPublicKey(),
+ 'subject' => 'test_subject',
+ ));
+ }
+
+ public function removeMongoDB(\MongoDB\Database $db)
+ {
+ $db->drop();
+ }
+
+ private function createRedisDb(Redis $storage)
+ {
+ $storage->setClientDetails("oauth_test_client", "testpass", "http://example.com", 'implicit password');
+ $storage->setAccessToken("testtoken", "Some Client", '', time() + 1000);
+ $storage->setAuthorizationCode("testcode", "Some Client", '', '', time() + 1000);
+ $storage->setUser("testuser", "password");
+
+ $storage->setScope('supportedscope1 supportedscope2 supportedscope3 supportedscope4');
+ $storage->setScope('defaultscope1 defaultscope2', null, 'default');
+
+ $storage->setScope('clientscope1 clientscope2', 'Test Client ID');
+ $storage->setScope('clientscope1 clientscope2', 'Test Client ID', 'default');
+
+ $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Client ID 2');
+ $storage->setScope('clientscope1 clientscope2', 'Test Client ID 2', 'default');
+
+ $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID');
+ $storage->setScope('clientscope1 clientscope2', 'Test Default Scope Client ID', 'default');
+
+ $storage->setScope('clientscope1 clientscope2 clientscope3', 'Test Default Scope Client ID 2');
+ $storage->setScope('clientscope3', 'Test Default Scope Client ID 2', 'default');
+
+ $storage->setClientKey('oauth_test_client', $this->getTestPublicKey(), 'test_subject');
+ }
+
+ public function getTestPublicKey()
+ {
+ return file_get_contents(__DIR__.'/../../../config/keys/id_rsa.pub');
+ }
+
+ private function getTestPrivateKey()
+ {
+ return file_get_contents(__DIR__.'/../../../config/keys/id_rsa');
+ }
+
+ public function getDynamoDbStorage()
+ {
+ if (!$this->dynamodb) {
+ // only run once per travis build
+ if (true == $this->getEnvVar('TRAVIS')) {
+ if (self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
+ $this->dynamodb = new NullStorage('DynamoDb', 'Skipping for travis.ci - only run once per build');
+
+ return;
+ }
+ }
+ if (class_exists('\Aws\DynamoDb\DynamoDbClient')) {
+ if ($client = $this->getDynamoDbClient()) {
+ // travis runs a unique set of tables per build, to avoid conflict
+ $prefix = '';
+ if ($build_id = $this->getEnvVar('TRAVIS_JOB_NUMBER')) {
+ $prefix = sprintf('build_%s_', $build_id);
+ } else {
+ if (!$this->deleteDynamoDb($client, $prefix, true)) {
+ return $this->dynamodb = new NullStorage('DynamoDb', 'Timed out while waiting for DynamoDB deletion (30 seconds)');
+ }
+ }
+ $this->createDynamoDb($client, $prefix);
+ $this->populateDynamoDb($client, $prefix);
+ $config = array(
+ 'client_table' => $prefix.'oauth_clients',
+ 'access_token_table' => $prefix.'oauth_access_tokens',
+ 'refresh_token_table' => $prefix.'oauth_refresh_tokens',
+ 'code_table' => $prefix.'oauth_authorization_codes',
+ 'user_table' => $prefix.'oauth_users',
+ 'jwt_table' => $prefix.'oauth_jwt',
+ 'scope_table' => $prefix.'oauth_scopes',
+ 'public_key_table' => $prefix.'oauth_public_keys',
+ );
+ $this->dynamodb = new DynamoDB($client, $config);
+ } elseif (!$this->dynamodb) {
+ $this->dynamodb = new NullStorage('DynamoDb', 'unable to connect to DynamoDB');
+ }
+ } else {
+ $this->dynamodb = new NullStorage('DynamoDb', 'Missing DynamoDB library. Please run "composer.phar require aws/aws-sdk-php:dev-master');
+ }
+ }
+
+ return $this->dynamodb;
+ }
+
+ private function getDynamoDbClient()
+ {
+ $config = array();
+ // check for environment variables
+ if (($key = $this->getEnvVar('AWS_ACCESS_KEY_ID')) && ($secret = $this->getEnvVar('AWS_SECRET_KEY'))) {
+ $config['key'] = $key;
+ $config['secret'] = $secret;
+ } else {
+ // fall back on ~/.aws/credentials file
+ // @see http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html#credential-profiles
+ if (!file_exists($this->getEnvVar('HOME') . '/.aws/credentials')) {
+ $this->dynamodb = new NullStorage('DynamoDb', 'No aws credentials file found, and no AWS_ACCESS_KEY_ID or AWS_SECRET_KEY environment variable set');
+
+ return;
+ }
+
+ // set profile in AWS_PROFILE environment variable, defaults to "default"
+ $config['profile'] = $this->getEnvVar('AWS_PROFILE', 'default');
+ }
+
+ // set region in AWS_REGION environment variable, defaults to "us-east-1"
+ $config['region'] = $this->getEnvVar('AWS_REGION', \Aws\Common\Enum\Region::US_EAST_1);
+
+ return \Aws\DynamoDb\DynamoDbClient::factory($config);
+ }
+
+ private function deleteDynamoDb(\Aws\DynamoDb\DynamoDbClient $client, $prefix = null, $waitForDeletion = false)
+ {
+ $tablesList = explode(' ', 'oauth_access_tokens oauth_authorization_codes oauth_clients oauth_jwt oauth_public_keys oauth_refresh_tokens oauth_scopes oauth_users');
+ $nbTables = count($tablesList);
+
+ // Delete all table.
+ foreach ($tablesList as $key => $table) {
+ try {
+ $client->deleteTable(array('TableName' => $prefix.$table));
+ } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
+ // Table does not exist : nothing to do
+ }
+ }
+
+ // Wait for deleting
+ if ($waitForDeletion) {
+ $retries = 5;
+ $nbTableDeleted = 0;
+ while ($nbTableDeleted != $nbTables) {
+ $nbTableDeleted = 0;
+ foreach ($tablesList as $key => $table) {
+ try {
+ $result = $client->describeTable(array('TableName' => $prefix.$table));
+ } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
+ // Table does not exist : nothing to do
+ $nbTableDeleted++;
+ }
+ }
+ if ($nbTableDeleted != $nbTables) {
+ if ($retries < 0) {
+ // we are tired of waiting
+ return false;
+ }
+ sleep(5);
+ echo "Sleeping 5 seconds for DynamoDB ($retries more retries)...\n";
+ $retries--;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private function createDynamoDb(\Aws\DynamoDb\DynamoDbClient $client, $prefix = null)
+ {
+ $tablesList = explode(' ', 'oauth_access_tokens oauth_authorization_codes oauth_clients oauth_jwt oauth_public_keys oauth_refresh_tokens oauth_scopes oauth_users');
+ $nbTables = count($tablesList);
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_access_tokens',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'access_token','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'access_token','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_authorization_codes',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'authorization_code','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'authorization_code','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'client_id','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'client_id','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_jwt',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'client_id','AttributeType' => 'S'),
+ array('AttributeName' => 'subject','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(
+ array('AttributeName' => 'client_id','KeyType' => 'HASH'),
+ array('AttributeName' => 'subject','KeyType' => 'RANGE')
+ ),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'client_id','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'client_id','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_refresh_tokens',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'refresh_token','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'refresh_token','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_scopes',
+ 'AttributeDefinitions' => array(
+ array('AttributeName' => 'scope','AttributeType' => 'S'),
+ array('AttributeName' => 'is_default','AttributeType' => 'S')
+ ),
+ 'KeySchema' => array(array('AttributeName' => 'scope','KeyType' => 'HASH')),
+ 'GlobalSecondaryIndexes' => array(
+ array(
+ 'IndexName' => 'is_default-index',
+ 'KeySchema' => array(array('AttributeName' => 'is_default', 'KeyType' => 'HASH')),
+ 'Projection' => array('ProjectionType' => 'ALL'),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ),
+ ),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ $client->createTable(array(
+ 'TableName' => $prefix.'oauth_users',
+ 'AttributeDefinitions' => array(array('AttributeName' => 'username','AttributeType' => 'S')),
+ 'KeySchema' => array(array('AttributeName' => 'username','KeyType' => 'HASH')),
+ 'ProvisionedThroughput' => array('ReadCapacityUnits' => 1,'WriteCapacityUnits' => 1)
+ ));
+
+ // Wait for creation
+ $nbTableCreated = 0;
+ while ($nbTableCreated != $nbTables) {
+ $nbTableCreated = 0;
+ foreach ($tablesList as $key => $table) {
+ try {
+ $result = $client->describeTable(array('TableName' => $prefix.$table));
+ if ($result['Table']['TableStatus'] == 'ACTIVE') {
+ $nbTableCreated++;
+ }
+ } catch (\Aws\DynamoDb\Exception\DynamoDbException $e) {
+ // Table does not exist : nothing to do
+ $nbTableCreated++;
+ }
+ }
+ if ($nbTableCreated != $nbTables) {
+ sleep(1);
+ }
+ }
+ }
+
+ private function populateDynamoDb($client, $prefix = null)
+ {
+ // set up scopes
+ foreach (explode(' ', 'supportedscope1 supportedscope2 supportedscope3 supportedscope4 clientscope1 clientscope2 clientscope3') as $supportedScope) {
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_scopes',
+ 'Item' => array('scope' => array('S' => $supportedScope))
+ ));
+ }
+
+ foreach (array('defaultscope1', 'defaultscope2') as $defaultScope) {
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_scopes',
+ 'Item' => array('scope' => array('S' => $defaultScope), 'is_default' => array('S' => "true"))
+ ));
+ }
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'Test Client ID'),
+ 'client_secret' => array('S' => 'TestSecret'),
+ 'scope' => array('S' => 'clientscope1 clientscope2')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'Test Client ID 2'),
+ 'client_secret' => array('S' => 'TestSecret'),
+ 'scope' => array('S' => 'clientscope1 clientscope2 clientscope3')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'Test Default Scope Client ID'),
+ 'client_secret' => array('S' => 'TestSecret'),
+ 'scope' => array('S' => 'clientscope1 clientscope2')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_clients',
+ 'Item' => array(
+ 'client_id' => array('S' => 'oauth_test_client'),
+ 'client_secret' => array('S' => 'testpass'),
+ 'grant_types' => array('S' => 'implicit password')
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_access_tokens',
+ 'Item' => array(
+ 'access_token' => array('S' => 'testtoken'),
+ 'client_id' => array('S' => 'Some Client'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_access_tokens',
+ 'Item' => array(
+ 'access_token' => array('S' => 'accesstoken-openid-connect'),
+ 'client_id' => array('S' => 'Some Client'),
+ 'user_id' => array('S' => 'testuser'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_authorization_codes',
+ 'Item' => array(
+ 'authorization_code' => array('S' => 'testcode'),
+ 'client_id' => array('S' => 'Some Client'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_users',
+ 'Item' => array(
+ 'username' => array('S' => 'testuser'),
+ 'password' => array('S' => 'password'),
+ 'email' => array('S' => 'testuser@test.com'),
+ 'email_verified' => array('S' => 'true'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'Item' => array(
+ 'client_id' => array('S' => 'ClientID_One'),
+ 'public_key' => array('S' => 'client_1_public'),
+ 'private_key' => array('S' => 'client_1_private'),
+ 'encryption_algorithm' => array('S' => 'RS256'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'Item' => array(
+ 'client_id' => array('S' => 'ClientID_Two'),
+ 'public_key' => array('S' => 'client_2_public'),
+ 'private_key' => array('S' => 'client_2_private'),
+ 'encryption_algorithm' => array('S' => 'RS256'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_public_keys',
+ 'Item' => array(
+ 'client_id' => array('S' => '0'),
+ 'public_key' => array('S' => $this->getTestPublicKey()),
+ 'private_key' => array('S' => $this->getTestPrivateKey()),
+ 'encryption_algorithm' => array('S' => 'RS256'),
+ )
+ ));
+
+ $client->putItem(array(
+ 'TableName' => $prefix.'oauth_jwt',
+ 'Item' => array(
+ 'client_id' => array('S' => 'oauth_test_client'),
+ 'subject' => array('S' => 'test_subject'),
+ 'public_key' => array('S' => $this->getTestPublicKey()),
+ )
+ ));
+ }
+
+ public function cleanupTravisDynamoDb($prefix = null)
+ {
+ if (is_null($prefix)) {
+ // skip this when not applicable
+ if (!$this->getEnvVar('TRAVIS') || self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
+ return;
+ }
+
+ $prefix = sprintf('build_%s_', $this->getEnvVar('TRAVIS_JOB_NUMBER'));
+ }
+
+ $client = $this->getDynamoDbClient();
+ $this->deleteDynamoDb($client, $prefix);
+ }
+
+ private function getEnvVar($var, $default = null)
+ {
+ return isset($_SERVER[$var]) ? $_SERVER[$var] : (getenv($var) ?: $default);
+ }
+}
diff --git a/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/NullStorage.php b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/NullStorage.php
new file mode 100644
index 000000000..6caa62068
--- /dev/null
+++ b/vendor/bshaffer/oauth2-server-php/test/lib/OAuth2/Storage/NullStorage.php
@@ -0,0 +1,32 @@
+name = $name;
+ $this->description = $description;
+ }
+
+ public function __toString()
+ {
+ return $this->name;
+ }
+
+ public function getMessage()
+ {
+ if ($this->description) {
+ return $this->description;
+ }
+
+ return $this->name;
+ }
+}
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
index 4626994fd..ff6ecfb82 100644
--- a/vendor/composer/ClassLoader.php
+++ b/vendor/composer/ClassLoader.php
@@ -53,9 +53,8 @@ class ClassLoader
private $useIncludePath = false;
private $classMap = array();
+
private $classMapAuthoritative = false;
- private $missingClasses = array();
- private $apcuPrefix;
public function getPrefixes()
{
@@ -272,26 +271,6 @@ class ClassLoader
return $this->classMapAuthoritative;
}
- /**
- * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
- *
- * @param string|null $apcuPrefix
- */
- public function setApcuPrefix($apcuPrefix)
- {
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
- }
-
- /**
- * The APCu prefix in use, or null if APCu caching is not enabled.
- *
- * @return string|null
- */
- public function getApcuPrefix()
- {
- return $this->apcuPrefix;
- }
-
/**
* Registers this instance as an autoloader.
*
@@ -334,34 +313,29 @@ class ClassLoader
*/
public function findFile($class)
{
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+ if ('\\' == $class[0]) {
+ $class = substr($class, 1);
+ }
+
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
- if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ if ($this->classMapAuthoritative) {
return false;
}
- if (null !== $this->apcuPrefix) {
- $file = apcu_fetch($this->apcuPrefix.$class, $hit);
- if ($hit) {
- return $file;
- }
- }
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
- if (false === $file && defined('HHVM_VERSION')) {
+ if ($file === null && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
- if (null !== $this->apcuPrefix) {
- apcu_add($this->apcuPrefix.$class, $file);
- }
-
- if (false === $file) {
+ if ($file === null) {
// Remember that this class does not exist.
- $this->missingClasses[$class] = true;
+ return $this->classMap[$class] = false;
}
return $file;
@@ -425,8 +399,6 @@ class ClassLoader
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
-
- return false;
}
}
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
index 1a2812488..ee274f1d3 100644
--- a/vendor/composer/LICENSE
+++ b/vendor/composer/LICENSE
@@ -1,21 +1,433 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: Composer
+Upstream-Contact: Jordi Boggiano
+Source: https://github.com/composer/composer
-Copyright (c) 2016 Nils Adermann, Jordi Boggiano
+Files: *
+Copyright: 2016, Nils Adermann
+ 2016, Jordi Boggiano
+License: Expat
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
+Files: res/cacert.pem
+Copyright: 2015, Mozilla Foundation
+License: MPL-2.0
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+Files: src/Composer/Util/RemoteFilesystem.php
+ src/Composer/Util/TlsHelper.php
+Copyright: 2016, Nils Adermann
+ 2016, Jordi Boggiano
+ 2013, Evan Coury
+License: Expat and BSD-2-Clause
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+License: BSD-2-Clause
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+ .
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ .
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is furnished
+ to do so, subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+License: MPL-2.0
+ 1. Definitions
+ --------------
+ .
+ 1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+ .
+ 1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+ .
+ 1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+ .
+ 1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+ .
+ 1.5. "Incompatible With Secondary Licenses"
+ means
+ .
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+ .
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+ .
+ 1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+ .
+ 1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+ .
+ 1.8. "License"
+ means this document.
+ .
+ 1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+ .
+ 1.10. "Modifications"
+ means any of the following:
+ .
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+ .
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+ .
+ 1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+ .
+ 1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+ .
+ 1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+ .
+ 1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+ .
+ 2. License Grants and Conditions
+ --------------------------------
+ .
+ 2.1. Grants
+ .
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+ .
+ (a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+ .
+ (b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+ .
+ 2.2. Effective Date
+ .
+ The licenses granted in Section 2.1 with respect to any Contribution
+ become effective for each Contribution on the date the Contributor first
+ distributes such Contribution.
+ .
+ 2.3. Limitations on Grant Scope
+ .
+ The licenses granted in this Section 2 are the only rights granted under
+ this License. No additional rights or licenses will be implied from the
+ distribution or licensing of Covered Software under this License.
+ Notwithstanding Section 2.1(b) above, no patent license is granted by a
+ Contributor:
+ .
+ (a) for any code that a Contributor has removed from Covered Software;
+ or
+ .
+ (b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+ .
+ (c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+ .
+ This License does not grant any rights in the trademarks, service marks,
+ or logos of any Contributor (except as may be necessary to comply with
+ the notice requirements in Section 3.4).
+ .
+ 2.4. Subsequent Licenses
+ .
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this
+ License (see Section 10.2) or under the terms of a Secondary License (if
+ permitted under the terms of Section 3.3).
+ .
+ 2.5. Representation
+ .
+ Each Contributor represents that the Contributor believes its
+ Contributions are its original creation(s) or it has sufficient rights
+ to grant the rights to its Contributions conveyed by this License.
+ .
+ 2.6. Fair Use
+ .
+ This License is not intended to limit any rights You have under
+ applicable copyright doctrines of fair use, fair dealing, or other
+ equivalents.
+ .
+ 2.7. Conditions
+ .
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+ in Section 2.1.
+ .
+ 3. Responsibilities
+ -------------------
+ .
+ 3.1. Distribution of Source Form
+ .
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under
+ the terms of this License. You must inform recipients that the Source
+ Code Form of the Covered Software is governed by the terms of this
+ License, and how they can obtain a copy of this License. You may not
+ attempt to alter or restrict the recipients' rights in the Source Code
+ Form.
+ .
+ 3.2. Distribution of Executable Form
+ .
+ If You distribute Covered Software in Executable Form then:
+ .
+ (a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+ .
+ (b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+ .
+ 3.3. Distribution of a Larger Work
+ .
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for
+ the Covered Software. If the Larger Work is a combination of Covered
+ Software with a work governed by one or more Secondary Licenses, and the
+ Covered Software is not Incompatible With Secondary Licenses, this
+ License permits You to additionally distribute such Covered Software
+ under the terms of such Secondary License(s), so that the recipient of
+ the Larger Work may, at their option, further distribute the Covered
+ Software under the terms of either this License or such Secondary
+ License(s).
+ .
+ 3.4. Notices
+ .
+ You may not remove or alter the substance of any license notices
+ (including copyright notices, patent notices, disclaimers of warranty,
+ or limitations of liability) contained within the Source Code Form of
+ the Covered Software, except that You may alter any license notices to
+ the extent required to remedy known factual inaccuracies.
+ .
+ 3.5. Application of Additional Terms
+ .
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on
+ behalf of any Contributor. You must make it absolutely clear that any
+ such warranty, support, indemnity, or liability obligation is offered by
+ You alone, and You hereby agree to indemnify every Contributor for any
+ liability incurred by such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer. You may include additional
+ disclaimers of warranty and limitations of liability specific to any
+ jurisdiction.
+ .
+ 4. Inability to Comply Due to Statute or Regulation
+ ---------------------------------------------------
+ .
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Software due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description must
+ be placed in a text file included with all distributions of the Covered
+ Software under this License. Except to the extent prohibited by statute
+ or regulation, such description must be sufficiently detailed for a
+ recipient of ordinary skill to be able to understand it.
+ .
+ 5. Termination
+ --------------
+ .
+ 5.1. The rights granted under this License will terminate automatically
+ if You fail to comply with any of its terms. However, if You become
+ compliant, then the rights granted under this License from a particular
+ Contributor are reinstated (a) provisionally, unless and until such
+ Contributor explicitly and finally terminates Your grants, and (b) on an
+ ongoing basis, if such Contributor fails to notify You of the
+ non-compliance by some reasonable means prior to 60 days after You have
+ come back into compliance. Moreover, Your grants from a particular
+ Contributor are reinstated on an ongoing basis if such Contributor
+ notifies You of the non-compliance by some reasonable means, this is the
+ first time You have received notice of non-compliance with this License
+ from such Contributor, and You become compliant prior to 30 days after
+ Your receipt of the notice.
+ .
+ 5.2. If You initiate litigation against any entity by asserting a patent
+ infringement claim (excluding declaratory judgment actions,
+ counter-claims, and cross-claims) alleging that a Contributor Version
+ directly or indirectly infringes any patent, then the rights granted to
+ You by any and all Contributors for the Covered Software under Section
+ 2.1 of this License shall terminate.
+ .
+ 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+ end user license agreements (excluding distributors and resellers) which
+ have been validly granted by You or Your distributors under this License
+ prior to termination shall survive termination.
+ .
+ ************************************************************************
+ * *
+ * 6. Disclaimer of Warranty *
+ * ------------------------- *
+ * *
+ * Covered Software is provided under this License on an "as is" *
+ * basis, without warranty of any kind, either expressed, implied, or *
+ * statutory, including, without limitation, warranties that the *
+ * Covered Software is free of defects, merchantable, fit for a *
+ * particular purpose or non-infringing. The entire risk as to the *
+ * quality and performance of the Covered Software is with You. *
+ * Should any Covered Software prove defective in any respect, You *
+ * (not any Contributor) assume the cost of any necessary servicing, *
+ * repair, or correction. This disclaimer of warranty constitutes an *
+ * essential part of this License. No use of any Covered Software is *
+ * authorized under this License except under this disclaimer. *
+ * *
+ ************************************************************************
+ .
+ ************************************************************************
+ * *
+ * 7. Limitation of Liability *
+ * -------------------------- *
+ * *
+ * Under no circumstances and under no legal theory, whether tort *
+ * (including negligence), contract, or otherwise, shall any *
+ * Contributor, or anyone who distributes Covered Software as *
+ * permitted above, be liable to You for any direct, indirect, *
+ * special, incidental, or consequential damages of any character *
+ * including, without limitation, damages for lost profits, loss of *
+ * goodwill, work stoppage, computer failure or malfunction, or any *
+ * and all other commercial damages or losses, even if such party *
+ * shall have been informed of the possibility of such damages. This *
+ * limitation of liability shall not apply to liability for death or *
+ * personal injury resulting from such party's negligence to the *
+ * extent applicable law prohibits such limitation. Some *
+ * jurisdictions do not allow the exclusion or limitation of *
+ * incidental or consequential damages, so this exclusion and *
+ * limitation may not apply to You. *
+ * *
+ ************************************************************************
+ .
+ 8. Litigation
+ -------------
+ .
+ Any litigation relating to this License may be brought only in the
+ courts of a jurisdiction where the defendant maintains its principal
+ place of business and such litigation shall be governed by laws of that
+ jurisdiction, without reference to its conflict-of-law provisions.
+ Nothing in this Section shall prevent a party's ability to bring
+ cross-claims or counter-claims.
+ .
+ 9. Miscellaneous
+ ----------------
+ .
+ This License represents the complete agreement concerning the subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. Any law or regulation which provides
+ that the language of a contract shall be construed against the drafter
+ shall not be used to construe this License against a Contributor.
+ .
+ 10. Versions of the License
+ ---------------------------
+ .
+ 10.1. New Versions
+ .
+ Mozilla Foundation is the license steward. Except as provided in Section
+ 10.3, no one other than the license steward has the right to modify or
+ publish new versions of this License. Each version will be given a
+ distinguishing version number.
+ .
+ 10.2. Effect of New Versions
+ .
+ You may distribute the Covered Software under the terms of the version
+ of the License under which You originally received the Covered Software,
+ or under the terms of any subsequent version published by the license
+ steward.
+ .
+ 10.3. Modified Versions
+ .
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a
+ modified version of this License if you rename the license and remove
+ any references to the name of the license steward (except to note that
+ such modified license differs from this License).
+ .
+ 10.4. Distributing Source Code Form that is Incompatible With Secondary
+ Licenses
+ .
+ If You choose to distribute Source Code Form that is Incompatible With
+ Secondary Licenses under the terms of this version of the License, the
+ notice described in Exhibit B of this License must be attached.
+ .
+ Exhibit A - Source Code Form License Notice
+ -------------------------------------------
+ .
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ .
+ If it is not possible or desirable to put the notice in a particular
+ file, then You may include the notice in a location (such as a LICENSE
+ file in a relevant directory) where a recipient would be likely to look
+ for such a notice.
+ .
+ You may add additional accurate notices of copyright ownership.
+ .
+ Exhibit B - "Incompatible With Secondary Licenses" Notice
+ ---------------------------------------------------------
+ .
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index 2adb2fe53..7a91153b0 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -6,623 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
- 'Hubzilla\\Import\\Import' => $baseDir . '/include/Import/Importer.php',
- 'Markdownify\\Converter' => $vendorDir . '/pixel418/markdownify/src/Converter.php',
- 'Markdownify\\ConverterExtra' => $vendorDir . '/pixel418/markdownify/src/ConverterExtra.php',
- 'Markdownify\\Parser' => $vendorDir . '/pixel418/markdownify/src/Parser.php',
- 'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php',
- 'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php',
- 'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php',
- 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
- 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
- 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
- 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
- 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
- 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
- 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
- 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
- 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
- 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
- 'Sabre\\CalDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php',
- 'Sabre\\CalDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php',
- 'Sabre\\CalDAV\\Backend\\NotificationSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php',
- 'Sabre\\CalDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/PDO.php',
- 'Sabre\\CalDAV\\Backend\\SchedulingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php',
- 'Sabre\\CalDAV\\Backend\\SharingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SharingSupport.php',
- 'Sabre\\CalDAV\\Backend\\SimplePDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SimplePDO.php',
- 'Sabre\\CalDAV\\Backend\\SubscriptionSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php',
- 'Sabre\\CalDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SyncSupport.php',
- 'Sabre\\CalDAV\\Calendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Calendar.php',
- 'Sabre\\CalDAV\\CalendarHome' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarHome.php',
- 'Sabre\\CalDAV\\CalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarObject.php',
- 'Sabre\\CalDAV\\CalendarQueryValidator' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarQueryValidator.php',
- 'Sabre\\CalDAV\\CalendarRoot' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarRoot.php',
- 'Sabre\\CalDAV\\Exception\\InvalidComponentType' => $vendorDir . '/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php',
- 'Sabre\\CalDAV\\ICSExportPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/ICSExportPlugin.php',
- 'Sabre\\CalDAV\\ICalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendar.php',
- 'Sabre\\CalDAV\\ICalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObject.php',
- 'Sabre\\CalDAV\\ICalendarObjectContainer' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php',
- 'Sabre\\CalDAV\\ISharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ISharedCalendar.php',
- 'Sabre\\CalDAV\\Notifications\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Collection.php',
- 'Sabre\\CalDAV\\Notifications\\ICollection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/ICollection.php',
- 'Sabre\\CalDAV\\Notifications\\INode' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/INode.php',
- 'Sabre\\CalDAV\\Notifications\\Node' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Node.php',
- 'Sabre\\CalDAV\\Notifications\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Plugin.php',
- 'Sabre\\CalDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Plugin.php',
- 'Sabre\\CalDAV\\Principal\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/Collection.php',
- 'Sabre\\CalDAV\\Principal\\IProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyRead.php',
- 'Sabre\\CalDAV\\Principal\\IProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyWrite.php',
- 'Sabre\\CalDAV\\Principal\\ProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyRead.php',
- 'Sabre\\CalDAV\\Principal\\ProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php',
- 'Sabre\\CalDAV\\Principal\\User' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/User.php',
- 'Sabre\\CalDAV\\Schedule\\IInbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IInbox.php',
- 'Sabre\\CalDAV\\Schedule\\IMipPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php',
- 'Sabre\\CalDAV\\Schedule\\IOutbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IOutbox.php',
- 'Sabre\\CalDAV\\Schedule\\ISchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/ISchedulingObject.php',
- 'Sabre\\CalDAV\\Schedule\\Inbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Inbox.php',
- 'Sabre\\CalDAV\\Schedule\\Outbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Outbox.php',
- 'Sabre\\CalDAV\\Schedule\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Plugin.php',
- 'Sabre\\CalDAV\\Schedule\\SchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php',
- 'Sabre\\CalDAV\\SharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/SharedCalendar.php',
- 'Sabre\\CalDAV\\SharingPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/SharingPlugin.php',
- 'Sabre\\CalDAV\\Subscriptions\\ISubscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php',
- 'Sabre\\CalDAV\\Subscriptions\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php',
- 'Sabre\\CalDAV\\Subscriptions\\Subscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\NotificationInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\SystemStatus' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php',
- 'Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php',
- 'Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php',
- 'Sabre\\CalDAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/Invite.php',
- 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php',
- 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php',
- 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php',
- 'Sabre\\CalDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php',
- 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php',
- 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php',
- 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php',
- 'Sabre\\CalDAV\\Xml\\Request\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php',
- 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php',
- 'Sabre\\CalDAV\\Xml\\Request\\Share' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/Share.php',
- 'Sabre\\CardDAV\\AddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBook.php',
- 'Sabre\\CardDAV\\AddressBookHome' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookHome.php',
- 'Sabre\\CardDAV\\AddressBookRoot' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookRoot.php',
- 'Sabre\\CardDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php',
- 'Sabre\\CardDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/BackendInterface.php',
- 'Sabre\\CardDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/PDO.php',
- 'Sabre\\CardDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/SyncSupport.php',
- 'Sabre\\CardDAV\\Card' => $vendorDir . '/sabre/dav/lib/CardDAV/Card.php',
- 'Sabre\\CardDAV\\IAddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/IAddressBook.php',
- 'Sabre\\CardDAV\\ICard' => $vendorDir . '/sabre/dav/lib/CardDAV/ICard.php',
- 'Sabre\\CardDAV\\IDirectory' => $vendorDir . '/sabre/dav/lib/CardDAV/IDirectory.php',
- 'Sabre\\CardDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CardDAV/Plugin.php',
- 'Sabre\\CardDAV\\VCFExportPlugin' => $vendorDir . '/sabre/dav/lib/CardDAV/VCFExportPlugin.php',
- 'Sabre\\CardDAV\\Xml\\Filter\\AddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php',
- 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php',
- 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php',
- 'Sabre\\CardDAV\\Xml\\Property\\SupportedAddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php',
- 'Sabre\\CardDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php',
- 'Sabre\\CardDAV\\Xml\\Request\\AddressBookMultiGetReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php',
- 'Sabre\\CardDAV\\Xml\\Request\\AddressBookQueryReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php',
- 'Sabre\\DAVACL\\ACLTrait' => $vendorDir . '/sabre/dav/lib/DAVACL/ACLTrait.php',
- 'Sabre\\DAVACL\\AbstractPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php',
- 'Sabre\\DAVACL\\Exception\\AceConflict' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/AceConflict.php',
- 'Sabre\\DAVACL\\Exception\\NeedPrivileges' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php',
- 'Sabre\\DAVACL\\Exception\\NoAbstract' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NoAbstract.php',
- 'Sabre\\DAVACL\\Exception\\NotRecognizedPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php',
- 'Sabre\\DAVACL\\Exception\\NotSupportedPrivilege' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php',
- 'Sabre\\DAVACL\\FS\\Collection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/Collection.php',
- 'Sabre\\DAVACL\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/File.php',
- 'Sabre\\DAVACL\\FS\\HomeCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/HomeCollection.php',
- 'Sabre\\DAVACL\\IACL' => $vendorDir . '/sabre/dav/lib/DAVACL/IACL.php',
- 'Sabre\\DAVACL\\IPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipal.php',
- 'Sabre\\DAVACL\\IPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipalCollection.php',
- 'Sabre\\DAVACL\\Plugin' => $vendorDir . '/sabre/dav/lib/DAVACL/Plugin.php',
- 'Sabre\\DAVACL\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Principal.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\CreatePrincipalSupport' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/CreatePrincipalSupport.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\PDO' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php',
- 'Sabre\\DAVACL\\PrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalCollection.php',
- 'Sabre\\DAVACL\\Xml\\Property\\Acl' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Acl.php',
- 'Sabre\\DAVACL\\Xml\\Property\\AclRestrictions' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php',
- 'Sabre\\DAVACL\\Xml\\Property\\CurrentUserPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php',
- 'Sabre\\DAVACL\\Xml\\Property\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Principal.php',
- 'Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php',
- 'Sabre\\DAVACL\\Xml\\Request\\AclPrincipalPropSetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\PrincipalMatchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php',
- 'Sabre\\DAV\\Auth\\Backend\\AbstractBasic' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php',
- 'Sabre\\DAV\\Auth\\Backend\\AbstractBearer' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php',
- 'Sabre\\DAV\\Auth\\Backend\\AbstractDigest' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php',
- 'Sabre\\DAV\\Auth\\Backend\\Apache' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/Apache.php',
- 'Sabre\\DAV\\Auth\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php',
- 'Sabre\\DAV\\Auth\\Backend\\BasicCallBack' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php',
- 'Sabre\\DAV\\Auth\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/File.php',
- 'Sabre\\DAV\\Auth\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/PDO.php',
- 'Sabre\\DAV\\Auth\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Plugin.php',
- 'Sabre\\DAV\\Browser\\GuessContentType' => $vendorDir . '/sabre/dav/lib/DAV/Browser/GuessContentType.php',
- 'Sabre\\DAV\\Browser\\HtmlOutput' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutput.php',
- 'Sabre\\DAV\\Browser\\HtmlOutputHelper' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutputHelper.php',
- 'Sabre\\DAV\\Browser\\MapGetToPropFind' => $vendorDir . '/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php',
- 'Sabre\\DAV\\Browser\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Browser/Plugin.php',
- 'Sabre\\DAV\\Browser\\PropFindAll' => $vendorDir . '/sabre/dav/lib/DAV/Browser/PropFindAll.php',
- 'Sabre\\DAV\\Client' => $vendorDir . '/sabre/dav/lib/DAV/Client.php',
- 'Sabre\\DAV\\Collection' => $vendorDir . '/sabre/dav/lib/DAV/Collection.php',
- 'Sabre\\DAV\\CorePlugin' => $vendorDir . '/sabre/dav/lib/DAV/CorePlugin.php',
- 'Sabre\\DAV\\Exception' => $vendorDir . '/sabre/dav/lib/DAV/Exception.php',
- 'Sabre\\DAV\\Exception\\BadRequest' => $vendorDir . '/sabre/dav/lib/DAV/Exception/BadRequest.php',
- 'Sabre\\DAV\\Exception\\Conflict' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Conflict.php',
- 'Sabre\\DAV\\Exception\\ConflictingLock' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ConflictingLock.php',
- 'Sabre\\DAV\\Exception\\Forbidden' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Forbidden.php',
- 'Sabre\\DAV\\Exception\\InsufficientStorage' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InsufficientStorage.php',
- 'Sabre\\DAV\\Exception\\InvalidResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidResourceType.php',
- 'Sabre\\DAV\\Exception\\InvalidSyncToken' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php',
- 'Sabre\\DAV\\Exception\\LengthRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LengthRequired.php',
- 'Sabre\\DAV\\Exception\\LockTokenMatchesRequestUri' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LockTokenMatchesRequestUri.php',
- 'Sabre\\DAV\\Exception\\Locked' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Locked.php',
- 'Sabre\\DAV\\Exception\\MethodNotAllowed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php',
- 'Sabre\\DAV\\Exception\\NotAuthenticated' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotAuthenticated.php',
- 'Sabre\\DAV\\Exception\\NotFound' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotFound.php',
- 'Sabre\\DAV\\Exception\\NotImplemented' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotImplemented.php',
- 'Sabre\\DAV\\Exception\\PaymentRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PaymentRequired.php',
- 'Sabre\\DAV\\Exception\\PreconditionFailed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PreconditionFailed.php',
- 'Sabre\\DAV\\Exception\\ReportNotSupported' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ReportNotSupported.php',
- 'Sabre\\DAV\\Exception\\RequestedRangeNotSatisfiable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php',
- 'Sabre\\DAV\\Exception\\ServiceUnavailable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ServiceUnavailable.php',
- 'Sabre\\DAV\\Exception\\TooManyMatches' => $vendorDir . '/sabre/dav/lib/DAV/Exception/TooManyMatches.php',
- 'Sabre\\DAV\\Exception\\UnsupportedMediaType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php',
- 'Sabre\\DAV\\FSExt\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/Directory.php',
- 'Sabre\\DAV\\FSExt\\File' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/File.php',
- 'Sabre\\DAV\\FS\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FS/Directory.php',
- 'Sabre\\DAV\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAV/FS/File.php',
- 'Sabre\\DAV\\FS\\Node' => $vendorDir . '/sabre/dav/lib/DAV/FS/Node.php',
- 'Sabre\\DAV\\File' => $vendorDir . '/sabre/dav/lib/DAV/File.php',
- 'Sabre\\DAV\\ICollection' => $vendorDir . '/sabre/dav/lib/DAV/ICollection.php',
- 'Sabre\\DAV\\IExtendedCollection' => $vendorDir . '/sabre/dav/lib/DAV/IExtendedCollection.php',
- 'Sabre\\DAV\\IFile' => $vendorDir . '/sabre/dav/lib/DAV/IFile.php',
- 'Sabre\\DAV\\IMoveTarget' => $vendorDir . '/sabre/dav/lib/DAV/IMoveTarget.php',
- 'Sabre\\DAV\\IMultiGet' => $vendorDir . '/sabre/dav/lib/DAV/IMultiGet.php',
- 'Sabre\\DAV\\INode' => $vendorDir . '/sabre/dav/lib/DAV/INode.php',
- 'Sabre\\DAV\\IProperties' => $vendorDir . '/sabre/dav/lib/DAV/IProperties.php',
- 'Sabre\\DAV\\IQuota' => $vendorDir . '/sabre/dav/lib/DAV/IQuota.php',
- 'Sabre\\DAV\\Locks\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/AbstractBackend.php',
- 'Sabre\\DAV\\Locks\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/BackendInterface.php',
- 'Sabre\\DAV\\Locks\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/File.php',
- 'Sabre\\DAV\\Locks\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/PDO.php',
- 'Sabre\\DAV\\Locks\\LockInfo' => $vendorDir . '/sabre/dav/lib/DAV/Locks/LockInfo.php',
- 'Sabre\\DAV\\Locks\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Plugin.php',
- 'Sabre\\DAV\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/MkCol.php',
- 'Sabre\\DAV\\Mount\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Mount/Plugin.php',
- 'Sabre\\DAV\\Node' => $vendorDir . '/sabre/dav/lib/DAV/Node.php',
- 'Sabre\\DAV\\PartialUpdate\\IPatchSupport' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php',
- 'Sabre\\DAV\\PartialUpdate\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/Plugin.php',
- 'Sabre\\DAV\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/PropFind.php',
- 'Sabre\\DAV\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/PropPatch.php',
- 'Sabre\\DAV\\PropertyStorage\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php',
- 'Sabre\\DAV\\PropertyStorage\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php',
- 'Sabre\\DAV\\PropertyStorage\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Plugin.php',
- 'Sabre\\DAV\\Server' => $vendorDir . '/sabre/dav/lib/DAV/Server.php',
- 'Sabre\\DAV\\ServerPlugin' => $vendorDir . '/sabre/dav/lib/DAV/ServerPlugin.php',
- 'Sabre\\DAV\\Sharing\\ISharedNode' => $vendorDir . '/sabre/dav/lib/DAV/Sharing/ISharedNode.php',
- 'Sabre\\DAV\\Sharing\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sharing/Plugin.php',
- 'Sabre\\DAV\\SimpleCollection' => $vendorDir . '/sabre/dav/lib/DAV/SimpleCollection.php',
- 'Sabre\\DAV\\SimpleFile' => $vendorDir . '/sabre/dav/lib/DAV/SimpleFile.php',
- 'Sabre\\DAV\\StringUtil' => $vendorDir . '/sabre/dav/lib/DAV/StringUtil.php',
- 'Sabre\\DAV\\Sync\\ISyncCollection' => $vendorDir . '/sabre/dav/lib/DAV/Sync/ISyncCollection.php',
- 'Sabre\\DAV\\Sync\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sync/Plugin.php',
- 'Sabre\\DAV\\TemporaryFileFilterPlugin' => $vendorDir . '/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php',
- 'Sabre\\DAV\\Tree' => $vendorDir . '/sabre/dav/lib/DAV/Tree.php',
- 'Sabre\\DAV\\UUIDUtil' => $vendorDir . '/sabre/dav/lib/DAV/UUIDUtil.php',
- 'Sabre\\DAV\\Version' => $vendorDir . '/sabre/dav/lib/DAV/Version.php',
- 'Sabre\\DAV\\Xml\\Element\\Prop' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Prop.php',
- 'Sabre\\DAV\\Xml\\Element\\Response' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Response.php',
- 'Sabre\\DAV\\Xml\\Element\\Sharee' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Sharee.php',
- 'Sabre\\DAV\\Xml\\Property\\Complex' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Complex.php',
- 'Sabre\\DAV\\Xml\\Property\\GetLastModified' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php',
- 'Sabre\\DAV\\Xml\\Property\\Href' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Href.php',
- 'Sabre\\DAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Invite.php',
- 'Sabre\\DAV\\Xml\\Property\\LocalHref' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LocalHref.php',
- 'Sabre\\DAV\\Xml\\Property\\LockDiscovery' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LockDiscovery.php',
- 'Sabre\\DAV\\Xml\\Property\\ResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ResourceType.php',
- 'Sabre\\DAV\\Xml\\Property\\ShareAccess' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php',
- 'Sabre\\DAV\\Xml\\Property\\SupportedLock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php',
- 'Sabre\\DAV\\Xml\\Property\\SupportedMethodSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php',
- 'Sabre\\DAV\\Xml\\Property\\SupportedReportSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php',
- 'Sabre\\DAV\\Xml\\Request\\Lock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/Lock.php',
- 'Sabre\\DAV\\Xml\\Request\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/MkCol.php',
- 'Sabre\\DAV\\Xml\\Request\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropFind.php',
- 'Sabre\\DAV\\Xml\\Request\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropPatch.php',
- 'Sabre\\DAV\\Xml\\Request\\ShareResource' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/ShareResource.php',
- 'Sabre\\DAV\\Xml\\Request\\SyncCollectionReport' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php',
- 'Sabre\\DAV\\Xml\\Response\\MultiStatus' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php',
- 'Sabre\\DAV\\Xml\\Service' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Service.php',
- 'Sabre\\Event\\EventEmitter' => $vendorDir . '/sabre/event/lib/EventEmitter.php',
- 'Sabre\\Event\\EventEmitterInterface' => $vendorDir . '/sabre/event/lib/EventEmitterInterface.php',
- 'Sabre\\Event\\EventEmitterTrait' => $vendorDir . '/sabre/event/lib/EventEmitterTrait.php',
- 'Sabre\\Event\\Loop\\Loop' => $vendorDir . '/sabre/event/lib/Loop/Loop.php',
- 'Sabre\\Event\\Promise' => $vendorDir . '/sabre/event/lib/Promise.php',
- 'Sabre\\Event\\PromiseAlreadyResolvedException' => $vendorDir . '/sabre/event/lib/PromiseAlreadyResolvedException.php',
- 'Sabre\\Event\\Version' => $vendorDir . '/sabre/event/lib/Version.php',
- 'Sabre\\HTTP\\Auth\\AWS' => $vendorDir . '/sabre/http/lib/Auth/AWS.php',
- 'Sabre\\HTTP\\Auth\\AbstractAuth' => $vendorDir . '/sabre/http/lib/Auth/AbstractAuth.php',
- 'Sabre\\HTTP\\Auth\\Basic' => $vendorDir . '/sabre/http/lib/Auth/Basic.php',
- 'Sabre\\HTTP\\Auth\\Bearer' => $vendorDir . '/sabre/http/lib/Auth/Bearer.php',
- 'Sabre\\HTTP\\Auth\\Digest' => $vendorDir . '/sabre/http/lib/Auth/Digest.php',
- 'Sabre\\HTTP\\Client' => $vendorDir . '/sabre/http/lib/Client.php',
- 'Sabre\\HTTP\\ClientException' => $vendorDir . '/sabre/http/lib/ClientException.php',
- 'Sabre\\HTTP\\ClientHttpException' => $vendorDir . '/sabre/http/lib/ClientHttpException.php',
- 'Sabre\\HTTP\\HttpException' => $vendorDir . '/sabre/http/lib/HttpException.php',
- 'Sabre\\HTTP\\Message' => $vendorDir . '/sabre/http/lib/Message.php',
- 'Sabre\\HTTP\\MessageDecoratorTrait' => $vendorDir . '/sabre/http/lib/MessageDecoratorTrait.php',
- 'Sabre\\HTTP\\MessageInterface' => $vendorDir . '/sabre/http/lib/MessageInterface.php',
- 'Sabre\\HTTP\\Request' => $vendorDir . '/sabre/http/lib/Request.php',
- 'Sabre\\HTTP\\RequestDecorator' => $vendorDir . '/sabre/http/lib/RequestDecorator.php',
- 'Sabre\\HTTP\\RequestInterface' => $vendorDir . '/sabre/http/lib/RequestInterface.php',
- 'Sabre\\HTTP\\Response' => $vendorDir . '/sabre/http/lib/Response.php',
- 'Sabre\\HTTP\\ResponseDecorator' => $vendorDir . '/sabre/http/lib/ResponseDecorator.php',
- 'Sabre\\HTTP\\ResponseInterface' => $vendorDir . '/sabre/http/lib/ResponseInterface.php',
- 'Sabre\\HTTP\\Sapi' => $vendorDir . '/sabre/http/lib/Sapi.php',
- 'Sabre\\HTTP\\URLUtil' => $vendorDir . '/sabre/http/lib/URLUtil.php',
- 'Sabre\\HTTP\\Util' => $vendorDir . '/sabre/http/lib/Util.php',
- 'Sabre\\HTTP\\Version' => $vendorDir . '/sabre/http/lib/Version.php',
- 'Sabre\\Uri\\Version' => $vendorDir . '/sabre/uri/lib/Version.php',
- 'Sabre\\VObject\\BirthdayCalendarGenerator' => $vendorDir . '/sabre/vobject/lib/BirthdayCalendarGenerator.php',
- 'Sabre\\VObject\\Cli' => $vendorDir . '/sabre/vobject/lib/Cli.php',
- 'Sabre\\VObject\\Component' => $vendorDir . '/sabre/vobject/lib/Component.php',
- 'Sabre\\VObject\\Component\\Available' => $vendorDir . '/sabre/vobject/lib/Component/Available.php',
- 'Sabre\\VObject\\Component\\VAlarm' => $vendorDir . '/sabre/vobject/lib/Component/VAlarm.php',
- 'Sabre\\VObject\\Component\\VAvailability' => $vendorDir . '/sabre/vobject/lib/Component/VAvailability.php',
- 'Sabre\\VObject\\Component\\VCalendar' => $vendorDir . '/sabre/vobject/lib/Component/VCalendar.php',
- 'Sabre\\VObject\\Component\\VCard' => $vendorDir . '/sabre/vobject/lib/Component/VCard.php',
- 'Sabre\\VObject\\Component\\VEvent' => $vendorDir . '/sabre/vobject/lib/Component/VEvent.php',
- 'Sabre\\VObject\\Component\\VFreeBusy' => $vendorDir . '/sabre/vobject/lib/Component/VFreeBusy.php',
- 'Sabre\\VObject\\Component\\VJournal' => $vendorDir . '/sabre/vobject/lib/Component/VJournal.php',
- 'Sabre\\VObject\\Component\\VTimeZone' => $vendorDir . '/sabre/vobject/lib/Component/VTimeZone.php',
- 'Sabre\\VObject\\Component\\VTodo' => $vendorDir . '/sabre/vobject/lib/Component/VTodo.php',
- 'Sabre\\VObject\\DateTimeParser' => $vendorDir . '/sabre/vobject/lib/DateTimeParser.php',
- 'Sabre\\VObject\\Document' => $vendorDir . '/sabre/vobject/lib/Document.php',
- 'Sabre\\VObject\\ElementList' => $vendorDir . '/sabre/vobject/lib/ElementList.php',
- 'Sabre\\VObject\\EofException' => $vendorDir . '/sabre/vobject/lib/EofException.php',
- 'Sabre\\VObject\\FreeBusyData' => $vendorDir . '/sabre/vobject/lib/FreeBusyData.php',
- 'Sabre\\VObject\\FreeBusyGenerator' => $vendorDir . '/sabre/vobject/lib/FreeBusyGenerator.php',
- 'Sabre\\VObject\\ITip\\Broker' => $vendorDir . '/sabre/vobject/lib/ITip/Broker.php',
- 'Sabre\\VObject\\ITip\\ITipException' => $vendorDir . '/sabre/vobject/lib/ITip/ITipException.php',
- 'Sabre\\VObject\\ITip\\Message' => $vendorDir . '/sabre/vobject/lib/ITip/Message.php',
- 'Sabre\\VObject\\ITip\\SameOrganizerForAllComponentsException' => $vendorDir . '/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php',
- 'Sabre\\VObject\\InvalidDataException' => $vendorDir . '/sabre/vobject/lib/InvalidDataException.php',
- 'Sabre\\VObject\\Node' => $vendorDir . '/sabre/vobject/lib/Node.php',
- 'Sabre\\VObject\\PHPUnitAssertions' => $vendorDir . '/sabre/vobject/lib/PHPUnitAssertions.php',
- 'Sabre\\VObject\\Parameter' => $vendorDir . '/sabre/vobject/lib/Parameter.php',
- 'Sabre\\VObject\\ParseException' => $vendorDir . '/sabre/vobject/lib/ParseException.php',
- 'Sabre\\VObject\\Parser\\Json' => $vendorDir . '/sabre/vobject/lib/Parser/Json.php',
- 'Sabre\\VObject\\Parser\\MimeDir' => $vendorDir . '/sabre/vobject/lib/Parser/MimeDir.php',
- 'Sabre\\VObject\\Parser\\Parser' => $vendorDir . '/sabre/vobject/lib/Parser/Parser.php',
- 'Sabre\\VObject\\Parser\\XML' => $vendorDir . '/sabre/vobject/lib/Parser/XML.php',
- 'Sabre\\VObject\\Parser\\XML\\Element\\KeyValue' => $vendorDir . '/sabre/vobject/lib/Parser/XML/Element/KeyValue.php',
- 'Sabre\\VObject\\Property' => $vendorDir . '/sabre/vobject/lib/Property.php',
- 'Sabre\\VObject\\Property\\Binary' => $vendorDir . '/sabre/vobject/lib/Property/Binary.php',
- 'Sabre\\VObject\\Property\\Boolean' => $vendorDir . '/sabre/vobject/lib/Property/Boolean.php',
- 'Sabre\\VObject\\Property\\FlatText' => $vendorDir . '/sabre/vobject/lib/Property/FlatText.php',
- 'Sabre\\VObject\\Property\\FloatValue' => $vendorDir . '/sabre/vobject/lib/Property/FloatValue.php',
- 'Sabre\\VObject\\Property\\ICalendar\\CalAddress' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/CalAddress.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Date' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Date.php',
- 'Sabre\\VObject\\Property\\ICalendar\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/DateTime.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Duration' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Duration.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Period' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Period.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Recur' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Recur.php',
- 'Sabre\\VObject\\Property\\IntegerValue' => $vendorDir . '/sabre/vobject/lib/Property/IntegerValue.php',
- 'Sabre\\VObject\\Property\\Text' => $vendorDir . '/sabre/vobject/lib/Property/Text.php',
- 'Sabre\\VObject\\Property\\Time' => $vendorDir . '/sabre/vobject/lib/Property/Time.php',
- 'Sabre\\VObject\\Property\\Unknown' => $vendorDir . '/sabre/vobject/lib/Property/Unknown.php',
- 'Sabre\\VObject\\Property\\Uri' => $vendorDir . '/sabre/vobject/lib/Property/Uri.php',
- 'Sabre\\VObject\\Property\\UtcOffset' => $vendorDir . '/sabre/vobject/lib/Property/UtcOffset.php',
- 'Sabre\\VObject\\Property\\VCard\\Date' => $vendorDir . '/sabre/vobject/lib/Property/VCard/Date.php',
- 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateAndOrTime.php',
- 'Sabre\\VObject\\Property\\VCard\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateTime.php',
- 'Sabre\\VObject\\Property\\VCard\\LanguageTag' => $vendorDir . '/sabre/vobject/lib/Property/VCard/LanguageTag.php',
- 'Sabre\\VObject\\Property\\VCard\\TimeStamp' => $vendorDir . '/sabre/vobject/lib/Property/VCard/TimeStamp.php',
- 'Sabre\\VObject\\Reader' => $vendorDir . '/sabre/vobject/lib/Reader.php',
- 'Sabre\\VObject\\Recur\\EventIterator' => $vendorDir . '/sabre/vobject/lib/Recur/EventIterator.php',
- 'Sabre\\VObject\\Recur\\MaxInstancesExceededException' => $vendorDir . '/sabre/vobject/lib/Recur/MaxInstancesExceededException.php',
- 'Sabre\\VObject\\Recur\\NoInstancesException' => $vendorDir . '/sabre/vobject/lib/Recur/NoInstancesException.php',
- 'Sabre\\VObject\\Recur\\RDateIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RDateIterator.php',
- 'Sabre\\VObject\\Recur\\RRuleIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RRuleIterator.php',
- 'Sabre\\VObject\\Settings' => $vendorDir . '/sabre/vobject/lib/Settings.php',
- 'Sabre\\VObject\\Splitter\\ICalendar' => $vendorDir . '/sabre/vobject/lib/Splitter/ICalendar.php',
- 'Sabre\\VObject\\Splitter\\SplitterInterface' => $vendorDir . '/sabre/vobject/lib/Splitter/SplitterInterface.php',
- 'Sabre\\VObject\\Splitter\\VCard' => $vendorDir . '/sabre/vobject/lib/Splitter/VCard.php',
- 'Sabre\\VObject\\StringUtil' => $vendorDir . '/sabre/vobject/lib/StringUtil.php',
- 'Sabre\\VObject\\TimeZoneUtil' => $vendorDir . '/sabre/vobject/lib/TimeZoneUtil.php',
- 'Sabre\\VObject\\UUIDUtil' => $vendorDir . '/sabre/vobject/lib/UUIDUtil.php',
- 'Sabre\\VObject\\VCardConverter' => $vendorDir . '/sabre/vobject/lib/VCardConverter.php',
- 'Sabre\\VObject\\Version' => $vendorDir . '/sabre/vobject/lib/Version.php',
- 'Sabre\\VObject\\Writer' => $vendorDir . '/sabre/vobject/lib/Writer.php',
- 'Sabre\\Xml\\ContextStackTrait' => $vendorDir . '/sabre/xml/lib/ContextStackTrait.php',
- 'Sabre\\Xml\\Element' => $vendorDir . '/sabre/xml/lib/Element.php',
- 'Sabre\\Xml\\Element\\Base' => $vendorDir . '/sabre/xml/lib/Element/Base.php',
- 'Sabre\\Xml\\Element\\Cdata' => $vendorDir . '/sabre/xml/lib/Element/Cdata.php',
- 'Sabre\\Xml\\Element\\Elements' => $vendorDir . '/sabre/xml/lib/Element/Elements.php',
- 'Sabre\\Xml\\Element\\KeyValue' => $vendorDir . '/sabre/xml/lib/Element/KeyValue.php',
- 'Sabre\\Xml\\Element\\Uri' => $vendorDir . '/sabre/xml/lib/Element/Uri.php',
- 'Sabre\\Xml\\Element\\XmlFragment' => $vendorDir . '/sabre/xml/lib/Element/XmlFragment.php',
- 'Sabre\\Xml\\LibXMLException' => $vendorDir . '/sabre/xml/lib/LibXMLException.php',
- 'Sabre\\Xml\\ParseException' => $vendorDir . '/sabre/xml/lib/ParseException.php',
- 'Sabre\\Xml\\Reader' => $vendorDir . '/sabre/xml/lib/Reader.php',
- 'Sabre\\Xml\\Service' => $vendorDir . '/sabre/xml/lib/Service.php',
- 'Sabre\\Xml\\Version' => $vendorDir . '/sabre/xml/lib/Version.php',
- 'Sabre\\Xml\\Writer' => $vendorDir . '/sabre/xml/lib/Writer.php',
- 'Sabre\\Xml\\XmlDeserializable' => $vendorDir . '/sabre/xml/lib/XmlDeserializable.php',
- 'Sabre\\Xml\\XmlSerializable' => $vendorDir . '/sabre/xml/lib/XmlSerializable.php',
- 'Test\\Markdownify\\ConverterExtraTest' => $vendorDir . '/pixel418/markdownify/test/ConverterExtraTest.php',
- 'Test\\Markdownify\\ConverterTest' => $vendorDir . '/pixel418/markdownify/test/ConverterTest.php',
- 'Test\\Markdownify\\ConverterTestCase' => $vendorDir . '/pixel418/markdownify/test/ConverterTestCase.php',
- 'Zotlabs\\Access\\AccessList' => $baseDir . '/Zotlabs/Access/AccessList.php',
- 'Zotlabs\\Access\\PermissionLimits' => $baseDir . '/Zotlabs/Access/PermissionLimits.php',
- 'Zotlabs\\Access\\PermissionRoles' => $baseDir . '/Zotlabs/Access/PermissionRoles.php',
- 'Zotlabs\\Access\\Permissions' => $baseDir . '/Zotlabs/Access/Permissions.php',
- 'Zotlabs\\Daemon\\Addon' => $baseDir . '/Zotlabs/Daemon/Addon.php',
- 'Zotlabs\\Daemon\\Checksites' => $baseDir . '/Zotlabs/Daemon/Checksites.php',
- 'Zotlabs\\Daemon\\Cli_suggest' => $baseDir . '/Zotlabs/Daemon/Cli_suggest.php',
- 'Zotlabs\\Daemon\\Cron' => $baseDir . '/Zotlabs/Daemon/Cron.php',
- 'Zotlabs\\Daemon\\Cron_daily' => $baseDir . '/Zotlabs/Daemon/Cron_daily.php',
- 'Zotlabs\\Daemon\\Cron_weekly' => $baseDir . '/Zotlabs/Daemon/Cron_weekly.php',
- 'Zotlabs\\Daemon\\Cronhooks' => $baseDir . '/Zotlabs/Daemon/Cronhooks.php',
- 'Zotlabs\\Daemon\\CurlAuth' => $baseDir . '/Zotlabs/Daemon/CurlAuth.php',
- 'Zotlabs\\Daemon\\Deliver' => $baseDir . '/Zotlabs/Daemon/Deliver.php',
- 'Zotlabs\\Daemon\\Deliver_hooks' => $baseDir . '/Zotlabs/Daemon/Deliver_hooks.php',
- 'Zotlabs\\Daemon\\Directory' => $baseDir . '/Zotlabs/Daemon/Directory.php',
- 'Zotlabs\\Daemon\\Expire' => $baseDir . '/Zotlabs/Daemon/Expire.php',
- 'Zotlabs\\Daemon\\Externals' => $baseDir . '/Zotlabs/Daemon/Externals.php',
- 'Zotlabs\\Daemon\\Gprobe' => $baseDir . '/Zotlabs/Daemon/Gprobe.php',
- 'Zotlabs\\Daemon\\Importdoc' => $baseDir . '/Zotlabs/Daemon/Importdoc.php',
- 'Zotlabs\\Daemon\\Master' => $baseDir . '/Zotlabs/Daemon/Master.php',
- 'Zotlabs\\Daemon\\Notifier' => $baseDir . '/Zotlabs/Daemon/Notifier.php',
- 'Zotlabs\\Daemon\\Onedirsync' => $baseDir . '/Zotlabs/Daemon/Onedirsync.php',
- 'Zotlabs\\Daemon\\Onepoll' => $baseDir . '/Zotlabs/Daemon/Onepoll.php',
- 'Zotlabs\\Daemon\\Poller' => $baseDir . '/Zotlabs/Daemon/Poller.php',
- 'Zotlabs\\Daemon\\Queue' => $baseDir . '/Zotlabs/Daemon/Queue.php',
- 'Zotlabs\\Daemon\\Ratenotif' => $baseDir . '/Zotlabs/Daemon/Ratenotif.php',
- 'Zotlabs\\Extend\\Hook' => $baseDir . '/Zotlabs/Extend/Hook.php',
- 'Zotlabs\\Identity\\BasicId\\BasicId' => $baseDir . '/Zotlabs/Identity/BasicId.php',
- 'Zotlabs\\Identity\\ProfilePhoto\\ProfilePhoto' => $baseDir . '/Zotlabs/Identity/ProfilePhoto.php',
- 'Zotlabs\\Lib\\AConfig' => $baseDir . '/Zotlabs/Lib/AConfig.php',
- 'Zotlabs\\Lib\\AbConfig' => $baseDir . '/Zotlabs/Lib/AbConfig.php',
- 'Zotlabs\\Lib\\Api_router' => $baseDir . '/Zotlabs/Lib/Api_router.php',
- 'Zotlabs\\Lib\\Apps' => $baseDir . '/Zotlabs/Lib/Apps.php',
- 'Zotlabs\\Lib\\Cache' => $baseDir . '/Zotlabs/Lib/Cache.php',
- 'Zotlabs\\Lib\\Chatroom' => $baseDir . '/Zotlabs/Lib/Chatroom.php',
- 'Zotlabs\\Lib\\Config' => $baseDir . '/Zotlabs/Lib/Config.php',
- 'Zotlabs\\Lib\\Enotify' => $baseDir . '/Zotlabs/Lib/Enotify.php',
- 'Zotlabs\\Lib\\ExtendedZip' => $baseDir . '/Zotlabs/Lib/ExtendedZip.php',
- 'Zotlabs\\Lib\\IConfig' => $baseDir . '/Zotlabs/Lib/IConfig.php',
- 'Zotlabs\\Lib\\NativeWiki' => $baseDir . '/Zotlabs/Lib/NativeWiki.php',
- 'Zotlabs\\Lib\\NativeWikiPage' => $baseDir . '/Zotlabs/Lib/NativeWikiPage.php',
- 'Zotlabs\\Lib\\PConfig' => $baseDir . '/Zotlabs/Lib/PConfig.php',
- 'Zotlabs\\Lib\\Permcat' => $baseDir . '/Zotlabs/Lib/Permcat.php',
- 'Zotlabs\\Lib\\PermissionDescription' => $baseDir . '/Zotlabs/Lib/PermissionDescription.php',
- 'Zotlabs\\Lib\\ProtoDriver' => $baseDir . '/Zotlabs/Lib/ProtoDriver.php',
- 'Zotlabs\\Lib\\SuperCurl' => $baseDir . '/Zotlabs/Lib/SuperCurl.php',
- 'Zotlabs\\Lib\\System' => $baseDir . '/Zotlabs/Lib/System.php',
- 'Zotlabs\\Lib\\Techlevels' => $baseDir . '/Zotlabs/Lib/Techlevels.php',
- 'Zotlabs\\Lib\\ThreadItem' => $baseDir . '/Zotlabs/Lib/ThreadItem.php',
- 'Zotlabs\\Lib\\ThreadStream' => $baseDir . '/Zotlabs/Lib/ThreadStream.php',
- 'Zotlabs\\Lib\\XConfig' => $baseDir . '/Zotlabs/Lib/XConfig.php',
- 'Zotlabs\\Lib\\ZotDriver' => $baseDir . '/Zotlabs/Lib/ZotDriver.php',
- 'Zotlabs\\Module\\Achievements' => $baseDir . '/Zotlabs/Module/Achievements.php',
- 'Zotlabs\\Module\\Acl' => $baseDir . '/Zotlabs/Module/Acl.php',
- 'Zotlabs\\Module\\Admin' => $baseDir . '/Zotlabs/Module/Admin.php',
- 'Zotlabs\\Module\\Admin\\Account_edit' => $baseDir . '/Zotlabs/Module/Admin/Account_edit.php',
- 'Zotlabs\\Module\\Admin\\Accounts' => $baseDir . '/Zotlabs/Module/Admin/Accounts.php',
- 'Zotlabs\\Module\\Admin\\Channels' => $baseDir . '/Zotlabs/Module/Admin/Channels.php',
- 'Zotlabs\\Module\\Admin\\Dbsync' => $baseDir . '/Zotlabs/Module/Admin/Dbsync.php',
- 'Zotlabs\\Module\\Admin\\Features' => $baseDir . '/Zotlabs/Module/Admin/Features.php',
- 'Zotlabs\\Module\\Admin\\Logs' => $baseDir . '/Zotlabs/Module/Admin/Logs.php',
- 'Zotlabs\\Module\\Admin\\Plugins' => $baseDir . '/Zotlabs/Module/Admin/Plugins.php',
- 'Zotlabs\\Module\\Admin\\Profs' => $baseDir . '/Zotlabs/Module/Admin/Profs.php',
- 'Zotlabs\\Module\\Admin\\Queue' => $baseDir . '/Zotlabs/Module/Admin/Queue.php',
- 'Zotlabs\\Module\\Admin\\Security' => $baseDir . '/Zotlabs/Module/Admin/Security.php',
- 'Zotlabs\\Module\\Admin\\Site' => $baseDir . '/Zotlabs/Module/Admin/Site.php',
- 'Zotlabs\\Module\\Admin\\Themes' => $baseDir . '/Zotlabs/Module/Admin/Themes.php',
- 'Zotlabs\\Module\\Api' => $baseDir . '/Zotlabs/Module/Api.php',
- 'Zotlabs\\Module\\Appman' => $baseDir . '/Zotlabs/Module/Appman.php',
- 'Zotlabs\\Module\\Apps' => $baseDir . '/Zotlabs/Module/Apps.php',
- 'Zotlabs\\Module\\Attach' => $baseDir . '/Zotlabs/Module/Attach.php',
- 'Zotlabs\\Module\\Authtest' => $baseDir . '/Zotlabs/Module/Authtest.php',
- 'Zotlabs\\Module\\Block' => $baseDir . '/Zotlabs/Module/Block.php',
- 'Zotlabs\\Module\\Blocks' => $baseDir . '/Zotlabs/Module/Blocks.php',
- 'Zotlabs\\Module\\Bookmarks' => $baseDir . '/Zotlabs/Module/Bookmarks.php',
- 'Zotlabs\\Module\\Branchtopic' => $baseDir . '/Zotlabs/Module/Branchtopic.php',
- 'Zotlabs\\Module\\Cal' => $baseDir . '/Zotlabs/Module/Cal.php',
- 'Zotlabs\\Module\\Channel' => $baseDir . '/Zotlabs/Module/Channel.php',
- 'Zotlabs\\Module\\Chanview' => $baseDir . '/Zotlabs/Module/Chanview.php',
- 'Zotlabs\\Module\\Chat' => $baseDir . '/Zotlabs/Module/Chat.php',
- 'Zotlabs\\Module\\Chatsvc' => $baseDir . '/Zotlabs/Module/Chatsvc.php',
- 'Zotlabs\\Module\\Cloud' => $baseDir . '/Zotlabs/Module/Cloud.php',
- 'Zotlabs\\Module\\Common' => $baseDir . '/Zotlabs/Module/Common.php',
- 'Zotlabs\\Module\\Connect' => $baseDir . '/Zotlabs/Module/Connect.php',
- 'Zotlabs\\Module\\Connections' => $baseDir . '/Zotlabs/Module/Connections.php',
- 'Zotlabs\\Module\\Connedit' => $baseDir . '/Zotlabs/Module/Connedit.php',
- 'Zotlabs\\Module\\Contactgroup' => $baseDir . '/Zotlabs/Module/Contactgroup.php',
- 'Zotlabs\\Module\\Cover_photo' => $baseDir . '/Zotlabs/Module/Cover_photo.php',
- 'Zotlabs\\Module\\Dav' => $baseDir . '/Zotlabs/Module/Dav.php',
- 'Zotlabs\\Module\\Directory' => $baseDir . '/Zotlabs/Module/Directory.php',
- 'Zotlabs\\Module\\Dirsearch' => $baseDir . '/Zotlabs/Module/Dirsearch.php',
- 'Zotlabs\\Module\\Display' => $baseDir . '/Zotlabs/Module/Display.php',
- 'Zotlabs\\Module\\Dreport' => $baseDir . '/Zotlabs/Module/Dreport.php',
- 'Zotlabs\\Module\\Editblock' => $baseDir . '/Zotlabs/Module/Editblock.php',
- 'Zotlabs\\Module\\Editlayout' => $baseDir . '/Zotlabs/Module/Editlayout.php',
- 'Zotlabs\\Module\\Editpost' => $baseDir . '/Zotlabs/Module/Editpost.php',
- 'Zotlabs\\Module\\Editwebpage' => $baseDir . '/Zotlabs/Module/Editwebpage.php',
- 'Zotlabs\\Module\\Embedphotos' => $baseDir . '/Zotlabs/Module/Embedphotos.php',
- 'Zotlabs\\Module\\Events' => $baseDir . '/Zotlabs/Module/Events.php',
- 'Zotlabs\\Module\\Fbrowser' => $baseDir . '/Zotlabs/Module/Fbrowser.php',
- 'Zotlabs\\Module\\Feed' => $baseDir . '/Zotlabs/Module/Feed.php',
- 'Zotlabs\\Module\\Fhublocs' => $baseDir . '/Zotlabs/Module/Fhublocs.php',
- 'Zotlabs\\Module\\File_upload' => $baseDir . '/Zotlabs/Module/File_upload.php',
- 'Zotlabs\\Module\\Filer' => $baseDir . '/Zotlabs/Module/Filer.php',
- 'Zotlabs\\Module\\Filerm' => $baseDir . '/Zotlabs/Module/Filerm.php',
- 'Zotlabs\\Module\\Filestorage' => $baseDir . '/Zotlabs/Module/Filestorage.php',
- 'Zotlabs\\Module\\Follow' => $baseDir . '/Zotlabs/Module/Follow.php',
- 'Zotlabs\\Module\\Getfile' => $baseDir . '/Zotlabs/Module/Getfile.php',
- 'Zotlabs\\Module\\Group' => $baseDir . '/Zotlabs/Module/Group.php',
- 'Zotlabs\\Module\\Hcard' => $baseDir . '/Zotlabs/Module/Hcard.php',
- 'Zotlabs\\Module\\Help' => $baseDir . '/Zotlabs/Module/Help.php',
- 'Zotlabs\\Module\\Home' => $baseDir . '/Zotlabs/Module/Home.php',
- 'Zotlabs\\Module\\Hostxrd' => $baseDir . '/Zotlabs/Module/Hostxrd.php',
- 'Zotlabs\\Module\\Impel' => $baseDir . '/Zotlabs/Module/Impel.php',
- 'Zotlabs\\Module\\Import' => $baseDir . '/Zotlabs/Module/Import.php',
- 'Zotlabs\\Module\\Import_items' => $baseDir . '/Zotlabs/Module/Import_items.php',
- 'Zotlabs\\Module\\Invite' => $baseDir . '/Zotlabs/Module/Invite.php',
- 'Zotlabs\\Module\\Item' => $baseDir . '/Zotlabs/Module/Item.php',
- 'Zotlabs\\Module\\Lang' => $baseDir . '/Zotlabs/Module/Lang.php',
- 'Zotlabs\\Module\\Layouts' => $baseDir . '/Zotlabs/Module/Layouts.php',
- 'Zotlabs\\Module\\Like' => $baseDir . '/Zotlabs/Module/Like.php',
- 'Zotlabs\\Module\\Linkinfo' => $baseDir . '/Zotlabs/Module/Linkinfo.php',
- 'Zotlabs\\Module\\Lockview' => $baseDir . '/Zotlabs/Module/Lockview.php',
- 'Zotlabs\\Module\\Locs' => $baseDir . '/Zotlabs/Module/Locs.php',
- 'Zotlabs\\Module\\Login' => $baseDir . '/Zotlabs/Module/Login.php',
- 'Zotlabs\\Module\\Lostpass' => $baseDir . '/Zotlabs/Module/Lostpass.php',
- 'Zotlabs\\Module\\Magic' => $baseDir . '/Zotlabs/Module/Magic.php',
- 'Zotlabs\\Module\\Mail' => $baseDir . '/Zotlabs/Module/Mail.php',
- 'Zotlabs\\Module\\Manage' => $baseDir . '/Zotlabs/Module/Manage.php',
- 'Zotlabs\\Module\\Menu' => $baseDir . '/Zotlabs/Module/Menu.php',
- 'Zotlabs\\Module\\Message' => $baseDir . '/Zotlabs/Module/Message.php',
- 'Zotlabs\\Module\\Mitem' => $baseDir . '/Zotlabs/Module/Mitem.php',
- 'Zotlabs\\Module\\Mood' => $baseDir . '/Zotlabs/Module/Mood.php',
- 'Zotlabs\\Module\\Network' => $baseDir . '/Zotlabs/Module/Network.php',
- 'Zotlabs\\Module\\New_channel' => $baseDir . '/Zotlabs/Module/New_channel.php',
- 'Zotlabs\\Module\\Nojs' => $baseDir . '/Zotlabs/Module/Nojs.php',
- 'Zotlabs\\Module\\Notes' => $baseDir . '/Zotlabs/Module/Notes.php',
- 'Zotlabs\\Module\\Notifications' => $baseDir . '/Zotlabs/Module/Notifications.php',
- 'Zotlabs\\Module\\Notify' => $baseDir . '/Zotlabs/Module/Notify.php',
- 'Zotlabs\\Module\\Oembed' => $baseDir . '/Zotlabs/Module/Oembed.php',
- 'Zotlabs\\Module\\Oep' => $baseDir . '/Zotlabs/Module/Oep.php',
- 'Zotlabs\\Module\\Oexchange' => $baseDir . '/Zotlabs/Module/Oexchange.php',
- 'Zotlabs\\Module\\Online' => $baseDir . '/Zotlabs/Module/Online.php',
- 'Zotlabs\\Module\\Page' => $baseDir . '/Zotlabs/Module/Page.php',
- 'Zotlabs\\Module\\Pconfig' => $baseDir . '/Zotlabs/Module/Pconfig.php',
- 'Zotlabs\\Module\\Pdledit' => $baseDir . '/Zotlabs/Module/Pdledit.php',
- 'Zotlabs\\Module\\Permcat' => $baseDir . '/Zotlabs/Module/Permcat.php',
- 'Zotlabs\\Module\\Photo' => $baseDir . '/Zotlabs/Module/Photo.php',
- 'Zotlabs\\Module\\Photos' => $baseDir . '/Zotlabs/Module/Photos.php',
- 'Zotlabs\\Module\\Ping' => $baseDir . '/Zotlabs/Module/Ping.php',
- 'Zotlabs\\Module\\Poco' => $baseDir . '/Zotlabs/Module/Poco.php',
- 'Zotlabs\\Module\\Poke' => $baseDir . '/Zotlabs/Module/Poke.php',
- 'Zotlabs\\Module\\Post' => $baseDir . '/Zotlabs/Module/Post.php',
- 'Zotlabs\\Module\\Prate' => $baseDir . '/Zotlabs/Module/Prate.php',
- 'Zotlabs\\Module\\Pretheme' => $baseDir . '/Zotlabs/Module/Pretheme.php',
- 'Zotlabs\\Module\\Probe' => $baseDir . '/Zotlabs/Module/Probe.php',
- 'Zotlabs\\Module\\Profile' => $baseDir . '/Zotlabs/Module/Profile.php',
- 'Zotlabs\\Module\\Profile_photo' => $baseDir . '/Zotlabs/Module/Profile_photo.php',
- 'Zotlabs\\Module\\Profiles' => $baseDir . '/Zotlabs/Module/Profiles.php',
- 'Zotlabs\\Module\\Profperm' => $baseDir . '/Zotlabs/Module/Profperm.php',
- 'Zotlabs\\Module\\Pubsites' => $baseDir . '/Zotlabs/Module/Pubsites.php',
- 'Zotlabs\\Module\\Pubstream' => $baseDir . '/Zotlabs/Module/Pubstream.php',
- 'Zotlabs\\Module\\Randprof' => $baseDir . '/Zotlabs/Module/Randprof.php',
- 'Zotlabs\\Module\\Rate' => $baseDir . '/Zotlabs/Module/Rate.php',
- 'Zotlabs\\Module\\Ratings' => $baseDir . '/Zotlabs/Module/Ratings.php',
- 'Zotlabs\\Module\\Ratingsearch' => $baseDir . '/Zotlabs/Module/Ratingsearch.php',
- 'Zotlabs\\Module\\Rbmark' => $baseDir . '/Zotlabs/Module/Rbmark.php',
- 'Zotlabs\\Module\\React' => $baseDir . '/Zotlabs/Module/React.php',
- 'Zotlabs\\Module\\Regdir' => $baseDir . '/Zotlabs/Module/Regdir.php',
- 'Zotlabs\\Module\\Register' => $baseDir . '/Zotlabs/Module/Register.php',
- 'Zotlabs\\Module\\Regmod' => $baseDir . '/Zotlabs/Module/Regmod.php',
- 'Zotlabs\\Module\\Regver' => $baseDir . '/Zotlabs/Module/Regver.php',
- 'Zotlabs\\Module\\Removeaccount' => $baseDir . '/Zotlabs/Module/Removeaccount.php',
- 'Zotlabs\\Module\\Removeme' => $baseDir . '/Zotlabs/Module/Removeme.php',
- 'Zotlabs\\Module\\Rmagic' => $baseDir . '/Zotlabs/Module/Rmagic.php',
- 'Zotlabs\\Module\\Rpost' => $baseDir . '/Zotlabs/Module/Rpost.php',
- 'Zotlabs\\Module\\Search' => $baseDir . '/Zotlabs/Module/Search.php',
- 'Zotlabs\\Module\\Search_ac' => $baseDir . '/Zotlabs/Module/Search_ac.php',
- 'Zotlabs\\Module\\Service_limits' => $baseDir . '/Zotlabs/Module/Service_limits.php',
- 'Zotlabs\\Module\\Settings' => $baseDir . '/Zotlabs/Module/Settings.php',
- 'Zotlabs\\Module\\Settings\\Account' => $baseDir . '/Zotlabs/Module/Settings/Account.php',
- 'Zotlabs\\Module\\Settings\\Channel' => $baseDir . '/Zotlabs/Module/Settings/Channel.php',
- 'Zotlabs\\Module\\Settings\\Display' => $baseDir . '/Zotlabs/Module/Settings/Display.php',
- 'Zotlabs\\Module\\Settings\\Featured' => $baseDir . '/Zotlabs/Module/Settings/Featured.php',
- 'Zotlabs\\Module\\Settings\\Features' => $baseDir . '/Zotlabs/Module/Settings/Features.php',
- 'Zotlabs\\Module\\Settings\\Oauth' => $baseDir . '/Zotlabs/Module/Settings/Oauth.php',
- 'Zotlabs\\Module\\Settings\\Permcats' => $baseDir . '/Zotlabs/Module/Settings/Permcats.php',
- 'Zotlabs\\Module\\Settings\\Tokens' => $baseDir . '/Zotlabs/Module/Settings/Tokens.php',
- 'Zotlabs\\Module\\Setup' => $baseDir . '/Zotlabs/Module/Setup.php',
- 'Zotlabs\\Module\\Share' => $baseDir . '/Zotlabs/Module/Share.php',
- 'Zotlabs\\Module\\Sharedwithme' => $baseDir . '/Zotlabs/Module/Sharedwithme.php',
- 'Zotlabs\\Module\\Siteinfo' => $baseDir . '/Zotlabs/Module/Siteinfo.php',
- 'Zotlabs\\Module\\Siteinfo_json' => $baseDir . '/Zotlabs/Module/Siteinfo_json.php',
- 'Zotlabs\\Module\\Sitelist' => $baseDir . '/Zotlabs/Module/Sitelist.php',
- 'Zotlabs\\Module\\Smilies' => $baseDir . '/Zotlabs/Module/Smilies.php',
- 'Zotlabs\\Module\\Snap' => $baseDir . '/Zotlabs/Module/Snap.php',
- 'Zotlabs\\Module\\Sources' => $baseDir . '/Zotlabs/Module/Sources.php',
- 'Zotlabs\\Module\\Sslify' => $baseDir . '/Zotlabs/Module/Sslify.php',
- 'Zotlabs\\Module\\Starred' => $baseDir . '/Zotlabs/Module/Starred.php',
- 'Zotlabs\\Module\\Subthread' => $baseDir . '/Zotlabs/Module/Subthread.php',
- 'Zotlabs\\Module\\Suggest' => $baseDir . '/Zotlabs/Module/Suggest.php',
- 'Zotlabs\\Module\\Tagger' => $baseDir . '/Zotlabs/Module/Tagger.php',
- 'Zotlabs\\Module\\Tagrm' => $baseDir . '/Zotlabs/Module/Tagrm.php',
- 'Zotlabs\\Module\\Tasks' => $baseDir . '/Zotlabs/Module/Tasks.php',
- 'Zotlabs\\Module\\Theme_info' => $baseDir . '/Zotlabs/Module/Theme_info.php',
- 'Zotlabs\\Module\\Thing' => $baseDir . '/Zotlabs/Module/Thing.php',
- 'Zotlabs\\Module\\Toggle_mobile' => $baseDir . '/Zotlabs/Module/Toggle_mobile.php',
- 'Zotlabs\\Module\\Toggle_safesearch' => $baseDir . '/Zotlabs/Module/Toggle_safesearch.php',
- 'Zotlabs\\Module\\Uexport' => $baseDir . '/Zotlabs/Module/Uexport.php',
- 'Zotlabs\\Module\\Update_channel' => $baseDir . '/Zotlabs/Module/Update_channel.php',
- 'Zotlabs\\Module\\Update_display' => $baseDir . '/Zotlabs/Module/Update_display.php',
- 'Zotlabs\\Module\\Update_home' => $baseDir . '/Zotlabs/Module/Update_home.php',
- 'Zotlabs\\Module\\Update_network' => $baseDir . '/Zotlabs/Module/Update_network.php',
- 'Zotlabs\\Module\\Update_pubstream' => $baseDir . '/Zotlabs/Module/Update_pubstream.php',
- 'Zotlabs\\Module\\Update_search' => $baseDir . '/Zotlabs/Module/Update_search.php',
- 'Zotlabs\\Module\\View' => $baseDir . '/Zotlabs/Module/View.php',
- 'Zotlabs\\Module\\Viewconnections' => $baseDir . '/Zotlabs/Module/Viewconnections.php',
- 'Zotlabs\\Module\\Viewsrc' => $baseDir . '/Zotlabs/Module/Viewsrc.php',
- 'Zotlabs\\Module\\Wall_attach' => $baseDir . '/Zotlabs/Module/Wall_attach.php',
- 'Zotlabs\\Module\\Wall_upload' => $baseDir . '/Zotlabs/Module/Wall_upload.php',
- 'Zotlabs\\Module\\Webfinger' => $baseDir . '/Zotlabs/Module/Webfinger.php',
- 'Zotlabs\\Module\\Webpages' => $baseDir . '/Zotlabs/Module/Webpages.php',
- 'Zotlabs\\Module\\Well_known' => $baseDir . '/Zotlabs/Module/Well_known.php',
- 'Zotlabs\\Module\\Wfinger' => $baseDir . '/Zotlabs/Module/Wfinger.php',
- 'Zotlabs\\Module\\Wiki' => $baseDir . '/Zotlabs/Module/Wiki.php',
- 'Zotlabs\\Module\\Xchan' => $baseDir . '/Zotlabs/Module/Xchan.php',
- 'Zotlabs\\Module\\Xpoco' => $baseDir . '/Zotlabs/Module/Xpoco.php',
- 'Zotlabs\\Module\\Xrd' => $baseDir . '/Zotlabs/Module/Xrd.php',
- 'Zotlabs\\Module\\Xref' => $baseDir . '/Zotlabs/Module/Xref.php',
- 'Zotlabs\\Module\\Zfinger' => $baseDir . '/Zotlabs/Module/Zfinger.php',
- 'Zotlabs\\Module\\Zotfeed' => $baseDir . '/Zotlabs/Module/Zotfeed.php',
- 'Zotlabs\\Module\\Zping' => $baseDir . '/Zotlabs/Module/Zping.php',
- 'Zotlabs\\Render\\Comanche' => $baseDir . '/Zotlabs/Render/Comanche.php',
- 'Zotlabs\\Render\\SimpleTemplate' => $baseDir . '/Zotlabs/Render/SimpleTemplate.php',
- 'Zotlabs\\Render\\SmartyInterface' => $baseDir . '/Zotlabs/Render/SmartyInterface.php',
- 'Zotlabs\\Render\\SmartyTemplate' => $baseDir . '/Zotlabs/Render/SmartyTemplate.php',
- 'Zotlabs\\Render\\TemplateEngine' => $baseDir . '/Zotlabs/Render/TemplateEngine.php',
- 'Zotlabs\\Render\\Theme' => $baseDir . '/Zotlabs/Render/Theme.php',
- 'Zotlabs\\Storage\\BasicAuth' => $baseDir . '/Zotlabs/Storage/BasicAuth.php',
- 'Zotlabs\\Storage\\Browser' => $baseDir . '/Zotlabs/Storage/Browser.php',
- 'Zotlabs\\Storage\\CalDAVClient' => $baseDir . '/Zotlabs/Storage/CalDAVClient.php',
- 'Zotlabs\\Storage\\Directory' => $baseDir . '/Zotlabs/Storage/Directory.php',
- 'Zotlabs\\Storage\\File' => $baseDir . '/Zotlabs/Storage/File.php',
- 'Zotlabs\\Storage\\GitRepo' => $baseDir . '/Zotlabs/Storage/GitRepo.php',
- 'Zotlabs\\Text\\Tagadelic' => $baseDir . '/Zotlabs/Text/Tagadelic.php',
- 'Zotlabs\\Web\\CheckJS' => $baseDir . '/Zotlabs/Web/CheckJS.php',
- 'Zotlabs\\Web\\Controller' => $baseDir . '/Zotlabs/Web/Controller.php',
- 'Zotlabs\\Web\\HTTPHeaders' => $baseDir . '/Zotlabs/Web/HTTPHeaders.php',
- 'Zotlabs\\Web\\HttpMeta' => $baseDir . '/Zotlabs/Web/HttpMeta.php',
- 'Zotlabs\\Web\\Router' => $baseDir . '/Zotlabs/Web/Router.php',
- 'Zotlabs\\Web\\Session' => $baseDir . '/Zotlabs/Web/Session.php',
- 'Zotlabs\\Web\\SessionHandler' => $baseDir . '/Zotlabs/Web/SessionHandler.php',
- 'Zotlabs\\Web\\SubModule' => $baseDir . '/Zotlabs/Web/SubModule.php',
- 'Zotlabs\\Web\\WebServer' => $baseDir . '/Zotlabs/Web/WebServer.php',
- 'Zotlabs\\Zot\\Auth' => $baseDir . '/Zotlabs/Zot/Auth.php',
- 'Zotlabs\\Zot\\DReport' => $baseDir . '/Zotlabs/Zot/DReport.php',
- 'Zotlabs\\Zot\\Finger' => $baseDir . '/Zotlabs/Zot/Finger.php',
- 'Zotlabs\\Zot\\IHandler' => $baseDir . '/Zotlabs/Zot/IHandler.php',
- 'Zotlabs\\Zot\\Receiver' => $baseDir . '/Zotlabs/Zot/Receiver.php',
- 'Zotlabs\\Zot\\Verify' => $baseDir . '/Zotlabs/Zot/Verify.php',
- 'Zotlabs\\Zot\\ZotHandler' => $baseDir . '/Zotlabs/Zot/ZotHandler.php',
);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
index 01914946c..d880bb6f5 100644
--- a/vendor/composer/autoload_namespaces.php
+++ b/vendor/composer/autoload_namespaces.php
@@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
+ 'OAuth2' => array($vendorDir . '/bshaffer/oauth2-server-php/src'),
'Michelf' => array($vendorDir . '/michelf/php-markdown'),
);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index bcae78e29..6200547d3 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -23,35 +23,24 @@ class ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d', 'loadClassLoader'));
- $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
- if ($useStaticLoader) {
- require_once __DIR__ . '/autoload_static.php';
-
- call_user_func(\Composer\Autoload\ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d::getInitializer($loader));
- } else {
- $map = require __DIR__ . '/autoload_namespaces.php';
- foreach ($map as $namespace => $path) {
- $loader->set($namespace, $path);
- }
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
- $map = require __DIR__ . '/autoload_psr4.php';
- foreach ($map as $namespace => $path) {
- $loader->setPsr4($namespace, $path);
- }
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
- $classMap = require __DIR__ . '/autoload_classmap.php';
- if ($classMap) {
- $loader->addClassMap($classMap);
- }
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
}
$loader->register(true);
- if ($useStaticLoader) {
- $includeFiles = Composer\Autoload\ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d::$files;
- } else {
- $includeFiles = require __DIR__ . '/autoload_files.php';
- }
+ $includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire7b34d7e50a62201ec5d5e526a5b8b35d($fileIdentifier, $file);
}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 0fb88e5a1..a03d306b4 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -21,7 +21,7 @@
"phpunit/phpunit": "*",
"sabre/cs": "~0.0.1"
},
- "time": "2016-03-08T02:29:27+00:00",
+ "time": "2016-03-08 02:29:27",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -79,7 +79,7 @@
"suggest": {
"hoa/bench": "If you would like to run the benchmark scripts"
},
- "time": "2016-07-15T19:52:17+00:00",
+ "time": "2016-07-15 19:52:17",
"bin": [
"bin/vobject",
"bin/generate_vcards"
@@ -173,7 +173,7 @@
"phpunit/phpunit": "*",
"sabre/cs": "~0.0.4"
},
- "time": "2015-11-05T20:14:39+00:00",
+ "time": "2015-11-05 20:14:39",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -238,7 +238,7 @@
"suggest": {
"ext-curl": " to make http requests with the Client class"
},
- "time": "2016-01-06T23:00:08+00:00",
+ "time": "2016-01-06 23:00:08",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -310,7 +310,7 @@
"ext-curl": "*",
"ext-pdo": "*"
},
- "time": "2016-06-28T02:44:05+00:00",
+ "time": "2016-06-28 02:44:05",
"bin": [
"bin/sabredav",
"bin/naturalselection"
@@ -379,7 +379,7 @@
"phpunit/phpunit": "*",
"sabre/cs": "~1.0.0"
},
- "time": "2016-10-09T22:57:52+00:00",
+ "time": "2016-10-09 22:57:52",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -435,7 +435,7 @@
"require": {
"php": ">=5.3.0"
},
- "time": "2016-10-10T12:19:37+00:00",
+ "time": "2016-10-10 12:19:37",
"type": "library",
"extra": {
"branch-alias": {
@@ -484,7 +484,7 @@
"require": {
"php": ">=5.3.0"
},
- "time": "2016-10-29T18:58:20+00:00",
+ "time": "2016-10-29 18:58:20",
"type": "library",
"extra": {
"branch-alias": {
@@ -540,7 +540,7 @@
"require-dev": {
"phpunit/phpunit": "^4.8"
},
- "time": "2016-09-21T13:01:43+00:00",
+ "time": "2016-09-21 13:01:43",
"type": "lib",
"installation-source": "dist",
"autoload": {
@@ -576,5 +576,63 @@
"markdown",
"markdownify"
]
+ },
+ {
+ "name": "bshaffer/oauth2-server-php",
+ "version": "v1.9.0",
+ "version_normalized": "1.9.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bshaffer/oauth2-server-php.git",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bshaffer/oauth2-server-php/zipball/8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "~2.8",
+ "firebase/php-jwt": "~2.2",
+ "mongodb/mongodb": "^1.1",
+ "predis/predis": "dev-master",
+ "thobbs/phpcassa": "dev-master"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
+ "firebase/php-jwt": "~1.1 is required to use MondoDB storage",
+ "predis/predis": "Required to use Redis storage",
+ "thobbs/phpcassa": "Required to use Cassandra storage"
+ },
+ "time": "2017-01-06 23:20:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "OAuth2": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brent Shaffer",
+ "email": "bshafs@gmail.com",
+ "homepage": "http://brentertainment.com"
+ }
+ ],
+ "description": "OAuth2 Server for PHP",
+ "homepage": "http://github.com/bshaffer/oauth2-server-php",
+ "keywords": [
+ "auth",
+ "oauth",
+ "oauth2"
+ ]
}
]
--
cgit v1.2.3
From 58aa0f3e1a52a0c20016a4330100231ad505e6e4 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Mon, 13 Mar 2017 16:19:47 -0700
Subject: code_allowed is a real mess. Start the cleanup by remving the account
level code allow and limiting to specific channels only. This reduces the
possibility of cross channel security issues coming into play. Then provide a
single function for checking the code permission. This is only partially done
as we often need to check against the observer or logged in channel as well
as the resource owner to ensure that this only returns true for local
channels which also own the requested resource.
---
Zotlabs/Module/Impel.php | 14 ++------------
Zotlabs/Module/Item.php | 14 ++------------
boot.php | 1 -
doc/database/db_account.bb | 1 -
include/channel.php | 17 +++++++++++++++++
include/import.php | 34 +++-------------------------------
include/text.php | 26 ++++----------------------
7 files changed, 28 insertions(+), 79 deletions(-)
diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php
index 197d9f859..77f488d26 100644
--- a/Zotlabs/Module/Impel.php
+++ b/Zotlabs/Module/Impel.php
@@ -144,18 +144,8 @@ class Impel extends \Zotlabs\Web\Controller {
// Verify ability to use html or php!!!
- $execflag = false;
-
- if($arr['mimetype'] === 'application/x-php') {
- $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1",
- intval(local_channel())
- );
-
- if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
- $execflag = true;
- }
- }
-
+ $execflag = ((intval($channel['channel_id']) == intval(local_channel()) && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
+
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
intval(local_channel())
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index afac1542d..43cf535a4 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -478,18 +478,8 @@ class Item extends \Zotlabs\Web\Controller {
// Verify ability to use html or php!!!
- $execflag = false;
-
- $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id
- where channel_id = %d limit 1",
- intval($profile_uid)
- );
- if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
- if($uid && (intval(get_account_id()) == intval($z[0]['account_id']))) {
- $execflag = true;
- }
- }
-
+ $execflag = ((intval($channel['channel_id']) == intval($profile_uid) && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
+
$gacl = $acl->get();
$str_contact_allow = $gacl['allow_cid'];
$str_group_allow = $gacl['allow_gid'];
diff --git a/boot.php b/boot.php
index a80bfbed3..e19ffddb0 100755
--- a/boot.php
+++ b/boot.php
@@ -541,7 +541,6 @@ define ( 'ACCOUNT_PENDING', 0x0010 );
* Account roles
*/
-define ( 'ACCOUNT_ROLE_ALLOWCODE', 0x0001 );
define ( 'ACCOUNT_ROLE_SYSTEM', 0x0002 );
define ( 'ACCOUNT_ROLE_DEVELOPER', 0x0004 );
define ( 'ACCOUNT_ROLE_ADMIN', 0x1000 );
diff --git a/doc/database/db_account.bb b/doc/database/db_account.bb
index 354f2d3a8..35d7a9eb3 100644
--- a/doc/database/db_account.bb
+++ b/doc/database/db_account.bb
@@ -58,7 +58,6 @@ define ( 'ACCOUNT_PENDING', 0x0010 );
* Account roles
*/
-define ( 'ACCOUNT_ROLE_ALLOWCODE', 0x0001 ); // 1 - this account can create content with PHP/Javascript
define ( 'ACCOUNT_ROLE_SYSTEM', 0x0002 ); // 2 - this is the special system account
define ( 'ACCOUNT_ROLE_DEVELOPER', 0x0004 );
define ( 'ACCOUNT_ROLE_ADMIN', 0x1000 ); // 4096 - this account is an administrator
diff --git a/include/channel.php b/include/channel.php
index b838f8393..ceb5eeb7a 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -2252,3 +2252,20 @@ function channel_remove($channel_id, $local = true, $unset_session=false) {
}
}
+
+/*
+ * This checks if a channel is allowed to publish executable code.
+ * It is up to the caller to determine if the observer or local_channel
+ * is in fact the resource owner whose channel_id is being checked
+ */
+
+function channel_codeallowed($channel_id) {
+
+ if(! intval($channel_id))
+ return false;
+
+ $x = channelx_by_n($channel_id);
+ if(($x) && ($x['channel_pageflags'] & PAGE_ALLOWCODE))
+ return true;
+ return false;
+}
\ No newline at end of file
diff --git a/include/import.php b/include/import.php
index 5c73b7ca3..bbe930864 100644
--- a/include/import.php
+++ b/include/import.php
@@ -534,16 +534,8 @@ function sync_chatrooms($channel,$chatrooms) {
function import_items($channel,$items,$sync = false,$relocate = null) {
if($channel && $items) {
- $allow_code = false;
- $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id
- where channel_id = %d limit 1",
- intval($channel['channel_id'])
- );
- if($r) {
- if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
- $allow_code = true;
- }
- }
+
+ $allow_code = channel_codeallowed($channel['channel_id']);
$deliver = false; // Don't deliver any messages or notifications when importing
@@ -1358,28 +1350,8 @@ function import_webpage_element($element, $channel, $type) {
}
// Verify ability to use html or php!!!
- $execflag = false;
- if($arr['mimetype'] === 'application/x-php' || $arr['mimetype'] === 'text/html') {
- $z = q("select account_id, account_roles, channel_pageflags from account "
- . "left join channel on channel_account_id = account_id where channel_id = %d limit 1",
- intval(local_channel())
- );
- if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
- $execflag = true;
- }
- else {
- logger('Unable to import element "' . $name .'" because AllowCode permission is denied.');
- notice( t('Unable to import element "' . $name .'" because AllowCode permission is denied.') . EOL);
- $element['import_success'] = 0;
- return $element;
- }
- }
-
-// $z = q("select * from iconfig where v = '%s' and k = '%s' and cat = 'system' limit 1",
-// dbesc($name),
-// dbesc($namespace)
-// );
+ $execflag = channel_codeallowed(local_channel());
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
diff --git a/include/text.php b/include/text.php
index fe3206b32..6715eca22 100644
--- a/include/text.php
+++ b/include/text.php
@@ -104,15 +104,11 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') {
return $s;
}
- $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1",
+ $r = q("select channel_pageflags from channel where channel_id = %d limit 1",
intval($channel_id)
);
- if($r) {
- if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
- if(local_channel() && (get_account_id() == $r[0]['account_id'])) {
- return $s;
- }
- }
+ if(($r) && (local_channel() == $channel_id) && ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
+ return $s;
}
if($type === 'text/html')
@@ -1795,23 +1791,9 @@ function mimetype_select($channel_id, $current = 'text/bbcode') {
);
- if(App::$is_sys) {
+ if((App::$is_sys) || (channel_codeallowed($channel_id) && $channel_id == local_channel())){
$x[] = 'application/x-php';
}
- else {
- $r = q("select account_id, account_roles, channel_pageflags from account left join channel on account_id = channel_account_id where
- channel_id = %d limit 1",
- intval($channel_id)
- );
-
- if($r) {
- if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
- if(local_channel() && get_account_id() == $r[0]['account_id']) {
- $x[] = 'application/x-php';
- }
- }
- }
- }
foreach($x as $y) {
$selected = (($y == $current) ? ' selected="selected" ' : '');
--
cgit v1.2.3
From 41fd72920995cd2844f0262c03685edf45f93723 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Mon, 13 Mar 2017 18:40:07 -0700
Subject: remove the unimplemented upload limit site settings
---
view/tpl/admin_site.tpl | 3 ---
1 file changed, 3 deletions(-)
diff --git a/view/tpl/admin_site.tpl b/view/tpl/admin_site.tpl
index 0bb3ceb15..1cdb4a56b 100755
--- a/view/tpl/admin_site.tpl
+++ b/view/tpl/admin_site.tpl
@@ -71,9 +71,6 @@
{{include file="field_select.tpl" field=$access_policy}}
-
{{include file="field_checkbox.tpl" field=$verify_email}}
{{include file="field_checkbox.tpl" field=$feed_contacts}}
--
cgit v1.2.3
From a153368814b9753e06ab4731fd2b19a1c394b1b1 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Mon, 13 Mar 2017 18:58:23 -0700
Subject: make redbasic compatible with red 5.x
---
view/theme/redbasic/php/theme.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/view/theme/redbasic/php/theme.php b/view/theme/redbasic/php/theme.php
index 95d5a2001..c76e77cf1 100644
--- a/view/theme/redbasic/php/theme.php
+++ b/view/theme/redbasic/php/theme.php
@@ -5,7 +5,7 @@
* * Description: Hubzilla standard theme
* * Version: 2.0
* * MinVersion: 2.2RC
- * * MaxVersion: 3.0
+ * * MaxVersion: 6.0
* * Author: Fabrixxm
* * Maintainer: Mike Macgirvin
* * Maintainer: Mario Vavti
--
cgit v1.2.3
From ab58c95d27e46b0fb37215d4c7b78ab370537cb6 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 00:22:57 -0700
Subject: get rid of some cruft in boot.php
---
boot.php | 79 ++++++++++++++--------------------------------------------------
1 file changed, 17 insertions(+), 62 deletions(-)
diff --git a/boot.php b/boot.php
index e19ffddb0..9ebc7e5b6 100755
--- a/boot.php
+++ b/boot.php
@@ -5,14 +5,13 @@
*/
/**
- * Hubzilla.
*
- * Hubzilla is an open source decentralised communications
+ * This is an open source decentralised communications
* platform combined with a decentralised identity/authentication framework
* wrapped in an extensible content management system, providing website designers
* the ability to embed fully decentralised communications and social tools
* into many traditional website designs (blogs, forums, small business
- * websites, charitable organisations, etc.). Hubzilla also provides DNS mobility
+ * websites, charitable organisations, etc.). Also provided is DNS mobility
* and internet scale privacy/access control.
*
* This allows any individual website to participate in a matrix of linked
@@ -126,7 +125,9 @@ define ( 'LANGUAGE_DETECT_MIN_CONFIDENCE', 0.01 );
* either more or less restrictive.
*/
-define ( 'STORAGE_DEFAULT_PERMISSIONS', 0770 );
+if(! defined('STORAGE_DEFAULT_PERMISSIONS')) {
+ define ( 'STORAGE_DEFAULT_PERMISSIONS', 0770 );
+}
/**
@@ -148,12 +149,6 @@ define ( 'STORAGE_DEFAULT_PERMISSIONS', 0770 );
define ( 'MAX_IMAGE_LENGTH', -1 );
-/**
- * Not yet used
- */
-
-define ( 'DEFAULT_DB_ENGINE', 'MyISAM' );
-
/**
* log levels
*/
@@ -183,15 +178,6 @@ define ( 'ACCESS_PAID', 1 );
define ( 'ACCESS_FREE', 2 );
define ( 'ACCESS_TIERED', 3 );
-/**
- * relationship types
- */
-
-define ( 'CONTACT_IS_FOLLOWER', 1);
-define ( 'CONTACT_IS_SHARING', 2);
-define ( 'CONTACT_IS_FRIEND', 3);
-
-
/**
* DB update return values
*/
@@ -518,14 +504,6 @@ define ( 'ACTIVITY_OBJ_THING', NAMESPACE_ZOT . '/activity/thing' );
define ( 'ACTIVITY_OBJ_LOCATION',NAMESPACE_ZOT . '/activity/location' );
define ( 'ACTIVITY_OBJ_FILE', NAMESPACE_ZOT . '/activity/file' );
-/**
- * item weight for query ordering
- */
-
-define ( 'GRAVITY_PARENT', 0);
-define ( 'GRAVITY_LIKE', 3);
-define ( 'GRAVITY_COMMENT', 6);
-
/**
* Account Flags
*/
@@ -550,16 +528,16 @@ define ( 'ACCOUNT_ROLE_ADMIN', 0x1000 );
*/
define ( 'ITEM_VISIBLE', 0x0000);
-//define ( 'ITEM_HIDDEN', 0x0001);
+define ( 'ITEM_HIDDEN', 0x0001);
define ( 'ITEM_BLOCKED', 0x0002);
define ( 'ITEM_MODERATED', 0x0004);
define ( 'ITEM_SPAM', 0x0008);
-//define ( 'ITEM_DELETED', 0x0010);
+define ( 'ITEM_DELETED', 0x0010);
define ( 'ITEM_UNPUBLISHED', 0x0020);
-//define ( 'ITEM_WEBPAGE', 0x0040); // is a static web page, not a conversational item
+define ( 'ITEM_WEBPAGE', 0x0040); // is a static web page, not a conversational item
define ( 'ITEM_DELAYED_PUBLISH', 0x0080);
define ( 'ITEM_BUILDBLOCK', 0x0100); // Named thusly to make sure nobody confuses this with ITEM_BLOCKED
-//define ( 'ITEM_PDL', 0x0200); // Page Description Language - e.g. Comanche
+define ( 'ITEM_PDL', 0x0200); // Page Description Language - e.g. Comanche
define ( 'ITEM_BUG', 0x0400); // Is a bug, can be used by the internal bug tracker
define ( 'ITEM_PENDING_REMOVE', 0x0800); // deleted, notification period has lapsed
define ( 'ITEM_DOC', 0x1000); // hubzilla only, define here so that item import does the right thing
@@ -710,6 +688,7 @@ function startup() {
* which is now static (although currently constructed at startup). We are only converting
* 'system' config settings.
*/
+
class miniApp {
public $config = array('system' => array());
@@ -1785,18 +1764,6 @@ function local_channel() {
return false;
}
-/**
- * local_user() got deprecated and replaced by local_channel().
- *
- * @deprecated since v2.1, use local_channel()
- * @see local_channel()
- */
-function local_user() {
- logger('local_user() is DEPRECATED, use local_channel()');
- return local_channel();
-}
-
-
/**
* @brief Returns a xchan_hash (visitor_id) of remote authenticated visitor
* or false.
@@ -1818,18 +1785,6 @@ function remote_channel() {
return false;
}
-/**
- * remote_user() got deprecated and replaced by remote_channel().
- *
- * @deprecated since v2.1, use remote_channel()
- * @see remote_channel()
- */
-function remote_user() {
- logger('remote_user() is DEPRECATED, use remote_channel()');
- return remote_channel();
-}
-
-
/**
* Contents of $s are displayed prominently on the page the next time
* a page is loaded. Usually used for errors or alerts.
@@ -2319,7 +2274,7 @@ function construct_page(&$a) {
}
/**
- * @brief Returns Hubzilla's root directory.
+ * @brief Returns appplication root directory.
*
* @return string
*/
@@ -2335,7 +2290,7 @@ function appdirpath() {
function head_set_icon($icon) {
App::$data['pageicon'] = $icon;
-// logger('head_set_icon: ' . $icon);
+
}
/**
@@ -2411,10 +2366,10 @@ function z_get_temp_dir() {
function z_check_cert() {
if(strpos(z_root(),'https://') !== false) {
- $x = z_fetch_url(z_root() . '/siteinfo/json');
+ $x = z_fetch_url(z_root() . '/siteinfo.json');
if(! $x['success']) {
$recurse = 0;
- $y = z_fetch_url(z_root() . '/siteinfo/json',false,$recurse,array('novalidate' => true));
+ $y = z_fetch_url(z_root() . '/siteinfo.json',false,$recurse,array('novalidate' => true));
if($y['success'])
cert_bad_email();
}
@@ -2425,9 +2380,9 @@ function z_check_cert() {
/**
* @brief Send email to admin if server has an invalid certificate.
*
- * If a Hubzilla hub is available over https it must have a publicly valid
- * certificate.
+ * If a hub is available over https it must have a publicly valid certificate.
*/
+
function cert_bad_email() {
$email_tpl = get_intltext_template("cert_bad_eml.tpl");
@@ -2437,7 +2392,7 @@ function cert_bad_email() {
'$error' => t('Website SSL certificate is not valid. Please correct.')
));
- $subject = email_header_encode(sprintf(t('[hubzilla] Website SSL error for %s'), App::get_hostname()));
+ $subject = email_header_encode(sprintf(t('[$Projectname] Website SSL error for %s'), App::get_hostname()));
mail(App::$config['system']['admin_email'], $subject, $email_msg,
'From: Administrator' . '@' . App::get_hostname() . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
--
cgit v1.2.3
From 1244b0e36af95226ba22f86025d2b24ab09003e6 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 00:23:44 -0700
Subject: class MarkdownSoap to safely store markdown by purifying and
preserving (escaped) what may be unsafe code in codeblocks. The stored item
needs to be unescaped just prior to calling the markdown-to-html processor
---
Zotlabs/Lib/MarkdownSoap.php | 86 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100644 Zotlabs/Lib/MarkdownSoap.php
diff --git a/Zotlabs/Lib/MarkdownSoap.php b/Zotlabs/Lib/MarkdownSoap.php
new file mode 100644
index 000000000..d0481eb4d
--- /dev/null
+++ b/Zotlabs/Lib/MarkdownSoap.php
@@ -0,0 +1,86 @@
+clean();
+ *
+ * What this does:
+ * 1. extracts code blocks and privately escapes them from processing
+ * 2. Run html purifier on the content
+ * 3. put back the code blocks
+ * 4. run htmlspecialchars on the entire content for safe storage
+ *
+ * At render time:
+ * $markdown = \Zotlabs\Lib\MarkdownSoap::unescape($text);
+ * $html = \Michelf\MarkdownExtra::DefaultTransform($markdown);
+ */
+
+
+
+class MarkdownSoap {
+
+ private $token;
+
+ private $str;
+
+ function __construct($s) {
+ $this->str = $s;
+ $this->token = random_string(20);
+ }
+
+
+ function clean() {
+ $x = $this->extract_code($this->str);
+ $x = $this->purify($x);
+ $x = $this->putback_code($x);
+ $x = $this->escape($x);
+
+ return $x;
+ }
+
+ function extract_code($s) {
+
+ $text = preg_replace_callback('{
+ (?:\n\n|\A\n?)
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
+ (?>
+ [ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ [ $this , 'encode_code' ], $s);
+
+ return $text;
+ }
+
+ function encode_code($matches) {
+ return $this->token . ';' . base64_encode($matches[1]) . ';' ;
+ }
+
+ function decode_code($matches) {
+ return base64_decode($matches[1]);
+ }
+
+ function putback_code($s) {
+ $text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm',[ $this, 'decode_code' ], $s);
+ return $text;
+ }
+
+ function purify($s) {
+ return purify_html($s);
+ }
+
+ function escape($s) {
+ return htmlspecialchars($s,ENT_QUOTES);
+ }
+
+ static public function unescape($s) {
+ return htmlspecialchars_decode($s,ENT_QUOTES);
+ }
+}
--
cgit v1.2.3
From 2f5f1a4d641c5873c308d6ab58ae239f2758e1e4 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 16:14:05 -0700
Subject: fix group by item query
---
include/items.php | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/include/items.php b/include/items.php
index 58305aa63..1037f9814 100755
--- a/include/items.php
+++ b/include/items.php
@@ -3674,7 +3674,7 @@ function zot_feed($uid,$observer_hash,$arr) {
if(! is_sys_channel($uid))
$sql_extra = item_permissions_sql($uid,$observer_hash);
- $limit = " LIMIT 100 ";
+ $limit = " LIMIT 5000 ";
if($mindate > NULL_DATE) {
$sql_extra .= " and ( created > '$mindate' or changed > '$mindate' ) ";
@@ -3686,15 +3686,7 @@ function zot_feed($uid,$observer_hash,$arr) {
}
- $items = array();
-
- /** @FIXME re-unite these SQL statements. There is no need for them to be separate. The mySQL is convoluted with misuse of group by. As it stands, there is a slight difference where the postgres version doesn't remove the duplicate parents up to 100. In practice this doesn't matter. It could be made to match behavior by adding "distinct on (parent) " to the front of the selection list, at a not-worth-it performance penalty (page temp results to disk). duplicates are still ignored in the in() clause, you just get less than 100 parents if there are many children. */
-
- if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
- $groupby = '';
- } else {
- $groupby = 'GROUP BY parent';
- }
+ $items = [];
$item_normal = item_normal();
@@ -3703,7 +3695,7 @@ function zot_feed($uid,$observer_hash,$arr) {
WHERE uid != %d
$item_normal
AND item_wall = 1
- and item_private = 0 $sql_extra $groupby ORDER BY created ASC $limit",
+ and item_private = 0 $sql_extra ORDER BY created ASC $limit",
intval($uid)
);
}
@@ -3711,19 +3703,25 @@ function zot_feed($uid,$observer_hash,$arr) {
$r = q("SELECT parent, created, postopts from item
WHERE uid = %d $item_normal
AND item_wall = 1
- $sql_extra $groupby ORDER BY created ASC $limit",
+ $sql_extra ORDER BY created ASC $limit",
intval($uid)
);
}
+ $parents = [];
+
if($r) {
- for($x = 0; $x < count($r); $x ++) {
- if(strpos($r[$x]['postopts'],'nodeliver') !== false) {
- unset($r[$x]);
- }
+ foreach($r as $rv) {
+ if(array_key_exists($rv['parent'],$parents))
+ continue;
+ if(strpos($rv['postopts'],'nodeliver') !== false)
+ continue;
+ $parents[$rv['parent']] = $rv;
+ if(count($parents) > 200)
+ break;
}
- $parents_str = ids_to_querystr($r,'parent');
+ $parents_str = ids_to_querystr($parents,'parent');
$sys_query = ((is_sys_channel($uid)) ? $sql_extra : '');
$item_normal = item_normal();
--
cgit v1.2.3
From 2c73b457ef0943d46804480a0aa016f64c11edbf Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 17:07:29 -0700
Subject: input filter updates
---
Zotlabs/Lib/MarkdownSoap.php | 2 +-
Zotlabs/Lib/NativeWikiPage.php | 31 +--------------
Zotlabs/Module/Item.php | 21 +++-------
Zotlabs/Module/Wiki.php | 1 +
include/items.php | 87 ++++++++++++++++++------------------------
include/text.php | 18 +++++----
6 files changed, 57 insertions(+), 103 deletions(-)
diff --git a/Zotlabs/Lib/MarkdownSoap.php b/Zotlabs/Lib/MarkdownSoap.php
index d0481eb4d..2dcaaec9a 100644
--- a/Zotlabs/Lib/MarkdownSoap.php
+++ b/Zotlabs/Lib/MarkdownSoap.php
@@ -5,7 +5,7 @@ namespace Zotlabs\Lib;
/**
* MarkdownSoap
* Purify Markdown for storage
- * $x = newMarkdownSoap($string_to_be_cleansed);
+ * $x = new MarkdownSoap($string_to_be_cleansed);
* $text = $x->clean();
*
* What this does:
diff --git a/Zotlabs/Lib/NativeWikiPage.php b/Zotlabs/Lib/NativeWikiPage.php
index 941ade90c..9f54081a1 100644
--- a/Zotlabs/Lib/NativeWikiPage.php
+++ b/Zotlabs/Lib/NativeWikiPage.php
@@ -307,34 +307,6 @@ class NativeWikiPage {
return null;
}
-
-
- static public function prepare_content($s) {
-
- $text = preg_replace_callback('{
- (?:\n\n|\A\n?)
- ( # $1 = the code block -- one or more lines, starting with a space/tab
- (?>
- [ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
- .*\n+
- )+
- )
- ((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
- }xm',
- 'self::nwiki_prepare_content_callback', $s);
-
- return $text;
- }
-
- static public function nwiki_prepare_content_callback($matches) {
- $codeblock = $matches[1];
-
- $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES, UTF8, false);
- return "\n\n" . $codeblock ;
- }
-
-
-
static public function save_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
@@ -352,7 +324,8 @@ class NativeWikiPage {
$mimetype = $w['mimeType'];
if($mimetype === 'text/markdown') {
- $content = purify_html(Zlib\NativeWikiPage::prepare_content($content));
+ $x = new Zlib\MarkdownSoap($content);
+ $content = $x->clean();
}
else {
$content = escape_tags($content);
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 43cf535a4..71f410b2a 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -471,15 +471,16 @@ class Item extends \Zotlabs\Web\Controller {
if(! $mimetype)
$mimetype = 'text/bbcode';
+
+ $execflag = ((intval($uid) == intval($profile_uid)
+ && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
+
if($preview) {
- $body = z_input_filter($profile_uid,$body,$mimetype);
+ $body = z_input_filter($body,$mimetype,$execflag);
}
-
// Verify ability to use html or php!!!
- $execflag = ((intval($channel['channel_id']) == intval($profile_uid) && ($channel['channel_pageflags'] & PAGE_ALLOWCODE)) ? true : false);
-
$gacl = $acl->get();
$str_contact_allow = $gacl['allow_cid'];
$str_group_allow = $gacl['allow_gid'];
@@ -843,18 +844,6 @@ class Item extends \Zotlabs\Web\Controller {
if(mb_strlen($datarray['title']) > 255)
$datarray['title'] = mb_substr($datarray['title'],0,255);
- if(array_key_exists('item_private',$datarray) && $datarray['item_private']) {
-
- $datarray['body'] = trim(z_input_filter($datarray['uid'],$datarray['body'],$datarray['mimetype']));
-
- if($uid) {
- if($channel['channel_hash'] === $datarray['author_xchan']) {
- $datarray['sig'] = base64url_encode(rsa_sign($datarray['body'],$channel['channel_prvkey']));
- $datarray['item_verified'] = 1;
- }
- }
- }
-
if($webpage) {
Zlib\IConfig::Set($datarray,'system', webpage_to_namespace($webpage),
(($pagetitle) ? $pagetitle : substr($datarray['mid'],0,16)),true);
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
index 5e7307c7b..79ec5ba25 100644
--- a/Zotlabs/Module/Wiki.php
+++ b/Zotlabs/Module/Wiki.php
@@ -243,6 +243,7 @@ class Wiki extends \Zotlabs\Web\Controller {
$renderedContent = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))), argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
else {
+ $content = Zlib\MarkdownSoap::unescape($content);
$html = Zlib\NativeWikiPage::generate_toc(zidify_text(purify_html(MarkdownExtra::defaultTransform(Zlib\NativeWikiPage::bbcode($content)))));
$renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
}
diff --git a/include/items.php b/include/items.php
index 1037f9814..c978805cd 100755
--- a/include/items.php
+++ b/include/items.php
@@ -334,18 +334,6 @@ function post_activity_item($arr,$allow_code = false,$deliver = true) {
if(! array_key_exists('mimetype',$arr))
$arr['mimetype'] = 'text/bbcode';
- if(array_key_exists('item_private',$arr) && $arr['item_private']) {
-
- $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
-
- if($channel) {
- if($channel['channel_hash'] === $arr['author_xchan']) {
- $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_verified'] = 1;
- }
- }
- }
-
$arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : item_message_id());
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']);
$arr['thr_parent'] = ((x($arr,'thr_parent')) ? $arr['thr_parent'] : $arr['mid']);
@@ -1483,35 +1471,36 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
// obsolete, but needed so as not to throw not-null constraints on some database driveres
$arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : 0 );
- // only detect language if we have text content, and if the post is private but not yet
- // obscured, make it so.
- if((! array_key_exists('item_obscured',$arr)) || $arr['item_obscured'] == 0) {
- $arr['lang'] = detect_language($arr['body']);
- // apply the input filter here - if it is obscured it has been filtered already
- $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
+ $arr['lang'] = detect_language($arr['body']);
+ // apply the input filter here
+ $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
- if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
+ if(local_channel() && (local_channel() == $arr['uid'])) {
+ if(! $arr['sig']) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
}
}
+ }
- $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
+ if(! array_key_exists('sig',$arr))
+ $arr['sig'] = '';
- if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
- $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
- call_hooks('item_translate', $translate);
- if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
- logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
- $ret['message'] = 'language not accepted';
- return $ret;
- }
- $arr = $translate['item'];
+ $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
+
+ if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
+ $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
+ call_hooks('item_translate', $translate);
+ if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
+ logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
+ $ret['message'] = 'language not accepted';
+ return $ret;
}
+ $arr = $translate['item'];
}
if((x($arr,'obj')) && is_array($arr['obj'])) {
@@ -1907,33 +1896,31 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
return $ret;
}
- if((! array_key_exists('item_obscured', $arr)) || $arr['item_obscured'] == 0) {
- $arr['lang'] = detect_language($arr['body']);
+ $arr['lang'] = detect_language($arr['body']);
- // apply the input filter here - if it is obscured it has been filtered already
- $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
+ // apply the input filter here
+ $arr['body'] = trim($arr['body'],$arr['mimetype'],$allow_exec);
- if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
- $channel = App::get_channel();
- if($channel['channel_hash'] === $arr['author_xchan']) {
- $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_verified'] = 1;
- }
- }
+ if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
+ $channel = App::get_channel();
+ if($channel['channel_hash'] === $arr['author_xchan']) {
+ $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
+ $arr['item_verified'] = 1;
+ }
+ }
- $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
+ $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages');
- if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
- $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
- call_hooks('item_translate', $translate);
- if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
- logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
- $ret['message'] = 'language not accepted';
- return $ret;
- }
- $arr = $translate['item'];
+ if((is_array($allowed_languages)) && ($arr['lang']) && (! array_key_exists($arr['lang'],$allowed_languages))) {
+ $translate = array('item' => $arr, 'from' => $arr['lang'], 'to' => $allowed_languages, 'translated' => false);
+ call_hooks('item_translate', $translate);
+ if((! $translate['translated']) && (intval(get_pconfig($arr['uid'],'system','reject_disallowed_languages')))) {
+ logger('item_store: language ' . $arr['lang'] . ' not accepted for uid ' . $arr['uid']);
+ $ret['message'] = 'language not accepted';
+ return $ret;
}
+ $arr = $translate['item'];
}
if((x($arr,'obj')) && is_array($arr['obj'])) {
diff --git a/include/text.php b/include/text.php
index 6715eca22..500c87ad5 100644
--- a/include/text.php
+++ b/include/text.php
@@ -3,6 +3,7 @@
* @file include/text.php
*/
+use \Zotlabs\Lib as Zlib;
use \Michelf\MarkdownExtra;
require_once("include/bbcode.php");
@@ -89,12 +90,10 @@ function escape_tags($string) {
}
-function z_input_filter($channel_id,$s,$type = 'text/bbcode') {
+function z_input_filter($s,$type = 'text/bbcode',$allow_code = false) {
if($type === 'text/bbcode')
return escape_tags($s);
- if($type === 'text/markdown')
- return escape_tags($s);
if($type == 'text/plain')
return escape_tags($s);
if($type == 'application/x-pdl')
@@ -104,13 +103,17 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') {
return $s;
}
- $r = q("select channel_pageflags from channel where channel_id = %d limit 1",
- intval($channel_id)
- );
- if(($r) && (local_channel() == $channel_id) && ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
+ if($allow_code) {
+ if($type === 'text/markdown')
+ return htmlspecialchars($s,ENT_QUOTES);
return $s;
}
+ if($type === 'text/markdown') {
+ $x = new Zlib\MarkdownSoap($s);
+ return $x->clean();
+ }
+
if($type === 'text/html')
return purify_html($s);
@@ -1636,6 +1639,7 @@ function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
break;
case 'text/markdown':
+ $text = Zlib\MarkdownSoap::unescape($text);
$s = MarkdownExtra::defaultTransform($text);
break;
--
cgit v1.2.3
From e891380ed571082612859554fb8fa805dc822b1a Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 18:42:51 -0700
Subject: dim class was un-themed
---
view/theme/redbasic/css/style.css | 2 +-
view/tpl/admin_channels.tpl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css
index c632dbc74..1c185a5d5 100644
--- a/view/theme/redbasic/css/style.css
+++ b/view/theme/redbasic/css/style.css
@@ -1104,7 +1104,7 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover {
.contact-block-content {
margin-top: 10px;
}
-.contact-block-img.archived, .app-deleted {
+.contact-block-img.archived, .app-deleted, .dim {
opacity: 0.3;
filter:alpha(opacity=30);
}
diff --git a/view/tpl/admin_channels.tpl b/view/tpl/admin_channels.tpl
index f15742f78..452e0eeec 100755
--- a/view/tpl/admin_channels.tpl
+++ b/view/tpl/admin_channels.tpl
@@ -35,7 +35,7 @@
-
+
--
cgit v1.2.3
From 32a9487ff9901bcd59d65a410becbed832dd2e2f Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 18:46:50 -0700
Subject: use dim for the button border also
---
view/tpl/admin_channels.tpl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/view/tpl/admin_channels.tpl b/view/tpl/admin_channels.tpl
index 452e0eeec..f15742f78 100755
--- a/view/tpl/admin_channels.tpl
+++ b/view/tpl/admin_channels.tpl
@@ -35,7 +35,7 @@
-
+
--
cgit v1.2.3
From e399de8ad4a17c4fa07f7ad41c879278f6ce5458 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 21:40:11 -0700
Subject: store os_path and display_path with files
---
include/attach.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/attach.php b/include/attach.php
index 79313ab1a..f8227fb4b 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -705,8 +705,9 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$os_relpath .= $hash;
// not yet used
- $os_path = '';
- $display_path = '';
+ $os_path = ltrim($os_relpath,'/');
+
+ $display_path = $pathname . '/' . $filename;
if($src)
@file_put_contents($os_basepath . $os_relpath,@file_get_contents($src));
--
cgit v1.2.3
From fa89b8f66d98f8d74ce9283314649d4916652df9 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Tue, 14 Mar 2017 22:02:28 -0700
Subject: add os_path and display_path to photos, fix some issues with multiple
path separators after cloud/nickname in the content field of attach and
photos
---
include/attach.php | 9 ++---
include/photo/photo_driver.php | 88 +-----------------------------------------
include/photos.php | 11 +++---
3 files changed, 12 insertions(+), 96 deletions(-)
diff --git a/include/attach.php b/include/attach.php
index f8227fb4b..cbcdbc399 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -702,11 +702,10 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$os_relpath .= $folder_hash . '/';
}
- $os_relpath .= $hash;
-
- // not yet used
- $os_path = ltrim($os_relpath,'/');
+ $os_relpath .= $hash;
+ $os_relpath = ltrim($os_relpath,'/');
+ $os_path = $os_relpath;
$display_path = $pathname . '/' . $filename;
if($src)
@@ -811,7 +810,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($is_photo) {
- $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options );
+ $args = array( 'source' => $source, 'visible' => $visible, 'resource_id' => $hash, 'album' => basename($pathname), 'os_syspath' => $os_basepath . $os_relpath, 'os_path' => $os_path, 'display_path' => $display_path, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct, 'options' => $options );
if($arr['contact_allow'])
$args['contact_allow'] = $arr['contact_allow'];
if($arr['group_allow'])
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index c8b3c3782..923e34dbe 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -380,7 +380,7 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
- (intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())),
+ (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())),
intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['imgscale']),
@@ -411,7 +411,7 @@ abstract class photo_driver {
dbesc($p['album']),
intval($this->getHeight()),
intval($this->getWidth()),
- (intval($p['os_storage']) ? dbescbin($p['os_path']) : dbescbin($this->imageString())),
+ (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())),
intval($p['os_storage']),
intval(strlen($this->imageString())),
intval($p['imgscale']),
@@ -429,90 +429,6 @@ abstract class photo_driver {
return $r;
}
-
- // should be obsolete now
-
- public function store($aid, $uid, $xchan, $rid, $filename, $album, $scale, $usage = PHOTO_NORMAL, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') {
-
- $x = q("select id from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1",
- dbesc($rid),
- intval($uid),
- dbesc($xchan),
- intval($scale)
- );
- if(count($x)) {
- $r = q("UPDATE photo
- set aid = %d,
- uid = %d,
- xchan = '%s',
- resource_id = '%s',
- created = '%s',
- edited = '%s',
- filename = '%s',
- mimetype = '%s',
- album = '%s',
- height = %d,
- width = %d,
- content = '%s',
- filesize = %d,
- imgscale = %d,
- photo_usage = %d,
- allow_cid = '%s',
- allow_gid = '%s',
- deny_cid = '%s',
- deny_gid = '%s'
- where id = %d",
-
- intval($aid),
- intval($uid),
- dbesc($xchan),
- dbesc($rid),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc(basename($filename)),
- dbesc($this->getType()),
- dbesc($album),
- intval($this->getHeight()),
- intval($this->getWidth()),
- dbescbin($this->imageString()),
- intval(strlen($this->imageString())),
- intval($scale),
- intval($photo_usage),
- dbesc($allow_cid),
- dbesc($allow_gid),
- dbesc($deny_cid),
- dbesc($deny_gid),
- intval($x[0]['id'])
- );
- }
- else {
- $r = q("INSERT INTO photo
- ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, filesize, imgscale, photo_usage, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s' )",
- intval($aid),
- intval($uid),
- dbesc($xchan),
- dbesc($rid),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc(basename($filename)),
- dbesc($this->getType()),
- dbesc($album),
- intval($this->getHeight()),
- intval($this->getWidth()),
- dbescbin($this->imageString()),
- intval(strlen($this->imageString())),
- intval($scale),
- intval($photo_usage),
- dbesc($allow_cid),
- dbesc($allow_gid),
- dbesc($deny_cid),
- dbesc($deny_gid)
- );
- }
- return $r;
- }
-
}
diff --git a/include/photos.php b/include/photos.php
index 68ff32924..46007fd42 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -65,8 +65,8 @@ function photo_upload($channel, $observer, $args) {
$os_storage = 0;
- if($args['os_path'] && $args['getimagesize']) {
- $imagedata = @file_get_contents($args['os_path']);
+ if($args['os_syspath'] && $args['getimagesize']) {
+ $imagedata = @file_get_contents($args['os_syspath']);
$filename = $args['filename'];
$filesize = strlen($imagedata);
// this is going to be deleted if it exists
@@ -149,7 +149,7 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
- $exif = $ph->orient(($args['os_path']) ? $args['os_path'] : $src);
+ $exif = $ph->orient(($args['os_syspath']) ? $args['os_syspath'] : $src);
@unlink($src);
@@ -176,7 +176,8 @@ function photo_upload($channel, $observer, $args) {
'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL,
'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'],
'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'],
- 'os_storage' => $os_storage, 'os_path' => $args['os_path']
+ 'os_storage' => $os_storage, 'os_syspath' => $args['os_syspath'],
+ 'os_path' => $args['os_path'], 'display_path' => $args['display_path']
);
if($args['created'])
$p['created'] = $args['created'];
@@ -201,7 +202,7 @@ function photo_upload($channel, $observer, $args) {
$errors = true;
unset($p['os_storage']);
- unset($p['os_path']);
+ unset($p['os_syspath']);
if(($width > 1024 || $height > 1024) && (! $errors))
$ph->scaleImage(1024);
--
cgit v1.2.3
From 6078d02c3ac8ead59dbbecab2eb5de88ad7a1efc Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Wed, 15 Mar 2017 01:20:21 -0700
Subject: more work related to attach/photo and os_path, display_path and
general code cleanup
---
Zotlabs/Module/Cover_photo.php | 64 +++++++++++++++++++++-------------------
Zotlabs/Module/Profile_photo.php | 12 ++++----
2 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php
index 72ec1020d..47bce6c2b 100644
--- a/Zotlabs/Module/Cover_photo.php
+++ b/Zotlabs/Module/Cover_photo.php
@@ -23,19 +23,17 @@ require_once('include/channel.php');
class Cover_photo extends \Zotlabs\Web\Controller {
function init() {
-
if(! local_channel()) {
return;
}
$channel = \App::get_channel();
- profile_load($channel['channel_address']);
-
+ profile_load($channel['channel_address']);
}
- /* @brief Evaluate posted values
+ /**
+ * @brief Evaluate posted values
*
- * @param $a Current application
* @return void
*
*/
@@ -130,8 +128,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$aid = get_account_id();
- $p = array('aid' => $aid, 'uid' => local_channel(), 'resource_id' => $base_image['resource_id'],
- 'filename' => $base_image['filename'], 'album' => t('Cover Photos'));
+ $p = [
+ 'aid' => $aid,
+ 'uid' => local_channel(),
+ 'resource_id' => $base_image['resource_id'],
+ 'filename' => $base_image['filename'],
+ 'album' => t('Cover Photos'),
+ 'os_path' => $base_image['os_path'],
+ 'display_path' => $base_image['display_path']
+ ];
$p['imgscale'] = 7;
$p['photo_usage'] = PHOTO_COVER;
@@ -195,11 +200,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$os_storage = false;
foreach($i as $ii) {
- $smallest = intval($ii['imgscale']);
+ $smallest = intval($ii['imgscale']);
$os_storage = intval($ii['os_storage']);
- $imagedata = $ii['content'];
- $filetype = $ii['mimetype'];
-
+ $imagedata = $ii['content'];
+ $filetype = $ii['mimetype'];
}
}
@@ -263,10 +267,10 @@ class Cover_photo extends \Zotlabs\Web\Controller {
}
- /* @brief Generate content of profile-photo view
+ /**
+ * @brief Generate content of profile-photo view
*
- * @param $a Current application
- * @return void
+ * @return string
*
*/
@@ -350,15 +354,15 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$tpl = get_markup_template('cover_photo.tpl');
$o .= replace_macros($tpl,array(
- '$user' => \App::$channel['channel_address'],
- '$lbl_upfile' => t('Upload File:'),
- '$lbl_profiles' => t('Select a profile:'),
- '$title' => t('Upload Cover Photo'),
- '$submit' => t('Upload'),
- '$profiles' => $profiles,
+ '$user' => \App::$channel['channel_address'],
+ '$lbl_upfile' => t('Upload File:'),
+ '$lbl_profiles' => t('Select a profile:'),
+ '$title' => t('Upload Cover Photo'),
+ '$submit' => t('Upload'),
+ '$profiles' => $profiles,
'$form_security_token' => get_form_security_token("cover_photo"),
- // FIXME - yuk
- '$select' => sprintf('%s %s', t('or'), ($newuser) ? '' . t('skip this step') . '' : '' . t('select a photo from your photo albums') . '')
+ /// @FIXME - yuk
+ '$select' => sprintf('%s %s', t('or'), ($newuser) ? '' . t('skip this step') . '' : '' . t('select a photo from your photo albums') . '')
));
call_hooks('cover_photo_content_end', $o);
@@ -370,14 +374,14 @@ class Cover_photo extends \Zotlabs\Web\Controller {
$resolution = 3;
$tpl = get_markup_template("cropcover.tpl");
$o .= replace_macros($tpl,array(
- '$filename' => $filename,
- '$profile' => intval($_REQUEST['profile']),
- '$resource' => \App::$data['imagecrop'] . '-3',
- '$image_url' => z_root() . '/photo/' . $filename,
- '$title' => t('Crop Image'),
- '$desc' => t('Please adjust the image cropping for optimum viewing.'),
+ '$filename' => $filename,
+ '$profile' => intval($_REQUEST['profile']),
+ '$resource' => \App::$data['imagecrop'] . '-3',
+ '$image_url' => z_root() . '/photo/' . $filename,
+ '$title' => t('Crop Image'),
+ '$desc' => t('Please adjust the image cropping for optimum viewing.'),
'$form_security_token' => get_form_security_token("cover_photo"),
- '$done' => t('Done Editing')
+ '$done' => t('Done Editing')
));
return $o;
}
@@ -393,8 +397,6 @@ class Cover_photo extends \Zotlabs\Web\Controller {
*
*/
-
-
function cover_photo_crop_ui_head(&$a, $ph, $hash, $smallest){
$max_length = get_config('system','max_image_length');
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 438580917..e8f0e5186 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -108,11 +108,13 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$aid = get_account_id();
$p = [
- 'aid' => $aid,
- 'uid' => local_channel(),
- 'resource_id' => $base_image['resource_id'],
- 'filename' => $base_image['filename'],
- 'album' => t('Profile Photos')
+ 'aid' => $aid,
+ 'uid' => local_channel(),
+ 'resource_id' => $base_image['resource_id'],
+ 'filename' => $base_image['filename'],
+ 'album' => t('Profile Photos'),
+ 'os_path' => $base_image['os_path'],
+ 'display_path' => $base_image['display_path']
];
$p['imgscale'] = PHOTO_RES_PROFILE_300;
--
cgit v1.2.3
From bcd02edd8032ba3a3de40cbc35dda3529da00a7c Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Wed, 15 Mar 2017 15:53:03 -0700
Subject: ensure z_input_filter is called exactly once, since we now depend on
the number of htmlspecialchars operations for markdown content. Also ensure
that the content is escaped the correct number of times on imported items.
---
include/items.php | 68 ++++++++++++++++++++++++++++++++++++------------------
include/photos.php | 9 ++++++++
2 files changed, 55 insertions(+), 22 deletions(-)
diff --git a/include/items.php b/include/items.php
index c978805cd..ace8b2fb2 100755
--- a/include/items.php
+++ b/include/items.php
@@ -528,11 +528,6 @@ function get_item_elements($x,$allow_code = false) {
$arr = array();
- if($allow_code)
- $arr['body'] = $x['body'];
- else
- $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
-
$key = get_config('system','pubkey');
$maxlen = get_max_import_size();
@@ -640,7 +635,17 @@ function get_item_elements($x,$allow_code = false) {
return array();
}
+ // Check signature on the body text received.
+ // This presents an issue that we aren't verifying the text that is actually displayed
+ // on this site. We are however verifying the received text was exactly as received.
+ // We have every right to strip content that poses a security risk. You are welcome to
+ // create a plugin to verify the content after filtering if this offends you.
+
if($arr['sig']) {
+
+ // check the supplied signature against the supplied content.
+ // Note that we will purify the content which could change it.
+
$r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['author_xchan'])
);
@@ -650,6 +655,14 @@ function get_item_elements($x,$allow_code = false) {
logger('get_item_elements: message verification failed.');
}
+ // if the input is markdown, remove one level of html escaping.
+ // It will be re-applied in item_store() and/or item_store_update().
+ // Do this after signature checking as the original signature
+ // was generated on the escaped content.
+
+ if($arr['mimetype'] === 'text/markdown')
+ $arr['body'] = \Zotlabs\Lib\MarkdownSoap::unescape($arr['body']);
+
if(array_key_exists('revision',$x)) {
// extended export encoding
@@ -1475,14 +1488,20 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['lang'] = detect_language($arr['body']);
// apply the input filter here
- $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
-
- if(local_channel() && (local_channel() == $arr['uid'])) {
- if(! $arr['sig']) {
- $channel = App::get_channel();
- if($channel['channel_hash'] === $arr['author_xchan']) {
- $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_verified'] = 1;
+
+ if(array_key_exists('input_filtered_signed',$arr)) {
+ unset($arr['input_filtered_signed']);
+ }
+ else {
+ $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
+
+ if(local_channel() && (local_channel() == $arr['uid'])) {
+ if(! $arr['sig']) {
+ $channel = App::get_channel();
+ if($channel['channel_hash'] === $arr['author_xchan']) {
+ $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
+ $arr['item_verified'] = 1;
+ }
}
}
}
@@ -1896,17 +1915,22 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
return $ret;
}
-
$arr['lang'] = detect_language($arr['body']);
- // apply the input filter here
- $arr['body'] = trim($arr['body'],$arr['mimetype'],$allow_exec);
-
- if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
- $channel = App::get_channel();
- if($channel['channel_hash'] === $arr['author_xchan']) {
- $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
- $arr['item_verified'] = 1;
+ if(array_key_exists('input_filtered_signed',$arr)) {
+ unset($arr['input_filtered_signed']);
+ }
+ else {
+ $arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
+
+ if(local_channel() && (local_channel() == $arr['uid'])) {
+ if(! $arr['sig']) {
+ $channel = App::get_channel();
+ if($channel['channel_hash'] === $arr['author_xchan']) {
+ $arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
+ $arr['item_verified'] = 1;
+ }
+ }
}
}
diff --git a/include/photos.php b/include/photos.php
index 46007fd42..c0f0ec8a9 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -333,12 +333,15 @@ function photo_upload($channel, $observer, $args) {
if($item['mid'] === $item['parent_mid']) {
$item['body'] = $summary;
+ $item['mimetype'] = 'text/bbcode';
$item['obj_type'] = ACTIVITY_OBJ_PHOTO;
$item['obj'] = json_encode($object);
$item['tgt_type'] = ACTIVITY_OBJ_ALBUM;
$item['target'] = json_encode($target);
+ $item['body'] = trim(z_input_filter($item['body'],$item['mimetype'],false));
+
if($item['author_xchan'] === $channel['channel_hash']) {
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
$item['item_verified'] = 1;
@@ -346,6 +349,12 @@ function photo_upload($channel, $observer, $args) {
else {
$item['sig'] = '';
}
+
+ // notify item_store or item_store_update that the input has been filtered and signed already.
+ // The signing procedure in those functions uses local_channel() which may not apply here.
+
+ $item['input_filtered_signed'] = true;
+
$force = true;
}
--
cgit v1.2.3
From df6c07aaadda2e89d2843bae136f813c909637ba Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Wed, 15 Mar 2017 16:55:47 -0700
Subject: Comanche: allow widgets to be class based and stored appropriately in
Zotlabs
---
Zotlabs/Render/Comanche.php | 14 ++++++++++++++
Zotlabs/Widget/Notes.php | 23 +++++++++++++++++++++++
include/widgets.php | 16 ----------------
3 files changed, 37 insertions(+), 16 deletions(-)
create mode 100644 Zotlabs/Widget/Notes.php
diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php
index 5826063fd..899fbd8aa 100644
--- a/Zotlabs/Render/Comanche.php
+++ b/Zotlabs/Render/Comanche.php
@@ -410,6 +410,20 @@ class Comanche {
}
}
+ $clsname = ucfirst($name);
+ $nsname = "Zotlabs\\Widget\\" . $clsname;
+ if(file_exists('Zotlabs/SiteWidget/' . $clsname . '.php'))
+ require_once('Zotlabs/SiteWidget/' . $clsname . '.php');
+ elseif(file_exists('Zotlabs/Widget/' . $clsname . '.php'))
+ require_once('Zotlabs/Widget/' . $clsname . '.php');
+ if(class_exists($nsname)) {
+ $x = new $nsname;
+ $f = 'widget';
+ if(method_exists($x,$f)) {
+ return $x->$f($vars);
+ }
+ }
+
$func = 'widget_' . trim($name);
if(! function_exists($func)) {
diff --git a/Zotlabs/Widget/Notes.php b/Zotlabs/Widget/Notes.php
new file mode 100644
index 000000000..5c83a550f
--- /dev/null
+++ b/Zotlabs/Widget/Notes.php
@@ -0,0 +1,23 @@
+ t('Notes'),
+ '$text' => $text,
+ '$save' => t('Save'),
+ ));
+
+ return $o;
+ }
+}
diff --git a/include/widgets.php b/include/widgets.php
index f05c7c0ee..b5389e60d 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -174,22 +174,6 @@ function widget_follow($args) {
}
-function widget_notes($arr) {
- if(! local_channel())
- return '';
- if(! feature_enabled(local_channel(),'private_notes'))
- return '';
-
- $text = get_pconfig(local_channel(),'notes','text');
-
- $o = replace_macros(get_markup_template('notes.tpl'), array(
- '$banner' => t('Notes'),
- '$text' => $text,
- '$save' => t('Save'),
- ));
-
- return $o;
-}
function widget_savedsearch($arr) {
--
cgit v1.2.3
From 14f16a7ef0ce1412fcccdabf6a44dd83efee9c60 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Wed, 15 Mar 2017 17:05:16 -0700
Subject: use absolute namespace
---
Zotlabs/Render/Comanche.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Zotlabs/Render/Comanche.php b/Zotlabs/Render/Comanche.php
index 899fbd8aa..60a7b232c 100644
--- a/Zotlabs/Render/Comanche.php
+++ b/Zotlabs/Render/Comanche.php
@@ -411,7 +411,8 @@ class Comanche {
}
$clsname = ucfirst($name);
- $nsname = "Zotlabs\\Widget\\" . $clsname;
+ $nsname = "\\Zotlabs\\Widget\\" . $clsname;
+
if(file_exists('Zotlabs/SiteWidget/' . $clsname . '.php'))
require_once('Zotlabs/SiteWidget/' . $clsname . '.php');
elseif(file_exists('Zotlabs/Widget/' . $clsname . '.php'))
--
cgit v1.2.3
From 8d4744d115036dd7ec4169f8b1fdebebac6fb602 Mon Sep 17 00:00:00 2001
From: zotlabs
Date: Thu, 16 Mar 2017 11:42:06 +1100
Subject: new composer.lock for red
---
composer.lock | 3633 ++++++++++++++++++++
vendor/composer/autoload_classmap.php | 616 ----
vendor/composer/installed.json | 695 ++--
vendor/sabre/dav/.travis.yml | 7 +-
vendor/sabre/dav/CHANGELOG.md | 56 +-
vendor/sabre/dav/README.md | 2 +
vendor/sabre/dav/bin/build.php | 0
vendor/sabre/dav/bin/googlecode_upload.py | 0
vendor/sabre/dav/bin/migrateto20.php | 0
vendor/sabre/dav/bin/migrateto21.php | 0
vendor/sabre/dav/bin/migrateto30.php | 0
vendor/sabre/dav/bin/migrateto32.php | 0
vendor/sabre/dav/bin/sabredav.php | 0
vendor/sabre/dav/composer.json | 4 +-
.../dav/lib/CalDAV/Backend/AbstractBackend.php | 6 +-
.../dav/lib/CalDAV/Backend/NotificationSupport.php | 4 +-
vendor/sabre/dav/lib/CalDAV/Backend/PDO.php | 68 +-
.../dav/lib/CalDAV/Backend/SharingSupport.php | 6 +-
vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php | 14 +-
.../dav/lib/CalDAV/Backend/SubscriptionSupport.php | 2 +-
vendor/sabre/dav/lib/CalDAV/Calendar.php | 2 +-
vendor/sabre/dav/lib/CalDAV/CalendarHome.php | 8 +-
vendor/sabre/dav/lib/CalDAV/CalendarObject.php | 2 +-
.../dav/lib/CalDAV/CalendarQueryValidator.php | 4 +-
vendor/sabre/dav/lib/CalDAV/CalendarRoot.php | 2 +-
.../lib/CalDAV/Exception/InvalidComponentType.php | 2 +-
vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php | 6 +-
.../dav/lib/CalDAV/Notifications/Collection.php | 4 +-
.../sabre/dav/lib/CalDAV/Notifications/INode.php | 8 +-
vendor/sabre/dav/lib/CalDAV/Notifications/Node.php | 12 +-
.../sabre/dav/lib/CalDAV/Notifications/Plugin.php | 4 +-
vendor/sabre/dav/lib/CalDAV/Plugin.php | 10 +-
.../sabre/dav/lib/CalDAV/Principal/ProxyRead.php | 4 +-
.../sabre/dav/lib/CalDAV/Principal/ProxyWrite.php | 4 +-
.../sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php | 2 +-
vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php | 6 +-
vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php | 2 +-
vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php | 33 +-
.../dav/lib/CalDAV/Schedule/SchedulingObject.php | 2 +-
vendor/sabre/dav/lib/CalDAV/SharingPlugin.php | 3 +-
.../sabre/dav/lib/CalDAV/Subscriptions/Plugin.php | 2 +-
.../dav/lib/CalDAV/Subscriptions/Subscription.php | 12 +-
.../dav/lib/CalDAV/Xml/Filter/CalendarData.php | 8 +-
.../sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php | 8 +-
.../dav/lib/CalDAV/Xml/Filter/ParamFilter.php | 4 +-
.../sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php | 8 +-
.../dav/lib/CalDAV/Xml/Notification/Invite.php | 10 +-
.../lib/CalDAV/Xml/Notification/InviteReply.php | 6 +-
.../Xml/Notification/NotificationInterface.php | 2 +-
.../lib/CalDAV/Xml/Notification/SystemStatus.php | 2 +-
.../CalDAV/Xml/Property/AllowedSharingModes.php | 8 +-
.../lib/CalDAV/Xml/Property/EmailAddressSet.php | 4 +-
.../sabre/dav/lib/CalDAV/Xml/Property/Invite.php | 13 +-
.../CalDAV/Xml/Property/ScheduleCalendarTransp.php | 10 +-
.../Xml/Property/SupportedCalendarComponentSet.php | 8 +-
.../CalDAV/Xml/Property/SupportedCalendarData.php | 8 +-
.../CalDAV/Xml/Property/SupportedCollationSet.php | 6 +-
.../CalDAV/Xml/Request/CalendarMultiGetReport.php | 6 +-
.../lib/CalDAV/Xml/Request/CalendarQueryReport.php | 8 +-
.../lib/CalDAV/Xml/Request/FreeBusyQueryReport.php | 2 +-
.../dav/lib/CalDAV/Xml/Request/InviteReply.php | 4 +-
.../dav/lib/CalDAV/Xml/Request/MkCalendar.php | 6 +-
vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php | 2 +-
vendor/sabre/dav/lib/CardDAV/AddressBook.php | 2 +-
vendor/sabre/dav/lib/CardDAV/AddressBookHome.php | 2 +-
vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php | 2 +-
.../dav/lib/CardDAV/Backend/BackendInterface.php | 2 +-
vendor/sabre/dav/lib/CardDAV/Backend/PDO.php | 6 +-
vendor/sabre/dav/lib/CardDAV/Card.php | 2 +-
vendor/sabre/dav/lib/CardDAV/Plugin.php | 19 +-
vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php | 4 +-
.../dav/lib/CardDAV/Xml/Filter/AddressData.php | 8 +-
.../dav/lib/CardDAV/Xml/Filter/ParamFilter.php | 6 +-
.../dav/lib/CardDAV/Xml/Filter/PropFilter.php | 6 +-
.../CardDAV/Xml/Property/SupportedAddressData.php | 6 +-
.../CardDAV/Xml/Property/SupportedCollationSet.php | 4 +-
.../Xml/Request/AddressBookMultiGetReport.php | 2 +-
.../CardDAV/Xml/Request/AddressBookQueryReport.php | 13 +-
.../dav/lib/DAV/Auth/Backend/AbstractDigest.php | 2 +-
vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php | 2 +-
vendor/sabre/dav/lib/DAV/Auth/Plugin.php | 6 +-
.../sabre/dav/lib/DAV/Browser/GuessContentType.php | 4 +-
.../sabre/dav/lib/DAV/Browser/MapGetToPropFind.php | 2 +-
vendor/sabre/dav/lib/DAV/Browser/Plugin.php | 62 +-
vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php | 2 +-
vendor/sabre/dav/lib/DAV/Client.php | 6 +-
vendor/sabre/dav/lib/DAV/Collection.php | 2 +-
vendor/sabre/dav/lib/DAV/CorePlugin.php | 30 +-
.../dav/lib/DAV/Exception/InvalidResourceType.php | 2 +-
vendor/sabre/dav/lib/DAV/FS/Node.php | 2 +-
vendor/sabre/dav/lib/DAV/File.php | 2 +-
vendor/sabre/dav/lib/DAV/IFile.php | 4 +-
vendor/sabre/dav/lib/DAV/IMoveTarget.php | 2 +-
vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php | 4 +-
vendor/sabre/dav/lib/DAV/Locks/Plugin.php | 6 +-
vendor/sabre/dav/lib/DAV/MkCol.php | 1 +
vendor/sabre/dav/lib/DAV/Mount/Plugin.php | 2 +-
vendor/sabre/dav/lib/DAV/Node.php | 4 +-
vendor/sabre/dav/lib/DAV/PartialUpdate/Plugin.php | 2 +-
vendor/sabre/dav/lib/DAV/PropFind.php | 2 +-
.../PropertyStorage/Backend/BackendInterface.php | 2 +-
.../dav/lib/DAV/PropertyStorage/Backend/PDO.php | 2 +-
.../sabre/dav/lib/DAV/PropertyStorage/Plugin.php | 13 +-
vendor/sabre/dav/lib/DAV/Server.php | 101 +-
vendor/sabre/dav/lib/DAV/Sharing/Plugin.php | 4 +-
vendor/sabre/dav/lib/DAV/Sync/Plugin.php | 2 +-
.../dav/lib/DAV/TemporaryFileFilterPlugin.php | 8 +-
vendor/sabre/dav/lib/DAV/Version.php | 2 +-
vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php | 6 +-
vendor/sabre/dav/lib/DAV/Xml/Element/Response.php | 2 +-
vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php | 4 +-
vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php | 2 +-
.../dav/lib/DAV/Xml/Property/GetLastModified.php | 8 +-
vendor/sabre/dav/lib/DAV/Xml/Property/Href.php | 10 +-
vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php | 6 +-
.../sabre/dav/lib/DAV/Xml/Property/LocalHref.php | 4 +-
.../dav/lib/DAV/Xml/Property/ResourceType.php | 4 +-
.../sabre/dav/lib/DAV/Xml/Property/ShareAccess.php | 6 +-
.../dav/lib/DAV/Xml/Property/SupportedLock.php | 8 +-
.../lib/DAV/Xml/Property/SupportedMethodSet.php | 4 +-
.../lib/DAV/Xml/Property/SupportedReportSet.php | 4 +-
vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php | 2 +-
vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php | 6 +-
vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php | 2 +-
vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php | 10 +-
.../dav/lib/DAV/Xml/Request/ShareResource.php | 4 +-
.../lib/DAV/Xml/Request/SyncCollectionReport.php | 8 +-
.../sabre/dav/lib/DAV/Xml/Response/MultiStatus.php | 2 +-
.../DAVACL/Exception/NotRecognizedPrincipal.php | 2 +-
vendor/sabre/dav/lib/DAVACL/FS/Collection.php | 4 +-
vendor/sabre/dav/lib/DAVACL/FS/File.php | 2 +-
vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php | 2 +-
vendor/sabre/dav/lib/DAVACL/Plugin.php | 38 +-
vendor/sabre/dav/lib/DAVACL/Principal.php | 2 +-
.../DAVACL/PrincipalBackend/BackendInterface.php | 2 +-
.../sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php | 8 +-
.../sabre/dav/lib/DAVACL/PrincipalCollection.php | 2 +-
vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php | 6 +-
.../lib/DAVACL/Xml/Property/AclRestrictions.php | 6 +-
.../Xml/Property/CurrentUserPrivilegeSet.php | 6 +-
.../dav/lib/DAVACL/Xml/Property/Principal.php | 4 +-
.../DAVACL/Xml/Property/SupportedPrivilegeSet.php | 11 +-
.../Xml/Request/AclPrincipalPropSetReport.php | 6 +-
.../DAVACL/Xml/Request/ExpandPropertyReport.php | 2 +-
.../DAVACL/Xml/Request/PrincipalMatchReport.php | 6 +-
.../Xml/Request/PrincipalPropertySearchReport.php | 4 +-
.../Request/PrincipalSearchPropertySetReport.php | 4 +-
.../tests/Sabre/CalDAV/Backend/AbstractPDOTest.php | 14 +-
.../sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php | 2 +-
.../dav/tests/Sabre/CalDAV/CalendarObjectTest.php | 2 +-
.../Sabre/CalDAV/CalendarQueryValidatorTest.php | 3 +
.../dav/tests/Sabre/CalDAV/FreeBusyReportTest.php | 4 +-
.../dav/tests/Sabre/CalDAV/ICSExportPluginTest.php | 2 +-
vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php | 6 +-
.../dav/tests/Sabre/CalDAV/SharingPluginTest.php | 4 +-
.../tests/Sabre/CardDAV/AddressBookQueryTest.php | 51 +-
.../dav/tests/Sabre/CardDAV/AddressBookTest.php | 6 +-
.../sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php | 13 +-
.../sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php | 2 +-
.../Sabre/CardDAV/SogoStripContentTypeTest.php | 2 +-
.../dav/tests/Sabre/CardDAV/ValidateFilterTest.php | 5 +
.../dav/tests/Sabre/CardDAV/ValidateVCardTest.php | 10 +-
.../dav/tests/Sabre/DAV/Auth/Backend/Mock.php | 2 +
.../sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php | 2 +-
vendor/sabre/dav/tests/Sabre/DAV/ClientTest.php | 6 +-
.../dav/tests/Sabre/DAV/Exception/LockedTest.php | 2 +-
vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php | 2 +-
.../sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php | 8 +-
.../sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php | 6 +-
.../sabre/dav/tests/Sabre/DAV/Mock/Collection.php | 3 +
vendor/sabre/dav/tests/Sabre/DAV/Mock/File.php | 7 +-
.../Sabre/DAV/PartialUpdate/SpecificationTest.php | 5 +
.../sabre/dav/tests/Sabre/DAV/ServerEventsTest.php | 8 +-
.../sabre/dav/tests/Sabre/DAV/ServerRangeTest.php | 2 +-
.../sabre/dav/tests/Sabre/DAV/StringUtilTest.php | 7 +
vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php | 5 +-
.../tests/Sabre/DAVACL/PrincipalBackend/Mock.php | 2 +-
vendor/sabre/http/.travis.yml | 4 +-
vendor/sabre/http/CHANGELOG.md | 8 +-
vendor/sabre/http/LICENSE | 2 +-
vendor/sabre/http/composer.json | 1 +
vendor/sabre/http/lib/Message.php | 12 +-
vendor/sabre/http/lib/MessageDecoratorTrait.php | 7 +-
vendor/sabre/http/lib/MessageInterface.php | 3 +-
vendor/sabre/http/lib/Request.php | 2 +-
vendor/sabre/http/lib/Response.php | 3 +-
vendor/sabre/http/lib/ResponseInterface.php | 2 +-
vendor/sabre/http/lib/URLUtil.php | 2 +-
vendor/sabre/http/lib/Util.php | 2 +-
vendor/sabre/http/lib/Version.php | 2 +-
vendor/sabre/http/lib/functions.php | 4 +-
vendor/sabre/uri/.travis.yml | 2 +-
vendor/sabre/uri/CHANGELOG.md | 23 +
vendor/sabre/uri/LICENSE | 2 +-
vendor/sabre/uri/README.md | 8 -
vendor/sabre/uri/composer.json | 4 +-
vendor/sabre/uri/lib/InvalidUriException.php | 17 +
vendor/sabre/uri/lib/Version.php | 2 +-
vendor/sabre/uri/lib/functions.php | 99 +-
vendor/sabre/vobject/.travis.yml | 3 +-
vendor/sabre/vobject/CHANGELOG.md | 18 +-
vendor/sabre/vobject/bin/fetch_windows_zones.php | 2 +-
vendor/sabre/vobject/composer.json | 4 +-
.../vobject/lib/BirthdayCalendarGenerator.php | 8 +-
vendor/sabre/vobject/lib/Component/VAlarm.php | 4 +-
vendor/sabre/vobject/lib/Component/VCalendar.php | 112 +-
vendor/sabre/vobject/lib/Component/VCard.php | 44 +-
vendor/sabre/vobject/lib/DateTimeParser.php | 14 +-
vendor/sabre/vobject/lib/FreeBusyGenerator.php | 6 +-
vendor/sabre/vobject/lib/Parameter.php | 2 +-
vendor/sabre/vobject/lib/Parser/Json.php | 2 +-
vendor/sabre/vobject/lib/Parser/MimeDir.php | 4 +-
vendor/sabre/vobject/lib/Parser/XML.php | 22 +-
.../vobject/lib/Property/ICalendar/Duration.php | 2 +-
.../vobject/lib/Property/ICalendar/Period.php | 2 +-
.../sabre/vobject/lib/Property/ICalendar/Recur.php | 48 +
vendor/sabre/vobject/lib/Property/Text.php | 4 +-
vendor/sabre/vobject/lib/Property/Uri.php | 2 +-
.../vobject/lib/Property/VCard/DateAndOrTime.php | 24 +-
vendor/sabre/vobject/lib/Recur/EventIterator.php | 6 +-
vendor/sabre/vobject/lib/Recur/RRuleIterator.php | 93 +-
vendor/sabre/vobject/lib/TimeZoneUtil.php | 10 +
vendor/sabre/vobject/lib/Version.php | 2 +-
.../sabre/vobject/lib/timezonedata/lotuszones.php | 158 +-
.../vobject/lib/timezonedata/windowszones.php | 32 +-
225 files changed, 5263 insertions(+), 1737 deletions(-)
create mode 100644 composer.lock
mode change 100644 => 100755 vendor/sabre/dav/bin/build.php
mode change 100644 => 100755 vendor/sabre/dav/bin/googlecode_upload.py
mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto20.php
mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto21.php
mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto30.php
mode change 100644 => 100755 vendor/sabre/dav/bin/migrateto32.php
mode change 100644 => 100755 vendor/sabre/dav/bin/sabredav.php
create mode 100644 vendor/sabre/uri/lib/InvalidUriException.php
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 000000000..c9c4eb230
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,3633 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "hash": "46492fdee6fa6ef4ef6612a0f0006c2b",
+ "content-hash": "b0d4055ddb064eafb50cf58cf939e1e5",
+ "packages": [
+ {
+ "name": "bshaffer/oauth2-server-php",
+ "version": "v1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bshaffer/oauth2-server-php.git",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bshaffer/oauth2-server-php/zipball/8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "~2.8",
+ "firebase/php-jwt": "~2.2",
+ "mongodb/mongodb": "^1.1",
+ "predis/predis": "dev-master",
+ "thobbs/phpcassa": "dev-master"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
+ "firebase/php-jwt": "~1.1 is required to use MondoDB storage",
+ "predis/predis": "Required to use Redis storage",
+ "thobbs/phpcassa": "Required to use Cassandra storage"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "OAuth2": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brent Shaffer",
+ "email": "bshafs@gmail.com",
+ "homepage": "http://brentertainment.com"
+ }
+ ],
+ "description": "OAuth2 Server for PHP",
+ "homepage": "http://github.com/bshaffer/oauth2-server-php",
+ "keywords": [
+ "auth",
+ "oauth",
+ "oauth2"
+ ],
+ "time": "2017-01-06 23:20:00"
+ },
+ {
+ "name": "michelf/php-markdown",
+ "version": "1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/michelf/php-markdown.git",
+ "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220",
+ "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-lib": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Michelf": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Michel Fortin",
+ "email": "michel.fortin@michelf.ca",
+ "homepage": "https://michelf.ca/",
+ "role": "Developer"
+ },
+ {
+ "name": "John Gruber",
+ "homepage": "https://daringfireball.net/"
+ }
+ ],
+ "description": "PHP Markdown",
+ "homepage": "https://michelf.ca/projects/php-markdown/",
+ "keywords": [
+ "markdown"
+ ],
+ "time": "2016-10-29 18:58:20"
+ },
+ {
+ "name": "pixel418/markdownify",
+ "version": "v2.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Elephant418/Markdownify.git",
+ "reference": "0160677f04c784550dd10fd72fdf3994967db848"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Elephant418/Markdownify/zipball/0160677f04c784550dd10fd72fdf3994967db848",
+ "reference": "0160677f04c784550dd10fd72fdf3994967db848",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8"
+ },
+ "type": "lib",
+ "autoload": {
+ "psr-4": {
+ "Markdownify\\": "src",
+ "Test\\Markdownify\\": "test"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL"
+ ],
+ "authors": [
+ {
+ "name": "Peter Kruithof",
+ "email": "pkruithof@gmail.com",
+ "homepage": "http://pkruithof.tumblr.com/"
+ },
+ {
+ "name": "Milian Wolff",
+ "email": "mail@milianw.de",
+ "homepage": "http://milianw.de"
+ },
+ {
+ "name": "Thomas Zilliox",
+ "email": "hello@tzi.fr",
+ "homepage": "http://tzi.fr"
+ }
+ ],
+ "description": "The HTML to Markdown converter for PHP ",
+ "homepage": "https://github.com/elephant418/Markdownify",
+ "keywords": [
+ "markdown",
+ "markdownify"
+ ],
+ "time": "2016-09-21 13:01:43"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "time": "2016-10-10 12:19:37"
+ },
+ {
+ "name": "sabre/dav",
+ "version": "3.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-dav.git",
+ "reference": "e987775e619728f12205606c9cc3ee565ffb1516"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/e987775e619728f12205606c9cc3ee565ffb1516",
+ "reference": "e987775e619728f12205606c9cc3ee565ffb1516",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-date": "*",
+ "ext-dom": "*",
+ "ext-iconv": "*",
+ "ext-mbstring": "*",
+ "ext-pcre": "*",
+ "ext-simplexml": "*",
+ "ext-spl": "*",
+ "lib-libxml": ">=2.7.0",
+ "php": ">=5.5.0",
+ "psr/log": "^1.0",
+ "sabre/event": ">=2.0.0, <4.0.0",
+ "sabre/http": "^4.2.1",
+ "sabre/uri": "^1.0.1",
+ "sabre/vobject": "^4.1.0",
+ "sabre/xml": "^1.4.0"
+ },
+ "require-dev": {
+ "evert/phpdoc-md": "~0.1.0",
+ "monolog/monolog": "^1.18",
+ "phpunit/phpunit": "> 4.8, <6.0.0",
+ "sabre/cs": "^1.0.0"
+ },
+ "suggest": {
+ "ext-curl": "*",
+ "ext-pdo": "*"
+ },
+ "bin": [
+ "bin/sabredav",
+ "bin/naturalselection"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Sabre\\DAV\\": "lib/DAV/",
+ "Sabre\\DAVACL\\": "lib/DAVACL/",
+ "Sabre\\CalDAV\\": "lib/CalDAV/",
+ "Sabre\\CardDAV\\": "lib/CardDAV/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "WebDAV Framework for PHP",
+ "homepage": "http://sabre.io/",
+ "keywords": [
+ "CalDAV",
+ "CardDAV",
+ "WebDAV",
+ "framework",
+ "iCalendar"
+ ],
+ "time": "2017-02-15 03:06:08"
+ },
+ {
+ "name": "sabre/event",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-event.git",
+ "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-event/zipball/831d586f5a442dceacdcf5e9c4c36a4db99a3534",
+ "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "sabre/cs": "~0.0.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Sabre\\Event\\": "lib/"
+ },
+ "files": [
+ "lib/coroutine.php",
+ "lib/Loop/functions.php",
+ "lib/Promise/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "sabre/event is a library for lightweight event-based programming",
+ "homepage": "http://sabre.io/event/",
+ "keywords": [
+ "EventEmitter",
+ "async",
+ "events",
+ "hooks",
+ "plugin",
+ "promise",
+ "signal"
+ ],
+ "time": "2015-11-05 20:14:39"
+ },
+ {
+ "name": "sabre/http",
+ "version": "4.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-http.git",
+ "reference": "dd50e7260356f4599d40270826f9548b23efa204"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-http/zipball/dd50e7260356f4599d40270826f9548b23efa204",
+ "reference": "dd50e7260356f4599d40270826f9548b23efa204",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-mbstring": "*",
+ "php": ">=5.4",
+ "sabre/event": ">=1.0.0,<4.0.0",
+ "sabre/uri": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.3",
+ "sabre/cs": "~0.0.1"
+ },
+ "suggest": {
+ "ext-curl": " to make http requests with the Client class"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
+ "psr-4": {
+ "Sabre\\HTTP\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
+ "homepage": "https://github.com/fruux/sabre-http",
+ "keywords": [
+ "http"
+ ],
+ "time": "2017-01-02 19:38:42"
+ },
+ {
+ "name": "sabre/uri",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-uri.git",
+ "reference": "ada354d83579565949d80b2e15593c2371225e61"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-uri/zipball/ada354d83579565949d80b2e15593c2371225e61",
+ "reference": "ada354d83579565949d80b2e15593c2371225e61",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=4.0,<6.0",
+ "sabre/cs": "~1.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
+ "psr-4": {
+ "Sabre\\Uri\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Functions for making sense out of URIs.",
+ "homepage": "http://sabre.io/uri/",
+ "keywords": [
+ "rfc3986",
+ "uri",
+ "url"
+ ],
+ "time": "2017-02-20 19:59:28"
+ },
+ {
+ "name": "sabre/vobject",
+ "version": "4.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-vobject.git",
+ "reference": "d0fde2fafa2a3dad1f559c2d1c2591d4fd75ae3c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/d0fde2fafa2a3dad1f559c2d1c2591d4fd75ae3c",
+ "reference": "d0fde2fafa2a3dad1f559c2d1c2591d4fd75ae3c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.5",
+ "sabre/xml": ">=1.5 <3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "sabre/cs": "^1.0.0"
+ },
+ "suggest": {
+ "hoa/bench": "If you would like to run the benchmark scripts"
+ },
+ "bin": [
+ "bin/vobject",
+ "bin/generate_vcards"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Sabre\\VObject\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ },
+ {
+ "name": "Dominik Tobschall",
+ "email": "dominik@fruux.com",
+ "homepage": "http://tobschall.de/",
+ "role": "Developer"
+ },
+ {
+ "name": "Ivan Enderlin",
+ "email": "ivan.enderlin@hoa-project.net",
+ "homepage": "http://mnt.io/",
+ "role": "Developer"
+ }
+ ],
+ "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
+ "homepage": "http://sabre.io/vobject/",
+ "keywords": [
+ "availability",
+ "freebusy",
+ "iCalendar",
+ "ical",
+ "ics",
+ "jCal",
+ "jCard",
+ "recurrence",
+ "rfc2425",
+ "rfc2426",
+ "rfc2739",
+ "rfc4770",
+ "rfc5545",
+ "rfc5546",
+ "rfc6321",
+ "rfc6350",
+ "rfc6351",
+ "rfc6474",
+ "rfc6638",
+ "rfc6715",
+ "rfc6868",
+ "vCalendar",
+ "vCard",
+ "vcf",
+ "xCal",
+ "xCard"
+ ],
+ "time": "2016-12-06 04:14:09"
+ },
+ {
+ "name": "sabre/xml",
+ "version": "1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-xml.git",
+ "reference": "59b20e5bbace9912607481634f97d05a776ffca7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/59b20e5bbace9912607481634f97d05a776ffca7",
+ "reference": "59b20e5bbace9912607481634f97d05a776ffca7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "lib-libxml": ">=2.6.20",
+ "php": ">=5.5.5",
+ "sabre/uri": ">=1.0,<3.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "sabre/cs": "~1.0.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Sabre\\Xml\\": "lib/"
+ },
+ "files": [
+ "lib/Deserializer/functions.php",
+ "lib/Serializer/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ },
+ {
+ "name": "Markus Staab",
+ "email": "markus.staab@redaxo.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "sabre/xml is an XML library that you may not hate.",
+ "homepage": "https://sabre.io/xml/",
+ "keywords": [
+ "XMLReader",
+ "XMLWriter",
+ "dom",
+ "xml"
+ ],
+ "time": "2016-10-09 22:57:52"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "behat/behat",
+ "version": "v3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/Behat.git",
+ "reference": "15a3a1857457eaa29cdf41564a5e421effb09526"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/Behat/zipball/15a3a1857457eaa29cdf41564a5e421effb09526",
+ "reference": "15a3a1857457eaa29cdf41564a5e421effb09526",
+ "shasum": ""
+ },
+ "require": {
+ "behat/gherkin": "^4.4.4",
+ "behat/transliterator": "~1.0",
+ "container-interop/container-interop": "^1.1",
+ "ext-mbstring": "*",
+ "php": ">=5.3.3",
+ "symfony/class-loader": "~2.1||~3.0",
+ "symfony/config": "~2.3||~3.0",
+ "symfony/console": "~2.5||~3.0",
+ "symfony/dependency-injection": "~2.1||~3.0",
+ "symfony/event-dispatcher": "~2.1||~3.0",
+ "symfony/translation": "~2.3||~3.0",
+ "symfony/yaml": "~2.1||~3.0"
+ },
+ "require-dev": {
+ "herrera-io/box": "~1.6.1",
+ "phpunit/phpunit": "~4.5",
+ "symfony/process": "~2.5|~3.0"
+ },
+ "suggest": {
+ "behat/mink-extension": "for integration with Mink testing framework",
+ "behat/symfony2-extension": "for integration with Symfony2 web framework",
+ "behat/yii-extension": "for integration with Yii web framework"
+ },
+ "bin": [
+ "bin/behat"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\Behat": "src/",
+ "Behat\\Testwork": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Scenario-oriented BDD framework for PHP 5.3",
+ "homepage": "http://behat.org/",
+ "keywords": [
+ "Agile",
+ "BDD",
+ "ScenarioBDD",
+ "Scrum",
+ "StoryBDD",
+ "User story",
+ "business",
+ "development",
+ "documentation",
+ "examples",
+ "symfony",
+ "testing"
+ ],
+ "time": "2016-12-25 13:43:52"
+ },
+ {
+ "name": "behat/gherkin",
+ "version": "v4.4.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/Gherkin.git",
+ "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c14cff4f955b17d20d088dec1bde61c0539ec74",
+ "reference": "5c14cff4f955b17d20d088dec1bde61c0539ec74",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.5|~5",
+ "symfony/phpunit-bridge": "~2.7|~3",
+ "symfony/yaml": "~2.3|~3"
+ },
+ "suggest": {
+ "symfony/yaml": "If you want to parse features, represented in YAML files"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\Gherkin": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Gherkin DSL parser for PHP 5.3",
+ "homepage": "http://behat.org/",
+ "keywords": [
+ "BDD",
+ "Behat",
+ "Cucumber",
+ "DSL",
+ "gherkin",
+ "parser"
+ ],
+ "time": "2016-10-30 11:50:56"
+ },
+ {
+ "name": "behat/mink",
+ "version": "v1.7.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/minkphp/Mink.git",
+ "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9",
+ "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.1",
+ "symfony/css-selector": "~2.1|~3.0"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0"
+ },
+ "suggest": {
+ "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
+ "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
+ "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
+ "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Behat\\Mink\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Browser controller/emulator abstraction for PHP",
+ "homepage": "http://mink.behat.org/",
+ "keywords": [
+ "browser",
+ "testing",
+ "web"
+ ],
+ "time": "2016-03-05 08:26:18"
+ },
+ {
+ "name": "behat/mink-browserkit-driver",
+ "version": "v1.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
+ "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb",
+ "reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb",
+ "shasum": ""
+ },
+ "require": {
+ "behat/mink": "^1.7.1@dev",
+ "php": ">=5.3.6",
+ "symfony/browser-kit": "~2.3|~3.0",
+ "symfony/dom-crawler": "~2.3|~3.0"
+ },
+ "require-dev": {
+ "silex/silex": "~1.2",
+ "symfony/phpunit-bridge": "~2.7|~3.0"
+ },
+ "type": "mink-driver",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Behat\\Mink\\Driver\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Symfony2 BrowserKit driver for Mink framework",
+ "homepage": "http://mink.behat.org/",
+ "keywords": [
+ "Mink",
+ "Symfony2",
+ "browser",
+ "testing"
+ ],
+ "time": "2016-03-05 08:59:47"
+ },
+ {
+ "name": "behat/mink-extension",
+ "version": "v2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/MinkExtension.git",
+ "reference": "5b4bda64ff456104564317e212c823e45cad9d59"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/5b4bda64ff456104564317e212c823e45cad9d59",
+ "reference": "5b4bda64ff456104564317e212c823e45cad9d59",
+ "shasum": ""
+ },
+ "require": {
+ "behat/behat": "~3.0,>=3.0.5",
+ "behat/mink": "~1.5",
+ "php": ">=5.3.2",
+ "symfony/config": "~2.2|~3.0"
+ },
+ "require-dev": {
+ "behat/mink-goutte-driver": "~1.1",
+ "phpspec/phpspec": "~2.0"
+ },
+ "type": "behat-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\MinkExtension": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Christophe Coevoet",
+ "email": "stof@notk.org"
+ },
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com"
+ }
+ ],
+ "description": "Mink extension for Behat",
+ "homepage": "http://extensions.behat.org/mink",
+ "keywords": [
+ "browser",
+ "gui",
+ "test",
+ "web"
+ ],
+ "time": "2016-02-15 07:55:18"
+ },
+ {
+ "name": "behat/mink-goutte-driver",
+ "version": "v1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/minkphp/MinkGoutteDriver.git",
+ "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
+ "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
+ "shasum": ""
+ },
+ "require": {
+ "behat/mink": "~1.6@dev",
+ "behat/mink-browserkit-driver": "~1.2@dev",
+ "fabpot/goutte": "~1.0.4|~2.0|~3.1",
+ "php": ">=5.3.1"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7|~3.0"
+ },
+ "type": "mink-driver",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Behat\\Mink\\Driver\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Goutte driver for Mink framework",
+ "homepage": "http://mink.behat.org/",
+ "keywords": [
+ "browser",
+ "goutte",
+ "headless",
+ "testing"
+ ],
+ "time": "2016-03-05 09:04:22"
+ },
+ {
+ "name": "behat/transliterator",
+ "version": "v1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/Transliterator.git",
+ "reference": "868e05be3a9f25ba6424c2dd4849567f50715003"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/Transliterator/zipball/868e05be3a9f25ba6424c2dd4849567f50715003",
+ "reference": "868e05be3a9f25ba6424c2dd4849567f50715003",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\Transliterator": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Artistic-1.0"
+ ],
+ "description": "String transliterator",
+ "keywords": [
+ "i18n",
+ "slug",
+ "transliterator"
+ ],
+ "time": "2015-09-28 16:26:35"
+ },
+ {
+ "name": "container-interop/container-interop",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/container-interop/container-interop.git",
+ "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
+ "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
+ "shasum": ""
+ },
+ "require": {
+ "psr/container": "^1.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Interop\\Container\\": "src/Interop/Container/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
+ "homepage": "https://github.com/container-interop/container-interop",
+ "time": "2017-02-14 19:40:03"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3,<8.0-DEV"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2015-06-14 21:17:01"
+ },
+ {
+ "name": "fabpot/goutte",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/FriendsOfPHP/Goutte.git",
+ "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/db5c28f4a010b4161d507d5304e28a7ebf211638",
+ "reference": "db5c28f4a010b4161d507d5304e28a7ebf211638",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^6.0",
+ "php": ">=5.5.0",
+ "symfony/browser-kit": "~2.1|~3.0",
+ "symfony/css-selector": "~2.1|~3.0",
+ "symfony/dom-crawler": "~2.1|~3.0"
+ },
+ "type": "application",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Goutte\\": "Goutte"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "A simple PHP Web Scraper",
+ "homepage": "https://github.com/FriendsOfPHP/Goutte",
+ "keywords": [
+ "scraper"
+ ],
+ "time": "2017-01-03 13:21:43"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "6.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006",
+ "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.4",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.0",
+ "psr/log": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.2-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2017-02-28 22:50:30"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "v1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "time": "2016-12-20 10:07:11"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/0d6c7ca039329247e4f0f8f8f6506810e8248855",
+ "reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2017-02-27 10:51:17"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
+ "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "doctrine/collections": "1.*",
+ "phpunit/phpunit": "~4.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "homepage": "https://github.com/myclabs/DeepCopy",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2017-01-26 22:05:40"
+ },
+ {
+ "name": "php-mock/php-mock",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-mock/php-mock.git",
+ "reference": "22d297231118e6fd5b9db087fbe1ef866c2b95d2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-mock/php-mock/zipball/22d297231118e6fd5b9db087fbe1ef866c2b95d2",
+ "reference": "22d297231118e6fd5b9db087fbe1ef866c2b95d2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "phpunit/php-text-template": "^1"
+ },
+ "replace": {
+ "malkusch/php-mock": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7"
+ },
+ "suggest": {
+ "php-mock/php-mock-phpunit": "Allows integration into PHPUnit testcase with the trait PHPMock."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "phpmock\\": [
+ "classes/",
+ "tests/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "WTFPL"
+ ],
+ "authors": [
+ {
+ "name": "Markus Malkusch",
+ "email": "markus@malkusch.de",
+ "homepage": "http://markus.malkusch.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP-Mock can mock built-in PHP functions (e.g. time()). PHP-Mock relies on PHP's namespace fallback policy. No further extension is needed.",
+ "homepage": "https://github.com/php-mock/php-mock",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "function",
+ "mock",
+ "stub",
+ "test",
+ "test double"
+ ],
+ "time": "2017-02-17 20:52:52"
+ },
+ {
+ "name": "php-mock/php-mock-integration",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-mock/php-mock-integration.git",
+ "reference": "5a0d7d7755f823bc2a230cfa45058b40f9013bc4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-mock/php-mock-integration/zipball/5a0d7d7755f823bc2a230cfa45058b40f9013bc4",
+ "reference": "5a0d7d7755f823bc2a230cfa45058b40f9013bc4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "php-mock/php-mock": "^2",
+ "phpunit/php-text-template": "^1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4|^5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "phpmock\\integration\\": "classes/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "WTFPL"
+ ],
+ "authors": [
+ {
+ "name": "Markus Malkusch",
+ "email": "markus@malkusch.de",
+ "homepage": "http://markus.malkusch.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Integration package for PHP-Mock",
+ "homepage": "https://github.com/php-mock/php-mock-integration",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "function",
+ "mock",
+ "stub",
+ "test",
+ "test double"
+ ],
+ "time": "2017-02-17 21:31:34"
+ },
+ {
+ "name": "php-mock/php-mock-phpunit",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-mock/php-mock-phpunit.git",
+ "reference": "173781abdc632c59200253e12e2b991ae6a4574f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-mock/php-mock-phpunit/zipball/173781abdc632c59200253e12e2b991ae6a4574f",
+ "reference": "173781abdc632c59200253e12e2b991ae6a4574f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7",
+ "php-mock/php-mock-integration": "^2",
+ "phpunit/phpunit": "^6"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "phpmock\\phpunit\\": "classes/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "WTFPL"
+ ],
+ "authors": [
+ {
+ "name": "Markus Malkusch",
+ "email": "markus@malkusch.de",
+ "homepage": "http://markus.malkusch.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.",
+ "homepage": "https://github.com/php-mock/php-mock-phpunit",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "function",
+ "mock",
+ "phpunit",
+ "stub",
+ "test",
+ "test double"
+ ],
+ "time": "2017-02-17 22:44:38"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2015-12-27 11:43:31"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
+ "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5",
+ "phpdocumentor/reflection-common": "^1.0@dev",
+ "phpdocumentor/type-resolver": "^0.2.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^4.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2016-09-30 07:12:33"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
+ "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "time": "2016-11-25 06:54:22"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "v1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
+ "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+ "sebastian/comparator": "^1.1|^2.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8 || ^5.6.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.6.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "time": "2017-03-02 20:05:34"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "5.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "4e99e1c4f9b05cbf4d6e84b100b3ff4107cf8cd1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4e99e1c4f9b05cbf4d6e84b100b3ff4107cf8cd1",
+ "reference": "4e99e1c4f9b05cbf4d6e84b100b3ff4107cf8cd1",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0",
+ "phpunit/php-file-iterator": "^1.3",
+ "phpunit/php-text-template": "^1.2",
+ "phpunit/php-token-stream": "^1.4.11 || ^2.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0",
+ "sebastian/environment": "^2.0",
+ "sebastian/version": "^2.0"
+ },
+ "require-dev": {
+ "ext-xdebug": "^2.5",
+ "phpunit/phpunit": "^6.0"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.5.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2017-03-06 14:22:16"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2016-10-03 07:40:28"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2015-06-21 13:50:34"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2017-02-26 11:10:40"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "1.4.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
+ "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2017-02-27 10:12:30"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "6.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "9bd36d990884d8fb3313232e0002ed4cdf79f428"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9bd36d990884d8fb3313232e0002ed4cdf79f428",
+ "reference": "9bd36d990884d8fb3313232e0002ed4cdf79f428",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "^1.3",
+ "php": "^7.0",
+ "phpspec/prophecy": "^1.7",
+ "phpunit/php-code-coverage": "^5.0",
+ "phpunit/php-file-iterator": "^1.4",
+ "phpunit/php-text-template": "^1.2",
+ "phpunit/php-timer": "^1.0.6",
+ "phpunit/phpunit-mock-objects": "^4.0",
+ "sebastian/comparator": "^2.0",
+ "sebastian/diff": "^1.2",
+ "sebastian/environment": "^2.0",
+ "sebastian/exporter": "^3.0",
+ "sebastian/global-state": "^1.1 || ^2.0",
+ "sebastian/object-enumerator": "^3.0.2",
+ "sebastian/resource-operations": "^1.0",
+ "sebastian/version": "^2.0"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2",
+ "phpunit/dbunit": "<3.0"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "^1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2017-03-15 13:04:13"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "4.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "eabce450df194817a7d7e27e19013569a903a2bf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/eabce450df194817a7d7e27e19013569a903a2bf",
+ "reference": "eabce450df194817a7d7e27e19013569a903a2bf",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^7.0",
+ "phpunit/php-text-template": "^1.2",
+ "sebastian/exporter": "^3.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2017-03-03 06:30:20"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "time": "2017-02-14 16:28:37"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06 14:39:51"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "time": "2017-03-04 06:30:41"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "20f84f468cb67efee293246e6a09619b891f55f0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0",
+ "reference": "20f84f468cb67efee293246e6a09619b891f55f0",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/diff": "^1.2",
+ "sebastian/exporter": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2017-03-03 06:26:08"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2015-12-08 07:14:41"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2016-11-26 07:53:53"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "b82d077cb3459e393abcf4867ae8f7230dcb51f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/b82d077cb3459e393abcf4867ae8f7230dcb51f6",
+ "reference": "b82d077cb3459e393abcf4867ae8f7230dcb51f6",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2017-03-03 06:25:06"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "time": "2015-10-12 03:26:01"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/31dd3379d16446c5d86dec32ab1ad1f378581ad8",
+ "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/object-reflector": "^1.0",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "time": "2017-03-12 15:17:29"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "2201553542d60d25db9c5b2c54330df776648008"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/2201553542d60d25db9c5b2c54330df776648008",
+ "reference": "2201553542d60d25db9c5b2c54330df776648008",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "time": "2017-03-12 15:10:22"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "time": "2017-03-03 06:23:57"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "time": "2015-07-28 20:34:47"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2016-10-03 07:35:21"
+ },
+ {
+ "name": "symfony/browser-kit",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2fe0caa60c1a1dfeefd0425741182687a9b382b8",
+ "reference": "2fe0caa60c1a1dfeefd0425741182687a9b382b8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/dom-crawler": "~2.8|~3.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\BrowserKit\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony BrowserKit Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-21 09:12:04"
+ },
+ {
+ "name": "symfony/class-loader",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/class-loader.git",
+ "reference": "c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/class-loader/zipball/c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9",
+ "reference": "c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "require-dev": {
+ "symfony/finder": "~2.8|~3.0",
+ "symfony/polyfill-apcu": "~1.1"
+ },
+ "suggest": {
+ "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\ClassLoader\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony ClassLoader Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-18 17:28:00"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "741d6d4cd1414d67d48eb71aba6072b46ba740c2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/741d6d4cd1414d67d48eb71aba6072b46ba740c2",
+ "reference": "741d6d4cd1414d67d48eb71aba6072b46ba740c2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/filesystem": "~2.8|~3.0"
+ },
+ "require-dev": {
+ "symfony/yaml": "~3.0"
+ },
+ "suggest": {
+ "symfony/yaml": "To use the yaml reference dumper"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Config\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Config Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-03-01 18:18:25"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "28fb243a2b5727774ca309ec2d92da240f1af0dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/28fb243a2b5727774ca309ec2d92da240f1af0dd",
+ "reference": "28fb243a2b5727774ca309ec2d92da240f1af0dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/debug": "~2.8|~3.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/event-dispatcher": "~2.8|~3.0",
+ "symfony/filesystem": "~2.8|~3.0",
+ "symfony/process": "~2.8|~3.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/filesystem": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-03-06 19:30:27"
+ },
+ {
+ "name": "symfony/css-selector",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/a48f13dc83c168f1253a5d2a5a4fb46c36244c4c",
+ "reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony CssSelector Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-21 09:12:04"
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "b90c9f91ad8ac37d9f114e369042d3226b34dc1a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/b90c9f91ad8ac37d9f114e369042d3226b34dc1a",
+ "reference": "b90c9f91ad8ac37d9f114e369042d3226b34dc1a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "psr/log": "~1.0"
+ },
+ "conflict": {
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+ },
+ "require-dev": {
+ "symfony/class-loader": "~2.8|~3.0",
+ "symfony/http-kernel": "~2.8|~3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Debug\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Debug Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-18 17:28:00"
+ },
+ {
+ "name": "symfony/dependency-injection",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dependency-injection.git",
+ "reference": "74e0935e414ad33d5e82074212c0eedb4681a691"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/74e0935e414ad33d5e82074212c0eedb4681a691",
+ "reference": "74e0935e414ad33d5e82074212c0eedb4681a691",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "conflict": {
+ "symfony/yaml": "<3.2"
+ },
+ "require-dev": {
+ "symfony/config": "~2.8|~3.0",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/yaml": "~3.2"
+ },
+ "suggest": {
+ "symfony/config": "",
+ "symfony/expression-language": "For using expressions in service container configuration",
+ "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
+ "symfony/yaml": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DependencyInjection\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony DependencyInjection Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-03-05 00:06:55"
+ },
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/403944e294cf4ceb3b8447f54cbad88ea7b99cee",
+ "reference": "403944e294cf4ceb3b8447f54cbad88ea7b99cee",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/css-selector": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony DomCrawler Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-21 09:12:04"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "b7a1b9e0a0f623ce43b4c8d775eb138f190c9d8d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7a1b9e0a0f623ce43b4c8d775eb138f190c9d8d",
+ "reference": "b7a1b9e0a0f623ce43b4c8d775eb138f190c9d8d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/dependency-injection": "~2.8|~3.0",
+ "symfony/expression-language": "~2.8|~3.0",
+ "symfony/stopwatch": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-02-21 09:12:04"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "bc0f17bed914df2cceb989972c3b996043c4da4a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/bc0f17bed914df2cceb989972c3b996043c4da4a",
+ "reference": "bc0f17bed914df2cceb989972c3b996043c4da4a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Filesystem Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-03-06 19:30:27"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "time": "2016-11-14 01:06:16"
+ },
+ {
+ "name": "symfony/translation",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "0e1b15ce8fbf3890f4ccdac430ed5e07fdfe0690"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/0e1b15ce8fbf3890f4ccdac430ed5e07fdfe0690",
+ "reference": "0e1b15ce8fbf3890f4ccdac430ed5e07fdfe0690",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/config": "<2.8"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.8|~3.0",
+ "symfony/intl": "^2.8.18|^3.2.5",
+ "symfony/yaml": "~2.8|~3.0"
+ },
+ "suggest": {
+ "psr/log": "To use logging capability in translator",
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Translation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Translation Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-03-04 12:23:14"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v3.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/093e416ad096355149e265ea2e4cc1f9ee40ab1a",
+ "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.9"
+ },
+ "require-dev": {
+ "symfony/console": "~2.8|~3.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2017-03-07 16:47:02"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
+ "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2016-11-23 20:04:58"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {
+ "behat/behat": 0,
+ "behat/mink-extension": 0,
+ "behat/mink-goutte-driver": 0
+ },
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=5.5",
+ "ext-curl": "*",
+ "ext-gd": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-openssl": "*"
+ },
+ "platform-dev": {
+ "php": ">=7.0"
+ }
+}
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index 28ef0d2bf..7a91153b0 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -6,620 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
- 'Hubzilla\\Import\\Import' => $baseDir . '/include/Import/Importer.php',
- 'Markdownify\\Converter' => $vendorDir . '/pixel418/markdownify/src/Converter.php',
- 'Markdownify\\ConverterExtra' => $vendorDir . '/pixel418/markdownify/src/ConverterExtra.php',
- 'Markdownify\\Parser' => $vendorDir . '/pixel418/markdownify/src/Parser.php',
- 'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php',
- 'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php',
- 'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php',
- 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
- 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
- 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
- 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
- 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
- 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
- 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
- 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
- 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
- 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
- 'Sabre\\CalDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php',
- 'Sabre\\CalDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php',
- 'Sabre\\CalDAV\\Backend\\NotificationSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php',
- 'Sabre\\CalDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/PDO.php',
- 'Sabre\\CalDAV\\Backend\\SchedulingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php',
- 'Sabre\\CalDAV\\Backend\\SharingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SharingSupport.php',
- 'Sabre\\CalDAV\\Backend\\SimplePDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SimplePDO.php',
- 'Sabre\\CalDAV\\Backend\\SubscriptionSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php',
- 'Sabre\\CalDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SyncSupport.php',
- 'Sabre\\CalDAV\\Calendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Calendar.php',
- 'Sabre\\CalDAV\\CalendarHome' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarHome.php',
- 'Sabre\\CalDAV\\CalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarObject.php',
- 'Sabre\\CalDAV\\CalendarQueryValidator' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarQueryValidator.php',
- 'Sabre\\CalDAV\\CalendarRoot' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarRoot.php',
- 'Sabre\\CalDAV\\Exception\\InvalidComponentType' => $vendorDir . '/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php',
- 'Sabre\\CalDAV\\ICSExportPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/ICSExportPlugin.php',
- 'Sabre\\CalDAV\\ICalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendar.php',
- 'Sabre\\CalDAV\\ICalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObject.php',
- 'Sabre\\CalDAV\\ICalendarObjectContainer' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php',
- 'Sabre\\CalDAV\\ISharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ISharedCalendar.php',
- 'Sabre\\CalDAV\\Notifications\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Collection.php',
- 'Sabre\\CalDAV\\Notifications\\ICollection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/ICollection.php',
- 'Sabre\\CalDAV\\Notifications\\INode' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/INode.php',
- 'Sabre\\CalDAV\\Notifications\\Node' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Node.php',
- 'Sabre\\CalDAV\\Notifications\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Plugin.php',
- 'Sabre\\CalDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Plugin.php',
- 'Sabre\\CalDAV\\Principal\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/Collection.php',
- 'Sabre\\CalDAV\\Principal\\IProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyRead.php',
- 'Sabre\\CalDAV\\Principal\\IProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyWrite.php',
- 'Sabre\\CalDAV\\Principal\\ProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyRead.php',
- 'Sabre\\CalDAV\\Principal\\ProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php',
- 'Sabre\\CalDAV\\Principal\\User' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/User.php',
- 'Sabre\\CalDAV\\Schedule\\IInbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IInbox.php',
- 'Sabre\\CalDAV\\Schedule\\IMipPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php',
- 'Sabre\\CalDAV\\Schedule\\IOutbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IOutbox.php',
- 'Sabre\\CalDAV\\Schedule\\ISchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/ISchedulingObject.php',
- 'Sabre\\CalDAV\\Schedule\\Inbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Inbox.php',
- 'Sabre\\CalDAV\\Schedule\\Outbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Outbox.php',
- 'Sabre\\CalDAV\\Schedule\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Plugin.php',
- 'Sabre\\CalDAV\\Schedule\\SchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php',
- 'Sabre\\CalDAV\\SharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/SharedCalendar.php',
- 'Sabre\\CalDAV\\SharingPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/SharingPlugin.php',
- 'Sabre\\CalDAV\\Subscriptions\\ISubscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php',
- 'Sabre\\CalDAV\\Subscriptions\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php',
- 'Sabre\\CalDAV\\Subscriptions\\Subscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php',
- 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\NotificationInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php',
- 'Sabre\\CalDAV\\Xml\\Notification\\SystemStatus' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php',
- 'Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php',
- 'Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php',
- 'Sabre\\CalDAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/Invite.php',
- 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php',
- 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php',
- 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php',
- 'Sabre\\CalDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php',
- 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php',
- 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php',
- 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php',
- 'Sabre\\CalDAV\\Xml\\Request\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php',
- 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php',
- 'Sabre\\CalDAV\\Xml\\Request\\Share' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/Share.php',
- 'Sabre\\CardDAV\\AddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBook.php',
- 'Sabre\\CardDAV\\AddressBookHome' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookHome.php',
- 'Sabre\\CardDAV\\AddressBookRoot' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookRoot.php',
- 'Sabre\\CardDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php',
- 'Sabre\\CardDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/BackendInterface.php',
- 'Sabre\\CardDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/PDO.php',
- 'Sabre\\CardDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/SyncSupport.php',
- 'Sabre\\CardDAV\\Card' => $vendorDir . '/sabre/dav/lib/CardDAV/Card.php',
- 'Sabre\\CardDAV\\IAddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/IAddressBook.php',
- 'Sabre\\CardDAV\\ICard' => $vendorDir . '/sabre/dav/lib/CardDAV/ICard.php',
- 'Sabre\\CardDAV\\IDirectory' => $vendorDir . '/sabre/dav/lib/CardDAV/IDirectory.php',
- 'Sabre\\CardDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CardDAV/Plugin.php',
- 'Sabre\\CardDAV\\VCFExportPlugin' => $vendorDir . '/sabre/dav/lib/CardDAV/VCFExportPlugin.php',
- 'Sabre\\CardDAV\\Xml\\Filter\\AddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php',
- 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php',
- 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php',
- 'Sabre\\CardDAV\\Xml\\Property\\SupportedAddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php',
- 'Sabre\\CardDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php',
- 'Sabre\\CardDAV\\Xml\\Request\\AddressBookMultiGetReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php',
- 'Sabre\\CardDAV\\Xml\\Request\\AddressBookQueryReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php',
- 'Sabre\\DAVACL\\ACLTrait' => $vendorDir . '/sabre/dav/lib/DAVACL/ACLTrait.php',
- 'Sabre\\DAVACL\\AbstractPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php',
- 'Sabre\\DAVACL\\Exception\\AceConflict' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/AceConflict.php',
- 'Sabre\\DAVACL\\Exception\\NeedPrivileges' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php',
- 'Sabre\\DAVACL\\Exception\\NoAbstract' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NoAbstract.php',
- 'Sabre\\DAVACL\\Exception\\NotRecognizedPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php',
- 'Sabre\\DAVACL\\Exception\\NotSupportedPrivilege' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php',
- 'Sabre\\DAVACL\\FS\\Collection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/Collection.php',
- 'Sabre\\DAVACL\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/File.php',
- 'Sabre\\DAVACL\\FS\\HomeCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/HomeCollection.php',
- 'Sabre\\DAVACL\\IACL' => $vendorDir . '/sabre/dav/lib/DAVACL/IACL.php',
- 'Sabre\\DAVACL\\IPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipal.php',
- 'Sabre\\DAVACL\\IPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipalCollection.php',
- 'Sabre\\DAVACL\\Plugin' => $vendorDir . '/sabre/dav/lib/DAVACL/Plugin.php',
- 'Sabre\\DAVACL\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Principal.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\CreatePrincipalSupport' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/CreatePrincipalSupport.php',
- 'Sabre\\DAVACL\\PrincipalBackend\\PDO' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php',
- 'Sabre\\DAVACL\\PrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalCollection.php',
- 'Sabre\\DAVACL\\Xml\\Property\\Acl' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Acl.php',
- 'Sabre\\DAVACL\\Xml\\Property\\AclRestrictions' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php',
- 'Sabre\\DAVACL\\Xml\\Property\\CurrentUserPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php',
- 'Sabre\\DAVACL\\Xml\\Property\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Principal.php',
- 'Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php',
- 'Sabre\\DAVACL\\Xml\\Request\\AclPrincipalPropSetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\PrincipalMatchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php',
- 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php',
- 'Sabre\\DAV\\Auth\\Backend\\AbstractBasic' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php',
- 'Sabre\\DAV\\Auth\\Backend\\AbstractBearer' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php',
- 'Sabre\\DAV\\Auth\\Backend\\AbstractDigest' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php',
- 'Sabre\\DAV\\Auth\\Backend\\Apache' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/Apache.php',
- 'Sabre\\DAV\\Auth\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php',
- 'Sabre\\DAV\\Auth\\Backend\\BasicCallBack' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php',
- 'Sabre\\DAV\\Auth\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/File.php',
- 'Sabre\\DAV\\Auth\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/PDO.php',
- 'Sabre\\DAV\\Auth\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Plugin.php',
- 'Sabre\\DAV\\Browser\\GuessContentType' => $vendorDir . '/sabre/dav/lib/DAV/Browser/GuessContentType.php',
- 'Sabre\\DAV\\Browser\\HtmlOutput' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutput.php',
- 'Sabre\\DAV\\Browser\\HtmlOutputHelper' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutputHelper.php',
- 'Sabre\\DAV\\Browser\\MapGetToPropFind' => $vendorDir . '/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php',
- 'Sabre\\DAV\\Browser\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Browser/Plugin.php',
- 'Sabre\\DAV\\Browser\\PropFindAll' => $vendorDir . '/sabre/dav/lib/DAV/Browser/PropFindAll.php',
- 'Sabre\\DAV\\Client' => $vendorDir . '/sabre/dav/lib/DAV/Client.php',
- 'Sabre\\DAV\\Collection' => $vendorDir . '/sabre/dav/lib/DAV/Collection.php',
- 'Sabre\\DAV\\CorePlugin' => $vendorDir . '/sabre/dav/lib/DAV/CorePlugin.php',
- 'Sabre\\DAV\\Exception' => $vendorDir . '/sabre/dav/lib/DAV/Exception.php',
- 'Sabre\\DAV\\Exception\\BadRequest' => $vendorDir . '/sabre/dav/lib/DAV/Exception/BadRequest.php',
- 'Sabre\\DAV\\Exception\\Conflict' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Conflict.php',
- 'Sabre\\DAV\\Exception\\ConflictingLock' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ConflictingLock.php',
- 'Sabre\\DAV\\Exception\\Forbidden' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Forbidden.php',
- 'Sabre\\DAV\\Exception\\InsufficientStorage' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InsufficientStorage.php',
- 'Sabre\\DAV\\Exception\\InvalidResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidResourceType.php',
- 'Sabre\\DAV\\Exception\\InvalidSyncToken' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php',
- 'Sabre\\DAV\\Exception\\LengthRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LengthRequired.php',
- 'Sabre\\DAV\\Exception\\LockTokenMatchesRequestUri' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LockTokenMatchesRequestUri.php',
- 'Sabre\\DAV\\Exception\\Locked' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Locked.php',
- 'Sabre\\DAV\\Exception\\MethodNotAllowed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php',
- 'Sabre\\DAV\\Exception\\NotAuthenticated' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotAuthenticated.php',
- 'Sabre\\DAV\\Exception\\NotFound' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotFound.php',
- 'Sabre\\DAV\\Exception\\NotImplemented' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotImplemented.php',
- 'Sabre\\DAV\\Exception\\PaymentRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PaymentRequired.php',
- 'Sabre\\DAV\\Exception\\PreconditionFailed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PreconditionFailed.php',
- 'Sabre\\DAV\\Exception\\ReportNotSupported' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ReportNotSupported.php',
- 'Sabre\\DAV\\Exception\\RequestedRangeNotSatisfiable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php',
- 'Sabre\\DAV\\Exception\\ServiceUnavailable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ServiceUnavailable.php',
- 'Sabre\\DAV\\Exception\\TooManyMatches' => $vendorDir . '/sabre/dav/lib/DAV/Exception/TooManyMatches.php',
- 'Sabre\\DAV\\Exception\\UnsupportedMediaType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php',
- 'Sabre\\DAV\\FSExt\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/Directory.php',
- 'Sabre\\DAV\\FSExt\\File' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/File.php',
- 'Sabre\\DAV\\FS\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FS/Directory.php',
- 'Sabre\\DAV\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAV/FS/File.php',
- 'Sabre\\DAV\\FS\\Node' => $vendorDir . '/sabre/dav/lib/DAV/FS/Node.php',
- 'Sabre\\DAV\\File' => $vendorDir . '/sabre/dav/lib/DAV/File.php',
- 'Sabre\\DAV\\ICollection' => $vendorDir . '/sabre/dav/lib/DAV/ICollection.php',
- 'Sabre\\DAV\\IExtendedCollection' => $vendorDir . '/sabre/dav/lib/DAV/IExtendedCollection.php',
- 'Sabre\\DAV\\IFile' => $vendorDir . '/sabre/dav/lib/DAV/IFile.php',
- 'Sabre\\DAV\\IMoveTarget' => $vendorDir . '/sabre/dav/lib/DAV/IMoveTarget.php',
- 'Sabre\\DAV\\IMultiGet' => $vendorDir . '/sabre/dav/lib/DAV/IMultiGet.php',
- 'Sabre\\DAV\\INode' => $vendorDir . '/sabre/dav/lib/DAV/INode.php',
- 'Sabre\\DAV\\IProperties' => $vendorDir . '/sabre/dav/lib/DAV/IProperties.php',
- 'Sabre\\DAV\\IQuota' => $vendorDir . '/sabre/dav/lib/DAV/IQuota.php',
- 'Sabre\\DAV\\Locks\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/AbstractBackend.php',
- 'Sabre\\DAV\\Locks\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/BackendInterface.php',
- 'Sabre\\DAV\\Locks\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/File.php',
- 'Sabre\\DAV\\Locks\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/PDO.php',
- 'Sabre\\DAV\\Locks\\LockInfo' => $vendorDir . '/sabre/dav/lib/DAV/Locks/LockInfo.php',
- 'Sabre\\DAV\\Locks\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Plugin.php',
- 'Sabre\\DAV\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/MkCol.php',
- 'Sabre\\DAV\\Mount\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Mount/Plugin.php',
- 'Sabre\\DAV\\Node' => $vendorDir . '/sabre/dav/lib/DAV/Node.php',
- 'Sabre\\DAV\\PartialUpdate\\IPatchSupport' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php',
- 'Sabre\\DAV\\PartialUpdate\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/Plugin.php',
- 'Sabre\\DAV\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/PropFind.php',
- 'Sabre\\DAV\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/PropPatch.php',
- 'Sabre\\DAV\\PropertyStorage\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php',
- 'Sabre\\DAV\\PropertyStorage\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php',
- 'Sabre\\DAV\\PropertyStorage\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Plugin.php',
- 'Sabre\\DAV\\Server' => $vendorDir . '/sabre/dav/lib/DAV/Server.php',
- 'Sabre\\DAV\\ServerPlugin' => $vendorDir . '/sabre/dav/lib/DAV/ServerPlugin.php',
- 'Sabre\\DAV\\Sharing\\ISharedNode' => $vendorDir . '/sabre/dav/lib/DAV/Sharing/ISharedNode.php',
- 'Sabre\\DAV\\Sharing\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sharing/Plugin.php',
- 'Sabre\\DAV\\SimpleCollection' => $vendorDir . '/sabre/dav/lib/DAV/SimpleCollection.php',
- 'Sabre\\DAV\\SimpleFile' => $vendorDir . '/sabre/dav/lib/DAV/SimpleFile.php',
- 'Sabre\\DAV\\StringUtil' => $vendorDir . '/sabre/dav/lib/DAV/StringUtil.php',
- 'Sabre\\DAV\\Sync\\ISyncCollection' => $vendorDir . '/sabre/dav/lib/DAV/Sync/ISyncCollection.php',
- 'Sabre\\DAV\\Sync\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sync/Plugin.php',
- 'Sabre\\DAV\\TemporaryFileFilterPlugin' => $vendorDir . '/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php',
- 'Sabre\\DAV\\Tree' => $vendorDir . '/sabre/dav/lib/DAV/Tree.php',
- 'Sabre\\DAV\\UUIDUtil' => $vendorDir . '/sabre/dav/lib/DAV/UUIDUtil.php',
- 'Sabre\\DAV\\Version' => $vendorDir . '/sabre/dav/lib/DAV/Version.php',
- 'Sabre\\DAV\\Xml\\Element\\Prop' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Prop.php',
- 'Sabre\\DAV\\Xml\\Element\\Response' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Response.php',
- 'Sabre\\DAV\\Xml\\Element\\Sharee' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Sharee.php',
- 'Sabre\\DAV\\Xml\\Property\\Complex' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Complex.php',
- 'Sabre\\DAV\\Xml\\Property\\GetLastModified' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php',
- 'Sabre\\DAV\\Xml\\Property\\Href' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Href.php',
- 'Sabre\\DAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Invite.php',
- 'Sabre\\DAV\\Xml\\Property\\LocalHref' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LocalHref.php',
- 'Sabre\\DAV\\Xml\\Property\\LockDiscovery' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LockDiscovery.php',
- 'Sabre\\DAV\\Xml\\Property\\ResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ResourceType.php',
- 'Sabre\\DAV\\Xml\\Property\\ShareAccess' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php',
- 'Sabre\\DAV\\Xml\\Property\\SupportedLock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php',
- 'Sabre\\DAV\\Xml\\Property\\SupportedMethodSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php',
- 'Sabre\\DAV\\Xml\\Property\\SupportedReportSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php',
- 'Sabre\\DAV\\Xml\\Request\\Lock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/Lock.php',
- 'Sabre\\DAV\\Xml\\Request\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/MkCol.php',
- 'Sabre\\DAV\\Xml\\Request\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropFind.php',
- 'Sabre\\DAV\\Xml\\Request\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropPatch.php',
- 'Sabre\\DAV\\Xml\\Request\\ShareResource' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/ShareResource.php',
- 'Sabre\\DAV\\Xml\\Request\\SyncCollectionReport' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php',
- 'Sabre\\DAV\\Xml\\Response\\MultiStatus' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php',
- 'Sabre\\DAV\\Xml\\Service' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Service.php',
- 'Sabre\\Event\\EventEmitter' => $vendorDir . '/sabre/event/lib/EventEmitter.php',
- 'Sabre\\Event\\EventEmitterInterface' => $vendorDir . '/sabre/event/lib/EventEmitterInterface.php',
- 'Sabre\\Event\\EventEmitterTrait' => $vendorDir . '/sabre/event/lib/EventEmitterTrait.php',
- 'Sabre\\Event\\Loop\\Loop' => $vendorDir . '/sabre/event/lib/Loop/Loop.php',
- 'Sabre\\Event\\Promise' => $vendorDir . '/sabre/event/lib/Promise.php',
- 'Sabre\\Event\\PromiseAlreadyResolvedException' => $vendorDir . '/sabre/event/lib/PromiseAlreadyResolvedException.php',
- 'Sabre\\Event\\Version' => $vendorDir . '/sabre/event/lib/Version.php',
- 'Sabre\\HTTP\\Auth\\AWS' => $vendorDir . '/sabre/http/lib/Auth/AWS.php',
- 'Sabre\\HTTP\\Auth\\AbstractAuth' => $vendorDir . '/sabre/http/lib/Auth/AbstractAuth.php',
- 'Sabre\\HTTP\\Auth\\Basic' => $vendorDir . '/sabre/http/lib/Auth/Basic.php',
- 'Sabre\\HTTP\\Auth\\Bearer' => $vendorDir . '/sabre/http/lib/Auth/Bearer.php',
- 'Sabre\\HTTP\\Auth\\Digest' => $vendorDir . '/sabre/http/lib/Auth/Digest.php',
- 'Sabre\\HTTP\\Client' => $vendorDir . '/sabre/http/lib/Client.php',
- 'Sabre\\HTTP\\ClientException' => $vendorDir . '/sabre/http/lib/ClientException.php',
- 'Sabre\\HTTP\\ClientHttpException' => $vendorDir . '/sabre/http/lib/ClientHttpException.php',
- 'Sabre\\HTTP\\HttpException' => $vendorDir . '/sabre/http/lib/HttpException.php',
- 'Sabre\\HTTP\\Message' => $vendorDir . '/sabre/http/lib/Message.php',
- 'Sabre\\HTTP\\MessageDecoratorTrait' => $vendorDir . '/sabre/http/lib/MessageDecoratorTrait.php',
- 'Sabre\\HTTP\\MessageInterface' => $vendorDir . '/sabre/http/lib/MessageInterface.php',
- 'Sabre\\HTTP\\Request' => $vendorDir . '/sabre/http/lib/Request.php',
- 'Sabre\\HTTP\\RequestDecorator' => $vendorDir . '/sabre/http/lib/RequestDecorator.php',
- 'Sabre\\HTTP\\RequestInterface' => $vendorDir . '/sabre/http/lib/RequestInterface.php',
- 'Sabre\\HTTP\\Response' => $vendorDir . '/sabre/http/lib/Response.php',
- 'Sabre\\HTTP\\ResponseDecorator' => $vendorDir . '/sabre/http/lib/ResponseDecorator.php',
- 'Sabre\\HTTP\\ResponseInterface' => $vendorDir . '/sabre/http/lib/ResponseInterface.php',
- 'Sabre\\HTTP\\Sapi' => $vendorDir . '/sabre/http/lib/Sapi.php',
- 'Sabre\\HTTP\\URLUtil' => $vendorDir . '/sabre/http/lib/URLUtil.php',
- 'Sabre\\HTTP\\Util' => $vendorDir . '/sabre/http/lib/Util.php',
- 'Sabre\\HTTP\\Version' => $vendorDir . '/sabre/http/lib/Version.php',
- 'Sabre\\Uri\\Version' => $vendorDir . '/sabre/uri/lib/Version.php',
- 'Sabre\\VObject\\BirthdayCalendarGenerator' => $vendorDir . '/sabre/vobject/lib/BirthdayCalendarGenerator.php',
- 'Sabre\\VObject\\Cli' => $vendorDir . '/sabre/vobject/lib/Cli.php',
- 'Sabre\\VObject\\Component' => $vendorDir . '/sabre/vobject/lib/Component.php',
- 'Sabre\\VObject\\Component\\Available' => $vendorDir . '/sabre/vobject/lib/Component/Available.php',
- 'Sabre\\VObject\\Component\\VAlarm' => $vendorDir . '/sabre/vobject/lib/Component/VAlarm.php',
- 'Sabre\\VObject\\Component\\VAvailability' => $vendorDir . '/sabre/vobject/lib/Component/VAvailability.php',
- 'Sabre\\VObject\\Component\\VCalendar' => $vendorDir . '/sabre/vobject/lib/Component/VCalendar.php',
- 'Sabre\\VObject\\Component\\VCard' => $vendorDir . '/sabre/vobject/lib/Component/VCard.php',
- 'Sabre\\VObject\\Component\\VEvent' => $vendorDir . '/sabre/vobject/lib/Component/VEvent.php',
- 'Sabre\\VObject\\Component\\VFreeBusy' => $vendorDir . '/sabre/vobject/lib/Component/VFreeBusy.php',
- 'Sabre\\VObject\\Component\\VJournal' => $vendorDir . '/sabre/vobject/lib/Component/VJournal.php',
- 'Sabre\\VObject\\Component\\VTimeZone' => $vendorDir . '/sabre/vobject/lib/Component/VTimeZone.php',
- 'Sabre\\VObject\\Component\\VTodo' => $vendorDir . '/sabre/vobject/lib/Component/VTodo.php',
- 'Sabre\\VObject\\DateTimeParser' => $vendorDir . '/sabre/vobject/lib/DateTimeParser.php',
- 'Sabre\\VObject\\Document' => $vendorDir . '/sabre/vobject/lib/Document.php',
- 'Sabre\\VObject\\ElementList' => $vendorDir . '/sabre/vobject/lib/ElementList.php',
- 'Sabre\\VObject\\EofException' => $vendorDir . '/sabre/vobject/lib/EofException.php',
- 'Sabre\\VObject\\FreeBusyData' => $vendorDir . '/sabre/vobject/lib/FreeBusyData.php',
- 'Sabre\\VObject\\FreeBusyGenerator' => $vendorDir . '/sabre/vobject/lib/FreeBusyGenerator.php',
- 'Sabre\\VObject\\ITip\\Broker' => $vendorDir . '/sabre/vobject/lib/ITip/Broker.php',
- 'Sabre\\VObject\\ITip\\ITipException' => $vendorDir . '/sabre/vobject/lib/ITip/ITipException.php',
- 'Sabre\\VObject\\ITip\\Message' => $vendorDir . '/sabre/vobject/lib/ITip/Message.php',
- 'Sabre\\VObject\\ITip\\SameOrganizerForAllComponentsException' => $vendorDir . '/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php',
- 'Sabre\\VObject\\InvalidDataException' => $vendorDir . '/sabre/vobject/lib/InvalidDataException.php',
- 'Sabre\\VObject\\Node' => $vendorDir . '/sabre/vobject/lib/Node.php',
- 'Sabre\\VObject\\PHPUnitAssertions' => $vendorDir . '/sabre/vobject/lib/PHPUnitAssertions.php',
- 'Sabre\\VObject\\Parameter' => $vendorDir . '/sabre/vobject/lib/Parameter.php',
- 'Sabre\\VObject\\ParseException' => $vendorDir . '/sabre/vobject/lib/ParseException.php',
- 'Sabre\\VObject\\Parser\\Json' => $vendorDir . '/sabre/vobject/lib/Parser/Json.php',
- 'Sabre\\VObject\\Parser\\MimeDir' => $vendorDir . '/sabre/vobject/lib/Parser/MimeDir.php',
- 'Sabre\\VObject\\Parser\\Parser' => $vendorDir . '/sabre/vobject/lib/Parser/Parser.php',
- 'Sabre\\VObject\\Parser\\XML' => $vendorDir . '/sabre/vobject/lib/Parser/XML.php',
- 'Sabre\\VObject\\Parser\\XML\\Element\\KeyValue' => $vendorDir . '/sabre/vobject/lib/Parser/XML/Element/KeyValue.php',
- 'Sabre\\VObject\\Property' => $vendorDir . '/sabre/vobject/lib/Property.php',
- 'Sabre\\VObject\\Property\\Binary' => $vendorDir . '/sabre/vobject/lib/Property/Binary.php',
- 'Sabre\\VObject\\Property\\Boolean' => $vendorDir . '/sabre/vobject/lib/Property/Boolean.php',
- 'Sabre\\VObject\\Property\\FlatText' => $vendorDir . '/sabre/vobject/lib/Property/FlatText.php',
- 'Sabre\\VObject\\Property\\FloatValue' => $vendorDir . '/sabre/vobject/lib/Property/FloatValue.php',
- 'Sabre\\VObject\\Property\\ICalendar\\CalAddress' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/CalAddress.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Date' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Date.php',
- 'Sabre\\VObject\\Property\\ICalendar\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/DateTime.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Duration' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Duration.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Period' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Period.php',
- 'Sabre\\VObject\\Property\\ICalendar\\Recur' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Recur.php',
- 'Sabre\\VObject\\Property\\IntegerValue' => $vendorDir . '/sabre/vobject/lib/Property/IntegerValue.php',
- 'Sabre\\VObject\\Property\\Text' => $vendorDir . '/sabre/vobject/lib/Property/Text.php',
- 'Sabre\\VObject\\Property\\Time' => $vendorDir . '/sabre/vobject/lib/Property/Time.php',
- 'Sabre\\VObject\\Property\\Unknown' => $vendorDir . '/sabre/vobject/lib/Property/Unknown.php',
- 'Sabre\\VObject\\Property\\Uri' => $vendorDir . '/sabre/vobject/lib/Property/Uri.php',
- 'Sabre\\VObject\\Property\\UtcOffset' => $vendorDir . '/sabre/vobject/lib/Property/UtcOffset.php',
- 'Sabre\\VObject\\Property\\VCard\\Date' => $vendorDir . '/sabre/vobject/lib/Property/VCard/Date.php',
- 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateAndOrTime.php',
- 'Sabre\\VObject\\Property\\VCard\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateTime.php',
- 'Sabre\\VObject\\Property\\VCard\\LanguageTag' => $vendorDir . '/sabre/vobject/lib/Property/VCard/LanguageTag.php',
- 'Sabre\\VObject\\Property\\VCard\\TimeStamp' => $vendorDir . '/sabre/vobject/lib/Property/VCard/TimeStamp.php',
- 'Sabre\\VObject\\Reader' => $vendorDir . '/sabre/vobject/lib/Reader.php',
- 'Sabre\\VObject\\Recur\\EventIterator' => $vendorDir . '/sabre/vobject/lib/Recur/EventIterator.php',
- 'Sabre\\VObject\\Recur\\MaxInstancesExceededException' => $vendorDir . '/sabre/vobject/lib/Recur/MaxInstancesExceededException.php',
- 'Sabre\\VObject\\Recur\\NoInstancesException' => $vendorDir . '/sabre/vobject/lib/Recur/NoInstancesException.php',
- 'Sabre\\VObject\\Recur\\RDateIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RDateIterator.php',
- 'Sabre\\VObject\\Recur\\RRuleIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RRuleIterator.php',
- 'Sabre\\VObject\\Settings' => $vendorDir . '/sabre/vobject/lib/Settings.php',
- 'Sabre\\VObject\\Splitter\\ICalendar' => $vendorDir . '/sabre/vobject/lib/Splitter/ICalendar.php',
- 'Sabre\\VObject\\Splitter\\SplitterInterface' => $vendorDir . '/sabre/vobject/lib/Splitter/SplitterInterface.php',
- 'Sabre\\VObject\\Splitter\\VCard' => $vendorDir . '/sabre/vobject/lib/Splitter/VCard.php',
- 'Sabre\\VObject\\StringUtil' => $vendorDir . '/sabre/vobject/lib/StringUtil.php',
- 'Sabre\\VObject\\TimeZoneUtil' => $vendorDir . '/sabre/vobject/lib/TimeZoneUtil.php',
- 'Sabre\\VObject\\UUIDUtil' => $vendorDir . '/sabre/vobject/lib/UUIDUtil.php',
- 'Sabre\\VObject\\VCardConverter' => $vendorDir . '/sabre/vobject/lib/VCardConverter.php',
- 'Sabre\\VObject\\Version' => $vendorDir . '/sabre/vobject/lib/Version.php',
- 'Sabre\\VObject\\Writer' => $vendorDir . '/sabre/vobject/lib/Writer.php',
- 'Sabre\\Xml\\ContextStackTrait' => $vendorDir . '/sabre/xml/lib/ContextStackTrait.php',
- 'Sabre\\Xml\\Element' => $vendorDir . '/sabre/xml/lib/Element.php',
- 'Sabre\\Xml\\Element\\Base' => $vendorDir . '/sabre/xml/lib/Element/Base.php',
- 'Sabre\\Xml\\Element\\Cdata' => $vendorDir . '/sabre/xml/lib/Element/Cdata.php',
- 'Sabre\\Xml\\Element\\Elements' => $vendorDir . '/sabre/xml/lib/Element/Elements.php',
- 'Sabre\\Xml\\Element\\KeyValue' => $vendorDir . '/sabre/xml/lib/Element/KeyValue.php',
- 'Sabre\\Xml\\Element\\Uri' => $vendorDir . '/sabre/xml/lib/Element/Uri.php',
- 'Sabre\\Xml\\Element\\XmlFragment' => $vendorDir . '/sabre/xml/lib/Element/XmlFragment.php',
- 'Sabre\\Xml\\LibXMLException' => $vendorDir . '/sabre/xml/lib/LibXMLException.php',
- 'Sabre\\Xml\\ParseException' => $vendorDir . '/sabre/xml/lib/ParseException.php',
- 'Sabre\\Xml\\Reader' => $vendorDir . '/sabre/xml/lib/Reader.php',
- 'Sabre\\Xml\\Service' => $vendorDir . '/sabre/xml/lib/Service.php',
- 'Sabre\\Xml\\Version' => $vendorDir . '/sabre/xml/lib/Version.php',
- 'Sabre\\Xml\\Writer' => $vendorDir . '/sabre/xml/lib/Writer.php',
- 'Sabre\\Xml\\XmlDeserializable' => $vendorDir . '/sabre/xml/lib/XmlDeserializable.php',
- 'Sabre\\Xml\\XmlSerializable' => $vendorDir . '/sabre/xml/lib/XmlSerializable.php',
- 'Zotlabs\\Access\\AccessList' => $baseDir . '/Zotlabs/Access/AccessList.php',
- 'Zotlabs\\Access\\PermissionLimits' => $baseDir . '/Zotlabs/Access/PermissionLimits.php',
- 'Zotlabs\\Access\\PermissionRoles' => $baseDir . '/Zotlabs/Access/PermissionRoles.php',
- 'Zotlabs\\Access\\Permissions' => $baseDir . '/Zotlabs/Access/Permissions.php',
- 'Zotlabs\\Daemon\\Addon' => $baseDir . '/Zotlabs/Daemon/Addon.php',
- 'Zotlabs\\Daemon\\Checksites' => $baseDir . '/Zotlabs/Daemon/Checksites.php',
- 'Zotlabs\\Daemon\\Cli_suggest' => $baseDir . '/Zotlabs/Daemon/Cli_suggest.php',
- 'Zotlabs\\Daemon\\Cron' => $baseDir . '/Zotlabs/Daemon/Cron.php',
- 'Zotlabs\\Daemon\\Cron_daily' => $baseDir . '/Zotlabs/Daemon/Cron_daily.php',
- 'Zotlabs\\Daemon\\Cron_weekly' => $baseDir . '/Zotlabs/Daemon/Cron_weekly.php',
- 'Zotlabs\\Daemon\\Cronhooks' => $baseDir . '/Zotlabs/Daemon/Cronhooks.php',
- 'Zotlabs\\Daemon\\CurlAuth' => $baseDir . '/Zotlabs/Daemon/CurlAuth.php',
- 'Zotlabs\\Daemon\\Deliver' => $baseDir . '/Zotlabs/Daemon/Deliver.php',
- 'Zotlabs\\Daemon\\Deliver_hooks' => $baseDir . '/Zotlabs/Daemon/Deliver_hooks.php',
- 'Zotlabs\\Daemon\\Directory' => $baseDir . '/Zotlabs/Daemon/Directory.php',
- 'Zotlabs\\Daemon\\Expire' => $baseDir . '/Zotlabs/Daemon/Expire.php',
- 'Zotlabs\\Daemon\\Externals' => $baseDir . '/Zotlabs/Daemon/Externals.php',
- 'Zotlabs\\Daemon\\Gprobe' => $baseDir . '/Zotlabs/Daemon/Gprobe.php',
- 'Zotlabs\\Daemon\\Importdoc' => $baseDir . '/Zotlabs/Daemon/Importdoc.php',
- 'Zotlabs\\Daemon\\Master' => $baseDir . '/Zotlabs/Daemon/Master.php',
- 'Zotlabs\\Daemon\\Notifier' => $baseDir . '/Zotlabs/Daemon/Notifier.php',
- 'Zotlabs\\Daemon\\Onedirsync' => $baseDir . '/Zotlabs/Daemon/Onedirsync.php',
- 'Zotlabs\\Daemon\\Onepoll' => $baseDir . '/Zotlabs/Daemon/Onepoll.php',
- 'Zotlabs\\Daemon\\Poller' => $baseDir . '/Zotlabs/Daemon/Poller.php',
- 'Zotlabs\\Daemon\\Queue' => $baseDir . '/Zotlabs/Daemon/Queue.php',
- 'Zotlabs\\Daemon\\Ratenotif' => $baseDir . '/Zotlabs/Daemon/Ratenotif.php',
- 'Zotlabs\\Extend\\Hook' => $baseDir . '/Zotlabs/Extend/Hook.php',
- 'Zotlabs\\Identity\\BasicId\\BasicId' => $baseDir . '/Zotlabs/Identity/BasicId.php',
- 'Zotlabs\\Identity\\ProfilePhoto\\ProfilePhoto' => $baseDir . '/Zotlabs/Identity/ProfilePhoto.php',
- 'Zotlabs\\Lib\\AConfig' => $baseDir . '/Zotlabs/Lib/AConfig.php',
- 'Zotlabs\\Lib\\AbConfig' => $baseDir . '/Zotlabs/Lib/AbConfig.php',
- 'Zotlabs\\Lib\\Api_router' => $baseDir . '/Zotlabs/Lib/Api_router.php',
- 'Zotlabs\\Lib\\Apps' => $baseDir . '/Zotlabs/Lib/Apps.php',
- 'Zotlabs\\Lib\\Cache' => $baseDir . '/Zotlabs/Lib/Cache.php',
- 'Zotlabs\\Lib\\Chatroom' => $baseDir . '/Zotlabs/Lib/Chatroom.php',
- 'Zotlabs\\Lib\\Config' => $baseDir . '/Zotlabs/Lib/Config.php',
- 'Zotlabs\\Lib\\Enotify' => $baseDir . '/Zotlabs/Lib/Enotify.php',
- 'Zotlabs\\Lib\\ExtendedZip' => $baseDir . '/Zotlabs/Lib/ExtendedZip.php',
- 'Zotlabs\\Lib\\IConfig' => $baseDir . '/Zotlabs/Lib/IConfig.php',
- 'Zotlabs\\Lib\\NativeWiki' => $baseDir . '/Zotlabs/Lib/NativeWiki.php',
- 'Zotlabs\\Lib\\NativeWikiPage' => $baseDir . '/Zotlabs/Lib/NativeWikiPage.php',
- 'Zotlabs\\Lib\\PConfig' => $baseDir . '/Zotlabs/Lib/PConfig.php',
- 'Zotlabs\\Lib\\Permcat' => $baseDir . '/Zotlabs/Lib/Permcat.php',
- 'Zotlabs\\Lib\\PermissionDescription' => $baseDir . '/Zotlabs/Lib/PermissionDescription.php',
- 'Zotlabs\\Lib\\ProtoDriver' => $baseDir . '/Zotlabs/Lib/ProtoDriver.php',
- 'Zotlabs\\Lib\\SuperCurl' => $baseDir . '/Zotlabs/Lib/SuperCurl.php',
- 'Zotlabs\\Lib\\System' => $baseDir . '/Zotlabs/Lib/System.php',
- 'Zotlabs\\Lib\\Techlevels' => $baseDir . '/Zotlabs/Lib/Techlevels.php',
- 'Zotlabs\\Lib\\ThreadItem' => $baseDir . '/Zotlabs/Lib/ThreadItem.php',
- 'Zotlabs\\Lib\\ThreadStream' => $baseDir . '/Zotlabs/Lib/ThreadStream.php',
- 'Zotlabs\\Lib\\XConfig' => $baseDir . '/Zotlabs/Lib/XConfig.php',
- 'Zotlabs\\Lib\\ZotDriver' => $baseDir . '/Zotlabs/Lib/ZotDriver.php',
- 'Zotlabs\\Module\\Achievements' => $baseDir . '/Zotlabs/Module/Achievements.php',
- 'Zotlabs\\Module\\Acl' => $baseDir . '/Zotlabs/Module/Acl.php',
- 'Zotlabs\\Module\\Admin' => $baseDir . '/Zotlabs/Module/Admin.php',
- 'Zotlabs\\Module\\Admin\\Account_edit' => $baseDir . '/Zotlabs/Module/Admin/Account_edit.php',
- 'Zotlabs\\Module\\Admin\\Accounts' => $baseDir . '/Zotlabs/Module/Admin/Accounts.php',
- 'Zotlabs\\Module\\Admin\\Channels' => $baseDir . '/Zotlabs/Module/Admin/Channels.php',
- 'Zotlabs\\Module\\Admin\\Dbsync' => $baseDir . '/Zotlabs/Module/Admin/Dbsync.php',
- 'Zotlabs\\Module\\Admin\\Features' => $baseDir . '/Zotlabs/Module/Admin/Features.php',
- 'Zotlabs\\Module\\Admin\\Logs' => $baseDir . '/Zotlabs/Module/Admin/Logs.php',
- 'Zotlabs\\Module\\Admin\\Plugins' => $baseDir . '/Zotlabs/Module/Admin/Plugins.php',
- 'Zotlabs\\Module\\Admin\\Profs' => $baseDir . '/Zotlabs/Module/Admin/Profs.php',
- 'Zotlabs\\Module\\Admin\\Queue' => $baseDir . '/Zotlabs/Module/Admin/Queue.php',
- 'Zotlabs\\Module\\Admin\\Security' => $baseDir . '/Zotlabs/Module/Admin/Security.php',
- 'Zotlabs\\Module\\Admin\\Site' => $baseDir . '/Zotlabs/Module/Admin/Site.php',
- 'Zotlabs\\Module\\Admin\\Themes' => $baseDir . '/Zotlabs/Module/Admin/Themes.php',
- 'Zotlabs\\Module\\Api' => $baseDir . '/Zotlabs/Module/Api.php',
- 'Zotlabs\\Module\\Appman' => $baseDir . '/Zotlabs/Module/Appman.php',
- 'Zotlabs\\Module\\Apps' => $baseDir . '/Zotlabs/Module/Apps.php',
- 'Zotlabs\\Module\\Attach' => $baseDir . '/Zotlabs/Module/Attach.php',
- 'Zotlabs\\Module\\Authtest' => $baseDir . '/Zotlabs/Module/Authtest.php',
- 'Zotlabs\\Module\\Block' => $baseDir . '/Zotlabs/Module/Block.php',
- 'Zotlabs\\Module\\Blocks' => $baseDir . '/Zotlabs/Module/Blocks.php',
- 'Zotlabs\\Module\\Bookmarks' => $baseDir . '/Zotlabs/Module/Bookmarks.php',
- 'Zotlabs\\Module\\Branchtopic' => $baseDir . '/Zotlabs/Module/Branchtopic.php',
- 'Zotlabs\\Module\\Cal' => $baseDir . '/Zotlabs/Module/Cal.php',
- 'Zotlabs\\Module\\Channel' => $baseDir . '/Zotlabs/Module/Channel.php',
- 'Zotlabs\\Module\\Chanview' => $baseDir . '/Zotlabs/Module/Chanview.php',
- 'Zotlabs\\Module\\Chat' => $baseDir . '/Zotlabs/Module/Chat.php',
- 'Zotlabs\\Module\\Chatsvc' => $baseDir . '/Zotlabs/Module/Chatsvc.php',
- 'Zotlabs\\Module\\Cloud' => $baseDir . '/Zotlabs/Module/Cloud.php',
- 'Zotlabs\\Module\\Common' => $baseDir . '/Zotlabs/Module/Common.php',
- 'Zotlabs\\Module\\Connect' => $baseDir . '/Zotlabs/Module/Connect.php',
- 'Zotlabs\\Module\\Connections' => $baseDir . '/Zotlabs/Module/Connections.php',
- 'Zotlabs\\Module\\Connedit' => $baseDir . '/Zotlabs/Module/Connedit.php',
- 'Zotlabs\\Module\\Contactgroup' => $baseDir . '/Zotlabs/Module/Contactgroup.php',
- 'Zotlabs\\Module\\Cover_photo' => $baseDir . '/Zotlabs/Module/Cover_photo.php',
- 'Zotlabs\\Module\\Dav' => $baseDir . '/Zotlabs/Module/Dav.php',
- 'Zotlabs\\Module\\Directory' => $baseDir . '/Zotlabs/Module/Directory.php',
- 'Zotlabs\\Module\\Dirsearch' => $baseDir . '/Zotlabs/Module/Dirsearch.php',
- 'Zotlabs\\Module\\Display' => $baseDir . '/Zotlabs/Module/Display.php',
- 'Zotlabs\\Module\\Dreport' => $baseDir . '/Zotlabs/Module/Dreport.php',
- 'Zotlabs\\Module\\Editblock' => $baseDir . '/Zotlabs/Module/Editblock.php',
- 'Zotlabs\\Module\\Editlayout' => $baseDir . '/Zotlabs/Module/Editlayout.php',
- 'Zotlabs\\Module\\Editpost' => $baseDir . '/Zotlabs/Module/Editpost.php',
- 'Zotlabs\\Module\\Editwebpage' => $baseDir . '/Zotlabs/Module/Editwebpage.php',
- 'Zotlabs\\Module\\Embedphotos' => $baseDir . '/Zotlabs/Module/Embedphotos.php',
- 'Zotlabs\\Module\\Events' => $baseDir . '/Zotlabs/Module/Events.php',
- 'Zotlabs\\Module\\Fbrowser' => $baseDir . '/Zotlabs/Module/Fbrowser.php',
- 'Zotlabs\\Module\\Feed' => $baseDir . '/Zotlabs/Module/Feed.php',
- 'Zotlabs\\Module\\Fhublocs' => $baseDir . '/Zotlabs/Module/Fhublocs.php',
- 'Zotlabs\\Module\\File_upload' => $baseDir . '/Zotlabs/Module/File_upload.php',
- 'Zotlabs\\Module\\Filer' => $baseDir . '/Zotlabs/Module/Filer.php',
- 'Zotlabs\\Module\\Filerm' => $baseDir . '/Zotlabs/Module/Filerm.php',
- 'Zotlabs\\Module\\Filestorage' => $baseDir . '/Zotlabs/Module/Filestorage.php',
- 'Zotlabs\\Module\\Follow' => $baseDir . '/Zotlabs/Module/Follow.php',
- 'Zotlabs\\Module\\Getfile' => $baseDir . '/Zotlabs/Module/Getfile.php',
- 'Zotlabs\\Module\\Group' => $baseDir . '/Zotlabs/Module/Group.php',
- 'Zotlabs\\Module\\Hcard' => $baseDir . '/Zotlabs/Module/Hcard.php',
- 'Zotlabs\\Module\\Help' => $baseDir . '/Zotlabs/Module/Help.php',
- 'Zotlabs\\Module\\Home' => $baseDir . '/Zotlabs/Module/Home.php',
- 'Zotlabs\\Module\\Hostxrd' => $baseDir . '/Zotlabs/Module/Hostxrd.php',
- 'Zotlabs\\Module\\Impel' => $baseDir . '/Zotlabs/Module/Impel.php',
- 'Zotlabs\\Module\\Import' => $baseDir . '/Zotlabs/Module/Import.php',
- 'Zotlabs\\Module\\Import_items' => $baseDir . '/Zotlabs/Module/Import_items.php',
- 'Zotlabs\\Module\\Invite' => $baseDir . '/Zotlabs/Module/Invite.php',
- 'Zotlabs\\Module\\Item' => $baseDir . '/Zotlabs/Module/Item.php',
- 'Zotlabs\\Module\\Lang' => $baseDir . '/Zotlabs/Module/Lang.php',
- 'Zotlabs\\Module\\Layouts' => $baseDir . '/Zotlabs/Module/Layouts.php',
- 'Zotlabs\\Module\\Like' => $baseDir . '/Zotlabs/Module/Like.php',
- 'Zotlabs\\Module\\Linkinfo' => $baseDir . '/Zotlabs/Module/Linkinfo.php',
- 'Zotlabs\\Module\\Lockview' => $baseDir . '/Zotlabs/Module/Lockview.php',
- 'Zotlabs\\Module\\Locs' => $baseDir . '/Zotlabs/Module/Locs.php',
- 'Zotlabs\\Module\\Login' => $baseDir . '/Zotlabs/Module/Login.php',
- 'Zotlabs\\Module\\Lostpass' => $baseDir . '/Zotlabs/Module/Lostpass.php',
- 'Zotlabs\\Module\\Magic' => $baseDir . '/Zotlabs/Module/Magic.php',
- 'Zotlabs\\Module\\Mail' => $baseDir . '/Zotlabs/Module/Mail.php',
- 'Zotlabs\\Module\\Manage' => $baseDir . '/Zotlabs/Module/Manage.php',
- 'Zotlabs\\Module\\Menu' => $baseDir . '/Zotlabs/Module/Menu.php',
- 'Zotlabs\\Module\\Message' => $baseDir . '/Zotlabs/Module/Message.php',
- 'Zotlabs\\Module\\Mitem' => $baseDir . '/Zotlabs/Module/Mitem.php',
- 'Zotlabs\\Module\\Mood' => $baseDir . '/Zotlabs/Module/Mood.php',
- 'Zotlabs\\Module\\Network' => $baseDir . '/Zotlabs/Module/Network.php',
- 'Zotlabs\\Module\\New_channel' => $baseDir . '/Zotlabs/Module/New_channel.php',
- 'Zotlabs\\Module\\Nojs' => $baseDir . '/Zotlabs/Module/Nojs.php',
- 'Zotlabs\\Module\\Notes' => $baseDir . '/Zotlabs/Module/Notes.php',
- 'Zotlabs\\Module\\Notifications' => $baseDir . '/Zotlabs/Module/Notifications.php',
- 'Zotlabs\\Module\\Notify' => $baseDir . '/Zotlabs/Module/Notify.php',
- 'Zotlabs\\Module\\Oembed' => $baseDir . '/Zotlabs/Module/Oembed.php',
- 'Zotlabs\\Module\\Oep' => $baseDir . '/Zotlabs/Module/Oep.php',
- 'Zotlabs\\Module\\Oexchange' => $baseDir . '/Zotlabs/Module/Oexchange.php',
- 'Zotlabs\\Module\\Online' => $baseDir . '/Zotlabs/Module/Online.php',
- 'Zotlabs\\Module\\Page' => $baseDir . '/Zotlabs/Module/Page.php',
- 'Zotlabs\\Module\\Pconfig' => $baseDir . '/Zotlabs/Module/Pconfig.php',
- 'Zotlabs\\Module\\Pdledit' => $baseDir . '/Zotlabs/Module/Pdledit.php',
- 'Zotlabs\\Module\\Permcat' => $baseDir . '/Zotlabs/Module/Permcat.php',
- 'Zotlabs\\Module\\Photo' => $baseDir . '/Zotlabs/Module/Photo.php',
- 'Zotlabs\\Module\\Photos' => $baseDir . '/Zotlabs/Module/Photos.php',
- 'Zotlabs\\Module\\Ping' => $baseDir . '/Zotlabs/Module/Ping.php',
- 'Zotlabs\\Module\\Poco' => $baseDir . '/Zotlabs/Module/Poco.php',
- 'Zotlabs\\Module\\Poke' => $baseDir . '/Zotlabs/Module/Poke.php',
- 'Zotlabs\\Module\\Post' => $baseDir . '/Zotlabs/Module/Post.php',
- 'Zotlabs\\Module\\Prate' => $baseDir . '/Zotlabs/Module/Prate.php',
- 'Zotlabs\\Module\\Pretheme' => $baseDir . '/Zotlabs/Module/Pretheme.php',
- 'Zotlabs\\Module\\Probe' => $baseDir . '/Zotlabs/Module/Probe.php',
- 'Zotlabs\\Module\\Profile' => $baseDir . '/Zotlabs/Module/Profile.php',
- 'Zotlabs\\Module\\Profile_photo' => $baseDir . '/Zotlabs/Module/Profile_photo.php',
- 'Zotlabs\\Module\\Profiles' => $baseDir . '/Zotlabs/Module/Profiles.php',
- 'Zotlabs\\Module\\Profperm' => $baseDir . '/Zotlabs/Module/Profperm.php',
- 'Zotlabs\\Module\\Pubsites' => $baseDir . '/Zotlabs/Module/Pubsites.php',
- 'Zotlabs\\Module\\Pubstream' => $baseDir . '/Zotlabs/Module/Pubstream.php',
- 'Zotlabs\\Module\\Randprof' => $baseDir . '/Zotlabs/Module/Randprof.php',
- 'Zotlabs\\Module\\Rate' => $baseDir . '/Zotlabs/Module/Rate.php',
- 'Zotlabs\\Module\\Ratings' => $baseDir . '/Zotlabs/Module/Ratings.php',
- 'Zotlabs\\Module\\Ratingsearch' => $baseDir . '/Zotlabs/Module/Ratingsearch.php',
- 'Zotlabs\\Module\\Rbmark' => $baseDir . '/Zotlabs/Module/Rbmark.php',
- 'Zotlabs\\Module\\React' => $baseDir . '/Zotlabs/Module/React.php',
- 'Zotlabs\\Module\\Regdir' => $baseDir . '/Zotlabs/Module/Regdir.php',
- 'Zotlabs\\Module\\Register' => $baseDir . '/Zotlabs/Module/Register.php',
- 'Zotlabs\\Module\\Regmod' => $baseDir . '/Zotlabs/Module/Regmod.php',
- 'Zotlabs\\Module\\Regver' => $baseDir . '/Zotlabs/Module/Regver.php',
- 'Zotlabs\\Module\\Removeaccount' => $baseDir . '/Zotlabs/Module/Removeaccount.php',
- 'Zotlabs\\Module\\Removeme' => $baseDir . '/Zotlabs/Module/Removeme.php',
- 'Zotlabs\\Module\\Rmagic' => $baseDir . '/Zotlabs/Module/Rmagic.php',
- 'Zotlabs\\Module\\Rpost' => $baseDir . '/Zotlabs/Module/Rpost.php',
- 'Zotlabs\\Module\\Search' => $baseDir . '/Zotlabs/Module/Search.php',
- 'Zotlabs\\Module\\Search_ac' => $baseDir . '/Zotlabs/Module/Search_ac.php',
- 'Zotlabs\\Module\\Service_limits' => $baseDir . '/Zotlabs/Module/Service_limits.php',
- 'Zotlabs\\Module\\Settings' => $baseDir . '/Zotlabs/Module/Settings.php',
- 'Zotlabs\\Module\\Settings\\Account' => $baseDir . '/Zotlabs/Module/Settings/Account.php',
- 'Zotlabs\\Module\\Settings\\Channel' => $baseDir . '/Zotlabs/Module/Settings/Channel.php',
- 'Zotlabs\\Module\\Settings\\Display' => $baseDir . '/Zotlabs/Module/Settings/Display.php',
- 'Zotlabs\\Module\\Settings\\Featured' => $baseDir . '/Zotlabs/Module/Settings/Featured.php',
- 'Zotlabs\\Module\\Settings\\Features' => $baseDir . '/Zotlabs/Module/Settings/Features.php',
- 'Zotlabs\\Module\\Settings\\Oauth' => $baseDir . '/Zotlabs/Module/Settings/Oauth.php',
- 'Zotlabs\\Module\\Settings\\Permcats' => $baseDir . '/Zotlabs/Module/Settings/Permcats.php',
- 'Zotlabs\\Module\\Settings\\Tokens' => $baseDir . '/Zotlabs/Module/Settings/Tokens.php',
- 'Zotlabs\\Module\\Setup' => $baseDir . '/Zotlabs/Module/Setup.php',
- 'Zotlabs\\Module\\Share' => $baseDir . '/Zotlabs/Module/Share.php',
- 'Zotlabs\\Module\\Sharedwithme' => $baseDir . '/Zotlabs/Module/Sharedwithme.php',
- 'Zotlabs\\Module\\Siteinfo' => $baseDir . '/Zotlabs/Module/Siteinfo.php',
- 'Zotlabs\\Module\\Siteinfo_json' => $baseDir . '/Zotlabs/Module/Siteinfo_json.php',
- 'Zotlabs\\Module\\Sitelist' => $baseDir . '/Zotlabs/Module/Sitelist.php',
- 'Zotlabs\\Module\\Smilies' => $baseDir . '/Zotlabs/Module/Smilies.php',
- 'Zotlabs\\Module\\Snap' => $baseDir . '/Zotlabs/Module/Snap.php',
- 'Zotlabs\\Module\\Sources' => $baseDir . '/Zotlabs/Module/Sources.php',
- 'Zotlabs\\Module\\Sslify' => $baseDir . '/Zotlabs/Module/Sslify.php',
- 'Zotlabs\\Module\\Starred' => $baseDir . '/Zotlabs/Module/Starred.php',
- 'Zotlabs\\Module\\Subthread' => $baseDir . '/Zotlabs/Module/Subthread.php',
- 'Zotlabs\\Module\\Suggest' => $baseDir . '/Zotlabs/Module/Suggest.php',
- 'Zotlabs\\Module\\Tagger' => $baseDir . '/Zotlabs/Module/Tagger.php',
- 'Zotlabs\\Module\\Tagrm' => $baseDir . '/Zotlabs/Module/Tagrm.php',
- 'Zotlabs\\Module\\Tasks' => $baseDir . '/Zotlabs/Module/Tasks.php',
- 'Zotlabs\\Module\\Theme_info' => $baseDir . '/Zotlabs/Module/Theme_info.php',
- 'Zotlabs\\Module\\Thing' => $baseDir . '/Zotlabs/Module/Thing.php',
- 'Zotlabs\\Module\\Toggle_mobile' => $baseDir . '/Zotlabs/Module/Toggle_mobile.php',
- 'Zotlabs\\Module\\Toggle_safesearch' => $baseDir . '/Zotlabs/Module/Toggle_safesearch.php',
- 'Zotlabs\\Module\\Uexport' => $baseDir . '/Zotlabs/Module/Uexport.php',
- 'Zotlabs\\Module\\Update_channel' => $baseDir . '/Zotlabs/Module/Update_channel.php',
- 'Zotlabs\\Module\\Update_display' => $baseDir . '/Zotlabs/Module/Update_display.php',
- 'Zotlabs\\Module\\Update_home' => $baseDir . '/Zotlabs/Module/Update_home.php',
- 'Zotlabs\\Module\\Update_network' => $baseDir . '/Zotlabs/Module/Update_network.php',
- 'Zotlabs\\Module\\Update_pubstream' => $baseDir . '/Zotlabs/Module/Update_pubstream.php',
- 'Zotlabs\\Module\\Update_search' => $baseDir . '/Zotlabs/Module/Update_search.php',
- 'Zotlabs\\Module\\View' => $baseDir . '/Zotlabs/Module/View.php',
- 'Zotlabs\\Module\\Viewconnections' => $baseDir . '/Zotlabs/Module/Viewconnections.php',
- 'Zotlabs\\Module\\Viewsrc' => $baseDir . '/Zotlabs/Module/Viewsrc.php',
- 'Zotlabs\\Module\\Wall_attach' => $baseDir . '/Zotlabs/Module/Wall_attach.php',
- 'Zotlabs\\Module\\Wall_upload' => $baseDir . '/Zotlabs/Module/Wall_upload.php',
- 'Zotlabs\\Module\\Webfinger' => $baseDir . '/Zotlabs/Module/Webfinger.php',
- 'Zotlabs\\Module\\Webpages' => $baseDir . '/Zotlabs/Module/Webpages.php',
- 'Zotlabs\\Module\\Well_known' => $baseDir . '/Zotlabs/Module/Well_known.php',
- 'Zotlabs\\Module\\Wfinger' => $baseDir . '/Zotlabs/Module/Wfinger.php',
- 'Zotlabs\\Module\\Wiki' => $baseDir . '/Zotlabs/Module/Wiki.php',
- 'Zotlabs\\Module\\Xchan' => $baseDir . '/Zotlabs/Module/Xchan.php',
- 'Zotlabs\\Module\\Xpoco' => $baseDir . '/Zotlabs/Module/Xpoco.php',
- 'Zotlabs\\Module\\Xrd' => $baseDir . '/Zotlabs/Module/Xrd.php',
- 'Zotlabs\\Module\\Xref' => $baseDir . '/Zotlabs/Module/Xref.php',
- 'Zotlabs\\Module\\Zfinger' => $baseDir . '/Zotlabs/Module/Zfinger.php',
- 'Zotlabs\\Module\\Zotfeed' => $baseDir . '/Zotlabs/Module/Zotfeed.php',
- 'Zotlabs\\Module\\Zping' => $baseDir . '/Zotlabs/Module/Zping.php',
- 'Zotlabs\\Render\\Comanche' => $baseDir . '/Zotlabs/Render/Comanche.php',
- 'Zotlabs\\Render\\SimpleTemplate' => $baseDir . '/Zotlabs/Render/SimpleTemplate.php',
- 'Zotlabs\\Render\\SmartyInterface' => $baseDir . '/Zotlabs/Render/SmartyInterface.php',
- 'Zotlabs\\Render\\SmartyTemplate' => $baseDir . '/Zotlabs/Render/SmartyTemplate.php',
- 'Zotlabs\\Render\\TemplateEngine' => $baseDir . '/Zotlabs/Render/TemplateEngine.php',
- 'Zotlabs\\Render\\Theme' => $baseDir . '/Zotlabs/Render/Theme.php',
- 'Zotlabs\\Storage\\BasicAuth' => $baseDir . '/Zotlabs/Storage/BasicAuth.php',
- 'Zotlabs\\Storage\\Browser' => $baseDir . '/Zotlabs/Storage/Browser.php',
- 'Zotlabs\\Storage\\CalDAVClient' => $baseDir . '/Zotlabs/Storage/CalDAVClient.php',
- 'Zotlabs\\Storage\\Directory' => $baseDir . '/Zotlabs/Storage/Directory.php',
- 'Zotlabs\\Storage\\File' => $baseDir . '/Zotlabs/Storage/File.php',
- 'Zotlabs\\Storage\\GitRepo' => $baseDir . '/Zotlabs/Storage/GitRepo.php',
- 'Zotlabs\\Text\\Tagadelic' => $baseDir . '/Zotlabs/Text/Tagadelic.php',
- 'Zotlabs\\Web\\CheckJS' => $baseDir . '/Zotlabs/Web/CheckJS.php',
- 'Zotlabs\\Web\\Controller' => $baseDir . '/Zotlabs/Web/Controller.php',
- 'Zotlabs\\Web\\HTTPHeaders' => $baseDir . '/Zotlabs/Web/HTTPHeaders.php',
- 'Zotlabs\\Web\\HttpMeta' => $baseDir . '/Zotlabs/Web/HttpMeta.php',
- 'Zotlabs\\Web\\Router' => $baseDir . '/Zotlabs/Web/Router.php',
- 'Zotlabs\\Web\\Session' => $baseDir . '/Zotlabs/Web/Session.php',
- 'Zotlabs\\Web\\SessionHandler' => $baseDir . '/Zotlabs/Web/SessionHandler.php',
- 'Zotlabs\\Web\\SubModule' => $baseDir . '/Zotlabs/Web/SubModule.php',
- 'Zotlabs\\Web\\WebServer' => $baseDir . '/Zotlabs/Web/WebServer.php',
- 'Zotlabs\\Zot\\Auth' => $baseDir . '/Zotlabs/Zot/Auth.php',
- 'Zotlabs\\Zot\\DReport' => $baseDir . '/Zotlabs/Zot/DReport.php',
- 'Zotlabs\\Zot\\Finger' => $baseDir . '/Zotlabs/Zot/Finger.php',
- 'Zotlabs\\Zot\\IHandler' => $baseDir . '/Zotlabs/Zot/IHandler.php',
- 'Zotlabs\\Zot\\Receiver' => $baseDir . '/Zotlabs/Zot/Receiver.php',
- 'Zotlabs\\Zot\\Verify' => $baseDir . '/Zotlabs/Zot/Verify.php',
- 'Zotlabs\\Zot\\ZotHandler' => $baseDir . '/Zotlabs/Zot/ZotHandler.php',
);
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index a03d306b4..1a0de2cb8 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1,36 +1,38 @@
[
{
- "name": "sabre/uri",
- "version": "1.1.0",
- "version_normalized": "1.1.0.0",
+ "name": "sabre/event",
+ "version": "3.0.0",
+ "version_normalized": "3.0.0.0",
"source": {
"type": "git",
- "url": "https://github.com/fruux/sabre-uri.git",
- "reference": "9012116434d84ef6e5e37a89dfdbfbe2204a8704"
+ "url": "https://github.com/fruux/sabre-event.git",
+ "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-uri/zipball/9012116434d84ef6e5e37a89dfdbfbe2204a8704",
- "reference": "9012116434d84ef6e5e37a89dfdbfbe2204a8704",
+ "url": "https://api.github.com/repos/fruux/sabre-event/zipball/831d586f5a442dceacdcf5e9c4c36a4db99a3534",
+ "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534",
"shasum": ""
},
"require": {
- "php": ">=5.4.7"
+ "php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "*",
- "sabre/cs": "~0.0.1"
+ "sabre/cs": "~0.0.4"
},
- "time": "2016-03-08 02:29:27",
+ "time": "2015-11-05 20:14:39",
"type": "library",
"installation-source": "dist",
"autoload": {
- "files": [
- "lib/functions.php"
- ],
"psr-4": {
- "Sabre\\Uri\\": "lib/"
- }
+ "Sabre\\Event\\": "lib/"
+ },
+ "files": [
+ "lib/coroutine.php",
+ "lib/Loop/functions.php",
+ "lib/Promise/functions.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -44,57 +46,56 @@
"role": "Developer"
}
],
- "description": "Functions for making sense out of URIs.",
- "homepage": "http://sabre.io/uri/",
+ "description": "sabre/event is a library for lightweight event-based programming",
+ "homepage": "http://sabre.io/event/",
"keywords": [
- "rfc3986",
- "uri",
- "url"
+ "EventEmitter",
+ "async",
+ "events",
+ "hooks",
+ "plugin",
+ "promise",
+ "signal"
]
},
{
- "name": "sabre/vobject",
- "version": "4.1.1",
- "version_normalized": "4.1.1.0",
+ "name": "sabre/xml",
+ "version": "1.5.0",
+ "version_normalized": "1.5.0.0",
"source": {
"type": "git",
- "url": "https://github.com/fruux/sabre-vobject.git",
- "reference": "a3a59b06947f122af2d45d52b72172cdc1efd68f"
+ "url": "https://github.com/fruux/sabre-xml.git",
+ "reference": "59b20e5bbace9912607481634f97d05a776ffca7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/a3a59b06947f122af2d45d52b72172cdc1efd68f",
- "reference": "a3a59b06947f122af2d45d52b72172cdc1efd68f",
+ "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/59b20e5bbace9912607481634f97d05a776ffca7",
+ "reference": "59b20e5bbace9912607481634f97d05a776ffca7",
"shasum": ""
},
"require": {
- "ext-mbstring": "*",
- "php": ">=5.5",
- "sabre/xml": "~1.1"
+ "ext-dom": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "lib-libxml": ">=2.6.20",
+ "php": ">=5.5.5",
+ "sabre/uri": ">=1.0,<3.0.0"
},
"require-dev": {
"phpunit/phpunit": "*",
- "sabre/cs": "~0.0.3"
- },
- "suggest": {
- "hoa/bench": "If you would like to run the benchmark scripts"
+ "sabre/cs": "~1.0.0"
},
- "time": "2016-07-15 19:52:17",
- "bin": [
- "bin/vobject",
- "bin/generate_vcards"
- ],
+ "time": "2016-10-09 22:57:52",
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.0.x-dev"
- }
- },
"installation-source": "dist",
"autoload": {
"psr-4": {
- "Sabre\\VObject\\": "lib/"
- }
+ "Sabre\\Xml\\": "lib/"
+ },
+ "files": [
+ "lib/Deserializer/functions.php",
+ "lib/Serializer/functions.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -108,145 +109,98 @@
"role": "Developer"
},
{
- "name": "Dominik Tobschall",
- "email": "dominik@fruux.com",
- "homepage": "http://tobschall.de/",
- "role": "Developer"
- },
- {
- "name": "Ivan Enderlin",
- "email": "ivan.enderlin@hoa-project.net",
- "homepage": "http://mnt.io/",
+ "name": "Markus Staab",
+ "email": "markus.staab@redaxo.de",
"role": "Developer"
}
],
- "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
- "homepage": "http://sabre.io/vobject/",
+ "description": "sabre/xml is an XML library that you may not hate.",
+ "homepage": "https://sabre.io/xml/",
"keywords": [
- "availability",
- "freebusy",
- "iCalendar",
- "ical",
- "ics",
- "jCal",
- "jCard",
- "recurrence",
- "rfc2425",
- "rfc2426",
- "rfc2739",
- "rfc4770",
- "rfc5545",
- "rfc5546",
- "rfc6321",
- "rfc6350",
- "rfc6351",
- "rfc6474",
- "rfc6638",
- "rfc6715",
- "rfc6868",
- "vCalendar",
- "vCard",
- "vcf",
- "xCal",
- "xCard"
+ "XMLReader",
+ "XMLWriter",
+ "dom",
+ "xml"
]
},
{
- "name": "sabre/event",
- "version": "3.0.0",
- "version_normalized": "3.0.0.0",
+ "name": "psr/log",
+ "version": "1.0.2",
+ "version_normalized": "1.0.2.0",
"source": {
"type": "git",
- "url": "https://github.com/fruux/sabre-event.git",
- "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534"
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-event/zipball/831d586f5a442dceacdcf5e9c4c36a4db99a3534",
- "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"shasum": ""
},
"require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "phpunit/phpunit": "*",
- "sabre/cs": "~0.0.4"
+ "php": ">=5.3.0"
},
- "time": "2015-11-05 20:14:39",
+ "time": "2016-10-10 12:19:37",
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
"installation-source": "dist",
"autoload": {
"psr-4": {
- "Sabre\\Event\\": "lib/"
- },
- "files": [
- "lib/coroutine.php",
- "lib/Loop/functions.php",
- "lib/Promise/functions.php"
- ]
+ "Psr\\Log\\": "Psr/Log/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Evert Pot",
- "email": "me@evertpot.com",
- "homepage": "http://evertpot.com/",
- "role": "Developer"
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
}
],
- "description": "sabre/event is a library for lightweight event-based programming",
- "homepage": "http://sabre.io/event/",
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
"keywords": [
- "EventEmitter",
- "async",
- "events",
- "hooks",
- "plugin",
- "promise",
- "signal"
+ "log",
+ "psr",
+ "psr-3"
]
},
{
- "name": "sabre/http",
- "version": "4.2.1",
- "version_normalized": "4.2.1.0",
+ "name": "michelf/php-markdown",
+ "version": "1.7.0",
+ "version_normalized": "1.7.0.0",
"source": {
"type": "git",
- "url": "https://github.com/fruux/sabre-http.git",
- "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e"
+ "url": "https://github.com/michelf/php-markdown.git",
+ "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-http/zipball/2e93bc8321524c67be4ca5b8415daebd4c8bf85e",
- "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e",
+ "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220",
+ "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220",
"shasum": ""
},
"require": {
- "ext-mbstring": "*",
- "php": ">=5.4",
- "sabre/event": ">=1.0.0,<4.0.0",
- "sabre/uri": "~1.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.3",
- "sabre/cs": "~0.0.1"
- },
- "suggest": {
- "ext-curl": " to make http requests with the Client class"
+ "php": ">=5.3.0"
},
- "time": "2016-01-06 23:00:08",
+ "time": "2016-10-29 18:58:20",
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-lib": "1.4.x-dev"
+ }
+ },
"installation-source": "dist",
"autoload": {
- "files": [
- "lib/functions.php"
- ],
- "psr-4": {
- "Sabre\\HTTP\\": "lib/"
+ "psr-0": {
+ "Michelf": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -255,246 +209,233 @@
],
"authors": [
{
- "name": "Evert Pot",
- "email": "me@evertpot.com",
- "homepage": "http://evertpot.com/",
+ "name": "Michel Fortin",
+ "email": "michel.fortin@michelf.ca",
+ "homepage": "https://michelf.ca/",
"role": "Developer"
+ },
+ {
+ "name": "John Gruber",
+ "homepage": "https://daringfireball.net/"
}
],
- "description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
- "homepage": "https://github.com/fruux/sabre-http",
+ "description": "PHP Markdown",
+ "homepage": "https://michelf.ca/projects/php-markdown/",
"keywords": [
- "http"
+ "markdown"
]
},
{
- "name": "sabre/dav",
- "version": "3.2.0",
- "version_normalized": "3.2.0.0",
+ "name": "pixel418/markdownify",
+ "version": "v2.2.1",
+ "version_normalized": "2.2.1.0",
"source": {
"type": "git",
- "url": "https://github.com/fruux/sabre-dav.git",
- "reference": "5b9737cc2f0182e368d14c80df7f6b2d77dc1457"
+ "url": "https://github.com/Elephant418/Markdownify.git",
+ "reference": "0160677f04c784550dd10fd72fdf3994967db848"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/5b9737cc2f0182e368d14c80df7f6b2d77dc1457",
- "reference": "5b9737cc2f0182e368d14c80df7f6b2d77dc1457",
+ "url": "https://api.github.com/repos/Elephant418/Markdownify/zipball/0160677f04c784550dd10fd72fdf3994967db848",
+ "reference": "0160677f04c784550dd10fd72fdf3994967db848",
"shasum": ""
},
"require": {
- "ext-ctype": "*",
- "ext-date": "*",
- "ext-dom": "*",
- "ext-iconv": "*",
- "ext-mbstring": "*",
- "ext-pcre": "*",
- "ext-simplexml": "*",
- "ext-spl": "*",
- "lib-libxml": ">=2.7.0",
- "php": ">=5.5.0",
- "psr/log": "^1.0",
- "sabre/event": ">=2.0.0, <4.0.0",
- "sabre/http": "^4.2.1",
- "sabre/uri": "^1.0.1",
- "sabre/vobject": "^4.1.0",
- "sabre/xml": "^1.4.0"
+ "php": ">=5.3.0"
},
"require-dev": {
- "evert/phpdoc-md": "~0.1.0",
- "monolog/monolog": "^1.18",
- "phpunit/phpunit": "> 4.8, <=6.0.0",
- "sabre/cs": "~0.0.5"
- },
- "suggest": {
- "ext-curl": "*",
- "ext-pdo": "*"
- },
- "time": "2016-06-28 02:44:05",
- "bin": [
- "bin/sabredav",
- "bin/naturalselection"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1.0-dev"
- }
+ "phpunit/phpunit": "^4.8"
},
+ "time": "2016-09-21 13:01:43",
+ "type": "lib",
"installation-source": "dist",
"autoload": {
"psr-4": {
- "Sabre\\DAV\\": "lib/DAV/",
- "Sabre\\DAVACL\\": "lib/DAVACL/",
- "Sabre\\CalDAV\\": "lib/CalDAV/",
- "Sabre\\CardDAV\\": "lib/CardDAV/"
+ "Markdownify\\": "src",
+ "Test\\Markdownify\\": "test"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "LGPL"
],
"authors": [
{
- "name": "Evert Pot",
- "email": "me@evertpot.com",
- "homepage": "http://evertpot.com/",
- "role": "Developer"
+ "name": "Peter Kruithof",
+ "email": "pkruithof@gmail.com",
+ "homepage": "http://pkruithof.tumblr.com/"
+ },
+ {
+ "name": "Milian Wolff",
+ "email": "mail@milianw.de",
+ "homepage": "http://milianw.de"
+ },
+ {
+ "name": "Thomas Zilliox",
+ "email": "hello@tzi.fr",
+ "homepage": "http://tzi.fr"
}
],
- "description": "WebDAV Framework for PHP",
- "homepage": "http://sabre.io/",
+ "description": "The HTML to Markdown converter for PHP ",
+ "homepage": "https://github.com/elephant418/Markdownify",
"keywords": [
- "CalDAV",
- "CardDAV",
- "WebDAV",
- "framework",
- "iCalendar"
+ "markdown",
+ "markdownify"
]
},
{
- "name": "sabre/xml",
- "version": "1.5.0",
- "version_normalized": "1.5.0.0",
+ "name": "bshaffer/oauth2-server-php",
+ "version": "v1.9.0",
+ "version_normalized": "1.9.0.0",
"source": {
"type": "git",
- "url": "https://github.com/fruux/sabre-xml.git",
- "reference": "59b20e5bbace9912607481634f97d05a776ffca7"
+ "url": "https://github.com/bshaffer/oauth2-server-php.git",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/59b20e5bbace9912607481634f97d05a776ffca7",
- "reference": "59b20e5bbace9912607481634f97d05a776ffca7",
+ "url": "https://api.github.com/repos/bshaffer/oauth2-server-php/zipball/8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697",
"shasum": ""
},
"require": {
- "ext-dom": "*",
- "ext-xmlreader": "*",
- "ext-xmlwriter": "*",
- "lib-libxml": ">=2.6.20",
- "php": ">=5.5.5",
- "sabre/uri": ">=1.0,<3.0.0"
+ "php": ">=5.3.9"
},
"require-dev": {
- "phpunit/phpunit": "*",
- "sabre/cs": "~1.0.0"
+ "aws/aws-sdk-php": "~2.8",
+ "firebase/php-jwt": "~2.2",
+ "mongodb/mongodb": "^1.1",
+ "predis/predis": "dev-master",
+ "thobbs/phpcassa": "dev-master"
},
- "time": "2016-10-09 22:57:52",
+ "suggest": {
+ "aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
+ "firebase/php-jwt": "~1.1 is required to use MondoDB storage",
+ "predis/predis": "Required to use Redis storage",
+ "thobbs/phpcassa": "Required to use Cassandra storage"
+ },
+ "time": "2017-01-06 23:20:00",
"type": "library",
"installation-source": "dist",
"autoload": {
- "psr-4": {
- "Sabre\\Xml\\": "lib/"
- },
- "files": [
- "lib/Deserializer/functions.php",
- "lib/Serializer/functions.php"
- ]
+ "psr-0": {
+ "OAuth2": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Evert Pot",
- "email": "me@evertpot.com",
- "homepage": "http://evertpot.com/",
- "role": "Developer"
- },
- {
- "name": "Markus Staab",
- "email": "markus.staab@redaxo.de",
- "role": "Developer"
+ "name": "Brent Shaffer",
+ "email": "bshafs@gmail.com",
+ "homepage": "http://brentertainment.com"
}
],
- "description": "sabre/xml is an XML library that you may not hate.",
- "homepage": "https://sabre.io/xml/",
+ "description": "OAuth2 Server for PHP",
+ "homepage": "http://github.com/bshaffer/oauth2-server-php",
"keywords": [
- "XMLReader",
- "XMLWriter",
- "dom",
- "xml"
+ "auth",
+ "oauth",
+ "oauth2"
]
},
{
- "name": "psr/log",
- "version": "1.0.2",
- "version_normalized": "1.0.2.0",
+ "name": "sabre/uri",
+ "version": "1.2.1",
+ "version_normalized": "1.2.1.0",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/log.git",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ "url": "https://github.com/fruux/sabre-uri.git",
+ "reference": "ada354d83579565949d80b2e15593c2371225e61"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "url": "https://api.github.com/repos/fruux/sabre-uri/zipball/ada354d83579565949d80b2e15593c2371225e61",
+ "reference": "ada354d83579565949d80b2e15593c2371225e61",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=5.4.7"
},
- "time": "2016-10-10 12:19:37",
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "require-dev": {
+ "phpunit/phpunit": ">=4.0,<6.0",
+ "sabre/cs": "~1.0.0"
},
+ "time": "2017-02-20 19:59:28",
+ "type": "library",
"installation-source": "dist",
"autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
"psr-4": {
- "Psr\\Log\\": "Psr/Log/"
+ "Sabre\\Uri\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
}
],
- "description": "Common interface for logging libraries",
- "homepage": "https://github.com/php-fig/log",
+ "description": "Functions for making sense out of URIs.",
+ "homepage": "http://sabre.io/uri/",
"keywords": [
- "log",
- "psr",
- "psr-3"
+ "rfc3986",
+ "uri",
+ "url"
]
},
{
- "name": "michelf/php-markdown",
- "version": "1.7.0",
- "version_normalized": "1.7.0.0",
+ "name": "sabre/vobject",
+ "version": "4.1.2",
+ "version_normalized": "4.1.2.0",
"source": {
"type": "git",
- "url": "https://github.com/michelf/php-markdown.git",
- "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220"
+ "url": "https://github.com/fruux/sabre-vobject.git",
+ "reference": "d0fde2fafa2a3dad1f559c2d1c2591d4fd75ae3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220",
- "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220",
+ "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/d0fde2fafa2a3dad1f559c2d1c2591d4fd75ae3c",
+ "reference": "d0fde2fafa2a3dad1f559c2d1c2591d4fd75ae3c",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "ext-mbstring": "*",
+ "php": ">=5.5",
+ "sabre/xml": ">=1.5 <3.0"
},
- "time": "2016-10-29 18:58:20",
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "sabre/cs": "^1.0.0"
+ },
+ "suggest": {
+ "hoa/bench": "If you would like to run the benchmark scripts"
+ },
+ "time": "2016-12-06 04:14:09",
+ "bin": [
+ "bin/vobject",
+ "bin/generate_vcards"
+ ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-lib": "1.4.x-dev"
+ "dev-master": "4.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
- "psr-0": {
- "Michelf": ""
+ "psr-4": {
+ "Sabre\\VObject\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -503,136 +444,196 @@
],
"authors": [
{
- "name": "Michel Fortin",
- "email": "michel.fortin@michelf.ca",
- "homepage": "https://michelf.ca/",
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
"role": "Developer"
},
{
- "name": "John Gruber",
- "homepage": "https://daringfireball.net/"
+ "name": "Dominik Tobschall",
+ "email": "dominik@fruux.com",
+ "homepage": "http://tobschall.de/",
+ "role": "Developer"
+ },
+ {
+ "name": "Ivan Enderlin",
+ "email": "ivan.enderlin@hoa-project.net",
+ "homepage": "http://mnt.io/",
+ "role": "Developer"
}
],
- "description": "PHP Markdown",
- "homepage": "https://michelf.ca/projects/php-markdown/",
+ "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
+ "homepage": "http://sabre.io/vobject/",
"keywords": [
- "markdown"
+ "availability",
+ "freebusy",
+ "iCalendar",
+ "ical",
+ "ics",
+ "jCal",
+ "jCard",
+ "recurrence",
+ "rfc2425",
+ "rfc2426",
+ "rfc2739",
+ "rfc4770",
+ "rfc5545",
+ "rfc5546",
+ "rfc6321",
+ "rfc6350",
+ "rfc6351",
+ "rfc6474",
+ "rfc6638",
+ "rfc6715",
+ "rfc6868",
+ "vCalendar",
+ "vCard",
+ "vcf",
+ "xCal",
+ "xCard"
]
},
{
- "name": "pixel418/markdownify",
- "version": "v2.2.1",
- "version_normalized": "2.2.1.0",
+ "name": "sabre/http",
+ "version": "4.2.2",
+ "version_normalized": "4.2.2.0",
"source": {
"type": "git",
- "url": "https://github.com/Elephant418/Markdownify.git",
- "reference": "0160677f04c784550dd10fd72fdf3994967db848"
+ "url": "https://github.com/fruux/sabre-http.git",
+ "reference": "dd50e7260356f4599d40270826f9548b23efa204"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Elephant418/Markdownify/zipball/0160677f04c784550dd10fd72fdf3994967db848",
- "reference": "0160677f04c784550dd10fd72fdf3994967db848",
+ "url": "https://api.github.com/repos/fruux/sabre-http/zipball/dd50e7260356f4599d40270826f9548b23efa204",
+ "reference": "dd50e7260356f4599d40270826f9548b23efa204",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "ext-ctype": "*",
+ "ext-mbstring": "*",
+ "php": ">=5.4",
+ "sabre/event": ">=1.0.0,<4.0.0",
+ "sabre/uri": "~1.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8"
+ "phpunit/phpunit": "~4.3",
+ "sabre/cs": "~0.0.1"
},
- "time": "2016-09-21 13:01:43",
- "type": "lib",
+ "suggest": {
+ "ext-curl": " to make http requests with the Client class"
+ },
+ "time": "2017-01-02 19:38:42",
+ "type": "library",
"installation-source": "dist",
"autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
"psr-4": {
- "Markdownify\\": "src",
- "Test\\Markdownify\\": "test"
+ "Sabre\\HTTP\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "LGPL"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Peter Kruithof",
- "email": "pkruithof@gmail.com",
- "homepage": "http://pkruithof.tumblr.com/"
- },
- {
- "name": "Milian Wolff",
- "email": "mail@milianw.de",
- "homepage": "http://milianw.de"
- },
- {
- "name": "Thomas Zilliox",
- "email": "hello@tzi.fr",
- "homepage": "http://tzi.fr"
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
}
],
- "description": "The HTML to Markdown converter for PHP ",
- "homepage": "https://github.com/elephant418/Markdownify",
+ "description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
+ "homepage": "https://github.com/fruux/sabre-http",
"keywords": [
- "markdown",
- "markdownify"
+ "http"
]
},
{
- "name": "bshaffer/oauth2-server-php",
- "version": "v1.9.0",
- "version_normalized": "1.9.0.0",
+ "name": "sabre/dav",
+ "version": "3.2.2",
+ "version_normalized": "3.2.2.0",
"source": {
"type": "git",
- "url": "https://github.com/bshaffer/oauth2-server-php.git",
- "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697"
+ "url": "https://github.com/fruux/sabre-dav.git",
+ "reference": "e987775e619728f12205606c9cc3ee565ffb1516"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bshaffer/oauth2-server-php/zipball/8856aed1a98d6da596ae3f9b8095b5c7a1581697",
- "reference": "8856aed1a98d6da596ae3f9b8095b5c7a1581697",
+ "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/e987775e619728f12205606c9cc3ee565ffb1516",
+ "reference": "e987775e619728f12205606c9cc3ee565ffb1516",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "ext-ctype": "*",
+ "ext-date": "*",
+ "ext-dom": "*",
+ "ext-iconv": "*",
+ "ext-mbstring": "*",
+ "ext-pcre": "*",
+ "ext-simplexml": "*",
+ "ext-spl": "*",
+ "lib-libxml": ">=2.7.0",
+ "php": ">=5.5.0",
+ "psr/log": "^1.0",
+ "sabre/event": ">=2.0.0, <4.0.0",
+ "sabre/http": "^4.2.1",
+ "sabre/uri": "^1.0.1",
+ "sabre/vobject": "^4.1.0",
+ "sabre/xml": "^1.4.0"
},
"require-dev": {
- "aws/aws-sdk-php": "~2.8",
- "firebase/php-jwt": "~2.2",
- "mongodb/mongodb": "^1.1",
- "predis/predis": "dev-master",
- "thobbs/phpcassa": "dev-master"
+ "evert/phpdoc-md": "~0.1.0",
+ "monolog/monolog": "^1.18",
+ "phpunit/phpunit": "> 4.8, <6.0.0",
+ "sabre/cs": "^1.0.0"
},
"suggest": {
- "aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
- "firebase/php-jwt": "~1.1 is required to use MondoDB storage",
- "predis/predis": "Required to use Redis storage",
- "thobbs/phpcassa": "Required to use Cassandra storage"
+ "ext-curl": "*",
+ "ext-pdo": "*"
},
- "time": "2017-01-06 23:20:00",
+ "time": "2017-02-15 03:06:08",
+ "bin": [
+ "bin/sabredav",
+ "bin/naturalselection"
+ ],
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.0-dev"
+ }
+ },
"installation-source": "dist",
"autoload": {
- "psr-0": {
- "OAuth2": "src/"
+ "psr-4": {
+ "Sabre\\DAV\\": "lib/DAV/",
+ "Sabre\\DAVACL\\": "lib/DAVACL/",
+ "Sabre\\CalDAV\\": "lib/CalDAV/",
+ "Sabre\\CardDAV\\": "lib/CardDAV/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Brent Shaffer",
- "email": "bshafs@gmail.com",
- "homepage": "http://brentertainment.com"
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
}
],
- "description": "OAuth2 Server for PHP",
- "homepage": "http://github.com/bshaffer/oauth2-server-php",
+ "description": "WebDAV Framework for PHP",
+ "homepage": "http://sabre.io/",
"keywords": [
- "auth",
- "oauth",
- "oauth2"
+ "CalDAV",
+ "CardDAV",
+ "WebDAV",
+ "framework",
+ "iCalendar"
]
}
]
diff --git a/vendor/sabre/dav/.travis.yml b/vendor/sabre/dav/.travis.yml
index a9189c981..85637048a 100644
--- a/vendor/sabre/dav/.travis.yml
+++ b/vendor/sabre/dav/.travis.yml
@@ -2,7 +2,9 @@ language: php
php:
- 5.5
- 5.6
- - 7
+ - 7.0
+ - 7.1
+
env:
matrix:
@@ -19,7 +21,6 @@ before_script:
- mysql -e 'create database sabredav_test'
- psql -c "create database sabredav_test" -U postgres
- psql -c "create user sabredav with PASSWORD 'sabredav';GRANT ALL PRIVILEGES ON DATABASE sabredav_test TO sabredav" -U postgres
- - phpenv config-rm xdebug.ini; true
# - composer self-update
- composer update --prefer-dist $LOWEST_DEPS
@@ -28,7 +29,7 @@ before_script:
script:
- ./bin/phpunit --configuration tests/phpunit.xml.dist $TEST_DEPS
- - ./bin/sabre-cs-fixer fix lib/ --dry-run --diff
+ - ./bin/sabre-cs-fixer fix . --dry-run --diff
cache:
directories:
diff --git a/vendor/sabre/dav/CHANGELOG.md b/vendor/sabre/dav/CHANGELOG.md
index d8a3898c3..0bccc995c 100644
--- a/vendor/sabre/dav/CHANGELOG.md
+++ b/vendor/sabre/dav/CHANGELOG.md
@@ -1,6 +1,28 @@
ChangeLog
=========
+3.2.2 (2017-02-14)
+------------------
+
+* #943: Fix CardDAV XML reporting bug, which was affecting several CardDAV
+ clients. Bug was introduced in 3.2.1.
+* The zip release ships with [sabre/vobject 4.1.2][vobj],
+ [sabre/http 4.2.2][http], [sabre/event 3.0.0][evnt],
+ [sabre/uri 1.2.0][uri] and [sabre/xml 1.5.0][xml].
+
+
+3.2.1 (2017-01-28)
+------------------
+
+* #877: Fix for syncing large calendars when using the Sqlite PDO backend.
+ (@theseer).
+* #889 Added support for filtering vCard properties in the addressbook-query
+ REPORT (@DeepDiver1975).
+* The zip release ships with [sabre/vobject 4.1.2][vobj],
+ [sabre/http 4.2.2][http], [sabre/event 3.0.0][evnt],
+ [sabre/uri 1.2.0][uri] and [sabre/xml 1.5.0][xml].
+
+
3.2.0 (2016-06-27)
------------------
@@ -88,6 +110,9 @@ ChangeLog
------------------
* Fixed: Creating a new calendar on some MySQL configurations caused an error.
+* #889 Added support for filtering vCard properties in the addressbook-query
+ REPORT (@DeepDiver1975).
+
3.1.4 (2016-05-28)
@@ -200,6 +225,13 @@ ChangeLog
[sabre/uri 1.0.1][uri] and [sabre/xml 1.1.0][xml].
+3.0.10 (2016-??-??)
+------------------
+
+* #889 Added support for filtering vCard properties in the addressbook-query
+ REPORT (@DeepDiver1975).
+
+
3.0.9 (2016-04-06)
------------------
@@ -463,11 +495,13 @@ ChangeLog
* #193: Fix `Sabre\DAV\FSExt\Directory::getQuotaInfo()` on windows.
-2.1.11 (2016-??-??)
+2.1.11 (2016-10-06)
-------------------
* #805: It wasn't possible to create calendars that hold events, journals and
todos using MySQL, because the `components` column was 1 byte too small.
+* The zip release ships with [sabre/vobject 3.5.3][vobj],
+ [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt].
2.1.10 (2016-03-10)
@@ -475,6 +509,8 @@ ChangeLog
* #784: Sync logs for address books were not correctly cleaned up after
deleting them.
+* The zip release ships with [sabre/vobject 3.5.0][vobj],
+ [sabre/http 3.0.5][http], and [sabre/event 2.0.2][evnt].
2.1.9 (2016-01-25)
@@ -627,7 +663,7 @@ ChangeLog
* Added: Automatically converting between vCard 3, 4 and jCard using the
`Accept:` header, in CardDAV reports, and automatically converting from
jCard to vCard upon `PUT`. It's important to note that your backends _may_
- now recieve both vCard 3.0 and 4.0.
+ now receive both vCard 3.0 and 4.0.
* Added: #444. Collections can now opt-in to support high-speed `MOVE`.
* Changed: PropertyStorage backends now have a `move` method.
* Added: `beforeMove`, and `afterMove` events.
@@ -812,7 +848,7 @@ ChangeLog
* Added: Support for the `{DAV:}supported-method-set` property server-wide.
* Making it easier for implementors to override how the CardDAV addressbook
home is located.
-* Fixed: Issue #422 Preconditions were not being set on PUT on non-existant
+* Fixed: Issue #422 Preconditions were not being set on PUT on non-existent
files. Not really a chance for data-loss, but incorrect nevertheless.
* Fixed: Issue #428: Etag check with `If:` fails if the target is a collection.
* Fixed: Issues #430, #431, #433: Locks plugin didn't not properly release
@@ -1024,7 +1060,7 @@ ChangeLog
* Added: Sharee's can now also read out the list of invites for a shared
calendar.
* Added: The Proxy principal classes now both implement an interface, for
- greater flexiblity.
+ greater flexibility.
1.7.13 (2014-07-28)
@@ -1042,7 +1078,7 @@ ChangeLog
Sabre_DAV_PartialUpdate_IFile interface is now deprecated and will be removed
in a future version.
* Fixed: Restoring old setting after changing libxml_disable_entity_loader.
-* Fixed: Issue #422: Preconditions were not being set on PUT on non-existant
+* Fixed: Issue #422: Preconditions were not being set on PUT on non-existent
files. Not really a chance for data-loss, but incorrect nevertheless.
* Fixed: Issue #427: Now checking preconditions on DELETE requests.
* Fixed: Issue #428: Etag check with If: fails if the target is a collection.
@@ -1121,7 +1157,7 @@ ChangeLog
------------------
* The zip release ships with sabre/vobject 2.0.5.
-* Changed: To be compatibile with MS Office 2011 for Mac, a workaround was
+* Changed: To be compatible with MS Office 2011 for Mac, a workaround was
removed that was added to support old versions of Windows XP (pre-SP3).
Indeed! We needed a crazy workaround to work with one MS product in the past,
and we can't keep that workaround to be compatible with another MS product.
@@ -1129,7 +1165,7 @@ ChangeLog
* Fixed: Range requests now work for non-seekable streams. (Thanks Alfred
Klomp).
* Fixed: Changed serialization of {DAV:}getlastmodified and {DAV:}supportedlock
- to improve compatiblity with MS Office 2011 for Mac.
+ to improve compatibility with MS Office 2011 for Mac.
* Changed: reverted the automatic translation of 'DAV:' xml namespaces to
'urn:DAV' when parsing files. Issues were reported with libxml 2.6.32, on a
relatively recent debian release, so we'll wait till 2015 to take this one out
@@ -2006,7 +2042,7 @@ ChangeLog
-------------------
* Fixed: Issue 34: Invalid Lock-Token header response.
-* Added: Issue 35: Addign SabreDAV version to HTTP OPTIONS responses.
+* Added: Issue 35: Adding SabreDAV version to HTTP OPTIONS responses.
1.0.9 (2010-03-19)
@@ -2220,7 +2256,7 @@ ChangeLog
* Added: Simple HTML directory plugin, for browser access.
* Added: Server class now sends back standard pre-condition error xml bodies.
This was new since RFC4918.
-* Added: Sabre_DAV_Tree_Aggregrate, which can 'host' multiple Tree objects into
+* Added: Sabre_DAV_Tree_Aggregate, which can 'host' multiple Tree objects into
one.
* Added: simple basis for HTTP REPORT method. This method is not used yet, but
can be used by plugins to add reports.
@@ -2237,7 +2273,7 @@ ChangeLog
8.2.
* Fixed: TemporaryFileFilter now lets through GET's if they actually exist on
the backend. (r274)
-* FIxed: Some methods didn't get passed through in the FilterTree (r283).
+* Fixed: Some methods didn't get passed through in the FilterTree (r283).
* Fixed: LockManager is now slightly more complex, Tree classes slightly less.
(r287)
diff --git a/vendor/sabre/dav/README.md b/vendor/sabre/dav/README.md
index 8edcd4073..86a0fe9a6 100644
--- a/vendor/sabre/dav/README.md
+++ b/vendor/sabre/dav/README.md
@@ -10,6 +10,7 @@ Full documentation can be found on the website:
http://sabre.io/
+
Build status
------------
@@ -30,6 +31,7 @@ Documentation
* [Introduction](http://sabre.io/dav/).
* [Installation](http://sabre.io/dav/install/).
+
Made at fruux
-------------
diff --git a/vendor/sabre/dav/bin/build.php b/vendor/sabre/dav/bin/build.php
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/bin/googlecode_upload.py b/vendor/sabre/dav/bin/googlecode_upload.py
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/bin/migrateto20.php b/vendor/sabre/dav/bin/migrateto20.php
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/bin/migrateto21.php b/vendor/sabre/dav/bin/migrateto21.php
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/bin/migrateto30.php b/vendor/sabre/dav/bin/migrateto30.php
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/bin/migrateto32.php b/vendor/sabre/dav/bin/migrateto32.php
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/bin/sabredav.php b/vendor/sabre/dav/bin/sabredav.php
old mode 100644
new mode 100755
diff --git a/vendor/sabre/dav/composer.json b/vendor/sabre/dav/composer.json
index f85d9655e..fca0e07fb 100644
--- a/vendor/sabre/dav/composer.json
+++ b/vendor/sabre/dav/composer.json
@@ -32,9 +32,9 @@
"psr/log": "^1.0"
},
"require-dev" : {
- "phpunit/phpunit" : "> 4.8, <=6.0.0",
+ "phpunit/phpunit" : "> 4.8, <6.0.0",
"evert/phpdoc-md" : "~0.1.0",
- "sabre/cs" : "~0.0.5",
+ "sabre/cs" : "^1.0.0",
"monolog/monolog": "^1.18"
},
"suggest" : {
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php b/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php
index d58b4a46e..311b1c415 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Backend;
-use Sabre\VObject;
use Sabre\CalDAV;
+use Sabre\VObject;
/**
* Abstract Calendaring backend. Extend this class to create your own backends.
@@ -26,9 +26,9 @@ abstract class AbstractBackend implements BackendInterface {
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
- * @param string $path
+ * @param mixed $calendarId
* @param \Sabre\DAV\PropPatch $propPatch
* @return void
*/
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php b/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
index 9c00a89ef..bf2ef27a0 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
@@ -49,8 +49,8 @@ interface NotificationSupport extends BackendInterface {
* If the user chose to accept the share, this method should return the
* newly created calendar url.
*
- * @param string href The sharee who is replying (often a mailto: address)
- * @param int status One of the SharingPlugin::STATUS_* constants
+ * @param string $href The sharee who is replying (often a mailto: address)
+ * @param int $status One of the SharingPlugin::STATUS_* constants
* @param string $calendarUri The url to the calendar thats being shared
* @param string $inReplyTo The unique id this message is a response to
* @param string $summary A description of the reply
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
index 95f1d49a6..458440588 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
@@ -5,8 +5,8 @@ namespace Sabre\CalDAV\Backend;
use Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\Exception\Forbidden;
-use Sabre\VObject;
use Sabre\DAV\Xml\Element\Sharee;
+use Sabre\VObject;
/**
* PDO CalDAV backend
@@ -296,7 +296,7 @@ SQL
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param mixed $calendarId
* @param \Sabre\DAV\PropPatch $propPatch
@@ -481,13 +481,13 @@ SQL
if (!$row) return null;
return [
- 'id' => $row['id'],
- 'uri' => $row['uri'],
- 'lastmodified' => (int)$row['lastmodified'],
- 'etag' => '"' . $row['etag'] . '"',
- 'size' => (int)$row['size'],
- 'calendardata' => $row['calendardata'],
- 'component' => strtolower($row['componenttype']),
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'lastmodified' => (int)$row['lastmodified'],
+ 'etag' => '"' . $row['etag'] . '"',
+ 'size' => (int)$row['size'],
+ 'calendardata' => $row['calendardata'],
+ 'component' => strtolower($row['componenttype']),
];
}
@@ -511,27 +511,29 @@ SQL
}
list($calendarId, $instanceId) = $calendarId;
- $query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri IN (';
- // Inserting a whole bunch of question marks
- $query .= implode(',', array_fill(0, count($uris), '?'));
- $query .= ')';
+ $result = [];
+ foreach (array_chunk($uris, 900) as $chunk) {
+ $query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri IN (';
+ // Inserting a whole bunch of question marks
+ $query .= implode(',', array_fill(0, count($chunk), '?'));
+ $query .= ')';
- $stmt = $this->pdo->prepare($query);
- $stmt->execute(array_merge([$calendarId], $uris));
+ $stmt = $this->pdo->prepare($query);
+ $stmt->execute(array_merge([$calendarId], $chunk));
- $result = [];
- while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- $result[] = [
- 'id' => $row['id'],
- 'uri' => $row['uri'],
- 'lastmodified' => (int)$row['lastmodified'],
- 'etag' => '"' . $row['etag'] . '"',
- 'size' => (int)$row['size'],
- 'calendardata' => $row['calendardata'],
- 'component' => strtolower($row['componenttype']),
- ];
+ $result[] = [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'lastmodified' => (int)$row['lastmodified'],
+ 'etag' => '"' . $row['etag'] . '"',
+ 'size' => (int)$row['size'],
+ 'calendardata' => $row['calendardata'],
+ 'component' => strtolower($row['componenttype']),
+ ];
+ }
}
return $result;
@@ -686,7 +688,7 @@ SQL
}
}
-
+
// Ensure Occurence values are positive
if ($firstOccurence < 0) $firstOccurence = 0;
if ($lastOccurence < 0) $lastOccurence = 0;
@@ -769,7 +771,7 @@ SQL
* Note that especially time-range-filters may be difficult to parse. A
* time-range filter specified on a VEVENT must for instance also handle
* recurrence rules correctly.
- * A good example of how to interprete all these filters can also simply
+ * A good example of how to interpret all these filters can also simply
* be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct
* as possible, so it gives you a good idea on what type of stuff you need
* to think of.
@@ -969,7 +971,7 @@ SQL;
// Current synctoken
$stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->calendarTableName . ' WHERE id = ?');
- $stmt->execute([ $calendarId ]);
+ $stmt->execute([$calendarId]);
$currentToken = $stmt->fetchColumn(0);
if (is_null($currentToken)) return null;
@@ -1181,7 +1183,7 @@ SQL;
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param mixed $subscriptionId
* @param \Sabre\DAV\PropPatch $propPatch
@@ -1327,7 +1329,7 @@ SQL;
function createSchedulingObject($principalUri, $objectUri, $objectData) {
$stmt = $this->pdo->prepare('INSERT INTO ' . $this->schedulingObjectTableName . ' (principaluri, calendardata, uri, lastmodified, etag, size) VALUES (?, ?, ?, ?, ?, ?)');
- $stmt->execute([$principalUri, $objectData, $objectUri, time(), md5($objectData), strlen($objectData) ]);
+ $stmt->execute([$principalUri, $objectData, $objectUri, time(), md5($objectData), strlen($objectData)]);
}
@@ -1483,7 +1485,7 @@ SQL;
'inviteStatus' => (int)$row['share_invitestatus'],
'properties' =>
!empty($row['share_displayname'])
- ? [ '{DAV:}displayname' => $row['share_displayname'] ]
+ ? ['{DAV:}displayname' => $row['share_displayname']]
: [],
'principal' => $row['principaluri'],
]);
@@ -1502,7 +1504,7 @@ SQL;
*/
function setPublishStatus($calendarId, $value) {
- throw new \Sabre\DAV\Exception\NotImplemented('Not implemented');
+ throw new DAV\Exception\NotImplemented('Not implemented');
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php b/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
index 8b6e074e0..278ec2564 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
@@ -11,9 +11,9 @@ namespace Sabre\CalDAV\Backend;
* 1. Return shared calendars for users.
* 2. For every calendar, return calendar-resource-uri. This strings is a URI or
* relative URI reference that must be unique for every calendar, but
- * identical for every instance of the same shared calenar.
- * 3. For every calenar, you must return a share-access element. This element
- * should contain one of the Sabre\DAV\Sharing\Plugin:ACCESS_* contants and
+ * identical for every instance of the same shared calendar.
+ * 3. For every calendar, you must return a share-access element. This element
+ * should contain one of the Sabre\DAV\Sharing\Plugin:ACCESS_* constants and
* indicates the access level the user has.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php b/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
index f8238ea9a..d21f7f916 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
@@ -8,7 +8,7 @@ use Sabre\DAV;
/**
* Simple PDO CalDAV backend.
*
- * This class is basically the most minmum example to get a caldav backend up
+ * This class is basically the most minimum example to get a caldav backend up
* and running. This class uses the following schema (MySQL example):
*
* CREATE TABLE simple_calendars (
@@ -209,12 +209,12 @@ class SimplePDO extends AbstractBackend {
if (!$row) return null;
return [
- 'id' => $row['id'],
- 'uri' => $row['uri'],
- 'etag' => '"' . md5($row['calendardata']) . '"',
- 'calendarid' => $calendarId,
- 'size' => strlen($row['calendardata']),
- 'calendardata' => $row['calendardata'],
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'etag' => '"' . md5($row['calendardata']) . '"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($row['calendardata']),
+ 'calendardata' => $row['calendardata'],
];
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php b/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php
index a39289f5e..d77a2fe0f 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php
@@ -70,7 +70,7 @@ interface SubscriptionSupport extends BackendInterface {
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param mixed $subscriptionId
* @param \Sabre\DAV\PropPatch $propPatch
diff --git a/vendor/sabre/dav/lib/CalDAV/Calendar.php b/vendor/sabre/dav/lib/CalDAV/Calendar.php
index 90ace0d21..7467900cc 100644
--- a/vendor/sabre/dav/lib/CalDAV/Calendar.php
+++ b/vendor/sabre/dav/lib/CalDAV/Calendar.php
@@ -3,8 +3,8 @@
namespace Sabre\CalDAV;
use Sabre\DAV;
-use Sabre\DAVACL;
use Sabre\DAV\PropPatch;
+use Sabre\DAVACL;
/**
* This object represents a CalDAV calendar.
diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarHome.php b/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
index 0a4bfb68f..ffd7f72fb 100644
--- a/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
+++ b/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
@@ -27,7 +27,7 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
/**
* CalDAV backend
*
- * @var Sabre\CalDAV\Backend\BackendInterface
+ * @var Backend\BackendInterface
*/
protected $caldavBackend;
@@ -42,7 +42,7 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
* Constructor
*
* @param Backend\BackendInterface $caldavBackend
- * @param mixed $userUri
+ * @param array $principalInfo
*/
function __construct(Backend\BackendInterface $caldavBackend, $principalInfo) {
@@ -334,8 +334,8 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
* This method should return the url of the newly created calendar if the
* share was accepted.
*
- * @param string href The sharee who is replying (often a mailto: address)
- * @param int status One of the SharingPlugin::STATUS_* constants
+ * @param string $href The sharee who is replying (often a mailto: address)
+ * @param int $status One of the SharingPlugin::STATUS_* constants
* @param string $calendarUri The url to the calendar thats being shared
* @param string $inReplyTo The unique id this message is a response to
* @param string $summary A description of the reply
diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarObject.php b/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
index 001b35112..9d6532a35 100644
--- a/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
+++ b/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
@@ -16,7 +16,7 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
/**
* Sabre\CalDAV\Backend\BackendInterface
*
- * @var Sabre\CalDAV\Backend\AbstractBackend
+ * @var Backend\AbstractBackend
*/
protected $caldavBackend;
diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php b/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php
index f3c7524d2..df8008fe2 100644
--- a/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php
+++ b/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV;
-use Sabre\VObject;
use DateTime;
+use Sabre\VObject;
/**
* CalendarQuery Validator
@@ -25,7 +25,7 @@ class CalendarQueryValidator {
*
* The list of filters must be formatted as parsed by \Sabre\CalDAV\CalendarQueryParser
*
- * @param VObject\Component $vObject
+ * @param VObject\Component\VCalendar $vObject
* @param array $filters
* @return bool
*/
diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php b/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php
index 0ac50e41d..1d6b2ac9f 100644
--- a/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php
+++ b/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php
@@ -22,7 +22,7 @@ class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection {
/**
* CalDAV backend
*
- * @var Sabre\CalDAV\Backend\BackendInterface
+ * @var Backend\BackendInterface
*/
protected $caldavBackend;
diff --git a/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php b/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php
index 5ce8a93f5..7aff2edab 100644
--- a/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php
+++ b/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Exception;
-use Sabre\DAV;
use Sabre\CalDAV;
+use Sabre\DAV;
/**
* InvalidComponentType
diff --git a/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php b/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
index a3a824c71..fc8b971f3 100644
--- a/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
@@ -2,13 +2,13 @@
namespace Sabre\CalDAV;
+use DateTime;
use DateTimeZone;
use Sabre\DAV;
-use Sabre\VObject;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
-use Sabre\DAV\Exception\BadRequest;
-use DateTime;
+use Sabre\VObject;
/**
* ICS Exporter
diff --git a/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php b/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
index 5fda61dfa..557832a5a 100644
--- a/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
+++ b/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Notifications;
-use Sabre\DAV;
use Sabre\CalDAV;
+use Sabre\DAV;
use Sabre\DAVACL;
/**
@@ -27,7 +27,7 @@ class Collection extends DAV\Collection implements ICollection, DAVACL\IACL {
/**
* The notification backend
*
- * @var Sabre\CalDAV\Backend\NotificationSupport
+ * @var CalDAV\Backend\NotificationSupport
*/
protected $caldavBackend;
diff --git a/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php b/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php
index f9986b714..783b92be9 100644
--- a/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php
+++ b/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php
@@ -2,6 +2,8 @@
namespace Sabre\CalDAV\Notifications;
+use Sabre\CalDAV\Xml\Notification\NotificationInterface;
+
/**
* This node represents a single notification.
*
@@ -20,16 +22,16 @@ interface INode {
/**
* This method must return an xml element, using the
- * Sabre\CalDAV\Notifications\INotificationType classes.
+ * Sabre\CalDAV\Xml\Notification\NotificationInterface classes.
*
- * @return INotificationType
+ * @return NotificationInterface
*/
function getNotificationType();
/**
* Returns the etag for the notification.
*
- * The etag must be surrounded by litteral double-quotes.
+ * The etag must be surrounded by literal double-quotes.
*
* @return string
*/
diff --git a/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php b/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
index 11df0c94b..ad7ddf8f5 100644
--- a/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
+++ b/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
@@ -2,9 +2,9 @@
namespace Sabre\CalDAV\Notifications;
-use Sabre\DAV;
use Sabre\CalDAV;
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
+use Sabre\DAV;
use Sabre\DAVACL;
/**
@@ -25,14 +25,14 @@ class Node extends DAV\File implements INode, DAVACL\IACL {
/**
* The notification backend
*
- * @var Sabre\CalDAV\Backend\NotificationSupport
+ * @var CalDAV\Backend\NotificationSupport
*/
protected $caldavBackend;
/**
* The actual notification
*
- * @var Sabre\CalDAV\Notifications\INotificationType
+ * @var NotificationInterface
*/
protected $notification;
@@ -61,7 +61,7 @@ class Node extends DAV\File implements INode, DAVACL\IACL {
/**
* Returns the path name for this notification
*
- * @return id
+ * @return string
*/
function getName() {
@@ -84,9 +84,9 @@ class Node extends DAV\File implements INode, DAVACL\IACL {
/**
* This method must return an xml element, using the
- * Sabre\CalDAV\Notifications\INotificationType classes.
+ * Sabre\CalDAV\Xml\Notification\NotificationInterface classes.
*
- * @return INotificationType
+ * @return NotificationInterface
*/
function getNotificationType() {
diff --git a/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php
index 546bf927f..e742351f5 100644
--- a/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php
@@ -3,10 +3,10 @@
namespace Sabre\CalDAV\Notifications;
use Sabre\DAV;
-use Sabre\DAV\PropFind;
use Sabre\DAV\INode as BaseINode;
-use Sabre\DAV\ServerPlugin;
+use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
use Sabre\DAVACL;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
diff --git a/vendor/sabre/dav/lib/CalDAV/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Plugin.php
index 71ba75206..def11d52d 100644
--- a/vendor/sabre/dav/lib/CalDAV/Plugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Plugin.php
@@ -9,11 +9,11 @@ use Sabre\DAV\INode;
use Sabre\DAV\MkCol;
use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\DAVACL;
-use Sabre\VObject;
use Sabre\HTTP;
-use Sabre\Uri;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
+use Sabre\Uri;
+use Sabre\VObject;
/**
* CalDAV plugin
@@ -302,8 +302,8 @@ class Plugin extends DAV\ServerPlugin {
$this->server->createCollection($path, new MkCol($resourceType, $properties));
- $this->server->httpResponse->setStatus(201);
- $this->server->httpResponse->setHeader('Content-Length', 0);
+ $response->setStatus(201);
+ $response->setHeader('Content-Length', 0);
// This breaks the method chain.
return false;
@@ -926,7 +926,7 @@ class Plugin extends DAV\ServerPlugin {
);
}
- // We use an extra variable to allow event handles to tell us wether
+ // We use an extra variable to allow event handles to tell us whether
// the object was modified or not.
//
// This helps us determine if we need to re-serialize the object.
diff --git a/vendor/sabre/dav/lib/CalDAV/Principal/ProxyRead.php b/vendor/sabre/dav/lib/CalDAV/Principal/ProxyRead.php
index 93f0fe095..e3881831e 100644
--- a/vendor/sabre/dav/lib/CalDAV/Principal/ProxyRead.php
+++ b/vendor/sabre/dav/lib/CalDAV/Principal/ProxyRead.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Principal;
-use Sabre\DAVACL;
use Sabre\DAV;
+use Sabre\DAVACL;
/**
* ProxyRead principal
@@ -84,8 +84,8 @@ class ProxyRead implements IProxyRead {
/**
* Renames the node
*
- * @throws DAV\Exception\Forbidden
* @param string $name The new name
+ * @throws DAV\Exception\Forbidden
* @return void
*/
function setName($name) {
diff --git a/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php b/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php
index 8124c05e0..43dd9bf07 100644
--- a/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php
+++ b/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Principal;
-use Sabre\DAVACL;
use Sabre\DAV;
+use Sabre\DAVACL;
/**
* ProxyWrite principal
@@ -84,8 +84,8 @@ class ProxyWrite implements IProxyWrite {
/**
* Renames the node
*
- * @throws DAV\Exception\Forbidden
* @param string $name The new name
+ * @throws DAV\Exception\Forbidden
* @return void
*/
function setName($name) {
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php b/vendor/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php
index ffb1fe45b..6f5acb29a 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php
@@ -181,7 +181,7 @@ class IMipPlugin extends DAV\ServerPlugin {
return [
'name' => $this->getPluginName(),
- 'description' => 'Email delivery (rfc6037) for CalDAV scheduling',
+ 'description' => 'Email delivery (rfc6047) for CalDAV scheduling',
'link' => 'http://sabre.io/dav/scheduling/',
];
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php
index 6b374ea3f..81b017307 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php
@@ -2,10 +2,10 @@
namespace Sabre\CalDAV\Schedule;
-use Sabre\DAV;
use Sabre\CalDAV;
-use Sabre\DAVACL;
use Sabre\CalDAV\Backend;
+use Sabre\DAV;
+use Sabre\DAVACL;
use Sabre\VObject;
/**
@@ -83,7 +83,7 @@ class Inbox extends DAV\Collection implements IInbox {
* Data will either be supplied as a stream resource, or in certain cases
* as a string. Keep in mind that you may have to support either.
*
- * After succesful creation of the file, you may choose to return the ETag
+ * After successful creation of the file, you may choose to return the ETag
* of the new file here.
*
* The returned ETag must be surrounded by double-quotes (The quotes should
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php
index 29eefa744..888ea3086 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Schedule;
-use Sabre\DAV;
use Sabre\CalDAV;
+use Sabre\DAV;
use Sabre\DAVACL;
/**
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php
index 47511140f..0b991e619 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php
@@ -3,29 +3,28 @@
namespace Sabre\CalDAV\Schedule;
use DateTimeZone;
+use Sabre\CalDAV\ICalendar;
+use Sabre\CalDAV\ICalendarObject;
+use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\Exception\NotImplemented;
+use Sabre\DAV\INode;
+use Sabre\DAV\PropFind;
+use Sabre\DAV\PropPatch;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
use Sabre\DAV\Sharing;
-use Sabre\DAV\PropFind;
-use Sabre\DAV\PropPatch;
-use Sabre\DAV\INode;
-use Sabre\DAV\Xml\Property\Href;
use Sabre\DAV\Xml\Property\LocalHref;
+use Sabre\DAVACL;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Sabre\VObject;
-use Sabre\VObject\Reader;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\ITip;
use Sabre\VObject\ITip\Message;
-use Sabre\DAVACL;
-use Sabre\CalDAV\ICalendar;
-use Sabre\CalDAV\ICalendarObject;
-use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
-use Sabre\DAV\Exception\NotFound;
-use Sabre\DAV\Exception\Forbidden;
-use Sabre\DAV\Exception\BadRequest;
-use Sabre\DAV\Exception\NotImplemented;
+use Sabre\VObject\Reader;
/**
* CalDAV scheduling plugin.
@@ -377,7 +376,7 @@ class Plugin extends ServerPlugin {
/**
* This method is responsible for delivering the ITip message.
*
- * @param ITip\Message $itipMessage
+ * @param ITip\Message $iTipMessage
* @return void
*/
function deliver(ITip\Message $iTipMessage) {
@@ -890,8 +889,8 @@ class Plugin extends ServerPlugin {
* * 3.7;description
*
* @param string $email address
- * @param DateTimeInterface $start
- * @param DateTimeInterface $end
+ * @param \DateTimeInterface $start
+ * @param \DateTimeInterface $end
* @param VObject\Component $request
* @return array
*/
@@ -1059,7 +1058,7 @@ class Plugin extends ServerPlugin {
return [
'name' => $this->getPluginName(),
- 'description' => 'Adds calendar-auto-schedule, as defined in rf6868',
+ 'description' => 'Adds calendar-auto-schedule, as defined in rfc6638',
'link' => 'http://sabre.io/dav/scheduling/',
];
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php b/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php
index 6d9d3d5ec..0cd05a965 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php
@@ -42,7 +42,7 @@ class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements IScheduli
* * lastmodified - (optional) format as a unix timestamp.
* * acl - (optional) Use this to override the default ACL for the node.
*
- * @param Backend\BackendInterface $caldavBackend
+ * @param Backend\SchedulingSupport $caldavBackend
* @param array $objectData
*/
function __construct(Backend\SchedulingSupport $caldavBackend, array $objectData) {
diff --git a/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php b/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php
index 6f7df02bc..5cce79678 100644
--- a/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php
@@ -3,7 +3,6 @@
namespace Sabre\CalDAV;
use Sabre\DAV;
-use Sabre\DAV\Xml\Property\Href;
use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -29,7 +28,7 @@ class SharingPlugin extends DAV\ServerPlugin {
/**
* Reference to SabreDAV server object.
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
diff --git a/vendor/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php
index 7abbfb1f9..877d96c6c 100644
--- a/vendor/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php
@@ -4,8 +4,8 @@ namespace Sabre\CalDAV\Subscriptions;
use Sabre\DAV\INode;
use Sabre\DAV\PropFind;
-use Sabre\DAV\ServerPlugin;
use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
/**
* This plugin adds calendar-subscription support to your CalDAV server.
diff --git a/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php b/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php
index 3bb3451f3..6a1851ed8 100644
--- a/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php
+++ b/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php
@@ -2,12 +2,12 @@
namespace Sabre\CalDAV\Subscriptions;
+use Sabre\CalDAV\Backend\SubscriptionSupport;
use Sabre\DAV\Collection;
-use Sabre\DAV\Xml\Property\Href;
use Sabre\DAV\PropPatch;
-use Sabre\DAVACL\IACL;
+use Sabre\DAV\Xml\Property\Href;
use Sabre\DAVACL\ACLTrait;
-use Sabre\CalDAV\Backend\SubscriptionSupport;
+use Sabre\DAVACL\IACL;
/**
* Subscription Node
@@ -25,7 +25,7 @@ class Subscription extends Collection implements ISubscription, IACL {
/**
* caldavBackend
*
- * @var SupportsSubscriptions
+ * @var SubscriptionSupport
*/
protected $caldavBackend;
@@ -40,7 +40,7 @@ class Subscription extends Collection implements ISubscription, IACL {
* Constructor
*
* @param SubscriptionSupport $caldavBackend
- * @param array $calendarInfo
+ * @param array $subscriptionInfo
*/
function __construct(SubscriptionSupport $caldavBackend, array $subscriptionInfo) {
@@ -104,7 +104,7 @@ class Subscription extends Collection implements ISubscription, IACL {
/**
* Returns an array with all the child nodes
*
- * @return DAV\INode[]
+ * @return \Sabre\DAV\INode[]
*/
function getChildren() {
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php
index 9babcf15c..9669be304 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php
@@ -2,11 +2,11 @@
namespace Sabre\CalDAV\Xml\Filter;
-use Sabre\Xml\Reader;
-use Sabre\Xml\XmlDeserializable;
-use Sabre\DAV\Exception\BadRequest;
use Sabre\CalDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\VObject\DateTimeParser;
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
/**
* CalendarData parser.
@@ -30,7 +30,7 @@ class CalendarData implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php
index c9b27dbfd..c21ede66b 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php
@@ -2,11 +2,11 @@
namespace Sabre\CalDAV\Xml\Filter;
-use Sabre\Xml\Reader;
-use Sabre\Xml\XmlDeserializable;
-use Sabre\DAV\Exception\BadRequest;
use Sabre\CalDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\VObject\DateTimeParser;
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
/**
* CompFilter parser.
@@ -27,7 +27,7 @@ class CompFilter implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php
index eb7f564df..bf422cf05 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php
@@ -2,9 +2,9 @@
namespace Sabre\CalDAV\Xml\Filter;
+use Sabre\CalDAV\Plugin;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\CalDAV\Plugin;
/**
* PropFilter parser.
@@ -25,7 +25,7 @@ class ParamFilter implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php
index 4c2e1b172..db9207295 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php
@@ -2,11 +2,11 @@
namespace Sabre\CalDAV\Xml\Filter;
-use Sabre\Xml\Reader;
-use Sabre\Xml\XmlDeserializable;
-use Sabre\DAV\Exception\BadRequest;
use Sabre\CalDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\VObject\DateTimeParser;
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
/**
* PropFilter parser.
@@ -27,7 +27,7 @@ class PropFilter implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php
index 1ca64f3e8..92a9ac7b7 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php
@@ -2,10 +2,10 @@
namespace Sabre\CalDAV\Xml\Notification;
-use Sabre\Xml\Writer;
-use Sabre\CalDAV\SharingPlugin as SharingPlugin;
use Sabre\CalDAV;
+use Sabre\CalDAV\SharingPlugin as SharingPlugin;
use Sabre\DAV;
+use Sabre\Xml\Writer;
/**
* This class represents the cs:invite-notification notification element.
@@ -107,7 +107,7 @@ class Invite implements NotificationInterface {
/**
* The list of supported components
*
- * @var Sabre\CalDAV\Property\SupportedCalendarComponentSet
+ * @var CalDAV\Xml\Property\SupportedCalendarComponentSet
*/
protected $supportedComponents;
@@ -166,12 +166,12 @@ class Invite implements NotificationInterface {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php
index 51bfc178a..f4b10a396 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php
@@ -2,10 +2,10 @@
namespace Sabre\CalDAV\Xml\Notification;
-use Sabre\Xml\Writer;
use Sabre\CalDAV;
use Sabre\CalDAV\SharingPlugin;
use Sabre\DAV;
+use Sabre\Xml\Writer;
/**
* This class represents the cs:invite-reply notification element.
@@ -117,12 +117,12 @@ class InviteReply implements NotificationInterface {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php
index 1c08f12fd..b98f9c888 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Xml\Notification;
-use Sabre\Xml\XmlSerializable;
use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* This interface reflects a single notification type.
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php
index d41702e07..8c945dd68 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php
@@ -2,8 +2,8 @@
namespace Sabre\CalDAV\Xml\Notification;
-use Sabre\Xml\Writer;
use Sabre\CalDAV\Plugin;
+use Sabre\Xml\Writer;
/**
* SystemStatus notification
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php
index c2a2d565e..54e5a116a 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php
@@ -2,9 +2,9 @@
namespace Sabre\CalDAV\Xml\Property;
-use Sabre\Xml\XmlSerializable;
-use Sabre\Xml\Writer;
use Sabre\CalDAV\Plugin;
+use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* AllowedSharingModes
@@ -53,12 +53,12 @@ class AllowedSharingModes implements XmlSerializable {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php
index f577a9919..fc6f1d505 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php
@@ -49,12 +49,12 @@ class EmailAddressSet implements XmlSerializable {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php
index 40ff6b936..4f33c464c 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php
@@ -2,10 +2,11 @@
namespace Sabre\CalDAV\Xml\Property;
-use Sabre\Xml\XmlSerializable;
-use Sabre\Xml\Writer;
use Sabre\CalDAV\Plugin;
use Sabre\DAV;
+use Sabre\DAV\Xml\Element\Sharee;
+use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* Invite property
@@ -51,12 +52,12 @@ class Invite implements XmlSerializable {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -75,7 +76,7 @@ class Invite implements XmlSerializable {
foreach ($this->sharees as $sharee) {
- if ($sharee->access === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) {
+ if ($sharee->access === DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) {
$writer->startElement($cs . 'organizer');
} else {
$writer->startElement($cs . 'user');
@@ -109,7 +110,7 @@ class Invite implements XmlSerializable {
}
- $href = new \Sabre\DAV\Xml\Property\Href($sharee->href);
+ $href = new DAV\Xml\Property\Href($sharee->href);
$href->xmlSerialize($writer);
if (isset($sharee->properties['{DAV:}displayname'])) {
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php
index a82b8eff7..10c20be55 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php
@@ -2,11 +2,11 @@
namespace Sabre\CalDAV\Xml\Property;
+use Sabre\CalDAV\Plugin;
+use Sabre\Xml\Deserializer;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
-use Sabre\Xml\Deserializer;
use Sabre\Xml\Writer;
-use Sabre\CalDAV\Plugin;
/**
* schedule-calendar-transp property.
@@ -62,12 +62,12 @@ class ScheduleCalendarTransp implements Element {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -96,7 +96,7 @@ class ScheduleCalendarTransp implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php
index 7a26e767e..7fc25c5f0 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php
@@ -2,11 +2,11 @@
namespace Sabre\CalDAV\Xml\Property;
+use Sabre\CalDAV\Plugin;
use Sabre\Xml\Element;
use Sabre\Xml\ParseException;
use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
-use Sabre\CalDAV\Plugin;
/**
* SupportedCalendarComponentSet property.
@@ -55,12 +55,12 @@ class SupportedCalendarComponentSet implements Element {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -88,7 +88,7 @@ class SupportedCalendarComponentSet implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php
index b0c407fd6..d123ba4c0 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php
@@ -2,9 +2,9 @@
namespace Sabre\CalDAV\Xml\Property;
-use Sabre\Xml\XmlSerializable;
-use Sabre\Xml\Writer;
use Sabre\CalDAV\Plugin;
+use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* Supported-calendar-data property
@@ -23,12 +23,12 @@ use Sabre\CalDAV\Plugin;
class SupportedCalendarData implements XmlSerializable {
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php
index 71de25a62..af10860d0 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php
@@ -2,9 +2,9 @@
namespace Sabre\CalDAV\Xml\Property;
+use Sabre\CalDAV\Plugin;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
-use Sabre\CalDAV\Plugin;
/**
* supported-collation-set property
@@ -22,12 +22,12 @@ use Sabre\CalDAV\Plugin;
class SupportedCollationSet implements XmlSerializable {
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php
index 79b3bb3ac..6d3c5d508 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php
@@ -2,10 +2,10 @@
namespace Sabre\CalDAV\Xml\Request;
-use Sabre\Xml\XmlDeserializable;
-use Sabre\Xml\Reader;
use Sabre\CalDAV\Plugin;
use Sabre\Uri;
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
/**
* CalendarMultiGetReport request parser.
@@ -64,7 +64,7 @@ class CalendarMultiGetReport implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php
index 848a4dc46..e0b1c7950 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php
@@ -2,10 +2,10 @@
namespace Sabre\CalDAV\Xml\Request;
-use Sabre\Xml\XmlDeserializable;
-use Sabre\Xml\Reader;
-use Sabre\DAV\Exception\BadRequest;
use Sabre\CalDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
/**
* CalendarQueryReport request parser.
@@ -64,7 +64,7 @@ class CalendarQueryReport implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php
index e3b27d08e..0f6c1e074 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php
@@ -38,7 +38,7 @@ class FreeBusyQueryReport implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php
index 2ecf6c2bb..db32cc6a5 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php
@@ -6,9 +6,9 @@ use Sabre\CalDAV\Plugin;
use Sabre\CalDAV\SharingPlugin;
use Sabre\DAV;
use Sabre\DAV\Exception\BadRequest;
+use Sabre\Xml\Element\KeyValue;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\Xml\Element\KeyValue;
/**
* Invite-reply POST request parser
@@ -82,7 +82,7 @@ class InviteReply implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php
index 7b745db55..ce7fafde9 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php
@@ -39,7 +39,7 @@ class MkCalendar implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
@@ -62,8 +62,8 @@ class MkCalendar implements XmlDeserializable {
$self = new self();
$elementMap = $reader->elementMap;
- $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
- $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
+ $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
+ $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
$elems = $reader->parseInnerTree($elementMap);
foreach ($elems as $elem) {
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php
index b5d9a133c..e0bd8e0af 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php
@@ -41,7 +41,7 @@ class Share implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CardDAV/AddressBook.php b/vendor/sabre/dav/lib/CardDAV/AddressBook.php
index 6dd098618..c9d28a091 100644
--- a/vendor/sabre/dav/lib/CardDAV/AddressBook.php
+++ b/vendor/sabre/dav/lib/CardDAV/AddressBook.php
@@ -60,7 +60,7 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
* Returns a card
*
* @param string $name
- * @return \ICard
+ * @return Card
*/
function getChild($name) {
diff --git a/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php b/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php
index 888a44a40..d770c0ffe 100644
--- a/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php
+++ b/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php
@@ -127,7 +127,7 @@ class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection,
*
* @param string $name
* @todo needs optimizing
- * @return \AddressBook
+ * @return AddressBook
*/
function getChild($name) {
diff --git a/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php b/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php
index 4a33df4ec..a9f1183da 100644
--- a/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php
+++ b/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php
@@ -18,7 +18,7 @@ class AddressBookRoot extends DAVACL\AbstractPrincipalCollection {
/**
* Principal Backend
*
- * @var Sabre\DAVACL\PrincipalBackend\BackendInteface
+ * @var DAVACL\PrincipalBackend\BackendInterface
*/
protected $principalBackend;
diff --git a/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php b/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php
index 54e42b899..18c0c0a99 100644
--- a/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php
+++ b/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php
@@ -46,7 +46,7 @@ interface BackendInterface {
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param string $addressBookId
* @param \Sabre\DAV\PropPatch $propPatch
diff --git a/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php
index 7c3feff93..13487e9da 100644
--- a/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php
@@ -93,7 +93,7 @@ class PDO extends AbstractBackend implements SyncSupport {
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param string $addressBookId
* @param \Sabre\DAV\PropPatch $propPatch
@@ -240,7 +240,7 @@ class PDO extends AbstractBackend implements SyncSupport {
}
/**
- * Returns a specfic card.
+ * Returns a specific card.
*
* The same set of properties must be returned as with getCards. The only
* exception is that 'carddata' is absolutely required.
@@ -466,7 +466,7 @@ class PDO extends AbstractBackend implements SyncSupport {
// Current synctoken
$stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->addressBooksTableName . ' WHERE id = ?');
- $stmt->execute([ $addressBookId ]);
+ $stmt->execute([$addressBookId]);
$currentToken = $stmt->fetchColumn(0);
if (is_null($currentToken)) return null;
diff --git a/vendor/sabre/dav/lib/CardDAV/Card.php b/vendor/sabre/dav/lib/CardDAV/Card.php
index 0a040be6b..42a2d7b6a 100644
--- a/vendor/sabre/dav/lib/CardDAV/Card.php
+++ b/vendor/sabre/dav/lib/CardDAV/Card.php
@@ -2,8 +2,8 @@
namespace Sabre\CardDAV;
-use Sabre\DAVACL;
use Sabre\DAV;
+use Sabre\DAVACL;
/**
* The Card object represents a single Card from an addressbook
diff --git a/vendor/sabre/dav/lib/CardDAV/Plugin.php b/vendor/sabre/dav/lib/CardDAV/Plugin.php
index 0507df100..272ae71fa 100644
--- a/vendor/sabre/dav/lib/CardDAV/Plugin.php
+++ b/vendor/sabre/dav/lib/CardDAV/Plugin.php
@@ -43,7 +43,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* Server class
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
@@ -490,7 +490,8 @@ class Plugin extends DAV\ServerPlugin {
$props[200]['{' . self::NS_CARDDAV . '}address-data'] = $this->convertVCard(
$props[200]['{' . self::NS_CARDDAV . '}address-data'],
- $vcardType
+ $vcardType,
+ $report->addressDataProperties
);
}
@@ -845,14 +846,26 @@ class Plugin extends DAV\ServerPlugin {
*
* @param string|resource $data
* @param string $target
+ * @param array $propertiesFilter
* @return string
*/
- protected function convertVCard($data, $target) {
+ protected function convertVCard($data, $target, array $propertiesFilter = null) {
if (is_resource($data)) {
$data = stream_get_contents($data);
}
$input = VObject\Reader::read($data);
+ if (!empty($propertiesFilter)) {
+ $propertiesFilter = array_merge(['UID', 'VERSION', 'FN'], $propertiesFilter);
+ $keys = array_unique(array_map(function($child) {
+ return $child->name;
+ }, $input->children()));
+ $keys = array_diff($keys, $propertiesFilter);
+ foreach ($keys as $key) {
+ unset($input->$key);
+ }
+ $data = $input->serialize();
+ }
$output = null;
try {
diff --git a/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php b/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php
index d015589ad..2d61db6ac 100644
--- a/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php
+++ b/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php
@@ -3,9 +3,9 @@
namespace Sabre\CardDAV;
use Sabre\DAV;
-use Sabre\VObject;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
+use Sabre\VObject;
/**
* VCF Exporter
@@ -24,7 +24,7 @@ class VCFExportPlugin extends DAV\ServerPlugin {
/**
* Reference to Server class
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php b/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php
index 34028db85..a130cd61d 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php
@@ -26,7 +26,7 @@ class AddressData implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
@@ -51,7 +51,11 @@ class AddressData implements XmlDeserializable {
'version' => $reader->getAttribute('version') ?: '3.0',
];
- $reader->next();
+ $elems = (array)$reader->parseInnerTree();
+ $result['addressDataProperties'] = array_map(function($element) {
+ return $element['attributes']['name'];
+ }, $elems);
+
return $result;
}
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php b/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php
index 9646ae3e6..936e26917 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php
@@ -2,10 +2,10 @@
namespace Sabre\CardDAV\Xml\Filter;
+use Sabre\CardDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
-use Sabre\DAV\Exception\BadRequest;
-use Sabre\CardDAV\Plugin;
/**
* ParamFilter parser.
@@ -26,7 +26,7 @@ abstract class ParamFilter implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php b/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php
index c162da160..d7799429d 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php
@@ -2,10 +2,10 @@
namespace Sabre\CardDAV\Xml\Filter;
+use Sabre\CardDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\DAV\Exception\BadRequest;
-use Sabre\CardDAV\Plugin;
/**
* PropFilter parser.
@@ -26,7 +26,7 @@ class PropFilter implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php b/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php
index 6ff57b6e3..aecd8a09f 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php
@@ -2,9 +2,9 @@
namespace Sabre\CardDAV\Xml\Property;
+use Sabre\CardDAV\Plugin;
use Sabre\Xml\Writer;
use Sabre\Xml\XmlSerializable;
-use Sabre\CardDAV\Plugin;
/**
* Supported-address-data property
@@ -49,12 +49,12 @@ class SupportedAddressData implements XmlSerializable {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php b/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php
index 1fc064900..778aa2b64 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php
@@ -18,12 +18,12 @@ use Sabre\Xml\XmlSerializable;
class SupportedCollationSet implements XmlSerializable {
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php b/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php
index c97c5eb4f..0115a0107 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php
@@ -54,7 +54,7 @@ class AddressBookMultiGetReport implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php b/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php
index a68ac5800..09fad008a 100644
--- a/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php
+++ b/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php
@@ -2,10 +2,10 @@
namespace Sabre\CardDAV\Xml\Request;
+use Sabre\CardDAV\Plugin;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\DAV\Exception\BadRequest;
-use Sabre\CardDAV\Plugin;
/**
* AddressBookQueryReport request parser.
@@ -28,6 +28,13 @@ class AddressBookQueryReport implements XmlDeserializable {
*/
public $properties;
+ /**
+ * An array with requested vcard properties.
+ *
+ * @var array
+ */
+ public $addressDataProperties = [];
+
/**
* List of property/component filters.
*
@@ -92,7 +99,7 @@ class AddressBookQueryReport implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php
index 85c5f30d5..4b47f56c9 100644
--- a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php
+++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php
@@ -2,8 +2,8 @@
namespace Sabre\DAV\Auth\Backend;
-use Sabre\HTTP;
use Sabre\DAV;
+use Sabre\HTTP;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php
index 76ad89391..c2f6de974 100644
--- a/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php
@@ -31,7 +31,7 @@ class PDO extends AbstractDigest {
*
* If the filename argument is passed in, it will parse out the specified file fist.
*
- * @param PDO $pdo
+ * @param \PDO $pdo
*/
function __construct(\PDO $pdo) {
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Plugin.php b/vendor/sabre/dav/lib/DAV/Auth/Plugin.php
index 4b5f35ac3..bbb5d180d 100644
--- a/vendor/sabre/dav/lib/DAV/Auth/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Auth/Plugin.php
@@ -2,11 +2,11 @@
namespace Sabre\DAV\Auth;
-use Sabre\HTTP\RequestInterface;
-use Sabre\HTTP\ResponseInterface;
use Sabre\DAV\Exception\NotAuthenticated;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
/**
* This plugin provides Authentication for a WebDAV server.
@@ -181,7 +181,7 @@ class Plugin extends ServerPlugin {
*
* If login was not successful, the second item in the array will contain a
* an array with strings. The strings are a list of reasons why login was
- * unsuccesful. For every auth backend there will be one reason, so usually
+ * unsuccessful. For every auth backend there will be one reason, so usually
* there's just one.
*
* @param RequestInterface $request
diff --git a/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php b/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php
index 01cddc230..3ba2aee25 100644
--- a/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php
+++ b/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php
@@ -2,10 +2,10 @@
namespace Sabre\DAV\Browser;
-use Sabre\HTTP\URLUtil;
use Sabre\DAV;
-use Sabre\DAV\PropFind;
use Sabre\DAV\Inode;
+use Sabre\DAV\PropFind;
+use Sabre\HTTP\URLUtil;
/**
* GuessContentType plugin
diff --git a/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php b/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php
index 38ee63bcd..61327c49a 100644
--- a/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php
+++ b/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php
@@ -21,7 +21,7 @@ class MapGetToPropFind extends DAV\ServerPlugin {
/**
* reference to server class
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
diff --git a/vendor/sabre/dav/lib/DAV/Browser/Plugin.php b/vendor/sabre/dav/lib/DAV/Browser/Plugin.php
index 49359a045..545ad5633 100644
--- a/vendor/sabre/dav/lib/DAV/Browser/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Browser/Plugin.php
@@ -4,9 +4,9 @@ namespace Sabre\DAV\Browser;
use Sabre\DAV;
use Sabre\DAV\MkCol;
-use Sabre\HTTP\URLUtil;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
+use Sabre\HTTP\URLUtil;
/**
* Browser Plugin
@@ -26,7 +26,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* reference to server class
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
@@ -112,7 +112,7 @@ class Plugin extends DAV\ServerPlugin {
$getVars = $request->getQueryParameters();
// CSP headers
- $this->server->httpResponse->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
+ $response->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
$sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null;
@@ -317,7 +317,7 @@ class Plugin extends DAV\ServerPlugin {
$buttonActions = '';
if ($subProps['subNode'] instanceof DAV\IFile) {
- $buttonActions = '';
+ $buttonActions = '';
}
$this->server->emit('browserButtonActions', [$subProps['fullPath'], $subProps['subNode'], &$buttonActions]);
@@ -414,11 +414,14 @@ class Plugin extends DAV\ServerPlugin {
*
* @param string $title
* @param string $path
- * @return void
+ * @return string
*/
function generateHeader($title, $path = null) {
- $version = DAV\Version::VERSION;
+ $version = '';
+ if (DAV\Server::$exposeVersion) {
+ $version = DAV\Version::VERSION;
+ }
$vars = [
'title' => $this->escapeHTML($title),
@@ -475,7 +478,10 @@ HTML;
*/
function generateFooter() {
- $version = DAV\Version::VERSION;
+ $version = '';
+ if (DAV\Server::$exposeVersion) {
+ $version = DAV\Version::VERSION;
+ }
return <<Generated by SabreDAV $version (c)2007-2016 http://sabre.io/
@@ -506,23 +512,21 @@ HTML;
if (get_class($node) === 'Sabre\\DAV\\SimpleCollection')
return;
- ob_start();
- echo '
-
- ';
-
- $output .= ob_get_clean();
+ $output .= <<
+
Create new folder
+
+
+
+
+
+HTML;
}
@@ -543,8 +547,8 @@ HTML;
* This method returns a local pathname to an asset.
*
* @param string $assetName
- * @return string
* @throws DAV\Exception\NotFound
+ * @return string
*/
protected function getLocalAssetPath($assetName) {
@@ -575,9 +579,9 @@ HTML;
// Rudimentary mime type detection
$mime = 'application/octet-stream';
$map = [
- 'ico' => 'image/vnd.microsoft.icon',
- 'png' => 'image/png',
- 'css' => 'text/css',
+ 'ico' => 'image/vnd.microsoft.icon',
+ 'png' => 'image/png',
+ 'css' => 'text/css',
];
$ext = substr($assetName, strrpos($assetName, '.') + 1);
@@ -623,7 +627,7 @@ HTML;
* Maps a resource type to a human-readable string and icon.
*
* @param array $resourceTypes
- * @param INode $node
+ * @param DAV\INode $node
* @return array
*/
private function mapResourceType(array $resourceTypes, $node) {
diff --git a/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php b/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php
index 1ac439672..c14b7f2f9 100644
--- a/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php
+++ b/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php
@@ -28,7 +28,7 @@ class PropFindAll extends PropFind {
/**
* Handles a specific property.
*
- * This method checks wether the specified property was requested in this
+ * This method checks whether the specified property was requested in this
* PROPFIND request, and if so, it will call the callback and use the
* return value for it's value.
*
diff --git a/vendor/sabre/dav/lib/DAV/Client.php b/vendor/sabre/dav/lib/DAV/Client.php
index 08d5d4702..175ad1bc4 100644
--- a/vendor/sabre/dav/lib/DAV/Client.php
+++ b/vendor/sabre/dav/lib/DAV/Client.php
@@ -231,7 +231,7 @@ class Client extends HTTP\Client {
$response = $this->send($request);
if ((int)$response->getStatus() >= 400) {
- throw new \Sabre\HTTP\ClientHttpException($response);
+ throw new HTTP\ClientHttpException($response);
}
$result = $this->parseMultiStatus($response->getBodyAsString());
@@ -281,7 +281,7 @@ class Client extends HTTP\Client {
$response = $this->send($request);
if ($response->getStatus() >= 400) {
- throw new \Sabre\HTTP\ClientHttpException($response);
+ throw new HTTP\ClientHttpException($response);
}
if ($response->getStatus() === 207) {
@@ -303,7 +303,7 @@ class Client extends HTTP\Client {
}
if ($errorProperties) {
- throw new \Sabre\HTTP\ClientException('PROPPATCH failed. The following properties errored: ' . implode(', ', $errorProperties));
+ throw new HTTP\ClientException('PROPPATCH failed. The following properties errored: ' . implode(', ', $errorProperties));
}
}
return true;
diff --git a/vendor/sabre/dav/lib/DAV/Collection.php b/vendor/sabre/dav/lib/DAV/Collection.php
index a46bcc342..35c90b5af 100644
--- a/vendor/sabre/dav/lib/DAV/Collection.php
+++ b/vendor/sabre/dav/lib/DAV/Collection.php
@@ -68,7 +68,7 @@ abstract class Collection extends Node implements ICollection {
* Data will either be supplied as a stream resource, or in certain cases
* as a string. Keep in mind that you may have to support either.
*
- * After succesful creation of the file, you may choose to return the ETag
+ * After successful creation of the file, you may choose to return the ETag
* of the new file here.
*
* The returned ETag must be surrounded by double-quotes (The quotes should
diff --git a/vendor/sabre/dav/lib/DAV/CorePlugin.php b/vendor/sabre/dav/lib/DAV/CorePlugin.php
index a1b052915..676cdd04a 100644
--- a/vendor/sabre/dav/lib/DAV/CorePlugin.php
+++ b/vendor/sabre/dav/lib/DAV/CorePlugin.php
@@ -165,7 +165,7 @@ class CorePlugin extends ServerPlugin {
} else {
$start = $nodeSize - $range[1];
- $end = $nodeSize - 1;
+ $end = $nodeSize - 1;
if ($start < 0) $start = 0;
@@ -194,7 +194,7 @@ class CorePlugin extends ServerPlugin {
$response->setBody($body);
}
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -224,7 +224,7 @@ class CorePlugin extends ServerPlugin {
$response->setHeader('Content-Length', '0');
$response->setStatus(200);
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -264,7 +264,7 @@ class CorePlugin extends ServerPlugin {
$response->setHeader('X-Sabre-Real-Status', $e->getHTTPCode());
}
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -290,7 +290,7 @@ class CorePlugin extends ServerPlugin {
$response->setStatus(204);
$response->setHeader('Content-Length', '0');
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -333,7 +333,7 @@ class CorePlugin extends ServerPlugin {
// The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled
if (!$this->server->enablePropfindDepthInfinity && $depth != 0) $depth = 1;
- $newProperties = $this->server->getPropertiesForPath($path, $propFindXml->properties, $depth);
+ $newProperties = $this->server->getPropertiesIteratorForPath($path, $propFindXml->properties, $depth);
// This is a multi-status response
$response->setStatus(207);
@@ -355,7 +355,7 @@ class CorePlugin extends ServerPlugin {
$data = $this->server->generateMultiStatus($newProperties, $minimal);
$response->setBody($data);
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -390,7 +390,7 @@ class CorePlugin extends ServerPlugin {
if ($prefer['return'] === 'minimal') {
// If return-minimal is specified, we only have to check if the
- // request was succesful, and don't need to return the
+ // request was successful, and don't need to return the
// multi-status.
$ok = true;
foreach ($result as $prop => $code) {
@@ -427,7 +427,7 @@ class CorePlugin extends ServerPlugin {
$this->server->generateMultiStatus([$multiStatus])
);
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -533,7 +533,7 @@ class CorePlugin extends ServerPlugin {
}
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -602,7 +602,7 @@ class CorePlugin extends ServerPlugin {
$response->setStatus(201);
}
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -653,7 +653,7 @@ class CorePlugin extends ServerPlugin {
$response->setHeader('Content-Length', '0');
$response->setStatus($moveInfo['destinationExists'] ? 204 : 201);
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -688,7 +688,7 @@ class CorePlugin extends ServerPlugin {
$response->setHeader('Content-Length', '0');
$response->setStatus($copyInfo['destinationExists'] ? 204 : 201);
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -722,7 +722,7 @@ class CorePlugin extends ServerPlugin {
}
- // Sending back false will interupt the event chain and tell the server
+ // Sending back false will interrupt the event chain and tell the server
// we've handled this method.
return false;
@@ -740,7 +740,7 @@ class CorePlugin extends ServerPlugin {
*/
function propPatchProtectedPropertyCheck($path, PropPatch $propPatch) {
- // Comparing the mutation list to the list of propetected properties.
+ // Comparing the mutation list to the list of protected properties.
$mutations = $propPatch->getMutations();
$protected = array_intersect(
diff --git a/vendor/sabre/dav/lib/DAV/Exception/InvalidResourceType.php b/vendor/sabre/dav/lib/DAV/Exception/InvalidResourceType.php
index 505fe5c10..6324d9f3a 100644
--- a/vendor/sabre/dav/lib/DAV/Exception/InvalidResourceType.php
+++ b/vendor/sabre/dav/lib/DAV/Exception/InvalidResourceType.php
@@ -19,7 +19,7 @@ class InvalidResourceType extends Forbidden {
/**
* This method allows the exception to include additional information into the WebDAV error response
*
- * @param DAV\Server $server
+ * @param \Sabre\DAV\Server $server
* @param \DOMElement $errorNode
* @return void
*/
diff --git a/vendor/sabre/dav/lib/DAV/FS/Node.php b/vendor/sabre/dav/lib/DAV/FS/Node.php
index 831c11911..424718f96 100644
--- a/vendor/sabre/dav/lib/DAV/FS/Node.php
+++ b/vendor/sabre/dav/lib/DAV/FS/Node.php
@@ -43,7 +43,7 @@ abstract class Node implements DAV\INode {
*/
function getName() {
- list(, $name) = URLUtil::splitPath($this->path);
+ list(, $name) = URLUtil::splitPath($this->path);
return $name;
}
diff --git a/vendor/sabre/dav/lib/DAV/File.php b/vendor/sabre/dav/lib/DAV/File.php
index 675956b22..5161fbd51 100644
--- a/vendor/sabre/dav/lib/DAV/File.php
+++ b/vendor/sabre/dav/lib/DAV/File.php
@@ -19,7 +19,7 @@ abstract class File extends Node implements IFile {
*
* The data argument is a readable stream resource.
*
- * After a succesful put operation, you may choose to return an ETag. The
+ * After a successful put operation, you may choose to return an ETag. The
* etag must always be surrounded by double-quotes. These quotes must
* appear in the actual string you're returning.
*
diff --git a/vendor/sabre/dav/lib/DAV/IFile.php b/vendor/sabre/dav/lib/DAV/IFile.php
index 37e7cd33c..19d8d8637 100644
--- a/vendor/sabre/dav/lib/DAV/IFile.php
+++ b/vendor/sabre/dav/lib/DAV/IFile.php
@@ -20,7 +20,7 @@ interface IFile extends INode {
*
* The data argument is a readable stream resource.
*
- * After a succesful put operation, you may choose to return an ETag. The
+ * After a successful put operation, you may choose to return an ETag. The
* etag must always be surrounded by double-quotes. These quotes must
* appear in the actual string you're returning.
*
@@ -32,7 +32,7 @@ interface IFile extends INode {
* different object on a subsequent GET you are strongly recommended to not
* return an ETag, and just return null.
*
- * @param resource|data $data
+ * @param resource|string $data
* @return string|null
*/
function put($data);
diff --git a/vendor/sabre/dav/lib/DAV/IMoveTarget.php b/vendor/sabre/dav/lib/DAV/IMoveTarget.php
index f0f67bc26..92fde1d5c 100644
--- a/vendor/sabre/dav/lib/DAV/IMoveTarget.php
+++ b/vendor/sabre/dav/lib/DAV/IMoveTarget.php
@@ -7,7 +7,7 @@ namespace Sabre\DAV;
* nodes may be moved into this collection".
*
* The benefit of this, is that sabre/dav will by default perform a move, by
- * tranfersing an entire directory tree, copying every collection, and deleting
+ * transferring an entire directory tree, copying every collection, and deleting
* every item.
*
* If a backend supports a better optimized move operation, this can trigger
diff --git a/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php b/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php
index a01d9bae4..510f266f7 100644
--- a/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php
@@ -33,7 +33,7 @@ class PDO extends AbstractBackend {
/**
* Constructor
*
- * @param PDO $pdo
+ * @param \PDO $pdo
*/
function __construct(\PDO $pdo) {
@@ -102,7 +102,7 @@ class PDO extends AbstractBackend {
$lockInfo->created = $row['created'];
$lockInfo->scope = $row['scope'];
$lockInfo->depth = $row['depth'];
- $lockInfo->uri = $row['uri'];
+ $lockInfo->uri = $row['uri'];
$lockList[] = $lockInfo;
}
diff --git a/vendor/sabre/dav/lib/DAV/Locks/Plugin.php b/vendor/sabre/dav/lib/DAV/Locks/Plugin.php
index 4855b7076..41a3bf3fa 100644
--- a/vendor/sabre/dav/lib/DAV/Locks/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Locks/Plugin.php
@@ -25,14 +25,14 @@ class Plugin extends DAV\ServerPlugin {
/**
* locksBackend
*
- * @var Backend\Backend\Interface
+ * @var Backend\BackendInterface
*/
protected $locksBackend;
/**
* server
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
@@ -256,7 +256,7 @@ class Plugin extends DAV\ServerPlugin {
$response->setStatus($newFile ? 201 : 200);
$response->setBody($this->generateLockResponse($lockInfo));
- // Returning false will interupt the event chain and mark this method
+ // Returning false will interrupt the event chain and mark this method
// as 'handled'.
return false;
diff --git a/vendor/sabre/dav/lib/DAV/MkCol.php b/vendor/sabre/dav/lib/DAV/MkCol.php
index c79055418..042e14bca 100644
--- a/vendor/sabre/dav/lib/DAV/MkCol.php
+++ b/vendor/sabre/dav/lib/DAV/MkCol.php
@@ -61,6 +61,7 @@ class MkCol extends PropPatch {
* checked.
*
* @param string|string[] $resourceType
+ * @return bool
*/
function hasResourceType($resourceType) {
diff --git a/vendor/sabre/dav/lib/DAV/Mount/Plugin.php b/vendor/sabre/dav/lib/DAV/Mount/Plugin.php
index 8e06acb9f..dc923ad85 100644
--- a/vendor/sabre/dav/lib/DAV/Mount/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Mount/Plugin.php
@@ -20,7 +20,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* Reference to Server class
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
diff --git a/vendor/sabre/dav/lib/DAV/Node.php b/vendor/sabre/dav/lib/DAV/Node.php
index ba270e8f9..ef6eea18e 100644
--- a/vendor/sabre/dav/lib/DAV/Node.php
+++ b/vendor/sabre/dav/lib/DAV/Node.php
@@ -29,7 +29,7 @@ abstract class Node implements INode {
/**
* Deletes the current node
*
- * @throws Sabre\DAV\Exception\Forbidden
+ * @throws Exception\Forbidden
* @return void
*/
function delete() {
@@ -41,8 +41,8 @@ abstract class Node implements INode {
/**
* Renames the node
*
- * @throws Sabre\DAV\Exception\Forbidden
* @param string $name The new name
+ * @throws Exception\Forbidden
* @return void
*/
function setName($name) {
diff --git a/vendor/sabre/dav/lib/DAV/PartialUpdate/Plugin.php b/vendor/sabre/dav/lib/DAV/PartialUpdate/Plugin.php
index 24ba970b1..9c129d705 100644
--- a/vendor/sabre/dav/lib/DAV/PartialUpdate/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/PartialUpdate/Plugin.php
@@ -29,7 +29,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* Reference to server
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
diff --git a/vendor/sabre/dav/lib/DAV/PropFind.php b/vendor/sabre/dav/lib/DAV/PropFind.php
index 8ae6b6cfd..0940a1ce2 100644
--- a/vendor/sabre/dav/lib/DAV/PropFind.php
+++ b/vendor/sabre/dav/lib/DAV/PropFind.php
@@ -72,7 +72,7 @@ class PropFind {
/**
* Handles a specific property.
*
- * This method checks wether the specified property was requested in this
+ * This method checks whether the specified property was requested in this
* PROPFIND request, and if so, it will call the callback and use the
* return value for it's value.
*
diff --git a/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php b/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php
index 31ecafdb2..b15d7fef9 100644
--- a/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php
+++ b/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php
@@ -23,7 +23,7 @@ interface BackendInterface {
* This method received a PropFind object, which contains all the
* information about the properties that need to be fetched.
*
- * Ususually you would just want to call 'get404Properties' on this object,
+ * Usually you would just want to call 'get404Properties' on this object,
* as this will give you the _exact_ list of properties that need to be
* fetched, and haven't yet.
*
diff --git a/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php b/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php
index 2fe843884..6f3f1feaf 100644
--- a/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php
@@ -66,7 +66,7 @@ class PDO implements BackendInterface {
* This method received a PropFind object, which contains all the
* information about the properties that need to be fetched.
*
- * Ususually you would just want to call 'get404Properties' on this object,
+ * Usually you would just want to call 'get404Properties' on this object,
* as this will give you the _exact_ list of properties that need to be
* fetched, and haven't yet.
*
diff --git a/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php b/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php
index 0c28b7882..a66a14113 100644
--- a/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php
@@ -2,11 +2,11 @@
namespace Sabre\DAV\PropertyStorage;
+use Sabre\DAV\INode;
+use Sabre\DAV\PropFind;
+use Sabre\DAV\PropPatch;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
-use Sabre\DAV\PropPatch;
-use Sabre\DAV\PropFind;
-use Sabre\DAV\INode;
/**
* PropertyStorage Plugin.
@@ -30,13 +30,18 @@ class Plugin extends ServerPlugin {
* paths, you can use a pathFilter to do this.
*
* The pathFilter should be a callable. The callable retrieves a path as
- * its argument, and should return true or false wether it allows
+ * its argument, and should return true or false whether it allows
* properties to be stored.
*
* @var callable
*/
public $pathFilter;
+ /**
+ * @var Backend\BackendInterface
+ */
+ public $backend;
+
/**
* Creates the plugin
*
diff --git a/vendor/sabre/dav/lib/DAV/Server.php b/vendor/sabre/dav/lib/DAV/Server.php
index 024b7a557..6805ec0b0 100644
--- a/vendor/sabre/dav/lib/DAV/Server.php
+++ b/vendor/sabre/dav/lib/DAV/Server.php
@@ -2,16 +2,16 @@
namespace Sabre\DAV;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
use Sabre\Event\EventEmitter;
use Sabre\HTTP;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Sabre\HTTP\URLUtil;
use Sabre\Uri;
-use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LoggerAwareTrait;
-use Psr\Log\LoggerInterface;
-use Psr\Log\NullLogger;
/**
* Main DAV server class
@@ -37,7 +37,7 @@ class Server extends EventEmitter implements LoggerAwareInterface {
/**
* The tree object
*
- * @var Sabre\DAV\Tree
+ * @var Tree
*/
public $tree;
@@ -51,21 +51,21 @@ class Server extends EventEmitter implements LoggerAwareInterface {
/**
* httpResponse
*
- * @var Sabre\HTTP\Response
+ * @var HTTP\Response
*/
public $httpResponse;
/**
* httpRequest
*
- * @var Sabre\HTTP\Request
+ * @var HTTP\Request
*/
public $httpRequest;
/**
* PHP HTTP Sapi
*
- * @var Sabre\HTTP\Sapi
+ * @var HTTP\Sapi
*/
public $sapi;
@@ -437,7 +437,7 @@ class Server extends EventEmitter implements LoggerAwareInterface {
}
/**
- * Returns the PSR-3 logger objcet.
+ * Returns the PSR-3 logger object.
*
* @return LoggerInterface
*/
@@ -455,7 +455,7 @@ class Server extends EventEmitter implements LoggerAwareInterface {
*
* @param RequestInterface $request
* @param ResponseInterface $response
- * @param $sendResponse Whether to send the HTTP response to the DAV client.
+ * @param bool $sendResponse Whether to send the HTTP response to the DAV client.
* @return void
*/
function invokeMethod(RequestInterface $request, ResponseInterface $response, $sendResponse = true) {
@@ -681,18 +681,18 @@ class Server extends EventEmitter implements LoggerAwareInterface {
// can be true or false
'respond-async' => false,
// Could be set to 'representation' or 'minimal'.
- 'return' => null,
+ 'return' => null,
// Used as a timeout, is usually a number.
- 'wait' => null,
+ 'wait' => null,
// can be 'strict' or 'lenient'.
- 'handling' => false,
+ 'handling' => false,
];
if ($prefer = $this->httpRequest->getHeader('Prefer')) {
$result = array_merge(
$result,
- \Sabre\HTTP\parsePrefer($prefer)
+ HTTP\parsePrefer($prefer)
);
} elseif ($this->httpRequest->getHeader('Brief') == 't') {
@@ -794,6 +794,7 @@ class Server extends EventEmitter implements LoggerAwareInterface {
*
* @param string $path
* @param array $propertyNames
+ * @return array
*/
function getProperties($path, $propertyNames) {
@@ -877,12 +878,14 @@ class Server extends EventEmitter implements LoggerAwareInterface {
/**
* Small helper to support PROPFIND with DEPTH_INFINITY.
*
- * @param array[] $propFindRequests
* @param PropFind $propFind
- * @return void
+ * @param array $yieldFirst
+ * @return \Iterator
*/
- private function addPathNodesRecursively(&$propFindRequests, PropFind $propFind) {
-
+ private function generatePathNodes(PropFind $propFind, array $yieldFirst = null) {
+ if ($yieldFirst !== null) {
+ yield $yieldFirst;
+ }
$newDepth = $propFind->getDepth();
$path = $propFind->getPath();
@@ -900,13 +903,15 @@ class Server extends EventEmitter implements LoggerAwareInterface {
}
$subPropFind->setPath($subPath);
- $propFindRequests[] = [
+ yield [
$subPropFind,
$childNode
];
if (($newDepth === self::DEPTH_INFINITY || $newDepth >= 1) && $childNode instanceof ICollection) {
- $this->addPathNodesRecursively($propFindRequests, $subPropFind);
+ foreach ($this->generatePathNodes($subPropFind) as $subItem) {
+ yield $subItem;
+ }
}
}
@@ -925,9 +930,31 @@ class Server extends EventEmitter implements LoggerAwareInterface {
* @param array $propertyNames
* @param int $depth
* @return array
+ *
+ * @deprecated Use getPropertiesIteratorForPath() instead (as it's more memory efficient)
+ * @see getPropertiesIteratorForPath()
*/
function getPropertiesForPath($path, $propertyNames = [], $depth = 0) {
+ return iterator_to_array($this->getPropertiesIteratorForPath($path, $propertyNames, $depth));
+
+ }
+ /**
+ * Returns a list of properties for a given path
+ *
+ * The path that should be supplied should have the baseUrl stripped out
+ * The list of properties should be supplied in Clark notation. If the list is empty
+ * 'allprops' is assumed.
+ *
+ * If a depth of 1 is requested child elements will also be returned.
+ *
+ * @param string $path
+ * @param array $propertyNames
+ * @param int $depth
+ * @return \Iterator
+ */
+ function getPropertiesIteratorForPath($path, $propertyNames = [], $depth = 0) {
+
// The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled
if (!$this->enablePropfindDepthInfinity && $depth != 0) $depth = 1;
@@ -944,11 +971,9 @@ class Server extends EventEmitter implements LoggerAwareInterface {
]];
if (($depth > 0 || $depth === self::DEPTH_INFINITY) && $parentNode instanceof ICollection) {
- $this->addPathNodesRecursively($propFindRequests, $propFind);
+ $propFindRequests = $this->generatePathNodes(clone $propFind, current($propFindRequests));
}
- $returnPropertyList = [];
-
foreach ($propFindRequests as $propFindRequest) {
list($propFind, $node) = $propFindRequest;
@@ -965,13 +990,11 @@ class Server extends EventEmitter implements LoggerAwareInterface {
if (in_array('{DAV:}collection', $resourceType) || in_array('{DAV:}principal', $resourceType)) {
$result['href'] .= '/';
}
- $returnPropertyList[] = $result;
+ yield $result;
}
}
- return $returnPropertyList;
-
}
/**
@@ -1430,7 +1453,7 @@ class Server extends EventEmitter implements LoggerAwareInterface {
// Plugins are responsible for validating all the tokens.
// If a plugin deemed a token 'valid', it will set 'validToken' to
// true.
- $this->emit('validateTokens', [ $request, &$ifConditions ]);
+ $this->emit('validateTokens', [$request, &$ifConditions]);
// Now we're going to analyze the result.
@@ -1450,7 +1473,7 @@ class Server extends EventEmitter implements LoggerAwareInterface {
if (!$token['etag']) {
$etagValid = true;
}
- // Checking the ETag, only if the token was already deamed
+ // Checking the ETag, only if the token was already deemed
// valid and there is one.
if ($token['etag'] && $tokenValid) {
@@ -1626,13 +1649,18 @@ class Server extends EventEmitter implements LoggerAwareInterface {
*
* If 'strip404s' is set to true, all 404 responses will be removed.
*
- * @param array $fileProperties The list with nodes
- * @param bool strip404s
+ * @param array|\Traversable $fileProperties The list with nodes
+ * @param bool $strip404s
* @return string
*/
- function generateMultiStatus(array $fileProperties, $strip404s = false) {
+ function generateMultiStatus($fileProperties, $strip404s = false) {
- $xml = [];
+ $w = $this->xml->getWriter();
+ $w->openMemory();
+ $w->contextUri = $this->baseUri;
+ $w->startDocument();
+
+ $w->startElement('{DAV:}multistatus');
foreach ($fileProperties as $entry) {
@@ -1645,13 +1673,14 @@ class Server extends EventEmitter implements LoggerAwareInterface {
ltrim($href, '/'),
$entry
);
- $xml[] = [
+ $w->write([
'name' => '{DAV:}response',
'value' => $response
- ];
-
+ ]);
}
- return $this->xml->write('{DAV:}multistatus', $xml, $this->baseUri);
+ $w->endElement();
+
+ return $w->outputMemory();
}
diff --git a/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php b/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php
index 354d06a56..ef5702c57 100644
--- a/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php
@@ -8,8 +8,8 @@ use Sabre\DAV\INode;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
-use Sabre\DAV\Xml\Property;
use Sabre\DAV\Xml\Element\Sharee;
+use Sabre\DAV\Xml\Property;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -40,7 +40,7 @@ class Plugin extends ServerPlugin {
/**
* Reference to SabreDAV server object.
*
- * @var Sabre\DAV\Server
+ * @var Server
*/
protected $server;
diff --git a/vendor/sabre/dav/lib/DAV/Sync/Plugin.php b/vendor/sabre/dav/lib/DAV/Sync/Plugin.php
index 4a141c72b..8e4b1aa64 100644
--- a/vendor/sabre/dav/lib/DAV/Sync/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Sync/Plugin.php
@@ -3,8 +3,8 @@
namespace Sabre\DAV\Sync;
use Sabre\DAV;
-use Sabre\HTTP\RequestInterface;
use Sabre\DAV\Xml\Request\SyncCollectionReport;
+use Sabre\HTTP\RequestInterface;
/**
* This plugin all WebDAV-sync capabilities to the Server.
diff --git a/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php b/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php
index c5b8aa1ca..7b453d105 100644
--- a/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php
+++ b/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php
@@ -14,7 +14,7 @@ use Sabre\HTTP\URLUtil;
* a WebDAV share as a disk.
*
* It will intercept these files and place them in a separate directory.
- * these files are not deleted automatically, so it is adviceable to
+ * these files are not deleted automatically, so it is advisable to
* delete these after they are not accessed for 24 hours.
*
* Currently it supports:
@@ -51,7 +51,7 @@ class TemporaryFileFilterPlugin extends ServerPlugin {
/**
* A reference to the main Server class
*
- * @var Sabre\DAV\Server
+ * @var \Sabre\DAV\Server
*/
protected $server;
@@ -134,12 +134,12 @@ class TemporaryFileFilterPlugin extends ServerPlugin {
*
* @param string $uri
* @param resource $data
- * @param DAV\ICollection $parentNode
+ * @param ICollection $parent
* @param bool $modified Should be set to true, if this event handler
* changed &$data.
* @return bool
*/
- function beforeCreateFile($uri, $data, $parent, $modified) {
+ function beforeCreateFile($uri, $data, ICollection $parent, $modified) {
if ($tempPath = $this->isTempFile($uri)) {
diff --git a/vendor/sabre/dav/lib/DAV/Version.php b/vendor/sabre/dav/lib/DAV/Version.php
index 2fda85db8..89918e5bc 100644
--- a/vendor/sabre/dav/lib/DAV/Version.php
+++ b/vendor/sabre/dav/lib/DAV/Version.php
@@ -14,6 +14,6 @@ class Version {
/**
* Full version number
*/
- const VERSION = '3.2.0';
+ const VERSION = '3.2.2';
}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php b/vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php
index db5332c50..71ef03e3f 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php
@@ -3,8 +3,8 @@
namespace Sabre\DAV\Xml\Element;
use Sabre\DAV\Xml\Property\Complex;
-use Sabre\Xml\XmlDeserializable;
use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
/**
* This class is responsible for decoding the {DAV:}prop element as it appears
@@ -22,7 +22,7 @@ class Prop implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
@@ -90,7 +90,7 @@ class Prop implements XmlDeserializable {
if (array_key_exists($name, $reader->elementMap)) {
$deserializer = $reader->elementMap[$name];
if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) {
- $value = call_user_func([ $deserializer, 'xmlDeserialize' ], $reader);
+ $value = call_user_func([$deserializer, 'xmlDeserialize'], $reader);
} elseif (is_callable($deserializer)) {
$value = call_user_func($deserializer, $reader);
} else {
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php b/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php
index 97a2bb59f..ce97ae943 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php
@@ -160,7 +160,7 @@ class Response implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php b/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php
index dcfd7bd2e..e187bf11c 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php
@@ -105,7 +105,7 @@ class Sharee implements Element {
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -146,7 +146,7 @@ class Sharee implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php b/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php
index 1d9202082..258806e4a 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php
@@ -20,7 +20,7 @@ class Complex extends XmlFragment {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php b/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php
index 2db47269f..101a0f0c9 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php
@@ -2,12 +2,12 @@
namespace Sabre\DAV\Xml\Property;
+use DateTime;
+use DateTimeZone;
+use Sabre\HTTP;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
-use Sabre\HTTP;
-use DateTime;
-use DateTimeZone;
/**
* This property represents the {DAV:}getlastmodified property.
@@ -83,7 +83,7 @@ class GetLastModified implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php b/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php
index 0027f72e1..6c4f11b87 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php
@@ -4,10 +4,10 @@ namespace Sabre\DAV\Xml\Property;
use Sabre\DAV\Browser\HtmlOutput;
use Sabre\DAV\Browser\HtmlOutputHelper;
+use Sabre\Uri;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
-use Sabre\Uri;
/**
* Href property
@@ -40,7 +40,7 @@ class Href implements Element, HtmlOutput {
* If auto-prefix is set to false, the hrefs will be treated as absolute
* and not relative to the servers base uri.
*
- * @param string|string[] $href
+ * @param string|string[] $hrefs
*/
function __construct($hrefs) {
@@ -74,12 +74,12 @@ class Href implements Element, HtmlOutput {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -128,7 +128,7 @@ class Href implements Element, HtmlOutput {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php b/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php
index 0616ff113..6adad3650 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php
@@ -2,9 +2,9 @@
namespace Sabre\DAV\Xml\Property;
-use Sabre\DAV\Sharing\Sharee;
-use Sabre\Xml\XmlSerializable;
+use Sabre\DAV\Xml\Element\Sharee;
use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* This class represents the {DAV:}invite property.
@@ -46,7 +46,7 @@ class Invite implements XmlSerializable {
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php b/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php
index 76a27b95d..00d2fa708 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php
@@ -8,7 +8,7 @@ use Sabre\HTTP;
* LocalHref property
*
* Like the Href property, this element represents {DAV:}href. The difference
- * is that this is used stricly for paths on the server. The LocalHref property
+ * is that this is used strictly for paths on the server. The LocalHref property
* will prepare the path so it's a valid URI.
*
* These two objects behave identically:
@@ -32,7 +32,7 @@ class LocalHref extends Href {
* If auto-prefix is set to false, the hrefs will be treated as absolute
* and not relative to the servers base uri.
*
- * @param string|string[] $href
+ * @param string|string[] $hrefs
*/
function __construct($hrefs) {
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php b/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php
index 302888321..ce640ff32 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php
@@ -28,7 +28,7 @@ class ResourceType extends Element\Elements implements HtmlOutput {
*
* The resourcetype must be specified in clark-notation
*
- * @param array|string|null $resourceType
+ * @param array|string|null $resourceTypes
*/
function __construct($resourceTypes = null) {
@@ -77,7 +77,7 @@ class ResourceType extends Element\Elements implements HtmlOutput {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php b/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php
index a3fc6b0e1..939062f76 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php
@@ -2,8 +2,8 @@
namespace Sabre\DAV\Xml\Property;
-use Sabre\DAV\Sharing\Plugin as SharingPlugin;
use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Sharing\Plugin as SharingPlugin;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
@@ -62,7 +62,7 @@ class ShareAccess implements Element {
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -102,7 +102,7 @@ class ShareAccess implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php
index f6d01aa37..677fdde4b 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php
@@ -21,12 +21,12 @@ use Sabre\Xml\XmlSerializable;
class SupportedLock implements XmlSerializable {
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -43,11 +43,11 @@ class SupportedLock implements XmlSerializable {
$writer->writeElement('{DAV:}lockentry', [
'{DAV:}lockscope' => ['{DAV:}exclusive' => null],
- '{DAV:}locktype' => ['{DAV:}write' => null],
+ '{DAV:}locktype' => ['{DAV:}write' => null],
]);
$writer->writeElement('{DAV:}lockentry', [
'{DAV:}lockscope' => ['{DAV:}shared' => null],
- '{DAV:}locktype' => ['{DAV:}write' => null],
+ '{DAV:}locktype' => ['{DAV:}write' => null],
]);
}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php
index 7641f3739..1a3878ef7 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php
@@ -67,12 +67,12 @@ class SupportedMethodSet implements XmlSerializable, HtmlOutput {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php
index ebf27300d..96383ec96 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php
@@ -98,12 +98,12 @@ class SupportedReportSet implements XmlSerializable, HtmlOutput {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php b/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php
index 76df98d13..c315a9a45 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php
@@ -38,7 +38,7 @@ class Lock implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php b/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php
index 5db239061..9490bf58c 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php
@@ -40,7 +40,7 @@ class MkCol implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
@@ -63,8 +63,8 @@ class MkCol implements XmlDeserializable {
$self = new self();
$elementMap = $reader->elementMap;
- $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
- $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
+ $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
+ $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
$elementMap['{DAV:}remove'] = 'Sabre\Xml\Element\KeyValue';
$elems = $reader->parseInnerTree($elementMap);
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php b/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php
index ad3ad7c43..f1b5b6fdc 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php
@@ -36,7 +36,7 @@ class PropFind implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php b/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php
index 07a05f887..821b9e047 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php
@@ -29,12 +29,12 @@ class PropPatch implements Element {
public $properties = [];
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -68,7 +68,7 @@ class PropPatch implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
@@ -91,8 +91,8 @@ class PropPatch implements Element {
$self = new self();
$elementMap = $reader->elementMap;
- $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
- $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
+ $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop';
+ $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue';
$elementMap['{DAV:}remove'] = 'Sabre\Xml\Element\KeyValue';
$elems = $reader->parseInnerTree($elementMap);
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php b/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php
index 965e5857c..526a4eb6f 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php
@@ -2,9 +2,9 @@
namespace Sabre\DAV\Xml\Request;
+use Sabre\DAV\Xml\Element\Sharee;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\DAV\Xml\Element\Sharee;
/**
* ShareResource request parser.
@@ -40,7 +40,7 @@ class ShareResource implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php b/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php
index 3092ada47..830293a01 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php
@@ -2,10 +2,10 @@
namespace Sabre\DAV\Xml\Request;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\Xml\Element\KeyValue;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\Xml\Element\KeyValue;
-use Sabre\DAV\Exception\BadRequest;
/**
* SyncCollection request parser.
@@ -51,7 +51,7 @@ class SyncCollectionReport implements XmlDeserializable {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
@@ -75,7 +75,7 @@ class SyncCollectionReport implements XmlDeserializable {
$reader->pushContext();
- $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Element\Elements';
+ $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Element\Elements';
$elems = KeyValue::xmlDeserialize($reader);
$reader->popContext();
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php b/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php
index 16a3d4a68..cf5a0453b 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php
@@ -99,7 +99,7 @@ class MultiStatus implements Element {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php b/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php
index 4349bf101..d7ae188ae 100644
--- a/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php
+++ b/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php
@@ -5,7 +5,7 @@ namespace Sabre\DAVACL\Exception;
use Sabre\DAV;
/**
- * If a client tried to set a privilege assigned to a non-existant principal,
+ * If a client tried to set a privilege assigned to a non-existent principal,
* this exception will be thrown.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
diff --git a/vendor/sabre/dav/lib/DAVACL/FS/Collection.php b/vendor/sabre/dav/lib/DAVACL/FS/Collection.php
index 1c08b43b1..b4fe7a1b0 100644
--- a/vendor/sabre/dav/lib/DAVACL/FS/Collection.php
+++ b/vendor/sabre/dav/lib/DAVACL/FS/Collection.php
@@ -2,11 +2,11 @@
namespace Sabre\DAVACL\FS;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\FSExt\Directory as BaseCollection;
use Sabre\DAVACL\ACLTrait;
use Sabre\DAVACL\IACL;
-use Sabre\DAV\Exception\Forbidden;
-use Sabre\DAV\Exception\NotFound;
/**
* This is an ACL-enabled collection.
diff --git a/vendor/sabre/dav/lib/DAVACL/FS/File.php b/vendor/sabre/dav/lib/DAVACL/FS/File.php
index 387597bf7..aaf2ae148 100644
--- a/vendor/sabre/dav/lib/DAVACL/FS/File.php
+++ b/vendor/sabre/dav/lib/DAVACL/FS/File.php
@@ -3,8 +3,8 @@
namespace Sabre\DAVACL\FS;
use Sabre\DAV\FSExt\File as BaseFile;
-use Sabre\DAVACL\IACL;
use Sabre\DAVACL\ACLTrait;
+use Sabre\DAVACL\IACL;
/**
* This is an ACL-enabled file node.
diff --git a/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php b/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php
index 9e21353ea..201235e5a 100644
--- a/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php
+++ b/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php
@@ -72,7 +72,7 @@ class HomeCollection extends AbstractPrincipalCollection implements IACL {
* supplied by the authentication backend.
*
* @param array $principalInfo
- * @return \Sabre\DAVACL\INode
+ * @return \Sabre\DAV\INode
*/
function getChildForPrincipal(array $principalInfo) {
diff --git a/vendor/sabre/dav/lib/DAVACL/Plugin.php b/vendor/sabre/dav/lib/DAVACL/Plugin.php
index 8e912309e..a2aa118d7 100644
--- a/vendor/sabre/dav/lib/DAVACL/Plugin.php
+++ b/vendor/sabre/dav/lib/DAVACL/Plugin.php
@@ -3,11 +3,12 @@
namespace Sabre\DAVACL;
use Sabre\DAV;
-use Sabre\DAV\INode;
-use Sabre\DAV\Xml\Property\Href;
use Sabre\DAV\Exception\BadRequest;
-use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotAuthenticated;
+use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\INode;
+use Sabre\DAV\Xml\Property\Href;
use Sabre\DAVACL\Exception\NeedPrivileges;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -53,7 +54,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* Reference to server object.
*
- * @var Sabre\DAV\Server
+ * @var DAV\Server
*/
protected $server;
@@ -228,14 +229,14 @@ class Plugin extends DAV\ServerPlugin {
/**
* Returns the standard users' principal.
*
- * This is one authorative principal url for the current user.
+ * This is one authoritative principal url for the current user.
* This method will return null if the user wasn't logged in.
*
* @return string|null
*/
function getCurrentUserPrincipal() {
- /** @var $authPlugin Sabre\DAV\Auth\Plugin */
+ /** @var $authPlugin \Sabre\DAV\Auth\Plugin */
$authPlugin = $this->server->getPlugin('auth');
if (!$authPlugin) {
return null;
@@ -283,8 +284,7 @@ class Plugin extends DAV\ServerPlugin {
*
* These rules are used for all nodes that don't implement the IACL interface.
*
- * @param array $acl
- * @return void
+ * @return array
*/
function getDefaultAcl() {
@@ -299,7 +299,7 @@ class Plugin extends DAV\ServerPlugin {
* set of rules allow anyone to do anything, as long as they are
* authenticated.
*
- * var array
+ * @var array
*/
protected $defaultAcl = [
[
@@ -321,7 +321,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* Returns all the principal groups the specified principal is a member of.
*
- * @param string $principal
+ * @param string $mainPrincipal
* @return array
*/
function getPrincipalMembership($mainPrincipal) {
@@ -365,7 +365,7 @@ class Plugin extends DAV\ServerPlugin {
/**
* Find out of a principal equals another principal.
*
- * This is a quick way to find out wether a principal URI is part of a
+ * This is a quick way to find out whether a principal URI is part of a
* group, or any subgroups.
*
* The first argument is the principal URI you want to check against. For
@@ -373,10 +373,10 @@ class Plugin extends DAV\ServerPlugin {
* which you want to find out of it is the same as the first principal, or
* in a member of the first principal's group or subgroups.
*
- * So the arguments are not interchangable. If principal A is in group B,
+ * So the arguments are not interchangeable. If principal A is in group B,
* passing 'B', 'A' will yield true, but 'A', 'B' is false.
*
- * If the sceond argument is not passed, we will use the current user
+ * If the second argument is not passed, we will use the current user
* principal.
*
* @param string $checkPrincipal
@@ -412,8 +412,8 @@ class Plugin extends DAV\ServerPlugin {
* ]
* ]
*
- * Privileges can be nested using "aggregrates". Doing so means that
- * if you assign someone the aggregrating privilege, all the
+ * Privileges can be nested using "aggregates". Doing so means that
+ * if you assign someone the aggregating privilege, all the
* sub-privileges will automatically be granted.
*
* Marking a privilege as abstract means that the privilege cannot be
@@ -484,7 +484,7 @@ class Plugin extends DAV\ServerPlugin {
],
],
];
- if ($node instanceof \Sabre\DAV\ICollection) {
+ if ($node instanceof DAV\ICollection) {
$supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}bind'] = [
'abstract' => false,
'aggregates' => [],
@@ -494,7 +494,7 @@ class Plugin extends DAV\ServerPlugin {
'aggregates' => [],
];
}
- if ($node instanceof \Sabre\DAVACL\IACL) {
+ if ($node instanceof IACL) {
$supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}write-acl'] = [
'abstract' => false,
'aggregates' => [],
@@ -980,8 +980,6 @@ class Plugin extends DAV\ServerPlugin {
*
* @param DAV\PropFind $propFind
* @param DAV\INode $node
- * @param array $requestedProperties
- * @param array $returnedProperties
* @TODO really should be broken into multiple methods, or even a class.
* @return bool
*/
@@ -1423,7 +1421,7 @@ class Plugin extends DAV\ServerPlugin {
];
}
- // Replacing the property with its expannded form.
+ // Replacing the property with its expanded form.
$node[200][$propertyName] = $childProps;
}
diff --git a/vendor/sabre/dav/lib/DAVACL/Principal.php b/vendor/sabre/dav/lib/DAVACL/Principal.php
index 6ebb30907..d7db94999 100644
--- a/vendor/sabre/dav/lib/DAVACL/Principal.php
+++ b/vendor/sabre/dav/lib/DAVACL/Principal.php
@@ -41,7 +41,7 @@ class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL {
/**
* Creates the principal object
*
- * @param IPrincipalBackend $principalBackend
+ * @param PrincipalBackend\BackendInterface $principalBackend
* @param array $principalProperties
*/
function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = []) {
diff --git a/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php b/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php
index 2cb83071a..40b6e33ea 100644
--- a/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php
+++ b/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php
@@ -53,7 +53,7 @@ interface BackendInterface {
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param string $path
* @param \Sabre\DAV\PropPatch $propPatch
diff --git a/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php b/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php
index a491dc88f..eb0df888b 100644
--- a/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php
+++ b/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php
@@ -11,7 +11,7 @@ use Sabre\HTTP\URLUtil;
*
*
* This backend assumes all principals are in a single collection. The default collection
- * is 'principals/', but this can be overriden.
+ * is 'principals/', but this can be overridden.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
@@ -65,7 +65,7 @@ class PDO extends AbstractBackend implements CreatePrincipalSupport {
/**
* Sets up the backend.
*
- * @param PDO $pdo
+ * @param \PDO $pdo
*/
function __construct(\PDO $pdo) {
@@ -171,7 +171,7 @@ class PDO extends AbstractBackend implements CreatePrincipalSupport {
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
- * Read the PropPatch documenation for more info and examples.
+ * Read the PropPatch documentation for more info and examples.
*
* @param string $path
* @param DAV\PropPatch $propPatch
@@ -307,7 +307,7 @@ class PDO extends AbstractBackend implements CreatePrincipalSupport {
case "mailto":
$query = 'SELECT uri FROM ' . $this->tableName . ' WHERE lower(email)=lower(?)';
$stmt = $this->pdo->prepare($query);
- $stmt->execute([ $value ]);
+ $stmt->execute([$value]);
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
// Checking if the principal is in the prefix
diff --git a/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php b/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php
index d8a90153a..ee5b88a90 100644
--- a/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php
+++ b/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php
@@ -57,7 +57,7 @@ class PrincipalCollection extends AbstractPrincipalCollection implements IExtend
*
* @param string $name
* @param MkCol $mkCol
- * @throws Exception\InvalidResourceType
+ * @throws InvalidResourceType
* @return void
*/
function createExtendedCollection($name, MkCol $mkCol) {
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php
index 9f5e40df1..0e1c30ccf 100644
--- a/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php
@@ -78,12 +78,12 @@ class Acl implements Element, HtmlOutput {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -149,7 +149,7 @@ class Acl implements Element, HtmlOutput {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php
index f669cc5e1..8d5854c23 100644
--- a/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php
@@ -2,8 +2,8 @@
namespace Sabre\DAVACL\Xml\Property;
-use Sabre\Xml\XmlSerializable;
use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* AclRestrictions property
@@ -17,12 +17,12 @@ use Sabre\Xml\Writer;
class AclRestrictions implements XmlSerializable {
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php
index 0a95eb2b7..74c09cee1 100644
--- a/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php
@@ -41,12 +41,12 @@ class CurrentUserPrivilegeSet implements Element, HtmlOutput {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -99,7 +99,7 @@ class CurrentUserPrivilegeSet implements Element, HtmlOutput {
/**
* The deserialize method is called during xml parsing.
*
- * This method is called statictly, this is because in theory this method
+ * This method is called statically, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php
index d32249d8b..04d22165d 100644
--- a/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php
@@ -85,12 +85,12 @@ class Principal extends DAV\Xml\Property\Href {
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
index 55e7783ae..b963cc8c3 100644
--- a/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
@@ -4,8 +4,8 @@ namespace Sabre\DAVACL\Xml\Property;
use Sabre\DAV\Browser\HtmlOutput;
use Sabre\DAV\Browser\HtmlOutputHelper;
-use Sabre\Xml\XmlSerializable;
use Sabre\Xml\Writer;
+use Sabre\Xml\XmlSerializable;
/**
* SupportedPrivilegeSet property
@@ -53,12 +53,12 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
}
/**
- * The xmlSerialize metod is called during xml writing.
+ * The xmlSerialize method is called during xml writing.
*
* Use the $writer argument to write its own xml serialization.
*
* An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
+ * implementing XmlSerializable should only ever write what's considered
* its 'inner xml'.
*
* The parent of the current element is responsible for writing a
@@ -73,7 +73,7 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
*/
function xmlSerialize(Writer $writer) {
- $this->serializePriv($writer, '{DAV:}all', [ 'aggregates' => $this->privileges]);
+ $this->serializePriv($writer, '{DAV:}all', ['aggregates' => $this->privileges]);
}
@@ -114,7 +114,7 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
ob_start();
echo "
';
-
- return $o;
-
-}
-
-// used by site ratings pages to provide a return link
-function widget_pubsites($arr) {
- if(App::$poi)
- return;
- return '
';
-}
-
-
-function widget_forums($arr) {
-
- if(! local_channel())
- return '';
-
- $o = '';
-
- if(is_array($arr) && array_key_exists('limit',$arr))
- $limit = " limit " . intval($limit) . " ";
- else
- $limit = '';
-
- $unseen = 0;
- if(is_array($arr) && array_key_exists('unseen',$arr) && intval($arr['unseen']))
- $unseen = 1;
-
- $perms_sql = item_permissions_sql(local_channel()) . item_normal();
-
- $xf = false;
-
- $x1 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'send_stream' and v = '0'",
- intval(local_channel())
- );
- if($x1) {
- $xc = ids_to_querystr($x1,'xchan',true);
- $x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
- intval(local_channel())
- );
- if($x2)
- $xf = ids_to_querystr($x2,'xchan',true);
- }
-
- $sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
-
- $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d $sql_extra order by xchan_name $limit ",
- intval(local_channel())
- );
- if(! $r1)
- return $o;
-
- $str = '';
-
- // Trying to cram all this into a single query with joins and the proper group by's is tough.
- // There also should be a way to update this via ajax.
-
- for($x = 0; $x < count($r1); $x ++) {
- $r = q("select sum(item_unseen) as unseen from item where owner_xchan = '%s' and uid = %d and item_unseen = 1 $perms_sql ",
- dbesc($r1[$x]['xchan_hash']),
- intval(local_channel())
- );
- if($r)
- $r1[$x]['unseen'] = $r[0]['unseen'];
-
-/**
- * @FIXME
- * This SQL makes the counts correct when you get forum posts arriving from different routes/sources
- * (like personal channels). However the network query for these posts doesn't yet include this
- * correction and it makes the SQL for that query pretty hairy so this is left as a future exercise.
- * It may make more sense in that query to look for the mention in the body rather than another join,
- * but that makes it very inefficient.
- *
- $r = q("select sum(item_unseen) as unseen from item left join term on oid = id where otype = %d and owner_xchan != '%s' and item.uid = %d and url = '%s' and ttype = %d $perms_sql ",
- intval(TERM_OBJ_POST),
- dbesc($r1[$x]['xchan_hash']),
- intval(local_channel()),
- dbesc($r1[$x]['xchan_url']),
- intval(TERM_MENTION)
- );
- if($r)
- $r1[$x]['unseen'] = ((array_key_exists('unseen',$r1[$x])) ? $r1[$x]['unseen'] + $r[0]['unseen'] : $r[0]['unseen']);
- *
- * end @FIXME
- */
-
- }
-
- if($r1) {
- $o .= '
");_bb=_b7.firstChild}else{dom.setInnerHtml(_b7,"X X X")}var _bd=_bb.getClientRects();_b8=_bd[1].bottom-_bd[1].top;_b8=Math.ceil(_b8*0.8);if(_bc){dom.setInnerHtml(_b7,"
"+_ba+"
");_bb=_b7.firstChild}else{dom.setInnerHtml(_b7,_ba)}_bd=_bb.getClientRects();_b9=_bd.length;if(_bc){dom.setInnerHtml(_b7,_ba)}_b7.style.visibility=_b7.style.width=_b7.style.height=_b7.style.maxWidth=_b7.style.maxHeight=_b7.style.overflow=_b7.style.styleFloat=_b7.style.position=_b7.style.zoom=_b7.style.writingMode=""}}return {lineHeight:_b8,lines:_b9}}this.replace=function(_be,_bf){if(!ua.supported){return}if(_bf){for(var _c0 in _be){if(typeof (_bf[_c0])=="undefined"){_bf[_c0]=_be[_c0]}}_be=_bf}if(!_4c){return _9b.kwargs.push(_be)}if(_66.synchronizer.isBlocked){return _96.kwargs.push(_be)}var _c1=_be.elements;if(!_c1&&parseSelector){_c1=parseSelector(_be.selector)}if(_c1.length==0){return}this.setFlashClass();var src=getSource(_be.src);var css=_72.convertCssArg(_be.css);var _c4=getFilters(_be.filters);var _c5=(_be.forceClear==null)?_3b.forceClear:_be.forceClear;var _c6=(_be.fitExactly==null)?_3b.fitExactly:_be.fitExactly;var _c7=_c6||(_be.forceWidth==null?_3b.forceWidth:_be.forceWidth);var _c8=parseInt(_72.extractFromCss(css,".sIFR-root","leading"))||0;var _c9=_72.extractFromCss(css,".sIFR-root","font-size",true)||0;var _ca=_72.extractFromCss(css,".sIFR-root","background-color",true)||"#FFFFFF";var _cb=_72.extractFromCss(css,".sIFR-root","kerning",true)||"";var _cc=_be.gridFitType||_72.extractFromCss(css,".sIFR-root","text-align")=="right"?"subpixel":"pixel";var _cd=_3b.forceTextTransform?_72.extractFromCss(css,".sIFR-root","text-transform",true)||"none":"none";var _ce=_72.extractFromCss(css,".sIFR-root","opacity",true)||"100";var _cf=_be.pixelFont||false;var _d0=_be.ratios||_48;if(parseInt(_c9).toString()!=_c9&&_c9.indexOf("px")==-1){_c9=0}else{_c9=parseInt(_c9)}if(parseFloat(_ce)<1){_ce=100*parseFloat(_ce)}var _d1=null;var _d2="";if(_c6){_72.extractFromCss(css,".sIFR-root","text-align",true)}if(!_be.modifyCss){_d2=_72.cssToString(css);_d1=_3b.fixHover&&_d2.indexOf("%3Ahover")>-1}var _d3=!ua.opera&&_3b.delayCss;var _d4=_be.wmode||"";if(!_d4){if(_be.transparent){_d4="transparent"}else{if(_be.opaque){_d4="opaque"}}}if(_d4=="transparent"){if(!ua.transparencySupport){_d4="opaque"}else{_ca="transparent"}}for(var i=0;i<_c1.length;i++){var _d6=_c1[i];if(!ua.verifiedKonqueror){if(dom.getComputedStyle(_d6,"lineHeight").match(/e\+08px/)){ua.supported=_3b.isEnabled=false;this.removeFlashClass();return}ua.verifiedKonqueror=true}if(dom.hasOneOfClassses([_3d,_3e,_40,_41],_d6)){continue}var _d7=_d6.offsetHeight;var _d8=_d6.offsetWidth;var _d9=dom.getComputedStyle(_d6,"display");if(!_d7||!_d8||_d9==null||_d9=="none"){continue}if(_c5&&ua.gecko){_d6.style.clear="both"}var _da=null;if(_3b.fixWrap&&ua.ie&&_d9=="block"){_da=_d6.innerHTML;dom.setInnerHtml(_d6,"X")}_d8=dom.getStyleAsInt(_d6,"width",ua.ie);if(_d8==0){var _db=dom.getStyleAsInt(_d6,"paddingRight",true);var _dc=dom.getStyleAsInt(_d6,"paddingLeft",true);var _dd=dom.getStyleAsInt(_d6,"borderRightWidth",true);var _de=dom.getStyleAsInt(_d6,"borderLeftWidth",true);_d8=_d6.offsetWidth-_dc-_db-_de-_dd}if(_da&&_3b.fixWrap&&ua.ie){dom.setInnerHtml(_d6,_da)}var _df,_e0;if(!_c9){var _e1=calculate(_d6);_df=Math.min(_45,Math.max(_44,_e1.lineHeight));if(_cf){_df=Math.max(8,8*Math.round(_df/8))}_e0=_e1.lines;if(isNaN(_e0)||!isFinite(_e0)||_e0==0){_e0=1}if(_e0>1&&_c8){_d7+=Math.round((_e0-1)*_c8)}}else{_df=_c9;_e0=1}_d7=Math.round(_e0*_df);if(_c5&&ua.gecko){_d6.style.clear=""}var _e2=dom.create("span");_e2.className=_41;var _e3=_d6.cloneNode(true);for(var j=0,l=_e3.childNodes.length;j-1}var _e6=handleContent(_e3,_cd);if(_be.modifyContentString){_e6=_be.modifyContentString(_e6,_be.selector)}if(_e6==""){continue}var _e7=["content="+_e6,"width="+_d8,"height="+_d7,"fitexactly="+(_c6?"true":""),"tunewidth="+(_be.tuneWidth||""),"tuneheight="+(_be.tuneHeight||""),"offsetleft="+(_be.offsetLeft||""),"offsettop="+(_be.offsetTop||""),"thickness="+(_be.thickness||""),"sharpness="+(_be.sharpness||""),"kerning="+_cb,"gridfittype="+_cc,"zoomsupport="+ua.zoomSupport,"flashfilters="+_c4,"opacity="+_ce,"blendmode="+(_be.blendMode||""),"size="+_df,"zoom="+dom.getZoom(),"css="+_d2,"selectable="+(_be.selectable==null?"true":_be.selectable),"lines="+_e0];var _e8=encodeURI(_e7.join("&"));var _e9="sIFR_callback_"+_4a++;var _ea=new CallbackInfo(_e9,_e7,_be.onReplacement,_d1);window[_e9+"_DoFSCommand"]=(function(_eb){return function(_ec,arg){_eb.handle(_ec,arg)}})(_ea);_d7=Math.round(_e0*getRatio(_df,_d0)*_df)+_49;var _ee=_c7?_d8:"100%";var _ef;if(ua.ie){_ef=["","",_e9,"_DoFSCommand(info, args);","","script>"].join("")}else{_ef=[""].join("")}dom.setInnerHtml(_d6,_ef);_ea.flashNode=_d6.firstChild;_ea.html=_ef;_3b.callbacks.push(_ea);if(_be.selector){if(!_3b.callbacks[_be.selector]){_3b.callbacks[_be.selector]=[_ea]}else{_3b.callbacks[_be.selector].push(_ea)}}_d6.appendChild(_e2);dom.addClass(_d3?_3e:_3d,_d6);_ea.setupFixHover()}_66.fragmentIdentifier.restore()};this.getCallbackByFlashElement=function(_f0){for(var i=0;i<_3b.callbacks.length;i++){if(_3b.callbacks[i].id==_f0.getAttribute("id")){return _3b.callbacks[i]}}};function handleContent(_f2,_f3){var _f4=[],_f5=[];var _f6=_f2.childNodes;var i=0;while(i<_f6.length){var _f8=_f6[i];if(_f8.nodeType==3){var _f9=_72.normalize(_f8.nodeValue);_f9=_72.textTransform(_f3,_f9);_f5.push(_f9.replace(/\%/g,"%25").replace(/\&/g,"%26").replace(/\,/g,"%2C").replace(/\+/g,"%2B"))}if(_f8.nodeType==1){var _fa=[];var _fb=_f8.nodeName.toLowerCase();var _fc=_f8.className||"";if(/\s+/.test(_fc)){if(_fc.indexOf(_42)>-1){_fc=_fc.match("(\\s|^)"+_42+"-([^\\s$]*)(\\s|$)")[2]}else{_fc=_fc.match(/^([^\s]+)/)[1]}}if(_fc!=""){_fa.push("class=\""+_fc+"\"")}if(_fb=="a"){var _fd=_f8.getAttribute("href")||"";var _fe=_f8.getAttribute("target")||"";_fa.push("href=\""+_fd+"\"","target=\""+_fe+"\"")}_f5.push("<"+_fb+(_fa.length>0?" ":"")+escape(_fa.join(" "))+">");if(_f8.hasChildNodes()){_f4.push(i);i=0;_f6=_f8.childNodes;continue}else{if(!/^(br|img)$/i.test(_f8.nodeName)){_f5.push("",_f8.nodeName.toLowerCase(),">")}}}if(_f4.length>0&&!_f8.nextSibling){do{i=_f4.pop();_f6=_f8.parentNode.parentNode.childNodes;_f8=_f6[i];if(_f8){_f5.push("",_f8.nodeName.toLowerCase(),">")}}while(i==_f6.length-1&&_f4.length>0)}i++}return _f5.join("").replace(/\n|\r/g,"")}function CallbackInfo(id,vars,_101,_102){this.id=id;this.vars=vars;this._replacementHandler=_101;this._firedReplacementEvent=!(this._replacementHandler!=null);this._fixHover=_102;this._setClasses=!_3b.delayCss;this.html="";this._pings=0}CallbackInfo.prototype.getFlashElement=function(){return document.getElementById(this.id)};CallbackInfo.prototype.handle=function(info,arg){if(/(FSCommand\:)?resize/.test(info)){var _105=this.getFlashElement();var $=arg.split(/\:|,/);_105.setAttribute($[0],$[1]);if($.length>2){_105.setAttribute($[2],$[3])}if(!this._setClasses){if(!ua.ie&&!ua.opera){dom.addClass(_3f,_105)}dom.removeClass(_3e,_105.parentNode);dom.addClass(_3d,_105.parentNode);this._setClasses=true}if(ua.khtml){var _107=_105.offsetHeight}if(!this._firedReplacementEvent){this._replacementHandler(this);this._firedReplacementEvent=true}}else{if(/(FSCommand\:)?resetmovie/.test(info)){this.resetMovie()}else{if(/(FSCommand\:)?ping/.test(info)){if(this._pings>0){this.setupFixHover()}this._pings++}else{if(this.debugHandler&&/(FSCommand\:)?debug/.test(info)){this.debugHandler(info,arg)}}}}};CallbackInfo.prototype.call=function(type,_109){var _10a=this.getFlashElement();if(!_10a){return}_10a.SetVariable("callbackType",type);_10a.SetVariable("callbackValue",_109);_10a.SetVariable("callbackTrigger",true)};CallbackInfo.prototype.replaceText=function(_10b){_10b=escape(_10b);this.call("replacetext",_10b);this.vars[0]="content="+_10b;this.html=this.html.replace(/(flashvars(=|\"\svalue=)\")[^\"]+/,"$1"+encodeURI(this.vars.join("&")))};CallbackInfo.prototype.resetMovie=function(){var _10c=this.getFlashElement();var node=_10c.parentNode;node.replaceChild(dom.nodeFromHtml(this.html),_10c);this.setupFixHover()};CallbackInfo.prototype.setupFixHover=function(){var _10e=this.getFlashElement();if(!this._fixHover||!_10e){return}var node=_10e.parentNode;if(node.addEventListener){node.addEventListener("mouseout",_72.bind(this,"fixHover"),false)}else{if(node.attachEvent){node.attachEvent("onmouseout",_72.bind(this,"fixHover"))}}};CallbackInfo.prototype.fixHover=function(){this.call("resettext")}};
\ No newline at end of file
diff --git a/library/simplepie/demo/for_the_demo/simplepie.css b/library/simplepie/demo/for_the_demo/simplepie.css
deleted file mode 100644
index 3753cb96d..000000000
--- a/library/simplepie/demo/for_the_demo/simplepie.css
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
-Theme Name: SimplePie
-Theme URI: http://simplepie.org
-Description: A simple, yet beautiful theme inspired by several cleanly designed websites.
-Version: 1.4
-Author: Ryan Parman
-Author URI: http://skyzyx.com
-Updated: 21 June 2007
-*/
-
-
-/*********************************************
-HYPERLINK STYLES
-*********************************************/
-a {
- color:#369;
- text-decoration:underline;
- padding:0 1px;
-}
-
-a:hover {
- color:#fff !important;
- background-color:#333;
- text-decoration:none;
- padding:0 1px;
-}
-
-a.nohover {
- text-decoration:none;
- border:none;
-}
-
-a.nohover:hover {
- background-color:transparent;
- border:none;
-}
-
-a.namelink {
- padding:0;
- margin:0;
- overflow:hidden;
- height:1px;
-}
-
-h4 a,
-.sample_feeds a {
- color:#000;
-}
-
-
-/*********************************************
-GENERAL STYLES
-*********************************************/
-body {
- /*font:12px/18px Verdana, sans-serif;*/
- font:14px/1.5em "Lucida Grande", Tahoma, sans-serif;
- letter-spacing:0px;
- color:#333;
- background-color:#fff;
- margin:0;
- padding:0;
-}
-
-div#site {
- width:600px;
- margin:50px auto 0 auto;
-}
-
-h1#logo {
- margin:0;
- padding:0;
- text-align:center;
-}
-
-h1#logo a,
-h1#logo a:hover {
- background-color:transparent;
- text-decoration:none;
- padding:0;
-}
-
-h2.image {
- margin:0;
- padding:0;
- text-align:center;
-}
-
-h3 {
- margin:20px 0 0 0;
- padding:0;
- font-size:1.5em;
-}
-
-h4 {
- margin:20px 0 0 0;
- padding:0;
- font-size:1.2em;
- letter-spacing:-1px;
-}
-
-h5 {
- margin:10px 0 0 0;
- padding:0;
- font-size:1em;
- font-weight:bold;
-}
-
-em {
- font-style:normal;
- background-color:#ffc;
-}
-
-p {
- margin:0;
- padding:5px 0;
-}
-
-ul, ol {
- margin:10px 0 10px 20px;
- padding:0 0 0 15px;
-}
-
-ul li, ol li {
- margin:0 0 7px 0;
- padding:0 0 0 3px;
-}
-
-form {
- margin:0;
- padding:0;
-}
-
-code {
- font-size:1em;
- background-color:#f3f3ff;
- color:#000;
-}
-
-div#site pre {
- background-color:#f3f3ff;
- color:#000080;
- border:1px dotted #000080;
- overflow:auto;
- padding:3px 5px;
-}
-
-blockquote {
- font-size:1em;
- color:#666;
- border-left:4px solid #666;
- margin:10px 0 10px 30px;
- padding:0 5px 0 10px;
- background:#f3f3f3 url(background_blockquote.png) repeat top left;
-}
-
-input, select, textarea {
- font-size:12px;
- line-height:1.2em;
- padding:2px;
-}
-
-input[type=text], select, textarea {
- background-color:#e9f5ff;
- border:1px solid #333;
-}
-
-input[type=text]:focus, select:focus, textarea:focus {
- background-color:#ffe;
-}
-
-.clearLeft {clear:left;}
-.clearRight {clear:right;}
-.clearBoth {clear:both;}
-.hide {display:none;}
-
-
-/*********************************************
-NAVIGATION STYLES
-*********************************************/
-div#header {
- background:#fff url(top_gradient.gif) repeat-x top left;
- margin:0;
- padding:0;
-}
-
-div#header form {
- margin:0;
- padding:0;
-}
-
-div#header div#headerInner {
- margin:0;
- padding:0;
-}
-
-div#header div#headerInner div#logoContainer {}
-
-div#header div#headerInner div#logoContainerInner {
- width:550px;
- margin:0 auto;
- padding:20px;
-}
-
-div#header div#headerInner div#logoContainer div#logo {
- float:left;
- width:200px;
-}
-
-div#header div#headerInner div#logoContainer div#logo a,
-div#header div#headerInner div#logoContainer div#logo a:hover {
- border:none;
- background:none;
-}
-
-div#header div#headerInner div#logoContainer div#feed {
- float:right;
- width:300px;
- text-align:right;
- padding:10px 0 0 0;
-}
-
-div#header div#headerInner div#logoContainer div#feed input.text {
- width:60%;
-}
-
-div#header div#headerInner div#menu {
- background:#eee url(background_menuitem_shadow.gif) repeat-x top left;
- border-top:2px solid #ccc;
- border-bottom:1px solid #ddd;
- text-align:center;
-}
-
-div#header div#headerInner div#menu table {
- width:auto;
- margin:0 auto;
-}
-
-div#header div#headerInner div#menu ul {
- display:block;
- width:100%;
- margin:0 auto;
- padding:0;
- font-size:12px;
-}
-
-div#header div#headerInner div#menu ul li {
- display:block;
- float:left;
-}
-
-div#header div#headerInner div#menu ul li a {
- display:block;
- margin:-2px 0 0 0;
- padding:5px 7px 8px 7px;
- text-decoration:none;
- color:#666 !important;
- background-color:transparent;
-}
-
-div#header div#headerInner div#menu ul li a:hover {
- display:block;
- margin:-2px 0 0 0;
- padding:5px 7px 8px 7px;
- text-decoration:none;
- color:#666;
- background:#fff url(background_menuitem_off.gif) no-repeat bottom right;
-}
-
-body#bodydemo div#header div#headerInner div#menu ul li#demo a {
- display:block;
- margin:-2px 0 0 0;
- padding:5px 7px 8px 7px;
- text-decoration:none;
- color:#333;
- font-weight:bold;
- background:#fff url(background_menuitem.gif) no-repeat bottom right;
-}
-
-
-/*********************************************
-CONTENT STYLES
-*********************************************/
-div.chunk {
- margin:20px 0 0 0;
- padding:0 0 10px 0;
- border-bottom:1px solid #ccc;
-}
-
-div.topchunk {
- margin:0 !important;
-}
-
-.footnote,
-.footnote a {
- font-size:12px;
- line-height:1.3em;
- color:#aaa;
-}
-
-.footnote em {
- background-color:transparent;
- font-style:italic;
-}
-
-.footnote code {
- background-color:transparent;
- font:11px/14px monospace;
- color:#aaa;
-}
-
-p.subscribe {
- background-color:#f3f3f3;
- font-size:12px;
- text-align:center;
-}
-
-p.highlight {
- background-color:#ffc;
- font-size:12px;
- text-align:center;
-}
-
-p.sample_feeds {
- font-size:12px;
- line-height:1.2em;
-}
-
-div.sp_errors {
- background-color:#eee;
- padding:5px;
- text-align:center;
- font-size:12px;
-}
-
-.noborder {
- border:none !important;
-}
-
-img.favicon {
- margin:0 4px -2px 0;
- width:16px;
- height:16px;
-}
-
-p.favicons a,
-p.favicons a:hover {
- border:none;
- background-color:transparent;
-}
-
-p.favicons img {
- border:none;
-}
-
-
-/*********************************************
-DEMO STYLES
-*********************************************/
-div#sp_input {
- background-color:#ffc;
- border:2px solid #f90;
- padding:5px;
- text-align:center;
-}
-
-div#sp_input input.text {
- border:1px solid #999;
- background:#e9f5ff url(feed.png) no-repeat 4px 50%;
- width:75%;
- padding:2px 2px 2px 28px;
- font:18px/22px "Lucida Grande", Verdana, sans-serif;
- font-weight:bold;
- letter-spacing:-1px;
-}
-
-form#sp_form {
- margin:15px 0;
-}
-
-div.focus {
- margin:0;
- padding:10px 20px;
- background-color:#efe;
-}
-
-p.sample_feeds {
- text-align:justify;
-}
-
-
-/*********************************************
-SIFR STYLES
-*********************************************/
-.sIFR-active h3.header {
- visibility:hidden;
- line-height:1em;
-}
diff --git a/library/simplepie/demo/for_the_demo/sleight.js b/library/simplepie/demo/for_the_demo/sleight.js
deleted file mode 100644
index 4b5058e9a..000000000
--- a/library/simplepie/demo/for_the_demo/sleight.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**********************************************************
-Sleight
-(c) 2001, Aaron Boodman
-http://www.youngpup.net
-**********************************************************/
-
-if (navigator.platform == "Win32" && navigator.appName == "Microsoft Internet Explorer" && window.attachEvent)
-{
- document.writeln('');
- window.attachEvent("onload", fnLoadPngs);
-}
-
-function fnLoadPngs()
-{
- var rslt = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
- var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);
-
- for (var i = document.images.length - 1, img = null; (img = document.images[i]); i--)
- {
- if (itsAllGood && img.src.match(/\.png$/i) != null)
- {
- var src = img.src;
- var div = document.createElement("DIV");
- div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizing='scale')"
- div.style.width = img.width + "px";
- div.style.height = img.height + "px";
- img.replaceNode(div);
- }
- img.style.visibility = "visible";
- }
-}
diff --git a/library/simplepie/demo/for_the_demo/source_files/place_audio_fireworksfile.png b/library/simplepie/demo/for_the_demo/source_files/place_audio_fireworksfile.png
deleted file mode 100644
index 2bfd87d0c..000000000
Binary files a/library/simplepie/demo/for_the_demo/source_files/place_audio_fireworksfile.png and /dev/null differ
diff --git a/library/simplepie/demo/for_the_demo/source_files/place_video_fireworksfile.png b/library/simplepie/demo/for_the_demo/source_files/place_video_fireworksfile.png
deleted file mode 100644
index d0629769c..000000000
Binary files a/library/simplepie/demo/for_the_demo/source_files/place_video_fireworksfile.png and /dev/null differ
diff --git a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/SifrStyleSheet.as b/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/SifrStyleSheet.as
deleted file mode 100644
index 6a98ca552..000000000
--- a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/SifrStyleSheet.as
+++ /dev/null
@@ -1,71 +0,0 @@
-/*=:project
- scalable Inman Flash Replacement (sIFR) version 3.
-
- =:file
- Copyright: 2006 Mark Wubben.
- Author: Mark Wubben,
-
- =:history
- * IFR: Shaun Inman
- * sIFR 1: Mike Davidson, Shaun Inman and Tomas Jogin
- * sIFR 2: Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
-
- =:license
- This software is licensed and provided under the CC-GNU LGPL.
- See
-*/
-
-import TextField.StyleSheet;
-
-class SifrStyleSheet extends TextField.StyleSheet {
- public var fontSize;
- public var latestLeading = 0;
-
- public function parseCSS(cssText:String) {
- var native = new TextField.StyleSheet();
- var parsed = native.parseCSS(cssText);
-
- if(!parsed) return false;
-
- var selectors = native.getStyleNames();
- for(var i = selectors.length - 1; i >= 0; i--) {
- var selector = selectors[i];
- var nativeStyle = native.getStyle(selector);
- var style = this.getStyle(selector) || nativeStyle;
- if(style != nativeStyle) {
- for(var property in nativeStyle) style[property] = nativeStyle[property];
- }
- this.setStyle(selector, style);
- }
-
- return true;
- }
-
- // Apply leading to the textFormat. Much thanks to .
- private function applyLeading(format, leading) {
- this.latestLeading = leading;
-
- if(leading >= 0) {
- format.leading = leading;
- return format;
- }
-
- // Workaround for negative leading, which is ignored otherwise.
- var newFormat = new TextFormat(null, null, null, null, null, null, null, null, null, null, null, null, leading);
- for(var property in format) if(property != 'leading') newFormat[property] = format[property];
-
- return newFormat;
- }
-
- public function transform(style) {
- var format = super.transform(style);
- if(style.leading) format = applyLeading(format, style.leading);
- if(style.letterSpacing) format.letterSpacing = style.letterSpacing;
- // Support font sizes relative to the size of .sIFR-root.
- if(this.fontSize && style.fontSize && style.fontSize.indexOf('%')) {
- format.size = this.fontSize * parseInt(style.fontSize) / 100;
- }
- format.kerning = _root.kerning == 'true' || !(_root.kerning == 'false') || sIFR.defaultKerning;
- return format;
- }
-}
\ No newline at end of file
diff --git a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/_README_.txt b/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/_README_.txt
deleted file mode 100644
index 2b9d32d20..000000000
--- a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/_README_.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a pre-release nightly of sIFR 3 (r245 to be exact). We (the SimplePie team) will be updating the
-sIFR code and font files from time to time as new releases of sIFR 3 are made available.
-
-In this folder you'll find a few Flash 8 files. The only one of you might want to mess with is sifr.fla.
- * Open it up
- * Double-click the rectangle in the middle
- * Select all
- * Change the font
-
-More information about sIFR 3 can be found here:
- * http://dev.novemberborn.net/sifr3/
- * http://wiki.novemberborn.net/sifr3/
\ No newline at end of file
diff --git a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/options.as b/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/options.as
deleted file mode 100644
index 4d371954b..000000000
--- a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/options.as
+++ /dev/null
@@ -1,12 +0,0 @@
-// MTASC only parses as-files with class definitions, so here goes...
-class Options {
- public static function apply() {
- sIFR.fromLocal = true;
- sIFR.domains = ['*'];
-
- // Parsing `p.foo` might not work, see:
- // Appearantly you have to use hex color codes as well, names are not supported!
-
- sIFR.styles.parseCSS('.foo { text-decoration: underline; }');
- }
-}
diff --git a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/sIFR.as b/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/sIFR.as
deleted file mode 100644
index 4902e003f..000000000
--- a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/sIFR.as
+++ /dev/null
@@ -1,359 +0,0 @@
-/*=:project
- scalable Inman Flash Replacement (sIFR) version 3.
-
- =:file
- Copyright: 2006 Mark Wubben.
- Author: Mark Wubben,
-
- =:history
- * IFR: Shaun Inman
- * sIFR 1: Mike Davidson, Shaun Inman and Tomas Jogin
- * sIFR 2: Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
-
- =:license
- This software is licensed and provided under the CC-GNU LGPL.
- See
-*/
-
-import SifrStyleSheet;
-
-class sIFR {
- public static var DEFAULT_TEXT = 'Rendered with sIFR 3, revision 245';
- public static var CSS_ROOT_CLASS = 'sIFR-root';
- public static var DEFAULT_WIDTH = 300;
- public static var DEFAULT_HEIGHT = 100;
- public static var DEFAULT_ANTI_ALIAS_TYPE = 'advanced';
- public static var MARGIN_LEFT = -3;
- public static var PADDING_BOTTOM = 5; // Extra padding to make sure the movie is high enough in most cases.
- public static var LEADING_REMAINDER = 2; // Flash uses the specified leading minus 2 as the applied leading.
-
- public static var MAX_FONT_SIZE = 126;
- public static var ALIASING_MAX_FONT_SIZE = 48;
-
- //= Holds CSS properties and other rendering properties for the Flash movie.
- // *Don't overwrite!*
- public static var styles:SifrStyleSheet = new SifrStyleSheet();
- //= Allow sIFR to be run from localhost
- public static var fromLocal:Boolean = true;
- //= Array containing domains for which sIFR may render text. Used to prevent
- // hotlinking. Use `*` to allow all domains.
- public static var domains:Array = [];
- //= Whether kerning is enabled by default. This can be overriden from the client side.
- // See also .
- public static var defaultKerning:Boolean = true;
- //= Default value which can be overriden from the client side.
- // See also .
- public static var defaultSharpness:Number = 0;
- //= Default value which can be overriden from the client side.
- // See also .
- public static var defaultThickness:Number = 0;
- //= Default value which can be overriden from the client side.
- // See also .
- public static var defaultOpacity:Number = -1; // Use client settings
- //= Default value which can be overriden from the client side.
- // See also .
- public static var defaultBlendMode:Number = -1; // Use cliest settings
- //= Overrides the grid fit type as defined on the client side.
- // See also .
- public static var enforcedGridFitType:String = null;
- //= If `true` sIFR won't override the anti aliasing set in the Flash IDE when exporting.
- // Thickness and sharpness won't be affected either.
- public static var preserveAntiAlias:Boolean = false;
- //= If `true` sIFR will disable anti-aliasing if the font size is larger than `ALIASING_MAX_FONT_SIZE`.
- // This setting is *independent* from `preserveAntiAlias`.
- public static var conditionalAntiAlias:Boolean = true;
- //= Sets the anti alias type. By default it's `DEFAULT_ANTI_ALIAS_TYPE`.
- // See also .
- public static var antiAliasType:String = null;
- //= Flash filters can be added to this array and will be applied to the text field.
- public static var filters:Array = [];
- //= A mapping from the names of the filters to their actual objecs, used when transforming
- // filters defined on the client. You can add additional filters here so they'll be supported
- // when defined on the client.
- public static var filterMap:Object = {
- DisplacementMapFilter : flash.filters.DisplacementMapFilter,
- ColorMatrixFilter : flash.filters.ColorMatrixFilter,
- ConvolutionFilter : flash.filters.ConvolutionFilter,
- GradientBevelFilter : flash.filters.GradientBevelFilter,
- GradientGlowFilter : flash.filters.GradientGlowFilter,
- BevelFilter : flash.filters.BevelFilter,
- GlowFilter : flash.filters.GlowFilter,
- BlurFilter : flash.filters.BlurFilter,
- DropShadowFilter : flash.filters.DropShadowFilter
- };
-
- private static var instance;
-
- private var textField;
- private var content;
- private var realHeight;
- private var originalHeight;
- private var currentHeight;
- private var fontSize;
- private var tuneWidth;
- private var tuneHeight;
-
-
-
- //= Sets the default styles for `sIFR.styles`. This method is called
- // directly in `sifr.fla`, before options are applied.
- public static function setDefaultStyles() {
- sIFR.styles.parseCSS([
- '.', CSS_ROOT_CLASS, ' { color: #000000; }',
- 'strong { display: inline; font-weight: bold; } ',
- 'em { display: inline; font-style: italic; }',
- 'a { color: #0000FF; text-decoration: underline; }',
- 'a:hover { color: #0000FF; text-decoration: none; }'
- ].join(''));
- }
-
- //= Validates the domain sIFR is being used on.
- // Returns `true` if the domain is valid, `false` otherwise.
- public static function checkDomain():Boolean {
- if(sIFR.domains.length == 0) return true;
-
- var domain = (new LocalConnection()).domain();
- if(sIFR.fromLocal) sIFR.domains.push('localhost');
-
- for(var i = 0; i < sIFR.domains.length; i++) {
- var match = sIFR.domains[i];
- if(match == '*' || match == domain) return true;
-
- var wildcard = match.lastIndexOf('*');
- if(wildcard > -1) {
- match = match.substr(wildcard + 1);
- var matchPosition = domain.lastIndexOf(match);
- if(matchPosition > -1 && (matchPosition + match.length) == domain.length) return true;
- }
- }
-
- return false;
- }
-
- //= Runs sIFR. Called automatically.
- public static function run() {
- var holder = _root.holder;
- var content = checkDomain() ? unescape(_root.content) : DEFAULT_TEXT
- if(content == 'undefined' || content == '') {
- content = DEFAULT_TEXT;
- fscommand('resetmovie', '');
- } else fscommand('ping', '');
-
- // Sets stage parameters
- Stage.scaleMode = 'noscale';
- Stage.align = 'TL';
- Stage.showMenu = false;
-
- // Other parameters
- var opacity = parseInt(_root.opacity);
- if(!isNaN(opacity)) holder._alpha = sIFR.defaultOpacity == -1 ? opacity : sIFR.defaultOpacity;
- else holder._alpha = 100;
- _root.blendMode = sIFR.defaultBlendMode == -1 ? _root.blendmode : sIFR.defaultBlendMode;
-
- sIFR.instance = new sIFR(holder.txtF, content);
- // This should ignore resizes from the callback. Disabled for now.
-/* if(_root.zoomsupport == 'true') Stage.addListener({onResize: function() { sIFR.instance.scale() }});*/
-
- // Setup callbacks
- _root.watch('callbackTrigger', function() {
- sIFR.callback();
- return false;
- });
- }
-
- private static function eval(str) {
- var as;
-
- if(str.charAt(0) == '{') { // Ah, we need to create an object
- as = {};
- str = str.substring(1, str.length - 1);
- var $ = str.split(',');
- for(var i = 0; i < $.length; i++) {
- var $1 = $[i].split(':');
- as[$1[0]] = sIFR.eval($1[1]);
- }
- } else if(str.charAt(0) == '"') { // String
- as = str.substring(1, str.length - 1);
- } else if(str == 'true' || str == 'false') { // Boolean
- as = str == 'true';
- } else { // Float
- as = parseFloat(str);
- }
-
- return as;
- }
-
- private function applyFilters() {
- var $filters = this.textField.filters;
- $filters = $filters.concat(sIFR.filters);
-
- var $ = _root.flashfilters.split(';'); // name,prop:value,...;
- for(var i = 0; i < $.length; i++) {
- var $1 = $[i].split(',');
-
- var newFilter = new sIFR.filterMap[$1[0]]();
- for(var j = 1; j < $1.length; j++) {
- var $2 = $1[j].split(':');
- newFilter[$2[0]] = sIFR.eval(unescape($2[1]));
- }
-
- $filters.push(newFilter);
- }
-
- this.textField.filters = $filters;
- }
-
- private function sIFR(textField, content) {
- this.textField = textField;
- this.content = content;
-
- var offsetLeft = parseInt(_root.offsetleft);
- textField._x = MARGIN_LEFT + (isNaN(offsetLeft) ? 0 : offsetLeft);
- var offsetTop = parseInt(_root.offsettop);
- if(!isNaN(offsetTop)) textField._y += offsetTop;
-
- tuneWidth = parseInt(_root.tunewidth);
- if(isNaN(tuneWidth)) tuneWidth = 0;
- tuneHeight = parseInt(_root.tuneheight);
- if(isNaN(tuneHeight)) tuneHeight = 0;
-
- textField._width = tuneWidth + (isNaN(parseInt(_root.width)) ? DEFAULT_WIDTH : parseInt(_root.width));
- textField._height = tuneHeight + (isNaN(parseInt(_root.height)) ? DEFAULT_HEIGHT : parseInt(_root.height));
- textField.wordWrap = true;
- textField.selectable = _root.selectable == 'true';
- textField.gridFitType = sIFR.enforcedGridFitType || _root.gridfittype;
- this.applyFilters();
-
- // Determine font-size and the number of lines
- this.fontSize = parseInt(_root.size);
- if(isNaN(this.fontSize)) this.fontSize = 26;
- styles.fontSize = this.fontSize;
-
- if(!sIFR.preserveAntiAlias && (sIFR.conditionalAntiAlias && this.fontSize < ALIASING_MAX_FONT_SIZE
- || !sIFR.conditionalAntiAlias)) {
- textField.antiAliasType = sIFR.antiAliasType || DEFAULT_ANTI_ALIAS_TYPE;
- }
-
- if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.sharpness))) {
- textField.sharpness = parseInt(_root.sharpness);
- }
- if(isNaN(textField.sharpness)) textField.sharpness = sIFR.defaultSharpness;
-
- if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.thickness))) {
- textField.thickness = parseInt(_root.thickness);
- }
- if(isNaN(textField.thickness)) textField.thickness = sIFR.defaultThickness;
-
- // Set font-size and other styles
- sIFR.styles.parseCSS(unescape(_root.css));
-
- var rootStyle = styles.getStyle('.sIFR-root') || {};
- rootStyle.fontSize = this.fontSize; // won't go higher than 126!
- styles.setStyle('.sIFR-root', rootStyle);
- textField.styleSheet = styles;
-
- this.write(content);
- this.repaint();
- }
-
- private function repaint() {
- var leadingFix = this.isSingleLine() ? sIFR.styles.latestLeading : 0;
- if(leadingFix > 0) leadingFix -= LEADING_REMAINDER;
-
- // Flash wants to scroll the movie by one line, by adding the fontSize to the
- // textField height this is no longer happens. We also add the absolute tuneHeight,
- // to prevent a negative value from triggering the bug. We won't send the fake
- // value to the JavaScript side, though.
- textField._height = textField.textHeight + PADDING_BOTTOM + this.fontSize + Math.abs(tuneHeight) + tuneHeight - leadingFix;
- this.realHeight = textField._height - this.fontSize - Math.abs(tuneHeight);
- var arg = 'height:' + this.realHeight;
- if(_root.fitexactly == 'true') arg += ',width:' + (textField.textWidth + tuneWidth);
- fscommand('resize', arg);
-
- this.originalHeight = textField._height;
- this.currentHeight = Stage.height;
-
- textField._xscale = textField._yscale = parseInt(_root.zoom);
- }
-
- private function write(content) {
- this.textField.htmlText = ['
',
- content, '
'
- ].join('');
- }
-
- private function isSingleLine() {
- return Math.round((this.textField.textHeight - sIFR.styles.latestLeading) / this.fontSize) == 1;
- }
-
- //= Scales the text field to the new scale of the Flash movie itself.
- public function scale() {
- this.currentHeight = Stage.height;
- var scale = 100 * Math.round(this.currentHeight / this.originalHeight);
- textField._xscale = textField._yscale = scale;
- }
-
- private function calculateRatios() {
- var strings = ['X', 'X X', 'X X X', 'X X X X'];
- var results = {};
-
- for(var i = 1; i <= strings.length; i++) {
- var size = 6;
-
- this.write(strings[i - 1]);
- while(size < MAX_FONT_SIZE) {
- var rootStyle = sIFR.styles.getStyle('.sIFR-root') || {};
- rootStyle.fontSize = size;
- sIFR.styles.setStyle('.sIFR-root', rootStyle);
- this.textField.styleSheet = sIFR.styles;
- this.repaint();
- var ratio = (this.realHeight - PADDING_BOTTOM) / i / size;
- if(!results[size]) results[size] = ratio;
- else results[size] = ((i - 1) * results[size] + ratio) / i;
- size++;
- }
- }
-
- var sizes = [], ratios = [];
- var ratiosToSizes = {}, sizesToRatios = {};
-
- for(var size in results) {
- if(results[size] == Object.prototype[size]) continue;
- var ratio = results[size];
- ratiosToSizes[ratio] = Math.max(ratio, parseInt(size));
- }
-
- for(var ratio in ratiosToSizes) {
- if(ratiosToSizes[ratio] == Object.prototype[ratio]) continue;
- sizesToRatios[ratiosToSizes[ratio]] = roundDecimals(ratio, 2);
- sizes.push(ratiosToSizes[ratio]);
- }
-
- sizes.sort(function(a, b) { return a - b; });
- for(var j = 0; j < sizes.length - 1; j++) ratios.push(sizes[j], sizesToRatios[sizes[j]]);
- ratios.push(sizesToRatios[sizes[sizes.length - 1]]);
-
- fscommand('debug:ratios', '[' + ratios.join(',') + ']');
- }
-
- private function roundDecimals(value, decimals) {
- return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
- }
-
- public static function callback() {
- switch(_root.callbackType) {
- case 'replacetext':
- sIFR.instance.content = _root.callbackValue;
- sIFR.instance.write(_root.callbackValue);
- sIFR.instance.repaint();
- break;
- case 'resettext':
- sIFR.instance.write('');
- sIFR.instance.write(sIFR.instance.content);
- break;
- case 'ratios':
- sIFR.instance.calculateRatios();
- break;
- }
- }
-}
diff --git a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/sifr.fla b/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/sifr.fla
deleted file mode 100644
index 2aa3f647f..000000000
Binary files a/library/simplepie/demo/for_the_demo/source_files/sIFR-r245/sifr.fla and /dev/null differ
diff --git a/library/simplepie/demo/for_the_demo/top_gradient.gif b/library/simplepie/demo/for_the_demo/top_gradient.gif
deleted file mode 100644
index f77bd38f9..000000000
Binary files a/library/simplepie/demo/for_the_demo/top_gradient.gif and /dev/null differ
diff --git a/library/simplepie/demo/for_the_demo/verdana.swf b/library/simplepie/demo/for_the_demo/verdana.swf
deleted file mode 100644
index baf035047..000000000
Binary files a/library/simplepie/demo/for_the_demo/verdana.swf and /dev/null differ
diff --git a/library/simplepie/demo/for_the_demo/yanone-kaffeesatz-bold.swf b/library/simplepie/demo/for_the_demo/yanone-kaffeesatz-bold.swf
deleted file mode 100644
index c812a79dc..000000000
Binary files a/library/simplepie/demo/for_the_demo/yanone-kaffeesatz-bold.swf and /dev/null differ
diff --git a/library/simplepie/demo/handler_image.php b/library/simplepie/demo/handler_image.php
deleted file mode 100644
index 49c3ec89b..000000000
--- a/library/simplepie/demo/handler_image.php
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/library/simplepie/demo/index.php b/library/simplepie/demo/index.php
deleted file mode 100644
index 1481ba917..000000000
--- a/library/simplepie/demo/index.php
+++ /dev/null
@@ -1,295 +0,0 @@
-force_fsockopen(true);
-
-// Make sure that page is getting passed a URL
-if (isset($_GET['feed']) && $_GET['feed'] !== '')
-{
- // Strip slashes if magic quotes is enabled (which automatically escapes certain characters)
- if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
- {
- $_GET['feed'] = stripslashes($_GET['feed']);
- }
-
- // Use the URL that was passed to the page in SimplePie
- $feed->set_feed_url($_GET['feed']);
-
- // XML dump
- $feed->enable_xml_dump(isset($_GET['xmldump']) ? true : false);
-}
-
-// Allow us to change the input encoding from the URL string if we want to. (optional)
-if (!empty($_GET['input']))
-{
- $feed->set_input_encoding($_GET['input']);
-}
-
-// Allow us to choose to not re-order the items by date. (optional)
-if (!empty($_GET['orderbydate']) && $_GET['orderbydate'] == 'false')
-{
- $feed->enable_order_by_date(false);
-}
-
-// Allow us to cache images in feeds. This will also bypass any hotlink blocking put in place by the website.
-if (!empty($_GET['image']) && $_GET['image'] == 'true')
-{
- $feed->set_image_handler('./handler_image.php');
-}
-
-// We'll enable the discovering and caching of favicons.
-$feed->set_favicon_handler('./handler_image.php');
-
-// Initialize the whole SimplePie object. Read the feed, process it, parse it, cache it, and
-// all that other good stuff. The feed's information will not be available to SimplePie before
-// this is called.
-$success = $feed->init();
-
-// We'll make sure that the right content type and character encoding gets set automatically.
-// This function will grab the proper character encoding, as well as set the content type to text/html.
-$feed->handle_content_type();
-
-// When we end our PHP block, we want to make sure our DOCTYPE is on the top line to make
-// sure that the browser snaps into Standards Mode.
-?>
-
-
-
-SimplePie: Demo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/library/simplepie/demo/multifeeds.php b/library/simplepie/demo/multifeeds.php
deleted file mode 100644
index b23d792a2..000000000
--- a/library/simplepie/demo/multifeeds.php
+++ /dev/null
@@ -1,108 +0,0 @@
-set_feed_url(array(
- 'http://rss.news.yahoo.com/rss/topstories',
- 'http://news.google.com/?output=atom',
- 'http://rss.cnn.com/rss/cnn_topstories.rss'
-));
-
-// When we set these, we need to make sure that the handler_image.php file is also trying to read from the same cache directory that we are.
-$feed->set_favicon_handler('./handler_image.php');
-$feed->set_image_handler('./handler_image.php');
-
-// Initialize the feed.
-$feed->init();
-
-// Make sure the page is being served with the UTF-8 headers.
-$feed->handle_content_type();
-
-// Begin the (X)HTML page.
-?>
-
-
- Multifeeds Test page
-
-
-
-
-
-
- error): ?>
-
=$feed->error()?>
-
-
-
-
Quick-n-Dirty Multifeeds Demo
-
-
- get_items() as $item):
-
- // Let's give ourselves a reference to the parent $feed object for this particular item.
- $feed = $item->get_feed();
- ?>
-
-
';
-
- return $o;
-
-}
-
-// used by site ratings pages to provide a return link
-function widget_pubsites($arr) {
- if(App::$poi)
- return;
- return '
';
-}
-
-
-function widget_forums($arr) {
-
- if(! local_channel())
- return '';
-
- $o = '';
-
- if(is_array($arr) && array_key_exists('limit',$arr))
- $limit = " limit " . intval($limit) . " ";
- else
- $limit = '';
-
- $unseen = 0;
- if(is_array($arr) && array_key_exists('unseen',$arr) && intval($arr['unseen']))
- $unseen = 1;
-
- $perms_sql = item_permissions_sql(local_channel()) . item_normal();
-
- $xf = false;
-
- $x1 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'send_stream' and v = '0'",
- intval(local_channel())
- );
- if($x1) {
- $xc = ids_to_querystr($x1,'xchan',true);
- $x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
- intval(local_channel())
- );
- if($x2)
- $xf = ids_to_querystr($x2,'xchan',true);
- }
-
- $sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
-
- $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d $sql_extra order by xchan_name $limit ",
- intval(local_channel())
- );
- if(! $r1)
- return $o;
-
- $str = '';
-
- // Trying to cram all this into a single query with joins and the proper group by's is tough.
- // There also should be a way to update this via ajax.
-
- for($x = 0; $x < count($r1); $x ++) {
- $r = q("select sum(item_unseen) as unseen from item where owner_xchan = '%s' and uid = %d and item_unseen = 1 $perms_sql ",
- dbesc($r1[$x]['xchan_hash']),
- intval(local_channel())
- );
- if($r)
- $r1[$x]['unseen'] = $r[0]['unseen'];
-
-/**
- * @FIXME
- * This SQL makes the counts correct when you get forum posts arriving from different routes/sources
- * (like personal channels). However the network query for these posts doesn't yet include this
- * correction and it makes the SQL for that query pretty hairy so this is left as a future exercise.
- * It may make more sense in that query to look for the mention in the body rather than another join,
- * but that makes it very inefficient.
- *
- $r = q("select sum(item_unseen) as unseen from item left join term on oid = id where otype = %d and owner_xchan != '%s' and item.uid = %d and url = '%s' and ttype = %d $perms_sql ",
- intval(TERM_OBJ_POST),
- dbesc($r1[$x]['xchan_hash']),
- intval(local_channel()),
- dbesc($r1[$x]['xchan_url']),
- intval(TERM_MENTION)
- );
- if($r)
- $r1[$x]['unseen'] = ((array_key_exists('unseen',$r1[$x])) ? $r1[$x]['unseen'] + $r[0]['unseen'] : $r[0]['unseen']);
- *
- * end @FIXME
- */
-
- }
-
- if($r1) {
- $o .= '
+ {{foreach $plugins.1 as $p}} {{$p}} {{/foreach}}
+
+
+
+
{{$version.0}}
+
{{$version.1}} - {{$build}}
+
+
+
{{$vmaster.0}}
+
{{$vmaster.1}}
+
+
+
{{$vdev.0}}
+
{{$vdev.1}}
+
+
\ No newline at end of file
diff --git a/view/theme/redbasic/tpl/album_edit.tpl b/view/theme/redbasic/tpl/album_edit.tpl
new file mode 100755
index 000000000..f5495f149
--- /dev/null
+++ b/view/theme/redbasic/tpl/album_edit.tpl
@@ -0,0 +1,22 @@
+
diff --git a/view/theme/redbasic/tpl/follow.tpl b/view/theme/redbasic/tpl/follow.tpl
new file mode 100755
index 000000000..4def1415d
--- /dev/null
+++ b/view/theme/redbasic/tpl/follow.tpl
@@ -0,0 +1,14 @@
+
+
{{$connect}}
+
+
+
+
+
+
+
+
+ {{if $abook_usage_message}}
+
{{$abook_usage_message}}
+ {{/if}}
+
diff --git a/view/theme/redbasic/tpl/force_image_reload.tpl b/view/theme/redbasic/tpl/force_image_reload.tpl
new file mode 100644
index 000000000..839bd22b5
--- /dev/null
+++ b/view/theme/redbasic/tpl/force_image_reload.tpl
@@ -0,0 +1,72 @@
+{{*
+Force the browser to reload an image from the server instead of the cache.
+based on an answer from http://stackoverflow.com/a/22429796/3343347
+
+Usage: Set $imgUrl to the src url you want to be re-fetched from the server
+
+*}}
+
+
diff --git a/view/theme/redbasic/tpl/generic_addon_settings.tpl b/view/theme/redbasic/tpl/generic_addon_settings.tpl
new file mode 100644
index 000000000..bf39b2aea
--- /dev/null
+++ b/view/theme/redbasic/tpl/generic_addon_settings.tpl
@@ -0,0 +1,19 @@
+
+ {{foreach $tabs as $tab}} +- {{$tab.label}}
+ {{/foreach}}
+
+{{if $contact.public_forum}} {{/if}}{{$contact.name}}{{if $contact.phone}} {{/if}}
+{{$finding}}
{{else}}{{$header}}{{if $total}} ({{$total}}){{/if}}
{{/if}} +{{$contacts}}
+ {{if $micropro}} + {{if $viewconnections}} + {{$viewconnections}} + {{/if}} ++ {{/if}} + {{/if}} +
{{$response.count}} {{$response.button}}
+ +{{foreach $response.list as $liker}}- {{$liker}}
{{/foreach}}
++ {{/if}} + {{/if}} +
{{$item.attachments}}
+{{$response.count}} {{$response.button}}
+ +{{foreach $response.list as $liker}}- {{$liker}}
{{/foreach}}
+{{$title}}
++
+
{{$title}}
+{{$subtitle}}
+{{$title}}
++{{$desc}} +
+{{$title}}
++{{$desc}} +
+{{$header}}
+ +{{$head_managers}}
+ +{{foreach $managers as $x}} + ++{{/if}} + + +
{{$head_delegates}}
+ +{{if $delegates}} +{{foreach $delegates as $x}} + ++ + +
{{$head_potentials}}
+{{if $potentials}} +{{foreach $potentials as $x}} + ++ diff --git a/view/theme/redbasic/tpl/design_tools.tpl b/view/theme/redbasic/tpl/design_tools.tpl new file mode 100644 index 000000000..bc7d46dc1 --- /dev/null +++ b/view/theme/redbasic/tpl/design_tools.tpl @@ -0,0 +1,9 @@ +
{{$title}}
+{{$header}}
+ +{{include file="field_checkbox.tpl" field=$safemode}} +{{include file="field_checkbox.tpl" field=$globaldir}} +{{include file="field_checkbox.tpl" field=$pubforums}} + +{{$dirlbl}}{{if $search}}: {{$safetxt}}{{/if}}
+{{if $entry.public_forum}} {{/if}}{{$entry.name}}{{if $entry.online}} {{/if}}
++- {{$push}}
+
+{{$title}}
+{{$title}}
+ +{{$title}}
+{{$title}}
++- {{$month}}
+ - {{$week}}
+ - {{$day}}
+
+{{$title}}
++- {{$export}}
+ - {{$import}}
+
+{{$banner}}
+ +{{$f}}
++- {{$mark}}
+- {{$apply}}
+
+ ++{{/foreach}} +{{/if}} +
+ {{$field.6}} +
{{$title}}
++- {{$all}}
+ {{foreach $terms as $term}}
+ - {{$term.name}}
+ {{/foreach}}
+
+ ++- FileBrowser
+
++ {{foreach $folders as $f}}- {{$f.1}}
{{/foreach}}
+
++ {{foreach $files as $f}} +
{{$f.1}}
+ {{/foreach}}
+
+{{$title}}
+ +{{$connect}}
+ ++ + {{$addon.1}} + +
+{{$title}}
{{/if}} + {{if $desc}}+ {{foreach $items as $item}} +- {{$item.label}}
+ {{/foreach}}
+
+ +{{$title}}
+ +{{$title}}
+ + +{{$title}}
++ {{foreach $groups as $group}} +-
+ {{if $group.cid}}
+
+ {{/if}}
+ {{if $group.edit}}
+
+ {{/if}}
+ {{$group.text}}
+
+ {{/foreach}}
+ -
+ {{$createtext}}
+
+
+ +{{$groupeditor.label_members}}
++
{{$groupeditor.label_contacts}}
+{4} +
{{$title}}: {{$heading}}
++ + + {{$tocHeading}} + +
++ {{$content}} +
{{$title}}
+{{$pass}}
+ + +{{if $status}} +{{$status}}
+{{/if}} + +{{$text}} diff --git a/view/theme/redbasic/tpl/install_checks.tpl b/view/theme/redbasic/tpl/install_checks.tpl new file mode 100755 index 000000000..ad0aef6a3 --- /dev/null +++ b/view/theme/redbasic/tpl/install_checks.tpl @@ -0,0 +1,24 @@ +{{$title}}
+{{$pass}}
+ diff --git a/view/theme/redbasic/tpl/install_db.tpl b/view/theme/redbasic/tpl/install_db.tpl new file mode 100755 index 000000000..1a58de129 --- /dev/null +++ b/view/theme/redbasic/tpl/install_db.tpl @@ -0,0 +1,30 @@ +{{$title}}
+{{$pass}}
+ + ++{{$info_01}}
+ +{{if $status}} ++{{$info_02}}
+{{$info_03}} +
{{$status}}
+{{/if}} + + + diff --git a/view/theme/redbasic/tpl/install_settings.tpl b/view/theme/redbasic/tpl/install_settings.tpl new file mode 100755 index 000000000..62dcbb8b3 --- /dev/null +++ b/view/theme/redbasic/tpl/install_settings.tpl @@ -0,0 +1,28 @@ +{{$title}}
+{{$pass}}
+ + +{{if $status}} +{{$status}}
+{{/if}} + + + diff --git a/view/theme/redbasic/tpl/invite.tpl b/view/theme/redbasic/tpl/invite.tpl new file mode 100755 index 000000000..440e1e02b --- /dev/null +++ b/view/theme/redbasic/tpl/invite.tpl @@ -0,0 +1,28 @@ +{{$invite}}
++
{{$title}}
+ + diff --git a/view/theme/redbasic/tpl/jot-header.tpl b/view/theme/redbasic/tpl/jot-header.tpl new file mode 100755 index 000000000..1cc5a898a --- /dev/null +++ b/view/theme/redbasic/tpl/jot-header.tpl @@ -0,0 +1,598 @@ + + + + + diff --git a/view/theme/redbasic/tpl/jot.tpl b/view/theme/redbasic/tpl/jot.tpl new file mode 100755 index 000000000..dbbb470c5 --- /dev/null +++ b/view/theme/redbasic/tpl/jot.tpl @@ -0,0 +1,303 @@ +