forked from leftypol/leftypol
Compare commits
24 Commits
mitigate-m
...
config
Author | SHA1 | Date | |
---|---|---|---|
b0b684bdb1 | |||
8626ab7571 | |||
0ce203f1d2 | |||
9efc35e441 | |||
0d38349a10 | |||
295cde61f6 | |||
cfdbcfcad9 | |||
2030b60acf | |||
428d9e9001 | |||
7dcdbc065d | |||
47d704ed01 | |||
9723bb8f4a | |||
217f52ec69 | |||
aa99d10f1a | |||
003152095a | |||
940ea3f4b5 | |||
f6cc9a2f9f | |||
f5aa60627e | |||
909c2040da | |||
86fc44d2f3 | |||
1da97d77ca | |||
8bc9a22920 | |||
9084588fa0 | |||
3351715795 |
|
@ -22,7 +22,8 @@
|
|||
"inc/queue.php",
|
||||
"inc/polyfill.php",
|
||||
"inc/error.php",
|
||||
"inc/functions.php"
|
||||
"inc/functions.php",
|
||||
"inc/functions/net.php"
|
||||
]
|
||||
},
|
||||
"license": "Tinyboard + vichan",
|
||||
|
|
17
inc/bans.php
17
inc/bans.php
|
@ -311,16 +311,13 @@ class Bans {
|
|||
|
||||
$query->execute() or error(db_error($query));
|
||||
|
||||
if (isset($mod['id']) && $mod['id'] == $mod_id) {
|
||||
modLog('Created a new ' .
|
||||
($length > 0 ? preg_replace('/^(\d+) (\w+?)s?$/', '$1-$2', until($length)) : 'permanent') .
|
||||
' ban on ' .
|
||||
($ban_board ? '/' . $ban_board . '/' : 'all boards') .
|
||||
' for ' .
|
||||
(filter_var($mask, FILTER_VALIDATE_IP) !== false ? "<a href=\"?/IP/$mask\">$mask</a>" : $mask) .
|
||||
' (<small>#' . $pdo->lastInsertId() . '</small>)' .
|
||||
' with ' . ($reason ? 'reason: ' . utf8tohtml($reason) . '' : 'no reason'));
|
||||
}
|
||||
$ban_len = $length > 0 ? preg_replace('/^(\d+) (\w+?)s?$/', '$1-$2', until($length)) : 'permanent';
|
||||
$ban_board = $ban_board ? "/$ban_board/" : 'all boards';
|
||||
$ban_ip = filter_var($mask, FILTER_VALIDATE_IP) !== false ? "<a href=\"?/IP/$mask\">$mask</a>" : $mask;
|
||||
$ban_id = $pdo->lastInsertId();
|
||||
$ban_reason = $reason ? 'reason: ' . utf8tohtml($reason) : 'no reason';
|
||||
|
||||
modLog("Created a new $ban_len ban on $ban_board for $ban_ip (<small># $ban_id </small>) with $ban_reason");
|
||||
|
||||
rebuildThemes('bans');
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@
|
|||
|
||||
// How long should the cookies last (in seconds). Defines how long should moderators should remain logged
|
||||
// in (0 = browser session).
|
||||
$config['cookies']['expire'] = 60 * 60 * 24 * 30 * 6; // ~6 months
|
||||
$config['cookies']['expire'] = 60 * 60 * 24 * 7; // 1 week.
|
||||
|
||||
// Make this something long and random for security.
|
||||
$config['cookies']['salt'] = 'abcdefghijklmnopqrstuvwxyz09123456789!@#$%^&*()';
|
||||
|
@ -180,6 +180,10 @@
|
|||
// Whether or not you can access the mod cookie in JavaScript. Most users should not need to change this.
|
||||
$config['cookies']['httponly'] = true;
|
||||
|
||||
// Do not allow logins via unencrypted HTTP. Should only be changed in testing environments or if you connect to a
|
||||
// load-balancer without encryption.
|
||||
$config['cookies']['secure_login_only'] = true;
|
||||
|
||||
// Used to salt secure tripcodes ("##trip") and poster IDs (if enabled).
|
||||
$config['secure_trip_salt'] = ')(*&^%$#@!98765432190zyxwvutsrqponmlkjihgfedcba';
|
||||
|
||||
|
@ -1216,6 +1220,7 @@
|
|||
// Moderator errors
|
||||
$config['error']['toomanyunban'] = _('You are only allowed to unban %s users at a time. You tried to unban %u users.');
|
||||
$config['error']['invalid'] = _('Invalid username and/or password.');
|
||||
$config['error']['insecure'] = _('Login on insecure connections is disabled.');
|
||||
$config['error']['notamod'] = _('You are not a mod…');
|
||||
$config['error']['invalidafter'] = _('Invalid username and/or password. Your user may have been deleted or changed.');
|
||||
$config['error']['malformed'] = _('Invalid/malformed cookies.');
|
||||
|
|
17
inc/functions/net.php
Normal file
17
inc/functions/net.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace Vichan\Functions\Net;
|
||||
|
||||
|
||||
/**
|
||||
* @return bool Returns if the client-server connection is an HTTPS one.
|
||||
*/
|
||||
function is_connection_https(): bool {
|
||||
return !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Returns if the client-server connection is an encrypted one (HTTPS or Tor loopback).
|
||||
*/
|
||||
function is_connection_secure(): bool {
|
||||
return is_connection_https() || (!empty($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] === '127.0.0.1');
|
||||
}
|
|
@ -4,6 +4,8 @@
|
|||
* Copyright (c) 2010-2013 Tinyboard Development Group
|
||||
*/
|
||||
|
||||
use Vichan\Functions\Net;
|
||||
|
||||
defined('TINYBOARD') or exit;
|
||||
|
||||
// create a hash/salt pair for validate logins
|
||||
|
@ -37,12 +39,6 @@ function mkhash($username, $password, $salt = false) {
|
|||
return $hash;
|
||||
}
|
||||
|
||||
function crypt_password_old($password) {
|
||||
$salt = generate_salt();
|
||||
$password = hash('sha256', $salt . sha1($password));
|
||||
return array($salt, $password);
|
||||
}
|
||||
|
||||
function crypt_password($password) {
|
||||
global $config;
|
||||
// `salt` database field is reused as a version value. We don't want it to be 0.
|
||||
|
@ -69,12 +65,6 @@ function test_password($password, $salt, $test) {
|
|||
}
|
||||
|
||||
function generate_salt() {
|
||||
// mcrypt_create_iv() was deprecated in PHP 7.1.0, only use it if we're below that version number.
|
||||
if (PHP_VERSION_ID < 70100) {
|
||||
// 128 bits of entropy
|
||||
return strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
|
||||
}
|
||||
// Otherwise, use random_bytes()
|
||||
return strtr(base64_encode(random_bytes(16)), '+', '.');
|
||||
}
|
||||
|
||||
|
@ -117,19 +107,22 @@ function setCookies() {
|
|||
if (!$mod)
|
||||
error('setCookies() was called for a non-moderator!');
|
||||
|
||||
$is_https = Net\is_connection_https();
|
||||
|
||||
setcookie($config['cookies']['mod'],
|
||||
$mod['username'] . // username
|
||||
':' .
|
||||
$mod['hash'][0] . // password
|
||||
':' .
|
||||
$mod['hash'][1], // salt
|
||||
time() + $config['cookies']['expire'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', $config['cookies']['httponly']);
|
||||
time() + $config['cookies']['expire'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, $is_https, $config['cookies']['httponly']);
|
||||
}
|
||||
|
||||
function destroyCookies() {
|
||||
global $config;
|
||||
$is_https = Net\is_connection_https();
|
||||
// Delete the cookies
|
||||
setcookie($config['cookies']['mod'], 'deleted', time() - $config['cookies']['expire'], $config['cookies']['jail']?$config['cookies']['path'] : '/', null, !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true);
|
||||
setcookie($config['cookies']['mod'], 'deleted', time() - $config['cookies']['expire'], $config['cookies']['jail']?$config['cookies']['path'] : '/', null, $is_https, true);
|
||||
}
|
||||
|
||||
function modLog($action, $_board=null) {
|
||||
|
@ -186,6 +179,7 @@ function make_secure_link_token($uri) {
|
|||
|
||||
function check_login($prompt = false) {
|
||||
global $config, $mod;
|
||||
|
||||
// Validate session
|
||||
if (isset($_COOKIE[$config['cookies']['mod']])) {
|
||||
// Should be username:hash:salt
|
||||
|
|
|
@ -4,8 +4,11 @@
|
|||
* Copyright (c) 2010-2013 Tinyboard Development Group
|
||||
*/
|
||||
|
||||
use Vichan\Functions\Net;
|
||||
|
||||
defined('TINYBOARD') or exit;
|
||||
|
||||
|
||||
function mod_page($title, $template, $args, $subtitle = false) {
|
||||
global $config, $mod;
|
||||
|
||||
|
@ -35,9 +38,11 @@ function clone_wrapped_with_exist_check($clonefn, $src, $dest) {
|
|||
function mod_login($redirect = false) {
|
||||
global $config;
|
||||
|
||||
$args = array();
|
||||
$args = [];
|
||||
|
||||
if (isset($_POST['login'])) {
|
||||
if ($config['cookies']['secure_login_only'] && !Net\is_connection_secure()) {
|
||||
$args['error'] = $config['error']['insecure'];
|
||||
} elseif (isset($_POST['login'])) {
|
||||
// Check if inputs are set and not empty
|
||||
if (!isset($_POST['username'], $_POST['password']) || $_POST['username'] == '' || $_POST['password'] == '') {
|
||||
$args['error'] = $config['error']['invalid'];
|
||||
|
@ -858,7 +863,7 @@ function mod_page_ip($ip) {
|
|||
if (filter_var($ip, FILTER_VALIDATE_IP) === false)
|
||||
error("Invalid IP address.");
|
||||
|
||||
if (isset($_POST['ban_id'], $_POST['unban_mask'])) {
|
||||
if (isset($_POST['ban_id'], $_POST['unban'])) {
|
||||
if (!hasPermission($config['mod']['unban']))
|
||||
error($config['error']['noaccess']);
|
||||
|
||||
|
@ -1340,8 +1345,8 @@ function mod_move($originBoard, $postID) {
|
|||
if ($targetBoard === $originBoard)
|
||||
error(_('Target and source board are the same.'));
|
||||
|
||||
// copy() if leaving a shadow thread behind; else, rename().
|
||||
$clone = $shadow ? 'copy' : 'rename';
|
||||
// link() if leaving a shadow thread behind; else, rename().
|
||||
$clone = $shadow ? 'link' : 'rename';
|
||||
|
||||
// indicate that the post is a thread
|
||||
$post['op'] = true;
|
||||
|
@ -1634,7 +1639,7 @@ function mod_merge($originBoard, $postID) {
|
|||
$op = $post;
|
||||
$op['id'] = $newID;
|
||||
|
||||
$clone = $shadow ? 'copy' : 'rename';
|
||||
$clone = $shadow ? 'link' : 'rename';
|
||||
|
||||
if ($post['has_file']) {
|
||||
// copy image
|
||||
|
|
|
@ -42,7 +42,7 @@ $(document).ready(function() {
|
|||
|
||||
// Reload on new post: allows it to work with auto-reload.js etc.
|
||||
$(document).on('new_post', function(e, post) {
|
||||
setHudPinning(localStorage.hud_pinning === 'true');
|
||||
setHudPinning(localStorage.hud_pinning !== 'false');
|
||||
});
|
||||
|
||||
// Enforce the setting on loading.
|
||||
|
|
|
@ -185,7 +185,6 @@ div.boardlist:not(.bottom) {
|
|||
}
|
||||
|
||||
.desktop-style div.boardlist:not(.bottom) {
|
||||
position:static;
|
||||
text-shadow: black 1px 1px 1px, black -1px -1px 1px, black -1px 1px 1px, black 1px -1px 1px;
|
||||
color: #999999;
|
||||
background-color: #1E1E1E;
|
||||
|
|
|
@ -172,7 +172,6 @@ div.boardlist:not(.bottom) {
|
|||
|
||||
}
|
||||
.desktop-style div.boardlist:not(.bottom) {
|
||||
position:static;
|
||||
text-shadow: black 1px 1px 1px, black -1px -1px 1px, black -1px 1px 1px, black 1px -1px 1px;
|
||||
color: #999999;
|
||||
background-color: #1E1E1E;
|
||||
|
|
|
@ -743,7 +743,7 @@ div.blotter {
|
|||
}
|
||||
|
||||
.desktop-style div.boardlist:not(.bottom) {
|
||||
position: fixed;
|
||||
position: static;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
@ -751,7 +751,6 @@ div.blotter {
|
|||
z-index: 30;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
|
||||
border-bottom: 1px solid;
|
||||
background-color: #D6DAF0;
|
||||
}
|
||||
|
||||
/*.desktop-style body {
|
||||
|
@ -1040,16 +1039,10 @@ pre {
|
|||
}
|
||||
|
||||
#options_div {
|
||||
width: 600px;
|
||||
height: 360px;
|
||||
/* width: 620px;
|
||||
width: 620px;
|
||||
height: 400px;
|
||||
resize: both;
|
||||
overflow: auto;*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
#alert_div {
|
||||
width: 500px;
|
||||
}
|
||||
|
@ -1126,7 +1119,8 @@ pre {
|
|||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 0px;
|
||||
max-width: 620px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.mentioned {
|
||||
|
@ -1211,6 +1205,14 @@ span.pln {
|
|||
min-width: 48px;
|
||||
}
|
||||
|
||||
/* The center tag has been deprecated in HTML 5 */
|
||||
.center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Text and accessibility */
|
||||
.ltr {
|
||||
direction: ltr;
|
||||
|
@ -1986,4 +1988,3 @@ span.orangeQuote {
|
|||
float: right;
|
||||
margin: 0em 1em;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<th>{% trans 'Action' %}</th>
|
||||
<td>
|
||||
<input type="hidden" name="appeal_id" value="{{ ban.id }}">
|
||||
<input type="submit" name="unban_mask" value="Unban mask">
|
||||
<input type="submit" name="unban" value="Unban range">
|
||||
<input type="submit" name="deny" value="Deny appeal">
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -27,5 +27,5 @@ CREATE TABLE IF NOT EXISTS ``posts_{{ board }}`` (
|
|||
KEY `time` (`time`),
|
||||
KEY `ip` (`ip`),
|
||||
KEY `list_threads` (`thread`, `sticky`, `bump`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
|
||||
|
||||
|
|
32
templates/themes/about/about.html
Normal file
32
templates/themes/about/about.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
{% filter remove_whitespace %}
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
|
||||
<title>{{ theme_config.title }}</title>
|
||||
{% include 'header.html' %}
|
||||
</head>
|
||||
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
|
||||
<div id="top-hud" class="bar top">
|
||||
{{ board_list.top }}
|
||||
</div>
|
||||
<header>
|
||||
<h1 data-text="{{ theme_config.title }}"> {{ theme_config.title }}</h1>
|
||||
</header>
|
||||
<img class="center" img alt="logo" src="{{ config.logo }}" width=15%/>
|
||||
<div class="center ban">{{ theme_config.description }}</div>
|
||||
<hr/>
|
||||
<footer>
|
||||
<p class="unimportant" style="margin-top:20px;text-align:center;">- <a href="https://github.com/savetheinternet/Tinyboard">Tinyboard</a> +
|
||||
<a href='https://github.com/vichan-devel/vichan'>vichan</a> +
|
||||
<br><a href="https://github.com/savetheinternet/Tinyboard">Tinyboard</a> Copyright © 2010-2014 Tinyboard Development Group
|
||||
<br><a href="https://github.com/vichan-devel/vichan">vichan</a> Copyright © 2012-2016 vichan-devel
|
||||
</footer>
|
||||
<div id="bottom-hud" class="bar bottom">
|
||||
<div class="pages"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{% endfilter %}
|
31
templates/themes/about/info.php
Normal file
31
templates/themes/about/info.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
$theme = [
|
||||
// Theme name.
|
||||
'name' => 'About',
|
||||
// Description (you can use Tinyboard markup here).
|
||||
'description' => 'Extremely basic about page. Enabling board links is recommended for this theme.',
|
||||
'version' => 'v0.0.1',
|
||||
// Theme configuration.
|
||||
'config' => [
|
||||
[
|
||||
'title' => 'Site title',
|
||||
'name' => 'title',
|
||||
'type' => 'text',
|
||||
'default' => 'Title goes here'
|
||||
],
|
||||
[
|
||||
'title' => 'Text',
|
||||
'name' => 'description',
|
||||
'type' => 'text',
|
||||
'default' => 'Text goes here'
|
||||
],
|
||||
[
|
||||
'title' => 'File path',
|
||||
'name' => 'path',
|
||||
'type' => 'text',
|
||||
'default' => 'about.html',
|
||||
'comment' => '(eg. "about.html")'
|
||||
]
|
||||
],
|
||||
'build_function' => 'about_build'
|
||||
];
|
37
templates/themes/about/theme.php
Normal file
37
templates/themes/about/theme.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
require_once 'info.php';
|
||||
|
||||
function about_build(string $action, array $theme_config, $board): void {
|
||||
$obj = new AboutTheme($theme_config);
|
||||
$obj->build($action);
|
||||
}
|
||||
|
||||
class AboutTheme {
|
||||
private $theme_config;
|
||||
|
||||
|
||||
private function render(): string {
|
||||
global $config;
|
||||
|
||||
return Element('themes/about/about.html', [
|
||||
'theme_config' => $this->theme_config,
|
||||
'config' => $config,
|
||||
'board_list' => createBoardlist(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function __construct(array $theme_config) {
|
||||
$this->theme_config = $theme_config;
|
||||
}
|
||||
|
||||
public function build(string $action): void {
|
||||
global $config;
|
||||
|
||||
if ($action == 'all') {
|
||||
$about_page = $this->render();
|
||||
$home = $config['dir']['home'];
|
||||
$path = $this->theme_config['path'];
|
||||
file_write($home . $path, $about_page);
|
||||
}
|
||||
}
|
||||
}
|
BIN
templates/themes/about/thumb.png
Normal file
BIN
templates/themes/about/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
|
@ -13,7 +13,7 @@
|
|||
{% include 'header.html' %}
|
||||
</head>
|
||||
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} theme-catalog active-catalog" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
|
||||
<div class="top bar topbar">
|
||||
<div id="top-hud" class="top bar topbar">
|
||||
{{ boardlist.top }}
|
||||
</div>
|
||||
<header>
|
||||
|
@ -105,7 +105,10 @@
|
|||
<br><a href="https://github.com/vichan-devel/vichan">vichan</a> Copyright © 2012-2016 vichan-devel
|
||||
<br><a href="https://github.com/lainchan/lainchan">lainchan</a> Copyright © 2014-2017 lainchan Administration</p>
|
||||
</footer>
|
||||
|
||||
<div id="bottom-hud" class="bar bottom">
|
||||
<div class="pages"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">{% raw %}
|
||||
ready();
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
{% include 'header.html' %}
|
||||
</head>
|
||||
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
|
||||
<div class="bar top">
|
||||
<div id="top-hud" class="bar top">
|
||||
{{ boardlist.top }}
|
||||
</div>
|
||||
<header>
|
||||
|
@ -139,7 +139,11 @@
|
|||
<br>Tinyboard Copyright © 2010-2014 Tinyboard Development Group
|
||||
<br>vichan Copyright © 2012-2016 vichan-devel</p>
|
||||
</footer>
|
||||
|
||||
<div id="bottom-hud" class="bar bottom">
|
||||
<div class="pages"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">{% raw %}
|
||||
ready();
|
||||
{% endraw %}</script>
|
||||
|
|
Loading…
Reference in New Issue
Block a user