mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-06 10:52:31 +01:00
Merge branch 'master' into fix/claim_accounts
This commit is contained in:
commit
cf9a923838
45
Dockerfile
45
Dockerfile
@ -1,7 +1,40 @@
|
|||||||
FROM node:14
|
FROM node:alpine
|
||||||
WORKDIR /usr/src/fosscord-server/
|
|
||||||
COPY . .
|
# env vars
|
||||||
WORKDIR /usr/src/fosscord-server/bundle
|
ENV WORK_DIR="/srv/fosscord-server"
|
||||||
|
ENV DEV_MODE=0
|
||||||
|
ENV HTTP_PORT=3001
|
||||||
|
ENV WS_PORT=3002
|
||||||
|
ENV CDN_PORT=3003
|
||||||
|
ENV RTC_PORT=3004
|
||||||
|
ENV ADMIN_PORT=3005
|
||||||
|
|
||||||
|
# exposed ports (only for reference, see https://docs.docker.com/engine/reference/builder/#expose)
|
||||||
|
EXPOSE ${HTTP_PORT}/tcp ${WS_PORT}/tcp ${CDN_PORT}/tcp ${RTC_PORT}/tcp ${ADMIN_PORT}/tcp
|
||||||
|
|
||||||
|
# install required apps
|
||||||
|
RUN apk add --no-cache --update git python2 py-pip make build-base
|
||||||
|
|
||||||
|
# optionl: packages for debugging/development
|
||||||
|
RUN apk add --no-cache sqlite
|
||||||
|
|
||||||
|
# download fosscord-server
|
||||||
|
WORKDIR $WORK_DIR/src
|
||||||
|
RUN git clone https://github.com/fosscord/fosscord-server.git .
|
||||||
|
|
||||||
|
# setup and run
|
||||||
|
WORKDIR $WORK_DIR/src/bundle
|
||||||
RUN npm run setup
|
RUN npm run setup
|
||||||
EXPOSE 3001
|
RUN npm install @yukikaze-bot/erlpack
|
||||||
CMD [ "npm", "run", "start:bundle" ]
|
# RUN npm install mysql --save
|
||||||
|
|
||||||
|
# create update script
|
||||||
|
RUN printf '#!/bin/sh\n\ngit -C $WORK_DIR/src/ checkout master\ngit -C $WORK_DIR/src/ reset --hard HEAD\ngit -C $WORK_DIR/src/ pull\ncd $WORK_DIR/src/bundle/\nnpm run setup\n' > $WORK_DIR/update.sh
|
||||||
|
RUN chmod +x $WORK_DIR/update.sh
|
||||||
|
|
||||||
|
# configure entrypoint file
|
||||||
|
RUN printf '#!/bin/sh\n\nDEV_MODE=${DEV_MODE:-0}\n\nif [ "$DEV_MODE" -eq 1 ]; then\n tail -f /dev/null\nelse\n cd $WORK_DIR/src/bundle/\n npm run start:bundle\nfi\n' > $WORK_DIR/entrypoint.sh
|
||||||
|
RUN chmod +x $WORK_DIR/entrypoint.sh
|
||||||
|
|
||||||
|
WORKDIR $WORK_DIR
|
||||||
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
|
@ -30,6 +30,6 @@ This repository contains:
|
|||||||
|
|
||||||
- [Contributing](https://docs.fosscord.com/contributing/server/)
|
- [Contributing](https://docs.fosscord.com/contributing/server/)
|
||||||
|
|
||||||
## [Setup](https://docs.fosscord.com/setup/server/)
|
## [Setup](https://docs.fosscord.com/server/setup/)
|
||||||
|
|
||||||
- [Download](https://github.com/fosscord/fosscord-server/releases)
|
- [Download](https://github.com/fosscord/fosscord-server/releases)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"openapi": "3.0.0",
|
"openapi": "3.0.0",
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"url": "https://api.fosscord.com/v{version}",
|
"url": "https://api.fosscord.com/api/v{version}",
|
||||||
"description": "Official fosscord instance",
|
"description": "Official fosscord instance",
|
||||||
"variables": {
|
"variables": {
|
||||||
"version": {
|
"version": {
|
||||||
@ -2960,7 +2960,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"verifie": {
|
"verified": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"visibility": {
|
"visibility": {
|
||||||
@ -2980,7 +2980,7 @@
|
|||||||
"type",
|
"type",
|
||||||
"user",
|
"user",
|
||||||
"user_id",
|
"user_id",
|
||||||
"verifie",
|
"verified",
|
||||||
"visibility"
|
"visibility"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -3119,7 +3119,7 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"enum": ["dnd", "idle", "offline", "online"],
|
"enum": ["dnd", "idle", "offline", "online", "invisible"],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"stream_notifications_enabled": {
|
"stream_notifications_enabled": {
|
||||||
@ -5677,7 +5677,7 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"enum": ["dnd", "idle", "offline", "online"],
|
"enum": ["dnd", "idle", "offline", "online", "invisible"],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"stream_notifications_enabled": {
|
"stream_notifications_enabled": {
|
||||||
|
12
api/assets/preload-plugins/fosscord-login.js
Normal file
12
api/assets/preload-plugins/fosscord-login.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Remove `<link id="logincss" rel="stylesheet" href="/assets/fosscord-login.css" />` from header when we're not accessing `/login` or `/register`
|
||||||
|
// fosscord-login.css replaces discord's TOS tooltip with something more fitting for fosscord, which when included in the main app, causes other tooltips
|
||||||
|
// to be affected, which is potentially unwanted.
|
||||||
|
//
|
||||||
|
// This script removes fosscord-login.css when a user reloads the page. From testing, it appears fosscord already properly removes
|
||||||
|
// fosscord-login.css after login is successful, but not if you reload the page after logging in. This script is to remove fosscord-login.css in
|
||||||
|
// that specific case.
|
||||||
|
|
||||||
|
var token = JSON.parse(localStorage.getItem("token"));
|
||||||
|
if (!token && location.pathname !== "/login" && location.pathname !== "/register") {
|
||||||
|
document.getElementById("logincss").remove();
|
||||||
|
}
|
@ -355,11 +355,11 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"verifie": {
|
"verified": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["name", "type", "verifie"]
|
"required": ["name", "type", "verified"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
@ -7900,7 +7900,7 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"enum": ["dnd", "idle", "offline", "online"],
|
"enum": ["dnd", "idle", "offline", "online", "invisible"],
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"stream_notifications_enabled": {
|
"stream_notifications_enabled": {
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
"BASE_TYPE_BOOLEAN": "This field must be a boolean",
|
"BASE_TYPE_BOOLEAN": "This field must be a boolean",
|
||||||
"BASE_TYPE_CHOICES": "This field must be one of ({{types}})",
|
"BASE_TYPE_CHOICES": "This field must be one of ({{types}})",
|
||||||
"BASE_TYPE_CLASS": "This field must be an instance of {{type}}",
|
"BASE_TYPE_CLASS": "This field must be an instance of {{type}}",
|
||||||
"BASE_TYPE_OBJECT": "This field must be an object",
|
"BASE_TYPE_OBJECT": "שדה זה חייב להיות אובייקט",
|
||||||
"BASE_TYPE_ARRAY": "This field must be an array",
|
"BASE_TYPE_ARRAY": "שדה זה חייב להיות מערך",
|
||||||
"UNKOWN_FIELD": "Unknown key: {{key}}",
|
"UNKOWN_FIELD": "מפתח לא ידוע: {{key}}",
|
||||||
"BASE_TYPE_CONSTANT": "This field must be {{value}}",
|
"BASE_TYPE_CONSTANT": "שדה זה להיות {{value}}",
|
||||||
"EMAIL_TYPE_INVALID_EMAIL": "Not a well-formed email address",
|
"EMAIL_TYPE_INVALID_EMAIL": "כתובת דואר אלקטרוני לא חוקית",
|
||||||
"DATE_TYPE_PARSE": "Could not parse {{date}}. Should be ISO8601",
|
"DATE_TYPE_PARSE": "לא ניתן לנתח {{date}}. צריך להיות ISO8601",
|
||||||
"BASE_TYPE_BAD_LENGTH": "Must be between {{length}} in length"
|
"BASE_TYPE_BAD_LENGTH": "האורך חייב להיות בין {{length}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6397
api/package-lock.json
generated
6397
api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,7 @@
|
|||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/multer": "^1.4.5",
|
"@types/multer": "^1.4.5",
|
||||||
"@types/node": "^14.17.9",
|
"@types/node": "^14.17.9",
|
||||||
"@types/node-fetch": "^2.5.7",
|
"@types/node-fetch": "^2.5.5",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@zerollup/ts-transform-paths": "^1.7.18",
|
"@zerollup/ts-transform-paths": "^1.7.18",
|
||||||
"jest": "^27.2.5",
|
"jest": "^27.2.5",
|
||||||
@ -86,7 +86,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.18",
|
"missing-native-js-functions": "^1.2.18",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"node-fetch": "^3.1.1",
|
"node-fetch": "^2.6.2",
|
||||||
"patch-package": "^6.4.7",
|
"patch-package": "^6.4.7",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
"proxy-agent": "^5.0.0",
|
"proxy-agent": "^5.0.0",
|
||||||
|
@ -26,6 +26,6 @@ DROP TABLE webhooks;
|
|||||||
DROP TABLE channels;
|
DROP TABLE channels;
|
||||||
DROP TABLE members;
|
DROP TABLE members;
|
||||||
DROP TABLE guilds;
|
DROP TABLE guilds;
|
||||||
DROP TABLE client_relase;
|
DROP TABLE client_release;
|
||||||
-- DROP TABLE users;
|
-- DROP TABLE users;
|
||||||
-- DROP TABLE config;
|
-- DROP TABLE config;
|
@ -15,6 +15,7 @@ export const NO_AUTHORIZATION_ROUTES = [
|
|||||||
"/experiments",
|
"/experiments",
|
||||||
"/updates",
|
"/updates",
|
||||||
"/downloads/",
|
"/downloads/",
|
||||||
|
"/scheduled-maintenances/upcoming.json",
|
||||||
// Public kubernetes integration
|
// Public kubernetes integration
|
||||||
"/-/readyz",
|
"/-/readyz",
|
||||||
"/-/healthz",
|
"/-/healthz",
|
||||||
|
@ -19,7 +19,8 @@ export interface InviteCreateSchema {
|
|||||||
target_user_type?: number;
|
target_user_type?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE" }), async (req: Request, res: Response) => {
|
router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES" }),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
const { user_id } = req;
|
const { user_id } = req;
|
||||||
const { channel_id } = req.params;
|
const { channel_id } = req.params;
|
||||||
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, select: ["id", "name", "type", "guild_id"] });
|
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, select: ["id", "name", "type", "guild_id"] });
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Channel, emitEvent, getPermission, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util";
|
import { Channel, emitEvent, getPermission, getRights, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util";
|
||||||
import { Router, Response, Request } from "express";
|
import { Router, Response, Request } from "express";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
import { handleMessage, postHandleMessage } from "@fosscord/api";
|
import { handleMessage, postHandleMessage } from "@fosscord/api";
|
||||||
@ -7,7 +7,7 @@ import { MessageCreateSchema } from "../index";
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
// TODO: message content/embed string length limit
|
// TODO: message content/embed string length limit
|
||||||
|
|
||||||
router.patch("/", route({ body: "MessageCreateSchema", permission: "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;
|
const { message_id, channel_id } = req.params;
|
||||||
var body = req.body as MessageCreateSchema;
|
var body = req.body as MessageCreateSchema;
|
||||||
|
|
||||||
@ -15,10 +15,15 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE
|
|||||||
|
|
||||||
const permissions = await getPermission(req.user_id, undefined, channel_id);
|
const permissions = await getPermission(req.user_id, undefined, channel_id);
|
||||||
|
|
||||||
if (req.user_id !== message.author_id) {
|
const rights = await getRights(req.user_id);
|
||||||
|
|
||||||
|
if ((req.user_id !== message.author_id)) {
|
||||||
|
if (!rights.has("MANAGE_MESSAGES")) {
|
||||||
permissions.hasThrow("MANAGE_MESSAGES");
|
permissions.hasThrow("MANAGE_MESSAGES");
|
||||||
body = { flags: body.flags }; // admins can only suppress embeds of other messages
|
body = { flags: body.flags };
|
||||||
|
// guild admins can only suppress embeds of other messages, no such restriction imposed to instance-wide admins
|
||||||
}
|
}
|
||||||
|
} else rights.hasThrow("SELF_EDIT_MESSAGES");
|
||||||
|
|
||||||
const new_message = await handleMessage({
|
const new_message = await handleMessage({
|
||||||
...message,
|
...message,
|
||||||
@ -46,17 +51,20 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE
|
|||||||
return res.json(message);
|
return res.json(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
// permission check only if deletes messagr from other user
|
|
||||||
router.delete("/", route({}), async (req: Request, res: Response) => {
|
router.delete("/", route({}), async (req: Request, res: Response) => {
|
||||||
const { message_id, channel_id } = req.params;
|
const { message_id, channel_id } = req.params;
|
||||||
|
|
||||||
const channel = await Channel.findOneOrFail({ id: channel_id });
|
const channel = await Channel.findOneOrFail({ id: channel_id });
|
||||||
const message = await Message.findOneOrFail({ id: message_id });
|
const message = await Message.findOneOrFail({ id: message_id });
|
||||||
|
|
||||||
if (message.author_id !== req.user_id) {
|
const rights = await getRights(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);
|
const permission = await getPermission(req.user_id, channel.guild_id, channel_id);
|
||||||
permission.hasThrow("MANAGE_MESSAGES");
|
permission.hasThrow("MANAGE_MESSAGES");
|
||||||
}
|
}
|
||||||
|
} else rights.hasThrow("SELF_DELETE_MESSAGES");
|
||||||
|
|
||||||
await Message.delete({ id: message_id });
|
await Message.delete({ id: message_id });
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Router, Response, Request } from "express";
|
import { Router, Response, Request } from "express";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
import { Relase, Config } from "@fosscord/util";
|
import { Release, Config } from "@fosscord/util";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@ -12,9 +12,9 @@ router.get("/:branch", route({}), async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
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 relase = await Relase.findOneOrFail({ name: client.relases.upstreamVersion });
|
const release = await Release.findOneOrFail({ name: client.releases.upstreamVersion });
|
||||||
|
|
||||||
res.redirect(relase[`win_url`]);
|
res.redirect(release[`win_url`]);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -33,17 +33,32 @@ router.get("/", route({ permission: "BAN_MEMBERS" }), async (req: Request, res:
|
|||||||
const { guild_id } = req.params;
|
const { guild_id } = req.params;
|
||||||
|
|
||||||
let bans = await Ban.find({ guild_id: guild_id });
|
let bans = await Ban.find({ guild_id: guild_id });
|
||||||
|
let promisesToAwait: object[] = [];
|
||||||
|
const bansObj: object[] = [];
|
||||||
|
|
||||||
/* Filter secret from database registry.*/
|
bans.filter((ban) => ban.user_id !== ban.executor_id); // pretend self-bans don't exist to prevent victim chasing
|
||||||
|
|
||||||
bans.filter(ban => ban.user_id !== ban.executor_id);
|
bans.forEach((ban) => {
|
||||||
// pretend self-bans don't exist to prevent victim chasing
|
promisesToAwait.push(User.getPublicUser(ban.user_id));
|
||||||
|
|
||||||
bans.forEach((registry: BanRegistrySchema) => {
|
|
||||||
delete registry.ip;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json(bans);
|
const bannedUsers: object[] = await Promise.all(promisesToAwait);
|
||||||
|
|
||||||
|
bans.forEach((ban, index) => {
|
||||||
|
const user = bannedUsers[index] as User;
|
||||||
|
bansObj.push({
|
||||||
|
reason: ban.reason,
|
||||||
|
user: {
|
||||||
|
username: user.username,
|
||||||
|
discriminator: user.discriminator,
|
||||||
|
id: user.id,
|
||||||
|
avatar: user.avatar,
|
||||||
|
public_flags: user.public_flags
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json(bansObj);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
|
router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Request, Response, Router } from "express";
|
import { Request, Response, Router } from "express";
|
||||||
import { emitEvent, getPermission, Guild, GuildUpdateEvent, handleFile, Member } from "@fosscord/util";
|
import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, handleFile, Member } from "@fosscord/util";
|
||||||
import { HTTPError } from "lambert-server";
|
import { HTTPError } from "lambert-server";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
import "missing-native-js-functions";
|
import "missing-native-js-functions";
|
||||||
@ -37,9 +37,17 @@ router.get("/", route({}), async (req: Request, res: Response) => {
|
|||||||
return res.send(guild);
|
return res.send(guild);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.patch("/", route({ body: "GuildUpdateSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
|
router.patch("/", route({ body: "GuildUpdateSchema"}), async (req: Request, res: Response) => {
|
||||||
const body = req.body as GuildUpdateSchema;
|
const body = req.body as GuildUpdateSchema;
|
||||||
const { guild_id } = req.params;
|
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"))
|
||||||
|
throw DiscordApiErrors.MISSING_PERMISSIONS.withParams("MANAGE_GUILD");
|
||||||
|
|
||||||
// TODO: guild update check image
|
// TODO: guild update check image
|
||||||
|
|
||||||
if (body.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon);
|
if (body.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon);
|
||||||
|
@ -25,13 +25,19 @@ router.patch("/", route({ body: "MemberChangeSchema" }), async (req: Request, re
|
|||||||
|
|
||||||
const member = await Member.findOneOrFail({ where: { id: member_id, guild_id }, relations: ["roles", "user"] });
|
const member = await Member.findOneOrFail({ where: { id: member_id, guild_id }, relations: ["roles", "user"] });
|
||||||
const permission = await getPermission(req.user_id, guild_id);
|
const permission = await getPermission(req.user_id, guild_id);
|
||||||
|
const everyone = await Role.findOneOrFail({ guild_id: guild_id, name: "@everyone", position: 0 });
|
||||||
|
|
||||||
if (body.roles) {
|
if (body.roles) {
|
||||||
permission.hasThrow("MANAGE_ROLES");
|
permission.hasThrow("MANAGE_ROLES");
|
||||||
|
|
||||||
|
if (body.roles.indexOf(everyone.id) === -1) body.roles.push(everyone.id);
|
||||||
member.roles = body.roles.map((x) => new Role({ id: x })); // foreign key constraint will fail if role doesn't exist
|
member.roles = body.roles.map((x) => new Role({ id: x })); // foreign key constraint will fail if role doesn't exist
|
||||||
}
|
}
|
||||||
|
|
||||||
await member.save();
|
await member.save();
|
||||||
|
|
||||||
|
member.roles = member.roles.filter((x) => x.id !== everyone.id);
|
||||||
|
|
||||||
// do not use promise.all as we have to first write to db before emitting the event to catch errors
|
// do not use promise.all as we have to first write to db before emitting the event to catch errors
|
||||||
await emitEvent({
|
await emitEvent({
|
||||||
event: "GUILD_MEMBER_UPDATE",
|
event: "GUILD_MEMBER_UPDATE",
|
||||||
|
@ -9,11 +9,19 @@ const InviteRegex = /\W/g;
|
|||||||
|
|
||||||
router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
|
router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
|
||||||
const { guild_id } = req.params;
|
const { guild_id } = req.params;
|
||||||
|
const guild = await Guild.findOneOrFail({ id: guild_id });
|
||||||
|
|
||||||
|
if (!guild.features.includes("ALIASABLE_NAMES")) {
|
||||||
const invite = await Invite.findOne({ where: { guild_id: guild_id, vanity_url: true } });
|
const invite = await Invite.findOne({ where: { guild_id: guild_id, vanity_url: true } });
|
||||||
if (!invite) return res.json({ code: null });
|
if (!invite) return res.json({ code: null });
|
||||||
|
|
||||||
return res.json({ code: invite.code, uses: invite.uses });
|
return res.json({ code: invite.code, uses: invite.uses });
|
||||||
|
} else {
|
||||||
|
const invite = await Invite.find({ where: { guild_id: guild_id, vanity_url: true } });
|
||||||
|
if (!invite || invite.length == 0) return res.json({ code: null });
|
||||||
|
|
||||||
|
return res.json(invite.map((x) => ({ code: x.code, uses: x.uses })));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface VanityUrlSchema {
|
export interface VanityUrlSchema {
|
||||||
@ -24,18 +32,33 @@ export interface VanityUrlSchema {
|
|||||||
code?: string;
|
code?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check if guild is elgible for vanity url
|
|
||||||
router.patch("/", route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
|
router.patch("/", route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
|
||||||
const { guild_id } = req.params;
|
const { guild_id } = req.params;
|
||||||
const body = req.body as VanityUrlSchema;
|
const body = req.body as VanityUrlSchema;
|
||||||
const code = body.code?.replace(InviteRegex, "");
|
const code = body.code?.replace(InviteRegex, "");
|
||||||
|
|
||||||
|
const guild = await Guild.findOneOrFail({ id: guild_id });
|
||||||
|
if (!guild.features.includes("VANITY_URL")) throw new HTTPError("Your guild doesn't support vanity urls");
|
||||||
|
|
||||||
|
if (!code || code.length === 0) throw new HTTPError("Code cannot be null or empty");
|
||||||
|
|
||||||
const invite = await Invite.findOne({ code });
|
const invite = await Invite.findOne({ code });
|
||||||
if (invite) throw new HTTPError("Invite already exists");
|
if (invite) throw new HTTPError("Invite already exists");
|
||||||
|
|
||||||
const { id } = await Channel.findOneOrFail({ guild_id, type: ChannelType.GUILD_TEXT });
|
const { id } = await Channel.findOneOrFail({ guild_id, type: ChannelType.GUILD_TEXT });
|
||||||
|
|
||||||
await Invite.update({ vanity_url: true, guild_id }, { code: code, channel_id: id });
|
await new Invite({
|
||||||
|
vanity_url: true,
|
||||||
|
code: code,
|
||||||
|
temporary: false,
|
||||||
|
uses: 0,
|
||||||
|
max_uses: 0,
|
||||||
|
max_age: 0,
|
||||||
|
created_at: new Date(),
|
||||||
|
expires_at: new Date(),
|
||||||
|
guild_id: guild_id,
|
||||||
|
channel_id: id
|
||||||
|
}).save();
|
||||||
|
|
||||||
return res.json({ code: code });
|
return res.json({ code: code });
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Router, Request, Response } from "express";
|
import { Router, Request, Response } from "express";
|
||||||
import { Role, Guild, Snowflake, Config, Member, Channel, DiscordApiErrors, handleFile } from "@fosscord/util";
|
import { Role, Guild, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile } from "@fosscord/util";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
import { ChannelModifySchema } from "../channels/#channel_id";
|
import { ChannelModifySchema } from "../channels/#channel_id";
|
||||||
|
|
||||||
@ -20,12 +20,13 @@ export interface GuildCreateSchema {
|
|||||||
|
|
||||||
//TODO: create default channel
|
//TODO: create default channel
|
||||||
|
|
||||||
router.post("/", route({ body: "GuildCreateSchema" }), async (req: Request, res: Response) => {
|
router.post("/", route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }), async (req: Request, res: Response) => {
|
||||||
const body = req.body as GuildCreateSchema;
|
const body = req.body as GuildCreateSchema;
|
||||||
|
|
||||||
const { maxGuilds } = Config.get().limits.user;
|
const { maxGuilds } = Config.get().limits.user;
|
||||||
const guild_count = await Member.count({ id: req.user_id });
|
const guild_count = await Member.count({ id: req.user_id });
|
||||||
if (guild_count >= maxGuilds) {
|
const rights = await getRights(req.user_id);
|
||||||
|
if ((guild_count >= maxGuilds)&&!rights.has("MANAGE_GUILDS")) {
|
||||||
throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds);
|
throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ router.get("/:code", route({}), async (req: Request, res: Response) => {
|
|||||||
res.status(200).send(invite);
|
res.status(200).send(invite);
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/:code", route({}), async (req: Request, res: Response) => {
|
router.post("/:code", route({right: "JOIN_GUILDS"}), async (req: Request, res: Response) => {
|
||||||
const { code } = req.params;
|
const { code } = req.params;
|
||||||
const { guild_id } = await Invite.findOneOrFail({ code })
|
const { guild_id } = await Invite.findOneOrFail({ code })
|
||||||
const { features } = await Guild.findOneOrFail({ id: guild_id});
|
const { features } = await Guild.findOneOrFail({ id: guild_id});
|
||||||
|
12
api/src/routes/scheduled-maintenances/upcoming_json.ts
Normal file
12
api/src/routes/scheduled-maintenances/upcoming_json.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Router, Request, Response } from "express";
|
||||||
|
import { route } from "@fosscord/api";
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/scheduled-maintenances/upcoming.json",route({}), async (req: Request, res: Response) => {
|
||||||
|
res.json({
|
||||||
|
"page": {},
|
||||||
|
"scheduled_maintenances": {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
@ -18,7 +18,7 @@ router.get("/:id", route({}), async (req: Request, res: Response) => {
|
|||||||
access_type: 2,
|
access_type: 2,
|
||||||
name: "",
|
name: "",
|
||||||
features: [],
|
features: [],
|
||||||
relase_date: "",
|
release_date: "",
|
||||||
premium: false,
|
premium: false,
|
||||||
slug: "",
|
slug: "",
|
||||||
flags: 4,
|
flags: 4,
|
||||||
|
@ -18,7 +18,7 @@ router.get("/:id", route({}), async (req: Request, res: Response) => {
|
|||||||
access_type: 2,
|
access_type: 2,
|
||||||
name: "",
|
name: "",
|
||||||
features: [],
|
features: [],
|
||||||
relase_date: "",
|
release_date: "",
|
||||||
premium: false,
|
premium: false,
|
||||||
slug: "",
|
slug: "",
|
||||||
flags: 4,
|
flags: 4,
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import { Router, Response, Request } from "express";
|
import { Router, Response, Request } from "express";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
import { Config, Relase } from "@fosscord/util";
|
import { Config, Release } from "@fosscord/util";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
router.get("/", route({}), async (req: Request, res: Response) => {
|
||||||
const { client } = Config.get();
|
const { client } = Config.get();
|
||||||
|
|
||||||
const relase = await Relase.findOneOrFail({ name: client.relases.upstreamVersion})
|
const release = await Release.findOneOrFail({ name: client.releases.upstreamVersion})
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
name: relase.name,
|
name: release.name,
|
||||||
pub_date: relase.pub_date,
|
pub_date: release.pub_date,
|
||||||
url: relase.url,
|
url: release.url,
|
||||||
notes: relase.notes
|
notes: release.notes
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,8 +53,6 @@ router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res:
|
|||||||
throw FieldErrors({ email: { message: req.t("auth:register.EMAIL_INVALID"), code: "EMAIL_INVALID" } });
|
throw FieldErrors({ email: { message: req.t("auth:register.EMAIL_INVALID"), code: "EMAIL_INVALID" } });
|
||||||
}
|
}
|
||||||
|
|
||||||
user.assign(body);
|
|
||||||
|
|
||||||
if (body.new_password) {
|
if (body.new_password) {
|
||||||
if (!body.password && !user.email) {
|
if (!body.password && !user.email) {
|
||||||
throw FieldErrors({
|
throw FieldErrors({
|
||||||
@ -64,14 +62,16 @@ router.patch("/", route({ body: "UserModifySchema" }), async (req: Request, res:
|
|||||||
user.data.hash = await bcrypt.hash(body.new_password, 12);
|
user.data.hash = await bcrypt.hash(body.new_password, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (body.username) {
|
||||||
var check_username = body?.username?.replace(/\s/g, '');
|
var check_username = body?.username?.replace(/\s/g, '');
|
||||||
|
if (!check_username) {
|
||||||
if(!check_username && !body?.avatar && !body?.banner) {
|
|
||||||
throw FieldErrors({
|
throw FieldErrors({
|
||||||
username: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") }
|
username: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user.assign(body);
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -1,14 +1,39 @@
|
|||||||
import { Request, Response, Router } from "express";
|
import { Request, Response, Router } from "express";
|
||||||
import { route } from "@fosscord/api";
|
import { route } from "@fosscord/api";
|
||||||
|
import { User, emitEvent } from "@fosscord/util";
|
||||||
|
|
||||||
const router: Router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
|
router.get("/:id", route({}), async (req: Request, res: Response) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["notes"] });
|
||||||
|
|
||||||
|
const note = user.notes[id];
|
||||||
|
return res.json({
|
||||||
|
note: note,
|
||||||
|
note_user_id: id,
|
||||||
|
user_id: user.id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.put("/:id", route({}), async (req: Request, res: Response) => {
|
router.put("/:id", route({}), async (req: Request, res: Response) => {
|
||||||
//TODO
|
const { id } = req.params;
|
||||||
res.json({
|
const user = await User.findOneOrFail({ where: { id: req.user_id } });
|
||||||
message: "400: Bad Request",
|
const noteUser = await User.findOneOrFail({ where: { id: id }}); //if noted user does not exist throw
|
||||||
code: 0
|
const { note } = req.body;
|
||||||
}).status(400);
|
|
||||||
|
await User.update({ id: req.user_id }, { notes: { ...user.notes, [noteUser.id]: note } });
|
||||||
|
|
||||||
|
await emitEvent({
|
||||||
|
event: "USER_NOTE_UPDATE",
|
||||||
|
data: {
|
||||||
|
note: note,
|
||||||
|
id: noteUser.id
|
||||||
|
},
|
||||||
|
user_id: user.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
return res.status(204);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
MessageCreateEvent,
|
MessageCreateEvent,
|
||||||
MessageUpdateEvent,
|
MessageUpdateEvent,
|
||||||
getPermission,
|
getPermission,
|
||||||
|
getRights,
|
||||||
CHANNEL_MENTION,
|
CHANNEL_MENTION,
|
||||||
Snowflake,
|
Snowflake,
|
||||||
USER_MENTION,
|
USER_MENTION,
|
||||||
@ -61,9 +62,10 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
throw new HTTPError("Content length over max character limit")
|
throw new HTTPError("Content length over max character limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: are tts messages allowed in dm channels? should permission be checked?
|
|
||||||
if (opts.author_id) {
|
if (opts.author_id) {
|
||||||
message.author = await User.getPublicUser(opts.author_id);
|
message.author = await User.getPublicUser(opts.author_id);
|
||||||
|
const rights = await getRights(opts.author_id);
|
||||||
|
rights.hasThrow("SEND_MESSAGES");
|
||||||
}
|
}
|
||||||
if (opts.application_id) {
|
if (opts.application_id) {
|
||||||
message.application = await Application.findOneOrFail({ id: opts.application_id });
|
message.application = await Application.findOneOrFail({ id: opts.application_id });
|
||||||
@ -73,7 +75,7 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const permission = await getPermission(opts.author_id, channel.guild_id, opts.channel_id);
|
const permission = await getPermission(opts.author_id, channel.guild_id, opts.channel_id);
|
||||||
permission.hasThrow("SEND_MESSAGES"); // TODO: add the rights check
|
permission.hasThrow("SEND_MESSAGES");
|
||||||
if (permission.cache.member) {
|
if (permission.cache.member) {
|
||||||
message.member = permission.cache.member;
|
message.member = permission.cache.member;
|
||||||
}
|
}
|
||||||
@ -81,13 +83,15 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
|
|||||||
if (opts.tts) permission.hasThrow("SEND_TTS_MESSAGES");
|
if (opts.tts) permission.hasThrow("SEND_TTS_MESSAGES");
|
||||||
if (opts.message_reference) {
|
if (opts.message_reference) {
|
||||||
permission.hasThrow("READ_MESSAGE_HISTORY");
|
permission.hasThrow("READ_MESSAGE_HISTORY");
|
||||||
// code below has to be redone when we add custom message routing and cross-channel replies
|
// code below has to be redone when we add custom message routing
|
||||||
|
if (message.guild_id !== null) {
|
||||||
const guild = await Guild.findOneOrFail({ id: channel.guild_id });
|
const guild = await Guild.findOneOrFail({ id: channel.guild_id });
|
||||||
if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) {
|
if (!guild.features.includes("CROSS_CHANNEL_REPLIES")) {
|
||||||
if (opts.message_reference.guild_id !== channel.guild_id) throw new HTTPError("You can only reference messages from this guild");
|
if (opts.message_reference.guild_id !== channel.guild_id) throw new HTTPError("You can only reference messages from this guild");
|
||||||
if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel");
|
if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel");
|
||||||
}
|
}
|
||||||
// TODO: should be checked if the referenced message exists?
|
}
|
||||||
|
// Q: should be checked if the referenced message exists? ANSWER: NO
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
message.type = MessageType.REPLY;
|
message.type = MessageType.REPLY;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ const blocklist: string[] = []; // TODO: update ones passwordblocklist is stored
|
|||||||
* - min <n> numbers
|
* - min <n> numbers
|
||||||
* - min <n> symbols
|
* - min <n> symbols
|
||||||
* - min <n> uppercase chars
|
* - min <n> uppercase chars
|
||||||
|
* - shannon entropy divided by password entropy
|
||||||
*
|
*
|
||||||
* Returns: 0 > pw > 1
|
* Returns: 0 > pw > 1
|
||||||
*/
|
*/
|
||||||
@ -22,22 +23,22 @@ export function checkPassword(password: string): number {
|
|||||||
|
|
||||||
// checks for total password len
|
// checks for total password len
|
||||||
if (password.length >= minLength - 1) {
|
if (password.length >= minLength - 1) {
|
||||||
strength += 0.25;
|
strength += 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks for amount of Numbers
|
// checks for amount of Numbers
|
||||||
if (password.count(reNUMBER) >= minNumbers - 1) {
|
if (password.count(reNUMBER) >= minNumbers - 1) {
|
||||||
strength += 0.25;
|
strength += 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks for amount of Uppercase Letters
|
// checks for amount of Uppercase Letters
|
||||||
if (password.count(reUPPERCASELETTER) >= minUpperCase - 1) {
|
if (password.count(reUPPERCASELETTER) >= minUpperCase - 1) {
|
||||||
strength += 0.25;
|
strength += 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks for amount of symbols
|
// checks for amount of symbols
|
||||||
if (password.replace(reSYMBOLS, "").length >= minSymbols - 1) {
|
if (password.replace(reSYMBOLS, "").length >= minSymbols - 1) {
|
||||||
strength += 0.25;
|
strength += 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if password only consists of numbers or only consists of chars
|
// checks if password only consists of numbers or only consists of chars
|
||||||
@ -45,5 +46,15 @@ export function checkPassword(password: string): number {
|
|||||||
strength = 0;
|
strength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let entropyMap;
|
||||||
|
for (let i = 0; i < password.length; i++) {
|
||||||
|
if (entropyMap[password[i]]) entropyMap[password[i]]++;
|
||||||
|
else entropyMap[password[i]] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let entropies = Array(entropyMap);
|
||||||
|
|
||||||
|
entropies.map(x => (x / entropyMap.length));
|
||||||
|
strength += entropies.reduceRight((a, x), a - (x * Math.log2(x))) / Math.log2(password.length);
|
||||||
return strength;
|
return strength;
|
||||||
}
|
}
|
||||||
|
25
bundle/.vscode/launch.json
vendored
25
bundle/.vscode/launch.json
vendored
@ -1,9 +1,26 @@
|
|||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"sourceMaps": true,
|
||||||
|
"name": "ts-node",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/src/start.ts"
|
||||||
|
],
|
||||||
|
"runtimeArgs": [
|
||||||
|
"-r",
|
||||||
|
"ts-node/register"
|
||||||
|
],
|
||||||
|
"protocol": "inspector",
|
||||||
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
|
"env": {
|
||||||
|
"TS_NODE_PROJECT": "${workspaceFolder}/tsnode.tsconfig.json",
|
||||||
|
"TS_NODE_COMPILER": "typescript-cached-transpile"
|
||||||
|
},
|
||||||
|
"resolveSourceMapLocations": null, /* allow breakpoints in modules other than bundle */
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"sourceMaps": true,
|
"sourceMaps": true,
|
||||||
"type": "node",
|
"type": "node",
|
||||||
@ -12,7 +29,7 @@
|
|||||||
"program": "${workspaceFolder}/dist/bundle/src/start.js",
|
"program": "${workspaceFolder}/dist/bundle/src/start.js",
|
||||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
|
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
|
||||||
"envFile": "${workspaceFolder}/.env"
|
"envFile": "${workspaceFolder}/.env",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
210
bundle/package-lock.json
generated
210
bundle/package-lock.json
generated
@ -45,6 +45,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.18",
|
"missing-native-js-functions": "^1.2.18",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
|
"nan": "^2.15.0",
|
||||||
"nanocolors": "^0.2.12",
|
"nanocolors": "^0.2.12",
|
||||||
"node-fetch": "^2.6.2",
|
"node-fetch": "^2.6.2",
|
||||||
"node-os-utils": "^1.3.5",
|
"node-os-utils": "^1.3.5",
|
||||||
@ -58,6 +59,7 @@
|
|||||||
"tslib": "^2.3.1",
|
"tslib": "^2.3.1",
|
||||||
"typeorm": "^0.2.37",
|
"typeorm": "^0.2.37",
|
||||||
"typescript": "^4.1.2",
|
"typescript": "^4.1.2",
|
||||||
|
"typescript-cached-transpile": "^0.0.6",
|
||||||
"typescript-json-schema": "^0.50.1",
|
"typescript-json-schema": "^0.50.1",
|
||||||
"ws": "^7.4.2"
|
"ws": "^7.4.2"
|
||||||
},
|
},
|
||||||
@ -90,6 +92,7 @@
|
|||||||
"ts-node": "^10.2.1",
|
"ts-node": "^10.2.1",
|
||||||
"ts-node-dev": "^1.1.6",
|
"ts-node-dev": "^1.1.6",
|
||||||
"ts-patch": "^1.4.4",
|
"ts-patch": "^1.4.4",
|
||||||
|
"tsconfig-paths": "^3.12.0",
|
||||||
"typescript": "^4.2.3",
|
"typescript": "^4.2.3",
|
||||||
"typescript-json-schema": "0.50.1"
|
"typescript-json-schema": "0.50.1"
|
||||||
}
|
}
|
||||||
@ -124,7 +127,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.18",
|
"missing-native-js-functions": "^1.2.18",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"node-fetch": "^3.1.1",
|
"node-fetch": "^2.6.2",
|
||||||
"patch-package": "^6.4.7",
|
"patch-package": "^6.4.7",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
"proxy-agent": "^5.0.0",
|
"proxy-agent": "^5.0.0",
|
||||||
@ -145,7 +148,7 @@
|
|||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/multer": "^1.4.5",
|
"@types/multer": "^1.4.5",
|
||||||
"@types/node": "^14.17.9",
|
"@types/node": "^14.17.9",
|
||||||
"@types/node-fetch": "^2.5.7",
|
"@types/node-fetch": "^2.5.5",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@zerollup/ts-transform-paths": "^1.7.18",
|
"@zerollup/ts-transform-paths": "^1.7.18",
|
||||||
"jest": "^27.2.5",
|
"jest": "^27.2.5",
|
||||||
@ -182,7 +185,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.17",
|
"missing-native-js-functions": "^1.2.17",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"nanocolors": "^0.2.12",
|
"nanocolors": "^0.2.12",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.2",
|
||||||
"supertest": "^6.1.6",
|
"supertest": "^6.1.6",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
},
|
},
|
||||||
@ -3601,6 +3604,12 @@
|
|||||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||||
"dev": true
|
"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=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/jsonwebtoken": {
|
"node_modules/@types/jsonwebtoken": {
|
||||||
"version": "8.5.5",
|
"version": "8.5.5",
|
||||||
"integrity": "sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw==",
|
"integrity": "sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw==",
|
||||||
@ -7325,8 +7334,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"node_modules/minipass": {
|
"node_modules/minipass": {
|
||||||
"version": "3.1.5",
|
"version": "3.1.5",
|
||||||
@ -7610,6 +7620,11 @@
|
|||||||
"thenify-all": "^1.0.0"
|
"thenify-all": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nan": {
|
||||||
|
"version": "2.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||||
|
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
|
||||||
|
},
|
||||||
"node_modules/nanocolors": {
|
"node_modules/nanocolors": {
|
||||||
"version": "0.2.12",
|
"version": "0.2.12",
|
||||||
"integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug=="
|
"integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug=="
|
||||||
@ -10157,6 +10172,39 @@
|
|||||||
"strip-json-comments": "^2.0.0"
|
"strip-json-comments": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tsconfig-paths": {
|
||||||
|
"version": "3.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||||
|
"integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
|
||||||
|
"dev": true,
|
||||||
|
"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==",
|
||||||
|
"dev": true,
|
||||||
|
"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=",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tsconfig/node_modules/strip-bom": {
|
"node_modules/tsconfig/node_modules/strip-bom": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
|
||||||
@ -10418,7 +10466,6 @@
|
|||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
|
"integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@ -10427,6 +10474,58 @@
|
|||||||
"node": ">=4.2.0"
|
"node": ">=4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/typescript-cached-transpile": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript-cached-transpile/-/typescript-cached-transpile-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-bfPc7YUW0PrVkQHU0xN0ANRuxdPgoYYXtZEW6PNkH5a97/AOM+kPPxSTMZbpWA3BG1do22JUkfC60KoCKJ9VZQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "^12.12.7",
|
||||||
|
"fs-extra": "^8.1.0",
|
||||||
|
"tslib": "^1.10.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript-cached-transpile/node_modules/@types/node": {
|
||||||
|
"version": "12.20.41",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
|
||||||
|
"integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
|
||||||
|
},
|
||||||
|
"node_modules/typescript-cached-transpile/node_modules/fs-extra": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^4.0.0",
|
||||||
|
"universalify": "^0.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6 <7 || >=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript-cached-transpile/node_modules/jsonfile": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||||
|
"optionalDependencies": {
|
||||||
|
"graceful-fs": "^4.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript-cached-transpile/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"node_modules/typescript-cached-transpile/node_modules/universalify": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript-json-schema": {
|
"node_modules/typescript-json-schema": {
|
||||||
"version": "0.50.1",
|
"version": "0.50.1",
|
||||||
"integrity": "sha512-GCof/SDoiTDl0qzPonNEV4CHyCsZEIIf+mZtlrjoD8vURCcEzEfa2deRuxYid8Znp/e27eDR7Cjg8jgGrimBCA==",
|
"integrity": "sha512-GCof/SDoiTDl0qzPonNEV4CHyCsZEIIf+mZtlrjoD8vURCcEzEfa2deRuxYid8Znp/e27eDR7Cjg8jgGrimBCA==",
|
||||||
@ -12885,7 +12984,7 @@
|
|||||||
"@types/morgan": "^1.9.3",
|
"@types/morgan": "^1.9.3",
|
||||||
"@types/multer": "^1.4.5",
|
"@types/multer": "^1.4.5",
|
||||||
"@types/node": "^14.17.9",
|
"@types/node": "^14.17.9",
|
||||||
"@types/node-fetch": "^2.5.7",
|
"@types/node-fetch": "^2.5.5",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@zerollup/ts-transform-paths": "^1.7.18",
|
"@zerollup/ts-transform-paths": "^1.7.18",
|
||||||
"ajv": "8.6.2",
|
"ajv": "8.6.2",
|
||||||
@ -12910,7 +13009,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.18",
|
"missing-native-js-functions": "^1.2.18",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"node-fetch": "^3.1.1",
|
"node-fetch": "^2.6.2",
|
||||||
"patch-package": "^6.4.7",
|
"patch-package": "^6.4.7",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
"proxy-agent": "^5.0.0",
|
"proxy-agent": "^5.0.0",
|
||||||
@ -12956,7 +13055,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.17",
|
"missing-native-js-functions": "^1.2.17",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"nanocolors": "^0.2.12",
|
"nanocolors": "^0.2.12",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.2",
|
||||||
"supertest": "^6.1.6",
|
"supertest": "^6.1.6",
|
||||||
"ts-patch": "^1.4.4",
|
"ts-patch": "^1.4.4",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
@ -13633,6 +13732,12 @@
|
|||||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||||
"dev": true
|
"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=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/jsonwebtoken": {
|
"@types/jsonwebtoken": {
|
||||||
"version": "8.5.5",
|
"version": "8.5.5",
|
||||||
"integrity": "sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw==",
|
"integrity": "sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw==",
|
||||||
@ -16446,8 +16551,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "3.1.5",
|
"version": "3.1.5",
|
||||||
@ -16633,6 +16739,11 @@
|
|||||||
"thenify-all": "^1.0.0"
|
"thenify-all": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||||
|
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
|
||||||
|
},
|
||||||
"nanocolors": {
|
"nanocolors": {
|
||||||
"version": "0.2.12",
|
"version": "0.2.12",
|
||||||
"integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug=="
|
"integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug=="
|
||||||
@ -18517,6 +18628,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tsconfig-paths": {
|
||||||
|
"version": "3.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||||
|
"integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
|
||||||
|
"dev": true,
|
||||||
|
"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==",
|
||||||
|
"dev": true,
|
||||||
|
"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=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||||
@ -18649,8 +18789,52 @@
|
|||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
|
"integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA=="
|
||||||
"dev": true
|
},
|
||||||
|
"typescript-cached-transpile": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript-cached-transpile/-/typescript-cached-transpile-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-bfPc7YUW0PrVkQHU0xN0ANRuxdPgoYYXtZEW6PNkH5a97/AOM+kPPxSTMZbpWA3BG1do22JUkfC60KoCKJ9VZQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "^12.12.7",
|
||||||
|
"fs-extra": "^8.1.0",
|
||||||
|
"tslib": "^1.10.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": {
|
||||||
|
"version": "12.20.41",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz",
|
||||||
|
"integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q=="
|
||||||
|
},
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"jsonfile": "^4.0.0",
|
||||||
|
"universalify": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jsonfile": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"universalify": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"typescript-json-schema": {
|
"typescript-json-schema": {
|
||||||
"version": "0.50.1",
|
"version": "0.50.1",
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"start": "node scripts/build.js && node dist/bundle/src/start.js",
|
"start": "node scripts/build.js && node dist/bundle/src/start.js",
|
||||||
"start:bundle": "node dist/bundle/src/start.js",
|
"start:bundle": "node dist/bundle/src/start.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"migrate": "cd ../util/ && npm i && node --require ts-node/register node_modules/typeorm/cli.js -f ../util/ormconfig.json migration:run"
|
"migrate": "cd ../util/ && npm i && node --require ts-node/register node_modules/typeorm/cli.js -f ../util/ormconfig.json migration:run",
|
||||||
|
"tsnode": "npx ts-node --transpile-only -P tsnode.tsconfig.json src/start.ts"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -51,6 +52,7 @@
|
|||||||
"ts-node": "^10.2.1",
|
"ts-node": "^10.2.1",
|
||||||
"ts-node-dev": "^1.1.6",
|
"ts-node-dev": "^1.1.6",
|
||||||
"ts-patch": "^1.4.4",
|
"ts-patch": "^1.4.4",
|
||||||
|
"tsconfig-paths": "^3.12.0",
|
||||||
"typescript": "^4.2.3",
|
"typescript": "^4.2.3",
|
||||||
"typescript-json-schema": "0.50.1"
|
"typescript-json-schema": "0.50.1"
|
||||||
},
|
},
|
||||||
@ -91,6 +93,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.18",
|
"missing-native-js-functions": "^1.2.18",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
|
"nan": "^2.15.0",
|
||||||
"nanocolors": "^0.2.12",
|
"nanocolors": "^0.2.12",
|
||||||
"node-fetch": "^2.6.2",
|
"node-fetch": "^2.6.2",
|
||||||
"node-os-utils": "^1.3.5",
|
"node-os-utils": "^1.3.5",
|
||||||
@ -104,8 +107,8 @@
|
|||||||
"tslib": "^2.3.1",
|
"tslib": "^2.3.1",
|
||||||
"typeorm": "^0.2.37",
|
"typeorm": "^0.2.37",
|
||||||
"typescript": "^4.1.2",
|
"typescript": "^4.1.2",
|
||||||
|
"typescript-cached-transpile": "^0.0.6",
|
||||||
"typescript-json-schema": "^0.50.1",
|
"typescript-json-schema": "^0.50.1",
|
||||||
"ws": "^7.4.2",
|
"ws": "^7.4.2"
|
||||||
"nan": "^2.15.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,6 @@
|
|||||||
"include": ["dist/**/*.ts"],
|
"include": ["dist/**/*.ts"],
|
||||||
"exclude": [],
|
"exclude": [],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
|
||||||
|
|
||||||
/* Basic Options */
|
/* Basic Options */
|
||||||
"incremental": false /* Enable incremental compilation */,
|
"incremental": false /* Enable incremental compilation */,
|
||||||
@ -16,7 +15,7 @@
|
|||||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||||
"declaration": false /* Generates corresponding '.d.ts' file. */,
|
"declaration": false /* Generates corresponding '.d.ts' file. */,
|
||||||
"declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */,
|
"declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */,
|
||||||
"sourceMap": false /* Generates corresponding '.map' file. */,
|
"sourceMap": true /* Generates corresponding '.map' file. */,
|
||||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||||
"outDir": "./dist/" /* Redirect output structure to the directory. */,
|
"outDir": "./dist/" /* Redirect output structure to the directory. */,
|
||||||
"rootDir": "./dist/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
"rootDir": "./dist/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
||||||
|
15
bundle/tsnode.tsconfig.json
Normal file
15
bundle/tsnode.tsconfig.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"ts-node": {
|
||||||
|
"transpileOnly": true,
|
||||||
|
"preferTsExts": true,
|
||||||
|
"require": ["tsconfig-paths/register"],
|
||||||
|
"compiler": "typescript-cached-transpile",
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "../",
|
||||||
|
"baseUrl": "../",
|
||||||
|
"sourceRoot": "../",
|
||||||
|
"sourceMap": true,
|
||||||
|
}
|
||||||
|
}
|
14
cdn/package-lock.json
generated
14
cdn/package-lock.json
generated
@ -28,7 +28,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.17",
|
"missing-native-js-functions": "^1.2.17",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"nanocolors": "^0.2.12",
|
"nanocolors": "^0.2.12",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.2",
|
||||||
"supertest": "^6.1.6",
|
"supertest": "^6.1.6",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
},
|
},
|
||||||
@ -5739,9 +5739,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"node_modules/minipass": {
|
"node_modules/minipass": {
|
||||||
"version": "3.1.6",
|
"version": "3.1.6",
|
||||||
@ -12301,9 +12301,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "3.1.6",
|
"version": "3.1.6",
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
"missing-native-js-functions": "^1.2.17",
|
"missing-native-js-functions": "^1.2.17",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"nanocolors": "^0.2.12",
|
"nanocolors": "^0.2.12",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.2",
|
||||||
"supertest": "^6.1.6",
|
"supertest": "^6.1.6",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,47 @@
|
|||||||
version: "3"
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
fosscord:
|
||||||
image: fosscord/server
|
container_name: fosscord
|
||||||
|
image: fosscord
|
||||||
|
restart: on-failure:5
|
||||||
|
# depends_on: mariadb
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- 3001:3001
|
- '3001-3005:3001-3005'
|
||||||
|
volumes:
|
||||||
|
# - ./data/:${WORK_DIR:-/srv/fosscord-server}/data/
|
||||||
|
- data:${WORK_DIR:-/srv/fosscord-server}/
|
||||||
|
environment:
|
||||||
|
WORK_DIR: ${WORK_DIR:-/srv/fosscord-server}
|
||||||
|
DEV_MODE: ${DEV_MODE:-0}
|
||||||
|
THREADS: ${THREADS:-1}
|
||||||
|
DATABASE: ${DATABASE:-../../data/database.db}
|
||||||
|
STORAGE_LOCATION: ${STORAGE_LOCATION:-../../data/files/}
|
||||||
|
HTTP_PORT: 3001
|
||||||
|
WS_PORT: 3002
|
||||||
|
CDN_PORT: 3003
|
||||||
|
RTC_PORT: 3004
|
||||||
|
ADMIN_PORT: 3005
|
||||||
|
|
||||||
|
# mariadb:
|
||||||
|
# image: mariadb:latest
|
||||||
|
# restart: on-failure:5
|
||||||
|
# environment:
|
||||||
|
# MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-secr3tpassw0rd}
|
||||||
|
# MYSQL_DATABASE: ${MYSQL_DATABASE:-fosscord}
|
||||||
|
# MYSQL_USER: ${MYSQL_USER:-fosscord}
|
||||||
|
# MYSQL_PASSWORD: ${MYSQL_PASSWORD:-password1}
|
||||||
|
# networks:
|
||||||
|
# - default
|
||||||
|
# volumes:
|
||||||
|
# - mariadb:/var/lib/mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
|
# mariadb:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: fosscord
|
||||||
|
driver: bridge
|
||||||
|
20
gateway/package-lock.json
generated
20
gateway/package-lock.json
generated
@ -4479,8 +4479,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"../util/node_modules/minimist": {
|
"../util/node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"../util/node_modules/minipass": {
|
"../util/node_modules/minipass": {
|
||||||
"version": "2.9.0",
|
"version": "2.9.0",
|
||||||
@ -8768,8 +8769,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/minipass": {
|
"node_modules/minipass": {
|
||||||
@ -13666,8 +13668,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.9.0",
|
"version": "2.9.0",
|
||||||
@ -16870,8 +16873,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
|
@ -240,8 +240,6 @@ export async function onIdentify(this: WebSocket, data: Payload) {
|
|||||||
x.guild_hashes = {}; // @ts-ignore
|
x.guild_hashes = {}; // @ts-ignore
|
||||||
x.guild_scheduled_events = []; // @ts-ignore
|
x.guild_scheduled_events = []; // @ts-ignore
|
||||||
x.threads = [];
|
x.threads = [];
|
||||||
x.premium_subscription_count = 30;
|
|
||||||
x.premium_tier = 3;
|
|
||||||
return x;
|
return x;
|
||||||
}),
|
}),
|
||||||
guild_experiments: [], // TODO
|
guild_experiments: [], // TODO
|
||||||
|
12
util/package-lock.json
generated
12
util/package-lock.json
generated
@ -5003,9 +5003,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"node_modules/minipass": {
|
"node_modules/minipass": {
|
||||||
"version": "2.9.0",
|
"version": "2.9.0",
|
||||||
@ -12060,9 +12060,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.9.0",
|
"version": "2.9.0",
|
||||||
|
@ -14,19 +14,23 @@ import { Webhook } from "./Webhook";
|
|||||||
import { DmChannelDTO } from "../dtos";
|
import { DmChannelDTO } from "../dtos";
|
||||||
|
|
||||||
export enum ChannelType {
|
export enum ChannelType {
|
||||||
GUILD_TEXT = 0, // a text channel within a server
|
GUILD_TEXT = 0, // a text channel within a guild
|
||||||
DM = 1, // a direct message between users
|
DM = 1, // a direct message between users
|
||||||
GUILD_VOICE = 2, // a voice channel within a server
|
GUILD_VOICE = 2, // a voice channel within a guild
|
||||||
GROUP_DM = 3, // a direct message between multiple users
|
GROUP_DM = 3, // a direct message between multiple users
|
||||||
GUILD_CATEGORY = 4, // an organizational category that contains up to 50 channels
|
GUILD_CATEGORY = 4, // an organizational category that contains zero or more channels
|
||||||
GUILD_NEWS = 5, // a channel that users can follow and crosspost into their own server
|
GUILD_NEWS = 5, // a channel that users can follow and crosspost into a guild or route
|
||||||
GUILD_STORE = 6, // a channel in which game developers can sell their game on Discord
|
GUILD_STORE = 6, // a channel in which game developers can sell their things
|
||||||
ENCRYPTED = 7, // end-to-end encrypted channel
|
ENCRYPTED = 7, // end-to-end encrypted channel
|
||||||
ENCRYPTED_THREAD = 8, // end-to-end encrypted thread channel
|
ENCRYPTED_THREAD = 8, // end-to-end encrypted thread channel
|
||||||
|
TRANSACTIONAL = 9, // event chain style transactional channel
|
||||||
GUILD_NEWS_THREAD = 10, // a temporary sub-channel within a GUILD_NEWS channel
|
GUILD_NEWS_THREAD = 10, // a temporary sub-channel within a GUILD_NEWS channel
|
||||||
GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel
|
GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel
|
||||||
GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission
|
GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission
|
||||||
GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience
|
GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience
|
||||||
|
TICKET_TRACKER = 33, // ticket tracker, individual ticket items shall have type 12
|
||||||
|
KANBAN = 34, // confluence like kanban board
|
||||||
|
VOICELESS_WHITEBOARD = 35, // whiteboard but without voice (whiteboard + voice is the same as stage)
|
||||||
CUSTOM_START = 64, // start custom channel types from here
|
CUSTOM_START = 64, // start custom channel types from here
|
||||||
UNHANDLED = 255 // unhandled unowned pass-through channel type
|
UNHANDLED = 255 // unhandled unowned pass-through channel type
|
||||||
}
|
}
|
||||||
@ -72,7 +76,7 @@ export class Channel extends BaseClass {
|
|||||||
@ManyToOne(() => Channel)
|
@ManyToOne(() => Channel)
|
||||||
parent?: Channel;
|
parent?: Channel;
|
||||||
|
|
||||||
// only for group dms
|
// for group DMs and owned custom channel types
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
@RelationId((channel: Channel) => channel.owner)
|
@RelationId((channel: Channel) => channel.owner)
|
||||||
owner_id: string;
|
owner_id: string;
|
||||||
@ -117,6 +121,9 @@ export class Channel extends BaseClass {
|
|||||||
})
|
})
|
||||||
invites?: Invite[];
|
invites?: Invite[];
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
retention_policy_id?: string;
|
||||||
|
|
||||||
@OneToMany(() => Message, (message: Message) => message.channel, {
|
@OneToMany(() => Message, (message: Message) => message.channel, {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
orphanedRowAction: "delete",
|
orphanedRowAction: "delete",
|
||||||
@ -182,6 +189,7 @@ export class Channel extends BaseClass {
|
|||||||
|
|
||||||
switch (channel.type) {
|
switch (channel.type) {
|
||||||
case ChannelType.GUILD_TEXT:
|
case ChannelType.GUILD_TEXT:
|
||||||
|
case ChannelType.GUILD_NEWS:
|
||||||
case ChannelType.GUILD_VOICE:
|
case ChannelType.GUILD_VOICE:
|
||||||
if (channel.parent_id && !opts?.skipExistsCheck) {
|
if (channel.parent_id && !opts?.skipExistsCheck) {
|
||||||
const exists = await Channel.findOneOrFail({ id: channel.parent_id });
|
const exists = await Channel.findOneOrFail({ id: channel.parent_id });
|
||||||
@ -191,25 +199,24 @@ export class Channel extends BaseClass {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ChannelType.GUILD_CATEGORY:
|
case ChannelType.GUILD_CATEGORY:
|
||||||
|
case ChannelType.UNHANDLED:
|
||||||
break;
|
break;
|
||||||
case ChannelType.DM:
|
case ChannelType.DM:
|
||||||
case ChannelType.GROUP_DM:
|
case ChannelType.GROUP_DM:
|
||||||
throw new HTTPError("You can't create a dm channel in a guild");
|
throw new HTTPError("You can't create a dm channel in a guild");
|
||||||
// TODO: check if guild is community server
|
|
||||||
case ChannelType.GUILD_STORE:
|
case ChannelType.GUILD_STORE:
|
||||||
case ChannelType.GUILD_NEWS:
|
|
||||||
default:
|
default:
|
||||||
throw new HTTPError("Not yet supported");
|
throw new HTTPError("Not yet supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel.permission_overwrites) channel.permission_overwrites = [];
|
if (!channel.permission_overwrites) channel.permission_overwrites = [];
|
||||||
// TODO: auto generate position
|
// TODO: eagerly auto generate position of all guild channels
|
||||||
|
|
||||||
channel = {
|
channel = {
|
||||||
...channel,
|
...channel,
|
||||||
...(!opts?.keepId && { id: Snowflake.generate() }),
|
...(!opts?.keepId && { id: Snowflake.generate() }),
|
||||||
created_at: new Date(),
|
created_at: new Date(),
|
||||||
position: channel.position || 0,
|
position: (channel.type === ChannelType.UNHANDLED ? 0 : channel.position) || 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -231,11 +238,13 @@ export class Channel extends BaseClass {
|
|||||||
const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });
|
const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });
|
||||||
|
|
||||||
// TODO: check config for max number of recipients
|
// TODO: check config for max number of recipients
|
||||||
|
/** if you want to disallow note to self channels, uncomment the conditional below
|
||||||
if (otherRecipientsUsers.length !== recipients.length) {
|
if (otherRecipientsUsers.length !== recipients.length) {
|
||||||
throw new HTTPError("Recipient/s not found");
|
throw new HTTPError("Recipient/s not found");
|
||||||
}
|
}
|
||||||
|
**/
|
||||||
|
|
||||||
const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM;
|
const type = recipients.length > 1 ? ChannelType.DM : ChannelType.GROUP_DM;
|
||||||
|
|
||||||
let channel = null;
|
let channel = null;
|
||||||
|
|
||||||
@ -288,7 +297,8 @@ export class Channel extends BaseClass {
|
|||||||
await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });
|
await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
return channel_dto.excludedRecipients([creator_user_id]);
|
if (recipients.length === 1) return channel_dto;
|
||||||
|
else return channel_dto.excludedRecipients([creator_user_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async removeRecipientFromChannel(channel: Channel, user_id: string) {
|
static async removeRecipientFromChannel(channel: Channel, user_id: string) {
|
||||||
@ -354,4 +364,5 @@ export interface ChannelPermissionOverwrite {
|
|||||||
export enum ChannelPermissionOverwriteType {
|
export enum ChannelPermissionOverwriteType {
|
||||||
role = 0,
|
role = 0,
|
||||||
member = 1,
|
member = 1,
|
||||||
|
group = 2,
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Column, Entity} from "typeorm";
|
import { Column, Entity} from "typeorm";
|
||||||
import { BaseClass } from "./BaseClass";
|
import { BaseClass } from "./BaseClass";
|
||||||
|
|
||||||
@Entity("client_relase")
|
@Entity("client_release")
|
||||||
export class Relase extends BaseClass {
|
export class Release extends BaseClass {
|
||||||
@Column()
|
@Column()
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -188,8 +188,8 @@ export interface ConfigValue {
|
|||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
useTestClient: Boolean;
|
useTestClient: Boolean;
|
||||||
relases: {
|
releases: {
|
||||||
useLocalRelases: Boolean; //TODO
|
useLocalRelease: Boolean; //TODO
|
||||||
upstreamVersion: string;
|
upstreamVersion: string;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -222,7 +222,7 @@ export const DefaultConfigOptions: ConfigValue = {
|
|||||||
},
|
},
|
||||||
general: {
|
general: {
|
||||||
instanceName: "Fosscord Instance",
|
instanceName: "Fosscord Instance",
|
||||||
instanceDescription: "This is a Fosscord instance made in pre-relase days",
|
instanceDescription: "This is a Fosscord instance made in pre-release days",
|
||||||
frontPage: null,
|
frontPage: null,
|
||||||
tosPage: null,
|
tosPage: null,
|
||||||
correspondenceEmail: "noreply@localhost.local",
|
correspondenceEmail: "noreply@localhost.local",
|
||||||
@ -389,8 +389,8 @@ export const DefaultConfigOptions: ConfigValue = {
|
|||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
useTestClient: true,
|
useTestClient: true,
|
||||||
relases: {
|
releases: {
|
||||||
useLocalRelases: true,
|
useLocalRelease: true,
|
||||||
upstreamVersion: "0.0.264"
|
upstreamVersion: "0.0.264"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,7 @@ import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
|
|||||||
import { BaseClass } from "./BaseClass";
|
import { BaseClass } from "./BaseClass";
|
||||||
import { User } from "./User";
|
import { User } from "./User";
|
||||||
|
|
||||||
export interface PublicConnectedAccount extends Pick<ConnectedAccount, "name" | "type" | "verifie"> {}
|
export interface PublicConnectedAccount extends Pick<ConnectedAccount, "name" | "type" | "verified"> {}
|
||||||
|
|
||||||
@Entity("connected_accounts")
|
@Entity("connected_accounts")
|
||||||
export class ConnectedAccount extends BaseClass {
|
export class ConnectedAccount extends BaseClass {
|
||||||
@ -35,7 +35,7 @@ export class ConnectedAccount extends BaseClass {
|
|||||||
type: string;
|
type: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
verifie: boolean;
|
verified: boolean;
|
||||||
|
|
||||||
@Column({ select: false })
|
@Column({ select: false })
|
||||||
visibility: number;
|
visibility: number;
|
||||||
|
35
util/src/entities/Encryption.ts
Normal file
35
util/src/entities/Encryption.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";
|
||||||
|
import { BaseClass } from "./BaseClass";
|
||||||
|
import { Guild } from "./Guild";
|
||||||
|
import { PublicUserProjection, User } from "./User";
|
||||||
|
import { HTTPError } from "lambert-server";
|
||||||
|
import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters } from "../util";
|
||||||
|
import { BitField, BitFieldResolvable, BitFlag } from "../util/BitField";
|
||||||
|
import { Recipient } from "./Recipient";
|
||||||
|
import { Message } from "./Message";
|
||||||
|
import { ReadState } from "./ReadState";
|
||||||
|
import { Invite } from "./Invite";
|
||||||
|
import { DmChannelDTO } from "../dtos";
|
||||||
|
|
||||||
|
@Entity("security_settings")
|
||||||
|
export class SecuritySettings extends BaseClass {
|
||||||
|
|
||||||
|
@Column({nullable: true})
|
||||||
|
guild_id: Snowflake;
|
||||||
|
|
||||||
|
@Column({nullable: true})
|
||||||
|
channel_id: Snowflake;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
encryption_permission_mask: BitField;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
allowed_algorithms: string[];
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
current_algorithm: string;
|
||||||
|
|
||||||
|
@Column({nullable: true})
|
||||||
|
used_since_message: Snowflake;
|
||||||
|
|
||||||
|
}
|
@ -187,11 +187,11 @@ export class Guild extends BaseClass {
|
|||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
@RelationId((guild: Guild) => guild.owner)
|
@RelationId((guild: Guild) => guild.owner)
|
||||||
owner_id: string;
|
owner_id?: string; // optional to allow for ownerless guilds
|
||||||
|
|
||||||
@JoinColumn({ name: "owner_id", referencedColumnName: "id" })
|
@JoinColumn({ name: "owner_id", referencedColumnName: "id" })
|
||||||
@ManyToOne(() => User)
|
@ManyToOne(() => User)
|
||||||
owner: User;
|
owner?: User; // optional to allow for ownerless guilds
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
preferred_locale?: string;
|
preferred_locale?: string;
|
||||||
@ -200,7 +200,7 @@ export class Guild extends BaseClass {
|
|||||||
premium_subscription_count?: number;
|
premium_subscription_count?: number;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
premium_tier?: number; // nitro boost level
|
premium_tier?: number; // crowd premium level
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
@RelationId((guild: Guild) => guild.public_updates_channel)
|
@RelationId((guild: Guild) => guild.public_updates_channel)
|
||||||
@ -270,6 +270,10 @@ export class Guild extends BaseClass {
|
|||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
nsfw?: boolean;
|
nsfw?: boolean;
|
||||||
|
|
||||||
|
// TODO: nested guilds
|
||||||
|
@Column({ nullable: true })
|
||||||
|
parent?: string;
|
||||||
|
|
||||||
// only for developer portal
|
// only for developer portal
|
||||||
permissions?: number;
|
permissions?: number;
|
||||||
|
|
||||||
@ -308,7 +312,7 @@ export class Guild extends BaseClass {
|
|||||||
verification_level: 0,
|
verification_level: 0,
|
||||||
welcome_screen: {
|
welcome_screen: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
description: "No description",
|
description: "Fill in your description",
|
||||||
welcome_channels: [],
|
welcome_channels: [],
|
||||||
},
|
},
|
||||||
widget_enabled: true, // NB: don't set it as false to prevent artificial restrictions
|
widget_enabled: true, // NB: don't set it as false to prevent artificial restrictions
|
||||||
|
@ -85,8 +85,8 @@ export class Member extends BaseClassWithoutId {
|
|||||||
@Column()
|
@Column()
|
||||||
joined_at: Date;
|
joined_at: Date;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ type: "bigint", nullable: true })
|
||||||
premium_since?: Date;
|
premium_since?: number;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
deaf: boolean;
|
deaf: boolean;
|
||||||
@ -103,7 +103,16 @@ export class Member extends BaseClassWithoutId {
|
|||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
last_message_id?: string;
|
last_message_id?: string;
|
||||||
|
|
||||||
// TODO: update
|
/**
|
||||||
|
@JoinColumn({ name: "id" })
|
||||||
|
@ManyToOne(() => User, {
|
||||||
|
onDelete: "DO NOTHING",
|
||||||
|
// do not auto-kick force-joined members just because their joiners left the server
|
||||||
|
}) **/
|
||||||
|
@Column({ nullable: true})
|
||||||
|
joined_by?: string;
|
||||||
|
|
||||||
|
// TODO: add this when we have proper read receipts
|
||||||
// @Column({ type: "simple-json" })
|
// @Column({ type: "simple-json" })
|
||||||
// read_state: ReadState;
|
// read_state: ReadState;
|
||||||
|
|
||||||
@ -245,7 +254,7 @@ export class Member extends BaseClassWithoutId {
|
|||||||
nick: undefined,
|
nick: undefined,
|
||||||
roles: [guild_id], // @everyone role
|
roles: [guild_id], // @everyone role
|
||||||
joined_at: new Date(),
|
joined_at: new Date(),
|
||||||
premium_since: new Date(),
|
premium_since: (new Date()).getTime(),
|
||||||
deaf: false,
|
deaf: false,
|
||||||
mute: false,
|
mute: false,
|
||||||
pending: false,
|
pending: false,
|
||||||
|
@ -41,8 +41,14 @@ export enum MessageType {
|
|||||||
CHANNEL_FOLLOW_ADD = 12,
|
CHANNEL_FOLLOW_ADD = 12,
|
||||||
GUILD_DISCOVERY_DISQUALIFIED = 14,
|
GUILD_DISCOVERY_DISQUALIFIED = 14,
|
||||||
GUILD_DISCOVERY_REQUALIFIED = 15,
|
GUILD_DISCOVERY_REQUALIFIED = 15,
|
||||||
|
ENCRYPTED = 16,
|
||||||
REPLY = 19,
|
REPLY = 19,
|
||||||
APPLICATION_COMMAND = 20,
|
APPLICATION_COMMAND = 20,
|
||||||
|
ROUTE_ADDED = 41, // custom message routing: new route affecting that channel
|
||||||
|
ROUTE_DISABLED = 42, // custom message routing: given route no longer affecting that channel
|
||||||
|
ENCRYPTION = 50,
|
||||||
|
CUSTOM_START = 63,
|
||||||
|
UNHANDLED = 255
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity("messages")
|
@Entity("messages")
|
||||||
@ -84,7 +90,7 @@ export class Message extends BaseClass {
|
|||||||
@RelationId((message: Message) => message.member)
|
@RelationId((message: Message) => message.member)
|
||||||
member_id: string;
|
member_id: string;
|
||||||
|
|
||||||
@JoinColumn({ name: "author_id", referencedColumnName: "id" })
|
@JoinColumn({ name: "member_id", referencedColumnName: "id" })
|
||||||
@ManyToOne(() => User, {
|
@ManyToOne(() => User, {
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
})
|
})
|
||||||
@ -203,6 +209,7 @@ export interface MessageComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum MessageComponentType {
|
export enum MessageComponentType {
|
||||||
|
Script = 0, // self command script
|
||||||
ActionRow = 1,
|
ActionRow = 1,
|
||||||
Button = 2,
|
Button = 2,
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ export class ReadState extends BaseClass {
|
|||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
mention_count: number;
|
mention_count: number;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
// @Column({ nullable: true })
|
||||||
|
// TODO: derive this from (last_message_id=notifications_cursor=public_ack)=true
|
||||||
manual: boolean;
|
manual: boolean;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ export class User extends BaseClass {
|
|||||||
username: string; // username max length 32, min 2 (should be configurable)
|
username: string; // username max length 32, min 2 (should be configurable)
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
discriminator: string; // #0001 4 digit long string from #0001 - #9999
|
discriminator: string; // opaque string: 4 digits on discord.com
|
||||||
|
|
||||||
setDiscriminator(val: string) {
|
setDiscriminator(val: string) {
|
||||||
const number = Number(val);
|
const number = Number(val);
|
||||||
@ -88,10 +88,10 @@ export class User extends BaseClass {
|
|||||||
mobile: boolean; // if the user has mobile app installed
|
mobile: boolean; // if the user has mobile app installed
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
premium: boolean; // if user bought nitro
|
premium: boolean; // if user bought individual premium
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
premium_type: number; // nitro level
|
premium_type: number; // individual premium level
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
bot: boolean; // if user is bot
|
bot: boolean; // if user is bot
|
||||||
@ -100,10 +100,10 @@ export class User extends BaseClass {
|
|||||||
bio: string; // short description of the user (max 190 chars -> should be configurable)
|
bio: string; // short description of the user (max 190 chars -> should be configurable)
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author
|
system: boolean; // shouldn't be used, the api sends this field type true, if the generated message comes from a system generated author
|
||||||
|
|
||||||
@Column({ select: false })
|
@Column({ select: false })
|
||||||
nsfw_allowed: boolean; // if the user is older than 18 (resp. Config)
|
nsfw_allowed: boolean; // if the user can do age-restricted actions (NSFW channels/guilds/commands)
|
||||||
|
|
||||||
@Column({ select: false })
|
@Column({ select: false })
|
||||||
mfa_enabled: boolean; // if multi factor authentication is enabled
|
mfa_enabled: boolean; // if multi factor authentication is enabled
|
||||||
@ -132,7 +132,7 @@ export class User extends BaseClass {
|
|||||||
@Column()
|
@Column()
|
||||||
public_flags: number;
|
public_flags: number;
|
||||||
|
|
||||||
@Column()
|
@Column({ type: "bigint" })
|
||||||
rights: string; // Rights
|
rights: string; // Rights
|
||||||
|
|
||||||
@OneToMany(() => Session, (session: Session) => session.user)
|
@OneToMany(() => Session, (session: Session) => session.user)
|
||||||
@ -164,6 +164,9 @@ export class User extends BaseClass {
|
|||||||
@Column({ type: "simple-json", select: false })
|
@Column({ type: "simple-json", select: false })
|
||||||
settings: UserSettings;
|
settings: UserSettings;
|
||||||
|
|
||||||
|
@Column({ type: "simple-json" })
|
||||||
|
notes: { [key: string]: string }; //key is ID of user
|
||||||
|
|
||||||
toPublicUser() {
|
toPublicUser() {
|
||||||
const user: any = {};
|
const user: any = {};
|
||||||
PublicUserProjection.forEach((x) => {
|
PublicUserProjection.forEach((x) => {
|
||||||
@ -271,6 +274,7 @@ export class User extends BaseClass {
|
|||||||
},
|
},
|
||||||
settings: { ...defaultSettings, locale: language },
|
settings: { ...defaultSettings, locale: language },
|
||||||
fingerprints: [],
|
fingerprints: [],
|
||||||
|
notes: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
await user.save();
|
await user.save();
|
||||||
@ -360,7 +364,7 @@ export interface UserSettings {
|
|||||||
render_reactions: boolean;
|
render_reactions: boolean;
|
||||||
restricted_guilds: string[];
|
restricted_guilds: string[];
|
||||||
show_current_game: boolean;
|
show_current_game: boolean;
|
||||||
status: "online" | "offline" | "dnd" | "idle";
|
status: "online" | "offline" | "dnd" | "idle" | "invisible";
|
||||||
stream_notifications_enabled: boolean;
|
stream_notifications_enabled: boolean;
|
||||||
theme: "dark" | "white"; // dark
|
theme: "dark" | "white"; // dark
|
||||||
timezone_offset: number; // e.g -60
|
timezone_offset: number; // e.g -60
|
||||||
|
@ -27,4 +27,4 @@ export * from "./Template";
|
|||||||
export * from "./User";
|
export * from "./User";
|
||||||
export * from "./VoiceState";
|
export * from "./VoiceState";
|
||||||
export * from "./Webhook";
|
export * from "./Webhook";
|
||||||
export * from "./ClientRelase";
|
export * from "./ClientRelease";
|
@ -623,6 +623,7 @@ export type EVENT =
|
|||||||
| "PRESENCE_UPDATE"
|
| "PRESENCE_UPDATE"
|
||||||
| "TYPING_START"
|
| "TYPING_START"
|
||||||
| "USER_UPDATE"
|
| "USER_UPDATE"
|
||||||
|
| "USER_NOTE_UPDATE"
|
||||||
| "WEBHOOKS_UPDATE"
|
| "WEBHOOKS_UPDATE"
|
||||||
| "INTERACTION_CREATE"
|
| "INTERACTION_CREATE"
|
||||||
| "VOICE_STATE_UPDATE"
|
| "VOICE_STATE_UPDATE"
|
||||||
|
@ -12,11 +12,13 @@ export interface Interaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum InteractionType {
|
export enum InteractionType {
|
||||||
|
SelfCommand = 0,
|
||||||
Ping = 1,
|
Ping = 1,
|
||||||
ApplicationCommand = 2,
|
ApplicationCommand = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum InteractionResponseType {
|
export enum InteractionResponseType {
|
||||||
|
SelfCommandResponse = 0,
|
||||||
Pong = 1,
|
Pong = 1,
|
||||||
Acknowledge = 2,
|
Acknowledge = 2,
|
||||||
ChannelMessage = 3,
|
ChannelMessage = 3,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export type Status = "idle" | "dnd" | "online" | "offline";
|
export type Status = "idle" | "dnd" | "online" | "offline" | "invisible";
|
||||||
|
|
||||||
export interface ClientStatus {
|
export interface ClientStatus {
|
||||||
desktop?: string; // e.g. Windows/Linux/Mac
|
desktop?: string; // e.g. Windows/Linux/Mac
|
||||||
|
16
util/src/migrations/1648643945733-ReleaseTypo.ts
Normal file
16
util/src/migrations/1648643945733-ReleaseTypo.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class ReleaseTypo1648643945733 implements MigrationInterface {
|
||||||
|
name = "ReleaseTypo1648643945733";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
//drop table first because typeorm creates it before migrations run
|
||||||
|
await queryRunner.dropTable("client_release", true);
|
||||||
|
await queryRunner.renameTable("client_relase", "client_release");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable("client_relase", true);
|
||||||
|
await queryRunner.renameTable("client_release", "client_relase");
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import { BitField } from "./BitField";
|
import { BitField } from "./BitField";
|
||||||
import "missing-native-js-functions";
|
import "missing-native-js-functions";
|
||||||
import { BitFieldResolvable, BitFlag } from "./BitField";
|
import { BitFieldResolvable, BitFlag } from "./BitField";
|
||||||
|
import { User } from "../entities";
|
||||||
|
|
||||||
var HTTPError: any;
|
var HTTPError: any;
|
||||||
|
|
||||||
@ -65,6 +66,8 @@ export class Rights extends BitField {
|
|||||||
// inverts the presence confidentiality default (OPERATOR's presence is not routed by default, others' are) for a given user
|
// inverts the presence confidentiality default (OPERATOR's presence is not routed by default, others' are) for a given user
|
||||||
SELF_ADD_DISCOVERABLE: BitFlag(36), // can mark discoverable guilds that they have permissions to mark as discoverable
|
SELF_ADD_DISCOVERABLE: BitFlag(36), // can mark discoverable guilds that they have permissions to mark as discoverable
|
||||||
MANAGE_GUILD_DIRECTORY: BitFlag(37), // can change anything in the primary guild directory
|
MANAGE_GUILD_DIRECTORY: BitFlag(37), // can change anything in the primary guild directory
|
||||||
|
POGGERS: BitFlag(38), // can send confetti, screenshake, random user mention (@someone)
|
||||||
|
USE_ACHIEVEMENTS: BitFlag(39), // can use achievements and cheers
|
||||||
INITIATE_INTERACTIONS: BitFlag(40), // can initiate interactions
|
INITIATE_INTERACTIONS: BitFlag(40), // can initiate interactions
|
||||||
RESPOND_TO_INTERACTIONS: BitFlag(41), // can respond to interactions
|
RESPOND_TO_INTERACTIONS: BitFlag(41), // can respond to interactions
|
||||||
SEND_BACKDATED_EVENTS: BitFlag(42), // can send backdated events
|
SEND_BACKDATED_EVENTS: BitFlag(42), // can send backdated events
|
||||||
@ -83,6 +86,15 @@ export class Rights extends BitField {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
throw new HTTPError(`You are missing the following rights ${permission}`, 403);
|
throw new HTTPError(`You are missing the following rights ${permission}`, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce((total, val) => total | val, BigInt(0));
|
const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce((total, val) => total | val, BigInt(0));
|
||||||
|
|
||||||
|
export async function getRights( user_id: string
|
||||||
|
/**, opts: {
|
||||||
|
in_behalf?: (keyof User)[];
|
||||||
|
} = {} **/) {
|
||||||
|
let user = await User.findOneOrFail({ where: { id: user_id } });
|
||||||
|
return new Rights(user.rights);
|
||||||
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { Server, traverseDirectory } from "lambert-server";
|
import { Server, traverseDirectory } from "lambert-server";
|
||||||
|
|
||||||
const DEFAULT_FILTER = /^([^\.].*)(?<!\.d)\.(js)$/;
|
//if we're using ts-node, use ts files instead of js
|
||||||
|
const extension = Symbol.for("ts-node.register.instance") in process ? "ts" : "js"
|
||||||
|
|
||||||
|
const DEFAULT_FILTER = new RegExp("^([^\.].*)(?<!\.d)\.(" + extension + ")$");
|
||||||
|
|
||||||
export function registerRoutes(server: Server, root: string) {
|
export function registerRoutes(server: Server, root: string) {
|
||||||
return traverseDirectory(
|
return traverseDirectory(
|
||||||
|
Loading…
Reference in New Issue
Block a user