Compare commits

...

24 Commits

Author SHA1 Message Date
b0b684bdb1 pages.php: use link to create hardlinks isntead of full file copy for thread moving 2024-05-22 23:55:06 +02:00
8626ab7571 Merge pull request 'Refactor ban log' (#142) from refactor-ban-log into config
Reviewed-on: leftypol/leftypol#142
2024-05-22 20:31:03 +00:00
0ce203f1d2 bans.php: always print modLog 2024-05-22 22:24:04 +02:00
9efc35e441 bans.php: simplify modLog string 2024-05-22 22:22:56 +02:00
0d38349a10 Merge pull request 'Add the About theme' (#141) from about-theme into config
Reviewed-on: leftypol/leftypol#141
2024-05-21 14:46:51 +00:00
295cde61f6 style.css: add center utility class 2024-05-21 16:43:30 +02:00
cfdbcfcad9 Add about theme 2024-05-21 16:43:26 +02:00
2030b60acf posts.sql: make default board table engine InnoDB 2024-05-14 19:40:00 +02:00
428d9e9001 functions net.php: add Tor connections to secure connections 2024-05-07 22:44:31 +02:00
7dcdbc065d faq.html catalog.html: fix top bar not being unpinned (missing hud hook) 2024-05-07 11:47:21 +02:00
47d704ed01 faq.html: fix broken style picker (due to missing hud hook) 2024-05-07 11:39:35 +02:00
9723bb8f4a faq.html: trim 2024-05-07 11:39:17 +02:00
217f52ec69 Merge pull request 'Disable login on insecure connections. Implements #134' (#136) from secure-login into config
Reviewed-on: leftypol/leftypol#136
Closes #134
2024-05-07 09:09:44 +00:00
aa99d10f1a auth.php: disallow unencrypted logins by default 2024-05-07 10:44:05 +02:00
003152095a auth.php: remove obsolete code 2024-05-07 10:32:34 +02:00
940ea3f4b5 config.php: reduce default login cookie expire timeout 2024-05-07 10:31:36 +02:00
f6cc9a2f9f auth.php: trim 2024-05-07 10:30:50 +02:00
f5aa60627e catalog.html: add bottom-hud hook on catalog template 2024-05-05 22:18:30 +02:00
909c2040da hud-pinning.js: fix inappropriate unpinning on image posting 2024-05-05 21:32:39 +02:00
86fc44d2f3 style.css: remove default top bar color re-declaration 2024-05-03 14:57:19 +02:00
1da97d77ca Fix broken top bar remaining still pinned on soome themes 2024-04-30 15:47:38 +02:00
8bc9a22920 Merge pull request 'style.css: better user options panel on mobile' (#132) from fix-options-panel-mobile into config
Reviewed-on: leftypol/leftypol#132
2024-04-27 19:50:28 +00:00
9084588fa0 style.css: better user options panel on mobile 2024-04-27 21:46:43 +02:00
3351715795 Attempt fix broken unban on serveral pages 2024-04-25 18:50:32 +02:00
18 changed files with 254 additions and 129 deletions

View File

@ -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",

View File

@ -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');

View File

@ -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
View 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');
}

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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>

View File

@ -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 ;

View 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 &copy; 2010-2014 Tinyboard Development Group
<br><a href="https://github.com/vichan-devel/vichan">vichan</a> Copyright &copy; 2012-2016 vichan-devel
</footer>
<div id="bottom-hud" class="bar bottom">
<div class="pages"></div>
</div>
</body>
</html>
{% endfilter %}

View 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'
];

View 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);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -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 &copy; 2012-2016 vichan-devel
<br><a href="https://github.com/lainchan/lainchan">lainchan</a> Copyright &copy; 2014-2017 lainchan Administration</p>
</footer>
<div id="bottom-hud" class="bar bottom">
<div class="pages"></div>
</div>
<script type="text/javascript">{% raw %}
ready();

View File

@ -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 &copy; 2010-2014 Tinyboard Development Group
<br>vichan Copyright &copy; 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>