Compare commits
14 commits
master
...
ui-customi
Author | SHA1 | Date | |
---|---|---|---|
f06b59ccd9 | |||
947b945d96 | |||
2e0c46b4c6 | |||
8ac2bbaf4f | |||
9f06d02e52 | |||
7764f1287d | |||
e7fbb1c8c6 | |||
d084ced575 | |||
650e682c4d | |||
|
6b13a8b564 | ||
|
c9060e49a1 | ||
6e6acabbfb | |||
d6ab5df482 | |||
7e1a483db2 |
11 changed files with 194 additions and 33 deletions
|
@ -4,3 +4,6 @@ insert_final_newline = true
|
|||
|
||||
[*.php]
|
||||
indent_style = tab
|
||||
|
||||
[*.js]
|
||||
indent_style = tab
|
||||
|
|
|
@ -263,7 +263,11 @@ class Handler_Public extends Handler {
|
|||
|
||||
function logout() {
|
||||
logout_user();
|
||||
header("Location: index.php");
|
||||
$location = 'index.php';
|
||||
if(defined('LOGOUT_LOCATION')) {
|
||||
$location = LOGOUT_LOCATION;
|
||||
}
|
||||
header("Location: $location");
|
||||
}
|
||||
|
||||
function share() {
|
||||
|
|
|
@ -90,6 +90,10 @@
|
|||
// If set to true, users won't be able to set application language
|
||||
// and settings profile.
|
||||
|
||||
define ('LOGIN_LOCATION', 'index.php');
|
||||
// When a user logs out, redirect to this location. This is useful when you have some central
|
||||
// authentication system, and you want to reach the main logout page
|
||||
|
||||
// *********************
|
||||
// *** Feed settings ***
|
||||
// *********************
|
||||
|
|
|
@ -23,3 +23,12 @@ body.ttrss_prefs,
|
|||
@import "dijit.less";
|
||||
@import "utility.less";
|
||||
@import "zoom.less";
|
||||
|
||||
#feeds-actions > ul {
|
||||
list-style: none;
|
||||
}
|
||||
#feeds-actions > ul > li {
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
|
||||
}
|
||||
|
|
12
grog/share_dialog.html
Normal file
12
grog/share_dialog.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<form>
|
||||
<div> <strong>Note:</strong>Every article you put in
|
||||
"Published" category will always be published! </div>
|
||||
<div> <input type="checkbox" name="share_all">Publish every feed you have</input></div>
|
||||
<div> <input type="checkbox" name="share_starred">Publish your starred articles</input> </div>
|
||||
<!-- TODO: make every category clickable -->
|
||||
<div>
|
||||
Remember: whatever you choose to publish, they are all available from http://grog.blah/u/$yourname
|
||||
</div>
|
||||
<hr>
|
||||
<input type="submit" value="Save" />
|
||||
</form>
|
55
index.php
55
index.php
|
@ -114,7 +114,7 @@
|
|||
require({cache:{}});
|
||||
<?php
|
||||
print get_minified_js(["tt-rss.js",
|
||||
"functions.js", "feedlist.js", "viewfeed.js", "PluginHost.js"]);
|
||||
"functions.js", "feedlist.js", "viewfeed.js", "PluginHost.js", "grog.js"]);
|
||||
?>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
|
@ -162,6 +162,13 @@
|
|||
<div id="main" dojoType="dijit.layout.BorderContainer">
|
||||
|
||||
<div id="feeds-holder" dojoType="dijit.layout.ContentPane" region="leading" style="width : 20%" splitter="true">
|
||||
<div id="feeds-actions">
|
||||
<ul>
|
||||
<li onclick="quickMenuGo('qmcAddFeed');"> <button class="btn-primary" dojoType="dijit.form.Button">Add feed</button> </li>
|
||||
<li onclick="gotoPreferences('feedConfig');"> <button class="btn-secondary" dojoType="dijit.form.Button">Manage feeds</button> </li>
|
||||
<li onclick="configShare();"> <button class="btn-secondary" dojoType="dijit.form.Button">Publishing options</button> </li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="feedlistLoading">
|
||||
<img src='images/indicator_tiny.gif'/>
|
||||
<?php echo __("Loading, please wait..."); ?></div>
|
||||
|
@ -186,26 +193,27 @@
|
|||
|
||||
<form id="main_toolbar_form" action="" onsubmit='return false'>
|
||||
|
||||
<select name="view_mode" title="<?php echo __('Show articles') ?>"
|
||||
onchange="viewModeChanged()"
|
||||
dojoType="dijit.form.Select">
|
||||
<option selected="selected" value="adaptive"><?php echo __('Adaptive') ?></option>
|
||||
<option value="all_articles"><?php echo __('All Articles') ?></option>
|
||||
<option value="marked"><?php echo __('Starred') ?></option>
|
||||
<option value="published"><?php echo __('Published') ?></option>
|
||||
<option value="unread"><?php echo __('Unread') ?></option>
|
||||
<option value="has_note"><?php echo __('With Note') ?></option>
|
||||
<!-- <option value="noscores"><?php echo __('Ignore Scoring') ?></option> -->
|
||||
</select>
|
||||
<div dojoType="dijit.form.DropDownButton">
|
||||
<span><?php echo __('Show only'); ?></span>
|
||||
<input name="view_mode" style="display: none;" value="adaptive"></input>
|
||||
<div dojoType="dijit.Menu" style="display: none">
|
||||
<div onclick="document.getElementsByName('view_mode')[0].value = 'all_articles'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('All') ?></div>
|
||||
<div onclick="document.getElementsByName('view_mode')[0].value = 'marked'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Starred') ?></div>
|
||||
<div onclick="document.getElementsByName('view_mode')[0].value = 'published'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Published') ?></div>
|
||||
<div onclick="document.getElementsByName('view_mode')[0].value = 'unread'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Unread') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<select title="<?php echo __('Sort articles') ?>"
|
||||
onchange="viewModeChanged()"
|
||||
dojoType="dijit.form.Select" name="order_by">
|
||||
<option selected="selected" value="default"><?php echo __('Default') ?></option>
|
||||
<option value="feed_dates"><?php echo __('Newest first') ?></option>
|
||||
<option value="date_reverse"><?php echo __('Oldest first') ?></option>
|
||||
<option value="title"><?php echo __('Title') ?></option>
|
||||
</select>
|
||||
<div dojoType="dijit.form.DropDownButton">
|
||||
<span><?php echo __('Sort'); ?></span>
|
||||
<input name="order_by" style="display: none;" value="default"></input>
|
||||
<div dojoType="dijit.Menu" style="display: none">
|
||||
<div onclick="document.getElementsByName('order_by')[0].value = 'default'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Default') ?></div>
|
||||
<div onclick="document.getElementsByName('order_by')[0].value = 'feed_dates'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Newest first') ?></div>
|
||||
<div onclick="document.getElementsByName('order_by')[0].value = 'date_reverse'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Oldest first') ?></div>
|
||||
<div onclick="document.getElementsByName('order_by')[0].value = 'title'; viewModeChanged()" dojoType="dijit.MenuItem" ><?php echo __('Title') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div dojoType="dijit.form.ComboButton" onclick="catchupCurrentFeed()">
|
||||
<span><?php echo __('Mark as read') ?></span>
|
||||
|
@ -241,17 +249,10 @@
|
|||
<span><?php echo __('Actions...') ?></span>
|
||||
<div dojoType="dijit.Menu" style="display: none">
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcPrefs')"><?php echo __('Preferences...') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcSearch')"><?php echo __('Search...') ?></div>
|
||||
<div dojoType="dijit.MenuItem" disabled="1"><?php echo __('Feed actions:') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcAddFeed')"><?php echo __('Subscribe to feed...') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcEditFeed')"><?php echo __('Edit this feed...') ?></div>
|
||||
<!-- <div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcRescoreFeed')"><?php echo __('Rescore feed') ?></div> -->
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcRemoveFeed')"><?php echo __('Unsubscribe') ?></div>
|
||||
<div dojoType="dijit.MenuItem" disabled="1"><?php echo __('All feeds:') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcCatchupAll')"><?php echo __('Mark as read') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcShowOnlyUnread')"><?php echo __('(Un)hide read feeds') ?></div>
|
||||
<div dojoType="dijit.MenuItem" disabled="1"><?php echo __('Other actions:') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcToggleWidescreen')"><?php echo __('Toggle widescreen mode') ?></div>
|
||||
<!-- <div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcAddLabel')"><?php echo __('Create label...') ?></div>
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcAddFilter')"><?php echo __('Create filter...') ?></div> -->
|
||||
<div dojoType="dijit.MenuItem" onclick="quickMenuGo('qmcHKhelp')"><?php echo __('Keyboard shortcuts help') ?></div>
|
||||
|
|
|
@ -141,6 +141,7 @@ require(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"]
|
|||
}}));
|
||||
|
||||
if (bare_id > 0) {
|
||||
menu.setAttribute('default_item', 1)
|
||||
menu.addChild(new dijit.MenuItem({
|
||||
label: __("Edit feed"),
|
||||
onClick: function() {
|
||||
|
|
23
js/grog.js
Normal file
23
js/grog.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
function configShare() {
|
||||
var query = "grog/share_dialog.html";
|
||||
|
||||
var dialog = new dijit.Dialog({
|
||||
id: "feedConfigShare",
|
||||
title: __("Share options"),
|
||||
style: "width: 90%",
|
||||
show_error: function(msg) {
|
||||
var elem = $("fadd_error_message");
|
||||
|
||||
elem.innerHTML = msg;
|
||||
|
||||
if (!Element.visible(elem))
|
||||
new Effect.Appear(elem);
|
||||
|
||||
},
|
||||
execute: function() {
|
||||
},
|
||||
href: query});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
19
js/tt-rss.js
19
js/tt-rss.js
|
@ -78,6 +78,25 @@ function updateFeedList() {
|
|||
persist: true,
|
||||
id: "feedTree",
|
||||
}, "feedTree");
|
||||
tree.on('dblclick', function(_, item, evt) {
|
||||
var tnode = dijit.byNode(item.domNode)
|
||||
if(tnode._menu === undefined || tnode._menu.attr('default_item') === undefined) {
|
||||
var element = tnode.domNode
|
||||
var newevt = new MouseEvent('contextmenu', {
|
||||
'view': window,
|
||||
'bubbles': true,
|
||||
'cancelable': true,
|
||||
'screenX': evt.screenX,
|
||||
'screenY': evt.screenY,
|
||||
'clientX': evt.clientX,
|
||||
'clientY': evt.clientY,
|
||||
});
|
||||
return !element.dispatchEvent(newevt);
|
||||
} else {
|
||||
var mi = tnode._menu.getChildren()[tnode._menu.attr('default_item')]
|
||||
mi.onClick(evt)
|
||||
}
|
||||
})
|
||||
|
||||
/* var menu = new dijit.Menu({id: 'feedMenu'});
|
||||
|
||||
|
|
|
@ -88,10 +88,6 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
|
|||
if (infscroll_req == false) {
|
||||
loaded_article_ids = [];
|
||||
|
||||
dojo.html.set($("headlines-toolbar"),
|
||||
reply['headlines']['toolbar'],
|
||||
{parseContent: true});
|
||||
|
||||
/*dojo.html.set($("headlines-frame"),
|
||||
reply['headlines']['content'],
|
||||
{parseContent: true});
|
||||
|
|
89
plugins/auth_proxy/init.php
Normal file
89
plugins/auth_proxy/init.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
class Auth_Proxy extends Plugin implements IAuthModule {
|
||||
|
||||
private $host;
|
||||
/* @var Auth_Base $base */
|
||||
private $base;
|
||||
|
||||
function about() {
|
||||
return array(1.0,
|
||||
"Trust proxy X-Forwarded-User. May be dangerous, see doc",
|
||||
"boyska",
|
||||
true);
|
||||
}
|
||||
|
||||
/* @var PluginHost $host */
|
||||
function init($host ) {
|
||||
$this->host = $host;
|
||||
$this->base = new Auth_Base();
|
||||
|
||||
$host->add_hook($host::HOOK_AUTH_USER, $this);
|
||||
}
|
||||
|
||||
/*
|
||||
* is_whitelisted check if an IP is whitelisted by defined values in config.php
|
||||
* it will check by-IP and by-NAME
|
||||
* currently, only exact IP is supported (no cidr, no wildcard); this is a TODO
|
||||
* check by
|
||||
*/
|
||||
private function is_whitelisted($client_ip) {
|
||||
if(!defined('AUTHPROXY_WHITELIST_IP') && !defined('AUTHPROXY_WHITELIST_NAME')) {
|
||||
// TODO: send a warning: this is a misconfiguration!
|
||||
return false;
|
||||
}
|
||||
if(defined('AUTHPROXY_WHITELIST_IP')) {
|
||||
$whitelist = explode(' ', AUTHPROXY_WHITELIST_IP);
|
||||
foreach($whitelist as $w_ip) {
|
||||
if($client_ip === $w_ip) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(defined('AUTHPROXY_WHITELIST_NAME')) {
|
||||
$whitelist = explode(' ', AUTHPROXY_WHITELIST_NAME);
|
||||
foreach($whitelist as $w_name) {
|
||||
foreach(gethostbynamel($w_name) as $w_ip) {
|
||||
if($client_ip === $w_ip) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
function authenticate($login, $password) {
|
||||
$client_ip = $_SERVER['REMOTE_ADDR'];
|
||||
if($this->is_whitelisted($client_ip) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!array_key_exists("HTTP_X_FORWARDED_USER", $_SERVER)) {
|
||||
return false;
|
||||
}
|
||||
$try_login = $_SERVER["HTTP_X_FORWARDED_USER"];
|
||||
|
||||
if ($try_login) {
|
||||
$user_id = $this->base->auto_create_user($try_login, $password);
|
||||
|
||||
if ($user_id) {
|
||||
$_SESSION["fake_login"] = $try_login;
|
||||
$_SESSION["fake_password"] = "******";
|
||||
$_SESSION["hide_hello"] = true;
|
||||
$_SESSION["hide_logout"] = true;
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function api_version() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue