summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--api/assets/schemas.json323
-rw-r--r--api/package.json1
-rw-r--r--api/src/Server.ts27
-rw-r--r--api/tests/routes.test.ts51
-rw-r--r--bundle/.gitignore3
-rw-r--r--bundle/package-lock.json18
-rw-r--r--bundle/package.json1
-rw-r--r--bundle/src/start.ts2
-rw-r--r--bundle/src/stats.ts1
-rw-r--r--dashboard/README.md12
-rw-r--r--util/src/util/Database.ts16
11 files changed, 415 insertions, 40 deletions
diff --git a/api/assets/schemas.json b/api/assets/schemas.json
index 03a2db07..5d78c602 100644
--- a/api/assets/schemas.json
+++ b/api/assets/schemas.json
@@ -2887,6 +2887,329 @@
         },
         "$schema": "http://json-schema.org/draft-07/schema#"
     },
+    "EmojiListResponse": {
+        "type": "array",
+        "items": {
+            "type": "object",
+            "properties": {
+                "animated": {
+                    "type": "boolean"
+                },
+                "available": {
+                    "type": "boolean"
+                },
+                "id": {
+                    "type": "string"
+                },
+                "managed": {
+                    "type": "boolean"
+                },
+                "name": {
+                    "type": "string"
+                },
+                "require_colons": {
+                    "type": "boolean"
+                },
+                "guild_id": {
+                    "type": "string"
+                },
+                "roles": {
+                    "type": "array",
+                    "items": {
+                        "type": "string"
+                    }
+                }
+            },
+            "required": [
+                "animated",
+                "available",
+                "id",
+                "managed",
+                "name",
+                "require_colons"
+            ]
+        },
+        "definitions": {
+            "ChannelPermissionOverwriteType": {
+                "enum": [
+                    0,
+                    1
+                ],
+                "type": "number"
+            },
+            "Embed": {
+                "type": "object",
+                "properties": {
+                    "title": {
+                        "type": "string"
+                    },
+                    "type": {
+                        "enum": [
+                            "article",
+                            "gifv",
+                            "image",
+                            "link",
+                            "rich",
+                            "video"
+                        ],
+                        "type": "string"
+                    },
+                    "description": {
+                        "type": "string"
+                    },
+                    "url": {
+                        "type": "string"
+                    },
+                    "timestamp": {
+                        "type": "string",
+                        "format": "date-time"
+                    },
+                    "color": {
+                        "type": "integer"
+                    },
+                    "footer": {
+                        "type": "object",
+                        "properties": {
+                            "text": {
+                                "type": "string"
+                            },
+                            "icon_url": {
+                                "type": "string"
+                            },
+                            "proxy_icon_url": {
+                                "type": "string"
+                            }
+                        },
+                        "required": [
+                            "text"
+                        ]
+                    },
+                    "image": {
+                        "$ref": "#/definitions/EmbedImage"
+                    },
+                    "thumbnail": {
+                        "$ref": "#/definitions/EmbedImage"
+                    },
+                    "video": {
+                        "$ref": "#/definitions/EmbedImage"
+                    },
+                    "provider": {
+                        "type": "object",
+                        "properties": {
+                            "name": {
+                                "type": "string"
+                            },
+                            "url": {
+                                "type": "string"
+                            }
+                        }
+                    },
+                    "author": {
+                        "type": "object",
+                        "properties": {
+                            "name": {
+                                "type": "string"
+                            },
+                            "url": {
+                                "type": "string"
+                            },
+                            "icon_url": {
+                                "type": "string"
+                            },
+                            "proxy_icon_url": {
+                                "type": "string"
+                            }
+                        }
+                    },
+                    "fields": {
+                        "type": "array",
+                        "items": {
+                            "type": "object",
+                            "properties": {
+                                "name": {
+                                    "type": "string"
+                                },
+                                "value": {
+                                    "type": "string"
+                                },
+                                "inline": {
+                                    "type": "boolean"
+                                }
+                            },
+                            "required": [
+                                "name",
+                                "value"
+                            ]
+                        }
+                    }
+                }
+            },
+            "EmbedImage": {
+                "type": "object",
+                "properties": {
+                    "url": {
+                        "type": "string"
+                    },
+                    "proxy_url": {
+                        "type": "string"
+                    },
+                    "height": {
+                        "type": "integer"
+                    },
+                    "width": {
+                        "type": "integer"
+                    }
+                }
+            },
+            "ChannelModifySchema": {
+                "type": "object",
+                "properties": {
+                    "name": {
+                        "maxLength": 100,
+                        "type": "string"
+                    },
+                    "type": {
+                        "enum": [
+                            0,
+                            1,
+                            10,
+                            11,
+                            12,
+                            13,
+                            2,
+                            3,
+                            4,
+                            5,
+                            6
+                        ],
+                        "type": "number"
+                    },
+                    "topic": {
+                        "type": "string"
+                    },
+                    "icon": {
+                        "type": [
+                            "null",
+                            "string"
+                        ]
+                    },
+                    "bitrate": {
+                        "type": "integer"
+                    },
+                    "user_limit": {
+                        "type": "integer"
+                    },
+                    "rate_limit_per_user": {
+                        "type": "integer"
+                    },
+                    "position": {
+                        "type": "integer"
+                    },
+                    "permission_overwrites": {
+                        "type": "array",
+                        "items": {
+                            "type": "object",
+                            "properties": {
+                                "id": {
+                                    "type": "string"
+                                },
+                                "type": {
+                                    "$ref": "#/definitions/ChannelPermissionOverwriteType"
+                                },
+                                "allow": {
+                                    "type": "string"
+                                },
+                                "deny": {
+                                    "type": "string"
+                                }
+                            },
+                            "required": [
+                                "allow",
+                                "deny",
+                                "id",
+                                "type"
+                            ]
+                        }
+                    },
+                    "parent_id": {
+                        "type": "string"
+                    },
+                    "id": {
+                        "type": "string"
+                    },
+                    "nsfw": {
+                        "type": "boolean"
+                    },
+                    "rtc_region": {
+                        "type": "string"
+                    },
+                    "default_auto_archive_duration": {
+                        "type": "integer"
+                    }
+                }
+            },
+            "UserPublic": {
+                "type": "object",
+                "properties": {
+                    "username": {
+                        "type": "string"
+                    },
+                    "discriminator": {
+                        "type": "string"
+                    },
+                    "id": {
+                        "type": "string"
+                    },
+                    "public_flags": {
+                        "type": "integer"
+                    },
+                    "avatar": {
+                        "type": "string"
+                    },
+                    "accent_color": {
+                        "type": "integer"
+                    },
+                    "banner": {
+                        "type": "string"
+                    },
+                    "bio": {
+                        "type": "string"
+                    },
+                    "bot": {
+                        "type": "boolean"
+                    }
+                },
+                "required": [
+                    "bio",
+                    "bot",
+                    "discriminator",
+                    "id",
+                    "public_flags",
+                    "username"
+                ]
+            },
+            "PublicConnectedAccount": {
+                "type": "object",
+                "properties": {
+                    "name": {
+                        "type": "string"
+                    },
+                    "type": {
+                        "type": "string"
+                    },
+                    "verifie": {
+                        "type": "boolean"
+                    }
+                },
+                "required": [
+                    "name",
+                    "type",
+                    "verifie"
+                ]
+            }
+        },
+        "$schema": "http://json-schema.org/draft-07/schema#"
+    },
     "GuildCreateSchema": {
         "type": "object",
         "properties": {
diff --git a/api/package.json b/api/package.json
index 8fc55e94..4fee791c 100644
--- a/api/package.json
+++ b/api/package.json
@@ -6,6 +6,7 @@
 	"types": "dist/Server.d.ts",
 	"scripts": {
 		"test:only": "jest --coverage --verbose --forceExit ./tests",
+		"test:routes": "jest --coverage --verbose --forceExit ./routes.test.ts",
 		"test": "npm run build && npm run test:only",
 		"test:watch": "jest --watch",
 		"start": "npm run build && node dist/start",
diff --git a/api/src/Server.ts b/api/src/Server.ts
index 4a226d12..a16a61f8 100644
--- a/api/src/Server.ts
+++ b/api/src/Server.ts
@@ -1,4 +1,4 @@
-import { OptionsJson } from 'body-parser';
+import { OptionsJson } from "body-parser";
 import "missing-native-js-functions";
 import { Connection } from "mongoose";
 import { Server, ServerOptions } from "lambert-server";
@@ -38,7 +38,6 @@ export class FosscordServer extends Server {
 		await Config.init();
 		await initEvent();
 
-
 		/* 
 		DOCUMENTATION: uses LOG_REQUESTS environment variable
 		
@@ -51,14 +50,16 @@ export class FosscordServer extends Server {
 		*/
 
 		let logRequests = process.env["LOG_REQUESTS"] != undefined;
-		if(logRequests) {
-			this.app.use(morgan("combined", {
-				skip: (req, res) => {
-					var skip = !(process.env["LOG_REQUESTS"]?.includes(res.statusCode.toString()) ?? false);
-					if(process.env["LOG_REQUESTS"]?.charAt(0) == '-') skip = !skip;
-					return skip;
-				}
-			}));
+		if (logRequests) {
+			this.app.use(
+				morgan("combined", {
+					skip: (req, res) => {
+						var skip = !(process.env["LOG_REQUESTS"]?.includes(res.statusCode.toString()) ?? false);
+						if (process.env["LOG_REQUESTS"]?.charAt(0) == "-") skip = !skip;
+						return skip;
+					}
+				})
+			);
 		}
 
 		this.app.use(CORS);
@@ -90,8 +91,10 @@ export class FosscordServer extends Server {
 		this.app.use(ErrorHandler);
 		TestClient(this.app);
 
-		if(logRequests){
-			console.log("Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!");
+		if (logRequests) {
+			console.log(
+				"Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!"
+			);
 		}
 		return super.start();
 	}
diff --git a/api/tests/routes.test.ts b/api/tests/routes.test.ts
index fcaa3124..ed391dfb 100644
--- a/api/tests/routes.test.ts
+++ b/api/tests/routes.test.ts
@@ -7,7 +7,7 @@ import fs from "fs";
 import Ajv from "ajv";
 import addFormats from "ajv-formats";
 import fetch from "node-fetch";
-import { Event, User, events } from "@fosscord/util";
+import { Event, User, events, Guild, Channel } from "@fosscord/util";
 
 const SchemaPath = join(__dirname, "..", "assets", "schemas.json");
 const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
@@ -25,11 +25,36 @@ addFormats(ajv);
 
 var token: string;
 var user: User;
+var guild: Guild;
+var channel: Channel;
+
+const request = async (path: string, opts: any = {}): Promise<any> => {
+	const response = await fetch(`http://localhost:3001/api${path}`, {
+		...opts,
+		method: opts.method || opts.body ? "POST" : "GET",
+		body: opts.body && JSON.stringify(opts.body),
+		headers: {
+			authorization: token,
+			...(opts.body ? { "content-type": "application/json" } : {}),
+			...(opts.header || {})
+		}
+	});
+	if (response.status === 204) return;
+
+	var data = await response.text();
+	try {
+		data = JSON.stringify(data);
+		if (response.status >= 400) throw data;
+		return data;
+	} catch (error) {
+		throw data;
+	}
+};
+
 beforeAll(async (done) => {
 	try {
-		const response = await fetch("http://localhost:3001/api/auth/register", {
-			method: "POST",
-			body: JSON.stringify({
+		const response = await request("/auth/register", {
+			body: {
 				fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw",
 				email: "test@example.com",
 				username: "tester",
@@ -39,18 +64,13 @@ beforeAll(async (done) => {
 				date_of_birth: "2000-01-01",
 				gift_code_sku_id: null,
 				captcha_key: null
-			}),
-			headers: {
-				"content-type": "application/json"
 			}
 		});
-		const json = await response.json();
-		token = json.token;
-		user = await (
-			await fetch(`http://localhost:3001/api/users/@me`, {
-				headers: { authorization: token }
-			})
-		).json();
+		token = response.token;
+		user = await request(`/users/@me`);
+		const { id: guild_id } = await request("/guilds", { body: { name: "test server" } });
+		guild = await request(`/guilds/${guild_id}`);
+		channel = (await request(`/guilds/${guild_id}/channels`))[0];
 
 		done();
 	} catch (error) {
@@ -75,7 +95,8 @@ describe("Automatic unit tests with route description middleware", () => {
 				console.log(`${(route as any).file}\nrouter.${method} is missing the test property`);
 				return done();
 			}
-			const urlPath = path.replace(":id", user.id) || route.test?.path;
+			const urlPath =
+				path.replace(":id", user.id).replace(":guild_id", guild.id).replace(":channel_id", channel.id) || route.test?.path;
 			var validate: any;
 			if (route.test.body) {
 				validate = ajv.getSchema(route.test.body);
diff --git a/bundle/.gitignore b/bundle/.gitignore
index 7d2cb508..cf073d9c 100644
--- a/bundle/.gitignore
+++ b/bundle/.gitignore
@@ -1 +1,2 @@
-files/
\ No newline at end of file
+files/
+.env
\ No newline at end of file
diff --git a/bundle/package-lock.json b/bundle/package-lock.json
index aaa0c1ee..090935f4 100644
--- a/bundle/package-lock.json
+++ b/bundle/package-lock.json
@@ -15,6 +15,7 @@
 				"@fosscord/gateway": "file:../gateway",
 				"@fosscord/util": "file:../util",
 				"async-exit-hook": "^2.0.1",
+				"dotenv": "^10.0.0",
 				"express": "^4.17.1",
 				"missing-native-js-functions": "^1.2.15",
 				"node-os-utils": "^1.3.5",
@@ -195,6 +196,9 @@
 				"ts-node-dev": "^1.1.6",
 				"ts-patch": "^1.4.4",
 				"typescript": "^4.2.3"
+			},
+			"optionalDependencies": {
+				"@yukikaze-bot/erlpack": "^1.0.1"
 			}
 		},
 		"../util": {
@@ -858,6 +862,14 @@
 				"node": ">=0.3.1"
 			}
 		},
+		"node_modules/dotenv": {
+			"version": "10.0.0",
+			"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
+			"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
+			"engines": {
+				"node": ">=10"
+			}
+		},
 		"node_modules/ee-first": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -1810,6 +1822,7 @@
 				"@types/node-fetch": "^2.5.12",
 				"@types/uuid": "^8.3.0",
 				"@types/ws": "^7.4.0",
+				"@yukikaze-bot/erlpack": "^1.0.1",
 				"@zerollup/ts-transform-paths": "^1.7.18",
 				"ajv": "^8.5.0",
 				"amqplib": "^0.8.0",
@@ -2336,6 +2349,11 @@
 			"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
 			"dev": true
 		},
+		"dotenv": {
+			"version": "10.0.0",
+			"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
+			"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
+		},
 		"ee-first": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
diff --git a/bundle/package.json b/bundle/package.json
index fa6fe669..f68ff0bd 100644
--- a/bundle/package.json
+++ b/bundle/package.json
@@ -54,6 +54,7 @@
 		"@fosscord/gateway": "file:../gateway",
 		"@fosscord/util": "file:../util",
 		"async-exit-hook": "^2.0.1",
+		"dotenv": "^10.0.0",
 		"express": "^4.17.1",
 		"missing-native-js-functions": "^1.2.15",
 		"node-os-utils": "^1.3.5",
diff --git a/bundle/src/start.ts b/bundle/src/start.ts
index f68a65bf..be67a122 100644
--- a/bundle/src/start.ts
+++ b/bundle/src/start.ts
@@ -2,6 +2,8 @@
 import cluster from "cluster";
 import os from "os";
 import { initStats } from "./stats";
+import { config } from "dotenv";
+config();
 
 // TODO: add tcp socket event transmission
 const cores = 1 || Number(process.env.threads) || os.cpus().length;
diff --git a/bundle/src/stats.ts b/bundle/src/stats.ts
index e6941db2..d5ceeff7 100644
--- a/bundle/src/stats.ts
+++ b/bundle/src/stats.ts
@@ -5,7 +5,6 @@ export function initStats() {
 	console.log(`[Path] running in ${__dirname}`);
 	console.log(`[CPU] ${osu.cpu.model()} Cores x${osu.cpu.count()}`);
 	console.log(`[System] ${os.platform()} ${os.arch()}`);
-	console.log(`[Database] started`);
 	console.log(`[Process] running with pid: ${process.pid}`);
 
 	setInterval(async () => {
diff --git a/dashboard/README.md b/dashboard/README.md
index c94ae96c..df1157a1 100644
--- a/dashboard/README.md
+++ b/dashboard/README.md
@@ -1,8 +1,12 @@
 # Fosscord-dashboard
+
 A admin dashboard for fosscord-server
 
 ## (planned) Features
-- [ ] Overview usage (registered users, concurrent connections, voice usage, reports)
-- [ ] Reports
-- [ ] Member managment (edit (disable, delete, premium, username, discriminator))
-- [ ] Configuration ([Config.ts](https://github.com/fosscord/fosscord-server-util/blob/master/src/util/Config.ts))
+
+-   [ ] Overview usage (registered users, concurrent connections, voice usage, reports)
+-   [ ] Reports
+-   [ ] Member managment (edit (disable, delete, premium, username, discriminator))
+-   [ ] Configuration ([Config.ts](https://github.com/fosscord/fosscord-server-util/blob/master/src/util/Config.ts))
+
+port = 3005
diff --git a/util/src/util/Database.ts b/util/src/util/Database.ts
index ab7c70c5..369a403c 100644
--- a/util/src/util/Database.ts
+++ b/util/src/util/Database.ts
@@ -1,6 +1,6 @@
 import path from "path";
 import "reflect-metadata";
-import { Connection, createConnection, ValueTransformer } from "typeorm";
+import { Connection, createConnection } from "typeorm";
 import * as Models from "../entities";
 
 // UUID extension option is only supported with postgres
@@ -8,18 +8,20 @@ import * as Models from "../entities";
 
 var promise: Promise<any>;
 var dbConnection: Connection | undefined;
+let dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db");
 
 export function initDatabase() {
 	if (promise) return promise; // prevent initalizing multiple times
 
-	console.log("[Database] connecting ...");
+	const type = dbConnectionString.includes(":") ? dbConnectionString.split(":")[0]?.replace("+srv", "") : "sqlite";
+	const isSqlite = type.includes("sqlite");
+
+	console.log(`[Database] connecting to ${type} db`);
 	// @ts-ignore
 	promise = createConnection({
-		type: "sqlite",
-		database: path.join(process.cwd(), "database.db"),
-		// type: "postgres",
-		// url: "postgres://fosscord:wb94SmuURM2Syv&@localhost/fosscord",
-		//
+		type,
+		url: isSqlite ? undefined : dbConnectionString,
+		database: isSqlite ? dbConnectionString : undefined,
 		entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"),
 		synchronize: true,
 		logging: false,