a277bab9fa0053c0d3222f2462bdfcb896c21a17
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) 					{
100) 						"userName": lib_sha256.get(ip_address).slice(0, 8),
101) 						"channels": internal_request.data["channels"],
102) 						"showErrors": true,
103) 						"autoConnect": false,
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

105) 				);
106) 				const connection: type_connection = 
107) 				{
108) 					"client": client,
109) 					"events": [],
110) 					"users": [],
111) 				};
112) 				client.addListener
113) 				(
114) 					"message",
115) 					(from, to, message) =>
116) 					{
117) 						connection.events.push
118) 						({
119) 							"timestamp": get_timestamp(),
120) 							"kind": "channel_message",
121) 							"data":
122) 							{
123) 								"from": from,
124) 								"to": to,
125) 								"message": message,
126) 							}
127) 						});
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

129) 				);
130) 				client.addListener
131) 				(
132) 					"pm",
133) 					(from, message) =>
134) 					{
135) 						connection.events.push
136) 						({
137) 							"timestamp": get_timestamp(),
138) 							"kind": "private_message",
139) 							"data":
140) 							{
141) 								"from": from,
142) 								"message": message,
143) 							}
144) 						});
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) 					"names",
150) 					(channel, users) =>
151) 					{
152) 						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

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

Christian Fraß authored 2 years ago

154) 				);
155) 				client.addListener
156) 				(
157) 					"error",
158) 					(error) =>
159) 					{
160) 						log(0, "irc_error", {"reason": error.message});
Christian Fraß [mod] allow multiple connec...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

162) 				);
163) 				client.connect
164) 				(
165) 					3,
166) 					() =>
167) 					{
168) 						_connections[id] = connection;
169) 					}
170) 				);
171) 				return Promise.resolve<type_internal_response>(id);
172) 			}
173) 			break;
174) 		}
175) 		case "check":
176) 		{
177) 			try
178) 			{
179) 				get_connection(internal_request.id);
180) 				return Promise.resolve<type_internal_response>(true);
181) 			}
182) 			catch (error)
183) 			{
184) 				return Promise.resolve<type_internal_response>(false);
185) 			}
186) 			break;
187) 		}
188) 		case "disconnect":
189) 		{
190) 			const connection: type_connection = get_connection(internal_request.id);
191) 			delete _connections[internal_request.id];
192) 			connection.client.disconnect("", () => {});
193) 			return Promise.resolve<type_internal_response>(null);
194) 			break;
195) 		}
196) 		case "say":
197) 		{
198) 			const connection: type_connection = get_connection(internal_request.id);
199) 			connection.client.say(internal_request.data["channel"], internal_request.data["message"]);
200) 			return Promise.resolve<type_internal_response>(null);
201) 			break;
202) 		}
203) 		case "fetch":
204) 		{
205) 			const connection: type_connection = get_connection(internal_request.id);
206) 			const internal_response: type_internal_response =
207) 			{
208) 				"users": connection.users,
209) 				"events": connection.events,
210) 			};
211) 			connection.events = [];
212) 			return Promise.resolve<type_internal_response>(internal_response);
213) 			break;
214) 		}
215) 	}
216) }
217) 
218) async function main(): Promise<void>
219) {
220) 	_conf = await lib_plankton.file.read("conf.json").then<any>(x => lib_json.decode(x));
221) 	const server: lib_server.class_server = new lib_server.class_server
222) 	(
223) 		_conf["port"],
224) 		async (input: string, metadata?: lib_server.type_metadata): Promise<string> =>
225) 		{
226) 			const http_request: lib_http.type_request = lib_http.decode_request(input);
227) 			log(2, "http_request", http_request);
228) 			const internal_request: type_internal_request = lib_json.decode(http_request.body);
229) 			log(1, "internal_request", internal_request);
230) 			let internal_response: type_internal_response;
231) 			let error: (null | Error);
232) 			try
233) 			{
234) 				internal_response = await execute(internal_request, metadata.ip_address);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

237) 			catch (error_)
238) 			{
239) 				internal_response = null;
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

242) 			if (error !== null)
243) 			{
244) 				log(0, "error_in_execution", {"reason": error.toString()});
245) 			}
246) 			const http_response: lib_http.type_response =
247) 			(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

248) 				(error !== null)
249) 				? {
250) 					"statuscode": 500,
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

253) 				}
254) 				: {
255) 					"statuscode": 200,
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

256) 					"headers": {"Access-Control-Allow-Origin": "*", "Content-Type": "application/json"},
257) 					"body": lib_json.encode(internal_response)
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) 			log(2, "http_response", http_response);
261) 			const output: string = lib_http.encode_response(http_response);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

262) 			return Promise.resolve<string>(output);
263) 		}
264) 	);
Christian Fraß [mod] logging [mod] code st...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

268)