Merge pull request #4303 from overleaf/sk-tag-saas-migrations

Migrations: tag migrations with relevant environment
GitOrigin-RevId: ad6c3bea19d3c21a1fdae58e09c861a3173c792b
This commit is contained in:
Shane Kilkelly 2021-07-21 11:34:09 +01:00 committed by Copybot
parent f7a4a57487
commit 4b9aa97ea1
56 changed files with 2139 additions and 12 deletions

View file

@ -1,10 +0,0 @@
#!/bin/sh
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
if [ -f /.dockerenv ]; then
# I'm running inside docker
npm run migrations -- "$@"
else
${SCRIPTPATH}/run web bin/east "$@"
fi

View file

@ -0,0 +1,25 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.migrations, [
{
key: { name: 1 },
unique: true,
},
])
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.migrations, [{ name: 1 }])
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,22 @@
/* eslint-disable no-unused-vars */
/*
* Example migration for a script:
*
* This migration demonstrates how to run a script. In this case, the example
* script will print "hello world" if there are no users in the users collection
* or "hello <name>", when User.findOne() finds something.
*/
const runScript = require('../scripts/example/script_for_migration.js')
exports.tags = []
exports.migrate = async client => {
const { db } = client
await runScript()
}
exports.rollback = async client => {
const { db } = client
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
unique: true,
key: {
user_id: 1,
},
name: 'user_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.contacts, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.contacts, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,36 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
'deleterData.deletedAt': 1,
},
name: 'deleterData.deletedAt_1',
},
{
key: {
'deleterData.deletedProjectId': 1,
},
name: 'deleterData.deletedProjectId_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.deletedProjects, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.deletedProjects, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,37 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
unique: true,
key: {
'subscription._id': 1,
},
name: 'subscription._id_1',
},
{
key: {
'subscription.admin_id': 1,
},
name: 'subscription.admin_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.deletedSubscriptions, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.deletedSubscriptions, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.docHistoryIndex, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.docHistoryIndex, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,58 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
doc_id: 1,
v: 1,
},
name: 'doc_id_1_v_1',
},
{
key: {
project_id: 1,
'meta.end_ts': 1,
},
name: 'project_id_1_meta.end_ts_1',
},
{
key: {
doc_id: 1,
project_id: 1,
},
name: 'doc_id_1_project_id_1',
},
{
key: {
expiresAt: 1,
},
name: 'expiresAt_1',
expireAfterSeconds: 0,
},
{
key: {
last_checked: 1,
},
name: 'last_checked_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.docHistory, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.docHistory, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
unique: true,
key: {
doc_id: 1,
},
name: 'doc_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.docOps, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.docOps, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,37 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
{
key: {
ts: 1,
},
name: 'ts_1',
expireAfterSeconds: 2592000,
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.docSnapshots, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.docSnapshots, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.docs, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.docs, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,41 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
pid: 1,
eid: 1,
},
name: 'pid_1_eid_1',
},
{
key: {
c: 1,
},
name: 'c_1',
expireAfterSeconds: 2592000,
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.githubSyncEntityVersions, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(
db.githubSyncEntityVersions,
indexes
)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,36 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
{
key: {
owner_id: 1,
},
name: 'owner_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.githubSyncProjectStates, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.githubSyncProjectStates, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,33 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
user_id: 1,
},
name: 'user_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.githubSyncUserCredentials, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(
db.githubSyncUserCredentials,
indexes
)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
unique: true,
key: {
v1Id: 1,
},
name: 'v1Id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.institutions, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.institutions, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
room_id: 1,
timestamp: -1,
},
name: 'room_id_1_timestamp_-1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.messages, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.messages, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,43 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
expires: 1,
},
name: 'expires_1',
expireAfterSeconds: 10,
},
{
key: {
key: 1,
},
name: 'key_1',
},
{
key: {
user_id: 1,
},
name: 'user_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.notifications, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.notifications, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,38 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
unique: true,
key: {
accessToken: 1,
},
name: 'accessToken_1',
},
{
unique: true,
key: {
refreshToken: 1,
},
name: 'refreshToken_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.oauthAccessTokens, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.oauthAccessTokens, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
unique: true,
key: {
id: 1,
},
name: 'id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.oauthApplications, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.oauthApplications, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
unique: true,
key: {
authorizationCode: 1,
},
name: 'authorizationCode_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.oauthAuthorizationCodes, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.oauthAuthorizationCodes, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projectHistoryFailures, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projectHistoryFailures, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,36 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
{
key: {
user_id: 1,
},
name: 'user_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projectHistoryLabels, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projectHistoryLabels, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projectHistoryMetaData, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projectHistoryMetaData, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,37 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id_1',
},
{
key: {
expiresAt: 1,
},
name: 'expiresAt_1',
expireAfterSeconds: 0,
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projectHistorySyncState, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projectHistorySyncState, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
v1_project_id: 1,
},
name: 'v1_project_id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projectImportFailures, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projectImportFailures, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,37 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
expires: 1,
},
name: 'expires_1',
expireAfterSeconds: 10,
},
{
key: {
projectId: 1,
},
name: 'projectId_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projectInvites, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projectInvites, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,140 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
active: 1,
lastOpened: 1,
},
name: 'active_1_lastOpened_1',
},
{
unique: true,
key: {
'tokens.readOnly': 1,
},
name: 'tokens.readOnly_1',
partialFilterExpression: {
'tokens.readOnly': {
$exists: true,
},
},
},
{
unique: true,
key: {
'overleaf.history.id': 1,
},
name: 'overleaf.history.id_1',
partialFilterExpression: {
'overleaf.history.id': {
$exists: true,
},
},
},
{
unique: true,
key: {
'tokens.readAndWritePrefix': 1,
},
name: 'tokens.readAndWritePrefix_1',
partialFilterExpression: {
'tokens.readAndWritePrefix': {
$exists: true,
},
},
},
{
key: {
publicAccesLevel: 1,
},
name: 'publicAccesLevel_1',
},
{
key: {
owner_ref: 1,
},
name: 'owner_ref_1',
},
{
key: {
tokenAccessReadAndWrite_refs: 1,
},
name: 'tokenAccessReadAndWrite_refs_1',
},
{
key: {
readOnly_refs: 1,
},
name: 'readOnly_refs_1',
},
{
key: {
tokenAccessReadOnly_refs: 1,
},
name: 'tokenAccessReadOnly_refs_1',
},
{
unique: true,
key: {
'overleaf.id': 1,
},
name: 'overleaf.id_1',
partialFilterExpression: {
'overleaf.id': {
$exists: true,
},
},
},
{
key: {
collaberator_refs: 1,
},
name: 'collaberator_refs_1',
},
{
key: {
name: 1,
},
name: 'name_1',
},
{
unique: true,
key: {
'tokens.readAndWrite': 1,
},
name: 'tokens.readAndWrite_1',
partialFilterExpression: {
'tokens.readAndWrite': {
$exists: true,
},
},
},
{
key: {
'collabratecUsers.user_id': 1,
},
name: 'collabratecUsers.user_id_1',
sparse: true,
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projects, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.projects, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,31 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
unique: true,
key: {
slug: 1,
},
name: 'slug_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.publishers, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.publishers, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
project_id: 1,
},
name: 'project_id',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.rooms, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.rooms, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
token: 1,
},
name: 'token',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.spellingPreferences, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.spellingPreferences, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,85 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
'teamInvites.token': 1,
},
name: 'teamInvites.token_1',
partialFilterExpression: {
'teamInvites.token': {
$exists: true,
},
},
},
{
unique: true,
key: {
manager_ids: 1,
},
name: 'manager_ids_1',
partialFilterExpression: {
manager_ids: {
$exists: true,
},
},
},
{
unique: true,
key: {
admin_id: 1,
},
name: 'admin_id_1',
},
{
key: {
'freeTrial.downgraded': 1,
'freeTrial.expiresAt': 1,
},
name: 'free_trial',
},
{
key: {
member_ids: 1,
},
name: 'member_ids_1',
},
{
key: {
invited_emails: 1,
},
name: 'invited_emails_1',
},
{
unique: true,
key: {
'overleaf.id': 1,
},
name: 'overleaf.id_1',
partialFilterExpression: {
'overleaf.id': {
$exists: true,
},
},
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.subscriptions, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.subscriptions, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,38 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
user_id: 1,
},
name: 'user_id_1',
},
{
unique: true,
key: {
user_id: 1,
name: 1,
},
name: 'user_id_1_name_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.tags, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.tags, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,43 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-pro', 'saas']
const indexes = [
{
unique: true,
key: {
project_id: 1,
},
name: 'project_id_1',
},
{
key: {
user_id: 1,
},
name: 'user_id_1',
},
{
key: {
name: 1,
},
name: 'name_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.templates, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.templates, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,32 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
unique: true,
key: {
token: 1,
use: 1,
},
name: 'token_1_use_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.tokens, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.tokens, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,165 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
unique: true,
key: {
email: 1,
},
name: 'email_case_insensitive',
collation: {
locale: 'en',
caseLevel: false,
caseFirst: 'off',
strength: 2,
numericOrdering: false,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
version: '57.1',
},
},
{
key: {
'dropbox.access_token.oauth_token_secret': 1,
},
name: 'has dropbox',
},
{
unique: true,
key: {
'overleaf.id': 1,
},
name: 'overleaf.id_1',
partialFilterExpression: {
'overleaf.id': {
$exists: true,
},
},
},
{
unique: true,
key: {
'thirdPartyIdentifiers.externalUserId': 1,
'thirdPartyIdentifiers.providerId': 1,
},
name:
'thirdPartyIdentifiers.externalUserId_1_thirdPartyIdentifiers.providerId_1',
sparse: true,
},
{
key: {
'subscription.freeTrialDowngraded': 1,
},
name: 'subscription.freeTrialDowngraded_1',
},
{
key: {
signUpDate: 1,
},
name: 'signUpDate',
},
{
unique: true,
key: {
'emails.email': 1,
},
name: 'emails_email_1',
partialFilterExpression: {
'emails.email': {
$exists: true,
},
},
},
{
unique: true,
key: {
'emails.email': 1,
},
name: 'emails_email_case_insensitive',
partialFilterExpression: {
'emails.email': {
$exists: true,
},
},
collation: {
locale: 'en',
caseLevel: false,
caseFirst: 'off',
strength: 2,
numericOrdering: false,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
version: '57.1',
},
},
{
unique: true,
key: {
'dropbox.access_token.uid': 1,
},
name: 'dropbox.access_token.uid_unique',
sparse: true,
},
{
key: {
password: 1,
email: 1,
},
name: 'password_and_email',
},
{
key: {
referal_id: 1,
},
name: 'referal_id',
},
{
key: {
'subscription.freeTrialExpiresAt': 1,
},
name: 'subscription.freeTrialExpiresAt_1',
},
{
key: {
auth_token: 1,
},
name: 'auth_token_1',
},
{
unique: true,
key: {
email: 1,
},
name: 'email_1',
},
{
key: {
'emails.reversedHostname': 1,
},
name: 'emails.reversedHostname_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.users, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.users, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,30 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
'overleaf.id': 1,
},
name: 'overleaf.id_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.userstubs, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.userstubs, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,44 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
providerId: 1,
},
name: 'providerId_1',
},
{
key: {
sessionId: 1,
},
name: 'sessionId_1',
},
{
// expire after 30 days
expireAfterSeconds: 60 * 60 * 24 * 30,
key: {
createdAt: 1,
},
name: 'createdAt_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.samllog, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.samllog, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,32 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
'samlIdentifiers.externalUserId': 1,
'samlIdentifiers.providerId': 1,
},
name: 'samlIdentifiers.externalUserId_1_samlIdentifiers.providerId_1',
sparse: true,
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.user, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.user, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,24 @@
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
brandVariationId: 1,
},
name: 'brandVariationId_1',
},
]
exports.migrate = async ({ db }) => {
await Helpers.addIndexesToCollection(db.projects, indexes)
}
exports.rollback = async ({ db }) => {
try {
await Helpers.dropIndexesFromCollection(db.projects, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,36 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = {
docSnapshots: [{ key: { project_id: 1, ts: 1 }, name: 'project_id_1_ts_1' }],
deletedProjects: [
{
key: { 'deleterData.deletedProjectOwnerId': 1 },
name: 'deleterdata_deletedProjectOwnerId_1',
},
],
docs: [{ key: { project_id: 1, inS3: 1 }, name: 'project_id_1_inS3_1' }],
}
exports.migrate = async client => {
const { db } = client
await Promise.all(
Object.keys(indexes).map(key =>
Helpers.addIndexesToCollection(db[key], indexes[key])
)
)
}
exports.rollback = async client => {
const { db } = client
await Promise.all(
Object.keys(indexes).map(key =>
Helpers.dropIndexesFromCollection(db[key], indexes[key])
)
)
}

View file

@ -0,0 +1,42 @@
/* eslint-disable no-unused-vars */
exports.tags = ['server-ce', 'server-pro', 'saas']
async function removeDuplicates(collection, field) {
const duplicates = await collection.aggregate(
[
{
$group: {
_id: { projectId: `$deleterData.${field}` },
dups: { $addToSet: '$_id' },
count: { $sum: 1 },
},
},
{ $match: { count: { $gt: 1 } } },
],
{ allowDiskUse: true }
)
let duplicate
while ((duplicate = await duplicates.next())) {
// find duplicate items, ignore the most recent and delete the rest
const items = await collection
.find(
{ _id: { $in: duplicate.dups } },
{ projection: { _id: 1 }, sort: { 'deleterData.deletedAt': -1 } }
)
.toArray()
items.pop()
const ids = items.map(item => item._id)
await collection.deleteMany({ _id: { $in: ids } })
}
}
exports.migrate = async client => {
const { db } = client
await removeDuplicates(db.deletedProjects, 'deletedProjectId')
await removeDuplicates(db.deletedUsers, 'deletedUserId')
}
exports.rollback = async client => {
// can't really do anything here
}

View file

@ -0,0 +1,70 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
exports.migrate = async client => {
const { db } = client
// deletedUsers did not have an index before
await Helpers.dropIndexesFromCollection(db.deletedProjects, [
{
key: {
'deleterData.deletedProjectId': 1,
},
name: 'deleterData.deletedProjectId_1',
},
])
// deletedUsers did not have an index before
await Helpers.addIndexesToCollection(db.deletedProjects, [
{
key: {
'deleterData.deletedProjectId': 1,
},
unique: true,
name: 'deleterData.deletedProjectId_1',
},
])
await Helpers.addIndexesToCollection(db.deletedUsers, [
{
key: {
'deleterData.deletedUserId': 1,
},
unique: true,
name: 'deleterData.deleteUserId_1',
},
])
}
exports.rollback = async client => {
const { db } = client
await Helpers.dropIndexesFromCollection(db.deletedProjects, [
{
key: {
'deleterData.deletedProjectId': 1,
},
unique: true,
name: 'deleterData.deletedProjectId_1',
},
])
await Helpers.dropIndexesFromCollection(db.deletedUsers, [
{
key: {
'deleterData.deletedUserId': 1,
},
unique: true,
name: 'deleterData.deleteUserId_1',
},
])
await Helpers.addIndexesToCollection(db.deletedProjects, [
{
key: {
'deleterData.deletedProjectId': 1,
},
name: 'deleterData.deletedProjectId_1',
},
])
// deletedUsers did not have an index before
}

View file

@ -0,0 +1,25 @@
/* eslint-disable no-unused-vars */
exports.tags = ['saas']
const Helpers = require('./lib/helpers')
const indexes = [
{
key: {
'emails.affiliationUnchecked': 1,
},
name: 'affiliationUnchecked_1',
sparse: true,
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.users, indexes)
}
exports.rollback = async client => {
const { db } = client
await Helpers.dropIndexesFromCollection(db.users, indexes)
}

View file

@ -0,0 +1,12 @@
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
exports.migrate = async client => {
const { db } = client
await Helpers.dropCollection(db, 'projectImportFailures')
}
exports.rollback = async client => {
// can't really do anything here
}

View file

@ -0,0 +1,12 @@
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
exports.migrate = async client => {
const { db } = client
await Helpers.dropCollection(db, 'projectImportBatchRecords')
}
exports.rollback = async client => {
// can't really do anything here
}

View file

@ -0,0 +1,38 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const indexes = [
{
key: {
requestId: 1,
},
name: 'requestId_1',
},
{
// expire after 24 hours
expireAfterSeconds: 60 * 60 * 24,
key: {
createdAt: 1,
},
name: 'createdAt_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.samlCache, indexes)
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.samlCache, indexes)
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,44 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['saas']
const oldIndex = {
unique: true,
key: {
manager_ids: 1,
},
name: 'manager_ids_1',
partialFilterExpression: {
manager_ids: {
$exists: true,
},
},
}
const newIndex = {
key: {
manager_ids: 1,
},
name: 'manager_ids_1',
sparse: true,
}
exports.migrate = async client => {
const { db } = client
await Helpers.dropIndexesFromCollection(db.subscriptions, [oldIndex])
await Helpers.addIndexesToCollection(db.subscriptions, [newIndex])
}
exports.rollback = async client => {
const { db } = client
try {
await Helpers.dropIndexesFromCollection(db.subscriptions, [newIndex])
await Helpers.addIndexesToCollection(db.subscriptions, [oldIndex])
} catch (err) {
console.error('Something went wrong rolling back the migrations', err)
}
}

View file

@ -0,0 +1,21 @@
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const index = {
key: { _id: 1, lastOpened: 1, active: 1 },
name: '_id_1_lastOpened_1_active_1',
partialFilterExpression: {
active: true,
},
}
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.projects, [index])
}
exports.rollback = async client => {
const { db } = client
await Helpers.dropIndexesFromCollection(db.projects, [index])
}

View file

@ -0,0 +1,22 @@
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
projectId: 1,
},
name: 'projectId_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.deletedFiles, indexes)
}
exports.rollback = async client => {
const { db } = client
await Helpers.dropIndexesFromCollection(db.deletedFiles, indexes)
}

View file

@ -0,0 +1,36 @@
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = {
tokens: [
{
// expire all tokens 90 days after they are created
expireAfterSeconds: 90 * 24 * 60 * 60,
key: {
createdAt: 1,
},
name: 'createdAt_1',
},
],
}
exports.migrate = async client => {
const { db } = client
await Promise.all(
Object.keys(indexes).map(key =>
Helpers.addIndexesToCollection(db[key], indexes[key])
)
)
}
exports.rollback = async client => {
const { db } = client
await Promise.all(
Object.keys(indexes).map(key =>
Helpers.dropIndexesFromCollection(db[key], indexes[key])
)
)
}

View file

@ -0,0 +1,24 @@
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
const indexes = [
{
key: {
project_id: 1,
deleted: 1,
deletedAt: -1,
},
name: 'project_id_deleted_deletedAt_1',
},
]
exports.migrate = async client => {
const { db } = client
await Helpers.addIndexesToCollection(db.docs, indexes)
}
exports.rollback = async client => {
const { db } = client
await Helpers.dropIndexesFromCollection(db.docs, indexes)
}

View file

@ -0,0 +1,69 @@
# Migrations
Migrations for the app environment live in this folder, and use the [East](https://github.com/okv/east) migration
framework.
We have an npm script which wraps east: `npm run migrations -- ...`
For example:
``` sh
npm run migrations -- list -t 'saas'
```
### Environments and Tags
Overleaf is deployed in three different environments:
- `server-ce`: community edition installations (the base system)
- `server-pro`: server pro installations
- `saas`: the production overleaf site
All migrations are tagged with the environments they should run in.
For example, a migration that should run in every environment would be tagged with `['server-ce', 'server-pro', 'saas']`.
When invoking east, we specify the relevant tags with the `-t` or `--tags` flag.
Our adapter will refuse to run if this flag is not set.
### Creating new migrations
To create a new migration, run:
```
npm run migrations -- create <migration name>
```
This command will create a new migration file in the migrations folder, based on a template. The template provides
`migrate` and `rollback` methods, which are run by the `east` binary when running the migrations. `rollback` should
undo the changes made in `migrate`.
#### Running scripts as a migration
To run a script in a migration file, look at `migrations/20190730093801_script_example.js`, which runs the script
`scripts/example/script_for_migration.js`. This uses a method where the script can be run standalone via `node`, or
through the migrations mechanism.
### Running migrations
To run all migrations in a server-ce environment:
``` sh
npm run migrations -- migrate -t 'server-ce'
```
To run all migrations in a saas environment:
``` sh
npm run migrations -- migrate -t 'saas'
```
The `-t` flag also works with other `east` commands like `rollback`, and `list`.
For other options, or for information on how to roll migrations back, take a look at the
[East](https://github.com/okv/east) documentation.
### Tips
Try to use Mongo directly via the `db` object instead of using Mongoose models. Migrations will need to run in the
future, and model files can change. It's unwise to make the migrations depend on code which might change.
**Note:** Running `east rollback` without any arguments rolls back *all* migrations, which you may well not want.

View file

@ -0,0 +1,56 @@
const Path = require('path')
const {
addCollection,
waitForDb,
db,
} = require('../../app/src/infrastructure/mongodb')
class Adapter {
constructor(params) {
if (!(process.argv.includes('-t') || process.argv.includes('--tags'))) {
console.error("ERROR: must pass tags using '-t' or '--tags', exiting")
process.exit(1)
}
this.params = params || {}
}
getTemplatePath() {
return Path.resolve(__dirname, 'template.js')
}
async connect() {
await waitForDb()
await addCollection('projectImportFailures')
await addCollection('samllog')
await addCollection('user')
return { db }
}
disconnect() {
return Promise.resolve()
}
async getExecutedMigrationNames() {
const migrations = await db.migrations
.find({}, { sort: { migratedAt: 1 }, projection: { name: 1 } })
.toArray()
return migrations.map(migration => migration.name)
}
async markExecuted(name) {
return db.migrations.insertOne({
name: name,
migratedAt: new Date(),
})
}
async unmarkExecuted(name) {
return db.migrations.deleteOne({
name: name,
})
}
}
module.exports = Adapter

View file

@ -0,0 +1,26 @@
const { getCollectionNames } = require('../../app/src/infrastructure/mongodb')
async function addIndexesToCollection(collection, indexes) {
return Promise.all(
indexes.map(index => {
index.background = true
return collection.createIndex(index.key, index)
})
)
}
async function dropIndexesFromCollection(collection, indexes) {
return Promise.all(indexes.map(index => collection.dropIndex(index.name)))
}
async function dropCollection(db, collectionName) {
const allCollections = await getCollectionNames()
if (!allCollections.includes(collectionName)) return
return db[collectionName].drop()
}
module.exports = {
addIndexesToCollection,
dropIndexesFromCollection,
dropCollection,
}

View file

@ -0,0 +1,15 @@
/* eslint-disable no-unused-vars */
const Helpers = require('./lib/helpers')
exports.tags = ['server-ce', 'server-pro', 'saas']
exports.migrate = async client => {
const { db } = client
// await Helpers.addIndexesToCollection(db.wombats, [{ name: 1 }])
}
exports.rollback = async client => {
const { db } = client
// Helpers.dropIndexesFromCollection(db.wombats, [{ name: 1 }])
}

View file

@ -1,12 +1,25 @@
const { exec } = require('child_process')
const { execFile } = require('child_process')
const { waitForDb, db } = require('../../../../app/src/infrastructure/mongodb')
const Settings = require('@overleaf/settings')
const DEFAULT_ENV = 'saas'
module.exports = {
initialize() {
before(waitForDb)
before(function (done) {
exec('bin/east migrate', (error, stdout, stderr) => {
const args = [
'run',
'migrations',
'--',
'migrate',
'-t',
Settings.env || DEFAULT_ENV,
]
execFile('npm', args, (error, stdout, stderr) => {
console.log(stdout)
console.error(stderr)
if (error) {
throw error
}