fix table width
more captcha changes
This commit is contained in:
parent
7dd44811a6
commit
1c0b1101b0
|
@ -6,3 +6,4 @@ apps:
|
|||
PORT: 8080
|
||||
HOST: "localhost"
|
||||
REDIS_URL: 'redis://localhost:6379'
|
||||
CAPTCHA_TIMEOUT: 120
|
||||
|
|
|
@ -8,6 +8,9 @@ import process from 'process';
|
|||
import http from 'http';
|
||||
import ppfunCaptcha from 'ppfun-captcha';
|
||||
|
||||
import { getIPFromRequest } from './utils/ip';
|
||||
import { setCaptchaSolution } from './utils/captcha';
|
||||
|
||||
const PORT = process.env.PORT || 8080;
|
||||
const HOST = process.env.HOST || 'localhost';
|
||||
|
||||
|
@ -22,8 +25,12 @@ const server = http.createServer((req, res) => {
|
|||
nodeDeviation: 0.5,
|
||||
connectionPathDeviation: 0.3,
|
||||
});
|
||||
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
|
||||
|
||||
const ip = getIPFromRequest(req);
|
||||
|
||||
setCaptchaSolution(captcha.text, ip);
|
||||
console.log(`Serving ${captcha.text} to ${ip}`);
|
||||
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'image/svg+xml',
|
||||
'Cache-Control': 'no-cache',
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
/*
|
||||
* Form to ask for captcha.
|
||||
* If callback is provided, it sets the captcha text to it.
|
||||
* If callback is not provided, it provides a button to send the
|
||||
* captcha itself
|
||||
* @flow
|
||||
*/
|
||||
|
||||
|
@ -6,6 +10,7 @@ import React, { useState } from 'react';
|
|||
import { t } from 'ttag';
|
||||
|
||||
import { IoReloadCircleSharp } from 'react-icons/io5';
|
||||
import { requestSolveCaptcha } from '../actions/fetch';
|
||||
|
||||
function getUrl() {
|
||||
return `${window.ssv.captchaurl}/captcha.svg?${new Date().getTime()}`;
|
||||
|
|
|
@ -90,5 +90,7 @@ export const auth = {
|
|||
|
||||
// time on which to display captcha in minutes
|
||||
export const CAPTCHA_TIME = parseInt(process.env.CAPTCHA_TIME, 10) || 30;
|
||||
// time during which the user can solve a captcha in seconds
|
||||
export const CAPTCHA_TIMEOUT = parseInt(process.env.CAPTCHA_TIMEOUT, 10) || 120;
|
||||
|
||||
export const SESSION_SECRET = process.env.SESSION_SECRET || 'dummy';
|
||||
|
|
|
@ -8,42 +8,51 @@
|
|||
import type { Request, Response } from 'express';
|
||||
|
||||
import logger from '../../core/logger';
|
||||
import { verifyCaptcha } from '../../utils/captcha';
|
||||
import { checkCaptchaSolution } from '../../utils/captcha';
|
||||
import { getIPFromRequest } from '../../utils/ip';
|
||||
|
||||
export default async (req: Request, res: Response) => {
|
||||
const ip = getIPFromRequest(req);
|
||||
const { t } = req.ttag;
|
||||
|
||||
try {
|
||||
const { token } = req.body;
|
||||
if (!token) {
|
||||
const { text } = req.body;
|
||||
if (!text) {
|
||||
res.status(400)
|
||||
.json({ errors: [{ msg: 'No token given' }] });
|
||||
.json({ errors: [t`No captcha text given`] });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await verifyCaptcha(token, ip)) {
|
||||
logger.info(`CAPTCHA ${ip} failed his captcha`);
|
||||
res.status(422)
|
||||
.json({
|
||||
errors: [{
|
||||
msg:
|
||||
'You failed your captcha',
|
||||
}],
|
||||
});
|
||||
return;
|
||||
}
|
||||
const ret = await checkCaptchaSolution(text, ip);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
res.status(200)
|
||||
.json({ success: true });
|
||||
break;
|
||||
case 1:
|
||||
res.status(422)
|
||||
.json({
|
||||
errors: [t`You took too long, try again.`],
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
res.status(422)
|
||||
.json({
|
||||
errors: [t`You failed your captcha`],
|
||||
});
|
||||
break;
|
||||
default:
|
||||
res.status(422)
|
||||
.json({
|
||||
errors: [t`Unknown Captcha Error`],
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('checkHuman', error);
|
||||
logger.error('CAPTCHA', error);
|
||||
res.status(500)
|
||||
.json({
|
||||
errors: [{
|
||||
msg:
|
||||
'Server error occured',
|
||||
}],
|
||||
errors: [t`Server error occured`],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -44,6 +44,11 @@ router.use((err, req, res, next) => {
|
|||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* make localisations available
|
||||
*/
|
||||
router.use(expressTTag);
|
||||
|
||||
// captcah doesn't need a user
|
||||
router.post('/captcha', captcha);
|
||||
|
||||
|
@ -89,11 +94,6 @@ router.post('/block', block);
|
|||
|
||||
router.post('/blockdm', blockdm);
|
||||
|
||||
/*
|
||||
* make localisations available
|
||||
*/
|
||||
router.use(expressTTag);
|
||||
|
||||
router.get('/chathistory', chatHistory);
|
||||
|
||||
router.get('/me', me);
|
||||
|
|
|
@ -24,8 +24,6 @@ const Html = ({
|
|||
styles,
|
||||
// code as string
|
||||
code,
|
||||
// if recaptcha should get loaded
|
||||
useCaptcha,
|
||||
}) => (
|
||||
<html className="no-js" lang="en">
|
||||
<head>
|
||||
|
|
|
@ -112,6 +112,8 @@ td, th {
|
|||
border: 1px solid #dddddd;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
max-width: 18em;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
|
|
|
@ -241,7 +241,7 @@ export function receivePixelReturn(
|
|||
case 10:
|
||||
store.dispatch(sweetAlert(
|
||||
'Captcha',
|
||||
`Please prove that you are human..`,
|
||||
t`Please prove that you are human`,
|
||||
'captcha',
|
||||
t`OK`,
|
||||
));
|
||||
|
|
|
@ -5,58 +5,60 @@
|
|||
|
||||
import logger from '../core/logger';
|
||||
import redis from '../data/redis';
|
||||
|
||||
import { getIPv6Subnet } from './ip';
|
||||
import {
|
||||
CAPTCHA_URL,
|
||||
CAPTCHA_TIME,
|
||||
CAPTCHA_TIMEOUT,
|
||||
} from '../core/config';
|
||||
|
||||
const TTL_CACHE = CAPTCHA_TIME * 60; // seconds
|
||||
|
||||
/*
|
||||
* https://docs.hcaptcha.com/
|
||||
* set captcha solution
|
||||
*
|
||||
* @param token
|
||||
* @param text Solution of captcha
|
||||
* @param ip
|
||||
* @return boolean, true if successful, false on error or fail
|
||||
* @param ttl time to be valid in seconds
|
||||
*/
|
||||
async function verifyHCaptcha(
|
||||
token: string,
|
||||
export function setCaptchaSolution(
|
||||
text: string,
|
||||
ip: string,
|
||||
): Promise<boolean> {
|
||||
const success = true;
|
||||
if (success) {
|
||||
logger.info(`CAPTCHA ${ip} successfully solved captcha`);
|
||||
return true;
|
||||
}
|
||||
logger.info(`CAPTCHA Token for ${ip} not ok`);
|
||||
return false;
|
||||
) {
|
||||
const key = `capt:${getIPv6Subnet(ip)}`;
|
||||
return redis.setAsync(key, text, 'EX', CAPTCHA_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* verify captcha token from client
|
||||
* check captcha solution
|
||||
*
|
||||
* @param token token of solved captcha from client
|
||||
* @param text Solution of captcha
|
||||
* @param ip
|
||||
* @returns Boolean if successful
|
||||
* @return 0 if solution right
|
||||
* 1 if timed out
|
||||
* 2 if wrong
|
||||
*/
|
||||
export async function verifyCaptcha(
|
||||
token: string,
|
||||
export async function checkCaptchaSolution(
|
||||
text: string,
|
||||
ip: string,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const key = `human:${ip}`;
|
||||
|
||||
if (!await verifyHCaptcha(token, ip)) {
|
||||
return false;
|
||||
) {
|
||||
const ipn = getIPv6Subnet(ip);
|
||||
const key = `capt:${ipn}`;
|
||||
const solution = await redis.getAsync(key);
|
||||
if (solution) {
|
||||
if (solution.toString('utf8') === text) {
|
||||
const solvkey = `human:${ipn}`;
|
||||
await redis.setAsync(solvkey, '', 'EX', TTL_CACHE);
|
||||
logger.info(`CAPTCHA ${ip} successfully solved captcha`);
|
||||
return 0;
|
||||
}
|
||||
|
||||
await redis.setAsync(key, '', 'EX', TTL_CACHE);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
logger.info(
|
||||
`CAPTCHA ${ip} got captcha wrong (${text} instead of ${solution})`,
|
||||
);
|
||||
return 2;
|
||||
}
|
||||
return false;
|
||||
logger.info(`CAPTCHA ${ip} timed out`);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -70,7 +72,7 @@ export async function needCaptcha(ip: string) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const key = `human:${ip}`;
|
||||
const key = `human:${getIPv6Subnet(ip)}`;
|
||||
const ttl: number = await redis.ttlAsync(key);
|
||||
if (ttl > 0) {
|
||||
return false;
|
||||
|
@ -78,6 +80,3 @@ export async function needCaptcha(ip: string) {
|
|||
logger.info(`CAPTCHA ${ip} got captcha`);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
export default verifyCaptcha;
|
||||
|
|
Loading…
Reference in New Issue
Block a user