diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index ca46e26f..00000000 --- a/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -root = true - -[*.ts] -indent_style = tab -indent_size = 4 diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 7d715cba..00000000 --- a/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "tabWidth": 4, - "useTabs": true, - "printWidth": 140, - "trailingComma": "none", - "useTabs": true -} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 64130e51..00000000 --- a/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM node:alpine - -# env vars -ENV HTTP_PORT=3001 -ENV WS_PORT=3002 -ENV CDN_PORT=3003 -ENV RTC_PORT=3004 -ENV ADMIN_PORT=3005 - -# exposed ports (only for reference, see https://docs.docker.com/engine/reference/builder/#expose) -EXPOSE ${HTTP_PORT}/tcp ${WS_PORT}/tcp ${CDN_PORT}/tcp ${RTC_PORT}/tcp ${ADMIN_PORT}/tcp - -# install required apps -RUN apk add --no-cache --update git python3 py-pip make build-base -RUN ln -s /usr/bin/python3 /usr/bin/python - -# Run as non-root user -# RUN adduser -D fosscord -# USER fosscord - -WORKDIR /srv/fosscord-server/bundle -ENTRYPOINT ["npm", "run", "start:bundle"] \ No newline at end of file diff --git a/api/.dockerignore b/api/.dockerignore deleted file mode 100644 index 76add878..00000000 --- a/api/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist \ No newline at end of file diff --git a/api/.env.example b/api/.env.example deleted file mode 100644 index 5974f628..00000000 --- a/api/.env.example +++ /dev/null @@ -1,8 +0,0 @@ -MONGO_URL=mongodb://localhost/fosscord -PORT=3001 -PRODUCTION=TRUE -THREADS=# automatically use all available cores, only available if production = true -#LOG_REQUESTS= -# only log 200 and 204: LOG_REQUESTS=200 204 -# log everything except 200 and 204: LOG_REQUESTS=-200 204 -# log all requests: LOG_REQUESTS=- \ No newline at end of file diff --git a/api/.gitignore b/api/.gitignore deleted file mode 100644 index 662816b9..00000000 --- a/api/.gitignore +++ /dev/null @@ -1,115 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist -build - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -.DS_STORE -src/ready.json - -# Docker -.docker/config/* -!.docker/config/.keep - -# fosscord -*.db \ No newline at end of file diff --git a/api/.npmignore b/api/.npmignore deleted file mode 100644 index 05a9d0cf..00000000 --- a/api/.npmignore +++ /dev/null @@ -1 +0,0 @@ -!dist/ \ No newline at end of file diff --git a/api/.prettierrc b/api/.prettierrc deleted file mode 100644 index 8a2c607f..00000000 --- a/api/.prettierrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "tabWidth": 4, - "useTabs": true, - "printWidth": 140, - "trailingComma": "none" -} diff --git a/api/.vscode/api-snippets.code-snippets b/api/.vscode/api-snippets.code-snippets deleted file mode 100644 index ef4b6386..00000000 --- a/api/.vscode/api-snippets.code-snippets +++ /dev/null @@ -1,25 +0,0 @@ -{ - "API Router": { - "scope": "javascript,typescript", - "prefix": "router", - "body": [ - "import { Router, Response, Request } from \"express\";", - "import { route } from \"@fosscord/api\";", - "", - "const router = Router();", - "", - "router.get(\"/\", route({}), (req: Request, res: Response) => {", - "\tres.json({});", - "});", - "", - "export default router;" - ], - "description": "A basic API router setup for a blank route." - }, - "Route": { - "scope": "typescript", - "prefix": "route", - "body": ["router.get(\"$1\", route({}), (req: Request, res: Response) => {", "\t$2", "});"], - "description": "An API endpoint" - } -} diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json deleted file mode 100644 index 221931ee..00000000 --- a/api/.vscode/launch.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "sourceMaps": true, - "type": "node", - "request": "launch", - "name": "Launch Server", - "program": "${workspaceFolder}/dist/start.js", - "preLaunchTask": "tsc: build - tsconfig.json", - "outFiles": ["${workspaceFolder}/dist/**/*.js"], - "envFile": "${workspaceFolder}/.env" - }, - { - "name": "Debug current file", - "program": "${file}", - "request": "launch", - "skipFiles": ["/**"], - "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"], - "preLaunchTask": "tsc: build - tsconfig.json", - "type": "node", - "resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"] - } - ] -} diff --git a/api/Dockerfile b/api/Dockerfile deleted file mode 100644 index 08d15f72..00000000 --- a/api/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM node:lts-alpine -# needed for native packages (bcrypt, canvas) -RUN apk add --no-cache make gcc g++ python cairo-dev jpeg-dev pango-dev giflib-dev -WORKDIR /usr/src/fosscord-server -COPY package.json . -COPY package-lock.json . -RUN npm rebuild bcrypt --build-from-source && npm install canvas --build-from-source -RUN npm install -COPY . . -EXPOSE 3001 -RUN npm run build-docker -CMD ["node", "dist/start.js"] diff --git a/api/README.md b/api/README.md deleted file mode 100644 index 384a9611..00000000 --- a/api/README.md +++ /dev/null @@ -1,67 +0,0 @@ -

- -

-

Fosscord HTTP API Server

- -

- - - - - - - - -

- -## [About](https://github.com/fosscord/fosscord-server/wiki) - -This repository contains the Fosscord HTTP API Server - -## Bug Tracker - -[Project Board](https://fosscord.notion.site/2c7fe9e73f9842d3bab3a4912dedd091) - -## API - -We use [express](https://expressjs.com/) for the HTTP Server and -[lambert-server](https://www.npmjs.com/package/lambert-server) for route handling and body validation (customized). - -## Contribution - -You should be familiar with: - -- [Git](https://git-scm.com/) -- [NodeJS](https://nodejs.org/) -- [TypeScript](https://www.typescriptlang.org/) -- [MongoDB/mongoose](http://mongoosejs.com/) - -and the other technologies we use - -### Getting Started - -Clone the Repository: - -```bash -git clone https://github.com/fosscord/fosscord-server -cd fosscord-server -``` - -#### Install (dev)dependencies: - -```bash -npm install -npm install --only=dev -``` - -#### Starting: - -``` -npm start -``` - -#### Debugging: - -**Vscode:** -The Launch file configuration is in `./vscode/launch.json`, -so you can just debug the server by pressing `F5` or the `> Launch Server` button diff --git a/api/assets/preload-plugins/loginRedirect.js b/api/assets/preload-plugins/loginRedirect.js deleted file mode 100644 index 895536ef..00000000 --- a/api/assets/preload-plugins/loginRedirect.js +++ /dev/null @@ -1,13 +0,0 @@ -const redirectIfOnLogin = () => { - const path = window.location.pathname; - if (path == "/login" || path == "/register") { - window.location.reload(); - } -} - -const observer = new MutationObserver((mutations) => { - redirectIfOnLogin(); -}); -observer.observe(document, { subtree: true, childList: true }) - -redirectIfOnLogin(); \ No newline at end of file diff --git a/api/babel.config.js b/api/babel.config.js deleted file mode 100644 index 45ab8ad8..00000000 --- a/api/babel.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - presets: [ - ["@babel/preset-env", { targets: { node: "current" } }], - ["@babel/preset-typescript", { allowDeclareFields: true }] - ] -}; diff --git a/api/jest/getRouteDescriptions.js b/api/jest/getRouteDescriptions.js deleted file mode 100644 index 4f8d2e75..00000000 --- a/api/jest/getRouteDescriptions.js +++ /dev/null @@ -1,66 +0,0 @@ -const { traverseDirectory } = require("lambert-server"); -const path = require("path"); -const express = require("express"); -const RouteUtility = require("../dist/util/route"); -const Router = express.Router; - -/** - * Some documentation. - * - * @type {Map} - */ -const routes = new Map(); -let currentPath = ""; -let currentFile = ""; -const methods = ["get", "post", "put", "delete", "patch"]; - -function registerPath(file, method, prefix, path, ...args) { - const urlPath = prefix + path; - const sourceFile = file.replace("/dist/", "/src/").replace(".js", ".ts"); - const opts = args.find((x) => typeof x === "object"); - if (opts) { - routes.set(urlPath + "|" + method, opts); // @ts-ignore - opts.file = sourceFile; - // console.log(method, urlPath, opts); - } else { - console.log(`${sourceFile}\nrouter.${method}("${path}") is missing the "route()" description middleware\n`); - } -} - -function routeOptions(opts) { - return opts; -} - -// @ts-ignore -RouteUtility.route = routeOptions; - -express.Router = (opts) => { - const path = currentPath; - const file = currentFile; - const router = Router(opts); - - for (const method of methods) { - router[method] = registerPath.bind(null, file, method, path); - } - - return router; -}; - -module.exports = function getRouteDescriptions() { - const root = path.join(__dirname, "..", "dist", "routes", "/"); - traverseDirectory({ dirname: root, recursive: true }, (file) => { - currentFile = file; - let path = file.replace(root.slice(0, -1), ""); - path = path.split(".").slice(0, -1).join("."); // trancate .js/.ts file extension of path - path = path.replaceAll("#", ":").replaceAll("\\", "/"); // replace # with : for path parameters and windows paths with slashes - if (path.endsWith("/index")) path = path.slice(0, "/index".length * -1); // delete index from path - currentPath = path; - - try { - require(file); - } catch (error) { - console.error("error loading file " + file, error); - } - }); - return routes; -}; diff --git a/api/jest/globalSetup.js b/api/jest/globalSetup.js deleted file mode 100644 index 520aa0e2..00000000 --- a/api/jest/globalSetup.js +++ /dev/null @@ -1,20 +0,0 @@ -const { Config, initDatabase } = require("@fosscord/util"); -const fs = require("fs"); -const path = require("path"); -const { FosscordServer } = require("../dist/Server"); -const Server = new FosscordServer({ port: 3001 }); -global.server = Server; -module.exports = async () => { - try { - fs.unlinkSync(path.join(process.cwd(), "database.db")); - } catch {} - - await initDatabase(); - await Config.init(); - Config.get().limits.rate.disabled = true; - return await Server.start(); -}; - -// afterAll(async () => { -// return await Server.stop(); -// }); diff --git a/api/jest/setup.js b/api/jest/setup.js deleted file mode 100644 index abc485ae..00000000 --- a/api/jest/setup.js +++ /dev/null @@ -1,2 +0,0 @@ -jest.spyOn(global.console, "log").mockImplementation(() => jest.fn()); -jest.spyOn(global.console, "info").mockImplementation(() => jest.fn()); diff --git a/api/package-lock.json b/api/package-lock.json deleted file mode 100644 index de889188..00000000 Binary files a/api/package-lock.json and /dev/null differ diff --git a/api/package.json b/api/package.json deleted file mode 100644 index 1bb49261..00000000 --- a/api/package.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "name": "@fosscord/api", - "version": "1.0.0", - "description": "This repository contains the HTTP API Server", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "test:only": "npx jest --coverage --verbose --forceExit ./tests", - "test:routes": "npx jest --coverage --verbose --forceExit ./routes.test.ts", - "test": "npm run build && npm run test:only", - "test:watch": "npx jest --watch", - "start": "npm run build && node dist/start", - "build": "npx tsc -p .", - "dev": "npx tsnd --respawn src/start.ts", - "patch": "npx ts-patch install -s && npx patch-package", - "postinstall": "npm run patch", - "generate:docs": "node scripts/generate_openapi", - "generate:schema": "node scripts/generate_schema" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/fosscord/fosscord-server.git" - }, - "keywords": [ - "discord", - "fosscord", - "fosscord-server", - "fosscord-api", - "discord open source", - "discord-open-source" - ], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/fosscord/fosscord-server/issues" - }, - "homepage": "https://fosscord.com", - "devDependencies": { - "@babel/core": "^7.15.5", - "@babel/preset-env": "^7.15.8", - "@babel/preset-typescript": "^7.15.0", - "@types/amqplib": "^0.8.1", - "@types/bcrypt": "^5.0.0", - "@types/express": "^4.17.9", - "@types/i18next-node-fs-backend": "^2.1.0", - "@types/jest": "^27.0.1", - "@types/jest-expect-message": "^1.0.3", - "@types/jsonwebtoken": "^8.5.0", - "@types/morgan": "^1.9.3", - "@types/multer": "^1.4.5", - "@types/node": "^14.17.9", - "@types/node-fetch": "^2.5.5", - "@types/supertest": "^2.0.11", - "@zerollup/ts-transform-paths": "^1.7.18", - "jest": "^27.2.5", - "jest-expect-message": "^1.0.2", - "jest-runtime": "^27.2.1", - "ts-node": "^9.1.1", - "ts-node-dev": "^1.1.6", - "ts-patch": "^1.4.4", - "typescript": "^4.4.2", - "typescript-json-schema": "0.50.1" - }, - "dependencies": { - "@babel/preset-env": "^7.15.8", - "@babel/preset-typescript": "^7.15.0", - "@fosscord/util": "file:../util", - "@sentry/node": "^6.16.1", - "@sentry/tracing": "^6.16.1", - "ajv": "8.6.2", - "ajv-formats": "^2.1.1", - "amqplib": "^0.8.0", - "assert": "^1.5.0", - "bcrypt": "^5.0.1", - "body-parser": "^1.19.0", - "cheerio": "^1.0.0-rc.10", - "dotenv": "^8.2.0", - "express": "^4.17.1", - "form-data": "^3.0.0", - "i18next": "^19.9.2", - "i18next-http-middleware": "^3.1.3", - "i18next-node-fs-backend": "^2.1.3", - "image-size": "^1.0.0", - "jsonwebtoken": "^8.5.1", - "lambert-server": "^1.2.12", - "missing-native-js-functions": "^1.2.18", - "morgan": "^1.10.0", - "multer": "^1.4.2", - "node-fetch": "^2.6.2", - "patch-package": "^6.4.7", - "picocolors": "^1.0.0", - "proxy-agent": "^5.0.0", - "supertest": "^6.1.6", - "typeorm": "^0.2.37" - }, - "jest": { - "setupFiles": [ - "/jest/setup.js" - ], - "setupFilesAfterEnv": [ - "jest-expect-message" - ], - "globalSetup": "/jest/globalSetup.js", - "verbose": true - } -} diff --git a/api/src/global.d.ts b/api/src/global.d.ts deleted file mode 100644 index 7751af8f..00000000 --- a/api/src/global.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -declare global { - namespace Express { - interface Request { - user_id: any; - token: any; - } - } -} diff --git a/api/tests/routes.test.ts b/api/tests/routes.test.ts deleted file mode 100644 index 35d74a94..00000000 --- a/api/tests/routes.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -// TODO: check every route based on route() parameters: https://github.com/fosscord/fosscord-server/issues/308 -// TODO: check every route with different database engine - -import getRouteDescriptions from "../jest/getRouteDescriptions"; -import { join } from "path"; -import fs from "fs"; -import Ajv from "ajv"; -import addFormats from "ajv-formats"; -import fetch from "node-fetch"; -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" })); -export const ajv = new Ajv({ - allErrors: true, - parseDate: true, - allowDate: true, - schemas, - messages: true, - strict: true, - strictRequired: true, - coerceTypes: true -}); -addFormats(ajv); - -var token: string; -var user: User; -var guild: Guild; -var channel: Channel; - -const request = async (path: string, opts: any = {}): Promise => { - 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.parse(data); - if (response.status >= 400) throw data; - return data; - } catch (error) { - throw data; - } -}; - -beforeAll(async (done) => { - try { - const response = await request("/auth/register", { - body: { - fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", - username: "tester", - invite: null, - consent: true, - date_of_birth: "2000-01-01", - gift_code_sku_id: null, - captcha_key: null - } - }); - 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) { - done(error); - } -}); - -const emit = events.emit; -events.emit = (event: string | symbol, ...args: any[]) => { - events.emit("event", args[0]); - return emit(event, ...args); -}; - -describe("Automatic unit tests with route description middleware", () => { - const routes = getRouteDescriptions(); - - routes.forEach((route, pathAndMethod) => { - const [path, method] = pathAndMethod.split("|"); - - test(`${method.toUpperCase()} ${path}`, async (done) => { - if (!route.test) { - console.log(`${(route as any).file}\nrouter.${method} is missing the test property`); - return done(); - } - 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); - if (!validate) return done(new Error(`Response schema ${route.test.body} not found`)); - } - - var body = ""; - let eventEmitted = Promise.resolve(); - - if (route.test.event) { - if (!Array.isArray(route.test.event)) route.test.event = [route.test.event]; - - eventEmitted = new Promise((resolve, reject) => { - const timeout = setTimeout(() => reject, 1000); - const received = []; - - events.on("event", (event: Event) => { - if (!route.test.event.includes(event.event)) return; - - received.push(event.event); - if (received.length === route.test.event.length) resolve(); - }); - }); - } - - try { - const response = await fetch(`http://localhost:3001/api${urlPath}`, { - method: method.toUpperCase(), - body: JSON.stringify(route.test.body), - headers: { ...route.test.headers, authorization: token } - }); - - body = await response.text(); - - expect(response.status, body).toBe(route.test.response.status || 200); - - // TODO: check headers - // TODO: expect event - - if (validate) { - body = JSON.parse(body); - const valid = validate(body); - if (!valid) return done(validate.errors); - } - } catch (error) { - return done(error); - } - - try { - await eventEmitted; - } catch (error) { - return done(new Error(`Event ${route.test.event} was not emitted`)); - } - - return done(); - }); - }); -}); diff --git a/api/tests/routes/auth/login.test.js b/api/tests/routes/auth/login.test.js deleted file mode 100644 index d4b52444..00000000 --- a/api/tests/routes/auth/login.test.js +++ /dev/null @@ -1,33 +0,0 @@ -const supertest = require("supertest"); -const request = supertest("http://localhost:3001"); - -describe("/api/auth/login", () => { - describe("POST", () => { - test("without body", async () => { - const response = await request.post("/api/auth/login").send({}); - expect(response.statusCode).toBe(400); - }); - test("with body", async () => { - const user = { - login: "fortnitefortnite@gmail.com", - password: "verysecurepassword" - }; - - await request.post("/api/auth/register").send({ - fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", - email: user.login, - username: user.login.split("@")[0], - password: user.password, - invite: null, - consent: true, - date_of_birth: "2000-04-04", - gift_code_sku_id: null, - captcha_key: null - }); - - const response = await request.post("/api/auth/login").send(user); - - expect(response.statusCode).toBe(200); - }); - }); -}); diff --git a/api/tests/routes/auth/register.test.js b/api/tests/routes/auth/register.test.js deleted file mode 100644 index 5d7b4eaa..00000000 --- a/api/tests/routes/auth/register.test.js +++ /dev/null @@ -1,27 +0,0 @@ -const supertest = require("supertest"); -const request = supertest("http://localhost:3001"); - -describe("/api/auth/register", () => { - describe("POST", () => { - test("without body", async () => { - const response = await request.post("/api/auth/register").send({}); - - expect(response.statusCode).toBe(400); - }); - test("with body", async () => { - const response = await request.post("/api/auth/register").send({ - fingerprint: "805826570869932034.wR8vi8lGlFBJerErO9LG5NViJFw", - email: "qo8etzvaf@gmail.com", - username: "qp39gr98", - password: "wtp9gep9gw", - invite: null, - consent: true, - date_of_birth: "2000-04-04", - gift_code_sku_id: null, - captcha_key: null - }); - - expect(response.statusCode).toBe(200); - }); - }); -}); diff --git a/api/tests/routes/ping.test.js b/api/tests/routes/ping.test.js deleted file mode 100644 index 6fa4b160..00000000 --- a/api/tests/routes/ping.test.js +++ /dev/null @@ -1,12 +0,0 @@ -const supertest = require("supertest"); -const request = supertest("http://localhost:3001"); - -describe("/ping", () => { - describe("GET", () => { - test("should return 200 and pong", async () => { - let response = await request.get("/api/ping"); - expect(response.text).toBe("pong"); - expect(response.statusCode).toBe(200); - }); - }); -}); diff --git a/api/tsconfig.json b/api/tsconfig.json deleted file mode 100644 index b558a0dd..00000000 --- a/api/tsconfig.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "exclude": ["node_modules"], - "include": ["src/**/*.ts"], - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - "incremental": true /* Enable incremental compilation */, - "target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": ["ES2021"] /* Specify library files to be included in the compilation. */, - "allowJs": true /* Allow javascript files to be compiled. */, - "checkJs": true /* Report errors in .js files. */, - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true /* Generates corresponding '.d.ts' file. */, - "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */, - "sourceMap": true /* Generates corresponding '.map' file. */, - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* Enable strict null checks. */, - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["node"] /* Type declaration files to be included in compilation. */, - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "baseUrl": ".", - "paths": { - "@fosscord/api": ["src/index"] - "@fosscord/util": ["../util/src/index"] - }, - "plugins": [{ "transform": "@zerollup/ts-transform-paths" }], - "experimentalDecorators": true - } -} diff --git a/api/assets/background.png b/assets/background.png similarity index 100% rename from api/assets/background.png rename to assets/background.png diff --git a/api/assets/checkLocale.js b/assets/checkLocale.js similarity index 100% rename from api/assets/checkLocale.js rename to assets/checkLocale.js diff --git a/api/client_test/developers.html b/assets/client_test/developers.html similarity index 100% rename from api/client_test/developers.html rename to assets/client_test/developers.html diff --git a/api/client_test/index.html b/assets/client_test/index.html similarity index 100% rename from api/client_test/index.html rename to assets/client_test/index.html diff --git a/api/assets/dff87c953f43b561d71fbcfe8a93a79a.png b/assets/dff87c953f43b561d71fbcfe8a93a79a.png similarity index 100% rename from api/assets/dff87c953f43b561d71fbcfe8a93a79a.png rename to assets/dff87c953f43b561d71fbcfe8a93a79a.png diff --git a/api/assets/endpoints.json b/assets/endpoints.json similarity index 100% rename from api/assets/endpoints.json rename to assets/endpoints.json diff --git a/api/assets/features.json b/assets/features.json similarity index 100% rename from api/assets/features.json rename to assets/features.json diff --git a/api/assets/fosscord-login.css b/assets/fosscord-login.css similarity index 100% rename from api/assets/fosscord-login.css rename to assets/fosscord-login.css diff --git a/api/assets/fosscord.css b/assets/fosscord.css similarity index 100% rename from api/assets/fosscord.css rename to assets/fosscord.css diff --git a/api/locales/af/auth.json b/assets/locales/af/auth.json similarity index 100% rename from api/locales/af/auth.json rename to assets/locales/af/auth.json diff --git a/api/locales/af/common.json b/assets/locales/af/common.json similarity index 100% rename from api/locales/af/common.json rename to assets/locales/af/common.json diff --git a/api/locales/ar/auth.json b/assets/locales/ar/auth.json similarity index 100% rename from api/locales/ar/auth.json rename to assets/locales/ar/auth.json diff --git a/api/locales/ar/common.json b/assets/locales/ar/common.json similarity index 100% rename from api/locales/ar/common.json rename to assets/locales/ar/common.json diff --git a/api/locales/arn/auth.json b/assets/locales/arn/auth.json similarity index 100% rename from api/locales/arn/auth.json rename to assets/locales/arn/auth.json diff --git a/api/locales/arn/common.json b/assets/locales/arn/common.json similarity index 100% rename from api/locales/arn/common.json rename to assets/locales/arn/common.json diff --git a/api/locales/az/auth.json b/assets/locales/az/auth.json similarity index 100% rename from api/locales/az/auth.json rename to assets/locales/az/auth.json diff --git a/api/locales/az/common.json b/assets/locales/az/common.json similarity index 100% rename from api/locales/az/common.json rename to assets/locales/az/common.json diff --git a/api/locales/be/auth.json b/assets/locales/be/auth.json similarity index 100% rename from api/locales/be/auth.json rename to assets/locales/be/auth.json diff --git a/api/locales/be/common.json b/assets/locales/be/common.json similarity index 100% rename from api/locales/be/common.json rename to assets/locales/be/common.json diff --git a/api/locales/ber/auth.json b/assets/locales/ber/auth.json similarity index 100% rename from api/locales/ber/auth.json rename to assets/locales/ber/auth.json diff --git a/api/locales/ber/common.json b/assets/locales/ber/common.json similarity index 100% rename from api/locales/ber/common.json rename to assets/locales/ber/common.json diff --git a/api/locales/bg/auth.json b/assets/locales/bg/auth.json similarity index 100% rename from api/locales/bg/auth.json rename to assets/locales/bg/auth.json diff --git a/api/locales/bg/common.json b/assets/locales/bg/common.json similarity index 100% rename from api/locales/bg/common.json rename to assets/locales/bg/common.json diff --git a/api/locales/bo/auth.json b/assets/locales/bo/auth.json similarity index 100% rename from api/locales/bo/auth.json rename to assets/locales/bo/auth.json diff --git a/api/locales/bo/common.json b/assets/locales/bo/common.json similarity index 100% rename from api/locales/bo/common.json rename to assets/locales/bo/common.json diff --git a/api/locales/ca/auth.json b/assets/locales/ca/auth.json similarity index 100% rename from api/locales/ca/auth.json rename to assets/locales/ca/auth.json diff --git a/api/locales/ca/common.json b/assets/locales/ca/common.json similarity index 100% rename from api/locales/ca/common.json rename to assets/locales/ca/common.json diff --git a/api/locales/cs/auth.json b/assets/locales/cs/auth.json similarity index 100% rename from api/locales/cs/auth.json rename to assets/locales/cs/auth.json diff --git a/api/locales/cs/common.json b/assets/locales/cs/common.json similarity index 100% rename from api/locales/cs/common.json rename to assets/locales/cs/common.json diff --git a/api/locales/da/auth.json b/assets/locales/da/auth.json similarity index 100% rename from api/locales/da/auth.json rename to assets/locales/da/auth.json diff --git a/api/locales/da/common.json b/assets/locales/da/common.json similarity index 100% rename from api/locales/da/common.json rename to assets/locales/da/common.json diff --git a/api/locales/de/auth.json b/assets/locales/de/auth.json similarity index 100% rename from api/locales/de/auth.json rename to assets/locales/de/auth.json diff --git a/api/locales/de/common.json b/assets/locales/de/common.json similarity index 100% rename from api/locales/de/common.json rename to assets/locales/de/common.json diff --git a/api/locales/el/auth.json b/assets/locales/el/auth.json similarity index 100% rename from api/locales/el/auth.json rename to assets/locales/el/auth.json diff --git a/api/locales/el/common.json b/assets/locales/el/common.json similarity index 100% rename from api/locales/el/common.json rename to assets/locales/el/common.json diff --git a/api/locales/en/auth.json b/assets/locales/en/auth.json similarity index 100% rename from api/locales/en/auth.json rename to assets/locales/en/auth.json diff --git a/api/locales/en/common.json b/assets/locales/en/common.json similarity index 100% rename from api/locales/en/common.json rename to assets/locales/en/common.json diff --git a/api/locales/eo/auth.json b/assets/locales/eo/auth.json similarity index 100% rename from api/locales/eo/auth.json rename to assets/locales/eo/auth.json diff --git a/api/locales/eo/common.json b/assets/locales/eo/common.json similarity index 100% rename from api/locales/eo/common.json rename to assets/locales/eo/common.json diff --git a/api/locales/es/auth.json b/assets/locales/es/auth.json similarity index 100% rename from api/locales/es/auth.json rename to assets/locales/es/auth.json diff --git a/api/locales/es/common.json b/assets/locales/es/common.json similarity index 100% rename from api/locales/es/common.json rename to assets/locales/es/common.json diff --git a/api/locales/eu/auth.json b/assets/locales/eu/auth.json similarity index 100% rename from api/locales/eu/auth.json rename to assets/locales/eu/auth.json diff --git a/api/locales/eu/common.json b/assets/locales/eu/common.json similarity index 100% rename from api/locales/eu/common.json rename to assets/locales/eu/common.json diff --git a/api/locales/fa/auth.json b/assets/locales/fa/auth.json similarity index 100% rename from api/locales/fa/auth.json rename to assets/locales/fa/auth.json diff --git a/api/locales/fa/common.json b/assets/locales/fa/common.json similarity index 100% rename from api/locales/fa/common.json rename to assets/locales/fa/common.json diff --git a/api/locales/fi/auth.json b/assets/locales/fi/auth.json similarity index 100% rename from api/locales/fi/auth.json rename to assets/locales/fi/auth.json diff --git a/api/locales/fi/common.json b/assets/locales/fi/common.json similarity index 100% rename from api/locales/fi/common.json rename to assets/locales/fi/common.json diff --git a/api/locales/fr/auth.json b/assets/locales/fr/auth.json similarity index 100% rename from api/locales/fr/auth.json rename to assets/locales/fr/auth.json diff --git a/api/locales/fr/common.json b/assets/locales/fr/common.json similarity index 100% rename from api/locales/fr/common.json rename to assets/locales/fr/common.json diff --git a/api/locales/gn/auth.json b/assets/locales/gn/auth.json similarity index 100% rename from api/locales/gn/auth.json rename to assets/locales/gn/auth.json diff --git a/api/locales/gn/common.json b/assets/locales/gn/common.json similarity index 100% rename from api/locales/gn/common.json rename to assets/locales/gn/common.json diff --git a/api/locales/ha/auth.json b/assets/locales/ha/auth.json similarity index 100% rename from api/locales/ha/auth.json rename to assets/locales/ha/auth.json diff --git a/api/locales/ha/common.json b/assets/locales/ha/common.json similarity index 100% rename from api/locales/ha/common.json rename to assets/locales/ha/common.json diff --git a/api/locales/he/auth.json b/assets/locales/he/auth.json similarity index 100% rename from api/locales/he/auth.json rename to assets/locales/he/auth.json diff --git a/api/locales/he/common.json b/assets/locales/he/common.json similarity index 100% rename from api/locales/he/common.json rename to assets/locales/he/common.json diff --git a/api/locales/hi/auth.json b/assets/locales/hi/auth.json similarity index 100% rename from api/locales/hi/auth.json rename to assets/locales/hi/auth.json diff --git a/api/locales/hi/common.json b/assets/locales/hi/common.json similarity index 100% rename from api/locales/hi/common.json rename to assets/locales/hi/common.json diff --git a/api/locales/hr/auth.json b/assets/locales/hr/auth.json similarity index 100% rename from api/locales/hr/auth.json rename to assets/locales/hr/auth.json diff --git a/api/locales/hr/common.json b/assets/locales/hr/common.json similarity index 100% rename from api/locales/hr/common.json rename to assets/locales/hr/common.json diff --git a/api/locales/hu/auth.json b/assets/locales/hu/auth.json similarity index 100% rename from api/locales/hu/auth.json rename to assets/locales/hu/auth.json diff --git a/api/locales/hu/common.json b/assets/locales/hu/common.json similarity index 100% rename from api/locales/hu/common.json rename to assets/locales/hu/common.json diff --git a/api/locales/id/auth.json b/assets/locales/id/auth.json similarity index 100% rename from api/locales/id/auth.json rename to assets/locales/id/auth.json diff --git a/api/locales/id/common.json b/assets/locales/id/common.json similarity index 100% rename from api/locales/id/common.json rename to assets/locales/id/common.json diff --git a/api/locales/it/auth.json b/assets/locales/it/auth.json similarity index 100% rename from api/locales/it/auth.json rename to assets/locales/it/auth.json diff --git a/api/locales/it/common.json b/assets/locales/it/common.json similarity index 100% rename from api/locales/it/common.json rename to assets/locales/it/common.json diff --git a/api/locales/ja/auth.json b/assets/locales/ja/auth.json similarity index 100% rename from api/locales/ja/auth.json rename to assets/locales/ja/auth.json diff --git a/api/locales/ja/common.json b/assets/locales/ja/common.json similarity index 100% rename from api/locales/ja/common.json rename to assets/locales/ja/common.json diff --git a/api/locales/jv/auth.json b/assets/locales/jv/auth.json similarity index 100% rename from api/locales/jv/auth.json rename to assets/locales/jv/auth.json diff --git a/api/locales/jv/common.json b/assets/locales/jv/common.json similarity index 100% rename from api/locales/jv/common.json rename to assets/locales/jv/common.json diff --git a/api/locales/kk/auth.json b/assets/locales/kk/auth.json similarity index 100% rename from api/locales/kk/auth.json rename to assets/locales/kk/auth.json diff --git a/api/locales/kk/common.json b/assets/locales/kk/common.json similarity index 100% rename from api/locales/kk/common.json rename to assets/locales/kk/common.json diff --git a/api/locales/ko/auth.json b/assets/locales/ko/auth.json similarity index 100% rename from api/locales/ko/auth.json rename to assets/locales/ko/auth.json diff --git a/api/locales/ko/common.json b/assets/locales/ko/common.json similarity index 100% rename from api/locales/ko/common.json rename to assets/locales/ko/common.json diff --git a/api/locales/ku/auth.json b/assets/locales/ku/auth.json similarity index 100% rename from api/locales/ku/auth.json rename to assets/locales/ku/auth.json diff --git a/api/locales/ku/common.json b/assets/locales/ku/common.json similarity index 100% rename from api/locales/ku/common.json rename to assets/locales/ku/common.json diff --git a/api/locales/la/auth.json b/assets/locales/la/auth.json similarity index 100% rename from api/locales/la/auth.json rename to assets/locales/la/auth.json diff --git a/api/locales/la/common.json b/assets/locales/la/common.json similarity index 100% rename from api/locales/la/common.json rename to assets/locales/la/common.json diff --git a/api/locales/lt/auth.json b/assets/locales/lt/auth.json similarity index 100% rename from api/locales/lt/auth.json rename to assets/locales/lt/auth.json diff --git a/api/locales/lt/common.json b/assets/locales/lt/common.json similarity index 100% rename from api/locales/lt/common.json rename to assets/locales/lt/common.json diff --git a/api/locales/mi/auth.json b/assets/locales/mi/auth.json similarity index 100% rename from api/locales/mi/auth.json rename to assets/locales/mi/auth.json diff --git a/api/locales/mi/common.json b/assets/locales/mi/common.json similarity index 100% rename from api/locales/mi/common.json rename to assets/locales/mi/common.json diff --git a/api/locales/mn/auth.json b/assets/locales/mn/auth.json similarity index 100% rename from api/locales/mn/auth.json rename to assets/locales/mn/auth.json diff --git a/api/locales/mn/common.json b/assets/locales/mn/common.json similarity index 100% rename from api/locales/mn/common.json rename to assets/locales/mn/common.json diff --git a/api/locales/mr/auth.json b/assets/locales/mr/auth.json similarity index 100% rename from api/locales/mr/auth.json rename to assets/locales/mr/auth.json diff --git a/api/locales/mr/common.json b/assets/locales/mr/common.json similarity index 100% rename from api/locales/mr/common.json rename to assets/locales/mr/common.json diff --git a/api/locales/nl/auth.json b/assets/locales/nl/auth.json similarity index 100% rename from api/locales/nl/auth.json rename to assets/locales/nl/auth.json diff --git a/api/locales/nl/common.json b/assets/locales/nl/common.json similarity index 100% rename from api/locales/nl/common.json rename to assets/locales/nl/common.json diff --git a/api/locales/nn/auth.json b/assets/locales/nn/auth.json similarity index 100% rename from api/locales/nn/auth.json rename to assets/locales/nn/auth.json diff --git a/api/locales/nn/common.json b/assets/locales/nn/common.json similarity index 100% rename from api/locales/nn/common.json rename to assets/locales/nn/common.json diff --git a/api/locales/no/auth.json b/assets/locales/no/auth.json similarity index 100% rename from api/locales/no/auth.json rename to assets/locales/no/auth.json diff --git a/api/locales/no/common.json b/assets/locales/no/common.json similarity index 100% rename from api/locales/no/common.json rename to assets/locales/no/common.json diff --git a/api/locales/pa/auth.json b/assets/locales/pa/auth.json similarity index 100% rename from api/locales/pa/auth.json rename to assets/locales/pa/auth.json diff --git a/api/locales/pa/common.json b/assets/locales/pa/common.json similarity index 100% rename from api/locales/pa/common.json rename to assets/locales/pa/common.json diff --git a/api/locales/pl/auth.json b/assets/locales/pl/auth.json similarity index 100% rename from api/locales/pl/auth.json rename to assets/locales/pl/auth.json diff --git a/api/locales/pl/common.json b/assets/locales/pl/common.json similarity index 100% rename from api/locales/pl/common.json rename to assets/locales/pl/common.json diff --git a/api/locales/pt/auth.json b/assets/locales/pt/auth.json similarity index 100% rename from api/locales/pt/auth.json rename to assets/locales/pt/auth.json diff --git a/api/locales/pt/common.json b/assets/locales/pt/common.json similarity index 100% rename from api/locales/pt/common.json rename to assets/locales/pt/common.json diff --git a/api/locales/qu/auth.json b/assets/locales/qu/auth.json similarity index 100% rename from api/locales/qu/auth.json rename to assets/locales/qu/auth.json diff --git a/api/locales/qu/common.json b/assets/locales/qu/common.json similarity index 100% rename from api/locales/qu/common.json rename to assets/locales/qu/common.json diff --git a/api/locales/ro/auth.json b/assets/locales/ro/auth.json similarity index 100% rename from api/locales/ro/auth.json rename to assets/locales/ro/auth.json diff --git a/api/locales/ro/common.json b/assets/locales/ro/common.json similarity index 100% rename from api/locales/ro/common.json rename to assets/locales/ro/common.json diff --git a/api/locales/ru/auth.json b/assets/locales/ru/auth.json similarity index 100% rename from api/locales/ru/auth.json rename to assets/locales/ru/auth.json diff --git a/api/locales/ru/common.json b/assets/locales/ru/common.json similarity index 100% rename from api/locales/ru/common.json rename to assets/locales/ru/common.json diff --git a/api/locales/sh/auth.json b/assets/locales/sh/auth.json similarity index 100% rename from api/locales/sh/auth.json rename to assets/locales/sh/auth.json diff --git a/api/locales/sh/common.json b/assets/locales/sh/common.json similarity index 100% rename from api/locales/sh/common.json rename to assets/locales/sh/common.json diff --git a/api/locales/si/auth.json b/assets/locales/si/auth.json similarity index 100% rename from api/locales/si/auth.json rename to assets/locales/si/auth.json diff --git a/api/locales/si/common.json b/assets/locales/si/common.json similarity index 100% rename from api/locales/si/common.json rename to assets/locales/si/common.json diff --git a/api/locales/sk/auth.json b/assets/locales/sk/auth.json similarity index 100% rename from api/locales/sk/auth.json rename to assets/locales/sk/auth.json diff --git a/api/locales/sk/common.json b/assets/locales/sk/common.json similarity index 100% rename from api/locales/sk/common.json rename to assets/locales/sk/common.json diff --git a/api/locales/sr/auth.json b/assets/locales/sr/auth.json similarity index 100% rename from api/locales/sr/auth.json rename to assets/locales/sr/auth.json diff --git a/api/locales/sr/common.json b/assets/locales/sr/common.json similarity index 100% rename from api/locales/sr/common.json rename to assets/locales/sr/common.json diff --git a/api/locales/sv/auth.json b/assets/locales/sv/auth.json similarity index 100% rename from api/locales/sv/auth.json rename to assets/locales/sv/auth.json diff --git a/api/locales/sv/common.json b/assets/locales/sv/common.json similarity index 100% rename from api/locales/sv/common.json rename to assets/locales/sv/common.json diff --git a/api/locales/sw/auth.json b/assets/locales/sw/auth.json similarity index 100% rename from api/locales/sw/auth.json rename to assets/locales/sw/auth.json diff --git a/api/locales/sw/common.json b/assets/locales/sw/common.json similarity index 100% rename from api/locales/sw/common.json rename to assets/locales/sw/common.json diff --git a/api/locales/ta/auth.json b/assets/locales/ta/auth.json similarity index 100% rename from api/locales/ta/auth.json rename to assets/locales/ta/auth.json diff --git a/api/locales/ta/common.json b/assets/locales/ta/common.json similarity index 100% rename from api/locales/ta/common.json rename to assets/locales/ta/common.json diff --git a/api/locales/te/auth.json b/assets/locales/te/auth.json similarity index 100% rename from api/locales/te/auth.json rename to assets/locales/te/auth.json diff --git a/api/locales/te/common.json b/assets/locales/te/common.json similarity index 100% rename from api/locales/te/common.json rename to assets/locales/te/common.json diff --git a/api/locales/tl/auth.json b/assets/locales/tl/auth.json similarity index 100% rename from api/locales/tl/auth.json rename to assets/locales/tl/auth.json diff --git a/api/locales/tl/common.json b/assets/locales/tl/common.json similarity index 100% rename from api/locales/tl/common.json rename to assets/locales/tl/common.json diff --git a/api/locales/tr/auth.json b/assets/locales/tr/auth.json similarity index 100% rename from api/locales/tr/auth.json rename to assets/locales/tr/auth.json diff --git a/api/locales/tr/common.json b/assets/locales/tr/common.json similarity index 100% rename from api/locales/tr/common.json rename to assets/locales/tr/common.json diff --git a/api/locales/ug/auth.json b/assets/locales/ug/auth.json similarity index 100% rename from api/locales/ug/auth.json rename to assets/locales/ug/auth.json diff --git a/api/locales/ug/common.json b/assets/locales/ug/common.json similarity index 100% rename from api/locales/ug/common.json rename to assets/locales/ug/common.json diff --git a/api/locales/uk/auth.json b/assets/locales/uk/auth.json similarity index 100% rename from api/locales/uk/auth.json rename to assets/locales/uk/auth.json diff --git a/api/locales/uk/common.json b/assets/locales/uk/common.json similarity index 100% rename from api/locales/uk/common.json rename to assets/locales/uk/common.json diff --git a/api/locales/ur/auth.json b/assets/locales/ur/auth.json similarity index 100% rename from api/locales/ur/auth.json rename to assets/locales/ur/auth.json diff --git a/api/locales/ur/common.json b/assets/locales/ur/common.json similarity index 100% rename from api/locales/ur/common.json rename to assets/locales/ur/common.json diff --git a/api/locales/vec/auth.json b/assets/locales/vec/auth.json similarity index 100% rename from api/locales/vec/auth.json rename to assets/locales/vec/auth.json diff --git a/api/locales/vec/common.json b/assets/locales/vec/common.json similarity index 100% rename from api/locales/vec/common.json rename to assets/locales/vec/common.json diff --git a/api/locales/vi/auth.json b/assets/locales/vi/auth.json similarity index 100% rename from api/locales/vi/auth.json rename to assets/locales/vi/auth.json diff --git a/api/locales/vi/common.json b/assets/locales/vi/common.json similarity index 100% rename from api/locales/vi/common.json rename to assets/locales/vi/common.json diff --git a/api/locales/zh/auth.json b/assets/locales/zh/auth.json similarity index 100% rename from api/locales/zh/auth.json rename to assets/locales/zh/auth.json diff --git a/api/locales/zh/common.json b/assets/locales/zh/common.json similarity index 100% rename from api/locales/zh/common.json rename to assets/locales/zh/common.json diff --git a/api/assets/openapi.json b/assets/openapi.json similarity index 100% rename from api/assets/openapi.json rename to assets/openapi.json diff --git a/api/assets/plugins/.gitkeep b/assets/plugins/.gitkeep similarity index 100% rename from api/assets/plugins/.gitkeep rename to assets/plugins/.gitkeep diff --git a/api/assets/preload-plugins/autoRegister.js b/assets/preload-plugins/autoRegister.js similarity index 100% rename from api/assets/preload-plugins/autoRegister.js rename to assets/preload-plugins/autoRegister.js diff --git a/api/assets/preload-plugins/fosscord-login.js b/assets/preload-plugins/fosscord-login.js similarity index 100% rename from api/assets/preload-plugins/fosscord-login.js rename to assets/preload-plugins/fosscord-login.js diff --git a/api/assets/preload-plugins/webrtc.js b/assets/preload-plugins/webrtc.js similarity index 100% rename from api/assets/preload-plugins/webrtc.js rename to assets/preload-plugins/webrtc.js diff --git a/api/assets/schemas.json b/assets/schemas.json similarity index 100% rename from api/assets/schemas.json rename to assets/schemas.json diff --git a/api/assets/user.css b/assets/user.css similarity index 100% rename from api/assets/user.css rename to assets/user.css diff --git a/api/assets/widget/banner1.png b/assets/widget/banner1.png similarity index 100% rename from api/assets/widget/banner1.png rename to assets/widget/banner1.png diff --git a/api/assets/widget/banner2.png b/assets/widget/banner2.png similarity index 100% rename from api/assets/widget/banner2.png rename to assets/widget/banner2.png diff --git a/api/assets/widget/banner3.png b/assets/widget/banner3.png similarity index 100% rename from api/assets/widget/banner3.png rename to assets/widget/banner3.png diff --git a/api/assets/widget/banner4.png b/assets/widget/banner4.png similarity index 100% rename from api/assets/widget/banner4.png rename to assets/widget/banner4.png diff --git a/api/assets/widget/shield.png b/assets/widget/shield.png similarity index 100% rename from api/assets/widget/shield.png rename to assets/widget/shield.png diff --git a/bundle/bannedWords b/bannedWords similarity index 100% rename from bundle/bannedWords rename to bannedWords diff --git a/bundle/.prettierrc b/bundle/.prettierrc deleted file mode 100644 index 6a48eb4a..00000000 --- a/bundle/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "useTabs": true, - "tabWidth": 4 -} diff --git a/bundle/.vscode/launch.json b/bundle/.vscode/launch.json deleted file mode 100644 index 6e1a34b2..00000000 --- a/bundle/.vscode/launch.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "sourceMaps": true, - "name": "ts-node", - "type": "node", - "request": "launch", - "args": [ - "${workspaceFolder}/src/start.ts" - ], - "runtimeArgs": [ - "-r", - "ts-node/register" - ], - "protocol": "inspector", - "internalConsoleOptions": "openOnSessionStart", - "env": { - "TS_NODE_PROJECT": "${workspaceFolder}/tsnode.tsconfig.json", - "TS_NODE_COMPILER": "typescript-cached-transpile" - }, - "resolveSourceMapLocations": null, /* allow breakpoints in modules other than bundle */ - }, - { - "sourceMaps": true, - "resolveSourceMapLocations": null, /* allow breakpoints in modules other than bundle */ - "type": "node", - "request": "launch", - "name": "Launch Server", - "program": "${workspaceFolder}/dist/bundle/src/start.js", - "preLaunchTask": "tsc: build - tsconfig.json", - "outFiles": ["${workspaceFolder}/dist/**/*.js"], - "envFile": "${workspaceFolder}/.env", - } - ] -} diff --git a/bundle/package-lock.json b/bundle/package-lock.json deleted file mode 100644 index 644a3a3c..00000000 Binary files a/bundle/package-lock.json and /dev/null differ diff --git a/bundle/package.json b/bundle/package.json deleted file mode 100644 index 3c1f5a8c..00000000 --- a/bundle/package.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "name": "@fosscord/server", - "version": "1.0.0", - "description": "", - "main": "src/start.js", - "scripts": { - "setup": "node scripts/install.js && npm install --no-optional && npx ts-patch install -s && npx patch-package --patch-dir ../api/patches/ && npm run build", - "build": "node scripts/build.js", - "start": "node scripts/build.js && node dist/bundle/src/start.js", - "start:bundle": "node dist/bundle/src/start.js", - "test": "echo \"Error: no test specified\" && exit 1", - "migrate": "cd ../util/ && npm i && node --require ts-node/register node_modules/typeorm/cli.js -f ../util/ormconfig.json migration:run", - "tsnode": "npx ts-node --transpile-only -P tsnode.tsconfig.json src/start.ts" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/fosscord/fosscord-server.git" - }, - "keywords": [], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/fosscord/fosscord-server/issues" - }, - "homepage": "https://fosscord.com", - "devDependencies": { - "@babel/core": "^7.15.5", - "@babel/preset-env": "^7.15.8", - "@babel/preset-typescript": "^7.15.0", - "@types/amqplib": "^0.8.1", - "@types/bcrypt": "^5.0.0", - "@types/body-parser": "^1.19.0", - "@types/btoa": "^1.2.3", - "@types/dotenv": "^8.2.0", - "@types/express": "^4.17.12", - "@types/fs-extra": "^9.0.12", - "@types/i18next-node-fs-backend": "^2.1.0", - "@types/jest": "^27.0.1", - "@types/jest-expect-message": "^1.0.3", - "@types/json-bigint": "^1.0.1", - "@types/jsonwebtoken": "^8.5.0", - "@types/morgan": "^1.9.3", - "@types/multer": "^1.4.7", - "@types/node": "^14.18.24", - "@types/node-fetch": "^2.5.12", - "@types/node-os-utils": "^1.2.0", - "@types/sharp": "^0.30.4", - "@types/supertest": "^2.0.11", - "@types/ws": "^7.4.0", - "@zerollup/ts-transform-paths": "^1.7.18", - "jest": "^27.0.6", - "jest-expect-message": "^1.0.2", - "jest-runtime": "^27.2.1", - "ts-node": "^10.2.1", - "ts-node-dev": "^1.1.6", - "ts-patch": "^1.4.4", - "tsconfig-paths": "^3.12.0", - "typescript": "^4.2.3", - "typescript-json-schema": "0.50.1" - }, - "dependencies": { - "@aws-sdk/client-s3": "^3.36.1", - "@aws-sdk/node-http-handler": "^3.36.0", - "@babel/preset-env": "^7.15.8", - "@babel/preset-typescript": "^7.15.0", - "@fosscord/api": "file:../api", - "@fosscord/cdn": "file:../cdn", - "@fosscord/gateway": "file:../gateway", - "@sentry/node": "^7.13.0", - "@sentry/tracing": "^7.13.0", - "@yukikaze-bot/erlpack": "^1.0.1", - "ajv": "8.6.2", - "ajv-formats": "^2.1.1", - "amqplib": "^0.8.0", - "assert": "^1.5.0", - "async-exit-hook": "^2.0.1", - "bcrypt": "^5.0.1", - "body-parser": "^1.19.0", - "btoa": "^1.2.1", - "cheerio": "^1.0.0-rc.10", - "dotenv": "^8.2.0", - "exif-be-gone": "^1.2.0", - "express": "^4.17.1", - "express-async-errors": "^3.1.1", - "fast-zlib": "^2.0.1", - "file-type": "^16.5.4", - "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "i18next": "^19.9.2", - "i18next-http-middleware": "^3.1.3", - "i18next-node-fs-backend": "^2.1.3", - "image-size": "^1.0.0", - "jest": "^27.0.6", - "json-bigint": "^1.0.0", - "jsonwebtoken": "^8.5.1", - "lambert-db": "^1.2.3", - "lambert-server": "^1.2.11", - "missing-native-js-functions": "^1.2.18", - "morgan": "^1.10.0", - "multer": "^1.4.2", - "nan": "^2.15.0", - "nanocolors": "^0.2.12", - "node-2fa": "^2.0.3", - "node-fetch": "^2.6.2", - "node-os-utils": "^1.3.5", - "patch-package": "^6.4.7", - "pg": "^8.7.1", - "picocolors": "^1.0.0", - "proxy-agent": "^5.0.0", - "reflect-metadata": "^0.1.13", - "sharp": "^0.30.7", - "sqlite3": "^4.2.0", - "supertest": "^6.1.6", - "tslib": "^2.3.1", - "typeorm": "^0.2.37", - "typescript": "^4.1.2", - "typescript-cached-transpile": "^0.0.6", - "typescript-json-schema": "^0.50.1", - "ws": "^7.4.2" - } -} diff --git a/bundle/tsconfig.json b/bundle/tsconfig.json deleted file mode 100644 index 1a1aa0bf..00000000 --- a/bundle/tsconfig.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "include": ["dist/**/*.ts"], - "exclude": [], - "compilerOptions": { - - /* Basic Options */ - "incremental": false /* Enable incremental compilation */, - "target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ES2021", - "DOM" - ] /* Specify library files to be included in the compilation. */, - "allowJs": true /* Allow javascript files to be compiled. */, - "checkJs": true /* Report errors in .js files. */, - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": false /* Generates corresponding '.d.ts' file. */, - "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */, - "sourceMap": true /* Generates corresponding '.map' file. */, - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "./dist/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* Enable strict null checks. */, - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": [ - "node" - ] /* Type declaration files to be included in compilation. */, - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "resolveJsonModule": true, - "baseUrl": "./dist/", - "paths": { - "@fosscord/api": ["api/src/index"], - "@fosscord/gateway": ["gateway/src/index"], - "@fosscord/cdn": ["cdn/src/index"], - "@fosscord/util": ["util/src/index"], - "@fosscord/webrtc": ["webrtc/src/index"] - }, - "plugins": [{ "transform": "@zerollup/ts-transform-paths" }], - "noEmitHelpers": true, - "importHelpers": true - } -} diff --git a/bundle/tsnode.tsconfig.json b/bundle/tsnode.tsconfig.json deleted file mode 100644 index 422d336c..00000000 --- a/bundle/tsnode.tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "ts-node": { - "transpileOnly": true, - "preferTsExts": true, - "require": ["tsconfig-paths/register"], - "compiler": "typescript-cached-transpile", - }, - "compilerOptions": { - "rootDir": "../", - "baseUrl": "../", - "sourceRoot": "../", - "sourceMap": true, - } -} \ No newline at end of file diff --git a/cdn/.env.example b/cdn/.env.example deleted file mode 100644 index b5e011f1..00000000 --- a/cdn/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -STORAGE_LOCATION=files/ -STORAGE_PROVIDER=file -PORT=3003 \ No newline at end of file diff --git a/cdn/.gitignore b/cdn/.gitignore deleted file mode 100644 index 14dd53b5..00000000 --- a/cdn/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.vscode/ -node_modules/ -.DS_Store -.env -dist/ -files/ -coverage/ \ No newline at end of file diff --git a/cdn/.swcrc b/cdn/.swcrc deleted file mode 100644 index ab531194..00000000 --- a/cdn/.swcrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "module": { - "type": "commonjs" - }, - "jsc": { - "parser": { - "syntax": "typescript", - "decorators": true - }, - "target": "es2021", - "baseUrl": ".", - "paths": { - "@fosscord/cdn/": ["src/index"], - "@fosscord/cdn/*": ["src/*"] - } - } -} diff --git a/cdn/Dockerfile b/cdn/Dockerfile deleted file mode 100644 index d9ad78f4..00000000 --- a/cdn/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM node:lts-alpine -WORKDIR /usr/src/fosscord-cdn -COPY package.json . -RUN npm install -COPY . . -EXPOSE 3003 -CMD ["node", "dist/"] \ No newline at end of file diff --git a/cdn/README.md b/cdn/README.md deleted file mode 100644 index 7d8e99b0..00000000 --- a/cdn/README.md +++ /dev/null @@ -1,112 +0,0 @@ -# Fosscord-CDN - -CDN for Fosscord - -## Run localy: - -``` -npm i -node dist/ -``` - -## Endpoints: - -### POST `/attachments/` - -``` -Content-Type: form-data - -attachment: File (binary-data) -``` - -##### Returns: - -``` -{ - "success": boolean, // true - "message": string, // "attachment uploaded" - "id": snowflake, // "794183329158135808" - "filename": string // "lakdoiauej.png" -} -``` - -### GET `/attachments//` - -``` -requests image from database with given and -``` - -##### Returns: - -``` -Content-Type: image/ -Image -``` - -### DELETE `/attachments//` - -``` -deletes database entry -``` - -##### Returns: - -``` -Content-Type: application/json - -{ - "success": true, - "message": "attachment deleted" -} -``` - -
- -_(endpoints for crawler):_ - -### POST `/external` - -``` -requests crawling of `og:`metadata and the download of the `og:image` property --------- -Content-Type: application/json - -body: -{"url": URL} // "https://discord.com" -``` - -##### Returns: - -``` -Content-Type: application/json - -{ - "id": string, // "aHR0cHM6Ly9kaXNjb3JkLmNvbQ==" - "ogTitle": string, // "Discord | Your Place to Talk and Hang Out" - "ogDescription": string, // "Discord is the easiest way to talk over voice, video, and text. Talk, chat, hang out, and stay close with your friends and communities." - "cachedImage": string, // "/external/aHR0cHM6Ly9kaXNjb3JkLmNvbQ==/discord.png" - "ogUrl": string, // "https://discord.com/" - "ogType": string // "website" -} -``` - -### GET `/external//` - -- requests cached crawled image - -``` -url-params: - :id // aHR0cHM6Ly9kaXNjb3JkLmNvbQ== - :filename // discord.png -``` - -``` -/external/aHR0cHM6Ly9kaXNjb3JkLmNvbQ==/discord.png -``` - -##### Returns: - -``` -Content-Type: image/ -Image -``` diff --git a/cdn/jest/setup.js b/cdn/jest/setup.js deleted file mode 100644 index abc485ae..00000000 --- a/cdn/jest/setup.js +++ /dev/null @@ -1,2 +0,0 @@ -jest.spyOn(global.console, "log").mockImplementation(() => jest.fn()); -jest.spyOn(global.console, "info").mockImplementation(() => jest.fn()); diff --git a/cdn/package-lock.json b/cdn/package-lock.json deleted file mode 100644 index 62c2cdc8..00000000 Binary files a/cdn/package-lock.json and /dev/null differ diff --git a/cdn/package.json b/cdn/package.json deleted file mode 100644 index 85e05708..00000000 --- a/cdn/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "@fosscord/cdn", - "version": "1.0.0", - "description": "cdn for fosscord", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "test": "npm run build && npx jest --coverage ./tests", - "build": "npx tsc -p .", - "start": "node dist/start.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/fosscord/fosscord-server.git" - }, - "keywords": [], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/fosscord/fosscord-server/issues" - }, - "homepage": "https://github.com/fosscord/fosscord-server#readme", - "devDependencies": { - "@types/amqplib": "^0.8.1", - "@types/body-parser": "^1.19.0", - "@types/btoa": "^1.2.3", - "@types/dotenv": "^8.2.0", - "@types/express": "^4.17.12", - "@types/fs-extra": "^9.0.12", - "@types/jsonwebtoken": "^8.5.0", - "@types/multer": "^1.4.7", - "@types/node": "^14.17.0", - "@types/node-fetch": "^2.5.7", - "@types/sharp": "^0.30.4", - "@zerollup/ts-transform-paths": "^1.7.18", - "ts-patch": "^1.4.4" - }, - "dependencies": { - "@aws-sdk/client-s3": "^3.36.1", - "@aws-sdk/node-http-handler": "^3.36.0", - "@fosscord/util": "file:../util", - "body-parser": "^1.19.0", - "btoa": "^1.2.1", - "dotenv": "^10.0.0", - "exif-be-gone": "^1.2.0", - "express": "^4.17.1", - "express-async-errors": "^3.1.1", - "file-type": "^16.5.4", - "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "image-size": "^1.0.0", - "jest": "^27.0.6", - "lambert-db": "^1.2.3", - "lambert-server": "^1.2.12", - "missing-native-js-functions": "^1.2.17", - "multer": "^1.4.2", - "nanocolors": "^0.2.12", - "node-fetch": "^2.6.2", - "sharp": "^0.30.7", - "supertest": "^6.1.6", - "typescript": "^4.1.2" - }, - "jest": { - "setupFilesAfterEnv": [ - "/jest/setup.js" - ], - "verbose": true - } -} diff --git a/cdn/tests/antman.jpg b/cdn/tests/antman.jpg deleted file mode 100644 index 56af9063..00000000 Binary files a/cdn/tests/antman.jpg and /dev/null differ diff --git a/cdn/tests/cdn_endpoints.test.js b/cdn/tests/cdn_endpoints.test.js deleted file mode 100644 index 5a543e54..00000000 --- a/cdn/tests/cdn_endpoints.test.js +++ /dev/null @@ -1,238 +0,0 @@ -const dotenv = require("dotenv"); -const path = require("path"); -const fs = require("fs"); -dotenv.config(); - -// TODO: write unittest to check if FileStorage.ts is working -// TODO: write unitest to check if env vars are defined - -if (!process.env.STORAGE_PROVIDER) process.env.STORAGE_PROVIDER = "file"; -// TODO:nodejs path.join trailing slash windows compatible -if (process.env.STORAGE_PROVIDER === "file") { - if (process.env.STORAGE_LOCATION) { - if (!process.env.STORAGE_LOCATION.startsWith("/")) { - process.env.STORAGE_LOCATION = path.join( - __dirname, - "..", - process.env.STORAGE_LOCATION, - "/" - ); - } - } else { - process.env.STORAGE_LOCATION = path.join(__dirname, "..", "files", "/"); - } - if(!fs.existsSync(process.env.STORAGE_LOCATION)) fs.mkdirSync(process.env.STORAGE_LOCATION, {recursive:true}); -} -const { CDNServer } = require("../dist/Server"); -const { Config } = require("@fosscord/util"); -const supertest = require("supertest"); -const request = supertest("http://localhost:3003"); -const server = new CDNServer({ port: Number(process.env.PORT) || 3003 }); - -beforeAll(async () => { - await server.start(); - return server; -}); - -afterAll(() => { - return server.stop(); -}); - -describe("/ping", () => { - describe("GET", () => { - describe("without signature specified", () => { - test("route should respond with 200", async () => { - let response = await request.get("/ping"); - expect(response.text).toBe("pong"); - }); - }); - }); -}); - -describe("/attachments", () => { - describe("POST", () => { - describe("without signature specified", () => { - test("route should respond with 400", async () => { - const response = await request.post("/attachments/123456789"); - expect(response.statusCode).toBe(400); - }); - }); - describe("with signature specified, without file specified", () => { - test("route should respond with 400", async () => { - const response = await request - .post("/attachments/123456789") - .set({ signature: Config.get().security.requestSignature }); - expect(response.statusCode).toBe(400); - }); - }); - describe("with signature specified, with file specified ", () => { - test("route should respond with Content-type: application/json, 200 and res.body.url", async () => { - const response = await request - .post("/attachments/123456789") - .set({ signature: Config.get().security.requestSignature }) - .attach("file", __dirname + "/antman.jpg"); - expect(response.statusCode).toBe(200); - expect(response.headers["content-type"]).toEqual( - expect.stringContaining("json") - ); - expect(response.body.url).toBeDefined(); - }); - }); - }); - describe("GET", () => { - describe("getting uploaded image by url returned by POST /attachments", () => { - test("route should respond with 200", async () => { - let response = await request - .post("/attachments/123456789") - .set({ signature: Config.get().security.requestSignature }) - .attach("file", __dirname + "/antman.jpg"); - request - .get(response.body.url.replace("http://localhost:3003", "")) - .then((x) => { - expect(x.statusCode).toBe(200); - }); - }); - }); - }); - describe("DELETE", () => { - describe("deleting uploaded image by url returned by POST /attachments", () => { - test("route should respond with res.body.success", async () => { - let response = await request - .post("/attachments/123456789") - .set({ signature: Config.get().security.requestSignature }) - .attach("file", __dirname + "/antman.jpg"); - request - .delete( - response.body.url.replace("http://localhost:3003", "") - ) - .then((x) => { - expect(x.body.success).toBeDefined(); - }); - }); - }); - }); -}); - -describe("/avatars", () => { - describe("POST", () => { - describe("without signature specified", () => { - test("route should respond with 400", async () => { - const response = await request.post("/avatars/123456789"); - expect(response.statusCode).toBe(400); - }); - }); - describe("with signature specified, without file specified", () => { - test("route should respond with 400", async () => { - const response = await request - .post("/avatars/123456789") - .set({ signature: Config.get().security.requestSignature }); - expect(response.statusCode).toBe(400); - }); - }); - describe("with signature specified, with file specified ", () => { - test("route should respond with Content-type: application/json, 200 and res.body.url", async () => { - const response = await request - .post("/avatars/123456789") - .set({ signature: Config.get().security.requestSignature }) - .attach("file", __dirname + "/antman.jpg"); - expect(response.statusCode).toBe(200); - expect(response.headers["content-type"]).toEqual( - expect.stringContaining("json") - ); - expect(response.body.url).toBeDefined(); - }); - }); - }); - describe("GET", () => { - describe("getting uploaded image by url returned by POST /avatars", () => { - test("route should respond with 200", async () => { - let response = await request - .post("/avatars/123456789") - .set({ signature: Config.get().security.requestSignature }) - .attach("file", __dirname + "/antman.jpg"); - request - .get(response.body.url.replace("http://localhost:3003", "")) - .then((x) => { - expect(x.statusCode).toBe(200); - }); - }); - }); - }); - describe("DELETE", () => { - describe("deleting uploaded image by url returned by POST /avatars", () => { - test("route should respond with res.body.success", async () => { - let response = await request - .post("/avatars/123456789") - .set({ signature: Config.get().security.requestSignature }) - .attach("file", __dirname + "/antman.jpg"); - request - .delete( - response.body.url.replace("http://localhost:3003", "") - ) - .then((x) => { - expect(x.body.success).toBeDefined(); - }); - }); - }); - }); -}); - -describe("/external", () => { - describe("POST", () => { - describe("without signature specified", () => { - test("route should respond with 400", async () => { - const response = await request.post("/external"); - expect(response.statusCode).toBe(400); - }); - }); - describe("with signature specified, without file specified", () => { - test("route should respond with 400", async () => { - const response = await request - .post("/external") - .set({ signature: Config.get().security.requestSignature }); - expect(response.statusCode).toBe(400); - }); - }); - describe("with signature specified, with file specified ", () => { - test("route should respond with Content-type: application/json, 200 and res.body.url", async () => { - const response = await request - .post("/external") - .set({ signature: Config.get().security.requestSignature }) - .send({ - url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp", - }); - expect(response.statusCode).toBe(200); - expect(response.headers["content-type"]).toEqual( - expect.stringContaining("json") - ); - expect(response.body.id).toBeDefined(); - }); - }); - describe("with signature specified, with falsy url specified ", () => { - test("route should respond with 400", async () => { - const response = await request - .post("/external") - .set({ signature: Config.get().security.requestSignature }) - .send({ - url: "notavalidurl.123", - }); - expect(response.statusCode).toBe(400); - }); - }); - }); - describe("GET", () => { - describe("getting uploaded image by url returned by POST /avatars", () => { - test("route should respond with 200", async () => { - let response = await request - .post("/external") - .set({ signature: Config.get().security.requestSignature }) - .send({ - url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp", - }); - request.get(`external/${response.body.id}`).then((x) => { - expect(x.statusCode).toBe(200); - }); - }); - }); - }); -}); diff --git a/cdn/tests/filestorage.test.js b/cdn/tests/filestorage.test.js deleted file mode 100644 index 78036602..00000000 --- a/cdn/tests/filestorage.test.js +++ /dev/null @@ -1,27 +0,0 @@ -const path = require("path"); -process.env.STORAGE_LOCATION = path.join(__dirname, "..", "files", "/"); - -const { FileStorage } = require("../dist/util/FileStorage"); -const storage = new FileStorage(); -const fs = require("fs"); - -const file = fs.readFileSync(path.join(__dirname, "antman.jpg")); - -describe("FileStorage", () => { - describe("saving a file", () => { - test("saving a buffer", async () => { - await storage.set("test_saving_file", file); - }); - }); - describe("getting a file", () => { - test("getting buffer with given name", async () => { - const buffer2 = await storage.get("test_saving_file"); - expect(Buffer.compare(file, buffer2)).toBeTruthy(); - }); - }); - describe("deleting a file", () => { - test("deleting buffer with given name", async () => { - await storage.delete("test_saving_file"); - }); - }); -}); diff --git a/cdn/tsconfig.json b/cdn/tsconfig.json deleted file mode 100644 index 64ab18f4..00000000 --- a/cdn/tsconfig.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - "incremental": true /* Enable incremental compilation */, - "target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ES2015", - "dom" - ] /* Specify library files to be included in the compilation. */, - "allowJs": true /* Allow javascript files to be compiled. */, - "checkJs": true /* Report errors in .js files. */, - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true /* Generates corresponding '.d.ts' file. */, - "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */, - "inlineSourceMap": true /* Emit a single file with source maps instead of having a separate file. */, - // "sourceMap": true /* Generates corresponding '.map' file. */, - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": [ - "node" - ] /* Type declaration files to be included in compilation. */, - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "baseUrl": ".", - "paths": { - "@fosscord/cdn": ["src/index"], - "@fosscord/cdn/*": ["src/*"] - }, - "plugins": [{ "transform": "@zerollup/ts-transform-paths" }] - } -} diff --git a/crowdin.yml b/crowdin.yml index a6330566..a72a2eb7 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,3 @@ files: - - source: /api/locales/en/*.json - translation: /api/locales/%two_letters_code%/%original_file_name% + - source: /assets/locales/en/*.json + translation: /assets/locales/%two_letters_code%/%original_file_name% diff --git a/dashboard/README.md b/dashboard/README.md deleted file mode 100644 index df1157a1..00000000 --- a/dashboard/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# 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)) - -port = 3005 diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json deleted file mode 100644 index 4d56041e..00000000 Binary files a/dashboard/package-lock.json and /dev/null differ diff --git a/dashboard/package.json b/dashboard/package.json deleted file mode 100644 index 87bc1699..00000000 --- a/dashboard/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@fosscord/dashboard", - "version": "1.0.0", - "description": "Dashboard for Fosscord", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "test": "npm run build && npx jest --coverage ./tests", - "build": "npx tsc -p .", - "start": "node dist/start.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/fosscord/fosscord-server.git" - }, - "keywords": [], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/fosscord/fosscord-server/issues" - }, - "homepage": "https://github.com/fosscord/fosscord-server#readme" -} diff --git a/dashboard/src/index.ts b/dashboard/src/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/docker-compose.cfg.yml b/docker-compose.cfg.yml deleted file mode 100644 index 18a7031d..00000000 --- a/docker-compose.cfg.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: '3.9' - -services: - - fosscord: - entrypoint: [ "npm", "run", "setup" ] diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 4dc1ee41..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,25 +0,0 @@ -version: '3.9' - -services: - - fosscord: - container_name: fosscord - image: fosscord - restart: on-failure:5 - build: . - ports: - - '3001-3005:3001-3005' - volumes: - - ./:/srv/fosscord-server/ - environment: - THREADS: ${THREADS:-1} - HTTP_PORT: 3001 - WS_PORT: 3002 - CDN_PORT: 3003 - RTC_PORT: 3004 - ADMIN_PORT: 3005 - -networks: - default: - name: fosscord - driver: bridge diff --git a/fosscord-server.code-workspace b/fosscord-server.code-workspace index c3542727..1740fb7d 100644 --- a/fosscord-server.code-workspace +++ b/fosscord-server.code-workspace @@ -1,31 +1,13 @@ { "folders": [ { - "path": "api" + "path": "src" }, { - "path": "dashboard" + "path": "assets" }, { - "path": "bundle" - }, - { - "path": "cdn" - }, - { - "path": "gateway" - }, - { - "path": "rtc" - }, - { - "path": "util" - }, - { - "path": "webrtc" - }, - { - "path": "slowcord" + "path": "." } ], "settings": { diff --git a/gateway/.env.example b/gateway/.env.example deleted file mode 100644 index 0224de64..00000000 --- a/gateway/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -MONGO_URL=mongodb://localhost/fosscord -PORT=3002 -PRODUCTION=TRUE -THREADS=# automatically use all available cores, only available if production = true \ No newline at end of file diff --git a/gateway/.gitignore b/gateway/.gitignore deleted file mode 100644 index daf8591a..00000000 --- a/gateway/.gitignore +++ /dev/null @@ -1,107 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port -.DS_Store - -data \ No newline at end of file diff --git a/gateway/.swcrc b/gateway/.swcrc deleted file mode 100644 index e8cbb8a1..00000000 --- a/gateway/.swcrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": { - "type": "commonjs" - }, - "jsc": { - "parser": { - "syntax": "typescript", - "decorators": true - }, - "target": "es5", - "baseUrl": ".", - "paths": { - "@fosscord/gateway": ["src/index"] - } - } -} diff --git a/gateway/.vscode/launch.json b/gateway/.vscode/launch.json deleted file mode 100644 index 29bdde13..00000000 --- a/gateway/.vscode/launch.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "sourceMaps": true, - "type": "node", - "request": "launch", - "name": "Launch Server", - "program": "${workspaceFolder}/dist/start.js", - "preLaunchTask": "tsc: build - tsconfig.json", - "outFiles": ["${workspaceFolder}/dist/**/*.js"] - } - ] -} diff --git a/gateway/Dockerfile b/gateway/Dockerfile deleted file mode 100644 index e07b7d8f..00000000 --- a/gateway/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM node:lts-alpine -WORKDIR /usr/src/fosscord-gateway -COPY package.json . -COPY package-lock.json . -RUN apk --no-cache --virtual build-dependencies add \ - python \ - make \ - g++ -RUN npm install -RUN apk del build-dependencies -COPY . . -RUN npm run build -EXPOSE 3002 -CMD ["node", "dist/start.js"] diff --git a/gateway/README.md b/gateway/README.md deleted file mode 100644 index 9ae6a5f1..00000000 --- a/gateway/README.md +++ /dev/null @@ -1,42 +0,0 @@ -

- -

-

Fosscord WebSocket Gateway Server

- -

- - - - -

- -## [About](https://github.com/fosscord/fosscord-gateway/wiki) - -Fosscord is **f**ree **o**pen **s**ource **s**oftware compatible to dis**cord**. It is a selfhostable Chat, Voice and Video platform similar to Slack, Rocket.chat and Discord-compatible. - -- Discord-compatible -- Selfhostable -- Open Source -- Configurable -- Secure -- Decentralized -- Extendable -- Themeable - -logo by [@nwlandas](https://twitter.com/nwlandas) - -## Installation - -_it is in development and not yet finished_ - -## Support - -https://discord.gg/ZrnGQP6p3d - -if we are finished we'll host our own support server. - -## Contribute - -This project is only possible by volunteers like you and me, your contribution is very much appreciated 🥺. - -If you want to make this project reality and and you would like to contribute then [read the wiki](https://github.com/fosscord/fosscord-gateway/wiki) first. diff --git a/gateway/package-lock.json b/gateway/package-lock.json deleted file mode 100644 index e39901de..00000000 Binary files a/gateway/package-lock.json and /dev/null differ diff --git a/gateway/package.json b/gateway/package.json deleted file mode 100644 index ad500897..00000000 --- a/gateway/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@fosscord/gateway", - "version": "1.0.0", - "description": "", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "postinstall": "npx ts-patch install -s", - "test": "echo \"Error: no test specified\" && exit 1", - "start": "npm run build && node dist/start.js", - "build": "npx tsc -p .", - "dev": "npx tsnd --respawn src/start.ts" - }, - "keywords": [], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "devDependencies": { - "@types/amqplib": "^0.8.1", - "@types/json-bigint": "^1.0.1", - "@types/jsonwebtoken": "^8.5.0", - "@types/node": "^14.18.24", - "@types/node-fetch": "^2.5.12", - "@types/ws": "^7.4.0", - "@zerollup/ts-transform-paths": "^1.7.18", - "ts-node-dev": "^1.1.6", - "ts-patch": "^1.4.4", - "typescript": "^4.2.3" - }, - "dependencies": { - "@fosscord/util": "file:../util", - "amqplib": "^0.8.0", - "dotenv": "^8.2.0", - "fast-zlib": "^2.0.1", - "json-bigint": "^1.0.0", - "jsonwebtoken": "^8.5.1", - "lambert-server": "^1.2.11", - "missing-native-js-functions": "^1.2.18", - "node-fetch": "^2.6.2", - "proxy-agent": "^5.0.0", - "typeorm": "^0.2.37", - "ws": "^7.4.2" - }, - "optionalDependencies": { - "@yukikaze-bot/erlpack": "^1.0.1" - } -} diff --git a/gateway/tsconfig.json b/gateway/tsconfig.json deleted file mode 100644 index e1508f89..00000000 --- a/gateway/tsconfig.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "exclude": ["*.js", "dist", "attachments"], - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - "incremental": true /* Enable incremental compilation */, - "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ES2015", - "ES2020.BigInt", - "DOM" - ] /* Specify library files to be included in the compilation. */, - "allowJs": true /* Allow javascript files to be compiled. */, - "checkJs": true /* Report errors in .js files. */, - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true /* Generates corresponding '.d.ts' file. */, - "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */, - // "sourceMap": true /* Generates corresponding '.map' file. */, - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* Enable strict null checks. */, - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": [ - "node" - ] /* Type declaration files to be included in compilation. */, - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - "inlineSourceMap": true /* Emit a single file with source maps instead of having a separate file. */, - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "resolveJsonModule": true, - "baseUrl": ".", - "paths": { - "@fosscord/gateway": ["src/index.ts"], - "@fosscord/util": ["../util/src/index"] - // "@fosscord/webrtc": ["../webrtc/src/index"] - }, - "plugins": [{ "transform": "@zerollup/ts-transform-paths" }] - } -} diff --git a/nginx.conf b/nginx.conf deleted file mode 100644 index a810567d..00000000 --- a/nginx.conf +++ /dev/null @@ -1,20 +0,0 @@ -# This is an example -server { - server_name fosscord.example.com; - listen 80; - location / { - proxy_pass http://127.0.0.1:3001; - proxy_set_header Host $host; - proxy_pass_request_headers on; - add_header Last-Modified $date_gmt; - add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-Proto https; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Host $remote_addr; - proxy_no_cache 1; - proxy_cache_bypass 1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ad152edd..7f0226b4 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 8488ff28..ee6a3c6b 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,12 @@ "name": "fosscord-server", "version": "1.0.0", "description": "A Fosscord server written in Node.js", - "workspaces": ["api", "cdn", "gateway"], - "scripts": {}, + "scripts": { + "start": "node dist/bundle/start.js", + "build": "tsc -p ." + }, + "main": "dist/bundle/start.js", + "types": "src/bundle/index.js", "repository": { "type": "git", "url": "git+https://github.com/fosscord/fosscord-server.git" @@ -13,5 +17,68 @@ "bugs": { "url": "https://github.com/fosscord/fosscord-server/issues" }, - "homepage": "https://fosscord.com" + "imports": { + "#*": "./dist/*/index.js" + }, + "homepage": "https://fosscord.com", + "devDependencies": { + "@types/amqplib": "^0.8.2", + "@types/bcrypt": "^5.0.0", + "@types/cookie-parser": "^1.4.3", + "@types/i18next-node-fs-backend": "^2.1.1", + "@types/json-bigint": "^1.0.1", + "@types/jsonwebtoken": "^8.5.9", + "@types/morgan": "^1.9.3", + "@types/multer": "^1.4.7", + "@types/node": "^18.7.20", + "@types/node-fetch": "^2.6.2", + "@types/node-os-utils": "^1.3.0", + "@types/sharp": "^0.31.0", + "@types/ws": "^8.5.3", + "express": "^4.18.1", + "typescript": "^4.8.3" + }, + "dependencies": { + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "bcrypt": "^5.0.1", + "cheerio": "^1.0.0-rc.12", + "cookie-parser": "^1.4.6", + "dotenv": "^16.0.2", + "exif-be-gone": "^1.3.1", + "fast-zlib": "^2.0.1", + "file-type": "16.5", + "form-data": "^4.0.0", + "i18next": "^21.9.2", + "i18next-http-middleware": "^3.2.1", + "i18next-node-fs-backend": "^2.1.3", + "image-size": "^1.0.2", + "json-bigint": "^1.0.0", + "jsonwebtoken": "^8.5.1", + "lambert-server": "^1.2.12", + "module-alias": "^2.2.2", + "morgan": "^1.10.0", + "multer": "^1.4.5-lts.1", + "node-2fa": "^2.0.3", + "node-fetch": "^2.6.7", + "node-os-utils": "^1.3.7", + "picocolors": "^1.0.0", + "proxy-agent": "^5.0.0", + "sharp": "^0.31.0", + "sqlite3": "^5.1.1", + "typeorm": "^0.3.10", + "ws": "^8.9.0" + }, + "optionalDependencies": { + "@aws-sdk/client-s3": "^3.178.0", + "@sentry/node": "^7.13.0", + "@sentry/tracing": "^7.13.0", + "amqplib": "^0.10.3" + }, + "_moduleAliases": { + "@fosscord/api": "dist/api", + "@fosscord/cdn": "dist/cdn", + "@fosscord/gateway": "dist/gateway", + "@fosscord/util": "dist/util" + } } diff --git a/api/patches/ajv+8.6.2.patch b/patches/ajv+8.6.2.patch similarity index 100% rename from api/patches/ajv+8.6.2.patch rename to patches/ajv+8.6.2.patch diff --git a/api/patches/typescript-json-schema+0.50.1.patch b/patches/typescript-json-schema+0.50.1.patch similarity index 100% rename from api/patches/typescript-json-schema+0.50.1.patch rename to patches/typescript-json-schema+0.50.1.patch diff --git a/rtc/.gitignore b/rtc/.gitignore deleted file mode 100644 index f14b4548..00000000 --- a/rtc/.gitignore +++ /dev/null @@ -1,145 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port -.DS_Store - -# Compiled TypeScript code -dist/ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.o - -# Protobuffer builds -*.pb.cc -*.pb.h - -# Directories -build/ -.vscode/ diff --git a/rtc/.npmignore b/rtc/.npmignore deleted file mode 100644 index 05a9d0cf..00000000 --- a/rtc/.npmignore +++ /dev/null @@ -1 +0,0 @@ -!dist/ \ No newline at end of file diff --git a/rtc/.prettierrc b/rtc/.prettierrc deleted file mode 100644 index d569c548..00000000 --- a/rtc/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "tabWidth": 4, - "useTabs": true, - "printWidth": 120 -} diff --git a/rtc/CMakeLists.txt b/rtc/CMakeLists.txt deleted file mode 100644 index 2cf5c0a6..00000000 --- a/rtc/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(fosscord-media) - -set(CMAKE_CXX_STANDARD 17) - -find_package(Threads REQUIRED) - -find_package(mongocxx REQUIRED) -find_package(Boost REQUIRED) - - -file(GLOB SourceFiles ${PROJECT_SOURCE_DIR}/src/*.cpp) -#include_directories("bsoncxx/v_noabi/bsoncxx/") -add_executable(${CMAKE_PROJECT_NAME} ${SourceFiles}) - -target_link_libraries(${CMAKE_PROJECT_NAME} datachannel mongo::mongocxx_shared Boost::boost) \ No newline at end of file diff --git a/rtc/README.md b/rtc/README.md deleted file mode 100644 index ee452adf..00000000 --- a/rtc/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Fosscord-media - -A Fosscord media (voice and video) server - -## Installation - -### Prerequisites - -- Install the [libdatachannel](https://github.com/paullouisageneau/libdatachannel) library -- Install the [libmongocxx](http://mongocxx.org/mongocxx-v3/installation/) driver and its requirements - -### Building - -```bash -$ cmake -$ cd build -$ make -``` diff --git a/rtc/config.json b/rtc/config.json deleted file mode 100644 index 0967ef42..00000000 --- a/rtc/config.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/rtc/src/main.cpp b/rtc/src/main.cpp deleted file mode 100644 index 372eaa00..00000000 --- a/rtc/src/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// $$$$$$\ $$\ -// $$ __$$\ $$ | -// $$ / \__|$$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$$ | -// $$$$\ $$ __$$\ $$ _____|$$ _____|$$ _____|$$ __$$\ $$ __$$\ $$ __$$ | -// $$ _| $$ / $$ |\$$$$$$\ \$$$$$$\ $$ / $$ / $$ |$$ | \__|$$ / $$ | -// $$ | $$ | $$ | \____$$\ \____$$\ $$ | $$ | $$ |$$ | $$ | $$ | -// $$ | \$$$$$$ |$$$$$$$ |$$$$$$$ |\$$$$$$$\ \$$$$$$ |$$ | \$$$$$$$ | -// \__| \______/ \_______/ \_______/ \_______| \______/ \__| \_______| -// -// -// -// $$\ $$$$$$\ -// \__| $$ __$$\ -// $$\ $$\ $$$$$$\ $$\ $$$$$$$\ $$$$$$\ $$ / \__| $$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\ -// \$$\ $$ |$$ __$$\ $$ |$$ _____|$$ __$$\ \$$$$$$\ $$ __$$\ $$ __$$\\$$\ $$ |$$ __$$\ $$ __$$\ -// \$$\$$ / $$ / $$ |$$ |$$ / $$$$$$$$ | \____$$\ $$$$$$$$ |$$ | \__|\$$\$$ / $$$$$$$$ |$$ | \__| -// \$$$ / $$ | $$ |$$ |$$ | $$ ____|$$\ $$ |$$ ____|$$ | \$$$ / $$ ____|$$ | -// \$ / \$$$$$$ |$$ |\$$$$$$$\ \$$$$$$$\ \$$$$$$ |\$$$$$$$\ $$ | \$ / \$$$$$$$\ $$ | -// \_/ \______/ \__| \_______| \_______| \______/ \_______|\__| \_/ \_______|\__| -// -// -// - -#include "rtcPeerHandler.hpp" //Handle peer connection requests -#include "mongoStub.hpp" //Handle communication with the MongoDB server - -int main(int argc, char **argv){ - - auto commsHandler = std::make_shared(); - auto mongoHandler = std::make_unique(); - - mongocxx::options::change_stream options; - //voiceEvents collection watcher - mongocxx::change_stream colCs = mongoHandler->getCol().watch(options); - - std::cout << "Server created and listening for events" << std::endl; - - //Check for new messages in the collection - for (;;){ - std::vector t = mongoHandler->getNewMessages(&colCs); - for(auto &i : t){ - std::cout << "[" << i.eventName << "] " << std::endl; - } - } - - return 0; -} \ No newline at end of file diff --git a/rtc/src/mongoStub.cpp b/rtc/src/mongoStub.cpp deleted file mode 100644 index ccd2abda..00000000 --- a/rtc/src/mongoStub.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "mongoStub.hpp" - -mongoStub::mongoStub() { - if (this->client) { - this->db = client["fosscord"]; - - if (this->db) { - this->col = db["events"]; - - } else { - std::cout << "db not found"; - exit(-1); - } - } else { - std::cout << "Client couldn't be initialized"; - exit(-1); - } -} - -// Too slow for my liking -std::vector mongoStub::getNewMessages( - mongocxx::change_stream* colCs) { - std::vector retVec; - - for (auto&& event : *colCs) { - mongoStub::mongoMessage returnValue; - - std::cout << bsoncxx::to_json(event) << std::endl; - - // Only listen to insert events (to avoid "precondition failed: data" - // exception) - if (event["operationType"].get_utf8().value.to_string() != "insert") { - continue; - } - - std::string evName = event["fullDocument"]["event"].get_utf8().value.to_string(); - - if(evName.substr(0, 7)=="VSERVER"){ continue; } //Ignore the event if it's been emited by a voice server - - if (evName == "UDP_CONNECTION") { - handleUdpRequest( - event["fullDocument"]["data"]["d"]["address"].get_utf8().value.to_string(), - event["fullDocument"]["data"]["d"]["port"].get_int32().value, - event["fullDocument"]["data"]["d"]["mode"].get_utf8().value.to_string() - ); - - } else if (evName == "VOICE_REQUEST") { - //TODO - continue; - } - - returnValue.eventName = evName; - retVec.push_back(returnValue); - } - - return retVec; -} - - -void mongoStub::handleUdpRequest(std::string address, int port, std::string mode) { - using bsoncxx::builder::basic::kvp; - using bsoncxx::builder::basic::sub_array; - using bsoncxx::builder::basic::sub_document; - - auto builder = bsoncxx::builder::basic::document{}; - - //Handle UDP socket stuff (later tho) - - builder.append(kvp("event", "VSERVER_UDP_RESPONSE")); - builder.append(kvp("op", "4")); - builder.append(kvp("d", [](sub_document subdoc) { - subdoc.append(kvp("mode", "CRYPT_MODE")), - subdoc.append(kvp("secret_key", [](sub_array subarr) { - subarr.append(1, 2, 3, 5); // HOW DO I GEN A SKEY? - })); - })); - - - bsoncxx::stdx::optional r= col.insert_one(builder.view()); -} - -void mongoStub::handleVoiceRequest() { - //Is this really needed? idk -} \ No newline at end of file diff --git a/rtc/src/mongoStub.hpp b/rtc/src/mongoStub.hpp deleted file mode 100644 index 2809142f..00000000 --- a/rtc/src/mongoStub.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef MONGOSTUB_HPP -#define MONGOSTUB_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -class mongoStub{ - public: - mongoStub(); - - struct mongoMessage{ - std::string eventName; - std::vector data; - }; - - std::vector getNewMessages(mongocxx::change_stream* colCs); - - mongocxx::collection getCol() const { return col; } - - - - private: - mongocxx::instance instance; - mongocxx::client client{mongocxx::uri{}}; - mongocxx::database db; - mongocxx::collection col; - mongocxx::change_stream* colCs = nullptr; - - void handleUdpRequest(std::string address, int port, std::string mode); - void handleVoiceRequest(); -}; - -#endif diff --git a/rtc/src/rtcPeerHandler.cpp b/rtc/src/rtcPeerHandler.cpp deleted file mode 100644 index 9bfc6466..00000000 --- a/rtc/src/rtcPeerHandler.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "rtcPeerHandler.hpp" - -rtcPeerHandler::rtcPeerHandler() { - rtc::InitLogger(rtc::LogLevel::Verbose, NULL); -} - -void rtcPeerHandler::initiateConnection(std::string peerIP, int peerPort) { - // Socket connection between client and server - SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); - sockaddr_in addr; - addr.sin_addr.s_addr = inet_addr(peerIP.c_str()); - addr.sin_port = htons(peerPort); - addr.sin_family = AF_INET; - - rtc::Configuration conf; - conf.enableIceTcp = false; - conf.disableAutoNegotiation = false; - - auto pc = std::make_shared(conf); - - rtc::Description::Audio media("audio", - rtc::Description::Direction::SendRecv); - media.addOpusCodec(96); - media.setBitrate(64); - - auto track = pc->addTrack(media); - - // auto session = std::make_shared(); - - // track->setMediaHandler(session); - - rtc::Reliability rtcRel; - rtcRel.unordered = true; - rtcRel.type = rtc::Reliability::Type::Timed; - rtcRel.rexmit = 500; - - rtc::DataChannelInit rtcConf; - rtcConf.reliability = rtcRel; - rtcConf.negotiated = false; - - pc->onStateChange([](rtc::PeerConnection::State state) { - std::cout << "State: " << state << std::endl; - if (state == rtc::PeerConnection::State::Disconnected || - state == rtc::PeerConnection::State::Failed || - state == rtc::PeerConnection::State::Closed) { - // remove disconnected client - } - }); - - pc->onGatheringStateChange([](rtc::PeerConnection::GatheringState state) { - std::cout << "Gathering State: " << state << std::endl; - }); - - /*std::tuple addAudio( - - const std::shared_ptr pc, - const uint8_t payloadType, const uint32_t ssrc, const std::string cname, - const std::string msid, const std::function onOpen) { - auto audio = Description::Audio(cname); - audio.addOpusCodec(payloadType); - audio.addSSRC(ssrc, cname, msid, cname); - auto track = pc->addTrack(audio); - // create RTP configuration - auto rtpConfig = make_shared( - ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate); - // create packetizer - auto packetizer = make_shared(rtpConfig); - // create opus handler - auto opusHandler = make_shared(packetizer); - - // add RTCP SR handler - auto srReporter = make_shared(rtpConfig); - opusHandler->addToChain(srReporter); - - // set handler - track->setMediaHandler(opusHandler); - track->onOpen(onOpen); - auto trackData = make_shared(track, srReporter); - return trackData; - }*/ - - pc->createDataChannel("Fosscord voice connection", rtcConf); -} diff --git a/rtc/src/rtcPeerHandler.hpp b/rtc/src/rtcPeerHandler.hpp deleted file mode 100644 index 3ba32a83..00000000 --- a/rtc/src/rtcPeerHandler.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "libdatachannel/rtc.hpp" -#include -#include -#include "nlohmann/json.hpp" -#include - -#ifdef _WIN32 -#include -#else -#include -typedef int SOCKET; -#endif - -using json = nlohmann::json; - -#ifndef RTCPEERHANDLER -#define RTCPEERHANDLER -class rtcPeerHandler{ -public: - rtcPeerHandler(); - void initiateConnection(std::string peerIP, int peerPort); - - struct client - { - std::shared_ptr pc; - std::shared_ptr dc; - }; - -private: - std::map clients; -}; -#endif \ No newline at end of file diff --git a/rtc/src/rtcServer.hpp b/rtc/src/rtcServer.hpp deleted file mode 100644 index e69de29b..00000000 diff --git a/bundle/scripts/benchmark/connections.js b/scripts/benchmark/connections.js similarity index 100% rename from bundle/scripts/benchmark/connections.js rename to scripts/benchmark/connections.js diff --git a/bundle/scripts/benchmark/index.js b/scripts/benchmark/index.js similarity index 100% rename from bundle/scripts/benchmark/index.js rename to scripts/benchmark/index.js diff --git a/bundle/scripts/benchmark/users.js b/scripts/benchmark/users.js similarity index 100% rename from bundle/scripts/benchmark/users.js rename to scripts/benchmark/users.js diff --git a/bundle/scripts/build.js b/scripts/build.js similarity index 100% rename from bundle/scripts/build.js rename to scripts/build.js diff --git a/api/scripts/droptables.sql b/scripts/droptables.sql similarity index 100% rename from api/scripts/droptables.sql rename to scripts/droptables.sql diff --git a/api/scripts/generate_openapi.js b/scripts/generate_openapi.js similarity index 100% rename from api/scripts/generate_openapi.js rename to scripts/generate_openapi.js diff --git a/api/scripts/generate_schema.js b/scripts/generate_schema.js similarity index 100% rename from api/scripts/generate_schema.js rename to scripts/generate_schema.js diff --git a/bundle/scripts/install.js b/scripts/install.js similarity index 100% rename from bundle/scripts/install.js rename to scripts/install.js diff --git a/util/scripts/migrate_db_engine.js b/scripts/migrate_db_engine.js similarity index 100% rename from util/scripts/migrate_db_engine.js rename to scripts/migrate_db_engine.js diff --git a/util/scripts/rights.js b/scripts/rights.js similarity index 100% rename from util/scripts/rights.js rename to scripts/rights.js diff --git a/api/scripts/stresstest/.gitignore b/scripts/stresstest/.gitignore similarity index 100% rename from api/scripts/stresstest/.gitignore rename to scripts/stresstest/.gitignore diff --git a/api/scripts/stresstest/accounts.json.example b/scripts/stresstest/accounts.json.example similarity index 100% rename from api/scripts/stresstest/accounts.json.example rename to scripts/stresstest/accounts.json.example diff --git a/api/scripts/stresstest/config.json.example b/scripts/stresstest/config.json.example similarity index 100% rename from api/scripts/stresstest/config.json.example rename to scripts/stresstest/config.json.example diff --git a/api/scripts/stresstest/index.js b/scripts/stresstest/index.js similarity index 100% rename from api/scripts/stresstest/index.js rename to scripts/stresstest/index.js diff --git a/api/scripts/stresstest/package-lock.json b/scripts/stresstest/package-lock.json similarity index 100% rename from api/scripts/stresstest/package-lock.json rename to scripts/stresstest/package-lock.json diff --git a/api/scripts/stresstest/package.json b/scripts/stresstest/package.json similarity index 100% rename from api/scripts/stresstest/package.json rename to scripts/stresstest/package.json diff --git a/api/scripts/stresstest/src/login/index.js b/scripts/stresstest/src/login/index.js similarity index 91% rename from api/scripts/stresstest/src/login/index.js rename to scripts/stresstest/src/login/index.js index bd9fea87..96603652 100644 --- a/api/scripts/stresstest/src/login/index.js +++ b/scripts/stresstest/src/login/index.js @@ -1,6 +1,6 @@ const fetch = require("node-fetch"); const fs = require("fs"); -var config = require("./../../config.json"); +var config = require("../../config.json"); module.exports = login; async function login(account) { var body = { diff --git a/api/scripts/stresstest/src/message/send.js b/scripts/stresstest/src/message/send.js similarity index 92% rename from api/scripts/stresstest/src/message/send.js rename to scripts/stresstest/src/message/send.js index 1f8af8aa..d21560d7 100644 --- a/api/scripts/stresstest/src/message/send.js +++ b/scripts/stresstest/src/message/send.js @@ -1,6 +1,6 @@ const fetch = require("node-fetch"); const fs = require("fs"); -var config = require("./../../config.json"); +var config = require("../../config.json"); module.exports = sendMessage; async function sendMessage(account) { var body = { diff --git a/api/scripts/stresstest/src/register/index.js b/scripts/stresstest/src/register/index.js similarity index 95% rename from api/scripts/stresstest/src/register/index.js rename to scripts/stresstest/src/register/index.js index bb6f839f..86f908cd 100644 --- a/api/scripts/stresstest/src/register/index.js +++ b/scripts/stresstest/src/register/index.js @@ -1,6 +1,6 @@ const fetch = require("node-fetch"); const fs = require("fs"); -var config = require("./../../config.json"); +var config = require("../../config.json"); module.exports = generate; async function generate() { var mail = (Math.random() + 10).toString(36).substring(2); diff --git a/slowcord/README.md b/src-slowcord/README.md similarity index 100% rename from slowcord/README.md rename to src-slowcord/README.md diff --git a/slowcord/bot/.vscode/launch.json b/src-slowcord/bot/.vscode/launch.json similarity index 100% rename from slowcord/bot/.vscode/launch.json rename to src-slowcord/bot/.vscode/launch.json diff --git a/slowcord/bot/.vscode/tasks.json b/src-slowcord/bot/.vscode/tasks.json similarity index 100% rename from slowcord/bot/.vscode/tasks.json rename to src-slowcord/bot/.vscode/tasks.json diff --git a/slowcord/bot/package-lock.json b/src-slowcord/bot/package-lock.json similarity index 100% rename from slowcord/bot/package-lock.json rename to src-slowcord/bot/package-lock.json diff --git a/slowcord/bot/package.json b/src-slowcord/bot/package.json similarity index 100% rename from slowcord/bot/package.json rename to src-slowcord/bot/package.json diff --git a/slowcord/bot/src/Bot.ts b/src-slowcord/bot/src/Bot.ts similarity index 100% rename from slowcord/bot/src/Bot.ts rename to src-slowcord/bot/src/Bot.ts diff --git a/slowcord/bot/src/commands/index.ts b/src-slowcord/bot/src/commands/index.ts similarity index 100% rename from slowcord/bot/src/commands/index.ts rename to src-slowcord/bot/src/commands/index.ts diff --git a/slowcord/bot/src/commands/instance.ts b/src-slowcord/bot/src/commands/instance.ts similarity index 100% rename from slowcord/bot/src/commands/instance.ts rename to src-slowcord/bot/src/commands/instance.ts diff --git a/slowcord/bot/src/index.ts b/src-slowcord/bot/src/index.ts similarity index 100% rename from slowcord/bot/src/index.ts rename to src-slowcord/bot/src/index.ts diff --git a/slowcord/bot/tsconfig.json b/src-slowcord/bot/tsconfig.json similarity index 100% rename from slowcord/bot/tsconfig.json rename to src-slowcord/bot/tsconfig.json diff --git a/slowcord/login/.env.template b/src-slowcord/login/.env.template similarity index 100% rename from slowcord/login/.env.template rename to src-slowcord/login/.env.template diff --git a/slowcord/login/package-lock.json b/src-slowcord/login/package-lock.json similarity index 100% rename from slowcord/login/package-lock.json rename to src-slowcord/login/package-lock.json diff --git a/slowcord/login/package.json b/src-slowcord/login/package.json similarity index 100% rename from slowcord/login/package.json rename to src-slowcord/login/package.json diff --git a/slowcord/login/public/css/index.css b/src-slowcord/login/public/css/index.css similarity index 100% rename from slowcord/login/public/css/index.css rename to src-slowcord/login/public/css/index.css diff --git a/slowcord/login/public/js/handler.js b/src-slowcord/login/public/js/handler.js similarity index 100% rename from slowcord/login/public/js/handler.js rename to src-slowcord/login/public/js/handler.js diff --git a/slowcord/login/public/login.html b/src-slowcord/login/public/login.html similarity index 100% rename from slowcord/login/public/login.html rename to src-slowcord/login/public/login.html diff --git a/slowcord/login/public/register.html b/src-slowcord/login/public/register.html similarity index 100% rename from slowcord/login/public/register.html rename to src-slowcord/login/public/register.html diff --git a/slowcord/login/src/index.ts b/src-slowcord/login/src/index.ts similarity index 100% rename from slowcord/login/src/index.ts rename to src-slowcord/login/src/index.ts diff --git a/slowcord/login/tsconfig.json b/src-slowcord/login/tsconfig.json similarity index 100% rename from slowcord/login/tsconfig.json rename to src-slowcord/login/tsconfig.json diff --git a/slowcord/nginx/fosscord b/src-slowcord/nginx/fosscord similarity index 100% rename from slowcord/nginx/fosscord rename to src-slowcord/nginx/fosscord diff --git a/slowcord/nginx/voice b/src-slowcord/nginx/voice similarity index 100% rename from slowcord/nginx/voice rename to src-slowcord/nginx/voice diff --git a/slowcord/rules.md b/src-slowcord/rules.md similarity index 100% rename from slowcord/rules.md rename to src-slowcord/rules.md diff --git a/slowcord/status/.env.template b/src-slowcord/status/.env.template similarity index 100% rename from slowcord/status/.env.template rename to src-slowcord/status/.env.template diff --git a/slowcord/status/package-lock.json b/src-slowcord/status/package-lock.json similarity index 100% rename from slowcord/status/package-lock.json rename to src-slowcord/status/package-lock.json diff --git a/slowcord/status/package.json b/src-slowcord/status/package.json similarity index 100% rename from slowcord/status/package.json rename to src-slowcord/status/package.json diff --git a/slowcord/status/src/gateway.ts b/src-slowcord/status/src/gateway.ts similarity index 100% rename from slowcord/status/src/gateway.ts rename to src-slowcord/status/src/gateway.ts diff --git a/slowcord/status/src/index.ts b/src-slowcord/status/src/index.ts similarity index 100% rename from slowcord/status/src/index.ts rename to src-slowcord/status/src/index.ts diff --git a/slowcord/status/tsconfig.json b/src-slowcord/status/tsconfig.json similarity index 100% rename from slowcord/status/tsconfig.json rename to src-slowcord/status/tsconfig.json diff --git a/api/src/Server.ts b/src/api/Server.ts similarity index 100% rename from api/src/Server.ts rename to src/api/Server.ts diff --git a/src/api/global.d.ts b/src/api/global.d.ts new file mode 100644 index 00000000..ed23cacb --- /dev/null +++ b/src/api/global.d.ts @@ -0,0 +1,8 @@ +// declare global { +// namespace Express { +// interface Request { +// user_id: any; +// token: any; +// } +// } +// } diff --git a/api/src/index.ts b/src/api/index.ts similarity index 100% rename from api/src/index.ts rename to src/api/index.ts diff --git a/api/src/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts similarity index 100% rename from api/src/middlewares/Authentication.ts rename to src/api/middlewares/Authentication.ts diff --git a/api/src/middlewares/BodyParser.ts b/src/api/middlewares/BodyParser.ts similarity index 100% rename from api/src/middlewares/BodyParser.ts rename to src/api/middlewares/BodyParser.ts diff --git a/api/src/middlewares/CORS.ts b/src/api/middlewares/CORS.ts similarity index 100% rename from api/src/middlewares/CORS.ts rename to src/api/middlewares/CORS.ts diff --git a/api/src/middlewares/ErrorHandler.ts b/src/api/middlewares/ErrorHandler.ts similarity index 100% rename from api/src/middlewares/ErrorHandler.ts rename to src/api/middlewares/ErrorHandler.ts diff --git a/api/src/middlewares/RateLimit.ts b/src/api/middlewares/RateLimit.ts similarity index 100% rename from api/src/middlewares/RateLimit.ts rename to src/api/middlewares/RateLimit.ts diff --git a/api/src/middlewares/Translation.ts b/src/api/middlewares/Translation.ts similarity index 92% rename from api/src/middlewares/Translation.ts rename to src/api/middlewares/Translation.ts index baabf221..741d6baf 100644 --- a/api/src/middlewares/Translation.ts +++ b/src/api/middlewares/Translation.ts @@ -6,8 +6,8 @@ import i18nextBackend from "i18next-node-fs-backend"; import { Router } from "express"; export async function initTranslation(router: Router) { - const languages = fs.readdirSync(path.join(__dirname, "..", "..", "locales")); - const namespaces = fs.readdirSync(path.join(__dirname, "..", "..", "locales", "en")); + const languages = fs.readdirSync(path.join(__dirname, "..", "..", "..", "assets", "locales")); + const namespaces = fs.readdirSync(path.join(__dirname, "..", "..", "..", "assets", "locales", "en")); const ns = namespaces.filter((x) => x.endsWith(".json")).map((x) => x.slice(0, x.length - 5)); await i18next diff --git a/api/src/middlewares/index.ts b/src/api/middlewares/index.ts similarity index 100% rename from api/src/middlewares/index.ts rename to src/api/middlewares/index.ts diff --git a/api/src/routes/-/healthz.ts b/src/api/routes/-/healthz.ts similarity index 52% rename from api/src/routes/-/healthz.ts rename to src/api/routes/-/healthz.ts index f7bcfebf..d9d1c026 100644 --- a/api/src/routes/-/healthz.ts +++ b/src/api/routes/-/healthz.ts @@ -1,17 +1,13 @@ import { Router, Response, Request } from "express"; import { route } from "@fosscord/api"; -import { getConnection } from "typeorm"; +import { getDatabase } from "@fosscord/util"; const router = Router(); router.get("/", route({}), (req: Request, res: Response) => { - try { - // test that the database is alive & responding - getConnection(); - return res.sendStatus(200); - } catch (e) { - res.sendStatus(503); - } + if (!getDatabase()) return res.sendStatus(503); + + return res.sendStatus(200); }); export default router; diff --git a/api/src/routes/-/monitorz.ts b/src/api/routes/-/monitorz.ts similarity index 100% rename from api/src/routes/-/monitorz.ts rename to src/api/routes/-/monitorz.ts diff --git a/api/src/routes/-/readyz.ts b/src/api/routes/-/readyz.ts similarity index 52% rename from api/src/routes/-/readyz.ts rename to src/api/routes/-/readyz.ts index f7bcfebf..d9d1c026 100644 --- a/api/src/routes/-/readyz.ts +++ b/src/api/routes/-/readyz.ts @@ -1,17 +1,13 @@ import { Router, Response, Request } from "express"; import { route } from "@fosscord/api"; -import { getConnection } from "typeorm"; +import { getDatabase } from "@fosscord/util"; const router = Router(); router.get("/", route({}), (req: Request, res: Response) => { - try { - // test that the database is alive & responding - getConnection(); - return res.sendStatus(200); - } catch (e) { - res.sendStatus(503); - } + if (!getDatabase()) return res.sendStatus(503); + + return res.sendStatus(200); }); export default router; diff --git a/api/src/routes/applications/#id/entitlements.ts b/src/api/routes/applications/#id/entitlements.ts similarity index 100% rename from api/src/routes/applications/#id/entitlements.ts rename to src/api/routes/applications/#id/entitlements.ts diff --git a/api/src/routes/applications/detectable.ts b/src/api/routes/applications/detectable.ts similarity index 100% rename from api/src/routes/applications/detectable.ts rename to src/api/routes/applications/detectable.ts diff --git a/api/src/routes/applications/index.ts b/src/api/routes/applications/index.ts similarity index 100% rename from api/src/routes/applications/index.ts rename to src/api/routes/applications/index.ts diff --git a/api/src/routes/auth/location-metadata.ts b/src/api/routes/auth/location-metadata.ts similarity index 100% rename from api/src/routes/auth/location-metadata.ts rename to src/api/routes/auth/location-metadata.ts diff --git a/api/src/routes/auth/login.ts b/src/api/routes/auth/login.ts similarity index 100% rename from api/src/routes/auth/login.ts rename to src/api/routes/auth/login.ts diff --git a/api/src/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts similarity index 89% rename from api/src/routes/auth/mfa/totp.ts rename to src/api/routes/auth/mfa/totp.ts index cec6e5ee..50b9e9c8 100644 --- a/api/src/routes/auth/mfa/totp.ts +++ b/src/api/routes/auth/mfa/totp.ts @@ -26,7 +26,14 @@ router.post("/", route({ body: "TotpSchema" }), async (req: Request, res: Respon ], }); - const backup = await BackupCode.findOne({ code: code, expired: false, consumed: false, user: { id: user.id }}); + const backup = await BackupCode.findOne({ + where: { + code: code, + expired: false, + consumed: false, + user: { id: user.id } + } + }); if (!backup) { const ret = verifyToken(user.totp_secret!, code); diff --git a/api/src/routes/auth/register.ts b/src/api/routes/auth/register.ts similarity index 98% rename from api/src/routes/auth/register.ts rename to src/api/routes/auth/register.ts index f74d0d63..b7122dad 100644 --- a/api/src/routes/auth/register.ts +++ b/src/api/routes/auth/register.ts @@ -117,7 +117,7 @@ router.post("/", route({ body: "RegisterSchema" }), async (req: Request, res: Re } // check if there is already an account with this email - const exists = await User.findOne({ email: email }); + const exists = await User.findOne({ where: { email: email } }); if (exists) { throw FieldErrors({ diff --git a/api/src/routes/auth/verify/view-backup-codes-challenge.ts b/src/api/routes/auth/verify/view-backup-codes-challenge.ts similarity index 88% rename from api/src/routes/auth/verify/view-backup-codes-challenge.ts rename to src/api/routes/auth/verify/view-backup-codes-challenge.ts index be651686..36bfeb0c 100644 --- a/api/src/routes/auth/verify/view-backup-codes-challenge.ts +++ b/src/api/routes/auth/verify/view-backup-codes-challenge.ts @@ -11,7 +11,7 @@ export interface BackupCodesChallengeSchema { router.post("/", route({ body: "BackupCodesChallengeSchema" }), async (req: Request, res: Response) => { const { password } = req.body as BackupCodesChallengeSchema; - const user = await User.findOneOrFail({ id: req.user_id }, { select: ["data"] }); + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["data"] }); if (!await bcrypt.compare(password, user.data.hash || "")) { throw FieldErrors({ password: { message: req.t("auth:login.INVALID_PASSWORD"), code: "INVALID_PASSWORD" } }); @@ -20,7 +20,7 @@ router.post("/", route({ body: "BackupCodesChallengeSchema" }), async (req: Requ return res.json({ nonce: "NoncePlaceholder", regenerate_nonce: "RegenNoncePlaceholder", - }) + }); }); export default router; diff --git a/api/src/routes/channels/#channel_id/followers.ts b/src/api/routes/channels/#channel_id/followers.ts similarity index 100% rename from api/src/routes/channels/#channel_id/followers.ts rename to src/api/routes/channels/#channel_id/followers.ts diff --git a/api/src/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts similarity index 94% rename from api/src/routes/channels/#channel_id/index.ts rename to src/api/routes/channels/#channel_id/index.ts index 932a933a..0340a616 100644 --- a/api/src/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -18,7 +18,7 @@ const router: Router = Router(); router.get("/", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: Response) => { const { channel_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); return res.send(channel); }); @@ -81,7 +81,7 @@ router.patch("/", route({ body: "ChannelModifySchema", permission: "MANAGE_CHANN const { channel_id } = req.params; if (payload.icon) payload.icon = await handleFile(`/channel-icons/${channel_id}`, payload.icon); - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); channel.assign(payload); await Promise.all([ diff --git a/api/src/routes/channels/#channel_id/invites.ts b/src/api/routes/channels/#channel_id/invites.ts similarity index 54% rename from api/src/routes/channels/#channel_id/invites.ts rename to src/api/routes/channels/#channel_id/invites.ts index 9c361164..fd8339ad 100644 --- a/api/src/routes/channels/#channel_id/invites.ts +++ b/src/api/routes/channels/#channel_id/invites.ts @@ -20,44 +20,44 @@ export interface InviteCreateSchema { } router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES" }), - async (req: Request, res: Response) => { - const { user_id } = req; - const { channel_id } = req.params; - const channel = await Channel.findOneOrFail({ where: { id: channel_id }, select: ["id", "name", "type", "guild_id"] }); - isTextChannel(channel.type); + async (req: Request, res: Response) => { + const { user_id } = req; + const { channel_id } = req.params; + const channel = await Channel.findOneOrFail({ where: { id: channel_id }, select: ["id", "name", "type", "guild_id"] }); + isTextChannel(channel.type); - if (!channel.guild_id) { - throw new HTTPError("This channel doesn't exist", 404); - } - const { guild_id } = channel; + if (!channel.guild_id) { + throw new HTTPError("This channel doesn't exist", 404); + } + const { guild_id } = channel; - const expires_at = new Date(req.body.max_age * 1000 + Date.now()); + const expires_at = new Date(req.body.max_age * 1000 + Date.now()); - const invite = await new Invite({ - code: random(), - temporary: req.body.temporary, - uses: 0, - max_uses: req.body.max_uses, - max_age: req.body.max_age, - expires_at, - created_at: new Date(), - guild_id, - channel_id: channel_id, - inviter_id: user_id - }).save(); - const data = invite.toJSON(); - data.inviter = await User.getPublicUser(req.user_id); - data.guild = await Guild.findOne({ id: guild_id }); - data.channel = channel; + const invite = await Invite.create({ + code: random(), + temporary: req.body.temporary, + uses: 0, + max_uses: req.body.max_uses, + max_age: req.body.max_age, + expires_at, + created_at: new Date(), + guild_id, + channel_id: channel_id, + inviter_id: user_id + }).save(); + const data = invite.toJSON(); + data.inviter = await User.getPublicUser(req.user_id); + data.guild = await Guild.findOne({ where: { id: guild_id } }); + data.channel = channel; - await emitEvent({ event: "INVITE_CREATE", data, guild_id } as InviteCreateEvent); - res.status(201).send(data); -}); + await emitEvent({ event: "INVITE_CREATE", data, guild_id } as InviteCreateEvent); + res.status(201).send(data); + }); router.get("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => { const { user_id } = req; const { channel_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); if (!channel.guild_id) { throw new HTTPError("This channel doesn't exist", 404); diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts similarity index 84% rename from api/src/routes/channels/#channel_id/messages/#message_id/ack.ts rename to src/api/routes/channels/#channel_id/messages/#message_id/ack.ts index 1e3564d8..3abae7ce 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts @@ -19,8 +19,8 @@ router.post("/", route({ body: "MessageAcknowledgeSchema" }), async (req: Reques const permission = await getPermission(req.user_id, undefined, channel_id); permission.hasThrow("VIEW_CHANNEL"); - let read_state = await ReadState.findOne({ user_id: req.user_id, channel_id }); - if (!read_state) read_state = new ReadState({ user_id: req.user_id, channel_id }); + let read_state = await ReadState.findOne({ where: { user_id: req.user_id, channel_id } }); + if (!read_state) read_state = ReadState.create({ user_id: req.user_id, channel_id }); read_state.last_message_id = message_id; await read_state.save(); diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts similarity index 100% rename from api/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts rename to src/api/routes/channels/#channel_id/messages/#message_id/crosspost.ts diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts similarity index 90% rename from api/src/routes/channels/#channel_id/messages/#message_id/index.ts rename to src/api/routes/channels/#channel_id/messages/#message_id/index.ts index 37734397..a02a9abe 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts @@ -7,12 +7,12 @@ import { FosscordApiErrors, getPermission, getRights, - Message, + Message, MessageCreateEvent, MessageDeleteEvent, MessageUpdateEvent, Snowflake, - uploadFile + uploadFile } from "@fosscord/util"; import { Router, Response, Request } from "express"; import multer from "multer"; @@ -40,14 +40,14 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE const message = await Message.findOneOrFail({ where: { id: message_id, channel_id }, relations: ["attachments"] }); const permissions = await getPermission(req.user_id, undefined, channel_id); - + const rights = await getRights(req.user_id); if ((req.user_id !== message.author_id)) { if (!rights.has("MANAGE_MESSAGES")) { permissions.hasThrow("MANAGE_MESSAGES"); body = { flags: body.flags }; -// guild admins can only suppress embeds of other messages, no such restriction imposed to instance-wide admins + // guild admins can only suppress embeds of other messages, no such restriction imposed to instance-wide admins } } else rights.hasThrow("SELF_EDIT_MESSAGES"); @@ -94,7 +94,7 @@ router.put( const { channel_id, message_id } = req.params; var body = req.body as MessageCreateSchema; const attachments: Attachment[] = []; - + const rights = await getRights(req.user_id); rights.hasThrow("SEND_MESSAGES"); @@ -103,13 +103,13 @@ router.put( throw new HTTPError("Message IDs must be positive integers", 400); } - const snowflake = Snowflake.deconstruct(message_id) + const snowflake = Snowflake.deconstruct(message_id); if (Date.now() < snowflake.timestamp) { // message is in the future throw FosscordApiErrors.CANNOT_BACKFILL_TO_THE_FUTURE; } - const exists = await Message.findOne({ where: { id: message_id, channel_id: channel_id }}); + const exists = await Message.findOne({ where: { id: message_id, channel_id: channel_id } }); if (exists) { throw FosscordApiErrors.CANNOT_REPLACE_BY_BACKFILL; } @@ -117,7 +117,7 @@ router.put( if (req.file) { try { const file = await uploadFile(`/attachments/${req.params.channel_id}`, req.file); - attachments.push({ ...file, proxy_url: file.url }); + attachments.push(Attachment.create({ ...file, proxy_url: file.url })); } catch (error) { return res.status(400).json(error); } @@ -135,13 +135,13 @@ router.put( embeds, channel_id, attachments, - edited_timestamp: null, + edited_timestamp: undefined, timestamp: new Date(snowflake.timestamp), }); //Fix for the client bug - delete message.member - + delete message.member; + await Promise.all([ message.save(), emitEvent({ event: "MESSAGE_CREATE", channel_id: channel_id, data: message } as MessageCreateEvent), @@ -160,7 +160,7 @@ router.get("/", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: const message = await Message.findOneOrFail({ where: { id: message_id, channel_id }, relations: ["attachments"] }); const permissions = await getPermission(req.user_id, undefined, channel_id); - + if (message.author_id !== req.user_id) permissions.hasThrow("READ_MESSAGE_HISTORY"); return res.json(message); @@ -169,9 +169,9 @@ router.get("/", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: router.delete("/", route({}), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); - const message = await Message.findOneOrFail({ id: message_id }); - + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); + const message = await Message.findOneOrFail({ where: { id: message_id } }); + const rights = await getRights(req.user_id); if ((message.author_id !== req.user_id)) { diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts similarity index 87% rename from api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts rename to src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts index d93cf70f..c3cca05d 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/reactions.ts @@ -39,7 +39,7 @@ function getEmoji(emoji: string): PartialEmoji { router.delete("/", route({ permission: "MANAGE_MESSAGES" }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); await Message.update({ id: message_id, channel_id }, { reactions: [] }); @@ -60,7 +60,7 @@ router.delete("/:emoji", route({ permission: "MANAGE_MESSAGES" }), async (req: R const { message_id, channel_id } = req.params; const emoji = getEmoji(req.params.emoji); - const message = await Message.findOneOrFail({ id: message_id, channel_id }); + const message = await Message.findOneOrFail({ where: { id: message_id, channel_id } }); const already_added = message.reactions.find((x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name); if (!already_added) throw new HTTPError("Reaction not found", 404); @@ -87,7 +87,7 @@ router.get("/:emoji", route({ permission: "VIEW_CHANNEL" }), async (req: Request const { message_id, channel_id } = req.params; const emoji = getEmoji(req.params.emoji); - const message = await Message.findOneOrFail({ id: message_id, channel_id }); + const message = await Message.findOneOrFail({ where: { id: message_id, channel_id } }); const reaction = message.reactions.find((x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name); if (!reaction) throw new HTTPError("Reaction not found", 404); @@ -106,14 +106,14 @@ router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY", right if (user_id !== "@me") throw new HTTPError("Invalid user"); const emoji = getEmoji(req.params.emoji); - const channel = await Channel.findOneOrFail({ id: channel_id }); - const message = await Message.findOneOrFail({ id: message_id, channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); + const message = await Message.findOneOrFail({ where: { id: message_id, channel_id } }); const already_added = message.reactions.find((x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name); if (!already_added) req.permission!.hasThrow("ADD_REACTIONS"); if (emoji.id) { - const external_emoji = await Emoji.findOneOrFail({ id: emoji.id }); + const external_emoji = await Emoji.findOneOrFail({ where: { id: emoji.id } }); if (!already_added) req.permission!.hasThrow("USE_EXTERNAL_EMOJIS"); emoji.animated = external_emoji.animated; emoji.name = external_emoji.name; @@ -126,7 +126,7 @@ router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY", right await message.save(); - const member = channel.guild_id && (await Member.findOneOrFail({ id: req.user_id })); + const member = channel.guild_id && (await Member.findOneOrFail({ where: { id: req.user_id } })); await emitEvent({ event: "MESSAGE_REACTION_ADD", @@ -149,8 +149,8 @@ router.delete("/:emoji/:user_id", route({}), async (req: Request, res: Response) const emoji = getEmoji(req.params.emoji); - const channel = await Channel.findOneOrFail({ id: channel_id }); - const message = await Message.findOneOrFail({ id: message_id, channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); + const message = await Message.findOneOrFail({ where: { id: message_id, channel_id } }); if (user_id === "@me") user_id = req.user_id; else { diff --git a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts similarity index 93% rename from api/src/routes/channels/#channel_id/messages/bulk-delete.ts rename to src/api/routes/channels/#channel_id/messages/bulk-delete.ts index 6eacf249..b6fd37f4 100644 --- a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts @@ -17,7 +17,7 @@ export interface BulkDeleteSchema { // https://discord.com/developers/docs/resources/channel#bulk-delete-messages router.post("/", route({ body: "BulkDeleteSchema" }), async (req: Request, res: Response) => { const { channel_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); if (!channel.guild_id) throw new HTTPError("Can't bulk delete dm channel messages", 400); const rights = await getRights(req.user_id); @@ -35,7 +35,7 @@ router.post("/", route({ body: "BulkDeleteSchema" }), async (req: Request, res: if (messages.length > maxBulkDelete) throw new HTTPError(`You cannot delete more than ${maxBulkDelete} messages`); } - await Message.delete(messages.map((x) => ({ id: x }))); + await Message.delete(messages); await emitEvent({ event: "MESSAGE_DELETE_BULK", diff --git a/api/src/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts similarity index 98% rename from api/src/routes/channels/#channel_id/messages/index.ts rename to src/api/routes/channels/#channel_id/messages/index.ts index 3c014f5c..154dc8ed 100644 --- a/api/src/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -203,7 +203,7 @@ router.post( for (var currFile of files) { try { const file = await uploadFile(`/attachments/${channel.id}`, currFile); - attachments.push({ ...file, proxy_url: file.url }); + attachments.push(Attachment.create({ ...file, proxy_url: file.url })); } catch (error) { return res.status(400).json(error); @@ -220,7 +220,7 @@ router.post( embeds, channel_id, attachments, - edited_timestamp: null, + edited_timestamp: undefined, timestamp: new Date() }); diff --git a/api/src/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts similarity index 85% rename from api/src/routes/channels/#channel_id/permissions.ts rename to src/api/routes/channels/#channel_id/permissions.ts index 2eded853..e74a0255 100644 --- a/api/src/routes/channels/#channel_id/permissions.ts +++ b/src/api/routes/channels/#channel_id/permissions.ts @@ -16,7 +16,7 @@ const router: Router = Router(); // TODO: Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel) -export interface ChannelPermissionOverwriteSchema extends ChannelPermissionOverwrite {} +export interface ChannelPermissionOverwriteSchema extends ChannelPermissionOverwrite { } router.put( "/:overwrite_id", @@ -25,13 +25,13 @@ router.put( const { channel_id, overwrite_id } = req.params; const body = req.body as ChannelPermissionOverwriteSchema; - var channel = await Channel.findOneOrFail({ id: channel_id }); + var channel = await Channel.findOneOrFail({ where: { id: channel_id } }); if (!channel.guild_id) throw new HTTPError("Channel not found", 404); if (body.type === 0) { - if (!(await Role.count({ id: overwrite_id }))) throw new HTTPError("role not found", 404); + if (!(await Role.count({ where: { id: overwrite_id } }))) throw new HTTPError("role not found", 404); } else if (body.type === 1) { - if (!(await Member.count({ id: overwrite_id }))) throw new HTTPError("user not found", 404); + if (!(await Member.count({ where: { id: overwrite_id } }))) throw new HTTPError("user not found", 404); } else throw new HTTPError("type not supported", 501); // @ts-ignore @@ -64,7 +64,7 @@ router.put( router.delete("/:overwrite_id", route({ permission: "MANAGE_ROLES" }), async (req: Request, res: Response) => { const { channel_id, overwrite_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); if (!channel.guild_id) throw new HTTPError("Channel not found", 404); channel.permission_overwrites = channel.permission_overwrites!.filter((x) => x.id === overwrite_id); diff --git a/api/src/routes/channels/#channel_id/pins.ts b/src/api/routes/channels/#channel_id/pins.ts similarity index 82% rename from api/src/routes/channels/#channel_id/pins.ts rename to src/api/routes/channels/#channel_id/pins.ts index e71e659f..30507c71 100644 --- a/api/src/routes/channels/#channel_id/pins.ts +++ b/src/api/routes/channels/#channel_id/pins.ts @@ -17,12 +17,12 @@ const router: Router = Router(); router.put("/:message_id", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; - const message = await Message.findOneOrFail({ id: message_id }); + const message = await Message.findOneOrFail({ where: { id: message_id } }); // * in dm channels anyone can pin messages -> only check for guilds if (message.guild_id) req.permission!.hasThrow("MANAGE_MESSAGES"); - const pinned_count = await Message.count({ channel: { id: channel_id }, pinned: true }); + const pinned_count = await Message.count({ where: { channel: { id: channel_id }, pinned: true } }); const { maxPins } = Config.get().limits.channel; if (pinned_count >= maxPins) throw DiscordApiErrors.MAXIMUM_PINS.withParams(maxPins); @@ -50,10 +50,10 @@ router.put("/:message_id", route({ permission: "VIEW_CHANNEL" }), async (req: Re router.delete("/:message_id", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); if (channel.guild_id) req.permission!.hasThrow("MANAGE_MESSAGES"); - const message = await Message.findOneOrFail({ id: message_id }); + const message = await Message.findOneOrFail({ where: { id: message_id } }); message.pinned = false; await Promise.all([ @@ -82,7 +82,7 @@ router.delete("/:message_id", route({ permission: "VIEW_CHANNEL" }), async (req: router.get("/", route({ permission: ["READ_MESSAGE_HISTORY"] }), async (req: Request, res: Response) => { const { channel_id } = req.params; - let pins = await Message.find({ channel_id: channel_id, pinned: true }); + let pins = await Message.find({ where: { channel_id: channel_id, pinned: true } }); res.send(pins); }); diff --git a/api/src/routes/channels/#channel_id/purge.ts b/src/api/routes/channels/#channel_id/purge.ts similarity index 82% rename from api/src/routes/channels/#channel_id/purge.ts rename to src/api/routes/channels/#channel_id/purge.ts index 28b52b50..bfac27ee 100644 --- a/api/src/routes/channels/#channel_id/purge.ts +++ b/src/api/routes/channels/#channel_id/purge.ts @@ -12,10 +12,10 @@ import { FosscordApiErrors, getPermission, getRights, - Message, + Message, MessageDeleteBulkEvent, Snowflake, - uploadFile + uploadFile } from "@fosscord/util"; import { Router, Response, Request } from "express"; import multer from "multer"; @@ -27,7 +27,7 @@ export default router; export interface PurgeSchema { before: string; - after: string + after: string; } /** @@ -35,8 +35,8 @@ TODO: apply the delete bit by bit to prevent client and database stress **/ router.post("/", route({ /*body: "PurgeSchema",*/ }), async (req: Request, res: Response) => { const { channel_id } = req.params; - const channel = await Channel.findOneOrFail({ id: channel_id }); - + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); + if (!channel.guild_id) throw new HTTPError("Can't purge dm channels", 400); isTextChannel(channel.type); @@ -46,7 +46,7 @@ router.post("/", route({ /*body: "PurgeSchema",*/ }), async (req: Request, res: permissions.hasThrow("MANAGE_MESSAGES"); permissions.hasThrow("MANAGE_CHANNELS"); } - + const { before, after } = req.body as PurgeSchema; // TODO: send the deletion event bite-by-bite to prevent client stress @@ -55,25 +55,25 @@ router.post("/", route({ /*body: "PurgeSchema",*/ }), async (req: Request, res: order: { id: "ASC" }, // take: limit, where: { - channel_id, - id: Between(after, before), // the right way around - author_id: rights.has("SELF_DELETE_MESSAGES") ? undefined : Not(req.user_id) - // if you lack the right of self-deletion, you can't delete your own messages, even in purges - }, + channel_id, + id: Between(after, before), // the right way around + author_id: rights.has("SELF_DELETE_MESSAGES") ? undefined : Not(req.user_id) + // if you lack the right of self-deletion, you can't delete your own messages, even in purges + }, relations: ["author", "webhook", "application", "mentions", "mention_roles", "mention_channels", "sticker_items", "attachments"] }; - + const messages = await Message.find(query); const endpoint = Config.get().cdn.endpointPublic; - - if (messages.length == 0) { + + if (messages.length == 0) { res.sendStatus(304); return; } - await Message.delete(messages.map((x) => ({ id: x }))); - + await Message.delete(messages.map((x) => x.id)); + await emitEvent({ event: "MESSAGE_DELETE_BULK", channel_id, diff --git a/api/src/routes/channels/#channel_id/recipients.ts b/src/api/routes/channels/#channel_id/recipients.ts similarity index 95% rename from api/src/routes/channels/#channel_id/recipients.ts rename to src/api/routes/channels/#channel_id/recipients.ts index e6466211..25854415 100644 --- a/api/src/routes/channels/#channel_id/recipients.ts +++ b/src/api/routes/channels/#channel_id/recipients.ts @@ -28,7 +28,7 @@ router.put("/:user_id", route({}), async (req: Request, res: Response) => { throw DiscordApiErrors.INVALID_RECIPIENT; //TODO is this the right error? } - channel.recipients!.push(new Recipient({ channel_id: channel_id, user_id: user_id })); + channel.recipients!.push(Recipient.create({ channel_id: channel_id, user_id: user_id })); await channel.save(); await emitEvent({ diff --git a/api/src/routes/channels/#channel_id/typing.ts b/src/api/routes/channels/#channel_id/typing.ts similarity index 91% rename from api/src/routes/channels/#channel_id/typing.ts rename to src/api/routes/channels/#channel_id/typing.ts index 56652368..99460f6e 100644 --- a/api/src/routes/channels/#channel_id/typing.ts +++ b/src/api/routes/channels/#channel_id/typing.ts @@ -8,7 +8,7 @@ router.post("/", route({ permission: "SEND_MESSAGES" }), async (req: Request, re const { channel_id } = req.params; const user_id = req.user_id; const timestamp = Date.now(); - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); const member = await Member.findOne({ where: { id: user_id, guild_id: channel.guild_id }, relations: ["roles", "user"] }); await emitEvent({ diff --git a/api/src/routes/channels/#channel_id/webhooks.ts b/src/api/routes/channels/#channel_id/webhooks.ts similarity index 89% rename from api/src/routes/channels/#channel_id/webhooks.ts rename to src/api/routes/channels/#channel_id/webhooks.ts index 92895da6..93f70a41 100644 --- a/api/src/routes/channels/#channel_id/webhooks.ts +++ b/src/api/routes/channels/#channel_id/webhooks.ts @@ -22,12 +22,12 @@ router.get("/", route({}), async (req: Request, res: Response) => { // TODO: use Image Data Type for avatar instead of String router.post("/", route({ body: "WebhookCreateSchema", permission: "MANAGE_WEBHOOKS" }), async (req: Request, res: Response) => { const channel_id = req.params.channel_id; - const channel = await Channel.findOneOrFail({ id: channel_id }); + const channel = await Channel.findOneOrFail({ where: { id: channel_id } }); isTextChannel(channel.type); if (!channel.guild_id) throw new HTTPError("Not a guild channel", 400); - const webhook_count = await Webhook.count({ channel_id }); + const webhook_count = await Webhook.count({ where: { channel_id } }); const { maxWebhooks } = Config.get().limits.channel; if (webhook_count > maxWebhooks) throw DiscordApiErrors.MAXIMUM_WEBHOOKS.withParams(maxWebhooks); diff --git a/api/src/routes/discoverable-guilds.ts b/src/api/routes/discoverable-guilds.ts similarity index 69% rename from api/src/routes/discoverable-guilds.ts rename to src/api/routes/discoverable-guilds.ts index 0aa2baa9..383e2b24 100644 --- a/api/src/routes/discoverable-guilds.ts +++ b/src/api/routes/discoverable-guilds.ts @@ -2,6 +2,7 @@ import { Guild, Config } from "@fosscord/util"; import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; +import { Like } from "typeorm"; const router = Router(); @@ -16,14 +17,14 @@ router.get("/", route({}), async (req: Request, res: Response) => { if (categories == undefined) { guilds = showAllGuilds ? await Guild.find({ take: Math.abs(Number(limit || configLimit)) }) - : await Guild.find({ where: `"features" LIKE '%DISCOVERABLE%'`, take: Math.abs(Number(limit || configLimit)) }); + : await Guild.find({ where: { features: Like(`%DISCOVERABLE%`) }, take: Math.abs(Number(limit || configLimit)) }); } else { guilds = showAllGuilds - ? await Guild.find({ where: `"primary_category_id" = ${categories}`, take: Math.abs(Number(limit || configLimit)) }) - : await Guild.find({ - where: `"primary_category_id" = ${categories} AND "features" LIKE '%DISCOVERABLE%'`, - take: Math.abs(Number(limit || configLimit)) - }); + ? await Guild.find({ where: { primary_category_id: categories.toString() }, take: Math.abs(Number(limit || configLimit)) }) + : await Guild.find({ + where: { primary_category_id: categories.toString(), features: Like("%DISCOVERABLE%") }, + take: Math.abs(Number(limit || configLimit)) + }); } const total = guilds ? guilds.length : undefined; diff --git a/api/src/routes/discovery.ts b/src/api/routes/discovery.ts similarity index 89% rename from api/src/routes/discovery.ts rename to src/api/routes/discovery.ts index 1991400e..6ab2cc13 100644 --- a/api/src/routes/discovery.ts +++ b/src/api/routes/discovery.ts @@ -10,7 +10,7 @@ router.get("/categories", route({}), async (req: Request, res: Response) => { const { locale, primary_only } = req.query; - const out = primary_only ? await Categories.find() : await Categories.find({ where: `"is_primary" = "true"` }); + const out = primary_only ? await Categories.find() : await Categories.find({ where: { is_primary: true } }); res.send(out); }); diff --git a/api/src/routes/downloads.ts b/src/api/routes/downloads.ts similarity index 67% rename from api/src/routes/downloads.ts rename to src/api/routes/downloads.ts index ddfc080c..df3df911 100644 --- a/api/src/routes/downloads.ts +++ b/src/api/routes/downloads.ts @@ -10,9 +10,9 @@ router.get("/:branch", route({}), async (req: Request, res: Response) => { const { platform } = req.query; //TODO - if(!platform || !["linux", "osx", "win"].includes(platform.toString())) return res.status(404) + if (!platform || !["linux", "osx", "win"].includes(platform.toString())) return res.status(404); - const release = await Release.findOneOrFail({ name: client.releases.upstreamVersion }); + const release = await Release.findOneOrFail({ where: { name: client.releases.upstreamVersion } }); res.redirect(release[`win_url`]); }); diff --git a/api/src/routes/experiments.ts b/src/api/routes/experiments.ts similarity index 100% rename from api/src/routes/experiments.ts rename to src/api/routes/experiments.ts diff --git a/api/src/routes/gateway/bot.ts b/src/api/routes/gateway/bot.ts similarity index 100% rename from api/src/routes/gateway/bot.ts rename to src/api/routes/gateway/bot.ts diff --git a/api/src/routes/gateway/index.ts b/src/api/routes/gateway/index.ts similarity index 100% rename from api/src/routes/gateway/index.ts rename to src/api/routes/gateway/index.ts diff --git a/api/src/routes/gifs/search.ts b/src/api/routes/gifs/search.ts similarity index 91% rename from api/src/routes/gifs/search.ts rename to src/api/routes/gifs/search.ts index 9ad7a592..c7468641 100644 --- a/api/src/routes/gifs/search.ts +++ b/src/api/routes/gifs/search.ts @@ -20,7 +20,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { headers: { "Content-Type": "application/json" } }); - const { results } = await response.json(); + const { results } = await response.json() as any; // TODO: types res.json(results.map(parseGifResult)).status(200); }); diff --git a/api/src/routes/gifs/trending-gifs.ts b/src/api/routes/gifs/trending-gifs.ts similarity index 91% rename from api/src/routes/gifs/trending-gifs.ts rename to src/api/routes/gifs/trending-gifs.ts index 6d97bf7c..52a8969d 100644 --- a/api/src/routes/gifs/trending-gifs.ts +++ b/src/api/routes/gifs/trending-gifs.ts @@ -20,7 +20,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { headers: { "Content-Type": "application/json" } }); - const { results } = await response.json(); + const { results } = await response.json() as any; // TODO: types res.json(results.map(parseGifResult)).status(200); }); diff --git a/api/src/routes/gifs/trending.ts b/src/api/routes/gifs/trending.ts similarity index 92% rename from api/src/routes/gifs/trending.ts rename to src/api/routes/gifs/trending.ts index c81b4c08..aa976c3f 100644 --- a/api/src/routes/gifs/trending.ts +++ b/src/api/routes/gifs/trending.ts @@ -50,8 +50,8 @@ router.get("/", route({}), async (req: Request, res: Response) => { }) ]); - const { tags } = await responseSource.json(); - const { results } = await trendGifSource.json(); + const { tags } = await responseSource.json() as any; // TODO: types + const { results } = await trendGifSource.json() as any; //TODO: types; res.json({ categories: tags.map((x: any) => ({ name: x.searchterm, src: x.image })), diff --git a/api/src/routes/guild-recommendations.ts b/src/api/routes/guild-recommendations.ts similarity index 83% rename from api/src/routes/guild-recommendations.ts rename to src/api/routes/guild-recommendations.ts index 1432f39c..b851d710 100644 --- a/api/src/routes/guild-recommendations.ts +++ b/src/api/routes/guild-recommendations.ts @@ -2,6 +2,7 @@ import { Guild, Config } from "@fosscord/util"; import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; +import { Like } from "typeorm"; const router = Router(); @@ -16,8 +17,8 @@ router.get("/", route({}), async (req: Request, res: Response) => { const guilds = showAllGuilds ? await Guild.find({ take: Math.abs(Number(limit || 24)) }) - : await Guild.find({ where: `"features" LIKE '%DISCOVERABLE%'`, take: Math.abs(Number(limit || 24)) }); - res.send({ recommended_guilds: guilds, load_id: `server_recs/${genLoadId(32)}`}).status(200); + : await Guild.find({ where: { features: Like("%DISCOVERABLE%") }, take: Math.abs(Number(limit || 24)) }); + res.send({ recommended_guilds: guilds, load_id: `server_recs/${genLoadId(32)}` }).status(200); }); export default router; diff --git a/api/src/routes/guilds/#guild_id/audit-logs.ts b/src/api/routes/guilds/#guild_id/audit-logs.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/audit-logs.ts rename to src/api/routes/guilds/#guild_id/audit-logs.ts diff --git a/api/src/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts similarity index 86% rename from api/src/routes/guilds/#guild_id/bans.ts rename to src/api/routes/guilds/#guild_id/bans.ts index 1ce41936..51d3ca67 100644 --- a/api/src/routes/guilds/#guild_id/bans.ts +++ b/src/api/routes/guilds/#guild_id/bans.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util"; +import { DiscordApiErrors, emitEvent, GuildBanAddEvent, GuildBanRemoveEvent, Ban, User, Member } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { getIpAdress, route } from "@fosscord/api"; @@ -32,7 +32,7 @@ const router: Router = Router(); router.get("/", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => { const { guild_id } = req.params; - let bans = await Ban.find({ guild_id: guild_id }); + let bans = await Ban.find({ where: { guild_id: guild_id } }); let promisesToAwait: object[] = []; const bansObj: object[] = []; @@ -65,16 +65,16 @@ router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request, const { guild_id } = req.params; const user_id = req.params.ban; - let ban = await Ban.findOneOrFail({ guild_id: guild_id, user_id: user_id }) as BanRegistrySchema; - + let ban = await Ban.findOneOrFail({ where: { guild_id: guild_id, user_id: user_id } }) as BanRegistrySchema; + if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN; // pretend self-bans don't exist to prevent victim chasing - + /* Filter secret from registry. */ - + ban = ban as BanModeratorSchema; - delete ban.ip + delete ban.ip; return res.json(ban); }); @@ -83,14 +83,14 @@ router.put("/:user_id", route({ body: "BanCreateSchema", permission: "BAN_MEMBER const { guild_id } = req.params; const banned_user_id = req.params.user_id; - if ( (req.user_id === banned_user_id) && (banned_user_id === req.permission!.cache.guild?.owner_id)) + if ((req.user_id === banned_user_id) && (banned_user_id === req.permission!.cache.guild?.owner_id)) throw new HTTPError("You are the guild owner, hence can't ban yourself", 403); - + if (req.permission!.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400); - + const banned_user = await User.getPublicUser(banned_user_id); - const ban = new Ban({ + const ban = Ban.create({ user_id: banned_user_id, guild_id: guild_id, ip: getIpAdress(req), @@ -114,15 +114,15 @@ router.put("/:user_id", route({ body: "BanCreateSchema", permission: "BAN_MEMBER return res.json(ban); }); -router.put("/@me", route({ body: "BanCreateSchema"}), async (req: Request, res: Response) => { +router.put("/@me", route({ body: "BanCreateSchema" }), async (req: Request, res: Response) => { const { guild_id } = req.params; const banned_user = await User.getPublicUser(req.params.user_id); - if (req.permission!.cache.guild?.owner_id === req.params.user_id) + if (req.permission!.cache.guild?.owner_id === req.params.user_id) throw new HTTPError("You are the guild owner, hence can't ban yourself", 403); - - const ban = new Ban({ + + const ban = Ban.create({ user_id: req.params.user_id, guild_id: guild_id, ip: getIpAdress(req), @@ -149,13 +149,13 @@ router.put("/@me", route({ body: "BanCreateSchema"}), async (req: Request, res: router.delete("/:user_id", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => { const { guild_id, user_id } = req.params; - let ban = await Ban.findOneOrFail({ guild_id: guild_id, user_id: user_id }); - + let ban = await Ban.findOneOrFail({ where: { guild_id: guild_id, user_id: user_id } }); + if (ban.user_id === ban.executor_id) throw DiscordApiErrors.UNKNOWN_BAN; // make self-bans irreversible and hide them from view to avoid victim chasing - + const banned_user = await User.getPublicUser(user_id); - + await Promise.all([ Ban.delete({ user_id: user_id, diff --git a/api/src/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts similarity index 90% rename from api/src/routes/guilds/#guild_id/channels.ts rename to src/api/routes/guilds/#guild_id/channels.ts index a921fa21..11f727fc 100644 --- a/api/src/routes/guilds/#guild_id/channels.ts +++ b/src/api/routes/guilds/#guild_id/channels.ts @@ -7,7 +7,7 @@ const router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; - const channels = await Channel.find({ guild_id }); + const channels = await Channel.find({ where: { guild_id } }); res.json(channels); }); @@ -22,7 +22,7 @@ router.post("/", route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNE res.status(201).json(channel); }); -export type ChannelReorderSchema = { id: string; position?: number; lock_permissions?: boolean; parent_id?: string }[]; +export type ChannelReorderSchema = { id: string; position?: number; lock_permissions?: boolean; parent_id?: string; }[]; router.patch("/", route({ body: "ChannelReorderSchema", permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => { // changes guild channel position @@ -48,7 +48,7 @@ router.patch("/", route({ body: "ChannelReorderSchema", permission: "MANAGE_CHAN } await Channel.update({ guild_id, id: x.id }, opts); - const channel = await Channel.findOneOrFail({ guild_id, id: x.id }); + const channel = await Channel.findOneOrFail({ where: { guild_id, id: x.id } }); await emitEvent({ event: "CHANNEL_UPDATE", data: channel, channel_id: x.id, guild_id } as ChannelUpdateEvent); }) diff --git a/api/src/routes/guilds/#guild_id/delete.ts b/src/api/routes/guilds/#guild_id/delete.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/delete.ts rename to src/api/routes/guilds/#guild_id/delete.ts diff --git a/api/src/routes/guilds/#guild_id/discovery-requirements.ts b/src/api/routes/guilds/#guild_id/discovery-requirements.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/discovery-requirements.ts rename to src/api/routes/guilds/#guild_id/discovery-requirements.ts diff --git a/api/src/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts similarity index 83% rename from api/src/routes/guilds/#guild_id/emojis.ts rename to src/api/routes/guilds/#guild_id/emojis.ts index 85d7ac05..75998e04 100644 --- a/api/src/routes/guilds/#guild_id/emojis.ts +++ b/src/api/routes/guilds/#guild_id/emojis.ts @@ -41,19 +41,20 @@ router.post("/", route({ body: "EmojiCreateSchema", permission: "MANAGE_EMOJIS_A const body = req.body as EmojiCreateSchema; const id = Snowflake.generate(); - const emoji_count = await Emoji.count({ guild_id: guild_id }); + const emoji_count = await Emoji.count({ where: { guild_id: guild_id } }); const { maxEmojis } = Config.get().limits.guild; if (emoji_count >= maxEmojis) throw DiscordApiErrors.MAXIMUM_NUMBER_OF_EMOJIS_REACHED.withParams(maxEmojis); if (body.require_colons == null) body.require_colons = true; - const user = await User.findOneOrFail({ id: req.user_id }); + const user = await User.findOneOrFail({ where: { id: req.user_id } }); body.image = (await handleFile(`/emojis/${id}`, body.image)) as string; - const emoji = await new Emoji({ + const emoji = await Emoji.create({ id: id, guild_id: guild_id, ...body, + require_colons: body.require_colons ?? undefined, // schema allows nulls, db does not user: user, managed: false, animated: false, // TODO: Add support animated emojis @@ -66,7 +67,7 @@ router.post("/", route({ body: "EmojiCreateSchema", permission: "MANAGE_EMOJIS_A guild_id: guild_id, data: { guild_id: guild_id, - emojis: await Emoji.find({ guild_id: guild_id }) + emojis: await Emoji.find({ where: { guild_id: guild_id } }) } } as GuildEmojisUpdateEvent); @@ -80,14 +81,14 @@ router.patch( const { emoji_id, guild_id } = req.params; const body = req.body as EmojiModifySchema; - const emoji = await new Emoji({ ...body, id: emoji_id, guild_id: guild_id }).save(); + const emoji = await Emoji.create({ ...body, id: emoji_id, guild_id: guild_id }).save(); await emitEvent({ event: "GUILD_EMOJIS_UPDATE", guild_id: guild_id, data: { guild_id: guild_id, - emojis: await Emoji.find({ guild_id: guild_id }) + emojis: await Emoji.find({ where: { guild_id: guild_id } }) } } as GuildEmojisUpdateEvent); @@ -108,7 +109,7 @@ router.delete("/:emoji_id", route({ permission: "MANAGE_EMOJIS_AND_STICKERS" }), guild_id: guild_id, data: { guild_id: guild_id, - emojis: await Emoji.find({ guild_id: guild_id }) + emojis: await Emoji.find({ where: { guild_id: guild_id } }) } } as GuildEmojisUpdateEvent); diff --git a/api/src/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts similarity index 88% rename from api/src/routes/guilds/#guild_id/index.ts rename to src/api/routes/guilds/#guild_id/index.ts index 45e30a74..45bbe348 100644 --- a/api/src/routes/guilds/#guild_id/index.ts +++ b/src/api/routes/guilds/#guild_id/index.ts @@ -27,8 +27,8 @@ router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; const [guild, member] = await Promise.all([ - Guild.findOneOrFail({ id: guild_id }), - Member.findOne({ guild_id: guild_id, id: req.user_id }) + Guild.findOneOrFail({ where: { id: guild_id } }), + Member.findOne({ where: { guild_id: guild_id, id: req.user_id } }) ]); if (!member) throw new HTTPError("You are not a member of the guild you are trying to access", 401); @@ -38,17 +38,17 @@ router.get("/", route({}), async (req: Request, res: Response) => { return res.send(guild); }); -router.patch("/", route({ body: "GuildUpdateSchema"}), async (req: Request, res: Response) => { +router.patch("/", route({ body: "GuildUpdateSchema" }), async (req: Request, res: Response) => { const body = req.body as GuildUpdateSchema; const { guild_id } = req.params; - - + + const rights = await getRights(req.user_id); const permission = await getPermission(req.user_id, guild_id); - - if (!rights.has("MANAGE_GUILDS")||!permission.has("MANAGE_GUILD")) + + if (!rights.has("MANAGE_GUILDS") || !permission.has("MANAGE_GUILD")) throw DiscordApiErrors.MISSING_PERMISSIONS.withParams("MANAGE_GUILD"); - + // TODO: guild update check image if (body.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon); diff --git a/api/src/routes/guilds/#guild_id/integrations.ts b/src/api/routes/guilds/#guild_id/integrations.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/integrations.ts rename to src/api/routes/guilds/#guild_id/integrations.ts diff --git a/api/src/routes/guilds/#guild_id/invites.ts b/src/api/routes/guilds/#guild_id/invites.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/invites.ts rename to src/api/routes/guilds/#guild_id/invites.ts diff --git a/api/src/routes/guilds/#guild_id/member-verification.ts b/src/api/routes/guilds/#guild_id/member-verification.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/member-verification.ts rename to src/api/routes/guilds/#guild_id/member-verification.ts diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts similarity index 90% rename from api/src/routes/guilds/#guild_id/members/#member_id/index.ts rename to src/api/routes/guilds/#guild_id/members/#member_id/index.ts index d923c10f..d785eb00 100644 --- a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts @@ -14,7 +14,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id, member_id } = req.params; await Member.IsInGuildOrFail(req.user_id, guild_id); - const member = await Member.findOneOrFail({ id: member_id, guild_id }); + const member = await Member.findOneOrFail({ where: { id: member_id, guild_id } }); return res.json(member); }); @@ -26,13 +26,13 @@ router.patch("/", route({ body: "MemberChangeSchema" }), async (req: Request, re const member = await Member.findOneOrFail({ where: { id: member_id, guild_id }, relations: ["roles", "user"] }); const permission = await getPermission(req.user_id, guild_id); - const everyone = await Role.findOneOrFail({ guild_id: guild_id, name: "@everyone", position: 0 }); + const everyone = await Role.findOneOrFail({ where: { guild_id: guild_id, name: "@everyone", position: 0 } }); if (body.roles) { permission.hasThrow("MANAGE_ROLES"); if (body.roles.indexOf(everyone.id) === -1) body.roles.push(everyone.id); - member.roles = body.roles.map((x) => new Role({ id: x })); // foreign key constraint will fail if role doesn't exist + member.roles = body.roles.map((x) => Role.create({ id: x })); // foreign key constraint will fail if role doesn't exist } if ('nick' in body) { diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/members/#member_id/nick.ts rename to src/api/routes/guilds/#guild_id/members/#member_id/nick.ts diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts rename to src/api/routes/guilds/#guild_id/members/#member_id/roles/#role_id/index.ts diff --git a/api/src/routes/guilds/#guild_id/members/index.ts b/src/api/routes/guilds/#guild_id/members/index.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/members/index.ts rename to src/api/routes/guilds/#guild_id/members/index.ts diff --git a/api/src/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/messages/search.ts rename to src/api/routes/guilds/#guild_id/messages/search.ts diff --git a/api/src/routes/guilds/#guild_id/premium.ts b/src/api/routes/guilds/#guild_id/premium.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/premium.ts rename to src/api/routes/guilds/#guild_id/premium.ts diff --git a/api/src/routes/guilds/#guild_id/prune.ts b/src/api/routes/guilds/#guild_id/prune.ts similarity index 96% rename from api/src/routes/guilds/#guild_id/prune.ts rename to src/api/routes/guilds/#guild_id/prune.ts index 0e587d22..cf3466f1 100644 --- a/api/src/routes/guilds/#guild_id/prune.ts +++ b/src/api/routes/guilds/#guild_id/prune.ts @@ -33,7 +33,7 @@ export const inactiveMembers = async (guild_id: string, user_id: string, days: n //I'm sure I can do this in the above db query ( and it would probably be better to do so ), but oh well. if (roles.length && members.length) members = members.filter((user) => user.roles?.some((role) => roles.includes(role.id))); - const me = await Member.findOneOrFail({ id: user_id, guild_id }, { relations: ["roles"] }); + const me = await Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["roles"] }); const myHighestRole = Math.max(...(me.roles?.map((x) => x.position) || [])); const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); diff --git a/api/src/routes/guilds/#guild_id/regions.ts b/src/api/routes/guilds/#guild_id/regions.ts similarity index 88% rename from api/src/routes/guilds/#guild_id/regions.ts rename to src/api/routes/guilds/#guild_id/regions.ts index 75d24fd1..308d5ee5 100644 --- a/api/src/routes/guilds/#guild_id/regions.ts +++ b/src/api/routes/guilds/#guild_id/regions.ts @@ -7,7 +7,7 @@ const router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); //TODO we should use an enum for guild's features and not hardcoded strings return res.json(await getVoiceRegions(getIpAdress(req), guild.features.includes("VIP_REGIONS"))); }); diff --git a/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts similarity index 94% rename from api/src/routes/guilds/#guild_id/roles/#role_id/index.ts rename to src/api/routes/guilds/#guild_id/roles/#role_id/index.ts index 16b5a59f..a01068c0 100644 --- a/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts @@ -9,7 +9,7 @@ const router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id, role_id } = req.params; await Member.IsInGuildOrFail(req.user_id, guild_id); - const role = await Role.findOneOrFail({ guild_id, id: role_id }); + const role = await Role.findOneOrFail({ where: { guild_id, id: role_id } }); return res.json(role); }); @@ -44,7 +44,7 @@ router.patch("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" } if (body.icon && body.icon.length) body.icon = await handleFile(`/role-icons/${role_id}`, body.icon as string); else body.icon = undefined; - const role = new Role({ + const role = Role.create({ ...body, id: role_id, guild_id, diff --git a/api/src/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts similarity index 92% rename from api/src/routes/guilds/#guild_id/roles/index.ts rename to src/api/routes/guilds/#guild_id/roles/index.ts index 53465105..7e839f08 100644 --- a/api/src/routes/guilds/#guild_id/roles/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/index.ts @@ -37,7 +37,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { await Member.IsInGuildOrFail(req.user_id, guild_id); - const roles = await Role.find({ guild_id: guild_id }); + const roles = await Role.find({ where: { guild_id: guild_id } }); return res.json(roles); }); @@ -46,12 +46,12 @@ router.post("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }) const guild_id = req.params.guild_id; const body = req.body as RoleModifySchema; - const role_count = await Role.count({ guild_id }); + const role_count = await Role.count({ where: { guild_id } }); const { maxRoles } = Config.get().limits.guild; if (role_count > maxRoles) throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles); - const role = new Role({ + const role = Role.create({ // values before ...body are default and can be overriden position: 0, hoist: false, @@ -62,8 +62,8 @@ router.post("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" }) managed: false, permissions: String(req.permission!.bitfield & BigInt(body.permissions || "0")), tags: undefined, - icon: null, - unicode_emoji: null + icon: undefined, + unicode_emoji: undefined }); await Promise.all([ diff --git a/api/src/routes/guilds/#guild_id/stickers.ts b/src/api/routes/guilds/#guild_id/stickers.ts similarity index 90% rename from api/src/routes/guilds/#guild_id/stickers.ts rename to src/api/routes/guilds/#guild_id/stickers.ts index 4ea1dce1..7a4e71ee 100644 --- a/api/src/routes/guilds/#guild_id/stickers.ts +++ b/src/api/routes/guilds/#guild_id/stickers.ts @@ -19,7 +19,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; await Member.IsInGuildOrFail(req.user_id, guild_id); - res.json(await Sticker.find({ guild_id })); + res.json(await Sticker.find({ where: { guild_id } })); }); const bodyParser = multer({ @@ -43,7 +43,7 @@ router.post( const id = Snowflake.generate(); const [sticker] = await Promise.all([ - new Sticker({ + Sticker.create({ ...body, guild_id, id, @@ -79,7 +79,7 @@ router.get("/:sticker_id", route({}), async (req: Request, res: Response) => { const { guild_id, sticker_id } = req.params; await Member.IsInGuildOrFail(req.user_id, guild_id); - res.json(await Sticker.findOneOrFail({ guild_id, id: sticker_id })); + res.json(await Sticker.findOneOrFail({ where: { guild_id, id: sticker_id } })); }); export interface ModifyGuildStickerSchema { @@ -105,7 +105,7 @@ router.patch( const { guild_id, sticker_id } = req.params; const body = req.body as ModifyGuildStickerSchema; - const sticker = await new Sticker({ ...body, guild_id, id: sticker_id }).save(); + const sticker = await Sticker.create({ ...body, guild_id, id: sticker_id }).save(); await sendStickerUpdateEvent(guild_id); return res.json(sticker); @@ -118,7 +118,7 @@ async function sendStickerUpdateEvent(guild_id: string) { guild_id: guild_id, data: { guild_id: guild_id, - stickers: await Sticker.find({ guild_id: guild_id }) + stickers: await Sticker.find({ where: { guild_id: guild_id } }) } } as GuildStickersUpdateEvent); } diff --git a/api/src/routes/guilds/#guild_id/templates.ts b/src/api/routes/guilds/#guild_id/templates.ts similarity index 83% rename from api/src/routes/guilds/#guild_id/templates.ts rename to src/api/routes/guilds/#guild_id/templates.ts index 5179e761..0444c402 100644 --- a/api/src/routes/guilds/#guild_id/templates.ts +++ b/src/api/routes/guilds/#guild_id/templates.ts @@ -36,7 +36,7 @@ export interface TemplateModifySchema { router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; - var templates = await Template.find({ source_guild_id: guild_id }); + var templates = await Template.find({ where: { source_guild_id: guild_id } }); return res.json(templates); }); @@ -44,10 +44,10 @@ router.get("/", route({}), async (req: Request, res: Response) => { router.post("/", route({ body: "TemplateCreateSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => { const { guild_id } = req.params; const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: TemplateGuildProjection }); - const exists = await Template.findOneOrFail({ id: guild_id }).catch((e) => {}); + const exists = await Template.findOneOrFail({ where: { id: guild_id } }).catch((e) => { }); if (exists) throw new HTTPError("Template already exists", 400); - const template = await new Template({ + const template = await Template.create({ ...req.body, code: generateCode(), creator_id: req.user_id, @@ -75,7 +75,7 @@ router.put("/:code", route({ permission: "MANAGE_GUILD" }), async (req: Request, const { code, guild_id } = req.params; const guild = await Guild.findOneOrFail({ where: { id: guild_id }, select: TemplateGuildProjection }); - const template = await new Template({ code, serialized_source_guild: guild }).save(); + const template = await Template.create({ code, serialized_source_guild: guild }).save(); res.json(template); }); @@ -84,7 +84,7 @@ router.patch("/:code", route({ body: "TemplateModifySchema", permission: "MANAGE const { code, guild_id } = req.params; const { name, description } = req.body; - const template = await new Template({ code, name: name, description: description, source_guild_id: guild_id }).save(); + const template = await Template.create({ code, name: name, description: description, source_guild_id: guild_id }).save(); res.json(template); }); diff --git a/api/src/routes/guilds/#guild_id/vanity-url.ts b/src/api/routes/guilds/#guild_id/vanity-url.ts similarity index 84% rename from api/src/routes/guilds/#guild_id/vanity-url.ts rename to src/api/routes/guilds/#guild_id/vanity-url.ts index 29cd25e2..040bc1fd 100644 --- a/api/src/routes/guilds/#guild_id/vanity-url.ts +++ b/src/api/routes/guilds/#guild_id/vanity-url.ts @@ -9,7 +9,7 @@ const InviteRegex = /\W/g; router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); if (!guild.features.includes("ALIASABLE_NAMES")) { const invite = await Invite.findOne({ where: { guild_id: guild_id, vanity_url: true } }); @@ -37,17 +37,17 @@ router.patch("/", route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }) const body = req.body as VanityUrlSchema; const code = body.code?.replace(InviteRegex, ""); - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); if (!guild.features.includes("VANITY_URL")) throw new HTTPError("Your guild doesn't support vanity urls"); if (!code || code.length === 0) throw new HTTPError("Code cannot be null or empty"); - const invite = await Invite.findOne({ code }); + const invite = await Invite.findOne({ where: { code } }); if (invite) throw new HTTPError("Invite already exists"); - const { id } = await Channel.findOneOrFail({ guild_id, type: ChannelType.GUILD_TEXT }); + const { id } = await Channel.findOneOrFail({ where: { guild_id, type: ChannelType.GUILD_TEXT } }); - await new Invite({ + await Invite.create({ vanity_url: true, code: code, temporary: false, diff --git a/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts similarity index 92% rename from api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts rename to src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts index f9fbea54..b7fdfecd 100644 --- a/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts +++ b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts @@ -34,14 +34,16 @@ router.patch("/", route({ body: "VoiceStateUpdateSchema" }), async (req: Request if (body.request_to_speak_timestamp) perms.hasThrow("REQUEST_TO_SPEAK"); const voice_state = await VoiceState.findOne({ - guild_id, - channel_id: body.channel_id, - user_id + where: { + guild_id, + channel_id: body.channel_id, + user_id + } }); if (!voice_state) throw DiscordApiErrors.UNKNOWN_VOICE_STATE; voice_state.assign(body); - const channel = await Channel.findOneOrFail({ guild_id, id: body.channel_id }); + const channel = await Channel.findOneOrFail({ where: { guild_id, id: body.channel_id } }); if (channel.type !== ChannelType.GUILD_STAGE_VOICE) { throw DiscordApiErrors.CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE; } diff --git a/api/src/routes/guilds/#guild_id/webhooks.ts b/src/api/routes/guilds/#guild_id/webhooks.ts similarity index 100% rename from api/src/routes/guilds/#guild_id/webhooks.ts rename to src/api/routes/guilds/#guild_id/webhooks.ts diff --git a/api/src/routes/guilds/#guild_id/welcome-screen.ts b/src/api/routes/guilds/#guild_id/welcome-screen.ts similarity index 90% rename from api/src/routes/guilds/#guild_id/welcome-screen.ts rename to src/api/routes/guilds/#guild_id/welcome-screen.ts index 5c7a9daa..a57255f0 100644 --- a/api/src/routes/guilds/#guild_id/welcome-screen.ts +++ b/src/api/routes/guilds/#guild_id/welcome-screen.ts @@ -19,7 +19,7 @@ export interface GuildUpdateWelcomeScreenSchema { router.get("/", route({}), async (req: Request, res: Response) => { const guild_id = req.params.guild_id; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); await Member.IsInGuildOrFail(req.user_id, guild_id); res.json(guild.welcome_screen); @@ -29,7 +29,7 @@ router.patch("/", route({ body: "GuildUpdateWelcomeScreenSchema", permission: "M const guild_id = req.params.guild_id; const body = req.body as GuildUpdateWelcomeScreenSchema; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); if (!guild.welcome_screen.enabled) throw new HTTPError("Welcome screen disabled", 400); if (body.welcome_channels) guild.welcome_screen.welcome_channels = body.welcome_channels; // TODO: check if they exist and are valid diff --git a/api/src/routes/guilds/#guild_id/widget.json.ts b/src/api/routes/guilds/#guild_id/widget.json.ts similarity index 90% rename from api/src/routes/guilds/#guild_id/widget.json.ts rename to src/api/routes/guilds/#guild_id/widget.json.ts index c31519fa..be5bf23f 100644 --- a/api/src/routes/guilds/#guild_id/widget.json.ts +++ b/src/api/routes/guilds/#guild_id/widget.json.ts @@ -17,18 +17,19 @@ const router: Router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); if (!guild.widget_enabled) throw new HTTPError("Widget Disabled", 404); // Fetch existing widget invite for widget channel - var invite = await Invite.findOne({ channel_id: guild.widget_channel_id }); + var invite = await Invite.findOne({ where: { channel_id: guild.widget_channel_id } }); if (guild.widget_channel_id && !invite) { // Create invite for channel if none exists // TODO: Refactor invite create code to a shared function const max_age = 86400; // 24 hours const expires_at = new Date(max_age * 1000 + Date.now()); - const body = { + + invite = await Invite.create({ code: random(), temporary: false, uses: 0, @@ -38,10 +39,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { created_at: new Date(), guild_id, channel_id: guild.widget_channel_id, - inviter_id: null - }; - - invite = await new Invite(body).save(); + }).save(); } // Fetch voice channels, and the @everyone permissions object @@ -63,7 +61,7 @@ router.get("/", route({}), async (req: Request, res: Response) => { // Fetch members // TODO: Understand how Discord's max 100 random member sample works, and apply to here (see top of this file) - let members = await Member.find({ guild_id: guild_id }); + let members = await Member.find({ where: { guild_id: guild_id } }); // Construct object to respond with const data = { diff --git a/api/src/routes/guilds/#guild_id/widget.png.ts b/src/api/routes/guilds/#guild_id/widget.png.ts similarity index 98% rename from api/src/routes/guilds/#guild_id/widget.png.ts rename to src/api/routes/guilds/#guild_id/widget.png.ts index 4c82b740..721b59fb 100644 --- a/api/src/routes/guilds/#guild_id/widget.png.ts +++ b/src/api/routes/guilds/#guild_id/widget.png.ts @@ -14,7 +14,7 @@ const router: Router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); if (!guild.widget_enabled) throw new HTTPError("Unknown Guild", 404); // Fetch guild information diff --git a/api/src/routes/guilds/#guild_id/widget.ts b/src/api/routes/guilds/#guild_id/widget.ts similarity index 94% rename from api/src/routes/guilds/#guild_id/widget.ts rename to src/api/routes/guilds/#guild_id/widget.ts index 2640618d..103f84a3 100644 --- a/api/src/routes/guilds/#guild_id/widget.ts +++ b/src/api/routes/guilds/#guild_id/widget.ts @@ -13,7 +13,7 @@ const router: Router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; - const guild = await Guild.findOneOrFail({ id: guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: guild_id } }); return res.json({ enabled: guild.widget_enabled || false, channel_id: guild.widget_channel_id || null }); }); diff --git a/api/src/routes/guilds/index.ts b/src/api/routes/guilds/index.ts similarity index 90% rename from api/src/routes/guilds/index.ts rename to src/api/routes/guilds/index.ts index 489dea49..d44cd735 100644 --- a/api/src/routes/guilds/index.ts +++ b/src/api/routes/guilds/index.ts @@ -24,9 +24,9 @@ router.post("/", route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }), a const body = req.body as GuildCreateSchema; const { maxGuilds } = Config.get().limits.user; - const guild_count = await Member.count({ id: req.user_id }); + const guild_count = await Member.count({ where: { id: req.user_id } }); const rights = await getRights(req.user_id); - if ((guild_count >= maxGuilds)&&!rights.has("MANAGE_GUILDS")) { + if ((guild_count >= maxGuilds) && !rights.has("MANAGE_GUILDS")) { throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds); } diff --git a/api/src/routes/guilds/templates/index.ts b/src/api/routes/guilds/templates/index.ts similarity index 84% rename from api/src/routes/guilds/templates/index.ts rename to src/api/routes/guilds/templates/index.ts index 3d922e85..e281214f 100644 --- a/api/src/routes/guilds/templates/index.ts +++ b/src/api/routes/guilds/templates/index.ts @@ -15,9 +15,9 @@ router.get("/:code", route({}), async (req: Request, res: Response) => { if (!enabled) res.json({ code: 403, message: "Template creation & usage is disabled on this instance." }).sendStatus(403); const { code } = req.params; - + if (code.startsWith("discord:")) { - if (!allowDiscordTemplates) return res.json({ code: 403, message: "Discord templates cannot be used on this instance." }).sendStatus(403); + if (!allowDiscordTemplates) return res.json({ code: 403, message: "Discord templates cannot be used on this instance." }).sendStatus(403); const discordTemplateID = code.split("discord:", 2)[1]; const discordTemplateData = await fetch(`https://discord.com/api/v9/guilds/templates/${discordTemplateID}`, { @@ -28,12 +28,12 @@ router.get("/:code", route({}), async (req: Request, res: Response) => { } if (code.startsWith("external:")) { - if (!allowRaws) return res.json({ code: 403, message: "Importing raws is disabled on this instance." }).sendStatus(403); + if (!allowRaws) return res.json({ code: 403, message: "Importing raws is disabled on this instance." }).sendStatus(403); return res.json(code.split("external:", 2)[1]); } - const template = await Template.findOneOrFail({ code: code }); + const template = await Template.findOneOrFail({ where: { code: code } }); res.json(template); }); @@ -47,23 +47,23 @@ router.post("/:code", route({ body: "GuildTemplateCreateSchema" }), async (req: const { maxGuilds } = Config.get().limits.user; - const guild_count = await Member.count({ id: req.user_id }); + const guild_count = await Member.count({ where: { id: req.user_id } }); if (guild_count >= maxGuilds) { throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds); } - const template = await Template.findOneOrFail({ code: code }); + const template = await Template.findOneOrFail({ where: { code: code } }); const guild_id = Snowflake.generate(); const [guild, role] = await Promise.all([ - new Guild({ + Guild.create({ ...body, ...template.serialized_source_guild, id: guild_id, owner_id: req.user_id }).save(), - new Role({ + Role.create({ id: guild_id, guild_id: guild_id, color: 0, @@ -71,9 +71,8 @@ router.post("/:code", route({ body: "GuildTemplateCreateSchema" }), async (req: managed: true, mentionable: true, name: "@everyone", - permissions: BigInt("2251804225"), + permissions: BigInt("2251804225").toString(), // TODO: where did this come from? position: 0, - tags: null }).save() ]); diff --git a/api/src/routes/invites/index.ts b/src/api/routes/invites/index.ts similarity index 68% rename from api/src/routes/invites/index.ts rename to src/api/routes/invites/index.ts index eeafb22a..c268085f 100644 --- a/api/src/routes/invites/index.ts +++ b/src/api/routes/invites/index.ts @@ -13,15 +13,15 @@ router.get("/:code", route({}), async (req: Request, res: Response) => { res.status(200).send(invite); }); -router.post("/:code", route({right: "USE_MASS_INVITES"}), async (req: Request, res: Response) => { +router.post("/:code", route({ right: "USE_MASS_INVITES" }), async (req: Request, res: Response) => { const { code } = req.params; - const { guild_id } = await Invite.findOneOrFail({ code }) - const { features } = await Guild.findOneOrFail({ id: guild_id}); - const { public_flags } = await User.findOneOrFail({ id: req.user_id }); - - if(features.includes("INTERNAL_EMPLOYEE_ONLY") && (public_flags & 1) !== 1) throw new HTTPError("Only intended for the staff of this server.", 401); - if(features.includes("INVITES_CLOSED")) throw new HTTPError("Sorry, this guild has joins closed.", 403); - + const { guild_id } = await Invite.findOneOrFail({ where: { code: code } }); + const { features } = await Guild.findOneOrFail({ where: { id: guild_id } }); + const { public_flags } = await User.findOneOrFail({ where: { id: req.user_id } }); + + if (features.includes("INTERNAL_EMPLOYEE_ONLY") && (public_flags & 1) !== 1) throw new HTTPError("Only intended for the staff of this server.", 401); + if (features.includes("INVITES_CLOSED")) throw new HTTPError("Sorry, this guild has joins closed.", 403); + const invite = await Invite.joinGuild(req.user_id, code); res.json(invite); @@ -30,7 +30,7 @@ router.post("/:code", route({right: "USE_MASS_INVITES"}), async (req: Request, r // * cant use permission of route() function because path doesn't have guild_id/channel_id router.delete("/:code", route({}), async (req: Request, res: Response) => { const { code } = req.params; - const invite = await Invite.findOneOrFail({ code }); + const invite = await Invite.findOneOrFail({ where: { code } }); const { guild_id, channel_id } = invite; const permission = await getPermission(req.user_id, guild_id, channel_id); diff --git a/api/src/routes/oauth2/tokens.ts b/src/api/routes/oauth2/tokens.ts similarity index 100% rename from api/src/routes/oauth2/tokens.ts rename to src/api/routes/oauth2/tokens.ts diff --git a/api/src/routes/outbound-promotions.ts b/src/api/routes/outbound-promotions.ts similarity index 100% rename from api/src/routes/outbound-promotions.ts rename to src/api/routes/outbound-promotions.ts diff --git a/api/src/routes/partners/#guild_id/requirements.ts b/src/api/routes/partners/#guild_id/requirements.ts similarity index 100% rename from api/src/routes/partners/#guild_id/requirements.ts rename to src/api/routes/partners/#guild_id/requirements.ts diff --git a/api/src/routes/ping.ts b/src/api/routes/ping.ts similarity index 100% rename from api/src/routes/ping.ts rename to src/api/routes/ping.ts diff --git a/api/src/routes/policies/instance/domains.ts b/src/api/routes/policies/instance/domains.ts similarity index 100% rename from api/src/routes/policies/instance/domains.ts rename to src/api/routes/policies/instance/domains.ts diff --git a/api/src/routes/policies/instance/index.ts b/src/api/routes/policies/instance/index.ts similarity index 100% rename from api/src/routes/policies/instance/index.ts rename to src/api/routes/policies/instance/index.ts diff --git a/api/src/routes/policies/instance/limits.ts b/src/api/routes/policies/instance/limits.ts similarity index 100% rename from api/src/routes/policies/instance/limits.ts rename to src/api/routes/policies/instance/limits.ts diff --git a/api/src/routes/scheduled-maintenances/upcoming_json.ts b/src/api/routes/scheduled-maintenances/upcoming_json.ts similarity index 100% rename from api/src/routes/scheduled-maintenances/upcoming_json.ts rename to src/api/routes/scheduled-maintenances/upcoming_json.ts diff --git a/api/src/routes/science.ts b/src/api/routes/science.ts similarity index 100% rename from api/src/routes/science.ts rename to src/api/routes/science.ts diff --git a/api/src/routes/stage-instances.ts b/src/api/routes/stage-instances.ts similarity index 100% rename from api/src/routes/stage-instances.ts rename to src/api/routes/stage-instances.ts diff --git a/api/src/routes/sticker-packs/index.ts b/src/api/routes/sticker-packs/index.ts similarity index 100% rename from api/src/routes/sticker-packs/index.ts rename to src/api/routes/sticker-packs/index.ts diff --git a/api/src/routes/stickers/#sticker_id/index.ts b/src/api/routes/stickers/#sticker_id/index.ts similarity index 82% rename from api/src/routes/stickers/#sticker_id/index.ts rename to src/api/routes/stickers/#sticker_id/index.ts index 293ca089..b484a7a1 100644 --- a/api/src/routes/stickers/#sticker_id/index.ts +++ b/src/api/routes/stickers/#sticker_id/index.ts @@ -6,7 +6,7 @@ const router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { sticker_id } = req.params; - res.json(await Sticker.find({ id: sticker_id })); + res.json(await Sticker.find({ where: { id: sticker_id } })); }); export default router; diff --git a/api/src/routes/stop.ts b/src/api/routes/stop.ts similarity index 100% rename from api/src/routes/stop.ts rename to src/api/routes/stop.ts diff --git a/api/src/routes/store/published-listings/applications.ts b/src/api/routes/store/published-listings/applications.ts similarity index 100% rename from api/src/routes/store/published-listings/applications.ts rename to src/api/routes/store/published-listings/applications.ts diff --git a/api/src/routes/store/published-listings/applications/#id/subscription-plans.ts b/src/api/routes/store/published-listings/applications/#id/subscription-plans.ts similarity index 100% rename from api/src/routes/store/published-listings/applications/#id/subscription-plans.ts rename to src/api/routes/store/published-listings/applications/#id/subscription-plans.ts diff --git a/api/src/routes/store/published-listings/skus.ts b/src/api/routes/store/published-listings/skus.ts similarity index 100% rename from api/src/routes/store/published-listings/skus.ts rename to src/api/routes/store/published-listings/skus.ts diff --git a/api/src/routes/store/published-listings/skus/#sku_id/subscription-plans.ts b/src/api/routes/store/published-listings/skus/#sku_id/subscription-plans.ts similarity index 100% rename from api/src/routes/store/published-listings/skus/#sku_id/subscription-plans.ts rename to src/api/routes/store/published-listings/skus/#sku_id/subscription-plans.ts diff --git a/api/src/routes/teams.ts b/src/api/routes/teams.ts similarity index 100% rename from api/src/routes/teams.ts rename to src/api/routes/teams.ts diff --git a/api/src/routes/template.ts.disabled b/src/api/routes/template.ts.disabled similarity index 100% rename from api/src/routes/template.ts.disabled rename to src/api/routes/template.ts.disabled diff --git a/api/src/routes/track.ts b/src/api/routes/track.ts similarity index 100% rename from api/src/routes/track.ts rename to src/api/routes/track.ts diff --git a/api/src/routes/updates.ts b/src/api/routes/updates.ts similarity index 59% rename from api/src/routes/updates.ts rename to src/api/routes/updates.ts index cb4577c8..42f77323 100644 --- a/api/src/routes/updates.ts +++ b/src/api/routes/updates.ts @@ -7,14 +7,14 @@ const router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { const { client } = Config.get(); - const release = await Release.findOneOrFail({ name: client.releases.upstreamVersion}) + const release = await Release.findOneOrFail({ where: { name: client.releases.upstreamVersion } }); res.json({ - name: release.name, - pub_date: release.pub_date, - url: release.url, - notes: release.notes - }); + name: release.name, + pub_date: release.pub_date, + url: release.url, + notes: release.notes + }); }); export default router; diff --git a/api/src/routes/users/#id/index.ts b/src/api/routes/users/#id/index.ts similarity index 100% rename from api/src/routes/users/#id/index.ts rename to src/api/routes/users/#id/index.ts diff --git a/api/src/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts similarity index 90% rename from api/src/routes/users/#id/profile.ts rename to src/api/routes/users/#id/profile.ts index a77fbdb5..de96422a 100644 --- a/api/src/routes/users/#id/profile.ts +++ b/src/api/routes/users/#id/profile.ts @@ -22,8 +22,8 @@ router.get("/", route({ test: { response: { body: "UserProfileResponse" } } }), var premium_guild_since; if (with_mutual_guilds == "true") { - const requested_member = await Member.find({ id: req.params.id, }); - const self_member = await Member.find({ id: req.user_id, }); + const requested_member = await Member.find({ where: { id: req.params.id } }); + const self_member = await Member.find({ where: { id: req.user_id } }); for (const rmem of requested_member) { if (rmem.premium_since) { @@ -44,7 +44,7 @@ router.get("/", route({ test: { response: { body: "UserProfileResponse" } } }), } const guild_member = guild_id && typeof guild_id == "string" - ? await Member.findOneOrFail({ id: req.params.id, guild_id: guild_id }, { relations: ["roles"] }) + ? await Member.findOneOrFail({ where: { id: req.params.id, guild_id: guild_id }, relations: ["roles"] }) : undefined; // TODO: make proper DTO's in util? diff --git a/api/src/routes/users/#id/relationships.ts b/src/api/routes/users/#id/relationships.ts similarity index 100% rename from api/src/routes/users/#id/relationships.ts rename to src/api/routes/users/#id/relationships.ts diff --git a/api/src/routes/users/@me/activities/statistics/applications.ts b/src/api/routes/users/@me/activities/statistics/applications.ts similarity index 100% rename from api/src/routes/users/@me/activities/statistics/applications.ts rename to src/api/routes/users/@me/activities/statistics/applications.ts diff --git a/api/src/routes/users/@me/affinities/guilds.ts b/src/api/routes/users/@me/affinities/guilds.ts similarity index 100% rename from api/src/routes/users/@me/affinities/guilds.ts rename to src/api/routes/users/@me/affinities/guilds.ts diff --git a/api/src/routes/users/@me/affinities/users.ts b/src/api/routes/users/@me/affinities/users.ts similarity index 100% rename from api/src/routes/users/@me/affinities/users.ts rename to src/api/routes/users/@me/affinities/users.ts diff --git a/api/src/routes/users/@me/applications/#app_id/entitlements.ts b/src/api/routes/users/@me/applications/#app_id/entitlements.ts similarity index 100% rename from api/src/routes/users/@me/applications/#app_id/entitlements.ts rename to src/api/routes/users/@me/applications/#app_id/entitlements.ts diff --git a/api/src/routes/users/@me/billing/country-code.ts b/src/api/routes/users/@me/billing/country-code.ts similarity index 100% rename from api/src/routes/users/@me/billing/country-code.ts rename to src/api/routes/users/@me/billing/country-code.ts diff --git a/api/src/routes/users/@me/billing/payment-sources.ts b/src/api/routes/users/@me/billing/payment-sources.ts similarity index 100% rename from api/src/routes/users/@me/billing/payment-sources.ts rename to src/api/routes/users/@me/billing/payment-sources.ts diff --git a/api/src/routes/users/@me/billing/subscriptions.ts b/src/api/routes/users/@me/billing/subscriptions.ts similarity index 100% rename from api/src/routes/users/@me/billing/subscriptions.ts rename to src/api/routes/users/@me/billing/subscriptions.ts diff --git a/api/src/routes/users/@me/channels.ts b/src/api/routes/users/@me/channels.ts similarity index 100% rename from api/src/routes/users/@me/channels.ts rename to src/api/routes/users/@me/channels.ts diff --git a/api/src/routes/users/@me/connections.ts b/src/api/routes/users/@me/connections.ts similarity index 100% rename from api/src/routes/users/@me/connections.ts rename to src/api/routes/users/@me/connections.ts diff --git a/api/src/routes/users/@me/delete.ts b/src/api/routes/users/@me/delete.ts similarity index 100% rename from api/src/routes/users/@me/delete.ts rename to src/api/routes/users/@me/delete.ts diff --git a/api/src/routes/users/@me/devices.ts b/src/api/routes/users/@me/devices.ts similarity index 100% rename from api/src/routes/users/@me/devices.ts rename to src/api/routes/users/@me/devices.ts diff --git a/api/src/routes/users/@me/disable.ts b/src/api/routes/users/@me/disable.ts similarity index 100% rename from api/src/routes/users/@me/disable.ts rename to src/api/routes/users/@me/disable.ts diff --git a/api/src/routes/users/@me/email-settings.ts b/src/api/routes/users/@me/email-settings.ts similarity index 100% rename from api/src/routes/users/@me/email-settings.ts rename to src/api/routes/users/@me/email-settings.ts diff --git a/api/src/routes/users/@me/entitlements.ts b/src/api/routes/users/@me/entitlements.ts similarity index 100% rename from api/src/routes/users/@me/entitlements.ts rename to src/api/routes/users/@me/entitlements.ts diff --git a/api/src/routes/users/@me/guilds.ts b/src/api/routes/users/@me/guilds.ts similarity index 100% rename from api/src/routes/users/@me/guilds.ts rename to src/api/routes/users/@me/guilds.ts diff --git a/api/src/routes/users/@me/guilds/#guild_id/settings.ts b/src/api/routes/users/@me/guilds/#guild_id/settings.ts similarity index 100% rename from api/src/routes/users/@me/guilds/#guild_id/settings.ts rename to src/api/routes/users/@me/guilds/#guild_id/settings.ts diff --git a/api/src/routes/users/@me/guilds/premium/subscription-slots.ts b/src/api/routes/users/@me/guilds/premium/subscription-slots.ts similarity index 100% rename from api/src/routes/users/@me/guilds/premium/subscription-slots.ts rename to src/api/routes/users/@me/guilds/premium/subscription-slots.ts diff --git a/api/src/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts similarity index 100% rename from api/src/routes/users/@me/index.ts rename to src/api/routes/users/@me/index.ts diff --git a/api/src/routes/users/@me/library.ts b/src/api/routes/users/@me/library.ts similarity index 100% rename from api/src/routes/users/@me/library.ts rename to src/api/routes/users/@me/library.ts diff --git a/api/src/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts similarity index 86% rename from api/src/routes/users/@me/mfa/codes-verification.ts rename to src/api/routes/users/@me/mfa/codes-verification.ts index 3aca44a6..09000d07 100644 --- a/api/src/routes/users/@me/mfa/codes-verification.ts +++ b/src/api/routes/users/@me/mfa/codes-verification.ts @@ -16,7 +16,7 @@ router.post("/", route({ body: "CodesVerificationSchema" }), async (req: Request // TODO: We don't have email/etc etc, so can't send a verification code. // Once that's done, this route can verify `key` - const user = await User.findOneOrFail({ id: req.user_id }); + const user = await User.findOneOrFail({ where: { id: req.user_id } }); var codes: BackupCode[]; if (regenerate) { @@ -30,16 +30,18 @@ router.post("/", route({ body: "CodesVerificationSchema" }), async (req: Request } else { codes = await BackupCode.find({ - user: { - id: req.user_id, - }, - expired: false, + where: { + user: { + id: req.user_id, + }, + expired: false, + } }); } return res.json({ backup_codes: codes.map(x => ({ ...x, expired: undefined })), - }) + }); }); export default router; diff --git a/api/src/routes/users/@me/mfa/codes.ts b/src/api/routes/users/@me/mfa/codes.ts similarity index 86% rename from api/src/routes/users/@me/mfa/codes.ts rename to src/api/routes/users/@me/mfa/codes.ts index 2a1fb498..67bd3d5b 100644 --- a/api/src/routes/users/@me/mfa/codes.ts +++ b/src/api/routes/users/@me/mfa/codes.ts @@ -15,7 +15,7 @@ export interface MfaCodesSchema { router.post("/", route({ body: "MfaCodesSchema" }), async (req: Request, res: Response) => { const { password, regenerate } = req.body as MfaCodesSchema; - const user = await User.findOneOrFail({ id: req.user_id }, { select: ["data"] }); + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["data"] }); if (!await bcrypt.compare(password, user.data.hash || "")) { throw FieldErrors({ password: { message: req.t("auth:login.INVALID_PASSWORD"), code: "INVALID_PASSWORD" } }); @@ -33,16 +33,18 @@ router.post("/", route({ body: "MfaCodesSchema" }), async (req: Request, res: Re } else { codes = await BackupCode.find({ - user: { - id: req.user_id, - }, - expired: false, + where: { + user: { + id: req.user_id, + }, + expired: false, + } }); } return res.json({ backup_codes: codes.map(x => ({ ...x, expired: undefined })), - }) + }); }); export default router; diff --git a/api/src/routes/users/@me/mfa/totp/disable.ts b/src/api/routes/users/@me/mfa/totp/disable.ts similarity index 82% rename from api/src/routes/users/@me/mfa/totp/disable.ts rename to src/api/routes/users/@me/mfa/totp/disable.ts index 5e039ea3..2d385fda 100644 --- a/api/src/routes/users/@me/mfa/totp/disable.ts +++ b/src/api/routes/users/@me/mfa/totp/disable.ts @@ -13,9 +13,9 @@ export interface TotpDisableSchema { router.post("/", route({ body: "TotpDisableSchema" }), async (req: Request, res: Response) => { const body = req.body as TotpDisableSchema; - const user = await User.findOneOrFail({ id: req.user_id }, { select: ["totp_secret"] }); + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["totp_secret"] }); - const backup = await BackupCode.findOne({ code: body.code }); + const backup = await BackupCode.findOne({ where: { code: body.code } }); if (!backup) { const ret = verifyToken(user.totp_secret!, body.code); if (!ret || ret.delta != 0) diff --git a/api/src/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts similarity index 100% rename from api/src/routes/users/@me/mfa/totp/enable.ts rename to src/api/routes/users/@me/mfa/totp/enable.ts diff --git a/api/src/routes/users/@me/notes.ts b/src/api/routes/users/@me/notes.ts similarity index 93% rename from api/src/routes/users/@me/notes.ts rename to src/api/routes/users/@me/notes.ts index 3c503942..f938f088 100644 --- a/api/src/routes/users/@me/notes.ts +++ b/src/api/routes/users/@me/notes.ts @@ -29,7 +29,7 @@ router.put("/:id", route({}), async (req: Request, res: Response) => { if (note && note.length) { // upsert a note - if (await Note.findOne({ owner: { id: owner.id }, target: { id: target.id } })) { + if (await Note.findOne({ where: { owner: { id: owner.id }, target: { id: target.id } } })) { Note.update( { owner: { id: owner.id }, target: { id: target.id } }, { owner, target, content: note } diff --git a/api/src/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts similarity index 88% rename from api/src/routes/users/@me/relationships.ts rename to src/api/routes/users/@me/relationships.ts index c5a643d2..00d4da0b 100644 --- a/api/src/routes/users/@me/relationships.ts +++ b/src/api/routes/users/@me/relationships.ts @@ -45,7 +45,7 @@ router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request return await updateRelationship( req, res, - await User.findOneOrFail({ id: req.params.id }, { relations: ["relationships", "relationships.to"], select: userProjection }), + await User.findOneOrFail({ where: { id: req.params.id }, relations: ["relationships", "relationships.to"], select: userProjection }), req.body.type ?? RelationshipType.friends ); }); @@ -75,8 +75,8 @@ router.delete("/:id", route({}), async (req: Request, res: Response) => { const { id } = req.params; if (id === req.user_id) throw new HTTPError("You can't remove yourself as a friend"); - const user = await User.findOneOrFail({ id: req.user_id }, { select: userProjection, relations: ["relationships"] }); - const friend = await User.findOneOrFail({ id: id }, { select: userProjection, relations: ["relationships"] }); + const user = await User.findOneOrFail({ where: { id: req.user_id }, select: userProjection, relations: ["relationships"] }); + const friend = await User.findOneOrFail({ where: { id: id }, select: userProjection, relations: ["relationships"] }); const relationship = user.relationships.find((x) => x.to_id === id); const friendRequest = friend.relationships.find((x) => x.to_id === req.user_id); @@ -124,10 +124,10 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ const id = friend.id; if (id === req.user_id) throw new HTTPError("You can't add yourself as a friend"); - const user = await User.findOneOrFail( - { id: req.user_id }, - { relations: ["relationships", "relationships.to"], select: userProjection } - ); + const user = await User.findOneOrFail({ + where: { id: req.user_id }, + relations: ["relationships", "relationships.to"], select: userProjection + }); var relationship = user.relationships.find((x) => x.to_id === id); const friendRequest = friend.relationships.find((x) => x.to_id === req.user_id); @@ -139,7 +139,7 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ relationship.type = RelationshipType.blocked; await relationship.save(); } else { - relationship = await new Relationship({ to_id: id, type: RelationshipType.blocked, from_id: req.user_id }).save(); + relationship = await Relationship.create({ to_id: id, type: RelationshipType.blocked, from_id: req.user_id }).save(); } if (friendRequest && friendRequest.type !== RelationshipType.blocked) { @@ -165,8 +165,8 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ const { maxFriends } = Config.get().limits.user; if (user.relationships.length >= maxFriends) throw DiscordApiErrors.MAXIMUM_FRIENDS.withParams(maxFriends); - var incoming_relationship = new Relationship({ nickname: undefined, type: RelationshipType.incoming, to: user, from: friend }); - var outgoing_relationship = new Relationship({ + var incoming_relationship = Relationship.create({ nickname: undefined, type: RelationshipType.incoming, to: user, from: friend }); + var outgoing_relationship = Relationship.create({ nickname: undefined, type: RelationshipType.outgoing, to: friend, diff --git a/api/src/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts similarity index 79% rename from api/src/routes/users/@me/settings.ts rename to src/api/routes/users/@me/settings.ts index a03e2fdd..9060baf7 100644 --- a/api/src/routes/users/@me/settings.ts +++ b/src/api/routes/users/@me/settings.ts @@ -7,10 +7,10 @@ const router = Router(); export interface UserSettingsSchema extends Partial { } router.get("/", route({}), async (req: Request, res: Response) => { - const user = await User.findOneOrFail( - { id: req.user_id }, - { select: ["settings"] } - ); + const user = await User.findOneOrFail({ + where: { id: req.user_id }, + select: ["settings"] + }); return res.json(user.settings); }); @@ -18,7 +18,7 @@ router.patch("/", route({ body: "UserSettingsSchema" }), async (req: Request, re const body = req.body as UserSettings; if (body.locale === "en") body.locale = "en-US"; // fix discord client crash on unkown locale - const user = await User.findOneOrFail({ id: req.user_id, bot: false }); + const user = await User.findOneOrFail({ where: { id: req.user_id, bot: false } }); user.settings = { ...user.settings, ...body }; await user.save(); diff --git a/api/src/routes/voice/regions.ts b/src/api/routes/voice/regions.ts similarity index 100% rename from api/src/routes/voice/regions.ts rename to src/api/routes/voice/regions.ts diff --git a/api/src/start.ts b/src/api/start.ts similarity index 100% rename from api/src/start.ts rename to src/api/start.ts diff --git a/api/src/util/entities/blockedEmailDomains.txt b/src/api/util/entities/blockedEmailDomains.txt similarity index 100% rename from api/src/util/entities/blockedEmailDomains.txt rename to src/api/util/entities/blockedEmailDomains.txt diff --git a/api/src/util/entities/trustedEmailDomains.txt b/src/api/util/entities/trustedEmailDomains.txt similarity index 100% rename from api/src/util/entities/trustedEmailDomains.txt rename to src/api/util/entities/trustedEmailDomains.txt diff --git a/api/src/util/handlers/Instance.ts b/src/api/util/handlers/Instance.ts similarity index 90% rename from api/src/util/handlers/Instance.ts rename to src/api/util/handlers/Instance.ts index 6bddfa98..fa134fd8 100644 --- a/api/src/util/handlers/Instance.ts +++ b/src/api/util/handlers/Instance.ts @@ -9,7 +9,7 @@ export async function initInstance() { const { autoJoin } = Config.get().guild; if (autoJoin.enabled && !autoJoin.guilds?.length) { - let guild = await Guild.findOne({}); + let guild = await Guild.findOne({ where: {}, select: ["id"] }); if (guild) { // @ts-ignore await Config.set({ guild: { autoJoin: { guilds: [guild.id] } } }); diff --git a/api/src/util/handlers/Message.ts b/src/api/util/handlers/Message.ts similarity index 90% rename from api/src/util/handlers/Message.ts rename to src/api/util/handlers/Message.ts index 398b8914..7e91fb7b 100644 --- a/api/src/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -21,11 +21,13 @@ import { Webhook, Attachment, Config, + Sticker, } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import fetch from "node-fetch"; import cheerio from "cheerio"; import { MessageCreateSchema } from "../../routes/channels/#channel_id/messages"; +import { In } from "typeorm"; const allow_empty = false; // TODO: check webhook, application, system author, stickers // TODO: embed gifs/videos/images @@ -47,9 +49,11 @@ export async function handleMessage(opts: MessageOptions): Promise { const channel = await Channel.findOneOrFail({ where: { id: opts.channel_id }, relations: ["recipients"] }); if (!channel || !opts.channel_id) throw new HTTPError("Channel not found", 404); - const message = new Message({ + const stickers = opts.sticker_ids ? await Sticker.find({ where: { id: In(opts.sticker_ids) } }) : undefined; + const message = Message.create({ ...opts, - sticker_items: opts.sticker_ids?.map((x) => ({ id: x })), + id: Snowflake.generate(), + sticker_items: stickers, guild_id: channel.guild_id, channel_id: opts.channel_id, attachments: opts.attachments || [], @@ -68,10 +72,10 @@ export async function handleMessage(opts: MessageOptions): Promise { rights.hasThrow("SEND_MESSAGES"); } if (opts.application_id) { - message.application = await Application.findOneOrFail({ id: opts.application_id }); + message.application = await Application.findOneOrFail({ where: { id: opts.application_id } }); } if (opts.webhook_id) { - message.webhook = await Webhook.findOneOrFail({ id: opts.webhook_id }); + message.webhook = await Webhook.findOneOrFail({ where: { id: opts.webhook_id } }); } const permission = await getPermission(opts.author_id, channel.guild_id, opts.channel_id); @@ -85,7 +89,7 @@ export async function handleMessage(opts: MessageOptions): Promise { permission.hasThrow("READ_MESSAGE_HISTORY"); // code below has to be redone when we add custom message routing if (message.guild_id !== null) { - const guild = await Guild.findOneOrFail({ id: channel.guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: channel.guild_id } }); if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) { if (opts.message_reference.guild_id !== channel.guild_id) throw new HTTPError("You can only reference messages from this guild"); if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel"); @@ -120,7 +124,7 @@ export async function handleMessage(opts: MessageOptions): Promise { await Promise.all( Array.from(content.matchAll(ROLE_MENTION)).map(async ([_, mention]) => { - const role = await Role.findOneOrFail({ id: mention, guild_id: channel.guild_id }); + const role = await Role.findOneOrFail({ where: { id: mention, guild_id: channel.guild_id } }); if (role.mentionable || permission.has("MANAGE_ROLES")) { mention_role_ids.push(mention); } @@ -132,9 +136,9 @@ export async function handleMessage(opts: MessageOptions): Promise { } } - message.mention_channels = mention_channel_ids.map((x) => new Channel({ id: x })); - message.mention_roles = mention_role_ids.map((x) => new Role({ id: x })); - message.mentions = mention_user_ids.map((x) => new User({ id: x })); + message.mention_channels = mention_channel_ids.map((x) => Channel.create({ id: x })); + message.mention_roles = mention_role_ids.map((x) => Role.create({ id: x })); + message.mentions = mention_user_ids.map((x) => User.create({ id: x })); message.mention_everyone = mention_everyone; // TODO: check and put it all in the body @@ -278,6 +282,6 @@ interface MessageOptions extends MessageCreateSchema { embeds?: Embed[]; channel_id?: string; attachments?: Attachment[]; - edited_timestamp: Date | null; + edited_timestamp?: Date; timestamp?: Date; } diff --git a/api/src/util/handlers/Voice.ts b/src/api/util/handlers/Voice.ts similarity index 100% rename from api/src/util/handlers/Voice.ts rename to src/api/util/handlers/Voice.ts diff --git a/api/src/util/handlers/route.ts b/src/api/util/handlers/route.ts similarity index 56% rename from api/src/util/handlers/route.ts rename to src/api/util/handlers/route.ts index 3d3bbc37..c245b411 100644 --- a/api/src/util/handlers/route.ts +++ b/src/api/util/handlers/route.ts @@ -1,39 +1,19 @@ import { + ajv, DiscordApiErrors, EVENT, - Event, - EventData, FieldErrors, FosscordApiErrors, getPermission, getRights, + normalizeBody, PermissionResolvable, Permissions, RightResolvable, Rights } from "@fosscord/util"; import { NextFunction, Request, Response } from "express"; -import fs from "fs"; -import path from "path"; -import Ajv from "ajv"; import { AnyValidateFunction } from "ajv/dist/core"; -import addFormats from "ajv-formats"; - -const SchemaPath = path.join(__dirname, "..", "..", "..", "assets", "schemas.json"); -const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" })); - -export const ajv = new Ajv({ - allErrors: true, - parseDate: true, - allowDate: true, - schemas, - coerceTypes: true, - messages: true, - strict: true, - strictRequired: true -}); - -addFormats(ajv); declare global { namespace Express { @@ -58,34 +38,6 @@ export interface RouteOptions { }; } -// Normalizer is introduced to workaround https://github.com/ajv-validator/ajv/issues/1287 -// this removes null values as ajv doesn't treat them as undefined -// normalizeBody allows to handle circular structures without issues -// taken from https://github.com/serverless/serverless/blob/master/lib/classes/ConfigSchemaHandler/index.js#L30 (MIT license) -const normalizeBody = (body: any = {}) => { - const normalizedObjectsSet = new WeakSet(); - const normalizeObject = (object: any) => { - if (normalizedObjectsSet.has(object)) return; - normalizedObjectsSet.add(object); - if (Array.isArray(object)) { - for (const [index, value] of object.entries()) { - if (typeof value === "object") normalizeObject(value); - } - } else { - for (const [key, value] of Object.entries(object)) { - if (value == null) { - if (key === "icon" || key === "avatar" || key === "banner" || key === "splash" || key === "discovery_splash") continue; - delete object[key]; - } else if (typeof value === "object") { - normalizeObject(value); - } - } - } - }; - normalizeObject(body); - return body; -}; - export function route(opts: RouteOptions) { var validate: AnyValidateFunction | undefined; if (opts.body) { diff --git a/api/src/util/index.ts b/src/api/util/index.ts similarity index 100% rename from api/src/util/index.ts rename to src/api/util/index.ts diff --git a/api/src/util/utility/Base64.ts b/src/api/util/utility/Base64.ts similarity index 100% rename from api/src/util/utility/Base64.ts rename to src/api/util/utility/Base64.ts diff --git a/api/src/util/utility/RandomInviteID.ts b/src/api/util/utility/RandomInviteID.ts similarity index 100% rename from api/src/util/utility/RandomInviteID.ts rename to src/api/util/utility/RandomInviteID.ts diff --git a/api/src/util/utility/String.ts b/src/api/util/utility/String.ts similarity index 100% rename from api/src/util/utility/String.ts rename to src/api/util/utility/String.ts diff --git a/api/src/util/utility/captcha.ts b/src/api/util/utility/captcha.ts similarity index 100% rename from api/src/util/utility/captcha.ts rename to src/api/util/utility/captcha.ts diff --git a/api/src/util/utility/ipAddress.ts b/src/api/util/utility/ipAddress.ts similarity index 98% rename from api/src/util/utility/ipAddress.ts rename to src/api/util/utility/ipAddress.ts index 13cc9603..f17b145e 100644 --- a/api/src/util/utility/ipAddress.ts +++ b/src/api/util/utility/ipAddress.ts @@ -65,7 +65,7 @@ export async function IPAnalysis(ip: string): Promise { const { ipdataApiKey } = Config.get().security; if (!ipdataApiKey) return { ...exampleData, ip }; - return (await fetch(`https://api.ipdata.co/${ip}?api-key=${ipdataApiKey}`)).json(); + return (await fetch(`https://api.ipdata.co/${ip}?api-key=${ipdataApiKey}`)).json() as any; // TODO: types } export function isProxy(data: typeof exampleData) { diff --git a/api/src/util/utility/passwordStrength.ts b/src/api/util/utility/passwordStrength.ts similarity index 100% rename from api/src/util/utility/passwordStrength.ts rename to src/api/util/utility/passwordStrength.ts diff --git a/bundle/src/Server.ts b/src/bundle/Server.ts similarity index 100% rename from bundle/src/Server.ts rename to src/bundle/Server.ts diff --git a/src/bundle/index.ts b/src/bundle/index.ts new file mode 100644 index 00000000..960d4dc0 --- /dev/null +++ b/src/bundle/index.ts @@ -0,0 +1,4 @@ +export * from "@fosscord/api"; +export * from "@fosscord/util"; +export * from "@fosscord/gateway"; +export * from "@fosscord/cdn"; \ No newline at end of file diff --git a/bundle/src/start.ts b/src/bundle/start.ts similarity index 92% rename from bundle/src/start.ts rename to src/bundle/start.ts index de3b5848..2a1e6520 100644 --- a/bundle/src/start.ts +++ b/src/bundle/start.ts @@ -1,4 +1,5 @@ // process.env.MONGOMS_DEBUG = "true"; +require('module-alias/register'); import "reflect-metadata"; import cluster, { Worker } from "cluster"; import os from "os"; @@ -13,7 +14,7 @@ var cores = 1; try { cores = Number(process.env.THREADS) || os.cpus().length; } catch { - console.log("[API] Failed to get thread count! Using 1...") + console.log("[API] Failed to get thread count! Using 1..."); } if (cluster.isMaster) { @@ -36,18 +37,16 @@ if (cluster.isMaster) { ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ fosscord-server | ${yellow( - `Pre-release (${ - commit !== null - ? commit.slice(0, 7) - : "Unknown (Git cannot be found)" + `Pre-release (${commit !== null + ? commit.slice(0, 7) + : "Unknown (Git cannot be found)" })` )} -Commit Hash: ${ - commit !== null +Commit Hash: ${commit !== null ? `${cyan(commit)} (${yellow(commit.slice(0, 7))})` : "Unknown (Git cannot be found)" - } + } Cores: ${cyan(os.cpus().length)} (Using ${cores} thread(s).) `) ); diff --git a/bundle/src/stats.ts b/src/bundle/stats.ts similarity index 100% rename from bundle/src/stats.ts rename to src/bundle/stats.ts diff --git a/cdn/src/Server.ts b/src/cdn/Server.ts similarity index 100% rename from cdn/src/Server.ts rename to src/cdn/Server.ts diff --git a/cdn/src/index.ts b/src/cdn/index.ts similarity index 100% rename from cdn/src/index.ts rename to src/cdn/index.ts diff --git a/cdn/src/routes/attachments.ts b/src/cdn/routes/attachments.ts similarity index 100% rename from cdn/src/routes/attachments.ts rename to src/cdn/routes/attachments.ts diff --git a/cdn/src/routes/avatars.ts b/src/cdn/routes/avatars.ts similarity index 100% rename from cdn/src/routes/avatars.ts rename to src/cdn/routes/avatars.ts diff --git a/cdn/src/routes/external.ts b/src/cdn/routes/external.ts similarity index 98% rename from cdn/src/routes/external.ts rename to src/cdn/routes/external.ts index fc12c017..cb17ff9b 100644 --- a/cdn/src/routes/external.ts +++ b/src/cdn/routes/external.ts @@ -3,7 +3,7 @@ import fetch from "node-fetch"; import { HTTPError } from "lambert-server"; import { Snowflake } from "@fosscord/util"; import { storage } from "../util/Storage"; -import FileType, { stream } from "file-type"; +import FileType from "file-type"; import { Config } from "@fosscord/util"; import sharp from "sharp"; diff --git a/cdn/src/routes/guilds.ts b/src/cdn/routes/guilds.ts similarity index 100% rename from cdn/src/routes/guilds.ts rename to src/cdn/routes/guilds.ts diff --git a/cdn/src/routes/ping.ts b/src/cdn/routes/ping.ts similarity index 100% rename from cdn/src/routes/ping.ts rename to src/cdn/routes/ping.ts diff --git a/cdn/src/routes/role-icons.ts b/src/cdn/routes/role-icons.ts similarity index 100% rename from cdn/src/routes/role-icons.ts rename to src/cdn/routes/role-icons.ts diff --git a/cdn/src/start.ts b/src/cdn/start.ts similarity index 91% rename from cdn/src/start.ts rename to src/cdn/start.ts index 71681b40..1fdea22e 100644 --- a/cdn/src/start.ts +++ b/src/cdn/start.ts @@ -1,3 +1,4 @@ +require('module-alias/register') import dotenv from "dotenv"; dotenv.config(); diff --git a/cdn/src/util/FileStorage.ts b/src/cdn/util/FileStorage.ts similarity index 91% rename from cdn/src/util/FileStorage.ts rename to src/cdn/util/FileStorage.ts index 84ecf556..955c570b 100644 --- a/cdn/src/util/FileStorage.ts +++ b/src/cdn/util/FileStorage.ts @@ -1,10 +1,9 @@ import { Storage } from "./Storage"; import fs from "fs"; -import fse from "fs-extra"; import { join, relative, dirname } from "path"; import "missing-native-js-functions"; import { Readable } from "stream"; -import ExifTransformer = require("exif-be-gone"); +import ExifTransformer from "exif-be-gone"; // TODO: split stored files into separate folders named after cloned route @@ -36,7 +35,7 @@ export class FileStorage implements Storage { async set(path: string, value: any) { path = getPath(path); - fse.ensureDirSync(dirname(path)); + if (!fs.existsSync(dirname(path))) fs.mkdirSync(dirname(path)); value = Readable.from(value); const cleaned_file = fs.createWriteStream(path); diff --git a/cdn/src/util/S3Storage.ts b/src/cdn/util/S3Storage.ts similarity index 100% rename from cdn/src/util/S3Storage.ts rename to src/cdn/util/S3Storage.ts diff --git a/cdn/src/util/Storage.ts b/src/cdn/util/Storage.ts similarity index 95% rename from cdn/src/util/Storage.ts rename to src/cdn/util/Storage.ts index 89dd5634..04fbacca 100644 --- a/cdn/src/util/Storage.ts +++ b/src/cdn/util/Storage.ts @@ -1,6 +1,6 @@ import { FileStorage } from "./FileStorage"; import path from "path"; -import fse from "fs-extra"; +import fs from "fs"; import { bgCyan, black } from "picocolors"; import { S3 } from "@aws-sdk/client-s3"; import { S3Storage } from "./S3Storage"; @@ -22,7 +22,7 @@ if (process.env.STORAGE_PROVIDER === "file" || !process.env.STORAGE_PROVIDER) { location = path.join(process.cwd(), "files"); } console.log(`[CDN] storage location: ${bgCyan(`${black(location)}`)}`); - fse.ensureDirSync(location); + if (!fs.existsSync(location)) fs.mkdirSync(location); process.env.STORAGE_LOCATION = location; storage = new FileStorage(); diff --git a/cdn/src/util/index.ts b/src/cdn/util/index.ts similarity index 100% rename from cdn/src/util/index.ts rename to src/cdn/util/index.ts diff --git a/cdn/src/util/multer.ts b/src/cdn/util/multer.ts similarity index 100% rename from cdn/src/util/multer.ts rename to src/cdn/util/multer.ts diff --git a/gateway/src/Server.ts b/src/gateway/Server.ts similarity index 100% rename from gateway/src/Server.ts rename to src/gateway/Server.ts diff --git a/gateway/src/events/Close.ts b/src/gateway/events/Close.ts similarity index 100% rename from gateway/src/events/Close.ts rename to src/gateway/events/Close.ts diff --git a/gateway/src/events/Connection.ts b/src/gateway/events/Connection.ts similarity index 100% rename from gateway/src/events/Connection.ts rename to src/gateway/events/Connection.ts diff --git a/gateway/src/events/Message.ts b/src/gateway/events/Message.ts similarity index 86% rename from gateway/src/events/Message.ts rename to src/gateway/events/Message.ts index b72ffa37..db7dbad2 100644 --- a/gateway/src/events/Message.ts +++ b/src/gateway/events/Message.ts @@ -51,22 +51,22 @@ export async function Message(this: WebSocket, buffer: WS.Data) { return; } - const transaction = Sentry.startTransaction({ - op: OPCODES[data.op], - name: `GATEWAY ${OPCODES[data.op]}`, - data: { - ...data.d, - token: data?.d?.token ? "[Redacted]" : undefined, - }, - }); + // const transaction = Sentry.startTransaction({ + // op: OPCODES[data.op], + // name: `GATEWAY ${OPCODES[data.op]}`, + // data: { + // ...data.d, + // token: data?.d?.token ? "[Redacted]" : undefined, + // }, + // }); try { var ret = await OPCodeHandler.call(this, data); - transaction.finish(); + // transaction.finish(); return ret; } catch (error) { Sentry.captureException(error); - transaction.finish(); + // transaction.finish(); console.error(`Error: Op ${data.op}`, error); // if (!this.CLOSED && this.CLOSING) return this.close(CLOSECODES.Unknown_error); diff --git a/gateway/src/index.ts b/src/gateway/index.ts similarity index 100% rename from gateway/src/index.ts rename to src/gateway/index.ts diff --git a/gateway/src/listener/listener.ts b/src/gateway/listener/listener.ts similarity index 97% rename from gateway/src/listener/listener.ts rename to src/gateway/listener/listener.ts index 5975fbb7..72dd9d5b 100644 --- a/gateway/src/listener/listener.ts +++ b/src/gateway/listener/listener.ts @@ -51,15 +51,17 @@ export async function setupListener(this: WebSocket) { relations: ["channel"], }), Relationship.find({ - from_id: this.user_id, - type: RelationshipType.friends, + where: { + from_id: this.user_id, + type: RelationshipType.friends, + } }), ]); const guilds = members.map((x) => x.guild); const dm_channels = recipients.map((x) => x.channel); - const opts: { acknowledge: boolean; channel?: AMQChannel } = { + const opts: { acknowledge: boolean; channel?: AMQChannel; } = { acknowledge: true, }; this.listen_options = opts; diff --git a/gateway/src/opcodes/Heartbeat.ts b/src/gateway/opcodes/Heartbeat.ts similarity index 100% rename from gateway/src/opcodes/Heartbeat.ts rename to src/gateway/opcodes/Heartbeat.ts diff --git a/gateway/src/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts similarity index 98% rename from gateway/src/opcodes/Identify.ts rename to src/gateway/opcodes/Identify.ts index 903934ce..3c40962c 100644 --- a/gateway/src/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -62,7 +62,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { relations: ["relationships", "relationships.to"], select: [...PrivateUserProjection, "relationships"], }), - ReadState.find({ user_id: this.user_id }), + ReadState.find({ where: { user_id: this.user_id } }), Member.find({ where: { id: this.user_id }, select: MemberPrivateProjection, @@ -87,7 +87,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { // TODO: public user selection }), // save the session and delete it when the websocket is closed - new Session({ + Session.create({ user_id: this.user_id, session_id: session_id, // TODO: check if status is only one of: online, dnd, offline, idle @@ -100,7 +100,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { }, activities: [], }).save(), - Application.findOne({ id: this.user_id }), + Application.findOne({ where: { id: this.user_id } }), ]); if (!user) return this.close(CLOSECODES.Authentication_failed); diff --git a/gateway/src/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts similarity index 91% rename from gateway/src/opcodes/LazyRequest.ts rename to src/gateway/opcodes/LazyRequest.ts index b0332969..82342224 100644 --- a/gateway/src/opcodes/LazyRequest.ts +++ b/src/gateway/opcodes/LazyRequest.ts @@ -1,12 +1,7 @@ -import { getPermission, listenEvent, Member, Role, Session } from "@fosscord/util"; +import { getDatabase, getPermission, listenEvent, Member, Role, Session } from "@fosscord/util"; +import { WebSocket, Payload, handlePresenceUpdate, OPCODES, Send } from "@fosscord/gateway"; import { LazyRequest } from "../schema/LazyRequest"; -import { Send } from "../util/Send"; -import { OPCODES } from "../util/Constants"; -import { WebSocket, Payload, handlePresenceUpdate } from "@fosscord/gateway"; import { check } from "./instanceOf"; -import "missing-native-js-functions"; -import { getRepository } from "typeorm"; -import "missing-native-js-functions"; // TODO: only show roles/members that have access to this channel // TODO: config: to list all members (even those who are offline) sorted by role, or just those who are online @@ -20,7 +15,7 @@ async function getMembers(guild_id: string, range: [number, number]) { let members: Member[] = []; try { - members = await getRepository(Member) + members = await getDatabase()!.getRepository(Member) .createQueryBuilder("member") .where("member.guild_id = :guild_id", { guild_id }) .leftJoinAndSelect("member.roles", "role") @@ -34,8 +29,8 @@ async function getMembers(guild_id: string, range: [number, number]) { .orderBy("role.position", "DESC") .addOrderBy("_status", "DESC") .addOrderBy("user.username", "ASC") - .skip(Number(range[0]) || 0) - .take(Number(range[1]) || 100) + .offset(Number(range[0]) || 0) + .limit(Number(range[1]) || 100) .getMany(); } catch (e) { diff --git a/gateway/src/opcodes/PresenceUpdate.ts b/src/gateway/opcodes/PresenceUpdate.ts similarity index 100% rename from gateway/src/opcodes/PresenceUpdate.ts rename to src/gateway/opcodes/PresenceUpdate.ts diff --git a/gateway/src/opcodes/RequestGuildMembers.ts b/src/gateway/opcodes/RequestGuildMembers.ts similarity index 100% rename from gateway/src/opcodes/RequestGuildMembers.ts rename to src/gateway/opcodes/RequestGuildMembers.ts diff --git a/gateway/src/opcodes/Resume.ts b/src/gateway/opcodes/Resume.ts similarity index 100% rename from gateway/src/opcodes/Resume.ts rename to src/gateway/opcodes/Resume.ts diff --git a/gateway/src/opcodes/VoiceStateUpdate.ts b/src/gateway/opcodes/VoiceStateUpdate.ts similarity index 96% rename from gateway/src/opcodes/VoiceStateUpdate.ts rename to src/gateway/opcodes/VoiceStateUpdate.ts index ec4b1a92..fa63f7fc 100644 --- a/gateway/src/opcodes/VoiceStateUpdate.ts +++ b/src/gateway/opcodes/VoiceStateUpdate.ts @@ -49,7 +49,7 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) { if (body.guild_id === null) body.guild_id = voiceState.guild_id; voiceState.assign(body); } catch (error) { - voiceState = new VoiceState({ + voiceState = VoiceState.create({ ...body, user_id: this.user_id, deaf: false, @@ -68,7 +68,7 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) { where: { id: voiceState.user_id, guild_id: voiceState.guild_id }, relations: ["user", "roles"], }); - + //If the session changed we generate a new token if (voiceState.session_id !== this.session_id) voiceState.token = genVoiceToken(); @@ -87,7 +87,7 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) { //If it's null it means that we are leaving the channel and this event is not needed if (voiceState.channel_id !== null) { - const guild = await Guild.findOne({ id: voiceState.guild_id }); + const guild = await Guild.findOne({ where: { id: voiceState.guild_id } }); const regions = Config.get().regions; let guildRegion: Region; if (guild && guild.region) { diff --git a/gateway/src/opcodes/experiments.json b/src/gateway/opcodes/experiments.json similarity index 100% rename from gateway/src/opcodes/experiments.json rename to src/gateway/opcodes/experiments.json diff --git a/gateway/src/opcodes/index.ts b/src/gateway/opcodes/index.ts similarity index 100% rename from gateway/src/opcodes/index.ts rename to src/gateway/opcodes/index.ts diff --git a/gateway/src/opcodes/instanceOf.ts b/src/gateway/opcodes/instanceOf.ts similarity index 100% rename from gateway/src/opcodes/instanceOf.ts rename to src/gateway/opcodes/instanceOf.ts diff --git a/gateway/src/schema/Activity.ts b/src/gateway/schema/Activity.ts similarity index 100% rename from gateway/src/schema/Activity.ts rename to src/gateway/schema/Activity.ts diff --git a/gateway/src/schema/Identify.ts b/src/gateway/schema/Identify.ts similarity index 100% rename from gateway/src/schema/Identify.ts rename to src/gateway/schema/Identify.ts diff --git a/gateway/src/schema/LazyRequest.ts b/src/gateway/schema/LazyRequest.ts similarity index 100% rename from gateway/src/schema/LazyRequest.ts rename to src/gateway/schema/LazyRequest.ts diff --git a/gateway/src/schema/VoiceStateUpdateSchema.ts b/src/gateway/schema/VoiceStateUpdateSchema.ts similarity index 100% rename from gateway/src/schema/VoiceStateUpdateSchema.ts rename to src/gateway/schema/VoiceStateUpdateSchema.ts diff --git a/gateway/src/start.ts b/src/gateway/start.ts similarity index 89% rename from gateway/src/start.ts rename to src/gateway/start.ts index 09a54751..90d7f34e 100644 --- a/gateway/src/start.ts +++ b/src/gateway/start.ts @@ -1,3 +1,4 @@ +require('module-alias/register'); process.on("uncaughtException", console.error); process.on("unhandledRejection", console.error); diff --git a/gateway/src/util/Constants.ts b/src/gateway/util/Constants.ts similarity index 100% rename from gateway/src/util/Constants.ts rename to src/gateway/util/Constants.ts diff --git a/gateway/src/util/Heartbeat.ts b/src/gateway/util/Heartbeat.ts similarity index 100% rename from gateway/src/util/Heartbeat.ts rename to src/gateway/util/Heartbeat.ts diff --git a/gateway/src/util/Send.ts b/src/gateway/util/Send.ts similarity index 100% rename from gateway/src/util/Send.ts rename to src/gateway/util/Send.ts diff --git a/gateway/src/util/SessionUtils.ts b/src/gateway/util/SessionUtils.ts similarity index 100% rename from gateway/src/util/SessionUtils.ts rename to src/gateway/util/SessionUtils.ts diff --git a/gateway/src/util/WebSocket.ts b/src/gateway/util/WebSocket.ts similarity index 100% rename from gateway/src/util/WebSocket.ts rename to src/gateway/util/WebSocket.ts diff --git a/gateway/src/util/index.ts b/src/gateway/util/index.ts similarity index 100% rename from gateway/src/util/index.ts rename to src/gateway/util/index.ts diff --git a/util/src/dtos/DmChannelDTO.ts b/src/util/dtos/DmChannelDTO.ts similarity index 100% rename from util/src/dtos/DmChannelDTO.ts rename to src/util/dtos/DmChannelDTO.ts diff --git a/util/src/dtos/UserDTO.ts b/src/util/dtos/UserDTO.ts similarity index 100% rename from util/src/dtos/UserDTO.ts rename to src/util/dtos/UserDTO.ts diff --git a/util/src/dtos/index.ts b/src/util/dtos/index.ts similarity index 100% rename from util/src/dtos/index.ts rename to src/util/dtos/index.ts diff --git a/util/src/entities/Application.ts b/src/util/entities/Application.ts similarity index 100% rename from util/src/entities/Application.ts rename to src/util/entities/Application.ts diff --git a/util/src/entities/Attachment.ts b/src/util/entities/Attachment.ts similarity index 100% rename from util/src/entities/Attachment.ts rename to src/util/entities/Attachment.ts diff --git a/util/src/entities/AuditLog.ts b/src/util/entities/AuditLog.ts similarity index 100% rename from util/src/entities/AuditLog.ts rename to src/util/entities/AuditLog.ts diff --git a/util/src/entities/BackupCodes.ts b/src/util/entities/BackupCodes.ts similarity index 100% rename from util/src/entities/BackupCodes.ts rename to src/util/entities/BackupCodes.ts diff --git a/util/src/entities/Ban.ts b/src/util/entities/Ban.ts similarity index 100% rename from util/src/entities/Ban.ts rename to src/util/entities/Ban.ts diff --git a/src/util/entities/BaseClass.ts b/src/util/entities/BaseClass.ts new file mode 100644 index 00000000..d5a7c2bf --- /dev/null +++ b/src/util/entities/BaseClass.ts @@ -0,0 +1,52 @@ +import "reflect-metadata"; +import { BaseEntity, BeforeInsert, BeforeUpdate, FindOptionsWhere, ObjectIdColumn, PrimaryColumn } from "typeorm"; +import { Snowflake } from "../util/Snowflake"; +import "missing-native-js-functions"; +import { getDatabase } from ".."; +import { OrmUtils } from "@fosscord/util"; + +export class BaseClassWithoutId extends BaseEntity { + private get construct(): any { + return this.constructor; + } + + private get metadata() { + return getDatabase()?.getMetadata(this.construct); + } + + assign(props: any) { + OrmUtils.mergeDeep(this, props); + return this; + } + + toJSON(): any { + return Object.fromEntries( + this.metadata!.columns // @ts-ignore + .map((x) => [x.propertyName, this[x.propertyName]]) // @ts-ignore + .concat(this.metadata.relations.map((x) => [x.propertyName, this[x.propertyName]])) + ); + } + + static increment(conditions: FindOptionsWhere, propertyPath: string, value: number | string) { + const repository = this.getRepository(); + return repository.increment(conditions, propertyPath, value); + } + + static decrement(conditions: FindOptionsWhere, propertyPath: string, value: number | string) { + const repository = this.getRepository(); + return repository.decrement(conditions, propertyPath, value); + } +} + +export const PrimaryIdColumn = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryColumn; + +export class BaseClass extends BaseClassWithoutId { + @PrimaryIdColumn() + id: string; + + @BeforeUpdate() + @BeforeInsert() + do_validate() { + if (!this.id) this.id = Snowflake.generate(); + } +} diff --git a/util/src/entities/Categories.ts b/src/util/entities/Categories.ts similarity index 100% rename from util/src/entities/Categories.ts rename to src/util/entities/Categories.ts diff --git a/util/src/entities/Channel.ts b/src/util/entities/Channel.ts similarity index 92% rename from util/src/entities/Channel.ts rename to src/util/entities/Channel.ts index 10fa03ff..577b627e 100644 --- a/util/src/entities/Channel.ts +++ b/src/util/entities/Channel.ts @@ -58,7 +58,7 @@ export class Channel extends BaseClass { recipients?: Recipient[]; @Column({ nullable: true }) - last_message_id: string; + last_message_id?: string; @Column({ nullable: true }) @RelationId((channel: Channel) => channel.guild) @@ -81,7 +81,7 @@ export class Channel extends BaseClass { // for group DMs and owned custom channel types @Column({ nullable: true }) @RelationId((channel: Channel) => channel.owner) - owner_id: string; + owner_id?: string; @JoinColumn({ name: "owner_id" }) @ManyToOne(() => User) @@ -169,7 +169,7 @@ export class Channel extends BaseClass { } if (!opts?.skipNameChecks) { - const guild = await Guild.findOneOrFail({ id: channel.guild_id }); + const guild = await Guild.findOneOrFail({ where: { id: channel.guild_id } }); if (!guild.features.includes("ALLOW_INVALID_CHANNEL_NAMES") && channel.name) { for (var character of InvisibleCharacters) if (channel.name.includes(character)) @@ -202,7 +202,7 @@ export class Channel extends BaseClass { case ChannelType.GUILD_NEWS: case ChannelType.GUILD_VOICE: if (channel.parent_id && !opts?.skipExistsCheck) { - const exists = await Channel.findOneOrFail({ id: channel.parent_id }); + const exists = await Channel.findOneOrFail({ where: { id: channel.parent_id } }); if (!exists) throw new HTTPError("Parent id channel doesn't exist", 400); if (exists.guild_id !== channel.guild_id) throw new HTTPError("The category channel needs to be in the guild"); @@ -230,7 +230,7 @@ export class Channel extends BaseClass { }; await Promise.all([ - new Channel(channel).save(), + Channel.create(channel).save(), !opts?.skipEventEmit ? emitEvent({ event: "CHANNEL_CREATE", @@ -281,15 +281,15 @@ export class Channel extends BaseClass { if (channel == null) { name = trimSpecial(name); - channel = await new Channel({ + channel = await Channel.create({ name, type, - owner_id: type === ChannelType.DM ? undefined : null, // 1:1 DMs are ownerless in fosscord-server + owner_id: undefined, created_at: new Date(), - last_message_id: null, + last_message_id: undefined, recipients: channelRecipients.map( (x) => - new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) }) + Recipient.create({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) }) ), nsfw: false, }).save(); diff --git a/util/src/entities/ClientRelease.ts b/src/util/entities/ClientRelease.ts similarity index 100% rename from util/src/entities/ClientRelease.ts rename to src/util/entities/ClientRelease.ts diff --git a/util/src/entities/Config.ts b/src/util/entities/Config.ts similarity index 100% rename from util/src/entities/Config.ts rename to src/util/entities/Config.ts diff --git a/util/src/entities/ConnectedAccount.ts b/src/util/entities/ConnectedAccount.ts similarity index 100% rename from util/src/entities/ConnectedAccount.ts rename to src/util/entities/ConnectedAccount.ts diff --git a/util/src/entities/Emoji.ts b/src/util/entities/Emoji.ts similarity index 100% rename from util/src/entities/Emoji.ts rename to src/util/entities/Emoji.ts diff --git a/util/src/entities/Encryption.ts b/src/util/entities/Encryption.ts similarity index 70% rename from util/src/entities/Encryption.ts rename to src/util/entities/Encryption.ts index 3b82ff84..b597b90a 100644 --- a/util/src/entities/Encryption.ts +++ b/src/util/entities/Encryption.ts @@ -14,22 +14,22 @@ import { DmChannelDTO } from "../dtos"; @Entity("security_settings") export class SecuritySettings extends BaseClass { - @Column({nullable: true}) - guild_id: Snowflake; + @Column({ nullable: true }) + guild_id: string; - @Column({nullable: true}) - channel_id: Snowflake; + @Column({ nullable: true }) + channel_id: string; - @Column() - encryption_permission_mask: BitField; + @Column() + encryption_permission_mask: number; - @Column() - allowed_algorithms: string[]; + @Column({ type: "simple-array" }) + allowed_algorithms: string[]; - @Column() - current_algorithm: string; + @Column() + current_algorithm: string; - @Column({nullable: true}) - used_since_message: Snowflake; + @Column({ nullable: true }) + used_since_message: string; } diff --git a/util/src/entities/Guild.ts b/src/util/entities/Guild.ts similarity index 97% rename from util/src/entities/Guild.ts rename to src/util/entities/Guild.ts index 143cb542..2ce7c213 100644 --- a/util/src/entities/Guild.ts +++ b/src/util/entities/Guild.ts @@ -86,7 +86,7 @@ export class Guild extends BaseClass { //TODO: https://discord.com/developers/docs/resources/guild#guild-object-guild-features @Column({ nullable: true }) - primary_category_id: number; + primary_category_id?: string; // TODO: this was number? @Column({ nullable: true }) icon?: string; @@ -285,7 +285,7 @@ export class Guild extends BaseClass { }) { const guild_id = Snowflake.generate(); - const guild = await new Guild({ + const guild = await Guild.create({ name: body.name || "Fosscord", icon: await handleFile(`/icons/${guild_id}`, body.icon as string), region: Config.get().regions.default, @@ -294,7 +294,7 @@ export class Guild extends BaseClass { default_message_notifications: 1, // defaults effect: setting the push default at mentions-only will save a lot explicit_content_filter: 0, features: Config.get().guild.defaultFeatures, - primary_category_id: null, + primary_category_id: undefined, id: guild_id, max_members: 250000, max_presences: 250000, @@ -320,7 +320,7 @@ export class Guild extends BaseClass { // we have to create the role _after_ the guild because else we would get a "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed" error // TODO: make the @everyone a pseudorole that is dynamically generated at runtime so we can save storage - await new Role({ + await Role.create({ id: guild_id, guild_id: guild_id, color: 0, @@ -331,8 +331,8 @@ export class Guild extends BaseClass { name: "@everyone", permissions: String("2251804225"), position: 0, - icon: null, - unicode_emoji: null + icon: undefined, + unicode_emoji: undefined }).save(); if (!body.channels || !body.channels.length) body.channels = [{ id: "01", type: 0, name: "general", nsfw: false }]; diff --git a/util/src/entities/Invite.ts b/src/util/entities/Invite.ts similarity index 95% rename from util/src/entities/Invite.ts rename to src/util/entities/Invite.ts index 6ac64ddc..4f36f247 100644 --- a/util/src/entities/Invite.ts +++ b/src/util/entities/Invite.ts @@ -52,7 +52,7 @@ export class Invite extends BaseClassWithoutId { @Column({ nullable: true }) @RelationId((invite: Invite) => invite.inviter) - inviter_id: string; + inviter_id?: string; @JoinColumn({ name: "inviter_id" }) @ManyToOne(() => User) @@ -75,7 +75,7 @@ export class Invite extends BaseClassWithoutId { vanity_url?: boolean; static async joinGuild(user_id: string, code: string) { - const invite = await Invite.findOneOrFail({ code }); + const invite = await Invite.findOneOrFail({ where: { code } }); if (invite.uses++ >= invite.max_uses && invite.max_uses !== 0) await Invite.delete({ code }); else await invite.save(); diff --git a/util/src/entities/Member.ts b/src/util/entities/Member.ts similarity index 89% rename from util/src/entities/Member.ts rename to src/util/entities/Member.ts index 03698453..d7bcefea 100644 --- a/util/src/entities/Member.ts +++ b/src/util/entities/Member.ts @@ -1,6 +1,8 @@ import { PublicUser, User } from "./User"; import { Message } from "./Message"; import { + BeforeInsert, + BeforeUpdate, Column, Entity, Index, @@ -73,17 +75,6 @@ export class Member extends BaseClassWithoutId { @Column({ nullable: true }) nick?: string; - setNick(val: string) { - - if (val) { - val = val.split("\n").join(""); - val = val.split("\t").join(""); - if (BannedWords.find(val)) throw FieldErrors({ nick: { message: "Bad nickname", code: "INVALID_NICKNAME" } }); - } - - this.nick = val; - } - @JoinTable({ name: "member_roles", joinColumn: { name: "index", referencedColumnName: "index" }, @@ -129,8 +120,18 @@ export class Member extends BaseClassWithoutId { // @Column({ type: "simple-json" }) // read_state: ReadState; + @BeforeUpdate() + @BeforeInsert() + validate() { + if (this.nick) { + this.nick = this.nick.split("\n").join(""); + this.nick = this.nick.split("\t").join(""); + if (BannedWords.find(this.nick)) throw FieldErrors({ nick: { message: "Bad nickname", code: "INVALID_NICKNAME" } }); + } + } + static async IsInGuildOrFail(user_id: string, guild_id: string) { - if (await Member.count({ id: user_id, guild: { id: guild_id } })) return true; + if (await Member.count({ where: { id: user_id, guild: { id: guild_id } } })) return true; throw new HTTPError("You are not member of this guild", 403); } @@ -168,11 +169,12 @@ export class Member extends BaseClassWithoutId { Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user", "roles"], // we don't want to load the role objects just the ids - select: ["index", "roles.id"], + //@ts-ignore + select: ["index", "roles.id"], // TODO fix type }), Role.findOneOrFail({ where: { id: role_id, guild_id }, select: ["id"] }), ]); - member.roles.push(new Role({ id: role_id })); + member.roles.push(Role.create({ id: role_id })); await Promise.all([ member.save(), @@ -194,9 +196,10 @@ export class Member extends BaseClassWithoutId { Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user", "roles"], // we don't want to load the role objects just the ids - select: ["roles.id", "index"], + //@ts-ignore + select: ["roles.id", "index"], // TODO: fix type }), - await Role.findOneOrFail({ id: role_id, guild_id }), + await Role.findOneOrFail({ where: { id: role_id, guild_id } }), ]); member.roles = member.roles.filter((x) => x.id == role_id); @@ -246,7 +249,7 @@ export class Member extends BaseClassWithoutId { throw DiscordApiErrors.USER_BANNED; } const { maxGuilds } = Config.get().limits.user; - const guild_count = await Member.count({ id: user_id }); + const guild_count = await Member.count({ where: { id: user_id } }); if (guild_count >= maxGuilds) { throw new HTTPError(`You are at the ${maxGuilds} server limit.`, 403); } @@ -258,7 +261,7 @@ export class Member extends BaseClassWithoutId { relations: [...PublicGuildRelations, "system_channel"], }); - if (await Member.count({ id: user.id, guild: { id: guild_id } })) + if (await Member.count({ where: { id: user.id, guild: { id: guild_id } } })) throw new HTTPError("You are already a member of this guild", 400); const member = { @@ -274,12 +277,18 @@ export class Member extends BaseClassWithoutId { }; await Promise.all([ - new Member({ + Member.create({ ...member, - roles: [new Role({ id: guild_id })], + roles: [Role.create({ id: guild_id })], // read_state: {}, settings: { - channel_overrides: [], + guild_id: null, + mute_config: null, + mute_scheduled_events: false, + flags: 0, + hide_muted_channels: false, + notify_highlights: 0, + channel_overrides: {}, message_notifications: 0, mobile_push: true, muted: false, @@ -318,13 +327,12 @@ export class Member extends BaseClassWithoutId { if (guild.system_channel_id) { // send welcome message - const message = new Message({ + const message = Message.create({ type: 7, guild_id: guild.id, channel_id: guild.system_channel_id, author: user, timestamp: new Date(), - reactions: [], attachments: [], embeds: [], @@ -385,7 +393,7 @@ export const DefaultUserGuildSettings: UserGuildSettings = { suppress_roles: false, version: 453, // ? guild_id: null, -} +}; export interface MuteConfig { end_time: number; diff --git a/util/src/entities/Message.ts b/src/util/entities/Message.ts similarity index 94% rename from util/src/entities/Message.ts rename to src/util/entities/Message.ts index 6ea5c4aa..3a3dd5e4 100644 --- a/util/src/entities/Message.ts +++ b/src/util/entities/Message.ts @@ -5,6 +5,8 @@ import { Channel } from "./Channel"; import { InteractionType } from "../interfaces/Interaction"; import { Application } from "./Application"; import { + BeforeInsert, + BeforeUpdate, Column, CreateDateColumn, Entity, @@ -23,6 +25,7 @@ import { Sticker } from "./Sticker"; import { Attachment } from "./Attachment"; import { BannedWords } from "../util"; import { HTTPError } from "lambert-server"; +import { ValidatorConstraint } from "class-validator"; export enum MessageType { DEFAULT = 0, @@ -58,7 +61,7 @@ export class Message extends BaseClass { @Column({ nullable: true }) @RelationId((message: Message) => message.channel) @Index() - channel_id: string; + channel_id?: string; @JoinColumn({ name: "channel_id" }) @ManyToOne(() => Channel, { @@ -79,7 +82,7 @@ export class Message extends BaseClass { @Column({ nullable: true }) @RelationId((message: Message) => message.author) @Index() - author_id: string; + author_id?: string; @JoinColumn({ name: "author_id", referencedColumnName: "id" }) @ManyToOne(() => User, { @@ -89,7 +92,7 @@ export class Message extends BaseClass { @Column({ nullable: true }) @RelationId((message: Message) => message.member) - member_id: string; + member_id?: string; @JoinColumn({ name: "member_id", referencedColumnName: "id" }) @ManyToOne(() => User, { @@ -99,7 +102,7 @@ export class Message extends BaseClass { @Column({ nullable: true }) @RelationId((message: Message) => message.webhook) - webhook_id: string; + webhook_id?: string; @JoinColumn({ name: "webhook_id" }) @ManyToOne(() => Webhook) @@ -107,7 +110,7 @@ export class Message extends BaseClass { @Column({ nullable: true }) @RelationId((message: Message) => message.application) - application_id: string; + application_id?: string; @JoinColumn({ name: "application_id" }) @ManyToOne(() => Application) @@ -116,17 +119,12 @@ export class Message extends BaseClass { @Column({ nullable: true, type: process.env.PRODUCTION ? "longtext" : undefined }) content?: string; - setContent(val: string) { - if (val && BannedWords.find(val)) throw new HTTPError("Message was blocked by automatic moderation", 200000); - this.content = val; - } - @Column() @CreateDateColumn() timestamp: Date; @Column({ nullable: true }) - edited_timestamp: Date; + edited_timestamp?: Date; @Column({ nullable: true }) tts?: boolean; @@ -179,6 +177,7 @@ export class Message extends BaseClass { @Column({ nullable: true }) flags?: string; + @Column({ type: "simple-json", nullable: true }) message_reference?: { message_id: string; @@ -201,6 +200,14 @@ export class Message extends BaseClass { @Column({ type: "simple-json", nullable: true }) components?: MessageComponent[]; + + @BeforeUpdate() + @BeforeInsert() + validate() { + if (this.content) { + if (BannedWords.find(this.content)) throw new HTTPError("Message was blocked by automatic moderation", 200000); + } + } } export interface MessageComponent { diff --git a/util/src/entities/Migration.ts b/src/util/entities/Migration.ts similarity index 100% rename from util/src/entities/Migration.ts rename to src/util/entities/Migration.ts diff --git a/util/src/entities/Note.ts b/src/util/entities/Note.ts similarity index 100% rename from util/src/entities/Note.ts rename to src/util/entities/Note.ts diff --git a/util/src/entities/RateLimit.ts b/src/util/entities/RateLimit.ts similarity index 100% rename from util/src/entities/RateLimit.ts rename to src/util/entities/RateLimit.ts diff --git a/util/src/entities/ReadState.ts b/src/util/entities/ReadState.ts similarity index 100% rename from util/src/entities/ReadState.ts rename to src/util/entities/ReadState.ts diff --git a/util/src/entities/Recipient.ts b/src/util/entities/Recipient.ts similarity index 100% rename from util/src/entities/Recipient.ts rename to src/util/entities/Recipient.ts diff --git a/util/src/entities/Relationship.ts b/src/util/entities/Relationship.ts similarity index 100% rename from util/src/entities/Relationship.ts rename to src/util/entities/Relationship.ts diff --git a/util/src/entities/Role.ts b/src/util/entities/Role.ts similarity index 95% rename from util/src/entities/Role.ts rename to src/util/entities/Role.ts index 4b721b5b..d87b835f 100644 --- a/util/src/entities/Role.ts +++ b/src/util/entities/Role.ts @@ -37,10 +37,10 @@ export class Role extends BaseClass { position: number; @Column({ nullable: true }) - icon: string; + icon?: string; @Column({ nullable: true }) - unicode_emoji: string; + unicode_emoji?: string; @Column({ type: "simple-json", nullable: true }) tags?: { diff --git a/util/src/entities/Session.ts b/src/util/entities/Session.ts similarity index 100% rename from util/src/entities/Session.ts rename to src/util/entities/Session.ts diff --git a/util/src/entities/Sticker.ts b/src/util/entities/Sticker.ts similarity index 100% rename from util/src/entities/Sticker.ts rename to src/util/entities/Sticker.ts diff --git a/util/src/entities/StickerPack.ts b/src/util/entities/StickerPack.ts similarity index 100% rename from util/src/entities/StickerPack.ts rename to src/util/entities/StickerPack.ts diff --git a/util/src/entities/Team.ts b/src/util/entities/Team.ts similarity index 100% rename from util/src/entities/Team.ts rename to src/util/entities/Team.ts diff --git a/util/src/entities/TeamMember.ts b/src/util/entities/TeamMember.ts similarity index 100% rename from util/src/entities/TeamMember.ts rename to src/util/entities/TeamMember.ts diff --git a/util/src/entities/Template.ts b/src/util/entities/Template.ts similarity index 100% rename from util/src/entities/Template.ts rename to src/util/entities/Template.ts diff --git a/util/src/entities/User.ts b/src/util/entities/User.ts similarity index 89% rename from util/src/entities/User.ts rename to src/util/entities/User.ts index 35aeea52..84a8a674 100644 --- a/util/src/entities/User.ts +++ b/src/util/entities/User.ts @@ -1,4 +1,4 @@ -import { Column, Entity, FindOneOptions, JoinColumn, OneToMany } from "typeorm"; +import { BeforeInsert, BeforeUpdate, Column, Entity, FindOneOptions, JoinColumn, OneToMany } from "typeorm"; import { BaseClass } from "./BaseClass"; import { BitField } from "../util/BitField"; import { Relationship } from "./Relationship"; @@ -59,23 +59,9 @@ export class User extends BaseClass { @Column() username: string; // username max length 32, min 2 (should be configurable) - setUsername(val: string) { - if (BannedWords.find(val)) throw FieldErrors({ username: { message: "Bad username", code: "INVALID_USERNAME" } }); - this.username = val; - } - @Column() discriminator: string; // opaque string: 4 digits on discord.com - setDiscriminator(val: string) { - const number = Number(val); - if (val.length > 4) throw new Error("invalid discriminator"); - if (isNaN(number)) throw new Error("invalid discriminator"); - if (number <= 0 || number >= 10000) throw new Error("discriminator must be between 1 and 9999"); - val = Number(val).toString(); - this.discriminator = val.toString().padStart(4, "0"); - } - @Column({ nullable: true }) avatar?: string; // hash of the user avatar @@ -139,13 +125,6 @@ export class User extends BaseClass { @Column({ nullable: true, select: false }) email?: string; // email of the user - setEmail(val?: string) { - val = adjustEmail(val); - if (!val) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } }); - if (!val.match(/([a-z\d.-]{3,})@([a-z\d.-]+).([a-z]{2,})/g)) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } }); - this.email = val; - } - @Column() flags: string; // UserFlags @@ -194,6 +173,22 @@ export class User extends BaseClass { @Column({ type: "simple-json", select: false }) extended_settings: string; + @BeforeUpdate() + @BeforeInsert() + validate() { + this.email = adjustEmail(this.email); + if (!this.email) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } }); + if (!this.email.match(/([a-z\d.-]{3,})@([a-z\d.-]+).([a-z]{2,})/g)) throw FieldErrors({ email: { message: "Invalid email", code: "EMAIL_INVALID" } }); + + const discrim = Number(this.discriminator); + if (this.discriminator.length > 4) throw FieldErrors({ email: { message: "Discriminator cannot be more than 4 digits.", code: "DISCRIMINATOR_INVALID" } }); + if (isNaN(discrim)) throw FieldErrors({ email: { message: "Discriminator must be a number.", code: "DISCRIMINATOR_INVALID" } }); + if (discrim <= 0 || discrim >= 10000) throw FieldErrors({ email: { message: "Discriminator must be a number.", code: "DISCRIMINATOR_INVALID" } }); + this.discriminator = discrim.toString().padStart(4, "0"); + + if (BannedWords.find(this.username)) throw FieldErrors({ username: { message: "Bad username", code: "INVALID_USERNAME" } }); + } + toPublicUser() { const user: any = {}; PublicUserProjection.forEach((x) => { @@ -203,13 +198,12 @@ export class User extends BaseClass { } static async getPublicUser(user_id: string, opts?: FindOneOptions) { - return await User.findOneOrFail( - { id: user_id }, - { - ...opts, - select: [...PublicUserProjection, ...(opts?.select || [])], - } - ); + return await User.findOneOrFail({ + where: { id: user_id }, + ...opts, + //@ts-ignore + select: [...PublicUserProjection, ...(opts?.select || [])], // TODO: fix + }); } private static async generateDiscriminator(username: string): Promise { @@ -273,7 +267,7 @@ export class User extends BaseClass { // if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false const language = req.language === "en" ? "en-US" : req.language || "en-US"; - const user = new User({ + const user = User.create({ created_at: new Date(), username: username, discriminator, @@ -293,7 +287,7 @@ export class User extends BaseClass { email: email, rights: Config.get().security.defaultRights, nsfw_allowed: true, // TODO: depending on age - public_flags: "0", + public_flags: 0, flags: "0", // TODO: generate data: { hash: password, @@ -302,9 +296,8 @@ export class User extends BaseClass { settings: { ...defaultSettings, locale: language }, purchased_flags: 5, // TODO: idk what the values for this are premium_usage_flags: 2, // TODO: idk what the values for this are - extended_settings: {}, + extended_settings: "", // TODO: was {} fingerprints: [], - notes: {}, }); await user.save(); diff --git a/util/src/entities/VoiceState.ts b/src/util/entities/VoiceState.ts similarity index 100% rename from util/src/entities/VoiceState.ts rename to src/util/entities/VoiceState.ts diff --git a/util/src/entities/Webhook.ts b/src/util/entities/Webhook.ts similarity index 100% rename from util/src/entities/Webhook.ts rename to src/util/entities/Webhook.ts diff --git a/util/src/entities/index.ts b/src/util/entities/index.ts similarity index 100% rename from util/src/entities/index.ts rename to src/util/entities/index.ts diff --git a/src/util/imports/OrmUtils.ts b/src/util/imports/OrmUtils.ts new file mode 100644 index 00000000..68a1932c --- /dev/null +++ b/src/util/imports/OrmUtils.ts @@ -0,0 +1,96 @@ +//source: https://github.com/typeorm/typeorm/blob/master/src/util/OrmUtils.ts +export class OrmUtils { + // Checks if it's an object made by Object.create(null), {} or new Object() + private static isPlainObject(item: any) { + if (item === null || item === undefined) { + return false; + } + + return !item.constructor || item.constructor === Object; + } + + private static mergeArrayKey(target: any, key: number, value: any, memo: Map) { + // Have we seen this before? Prevent infinite recursion. + if (memo.has(value)) { + target[key] = memo.get(value); + return; + } + + if (value instanceof Promise) { + // Skip promises entirely. + // This is a hold-over from the old code & is because we don't want to pull in + // the lazy fields. Ideally we'd remove these promises via another function first + // but for now we have to do it here. + return; + } + + if (!this.isPlainObject(value) && !Array.isArray(value)) { + target[key] = value; + return; + } + + if (!target[key]) { + target[key] = Array.isArray(value) ? [] : {}; + } + + memo.set(value, target[key]); + this.merge(target[key], value, memo); + memo.delete(value); + } + + private static mergeObjectKey(target: any, key: string, value: any, memo: Map) { + // Have we seen this before? Prevent infinite recursion. + if (memo.has(value)) { + Object.assign(target, { [key]: memo.get(value) }); + return; + } + + if (value instanceof Promise) { + // Skip promises entirely. + // This is a hold-over from the old code & is because we don't want to pull in + // the lazy fields. Ideally we'd remove these promises via another function first + // but for now we have to do it here. + return; + } + + if (!this.isPlainObject(value) && !Array.isArray(value)) { + Object.assign(target, { [key]: value }); + return; + } + + if (!target[key]) { + Object.assign(target, { [key]: value }); + } + + memo.set(value, target[key]); + this.merge(target[key], value, memo); + memo.delete(value); + } + + private static merge(target: any, source: any, memo: Map = new Map()): any { + if (Array.isArray(target) && Array.isArray(source)) { + for (let key = 0; key < source.length; key++) { + this.mergeArrayKey(target, key, source[key], memo); + } + } else { + for (const key of Object.keys(source)) { + this.mergeObjectKey(target, key, source[key], memo); + } + } + } + + /** + * Deep Object.assign. + */ + static mergeDeep(target: any, ...sources: any[]): any { + if (!sources.length) { + return target; + } + + for (const source of sources) { + OrmUtils.merge(target, source); + } + + return target; + } +} \ No newline at end of file diff --git a/src/util/imports/index.ts b/src/util/imports/index.ts new file mode 100644 index 00000000..5d9bfb5f --- /dev/null +++ b/src/util/imports/index.ts @@ -0,0 +1 @@ +export * from "./OrmUtils"; \ No newline at end of file diff --git a/util/src/index.ts b/src/util/index.ts similarity index 74% rename from util/src/index.ts rename to src/util/index.ts index 52117302..385070a3 100644 --- a/util/src/index.ts +++ b/src/util/index.ts @@ -4,4 +4,5 @@ export * from "./util/index"; export * from "./interfaces/index"; export * from "./entities/index"; export * from "./dtos/index"; -export * from "./schemas"; \ No newline at end of file +export * from "./schemas"; +export * from "./imports"; \ No newline at end of file diff --git a/util/src/interfaces/Activity.ts b/src/util/interfaces/Activity.ts similarity index 100% rename from util/src/interfaces/Activity.ts rename to src/util/interfaces/Activity.ts diff --git a/util/src/interfaces/Event.ts b/src/util/interfaces/Event.ts similarity index 100% rename from util/src/interfaces/Event.ts rename to src/util/interfaces/Event.ts diff --git a/util/src/interfaces/Interaction.ts b/src/util/interfaces/Interaction.ts similarity index 100% rename from util/src/interfaces/Interaction.ts rename to src/util/interfaces/Interaction.ts diff --git a/util/src/interfaces/Presence.ts b/src/util/interfaces/Presence.ts similarity index 100% rename from util/src/interfaces/Presence.ts rename to src/util/interfaces/Presence.ts diff --git a/util/src/interfaces/Status.ts b/src/util/interfaces/Status.ts similarity index 100% rename from util/src/interfaces/Status.ts rename to src/util/interfaces/Status.ts diff --git a/util/src/interfaces/index.ts b/src/util/interfaces/index.ts similarity index 100% rename from util/src/interfaces/index.ts rename to src/util/interfaces/index.ts diff --git a/util/src/migrations/1633864260873-EmojiRoles.ts b/src/util/migrations/1633864260873-EmojiRoles.ts similarity index 100% rename from util/src/migrations/1633864260873-EmojiRoles.ts rename to src/util/migrations/1633864260873-EmojiRoles.ts diff --git a/util/src/migrations/1633864669243-EmojiUser.ts b/src/util/migrations/1633864669243-EmojiUser.ts similarity index 100% rename from util/src/migrations/1633864669243-EmojiUser.ts rename to src/util/migrations/1633864669243-EmojiUser.ts diff --git a/util/src/migrations/1633881705509-VanityInvite.ts b/src/util/migrations/1633881705509-VanityInvite.ts similarity index 100% rename from util/src/migrations/1633881705509-VanityInvite.ts rename to src/util/migrations/1633881705509-VanityInvite.ts diff --git a/util/src/migrations/1634308884591-Stickers.ts b/src/util/migrations/1634308884591-Stickers.ts similarity index 100% rename from util/src/migrations/1634308884591-Stickers.ts rename to src/util/migrations/1634308884591-Stickers.ts diff --git a/util/src/migrations/1634424361103-Presence.ts b/src/util/migrations/1634424361103-Presence.ts similarity index 100% rename from util/src/migrations/1634424361103-Presence.ts rename to src/util/migrations/1634424361103-Presence.ts diff --git a/util/src/migrations/1634426540271-MigrationTimestamp.ts b/src/util/migrations/1634426540271-MigrationTimestamp.ts similarity index 100% rename from util/src/migrations/1634426540271-MigrationTimestamp.ts rename to src/util/migrations/1634426540271-MigrationTimestamp.ts diff --git a/util/src/migrations/1648643945733-ReleaseTypo.ts b/src/util/migrations/1648643945733-ReleaseTypo.ts similarity index 100% rename from util/src/migrations/1648643945733-ReleaseTypo.ts rename to src/util/migrations/1648643945733-ReleaseTypo.ts diff --git a/util/src/migrations/1660678870706-opencordFixes.ts b/src/util/migrations/1660678870706-opencordFixes.ts similarity index 100% rename from util/src/migrations/1660678870706-opencordFixes.ts rename to src/util/migrations/1660678870706-opencordFixes.ts diff --git a/util/src/migrations/1660689892073-mobileFixes2.ts b/src/util/migrations/1660689892073-mobileFixes2.ts similarity index 100% rename from util/src/migrations/1660689892073-mobileFixes2.ts rename to src/util/migrations/1660689892073-mobileFixes2.ts diff --git a/util/src/schemas/Validator.ts b/src/util/schemas/Validator.ts similarity index 94% rename from util/src/schemas/Validator.ts rename to src/util/schemas/Validator.ts index e5f12ac5..b71bf6a1 100644 --- a/util/src/schemas/Validator.ts +++ b/src/util/schemas/Validator.ts @@ -3,7 +3,7 @@ import addFormats from "ajv-formats"; import fs from "fs"; import path from "path"; -const SchemaPath = path.join(__dirname, "..", "..", "..", "api", "assets", "schemas.json"); +const SchemaPath = path.join(__dirname, "..", "..", "..", "assets", "schemas.json"); const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" })); export const ajv = new Ajv({ diff --git a/util/src/schemas/index.ts b/src/util/schemas/index.ts similarity index 100% rename from util/src/schemas/index.ts rename to src/util/schemas/index.ts diff --git a/util/src/schemas/voice.ts b/src/util/schemas/voice.ts similarity index 100% rename from util/src/schemas/voice.ts rename to src/util/schemas/voice.ts diff --git a/util/src/util/ApiError.ts b/src/util/util/ApiError.ts similarity index 100% rename from util/src/util/ApiError.ts rename to src/util/util/ApiError.ts diff --git a/util/src/util/Array.ts b/src/util/util/Array.ts similarity index 100% rename from util/src/util/Array.ts rename to src/util/util/Array.ts diff --git a/util/src/util/AutoUpdate.ts b/src/util/util/AutoUpdate.ts similarity index 97% rename from util/src/util/AutoUpdate.ts rename to src/util/util/AutoUpdate.ts index 531bd8b7..fd65ecf5 100644 --- a/util/src/util/AutoUpdate.ts +++ b/src/util/util/AutoUpdate.ts @@ -76,7 +76,7 @@ async function getLatestVersion(url: string) { try { const agent = new ProxyAgent(); const response = await fetch(url, { agent }); - const content = await response.json(); + const content = await response.json() as any; // TODO: types return content.version; } catch (error) { throw new Error("[Auto update] check failed for " + url); diff --git a/util/src/util/BannedWords.ts b/src/util/util/BannedWords.ts similarity index 100% rename from util/src/util/BannedWords.ts rename to src/util/util/BannedWords.ts diff --git a/util/src/util/BitField.ts b/src/util/util/BitField.ts similarity index 100% rename from util/src/util/BitField.ts rename to src/util/util/BitField.ts diff --git a/util/src/util/Categories.ts b/src/util/util/Categories.ts similarity index 100% rename from util/src/util/Categories.ts rename to src/util/util/Categories.ts diff --git a/util/src/util/Config.ts b/src/util/util/Config.ts similarity index 100% rename from util/src/util/Config.ts rename to src/util/util/Config.ts diff --git a/util/src/util/Constants.ts b/src/util/util/Constants.ts similarity index 100% rename from util/src/util/Constants.ts rename to src/util/util/Constants.ts diff --git a/src/util/util/Database.ts b/src/util/util/Database.ts new file mode 100644 index 00000000..ddbea57d --- /dev/null +++ b/src/util/util/Database.ts @@ -0,0 +1,96 @@ +import path from "path"; +import "reflect-metadata"; +import { DataSource } from "typeorm"; +import * as Models from "../entities"; +import { Migration } from "../entities/Migration"; +import { yellow, green, red } from "picocolors"; + +// UUID extension option is only supported with postgres +// We want to generate all id's with Snowflakes that's why we have our own BaseEntity class + +var dbConnection: DataSource | undefined; +let dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db"); + +export function getDatabase(): DataSource | null { + // if (!dbConnection) throw new Error("Tried to get database before it was initialised"); + if (!dbConnection) return null; + return dbConnection; +} + +export async function initDatabase(): Promise { + if (dbConnection) return dbConnection; + + const type = dbConnectionString.includes("://") ? dbConnectionString.split(":")[0]?.replace("+srv", "") : "sqlite"; + const isSqlite = type.includes("sqlite"); + + console.log(`[Database] ${yellow(`connecting to ${type} db`)}`); + if (isSqlite) { + console.log(`[Database] ${red(`You are running sqlite! Please keep in mind that we recommend setting up a dedicated database!`)}`); + } + + const dataSource = new DataSource({ + //@ts-ignore + type, + charset: 'utf8mb4', + url: isSqlite ? undefined : dbConnectionString, + database: isSqlite ? dbConnectionString : undefined, + entities: ["dist/util/entities/*.js"], + synchronize: type !== "mongodb", + logging: false, + bigNumberStrings: false, + supportBigNumbers: true, + name: "default", + // migrations: [path.join(__dirname, "..", "migrations", "*.js")], + }); + + dbConnection = await dataSource.initialize(); + + // // @ts-ignore + // promise = createConnection({ + // type, + // charset: 'utf8mb4', + // url: isSqlite ? undefined : dbConnectionString, + // database: isSqlite ? dbConnectionString : undefined, + // // @ts-ignore + // entities: Object.values(Models).filter((x) => x?.constructor?.name !== "Object" && x?.name), + // synchronize: type !== "mongodb", + // logging: false, + // // cache: { // cache is used only by query builder and entity manager + // // duration: 1000 * 30, + // // type: "redis", + // // options: { + // // host: "localhost", + // // port: 6379, + // // }, + // // }, + // bigNumberStrings: false, + // supportBigNumbers: true, + // name: "default", + // migrations: [path.join(__dirname, "..", "migrations", "*.js")], + // }); + + // // run migrations, and if it is a new fresh database, set it to the last migration + // if (dbConnection.migrations.length) { + // if (!(await Migration.findOne({ }))) { + // let i = 0; + + // await Migration.insert( + // dbConnection.migrations.map((x) => ({ + // id: i++, + // name: x.name, + // timestamp: Date.now(), + // })) + // ); + // } + // } + await dbConnection.runMigrations(); + console.log(`[Database] ${green("connected")}`); + + return dbConnection; +} + +export { dbConnection }; + +export function closeDatabase() { + dbConnection?.destroy(); +} diff --git a/util/src/util/Email.ts b/src/util/util/Email.ts similarity index 100% rename from util/src/util/Email.ts rename to src/util/util/Email.ts diff --git a/util/src/util/Event.ts b/src/util/util/Event.ts similarity index 100% rename from util/src/util/Event.ts rename to src/util/util/Event.ts diff --git a/util/src/util/FieldError.ts b/src/util/util/FieldError.ts similarity index 100% rename from util/src/util/FieldError.ts rename to src/util/util/FieldError.ts diff --git a/util/src/util/Intents.ts b/src/util/util/Intents.ts similarity index 100% rename from util/src/util/Intents.ts rename to src/util/util/Intents.ts diff --git a/util/src/util/InvisibleCharacters.ts b/src/util/util/InvisibleCharacters.ts similarity index 100% rename from util/src/util/InvisibleCharacters.ts rename to src/util/util/InvisibleCharacters.ts diff --git a/util/src/util/MessageFlags.ts b/src/util/util/MessageFlags.ts similarity index 100% rename from util/src/util/MessageFlags.ts rename to src/util/util/MessageFlags.ts diff --git a/util/src/util/Permissions.ts b/src/util/util/Permissions.ts similarity index 100% rename from util/src/util/Permissions.ts rename to src/util/util/Permissions.ts diff --git a/util/src/util/RabbitMQ.ts b/src/util/util/RabbitMQ.ts similarity index 100% rename from util/src/util/RabbitMQ.ts rename to src/util/util/RabbitMQ.ts diff --git a/util/src/util/Regex.ts b/src/util/util/Regex.ts similarity index 100% rename from util/src/util/Regex.ts rename to src/util/util/Regex.ts diff --git a/util/src/util/Rights.ts b/src/util/util/Rights.ts similarity index 100% rename from util/src/util/Rights.ts rename to src/util/util/Rights.ts diff --git a/util/src/util/Snowflake.ts b/src/util/util/Snowflake.ts similarity index 100% rename from util/src/util/Snowflake.ts rename to src/util/util/Snowflake.ts diff --git a/util/src/util/String.ts b/src/util/util/String.ts similarity index 100% rename from util/src/util/String.ts rename to src/util/util/String.ts diff --git a/util/src/util/Token.ts b/src/util/util/Token.ts similarity index 91% rename from util/src/util/Token.ts rename to src/util/util/Token.ts index 500ace45..5ba3e1ec 100644 --- a/util/src/util/Token.ts +++ b/src/util/util/Token.ts @@ -11,14 +11,14 @@ export function checkToken(token: string, jwtSecret: string): Promise { in fosscord, even with instances that have bot distinction; we won't enforce "Bot" prefix, as we don't really have separate pathways for bots **/ - + jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => { if (err || !decoded) return rej("Invalid Token"); - const user = await User.findOne( - { id: decoded.id }, - { select: ["data", "bot", "disabled", "deleted", "rights"] } - ); + const user = await User.findOne({ + where: { id: decoded.id }, + select: ["data", "bot", "disabled", "deleted", "rights"] + }); if (!user) return rej("Invalid Token"); // we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0)) diff --git a/util/src/util/TraverseDirectory.ts b/src/util/util/TraverseDirectory.ts similarity index 100% rename from util/src/util/TraverseDirectory.ts rename to src/util/util/TraverseDirectory.ts diff --git a/util/src/util/cdn.ts b/src/util/util/cdn.ts similarity index 92% rename from util/src/util/cdn.ts rename to src/util/util/cdn.ts index ea950cd1..812a4e1d 100644 --- a/util/src/util/cdn.ts +++ b/src/util/util/cdn.ts @@ -1,10 +1,10 @@ import FormData from "form-data"; import { HTTPError } from "lambert-server"; import fetch from "node-fetch"; +import { Attachment } from "../entities"; import { Config } from "./Config"; -import multer from "multer"; -export async function uploadFile(path: string, file?: Express.Multer.File) { +export async function uploadFile(path: string, file?: Express.Multer.File): Promise { if (!file?.buffer) throw new HTTPError("Missing file in body"); const form = new FormData(); @@ -21,7 +21,7 @@ export async function uploadFile(path: string, file?: Express.Multer.File) { method: "POST", body: form, }); - const result = await response.json(); + const result = await response.json() as Attachment; if (response.status !== 200) throw result; return result; diff --git a/util/src/util/index.ts b/src/util/util/index.ts similarity index 100% rename from util/src/util/index.ts rename to src/util/util/index.ts diff --git a/webrtc/.DS_Store b/src/webrtc/.DS_Store similarity index 100% rename from webrtc/.DS_Store rename to src/webrtc/.DS_Store diff --git a/webrtc/src/Server.ts b/src/webrtc/Server.ts similarity index 100% rename from webrtc/src/Server.ts rename to src/webrtc/Server.ts diff --git a/webrtc/src/events/Close.ts b/src/webrtc/events/Close.ts similarity index 100% rename from webrtc/src/events/Close.ts rename to src/webrtc/events/Close.ts diff --git a/webrtc/src/events/Connection.ts b/src/webrtc/events/Connection.ts similarity index 100% rename from webrtc/src/events/Connection.ts rename to src/webrtc/events/Connection.ts diff --git a/webrtc/src/events/Message.ts b/src/webrtc/events/Message.ts similarity index 100% rename from webrtc/src/events/Message.ts rename to src/webrtc/events/Message.ts diff --git a/webrtc/src/index.ts b/src/webrtc/index.ts similarity index 100% rename from webrtc/src/index.ts rename to src/webrtc/index.ts diff --git a/webrtc/src/opcodes/BackendVersion.ts b/src/webrtc/opcodes/BackendVersion.ts similarity index 100% rename from webrtc/src/opcodes/BackendVersion.ts rename to src/webrtc/opcodes/BackendVersion.ts diff --git a/webrtc/src/opcodes/Heartbeat.ts b/src/webrtc/opcodes/Heartbeat.ts similarity index 100% rename from webrtc/src/opcodes/Heartbeat.ts rename to src/webrtc/opcodes/Heartbeat.ts diff --git a/webrtc/src/opcodes/Identify.ts b/src/webrtc/opcodes/Identify.ts similarity index 100% rename from webrtc/src/opcodes/Identify.ts rename to src/webrtc/opcodes/Identify.ts diff --git a/webrtc/src/opcodes/SelectProtocol.ts b/src/webrtc/opcodes/SelectProtocol.ts similarity index 100% rename from webrtc/src/opcodes/SelectProtocol.ts rename to src/webrtc/opcodes/SelectProtocol.ts diff --git a/webrtc/src/opcodes/Speaking.ts b/src/webrtc/opcodes/Speaking.ts similarity index 100% rename from webrtc/src/opcodes/Speaking.ts rename to src/webrtc/opcodes/Speaking.ts diff --git a/webrtc/src/opcodes/Video.ts b/src/webrtc/opcodes/Video.ts similarity index 100% rename from webrtc/src/opcodes/Video.ts rename to src/webrtc/opcodes/Video.ts diff --git a/webrtc/src/opcodes/index.ts b/src/webrtc/opcodes/index.ts similarity index 100% rename from webrtc/src/opcodes/index.ts rename to src/webrtc/opcodes/index.ts diff --git a/webrtc/src/opcodes/sdp.json b/src/webrtc/opcodes/sdp.json similarity index 100% rename from webrtc/src/opcodes/sdp.json rename to src/webrtc/opcodes/sdp.json diff --git a/webrtc/src/start.ts b/src/webrtc/start.ts similarity index 100% rename from webrtc/src/start.ts rename to src/webrtc/start.ts diff --git a/webrtc/src/util/Constants.ts b/src/webrtc/util/Constants.ts similarity index 100% rename from webrtc/src/util/Constants.ts rename to src/webrtc/util/Constants.ts diff --git a/webrtc/src/util/MediaServer.ts b/src/webrtc/util/MediaServer.ts similarity index 100% rename from webrtc/src/util/MediaServer.ts rename to src/webrtc/util/MediaServer.ts diff --git a/webrtc/src/util/index.ts b/src/webrtc/util/index.ts similarity index 100% rename from webrtc/src/util/index.ts rename to src/webrtc/util/index.ts diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..9797ae10 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,113 @@ +{ + "exclude": [ + "./src/webrtc", + "./src-slowcord" + ], + "include": ["./src"], + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": ["ESNext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./src", /* Specify the root folder within your source files. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "baseUrl": "./src/", + "paths": { + "@fosscord/api*": ["./api"], + "@fosscord/gateway*": ["./gateway"], + "@fosscord/cdn*": ["./cdn"], + "@fosscord/util*": ["./util"] + }, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + "types": ["node"], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": false, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": false, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist/", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + "strictPropertyInitialization": false, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/util/.gitignore b/util/.gitignore deleted file mode 100644 index 87263762..00000000 --- a/util/.gitignore +++ /dev/null @@ -1,108 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port -.DS_Store - -# Compiled TypeScript code -dist/ -database.db \ No newline at end of file diff --git a/util/.npmignore b/util/.npmignore deleted file mode 100644 index 05a9d0cf..00000000 --- a/util/.npmignore +++ /dev/null @@ -1 +0,0 @@ -!dist/ \ No newline at end of file diff --git a/util/.prettierrc b/util/.prettierrc deleted file mode 100644 index d569c548..00000000 --- a/util/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "tabWidth": 4, - "useTabs": true, - "printWidth": 120 -} diff --git a/util/.vscode/launch.json b/util/.vscode/launch.json deleted file mode 100644 index 524622d1..00000000 --- a/util/.vscode/launch.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "sourceMaps": true, - "type": "node", - "request": "launch", - "name": "Launch Util", - "program": "${workspaceFolder}/dist/index.js", - "preLaunchTask": "tsc: build - tsconfig.json", - "outFiles": ["${workspaceFolder}/dist/**/*.js"] - }, - { - "name": "Debug Jest Tests", - "type": "node", - "request": "launch", - "runtimeArgs": ["--inspect-brk", "${workspaceRoot}/node_modules/jest/bin/jest.js", "--runInBand"], - "preLaunchTask": "tsc: build - tsconfig.json", - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen", - "port": 9229 - } - ] -} diff --git a/util/README.md b/util/README.md deleted file mode 100644 index fc9ad638..00000000 --- a/util/README.md +++ /dev/null @@ -1,29 +0,0 @@ -

- -

-

Fosscord server util

- -

- - - - - - - - -

- -## [About](https://fosscord.com) - -Fosscord is a free open source selfhostable chat, voice and video discord-compatible platform. - -Fosscord server util contains all necessary logic that is shared between the [api](https://github.com/fosscord/fosscord-server/tree/master/api), [gateway](https://github.com/fosscord/fosscord-server/tree/master/gateway) and [cdn](https://github.com/fosscord/fosscord-server/tree/master/cdn). - -It contains all mongoose database models and utility functions. - -## Installation - -```bash -npm install @fosscord/server-util -``` diff --git a/util/ormconfig.json b/util/ormconfig.json deleted file mode 100644 index c5587b8e..00000000 --- a/util/ormconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "sqlite", - "database": "../bundle/database.db", - "migrations": ["src/migrations/*.ts"], - "entities": ["src/entities/*.ts"], - "cli": { - "migrationsDir": "src/migrations" - } -} diff --git a/util/package-lock.json b/util/package-lock.json deleted file mode 100644 index 22896367..00000000 Binary files a/util/package-lock.json and /dev/null differ diff --git a/util/package.json b/util/package.json deleted file mode 100644 index 097fb2e4..00000000 --- a/util/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@fosscord/util", - "version": "1.0.0", - "description": "Utility functions for the all server repositories", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "start": "npm run build && node dist/", - "test": "npm run build && npx jest", - "postinstall": "npm run build", - "build": "npx tsc -p .", - "typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/fosscord/fosscord-server.git" - }, - "keywords": [ - "discord", - "fosscord", - "fosscord-server", - "discord open source", - "discord-open-source" - ], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "bugs": { - "url": "https://github.com/fosscord/fosscord-server/issues" - }, - "homepage": "https://docs.fosscord.com/", - "devDependencies": { - "@types/amqplib": "^0.8.1", - "@types/jsonwebtoken": "^8.5.0", - "@types/multer": "^1.4.7", - "@types/node": "^14.17.9", - "@types/node-fetch": "^2.5.12", - "jest": "^27.0.6", - "ts-node": "^10.2.1" - }, - "dependencies": { - "amqplib": "^0.8.0", - "form-data": "^4.0.0", - "jsonwebtoken": "^8.5.1", - "lambert-server": "^1.2.12", - "missing-native-js-functions": "^1.2.18", - "multer": "^1.4.3", - "node-fetch": "^2.6.2", - "patch-package": "^6.4.7", - "pg": "^8.7.1", - "picocolors": "^1.0.0", - "proxy-agent": "^5.0.0", - "reflect-metadata": "^0.1.13", - "typeorm": "^0.2.37", - "typescript": "^4.4.2", - "typescript-json-schema": "^0.50.1" - }, - "jest": { - "setupFilesAfterEnv": [ - "./tests/setupJest.js" - ] - } -} diff --git a/util/src/entities/BaseClass.ts b/util/src/entities/BaseClass.ts deleted file mode 100644 index aabca016..00000000 --- a/util/src/entities/BaseClass.ts +++ /dev/null @@ -1,75 +0,0 @@ -import "reflect-metadata"; -import { BaseEntity, EntityMetadata, FindConditions, ObjectIdColumn, PrimaryColumn } from "typeorm"; -import { Snowflake } from "../util/Snowflake"; -import "missing-native-js-functions"; - -export class BaseClassWithoutId extends BaseEntity { - constructor(props?: any) { - super(); - this.assign(props); - } - - private get construct(): any { - return this.constructor; - } - - private get metadata() { - return this.construct.getRepository().metadata as EntityMetadata; - } - - assign(props: any = {}) { - delete props.opts; - delete props.props; - - const properties = new Set( - this.metadata.columns - .map((x: any) => x.propertyName) - .concat(this.metadata.relations.map((x) => x.propertyName)) - ); - // will not include relational properties - - for (const key in props) { - if (!properties.has(key)) continue; - // @ts-ignore - const setter = this[`set${key.capitalize()}`]; // use setter function if it exists - - if (setter) { - setter.call(this, props[key]); - } else { - // @ts-ignore - this[key] = props[key]; - } - } - } - - toJSON(): any { - return Object.fromEntries( - this.metadata.columns // @ts-ignore - .map((x) => [x.propertyName, this[x.propertyName]]) // @ts-ignore - .concat(this.metadata.relations.map((x) => [x.propertyName, this[x.propertyName]])) - ); - } - - static increment(conditions: FindConditions, propertyPath: string, value: number | string) { - const repository = this.getRepository(); - return repository.increment(conditions as T, propertyPath, value); - } - - static decrement(conditions: FindConditions, propertyPath: string, value: number | string) { - const repository = this.getRepository(); - return repository.decrement(conditions as T, propertyPath, value); - } -} - -export const PrimaryIdColumn = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryColumn; - -export class BaseClass extends BaseClassWithoutId { - @PrimaryIdColumn() - id: string; - - assign(props: any = {}) { - super.assign(props); - if (!this.id) this.id = Snowflake.generate(); - return this; - } -} diff --git a/util/src/entities/Group.ts b/util/src/entities/Group.ts deleted file mode 100644 index b24d38cf..00000000 --- a/util/src/entities/Group.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; - -import { BaseClass } from "./BaseClass"; - -@Entity("groups") -export class UserGroup extends BaseClass { - @Column({ nullable: true }) - parent?: BigInt; - - @Column() - color: number; - - @Column() - hoist: boolean; - - @Column() - mentionable: boolean; - - @Column() - name: string; - - @Column() - rights: BigInt; - - @Column() - position: number; - - @Column({ nullable: true }) - icon: BigInt; - - @Column({ nullable: true }) - unicode_emoji: BigInt; -} diff --git a/util/src/entities/UserGroup.ts b/util/src/entities/UserGroup.ts deleted file mode 100644 index 709b9d0b..00000000 --- a/util/src/entities/UserGroup.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; - -import { BaseClass } from "./BaseClass"; -import { Guild } from "./Guild"; -import { User } from "./User"; - -@Entity("groups") -export class UserGroup extends BaseClass { - @Column() - color: number; - - @Column() - hoist: boolean; - - @JoinColumn({ name: "controller", referencedColumnName: "id" }) - @ManyToOne(() => User) - controller?: User; - - @Column() - mentionable_by?: string; - - @Column() - name: string; - - @Column() - rights: string; - - @Column({ nullable: true }) - icon: string; - - @Column({ nullable: true }) - parent?: string; - - @Column({ type: "simple-array", nullable: true}) - associciations: string[]; - -} diff --git a/util/src/util/Database.ts b/util/src/util/Database.ts deleted file mode 100644 index 47d1987b..00000000 --- a/util/src/util/Database.ts +++ /dev/null @@ -1,77 +0,0 @@ -import path from "path"; -import "reflect-metadata"; -import { Connection, createConnection } from "typeorm"; -import * as Models from "../entities"; -import { Migration } from "../entities/Migration"; -import { yellow, green, red } from "picocolors"; - -// UUID extension option is only supported with postgres -// We want to generate all id's with Snowflakes that's why we have our own BaseEntity class - -var promise: Promise; -var dbConnection: Connection | undefined; -let dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db"); - -export function initDatabase(): Promise { - if (promise) return promise; // prevent initalizing multiple times - - const type = dbConnectionString.includes("://") ? dbConnectionString.split(":")[0]?.replace("+srv", "") : "sqlite"; - const isSqlite = type.includes("sqlite"); - - console.log(`[Database] ${yellow(`connecting to ${type} db`)}`); - if(isSqlite) { - console.log(`[Database] ${red(`You are running sqlite! Please keep in mind that we recommend setting up a dedicated database!`)}`); - } - // @ts-ignore - promise = createConnection({ - type, - charset: 'utf8mb4', - url: isSqlite ? undefined : dbConnectionString, - database: isSqlite ? dbConnectionString : undefined, - // @ts-ignore - entities: Object.values(Models).filter((x) => x?.constructor?.name !== "Object" && x?.name), - synchronize: type !== "mongodb", - logging: false, - // cache: { // cache is used only by query builder and entity manager - // duration: 1000 * 30, - // type: "redis", - // options: { - // host: "localhost", - // port: 6379, - // }, - // }, - bigNumberStrings: false, - supportBigNumbers: true, - name: "default", - migrations: [path.join(__dirname, "..", "migrations", "*.js")], - }); - - promise.then(async (connection: Connection) => { - dbConnection = connection; - - // run migrations, and if it is a new fresh database, set it to the last migration - if (connection.migrations.length) { - if (!(await Migration.findOne({}))) { - let i = 0; - - await Migration.insert( - connection.migrations.map((x) => ({ - id: i++, - name: x.name, - timestamp: Date.now(), - })) - ); - } - } - await connection.runMigrations(); - console.log(`[Database] ${green("connected")}`); - }); - - return promise; -} - -export { dbConnection }; - -export function closeDatabase() { - dbConnection?.close(); -} diff --git a/util/tests/User.test.js b/util/tests/User.test.js deleted file mode 100644 index c0852ebc..00000000 --- a/util/tests/User.test.js +++ /dev/null @@ -1,43 +0,0 @@ -const { initDatabase, closeDatabase } = require("../dist/util/Database"); -const { User } = require("../dist/entities/User"); -jest.setTimeout(20000); - -beforeAll((done) => { - initDatabase().then(() => { - done(); - }); -}); - -afterAll(() => { - closeDatabase(); -}); - -describe("User", () => { - test("valid discriminator: 1", async () => { - new User({ discriminator: "1" }).validate(); - }); - test("invalid discriminator: test", async () => { - expect(() => { - new User({ discriminator: "test" }).validate(); - }).toThrow(); - }); - - test("invalid discriminator: 0", async () => { - expect(() => { - new User({ discriminator: "0" }).validate(); - }).toThrow(); - }); - - test("add guild", async () => { - try { - await new User({ guilds: [], discriminator: "1" }, { id: "0" }).save(); - const user = await User.find("0"); - - user.guilds.push(new Guild({ name: "test" })); - - user.save(); - } catch (error) { - console.error(error); - } - }); -}); diff --git a/util/tests/setupJest.js b/util/tests/setupJest.js deleted file mode 100644 index 35a3cb52..00000000 --- a/util/tests/setupJest.js +++ /dev/null @@ -1,23 +0,0 @@ -const { performance } = require("perf_hooks"); -const fs = require("fs"); -const path = require("path"); - -// fs.unlinkSync(path.join(__dirname, "..", "database.db")); - -global.expect.extend({ - toBeFasterThan: async (func, target) => { - const start = performance.now(); - var error; - try { - await func(); - } catch (e) { - error = e.toString(); - } - const time = performance.now() - start; - - return { - pass: time < target && !error, - message: () => error || `${func.name} took ${time}ms of maximum ${target}`, - }; - }, -}); diff --git a/util/tsconfig.json b/util/tsconfig.json deleted file mode 100644 index 0398ce9a..00000000 --- a/util/tsconfig.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - "incremental": true /* Enable incremental compilation */, - "target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": ["ES2021"] /* Specify library files to be included in the compilation. */, - "allowJs": true /* Allow javascript files to be compiled. */, - "checkJs": true /* Report errors in .js files. */, - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true /* Generates corresponding '.d.ts' file. */, - "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */, - "sourceMap": true /* Generates corresponding '.map' file. */, - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* Enable strict null checks. */, - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["node"] /* Type declaration files to be included in compilation. */, - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "resolveJsonModule": true - } -} diff --git a/webrtc/.gitignore b/webrtc/.gitignore deleted file mode 100644 index 67045665..00000000 --- a/webrtc/.gitignore +++ /dev/null @@ -1,104 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port diff --git a/webrtc/.vscode/launch.json b/webrtc/.vscode/launch.json deleted file mode 100644 index 49584172..00000000 --- a/webrtc/.vscode/launch.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "ts-node", - "type": "node", - "request": "launch", - "args": [ - "src/start.ts" - ], - "runtimeArgs": [ - "-r", - "ts-node/register" - ], - "cwd": "${workspaceRoot}", - "protocol": "inspector", - "internalConsoleOptions": "openOnSessionStart", - "sourceMaps": true, - "resolveSourceMapLocations": null, - } - ] -} \ No newline at end of file diff --git a/webrtc/README.md b/webrtc/README.md deleted file mode 100644 index c18ef54b..00000000 --- a/webrtc/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# fosscord-rtc-js - -A javascript fosscord webrtc server for voice and video communication diff --git a/webrtc/package-lock.json b/webrtc/package-lock.json deleted file mode 100644 index e27fbf3f..00000000 Binary files a/webrtc/package-lock.json and /dev/null differ diff --git a/webrtc/package.json b/webrtc/package.json deleted file mode 100644 index 1e333fb8..00000000 --- a/webrtc/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "rtc", - "version": "1.0.0", - "description": "A javascript fosscord webrtc server for voice and video communication", - "main": "dist/index.js", - "types": "src/index.ts", - "scripts": { - "test": "npm run build && node dist/test.js", - "build": "npx tsc -p .", - "start": "npm run build && node dist/start.js" - }, - "keywords": [], - "author": "Fosscord", - "license": "AGPL-3.0-only", - "devDependencies": { - "@types/node": "^15.6.1", - "@types/sdp-transform": "^2.4.5", - "@types/ws": "^7.4.7", - "ts-node": "^10.4.0", - "typescript": "^4.3.2" - }, - "dependencies": { - "@types/libsodium-wrappers": "^0.7.9", - "dotenv": "^12.0.4", - "libsodium": "^0.7.10", - "libsodium-wrappers": "^0.7.10", - "node-turn": "^0.0.6", - "tsconfig-paths": "^3.12.0", - "ws": "^7.5.8" - } -} diff --git a/webrtc/tsconfig.json b/webrtc/tsconfig.json deleted file mode 100644 index f45e0960..00000000 --- a/webrtc/tsconfig.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "ts-node": { - "require": ["tsconfig-paths/register"], - }, - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ES2021" - ] /* Specify library files to be included in the compilation. */, - "allowJs": true /* Allow javascript files to be compiled. */, - "checkJs": true /* Report errors in .js files. */, - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true /* Generates corresponding '.d.ts' file. */, - "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */, - "sourceMap": true /* Generates corresponding '.map' file. */, - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "../" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* Enable strict null checks. */, - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": [ - "node" - ] /* Type declaration files to be included in compilation. */, - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ - - "paths": { - "@fosscord/util": ["../util"], - "@fosscord/gateway": ["../gateway"], - "@fosscord/webrtc": ["."] - }, - } -}