1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-22 10:22:39 +01:00
This commit is contained in:
TheArcaneBrony 2022-08-20 03:27:03 +02:00
parent 363d9887cf
commit 04dea8d788
No known key found for this signature in database
GPG Key ID: 32FC5AAADAD75A22
339 changed files with 3825 additions and 4225 deletions

View File

@ -1,11 +1,15 @@
## Notes
## Additions
-
## Fixes
-
## Download
- [Windows]()
- [MacOS]()
- [Linux]()

8
.vscode/launch.json vendored
View File

@ -5,13 +5,9 @@
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"skipFiles": ["<node_internals>/**"],
"program": "${file}",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
"outFiles": ["${workspaceFolder}/**/*.js"]
}
]
}

View File

@ -1,2 +1 @@
The Docker image is coming with the dashboard. The planned release date is 2022-12-24.

View File

@ -87,6 +87,7 @@
"node-fetch": "^2.6.7",
"patch-package": "^6.4.7",
"picocolors": "^1.0.0",
"prettier": "^2.7.1",
"proxy-agent": "^5.0.0",
"reflect-metadata": "^0.1.13",
"typeorm": "^0.3.7",

View File

@ -8,7 +8,7 @@ const rl = readline.createInterface({ input: process.stdin, output: process.stdo
const data = { env: [], config: { register: {} }, extra_pkgs: [] };
let rights = [];
process.on('SIGINT', function() {
process.on("SIGINT", function () {
console.log("Caught interrupt signal");
process.exit();
});
@ -18,8 +18,8 @@ console.log("Please remember this is pre-release software!");
console.log("We will guide you through some important setup steps.");
console.log();
if(fs.existsSync("package-lock.json")) fs.rmSync("package-lock.json");
if(fs.existsSync("yarn.lock")) fs.rmSync("yarn.lock");
if (fs.existsSync("package-lock.json")) fs.rmSync("package-lock.json");
if (fs.existsSync("yarn.lock")) fs.rmSync("yarn.lock");
async function main() {
printTitle("Step 1: Database setup");
@ -82,7 +82,7 @@ async function main() {
if (data.db != "sqlite")
data.env.push(`DATABASE=${data.db}://${data.db_user}:${data.db_pass}@${data.db_host}:${data.db_port}/${data.db_name}`);
data.env.push(`PORT=${data.port}`);
data.env.push('THREADS=1')
data.env.push("THREADS=1");
printTitle("Step 4: Default rights");
console.log("Please enter the default rights for new users.");
@ -126,8 +126,9 @@ async function main() {
};
printTitle("Step 5: extra options");
if(/y?/i.test(await ask("Use fast BCrypt implementation (requires a compiler) (Y/n): "))) data.extra_pkgs.push("bcrypt");
if(/y?/.test(await ask("Enable support for widgets (requires compiler, known to fail on some ARM devices.) (Y/n): "))) data.extra_pkgs.push("canvas");
if (/y?/i.test(await ask("Use fast BCrypt implementation (requires a compiler) (Y/n): "))) data.extra_pkgs.push("bcrypt");
if (/y?/.test(await ask("Enable support for widgets (requires compiler, known to fail on some ARM devices.) (Y/n): ")))
data.extra_pkgs.push("canvas");
printTitle("Step 6: finalizing...");
//save
@ -140,13 +141,13 @@ async function main() {
console.log(" ==> Ensuring yarn is up to date (v3, not v1)...");
execIn("npx yarn set version stable", process.cwd());
console.log(" ==> Installing base packages");
execIn("npx --yes yarn install", process.cwd(), {stdio: "inherit"});
execIn("npx --yes yarn install", process.cwd(), { stdio: "inherit" });
console.log(` ==> Installing extra packages: ${data.extra_pkgs.join(', ')}...`);
execIn(`npx --yes yarn add -O ${data.extra_pkgs.join(' ')}`, process.cwd(), {stdio: "inherit"});
console.log(` ==> Installing extra packages: ${data.extra_pkgs.join(", ")}...`);
execIn(`npx --yes yarn add -O ${data.extra_pkgs.join(" ")}`, process.cwd(), { stdio: "inherit" });
console.log('==> Building...')
execIn('npx --yes yarn run build', process.cwd(), {stdio: "inherit"});
console.log("==> Building...");
execIn("npx --yes yarn run build", process.cwd(), { stdio: "inherit" });
printTitle("Step 6: run your instance!");
console.log("Installation is complete!");
console.log("You can now start your instance by running 'npm run start:bundle'!");

View File

@ -1,15 +1,15 @@
process.on("unhandledRejection", console.error);
process.on("uncaughtException", console.error);
import http from "http";
import * as Api from "@fosscord/api";
import * as Gateway from "@fosscord/gateway";
import { CDNServer } from "@fosscord/cdn";
import express from "express";
import { green, bold, yellow } from "picocolors";
import * as Gateway from "@fosscord/gateway";
import { Config, getOrInitialiseDatabase } from "@fosscord/util";
import * as Sentry from "@sentry/node";
import * as Tracing from "@sentry/tracing";
import express from "express";
import http from "http";
import { bold, green, yellow } from "picocolors";
// import { PluginLoader } from "@fosscord/util";
const app = express();
@ -26,12 +26,12 @@ const cdn = new CDNServer({ server, port, production, app });
const gateway = new Gateway.Server({ server, port, production });
//this is what has been added for the /stop API route
process.on('SIGTERM', () => {
setTimeout(()=>process.exit(0), 3000)
process.on("SIGTERM", () => {
setTimeout(() => process.exit(0), 3000);
server.close(() => {
console.log("Stop API has been successfully POSTed, SIGTERM sent")
})
})
console.log("Stop API has been successfully POSTed, SIGTERM sent");
});
});
//this is what has been added for the /stop API route
async function main() {
@ -42,16 +42,15 @@ async function main() {
await Config.set({
cdn: {
endpointClient: "${location.host}",
endpointPrivate: `http://localhost:${port}`,
endpointPrivate: `http://localhost:${port}`
},
gateway: {
endpointClient:
'${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}',
endpointClient: '${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}',
endpointPrivate: `ws://localhost:${port}`,
...(!Config.get().gateway.endpointPublic && {
endpointPublic: `ws://localhost:${port}`,
}),
},
endpointPublic: `ws://localhost:${port}`
})
}
// regions: {
// default: "fosscord",
// useDefaultAsOptimal: true,
@ -70,15 +69,10 @@ async function main() {
//Sentry
if (Config.get().sentry.enabled) {
console.log(
`[Bundle] ${yellow("You are using Sentry! This may slightly impact performance on large loads!")}`
);
console.log(`[Bundle] ${yellow("You are using Sentry! This may slightly impact performance on large loads!")}`);
Sentry.init({
dsn: Config.get().sentry.endpoint,
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
new Tracing.Integrations.Express({ app }),
],
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
tracesSampleRate: Config.get().sentry.traceSampleRate,
environment: Config.get().sentry.environment
});

View File

@ -1,16 +1,16 @@
import { Server, ServerOptions } from "lambert-server";
import { Authentication, CORS } from "./middlewares/";
import { Config, getOrInitialiseDatabase, initEvent, registerRoutes } from "@fosscord/util";
import { ErrorHandler } from "./middlewares/ErrorHandler";
import { BodyParser } from "./middlewares/BodyParser";
import { Router, Request, Response, NextFunction } from "express";
import { NextFunction, Request, Response, Router } from "express";
import { Server, ServerOptions } from "lambert-server";
import morgan from "morgan";
import path from "path";
import { red } from "picocolors";
import { Authentication, CORS } from "./middlewares/";
import { BodyParser } from "./middlewares/BodyParser";
import { ErrorHandler } from "./middlewares/ErrorHandler";
import { initRateLimits } from "./middlewares/RateLimit";
import TestClient from "./middlewares/TestClient";
import { initTranslation } from "./middlewares/Translation";
import morgan from "morgan";
import { initInstance } from "./util/handlers/Instance";
import { red } from "picocolors"
export interface FosscordServerOptions extends ServerOptions {}
@ -85,7 +85,12 @@ export class FosscordServer extends Server {
this.app.use(ErrorHandler);
TestClient(this.app);
if (logRequests) console.log(red(`Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!`));
if (logRequests)
console.log(
red(
`Warning: Request logging is enabled! This will spam your console!\nTo disable this, unset the 'LOG_REQUESTS' environment variable!`
)
);
return super.start();
}

View File

@ -1,3 +1,3 @@
export * from "./Server";
export * from "./middlewares/";
export * from "./Server";
export * from "./util/";

View File

@ -1,6 +1,5 @@
import { checkToken, Config, HTTPError, Rights } from "@fosscord/util";
import { NextFunction, Request, Response } from "express";
import { HTTPError } from "@fosscord/util";
import { checkToken, Config, Rights } from "@fosscord/util";
export const NO_AUTHORIZATION_ROUTES = [
// Authentication routes

View File

@ -1,6 +1,6 @@
import { HTTPError } from "@fosscord/util";
import bodyParser, { OptionsJson } from "body-parser";
import { NextFunction, Request, Response } from "express";
import { HTTPError } from "@fosscord/util";
export function BodyParser(opts?: OptionsJson) {
const jsonParser = bodyParser.json(opts);

View File

@ -1,6 +1,5 @@
import { ApiError, FieldError, HTTPError } from "@fosscord/util";
import { NextFunction, Request, Response } from "express";
import { HTTPError } from "@fosscord/util";
import { ApiError, FieldError } from "@fosscord/util";
const EntityNotFoundErrorRegex = /"(\w+)"/;
export function ErrorHandler(error: Error, req: Request, res: Response, next: NextFunction) {

View File

@ -1,6 +1,6 @@
import { Config, getRights, listenEvent, Rights } from "@fosscord/util";
import { NextFunction, Request, Response, Router } from "express";
import { getIpAdress } from "@fosscord/api";
import { Config, getRights, listenEvent } from "@fosscord/util";
import { NextFunction, Request, Response, Router } from "express";
import { API_PREFIX_TRAILING_SLASH } from "./Authentication";
// Docs: https://discord.com/developers/docs/topics/rate-limits
@ -163,7 +163,7 @@ export async function initRateLimits(app: Router) {
app.use("/auth/register", rateLimit({ onlyIp: true, success: true, ...routes.auth.register }));
}
async function hitRoute(opts: { executor_id: string; bucket_id: string; max_hits: number; window: number; }) {
async function hitRoute(opts: { executor_id: string; bucket_id: string; max_hits: number; window: number }) {
const id = opts.executor_id + opts.bucket_id;
let limit = Cache.get(id);
if (!limit) {

View File

@ -1,13 +1,13 @@
import express, { Request, Response, Application } from "express";
import fs from "fs";
import path from "path";
import fetch, { Response as FetchResponse, Headers } from "node-fetch";
import ProxyAgent from 'proxy-agent';
import { Config } from "@fosscord/util";
import { AssetCacheItem } from "../util/entities/AssetCacheItem"
import express, { Application, Request, Response } from "express";
import fs from "fs";
import fetch, { Headers, Response as FetchResponse } from "node-fetch";
import path from "path";
import { green } from "picocolors";
import ProxyAgent from "proxy-agent";
import { AssetCacheItem } from "../util/entities/AssetCacheItem";
const AssetsPath = path.join(__dirname, "..", "..", "..", "assets")
const AssetsPath = path.join(__dirname, "..", "..", "..", "assets");
export default function TestClient(app: Application) {
const agent = new ProxyAgent();
@ -22,14 +22,13 @@ export default function TestClient(app: Application) {
//load asset cache
let newAssetCache: Map<string, AssetCacheItem> = new Map<string, AssetCacheItem>();
let assetCacheDir = path.join(AssetsPath, "cache");
if(process.env.ASSET_CACHE_DIR)
assetCacheDir = process.env.ASSET_CACHE_DIR
if (process.env.ASSET_CACHE_DIR) assetCacheDir = process.env.ASSET_CACHE_DIR;
console.log(`[TestClient] ${green(`Using asset cache path: ${assetCacheDir}`)}`)
if(!fs.existsSync(assetCacheDir)) {
console.log(`[TestClient] ${green(`Using asset cache path: ${assetCacheDir}`)}`);
if (!fs.existsSync(assetCacheDir)) {
fs.mkdirSync(assetCacheDir);
}
if(fs.existsSync(path.join(assetCacheDir, "index.json"))) {
if (fs.existsSync(path.join(assetCacheDir, "index.json"))) {
let rawdata = fs.readFileSync(path.join(assetCacheDir, "index.json"));
newAssetCache = new Map<string, AssetCacheItem>(Object.entries(JSON.parse(rawdata.toString())));
}
@ -40,13 +39,12 @@ export default function TestClient(app: Application) {
let response: FetchResponse;
let buffer: Buffer;
let assetCacheItem: AssetCacheItem = new AssetCacheItem(req.params.file);
if(newAssetCache.has(req.params.file)){
if (newAssetCache.has(req.params.file)) {
assetCacheItem = newAssetCache.get(req.params.file)!;
assetCacheItem.Headers.forEach((value: any, name: any) => {
res.set(name, value);
});
}
else {
} else {
console.log(`[TestClient] Downloading file not yet cached! Asset file: ${req.params.file}`);
response = await fetch(`https://discord.com/assets/${req.params.file}`, {
agent,
@ -77,7 +75,7 @@ export default function TestClient(app: Application) {
res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24);
res.set("content-type", "text/html");
if(!useTestClient) return res.send("Test client is disabled on this instance. Use a stand-alone client to connect this instance.")
if (!useTestClient) return res.send("Test client is disabled on this instance. Use a stand-alone client to connect this instance.");
res.send(fs.readFileSync(path.join(__dirname, "..", "..", "..", "assets", "developers.html"), { encoding: "utf8" }));
});
@ -86,15 +84,13 @@ export default function TestClient(app: Application) {
res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24);
res.set("content-type", "text/html");
if(req.url.startsWith("/api") || req.url.startsWith("/__development")) return;
if (req.url.startsWith("/api") || req.url.startsWith("/__development")) return;
if(!useTestClient) return res.send("Test client is disabled on this instance. Use a stand-alone client to connect this instance.")
if (!useTestClient) return res.send("Test client is disabled on this instance. Use a stand-alone client to connect this instance.");
if (req.url.startsWith("/invite")) return res.send(html.replace("9b2b7f0632acd0c5e781", "9f24f709a3de09b67c49"));
res.send(html);
});
}
function applyEnv(html: string): string {
@ -117,23 +113,29 @@ function applyPlugins(html: string): string {
// plugins
let files = fs.readdirSync(path.join(AssetsPath, "plugins"));
let plugins = "";
files.forEach(x =>{if(x.endsWith(".js")) plugins += `<script src='/assets/plugins/${x}'></script>\n`; });
files.forEach((x) => {
if (x.endsWith(".js")) plugins += `<script src='/assets/plugins/${x}'></script>\n`;
});
return html.replaceAll("<!-- plugin marker -->", plugins);
}
function applyInlinePlugins(html: string): string{
function applyInlinePlugins(html: string): string {
// inline plugins
let files = fs.readdirSync(path.join(AssetsPath, "inline-plugins"));
let plugins = "";
files.forEach(x =>{if(x.endsWith(".js")) plugins += `<script src='/assets/inline-plugins/${x}'></script>\n\n`; });
files.forEach((x) => {
if (x.endsWith(".js")) plugins += `<script src='/assets/inline-plugins/${x}'></script>\n\n`;
});
return html.replaceAll("<!-- inline plugin marker -->", plugins);
}
function applyPreloadPlugins(html: string): string{
function applyPreloadPlugins(html: string): string {
//preload plugins
let files = fs.readdirSync(path.join(AssetsPath, "preload-plugins"));
let plugins = "";
files.forEach(x =>{if(x.endsWith(".js")) plugins += `<script>${fs.readFileSync(path.join(AssetsPath, "preload-plugins", x))}</script>\n`; });
files.forEach((x) => {
if (x.endsWith(".js")) plugins += `<script>${fs.readFileSync(path.join(AssetsPath, "preload-plugins", x))}</script>\n`;
});
return html.replaceAll("<!-- preload plugin marker -->", plugins);
}
@ -147,7 +149,7 @@ function stripHeaders(headers: Headers): Headers {
"expect-ct",
"access-control-allow-origin",
"content-encoding"
].forEach(headerName => {
].forEach((headerName) => {
headers.delete(headerName);
});
return headers;

View File

@ -1,9 +1,9 @@
import { Router } from "express";
import fs from "fs";
import path from "path";
import i18next from "i18next";
import i18nextMiddleware from "i18next-http-middleware";
import i18nextBackend from "i18next-node-fs-backend";
import { Router } from "express";
import path from "path";
export async function initTranslation(router: Router) {
const languages = fs.readdirSync(path.join(__dirname, "..", "..", "..", "assets", "locales"));

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
import { getConnection } from "typeorm";
const router = Router();

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
import { getConnection } from "typeorm";
const router = Router();

View File

@ -1,14 +1,14 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Application, Config, FieldErrors, generateToken, OrmUtils, Snowflake, trimSpecial, User, handleFile } from "@fosscord/util";
import { Application, Config, FieldErrors, generateToken, handleFile, OrmUtils, trimSpecial, User } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { verifyToken } from "node-2fa";
const router: Router = Router();
router.post("/", route({}), async (req: Request, res: Response) => {
const app = await Application.findOne({where: {id: req.params.id}});
if(!app) return res.status(404);
const app = await Application.findOne({ where: { id: req.params.id } });
if (!app) return res.status(404);
const username = trimSpecial(app.name);
const discriminator = await User.generateDiscriminator(username);
if (!discriminator) {
@ -16,8 +16,8 @@ router.post("/", route({}), async (req: Request, res: Response) => {
throw FieldErrors({
username: {
code: "USERNAME_TOO_MANY_USERS",
message: req?.t("auth:register.USERNAME_TOO_MANY_USERS"),
},
message: req?.t("auth:register.USERNAME_TOO_MANY_USERS")
}
});
}
@ -47,35 +47,35 @@ router.post("/", route({}), async (req: Request, res: Response) => {
flags: "0",
data: {
hash: null,
valid_tokens_since: new Date(),
valid_tokens_since: new Date()
},
settings: {},
extended_settings: {},
fingerprints: [],
notes: {},
notes: {}
});
await user.save();
app.bot = user;
await app.save();
res.send().status(204)
res.send().status(204);
});
router.post("/reset", route({}), async (req: Request, res: Response) => {
let bot = await User.findOne({where: {id: req.params.id}});
let owner = await User.findOne({where: {id: req.user_id}});
if(!bot) return res.status(404);
if(owner?.totp_secret && (!req.body.code || verifyToken(owner.totp_secret, req.body.code))) {
let bot = await User.findOne({ where: { id: req.params.id } });
let owner = await User.findOne({ where: { id: req.user_id } });
if (!bot) return res.status(404);
if (owner?.totp_secret && (!req.body.code || verifyToken(owner.totp_secret, req.body.code))) {
throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
}
bot.data = { hash: undefined, valid_tokens_since: new Date() };
await bot.save();
let token = await generateToken(bot.id);
res.json({token}).status(200);
res.json({ token }).status(200);
});
router.patch("/", route({}), async (req: Request, res: Response) => {
if (req.body.avatar) req.body.avatar = await handleFile(`/avatars/${req.params.id}`, req.body.avatar as string);
let app = OrmUtils.mergeDeep(await User.findOne({where: {id: req.params.id}}), req.body);
let app = OrmUtils.mergeDeep(await User.findOne({ where: { id: req.params.id } }), req.body);
await app.save();
res.json(app).status(200);
});

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,22 +1,22 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Application, OrmUtils, Team, trimSpecial, User } from "@fosscord/util";
import { Application, OrmUtils } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
let results = await Application.findOne({where: {id: req.params.id}, relations: ["owner", "bot"] });
let results = await Application.findOne({ where: { id: req.params.id }, relations: ["owner", "bot"] });
res.json(results).status(200);
});
router.patch("/", route({}), async (req: Request, res: Response) => {
delete req.body.icon;
let app = OrmUtils.mergeDeep(await Application.findOne({where: {id: req.params.id}, relations: ["owner", "bot"]}), req.body);
if(app.bot) {
app.bot.bio = req.body.description
let app = OrmUtils.mergeDeep(await Application.findOne({ where: { id: req.params.id }, relations: ["owner", "bot"] }), req.body);
if (app.bot) {
app.bot.bio = req.body.description;
app.bot?.save();
}
if(req.body.tags) app.tags = req.body.tags;
if (req.body.tags) app.tags = req.body.tags;
await app.save();
res.json(app).status(200);
});
@ -26,5 +26,4 @@ router.post("/delete", route({}), async (req: Request, res: Response) => {
res.send().status(200);
});
export default router;

View File

@ -1,6 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Application, OrmUtils, Team, trimSpecial, User } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,6 +1,6 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Application, OrmUtils, Team, trimSpecial, User } from "@fosscord/util";
import { Application, OrmUtils, trimSpecial, User } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -11,14 +11,14 @@ export interface ApplicationCreateSchema {
router.get("/", route({}), async (req: Request, res: Response) => {
//TODO
let results = await Application.find({where: {owner: {id: req.user_id}}, relations: ["owner", "bot"] });
let results = await Application.find({ where: { owner: { id: req.user_id } }, relations: ["owner", "bot"] });
res.json(results).status(200);
});
router.post("/", route({}), async (req: Request, res: Response) => {
const body = req.body as ApplicationCreateSchema;
const user = await User.findOne({where: {id: req.user_id}})
if(!user) res.status(420);
const user = await User.findOne({ where: { id: req.user_id } });
if (!user) res.status(420);
let app = OrmUtils.mergeDeep(new Application(), {
name: trimSpecial(body.name),
description: "",

View File

@ -1,13 +1,12 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { getIpAdress, IPAnalysis } from "@fosscord/api";
import { getIpAdress, IPAnalysis, route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/",route({}), async (req: Request, res: Response) => {
router.get("/", route({}), async (req: Request, res: Response) => {
//TODO
//Note: It's most likely related to legal. At the moment Discord hasn't finished this too
const country_code = (await IPAnalysis(getIpAdress(req))).country_code;
res.json({ consent_required: false, country_code: country_code, promotional_email_opt_in: { required: true, pre_checked: false}});
res.json({ consent_required: false, country_code: country_code, promotional_email_opt_in: { required: true, pre_checked: false } });
});
export default router;

View File

@ -1,7 +1,7 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { adjustEmail, Config, FieldErrors, generateToken, LoginSchema, User } from "@fosscord/util";
import crypto from "crypto";
import { Request, Response, Router } from "express";
let bcrypt: any;
try {
@ -65,8 +65,8 @@ router.post("/", route({ body: "LoginSchema" }), async (req: Request, res: Respo
ticket: ticket,
mfa: true,
sms: false, // TODO
token: null,
})
token: null
});
}
const token = await generateToken(user.id);

View File

@ -1,8 +1,8 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { BackupCode, FieldErrors, generateToken, TotpSchema, User } from "@fosscord/util";
import { verifyToken } from "node-2fa";
import { BackupCode, generateToken, TotpSchema, User } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import { verifyToken } from "node-2fa";
const router = Router();
router.post("/", route({ body: "TotpSchema" }), async (req: Request, res: Response) => {
@ -10,23 +10,17 @@ router.post("/", route({ body: "TotpSchema" }), async (req: Request, res: Respon
const user = await User.findOneOrFail({
where: {
totp_last_ticket: ticket,
totp_last_ticket: ticket
},
select: [
"id",
"totp_secret",
"settings",
],
select: ["id", "totp_secret", "settings"]
});
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);
if (!ret || ret.delta != 0)
throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
}
else {
if (!ret || ret.delta != 0) throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
} else {
backup.consumed = true;
await backup.save();
}
@ -35,7 +29,7 @@ router.post("/", route({ body: "TotpSchema" }), async (req: Request, res: Respon
return res.json({
token: await generateToken(user.id),
user_settings: user.settings,
user_settings: user.settings
});
});

View File

@ -1,4 +1,4 @@
import { Router, Response, Request } from "express";
import { Router } from "express";
const router: Router = Router();
// TODO:

View File

@ -1,17 +1,16 @@
import { route } from "@fosscord/api";
import {
Channel,
ChannelDeleteEvent,
ChannelPermissionOverwriteType,
ChannelModifySchema,
ChannelType,
ChannelUpdateEvent,
emitEvent,
Recipient,
handleFile,
ChannelModifySchema
OrmUtils,
Recipient
} from "@fosscord/util";
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
const router: Router = Router();
// TODO: delete channel

View File

@ -1,14 +1,13 @@
import { Router, Request, Response } from "express";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { random } from "@fosscord/api";
import { Channel, Invite, InviteCreateEvent, emitEvent, User, Guild, PublicInviteRelation } from "@fosscord/util";
import { Channel, emitEvent, Guild, HTTPError, Invite, InviteCreateEvent, OrmUtils, PublicInviteRelation, User } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { isTextChannel } from "./messages";
import { OrmUtils } from "@fosscord/util";
const router: Router = Router();
router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES" }),
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;
@ -22,7 +21,7 @@ router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT
const expires_at = new Date(req.body.max_age * 1000 + Date.now());
const invite = await OrmUtils.mergeDeep(new Invite(),{
const invite = await OrmUtils.mergeDeep(new Invite(), {
temporary: req.body.temporary || true,
max_uses: req.body.max_uses,
max_age: req.body.max_age,
@ -39,7 +38,8 @@ router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT
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 { channel_id } = req.params;

View File

@ -1,7 +1,6 @@
import { emitEvent, getPermission, MessageAckEvent, ReadState, Snowflake } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import { emitEvent, getPermission, MessageAckEvent, OrmUtils, ReadState } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,25 +1,22 @@
import { handleMessage, postHandleMessage, route } from "@fosscord/api";
import {
Attachment,
Channel,
Embed,
DiscordApiErrors,
emitEvent,
FosscordApiErrors,
getPermission,
getRights,
HTTPError,
Message,
MessageCreateEvent,
MessageCreateSchema,
MessageDeleteEvent,
MessageUpdateEvent,
Snowflake,
uploadFile,
MessageCreateSchema
uploadFile
} from "@fosscord/util";
import { Router, Response, Request } from "express";
import { Request, Response, Router } from "express";
import multer from "multer";
import { route } from "@fosscord/api";
import { handleMessage, postHandleMessage } from "@fosscord/api";
import { HTTPError } from "@fosscord/util";
const router = Router();
// TODO: message content/embed string length limit
@ -33,7 +30,10 @@ const messageUpload = multer({
storage: multer.memoryStorage()
}); // max upload 50 mb
router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }), async (req: Request, res: Response) => {
router.patch(
"/",
route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }),
async (req: Request, res: Response) => {
const { message_id, channel_id } = req.params;
let body = req.body as MessageCreateSchema;
@ -43,11 +43,11 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE
const rights = await getRights(req.user_id);
if ((req.user_id !== message.author_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");
@ -75,8 +75,8 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE
postHandleMessage(message);
return res.json(message);
});
}
);
// Backfill message with specific timestamp
router.put(
@ -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;
}
@ -136,11 +136,11 @@ router.put(
channel_id,
attachments,
edited_timestamp: undefined,
timestamp: new Date(snowflake.timestamp),
timestamp: new Date(snowflake.timestamp)
});
//Fix for the client bug
delete message.member
delete message.member;
await Promise.all([
message.save(),
@ -148,7 +148,7 @@ router.put(
channel.save()
]);
postHandleMessage(message).catch((e) => { }); // no await as it shouldnt block the message send function and silently catch error
postHandleMessage(message).catch((e) => {}); // no await as it shouldnt block the message send function and silently catch error
return res.json(message);
}
@ -174,7 +174,7 @@ router.delete("/", route({}), async (req: Request, res: Response) => {
const rights = await getRights(req.user_id);
if ((message.author_id !== req.user_id)) {
if (message.author_id !== req.user_id) {
if (!rights.has("MANAGE_MESSAGES")) {
const permission = await getPermission(req.user_id, channel.guild_id, channel_id);
permission.hasThrow("MANAGE_MESSAGES");

View File

@ -1,8 +1,10 @@
import { route } from "@fosscord/api";
import {
Channel,
emitEvent,
Emoji,
getPermission,
HTTPError,
Member,
Message,
MessageReactionAddEvent,
@ -13,9 +15,7 @@ import {
PublicUserProjection,
User
} from "@fosscord/util";
import { route } from "@fosscord/api";
import { Router, Response, Request } from "express";
import { HTTPError } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { In } from "typeorm";
const router = Router();
@ -101,7 +101,10 @@ router.get("/:emoji", route({ permission: "VIEW_CHANNEL" }), async (req: Request
res.json(users);
});
router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY", right: "SELF_ADD_REACTIONS" }), async (req: Request, res: Response) => {
router.put(
"/:emoji/:user_id",
route({ permission: "READ_MESSAGE_HISTORY", right: "SELF_ADD_REACTIONS" }),
async (req: Request, res: Response) => {
const { message_id, channel_id, user_id } = req.params;
if (user_id !== "@me") throw new HTTPError("Invalid user");
const emoji = getEmoji(req.params.emoji);
@ -142,7 +145,8 @@ router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY", right
} as MessageReactionAddEvent);
res.sendStatus(204);
});
}
);
router.delete("/:emoji/:user_id", route({}), async (req: Request, res: Response) => {
let { message_id, channel_id, user_id } = req.params;

View File

@ -1,7 +1,6 @@
import { Router, Response, Request } from "express";
import { Channel, Config, emitEvent, getPermission, getRights, MessageDeleteBulkEvent, Message } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Channel, Config, emitEvent, getPermission, getRights, HTTPError, Message, MessageDeleteBulkEvent } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { In } from "typeorm";
const router: Router = Router();
@ -13,7 +12,7 @@ export default router;
// 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({where:{ 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);

View File

@ -1,4 +1,4 @@
import { Router, Response, Request } from "express";
import { handleMessage, postHandleMessage, route } from "@fosscord/api";
import {
Attachment,
Channel,
@ -7,16 +7,15 @@ import {
DmChannelDTO,
emitEvent,
getPermission,
getRights,
HTTPError,
Member,
Message,
MessageCreateEvent,
MessageCreateSchema,
Snowflake,
uploadFile,
Member,
MessageCreateSchema
uploadFile
} from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { handleMessage, postHandleMessage, route } from "@fosscord/api";
import { Request, Response, Router } from "express";
import multer from "multer";
import { FindManyOptions, LessThan, MoreThan } from "typeorm";
import { URL } from "url";
@ -69,23 +68,20 @@ router.get("/", async (req: Request, res: Response) => {
permissions.hasThrow("VIEW_CHANNEL");
if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]);
let query: FindManyOptions<Message> & { where: { id?: any; }; } = {
let query: FindManyOptions<Message> & { where: { id?: any } } = {
order: { id: "DESC" },
take: limit,
where: { channel_id },
relations: ["author", "webhook", "application", "mentions", "mention_roles", "mention_channels", "sticker_items", "attachments"]
};
if (after) {
if (after > new Snowflake()) return res.status(422);
query.where.id = MoreThan(after);
}
else if (before) {
} else if (before) {
if (before < req.params.channel_id) return res.status(422);
query.where.id = LessThan(before);
}
else if (around) {
} else if (around) {
query.where.id = [
MoreThan((BigInt(around) - BigInt(halfLimit)).toString()),
LessThan((BigInt(around) + BigInt(halfLimit)).toString())
@ -117,8 +113,7 @@ router.get("/", async (req: Request, res: Response) => {
**/
for (let curr in x) {
if (x[curr] === null)
delete x[curr];
if (x[curr] === null) delete x[curr];
}
return x;
@ -130,7 +125,7 @@ router.get("/", async (req: Request, res: Response) => {
const messageUpload = multer({
limits: {
fileSize: 1024 * 1024 * 100,
fields: 10,
fields: 10
// files: 1
},
storage: multer.memoryStorage()
@ -162,16 +157,15 @@ router.post(
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] });
if (!channel.isWritable()) {
throw new HTTPError(`Cannot send messages to channel of type ${channel.type}`, 400)
throw new HTTPError(`Cannot send messages to channel of type ${channel.type}`, 400);
}
const files = req.files as Express.Multer.File[] ?? [];
const files = (req.files as Express.Multer.File[]) ?? [];
for (let currFile of files) {
try {
const file: any = await uploadFile(`/attachments/${channel.id}`, currFile);
attachments.push({ ...file, proxy_url: file.url });
}
catch (error) {
} catch (error) {
return res.status(400).json(error);
}
}
@ -233,9 +227,8 @@ router.post(
channel.save()
]);
postHandleMessage(message).catch((e) => { }); // no await as it shouldnt block the message send function and silently catch error
postHandleMessage(message).catch((e) => {}); // no await as it shouldnt block the message send function and silently catch error
return res.json(message);
}
);

View File

@ -1,17 +1,15 @@
import { route } from "@fosscord/api";
import {
Channel,
ChannelPermissionOverwrite,
ChannelPermissionOverwriteSchema,
ChannelPermissionOverwriteType,
ChannelUpdateEvent,
emitEvent,
getPermission,
HTTPError,
Member,
Role
} from "@fosscord/util";
import { Router, Response, Request } from "express";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -22,7 +20,7 @@ router.put(
const { channel_id, overwrite_id } = req.params;
const body = req.body as ChannelPermissionOverwriteSchema;
let channel = await Channel.findOneOrFail({ where: {id: channel_id} });
let channel = await Channel.findOneOrFail({ where: { id: channel_id } });
if (!channel.guild_id) throw new HTTPError("Channel not found", 404);
if (body.type === 0) {

View File

@ -1,16 +1,6 @@
import {
Channel,
ChannelPinsUpdateEvent,
Config,
emitEvent,
getPermission,
Message,
MessageUpdateEvent,
DiscordApiErrors
} from "@fosscord/util";
import { Router, Request, Response } from "express";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Channel, ChannelPinsUpdateEvent, Config, DiscordApiErrors, emitEvent, Message, MessageUpdateEvent } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,10 +1,18 @@
import { HTTPError, PurgeSchema } from "@fosscord/util";
import { route } from "@fosscord/api";
import {
Channel,
Config,
emitEvent,
getPermission,
getRights,
HTTPError,
Message,
MessageDeleteBulkEvent,
PurgeSchema
} from "@fosscord/util";
import { Request, Response, Router } from "express";
import { Between, FindManyOptions, In, Not } from "typeorm";
import { isTextChannel } from "./messages";
import { FindManyOptions, Between, Not } from "typeorm";
import { Channel, Config, emitEvent, getPermission, getRights, Message, MessageDeleteBulkEvent } from "@fosscord/util";
import { Router, Response, Request } from "express";
import { In } from "typeorm";
const router: Router = Router();
@ -13,7 +21,12 @@ export default router;
/**
TODO: apply the delete bit by bit to prevent client and database stress
**/
router.post("/",route({ /*body: "PurgeSchema",*/ }), async (req: Request, res: Response) => {
router.post(
"/",
route({
/*body: "PurgeSchema",*/
}),
async (req: Request, res: Response) => {
const { channel_id } = req.params;
const channel = await Channel.findOneOrFail({ where: { id: channel_id } });

View File

@ -1,4 +1,4 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import {
Channel,
ChannelRecipientAddEvent,
@ -6,12 +6,12 @@ import {
DiscordApiErrors,
DmChannelDTO,
emitEvent,
OrmUtils,
PublicUserProjection,
Recipient,
User
} from "@fosscord/util";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,6 +1,6 @@
import { Channel, emitEvent, Member, TypingStartEvent } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Router, Request, Response } from "express";
import { Channel, emitEvent, Member, TypingStartEvent } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,9 +1,7 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Channel, Config, getPermission, trimSpecial, Webhook } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { Channel, Config, DiscordApiErrors, HTTPError, trimSpecial, Webhook } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { isTextChannel } from "./messages/index";
import { DiscordApiErrors } from "@fosscord/util";
const router: Router = Router();
//TODO: implement webhooks

View File

@ -1,8 +1,8 @@
import { Guild, Config } from "@fosscord/util";
import { Config, Guild } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "..";
import { Request, Response, Router } from "express";
import { Like } from "typeorm";
import { route } from "..";
const router = Router();

View File

@ -1,5 +1,5 @@
import { Categories } from "@fosscord/util";
import { Router, Response, Request } from "express";
import { Request, Response, Router } from "express";
import { route } from "..";
const router = Router();
@ -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);
});

View File

@ -1,6 +1,6 @@
import { Router, Response, Request } from "express";
import { Config, Release } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { route } from "..";
import { Release, Config } from "@fosscord/util";
const router = Router();
@ -10,7 +10,7 @@ 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({ where: { name: client.releases.upstreamVersion } });

View File

@ -1,11 +1,11 @@
import { Router, Response, Request } from "express";
import { Request, Response, Router } from "express";
import { route } from "..";
const router = Router();
router.get("/", route({}), (req: Request, res: Response) => {
// TODO:
res.send({ fingerprint: "", assignments: [], guild_experiments:[] });
res.send({ fingerprint: "", assignments: [], guild_experiments: [] });
});
export default router;

View File

@ -1,6 +1,6 @@
import { Config } from "@fosscord/util";
import { Router, Response, Request } from "express";
import { route, RouteOptions } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,6 +1,6 @@
import { Config } from "@fosscord/util";
import { Router, Response, Request } from "express";
import { route, RouteOptions } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,7 +1,7 @@
import { Router, Response, Request } from "express";
import fetch from "node-fetch";
import ProxyAgent from 'proxy-agent';
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
import ProxyAgent from "proxy-agent";
import { getGifApiKey, parseGifResult } from "./trending";
const router = Router();
@ -20,7 +20,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
headers: { "Content-Type": "application/json" }
});
const { results } = await response.json() as any;
const { results } = (await response.json()) as any;
res.json(results.map(parseGifResult)).status(200);
});

View File

@ -1,7 +1,7 @@
import { Router, Response, Request } from "express";
import fetch from "node-fetch";
import ProxyAgent from 'proxy-agent';
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
import ProxyAgent from "proxy-agent";
import { getGifApiKey, parseGifResult } from "./trending";
const router = Router();
@ -20,7 +20,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
headers: { "Content-Type": "application/json" }
});
const { results } = await response.json() as any;
const { results } = (await response.json()) as any;
res.json(results.map(parseGifResult)).status(200);
});

View File

@ -1,9 +1,8 @@
import { Router, Response, Request } from "express";
import fetch from "node-fetch";
import ProxyAgent from 'proxy-agent';
import { route } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { Config, HTTPError } from "@fosscord/util";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
import ProxyAgent from "proxy-agent";
const router = Router();
@ -50,8 +49,8 @@ router.get("/", route({}), async (req: Request, res: Response) => {
})
]);
const { tags } = await responseSource.json() as any;
const { results } = await trendGifSource.json() as any;
const { tags } = (await responseSource.json()) as any;
const { results } = (await trendGifSource.json()) as any;
res.json({
categories: tags.map((x: any) => ({ name: x.searchterm, src: x.image })),

View File

@ -1,8 +1,8 @@
import { Guild, Config } from "@fosscord/util";
import { Config, Guild } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { Request, Response, Router } from "express";
import { Like } from "typeorm";
import { route } from "..";
import {Like} from "typeorm"
const router = Router();
@ -13,12 +13,12 @@ router.get("/", route({}), async (req: Request, res: Response) => {
// TODO: implement this with default typeorm query
// const guilds = await Guild.find({ where: { features: "DISCOVERABLE" } }); //, take: Math.abs(Number(limit)) });
const genLoadId = (size: Number) => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');
const genLoadId = (size: Number) => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join("");
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;

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
//TODO: implement audit logs

View File

@ -1,8 +1,18 @@
import { Request, Response, Router } from "express";
import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member, BanRegistrySchema, BanModeratorSchema } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { getIpAdress, route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import {
Ban,
BanModeratorSchema,
BanRegistrySchema,
DiscordApiErrors,
emitEvent,
GuildBanAddEvent,
GuildBanRemoveEvent,
HTTPError,
Member,
OrmUtils,
User
} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -44,7 +54,7 @@ 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({ where: { guild_id, user_id } }) as BanRegistrySchema;
let ban = (await Ban.findOneOrFail({ where: { guild_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
@ -53,7 +63,7 @@ router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request,
ban = ban as BanModeratorSchema;
delete ban.ip
delete ban.ip;
return res.json(ban);
});
@ -62,14 +72,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 = OrmUtils.mergeDeep(new Ban(),{
const ban = OrmUtils.mergeDeep(new Ban(), {
user_id: banned_user_id,
guild_id: guild_id,
ip: getIpAdress(req),
@ -93,7 +103,7 @@ 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);

View File

@ -1,7 +1,6 @@
import { Router, Response, Request } from "express";
import { Channel, ChannelUpdateEvent, getPermission, emitEvent, ChannelModifySchema, ChannelReorderSchema } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Channel, ChannelModifySchema, ChannelReorderSchema, ChannelUpdateEvent, emitEvent, HTTPError } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {

View File

@ -1,7 +1,6 @@
import { Channel, emitEvent, GuildDeleteEvent, Guild, Member, Message, Role, Invite, Emoji } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { emitEvent, Guild, GuildDeleteEvent, HTTPError } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,7 +1,5 @@
import { Guild, Config } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,7 +1,19 @@
import { Router, Request, Response } from "express";
import { Config, DiscordApiErrors, emitEvent, Emoji, EmojiCreateSchema, EmojiModifySchema, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User } from "@fosscord/util";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import {
Config,
DiscordApiErrors,
emitEvent,
Emoji,
EmojiCreateSchema,
EmojiModifySchema,
GuildEmojisUpdateEvent,
handleFile,
Member,
OrmUtils,
Snowflake,
User
} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,8 +1,18 @@
import { Request, Response, Router } from "express";
import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, GuildUpdateSchema, handleFile, Member } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import {
DiscordApiErrors,
emitEvent,
getPermission,
getRights,
Guild,
GuildUpdateEvent,
GuildUpdateSchema,
handleFile,
HTTPError,
Member,
OrmUtils
} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
@ -21,15 +31,14 @@ 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

View File

@ -1,7 +1,5 @@
import { Router, Response, Request } from "express";
import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
//TODO: implement integrations list

View File

@ -1,5 +1,5 @@
import { getPermission, Invite, PublicInviteRelation } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Invite, PublicInviteRelation } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,8 +1,18 @@
import { Request, Response, Router } from "express";
import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Rights, Guild, MemberChangeSchema } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import {
emitEvent,
Emoji,
getPermission,
getRights,
Guild,
GuildMemberUpdateEvent,
Member,
MemberChangeSchema,
OrmUtils,
Role,
Sticker
} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
@ -46,7 +56,6 @@ router.patch("/", route({ body: "MemberChangeSchema" }), async (req: Request, re
});
router.put("/", route({}), async (req: Request, res: Response) => {
// TODO: Lurker mode
const rights = await getRights(req.user_id);

View File

@ -1,5 +1,5 @@
import { getPermission, Member, PermissionResolvable } from "@fosscord/util";
import { route } from "@fosscord/api";
import { getPermission, Member, PermissionResolvable } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,5 +1,5 @@
import { getPermission, Member } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Member } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,8 +1,7 @@
import { Request, Response, Router } from "express";
import { Guild, Member, PublicMemberProjection } from "@fosscord/util";
import { route } from "@fosscord/api";
import { HTTPError, Member, PublicMemberProjection } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { MoreThan } from "typeorm";
import { HTTPError } from "@fosscord/util";
const router = Router();

View File

@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/subscriptions", route({}), async (req: Request, res: Response) => {

View File

@ -1,7 +1,7 @@
import { Router, Request, Response } from "express";
import { Guild, Member, Snowflake } from "@fosscord/util";
import { LessThan, IsNull } from "typeorm";
import { route } from "@fosscord/api";
import { Guild, Member, Snowflake } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { IsNull, LessThan } from "typeorm";
const router = Router();
//Returns all inactive members, respecting role hierarchy

View File

@ -1,7 +1,6 @@
import { Config, Guild, Member } from "@fosscord/util";
import { getIpAdress, getVoiceRegions, route } from "@fosscord/api";
import { Guild } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { getVoiceRegions, route } from "@fosscord/api";
import { getIpAdress } from "@fosscord/api";
const router = Router();

View File

@ -1,8 +1,16 @@
import { Router, Request, Response } from "express";
import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile, RoleModifySchema } from "@fosscord/util";
import { route } from "@fosscord/api";
import { HTTPError } from "@fosscord/util";
import { OrmUtils } from "@fosscord/util";
import {
emitEvent,
GuildRoleDeleteEvent,
GuildRoleUpdateEvent,
handleFile,
HTTPError,
Member,
OrmUtils,
Role,
RoleModifySchema
} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,21 +1,18 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import {
Role,
getPermission,
Member,
GuildRoleCreateEvent,
GuildRoleUpdateEvent,
GuildRoleDeleteEvent,
emitEvent,
Config,
DiscordApiErrors,
handleFile,
emitEvent,
getPermission,
GuildRoleCreateEvent,
GuildRoleUpdateEvent,
Member,
OrmUtils,
Role,
RoleModifySchema,
RolePositionUpdateSchema
} from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -38,7 +35,7 @@ router.post("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" })
if (role_count > maxRoles) throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles);
let role: Role = OrmUtils.mergeDeep(new Role(),{
let role: Role = OrmUtils.mergeDeep(new Role(), {
// values before ...body are default and can be overriden
position: 0,
hoist: false,

View File

@ -1,20 +1,19 @@
import { route } from "@fosscord/api";
import {
emitEvent,
GuildStickersUpdateEvent,
handleFile,
HTTPError,
Member,
ModifyGuildStickerSchema,
OrmUtils,
Snowflake,
Sticker,
StickerFormatType,
StickerType,
uploadFile
} from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
import multer from "multer";
import { HTTPError } from "@fosscord/util";
import { OrmUtils } from "@fosscord/util";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {

View File

@ -1,9 +1,6 @@
import { generateCode, route } from "@fosscord/api";
import { Guild, HTTPError, OrmUtils, Template } from "@fosscord/util";
import { Request, Response, Router } from "express";
import { Guild, Template } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { generateCode } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
const router: Router = Router();
@ -75,7 +72,12 @@ router.patch("/:code", route({ body: "TemplateModifySchema", permission: "MANAGE
const { code, guild_id } = req.params;
const { name, description } = req.body;
const template = await OrmUtils.mergeDeep(new Template(), { code, name: name, description: description, source_guild_id: guild_id }).save();
const template = await OrmUtils.mergeDeep(new Template(), {
code,
name: name,
description: description,
source_guild_id: guild_id
}).save();
res.json(template);
});

View File

@ -1,8 +1,6 @@
import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial, VanityUrlSchema } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { HTTPError } from "@fosscord/util";
import { OrmUtils } from "@fosscord/util";
import { Channel, ChannelType, Guild, HTTPError, Invite, OrmUtils, VanityUrlSchema } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,7 +1,16 @@
import { Channel, ChannelType, DiscordApiErrors, emitEvent, getPermission, VoiceState, VoiceStateUpdateEvent, VoiceStateUpdateSchema } from "@fosscord/util";
import { route } from "@fosscord/api";
import {
Channel,
ChannelType,
DiscordApiErrors,
emitEvent,
getPermission,
OrmUtils,
VoiceState,
VoiceStateUpdateEvent,
VoiceStateUpdateSchema
} from "@fosscord/util";
import { Request, Response, Router } from "express";
import { OrmUtils } from "@fosscord/util";
const router = Router();
router.patch("/", route({ body: "VoiceStateUpdateSchema" }), async (req: Request, res: Response) => {

View File

@ -1,7 +1,5 @@
import { Router, Response, Request } from "express";
import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
//TODO: implement webhooks

View File

@ -1,7 +1,6 @@
import { Request, Response, Router } from "express";
import { Guild, getPermission, Snowflake, Member, GuildUpdateWelcomeScreenSchema } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Guild, GuildUpdateWelcomeScreenSchema, HTTPError, Member } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,8 +1,6 @@
import { Request, Response, Router } from "express";
import { Config, Permissions, Guild, Invite, Channel, Member } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { random, route } from "@fosscord/api";
import { OrmUtils } from "@fosscord/util";
import { Channel, Guild, HTTPError, Invite, Member, OrmUtils, Permissions } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,7 +1,6 @@
import { Request, Response, Router } from "express";
import { Guild } from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Guild, HTTPError } from "@fosscord/util";
import { Request, Response, Router } from "express";
import fs from "fs";
import path from "path";

View File

@ -1,6 +1,6 @@
import { Request, Response, Router } from "express";
import { Guild, WidgetModifySchema } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Guild, WidgetModifySchema } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,6 +1,6 @@
import { Router, Request, Response } from "express";
import { Role, Guild, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile, GuildCreateSchema } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Config, DiscordApiErrors, getRights, Guild, GuildCreateSchema, Member } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -12,7 +12,7 @@ router.post("/", route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }), a
const { maxGuilds } = Config.get().limits.user;
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);
}

View File

@ -1,6 +1,6 @@
import { Request, Response, Router } from "express";
import { Template, Guild, Role, Snowflake, Config, User, Member, DiscordApiErrors, OrmUtils, GuildTemplateCreateSchema } from "@fosscord/util";
import { route } from "@fosscord/api";
import { Config, DiscordApiErrors, Guild, GuildTemplateCreateSchema, Member, OrmUtils, Role, Snowflake, Template } from "@fosscord/util";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
const router: Router = Router();
@ -11,7 +11,8 @@ router.get("/:code", route({}), async (req: Request, res: Response) => {
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}`, {
@ -57,7 +58,8 @@ router.post("/:code", route({ body: "GuildTemplateCreateSchema" }), async (req:
id: guild_id,
owner_id: req.user_id
}).save(),
(OrmUtils.mergeDeep(new Role(), {
(
OrmUtils.mergeDeep(new Role(), {
id: guild_id,
guild_id: guild_id,
color: 0,
@ -68,7 +70,8 @@ router.post("/:code", route({ body: "GuildTemplateCreateSchema" }), async (req:
permissions: BigInt("2251804225"),
position: 0,
tags: null
}) as Role).save()
}) as Role
).save()
]);
await Member.addToGuild(req.user_id, guild_id);

View File

@ -1,7 +1,6 @@
import { Router, Request, Response } from "express";
import { emitEvent, getPermission, Guild, Invite, InviteDeleteEvent, User, PublicInviteRelation } from "@fosscord/util";
import { route } from "@fosscord/api";
import { HTTPError } from "@fosscord/util";
import { emitEvent, getPermission, Guild, HTTPError, Invite, InviteDeleteEvent, PublicInviteRelation, User } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
@ -13,14 +12,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({ where: { code } })
const { features } = await Guild.findOneOrFail({ where: { id: guild_id} });
const { guild_id } = await Invite.findOneOrFail({ where: { 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);
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);

View File

@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,8 +1,5 @@
import { Guild, Config } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,6 +1,6 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
@ -18,8 +18,8 @@ router.get("/", route({}), (req: Request, res: Response) => {
correspondenceUserID: general.correspondenceUserID,
frontPage: general.frontPage,
tosPage: general.tosPage,
},
tosPage: general.tosPage
}
});
});

View File

@ -1,10 +1,9 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { config } from "dotenv"
import { Request, Response, Router } from "express";
const router = Router();
router.get("/",route({}), async (req: Request, res: Response) => {
router.get("/", route({}), async (req: Request, res: Response) => {
const { cdn, gateway } = Config.get();
const IdentityForm = {

View File

@ -1,10 +1,9 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/",route({}), async (req: Request, res: Response) => {
router.get("/", route({}), async (req: Request, res: Response) => {
const { general } = Config.get();
res.json(general);
});

View File

@ -1,9 +1,9 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Config } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/",route({}), async (req: Request, res: Response) => {
router.get("/", route({}), async (req: Request, res: Response) => {
const { limits } = Config.get();
res.json(limits);
});

View File

@ -1,11 +1,11 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/scheduled-maintenances/upcoming.json",route({}), async (req: Request, res: Response) => {
router.get("/scheduled-maintenances/upcoming.json", route({}), async (req: Request, res: Response) => {
res.json({
"page": {},
"scheduled_maintenances": {}
page: {},
scheduled_maintenances: {}
});
});

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,6 +1,6 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { StickerPack } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,6 +1,6 @@
import { Sticker } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { Sticker } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {

View File

@ -1,22 +1,21 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
import { User } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router: Router = Router();
router.post("/", route({}), async (req: Request, res: Response) => {
//EXPERIMENTAL: have an "OPERATOR" platform permission implemented for this API route
const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["rights"] });
if((Number(user.rights) << Number(0))%Number(2)==Number(1)) {
if ((Number(user.rights) << Number(0)) % Number(2) == Number(1)) {
console.log("user that POSTed to the API was ALLOWED");
console.log(user.rights);
res.sendStatus(200)
process.kill(process.pid, 'SIGTERM')
}
else {
res.sendStatus(200);
process.kill(process.pid, "SIGTERM");
} else {
console.log("operation failed");
console.log(user.rights);
res.sendStatus(403)
res.sendStatus(403);
}
});

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router: Router = Router();

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Request, Response, Router } from "express";
const router = Router();

View File

@ -1,13 +1,13 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { Config, Release } from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
const { client } = Config.get();
const release = await Release.findOneOrFail({ where: { name: client.releases.upstreamVersion } })
const release = await Release.findOneOrFail({ where: { name: client.releases.upstreamVersion } });
res.json({
name: release.name,

Some files were not shown because too many files have changed in this diff Show More