diff --git a/src/api/endpoints/messaging/history.js b/src/api/endpoints/messaging/history.ts similarity index 69% rename from src/api/endpoints/messaging/history.js rename to src/api/endpoints/messaging/history.ts index 60c34a6a4..07ad6e0f2 100644 --- a/src/api/endpoints/messaging/history.js +++ b/src/api/endpoints/messaging/history.ts @@ -3,7 +3,7 @@ /** * Module dependencies */ -import * as mongo from 'mongodb'; +import it from '../../it'; import History from '../../models/messaging-history'; import serialize from '../../serializers/messaging-message'; @@ -18,17 +18,8 @@ module.exports = (params, user) => new Promise(async (res, rej) => { // Get 'limit' parameter - let limit = params.limit; - if (limit !== undefined && limit !== null) { - limit = parseInt(limit, 10); - - // From 1 to 100 - if (!(1 <= limit && limit <= 100)) { - return rej('invalid limit range'); - } - } else { - limit = 10; - } + const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); + if (limitErr) return rej('invalid limit param'); // Get history const history = await History diff --git a/src/api/endpoints/messaging/messages.js b/src/api/endpoints/messaging/messages.ts similarity index 64% rename from src/api/endpoints/messaging/messages.js rename to src/api/endpoints/messaging/messages.ts index eaaf38c39..81562efbc 100644 --- a/src/api/endpoints/messaging/messages.js +++ b/src/api/endpoints/messaging/messages.ts @@ -3,7 +3,7 @@ /** * Module dependencies */ -import * as mongo from 'mongodb'; +import it from '../../it'; import Message from '../../models/messaging-message'; import User from '../../models/user'; import serialize from '../../serializers/messaging-message'; @@ -21,47 +21,40 @@ module.exports = (params, user) => new Promise(async (res, rej) => { // Get 'user_id' parameter - let recipient = params.user_id; - if (recipient !== undefined && recipient !== null) { - recipient = await User.findOne({ - _id: new mongo.ObjectID(recipient) - }, { - fields: { - _id: true - } - }); + const [recipientId, recipientIdErr] = it(params.user_id).expect.id().required().qed(); + if (recipientIdErr) return rej('invalid user_id param'); - if (recipient === null) { - return rej('user not found'); + // Fetch recipient + const recipient = await User.findOne({ + _id: recipientId + }, { + fields: { + _id: true } - } else { - return rej('user_id is required'); + }); + + if (recipient === null) { + return rej('user not found'); } // Get 'mark_as_read' parameter - let markAsRead = params.mark_as_read; - if (markAsRead == null) { - markAsRead = true; - } + const [markAsRead, markAsReadErr] = it(params.mark_as_read).expect.boolean().default(true).qed(); + if (markAsReadErr) return rej('invalid mark_as_read param'); // Get 'limit' parameter - let limit = params.limit; - if (limit !== undefined && limit !== null) { - limit = parseInt(limit, 10); + const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); + if (limitErr) return rej('invalid limit param'); - // From 1 to 100 - if (!(1 <= limit && limit <= 100)) { - return rej('invalid limit range'); - } - } else { - limit = 10; - } + // Get 'since_id' parameter + const [sinceId, sinceIdErr] = it(params.since_id).expect.id().qed(); + if (sinceIdErr) return rej('invalid since_id param'); - const since = params.since_id || null; - const max = params.max_id || null; + // Get 'max_id' parameter + const [maxId, maxIdErr] = it(params.max_id).expect.id().qed(); + if (maxIdErr) return rej('invalid max_id param'); // Check if both of since_id and max_id is specified - if (since !== null && max !== null) { + if (sinceId !== null && maxId !== null) { return rej('cannot set since_id and max_id'); } @@ -73,20 +66,20 @@ module.exports = (params, user) => user_id: recipient._id, recipient_id: user._id }] - }; + } as any; const sort = { _id: -1 }; - if (since !== null) { + if (sinceId) { sort._id = 1; query._id = { - $gt: new mongo.ObjectID(since) + $gt: sinceId }; - } else if (max !== null) { + } else if (maxId) { query._id = { - $lt: new mongo.ObjectID(max) + $lt: maxId }; } diff --git a/src/api/endpoints/messaging/messages/create.js b/src/api/endpoints/messaging/messages/create.ts similarity index 72% rename from src/api/endpoints/messaging/messages/create.js rename to src/api/endpoints/messaging/messages/create.ts index a88cc39ee..dbe7f617f 100644 --- a/src/api/endpoints/messaging/messages/create.js +++ b/src/api/endpoints/messaging/messages/create.ts @@ -3,8 +3,9 @@ /** * Module dependencies */ -import * as mongo from 'mongodb'; +import it from '../../../it'; import Message from '../../../models/messaging-message'; +import { isValidText } from '../../../models/messaging-message'; import History from '../../../models/messaging-history'; import User from '../../../models/user'; import DriveFile from '../../../models/drive-file'; @@ -13,11 +14,6 @@ import publishUserStream from '../../../event'; import { publishMessagingStream } from '../../../event'; import config from '../../../../conf'; -/** - * 最大文字数 - */ -const maxTextLength = 500; - /** * Create a message * @@ -29,55 +25,39 @@ module.exports = (params, user) => new Promise(async (res, rej) => { // Get 'user_id' parameter - let recipient = params.user_id; - if (recipient !== undefined && recipient !== null) { - if (typeof recipient != 'string') { - return rej('user_id must be a string'); - } + const [recipientId, recipientIdErr] = it(params.user_id).expect.id().required().qed(); + if (recipientIdErr) return rej('invalid user_id param'); - // Validate id - if (!mongo.ObjectID.isValid(recipient)) { - return rej('incorrect user_id'); - } + // Myself + if (recipientId.equals(user._id)) { + return rej('cannot send message to myself'); + } - // Myself - if (new mongo.ObjectID(recipient).equals(user._id)) { - return rej('cannot send message to myself'); + // Fetch recipient + const recipient = await User.findOne({ + _id: recipientId + }, { + fields: { + _id: true } + }); - recipient = await User.findOne({ - _id: new mongo.ObjectID(recipient) - }, { - fields: { - _id: true - } - }); - - if (recipient === null) { - return rej('user not found'); - } - } else { - return rej('user_id is required'); + if (recipient === null) { + return rej('user not found'); } // Get 'text' parameter - let text = params.text; - if (text !== undefined && text !== null) { - text = text.trim(); - if (text.length === 0) { - text = null; - } else if (text.length > maxTextLength) { - return rej('too long text'); - } - } else { - text = null; - } + const [text, textErr] = it(params.text).expect.string().validate(isValidText).qed(); + if (textErr) return rej('invalid text'); // Get 'file_id' parameter - let file = params.file_id; - if (file !== undefined && file !== null) { + const [fileId, fileIdErr] = it(params.file_id).expect.id().qed(); + if (fileIdErr) return rej('invalid file_id param'); + + let file = null; + if (fileId !== null) { file = await DriveFile.findOne({ - _id: new mongo.ObjectID(file), + _id: fileId, user_id: user._id }, { data: false @@ -86,8 +66,6 @@ module.exports = (params, user) => if (file === null) { return rej('file not found'); } - } else { - file = null; } // テキストが無いかつ添付ファイルも無かったらエラー diff --git a/src/api/endpoints/messaging/unread.js b/src/api/endpoints/messaging/unread.ts similarity index 100% rename from src/api/endpoints/messaging/unread.js rename to src/api/endpoints/messaging/unread.ts diff --git a/src/api/endpoints/my/apps.js b/src/api/endpoints/my/apps.ts similarity index 60% rename from src/api/endpoints/my/apps.js rename to src/api/endpoints/my/apps.ts index 1f45a1a27..2466a47ce 100644 --- a/src/api/endpoints/my/apps.js +++ b/src/api/endpoints/my/apps.ts @@ -3,7 +3,7 @@ /** * Module dependencies */ -import * as mongo from 'mongodb'; +import it from '../../it'; import App from '../../models/app'; import serialize from '../../serializers/app'; @@ -18,25 +18,12 @@ module.exports = (params, user) => new Promise(async (res, rej) => { // Get 'limit' parameter - let limit = params.limit; - if (limit !== undefined && limit !== null) { - limit = parseInt(limit, 10); - - // From 1 to 100 - if (!(1 <= limit && limit <= 100)) { - return rej('invalid limit range'); - } - } else { - limit = 10; - } + const [limit, limitErr] = it(params.limit).expect.number().range(1, 100).default(10).qed(); + if (limitErr) return rej('invalid limit param'); // Get 'offset' parameter - let offset = params.offset; - if (offset !== undefined && offset !== null) { - offset = parseInt(offset, 10); - } else { - offset = 0; - } + const [offset, offsetErr] = it(params.offset).expect.number().min(0).default(0).qed(); + if (offsetErr) return rej('invalid offset param'); const query = { user_id: user._id diff --git a/src/api/endpoints/notifications/mark_as_read.js b/src/api/endpoints/notifications/mark_as_read.ts similarity index 65% rename from src/api/endpoints/notifications/mark_as_read.js rename to src/api/endpoints/notifications/mark_as_read.ts index 9c8a5ee64..6e75927cf 100644 --- a/src/api/endpoints/notifications/mark_as_read.js +++ b/src/api/endpoints/notifications/mark_as_read.ts @@ -3,10 +3,10 @@ /** * Module dependencies */ -import * as mongo from 'mongodb'; -import Notification from '../../../models/notification'; -import serialize from '../../../serializers/notification'; -import event from '../../../event'; +import it from '../../it'; +import Notification from '../../models/notification'; +import serialize from '../../serializers/notification'; +import event from '../../event'; /** * Mark as read a notification @@ -17,16 +17,13 @@ import event from '../../../event'; */ module.exports = (params, user) => new Promise(async (res, rej) => { - const notificationId = params.notification; - - if (notificationId === undefined || notificationId === null) { - return rej('notification is required'); - } + const [notificationId, notificationIdErr] = it(params.notification_id).expect.id().required().qed(); + if (notificationIdErr) return rej('invalid notification_id param'); // Get notification const notification = await Notification .findOne({ - _id: new mongo.ObjectID(notificationId), + _id: notificationId, i: user._id }); diff --git a/src/api/it.ts b/src/api/it.ts index f4b28531d..039f87995 100644 --- a/src/api/it.ts +++ b/src/api/it.ts @@ -424,7 +424,7 @@ class IdQuery extends QueryCore { /** * このインスタンスの値およびエラーを取得します */ - qed(): [any[], Error] { + qed(): [mongo.ObjectID, Error] { return super.qed(); } @@ -433,7 +433,7 @@ class IdQuery extends QueryCore { * バリデータが false またはエラーを返した場合エラーにします * @param validator バリデータ */ - validate(validator: Validator) { + validate(validator: Validator) { return super.validate(validator); } } diff --git a/src/api/models/messaging-message.ts b/src/api/models/messaging-message.ts index cad6823cb..50955d7fb 100644 --- a/src/api/models/messaging-message.ts +++ b/src/api/models/messaging-message.ts @@ -1,3 +1,8 @@ import db from '../../db/mongodb'; export default db.get('messaging_messages') as any; // fuck type definition + +export function isValidText(text: string): boolean { + return text.length <= 1000 && text.trim() != ''; +} + diff --git a/src/api/serializers/messaging-message.ts b/src/api/serializers/messaging-message.ts index 4a4c8fc5b..da63f8b99 100644 --- a/src/api/serializers/messaging-message.ts +++ b/src/api/serializers/messaging-message.ts @@ -19,7 +19,7 @@ import deepcopy = require('deepcopy'); */ export default ( message: any, - me: any, + me?: any, options?: { populateRecipient: boolean }