mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-25 14:15:51 +02:00
tslint changes
This commit is contained in:
+130
-130
@@ -18,200 +18,200 @@ import { IAccount } from './db';
|
||||
const ROLLBAR_IP = '35.184.69.251';
|
||||
|
||||
export const notFound: RequestHandler = (_, res) => {
|
||||
res.setHeader('Cache-Control', 'public, max-age=0');
|
||||
res.sendStatus(404);
|
||||
res.setHeader('Cache-Control', 'public, max-age=0');
|
||||
res.sendStatus(404);
|
||||
};
|
||||
|
||||
export const validAccount = (server: ServerConfig): RequestHandler => (req, res, next) => {
|
||||
const account = req.user as IAccount | undefined;
|
||||
const accountId = req.body.accountId as string;
|
||||
const accountName = req.body.accountName as string;
|
||||
const account = req.user as IAccount | undefined;
|
||||
const accountId = req.body.accountId as string;
|
||||
const accountName = req.body.accountName as string;
|
||||
|
||||
if (!account || account.id !== accountId) {
|
||||
if (!/#$/.test(accountId)) {
|
||||
createFromRequest(server, req).warn(ACCOUNT_ERROR, `${accountName} [${accountId}] (${req.path})`);
|
||||
}
|
||||
//logger.warn(ACCOUNT_ERROR, `${accountName} [${accountId}] (${req.path})`);
|
||||
res.status(403).json({ error: ACCOUNT_ERROR });
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
if (!account || account.id !== accountId) {
|
||||
if (!/#$/.test(accountId)) {
|
||||
createFromRequest(server, req).warn(ACCOUNT_ERROR, `${accountName} [${accountId}] (${req.path})`);
|
||||
}
|
||||
//logger.warn(ACCOUNT_ERROR, `${accountName} [${accountId}] (${req.path})`);
|
||||
res.status(403).json({ error: ACCOUNT_ERROR });
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
};
|
||||
|
||||
export const blockMaps = (debug: boolean, local: boolean): RequestHandler => (req, res, next) => {
|
||||
if (!debug && !local && /\.map$/.test(req.path) && getIP(req) !== ROLLBAR_IP) {
|
||||
res.sendStatus(404);
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
if (!debug && !local && /\.map$/.test(req.path) && getIP(req) !== ROLLBAR_IP) {
|
||||
res.sendStatus(404);
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
};
|
||||
|
||||
export const hash: RequestHandler = (req, res, next) => {
|
||||
const apiVersion = req.get('api-version');
|
||||
const apiVersion = req.get('api-version');
|
||||
|
||||
if (apiVersion !== HASH) {
|
||||
res.status(400).json({ error: VERSION_ERROR });
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
if (apiVersion !== HASH) {
|
||||
res.status(400).json({ error: VERSION_ERROR });
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
};
|
||||
|
||||
export const offline = (settings: Settings): RequestHandler => (_req, res, next) => {
|
||||
if (settings.isPageOffline) {
|
||||
res.status(503).send(OFFLINE_ERROR);
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
if (settings.isPageOffline) {
|
||||
res.status(503).send(OFFLINE_ERROR);
|
||||
} else {
|
||||
next(null);
|
||||
}
|
||||
};
|
||||
|
||||
export const internal = (config: AppConfig, server: ServerConfig): RequestHandler => (req, res, next) => {
|
||||
if (req.get('api-token') === config.token) {
|
||||
next(null);
|
||||
} else {
|
||||
createFromRequest(server, req).warn('Unauthorized internal api call', req.originalUrl);
|
||||
res.sendStatus(403);
|
||||
}
|
||||
if (req.get('api-token') === config.token) {
|
||||
next(null);
|
||||
} else {
|
||||
createFromRequest(server, req).warn('Unauthorized internal api call', req.originalUrl);
|
||||
res.sendStatus(403);
|
||||
}
|
||||
};
|
||||
|
||||
export const auth: RequestHandler = (req, res, next) => {
|
||||
if (req.isAuthenticated()) {
|
||||
next(null);
|
||||
} else {
|
||||
//createFromRequest(req).warn('Unauthorized access', req.originalUrl);
|
||||
res.setHeader('X-Robots-Tag', 'noindex');
|
||||
res.sendStatus(403);
|
||||
}
|
||||
if (req.isAuthenticated()) {
|
||||
next(null);
|
||||
} else {
|
||||
//createFromRequest(req).warn('Unauthorized access', req.originalUrl);
|
||||
res.setHeader('X-Robots-Tag', 'noindex');
|
||||
res.sendStatus(403);
|
||||
}
|
||||
};
|
||||
|
||||
export const admin = (server: ServerConfig): RequestHandler => (req, res, next) => {
|
||||
if (req.isAuthenticated() && req.user && isAdmin(req.user)) {
|
||||
next(null);
|
||||
} else {
|
||||
if (!/Googlebot/.test(req.get('User-Agent')!)) {
|
||||
createFromRequest(server, req).warn(`Unauthorized access (admin)`, req.originalUrl);
|
||||
}
|
||||
if (req.isAuthenticated() && req.user && isAdmin(req.user)) {
|
||||
next(null);
|
||||
} else {
|
||||
if (!/Googlebot/.test(req.get('User-Agent')!)) {
|
||||
createFromRequest(server, req).warn(`Unauthorized access (admin)`, req.originalUrl);
|
||||
}
|
||||
|
||||
res.setHeader('X-Robots-Tag', 'noindex, nofollow');
|
||||
res.sendStatus(403);
|
||||
}
|
||||
res.setHeader('X-Robots-Tag', 'noindex, nofollow');
|
||||
res.sendStatus(403);
|
||||
}
|
||||
};
|
||||
|
||||
const store = new ExpressBrute.MemoryStore();
|
||||
|
||||
export function limit(freeRetries: number, lifetime: number) {
|
||||
const options: any = {
|
||||
freeRetries,
|
||||
lifetime,
|
||||
failCallback(req: Request, res: Response, _next: NextFunction, nextValidRequestDate: any) {
|
||||
logger.warn(`rate limit ${req.url} ${req.ip}`);
|
||||
res.status(429).send(`Too many requests, please try again ${moment(nextValidRequestDate).fromNow()}`);
|
||||
}
|
||||
};
|
||||
const options: any = {
|
||||
freeRetries,
|
||||
lifetime,
|
||||
failCallback(req: Request, res: Response, _next: NextFunction, nextValidRequestDate: any) {
|
||||
logger.warn(`rate limit ${req.url} ${req.ip}`);
|
||||
res.status(429).send(`Too many requests, please try again ${moment(nextValidRequestDate).fromNow()}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (new (ExpressBrute as any)(store, options)).prevent;
|
||||
return (new (ExpressBrute as any)(store, options)).prevent;
|
||||
}
|
||||
|
||||
function reportError(e: Error, server: ServerConfig, req: Request) {
|
||||
createFromRequest(server, req).danger(`Req error: ${e.message}`, `${req.method.toUpperCase()} ${req.originalUrl}`);
|
||||
logger.error(e);
|
||||
createFromRequest(server, req).danger(`Req error: ${e.message}`, `${req.method.toUpperCase()} ${req.originalUrl}`);
|
||||
logger.error(e);
|
||||
}
|
||||
|
||||
export function handleError(server: ServerConfig, req: Request, res: Response) {
|
||||
return (e: Error) => {
|
||||
if (isUserError(e)) {
|
||||
reportUserError(e, server, req);
|
||||
res.status(422).json({ error: e.message, userError: true });
|
||||
} else {
|
||||
reportError(e, server, req);
|
||||
res.status(500).json({ error: 'Error occurred' });
|
||||
}
|
||||
};
|
||||
return (e: Error) => {
|
||||
if (isUserError(e)) {
|
||||
reportUserError(e, server, req);
|
||||
res.status(422).json({ error: e.message, userError: true });
|
||||
} else {
|
||||
reportError(e, server, req);
|
||||
res.status(500).json({ error: 'Error occurred' });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let logRequest: (req: Request, result: any, url?: string) => void = noop;
|
||||
|
||||
export function initLogRequest(func: typeof logRequest) {
|
||||
logRequest = func;
|
||||
logRequest = func;
|
||||
}
|
||||
|
||||
export function handleJSON(server: ServerConfig, req: Request, res: Response, result: any): any {
|
||||
Promise.resolve(result)
|
||||
.then(result => {
|
||||
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate, max-age=0');
|
||||
res.json(result);
|
||||
return result;
|
||||
})
|
||||
.then(result => logRequest(req, result))
|
||||
.catch(handleError(server, req, res));
|
||||
Promise.resolve(result)
|
||||
.then(result => {
|
||||
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate, max-age=0');
|
||||
res.json(result);
|
||||
return result;
|
||||
})
|
||||
.then(result => logRequest(req, result))
|
||||
.catch(handleError(server, req, res));
|
||||
}
|
||||
|
||||
export function wrap(server: ServerConfig, handle: (req: Request) => any): RequestHandler {
|
||||
return (req, res) => handleJSON(server, req, res, handle(req));
|
||||
return (req, res) => handleJSON(server, req, res, handle(req));
|
||||
}
|
||||
|
||||
export function wrapApi(server: ServerConfig, api: any) {
|
||||
return wrap(server, ({ body: { method, args = [] } }) => {
|
||||
if (api[method]) {
|
||||
return api[method](...args);
|
||||
} else {
|
||||
return Promise.reject(new Error(`Invalid method (${method})`));
|
||||
}
|
||||
});
|
||||
return wrap(server, ({ body: { method, args = [] } }) => {
|
||||
if (api[method]) {
|
||||
return api[method](...args);
|
||||
} else {
|
||||
return Promise.reject(new Error(`Invalid method (${method})`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
interface StaticFile {
|
||||
buffer: Buffer;
|
||||
mimeType: string;
|
||||
buffer: Buffer;
|
||||
mimeType: string;
|
||||
}
|
||||
|
||||
function readFiles(files: Map<string, StaticFile>, dir: string, url: string) {
|
||||
const mimeTypes: any = {
|
||||
'.js': 'application/javascript; charset=utf-8',
|
||||
'.css': 'text/css; charset=utf-8',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
};
|
||||
const mimeTypes: any = {
|
||||
'.js': 'application/javascript; charset=utf-8',
|
||||
'.css': 'text/css; charset=utf-8',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
};
|
||||
|
||||
for (const file of fs.readdirSync(dir)) {
|
||||
const filePath = path.join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
for (const file of fs.readdirSync(dir)) {
|
||||
const filePath = path.join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
readFiles(files, filePath, `${url}/${file}`);
|
||||
} else {
|
||||
const ext = path.extname(file);
|
||||
const mimeType = mimeTypes[ext];
|
||||
if (stat.isDirectory()) {
|
||||
readFiles(files, filePath, `${url}/${file}`);
|
||||
} else {
|
||||
const ext = path.extname(file);
|
||||
const mimeType = mimeTypes[ext];
|
||||
|
||||
if (mimeType) {
|
||||
const buffer = fs.readFileSync(filePath);
|
||||
files.set(`${url}/${file}`, { mimeType, buffer });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mimeType) {
|
||||
const buffer = fs.readFileSync(filePath);
|
||||
files.set(`${url}/${file}`, { mimeType, buffer });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function inMemoryStaticFiles(assetsPath: string, assetsUrl: string, maxAge: number): RequestHandler {
|
||||
const staticFiles = new Map<string, StaticFile>();
|
||||
const cacheControl = `public, max-age=${Math.floor(maxAge / 1000)}`;
|
||||
readFiles(staticFiles, assetsPath, assetsUrl);
|
||||
const staticFiles = new Map<string, StaticFile>();
|
||||
const cacheControl = `public, max-age=${Math.floor(maxAge / 1000)}`;
|
||||
readFiles(staticFiles, assetsPath, assetsUrl);
|
||||
|
||||
return (req, res, next) => {
|
||||
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||
return next();
|
||||
}
|
||||
return (req, res, next) => {
|
||||
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||
return next();
|
||||
}
|
||||
|
||||
const staticFile = staticFiles.get(req.path);
|
||||
const staticFile = staticFiles.get(req.path);
|
||||
|
||||
if (!staticFile) {
|
||||
return next();
|
||||
}
|
||||
if (!staticFile) {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
res.setHeader('Content-Type', staticFile.mimeType);
|
||||
res.setHeader('Cache-Control', cacheControl);
|
||||
res.status(200).end(staticFile.buffer);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
};
|
||||
try {
|
||||
res.setHeader('Content-Type', staticFile.mimeType);
|
||||
res.setHeader('Cache-Control', cacheControl);
|
||||
res.status(200).end(staticFile.buffer);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user