fix: modernize nullresolve runtime
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* autocreated commitinfo by @push.rocks/commitinfo
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@losslessone_private/nullresolve',
|
||||
version: '1.0.31',
|
||||
description: 'The nullresolve project is a private service designed to handle requests that would otherwise remain unserved, providing appropriate feedback mechanisms within the servzone architecture.'
|
||||
}
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
import './nullresolve.logging.js';
|
||||
import { NullResolve } from './nullresolve.classes.nullresolve.js';
|
||||
export { NullResolve };
|
||||
|
||||
let mainNullResolve: NullResolve;
|
||||
let mainNullResolve: NullResolve | null;
|
||||
|
||||
export const runCli = async () => {
|
||||
mainNullResolve = new NullResolve();
|
||||
|
||||
@@ -1,147 +1,162 @@
|
||||
import * as plugins from './nullresolve.plugins.js';
|
||||
import { projectinfo } from './nullresolve.projectinfo.js';
|
||||
import * as paths from './nullresolve.paths.js';
|
||||
import { configObject } from './nullresolve.config.js';
|
||||
import type { IHtmlInfoOptions } from '@api.global/typedserver/infohtml';
|
||||
|
||||
export interface INullResolveOptions {
|
||||
port?: number;
|
||||
serviceDomain?: string;
|
||||
}
|
||||
|
||||
type TResolvedNullResolveOptions = INullResolveOptions & {
|
||||
serviceDomain: string;
|
||||
};
|
||||
|
||||
export class NullResolve {
|
||||
public serviceServer: plugins.typedserver.utilityservers.UtilityServiceServer;
|
||||
public serviceServer: plugins.typedserver.utilityservers.UtilityServiceServer | null = null;
|
||||
private options: TResolvedNullResolveOptions;
|
||||
|
||||
constructor() {
|
||||
this.serviceServer = new plugins.typedserver.utilityservers.UtilityServiceServer({
|
||||
constructor(optionsArg: INullResolveOptions = {}) {
|
||||
this.options = {
|
||||
serviceDomain: 'nullresolve.lossless.one',
|
||||
serviceName: 'nullresolve',
|
||||
serviceVersion: projectinfo.npm.version,
|
||||
addCustomRoutes: async (serverArg) => {
|
||||
serverArg.addRoute(
|
||||
'/status/:code',
|
||||
new plugins.typedserver.servertools.Handler('GET', async (req, res) => {
|
||||
let infoHtmlOptions: plugins.typedserverInfoHtml.IHtmlInfoOptions;
|
||||
...optionsArg,
|
||||
};
|
||||
}
|
||||
|
||||
switch (req.params.code) {
|
||||
case 'ipblock':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: Blocked IP',
|
||||
heading: 'Blocked IP',
|
||||
text: 'Your IP (::CLIENT_IP::) is not allowed to access this ressource.',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: 'ipblock',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case 'firewall':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: Firewall',
|
||||
heading: 'Firewall',
|
||||
text: 'Your request has been blocked by our firewall since it showed possibly harmful behaviour.',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: 'firewall',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case '500class':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: 5xx',
|
||||
heading: '5xx',
|
||||
text: '::CLOUDFLARE_ERROR_500S_BOX::',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: '5xx error',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case '1000class':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: DNS Resolution failed',
|
||||
heading: '1xxx',
|
||||
text: '::CLOUDFLARE_ERROR_1000S_BOX::',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: '1000 class error',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case 'alwaysonline':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: No Cache',
|
||||
heading: 'No Cache',
|
||||
text: '::ALWAYS_ONLINE_NO_COPY_BOX::',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: 'alwaysonline triggered. Potentially offline!',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case 'waf':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: Firewall Challenge',
|
||||
heading: 'Firewall Challenge',
|
||||
text: '::CAPTCHA_BOX::',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case 'country':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: Country Challenge',
|
||||
heading: 'Country Challenge',
|
||||
text: '::CAPTCHA_BOX::',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
case 'attack':
|
||||
infoHtmlOptions = {
|
||||
title: 'Lossless Network: Advanced User Challenge',
|
||||
heading: 'Advanced User Challenge',
|
||||
text: '::IM_UNDER_ATTACK_BOX::',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
break;
|
||||
default:
|
||||
const statusInstance = plugins.smartstatus.HttpStatus.getHttpStatusByString(
|
||||
req.params.code,
|
||||
);
|
||||
infoHtmlOptions = {
|
||||
title: `Lossless Network: ${statusInstance.code.toString()}`,
|
||||
heading: statusInstance.code.toString(),
|
||||
text: statusInstance.text,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
const infoHtmlInstance =
|
||||
await plugins.typedserverInfoHtml.InfoHtml.fromOptions(infoHtmlOptions);
|
||||
res.status(200);
|
||||
res.send(infoHtmlInstance.htmlString);
|
||||
}),
|
||||
);
|
||||
|
||||
serverArg.addRoute(
|
||||
'/custom',
|
||||
new plugins.typedserver.servertools.Handler('GET', async (req, res) => {
|
||||
console.log(req.query);
|
||||
const options: any = {
|
||||
title: 'Lossless Network',
|
||||
heading: 'Error!',
|
||||
text: 'Please wait...',
|
||||
redirectTo: 'https://lossless.com',
|
||||
...req.query,
|
||||
};
|
||||
const infoHtmlInstance = await plugins.typedserverInfoHtml.InfoHtml.fromOptions({
|
||||
title: decodeURI(options.title),
|
||||
heading: decodeURI(options.heading),
|
||||
text: decodeURI(options.text),
|
||||
redirectTo: decodeURI(options.redirectTo),
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: `nullresolve custom: ${decodeURI(options.title)}`,
|
||||
});
|
||||
res.status(200);
|
||||
res.send(infoHtmlInstance.htmlString);
|
||||
}),
|
||||
);
|
||||
private async createInfoHtmlResponse(
|
||||
infoHtmlOptionsArg: IHtmlInfoOptions,
|
||||
) {
|
||||
const { InfoHtml } = await import('@api.global/typedserver/infohtml');
|
||||
const infoHtmlInstance = await InfoHtml.fromOptions(infoHtmlOptionsArg);
|
||||
return new Response(infoHtmlInstance.htmlString, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'content-type': 'text/html; charset=utf-8',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private getStatusInfoOptions(statusCodeArg: string): IHtmlInfoOptions {
|
||||
switch (statusCodeArg) {
|
||||
case 'ipblock':
|
||||
return {
|
||||
title: 'Lossless Network: Blocked IP',
|
||||
heading: 'Blocked IP',
|
||||
text: 'Your IP (::CLIENT_IP::) is not allowed to access this resource.',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: 'ipblock',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case 'firewall':
|
||||
return {
|
||||
title: 'Lossless Network: Firewall',
|
||||
heading: 'Firewall',
|
||||
text: 'Your request has been blocked by our firewall since it showed possibly harmful behaviour.',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: 'firewall',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case '500class':
|
||||
return {
|
||||
title: 'Lossless Network: 5xx',
|
||||
heading: '5xx',
|
||||
text: '::CLOUDFLARE_ERROR_500S_BOX::',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: '5xx error',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case '1000class':
|
||||
return {
|
||||
title: 'Lossless Network: DNS Resolution failed',
|
||||
heading: '1xxx',
|
||||
text: '::CLOUDFLARE_ERROR_1000S_BOX::',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: '1000 class error',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case 'alwaysonline':
|
||||
return {
|
||||
title: 'Lossless Network: No Cache',
|
||||
heading: 'No Cache',
|
||||
text: '::ALWAYS_ONLINE_NO_COPY_BOX::',
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: 'alwaysonline triggered. Potentially offline!',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case 'waf':
|
||||
return {
|
||||
title: 'Lossless Network: Firewall Challenge',
|
||||
heading: 'Firewall Challenge',
|
||||
text: '::CAPTCHA_BOX::',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case 'country':
|
||||
return {
|
||||
title: 'Lossless Network: Country Challenge',
|
||||
heading: 'Country Challenge',
|
||||
text: '::CAPTCHA_BOX::',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
case 'attack':
|
||||
return {
|
||||
title: 'Lossless Network: Advanced User Challenge',
|
||||
heading: 'Advanced User Challenge',
|
||||
text: '::IM_UNDER_ATTACK_BOX::',
|
||||
redirectTo: 'https://lossless.com',
|
||||
};
|
||||
default: {
|
||||
const statusInstance = plugins.smartstatus.HttpStatus.getHttpStatusByString(statusCodeArg);
|
||||
return {
|
||||
title: `Lossless Network: ${statusInstance.code.toString()}`,
|
||||
heading: statusInstance.code.toString(),
|
||||
text: statusInstance.text,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async addCustomRoutes(typedServerArg: plugins.typedserver.TypedServer) {
|
||||
typedServerArg.addRoute('/status/:code', 'GET', async (ctxArg) => {
|
||||
return this.createInfoHtmlResponse(this.getStatusInfoOptions(ctxArg.params.code));
|
||||
});
|
||||
|
||||
typedServerArg.addRoute('/custom', 'GET', async (ctxArg) => {
|
||||
const options = {
|
||||
title: ctxArg.query.title || 'Lossless Network',
|
||||
heading: ctxArg.query.heading || 'Error!',
|
||||
text: ctxArg.query.text || 'Please wait...',
|
||||
redirectTo: ctxArg.query.redirectTo || 'https://lossless.com',
|
||||
};
|
||||
|
||||
return this.createInfoHtmlResponse({
|
||||
...options,
|
||||
sentryDsn: configObject.sentryDsn,
|
||||
sentryMessage: `nullresolve custom: ${options.title}`,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async start() {
|
||||
if (this.serviceServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const projectinfo = await plugins.projectinfo.ProjectInfo.create(paths.packageDir);
|
||||
this.serviceServer = new plugins.typedserver.utilityservers.UtilityServiceServer({
|
||||
serviceDomain: this.options.serviceDomain,
|
||||
serviceName: 'nullresolve',
|
||||
serviceVersion: projectinfo.npm.version,
|
||||
port: this.options.port,
|
||||
addCustomRoutes: async (typedServerArg) => this.addCustomRoutes(typedServerArg),
|
||||
});
|
||||
await this.serviceServer.start();
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
if (!this.serviceServer) {
|
||||
return;
|
||||
}
|
||||
await this.serviceServer.stop();
|
||||
this.serviceServer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import * as plugins from './nullresolve.plugins.js';
|
||||
import * as paths from './nullresolve.paths.js';
|
||||
|
||||
const projectInfoNpm = new plugins.projectinfo.ProjectinfoNpm(paths.packageDir);
|
||||
|
||||
import { commitinfo } from './00_commitinfo_data.js';
|
||||
|
||||
export const logger = plugins.smartlog.Smartlog.createForCommitinfo(commitinfo);
|
||||
@@ -5,14 +5,12 @@ export { path };
|
||||
|
||||
// @api.global scope
|
||||
import * as typedserver from '@api.global/typedserver';
|
||||
import * as typedserverInfoHtml from '@api.global/typedserver/infohtml';
|
||||
|
||||
export { typedserver, typedserverInfoHtml };
|
||||
export { typedserver };
|
||||
|
||||
// @push.rocks scope
|
||||
import * as projectinfo from '@push.rocks/projectinfo';
|
||||
import * as smartlog from '@push.rocks/smartlog';
|
||||
import * as smartpath from '@push.rocks/smartpath';
|
||||
import * as smartstatus from '@push.rocks/smartstatus';
|
||||
|
||||
export { projectinfo, smartlog, smartpath, smartstatus };
|
||||
export { projectinfo, smartpath, smartstatus };
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import * as plugins from './nullresolve.plugins.js';
|
||||
import * as paths from './nullresolve.paths.js';
|
||||
|
||||
export const projectinfo = new plugins.projectinfo.ProjectInfo(paths.packageDir);
|
||||
Reference in New Issue
Block a user