diff options
| author | Akihiko Odaki <nekomanma@pixiv.co.jp> | 2018-03-29 01:20:40 +0900 |
|---|---|---|
| committer | Akihiko Odaki <nekomanma@pixiv.co.jp> | 2018-03-29 01:54:41 +0900 |
| commit | 90f8fe7e538bb7e52d2558152a0390e693f39b11 (patch) | |
| tree | 0f830887053c8f352b1cd0c13ca715fd14c1f030 /src/api/models | |
| parent | Implement remote account resolution (diff) | |
| download | sharkey-90f8fe7e538bb7e52d2558152a0390e693f39b11.tar.gz sharkey-90f8fe7e538bb7e52d2558152a0390e693f39b11.tar.bz2 sharkey-90f8fe7e538bb7e52d2558152a0390e693f39b11.zip | |
Introduce processor
Diffstat (limited to 'src/api/models')
25 files changed, 0 insertions, 1431 deletions
diff --git a/src/api/models/access-token.ts b/src/api/models/access-token.ts deleted file mode 100644 index 9985be5013..0000000000 --- a/src/api/models/access-token.ts +++ /dev/null @@ -1,8 +0,0 @@ -import db from '../../db/mongodb'; - -const collection = db.get('access_tokens'); - -(collection as any).createIndex('token'); // fuck type definition -(collection as any).createIndex('hash'); // fuck type definition - -export default collection as any; // fuck type definition diff --git a/src/api/models/app.ts b/src/api/models/app.ts deleted file mode 100644 index 34e9867db7..0000000000 --- a/src/api/models/app.ts +++ /dev/null @@ -1,97 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import AccessToken from './access-token'; -import db from '../../db/mongodb'; -import config from '../../conf'; - -const App = db.get<IApp>('apps'); -App.createIndex('name_id'); -App.createIndex('name_id_lower'); -App.createIndex('secret'); -export default App; - -export type IApp = { - _id: mongo.ObjectID; - created_at: Date; - user_id: mongo.ObjectID; - secret: string; -}; - -export function isValidNameId(nameId: string): boolean { - return typeof nameId == 'string' && /^[a-zA-Z0-9\-]{3,30}$/.test(nameId); -} - -/** - * Pack an app for API response - * - * @param {any} app - * @param {any} me? - * @param {any} options? - * @return {Promise<any>} - */ -export const pack = ( - app: any, - me?: any, - options?: { - includeSecret?: boolean, - includeProfileImageIds?: boolean - } -) => new Promise<any>(async (resolve, reject) => { - const opts = options || { - includeSecret: false, - includeProfileImageIds: false - }; - - let _app: any; - - // Populate the app if 'app' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(app)) { - _app = await App.findOne({ - _id: app - }); - } else if (typeof app === 'string') { - _app = await App.findOne({ - _id: new mongo.ObjectID(app) - }); - } else { - _app = deepcopy(app); - } - - // Me - if (me && !mongo.ObjectID.prototype.isPrototypeOf(me)) { - if (typeof me === 'string') { - me = new mongo.ObjectID(me); - } else { - me = me._id; - } - } - - // Rename _id to id - _app.id = _app._id; - delete _app._id; - - delete _app.name_id_lower; - - // Visible by only owner - if (!opts.includeSecret) { - delete _app.secret; - } - - _app.icon_url = _app.icon != null - ? `${config.drive_url}/${_app.icon}` - : `${config.drive_url}/app-default.jpg`; - - if (me) { - // 既に連携しているか - const exist = await AccessToken.count({ - app_id: _app.id, - user_id: me, - }, { - limit: 1 - }); - - _app.is_authorized = exist === 1; - } - - resolve(_app); -}); diff --git a/src/api/models/appdata.ts b/src/api/models/appdata.ts deleted file mode 100644 index 3e68354fa4..0000000000 --- a/src/api/models/appdata.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('appdata') as any; // fuck type definition diff --git a/src/api/models/auth-session.ts b/src/api/models/auth-session.ts deleted file mode 100644 index 997ec61c20..0000000000 --- a/src/api/models/auth-session.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; -import { pack as packApp } from './app'; - -const AuthSession = db.get('auth_sessions'); -export default AuthSession; - -export interface IAuthSession { - _id: mongo.ObjectID; -} - -/** - * Pack an auth session for API response - * - * @param {any} session - * @param {any} me? - * @return {Promise<any>} - */ -export const pack = ( - session: any, - me?: any -) => new Promise<any>(async (resolve, reject) => { - let _session: any; - - // TODO: Populate session if it ID - - _session = deepcopy(session); - - // Me - if (me && !mongo.ObjectID.prototype.isPrototypeOf(me)) { - if (typeof me === 'string') { - me = new mongo.ObjectID(me); - } else { - me = me._id; - } - } - - delete _session._id; - - // Populate app - _session.app = await packApp(_session.app_id, me); - - resolve(_session); -}); diff --git a/src/api/models/channel-watching.ts b/src/api/models/channel-watching.ts deleted file mode 100644 index 6184ae408d..0000000000 --- a/src/api/models/channel-watching.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('channel_watching') as any; // fuck type definition diff --git a/src/api/models/channel.ts b/src/api/models/channel.ts deleted file mode 100644 index 815d53593c..0000000000 --- a/src/api/models/channel.ts +++ /dev/null @@ -1,74 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import { IUser } from './user'; -import Watching from './channel-watching'; -import db from '../../db/mongodb'; - -const Channel = db.get<IChannel>('channels'); -export default Channel; - -export type IChannel = { - _id: mongo.ObjectID; - created_at: Date; - title: string; - user_id: mongo.ObjectID; - index: number; -}; - -/** - * Pack a channel for API response - * - * @param channel target - * @param me? serializee - * @return response - */ -export const pack = ( - channel: string | mongo.ObjectID | IChannel, - me?: string | mongo.ObjectID | IUser -) => new Promise<any>(async (resolve, reject) => { - - let _channel: any; - - // Populate the channel if 'channel' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(channel)) { - _channel = await Channel.findOne({ - _id: channel - }); - } else if (typeof channel === 'string') { - _channel = await Channel.findOne({ - _id: new mongo.ObjectID(channel) - }); - } else { - _channel = deepcopy(channel); - } - - // Rename _id to id - _channel.id = _channel._id; - delete _channel._id; - - // Remove needless properties - delete _channel.user_id; - - // Me - const meId: mongo.ObjectID = me - ? mongo.ObjectID.prototype.isPrototypeOf(me) - ? me as mongo.ObjectID - : typeof me === 'string' - ? new mongo.ObjectID(me) - : (me as IUser)._id - : null; - - if (me) { - //#region Watchしているかどうか - const watch = await Watching.findOne({ - user_id: meId, - channel_id: _channel.id, - deleted_at: { $exists: false } - }); - - _channel.is_watching = watch !== null; - //#endregion - } - - resolve(_channel); -}); diff --git a/src/api/models/drive-file.ts b/src/api/models/drive-file.ts deleted file mode 100644 index 2a46d8dc4d..0000000000 --- a/src/api/models/drive-file.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as mongodb from 'mongodb'; -import deepcopy = require('deepcopy'); -import { pack as packFolder } from './drive-folder'; -import config from '../../conf'; -import monkDb, { nativeDbConn } from '../../db/mongodb'; - -const DriveFile = monkDb.get<IDriveFile>('drive_files.files'); - -export default DriveFile; - -const getGridFSBucket = async (): Promise<mongodb.GridFSBucket> => { - const db = await nativeDbConn(); - const bucket = new mongodb.GridFSBucket(db, { - bucketName: 'drive_files' - }); - return bucket; -}; - -export { getGridFSBucket }; - -export type IDriveFile = { - _id: mongodb.ObjectID; - uploadDate: Date; - md5: string; - filename: string; - contentType: string; - metadata: { - properties: any; - user_id: mongodb.ObjectID; - folder_id: mongodb.ObjectID; - } -}; - -export function validateFileName(name: string): boolean { - return ( - (name.trim().length > 0) && - (name.length <= 200) && - (name.indexOf('\\') === -1) && - (name.indexOf('/') === -1) && - (name.indexOf('..') === -1) - ); -} - -/** - * Pack a drive file for API response - * - * @param {any} file - * @param {any} options? - * @return {Promise<any>} - */ -export const pack = ( - file: any, - options?: { - detail: boolean - } -) => new Promise<any>(async (resolve, reject) => { - const opts = Object.assign({ - detail: false - }, options); - - let _file: any; - - // Populate the file if 'file' is ID - if (mongodb.ObjectID.prototype.isPrototypeOf(file)) { - _file = await DriveFile.findOne({ - _id: file - }); - } else if (typeof file === 'string') { - _file = await DriveFile.findOne({ - _id: new mongodb.ObjectID(file) - }); - } else { - _file = deepcopy(file); - } - - if (!_file) return reject('invalid file arg.'); - - // rendered target - let _target: any = {}; - - _target.id = _file._id; - _target.created_at = _file.uploadDate; - _target.name = _file.filename; - _target.type = _file.contentType; - _target.datasize = _file.length; - _target.md5 = _file.md5; - - _target = Object.assign(_target, _file.metadata); - - _target.url = `${config.drive_url}/${_target.id}/${encodeURIComponent(_target.name)}`; - - if (_target.properties == null) _target.properties = {}; - - if (opts.detail) { - if (_target.folder_id) { - // Populate folder - _target.folder = await packFolder(_target.folder_id, { - detail: true - }); - } - - /* - if (_target.tags) { - // Populate tags - _target.tags = await _target.tags.map(async (tag: any) => - await serializeDriveTag(tag) - ); - } - */ - } - - resolve(_target); -}); diff --git a/src/api/models/drive-folder.ts b/src/api/models/drive-folder.ts deleted file mode 100644 index 54b45049b9..0000000000 --- a/src/api/models/drive-folder.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; -import DriveFile from './drive-file'; - -const DriveFolder = db.get<IDriveFolder>('drive_folders'); -export default DriveFolder; - -export type IDriveFolder = { - _id: mongo.ObjectID; - created_at: Date; - name: string; - user_id: mongo.ObjectID; - parent_id: mongo.ObjectID; -}; - -export function isValidFolderName(name: string): boolean { - return ( - (name.trim().length > 0) && - (name.length <= 200) - ); -} - -/** - * Pack a drive folder for API response - * - * @param {any} folder - * @param {any} options? - * @return {Promise<any>} - */ -export const pack = ( - folder: any, - options?: { - detail: boolean - } -) => new Promise<any>(async (resolve, reject) => { - const opts = Object.assign({ - detail: false - }, options); - - let _folder: any; - - // Populate the folder if 'folder' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(folder)) { - _folder = await DriveFolder.findOne({ _id: folder }); - } else if (typeof folder === 'string') { - _folder = await DriveFolder.findOne({ _id: new mongo.ObjectID(folder) }); - } else { - _folder = deepcopy(folder); - } - - // Rename _id to id - _folder.id = _folder._id; - delete _folder._id; - - if (opts.detail) { - const childFoldersCount = await DriveFolder.count({ - parent_id: _folder.id - }); - - const childFilesCount = await DriveFile.count({ - 'metadata.folder_id': _folder.id - }); - - _folder.folders_count = childFoldersCount; - _folder.files_count = childFilesCount; - } - - if (opts.detail && _folder.parent_id) { - // Populate parent folder - _folder.parent = await pack(_folder.parent_id, { - detail: true - }); - } - - resolve(_folder); -}); diff --git a/src/api/models/drive-tag.ts b/src/api/models/drive-tag.ts deleted file mode 100644 index 991c935e81..0000000000 --- a/src/api/models/drive-tag.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('drive_tags') as any; // fuck type definition diff --git a/src/api/models/favorite.ts b/src/api/models/favorite.ts deleted file mode 100644 index e01d9e343c..0000000000 --- a/src/api/models/favorite.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('favorites') as any; // fuck type definition diff --git a/src/api/models/following.ts b/src/api/models/following.ts deleted file mode 100644 index cb3db9b539..0000000000 --- a/src/api/models/following.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('following') as any; // fuck type definition diff --git a/src/api/models/messaging-history.ts b/src/api/models/messaging-history.ts deleted file mode 100644 index c06987e451..0000000000 --- a/src/api/models/messaging-history.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('messaging_histories') as any; // fuck type definition diff --git a/src/api/models/messaging-message.ts b/src/api/models/messaging-message.ts deleted file mode 100644 index fcb356c5ca..0000000000 --- a/src/api/models/messaging-message.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import { pack as packUser } from './user'; -import { pack as packFile } from './drive-file'; -import db from '../../db/mongodb'; -import parse from '../common/text'; - -const MessagingMessage = db.get<IMessagingMessage>('messaging_messages'); -export default MessagingMessage; - -export interface IMessagingMessage { - _id: mongo.ObjectID; - created_at: Date; - text: string; - user_id: mongo.ObjectID; - recipient_id: mongo.ObjectID; - is_read: boolean; -} - -export function isValidText(text: string): boolean { - return text.length <= 1000 && text.trim() != ''; -} - -/** - * Pack a messaging message for API response - * - * @param {any} message - * @param {any} me? - * @param {any} options? - * @return {Promise<any>} - */ -export const pack = ( - message: any, - me?: any, - options?: { - populateRecipient: boolean - } -) => new Promise<any>(async (resolve, reject) => { - const opts = options || { - populateRecipient: true - }; - - let _message: any; - - // Populate the message if 'message' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(message)) { - _message = await MessagingMessage.findOne({ - _id: message - }); - } else if (typeof message === 'string') { - _message = await MessagingMessage.findOne({ - _id: new mongo.ObjectID(message) - }); - } else { - _message = deepcopy(message); - } - - // Rename _id to id - _message.id = _message._id; - delete _message._id; - - // Parse text - if (_message.text) { - _message.ast = parse(_message.text); - } - - // Populate user - _message.user = await packUser(_message.user_id, me); - - if (_message.file_id) { - // Populate file - _message.file = await packFile(_message.file_id); - } - - if (opts.populateRecipient) { - // Populate recipient - _message.recipient = await packUser(_message.recipient_id, me); - } - - resolve(_message); -}); diff --git a/src/api/models/meta.ts b/src/api/models/meta.ts deleted file mode 100644 index c7dba8fcba..0000000000 --- a/src/api/models/meta.ts +++ /dev/null @@ -1,7 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('meta') as any; // fuck type definition - -export type IMeta = { - top_image: string; -}; diff --git a/src/api/models/mute.ts b/src/api/models/mute.ts deleted file mode 100644 index 16018b82f7..0000000000 --- a/src/api/models/mute.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('mute') as any; // fuck type definition diff --git a/src/api/models/notification.ts b/src/api/models/notification.ts deleted file mode 100644 index fa7049d312..0000000000 --- a/src/api/models/notification.ts +++ /dev/null @@ -1,107 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; -import { IUser, pack as packUser } from './user'; -import { pack as packPost } from './post'; - -const Notification = db.get<INotification>('notifications'); -export default Notification; - -export interface INotification { - _id: mongo.ObjectID; - created_at: Date; - - /** - * 通知の受信者 - */ - notifiee?: IUser; - - /** - * 通知の受信者 - */ - notifiee_id: mongo.ObjectID; - - /** - * イニシエータ(initiator)、Origin。通知を行う原因となったユーザー - */ - notifier?: IUser; - - /** - * イニシエータ(initiator)、Origin。通知を行う原因となったユーザー - */ - notifier_id: mongo.ObjectID; - - /** - * 通知の種類。 - * follow - フォローされた - * mention - 投稿で自分が言及された - * reply - (自分または自分がWatchしている)投稿が返信された - * repost - (自分または自分がWatchしている)投稿がRepostされた - * quote - (自分または自分がWatchしている)投稿が引用Repostされた - * reaction - (自分または自分がWatchしている)投稿にリアクションされた - * poll_vote - (自分または自分がWatchしている)投稿の投票に投票された - */ - type: 'follow' | 'mention' | 'reply' | 'repost' | 'quote' | 'reaction' | 'poll_vote'; - - /** - * 通知が読まれたかどうか - */ - is_read: Boolean; -} - -/** - * Pack a notification for API response - * - * @param {any} notification - * @return {Promise<any>} - */ -export const pack = (notification: any) => new Promise<any>(async (resolve, reject) => { - let _notification: any; - - // Populate the notification if 'notification' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(notification)) { - _notification = await Notification.findOne({ - _id: notification - }); - } else if (typeof notification === 'string') { - _notification = await Notification.findOne({ - _id: new mongo.ObjectID(notification) - }); - } else { - _notification = deepcopy(notification); - } - - // Rename _id to id - _notification.id = _notification._id; - delete _notification._id; - - // Rename notifier_id to user_id - _notification.user_id = _notification.notifier_id; - delete _notification.notifier_id; - - const me = _notification.notifiee_id; - delete _notification.notifiee_id; - - // Populate notifier - _notification.user = await packUser(_notification.user_id, me); - - switch (_notification.type) { - case 'follow': - // nope - break; - case 'mention': - case 'reply': - case 'repost': - case 'quote': - case 'reaction': - case 'poll_vote': - // Populate post - _notification.post = await packPost(_notification.post_id, me); - break; - default: - console.error(`Unknown type: ${_notification.type}`); - break; - } - - resolve(_notification); -}); diff --git a/src/api/models/othello-game.ts b/src/api/models/othello-game.ts deleted file mode 100644 index 01c6ca6c00..0000000000 --- a/src/api/models/othello-game.ts +++ /dev/null @@ -1,109 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; -import { IUser, pack as packUser } from './user'; - -const Game = db.get<IGame>('othello_games'); -export default Game; - -export interface IGame { - _id: mongo.ObjectID; - created_at: Date; - started_at: Date; - user1_id: mongo.ObjectID; - user2_id: mongo.ObjectID; - user1_accepted: boolean; - user2_accepted: boolean; - - /** - * どちらのプレイヤーが先行(黒)か - * 1 ... user1 - * 2 ... user2 - */ - black: number; - - is_started: boolean; - is_ended: boolean; - winner_id: mongo.ObjectID; - logs: Array<{ - at: Date; - color: boolean; - pos: number; - }>; - settings: { - map: string[]; - bw: string | number; - is_llotheo: boolean; - can_put_everywhere: boolean; - looped_board: boolean; - }; - form1: any; - form2: any; - - // ログのposを文字列としてすべて連結したもののCRC32値 - crc32: string; -} - -/** - * Pack an othello game for API response - */ -export const pack = ( - game: any, - me?: string | mongo.ObjectID | IUser, - options?: { - detail?: boolean - } -) => new Promise<any>(async (resolve, reject) => { - const opts = Object.assign({ - detail: true - }, options); - - let _game: any; - - // Populate the game if 'game' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(game)) { - _game = await Game.findOne({ - _id: game - }); - } else if (typeof game === 'string') { - _game = await Game.findOne({ - _id: new mongo.ObjectID(game) - }); - } else { - _game = deepcopy(game); - } - - // Me - const meId: mongo.ObjectID = me - ? mongo.ObjectID.prototype.isPrototypeOf(me) - ? me as mongo.ObjectID - : typeof me === 'string' - ? new mongo.ObjectID(me) - : (me as IUser)._id - : null; - - // Rename _id to id - _game.id = _game._id; - delete _game._id; - - if (opts.detail === false) { - delete _game.logs; - delete _game.settings.map; - } else { - // 互換性のため - if (_game.settings.map.hasOwnProperty('size')) { - _game.settings.map = _game.settings.map.data.match(new RegExp(`.{1,${_game.settings.map.size}}`, 'g')); - } - } - - // Populate user - _game.user1 = await packUser(_game.user1_id, meId); - _game.user2 = await packUser(_game.user2_id, meId); - if (_game.winner_id) { - _game.winner = await packUser(_game.winner_id, meId); - } else { - _game.winner = null; - } - - resolve(_game); -}); diff --git a/src/api/models/othello-matching.ts b/src/api/models/othello-matching.ts deleted file mode 100644 index 5cc39cae13..0000000000 --- a/src/api/models/othello-matching.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; -import { IUser, pack as packUser } from './user'; - -const Matching = db.get<IMatching>('othello_matchings'); -export default Matching; - -export interface IMatching { - _id: mongo.ObjectID; - created_at: Date; - parent_id: mongo.ObjectID; - child_id: mongo.ObjectID; -} - -/** - * Pack an othello matching for API response - */ -export const pack = ( - matching: any, - me?: string | mongo.ObjectID | IUser -) => new Promise<any>(async (resolve, reject) => { - - // Me - const meId: mongo.ObjectID = me - ? mongo.ObjectID.prototype.isPrototypeOf(me) - ? me as mongo.ObjectID - : typeof me === 'string' - ? new mongo.ObjectID(me) - : (me as IUser)._id - : null; - - const _matching = deepcopy(matching); - - // Rename _id to id - _matching.id = _matching._id; - delete _matching._id; - - // Populate user - _matching.parent = await packUser(_matching.parent_id, meId); - _matching.child = await packUser(_matching.child_id, meId); - - resolve(_matching); -}); diff --git a/src/api/models/poll-vote.ts b/src/api/models/poll-vote.ts deleted file mode 100644 index af77a2643e..0000000000 --- a/src/api/models/poll-vote.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('poll_votes') as any; // fuck type definition diff --git a/src/api/models/post-reaction.ts b/src/api/models/post-reaction.ts deleted file mode 100644 index 639a70e006..0000000000 --- a/src/api/models/post-reaction.ts +++ /dev/null @@ -1,51 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; -import Reaction from './post-reaction'; -import { pack as packUser } from './user'; - -const PostReaction = db.get<IPostReaction>('post_reactions'); -export default PostReaction; - -export interface IPostReaction { - _id: mongo.ObjectID; - created_at: Date; - deleted_at: Date; - reaction: string; -} - -/** - * Pack a reaction for API response - * - * @param {any} reaction - * @param {any} me? - * @return {Promise<any>} - */ -export const pack = ( - reaction: any, - me?: any -) => new Promise<any>(async (resolve, reject) => { - let _reaction: any; - - // Populate the reaction if 'reaction' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(reaction)) { - _reaction = await Reaction.findOne({ - _id: reaction - }); - } else if (typeof reaction === 'string') { - _reaction = await Reaction.findOne({ - _id: new mongo.ObjectID(reaction) - }); - } else { - _reaction = deepcopy(reaction); - } - - // Rename _id to id - _reaction.id = _reaction._id; - delete _reaction._id; - - // Populate user - _reaction.user = await packUser(_reaction.user_id, me); - - resolve(_reaction); -}); diff --git a/src/api/models/post-watching.ts b/src/api/models/post-watching.ts deleted file mode 100644 index 41d37e2703..0000000000 --- a/src/api/models/post-watching.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('post_watching') as any; // fuck type definition diff --git a/src/api/models/post.ts b/src/api/models/post.ts deleted file mode 100644 index c37c8371c0..0000000000 --- a/src/api/models/post.ts +++ /dev/null @@ -1,219 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import rap from '@prezzemolo/rap'; -import db from '../../db/mongodb'; -import { IUser, pack as packUser } from './user'; -import { pack as packApp } from './app'; -import { pack as packChannel } from './channel'; -import Vote from './poll-vote'; -import Reaction from './post-reaction'; -import { pack as packFile } from './drive-file'; -import parse from '../common/text'; - -const Post = db.get<IPost>('posts'); - -export default Post; - -export function isValidText(text: string): boolean { - return text.length <= 1000 && text.trim() != ''; -} - -export type IPost = { - _id: mongo.ObjectID; - channel_id: mongo.ObjectID; - created_at: Date; - media_ids: mongo.ObjectID[]; - reply_id: mongo.ObjectID; - repost_id: mongo.ObjectID; - poll: any; // todo - text: string; - user_id: mongo.ObjectID; - app_id: mongo.ObjectID; - category: string; - is_category_verified: boolean; - via_mobile: boolean; - geo: { - latitude: number; - longitude: number; - altitude: number; - accuracy: number; - altitudeAccuracy: number; - heading: number; - speed: number; - }; -}; - -/** - * Pack a post for API response - * - * @param post target - * @param me? serializee - * @param options? serialize options - * @return response - */ -export const pack = async ( - post: string | mongo.ObjectID | IPost, - me?: string | mongo.ObjectID | IUser, - options?: { - detail: boolean - } -) => { - const opts = options || { - detail: true, - }; - - // Me - const meId: mongo.ObjectID = me - ? mongo.ObjectID.prototype.isPrototypeOf(me) - ? me as mongo.ObjectID - : typeof me === 'string' - ? new mongo.ObjectID(me) - : (me as IUser)._id - : null; - - let _post: any; - - // Populate the post if 'post' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(post)) { - _post = await Post.findOne({ - _id: post - }); - } else if (typeof post === 'string') { - _post = await Post.findOne({ - _id: new mongo.ObjectID(post) - }); - } else { - _post = deepcopy(post); - } - - if (!_post) throw 'invalid post arg.'; - - const id = _post._id; - - // Rename _id to id - _post.id = _post._id; - delete _post._id; - - delete _post.mentions; - - // Parse text - if (_post.text) { - _post.ast = parse(_post.text); - } - - // Populate user - _post.user = packUser(_post.user_id, meId); - - // Populate app - if (_post.app_id) { - _post.app = packApp(_post.app_id); - } - - // Populate channel - if (_post.channel_id) { - _post.channel = packChannel(_post.channel_id); - } - - // Populate media - if (_post.media_ids) { - _post.media = Promise.all(_post.media_ids.map(fileId => - packFile(fileId) - )); - } - - // When requested a detailed post data - if (opts.detail) { - // Get previous post info - _post.prev = (async () => { - const prev = await Post.findOne({ - user_id: _post.user_id, - _id: { - $lt: id - } - }, { - fields: { - _id: true - }, - sort: { - _id: -1 - } - }); - return prev ? prev._id : null; - })(); - - // Get next post info - _post.next = (async () => { - const next = await Post.findOne({ - user_id: _post.user_id, - _id: { - $gt: id - } - }, { - fields: { - _id: true - }, - sort: { - _id: 1 - } - }); - return next ? next._id : null; - })(); - - if (_post.reply_id) { - // Populate reply to post - _post.reply = pack(_post.reply_id, meId, { - detail: false - }); - } - - if (_post.repost_id) { - // Populate repost - _post.repost = pack(_post.repost_id, meId, { - detail: _post.text == null - }); - } - - // Poll - if (meId && _post.poll) { - _post.poll = (async (poll) => { - const vote = await Vote - .findOne({ - user_id: meId, - post_id: id - }); - - if (vote != null) { - const myChoice = poll.choices - .filter(c => c.id == vote.choice)[0]; - - myChoice.is_voted = true; - } - - return poll; - })(_post.poll); - } - - // Fetch my reaction - if (meId) { - _post.my_reaction = (async () => { - const reaction = await Reaction - .findOne({ - user_id: meId, - post_id: id, - deleted_at: { $exists: false } - }); - - if (reaction) { - return reaction.reaction; - } - - return null; - })(); - } - } - - // resolve promises in _post object - _post = await rap(_post); - - return _post; -}; diff --git a/src/api/models/signin.ts b/src/api/models/signin.ts deleted file mode 100644 index 262c8707ed..0000000000 --- a/src/api/models/signin.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import db from '../../db/mongodb'; - -const Signin = db.get<ISignin>('signin'); -export default Signin; - -export interface ISignin { - _id: mongo.ObjectID; -} - -/** - * Pack a signin record for API response - * - * @param {any} record - * @return {Promise<any>} - */ -export const pack = ( - record: any -) => new Promise<any>(async (resolve, reject) => { - - const _record = deepcopy(record); - - // Rename _id to id - _record.id = _record._id; - delete _record._id; - - resolve(_record); -}); diff --git a/src/api/models/sw-subscription.ts b/src/api/models/sw-subscription.ts deleted file mode 100644 index ecca04cb91..0000000000 --- a/src/api/models/sw-subscription.ts +++ /dev/null @@ -1,3 +0,0 @@ -import db from '../../db/mongodb'; - -export default db.get('sw_subscriptions') as any; // fuck type definition diff --git a/src/api/models/user.ts b/src/api/models/user.ts deleted file mode 100644 index e73c95faf2..0000000000 --- a/src/api/models/user.ts +++ /dev/null @@ -1,340 +0,0 @@ -import * as mongo from 'mongodb'; -import deepcopy = require('deepcopy'); -import rap from '@prezzemolo/rap'; -import db from '../../db/mongodb'; -import { IPost, pack as packPost } from './post'; -import Following from './following'; -import Mute from './mute'; -import getFriends from '../common/get-friends'; -import config from '../../conf'; - -const User = db.get<IUser>('users'); - -User.createIndex('username'); -User.createIndex('account.token'); - -export default User; - -export function validateUsername(username: string): boolean { - return typeof username == 'string' && /^[a-zA-Z0-9\-]{3,20}$/.test(username); -} - -export function validatePassword(password: string): boolean { - return typeof password == 'string' && password != ''; -} - -export function isValidName(name: string): boolean { - return typeof name == 'string' && name.length < 30 && name.trim() != ''; -} - -export function isValidDescription(description: string): boolean { - return typeof description == 'string' && description.length < 500 && description.trim() != ''; -} - -export function isValidLocation(location: string): boolean { - return typeof location == 'string' && location.length < 50 && location.trim() != ''; -} - -export function isValidBirthday(birthday: string): boolean { - return typeof birthday == 'string' && /^([0-9]{4})\-([0-9]{2})-([0-9]{2})$/.test(birthday); -} - -export type ILocalAccount = { - keypair: string; - email: string; - links: string[]; - password: string; - token: string; - twitter: { - access_token: string; - access_token_secret: string; - user_id: string; - screen_name: string; - }; - line: { - user_id: string; - }; - profile: { - location: string; - birthday: string; // 'YYYY-MM-DD' - tags: string[]; - }; - last_used_at: Date; - is_bot: boolean; - is_pro: boolean; - two_factor_secret: string; - two_factor_enabled: boolean; - client_settings: any; - settings: any; -}; - -export type IRemoteAccount = { - uri: string; -}; - -export type IUser = { - _id: mongo.ObjectID; - created_at: Date; - deleted_at: Date; - followers_count: number; - following_count: number; - name: string; - posts_count: number; - drive_capacity: number; - username: string; - username_lower: string; - avatar_id: mongo.ObjectID; - banner_id: mongo.ObjectID; - data: any; - description: string; - latest_post: IPost; - pinned_post_id: mongo.ObjectID; - is_suspended: boolean; - keywords: string[]; - host: string; - host_lower: string; - account: ILocalAccount | IRemoteAccount; -}; - -export function init(user): IUser { - user._id = new mongo.ObjectID(user._id); - user.avatar_id = new mongo.ObjectID(user.avatar_id); - user.banner_id = new mongo.ObjectID(user.banner_id); - user.pinned_post_id = new mongo.ObjectID(user.pinned_post_id); - return user; -} - -/** - * Pack a user for API response - * - * @param user target - * @param me? serializee - * @param options? serialize options - * @return Packed user - */ -export const pack = ( - user: string | mongo.ObjectID | IUser, - me?: string | mongo.ObjectID | IUser, - options?: { - detail?: boolean, - includeSecrets?: boolean - } -) => new Promise<any>(async (resolve, reject) => { - - const opts = Object.assign({ - detail: false, - includeSecrets: false - }, options); - - let _user: any; - - const fields = opts.detail ? { - } : { - 'account.settings': false, - 'account.client_settings': false, - 'account.profile': false, - 'account.keywords': false, - 'account.domains': false - }; - - // Populate the user if 'user' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(user)) { - _user = await User.findOne({ - _id: user - }, { fields }); - } else if (typeof user === 'string') { - _user = await User.findOne({ - _id: new mongo.ObjectID(user) - }, { fields }); - } else { - _user = deepcopy(user); - } - - if (!_user) return reject('invalid user arg.'); - - // Me - const meId: mongo.ObjectID = me - ? mongo.ObjectID.prototype.isPrototypeOf(me) - ? me as mongo.ObjectID - : typeof me === 'string' - ? new mongo.ObjectID(me) - : (me as IUser)._id - : null; - - // Rename _id to id - _user.id = _user._id; - delete _user._id; - - // Remove needless properties - delete _user.latest_post; - - if (!_user.host) { - // Remove private properties - delete _user.account.keypair; - delete _user.account.password; - delete _user.account.token; - delete _user.account.two_factor_temp_secret; - delete _user.account.two_factor_secret; - delete _user.username_lower; - if (_user.account.twitter) { - delete _user.account.twitter.access_token; - delete _user.account.twitter.access_token_secret; - } - delete _user.account.line; - - // Visible via only the official client - if (!opts.includeSecrets) { - delete _user.account.email; - delete _user.account.settings; - delete _user.account.client_settings; - } - - if (!opts.detail) { - delete _user.account.two_factor_enabled; - } - } - - _user.avatar_url = _user.avatar_id != null - ? `${config.drive_url}/${_user.avatar_id}` - : `${config.drive_url}/default-avatar.jpg`; - - _user.banner_url = _user.banner_id != null - ? `${config.drive_url}/${_user.banner_id}` - : null; - - if (!meId || !meId.equals(_user.id) || !opts.detail) { - delete _user.avatar_id; - delete _user.banner_id; - - delete _user.drive_capacity; - } - - if (meId && !meId.equals(_user.id)) { - // Whether the user is following - _user.is_following = (async () => { - const follow = await Following.findOne({ - follower_id: meId, - followee_id: _user.id, - deleted_at: { $exists: false } - }); - return follow !== null; - })(); - - // Whether the user is followed - _user.is_followed = (async () => { - const follow2 = await Following.findOne({ - follower_id: _user.id, - followee_id: meId, - deleted_at: { $exists: false } - }); - return follow2 !== null; - })(); - - // Whether the user is muted - _user.is_muted = (async () => { - const mute = await Mute.findOne({ - muter_id: meId, - mutee_id: _user.id, - deleted_at: { $exists: false } - }); - return mute !== null; - })(); - } - - if (opts.detail) { - if (_user.pinned_post_id) { - // Populate pinned post - _user.pinned_post = packPost(_user.pinned_post_id, meId, { - detail: true - }); - } - - if (meId && !meId.equals(_user.id)) { - const myFollowingIds = await getFriends(meId); - - // Get following you know count - _user.following_you_know_count = Following.count({ - followee_id: { $in: myFollowingIds }, - follower_id: _user.id, - deleted_at: { $exists: false } - }); - - // Get followers you know count - _user.followers_you_know_count = Following.count({ - followee_id: _user.id, - follower_id: { $in: myFollowingIds }, - deleted_at: { $exists: false } - }); - } - } - - // resolve promises in _user object - _user = await rap(_user); - - resolve(_user); -}); - -/** - * Pack a user for ActivityPub - * - * @param user target - * @return Packed user - */ -export const packForAp = ( - user: string | mongo.ObjectID | IUser -) => new Promise<any>(async (resolve, reject) => { - - let _user: any; - - const fields = { - // something - }; - - // Populate the user if 'user' is ID - if (mongo.ObjectID.prototype.isPrototypeOf(user)) { - _user = await User.findOne({ - _id: user - }, { fields }); - } else if (typeof user === 'string') { - _user = await User.findOne({ - _id: new mongo.ObjectID(user) - }, { fields }); - } else { - _user = deepcopy(user); - } - - if (!_user) return reject('invalid user arg.'); - - const userUrl = `${config.url}/@${_user.username}`; - - resolve({ - "@context": ["https://www.w3.org/ns/activitystreams", { - "@language": "ja" - }], - "type": "Person", - "id": userUrl, - "following": `${userUrl}/following.json`, - "followers": `${userUrl}/followers.json`, - "liked": `${userUrl}/liked.json`, - "inbox": `${userUrl}/inbox.json`, - "outbox": `${userUrl}/outbox.json`, - "preferredUsername": _user.username, - "name": _user.name, - "summary": _user.description, - "icon": [ - `${config.drive_url}/${_user.avatar_id}` - ] - }); -}); - -/* -function img(url) { - return { - thumbnail: { - large: `${url}`, - medium: '', - small: '' - } - }; -} -*/ |