This commit is contained in:
syuilo 2017-10-31 22:09:09 +09:00
parent dc9fddf839
commit b4340b1d91
2 changed files with 42 additions and 6 deletions

View File

@ -4,9 +4,9 @@
import $ from 'cafy'; import $ from 'cafy';
import deepEqual = require('deep-equal'); import deepEqual = require('deep-equal');
import parse from '../../common/text'; import parse from '../../common/text';
import Post from '../../models/post'; import { default as Post, IPost, isValidText } from '../../models/post';
import { isValidText } from '../../models/post';
import { default as User, IUser } from '../../models/user'; import { default as User, IUser } from '../../models/user';
import { default as Channel, IChannel } from '../../models/channel';
import Following from '../../models/following'; import Following from '../../models/following';
import DriveFile from '../../models/drive-file'; import DriveFile from '../../models/drive-file';
import Watching from '../../models/post-watching'; import Watching from '../../models/post-watching';
@ -62,7 +62,8 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
const [repostId, repostIdErr] = $(params.repost_id).optional.id().$; const [repostId, repostIdErr] = $(params.repost_id).optional.id().$;
if (repostIdErr) return rej('invalid repost_id'); if (repostIdErr) return rej('invalid repost_id');
let repost = null; let repost: IPost = null;
let isQuote = false;
if (repostId !== undefined) { if (repostId !== undefined) {
// Fetch repost to post // Fetch repost to post
repost = await Post.findOne({ repost = await Post.findOne({
@ -84,18 +85,20 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
} }
}); });
isQuote = text != null || files != null;
// 直近と同じRepost対象かつ引用じゃなかったらエラー // 直近と同じRepost対象かつ引用じゃなかったらエラー
if (latestPost && if (latestPost &&
latestPost.repost_id && latestPost.repost_id &&
latestPost.repost_id.equals(repost._id) && latestPost.repost_id.equals(repost._id) &&
text === undefined && files === null) { !isQuote) {
return rej('cannot repost same post that already reposted in your latest post'); return rej('cannot repost same post that already reposted in your latest post');
} }
// 直近がRepost対象かつ引用じゃなかったらエラー // 直近がRepost対象かつ引用じゃなかったらエラー
if (latestPost && if (latestPost &&
latestPost._id.equals(repost._id) && latestPost._id.equals(repost._id) &&
text === undefined && files === null) { !isQuote) {
return rej('cannot repost your latest post'); return rej('cannot repost your latest post');
} }
} }
@ -104,7 +107,7 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
const [inReplyToPostId, inReplyToPostIdErr] = $(params.reply_to_id).optional.id().$; const [inReplyToPostId, inReplyToPostIdErr] = $(params.reply_to_id).optional.id().$;
if (inReplyToPostIdErr) return rej('invalid in_reply_to_post_id'); if (inReplyToPostIdErr) return rej('invalid in_reply_to_post_id');
let inReplyToPost = null; let inReplyToPost: IPost = null;
if (inReplyToPostId !== undefined) { if (inReplyToPostId !== undefined) {
// Fetch reply // Fetch reply
inReplyToPost = await Post.findOne({ inReplyToPost = await Post.findOne({
@ -121,6 +124,37 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
} }
} }
// Get 'channel_id' parameter
const [channelId, channelIdErr] = $(params.channel_id).optional.id().$;
if (channelIdErr) return rej('invalid channel_id');
let channel: IChannel = null;
if (channelId !== undefined) {
// Fetch channel
channel = await Channel.findOne({
_id: channelId
});
if (channel === null) {
return rej('channel not found');
}
// 返信対象の投稿がこのチャンネルじゃなかったらダメ
if (inReplyToPost && !channelId.equals(inReplyToPost.channel_id)) {
return rej('チャンネル内部からチャンネル外部の投稿に返信することはできません');
}
// Repost対象の投稿がこのチャンネルじゃなかったらダメ
if (repost && !channelId.equals(repost.channel_id)) {
return rej('チャンネル内部からチャンネル外部の投稿をRepostすることはできません');
}
// 引用ではないRepostはダメ
if (repost && !isQuote) {
return rej('チャンネル内部では引用ではないRepostをすることはできません');
}
}
// Get 'poll' parameter // Get 'poll' parameter
const [poll, pollErr] = $(params.poll).optional.strict.object() const [poll, pollErr] = $(params.poll).optional.strict.object()
.have('choices', $().array('string') .have('choices', $().array('string')
@ -164,6 +198,7 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
// 投稿を作成 // 投稿を作成
const post = await Post.insert({ const post = await Post.insert({
created_at: new Date(), created_at: new Date(),
channel_id: channel ? channel._id : undefined,
media_ids: files ? files.map(file => file._id) : undefined, media_ids: files ? files.map(file => file._id) : undefined,
reply_to_id: inReplyToPost ? inReplyToPost._id : undefined, reply_to_id: inReplyToPost ? inReplyToPost._id : undefined,
repost_id: repost ? repost._id : undefined, repost_id: repost ? repost._id : undefined,

View File

@ -10,6 +10,7 @@ export function isValidText(text: string): boolean {
export type IPost = { export type IPost = {
_id: mongo.ObjectID; _id: mongo.ObjectID;
channel_id: mongo.ObjectID;
created_at: Date; created_at: Date;
media_ids: mongo.ObjectID[]; media_ids: mongo.ObjectID[];
reply_to_id: mongo.ObjectID; reply_to_id: mongo.ObjectID;