diff options
26 files changed, 210 insertions, 529 deletions
@@ -7,7 +7,7 @@ Misskey [![][dependencies-badge]][dependencies-link] [![][himawari-badge]][himasaku] [![][sakurako-badge]][himasaku] -[![][agpl-3.0-badge]][AGPL-3.0] +[](http://makeapullrequest.com) > Lead Maintainer: [syuilo][syuilo-link] @@ -50,6 +50,8 @@ If you want to donate to Misskey, please see [this](./docs/donate.ja.md). Misskey is an open-source software licensed under [GNU AGPLv3](LICENSE). +[![][agpl-3.0-badge]][AGPL-3.0] + [agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html [agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square [travis-link]: https://travis-ci.org/syuilo/misskey diff --git a/src/common/remote/activitypub/renderer/context.ts b/src/common/remote/activitypub/renderer/context.ts new file mode 100644 index 0000000000..b56f727ae7 --- /dev/null +++ b/src/common/remote/activitypub/renderer/context.ts @@ -0,0 +1,5 @@ +export default [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { Hashtag: 'as:Hashtag' } +]; diff --git a/src/common/remote/activitypub/renderer/document.ts b/src/common/remote/activitypub/renderer/document.ts new file mode 100644 index 0000000000..4a456416a9 --- /dev/null +++ b/src/common/remote/activitypub/renderer/document.ts @@ -0,0 +1,7 @@ +import config from '../../../../conf'; + +export default ({ _id, contentType }) => ({ + type: 'Document', + mediaType: contentType, + url: `${config.drive_url}/${_id}` +}); diff --git a/src/common/remote/activitypub/renderer/hashtag.ts b/src/common/remote/activitypub/renderer/hashtag.ts new file mode 100644 index 0000000000..ad42700204 --- /dev/null +++ b/src/common/remote/activitypub/renderer/hashtag.ts @@ -0,0 +1,7 @@ +import config from '../../../../conf'; + +export default tag => ({ + type: 'Hashtag', + href: `${config.url}/search?q=#${encodeURIComponent(tag)}`, + name: '#' + tag +}); diff --git a/src/common/remote/activitypub/renderer/image.ts b/src/common/remote/activitypub/renderer/image.ts new file mode 100644 index 0000000000..345fbbec59 --- /dev/null +++ b/src/common/remote/activitypub/renderer/image.ts @@ -0,0 +1,6 @@ +import config from '../../../../conf'; + +export default ({ _id }) => ({ + type: 'Image', + url: `${config.drive_url}/${_id}` +}); diff --git a/src/common/remote/activitypub/renderer/key.ts b/src/common/remote/activitypub/renderer/key.ts new file mode 100644 index 0000000000..7148c59745 --- /dev/null +++ b/src/common/remote/activitypub/renderer/key.ts @@ -0,0 +1,9 @@ +import config from '../../../../conf'; +import { extractPublic } from '../../../../crypto_key'; +import { ILocalAccount } from '../../../../models/user'; + +export default ({ username, account }) => ({ + type: 'Key', + owner: `${config.url}/@${username}`, + publicKeyPem: extractPublic((account as ILocalAccount).keypair) +}); diff --git a/src/common/remote/activitypub/renderer/note.ts b/src/common/remote/activitypub/renderer/note.ts new file mode 100644 index 0000000000..2fe20b2136 --- /dev/null +++ b/src/common/remote/activitypub/renderer/note.ts @@ -0,0 +1,44 @@ +import renderDocument from './document'; +import renderHashtag from './hashtag'; +import config from '../../../../conf'; +import DriveFile from '../../../../models/drive-file'; +import Post from '../../../../models/post'; +import User from '../../../../models/user'; + +export default async (user, post) => { + const promisedFiles = DriveFile.find({ _id: { $in: post.mediaIds } }); + let inReplyTo; + + if (post.replyId) { + const inReplyToPost = await Post.findOne({ + _id: post.replyId, + }); + + if (inReplyToPost !== null) { + const inReplyToUser = await User.findOne({ + _id: post.userId, + }); + + if (inReplyToUser !== null) { + inReplyTo = `${config.url}@${inReplyToUser.username}/${inReplyToPost._id}`; + } + } + } else { + inReplyTo = null; + } + + const attributedTo = `${config.url}/@${user.username}`; + + return { + id: `${attributedTo}/${post._id}`, + type: 'Note', + attributedTo, + content: post.textHtml, + published: post.createdAt.toISOString(), + to: 'https://www.w3.org/ns/activitystreams#Public', + cc: `${attributedTo}/followers`, + inReplyTo, + attachment: (await promisedFiles).map(renderDocument), + tag: post.tags.map(renderHashtag) + }; +}; diff --git a/src/common/remote/activitypub/renderer/ordered-collection.ts b/src/common/remote/activitypub/renderer/ordered-collection.ts new file mode 100644 index 0000000000..2ca0f77354 --- /dev/null +++ b/src/common/remote/activitypub/renderer/ordered-collection.ts @@ -0,0 +1,6 @@ +export default (id, totalItems, orderedItems) => ({ + id, + type: 'OrderedCollection', + totalItems, + orderedItems +}); diff --git a/src/common/remote/activitypub/renderer/person.ts b/src/common/remote/activitypub/renderer/person.ts new file mode 100644 index 0000000000..7303b30385 --- /dev/null +++ b/src/common/remote/activitypub/renderer/person.ts @@ -0,0 +1,20 @@ +import renderImage from './image'; +import renderKey from './key'; +import config from '../../../../conf'; + +export default user => { + const id = `${config.url}/@${user.username}`; + + return { + type: 'Person', + id, + inbox: `${id}/inbox`, + outbox: `${id}/outbox`, + preferredUsername: user.username, + name: user.name, + summary: user.description, + icon: user.avatarId && renderImage({ _id: user.avatarId }), + image: user.bannerId && renderImage({ _id: user.bannerId }), + publicKey: renderKey(user) + }; +}; diff --git a/src/models/post.ts b/src/models/post.ts index 6c853e4f81..4daad306d6 100644 --- a/src/models/post.ts +++ b/src/models/post.ts @@ -30,6 +30,7 @@ export type IPost = { repostId: mongo.ObjectID; poll: any; // todo text: string; + tags: string[]; textHtml: string; cw: string; userId: mongo.ObjectID; diff --git a/src/server/activitypub/inbox.ts b/src/server/activitypub/inbox.ts index b4761d9972..9151297487 100644 --- a/src/server/activitypub/inbox.ts +++ b/src/server/activitypub/inbox.ts @@ -36,7 +36,7 @@ app.post('/@:user/inbox', async (req, res) => { outbox: req.body, }).save(); - return res.sendStatus(200); + return res.status(202).end(); }); export default app; diff --git a/src/server/activitypub/index.ts b/src/server/activitypub/index.ts index 07ff407a76..c81024d15f 100644 --- a/src/server/activitypub/index.ts +++ b/src/server/activitypub/index.ts @@ -2,11 +2,15 @@ import * as express from 'express'; import user from './user'; import inbox from './inbox'; +import outbox from './outbox'; +import post from './post'; const app = express(); app.disable('x-powered-by'); app.use(user); app.use(inbox); +app.use(outbox); +app.use(post); export default app; diff --git a/src/server/activitypub/outbox.ts b/src/server/activitypub/outbox.ts new file mode 100644 index 0000000000..c5a42ae0a9 --- /dev/null +++ b/src/server/activitypub/outbox.ts @@ -0,0 +1,45 @@ +import * as express from 'express'; +import context from '../../common/remote/activitypub/renderer/context'; +import renderNote from '../../common/remote/activitypub/renderer/note'; +import renderOrderedCollection from '../../common/remote/activitypub/renderer/ordered-collection'; +import parseAcct from '../../common/user/parse-acct'; +import config from '../../conf'; +import Post from '../../models/post'; +import User from '../../models/user'; + +const app = express(); +app.disable('x-powered-by'); + +app.get('/@:user/outbox', async (req, res) => { + const { username, host } = parseAcct(req.params.user); + if (host !== null) { + return res.sendStatus(422); + } + + const user = await User.findOne({ + usernameLower: username.toLowerCase(), + host: null + }); + if (user === null) { + return res.sendStatus(404); + } + + const id = `${config.url}/@${user.username}/inbox`; + + if (username !== user.username) { + return res.redirect(id); + } + + const posts = await Post.find({ userId: user._id }, { + limit: 20, + sort: { _id: -1 } + }); + + const renderedPosts = await Promise.all(posts.map(post => renderNote(user, post))); + const rendered = renderOrderedCollection(id, user.postsCount, renderedPosts); + rendered['@context'] = context; + + res.json(rendered); +}); + +export default app; diff --git a/src/server/activitypub/post.ts b/src/server/activitypub/post.ts new file mode 100644 index 0000000000..6644563d8c --- /dev/null +++ b/src/server/activitypub/post.ts @@ -0,0 +1,44 @@ +import * as express from 'express'; +import context from '../../common/remote/activitypub/renderer/context'; +import render from '../../common/remote/activitypub/renderer/note'; +import parseAcct from '../../common/user/parse-acct'; +import Post from '../../models/post'; +import User from '../../models/user'; + +const app = express(); +app.disable('x-powered-by'); + +app.get('/@:user/:post', async (req, res, next) => { + const accepted = req.accepts(['html', 'application/activity+json', 'application/ld+json']); + if (!(['application/activity+json', 'application/ld+json'] as any[]).includes(accepted)) { + return next(); + } + + const { username, host } = parseAcct(req.params.user); + if (host !== null) { + return res.sendStatus(422); + } + + const user = await User.findOne({ + usernameLower: username.toLowerCase(), + host: null + }); + if (user === null) { + return res.sendStatus(404); + } + + const post = await Post.findOne({ + _id: req.params.post, + userId: user._id + }); + if (post === null) { + return res.sendStatus(404); + } + + const rendered = await render(user, post); + rendered['@context'] = context; + + res.json(rendered); +}); + +export default app; diff --git a/src/server/activitypub/user.ts b/src/server/activitypub/user.ts index 488de93a92..d43a9793d4 100644 --- a/src/server/activitypub/user.ts +++ b/src/server/activitypub/user.ts @@ -1,8 +1,9 @@ import * as express from 'express'; import config from '../../conf'; -import { extractPublic } from '../../crypto_key'; +import context from '../../common/remote/activitypub/renderer/context'; +import render from '../../common/remote/activitypub/renderer/person'; import parseAcct from '../../common/user/parse-acct'; -import User, { ILocalAccount } from '../../models/user'; +import User from '../../models/user'; const app = express(); app.disable('x-powered-by'); @@ -26,37 +27,14 @@ app.get('/@:user', async (req, res, next) => { return res.sendStatus(404); } - const id = `${config.url}/@${user.username}`; - if (username !== user.username) { - return res.redirect(id); + return res.redirect(`${config.url}/@${user.username}`); } - res.json({ - '@context': [ - 'https://www.w3.org/ns/activitystreams', - 'https://w3id.org/security/v1' - ], - type: 'Person', - id, - inbox: `${id}/inbox`, - preferredUsername: user.username, - name: user.name, - summary: user.description, - icon: user.avatarId && { - type: 'Image', - url: `${config.drive_url}/${user.avatarId}` - }, - image: user.bannerId && { - type: 'Image', - url: `${config.drive_url}/${user.bannerId}` - }, - publicKey: { - type: 'Key', - owner: id, - publicKeyPem: extractPublic((user.account as ILocalAccount).keypair) - } - }); + const rendered = render(user); + rendered['@context'] = context; + + res.json(rendered); }); export default app; diff --git a/tools/letsencrypt/get-cert.sh b/tools/letsencrypt/get-cert.sh deleted file mode 100644 index d44deb1443..0000000000 --- a/tools/letsencrypt/get-cert.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -certbot certonly --standalone\ - -d $1\ - -d api.$1\ - -d auth.$1\ - -d docs.$1\ - -d ch.$1\ - -d stats.$1\ - -d status.$1\ - -d dev.$1\ - -d file.$2\ diff --git a/tools/migration/node.1509958623.use-gridfs.js b/tools/migration/node.1509958623.use-gridfs.js deleted file mode 100644 index a9d2b12e95..0000000000 --- a/tools/migration/node.1509958623.use-gridfs.js +++ /dev/null @@ -1,71 +0,0 @@ -// for Node.js interpret - -const { default: db } = require('../../built/db/mongodb') -const { default: DriveFile, getGridFSBucket } = require('../../built/api/models/drive-file') -const { Duplex } = require('stream') -const { default: zip } = require('@prezzemolo/zip') - -const writeToGridFS = (bucket, buffer, ...rest) => new Promise((resolve, reject) => { - const writeStream = bucket.openUploadStreamWithId(...rest) - - const dataStream = new Duplex() - dataStream.push(buffer) - dataStream.push(null) - - writeStream.once('finish', resolve) - writeStream.on('error', reject) - - dataStream.pipe(writeStream) -}) - -const migrateToGridFS = async (doc) => { - const id = doc._id - const buffer = doc.data ? doc.data.buffer : Buffer.from([0x00]) // アップロードのバグなのか知らないけどなぜか data が存在しない drive_file ドキュメントがまれにあることがわかったので - const created_at = doc.created_at - const name = doc.name - const type = doc.type - - delete doc._id - delete doc.created_at - delete doc.datasize - delete doc.hash - delete doc.data - delete doc.name - delete doc.type - - const bucket = await getGridFSBucket() - const added = await writeToGridFS(bucket, buffer, id, name, { contentType: type, metadata: doc }) - - const result = await DriveFile.update(id, { - $set: { - uploadDate: created_at - } - }) - - return added && result.ok === 1 -} - -async function main() { - const count = await db.get('drive_files').count({}); - - console.log(`there are ${count} files.`) - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const doc = await db.get('drive_files').find({}, { limit: dop, skip: time * dop }) - return Promise.all(doc.map(migrateToGridFS)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/node.1510016282.change-gridfs-metadata-name-to-filename.js b/tools/migration/node.1510016282.change-gridfs-metadata-name-to-filename.js deleted file mode 100644 index d7b2a6eff4..0000000000 --- a/tools/migration/node.1510016282.change-gridfs-metadata-name-to-filename.js +++ /dev/null @@ -1,50 +0,0 @@ -// for Node.js interpret -/** - * change usage of GridFS filename - * see commit fb422b4d603c53a70712caba55b35a48a8c2e619 - */ - -const { default: DriveFile } = require('../../built/api/models/drive-file') - -async function applyNewChange (doc) { - const result = await DriveFile.update(doc._id, { - $set: { - filename: doc.metadata.name - }, - $unset: { - 'metadata.name': '' - } - }) - return result.ok === 1 -} - -async function main () { - const query = { - 'metadata.name': { - $exists: true - } - } - - const count = await DriveFile.count(query) - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const doc = await DriveFile.find(query, { - limit: dop, skip: time * dop - }) - return Promise.all(doc.map(applyNewChange)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/node.1510056272.issue_882.js b/tools/migration/node.1510056272.issue_882.js deleted file mode 100644 index 302ef3de65..0000000000 --- a/tools/migration/node.1510056272.issue_882.js +++ /dev/null @@ -1,47 +0,0 @@ -// for Node.js interpret - -const { default: DriveFile } = require('../../built/api/models/drive-file') -const { default: zip } = require('@prezzemolo/zip') - -const migrate = async (doc) => { - const result = await DriveFile.update(doc._id, { - $set: { - contentType: doc.metadata.type - }, - $unset: { - 'metadata.type': '' - } - }) - return result.ok === 1 -} - -async function main() { - const query = { - 'metadata.type': { - $exists: true - } - } - - const count = await DriveFile.count(query); - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const doc = await DriveFile.find(query, { - limit: dop, skip: time * dop - }) - return Promise.all(doc.map(migrate)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/node.2017-11-08.js b/tools/migration/node.2017-11-08.js deleted file mode 100644 index 196a5a90c8..0000000000 --- a/tools/migration/node.2017-11-08.js +++ /dev/null @@ -1,88 +0,0 @@ -const uuid = require('uuid'); -const { default: User } = require('../../built/api/models/user') -const { default: zip } = require('@prezzemolo/zip') - -const home = { - left: [ - 'profile', - 'calendar', - 'activity', - 'rss-reader', - 'trends', - 'photo-stream', - 'version' - ], - right: [ - 'broadcast', - 'notifications', - 'user-recommendation', - 'recommended-polls', - 'server', - 'donation', - 'nav', - 'tips' - ] -}; - -const migrate = async (doc) => { - - //#region Construct home data - const homeData = []; - - home.left.forEach(widget => { - homeData.push({ - name: widget, - id: uuid(), - place: 'left', - data: {} - }); - }); - - home.right.forEach(widget => { - homeData.push({ - name: widget, - id: uuid(), - place: 'right', - data: {} - }); - }); - //#endregion - - const result = await User.update(doc._id, { - $unset: { - data: '' - }, - $set: { - 'settings': {}, - 'client_settings.home': homeData, - 'client_settings.show_donation': false - } - }) - - return result.ok === 1 -} - -async function main() { - const count = await User.count(); - - console.log(`there are ${count} users.`) - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const docs = await User.find({}, { limit: dop, skip: time * dop }) - return Promise.all(docs.map(migrate)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/node.2017-12-11.js b/tools/migration/node.2017-12-11.js deleted file mode 100644 index b9686b8b4d..0000000000 --- a/tools/migration/node.2017-12-11.js +++ /dev/null @@ -1,71 +0,0 @@ -// for Node.js interpret - -const { default: DriveFile, getGridFSBucket } = require('../../built/api/models/drive-file') -const { default: zip } = require('@prezzemolo/zip') - -const _gm = require('gm'); -const gm = _gm.subClass({ - imageMagick: true -}); - -const migrate = doc => new Promise(async (res, rej) => { - const bucket = await getGridFSBucket(); - - const readable = bucket.openDownloadStream(doc._id); - - gm(readable) - .setFormat('ppm') - .resize(1, 1) - .toBuffer(async (err, buffer) => { - if (err) { - console.error(err); - res(false); - return; - } - const r = buffer.readUInt8(buffer.length - 3); - const g = buffer.readUInt8(buffer.length - 2); - const b = buffer.readUInt8(buffer.length - 1); - - const result = await DriveFile.update(doc._id, { - $set: { - 'metadata.properties.average_color': [r, g, b] - } - }) - - res(result.ok === 1); - }); -}); - -async function main() { - const query = { - contentType: { - $in: [ - 'image/png', - 'image/jpeg' - ] - } - } - - const count = await DriveFile.count(query); - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const doc = await DriveFile.find(query, { - limit: dop, skip: time * dop - }) - return Promise.all(doc.map(migrate)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/node.2017-12-22.hiseikika.js b/tools/migration/node.2017-12-22.hiseikika.js deleted file mode 100644 index ff8294c8d1..0000000000 --- a/tools/migration/node.2017-12-22.hiseikika.js +++ /dev/null @@ -1,67 +0,0 @@ -// for Node.js interpret - -const { default: Post } = require('../../built/api/models/post') -const { default: zip } = require('@prezzemolo/zip') - -const migrate = async (post) => { - const x = {}; - if (post.reply_id != null) { - const reply = await Post.findOne({ - _id: post.reply_id - }); - x['_reply.user_id'] = reply.user_id; - } - if (post.repost_id != null) { - const repost = await Post.findOne({ - _id: post.repost_id - }); - x['_repost.user_id'] = repost.user_id; - } - if (post.reply_id != null || post.repost_id != null) { - const result = await Post.update(post._id, { - $set: x, - }); - return result.ok === 1; - } else { - return true; - } -} - -async function main() { - const query = { - $or: [{ - reply_id: { - $exists: true, - $ne: null - } - }, { - repost_id: { - $exists: true, - $ne: null - } - }] - } - - const count = await Post.count(query); - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const doc = await Post.find(query, { - limit: dop, skip: time * dop - }) - return Promise.all(doc.map(migrate)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/node.2018-03-13.othello.js b/tools/migration/node.2018-03-13.othello.js deleted file mode 100644 index 4598f8d832..0000000000 --- a/tools/migration/node.2018-03-13.othello.js +++ /dev/null @@ -1,46 +0,0 @@ -// for Node.js interpret - -const { default: Othello } = require('../../built/api/models/othello-game') -const { default: zip } = require('@prezzemolo/zip') - -const migrate = async (doc) => { - const x = {}; - - doc.logs.forEach(log => { - log.color = log.color == 'black'; - }); - - const result = await Othello.update(doc._id, { - $set: { - logs: doc.logs - } - }); - - return result.ok === 1; -} - -async function main() { - - const count = await Othello.count({}); - - const dop = Number.parseInt(process.argv[2]) || 5 - const idop = ((count - (count % dop)) / dop) + 1 - - return zip( - 1, - async (time) => { - console.log(`${time} / ${idop}`) - const doc = await Othello.find({}, { - limit: dop, skip: time * dop - }) - return Promise.all(doc.map(migrate)) - }, - idop - ).then(a => { - const rv = [] - a.forEach(e => rv.push(...e)) - return rv - }) -} - -main().then(console.dir).catch(console.error) diff --git a/tools/migration/shell.1487734995.user-profile.js b/tools/migration/shell.1487734995.user-profile.js deleted file mode 100644 index e6666319e1..0000000000 --- a/tools/migration/shell.1487734995.user-profile.js +++ /dev/null @@ -1,18 +0,0 @@ -db.users.find({}).forEach(function(user) { - print(user._id); - db.users.update({ _id: user._id }, { - $rename: { - bio: 'description' - }, - $unset: { - location: '', - birthday: '' - }, - $set: { - profile: { - location: user.location || null, - birthday: user.birthday || null - } - } - }, false, false); -}); diff --git a/tools/migration/shell.1489951459.like-to-reactions.js b/tools/migration/shell.1489951459.like-to-reactions.js deleted file mode 100644 index 962a0f00ef..0000000000 --- a/tools/migration/shell.1489951459.like-to-reactions.js +++ /dev/null @@ -1,22 +0,0 @@ -db.users.update({}, { - $unset: { - likes_count: 1, - liked_count: 1 - } -}, false, true) - -db.likes.renameCollection('post_reactions') - -db.post_reactions.update({}, { - $set: { - reaction: 'like' - } -}, false, true) - -db.posts.update({}, { - $rename: { - likes_count: 'reaction_counts.like' - } -}, false, true); - -db.notifications.remove({}) diff --git a/tools/migration/shell.1509507382.reply_to-to-reply.js b/tools/migration/shell.1509507382.reply_to-to-reply.js deleted file mode 100644 index ceb272ebc9..0000000000 --- a/tools/migration/shell.1509507382.reply_to-to-reply.js +++ /dev/null @@ -1,5 +0,0 @@ -db.posts.update({}, { - $rename: { - reply_to_id: 'reply_id' - } -}, false, true); |