continue captchas
This commit is contained in:
parent
2b9cae2ca2
commit
45e6d15fb3
|
@ -34,6 +34,17 @@ async function fetchWithTimeout(resource, options) {
|
||||||
async function parseAPIresponse(response) {
|
async function parseAPIresponse(response) {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const code = response.status;
|
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 {
|
return {
|
||||||
errors: [t`Connection error ${code} :(`],
|
errors: [t`Connection error ${code} :(`],
|
||||||
};
|
};
|
||||||
|
@ -169,11 +180,17 @@ export async function requestLeaveChan(channelId: boolean) {
|
||||||
return t`Unknown Error`;
|
return t`Unknown Error`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestSolveCaptcha(text) {
|
export async function requestSolveCaptcha(text) {
|
||||||
return makeAPIPOSTRequest(
|
const res = await makeAPIPOSTRequest(
|
||||||
'api/captcha',
|
'api/captcha',
|
||||||
{ text },
|
{ text },
|
||||||
);
|
);
|
||||||
|
if (!res.errors && !res.success) {
|
||||||
|
return {
|
||||||
|
errors: [t`Server answered with gibberish :(`],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestPasswordChange(newPassword, password) {
|
export function requestPasswordChange(newPassword, password) {
|
||||||
|
|
|
@ -120,9 +120,9 @@ export function toggleOpenMenu(): Action {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setPlaceAllowed(requestingPixel: boolean): Action {
|
export function setRequestingPixel(requestingPixel: boolean): Action {
|
||||||
return {
|
return {
|
||||||
type: 'SET_PLACE_ALLOWED',
|
type: 'SET_REQUESTING_PIXEL',
|
||||||
requestingPixel,
|
requestingPixel,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ export type Action =
|
||||||
| { type: 'SELECT_STYLE', style: string }
|
| { type: 'SELECT_STYLE', style: string }
|
||||||
| { type: 'SET_NOTIFICATION', notification: string }
|
| { type: 'SET_NOTIFICATION', notification: string }
|
||||||
| { type: 'UNSET_NOTIFICATION' }
|
| { type: 'UNSET_NOTIFICATION' }
|
||||||
| { type: 'SET_PLACE_ALLOWED', requestingPixel: boolean }
|
| { type: 'SET_REQUESTING_PIXEL', requestingPixel: boolean }
|
||||||
| { type: 'SET_HOVER', hover: Cell }
|
| { type: 'SET_HOVER', hover: Cell }
|
||||||
| { type: 'UNSET_HOVER' }
|
| { type: 'UNSET_HOVER' }
|
||||||
| { type: 'SET_WAIT', wait: ?number }
|
| { type: 'SET_WAIT', wait: ?number }
|
||||||
|
|
|
@ -56,7 +56,7 @@ const Alert = () => {
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{(alertType === 'captcha')
|
{(alertType === 'captcha')
|
||||||
? <Captcha cancel={close} />
|
? <Captcha close={close} />
|
||||||
: (
|
: (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
@ -16,13 +16,18 @@ function getUrl() {
|
||||||
return `${window.ssv.captchaurl}/captcha.svg?${new Date().getTime()}`;
|
return `${window.ssv.captchaurl}/captcha.svg?${new Date().getTime()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Captcha = ({ callback, cancel }) => {
|
const Captcha = ({ callback, close }) => {
|
||||||
const [captchaUrl, setCaptchaUrl] = useState(getUrl());
|
const [captchaUrl, setCaptchaUrl] = useState(getUrl());
|
||||||
const [text, setText] = useState('');
|
const [text, setText] = useState('');
|
||||||
const [error, setError] = useState(false);
|
const [errors, setErrors] = useState([]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{errors.map((error) => (
|
||||||
|
<p key={error} className="errormessage">
|
||||||
|
<span>{t`Error`}</span>: {error}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
<p className="modaltext">
|
<p className="modaltext">
|
||||||
{t`Type the characters from the following image:`}
|
{t`Type the characters from the following image:`}
|
||||||
<span style={{ fontSize: 11 }}>
|
<span style={{ fontSize: 11 }}>
|
||||||
|
@ -32,7 +37,8 @@ const Captcha = ({ callback, cancel }) => {
|
||||||
<img
|
<img
|
||||||
style={{ width: '75%' }}
|
style={{ width: '75%' }}
|
||||||
src={captchaUrl}
|
src={captchaUrl}
|
||||||
onError={() => setError(true)}
|
alt="CAPTCHA"
|
||||||
|
onError={() => setErrors([t`Could not load captcha`])}
|
||||||
/>
|
/>
|
||||||
<p className="modaltext">
|
<p className="modaltext">
|
||||||
{t`Can't read? Reload:`}
|
{t`Can't read? Reload:`}
|
||||||
|
@ -62,12 +68,21 @@ const Captcha = ({ callback, cancel }) => {
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={cancel}
|
onClick={close}
|
||||||
>
|
>
|
||||||
{t`Cancel`}
|
{t`Cancel`}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
onClick={async () => {
|
||||||
|
const { errors: resErrors } = await requestSolveCaptcha(text);
|
||||||
|
if (resErrors) {
|
||||||
|
setCaptchaUrl(getUrl());
|
||||||
|
setErrors(resErrors);
|
||||||
|
} else {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{t`Send`}
|
{t`Send`}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -183,25 +183,6 @@ class UserArea extends React.Component {
|
||||||
done={() => { this.setState({ socialSettingsExtended: false }); }}
|
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>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ export default function user(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_PLACE_ALLOWED': {
|
case 'SET_REQUESTING_PIXEL': {
|
||||||
const { requestingPixel } = action;
|
const { requestingPixel } = action;
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default (store) => (next) => (action) => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_PLACE_ALLOWED': {
|
case 'SET_REQUESTING_PIXEL': {
|
||||||
const renderer = getRenderer();
|
const renderer = getRenderer();
|
||||||
renderer.forceNextSubRender = true;
|
renderer.forceNextSubRender = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import { t } from 'ttag';
|
import { t } from 'ttag';
|
||||||
import {
|
import {
|
||||||
notify,
|
notify,
|
||||||
setPlaceAllowed,
|
setRequestingPixel,
|
||||||
sweetAlert,
|
sweetAlert,
|
||||||
gotCoolDownDelta,
|
gotCoolDownDelta,
|
||||||
pixelFailure,
|
pixelFailure,
|
||||||
|
@ -48,7 +48,7 @@ function requestFromQueue(store) {
|
||||||
pixelTimeout = setTimeout(() => {
|
pixelTimeout = setTimeout(() => {
|
||||||
pixelQueue = [];
|
pixelQueue = [];
|
||||||
pixelTimeout = null;
|
pixelTimeout = null;
|
||||||
store.dispatch(setPlaceAllowed(true));
|
store.dispatch(setRequestingPixel(true));
|
||||||
store.dispatch(sweetAlert(
|
store.dispatch(sweetAlert(
|
||||||
t`Error :(`,
|
t`Error :(`,
|
||||||
t`Didn't get an answer from pixelplanet. Maybe try to refresh?`,
|
t`Didn't get an answer from pixelplanet. Maybe try to refresh?`,
|
||||||
|
@ -60,16 +60,7 @@ function requestFromQueue(store) {
|
||||||
lastRequestValues = pixelQueue.shift();
|
lastRequestValues = pixelQueue.shift();
|
||||||
const { i, j, pixels } = lastRequestValues;
|
const { i, j, pixels } = lastRequestValues;
|
||||||
ProtocolClient.requestPlacePixels(i, j, pixels);
|
ProtocolClient.requestPlacePixels(i, j, pixels);
|
||||||
store.dispatch(setPlaceAllowed(false));
|
store.dispatch(setRequestingPixel(false));
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// this is for resending after captcha returned
|
|
||||||
// window is ugly, put it into redux or something
|
|
||||||
window.pixel = {
|
|
||||||
i,
|
|
||||||
j,
|
|
||||||
pixels,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function receivePixelUpdate(
|
export function receivePixelUpdate(
|
||||||
|
@ -245,6 +236,7 @@ export function receivePixelReturn(
|
||||||
'captcha',
|
'captcha',
|
||||||
t`OK`,
|
t`OK`,
|
||||||
));
|
));
|
||||||
|
store.dispatch(setRequestingPixel(true));
|
||||||
return;
|
return;
|
||||||
case 11:
|
case 11:
|
||||||
errorTitle = t`No Proxies Allowed :(`;
|
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 */
|
/* start next request if queue isn't empty */
|
||||||
requestFromQueue(store);
|
requestFromQueue(store);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user