3be34c53119843db38b09bb0e19dd9d8addcd749
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

1) type type_event =
2) {
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

3) 	timestamp: int;
4) 	kind: string;
5) 	data: any;
6) };
7) 
8) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

9) type type_user =
10) {
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

11) 	name: string;
12) 	role: string;
13) };
14) 
15) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

16) type type_connection =
17) {
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

18) 	events: Array<type_event>;
19) 	users: Array<type_user>;
20) 	client: any;
21) };
22) 
23) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

24) type type_internal_request =
Christian Fraß [ini]

Christian Fraß authored 2 years ago

25) {
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

26) 	id: (null | string);
27) 	action: string;
28) 	data: any;
29) };
30) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

31) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

32) type type_internal_response = any;
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

33) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

34) 
35) function get_timestamp(): int
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

36) {
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

37) 	return Math.floor(Date.now()/1000);
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

38) }
39) 
40) function generate_id(): string
41) {
42) 	return (Math.random() * (1 << 24)).toFixed(0).padStart(8, '0');
43) }
44) 
45) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

46) var nm_irc: any = require("irc");
47) 
48) 
49) var _connections: Record<string, type_connection> = {};
50) 
51) 
52) var _conf: any = {};
53) 
54) 
55) function log(level: int, incident: string, details: Record<string, any> = {}): void
56) {
57) 	if (level <= _conf["verbosity"])
58) 	{
59) 		process.stderr.write(`-- ${incident} | ${lib_json.encode(details)}\n`);
60) 	}
61) }
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

62) 
63) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

64) function get_connection(id: string): type_connection
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

65) {
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

66) 	if (! _connections.hasOwnProperty(id))
67) 	{
68) 		throw (new Error("no connection for ID '" + id + "'"));
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

69) 	}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

70) 	else
71) 	{
72) 		return _connections[id];
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

73) 	}
74) }
75) 
76) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

77) async function execute(internal_request: type_internal_request, ip_address: string): Promise<type_internal_response>
Christian Fraß [ini]

Christian Fraß authored 2 years ago

78) {
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

79) 	switch (internal_request.action)
80) 	{
81) 		default:
82) 		{
83) 			throw (new Error("unhandled action: " + internal_request.action));
84) 			break;
85) 		}
86) 		case "connect":
87) 		{
88) 			if (_connections.hasOwnProperty(internal_request.id))
89) 			{
90) 				throw (new Error("already connected"));
91) 			}
92) 			else
93) 			{
94) 				const id: string = generate_id();
95) 				const client = new nm_irc.Client
96) 				(
97) 					internal_request.data["server"],
98) 					internal_request.data["nickname"],
99) 					{
Christian Fraß [mod] "say" -> "send"

Christian Fraß authored 2 years ago

100) 						"realName": "webirc",
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

101) 						"userName": lib_sha256.get(ip_address).slice(0, 8),
102) 						"channels": internal_request.data["channels"],
103) 						"showErrors": true,
104) 						"autoConnect": false,
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

105) 					}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

106) 				);
Christian Fraß [mod] "say" -> "send"

Christian Fraß authored 2 years ago

107) 				let connection: type_connection =
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

108) 				{
109) 					"client": client,
110) 					"events": [],
111) 					"users": [],
112) 				};
113) 				client.addListener
114) 				(
115) 					"message",
116) 					(from, to, message) =>
117) 					{
118) 						connection.events.push
119) 						({
120) 							"timestamp": get_timestamp(),
121) 							"kind": "channel_message",
Christian Fraß [mod] "say" -> "send"

Christian Fraß authored 2 years ago

122) 							"data": {"from": from, "to": to, "message": message}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

123) 						});
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

124) 					}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

125) 				);
126) 				client.addListener
127) 				(
128) 					"pm",
129) 					(from, message) =>
130) 					{
131) 						connection.events.push
132) 						({
133) 							"timestamp": get_timestamp(),
134) 							"kind": "private_message",
Christian Fraß [mod] "say" -> "send"

Christian Fraß authored 2 years ago

135) 							"data": {"from": from, "message": message}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

136) 						});
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

137) 					}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

138) 				);
139) 				client.addListener
140) 				(
141) 					"names",
142) 					(channel, users) =>
143) 					{
144) 						connection.users = Object.entries(users).map(([key, value]) => ({"name": key, "role": value.toString()}));
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

145) 					}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

146) 				);
147) 				client.addListener
148) 				(
149) 					"error",
150) 					(error) =>
151) 					{
152) 						log(0, "irc_error", {"reason": error.message});
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

153) 					}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

154) 				);
155) 				client.connect
156) 				(
157) 					3,
158) 					() =>
159) 					{
160) 						_connections[id] = connection;
161) 					}
162) 				);
163) 				return Promise.resolve<type_internal_response>(id);
164) 			}
165) 			break;
166) 		}
167) 		case "check":
168) 		{
169) 			try
170) 			{
171) 				get_connection(internal_request.id);
172) 				return Promise.resolve<type_internal_response>(true);
173) 			}
174) 			catch (error)
175) 			{
176) 				return Promise.resolve<type_internal_response>(false);
177) 			}
178) 			break;
179) 		}
180) 		case "disconnect":
181) 		{
182) 			const connection: type_connection = get_connection(internal_request.id);
183) 			delete _connections[internal_request.id];
184) 			connection.client.disconnect("", () => {});
185) 			return Promise.resolve<type_internal_response>(null);
186) 			break;
187) 		}
Christian Fraß [mod] "say" -> "send"

Christian Fraß authored 2 years ago

188) 		case "send":
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

189) 		{
190) 			const connection: type_connection = get_connection(internal_request.id);
191) 			connection.client.say(internal_request.data["channel"], internal_request.data["message"]);
192) 			return Promise.resolve<type_internal_response>(null);
193) 			break;
194) 		}
195) 		case "fetch":
196) 		{
197) 			const connection: type_connection = get_connection(internal_request.id);
198) 			const internal_response: type_internal_response =
199) 			{
200) 				"users": connection.users,
201) 				"events": connection.events,
202) 			};
203) 			connection.events = [];
204) 			return Promise.resolve<type_internal_response>(internal_response);
205) 			break;
206) 		}
207) 	}
208) }
209) 
210) async function main(): Promise<void>
211) {
212) 	_conf = await lib_plankton.file.read("conf.json").then<any>(x => lib_json.decode(x));
213) 	const server: lib_server.class_server = new lib_server.class_server
214) 	(
215) 		_conf["port"],
216) 		async (input: string, metadata?: lib_server.type_metadata): Promise<string> =>
217) 		{
218) 			const http_request: lib_http.type_request = lib_http.decode_request(input);
219) 			log(2, "http_request", http_request);
220) 			const internal_request: type_internal_request = lib_json.decode(http_request.body);
221) 			log(1, "internal_request", internal_request);
222) 			let internal_response: type_internal_response;
223) 			let error: (null | Error);
224) 			try
225) 			{
226) 				internal_response = await execute(internal_request, metadata.ip_address);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

227) 				error = null;
228) 			}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

229) 			catch (error_)
230) 			{
231) 				internal_response = null;
Christian Fraß [ini]

Christian Fraß authored 2 years ago

232) 				error = error_;
233) 			}
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

234) 			if (error !== null)
235) 			{
236) 				log(0, "error_in_execution", {"reason": error.toString()});
237) 			}
238) 			const http_response: lib_http.type_response =
239) 			(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

240) 				(error !== null)
241) 				? {
242) 					"statuscode": 500,
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

243) 					"headers": {"Access-Control-Allow-Origin": "*", "Content-Type": "text/plain"},
244) 					"body": "error executing the request; check the server logs for details",
Christian Fraß [ini]

Christian Fraß authored 2 years ago

245) 				}
246) 				: {
247) 					"statuscode": 200,
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

248) 					"headers": {"Access-Control-Allow-Origin": "*", "Content-Type": "application/json"},
249) 					"body": lib_json.encode(internal_response)
Christian Fraß [ini]

Christian Fraß authored 2 years ago

250) 				}
251) 			);
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

252) 			log(2, "http_response", http_response);
253) 			const output: string = lib_http.encode_response(http_response);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

254) 			return Promise.resolve<string>(output);
255) 		}
256) 	);
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

257) 	return server.start();
Christian Fraß [ini]

Christian Fraß authored 2 years ago

258) }
259) 
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

260)