🚧 different db engines

This commit is contained in:
Flam3rboy 2021-10-04 21:57:24 +02:00
parent e52e7ef0e1
commit b584af656d
11 changed files with 415 additions and 40 deletions

View File

@ -2887,6 +2887,329 @@
}, },
"$schema": "http://json-schema.org/draft-07/schema#" "$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": { "GuildCreateSchema": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -6,6 +6,7 @@
"types": "dist/Server.d.ts", "types": "dist/Server.d.ts",
"scripts": { "scripts": {
"test:only": "jest --coverage --verbose --forceExit ./tests", "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": "npm run build && npm run test:only",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"start": "npm run build && node dist/start", "start": "npm run build && node dist/start",

View File

@ -1,4 +1,4 @@
import { OptionsJson } from 'body-parser'; import { OptionsJson } from "body-parser";
import "missing-native-js-functions"; import "missing-native-js-functions";
import { Connection } from "mongoose"; import { Connection } from "mongoose";
import { Server, ServerOptions } from "lambert-server"; import { Server, ServerOptions } from "lambert-server";
@ -38,7 +38,6 @@ export class FosscordServer extends Server {
await Config.init(); await Config.init();
await initEvent(); await initEvent();
/* /*
DOCUMENTATION: uses LOG_REQUESTS environment variable DOCUMENTATION: uses LOG_REQUESTS environment variable
@ -51,14 +50,16 @@ export class FosscordServer extends Server {
*/ */
let logRequests = process.env["LOG_REQUESTS"] != undefined; let logRequests = process.env["LOG_REQUESTS"] != undefined;
if(logRequests) { if (logRequests) {
this.app.use(morgan("combined", { this.app.use(
morgan("combined", {
skip: (req, res) => { skip: (req, res) => {
var skip = !(process.env["LOG_REQUESTS"]?.includes(res.statusCode.toString()) ?? false); var skip = !(process.env["LOG_REQUESTS"]?.includes(res.statusCode.toString()) ?? false);
if(process.env["LOG_REQUESTS"]?.charAt(0) == '-') skip = !skip; if (process.env["LOG_REQUESTS"]?.charAt(0) == "-") skip = !skip;
return skip; return skip;
} }
})); })
);
} }
this.app.use(CORS); this.app.use(CORS);
@ -90,8 +91,10 @@ export class FosscordServer extends Server {
this.app.use(ErrorHandler); this.app.use(ErrorHandler);
TestClient(this.app); TestClient(this.app);
if(logRequests){ if (logRequests) {
console.log("Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!"); console.log(
"Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!"
);
} }
return super.start(); return super.start();
} }

View File

@ -7,7 +7,7 @@ import fs from "fs";
import Ajv from "ajv"; import Ajv from "ajv";
import addFormats from "ajv-formats"; import addFormats from "ajv-formats";
import fetch from "node-fetch"; 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 SchemaPath = join(__dirname, "..", "assets", "schemas.json");
const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" })); const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
@ -25,11 +25,36 @@ addFormats(ajv);
var token: string; var token: string;
var user: User; 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) => { beforeAll(async (done) => {
try { try {
const response = await fetch("http://localhost:3001/api/auth/register", { const response = await request("/auth/register", {
method: "POST", body: {
body: JSON.stringify({
fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw",
email: "test@example.com", email: "test@example.com",
username: "tester", username: "tester",
@ -39,18 +64,13 @@ beforeAll(async (done) => {
date_of_birth: "2000-01-01", date_of_birth: "2000-01-01",
gift_code_sku_id: null, gift_code_sku_id: null,
captcha_key: null captcha_key: null
}),
headers: {
"content-type": "application/json"
} }
}); });
const json = await response.json(); token = response.token;
token = json.token; user = await request(`/users/@me`);
user = await ( const { id: guild_id } = await request("/guilds", { body: { name: "test server" } });
await fetch(`http://localhost:3001/api/users/@me`, { guild = await request(`/guilds/${guild_id}`);
headers: { authorization: token } channel = (await request(`/guilds/${guild_id}/channels`))[0];
})
).json();
done(); done();
} catch (error) { } 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`); console.log(`${(route as any).file}\nrouter.${method} is missing the test property`);
return done(); 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; var validate: any;
if (route.test.body) { if (route.test.body) {
validate = ajv.getSchema(route.test.body); validate = ajv.getSchema(route.test.body);

1
bundle/.gitignore vendored
View File

@ -1 +1,2 @@
files/ files/
.env

View File

@ -15,6 +15,7 @@
"@fosscord/gateway": "file:../gateway", "@fosscord/gateway": "file:../gateway",
"@fosscord/util": "file:../util", "@fosscord/util": "file:../util",
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"dotenv": "^10.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"missing-native-js-functions": "^1.2.15", "missing-native-js-functions": "^1.2.15",
"node-os-utils": "^1.3.5", "node-os-utils": "^1.3.5",
@ -195,6 +196,9 @@
"ts-node-dev": "^1.1.6", "ts-node-dev": "^1.1.6",
"ts-patch": "^1.4.4", "ts-patch": "^1.4.4",
"typescript": "^4.2.3" "typescript": "^4.2.3"
},
"optionalDependencies": {
"@yukikaze-bot/erlpack": "^1.0.1"
} }
}, },
"../util": { "../util": {
@ -858,6 +862,14 @@
"node": ">=0.3.1" "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": { "node_modules/ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -1810,6 +1822,7 @@
"@types/node-fetch": "^2.5.12", "@types/node-fetch": "^2.5.12",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"@types/ws": "^7.4.0", "@types/ws": "^7.4.0",
"@yukikaze-bot/erlpack": "^1.0.1",
"@zerollup/ts-transform-paths": "^1.7.18", "@zerollup/ts-transform-paths": "^1.7.18",
"ajv": "^8.5.0", "ajv": "^8.5.0",
"amqplib": "^0.8.0", "amqplib": "^0.8.0",
@ -2336,6 +2349,11 @@
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true "dev": true
}, },
"dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
},
"ee-first": { "ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",

View File

@ -54,6 +54,7 @@
"@fosscord/gateway": "file:../gateway", "@fosscord/gateway": "file:../gateway",
"@fosscord/util": "file:../util", "@fosscord/util": "file:../util",
"async-exit-hook": "^2.0.1", "async-exit-hook": "^2.0.1",
"dotenv": "^10.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"missing-native-js-functions": "^1.2.15", "missing-native-js-functions": "^1.2.15",
"node-os-utils": "^1.3.5", "node-os-utils": "^1.3.5",

View File

@ -2,6 +2,8 @@
import cluster from "cluster"; import cluster from "cluster";
import os from "os"; import os from "os";
import { initStats } from "./stats"; import { initStats } from "./stats";
import { config } from "dotenv";
config();
// TODO: add tcp socket event transmission // TODO: add tcp socket event transmission
const cores = 1 || Number(process.env.threads) || os.cpus().length; const cores = 1 || Number(process.env.threads) || os.cpus().length;

View File

@ -5,7 +5,6 @@ export function initStats() {
console.log(`[Path] running in ${__dirname}`); console.log(`[Path] running in ${__dirname}`);
console.log(`[CPU] ${osu.cpu.model()} Cores x${osu.cpu.count()}`); console.log(`[CPU] ${osu.cpu.model()} Cores x${osu.cpu.count()}`);
console.log(`[System] ${os.platform()} ${os.arch()}`); console.log(`[System] ${os.platform()} ${os.arch()}`);
console.log(`[Database] started`);
console.log(`[Process] running with pid: ${process.pid}`); console.log(`[Process] running with pid: ${process.pid}`);
setInterval(async () => { setInterval(async () => {

View File

@ -1,8 +1,12 @@
# Fosscord-dashboard # Fosscord-dashboard
A admin dashboard for fosscord-server A admin dashboard for fosscord-server
## (planned) Features ## (planned) Features
- [ ] Overview usage (registered users, concurrent connections, voice usage, reports) - [ ] Overview usage (registered users, concurrent connections, voice usage, reports)
- [ ] Reports - [ ] Reports
- [ ] Member managment (edit (disable, delete, premium, username, discriminator)) - [ ] Member managment (edit (disable, delete, premium, username, discriminator))
- [ ] Configuration ([Config.ts](https://github.com/fosscord/fosscord-server-util/blob/master/src/util/Config.ts)) - [ ] Configuration ([Config.ts](https://github.com/fosscord/fosscord-server-util/blob/master/src/util/Config.ts))
port = 3005

View File

@ -1,6 +1,6 @@
import path from "path"; import path from "path";
import "reflect-metadata"; import "reflect-metadata";
import { Connection, createConnection, ValueTransformer } from "typeorm"; import { Connection, createConnection } from "typeorm";
import * as Models from "../entities"; import * as Models from "../entities";
// UUID extension option is only supported with postgres // UUID extension option is only supported with postgres
@ -8,18 +8,20 @@ import * as Models from "../entities";
var promise: Promise<any>; var promise: Promise<any>;
var dbConnection: Connection | undefined; var dbConnection: Connection | undefined;
let dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db");
export function initDatabase() { export function initDatabase() {
if (promise) return promise; // prevent initalizing multiple times 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 // @ts-ignore
promise = createConnection({ promise = createConnection({
type: "sqlite", type,
database: path.join(process.cwd(), "database.db"), url: isSqlite ? undefined : dbConnectionString,
// type: "postgres", database: isSqlite ? dbConnectionString : undefined,
// url: "postgres://fosscord:wb94SmuURM2Syv&@localhost/fosscord",
//
entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"), entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"),
synchronize: true, synchronize: true,
logging: false, logging: false,