Merge branch 'fosscord:master' into master
This commit is contained in:
		
						commit
						0e224fadf6
					
				
							
								
								
									
										694
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										694
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -9,7 +9,6 @@ | |||||||
| 		"test:watch": "jest --watch", | 		"test:watch": "jest --watch", | ||||||
| 		"start": "npm run build && node dist/start", | 		"start": "npm run build && node dist/start", | ||||||
| 		"build": "tsc -b .", | 		"build": "tsc -b .", | ||||||
| 		"postinstall": "patch-package", |  | ||||||
| 		"dev": "tsnd --respawn src/start.ts" | 		"dev": "tsnd --respawn src/start.ts" | ||||||
| 	}, | 	}, | ||||||
| 	"repository": { | 	"repository": { | ||||||
| @ -47,8 +46,7 @@ | |||||||
| 		"mongoose": "^5.12.3", | 		"mongoose": "^5.12.3", | ||||||
| 		"mongoose-autopopulate": "^0.12.3", | 		"mongoose-autopopulate": "^0.12.3", | ||||||
| 		"mongoose-long": "^0.3.2", | 		"mongoose-long": "^0.3.2", | ||||||
| 		"multer": "^1.4.2", | 		"multer": "^1.4.2" | ||||||
| 		"patch-package": "^6.2.2" |  | ||||||
| 	}, | 	}, | ||||||
| 	"devDependencies": { | 	"devDependencies": { | ||||||
| 		"@types/bcrypt": "^3.0.0", | 		"@types/bcrypt": "^3.0.0", | ||||||
|  | |||||||
| @ -1,274 +0,0 @@ | |||||||
| diff --git a/node_modules/i18next-http-middleware/cjs/httpFunctions.js b/node_modules/i18next-http-middleware/cjs/httpFunctions.js
 |  | ||||||
| index 47f0d61..c1ebebc 100644
 |  | ||||||
| --- a/node_modules/i18next-http-middleware/cjs/httpFunctions.js
 |  | ||||||
| +++ b/node_modules/i18next-http-middleware/cjs/httpFunctions.js
 |  | ||||||
| @@ -1,175 +1,181 @@
 |  | ||||||
|  "use strict"; |  | ||||||
|   |  | ||||||
|  Object.defineProperty(exports, "__esModule", { |  | ||||||
| -  value: true
 |  | ||||||
| +	value: true,
 |  | ||||||
|  }); |  | ||||||
|  exports.extendOptionsWithDefaults = exports.getSession = exports.send = exports.setStatus = exports.setContentType = exports.setHeader = exports.getHeader = exports.getBody = exports.getCookies = exports.getHeaders = exports.getParams = exports.getQuery = exports.getOriginalUrl = exports.setUrl = exports.getUrl = exports.getPath = void 0; |  | ||||||
|   |  | ||||||
|  var getPath = function getPath(req) { |  | ||||||
| -  if (req.path) return req.path;
 |  | ||||||
| -  if (req.raw && req.raw.path) return req.raw.path;
 |  | ||||||
| -  if (req.url) return req.url;
 |  | ||||||
| -  console.log('no possibility found to get path');
 |  | ||||||
| +	if (req.path) return req.path;
 |  | ||||||
| +	if (req.raw && req.raw.path) return req.raw.path;
 |  | ||||||
| +	if (req.url) return req.url;
 |  | ||||||
| +	console.log("no possibility found to get path");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getPath = getPath; |  | ||||||
|   |  | ||||||
|  var getUrl = function getUrl(req) { |  | ||||||
| -  if (req.url) return req.url;
 |  | ||||||
| -  if (req.raw && req.raw.url) return req.raw.url;
 |  | ||||||
| -  console.log('no possibility found to get url');
 |  | ||||||
| +	if (req.url) return req.url;
 |  | ||||||
| +	if (req.raw && req.raw.url) return req.raw.url;
 |  | ||||||
| +	console.log("no possibility found to get url");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getUrl = getUrl; |  | ||||||
|   |  | ||||||
|  var setUrl = function setUrl(req, url) { |  | ||||||
| -  if (req.url) {
 |  | ||||||
| -    req.url = url;
 |  | ||||||
| -    return;
 |  | ||||||
| -  }
 |  | ||||||
| +	if (req.url) {
 |  | ||||||
| +		req.url = url;
 |  | ||||||
| +		return;
 |  | ||||||
| +	}
 |  | ||||||
|   |  | ||||||
| -  console.log('no possibility found to get url');
 |  | ||||||
| +	console.log("no possibility found to get url");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.setUrl = setUrl; |  | ||||||
|   |  | ||||||
|  var getOriginalUrl = function getOriginalUrl(req) { |  | ||||||
| -  if (req.originalUrl) return req.originalUrl;
 |  | ||||||
| -  if (req.raw && req.raw.originalUrl) return req.raw.originalUrl;
 |  | ||||||
| -  return getUrl(req);
 |  | ||||||
| +	if (req.originalUrl) return req.originalUrl;
 |  | ||||||
| +	if (req.raw && req.raw.originalUrl) return req.raw.originalUrl;
 |  | ||||||
| +	return getUrl(req);
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getOriginalUrl = getOriginalUrl; |  | ||||||
|   |  | ||||||
|  var getQuery = function getQuery(req) { |  | ||||||
| -  if (req.query && typeof req.query.entries === 'function' && typeof Object.fromEntries === 'function') return Object.fromEntries(req.query);
 |  | ||||||
| -  if (req.query) return req.query;
 |  | ||||||
| -  if (req.raw && req.raw.query) return req.raw.query;
 |  | ||||||
| -  if (req.ctx && req.ctx.queryParams) return req.ctx.queryParams;
 |  | ||||||
| -  var url = req.url || req.raw && req.raw.url;
 |  | ||||||
| -  if (url && url.indexOf('?') < 0) return {};
 |  | ||||||
| -  console.log('no possibility found to get query');
 |  | ||||||
| -  return {};
 |  | ||||||
| +	try {
 |  | ||||||
| +		if (req.query && typeof req.query.entries === "function" && typeof Object.fromEntries === "function")
 |  | ||||||
| +			return Object.fromEntries(req.query);
 |  | ||||||
| +	} catch (e) {}
 |  | ||||||
| +
 |  | ||||||
| +	if (req.query) return req.query;
 |  | ||||||
| +	if (req.raw && req.raw.query) return req.raw.query;
 |  | ||||||
| +	if (req.ctx && req.ctx.queryParams) return req.ctx.queryParams;
 |  | ||||||
| +	var url = req.url || (req.raw && req.raw.url);
 |  | ||||||
| +	if (url && url.indexOf("?") < 0) return {};
 |  | ||||||
| +	console.log("no possibility found to get query");
 |  | ||||||
| +	return {};
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getQuery = getQuery; |  | ||||||
|   |  | ||||||
|  var getParams = function getParams(req) { |  | ||||||
| -  if (req.params) return req.params;
 |  | ||||||
| -  if (req.raw && req.raw.params) return req.raw.params;
 |  | ||||||
| -  if (req.ctx && req.ctx.params) return req.ctx.params;
 |  | ||||||
| -  console.log('no possibility found to get params');
 |  | ||||||
| -  return {};
 |  | ||||||
| +	if (req.params) return req.params;
 |  | ||||||
| +	if (req.raw && req.raw.params) return req.raw.params;
 |  | ||||||
| +	if (req.ctx && req.ctx.params) return req.ctx.params;
 |  | ||||||
| +	console.log("no possibility found to get params");
 |  | ||||||
| +	return {};
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getParams = getParams; |  | ||||||
|   |  | ||||||
|  var getHeaders = function getHeaders(req) { |  | ||||||
| -  if (req.headers) return req.headers;
 |  | ||||||
| -  console.log('no possibility found to get headers');
 |  | ||||||
| +	if (req.headers) return req.headers;
 |  | ||||||
| +	console.log("no possibility found to get headers");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getHeaders = getHeaders; |  | ||||||
|   |  | ||||||
|  var getCookies = function getCookies(req) { |  | ||||||
| -  if (req.cookies) return req.cookies;
 |  | ||||||
| +	if (req.cookies) return req.cookies;
 |  | ||||||
|   |  | ||||||
| -  if (getHeaders(req)) {
 |  | ||||||
| -    var list = {};
 |  | ||||||
| -    var rc = getHeaders(req).cookie;
 |  | ||||||
| -    rc && rc.split(';').forEach(function (cookie) {
 |  | ||||||
| -      var parts = cookie.split('=');
 |  | ||||||
| -      list[parts.shift().trim()] = decodeURI(encodeURI(parts.join('=')));
 |  | ||||||
| -    });
 |  | ||||||
| -    return list;
 |  | ||||||
| -  }
 |  | ||||||
| +	if (getHeaders(req)) {
 |  | ||||||
| +		var list = {};
 |  | ||||||
| +		var rc = getHeaders(req).cookie;
 |  | ||||||
| +		rc &&
 |  | ||||||
| +			rc.split(";").forEach(function (cookie) {
 |  | ||||||
| +				var parts = cookie.split("=");
 |  | ||||||
| +				list[parts.shift().trim()] = decodeURI(encodeURI(parts.join("=")));
 |  | ||||||
| +			});
 |  | ||||||
| +		return list;
 |  | ||||||
| +	}
 |  | ||||||
|   |  | ||||||
| -  console.log('no possibility found to get cookies');
 |  | ||||||
| +	console.log("no possibility found to get cookies");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getCookies = getCookies; |  | ||||||
|   |  | ||||||
|  var getBody = function getBody(req) { |  | ||||||
| -  if (req.ctx && typeof req.ctx.body === 'function') return req.ctx.body.bind(req.ctx);
 |  | ||||||
| -  if (req.ctx && req.ctx.body) return req.ctx.body;
 |  | ||||||
| -  if (req.json) return req.json;
 |  | ||||||
| -  if (req.body) return req.body;
 |  | ||||||
| -  console.log('no possibility found to get body');
 |  | ||||||
| -  return {};
 |  | ||||||
| +	if (req.ctx && typeof req.ctx.body === "function") return req.ctx.body.bind(req.ctx);
 |  | ||||||
| +	if (req.ctx && req.ctx.body) return req.ctx.body;
 |  | ||||||
| +	if (req.json) return req.json;
 |  | ||||||
| +	if (req.body) return req.body;
 |  | ||||||
| +	console.log("no possibility found to get body");
 |  | ||||||
| +	return {};
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getBody = getBody; |  | ||||||
|   |  | ||||||
|  var getHeader = function getHeader(res, name) { |  | ||||||
| -  if (res.getHeader) return res.getHeader(name);
 |  | ||||||
| -  if (res.headers) return res.headers[name];
 |  | ||||||
| -  if (getHeaders(res) && getHeaders(res)[name]) return getHeaders(res)[name];
 |  | ||||||
| -  console.log('no possibility found to get header');
 |  | ||||||
| -  return undefined;
 |  | ||||||
| +	if (res.getHeader) return res.getHeader(name);
 |  | ||||||
| +	if (res.headers) return res.headers[name];
 |  | ||||||
| +	if (getHeaders(res) && getHeaders(res)[name]) return getHeaders(res)[name];
 |  | ||||||
| +	console.log("no possibility found to get header");
 |  | ||||||
| +	return undefined;
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getHeader = getHeader; |  | ||||||
|   |  | ||||||
|  var setHeader = function setHeader(res, name, value) { |  | ||||||
| -  if (res._headerSent || res.headersSent) return;
 |  | ||||||
| -  if (typeof res.setHeader === 'function') return res.setHeader(name, value);
 |  | ||||||
| -  if (typeof res.header === 'function') return res.header(name, value);
 |  | ||||||
| -  if (res.responseHeaders && typeof res.responseHeaders.set === 'function') return res.responseHeaders.set(name, value);
 |  | ||||||
| -  if (res.headers && typeof res.headers.set === 'function') return res.headers.set(name, value);
 |  | ||||||
| -  console.log('no possibility found to set header');
 |  | ||||||
| +	if (res._headerSent || res.headersSent) return;
 |  | ||||||
| +	if (typeof res.setHeader === "function") return res.setHeader(name, value);
 |  | ||||||
| +	if (typeof res.header === "function") return res.header(name, value);
 |  | ||||||
| +	if (res.responseHeaders && typeof res.responseHeaders.set === "function")
 |  | ||||||
| +		return res.responseHeaders.set(name, value);
 |  | ||||||
| +	if (res.headers && typeof res.headers.set === "function") return res.headers.set(name, value);
 |  | ||||||
| +	console.log("no possibility found to set header");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.setHeader = setHeader; |  | ||||||
|   |  | ||||||
|  var setContentType = function setContentType(res, type) { |  | ||||||
| -  if (typeof res.contentType === 'function') return res.contentType(type);
 |  | ||||||
| -  if (typeof res.type === 'function') return res.type(type);
 |  | ||||||
| -  setHeader(res, 'Content-Type', type);
 |  | ||||||
| +	if (typeof res.contentType === "function") return res.contentType(type);
 |  | ||||||
| +	if (typeof res.type === "function") return res.type(type);
 |  | ||||||
| +	setHeader(res, "Content-Type", type);
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.setContentType = setContentType; |  | ||||||
|   |  | ||||||
|  var setStatus = function setStatus(res, code) { |  | ||||||
| -  if (typeof res.status === 'function') return res.status(code);
 |  | ||||||
| -  if (res.status) return res.status = code;
 |  | ||||||
| -  console.log('no possibility found to set status');
 |  | ||||||
| +	if (typeof res.status === "function") return res.status(code);
 |  | ||||||
| +	if (res.status) return (res.status = code);
 |  | ||||||
| +	console.log("no possibility found to set status");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.setStatus = setStatus; |  | ||||||
|   |  | ||||||
|  var send = function send(res, body) { |  | ||||||
| -  if (typeof res.send === 'function') return res.send(body);
 |  | ||||||
| -  return body;
 |  | ||||||
| +	if (typeof res.send === "function") return res.send(body);
 |  | ||||||
| +	return body;
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.send = send; |  | ||||||
|   |  | ||||||
|  var getSession = function getSession(req) { |  | ||||||
| -  if (req.session) return req.session;
 |  | ||||||
| -  if (req.raw && req.raw.session) return req.raw.session;
 |  | ||||||
| -  console.log('no possibility found to get session');
 |  | ||||||
| +	if (req.session) return req.session;
 |  | ||||||
| +	if (req.raw && req.raw.session) return req.raw.session;
 |  | ||||||
| +	console.log("no possibility found to get session");
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.getSession = getSession; |  | ||||||
|   |  | ||||||
|  var extendOptionsWithDefaults = function extendOptionsWithDefaults() { |  | ||||||
| -  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
 |  | ||||||
| -  options.getPath = options.getPath || getPath;
 |  | ||||||
| -  options.getOriginalUrl = options.getOriginalUrl || getOriginalUrl;
 |  | ||||||
| -  options.getUrl = options.getUrl || getUrl;
 |  | ||||||
| -  options.setUrl = options.setUrl || setUrl;
 |  | ||||||
| -  options.getParams = options.getParams || getParams;
 |  | ||||||
| -  options.getSession = options.getSession || getSession;
 |  | ||||||
| -  options.getQuery = options.getQuery || getQuery;
 |  | ||||||
| -  options.getCookies = options.getCookies || getCookies;
 |  | ||||||
| -  options.getBody = options.getBody || getBody;
 |  | ||||||
| -  options.getHeaders = options.getHeaders || getHeaders;
 |  | ||||||
| -  options.getHeader = options.getHeader || getHeader;
 |  | ||||||
| -  options.setHeader = options.setHeader || setHeader;
 |  | ||||||
| -  options.setContentType = options.setContentType || setContentType;
 |  | ||||||
| -  options.setStatus = options.setStatus || setStatus;
 |  | ||||||
| -  options.send = options.send || send;
 |  | ||||||
| -  return options;
 |  | ||||||
| +	var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
 |  | ||||||
| +	options.getPath = options.getPath || getPath;
 |  | ||||||
| +	options.getOriginalUrl = options.getOriginalUrl || getOriginalUrl;
 |  | ||||||
| +	options.getUrl = options.getUrl || getUrl;
 |  | ||||||
| +	options.setUrl = options.setUrl || setUrl;
 |  | ||||||
| +	options.getParams = options.getParams || getParams;
 |  | ||||||
| +	options.getSession = options.getSession || getSession;
 |  | ||||||
| +	options.getQuery = options.getQuery || getQuery;
 |  | ||||||
| +	options.getCookies = options.getCookies || getCookies;
 |  | ||||||
| +	options.getBody = options.getBody || getBody;
 |  | ||||||
| +	options.getHeaders = options.getHeaders || getHeaders;
 |  | ||||||
| +	options.getHeader = options.getHeader || getHeader;
 |  | ||||||
| +	options.setHeader = options.setHeader || setHeader;
 |  | ||||||
| +	options.setContentType = options.setContentType || setContentType;
 |  | ||||||
| +	options.setStatus = options.setStatus || setStatus;
 |  | ||||||
| +	options.send = options.send || send;
 |  | ||||||
| +	return options;
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  exports.extendOptionsWithDefaults = extendOptionsWithDefaults; |  | ||||||
| \ No newline at end of file |  | ||||||
| @ -1,11 +1,47 @@ | |||||||
| import { ChannelModel, getPermission, MessageDeleteEvent, MessageModel } from "@fosscord/server-util"; | import { ChannelModel, getPermission, MessageDeleteEvent, MessageModel, MessageUpdateEvent, toObject } from "@fosscord/server-util"; | ||||||
| import { Router } from "express"; | import { Router } from "express"; | ||||||
| import { HTTPError } from "lambert-server"; | import { HTTPError } from "lambert-server"; | ||||||
|  | import { MessageCreateSchema } from "../../../../../schema/Message"; | ||||||
| import { emitEvent } from "../../../../../util/Event"; | import { emitEvent } from "../../../../../util/Event"; | ||||||
| import { check } from "../../../../../util/instanceOf"; | import { check } from "../../../../../util/instanceOf"; | ||||||
|  | import { handleMessage } from "../../../../../util/Message"; | ||||||
| 
 | 
 | ||||||
| const router = Router(); | const router = Router(); | ||||||
| // TODO:
 | 
 | ||||||
|  | router.patch("/", check(MessageCreateSchema), async (req, res) => { | ||||||
|  | 	const { message_id, channel_id } = req.params; | ||||||
|  | 	var body = req.body as MessageCreateSchema; | ||||||
|  | 
 | ||||||
|  | 	var message = await MessageModel.findOne({ id: message_id, channel_id }, { author_id: true }).exec(); | ||||||
|  | 	if (!message) throw new HTTPError("Message not found", 404); | ||||||
|  | 
 | ||||||
|  | 	const permissions = await getPermission(req.user_id, undefined, channel_id); | ||||||
|  | 
 | ||||||
|  | 	if (req.user_id !== message.author_id) { | ||||||
|  | 		permissions.hasThrow("MANAGE_MESSAGES"); | ||||||
|  | 		body = { flags: body.flags }; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	const opts = await handleMessage({ | ||||||
|  | 		...body, | ||||||
|  | 		author_id: message.author_id, | ||||||
|  | 		channel_id, | ||||||
|  | 		id: message_id, | ||||||
|  | 		edited_timestamp: new Date() | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	message = await MessageModel.findOneAndUpdate({ id: message_id }, opts).populate("author").exec(); | ||||||
|  | 	if (!message) throw new HTTPError("Message not found", 404); | ||||||
|  | 
 | ||||||
|  | 	await emitEvent({ | ||||||
|  | 		event: "MESSAGE_UPDATE", | ||||||
|  | 		channel_id, | ||||||
|  | 		guild_id: message.guild_id, | ||||||
|  | 		data: { ...toObject(message), nonce: undefined } | ||||||
|  | 	} as MessageUpdateEvent); | ||||||
|  | 
 | ||||||
|  | 	return res.json(toObject(message)); | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| router.delete("/", async (req, res) => { | router.delete("/", async (req, res) => { | ||||||
| 	const { message_id, channel_id } = req.params; | 	const { message_id, channel_id } = req.params; | ||||||
|  | |||||||
| @ -5,13 +5,15 @@ import { | |||||||
| 	MemberModel, | 	MemberModel, | ||||||
| 	MessageModel, | 	MessageModel, | ||||||
| 	MessageReactionAddEvent, | 	MessageReactionAddEvent, | ||||||
|  | 	MessageReactionRemoveAllEvent, | ||||||
|  | 	MessageReactionRemoveEmojiEvent, | ||||||
| 	MessageReactionRemoveEvent, | 	MessageReactionRemoveEvent, | ||||||
| 	PartialEmoji, | 	PartialEmoji, | ||||||
| 	PublicUserProjection, | 	PublicUserProjection, | ||||||
| 	toObject, | 	toObject, | ||||||
| 	UserModel | 	UserModel | ||||||
| } from "@fosscord/server-util"; | } from "@fosscord/server-util"; | ||||||
| import { Request, Response, Router } from "express"; | import { Router } from "express"; | ||||||
| import { HTTPError } from "lambert-server"; | import { HTTPError } from "lambert-server"; | ||||||
| import { emitEvent } from "../../../../../util/Event"; | import { emitEvent } from "../../../../../util/Event"; | ||||||
| 
 | 
 | ||||||
| @ -33,6 +35,66 @@ function getEmoji(emoji: string): PartialEmoji { | |||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | router.delete("/", async (req, res) => { | ||||||
|  | 	const { message_id, channel_id } = req.params; | ||||||
|  | 
 | ||||||
|  | 	const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true }).exec(); | ||||||
|  | 	if (!channel) throw new HTTPError("Channel not found", 404); | ||||||
|  | 
 | ||||||
|  | 	const permissions = await getPermission(req.user_id, undefined, channel_id); | ||||||
|  | 	permissions.hasThrow("MANAGE_MESSAGES"); | ||||||
|  | 
 | ||||||
|  | 	const message = await MessageModel.findOneAndUpdate({ id: message_id, channel_id }, { reactions: [] }).exec(); | ||||||
|  | 	if (!message) throw new HTTPError("Message not found", 404); | ||||||
|  | 
 | ||||||
|  | 	await emitEvent({ | ||||||
|  | 		event: "MESSAGE_REACTION_REMOVE_ALL", | ||||||
|  | 		channel_id, | ||||||
|  | 		guild_id: channel.guild_id, | ||||||
|  | 		data: { | ||||||
|  | 			channel_id, | ||||||
|  | 			message_id, | ||||||
|  | 			guild_id: channel.guild_id | ||||||
|  | 		} | ||||||
|  | 	} as MessageReactionRemoveAllEvent); | ||||||
|  | 
 | ||||||
|  | 	res.sendStatus(204); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | router.delete("/:emoji", async (req, res) => { | ||||||
|  | 	const { message_id, channel_id } = req.params; | ||||||
|  | 	const emoji = getEmoji(req.params.emoji); | ||||||
|  | 
 | ||||||
|  | 	const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true }).exec(); | ||||||
|  | 	if (!channel) throw new HTTPError("Channel not found", 404); | ||||||
|  | 
 | ||||||
|  | 	const permissions = await getPermission(req.user_id, undefined, channel_id); | ||||||
|  | 	permissions.hasThrow("MANAGE_MESSAGES"); | ||||||
|  | 
 | ||||||
|  | 	const message = await MessageModel.findOne({ id: message_id, channel_id }).exec(); | ||||||
|  | 	if (!message) throw new HTTPError("Message not found", 404); | ||||||
|  | 
 | ||||||
|  | 	const already_added = message.reactions.find((x) => (x.emoji.id === emoji.id && emoji.id) || x.emoji.name === emoji.name); | ||||||
|  | 	if (!already_added) throw new HTTPError("Reaction not found", 404); | ||||||
|  | 	message.reactions.remove(already_added); | ||||||
|  | 
 | ||||||
|  | 	await MessageModel.updateOne({ id: message_id, channel_id }, message).exec(); | ||||||
|  | 
 | ||||||
|  | 	await emitEvent({ | ||||||
|  | 		event: "MESSAGE_REACTION_REMOVE_EMOJI", | ||||||
|  | 		channel_id, | ||||||
|  | 		guild_id: channel.guild_id, | ||||||
|  | 		data: { | ||||||
|  | 			channel_id, | ||||||
|  | 			message_id, | ||||||
|  | 			guild_id: channel.guild_id, | ||||||
|  | 			emoji | ||||||
|  | 		} | ||||||
|  | 	} as MessageReactionRemoveEmojiEvent); | ||||||
|  | 
 | ||||||
|  | 	res.sendStatus(204); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| router.get("/:emoji", async (req, res) => { | router.get("/:emoji", async (req, res) => { | ||||||
| 	const { message_id, channel_id } = req.params; | 	const { message_id, channel_id } = req.params; | ||||||
| 	const emoji = getEmoji(req.params.emoji); | 	const emoji = getEmoji(req.params.emoji); | ||||||
|  | |||||||
| @ -8,7 +8,8 @@ import { | |||||||
| 	Snowflake, | 	Snowflake, | ||||||
| 	MemberModel, | 	MemberModel, | ||||||
| 	GuildRoleCreateEvent, | 	GuildRoleCreateEvent, | ||||||
| 	GuildRoleUpdateEvent | 	GuildRoleUpdateEvent, | ||||||
|  | 	GuildRoleDeleteEvent | ||||||
| } from "@fosscord/server-util"; | } from "@fosscord/server-util"; | ||||||
| import { HTTPError } from "lambert-server"; | import { HTTPError } from "lambert-server"; | ||||||
| import { emitEvent } from "../../../util/Event"; | import { emitEvent } from "../../../util/Event"; | ||||||
| @ -85,6 +86,15 @@ router.delete("/:role_id", async (req: Request, res: Response) => { | |||||||
| 		guild_id: guild_id | 		guild_id: guild_id | ||||||
| 	}).exec(); | 	}).exec(); | ||||||
| 
 | 
 | ||||||
|  | 	await emitEvent({ | ||||||
|  | 		event: "GUILD_ROLE_DELETE", | ||||||
|  | 		guild_id, | ||||||
|  | 		data: { | ||||||
|  | 			guild_id, | ||||||
|  | 			role_id | ||||||
|  | 		} | ||||||
|  | 	} as GuildRoleDeleteEvent); | ||||||
|  | 
 | ||||||
| 	res.sendStatus(204); | 	res.sendStatus(204); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ export const MessageCreateSchema = { | |||||||
| 	$content: new Length(String, 0, 2000), | 	$content: new Length(String, 0, 2000), | ||||||
| 	$nonce: String, | 	$nonce: String, | ||||||
| 	$tts: Boolean, | 	$tts: Boolean, | ||||||
|  | 	$flags: BigInt, | ||||||
| 	$embed: { | 	$embed: { | ||||||
| 		$title: new Length(String, 0, 256), //title of embed
 | 		$title: new Length(String, 0, 256), //title of embed
 | ||||||
| 		$type: String, // type of embed (always "rich" for webhook embeds)
 | 		$type: String, // type of embed (always "rich" for webhook embeds)
 | ||||||
| @ -15,48 +16,49 @@ export const MessageCreateSchema = { | |||||||
| 		$footer: { | 		$footer: { | ||||||
| 			text: new Length(String, 0, 2048), | 			text: new Length(String, 0, 2048), | ||||||
| 			icon_url: String, | 			icon_url: String, | ||||||
| 			proxy_icon_url: String, | 			proxy_icon_url: String | ||||||
| 		}, // footer object	footer information
 | 		}, // footer object	footer information
 | ||||||
| 		$image: EmbedImage, // image object	image information
 | 		$image: EmbedImage, // image object	image information
 | ||||||
| 		$thumbnail: EmbedImage, // thumbnail object	thumbnail information
 | 		$thumbnail: EmbedImage, // thumbnail object	thumbnail information
 | ||||||
| 		$video: EmbedImage, // video object	video information
 | 		$video: EmbedImage, // video object	video information
 | ||||||
| 		$provider: { | 		$provider: { | ||||||
| 			name: String, | 			name: String, | ||||||
| 			url: String, | 			url: String | ||||||
| 		}, // provider object	provider information
 | 		}, // provider object	provider information
 | ||||||
| 		$author: { | 		$author: { | ||||||
| 			name: new Length(String, 0, 256), | 			name: new Length(String, 0, 256), | ||||||
| 			url: String, | 			url: String, | ||||||
| 			icon_url: String, | 			icon_url: String, | ||||||
| 			proxy_icon_url: String, | 			proxy_icon_url: String | ||||||
| 		}, // author object	author information
 | 		}, // author object	author information
 | ||||||
| 		$fields: new Length( | 		$fields: new Length( | ||||||
| 			[ | 			[ | ||||||
| 				{ | 				{ | ||||||
| 					name: new Length(String, 0, 256), | 					name: new Length(String, 0, 256), | ||||||
| 					value: new Length(String, 0, 1024), | 					value: new Length(String, 0, 1024), | ||||||
| 					$inline: Boolean, | 					$inline: Boolean | ||||||
| 				}, | 				} | ||||||
| 			], | 			], | ||||||
| 			0, | 			0, | ||||||
| 			25 | 			25 | ||||||
| 		), | 		) | ||||||
| 	}, | 	}, | ||||||
| 	$allowed_mentions: [], | 	$allowed_mentions: [], | ||||||
| 	$message_reference: { | 	$message_reference: { | ||||||
| 		message_id: String, | 		message_id: String, | ||||||
| 		channel_id: String, | 		channel_id: String, | ||||||
| 		$guild_id: String, | 		$guild_id: String, | ||||||
| 		$fail_if_not_exists: Boolean, | 		$fail_if_not_exists: Boolean | ||||||
| 	}, | 	}, | ||||||
| 	$payload_json: String, | 	$payload_json: String, | ||||||
| 	$file: Object, | 	$file: Object | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export interface MessageCreateSchema { | export interface MessageCreateSchema { | ||||||
| 	content?: string; | 	content?: string; | ||||||
| 	nonce?: string; | 	nonce?: string; | ||||||
| 	tts?: boolean; | 	tts?: boolean; | ||||||
|  | 	flags?: bigint; | ||||||
| 	embed?: Embed & { timestamp?: string }; | 	embed?: Embed & { timestamp?: string }; | ||||||
| 	allowed_mentions?: []; | 	allowed_mentions?: []; | ||||||
| 	message_reference?: { | 	message_reference?: { | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ import { HTTPError } from "lambert-server"; | |||||||
| import { emitEvent } from "./Event"; | import { emitEvent } from "./Event"; | ||||||
| // TODO: check webhook, application, system author
 | // TODO: check webhook, application, system author
 | ||||||
| 
 | 
 | ||||||
| export async function sendMessage(opts: Partial<Message>) { | export async function handleMessage(opts: Partial<Message>) { | ||||||
| 	const channel = await ChannelModel.findOne({ id: opts.channel_id }, { guild_id: true, type: true, permission_overwrites: true }).exec(); | 	const channel = await ChannelModel.findOne({ id: opts.channel_id }, { guild_id: true, type: true, permission_overwrites: true }).exec(); | ||||||
| 	if (!channel || !opts.channel_id) throw new HTTPError("Channel not found", 404); | 	if (!channel || !opts.channel_id) throw new HTTPError("Channel not found", 404); | ||||||
| 	// TODO: are tts messages allowed in dm channels? should permission be checked?
 | 	// TODO: are tts messages allowed in dm channels? should permission be checked?
 | ||||||
| @ -28,10 +28,8 @@ export async function sendMessage(opts: Partial<Message>) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// TODO: check and put it all in the body
 | 	// TODO: check and put it all in the body
 | ||||||
| 	const message: Message = { | 	return { | ||||||
| 		...opts, | 		...opts, | ||||||
| 		id: Snowflake.generate(), |  | ||||||
| 		timestamp: new Date(), |  | ||||||
| 		guild_id: channel.guild_id, | 		guild_id: channel.guild_id, | ||||||
| 		channel_id: opts.channel_id, | 		channel_id: opts.channel_id, | ||||||
| 		// TODO: generate mentions and check permissions
 | 		// TODO: generate mentions and check permissions
 | ||||||
| @ -43,10 +41,14 @@ export async function sendMessage(opts: Partial<Message>) { | |||||||
| 		reactions: opts.reactions || [], | 		reactions: opts.reactions || [], | ||||||
| 		type: opts.type ?? 0 | 		type: opts.type ?? 0 | ||||||
| 	}; | 	}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function sendMessage(opts: Partial<Message>) { | ||||||
|  | 	const message = await handleMessage({ ...opts, id: Snowflake.generate(), timestamp: new Date() }); | ||||||
| 
 | 
 | ||||||
| 	const data = toObject(await new MessageModel(message).populate({ path: "member", select: PublicMemberProjection }).save()); | 	const data = toObject(await new MessageModel(message).populate({ path: "member", select: PublicMemberProjection }).save()); | ||||||
| 
 | 
 | ||||||
| 	await emitEvent({ event: "MESSAGE_CREATE", channel_id: opts.channel_id, data, guild_id: channel.guild_id } as MessageCreateEvent); | 	await emitEvent({ event: "MESSAGE_CREATE", channel_id: opts.channel_id, data, guild_id: message.guild_id } as MessageCreateEvent); | ||||||
| 
 | 
 | ||||||
| 	return data; | 	return data; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paul Munteanu
						Paul Munteanu