🎨 remove long relatives paths -> short module paths

This commit is contained in:
Flam3rboy 2021-09-12 21:09:29 +02:00
parent 7eea37d184
commit 60535f5159
79 changed files with 1633 additions and 261 deletions

76
api/package-lock.json generated
View File

@ -38,6 +38,7 @@
"node-fetch": "^2.6.1",
"patch-package": "^6.4.7",
"supertest": "^6.1.6",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37"
},
"devDependencies": {
@ -79,12 +80,13 @@
"env-paths": "^2.2.1",
"jsonwebtoken": "^8.5.1",
"lambert-server": "^1.2.10",
"missing-native-js-functions": "^1.2.14",
"missing-native-js-functions": "^1.2.15",
"node-fetch": "^2.6.1",
"patch-package": "^6.4.7",
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.2",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"
@ -1396,6 +1398,11 @@
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
"dev": true
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
},
"node_modules/@types/jsonwebtoken": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.4.tgz",
@ -11344,6 +11351,36 @@
"strip-json-comments": "^2.0.0"
}
},
"node_modules/tsconfig-paths": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"dependencies": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"dependencies": {
"minimist": "^1.2.0"
},
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/tsconfig-paths/node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"engines": {
"node": ">=4"
}
},
"node_modules/tsconfig/node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
@ -12977,12 +13014,13 @@
"jest": "^27.0.6",
"jsonwebtoken": "^8.5.1",
"lambert-server": "^1.2.10",
"missing-native-js-functions": "^1.2.14",
"missing-native-js-functions": "^1.2.15",
"node-fetch": "^2.6.1",
"patch-package": "^6.4.7",
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.2",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"
@ -13574,6 +13612,11 @@
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
"dev": true
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
},
"@types/jsonwebtoken": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.4.tgz",
@ -18703,8 +18746,7 @@
"dev": true
},
"mpath": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
"version": "https://registry.npmjs.org/mpath/-/mpath-0.8.4.tgz",
"integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA=="
},
"mquery": {
@ -21726,6 +21768,32 @@
}
}
},
"tsconfig-paths": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
},
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"requires": {
"minimist": "^1.2.0"
}
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
}
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",

View File

@ -7,7 +7,7 @@
"scripts": {
"test": "npm run build && jest --coverage --verbose --forceExit ./tests",
"test:watch": "jest --watch",
"start": "npm run build && node dist/start",
"start": "npm run build && node -r ./scripts/tsconfig-paths-bootstrap.js dist/start",
"build": "npx tsc -b .",
"build-docker": "tsc -p tsconfig-docker.json",
"dev": "tsnd --respawn src/start.ts",
@ -86,6 +86,7 @@
"node-fetch": "^2.6.1",
"patch-package": "^6.4.7",
"supertest": "^6.1.6",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37"
},
"jest": {

View File

@ -0,0 +1,10 @@
const tsConfigPaths = require("tsconfig-paths");
const path = require("path");
const cleanup = tsConfigPaths.register({
baseUrl: path.join(__dirname, ".."),
paths: {
"@fosscord/api": ["dist/index.js"],
"@fosscord/api/*": ["dist/*"]
}
});

View File

@ -1,12 +1,3 @@
export * from "./Server";
export * from "./middlewares/";
export * from "./schema/Ban";
export * from "./schema/Channel";
export * from "./schema/Guild";
export * from "./schema/Invite";
export * from "./schema/Message";
export * from "./util/instanceOf";
export * from "./util/instanceOf";
export * from "./util/RandomInviteID";
export * from "./util/String";
export { check as checkPassword } from "./util/passwordStrength";
export * from "./util/";

View File

@ -1,7 +1,7 @@
import { NextFunction, Request, Response } from "express";
import { HTTPError } from "lambert-server";
import { EntityNotFoundError } from "typeorm";
import { FieldError } from "../util/instanceOf";
import { FieldError } from "@fosscord/api";
import { ApiError } from "@fosscord/util";
export function ErrorHandler(error: Error, req: Request, res: Response, next: NextFunction) {

View File

@ -1,6 +1,6 @@
import { Config, listenEvent } from "@fosscord/util";
import { NextFunction, Request, Response, Router } from "express";
import { getIpAdress } from "../util/ipAddress";
import { getIpAdress } from "@fosscord/api";
import { API_PREFIX_TRAILING_SLASH } from "./Authentication";
// Docs: https://discord.com/developers/docs/topics/rate-limits

View File

@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
import { check, FieldErrors, Length } from "../../util/instanceOf";
import { check, FieldErrors, Length } from "@fosscord/api";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { Config, User } from "@fosscord/util";

View File

@ -1,10 +1,10 @@
import { Request, Response, Router } from "express";
import { trimSpecial, User, Snowflake, Config, defaultSettings } from "@fosscord/util";
import bcrypt from "bcrypt";
import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "../../util/instanceOf";
import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "@fosscord/api";
import "missing-native-js-functions";
import { generateToken } from "./login";
import { getIpAdress, IPAnalysis, isProxy } from "../../util/ipAddress";
import { getIpAdress, IPAnalysis, isProxy } from "@fosscord/api";
import { HTTPError } from "lambert-server";
import { In } from "typeorm";

View File

@ -2,7 +2,7 @@ import { ChannelDeleteEvent, Channel, ChannelUpdateEvent, emitEvent, getPermissi
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
import { ChannelModifySchema } from "../../../schema/Channel";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
const router: Router = Router();
// TODO: delete channel
// TODO: Get channel

View File

@ -1,7 +1,7 @@
import { Router, Request, Response } from "express";
import { HTTPError } from "lambert-server";
import { check } from "../../../util/instanceOf";
import { random } from "../../../util/RandomInviteID";
import { check } from "@fosscord/api";
import { random } from "@fosscord/api";
import { InviteCreateSchema } from "../../../schema/Invite";
import { getPermission, Channel, Invite, InviteCreateEvent, emitEvent, User, Guild, PublicInviteRelation } from "@fosscord/util";
import { isTextChannel } from "./messages";

View File

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

View File

@ -1,8 +1,8 @@
import { Channel, emitEvent, getPermission, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util";
import { Router, Response, Request } from "express";
import { MessageCreateSchema } from "../../../../../schema/Message";
import { check } from "../../../../../util/instanceOf";
import { handleMessage, postHandleMessage } from "../../../../../util/Message";
import { check } from "@fosscord/api";
import { handleMessage, postHandleMessage } from "@fosscord/api";
const router = Router();

View File

@ -2,7 +2,7 @@ import { Router, Response, Request } from "express";
import { Channel, Config, emitEvent, getPermission, MessageDeleteBulkEvent, Message } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "../../../../util/instanceOf";
import { check } from "@fosscord/api";
import { In } from "typeorm";
const router: Router = Router();

View File

@ -2,11 +2,11 @@ import { Router, Response, Request } from "express";
import { Attachment, Channel, ChannelType, getPermission, Message } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { MessageCreateSchema } from "../../../../schema/Message";
import { check, instanceOf, Length } from "../../../../util/instanceOf";
import { check, instanceOf, Length } from "@fosscord/api";
import multer from "multer";
import { Query } from "mongoose";
import { sendMessage } from "../../../../util/Message";
import { uploadFile } from "../../../../util/cdn";
import { sendMessage } from "@fosscord/api";
import { uploadFile } from "@fosscord/api";
import { FindManyOptions, LessThan, MoreThan } from "typeorm";
const router: Router = Router();

View File

@ -2,7 +2,7 @@ import { Channel, ChannelPermissionOverwrite, ChannelUpdateEvent, emitEvent, get
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
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)

View File

@ -1,5 +1,5 @@
import { Router, Response, Request } from "express";
import { check, Length } from "../../../util/instanceOf";
import { check, Length } from "@fosscord/api";
import { Channel, Config, getPermission, trimSpecial, Webhook } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { isTextChannel } from "./messages/index";

View File

@ -1,9 +1,8 @@
import { Request, Response, Router } from "express";
import { emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { getIpAdress } from "../../../util/ipAddress";
import { BanCreateSchema } from "../../../schema/Ban";
import { check } from "../../../util/instanceOf";
import { getIpAdress, check } from "@fosscord/api";
import { BanCreateSchema } from "@fosscord/api/schema/Ban";
const router: Router = Router();

View File

@ -3,7 +3,7 @@ import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord
import { HTTPError } from "lambert-server";
import { ChannelModifySchema } from "../../../schema/Channel";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
const router = Router();
router.get("/", async (req: Request, res: Response) => {

View File

@ -3,8 +3,8 @@ import { emitEvent, getPermission, Guild, GuildUpdateEvent, Member } from "@foss
import { HTTPError } from "lambert-server";
import { GuildUpdateSchema } from "../../../schema/Guild";
import { check } from "../../../util/instanceOf";
import { handleFile } from "../../../util/cdn";
import { check } from "@fosscord/api";
import { handleFile } from "@fosscord/api";
import "missing-native-js-functions";
const router = Router();

View File

@ -11,8 +11,8 @@ import {
emitEvent
} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "../../../../../util/instanceOf";
import { MemberChangeSchema } from "../../../../../schema/Member";
import { check } from "@fosscord/api";
import { MemberChangeSchema } from "@fosscord/api/schema/Member";
import { In } from "typeorm";
const router = Router();

View File

@ -1,6 +1,6 @@
import { Request, Response, Router } from "express";
import { Guild, Member, PublicMemberProjection } from "@fosscord/util";
import { instanceOf, Length } from "../../../../util/instanceOf";
import { instanceOf, Length } from "@fosscord/api";
import { MoreThan } from "typeorm";
const router = Router();

View File

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

View File

@ -12,7 +12,7 @@ import {
} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
import { RoleModifySchema, RolePositionUpdateSchema } from "../../../schema/Roles";
import { DiscordApiErrors } from "@fosscord/util";
import { In } from "typeorm";

View File

@ -2,8 +2,8 @@ import { Request, Response, Router } from "express";
import { Guild, getPermission, Template } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { TemplateCreateSchema, TemplateModifySchema } from "../../../schema/Template";
import { check } from "../../../util/instanceOf";
import { generateCode } from "../../../util/String";
import { check } from "@fosscord/api";
import { generateCode } from "@fosscord/api";
const router: Router = Router();

View File

@ -1,7 +1,7 @@
import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { HTTPError } from "lambert-server";
import { check, Length } from "../../../util/instanceOf";
import { check, Length } from "@fosscord/api";
const router = Router();

View File

@ -1,15 +1,15 @@
import { check } from "../../../../../util/instanceOf";
import { check } from "@fosscord/api";
import { VoiceStateUpdateSchema } from "../../../../../schema";
import { Request, Response, Router } from "express";
import { updateVoiceState } from "../../../../../util/VoiceState";
import { updateVoiceState } from "@fosscord/api";
const router = Router();
router.patch("/", check(VoiceStateUpdateSchema), async (req: Request, res: Response) => {
const body = req.body as VoiceStateUpdateSchema;
const { guild_id, user_id } = req.params;
await updateVoiceState(body, guild_id, req.user_id, user_id)
await updateVoiceState(body, guild_id, req.user_id, user_id);
return res.sendStatus(204);
});
export default router;
export default router;

View File

@ -1,15 +1,15 @@
import { check } from "../../../../../util/instanceOf";
import { check } from "@fosscord/api";
import { VoiceStateUpdateSchema } from "../../../../../schema";
import { Request, Response, Router } from "express";
import { updateVoiceState } from "../../../../../util/VoiceState";
import { updateVoiceState } from "@fosscord/api";
const router = Router();
router.patch("/", check(VoiceStateUpdateSchema), async (req: Request, res: Response) => {
const body = req.body as VoiceStateUpdateSchema;
const { guild_id } = req.params;
await updateVoiceState(body, guild_id, req.user_id)
await updateVoiceState(body, guild_id, req.user_id);
return res.sendStatus(204);
});
export default router;
export default router;

View File

@ -2,7 +2,7 @@ import { Request, Response, Router } from "express";
import { Guild, getPermission, Snowflake, Member } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
import { GuildUpdateWelcomeScreenSchema } from "../../../schema/Guild";
const router: Router = Router();

View File

@ -1,7 +1,7 @@
import { Request, Response, Router } from "express";
import { Config, Permissions, Guild, Invite, Channel, Member } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { random } from "../../../util/RandomInviteID";
import { random } from "@fosscord/api";
const router: Router = Router();

View File

@ -1,7 +1,7 @@
import { Request, Response, Router } from "express";
import { getPermission, Guild } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
import { WidgetModifySchema } from "../../../schema/Widget";
const router: Router = Router();

View File

@ -1,7 +1,7 @@
import { Router, Request, Response } from "express";
import { Role, Guild, Snowflake, Config, User, Member, Channel } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "./../../util/instanceOf";
import { check } from "@fosscord/api";
import { GuildCreateSchema } from "../../schema/Guild";
import { DiscordApiErrors } from "@fosscord/util";

View File

@ -3,7 +3,7 @@ const router: Router = Router();
import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { GuildTemplateCreateSchema } from "../../../schema/Guild";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
import { DiscordApiErrors } from "@fosscord/util";
router.get("/:code", async (req: Request, res: Response) => {

View File

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

View File

@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
import { PublicConnectedAccount, PublicUser, User, UserPublic } from "../../../../../util/dist";
import { PublicConnectedAccount, PublicUser, User, UserPublic } from "@fosscord/util";
const router: Router = Router();

View File

@ -1,11 +1,9 @@
import { Router, Request, Response } from "express";
import { Channel, ChannelCreateEvent, ChannelType, Snowflake, trimSpecial, User, emitEvent } from "@fosscord/util";
import { Channel, ChannelCreateEvent, ChannelType, Snowflake, trimSpecial, User, emitEvent, Recipient } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { DmChannelCreateSchema } from "../../../schema/Channel";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
import { In } from "typeorm";
import { Recipient } from "../../../../../util/dist/entities/Recipient";
const router: Router = Router();

View File

@ -1,8 +1,8 @@
import { Router, Request, Response } from "express";
import { User, PrivateUserProjection } from "@fosscord/util";
import { UserModifySchema } from "../../../schema/User";
import { check } from "../../../util/instanceOf";
import { handleFile } from "../../../util/cdn";
import { check } from "@fosscord/api";
import { handleFile } from "@fosscord/api";
const router: Router = Router();

View File

@ -12,7 +12,7 @@ import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
import { DiscordApiErrors } from "@fosscord/util";
import { check, Length } from "../../../util/instanceOf";
import { check, Length } from "@fosscord/api";
const router = Router();

View File

@ -1,6 +1,6 @@
import { Router, Response, Request } from "express";
import { User, UserSettings } from "@fosscord/util";
import { check } from "../../../util/instanceOf";
import { check } from "@fosscord/api";
import { UserSettingsSchema } from "../../../schema/User";
const router = Router();

View File

@ -1,11 +1,11 @@
import { Router, Request, Response } from "express";
import {getIpAdress} from "../../util/ipAddress";
import {getVoiceRegions} from "../../util/Voice";
import { getIpAdress } from "@fosscord/api";
import { getVoiceRegions } from "@fosscord/api";
const router: Router = Router();
router.get("/", async (req: Request, res: Response) => {
res.json(await getVoiceRegions(getIpAdress(req), true))//vip true?
res.json(await getVoiceRegions(getIpAdress(req), true)); //vip true?
});
export default router;

View File

@ -1,12 +1,12 @@
import { check } from "./../util/passwordStrength";
import { checkPassword } from "@fosscord/api";
console.log(check("123456789012345"));
console.log(checkPassword("123456789012345"));
// -> 0.25
console.log(check("ABCDEFGHIJKLMOPQ"));
console.log(checkPassword("ABCDEFGHIJKLMOPQ"));
// -> 0.25
console.log(check("ABC123___...123"));
console.log(checkPassword("ABC123___...123"));
// ->
console.log(check(""));
console.log(checkPassword(""));
// ->
// console.log(check(""));
// console.log(checkPassword(""));
// // ->

11
api/src/util/index.ts Normal file
View File

@ -0,0 +1,11 @@
export * from "./Base64";
export * from "./cdn";
export * from "./instanceOf";
export * from "./ipAddress";
export * from "./Message";
export * from "./passwordStrength";
export * from "./RandomInviteID";
export * from "./route";
export * from "./String";
export * from "./Voice";
export * from "./VoiceState";

View File

@ -16,7 +16,7 @@ const blocklist: string[] = []; // TODO: update ones passwordblocklist is stored
*
* Returns: 0 > pw > 1
*/
export function check(password: string): number {
export function checkPassword(password: string): number {
const { minLength, minNumbers, minUpperCase, minSymbols } = Config.get().register.password;
var strength = 0;

View File

View File

@ -63,6 +63,11 @@
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
"baseUrl": ".",
"paths": {
"@fosscord/api": ["src/index.ts"],
"@fosscord/api/*": ["src/*"]
}
}
}

View File

@ -17,7 +17,8 @@
"async-exit-hook": "^2.0.1",
"express": "^4.17.1",
"missing-native-js-functions": "^1.2.15",
"node-os-utils": "^1.3.5"
"node-os-utils": "^1.3.5",
"tsconfig-paths": "^3.11.0"
},
"devDependencies": {
"@types/amqplib": "^0.8.1",
@ -73,6 +74,7 @@
"node-fetch": "^2.6.1",
"patch-package": "^6.4.7",
"supertest": "^6.1.6",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37"
},
"devDependencies": {
@ -158,6 +160,7 @@
"missing-native-js-functions": "^1.2.15",
"mongoose-autopopulate": "^0.12.3",
"node-fetch": "^2.6.1",
"typeorm": "^0.2.37",
"uuid": "^8.3.2",
"ws": "^7.4.2"
},
@ -194,6 +197,7 @@
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.2",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"
@ -326,6 +330,11 @@
"i18next": ">=17.0.11"
}
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
},
"node_modules/@types/jsonwebtoken": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.4.tgz",
@ -795,6 +804,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"dependencies": {
"minimist": "^1.2.0"
},
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -846,6 +866,11 @@
"node": ">= 0.6"
}
},
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"node_modules/missing-native-js-functions": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.15.tgz",
@ -1025,6 +1050,14 @@
"node": ">= 0.6"
}
},
"node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"engines": {
"node": ">=4"
}
},
"node_modules/toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@ -1033,6 +1066,17 @@
"node": ">=0.6"
}
},
"node_modules/tsconfig-paths": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"dependencies": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@ -1145,6 +1189,7 @@
"supertest": "^6.1.6",
"ts-node": "^9.1.1",
"ts-node-dev": "^1.1.6",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"
@ -1211,6 +1256,7 @@
"mongoose-autopopulate": "^0.12.3",
"node-fetch": "^2.6.1",
"ts-node-dev": "^1.1.6",
"typeorm": "^0.2.37",
"typescript": "^4.2.3",
"uuid": "^8.3.2",
"ws": "^7.4.2"
@ -1238,6 +1284,7 @@
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.2",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"
@ -1334,6 +1381,11 @@
"i18next": ">=17.0.11"
}
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
},
"@types/jsonwebtoken": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.4.tgz",
@ -1731,6 +1783,14 @@
"has": "^1.0.3"
}
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"requires": {
"minimist": "^1.2.0"
}
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -1764,6 +1824,11 @@
"mime-db": "1.49.0"
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"missing-native-js-functions": {
"version": "1.2.15",
"resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.15.tgz",
@ -1912,11 +1977,27 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"tsconfig-paths": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
}
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",

View File

@ -11,7 +11,7 @@
"build:api": "cd ../api/ && npm run build",
"build:cdn": "cd ../cdn/ && npm run build",
"build:gateway": "cd ../gateway/ && npm run build",
"start": "npm run build && node dist/start.js",
"start": "npm run build && node -r ./tsconfig-paths-bootstrap.js dist/start.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
@ -52,6 +52,7 @@
"async-exit-hook": "^2.0.1",
"express": "^4.17.1",
"missing-native-js-functions": "^1.2.15",
"node-os-utils": "^1.3.5"
"node-os-utils": "^1.3.5",
"tsconfig-paths": "^3.11.0"
}
}

View File

@ -0,0 +1,14 @@
const tsConfigPaths = require("tsconfig-paths");
const path = require("path");
const cleanup = tsConfigPaths.register({
baseUrl: path.join(__dirname, "node_modules", "@fosscord"),
paths: {
"@fosscord/api": ["api/dist/index.js"],
"@fosscord/api/*": ["api/dist/*"],
"@fosscord/gateway": ["gateway/dist/index.js"],
"@fosscord/gateway/*": ["gateway/dist/*"],
"@fosscord/cdn": ["cdn/dist/index.js"],
"@fosscord/cdn/*": ["cdn/dist/*"],
},
});

View File

@ -7,7 +7,7 @@
"scripts": {
"test": "npm run build && jest --coverage ./tests",
"build": "npx tsc -b .",
"start": "npm run build && node dist/start.js"
"start": "npm run build && node -r ./scripts/tsconfig-paths-bootstrap.js dist/start.js"
},
"repository": {
"type": "git",

View File

@ -0,0 +1,10 @@
const tsConfigPaths = require("tsconfig-paths");
const path = require("path");
const cleanup = tsConfigPaths.register({
baseUrl: path.join(__dirname, ".."),
paths: {
"@fosscord/cdn": ["dist/index.js"],
"@fosscord/cdn/*": ["dist/*"],
},
});

View File

@ -1,73 +1,87 @@
import { Router, Response, Request } from "express";
import { Config, Snowflake } from "@fosscord/util";
import { storage } from "../util/Storage";
import { storage } from "@fosscord/cdn/util/Storage";
import FileType from "file-type";
import { HTTPError } from "lambert-server";
import { multer } from "../util/multer";
import { multer } from "@fosscord/cdn/util/multer";
import imageSize from "image-size";
const router = Router();
router.post("/:channel_id", multer.single("file"), async (req: Request, res: Response) => {
if (req.headers.signature !== Config.get().security.requestSignature)
throw new HTTPError("Invalid request signature");
if (!req.file) throw new HTTPError("file missing");
router.post(
"/:channel_id",
multer.single("file"),
async (req: Request, res: Response) => {
if (req.headers.signature !== Config.get().security.requestSignature)
throw new HTTPError("Invalid request signature");
if (!req.file) throw new HTTPError("file missing");
const { buffer, mimetype, size, originalname, fieldname } = req.file;
const { channel_id } = req.params;
const filename = originalname.replaceAll(" ", "_").replace(/[^a-zA-Z0-9._]+/g, "");
const id = Snowflake.generate();
const path = `attachments/${channel_id}/${id}/${filename}`;
const { buffer, mimetype, size, originalname, fieldname } = req.file;
const { channel_id } = req.params;
const filename = originalname
.replaceAll(" ", "_")
.replace(/[^a-zA-Z0-9._]+/g, "");
const id = Snowflake.generate();
const path = `attachments/${channel_id}/${id}/${filename}`;
const endpoint = Config.get()?.cdn.endpoint || "http://localhost:3003";
const endpoint = Config.get()?.cdn.endpoint || "http://localhost:3003";
await storage.set(path, buffer);
var width;
var height;
if (mimetype.includes("image")) {
const dimensions = imageSize(buffer);
if (dimensions) {
width = dimensions.width;
height = dimensions.height;
await storage.set(path, buffer);
var width;
var height;
if (mimetype.includes("image")) {
const dimensions = imageSize(buffer);
if (dimensions) {
width = dimensions.width;
height = dimensions.height;
}
}
const file = {
id,
content_type: mimetype,
filename: filename,
size,
url: `${endpoint}/${path}`,
width,
height,
};
return res.json(file);
}
);
const file = {
id,
content_type: mimetype,
filename: filename,
size,
url: `${endpoint}/${path}`,
width,
height,
};
router.get(
"/:channel_id/:id/:filename",
async (req: Request, res: Response) => {
const { channel_id, id, filename } = req.params;
return res.json(file);
});
const file = await storage.get(
`attachments/${channel_id}/${id}/${filename}`
);
if (!file) throw new HTTPError("File not found");
const type = await FileType.fromBuffer(file);
router.get("/:channel_id/:id/:filename", async (req: Request, res: Response) => {
const { channel_id, id, filename } = req.params;
res.set("Content-Type", type?.mime);
res.set("Cache-Control", "public, max-age=31536000");
const file = await storage.get(`attachments/${channel_id}/${id}/${filename}`);
if (!file) throw new HTTPError("File not found");
const type = await FileType.fromBuffer(file);
return res.send(file);
}
);
res.set("Content-Type", type?.mime);
res.set("Cache-Control", "public, max-age=31536000");
router.delete(
"/:channel_id/:id/:filename",
async (req: Request, res: Response) => {
if (req.headers.signature !== Config.get().security.requestSignature)
throw new HTTPError("Invalid request signature");
return res.send(file);
});
const { channel_id, id, filename } = req.params;
const path = `attachments/${channel_id}/${id}/${filename}`;
router.delete("/:channel_id/:id/:filename", async (req: Request, res: Response) => {
if (req.headers.signature !== Config.get().security.requestSignature)
throw new HTTPError("Invalid request signature");
await storage.delete(path);
const { channel_id, id, filename } = req.params;
const path = `attachments/${channel_id}/${id}/${filename}`;
await storage.delete(path);
return res.send({ success: true });
});
return res.send({ success: true });
}
);
export default router;

View File

@ -1,9 +1,9 @@
import { Router, Response, Request } from "express";
import { Config, Snowflake } from "@fosscord/util";
import { storage } from "../util/Storage";
import { storage } from "@fosscord/cdn/util/Storage";
import FileType from "file-type";
import { HTTPError } from "lambert-server";
import { multer } from "../util/multer";
import { multer } from "@fosscord/cdn/util/multer";
import crypto from "crypto";
// TODO: check premium and animated pfp are allowed in the config
@ -12,36 +12,50 @@ import crypto from "crypto";
// TODO: delete old icons
const ANIMATED_MIME_TYPES = ["image/apng", "image/gif", "image/gifv"];
const STATIC_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/svg+xml", "image/svg"];
const STATIC_MIME_TYPES = [
"image/png",
"image/jpeg",
"image/webp",
"image/svg+xml",
"image/svg",
];
const ALLOWED_MIME_TYPES = [...ANIMATED_MIME_TYPES, ...STATIC_MIME_TYPES];
const router = Router();
router.post("/:user_id", multer.single("file"), async (req: Request, res: Response) => {
if (req.headers.signature !== Config.get().security.requestSignature)
throw new HTTPError("Invalid request signature");
if (!req.file) throw new HTTPError("Missing file");
const { buffer, mimetype, size, originalname, fieldname } = req.file;
const { user_id } = req.params;
router.post(
"/:user_id",
multer.single("file"),
async (req: Request, res: Response) => {
if (req.headers.signature !== Config.get().security.requestSignature)
throw new HTTPError("Invalid request signature");
if (!req.file) throw new HTTPError("Missing file");
const { buffer, mimetype, size, originalname, fieldname } = req.file;
const { user_id } = req.params;
var hash = crypto.createHash("md5").update(Snowflake.generate()).digest("hex");
var hash = crypto
.createHash("md5")
.update(Snowflake.generate())
.digest("hex");
const type = await FileType.fromBuffer(buffer);
if (!type || !ALLOWED_MIME_TYPES.includes(type.mime)) throw new HTTPError("Invalid file type");
if (ANIMATED_MIME_TYPES.includes(type.mime)) hash = `a_${hash}`; // animated icons have a_ infront of the hash
const type = await FileType.fromBuffer(buffer);
if (!type || !ALLOWED_MIME_TYPES.includes(type.mime))
throw new HTTPError("Invalid file type");
if (ANIMATED_MIME_TYPES.includes(type.mime)) hash = `a_${hash}`; // animated icons have a_ infront of the hash
const path = `avatars/${user_id}/${hash}`;
const endpoint = Config.get().cdn.endpoint || "http://localhost:3003";
const path = `avatars/${user_id}/${hash}`;
const endpoint = Config.get().cdn.endpoint || "http://localhost:3003";
await storage.set(path, buffer);
await storage.set(path, buffer);
return res.json({
id: hash,
content_type: type.mime,
size,
url: `${endpoint}${req.baseUrl}/${user_id}/${hash}`,
});
});
return res.json({
id: hash,
content_type: type.mime,
size,
url: `${endpoint}${req.baseUrl}/${user_id}/${hash}`,
});
}
);
router.get("/:user_id/:hash", async (req: Request, res: Response) => {
var { user_id, hash } = req.params;

View File

@ -2,7 +2,7 @@ import { Router, Response, Request } from "express";
import fetch from "node-fetch";
import { HTTPError } from "lambert-server";
import { Snowflake } from "@fosscord/util";
import { storage } from "../util/Storage";
import { storage } from "@fosscord/cdn/util/Storage";
import FileType from "file-type";
import { Config } from "@fosscord/util";
@ -13,7 +13,8 @@ const DEFAULT_FETCH_OPTIONS: any = {
redirect: "follow",
follow: 1,
headers: {
"user-agent": "Mozilla/5.0 (compatible Fosscordbot/0.1; +https://fosscord.com)",
"user-agent":
"Mozilla/5.0 (compatible Fosscordbot/0.1; +https://fosscord.com)",
},
size: 1024 * 1024 * 8,
compress: true,

View File

@ -65,6 +65,11 @@
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
"baseUrl": ".",
"paths": {
"@fosscord/cdn/": ["src/index.ts"],
"@fosscord/cdn/*": ["src/*"]
}
}
}

1056
gateway/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npm run build && node dist/start.js",
"start": "npm run build && node -r ./scripts/tsconfig-paths-bootstrap.js dist/start.js",
"build": "npx tsc -b .",
"dev": "tsnd --respawn src/start.ts"
},
@ -35,6 +35,7 @@
"missing-native-js-functions": "^1.2.15",
"mongoose-autopopulate": "^0.12.3",
"node-fetch": "^2.6.1",
"typeorm": "^0.2.37",
"uuid": "^8.3.2",
"ws": "^7.4.2"
}

View File

@ -0,0 +1,10 @@
const tsConfigPaths = require("tsconfig-paths");
const path = require("path");
const cleanup = tsConfigPaths.register({
baseUrl: path.join(__dirname, ".."),
paths: {
"@fosscord/gateway": ["dist/index.js"],
"@fosscord/gateway/*": ["dist/*"],
},
});

View File

@ -1,4 +1,4 @@
import WebSocket from "../util/WebSocket";
import WebSocket from "@fosscord/gateway/util/WebSocket";
import { Message } from "./Message";
import { Session } from "@fosscord/util";

View File

@ -1,10 +1,10 @@
import WebSocket, { Server } from "../util/WebSocket";
import WebSocket, { Server } from "@fosscord/gateway/util/WebSocket";
import { IncomingMessage } from "http";
import { Close } from "./Close";
import { Message } from "./Message";
import { setHeartbeat } from "../util/setHeartbeat";
import { Send } from "../util/Send";
import { CLOSECODES, OPCODES } from "../util/Constants";
import { setHeartbeat } from "@fosscord/gateway/util/setHeartbeat";
import { Send } from "@fosscord/gateway/util/Send";
import { CLOSECODES, OPCODES } from "@fosscord/gateway/util/Constants";
import { createDeflate } from "zlib";
import { URL } from "url";
import { Session } from "@fosscord/util";
@ -17,7 +17,11 @@ try {
// TODO: specify rate limit in config
// TODO: check msg max size
export async function Connection(this: Server, socket: WebSocket, request: IncomingMessage) {
export async function Connection(
this: Server,
socket: WebSocket,
request: IncomingMessage
) {
try {
socket.on("close", Close);
// @ts-ignore
@ -27,18 +31,21 @@ export async function Connection(this: Server, socket: WebSocket, request: Incom
// @ts-ignore
socket.encoding = searchParams.get("encoding") || "json";
if (!["json", "etf"].includes(socket.encoding)) {
if (socket.encoding === "etf" && erlpack) throw new Error("Erlpack is not installed: 'npm i -D erlpack'");
if (socket.encoding === "etf" && erlpack)
throw new Error("Erlpack is not installed: 'npm i -D erlpack'");
return socket.close(CLOSECODES.Decode_error);
}
// @ts-ignore
socket.version = Number(searchParams.get("version")) || 8;
if (socket.version != 8) return socket.close(CLOSECODES.Invalid_API_version);
if (socket.version != 8)
return socket.close(CLOSECODES.Invalid_API_version);
// @ts-ignore
socket.compress = searchParams.get("compress") || "";
if (socket.compress) {
if (socket.compress !== "zlib-stream") return socket.close(CLOSECODES.Decode_error);
if (socket.compress !== "zlib-stream")
return socket.close(CLOSECODES.Decode_error);
socket.deflate = createDeflate({ chunkSize: 65535 });
socket.deflate.on("data", (chunk) => socket.send(chunk));
}

View File

@ -1,10 +1,10 @@
import WebSocket, { Data } from "../util/WebSocket";
import WebSocket, { Data } from "@fosscord/gateway/util/WebSocket";
var erlpack: any;
try {
erlpack = require("erlpack");
} catch (error) {}
import OPCodeHandlers from "../opcodes";
import { Payload, CLOSECODES, OPCODES } from "../util/Constants";
import { Payload, CLOSECODES, OPCODES } from "@fosscord/gateway/util/Constants";
import { instanceOf, Tuple } from "lambert-server";
import { check } from "../opcodes/instanceOf";
import WS from "ws";
@ -20,8 +20,10 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
// TODO: compression
var data: Payload;
if (this.encoding === "etf" && buffer instanceof Buffer) data = erlpack.unpack(buffer);
else if (this.encoding === "json" && typeof buffer === "string") data = JSON.parse(buffer);
if (this.encoding === "etf" && buffer instanceof Buffer)
data = erlpack.unpack(buffer);
else if (this.encoding === "json" && typeof buffer === "string")
data = JSON.parse(buffer);
else return;
check.call(this, PayloadSchema, data);
@ -41,6 +43,7 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
return await OPCodeHandler.call(this, data);
} catch (error) {
console.error(error);
if (!this.CLOSED && this.CLOSING) return this.close(CLOSECODES.Unknown_error);
if (!this.CLOSED && this.CLOSING)
return this.close(CLOSECODES.Unknown_error);
}
}

View File

@ -1 +1,4 @@
export * from "./Server";
export * from "./util/";
export * from "./opcodes/";
export * from "./listener/listener";

View File

@ -9,13 +9,13 @@ import {
ListenEventOpts,
Member,
} from "@fosscord/util";
import { OPCODES } from "../util/Constants";
import { Send } from "../util/Send";
import WebSocket from "../util/WebSocket";
import { OPCODES } from "@fosscord/gateway/util/Constants";
import { Send } from "@fosscord/gateway/util/Send";
import WebSocket from "@fosscord/gateway/util/WebSocket";
import "missing-native-js-functions";
import { Channel as AMQChannel } from "amqplib";
import { In, Like } from "../../../util/node_modules/typeorm";
import { Recipient } from "../../../util/dist/entities/Recipient";
import { In, Like } from "typeorm";
import { Recipient } from "@fosscord/util";
// TODO: close connection on Invalidated Token
// TODO: check intent

View File

@ -1,7 +1,7 @@
import { CLOSECODES, Payload } from "../util/Constants";
import { Send } from "../util/Send";
import { setHeartbeat } from "../util/setHeartbeat";
import WebSocket from "../util/WebSocket";
import { CLOSECODES, Payload } from "@fosscord/gateway/util/Constants";
import { Send } from "@fosscord/gateway/util/Send";
import { setHeartbeat } from "@fosscord/gateway/util/setHeartbeat";
import WebSocket from "@fosscord/gateway/util/WebSocket";
export async function onHeartbeat(this: WebSocket, data: Payload) {
// TODO: validate payload

View File

@ -1,5 +1,5 @@
import { CLOSECODES, Payload, OPCODES } from "../util/Constants";
import WebSocket from "../util/WebSocket";
import { CLOSECODES, Payload, OPCODES } from "@fosscord/gateway/util/Constants";
import WebSocket from "@fosscord/gateway/util/WebSocket";
import {
Channel,
checkToken,
@ -17,12 +17,12 @@ import {
} from "@fosscord/util";
import { setupListener } from "../listener/listener";
import { IdentifySchema } from "../schema/Identify";
import { Send } from "../util/Send";
import { Send } from "@fosscord/gateway/util/Send";
// import experiments from "./experiments.json";
const experiments: any = [];
import { check } from "./instanceOf";
import { Recipient } from "../../../util/dist/entities/Recipient";
import { genSessionId } from "../util/SessionUtils";
import { Recipient } from "@fosscord/util";
import { genSessionId } from "@fosscord/gateway/util/SessionUtils";
// TODO: bot sharding
// TODO: check priviliged intents

View File

@ -6,9 +6,9 @@ import {
Role,
} from "@fosscord/util";
import { LazyRequest } from "../schema/LazyRequest";
import { OPCODES, Payload } from "../util/Constants";
import { Send } from "../util/Send";
import WebSocket from "../util/WebSocket";
import { OPCODES, Payload } from "@fosscord/gateway/util/Constants";
import { Send } from "@fosscord/gateway/util/Send";
import WebSocket from "@fosscord/gateway/util/WebSocket";
import { check } from "./instanceOf";
import "missing-native-js-functions";

View File

@ -1,5 +1,5 @@
import { CLOSECODES, Payload } from "../util/Constants";
import WebSocket from "../util/WebSocket";
import { CLOSECODES, Payload } from "@fosscord/gateway/util/Constants";
import WebSocket from "@fosscord/gateway/util/WebSocket";
export function onPresenceUpdate(this: WebSocket, data: Payload) {
// return this.close(CLOSECODES.Unknown_error);

View File

@ -1,6 +1,6 @@
import { CLOSECODES, Payload } from "../util/Constants";
import { CLOSECODES, Payload } from "@fosscord/gateway/util/Constants";
import WebSocket from "../util/WebSocket";
import WebSocket from "@fosscord/gateway/util/WebSocket";
export function onRequestGuildMembers(this: WebSocket, data: Payload) {
// return this.close(CLOSECODES.Unknown_error);

View File

@ -1,7 +1,7 @@
import { CLOSECODES, Payload } from "../util/Constants";
import { Send } from "../util/Send";
import { CLOSECODES, Payload } from "@fosscord/gateway/util/Constants";
import { Send } from "@fosscord/gateway/util/Send";
import WebSocket from "../util/WebSocket";
import WebSocket from "@fosscord/gateway/util/WebSocket";
export async function onResume(this: WebSocket, data: Payload) {
console.log("Got Resume -> cancel not implemented");

View File

@ -1,9 +1,18 @@
import { VoiceStateUpdateSchema } from "../schema/VoiceStateUpdateSchema";
import { Payload } from "../util/Constants";
import WebSocket from "../util/WebSocket";
import { Payload } from "@fosscord/gateway/util/Constants";
import WebSocket from "@fosscord/gateway/util/WebSocket";
import { check } from "./instanceOf";
import { Config, emitEvent, Guild, Member, Region, VoiceServerUpdateEvent, VoiceState, VoiceStateUpdateEvent } from "@fosscord/util";
import { genVoiceToken } from "../util/SessionUtils";
import {
Config,
emitEvent,
Guild,
Member,
Region,
VoiceServerUpdateEvent,
VoiceState,
VoiceStateUpdateEvent,
} from "@fosscord/util";
import { genVoiceToken } from "@fosscord/gateway/util/SessionUtils";
// TODO: check if a voice server is setup
// Notice: Bot users respect the voice channel's user limit, if set. When the voice channel is full, you will not receive the Voice State Update or Voice Server Update events in response to your own Voice State Update. Having MANAGE_CHANNELS permission bypasses this limit and allows you to join regardless of the channel being full or not.
@ -14,21 +23,27 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
let voiceState: VoiceState;
try {
voiceState = await VoiceState.findOneOrFail({
where: { user_id: this.user_id }
where: { user_id: this.user_id },
});
if (voiceState.session_id !== this.session_id && body.channel_id === null) {
if (
voiceState.session_id !== this.session_id &&
body.channel_id === null
) {
//Should we also check guild_id === null?
//changing deaf or mute on a client that's not the one with the same session of the voicestate in the database should be ignored
return;
}
//If a user change voice channel between guild we should send a left event first
if (voiceState.guild_id !== body.guild_id && voiceState.session_id === this.session_id) {
if (
voiceState.guild_id !== body.guild_id &&
voiceState.session_id === this.session_id
) {
await emitEvent({
event: "VOICE_STATE_UPDATE",
data: { ...voiceState, channel_id: null },
guild_id: voiceState.guild_id,
})
});
}
//The event send by Discord's client on channel leave has both guild_id and channel_id as null
@ -50,10 +65,11 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
voiceState.member = await Member.findOneOrFail({
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();
if (voiceState.session_id !== this.session_id)
voiceState.token = genVoiceToken();
voiceState.session_id = this.session_id;
const { id, ...newObj } = voiceState;
@ -69,13 +85,17 @@ 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({ id: voiceState.guild_id });
const regions = Config.get().regions;
let guildRegion: Region;
if (guild && guild.region) {
guildRegion = regions.available.filter(r => (r.id === guild.region))[0]
guildRegion = regions.available.filter(
(r) => r.id === guild.region
)[0];
} else {
guildRegion = regions.available.filter(r => (r.id === regions.default))[0]
guildRegion = regions.available.filter(
(r) => r.id === regions.default
)[0];
}
await emitEvent({

View File

@ -1,5 +1,5 @@
import { Payload } from "../util/Constants";
import WebSocket from "../util/WebSocket";
import { Payload } from "@fosscord/gateway/util/Constants";
import WebSocket from "@fosscord/gateway/util/WebSocket";
import { onHeartbeat } from "./Heartbeat";
import { onIdentify } from "./Identify";
import { onLazyRequest } from "./LazyRequest";

View File

@ -1,6 +1,6 @@
import { instanceOf } from "lambert-server";
import { CLOSECODES } from "../util/Constants";
import WebSocket from "../util/WebSocket";
import { CLOSECODES } from "@fosscord/gateway/util/Constants";
import WebSocket from "@fosscord/gateway/util/WebSocket";
export function check(this: WebSocket, schema: any, data: any) {
try {

View File

@ -2,7 +2,7 @@ var erlpack: any;
try {
erlpack = require("erlpack");
} catch (error) {}
import { Payload } from "../util/Constants";
import { Payload } from "@fosscord/gateway/util/Constants";
import WebSocket from "./WebSocket";

View File

@ -1,7 +1,6 @@
import { Intents, Permissions } from "@fosscord/util";
import WS, { Server, Data } from "ws";
import WS from "ws";
import { Deflate } from "zlib";
import { Channel } from "amqplib";
interface WebSocket extends WS {
version: number;
@ -21,4 +20,3 @@ interface WebSocket extends WS {
}
export default WebSocket;
export { Server, Data };

View File

@ -0,0 +1,5 @@
export * from "./Constants";
export * from "./Send";
export * from "./SessionUtils";
export * from "./setHeartbeat";
export * from "./WebSocket";

View File

@ -67,6 +67,11 @@
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
"resolveJsonModule": true
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"@fosscord/gateway/*": ["src/*"],
"@fosscord/util/*": ["../util/src/*"]
}
}
}

67
util/package-lock.json generated
View File

@ -23,6 +23,7 @@
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.2",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"
@ -1156,6 +1157,11 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ=="
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
},
"node_modules/@types/jsonwebtoken": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.4.tgz",
@ -7875,6 +7881,14 @@
"node": ">=8"
}
},
"node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"engines": {
"node": ">=4"
}
},
"node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
@ -8042,6 +8056,28 @@
"node": ">=0.8"
}
},
"node_modules/tsconfig-paths": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"dependencies": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"dependencies": {
"minimist": "^1.2.0"
},
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
@ -9666,6 +9702,11 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ=="
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
},
"@types/jsonwebtoken": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.4.tgz",
@ -14925,6 +14966,11 @@
"ansi-regex": "^5.0.0"
}
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
},
"strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
@ -15051,6 +15097,27 @@
"punycode": "^2.1.1"
}
},
"tsconfig-paths": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
},
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"requires": {
"minimist": "^1.2.0"
}
}
}
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",

View File

@ -49,6 +49,7 @@
"pg": "^8.7.1",
"reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.2",
"tsconfig-paths": "^3.11.0",
"typeorm": "^0.2.37",
"typescript": "^4.4.2",
"typescript-json-schema": "^0.50.1"

View File

@ -423,6 +423,51 @@ export interface RelationshipRemoveEvent extends Event {
data: Omit<Relationship, "nickname">;
}
export type EventData =
| InvalidatedEvent
| ReadyEvent
| ChannelCreateEvent
| ChannelUpdateEvent
| ChannelDeleteEvent
| ChannelPinsUpdateEvent
| GuildCreateEvent
| GuildUpdateEvent
| GuildDeleteEvent
| GuildBanAddEvent
| GuildBanRemoveEvent
| GuildEmojiUpdateEvent
| GuildIntegrationUpdateEvent
| GuildMemberAddEvent
| GuildMemberRemoveEvent
| GuildMemberUpdateEvent
| GuildMembersChunkEvent
| GuildRoleCreateEvent
| GuildRoleUpdateEvent
| GuildRoleDeleteEvent
| InviteCreateEvent
| InviteDeleteEvent
| MessageCreateEvent
| MessageUpdateEvent
| MessageDeleteEvent
| MessageDeleteBulkEvent
| MessageReactionAddEvent
| MessageReactionRemoveEvent
| MessageReactionRemoveAllEvent
| MessageReactionRemoveEmojiEvent
| PresenceUpdateEvent
| TypingStartEvent
| UserUpdateEvent
| VoiceStateUpdateEvent
| VoiceServerUpdateEvent
| WebhooksUpdateEvent
| ApplicationCommandCreateEvent
| ApplicationCommandUpdateEvent
| ApplicationCommandDeleteEvent
| InteractionCreateEvent
| MessageAckEvent
| RelationshipAddEvent
| RelationshipRemoveEvent;
// located in collection events
export enum EVENTEnum {

View File

@ -632,7 +632,7 @@ export const DiscordApiErrors = {
OAUTH2_APPLICATION_BOT_ABSENT: new ApiError("OAuth2 application does not have a bot", 50010),
MAXIMUM_OAUTH2_APPLICATIONS: new ApiError("OAuth2 application limit reached", 50011),
INVALID_OAUTH_STATE: new ApiError("Invalid OAuth2 state", 50012),
MISSING_PERMISSIONS: new ApiError("You lack permissions to perform that action", 50013),
MISSING_PERMISSIONS: new ApiError("You lack permissions to perform that action ({})", 50013, undefined, [""]),
INVALID_AUTHENTICATION_TOKEN: new ApiError("Invalid authentication token provided", 50014),
NOTE_TOO_LONG: new ApiError("Note was too long", 50015),
INVALID_BULK_DELETE_QUANTITY: new ApiError(

View File

@ -21,7 +21,7 @@ export function initDatabase() {
//
entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"),
synchronize: true,
logging: false,
logging: true,
cache: {
duration: 1000 * 3, // cache all find queries for 3 seconds
},