物理削除系の処理を削除
これらの処理はパフォーマンス的に現実的でないし、すべてのモデルの関係を把握している必要があり保守が困難 論理削除でなんとかする
This commit is contained in:
		
							parent
							
								
									d64dc45899
								
							
						
					
					
						commit
						108dcb3e61
					
				
					 20 changed files with 12 additions and 779 deletions
				
			
		| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const AccessToken = db.get<IAccessToken>('accessTokens');
 | 
					const AccessToken = db.get<IAccessToken>('accessTokens');
 | 
				
			||||||
AccessToken.createIndex('token');
 | 
					AccessToken.createIndex('token');
 | 
				
			||||||
| 
						 | 
					@ -15,30 +14,3 @@ export type IAccessToken = {
 | 
				
			||||||
	token: string;
 | 
						token: string;
 | 
				
			||||||
	hash: string;
 | 
						hash: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * AccessTokenを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteAccessToken(accessToken: string | mongo.ObjectID | IAccessToken) {
 | 
					 | 
				
			||||||
	let a: IAccessToken;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(accessToken)) {
 | 
					 | 
				
			||||||
		a = await AccessToken.findOne({
 | 
					 | 
				
			||||||
			_id: accessToken
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof accessToken === 'string') {
 | 
					 | 
				
			||||||
		a = await AccessToken.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(accessToken)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		a = accessToken as IAccessToken;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (a == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このAccessTokenを削除
 | 
					 | 
				
			||||||
	await AccessToken.remove({
 | 
					 | 
				
			||||||
		_id: a._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Blocking = db.get<IBlocking>('blocking');
 | 
					const Blocking = db.get<IBlocking>('blocking');
 | 
				
			||||||
Blocking.createIndex(['blockerId', 'blockeeId'], { unique: true });
 | 
					Blocking.createIndex(['blockerId', 'blockeeId'], { unique: true });
 | 
				
			||||||
| 
						 | 
					@ -12,30 +11,3 @@ export type IBlocking = {
 | 
				
			||||||
	blockeeId: mongo.ObjectID;
 | 
						blockeeId: mongo.ObjectID;
 | 
				
			||||||
	blockerId: mongo.ObjectID;
 | 
						blockerId: mongo.ObjectID;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Blockingを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteBlocking(blocking: string | mongo.ObjectID | IBlocking) {
 | 
					 | 
				
			||||||
	let f: IBlocking;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(blocking)) {
 | 
					 | 
				
			||||||
		f = await Blocking.findOne({
 | 
					 | 
				
			||||||
			_id: blocking
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof blocking === 'string') {
 | 
					 | 
				
			||||||
		f = await Blocking.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(blocking)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		f = blocking as IBlocking;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (f == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このBlockingを削除
 | 
					 | 
				
			||||||
	await Blocking.remove({
 | 
					 | 
				
			||||||
		_id: f._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import monkDb, { nativeDbConn } from '../db/mongodb';
 | 
					import monkDb, { nativeDbConn } from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DriveFileThumbnail = monkDb.get<IDriveFileThumbnail>('driveFileThumbnails.files');
 | 
					const DriveFileThumbnail = monkDb.get<IDriveFileThumbnail>('driveFileThumbnails.files');
 | 
				
			||||||
DriveFileThumbnail.createIndex('metadata.originalId', { sparse: true, unique: true });
 | 
					DriveFileThumbnail.createIndex('metadata.originalId', { sparse: true, unique: true });
 | 
				
			||||||
| 
						 | 
					@ -28,35 +27,3 @@ export type IDriveFileThumbnail = {
 | 
				
			||||||
	contentType: string;
 | 
						contentType: string;
 | 
				
			||||||
	metadata: IMetadata;
 | 
						metadata: IMetadata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * DriveFileThumbnailを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteDriveFileThumbnail(driveFile: string | mongo.ObjectID | IDriveFileThumbnail) {
 | 
					 | 
				
			||||||
	let d: IDriveFileThumbnail;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(driveFile)) {
 | 
					 | 
				
			||||||
		d = await DriveFileThumbnail.findOne({
 | 
					 | 
				
			||||||
			_id: driveFile
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof driveFile === 'string') {
 | 
					 | 
				
			||||||
		d = await DriveFileThumbnail.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(driveFile)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		d = driveFile as IDriveFileThumbnail;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (d == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileThumbnailのチャンクをすべて削除
 | 
					 | 
				
			||||||
	await DriveFileThumbnailChunk.remove({
 | 
					 | 
				
			||||||
		files_id: d._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileThumbnailを削除
 | 
					 | 
				
			||||||
	await DriveFileThumbnail.remove({
 | 
					 | 
				
			||||||
		_id: d._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,10 +4,6 @@ import { pack as packFolder } from './drive-folder';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
import monkDb, { nativeDbConn } from '../db/mongodb';
 | 
					import monkDb, { nativeDbConn } from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					import isObjectId from '../misc/is-objectid';
 | 
				
			||||||
import Note, { deleteNote } from './note';
 | 
					 | 
				
			||||||
import MessagingMessage, { deleteMessagingMessage } from './messaging-message';
 | 
					 | 
				
			||||||
import User from './user';
 | 
					 | 
				
			||||||
import DriveFileThumbnail, { deleteDriveFileThumbnail } from './drive-file-thumbnail';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
 | 
					const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
 | 
				
			||||||
DriveFile.createIndex('md5');
 | 
					DriveFile.createIndex('md5');
 | 
				
			||||||
| 
						 | 
					@ -77,64 +73,6 @@ export function validateFileName(name: string): boolean {
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * DriveFileを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteDriveFile(driveFile: string | mongo.ObjectID | IDriveFile) {
 | 
					 | 
				
			||||||
	let d: IDriveFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(driveFile)) {
 | 
					 | 
				
			||||||
		d = await DriveFile.findOne({
 | 
					 | 
				
			||||||
			_id: driveFile
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof driveFile === 'string') {
 | 
					 | 
				
			||||||
		d = await DriveFile.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(driveFile)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		d = driveFile as IDriveFile;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (d == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileを添付しているNoteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Note.find({ fileIds: d._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNote(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileを添付しているMessagingMessageをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await MessagingMessage.find({ fileId: d._id })
 | 
					 | 
				
			||||||
	).map(x => deleteMessagingMessage(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileがアバターやバナーに使われていたらそれらのプロパティをnullにする
 | 
					 | 
				
			||||||
	const u = await User.findOne({ _id: d.metadata.userId });
 | 
					 | 
				
			||||||
	if (u) {
 | 
					 | 
				
			||||||
		if (u.avatarId && u.avatarId.equals(d._id)) {
 | 
					 | 
				
			||||||
			await User.update({ _id: u._id }, { $set: { avatarId: null } });
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (u.bannerId && u.bannerId.equals(d._id)) {
 | 
					 | 
				
			||||||
			await User.update({ _id: u._id }, { $set: { bannerId: null } });
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileのDriveFileThumbnailをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await DriveFileThumbnail.find({ 'metadata.originalId': d._id })
 | 
					 | 
				
			||||||
	).map(x => deleteDriveFileThumbnail(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileのチャンクをすべて削除
 | 
					 | 
				
			||||||
	await DriveFileChunk.remove({
 | 
					 | 
				
			||||||
		files_id: d._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFileを削除
 | 
					 | 
				
			||||||
	await DriveFile.remove({
 | 
					 | 
				
			||||||
		_id: d._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const packMany = async (
 | 
					export const packMany = async (
 | 
				
			||||||
	files: any[],
 | 
						files: any[],
 | 
				
			||||||
	options?: {
 | 
						options?: {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,51 +23,6 @@ export function isValidFolderName(name: string): boolean {
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * DriveFolderを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteDriveFolder(driveFolder: string | mongo.ObjectID | IDriveFolder) {
 | 
					 | 
				
			||||||
	let d: IDriveFolder;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(driveFolder)) {
 | 
					 | 
				
			||||||
		d = await DriveFolder.findOne({
 | 
					 | 
				
			||||||
			_id: driveFolder
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof driveFolder === 'string') {
 | 
					 | 
				
			||||||
		d = await DriveFolder.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(driveFolder)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		d = driveFolder as IDriveFolder;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (d == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFolderに格納されているDriveFileがあればすべてルートに移動
 | 
					 | 
				
			||||||
	await DriveFile.update({
 | 
					 | 
				
			||||||
		'metadata.folderId': d._id
 | 
					 | 
				
			||||||
	}, {
 | 
					 | 
				
			||||||
		$set: {
 | 
					 | 
				
			||||||
			'metadata.folderId': null
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFolderに格納されているDriveFolderがあればすべてルートに移動
 | 
					 | 
				
			||||||
	await DriveFolder.update({
 | 
					 | 
				
			||||||
		parentId: d._id
 | 
					 | 
				
			||||||
	}, {
 | 
					 | 
				
			||||||
		$set: {
 | 
					 | 
				
			||||||
			parentId: null
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このDriveFolderを削除
 | 
					 | 
				
			||||||
	await DriveFolder.remove({
 | 
					 | 
				
			||||||
		_id: d._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Pack a drive folder for API response
 | 
					 * Pack a drive folder for API response
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,33 +15,6 @@ export type IFavorite = {
 | 
				
			||||||
	noteId: mongo.ObjectID;
 | 
						noteId: mongo.ObjectID;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Favoriteを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteFavorite(favorite: string | mongo.ObjectID | IFavorite) {
 | 
					 | 
				
			||||||
	let f: IFavorite;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(favorite)) {
 | 
					 | 
				
			||||||
		f = await Favorite.findOne({
 | 
					 | 
				
			||||||
			_id: favorite
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof favorite === 'string') {
 | 
					 | 
				
			||||||
		f = await Favorite.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(favorite)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		f = favorite as IFavorite;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (f == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このFavoriteを削除
 | 
					 | 
				
			||||||
	await Favorite.remove({
 | 
					 | 
				
			||||||
		_id: f._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const packMany = async (
 | 
					export const packMany = async (
 | 
				
			||||||
	favorites: any[],
 | 
						favorites: any[],
 | 
				
			||||||
	me: any
 | 
						me: any
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,33 +28,6 @@ export type IFollowRequest = {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * FollowRequestを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteFollowRequest(followRequest: string | mongo.ObjectID | IFollowRequest) {
 | 
					 | 
				
			||||||
	let f: IFollowRequest;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(followRequest)) {
 | 
					 | 
				
			||||||
		f = await FollowRequest.findOne({
 | 
					 | 
				
			||||||
			_id: followRequest
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof followRequest === 'string') {
 | 
					 | 
				
			||||||
		f = await FollowRequest.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(followRequest)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		f = followRequest as IFollowRequest;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (f == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このFollowingを削除
 | 
					 | 
				
			||||||
	await FollowRequest.remove({
 | 
					 | 
				
			||||||
		_id: f._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Pack a request for API response
 | 
					 * Pack a request for API response
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Following = db.get<IFollowing>('following');
 | 
					const Following = db.get<IFollowing>('following');
 | 
				
			||||||
Following.createIndex(['followerId', 'followeeId'], { unique: true });
 | 
					Following.createIndex(['followerId', 'followeeId'], { unique: true });
 | 
				
			||||||
| 
						 | 
					@ -25,30 +24,3 @@ export type IFollowing = {
 | 
				
			||||||
		sharedInbox?: string;
 | 
							sharedInbox?: string;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Followingを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteFollowing(following: string | mongo.ObjectID | IFollowing) {
 | 
					 | 
				
			||||||
	let f: IFollowing;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(following)) {
 | 
					 | 
				
			||||||
		f = await Following.findOne({
 | 
					 | 
				
			||||||
			_id: following
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof following === 'string') {
 | 
					 | 
				
			||||||
		f = await Following.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(following)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		f = following as IFollowing;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (f == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このFollowingを削除
 | 
					 | 
				
			||||||
	await Following.remove({
 | 
					 | 
				
			||||||
		_id: f._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MessagingHistory = db.get<IMessagingHistory>('messagingHistories');
 | 
					const MessagingHistory = db.get<IMessagingHistory>('messagingHistories');
 | 
				
			||||||
export default MessagingHistory;
 | 
					export default MessagingHistory;
 | 
				
			||||||
| 
						 | 
					@ -12,30 +11,3 @@ export type IMessagingHistory = {
 | 
				
			||||||
	partnerId: mongo.ObjectID;
 | 
						partnerId: mongo.ObjectID;
 | 
				
			||||||
	messageId: mongo.ObjectID;
 | 
						messageId: mongo.ObjectID;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * MessagingHistoryを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteMessagingHistory(messagingHistory: string | mongo.ObjectID | IMessagingHistory) {
 | 
					 | 
				
			||||||
	let m: IMessagingHistory;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(messagingHistory)) {
 | 
					 | 
				
			||||||
		m = await MessagingHistory.findOne({
 | 
					 | 
				
			||||||
			_id: messagingHistory
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof messagingHistory === 'string') {
 | 
					 | 
				
			||||||
		m = await MessagingHistory.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(messagingHistory)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		m = messagingHistory as IMessagingHistory;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (m == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このMessagingHistoryを削除
 | 
					 | 
				
			||||||
	await MessagingHistory.remove({
 | 
					 | 
				
			||||||
		_id: m._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,6 @@ import { pack as packUser } from './user';
 | 
				
			||||||
import { pack as packFile } from './drive-file';
 | 
					import { pack as packFile } from './drive-file';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					import isObjectId from '../misc/is-objectid';
 | 
				
			||||||
import MessagingHistory, { deleteMessagingHistory } from './messaging-history';
 | 
					 | 
				
			||||||
import { length } from 'stringz';
 | 
					import { length } from 'stringz';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MessagingMessage = db.get<IMessagingMessage>('messagingMessages');
 | 
					const MessagingMessage = db.get<IMessagingMessage>('messagingMessages');
 | 
				
			||||||
| 
						 | 
					@ -24,38 +23,6 @@ export function isValidText(text: string): boolean {
 | 
				
			||||||
	return length(text.trim()) <= 1000 && text.trim() != '';
 | 
						return length(text.trim()) <= 1000 && text.trim() != '';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * MessagingMessageを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteMessagingMessage(messagingMessage: string | mongo.ObjectID | IMessagingMessage) {
 | 
					 | 
				
			||||||
	let m: IMessagingMessage;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(messagingMessage)) {
 | 
					 | 
				
			||||||
		m = await MessagingMessage.findOne({
 | 
					 | 
				
			||||||
			_id: messagingMessage
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof messagingMessage === 'string') {
 | 
					 | 
				
			||||||
		m = await MessagingMessage.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(messagingMessage)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		m = messagingMessage as IMessagingMessage;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (m == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このMessagingMessageを指すMessagingHistoryをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await MessagingHistory.find({ messageId: m._id })
 | 
					 | 
				
			||||||
	).map(x => deleteMessagingHistory(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このMessagingMessageを削除
 | 
					 | 
				
			||||||
	await MessagingMessage.remove({
 | 
					 | 
				
			||||||
		_id: m._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Pack a messaging message for API response
 | 
					 * Pack a messaging message for API response
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Mute = db.get<IMute>('mute');
 | 
					const Mute = db.get<IMute>('mute');
 | 
				
			||||||
Mute.createIndex(['muterId', 'muteeId'], { unique: true });
 | 
					Mute.createIndex(['muterId', 'muteeId'], { unique: true });
 | 
				
			||||||
| 
						 | 
					@ -12,30 +11,3 @@ export interface IMute {
 | 
				
			||||||
	muterId: mongo.ObjectID;
 | 
						muterId: mongo.ObjectID;
 | 
				
			||||||
	muteeId: mongo.ObjectID;
 | 
						muteeId: mongo.ObjectID;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Muteを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteMute(mute: string | mongo.ObjectID | IMute) {
 | 
					 | 
				
			||||||
	let m: IMute;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(mute)) {
 | 
					 | 
				
			||||||
		m = await Mute.findOne({
 | 
					 | 
				
			||||||
			_id: mute
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof mute === 'string') {
 | 
					 | 
				
			||||||
		m = await Mute.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(mute)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		m = mute as IMute;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (m == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このMuteを削除
 | 
					 | 
				
			||||||
	await Mute.remove({
 | 
					 | 
				
			||||||
		_id: m._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,33 +33,6 @@ export const validateReaction = $.str.or([
 | 
				
			||||||
	'pudding'
 | 
						'pudding'
 | 
				
			||||||
]);
 | 
					]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * NoteReactionを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteNoteReaction(noteReaction: string | mongo.ObjectID | INoteReaction) {
 | 
					 | 
				
			||||||
	let n: INoteReaction;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(noteReaction)) {
 | 
					 | 
				
			||||||
		n = await NoteReaction.findOne({
 | 
					 | 
				
			||||||
			_id: noteReaction
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof noteReaction === 'string') {
 | 
					 | 
				
			||||||
		n = await NoteReaction.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(noteReaction)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		n = noteReaction as INoteReaction;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (n == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このNoteReactionを削除
 | 
					 | 
				
			||||||
	await NoteReaction.remove({
 | 
					 | 
				
			||||||
		_id: n._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Pack a reaction for API response
 | 
					 * Pack a reaction for API response
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const NoteWatching = db.get<INoteWatching>('noteWatching');
 | 
					const NoteWatching = db.get<INoteWatching>('noteWatching');
 | 
				
			||||||
NoteWatching.createIndex(['userId', 'noteId'], { unique: true });
 | 
					NoteWatching.createIndex(['userId', 'noteId'], { unique: true });
 | 
				
			||||||
| 
						 | 
					@ -12,30 +11,3 @@ export interface INoteWatching {
 | 
				
			||||||
	userId: mongo.ObjectID;
 | 
						userId: mongo.ObjectID;
 | 
				
			||||||
	noteId: mongo.ObjectID;
 | 
						noteId: mongo.ObjectID;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * NoteWatchingを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteNoteWatching(noteWatching: string | mongo.ObjectID | INoteWatching) {
 | 
					 | 
				
			||||||
	let n: INoteWatching;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(noteWatching)) {
 | 
					 | 
				
			||||||
		n = await NoteWatching.findOne({
 | 
					 | 
				
			||||||
			_id: noteWatching
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof noteWatching === 'string') {
 | 
					 | 
				
			||||||
		n = await NoteWatching.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(noteWatching)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		n = noteWatching as INoteWatching;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (n == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このNoteWatchingを削除
 | 
					 | 
				
			||||||
	await NoteWatching.remove({
 | 
					 | 
				
			||||||
		_id: n._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,13 +6,10 @@ import isObjectId from '../misc/is-objectid';
 | 
				
			||||||
import { length } from 'stringz';
 | 
					import { length } from 'stringz';
 | 
				
			||||||
import { IUser, pack as packUser } from './user';
 | 
					import { IUser, pack as packUser } from './user';
 | 
				
			||||||
import { pack as packApp } from './app';
 | 
					import { pack as packApp } from './app';
 | 
				
			||||||
import PollVote, { deletePollVote } from './poll-vote';
 | 
					import PollVote from './poll-vote';
 | 
				
			||||||
import Reaction, { deleteNoteReaction } from './note-reaction';
 | 
					import Reaction from './note-reaction';
 | 
				
			||||||
import { packMany as packFileMany, IDriveFile } from './drive-file';
 | 
					import { packMany as packFileMany, IDriveFile } from './drive-file';
 | 
				
			||||||
import NoteWatching, { deleteNoteWatching } from './note-watching';
 | 
					import Favorite from './favorite';
 | 
				
			||||||
import NoteReaction from './note-reaction';
 | 
					 | 
				
			||||||
import Favorite, { deleteFavorite } from './favorite';
 | 
					 | 
				
			||||||
import Notification, { deleteNotification } from './notification';
 | 
					 | 
				
			||||||
import Following from './following';
 | 
					import Following from './following';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,72 +105,6 @@ export type INote = {
 | 
				
			||||||
	_files?: IDriveFile[];
 | 
						_files?: IDriveFile[];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Noteを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteNote(note: string | mongo.ObjectID | INote) {
 | 
					 | 
				
			||||||
	let n: INote;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(note)) {
 | 
					 | 
				
			||||||
		n = await Note.findOne({
 | 
					 | 
				
			||||||
			_id: note
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof note === 'string') {
 | 
					 | 
				
			||||||
		n = await Note.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(note)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		n = note as INote;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	console.log(n == null ? `Note: delete skipped ${note}` : `Note: deleting ${n._id}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (n == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このNoteへの返信をすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Note.find({ replyId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNote(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このNoteのRenoteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Note.find({ renoteId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNote(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// この投稿に対するNoteWatchingをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await NoteWatching.find({ noteId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNoteWatching(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// この投稿に対するNoteReactionをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await NoteReaction.find({ noteId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNoteReaction(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// この投稿に対するPollVoteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await PollVote.find({ noteId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deletePollVote(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// この投稿に対するFavoriteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Favorite.find({ noteId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deleteFavorite(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// この投稿に対するNotificationをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Notification.find({ noteId: n._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNotification(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このNoteを削除
 | 
					 | 
				
			||||||
	await Note.remove({
 | 
					 | 
				
			||||||
		_id: n._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	console.log(`Note: deleted ${n._id}`);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const hideNote = async (packedNote: any, meId: mongo.ObjectID) => {
 | 
					export const hideNote = async (packedNote: any, meId: mongo.ObjectID) => {
 | 
				
			||||||
	let hide = false;
 | 
						let hide = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,33 +51,6 @@ export interface INotification {
 | 
				
			||||||
	isRead: Boolean;
 | 
						isRead: Boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Notificationを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteNotification(notification: string | mongo.ObjectID | INotification) {
 | 
					 | 
				
			||||||
	let n: INotification;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(notification)) {
 | 
					 | 
				
			||||||
		n = await Notification.findOne({
 | 
					 | 
				
			||||||
			_id: notification
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof notification === 'string') {
 | 
					 | 
				
			||||||
		n = await Notification.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(notification)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		n = notification as INotification;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (n == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このNotificationを削除
 | 
					 | 
				
			||||||
	await Notification.remove({
 | 
					 | 
				
			||||||
		_id: n._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const packMany = async (
 | 
					export const packMany = async (
 | 
				
			||||||
	notifications: any[]
 | 
						notifications: any[]
 | 
				
			||||||
) => {
 | 
					) => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const PollVote = db.get<IPollVote>('pollVotes');
 | 
					const PollVote = db.get<IPollVote>('pollVotes');
 | 
				
			||||||
export default PollVote;
 | 
					export default PollVote;
 | 
				
			||||||
| 
						 | 
					@ -12,30 +11,3 @@ export interface IPollVote {
 | 
				
			||||||
	noteId: mongo.ObjectID;
 | 
						noteId: mongo.ObjectID;
 | 
				
			||||||
	choice: number;
 | 
						choice: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * PollVoteを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deletePollVote(pollVote: string | mongo.ObjectID | IPollVote) {
 | 
					 | 
				
			||||||
	let p: IPollVote;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(pollVote)) {
 | 
					 | 
				
			||||||
		p = await PollVote.findOne({
 | 
					 | 
				
			||||||
			_id: pollVote
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof pollVote === 'string') {
 | 
					 | 
				
			||||||
		p = await PollVote.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(pollVote)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		p = pollVote as IPollVote;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (p == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このPollVoteを削除
 | 
					 | 
				
			||||||
	await PollVote.remove({
 | 
					 | 
				
			||||||
		_id: p._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SwSubscription = db.get<ISwSubscription>('swSubscriptions');
 | 
					const SwSubscription = db.get<ISwSubscription>('swSubscriptions');
 | 
				
			||||||
export default SwSubscription;
 | 
					export default SwSubscription;
 | 
				
			||||||
| 
						 | 
					@ -12,30 +11,3 @@ export interface ISwSubscription {
 | 
				
			||||||
	auth: string;
 | 
						auth: string;
 | 
				
			||||||
	publickey: string;
 | 
						publickey: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * SwSubscriptionを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteSwSubscription(swSubscription: string | mongo.ObjectID | ISwSubscription) {
 | 
					 | 
				
			||||||
	let s: ISwSubscription;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(swSubscription)) {
 | 
					 | 
				
			||||||
		s = await SwSubscription.findOne({
 | 
					 | 
				
			||||||
			_id: swSubscription
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof swSubscription === 'string') {
 | 
					 | 
				
			||||||
		s = await SwSubscription.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(swSubscription)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		s = swSubscription as ISwSubscription;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (s == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このSwSubscriptionを削除
 | 
					 | 
				
			||||||
	await SwSubscription.remove({
 | 
					 | 
				
			||||||
		_id: s._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,33 +14,6 @@ export interface IUserList {
 | 
				
			||||||
	userIds: mongo.ObjectID[];
 | 
						userIds: mongo.ObjectID[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * UserListを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteUserList(userList: string | mongo.ObjectID | IUserList) {
 | 
					 | 
				
			||||||
	let u: IUserList;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(userList)) {
 | 
					 | 
				
			||||||
		u = await UserList.findOne({
 | 
					 | 
				
			||||||
			_id: userList
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof userList === 'string') {
 | 
					 | 
				
			||||||
		u = await UserList.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(userList)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		u = userList as IUserList;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (u == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このUserListを削除
 | 
					 | 
				
			||||||
	await UserList.remove({
 | 
					 | 
				
			||||||
		_id: u._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const pack = (
 | 
					export const pack = (
 | 
				
			||||||
	userList: string | mongo.ObjectID | IUserList
 | 
						userList: string | mongo.ObjectID | IUserList
 | 
				
			||||||
) => new Promise<any>(async (resolve, reject) => {
 | 
					) => new Promise<any>(async (resolve, reject) => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,28 +1,15 @@
 | 
				
			||||||
import * as mongo from 'mongodb';
 | 
					import * as mongo from 'mongodb';
 | 
				
			||||||
const deepcopy = require('deepcopy');
 | 
					const deepcopy = require('deepcopy');
 | 
				
			||||||
const sequential = require('promise-sequential');
 | 
					 | 
				
			||||||
import rap from '@prezzemolo/rap';
 | 
					import rap from '@prezzemolo/rap';
 | 
				
			||||||
import db from '../db/mongodb';
 | 
					import db from '../db/mongodb';
 | 
				
			||||||
import isObjectId from '../misc/is-objectid';
 | 
					import isObjectId from '../misc/is-objectid';
 | 
				
			||||||
import Note, { packMany as packNoteMany, deleteNote } from './note';
 | 
					import { packMany as packNoteMany } from './note';
 | 
				
			||||||
import Following, { deleteFollowing } from './following';
 | 
					import Following from './following';
 | 
				
			||||||
import Blocking, { deleteBlocking } from './blocking';
 | 
					import Blocking from './blocking';
 | 
				
			||||||
import Mute, { deleteMute } from './mute';
 | 
					import Mute from './mute';
 | 
				
			||||||
import { getFriendIds } from '../server/api/common/get-friends';
 | 
					import { getFriendIds } from '../server/api/common/get-friends';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
import AccessToken, { deleteAccessToken } from './access-token';
 | 
					import FollowRequest from './follow-request';
 | 
				
			||||||
import NoteWatching, { deleteNoteWatching } from './note-watching';
 | 
					 | 
				
			||||||
import Favorite, { deleteFavorite } from './favorite';
 | 
					 | 
				
			||||||
import NoteReaction, { deleteNoteReaction } from './note-reaction';
 | 
					 | 
				
			||||||
import MessagingMessage, { deleteMessagingMessage } from './messaging-message';
 | 
					 | 
				
			||||||
import MessagingHistory, { deleteMessagingHistory } from './messaging-history';
 | 
					 | 
				
			||||||
import DriveFile, { deleteDriveFile } from './drive-file';
 | 
					 | 
				
			||||||
import DriveFolder, { deleteDriveFolder } from './drive-folder';
 | 
					 | 
				
			||||||
import PollVote, { deletePollVote } from './poll-vote';
 | 
					 | 
				
			||||||
import SwSubscription, { deleteSwSubscription } from './sw-subscription';
 | 
					 | 
				
			||||||
import Notification, { deleteNotification } from './notification';
 | 
					 | 
				
			||||||
import UserList, { deleteUserList } from './user-list';
 | 
					 | 
				
			||||||
import FollowRequest, { deleteFollowRequest } from './follow-request';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const User = db.get<IUser>('users');
 | 
					const User = db.get<IUser>('users');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,161 +155,6 @@ export function isValidBirthday(birthday: string): boolean {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//#endregion
 | 
					//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Userを物理削除します
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
export async function deleteUser(user: string | mongo.ObjectID | IUser) {
 | 
					 | 
				
			||||||
	let u: IUser;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Populate
 | 
					 | 
				
			||||||
	if (isObjectId(user)) {
 | 
					 | 
				
			||||||
		u = await User.findOne({
 | 
					 | 
				
			||||||
			_id: user
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else if (typeof user === 'string') {
 | 
					 | 
				
			||||||
		u = await User.findOne({
 | 
					 | 
				
			||||||
			_id: new mongo.ObjectID(user)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		u = user as IUser;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	console.log(u == null ? `User: delete skipped ${user}` : `User: deleting ${u._id}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (u == null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのAccessTokenをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await AccessToken.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteAccessToken(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのNoteをすべて削除
 | 
					 | 
				
			||||||
	await sequential((
 | 
					 | 
				
			||||||
		await Note.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => () => deleteNote(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのNoteReactionをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await NoteReaction.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNoteReaction(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのNoteWatchingをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await NoteWatching.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNoteWatching(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのPollVoteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await PollVote.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deletePollVote(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのFavoriteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Favorite.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteFavorite(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのMessageをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await MessagingMessage.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteMessagingMessage(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーへのMessageをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await MessagingMessage.find({ recipientId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteMessagingMessage(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーの関わるMessagingHistoryをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await MessagingHistory.find({ $or: [{ partnerId: u._id }, { userId: u._id }] })
 | 
					 | 
				
			||||||
	).map(x => deleteMessagingHistory(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのDriveFileをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await DriveFile.find({ 'metadata.userId': u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteDriveFile(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのDriveFolderをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await DriveFolder.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteDriveFolder(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのMuteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Mute.find({ muterId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteMute(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーへのMuteをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Mute.find({ muteeId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteMute(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのFollowingをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Following.find({ followerId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteFollowing(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーへのFollowingをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Following.find({ followeeId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteFollowing(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのFollowRequestをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await FollowRequest.find({ followerId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteFollowRequest(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーへのFollowRequestをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await FollowRequest.find({ followeeId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteFollowRequest(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのBlockingをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Blocking.find({ blockerId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteBlocking(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーへのBlockingをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Blocking.find({ blockeeId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteBlocking(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのSwSubscriptionをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await SwSubscription.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteSwSubscription(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのNotificationをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Notification.find({ notifieeId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNotification(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーが原因となったNotificationをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await Notification.find({ notifierId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteNotification(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーのUserListをすべて削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await UserList.find({ userId: u._id })
 | 
					 | 
				
			||||||
	).map(x => deleteUserList(x)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーが入っているすべてのUserListからこのユーザーを削除
 | 
					 | 
				
			||||||
	await Promise.all((
 | 
					 | 
				
			||||||
		await UserList.find({ userIds: u._id })
 | 
					 | 
				
			||||||
	).map(x =>
 | 
					 | 
				
			||||||
		UserList.update({ _id: x._id }, {
 | 
					 | 
				
			||||||
			$pull: { userIds: u._id }
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// このユーザーを削除
 | 
					 | 
				
			||||||
	await User.remove({
 | 
					 | 
				
			||||||
		_id: u._id
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	console.log(`User: deleted ${u._id}`);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Pack a user for API response
 | 
					 * Pack a user for API response
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import $ from 'cafy';
 | 
					import $ from 'cafy';
 | 
				
			||||||
import ID from '../../../../../misc/cafy-id';
 | 
					import ID from '../../../../../misc/cafy-id';
 | 
				
			||||||
import UserList, { deleteUserList } from '../../../../../models/user-list';
 | 
					import UserList from '../../../../../models/user-list';
 | 
				
			||||||
import { ILocalUser } from '../../../../../models/user';
 | 
					import { ILocalUser } from '../../../../../models/user';
 | 
				
			||||||
import getParams from '../../../get-params';
 | 
					import getParams from '../../../get-params';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,9 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 | 
				
			||||||
		return rej('list not found');
 | 
							return rej('list not found');
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	deleteUserList(userList);
 | 
						await UserList.remove({
 | 
				
			||||||
 | 
							_id: userList._id
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	res();
 | 
						res();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue