Merge pull request #97 from basefont/master

Count failed login attempts and warn about them. Delete public notes of deleted accounts.
This commit is contained in:
Daniel Winzen
2021-04-09 18:40:09 +02:00
committed by GitHub
15 changed files with 68 additions and 20 deletions

View File

@ -81,6 +81,7 @@ function route(){
send_post();
}elseif($_REQUEST['action']==='login'){
check_login();
show_fails();
send_frameset();
}elseif($_REQUEST['action']==='controls'){
check_session();
@ -769,7 +770,7 @@ function restore_backup(array $C){
if(isset($_POST['members']) && isset($code['members'])){
$db->exec('DELETE FROM ' . PREFIX . 'inbox;');
$db->exec('DELETE FROM ' . PREFIX . 'members;');
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, loginfails, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
foreach($code['members'] as $member){
$new_settings=['nocache', 'tz', 'eninbox', 'sortupdown', 'hidechatters', 'nocache_old'];
foreach($new_settings as $setting){
@ -777,7 +778,7 @@ function restore_backup(array $C){
$member[$setting]=0;
}
}
$stmt->execute([$member['nickname'], $member['passhash'], $member['status'], $member['refresh'], $member['bgcolour'], $member['regedby'], $member['lastlogin'], $member['timestamps'], $member['embed'], $member['incognito'], $member['style'], $member['nocache'], $member['tz'], $member['eninbox'], $member['sortupdown'], $member['hidechatters'], $member['nocache_old']]);
$stmt->execute([$member['nickname'], $member['passhash'], $member['status'], $member['refresh'], $member['bgcolour'], $member['regedby'], $member['lastlogin'], $member['loginfails'], $member['timestamps'], $member['embed'], $member['incognito'], $member['style'], $member['nocache'], $member['tz'], $member['eninbox'], $member['sortupdown'], $member['hidechatters'], $member['nocache_old']]);
}
}
if(isset($_POST['notes']) && isset($code['notes'])){
@ -2437,6 +2438,20 @@ function write_new_session(string $password){
}
}
function show_fails() {
global $db, $I, $U;
$stmt=$db->prepare('SELECT * FROM ' . PREFIX . 'members WHERE nickname=?;');
$stmt->execute([$U['nickname']]);
if($U['loginfails']>0){
print_start('failednotice');
echo (int) $U['loginfails']. "&nbsp;" . $I['failednotice']. "<br>";
$stmt=$db->prepare('UPDATE ' . PREFIX . 'members SET loginfails=? WHERE nickname=?;');
$stmt->execute([0, $U['nickname']]);
echo form_target('_blank', 'login').submit($I['dismiss']).'</form></td>';
print_end();
}
}
function approve_session(){
global $db;
if(isset($_POST['what'])){
@ -2658,6 +2673,9 @@ function check_member(string $password) : bool {
$stmt->execute([time(), $U['nickname']]);
return true;
}else{
$U=$temp;
$stmt=$db->prepare('UPDATE ' . PREFIX . 'members SET loginfails=? WHERE nickname=?;');
$stmt->execute([$U['loginfails']+1, $U['nickname']]);
send_error("$I[regednick]<br>$I[wrongpass]");
}
}
@ -2673,7 +2691,7 @@ function delete_account(){
$stmt->execute([$U['nickname']]);
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'inbox WHERE recipient=?;');
$stmt->execute([$U['nickname']]);
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'notes WHERE type=2 AND editedby=?;');
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'notes WHERE (type=2 OR type=3) AND editedby=?;');
$stmt->execute([$U['nickname']]);
$U['status']=1;
}
@ -2967,6 +2985,7 @@ function add_user_defaults(string $password){
}else{
$U['nocache_old']=1;
}
$U['loginfails']=0;
$U['tz']=get_setting('defaulttz');
$U['eninbox']=0;
$U['sortupdown']=get_setting('sortupdown');
@ -3268,14 +3287,14 @@ function add_system_message(string $mes, string $doer){
];
} else {
$sysmessage=[
'postdate' =>time(),
$sysmessage=[
'postdate' =>time(),
'poststatus' =>4,
'poster' =>'',
'recipient' =>'',
'poster' =>'',
'recipient' =>'',
'text' =>"$mes ($doer)",
'delstatus' =>4
];
'delstatus' =>4
];
}
write_message($sysmessage);
}
@ -3403,10 +3422,10 @@ function print_messages(int $delstatus=0){
if ($message['poststatus']==4) {
echo "<span class=\"sysmsg\" title=\"$I[sysmessage]\">".get_setting('sysmessagetxt')."$message[text]</span></div>";
} else {
echo "$message[text]</div>";
echo "$message[text]</div>";
}
}
}
}
echo '</div>';
}
@ -3649,7 +3668,7 @@ function cron(){
$limit=get_setting('numnotes');
$db->exec('DELETE FROM ' . PREFIX . 'notes WHERE type!=2 AND type!=3 AND id NOT IN (SELECT * FROM ( (SELECT id FROM ' . PREFIX . "notes WHERE type=0 ORDER BY id DESC LIMIT $limit) UNION (SELECT id FROM " . PREFIX . "notes WHERE type=1 ORDER BY id DESC LIMIT $limit) ) AS t);");
$result=$db->query('SELECT editedby, COUNT(*) AS cnt FROM ' . PREFIX . "notes WHERE type=2 GROUP BY editedby HAVING cnt>$limit;");
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'notes WHERE type=2 AND editedby=? AND id NOT IN (SELECT * FROM (SELECT id FROM ' . PREFIX . "notes WHERE type=2 AND editedby=? ORDER BY id DESC LIMIT $limit) AS t);");
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'notes WHERE (type=2 OR type=3) AND editedby=? AND id NOT IN (SELECT * FROM (SELECT id FROM ' . PREFIX . "notes WHERE (type=2 OR type=3) AND editedby=? ORDER BY id DESC LIMIT $limit) AS t);");
while($tmp=$result->fetch(PDO::FETCH_NUM)){
$stmt->execute([$tmp[0], $tmp[0]]);
}
@ -3662,7 +3681,7 @@ function destroy_chat(array $C){
global $I, $db, $memcached, $session;
setcookie(COOKIENAME, false);
$session = '';
print_start('destory');
print_start('destroy');
$db->exec('DROP TABLE ' . PREFIX . 'captcha;');
$db->exec('DROP TABLE ' . PREFIX . 'files;');
$db->exec('DROP TABLE ' . PREFIX . 'filter;');
@ -3737,7 +3756,7 @@ function init_chat(){
$db->exec('CREATE INDEX ' . PREFIX . 'inbox_poster ON ' . PREFIX . 'inbox(poster);');
$db->exec('CREATE INDEX ' . PREFIX . 'inbox_recipient ON ' . PREFIX . 'inbox(recipient);');
$db->exec('CREATE TABLE ' . PREFIX . "linkfilter (id $primary, filtermatch varchar(255) NOT NULL, filterreplace varchar(255) NOT NULL, regex smallint NOT NULL)$diskengine$charset;");
$db->exec('CREATE TABLE ' . PREFIX . "members (id $primary, nickname varchar(50) NOT NULL UNIQUE, passhash varchar(255) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL)$diskengine$charset;");
$db->exec('CREATE TABLE ' . PREFIX . "members (id $primary, nickname varchar(50) NOT NULL UNIQUE, passhash varchar(255) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, loginfails integer unsigned NOT NULL DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL)$diskengine$charset;");
$db->exec('ALTER TABLE ' . PREFIX . 'inbox ADD FOREIGN KEY (recipient) REFERENCES ' . PREFIX . 'members(nickname) ON DELETE CASCADE ON UPDATE CASCADE;');
$db->exec('CREATE TABLE ' . PREFIX . "messages (id $primary, postdate integer NOT NULL, poststatus smallint NOT NULL, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text text NOT NULL, delstatus smallint NOT NULL)$diskengine$charset;");
$db->exec('CREATE INDEX ' . PREFIX . 'poster ON ' . PREFIX . 'messages (poster);');
@ -4082,7 +4101,7 @@ function update_db(){
$data=$result->fetchAll(PDO::FETCH_NUM);
$db->exec('DROP TABLE ' . PREFIX . 'members;');
$db->exec('CREATE TABLE ' . PREFIX . "members (id integer PRIMARY KEY AUTO_INCREMENT, nickname varchar(50) NOT NULL UNIQUE, passhash char(32) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, tz smallint NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;");
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, loginfails, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);');
foreach($data as $tmp){
$stmt->execute($tmp);
}
@ -4194,6 +4213,9 @@ function update_db(){
if($dbversion<45){
$db->exec('INSERT INTO ' . PREFIX . "settings (setting,value) VALUES ('memkickalways', '0'), ('sysmessagetxt', ' &nbsp;'),('namedoers', '1');");
}
if($dbversion<46){
$db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN loginfails integer unsigned NOT NULL DEFAULT 0;');
}
update_setting('dbversion', DBVERSION);
if($msgencrypted!==MSGENCRYPTED){
if(!extension_loaded('sodium')){
@ -4387,7 +4409,7 @@ function load_lang(){
function load_config(){
mb_internal_encoding('UTF-8');
define('VERSION', '1.24.1'); // Script version
define('DBVERSION', 45); // Database layout version
define('DBVERSION', 46); // Database layout version
define('MSGENCRYPTED', false); // Store messages encrypted in the database to prevent other database users from reading them - true/false - visit the setup page after editing!
define('ENCRYPTKEY_PASS', 'MY_SECRET_KEY'); // Recommended length: 32. Encryption key for messages
define('AES_IV_PASS', '012345678912'); // Recommended length: 12. AES Encryption IV

View File

@ -342,6 +342,8 @@ $T=[
'optional' => '(опционално)',
'userloggedin' => 'Потребителят с това потребителско име е вече логнат.',
'regednick' => 'Този ник е на регистриран член.',
'failednotice' => 'неуспешен опит за влизане',
'dismiss' => 'призна',
'eninbox' => 'Позволи офлайн пощенска кутия',
'inboxmsgs' => 'Прочети %d съобщения в пощенската ти кутия',
'offline' => '(офлайн)',

View File

@ -342,6 +342,8 @@ $T=[
'optional' => '(volitelný)',
'userloggedin' => 'Uživatel s touto přezdívkou je již přihlášen.',
'regednick' => 'Tato přezdívka používá registrovaný člen.',
'failednotice' => 'neúspěšné pokusy o přihlášení',
'dismiss' => 'uznal',
'eninbox' => 'Povolit offline doručenou poštu ',
'inboxmsgs' => 'Přečtěte si %d zprávy ve vaší doručené poště',
'offline' => '(offline)',

View File

@ -343,6 +343,8 @@ $T=[
'optional' => '(optional)',
'userloggedin' => 'Ein Nutzer mit diesem Nicknamen ist bereits angemeldet.',
'regednick' => 'Dieser Nickname ist ein registeriertes Mitglied.',
'failednotice' => 'Fehlgeschlagener Anmeldeversuch(n)',
'dismiss' => 'entlassen',
'eninbox' => 'Offline Posteingang aktivieren',
'inboxmsgs' => '%d Nachrichten im Posteingang lesen',
'offline' => '(offline)',

View File

@ -343,6 +343,8 @@ $I=[
'optional' => '(optional)',
'userloggedin' => 'A user with this nickname is already logged in.',
'regednick' => 'This nickname is a registered member.',
'failednotice' => 'failed login attempt(s)',
'dismiss' => 'dismiss',
'eninbox' => 'Enable offline inbox',
'inboxmsgs' => 'Read %d messages in your inbox',
'offline' => '(offline)',

View File

@ -342,6 +342,8 @@ $T=[
'optional' => '(opcional)',
'userloggedin' => 'Un usuario con ese nombre ya está registrado.',
'regednick' => 'Este nombre es un usuario registrado.',
'failednotice' => 'intento(s) de inicio de sesión fallido(s)',
'dismiss' => 'reconocido',
'eninbox' => 'Activar inbox offline',
'inboxmsgs' => 'Leer %d mensajes en tu bandeja',
'offline' => '(offline)',

View File

@ -312,5 +312,7 @@ $T=[
'nicknametaken' => 'Pseudo déjà pris',
'nopass' => 'Mot de passe invalide (au moins % caractères), ne pas changer le pseudo',
'namedoers' => 'Montrez qui expulse les gens ou nettoie tous les messages.',
'failednotice' => 'tentative de connexion ratée(s)',
'dismiss' => 'reconnu',
];

View File

@ -311,6 +311,8 @@ $T=[
'newnickname' => 'Nama baru:',
'nicknametaken' => 'Nama sudah ada',
'nopass' => 'Kata sandi salah (Minimal %d karakter), tak merubah nama',
'namedoers' => 'Memperlihatkan siapa yang mengusir orang atau membersihkan semua pesan.'
'namedoers' => 'Memperlihatkan siapa yang mengusir orang atau membersihkan semua pesan.',
'failednotice' => 'upaya log masuk gagal',
'dismiss' => 'mengakui',
];

View File

@ -342,6 +342,8 @@ $T=[
'optional' => '(optional)',
'userloggedin' => 'Utilizzatore con questo nome è già in rete.',
'regednick' => 'Questo nome appartiene già ad un altro.',
'failednotice' => 'tentativi di accesso non riusciti',
'dismiss' => 'riconosciuto',
'eninbox' => 'Abilitare offline-posta',
'inboxmsgs' => 'Leggete %d messaggi in entrata',
'offline' => '(offline)',

View File

@ -343,6 +343,8 @@ $I=[
'optional' => '(opcional)',
'userloggedin' => 'Um usuário com este nickname já está logado.',
'regednick' => 'Este nickname é de um membro registrado.',
'failednotice' => 'tentativas de login falhada(s)',
'dismiss' => 'reconhecido',
'eninbox' => 'Ativar caixa de entrada offline',
'inboxmsgs' => 'Leia %d mensagens na sua caixa de entrada',
'offline' => '(offline)',

View File

@ -342,6 +342,8 @@ $T=[
'optional' => '(опционально)',
'userloggedin' => 'Пользователь с текущим именем уже в сети.',
'regednick' => 'Это имя принадлежит зарегистрированному пользователю.',
'failednotice' => 'неудачная попытка входа (ы)',
'dismiss' => 'признал',
'eninbox' => 'Включить оффлайн-почту',
'inboxmsgs' => 'Прочитайте %d входящих сообщений',
'offline' => '(оффлайн)',

View File

@ -343,6 +343,8 @@ $T=[
'optional' => '(isteğe bağlı)',
'userloggedin' => 'Bu kullanıcı ismine sahip birisi zaten giriş yapmış.',
'regednick' => 'Bu kullanıcı adı kayıtlı bir üyeye ait.',
'failednotice' => 'başarısız oturum açma girişimleri',
'dismiss' => 'anlaşıldı',
'eninbox' => 'Çevrimdışı gelen kutusunu etkinleştir',
'inboxmsgs' => 'Gelen kutunuzdaki %d mesajı okuyun',
'offline' => '(çevrimdışı)',

View File

@ -342,6 +342,8 @@ $T=[
'optional' => '(опційно)',
'userloggedin' => 'Гость з таким имям вже в чаті.',
'regednick' => 'Це імя використовуе зарегістріруваний участник.',
'failednotice' => 'невдалі спроби входу',
'dismiss' => 'визнав',
'eninbox' => 'Включити офлайн-почту',
'inboxmsgs' => 'Прочитайте %d вхідящих повідомлень',
'offline' => '(офлайн)',

View File

@ -1,7 +1,7 @@
<?php
$native = 'suomi (Suomi)'; // Native lanugae name
$english = 'Suomi (FI)'; // Enlish language name
$code = 'fi_FI'; // Language code
$native = 'Español (España)'; // Native language name
$english = 'Spanish (ES)'; // English language name
$code = 'es_ES'; // Language code
ob_start();
$file = "<?php

View File

@ -322,6 +322,8 @@ $T=[
'optional' => '(可选的)',
'userloggedin' => '具有此昵称的用户已登录.',
'regednick' => '这个昵称是注册会员.',
'failednotice' => '登录尝试失败',
'dismiss' => '承认',
'eninbox' => '启用离线收件箱',
'inboxmsgs' => '阅读收件箱中的%d条消息',
'offline' => '(离线)',