fix minor issues
This commit is contained in:
parent
be8f94b368
commit
0e78dea560
|
@ -7,12 +7,12 @@ import { t } from 'ttag';
|
|||
|
||||
async function submitIPAction(
|
||||
action,
|
||||
vallist,
|
||||
callback,
|
||||
) {
|
||||
const data = new FormData();
|
||||
const iplist = document.getElementById('iparea').value;
|
||||
data.append('ip', iplist);
|
||||
data.append('ipaction', action);
|
||||
data.append('ip', vallist);
|
||||
const resp = await fetch('./api/modtools', {
|
||||
credentials: 'include',
|
||||
method: 'POST',
|
||||
|
@ -72,8 +72,9 @@ async function submitMakeMod(
|
|||
|
||||
|
||||
function Admintools() {
|
||||
const [iPAction, selectIPAction] = useState('ban');
|
||||
const [iPAction, selectIPAction] = useState('iidtoip');
|
||||
const [modName, selectModName] = useState('');
|
||||
const [txtval, setTxtval] = useState('');
|
||||
const [resp, setResp] = useState(null);
|
||||
const [modlist, setModList] = useState([]);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
@ -114,9 +115,10 @@ function Admintools() {
|
|||
selectIPAction(sel.options[sel.selectedIndex].value);
|
||||
}}
|
||||
>
|
||||
{['iidtoip']
|
||||
{['iidtoip', 'iptoiid']
|
||||
.map((opt) => (
|
||||
<option
|
||||
key={opt}
|
||||
value={opt}
|
||||
>
|
||||
{opt}
|
||||
|
@ -124,7 +126,12 @@ function Admintools() {
|
|||
))}
|
||||
</select>
|
||||
<br />
|
||||
<textarea rows="10" cols="17" id="iparea" /><br />
|
||||
<textarea
|
||||
rows="10"
|
||||
cols="17"
|
||||
value={txtval}
|
||||
onChange={(e) => setTxtval(e.target.value)}
|
||||
/><br />
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
|
@ -134,9 +141,10 @@ function Admintools() {
|
|||
setSubmitting(true);
|
||||
submitIPAction(
|
||||
iPAction,
|
||||
txtval,
|
||||
(ret) => {
|
||||
setSubmitting(false);
|
||||
setResp(ret);
|
||||
setTxtval(ret);
|
||||
},
|
||||
);
|
||||
}}
|
||||
|
@ -157,6 +165,7 @@ function Admintools() {
|
|||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
key={mod[0]}
|
||||
onClick={() => {
|
||||
if (submitting) {
|
||||
return;
|
||||
|
|
|
@ -62,19 +62,19 @@ const Alert = () => {
|
|||
className={(open && render) ? 'Alert show' : 'Alert'}
|
||||
>
|
||||
<h2>{title}</h2>
|
||||
<p className="modaltext">
|
||||
{message}
|
||||
</p>
|
||||
<div>
|
||||
{(Content) ? (
|
||||
<Content close={close} />
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={close}
|
||||
>{btn}</button>
|
||||
)}
|
||||
</div>
|
||||
{(message) && (
|
||||
<p className="modaltext">
|
||||
{message}
|
||||
</p>
|
||||
)}
|
||||
{(Content) ? (
|
||||
<Content close={close} />
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={close}
|
||||
>{btn}</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import useInterval from './hooks/interval';
|
||||
import { showHelpModal } from '../store/actions';
|
||||
import {
|
||||
largeDurationToString,
|
||||
} from '../core/utils';
|
||||
|
@ -14,17 +16,20 @@ import { requestBanInfo } from '../store/actions/fetch';
|
|||
|
||||
const BanInfo = ({ close }) => {
|
||||
const [errors, setErrors] = useState([]);
|
||||
const [reason, setReason] = useState('');
|
||||
const [reason, setReason] = useState(null);
|
||||
const [mod, setMod] = useState(null);
|
||||
const [expireTs, setExpireTs] = useState(0);
|
||||
const [expire, setExpire] = useState(null);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const handleSubmit = async (evt) => {
|
||||
evt.preventDefault();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (submitting) {
|
||||
return;
|
||||
}
|
||||
setSubmitting(true);
|
||||
setErrors([]);
|
||||
const info = await requestBanInfo();
|
||||
setSubmitting(false);
|
||||
if (info.errors) {
|
||||
|
@ -32,37 +37,64 @@ const BanInfo = ({ close }) => {
|
|||
return;
|
||||
}
|
||||
const {
|
||||
ts,
|
||||
sleft,
|
||||
mod: newMod,
|
||||
reason: newReason,
|
||||
} = info;
|
||||
setExpireTs(ts);
|
||||
const tsDate = new Date(ts);
|
||||
setExpire(tsDate.toLocaleString);
|
||||
if (sleft) {
|
||||
const tsDate = new Date(Date.now() + sleft * 1000);
|
||||
setExpireTs(sleft);
|
||||
setExpire(tsDate.toLocaleString());
|
||||
}
|
||||
setMod(newMod);
|
||||
setReason(newReason);
|
||||
};
|
||||
|
||||
useInterval(() => {
|
||||
console.log('do');
|
||||
if (expireTs) {
|
||||
if (expireTs > 0) {
|
||||
setExpireTs(expireTs - 1);
|
||||
if (expireTs === 1) {
|
||||
handleSubmit();
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
/* eslint-disable max-len */
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ userSelect: 'text' }}>
|
||||
<p className="modaltext">
|
||||
{t`You are banned. You think it is unjustifed? Check out the `}
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="modallink"
|
||||
onClick={() => {
|
||||
dispatch(showHelpModal());
|
||||
close();
|
||||
}}
|
||||
>{t`Help`}</span>
|
||||
{t` on how to appeal.`}
|
||||
</p>
|
||||
{errors.map((error) => (
|
||||
<p key={error} className="errormessage">
|
||||
<span>{t`Error`}</span>: {error}
|
||||
</p>
|
||||
))}
|
||||
{(reason) && (
|
||||
<>
|
||||
<React.Fragment key="rea">
|
||||
<h3 className="modaltitle">{t`Reason`}:</h3>
|
||||
<p className="modaltext">{reason}</p>
|
||||
</>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{(expireTs) && (
|
||||
<>
|
||||
{(mod) && (
|
||||
<React.Fragment key="mod">
|
||||
<h3 className="modaltitle">{t`By Mod`}:</h3>
|
||||
<p className="modaltext">{mod}</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{(expireTs > 0) && (
|
||||
<React.Fragment key="exp">
|
||||
<h3 className="modaltitle">{t`Duration`}:</h3>
|
||||
<p className="modaltext">
|
||||
{t`Your ban expires at `}
|
||||
|
@ -74,17 +106,27 @@ const BanInfo = ({ close }) => {
|
|||
{largeDurationToString(expireTs)}
|
||||
</span>
|
||||
</p>
|
||||
</>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{(expireTs < 0) && (
|
||||
<React.Fragment key="nb">
|
||||
<h3 className="modaltitle">{t`Unbanned`}:</h3>
|
||||
<p className="modaltext">{t`Now that you have seen this message, you are no longer banned.`}</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<p>
|
||||
<button
|
||||
type="button"
|
||||
style={{ fontSize: 16 }}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{(submitting) ? '...' : t`Why?`}
|
||||
</button>
|
||||
|
||||
{(!reason) && (
|
||||
<React.Fragment key="btnr">
|
||||
<button
|
||||
type="button"
|
||||
style={{ fontSize: 16 }}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{(submitting) ? '...' : t`Why?`}
|
||||
</button>
|
||||
|
||||
</React.Fragment>
|
||||
)}
|
||||
<button
|
||||
type="submit"
|
||||
style={{ fontSize: 16 }}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* show IID
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import { notify } from '../store/actions';
|
||||
import copyTextToClipboard from '../utils/clipboard';
|
||||
import {
|
||||
requestIID,
|
||||
} from '../store/actions/fetch';
|
||||
|
||||
const GetIID = () => {
|
||||
const [iid, setIID] = useState('');
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<p>
|
||||
<input
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '100%',
|
||||
maxWidth: '18em',
|
||||
}}
|
||||
readOnly
|
||||
value={iid}
|
||||
/>
|
||||
{(!iid)
|
||||
? (
|
||||
<button
|
||||
key="subtn"
|
||||
type="button"
|
||||
onClick={async () => {
|
||||
setSubmitting(true);
|
||||
const resp = await requestIID();
|
||||
if (resp.iid) {
|
||||
setIID(resp.iid);
|
||||
}
|
||||
setSubmitting(false);
|
||||
}}
|
||||
>{(submitting) ? '...' : t`Get IID`}</button>
|
||||
) : (
|
||||
<button
|
||||
key="cobtn"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
copyTextToClipboard(iid);
|
||||
dispatch(notify(t`Copied!`));
|
||||
}}
|
||||
>{t`Copy`}</button>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(GetIID);
|
|
@ -43,6 +43,7 @@ function LanguageSelect() {
|
|||
{
|
||||
langs.map(([l]) => (
|
||||
<option
|
||||
key={l}
|
||||
value={l}
|
||||
>
|
||||
{l.toUpperCase()}
|
||||
|
|
|
@ -14,11 +14,18 @@ async function submitIIDAction(
|
|||
duration,
|
||||
callback,
|
||||
) {
|
||||
let time = parseInterval(duration);
|
||||
if (time === 0 && duration !== '0') {
|
||||
callback(t`You must enter an IID`);
|
||||
return;
|
||||
}
|
||||
if (!iid) {
|
||||
callback(t`You must enter an IID`);
|
||||
return;
|
||||
}
|
||||
const time = Date.now() + parseInterval(duration);
|
||||
if (time > 0) {
|
||||
time += Date.now();
|
||||
}
|
||||
const data = new FormData();
|
||||
data.append('iidaction', action);
|
||||
data.append('reason', reason);
|
||||
|
@ -61,7 +68,7 @@ function ModIIDtools() {
|
|||
))}
|
||||
</select>
|
||||
{(iIDAction === 'ban') && (
|
||||
<>
|
||||
<React.Fragment key="ban">
|
||||
<p>{t`Reason`}</p>
|
||||
<input
|
||||
maxLength="200"
|
||||
|
@ -88,7 +95,7 @@ function ModIIDtools() {
|
|||
/>
|
||||
{t`(0 = infinite)`}
|
||||
</p>
|
||||
</>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<p className="modalcotext">
|
||||
{' IID: '}
|
||||
|
|
|
@ -7,6 +7,7 @@ import React, { useState, useEffect } from 'react';
|
|||
import { useSelector, shallowEqual } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
|
||||
import copyTextToClipboard from '../utils/clipboard';
|
||||
import { parseInterval } from '../core/utils';
|
||||
|
||||
const keepState = {
|
||||
|
@ -341,11 +342,22 @@ function ModWatchtools() {
|
|||
);
|
||||
}
|
||||
case 'cid': {
|
||||
const cid = (cidColumn > 0)
|
||||
? row[cidColumn] : selectedCanvas;
|
||||
const ident = canvases[cid] && canvases[cid].ident;
|
||||
const ident = canvases[val] && canvases[val].ident;
|
||||
return (<td>{ident}</td>);
|
||||
}
|
||||
case 'uuid': {
|
||||
return (
|
||||
<td>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
style={{ cursor: 'pointer' }}
|
||||
title={t`Copy to Clipboard`}
|
||||
onClick={() => copyTextToClipboard(val)}
|
||||
>{val}</span>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
case 'user': {
|
||||
const seperator = val.lastIndexOf(',');
|
||||
if (seperator === -1) {
|
||||
|
|
|
@ -7,8 +7,9 @@ import { c, t, jt } from 'ttag';
|
|||
import { GiMouse } from 'react-icons/gi';
|
||||
import { MdTouchApp } from 'react-icons/md';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
import GetIID from '../GetIID';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
|
||||
const Help = () => {
|
||||
const bindG = <kbd>{c('keybinds').t`G`}</kbd>;
|
||||
|
@ -33,7 +34,6 @@ const Help = () => {
|
|||
const starhouseLink = <a href="https://twitter.com/starhousedev">starhouse </a>;
|
||||
const vinikLink = <a href="https://twitter.com/Vinikdev">Vinikdev</a>;
|
||||
const guildedLink = <a href="https://pixelplanet.fun/guilded">guilded</a>;
|
||||
const getIPLink = <a href="https://www.whatismyip.com/">{t`your IP`}</a>;
|
||||
const mailLink = <a href="mailto:admin@pixelplanet.fun">admin@pixelplanet.fun</a>;
|
||||
|
||||
return (
|
||||
|
@ -52,9 +52,10 @@ pixels and 7s on already set pixels.`}<br />
|
|||
<p className="modaltitle">{t`Map Data`}</p>
|
||||
<p className="modaltext">{t`The bare map data that we use, together with converted OpenStreetMap tiles for orientation, \
|
||||
can be downloaded from mega.nz here: `}<a href="https://mega.nz/#!JpkBwAbJ!EnSLlZmKv3kEBE0HDhakTgAZZycD3ELjduajJxPGaXo">pixelplanetmap.zip</a> (422MB)</p>
|
||||
<p className="modaltitle">{t`Detected as Proxy?`}</p>
|
||||
<p className="modaltitle">{t`Banned? Detected as Proxy?`}</p>
|
||||
<div className="modaltext">
|
||||
<p>{jt`If you got detected as proxy, but you are none, please go to our ${guildedLink} or send us an e-mail with ${getIPLink} to ${mailLink}. Do not post your IP anywhere else. We are sorry for the inconvenience.`}</p>
|
||||
<p>{jt`If you got detected as proxy, but you are none, or think that you got wrongfully banned, please go to our ${guildedLink} or send us an e-mail to ${mailLink} and include the following IID:`}</p>
|
||||
<GetIID />
|
||||
</div>
|
||||
<h3 className="modaltitle">2D {t`Controls`}</h3>
|
||||
<div className="modaltext" style={{ lineHeight: 1.8 }}>
|
||||
|
|
|
@ -26,7 +26,11 @@ import {
|
|||
banIP,
|
||||
unbanIP,
|
||||
} from '../data/sql/Ban';
|
||||
import { getInfoToIp, getIPofIID } from '../data/sql/IPInfo';
|
||||
import {
|
||||
getInfoToIp,
|
||||
getIPofIID,
|
||||
getIIDofIP,
|
||||
} from '../data/sql/IPInfo';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import canvases from './canvases.json';
|
||||
import {
|
||||
|
@ -48,31 +52,25 @@ import rollbackCanvasArea from './rollback';
|
|||
* @return text of success
|
||||
*/
|
||||
export async function executeIPAction(action, ips, logger = null) {
|
||||
const ipArray = ips.split('\n');
|
||||
const valueArray = ips.split('\n');
|
||||
let out = '';
|
||||
for (let i = 0; i < ipArray.length; i += 1) {
|
||||
const ip = ipArray[i].trim();
|
||||
for (let i = 0; i < valueArray.length; i += 1) {
|
||||
const value = valueArray[i].trim();
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (logger) logger(`${action} ${value}`);
|
||||
|
||||
if (action === 'iidtoip') {
|
||||
const resIp = await getIPofIID(ip);
|
||||
const iidPart = ip.slice(0, ip.indexOf('-'));
|
||||
if (resIp) {
|
||||
out += `${iidPart}: ${resIp}\n`;
|
||||
} else {
|
||||
out += `${iidPart}: N/A\n`;
|
||||
}
|
||||
const ip = await getIPofIID(value);
|
||||
out += (ip) ? `${ip}\n` : `${value}\n`;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ip || ip.length < 8 || ip.indexOf(' ') !== -1) {
|
||||
out += `Couln't parse ${action} ${ip}\n`;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (logger) logger(`${action} ${ip}`);
|
||||
switch (action) {
|
||||
default:
|
||||
return `Failed to ${action} ${ip}\n`;
|
||||
if (action === 'iptoiid') {
|
||||
const iid = await getIIDofIP(value);
|
||||
out += (iid) ? `${iid}\n` : `${value}\n`;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
@ -98,10 +96,12 @@ export async function executeIIDAction(
|
|||
}
|
||||
const iidPart = iid.slice(0, iid.indexOf('-'));
|
||||
|
||||
if (logger) logger(`${action} ${iid} ${ip}`);
|
||||
|
||||
switch (action) {
|
||||
case 'status': {
|
||||
const allowed = await isIPAllowed(ip, true);
|
||||
let out = `Allowed to place: ${allowed.allowed}`;
|
||||
let out = `Allowed to place: ${allowed.allowed}\n`;
|
||||
const info = await getInfoToIp(ip);
|
||||
out += `Country: ${info.country}\n`
|
||||
+ `CIDR: ${info.cidr}\n`
|
||||
|
@ -119,7 +119,8 @@ export async function executeIIDAction(
|
|||
if (!ban) {
|
||||
out += 'banned: false\n';
|
||||
} else {
|
||||
out += `reason: ${ban.reason}\n`;
|
||||
out += 'banned: true\n'
|
||||
+ `reason: ${ban.reason}\n`;
|
||||
if (ban.expires) {
|
||||
out += `expires: ${ban.expires.toLocaleString()}\n`;
|
||||
}
|
||||
|
@ -140,28 +141,27 @@ export async function executeIIDAction(
|
|||
return `${iidPart} would have gotten captcha anyway`;
|
||||
}
|
||||
case 'ban': {
|
||||
if (expire && expire < Date.now()) {
|
||||
const expireTs = parseInt(expire, 10);
|
||||
if (Number.isNaN(expireTs) || (expireTs && expireTs < Date.now())) {
|
||||
return 'No valid expiration time';
|
||||
}
|
||||
if (!reason) {
|
||||
if (!reason || !reason.trim()) {
|
||||
return 'No reason specified';
|
||||
}
|
||||
const ret = await banIP(ip, reason, expire || null, muid);
|
||||
const ret = await banIP(ip, reason, expireTs || null, muid);
|
||||
if (ret) {
|
||||
await cleanCacheForIP(ip);
|
||||
return 'Successfully banned user';
|
||||
}
|
||||
return 'User is already banned';
|
||||
return 'Updated existing ban of user';
|
||||
}
|
||||
case 'unban': {
|
||||
const ret = await unbanIP(ip);
|
||||
if (ret) {
|
||||
await cleanCacheForIP(ip);
|
||||
return 'Successfully unbanned user';
|
||||
}
|
||||
return 'User is not banned';
|
||||
}
|
||||
case 'Whitelist': {
|
||||
case 'whitelist': {
|
||||
const ret = await whitelistIP(ip);
|
||||
if (ret) {
|
||||
await cleanCacheForIP(ip);
|
||||
|
|
|
@ -94,14 +94,12 @@ async function dummy() {
|
|||
return [false, 'dummy'];
|
||||
}
|
||||
|
||||
async function saveIPInfo(ip, whoisRet, isProxy, info) {
|
||||
const whoisData = whoisRet || {};
|
||||
|
||||
async function saveIPInfo(ip, whoisRet, allowed, info) {
|
||||
try {
|
||||
IPInfo.upsert({
|
||||
await IPInfo.upsert({
|
||||
...whoisRet,
|
||||
ip,
|
||||
...whoisData,
|
||||
isProxy,
|
||||
proxy: allowed,
|
||||
pcheck: info,
|
||||
});
|
||||
} catch (error) {
|
||||
|
@ -136,9 +134,9 @@ async function withoutCache(f, ip) {
|
|||
allowed = !allowed;
|
||||
status = (allowed) ? 0 : 1;
|
||||
}
|
||||
whoisRet = await whois(ip);
|
||||
whoisRet = await whois(ip) || {};
|
||||
} finally {
|
||||
await saveIPInfo(ipKey, whoisRet, allowed, pcInfo);
|
||||
await saveIPInfo(ipKey, whoisRet, status, pcInfo);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -176,16 +174,18 @@ async function withCache(f, ip) {
|
|||
if (checking.indexOf(ipKey) === -1 && lock > 0) {
|
||||
lock -= 1;
|
||||
checking.push(ipKey);
|
||||
try {
|
||||
const result = await withoutCache(f, ip);
|
||||
cacheAllowed(ip, result);
|
||||
} catch (error) {
|
||||
logger.error('Error %s', error.message || error);
|
||||
} finally {
|
||||
const pos = checking.indexOf(ipKey);
|
||||
if (~pos) checking.splice(pos, 1);
|
||||
lock += 1;
|
||||
}
|
||||
withoutCache(f, ip)
|
||||
.then((result) => {
|
||||
cacheAllowed(ipKey, result);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error('Error %s', error.message || error);
|
||||
})
|
||||
.finally(() => {
|
||||
const pos = checking.indexOf(ipKey);
|
||||
if (~pos) checking.splice(pos, 1);
|
||||
lock += 1;
|
||||
});
|
||||
}
|
||||
return {
|
||||
allowed: true,
|
||||
|
|
|
@ -249,15 +249,13 @@ export function durationToString(
|
|||
export function largeDurationToString(
|
||||
ts,
|
||||
) {
|
||||
let restA = Math.round(ts / 1000);
|
||||
let restB = restA % (3600 * 24);
|
||||
const days = restA - restB;
|
||||
restA = restB % 3600;
|
||||
const hours = restB - restA;
|
||||
restB = restA % 60;
|
||||
const minutes = restA - restB;
|
||||
restA = restB % 60;
|
||||
const seconds = restB - restA;
|
||||
const seconds = ts % 60;
|
||||
let durs = (ts - seconds) / 60;
|
||||
const minutes = durs % 60;
|
||||
durs = (durs - minutes) / 60;
|
||||
const hours = durs % 24;
|
||||
durs = (durs - hours) / 24;
|
||||
const days = durs;
|
||||
let out = '';
|
||||
if (days) {
|
||||
out += ` ${days}d`;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { DataTypes } from 'sequelize';
|
||||
import { DataTypes, Op } from 'sequelize';
|
||||
import sequelize from './sequelize';
|
||||
|
||||
import RegUser from './RegUser';
|
||||
import { HourlyCron } from '../../utils/cron';
|
||||
import { cleanCacheForIP } from '../redis/isAllowedCache';
|
||||
|
||||
const Ban = sequelize.define('Blacklist', {
|
||||
const Ban = sequelize.define('Ban', {
|
||||
ip: {
|
||||
type: DataTypes.CHAR(39),
|
||||
allowNull: false,
|
||||
|
@ -41,7 +43,38 @@ const Ban = sequelize.define('Blacklist', {
|
|||
},
|
||||
});
|
||||
|
||||
Ban.belongsTo(RegUser, {
|
||||
as: 'mod',
|
||||
foreignKey: 'muid',
|
||||
});
|
||||
|
||||
async function cleanBans() {
|
||||
const expiredIPs = await Ban.findAll({
|
||||
attributes: [
|
||||
'ip',
|
||||
],
|
||||
where: {
|
||||
expires: {
|
||||
[Op.lte]: new Date(),
|
||||
},
|
||||
},
|
||||
raw: true,
|
||||
});
|
||||
const ips = [];
|
||||
for (let i = 0; i < expiredIPs.length; i += 1) {
|
||||
ips.push(expiredIPs[i].ip);
|
||||
}
|
||||
await Ban.destroy({
|
||||
where: {
|
||||
ip: ips,
|
||||
},
|
||||
});
|
||||
for (let i = 0; i < ips.length; i += 1) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await cleanCacheForIP(ips[i]);
|
||||
}
|
||||
}
|
||||
HourlyCron.hook(cleanBans);
|
||||
|
||||
/*
|
||||
* check if ip is whitelisted
|
||||
|
@ -61,16 +94,20 @@ export async function isIPBanned(ip) {
|
|||
* @param ip
|
||||
* @return
|
||||
*/
|
||||
export async function getBanInfo(ip) {
|
||||
const ban = await Ban.findByPk(ip, {
|
||||
include: [{
|
||||
export function getBanInfo(ip) {
|
||||
return Ban.findByPk(ip, {
|
||||
attributes: ['reason', 'expires'],
|
||||
include: {
|
||||
model: RegUser,
|
||||
as: 'mod',
|
||||
foreignKey: 'muid',
|
||||
attributes: ['id', 'name'],
|
||||
}],
|
||||
attributes: [
|
||||
'id',
|
||||
'name',
|
||||
],
|
||||
},
|
||||
raw: true,
|
||||
nest: true,
|
||||
});
|
||||
return ban;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -85,15 +122,14 @@ export async function banIP(
|
|||
expiresTs,
|
||||
muid,
|
||||
) {
|
||||
const expires = (expiresTs) ? new Date(expiresTs) : null;
|
||||
const [, created] = await Ban.findOrCreate({
|
||||
where: { ip },
|
||||
defaults: {
|
||||
reason,
|
||||
expires,
|
||||
muid,
|
||||
},
|
||||
const expires = (expiresTs) ? new Date(expiresTs).toISOString() : null;
|
||||
const [, created] = await Ban.upsert({
|
||||
ip,
|
||||
reason,
|
||||
expires,
|
||||
muid,
|
||||
});
|
||||
await cleanCacheForIP(ip);
|
||||
return created;
|
||||
}
|
||||
|
||||
|
@ -107,6 +143,7 @@ export async function unbanIP(ip) {
|
|||
const count = await Ban.destroy({
|
||||
where: { ip },
|
||||
});
|
||||
await cleanCacheForIP(ip);
|
||||
return !!count;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,9 @@ const IPInfo = sequelize.define('IPInfo', {
|
|||
},
|
||||
|
||||
pcheck(value) {
|
||||
this.setDataValue('pcheck', value.slice(0, 60));
|
||||
if (value) {
|
||||
this.setDataValue('pcheck', value.slice(0, 60));
|
||||
}
|
||||
},
|
||||
|
||||
country(value) {
|
||||
|
@ -101,12 +103,25 @@ export async function getIPofIID(uuid) {
|
|||
raw: true,
|
||||
});
|
||||
} catch {
|
||||
// nothing
|
||||
}
|
||||
return result && result.ip;
|
||||
}
|
||||
|
||||
export async function getIIDofIP(ip) {
|
||||
if (!ip) {
|
||||
return null;
|
||||
}
|
||||
if (result) {
|
||||
return result.ip;
|
||||
let result = null;
|
||||
try {
|
||||
result = await IPInfo.findByPk(ip, {
|
||||
attributes: ['uuid'],
|
||||
raw: true,
|
||||
});
|
||||
} catch {
|
||||
// nothing
|
||||
}
|
||||
return null;
|
||||
return result && result.uuid;
|
||||
}
|
||||
|
||||
export async function getIdsToIps(ips) {
|
||||
|
|
|
@ -103,12 +103,4 @@ router.post('/local', passport.authenticate('json'), async (req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
router.use((err, req, res, next) => {
|
||||
res.status(400);
|
||||
res.json({
|
||||
errors: [err.message],
|
||||
});
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
*
|
||||
*/
|
||||
import {
|
||||
getIPFromRequest,
|
||||
getIPv6Subnet,
|
||||
} from '../../utils/ip';
|
||||
import {
|
||||
getBanInfo,
|
||||
unbanIP,
|
||||
} from '../../data/sql/Ban';
|
||||
|
||||
async function baninfo(req, res, next) {
|
||||
try {
|
||||
const { t } = req.ttag;
|
||||
|
||||
const ip = getIPv6Subnet(
|
||||
getIPFromRequest(req),
|
||||
);
|
||||
|
||||
const info = await getBanInfo(ip);
|
||||
|
||||
if (!info) {
|
||||
throw new Error(t`You are not banned`);
|
||||
}
|
||||
let sleft = (info.expires)
|
||||
? Math.round((info.expires.getTime() - Date.now()) / 1000)
|
||||
: 0;
|
||||
|
||||
if (info.expires && sleft < 3) {
|
||||
await unbanIP(ip);
|
||||
sleft = -1;
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
reason: info.reason,
|
||||
sleft,
|
||||
mod: `${info.mod.name} (${info.mod.id})`,
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
|
||||
export default baninfo;
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
*
|
||||
*/
|
||||
import {
|
||||
getIPFromRequest,
|
||||
getIPv6Subnet,
|
||||
} from '../../utils/ip';
|
||||
import {
|
||||
getIIDofIP,
|
||||
} from '../../data/sql/IPInfo';
|
||||
|
||||
async function getiid(req, res, next) {
|
||||
try {
|
||||
const ip = getIPv6Subnet(
|
||||
getIPFromRequest(req),
|
||||
);
|
||||
|
||||
const iid = await getIIDofIP(ip);
|
||||
|
||||
if (!iid) {
|
||||
throw new Error('Could not get IID');
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
iid,
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
|
||||
export default getiid;
|
|
@ -15,24 +15,26 @@ import leaveChan from './leavechan';
|
|||
import block from './block';
|
||||
import blockdm from './blockdm';
|
||||
import modtools from './modtools';
|
||||
import baninfo from './baninfo';
|
||||
import getiid from './getiid';
|
||||
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.use(express.json());
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
router.use((err, req, res, next) => {
|
||||
if (err) {
|
||||
logger.warn(`Got invalid json from ${req.trueIp} on ${req.originalUrl}`);
|
||||
res.status(400);
|
||||
res.status(400).json({ errors: [{ msg: 'Invalid Request' }] });
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
logger.warn(`Got invalid json from ${req.trueIp} on ${req.originalUrl}`);
|
||||
res.status(400).json({
|
||||
errors: [{ msg: 'Invalid Request' }],
|
||||
});
|
||||
});
|
||||
|
||||
// captcah doesn't need a user
|
||||
// routes that don't need a user
|
||||
router.post('/captcha', captcha);
|
||||
router.get('/baninfo', baninfo);
|
||||
router.get('/getiid', getiid);
|
||||
|
||||
/*
|
||||
* get user session
|
||||
|
@ -87,4 +89,11 @@ router.get('/me', me);
|
|||
|
||||
router.use('/auth', auth);
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
router.use((err, req, res, next) => {
|
||||
res.status(400).json({
|
||||
errors: [err.message],
|
||||
});
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -89,103 +89,112 @@ router.post('/', upload.single('image'), async (req, res, next) => {
|
|||
);
|
||||
};
|
||||
|
||||
if (req.body.cleanerstat) {
|
||||
const ret = CanvasCleaner.reportStatus();
|
||||
res.status(200);
|
||||
res.json(ret);
|
||||
return;
|
||||
const bLogger = (text) => {
|
||||
logger.info(`IID> ${req.user.regUser.name}[${req.user.id}]> ${text}`);
|
||||
};
|
||||
|
||||
try {
|
||||
if (req.body.cleanerstat) {
|
||||
const ret = CanvasCleaner.reportStatus();
|
||||
res.status(200);
|
||||
res.json(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.cleanercancel) {
|
||||
const ret = CanvasCleaner.stop();
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.watchaction) {
|
||||
const {
|
||||
watchaction, ulcoor, brcoor, time, iid, canvasid,
|
||||
} = req.body;
|
||||
const ret = await executeWatchAction(
|
||||
watchaction,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
time,
|
||||
iid,
|
||||
canvasid,
|
||||
);
|
||||
res.status(200).json(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.iidaction) {
|
||||
const {
|
||||
iidaction, iid, reason, time,
|
||||
} = req.body;
|
||||
const ret = await executeIIDAction(
|
||||
iidaction,
|
||||
iid,
|
||||
reason,
|
||||
time,
|
||||
req.user.id,
|
||||
bLogger,
|
||||
);
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.cleaneraction) {
|
||||
const {
|
||||
cleaneraction, ulcoor, brcoor, canvasid,
|
||||
} = req.body;
|
||||
const [ret, msg] = await executeCleanerAction(
|
||||
cleaneraction,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
canvasid,
|
||||
aLogger,
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
if (req.body.imageaction) {
|
||||
const { imageaction, coords, canvasid } = req.body;
|
||||
const [ret, msg] = await executeImageAction(
|
||||
imageaction,
|
||||
req.file,
|
||||
coords,
|
||||
canvasid,
|
||||
aLogger,
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
if (req.body.protaction) {
|
||||
const {
|
||||
protaction, ulcoor, brcoor, canvasid,
|
||||
} = req.body;
|
||||
const [ret, msg] = await executeProtAction(
|
||||
protaction,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
canvasid,
|
||||
aLogger,
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
if (req.body.rollback) {
|
||||
// rollback is date as YYYYMMdd
|
||||
const {
|
||||
rollback, ulcoor, brcoor, canvasid,
|
||||
} = req.body;
|
||||
const [ret, msg] = await executeRollback(
|
||||
rollback,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
canvasid,
|
||||
aLogger,
|
||||
(req.user.userlvl === 1),
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
if (req.body.cleanercancel) {
|
||||
const ret = CanvasCleaner.stop();
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.watchaction) {
|
||||
const {
|
||||
watchaction, ulcoor, brcoor, time, iid, canvasid,
|
||||
} = req.body;
|
||||
const ret = await executeWatchAction(
|
||||
watchaction,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
time,
|
||||
iid,
|
||||
canvasid,
|
||||
);
|
||||
res.status(200).json(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.iidaction) {
|
||||
const {
|
||||
iidaction, iid, reason, time,
|
||||
} = req.body;
|
||||
const ret = await executeIIDAction(
|
||||
iidaction,
|
||||
iid,
|
||||
reason,
|
||||
time,
|
||||
req.user.id,
|
||||
);
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.cleaneraction) {
|
||||
const {
|
||||
cleaneraction, ulcoor, brcoor, canvasid,
|
||||
} = req.body;
|
||||
const [ret, msg] = await executeCleanerAction(
|
||||
cleaneraction,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
canvasid,
|
||||
aLogger,
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
if (req.body.imageaction) {
|
||||
const { imageaction, coords, canvasid } = req.body;
|
||||
const [ret, msg] = await executeImageAction(
|
||||
imageaction,
|
||||
req.file,
|
||||
coords,
|
||||
canvasid,
|
||||
aLogger,
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
if (req.body.protaction) {
|
||||
const {
|
||||
protaction, ulcoor, brcoor, canvasid,
|
||||
} = req.body;
|
||||
const [ret, msg] = await executeProtAction(
|
||||
protaction,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
canvasid,
|
||||
aLogger,
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
if (req.body.rollback) {
|
||||
// rollback is date as YYYYMMdd
|
||||
const {
|
||||
rollback, ulcoor, brcoor, canvasid,
|
||||
} = req.body;
|
||||
const [ret, msg] = await executeRollback(
|
||||
rollback,
|
||||
ulcoor,
|
||||
brcoor,
|
||||
canvasid,
|
||||
aLogger,
|
||||
(req.user.userlvl === 1),
|
||||
);
|
||||
res.status(ret).send(msg);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
|
@ -209,33 +218,37 @@ router.post('/', async (req, res, next) => {
|
|||
logger.info(`ADMIN> ${req.user.regUser.name}[${req.user.id}]> ${text}`);
|
||||
};
|
||||
|
||||
if (req.body.ipaction) {
|
||||
const ret = await executeIPAction(
|
||||
req.body.ipaction,
|
||||
req.body.ip,
|
||||
aLogger,
|
||||
);
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
try {
|
||||
if (req.body.ipaction) {
|
||||
const ret = await executeIPAction(
|
||||
req.body.ipaction,
|
||||
req.body.ip,
|
||||
aLogger,
|
||||
);
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.modlist) {
|
||||
const ret = await getModList();
|
||||
res.status(200);
|
||||
res.json(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.remmod) {
|
||||
const ret = await removeMod(req.body.remmod);
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.makemod) {
|
||||
const ret = await makeMod(req.body.makemod);
|
||||
res.status(200);
|
||||
res.json(ret);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
if (req.body.modlist) {
|
||||
const ret = await getModList();
|
||||
res.status(200);
|
||||
res.json(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.remmod) {
|
||||
const ret = await removeMod(req.body.remmod);
|
||||
res.status(200).send(ret);
|
||||
return;
|
||||
}
|
||||
if (req.body.makemod) {
|
||||
const ret = await makeMod(req.body.makemod);
|
||||
res.status(200);
|
||||
res.json(ret);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
router.use(async (req, res) => {
|
||||
|
|
|
@ -491,20 +491,21 @@ class SocketServer {
|
|||
if (await needCaptcha(ip)) {
|
||||
// need captcha
|
||||
failureRet = PixelReturn.dehydrate(10, 0, 0);
|
||||
}
|
||||
// (re)check for Proxy
|
||||
const allowed = await isIPAllowed(ip);
|
||||
if (!allowed.allowed) {
|
||||
// proxy
|
||||
let failureStatus = 11;
|
||||
if (allowed.status === 2) {
|
||||
// banned
|
||||
failureStatus = 14;
|
||||
} else if (allowed.status === 3) {
|
||||
// range banned
|
||||
failureStatus = 15;
|
||||
} else {
|
||||
// (re)check for Proxy
|
||||
const allowed = await isIPAllowed(ip);
|
||||
if (!allowed.allowed) {
|
||||
// proxy
|
||||
let failureStatus = 11;
|
||||
if (allowed.status === 2) {
|
||||
// banned
|
||||
failureStatus = 14;
|
||||
} else if (allowed.status === 3) {
|
||||
// range banned
|
||||
failureStatus = 15;
|
||||
}
|
||||
failureRet = PixelReturn.dehydrate(failureStatus, 0, 0);
|
||||
}
|
||||
failureRet = PixelReturn.dehydrate(failureStatus, 0, 0);
|
||||
}
|
||||
if (failureRet !== null) {
|
||||
const now = Date.now();
|
||||
|
|
|
@ -41,7 +41,6 @@ export type Action =
|
|||
| { type: 'SELECT_CANVAS', canvasId: number }
|
||||
| { type: 'PLACED_PIXELS', amount: number }
|
||||
| { type: 'PIXEL_WAIT' }
|
||||
| { type: 'PIXEL_FAILURE' }
|
||||
| { type: 'SET_VIEW_COORDINATES', view: Array }
|
||||
| { type: 'SET_SCALE', scale: number, zoompoint: Array }
|
||||
| { type: 'REQUEST_BIG_CHUNK', center: Array }
|
||||
|
|
|
@ -293,3 +293,9 @@ export function requestMe() {
|
|||
'api/me',
|
||||
);
|
||||
}
|
||||
|
||||
export function requestIID() {
|
||||
return makeAPIGETRequest(
|
||||
'api/getiid',
|
||||
);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,10 @@ export function toggleOpenMenu() {
|
|||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* requestingPixel is inveted, it has the meaning of
|
||||
* "can i request a pixel"
|
||||
*/
|
||||
export function setRequestingPixel(requestingPixel) {
|
||||
return {
|
||||
type: 'SET_REQUESTING_PIXEL',
|
||||
|
@ -195,12 +199,6 @@ export function pixelWait() {
|
|||
};
|
||||
}
|
||||
|
||||
export function pixelFailure() {
|
||||
return {
|
||||
type: 'PIXEL_FAILURE',
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveOnline(online) {
|
||||
return {
|
||||
type: 'RECEIVE_ONLINE',
|
||||
|
|
|
@ -94,7 +94,10 @@ export default (store) => (next) => (action) => {
|
|||
break;
|
||||
}
|
||||
|
||||
case 'PIXEL_FAILURE': {
|
||||
case 'ALERT': {
|
||||
if (action.alertType !== 'error') {
|
||||
break;
|
||||
}
|
||||
const oscillatorNode = context.createOscillator();
|
||||
const gainNode = context.createGain();
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
setRequestingPixel,
|
||||
pAlert,
|
||||
gotCoolDownDelta,
|
||||
pixelFailure,
|
||||
setWait,
|
||||
placedPixels,
|
||||
pixelWait,
|
||||
|
@ -187,6 +186,7 @@ export function receivePixelReturn(
|
|||
|
||||
let errorTitle = null;
|
||||
let msg = null;
|
||||
let type = 'error';
|
||||
switch (retCode) {
|
||||
case 0:
|
||||
store.dispatch(placedPixels(pxlCnt));
|
||||
|
@ -228,13 +228,10 @@ export function receivePixelReturn(
|
|||
store.dispatch(pixelWait());
|
||||
break;
|
||||
case 10:
|
||||
store.dispatch(pAlert(
|
||||
'Captcha',
|
||||
t`Please prove that you are human`,
|
||||
'captcha',
|
||||
));
|
||||
store.dispatch(setRequestingPixel(true));
|
||||
return;
|
||||
errorTitle = 'Captcha';
|
||||
msg = t`Please prove that you are human`;
|
||||
type = 'captcha';
|
||||
break;
|
||||
case 11:
|
||||
errorTitle = t`No Proxies Allowed :(`;
|
||||
msg = t`You are using a Proxy.`;
|
||||
|
@ -249,13 +246,9 @@ export function receivePixelReturn(
|
|||
msg = t`Server got confused by your pixels. Are you playing on multiple devices?`;
|
||||
break;
|
||||
case 14:
|
||||
store.dispatch(pAlert(
|
||||
'Banned',
|
||||
t`You are banned.`,
|
||||
'ban',
|
||||
));
|
||||
store.dispatch(setRequestingPixel(true));
|
||||
return;
|
||||
errorTitle = t`Banned`;
|
||||
type = t`ban`;
|
||||
break;
|
||||
case 15:
|
||||
errorTitle = t`Range Banned`;
|
||||
msg = t`Your Internet Provider is banned from playing this game`;
|
||||
|
@ -265,17 +258,19 @@ export function receivePixelReturn(
|
|||
msg = t`Couldn't set Pixel`;
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
store.dispatch(pixelFailure());
|
||||
if (msg || errorTitle) {
|
||||
store.dispatch(pAlert(
|
||||
(errorTitle || t`Error ${retCode}`),
|
||||
msg,
|
||||
'error',
|
||||
type,
|
||||
));
|
||||
}
|
||||
|
||||
store.dispatch(setRequestingPixel(true));
|
||||
/* start next request if queue isn't empty */
|
||||
requestFromQueue(store);
|
||||
|
||||
if (!msg) {
|
||||
/* start next request if queue isn't empty */
|
||||
requestFromQueue(store);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ class Cron {
|
|||
}
|
||||
|
||||
checkForExecution() {
|
||||
this.timeout = setTimeout(this.checkForExecution, HOUR);
|
||||
const curDate = new Date();
|
||||
const curTime = curDate.getTime();
|
||||
this.timeout = setTimeout(this.checkForExecution, HOUR);
|
||||
if (curTime + 120000 > this.lastRun + this.interval * HOUR) {
|
||||
// eslint-disable-next-line max-len
|
||||
logger.info(`${curDate.toUTCString()}> Run cron events for interval: ${this.interval}h`);
|
||||
|
@ -65,7 +65,7 @@ function initializeDailyCron() {
|
|||
}
|
||||
|
||||
function initializeHourlyCron() {
|
||||
const cron = new Cron(1, Date.now());
|
||||
const cron = new Cron(1);
|
||||
return cron;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue