continue captchas

This commit is contained in:
HF 2021-03-17 11:00:58 +01:00
parent 2b9cae2ca2
commit 45e6d15fb3
9 changed files with 49 additions and 44 deletions

View File

@ -34,6 +34,17 @@ async function fetchWithTimeout(resource, options) {
async function parseAPIresponse(response) {
if (!response.ok) {
const code = response.status;
if (code === 429) {
let error = t`You made too many requests`;
const retryAfter = response.headers.get('Retry-After');
if (!Number.isNaN(Number(retryAfter))) {
const ti = Math.floor(retryAfter / 60);
error += `, ${t`try again after ${ti}min`}`;
}
return {
errors: [error],
};
}
return {
errors: [t`Connection error ${code} :(`],
};
@ -169,11 +180,17 @@ export async function requestLeaveChan(channelId: boolean) {
return t`Unknown Error`;
}
export function requestSolveCaptcha(text) {
return makeAPIPOSTRequest(
export async function requestSolveCaptcha(text) {
const res = await makeAPIPOSTRequest(
'api/captcha',
{ text },
);
if (!res.errors && !res.success) {
return {
errors: [t`Server answered with gibberish :(`],
};
}
return res;
}
export function requestPasswordChange(newPassword, password) {

View File

@ -120,9 +120,9 @@ export function toggleOpenMenu(): Action {
};
}
export function setPlaceAllowed(requestingPixel: boolean): Action {
export function setRequestingPixel(requestingPixel: boolean): Action {
return {
type: 'SET_PLACE_ALLOWED',
type: 'SET_REQUESTING_PIXEL',
requestingPixel,
};
}

View File

@ -29,7 +29,7 @@ export type Action =
| { type: 'SELECT_STYLE', style: string }
| { type: 'SET_NOTIFICATION', notification: string }
| { type: 'UNSET_NOTIFICATION' }
| { type: 'SET_PLACE_ALLOWED', requestingPixel: boolean }
| { type: 'SET_REQUESTING_PIXEL', requestingPixel: boolean }
| { type: 'SET_HOVER', hover: Cell }
| { type: 'UNSET_HOVER' }
| { type: 'SET_WAIT', wait: ?number }

View File

@ -56,7 +56,7 @@ const Alert = () => {
</p>
<p>
{(alertType === 'captcha')
? <Captcha cancel={close} />
? <Captcha close={close} />
: (
<button
type="button"

View File

@ -16,13 +16,18 @@ function getUrl() {
return `${window.ssv.captchaurl}/captcha.svg?${new Date().getTime()}`;
}
const Captcha = ({ callback, cancel }) => {
const Captcha = ({ callback, close }) => {
const [captchaUrl, setCaptchaUrl] = useState(getUrl());
const [text, setText] = useState('');
const [error, setError] = useState(false);
const [errors, setErrors] = useState([]);
return (
<div>
{errors.map((error) => (
<p key={error} className="errormessage">
<span>{t`Error`}</span>:&nbsp;{error}
</p>
))}
<p className="modaltext">
{t`Type the characters from the following image:`}
<span style={{ fontSize: 11 }}>
@ -32,7 +37,8 @@ const Captcha = ({ callback, cancel }) => {
<img
style={{ width: '75%' }}
src={captchaUrl}
onError={() => setError(true)}
alt="CAPTCHA"
onError={() => setErrors([t`Could not load captcha`])}
/>
<p className="modaltext">
{t`Can't read? Reload:`}&nbsp;
@ -62,12 +68,21 @@ const Captcha = ({ callback, cancel }) => {
<div>
<button
type="button"
onClick={cancel}
onClick={close}
>
{t`Cancel`}
</button>
<button
type="button"
onClick={async () => {
const { errors: resErrors } = await requestSolveCaptcha(text);
if (resErrors) {
setCaptchaUrl(getUrl());
setErrors(resErrors);
} else {
close();
}
}}
>
{t`Send`}
</button>

View File

@ -183,25 +183,6 @@ class UserArea extends React.Component {
done={() => { this.setState({ socialSettingsExtended: false }); }}
/>
)}
{(typeof window.hcaptcha !== 'undefined')
&& (
<img
role="presentation"
src="hcaptcha.svg"
alt="hCaptcha"
title="test hCaptcha"
onClick={() => {
window.pixel = null;
window.hcaptcha.execute();
}}
style={{
width: '5%',
height: '5%',
paddingTop: 20,
cursor: 'pointer',
}}
/>
)}
</p>
);
}

View File

@ -68,7 +68,7 @@ export default function user(
};
}
case 'SET_PLACE_ALLOWED': {
case 'SET_REQUESTING_PIXEL': {
const { requestingPixel } = action;
return {
...state,

View File

@ -47,7 +47,7 @@ export default (store) => (next) => (action) => {
break;
}
case 'SET_PLACE_ALLOWED': {
case 'SET_REQUESTING_PIXEL': {
const renderer = getRenderer();
renderer.forceNextSubRender = true;
break;

View File

@ -8,7 +8,7 @@
import { t } from 'ttag';
import {
notify,
setPlaceAllowed,
setRequestingPixel,
sweetAlert,
gotCoolDownDelta,
pixelFailure,
@ -48,7 +48,7 @@ function requestFromQueue(store) {
pixelTimeout = setTimeout(() => {
pixelQueue = [];
pixelTimeout = null;
store.dispatch(setPlaceAllowed(true));
store.dispatch(setRequestingPixel(true));
store.dispatch(sweetAlert(
t`Error :(`,
t`Didn't get an answer from pixelplanet. Maybe try to refresh?`,
@ -60,16 +60,7 @@ function requestFromQueue(store) {
lastRequestValues = pixelQueue.shift();
const { i, j, pixels } = lastRequestValues;
ProtocolClient.requestPlacePixels(i, j, pixels);
store.dispatch(setPlaceAllowed(false));
// TODO:
// this is for resending after captcha returned
// window is ugly, put it into redux or something
window.pixel = {
i,
j,
pixels,
};
store.dispatch(setRequestingPixel(false));
}
export function receivePixelUpdate(
@ -245,6 +236,7 @@ export function receivePixelReturn(
'captcha',
t`OK`,
));
store.dispatch(setRequestingPixel(true));
return;
case 11:
errorTitle = t`No Proxies Allowed :(`;
@ -265,7 +257,7 @@ export function receivePixelReturn(
));
}
store.dispatch(setPlaceAllowed(true));
store.dispatch(setRequestingPixel(true));
/* start next request if queue isn't empty */
requestFromQueue(store);
}