@wepublish/api-db-mongodb
Version:
We.publish Database adapter for mongoDB
805 lines • 37.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LatestMigration = exports.Migrations = void 0;
const schema_1 = require("./db/schema");
const api_1 = require("@wepublish/api");
const utility_1 = require("./utility");
const SessionDocumentTTL = 60 * 60 * 24; // 24h
exports.Migrations = [
{
version: 0,
async migrate(db, locale) {
const migrations = await db.createCollection(schema_1.CollectionName.Migrations, { strict: true });
await migrations.createIndex({ name: 1 }, { unique: true });
const users = await db.createCollection(schema_1.CollectionName.Users, {
strict: true
});
await users.createIndex({ email: 1 }, { unique: true });
const sessions = await db.createCollection(schema_1.CollectionName.Sessions, {
strict: true
});
await sessions.createIndex({ userID: 1 });
await sessions.createIndex({ token: 1 }, { unique: true });
await sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: SessionDocumentTTL });
const navigations = await db.createCollection(schema_1.CollectionName.Navigations, { strict: true });
await navigations.createIndex({ createdAt: -1 });
await navigations.createIndex({ modifiedAt: -1 });
await navigations.createIndex({ name: 1 });
await navigations.createIndex({ key: 1 }, { unique: true });
const authors = await db.createCollection(schema_1.CollectionName.Authors, { strict: true });
await authors.createIndex({ createdAt: -1 });
await authors.createIndex({ modifiedAt: -1 });
await authors.createIndex({ name: 1 });
await authors.createIndex({ slug: 1 }, { unique: true });
const images = await db.createCollection(schema_1.CollectionName.Images, { strict: true });
await images.createIndex({ createdAt: -1 });
await images.createIndex({ modifiedAt: -1 });
await images.createIndex({ title: 1 });
await images.createIndex({ tags: 1 }, { collation: { locale, strength: 2 } });
const articles = await db.createCollection(schema_1.CollectionName.Articles, {
strict: true
});
await articles.createIndex({ createdAt: -1 });
await articles.createIndex({ modifiedAt: -1 });
await articles.createIndex({ 'published.publishedAt': -1 });
await articles.createIndex({ 'published.updatedAt': -1 });
await articles.createIndex({ 'pending.publishAt': -1 });
await articles.createIndex({ 'draft.tags': 1 }, { collation: { locale, strength: 2 } });
await articles.createIndex({ 'pending.tags': 1 }, { collation: { locale, strength: 2 } });
await articles.createIndex({ 'published.tags': 1 }, { collation: { locale, strength: 2 } });
await db.createCollection(schema_1.CollectionName.ArticlesHistory, {
strict: true
});
const pages = await db.createCollection(schema_1.CollectionName.Pages, {
strict: true
});
await pages.createIndex({ createdAt: -1 });
await pages.createIndex({ modifiedAt: -1 });
await pages.createIndex({ 'published.publishedAt': -1 });
await pages.createIndex({ 'published.updatedAt': -1 });
await pages.createIndex({ 'pending.publishAt': -1 });
await pages.createIndex({ 'draft.tags': 1 }, { collation: { locale, strength: 2 } });
await pages.createIndex({ 'pending.tags': 1 }, { collation: { locale, strength: 2 } });
await pages.createIndex({ 'published.tags': 1 }, { collation: { locale, strength: 2 } });
await db.createCollection(schema_1.CollectionName.PagesHistory, {
strict: true
});
}
},
{
// Fix incorrect migration index. Add user roles, Add name and roleIDs to users.
version: 1,
async migrate(db, locale) {
const migrations = db.collection(schema_1.CollectionName.Migrations);
await migrations.dropIndex('name_1');
await migrations.createIndex({ version: 1 }, { unique: true });
const userRoles = await db.createCollection(schema_1.CollectionName.UserRoles, {
strict: true
});
await userRoles.createIndex({ name: 1 }, { unique: true });
await userRoles.insertMany([
{
_id: 'admin',
createdAt: new Date(),
modifiedAt: new Date(),
systemRole: true,
name: 'Admin',
description: 'Administrator Role',
permissionIDs: []
},
{
_id: 'editor',
createdAt: new Date(),
modifiedAt: new Date(),
systemRole: true,
name: 'Editor',
description: 'Editor Role',
permissionIDs: []
}
]);
const user = db.collection(schema_1.CollectionName.Users);
await user.updateMany({}, [
{
$set: {
name: '$email',
roleIDs: ['admin']
}
}
]);
}
},
{
// Add peering and token collections and migrate ArticleTeaserGridBlock to TeaserGridBlock.
version: 2,
async migrate(db) {
const userRoles = db.collection(schema_1.CollectionName.UserRoles);
await userRoles.insertOne({
_id: 'peer',
createdAt: new Date(),
modifiedAt: new Date(),
systemRole: true,
name: 'Peer',
description: 'Peer Role',
permissionIDs: []
});
await db.createCollection(schema_1.CollectionName.PeerProfiles, { strict: true });
const peers = await db.createCollection(schema_1.CollectionName.Peers, { strict: true });
await peers.createIndex({ slug: 1 }, { unique: true });
const tokens = await db.createCollection(schema_1.CollectionName.Tokens, {
strict: true
});
await tokens.createIndex({ name: 1 }, { unique: true });
const filter = {
$or: [
{ 'draft.blocks.type': 'articleTeaserGrid' },
{ 'published.blocks.type': 'articleTeaserGrid' },
{ 'pending.blocks.type': 'articleTeaserGrid' }
]
};
function mapArticleTeaserGridBlock(block) {
if (block.type === 'articleTeaserGrid') {
return {
type: 'teaserGrid',
teasers: block.teasers.map((teaser) => teaser
? {
type: 'article',
style: 'default',
articleID: teaser.articleID
}
: null),
numColumns: block.numColumns
};
}
return block;
}
const articles = db.collection(schema_1.CollectionName.Articles);
const migrationArticles = await articles.find(filter).toArray();
for (const article of migrationArticles) {
if (article.draft) {
article.draft.blocks = article.draft.blocks.map(mapArticleTeaserGridBlock);
}
if (article.pending) {
article.pending.blocks = article.pending.blocks.map(mapArticleTeaserGridBlock);
}
if (article.published) {
article.published.blocks = article.published.blocks.map(mapArticleTeaserGridBlock);
}
await articles.findOneAndReplace({ _id: article._id }, article);
}
const pages = db.collection(schema_1.CollectionName.Pages);
const migrationPages = await pages.find(filter).toArray();
for (const page of migrationPages) {
if (page.draft) {
page.draft.blocks = page.draft.blocks.map(mapArticleTeaserGridBlock);
}
if (page.pending) {
page.pending.blocks = page.pending.blocks.map(mapArticleTeaserGridBlock);
}
if (page.published) {
page.published.blocks = page.published.blocks.map(mapArticleTeaserGridBlock);
}
await pages.findOneAndReplace({ _id: page._id }, page);
}
}
},
{
// Add peering and token collections and migrate ArticleTeaserGridBlock to TeaserGridBlock.
version: 3,
async migrate(db) {
const articles = db.collection(schema_1.CollectionName.Articles);
const migrationArticles = await articles.find().toArray();
for (const article of migrationArticles) {
if (article.draft) {
article.draft.properties = [];
}
if (article.pending) {
article.pending.properties = [];
}
if (article.published) {
article.published.properties = [];
}
await articles.findOneAndReplace({ _id: article._id }, article);
}
const pages = db.collection(schema_1.CollectionName.Pages);
const migrationPages = await pages.find().toArray();
for (const page of migrationPages) {
if (page.draft) {
page.draft.properties = [];
}
if (page.pending) {
page.pending.properties = [];
}
if (page.published) {
page.published.properties = [];
}
await pages.findOneAndReplace({ _id: page._id }, page);
}
}
},
{
// Add RTE to page break block if not exists in articles and pages
version: 4,
async migrate(db) {
await db.collection(schema_1.CollectionName.Articles).updateMany({ 'draft.blocks': { $elemMatch: { type: 'linkPageBreak', richText: { $exists: false } } } }, {
$set: {
'draft.blocks.$[elem].richText': [{ children: [{ text: '' }], type: 'paragraph' }]
}
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Articles).updateMany({
'published.blocks': {
$elemMatch: { type: 'linkPageBreak', richText: { $exists: false } }
}
}, {
$set: { 'published.blocks.$[elem].richText': [{ children: [{ text: '' }], type: 'paragraph' }] }
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Articles).updateMany({
'pending.blocks': { $elemMatch: { type: 'linkPageBreak', richText: { $exists: false } } }
}, { $set: { 'pending.blocks.$[elem].richText': [{ children: [{ text: '' }], type: 'paragraph' }] } }, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
// Add RTE to page break block if not exists in pages
await db.collection(schema_1.CollectionName.Pages).updateMany({ 'draft.blocks': { $elemMatch: { type: 'linkPageBreak', richText: { $exists: false } } } }, {
$set: {
'draft.blocks.$[elem].richText': [{ children: [{ text: '' }], type: 'paragraph' }]
}
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Pages).updateMany({
'published.blocks': {
$elemMatch: { type: 'linkPageBreak', richText: { $exists: false } }
}
}, {
$set: { 'published.blocks.$[elem].richText': [{ children: [{ text: '' }], type: 'paragraph' }] }
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Pages).updateMany({ 'pending.blocks': { $elemMatch: { type: 'linkPageBreak', richText: { $exists: false } } } }, {
$set: { 'pending.blocks.$[elem].richText': [{ children: [{ text: '' }], type: 'paragraph' }] }
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
}
},
{
// Add hideButton false to pageBreakBlocks
version: 5,
async migrate(db) {
await db.collection(schema_1.CollectionName.Articles).updateMany({ 'draft.blocks': { $elemMatch: { type: 'linkPageBreak', hideButton: { $exists: false } } } }, {
$set: {
'draft.blocks.$[elem].hideButton': false
}
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Articles).updateMany({
'published.blocks': {
$elemMatch: { type: 'linkPageBreak', hideButton: { $exists: false } }
}
}, {
$set: { 'published.blocks.$[elem].hideButton': false }
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Articles).updateMany({
'pending.blocks': { $elemMatch: { type: 'linkPageBreak', hideButton: { $exists: false } } }
}, { $set: { 'pending.blocks.$[elem].hideButton': false } }, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
// Add RTE to page break block if not exists in pages
await db.collection(schema_1.CollectionName.Pages).updateMany({ 'draft.blocks': { $elemMatch: { type: 'linkPageBreak', hideButton: { $exists: false } } } }, {
$set: {
'draft.blocks.$[elem].hideButton': false
}
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Pages).updateMany({
'published.blocks': {
$elemMatch: { type: 'linkPageBreak', hideButton: { $exists: false } }
}
}, {
$set: { 'published.blocks.$[elem].hideButton': false }
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
await db.collection(schema_1.CollectionName.Pages).updateMany({ 'pending.blocks': { $elemMatch: { type: 'linkPageBreak', hideButton: { $exists: false } } } }, {
$set: { 'pending.blocks.$[elem].hideButton': false }
}, { arrayFilters: [{ 'elem.type': 'linkPageBreak' }] });
}
},
{
// Add hide author property to article.
version: 6,
async migrate(db) {
await db.collection(schema_1.CollectionName.Articles).updateMany({
pending: { $ne: null },
'pending.hideAuthor': { $exists: false }
}, { $set: { 'pending.hideAuthor': false } });
await db.collection(schema_1.CollectionName.Articles).updateMany({
published: { $ne: null },
'published.hideAuthor': { $exists: false }
}, { $set: { 'published.hideAuthor': false } });
await db.collection(schema_1.CollectionName.Articles).updateMany({
draft: { $ne: null },
'draft.hideAuthor': { $exists: false }
}, { $set: { 'draft.hideAuthor': false } });
}
},
{
// Add Call To Action Details to Peer Profile.
version: 7,
async migrate(db) {
await db.collection(schema_1.CollectionName.PeerProfiles).updateMany({
callToActionURL: { $exists: false },
callToActionText: { $exists: false }
}, {
$set: {
callToActionURL: '',
callToActionText: []
}
});
}
},
{
// Add social media metatags to article.
version: 8,
async migrate(db) {
await db.collection(schema_1.CollectionName.Articles).updateMany({
pending: { $ne: null },
'pending.socialMediaAuthorIDs': { $exists: false }
}, {
$set: {
'pending.socialMediaAuthorIDs': []
}
});
await db.collection(schema_1.CollectionName.Articles).updateMany({
published: { $ne: null },
'published.socialMediaAuthorIDs': { $exists: false }
}, {
$set: {
'published.socialMediaAuthorIDs': []
}
});
await db.collection(schema_1.CollectionName.Articles).updateMany({
draft: { $ne: null },
'draft.socialMediaAuthorIDs': { $exists: false }
}, {
$set: {
'draft.socialMediaAuthorIDs': []
}
});
}
},
{
// Add new collection MailLog
version: 9,
async migrate(db) {
const mailLogs = await db.createCollection(schema_1.CollectionName.MailLog, { strict: true });
await mailLogs.createIndex({ subject: 1 });
}
},
{
// Add MemberPlan Collection and PaymentMethod Collection
version: 10,
async migrate(db, locale) {
const memberPlans = await db.createCollection(schema_1.CollectionName.MemberPlans, {
strict: true
});
await memberPlans.createIndex({ name: 1 });
await memberPlans.createIndex({ slug: 1 }, { unique: true });
const paymentMethod = await db.createCollection(schema_1.CollectionName.PaymentMethods, {
strict: true
});
await paymentMethod.createIndex({ name: 1 });
await paymentMethod.createIndex({ paymentAdapter: 1 });
const users = db.collection(schema_1.CollectionName.Users);
await users.createIndex({ 'subscription.memberPlanId': 1 });
await users.updateMany({
paymentProviderCustomers: { $exists: false }
}, { $set: { paymentProviderCustomers: {} } });
await users.updateMany({
active: { $exists: false }
}, { $set: { active: true } });
await users.updateMany({
lastLogin: { $exists: false }
}, { $set: { lastLogin: null } });
await users.updateMany({
properties: { $exists: false }
}, { $set: { properties: [] } });
const invoices = await db.createCollection(schema_1.CollectionName.Invoices, {
strict: true
});
await invoices.createIndex({ mail: 1 });
const payments = await db.createCollection(schema_1.CollectionName.Payments, {
strict: true
});
await payments.createIndex({ intentID: 1 });
}
},
{
// Add Commenting Table.
version: 11,
async migrate(db) {
const comments = await db.createCollection(schema_1.CollectionName.Comments, {
strict: true
});
await comments.createIndex({ createdAt: -1 });
await comments.createIndex({ 'revisions.createdAt': -1 });
}
},
{
// Make slug for published pages unique
version: 12,
async migrate(db, locale) {
const pages = await db.collection(schema_1.CollectionName.Pages);
await pages.createIndex({ 'published.slug': 1 }, {
collation: { locale, strength: 2 },
unique: true,
partialFilterExpression: { 'published.slug': { $exists: true } }
});
}
},
{
// Rename street field in address to address
version: 13,
async migrate(db, locale) {
const users = await db.collection(schema_1.CollectionName.Users);
await users.updateMany({
'address.street': { $exists: true }
}, {
$rename: { 'address.street': 'address.streetAddress' }
});
}
},
{
// Add emailVerifiedAt and oauth2Accounts to user model
version: 14,
async migrate(db, locale) {
const users = await db.collection(schema_1.CollectionName.Users);
await users.updateMany({
emailVerifiedAt: { $exists: false }
}, { $set: { emailVerifiedAt: null } });
await users.updateMany({
oauth2Accounts: { $exists: false }
}, { $set: { oauth2Accounts: [] } });
}
},
{
// Set paymentProviderCustomers to an empty array
version: 15,
async migrate(db, locale) {
const users = await db.collection(schema_1.CollectionName.Users);
const allUsers = await users.find({}).toArray();
for (const user of allUsers) {
const paymentProvidersCustomersArray = [];
const paymentProviderCustomers = Object.keys(user.paymentProviderCustomers);
paymentProviderCustomers.forEach(ppc => {
const userPPC = user.paymentProviderCustomers[+ppc];
paymentProvidersCustomersArray.push({
paymentProviderID: ppc,
customerID: userPPC.id
});
});
await users.updateOne({ _id: user._id }, { $set: { paymentProviderCustomers: paymentProvidersCustomersArray } });
}
}
},
{
// add slug to existing paymentMethods
version: 16,
async migrate(db, locale) {
const paymentMethods = await db.collection(schema_1.CollectionName.PaymentMethods);
const allPaymentMethods = await paymentMethods.find({}).toArray();
for (const paymentMethod of allPaymentMethods) {
const slug = (0, utility_1.slugify)(paymentMethod.name);
await paymentMethods.updateOne({ _id: paymentMethod._id }, { $set: { slug } });
}
}
},
{
// migrate existing deactivated subscriptions
version: 17,
async migrate(db, locale) {
const users = await db.collection(schema_1.CollectionName.Users);
await users.updateMany({
$and: [
{ 'subscription.deactivatedAt': { $exists: true } },
{ 'subscription.deactivatedAt': null }
]
}, [
{
$set: {
'subscription.deactivation': null
}
},
{
$unset: ['subscription.deactivatedAt']
}
]);
await users.updateMany({
$and: [
{ 'subscription.deactivatedAt': { $exists: true } },
{ 'subscription.deactivatedAt': { $ne: null } }
]
}, [
{
$set: {
'subscription.deactivation.date': '$subscription.deactivatedAt',
'subscription.deactivation.reason': api_1.SubscriptionDeactivationReason.None
}
},
{
$unset: ['subscription.deactivatedAt']
}
]);
}
},
{
// migrate existing deactivated subscriptions
version: 18,
async migrate(db, locale) {
// Values required to execute migration
const TEMP_USER_PREFIX = '__temp_';
const removePrefixTempUser = function removePrefixTempUser(userID) {
return userID.replace(TEMP_USER_PREFIX, '');
};
// 1. move subscription from user object into new subscription collection
const users = await db.collection(schema_1.CollectionName.Users);
const userWithSubscriptions = await users.find({ subscription: { $exists: true } }).toArray();
const newSubscriptions = [];
const OLD_TEMP_USER_REGEX = /^temp_[0-9]+_/;
for (const user of userWithSubscriptions) {
if (!user.subscription)
continue;
// create correct temp user reference id
const userId = OLD_TEMP_USER_REGEX.test(user.email)
? `${TEMP_USER_PREFIX}${user._id}`
: user._id;
newSubscriptions.push({
userID: userId,
createdAt: user.createdAt,
modifiedAt: user.modifiedAt,
memberPlanID: user.subscription.memberPlanID,
paymentPeriodicity: user.subscription.paymentPeriodicity,
monthlyAmount: user.subscription.monthlyAmount,
autoRenew: user.subscription.autoRenew,
startsAt: user.subscription.startsAt,
paidUntil: user.subscription.paidUntil,
periods: user.subscription.periods,
paymentMethodID: user.subscription.paymentMethodID,
properties: [],
deactivation: user.subscription.deactivation
});
}
const subscriptions = await db.createCollection(schema_1.CollectionName.Subscriptions, {
strict: true
});
if (newSubscriptions.length > 0)
await subscriptions.insertMany(newSubscriptions);
// 2. create new invoices
const invoices = await db.collection(schema_1.CollectionName.Invoices);
const allInvoices = await invoices.find({}).toArray();
const allSubscriptions = await subscriptions.find({}).toArray();
const newInvoices = [];
for (const invoice of allInvoices) {
const userID = invoice.userID;
const subscription = allSubscriptions.find(subscription => removePrefixTempUser(subscription.userID) === userID);
if (!subscription) {
continue;
}
newInvoices.push({
_id: invoice._id,
createdAt: invoice.createdAt,
modifiedAt: invoice.modifiedAt,
subscriptionID: subscription._id,
description: invoice.description,
canceledAt: invoice.canceledAt,
dueAt: invoice.dueAt,
items: invoice.items,
mail: invoice.mail,
paidAt: invoice.paidAt,
sentReminderAt: invoice.sentReminderAt
});
}
// inform We.Publish operators to remove this manually
await invoices.rename('invoices.bak');
const emptyInvoices = await db.createCollection(schema_1.CollectionName.Invoices, {
strict: true
});
if (newInvoices.length > 0)
await emptyInvoices.insertMany(newInvoices);
// 3. remove subscription object from user collection
await users.updateMany({ subscription: { $exists: true } }, {
$unset: { subscription: '' }
});
// 4. split existing user collection into new temp.user and user collection
const tempUserQuery = { email: { $regex: OLD_TEMP_USER_REGEX } };
const tempUsers = await users.find(tempUserQuery).toArray();
const newTempUserCollection = await db.createCollection('temp.users', {
strict: true
});
if (tempUsers.length) {
// remove old temp_ prefix from emails in the new temp.user collection
for (const tempUser of tempUsers) {
tempUser.email = tempUser.email.replace(OLD_TEMP_USER_REGEX, '');
}
await newTempUserCollection.insertMany(tempUsers);
// 5. delete migrated temp users from user collection
await users.deleteMany(tempUserQuery);
}
}
},
{
// rename image => source to link and author to source; This should make code and data consistent
version: 19,
async migrate(db, locale) {
const images = await db.collection(schema_1.CollectionName.Images);
await images.updateMany({}, { $rename: { source: 'link' } });
await images.updateMany({}, { $rename: { author: 'source' } });
}
},
{
// change embed block properties width and height from number to string
version: 20,
async migrate(db) {
const articles = db.collection(schema_1.CollectionName.Articles);
const migrationArticles = await articles.find().toArray();
for (const article of migrationArticles) {
if (article.draft) {
article.draft.blocks.forEach((block) => {
if (block.type === api_1.BlockType.Embed) {
block.height = String(block.height);
block.width = String(block.width);
}
});
}
if (article.published) {
article.published.blocks.forEach((block) => {
if (block.type === api_1.BlockType.Embed) {
block.height = String(block.height);
block.width = String(block.width);
}
});
}
if (article.pending) {
article.pending.blocks.forEach((block) => {
if (block.type === api_1.BlockType.Embed) {
block.height = String(block.height);
block.width = String(block.width);
}
});
}
await articles.findOneAndReplace({ _id: article._id }, article);
}
const pages = db.collection(schema_1.CollectionName.Pages);
const migrationPages = await pages.find().toArray();
for (const page of migrationPages) {
if (page.draft) {
page.draft.blocks.forEach((block) => {
if (block.type === api_1.BlockType.Embed) {
block.height = String(block.height);
block.width = String(block.width);
}
});
}
if (page.published) {
page.published.blocks.forEach((block) => {
if (block.type === api_1.BlockType.Embed) {
block.height = String(block.height);
block.width = String(block.width);
}
});
}
if (page.pending) {
page.pending.blocks.forEach((block) => {
if (block.type === api_1.BlockType.Embed) {
block.height = String(block.height);
block.width = String(block.width);
}
});
}
await pages.findOneAndReplace({ _id: page._id }, page);
}
}
},
{
version: 21,
async migrate(db, locale) {
const invoices = db.collection(schema_1.CollectionName.Invoices);
await invoices.updateMany({}, { $set: { manuallySetAsPaidByUserId: undefined } });
}
},
{
// Rename unused temp user collection. For operators to remove manually since the collection not used anymore.
version: 22,
async migrate(db) {
const collections = await db.listCollections().toArray();
if (collections.includes('temp.users')) {
const tempUser = await db.collection('temp.users');
await tempUser.rename('temp.users.bak');
}
}
},
{
// Try to migrate email addressees of users
version: 23,
async migrate(db) {
const userCollection = await db.collection(schema_1.CollectionName.Users);
const subscriptionCollection = await db.collection(schema_1.CollectionName.Subscriptions);
const sessionCollection = await db.collection(schema_1.CollectionName.Sessions);
const users = await userCollection.find().toArray();
// inform We.Publish operators to remove this manually
await userCollection.rename('23-users.bak');
const emptyUsers = await db.createCollection(schema_1.CollectionName.Users, {
strict: true
});
const listSanitizedUsers = [];
for (const user of users) {
user.email = user.email.toLowerCase();
const duplicatedMail = listSanitizedUsers.find(element => element.email === user.email);
// If already a user with normalized mail exist merge them
if (duplicatedMail) {
// Update userID in subscription table
const subscriptions = await subscriptionCollection.find({ userID: user._id }).toArray();
for (const subscription of subscriptions) {
subscription.properties.push({
key: 'UserIDChangedByMigration23',
value: subscription.userID,
public: false
});
subscription.userID = duplicatedMail.userId;
await subscriptionCollection.replaceOne({ _id: subscription._id }, subscription, {
upsert: true
});
}
// Update userID in session table
const sessions = await sessionCollection.find({ userID: user._id }).toArray();
for (const session of sessions) {
session.user = duplicatedMail.userId;
await sessionCollection.replaceOne({ _id: session._id }, session, { upsert: true });
}
}
else {
// If user is unique update mail of user
await emptyUsers.insertOne(user);
listSanitizedUsers.push({
userId: user._id,
email: user.email
});
}
}
}
},
{
// add settings category
version: 24,
async migrate(db, locale) {
const settingsDoc = await db.createCollection(schema_1.CollectionName.Settings, {
strict: true
});
const peeringTimeout = {
name: api_1.SettingName.PEERING_TIMEOUT_MS,
value: 3000,
settingRestriction: { minValue: 1000, maxValue: 10000 }
};
const allowAnonCommenting = {
name: api_1.SettingName.ALLOW_GUEST_COMMENTING,
value: false,
settingRestriction: { allowedValues: { boolChoice: true } }
};
const sendLoginJWTExpires = {
name: api_1.SettingName.SEND_LOGIN_JWT_EXPIRES_MIN,
value: 10080,
settingRestriction: { minValue: 1, maxValue: 10080 }
};
const resetPwdExpires = {
name: api_1.SettingName.RESET_PASSWORD_JWT_EXPIRES_MIN,
value: 1440,
settingRestriction: { minValue: 1, maxValue: 10080 }
};
const invoiceReminderFreq = {
name: api_1.SettingName.INVOICE_REMINDER_FREQ,
value: 3,
settingRestriction: { minValue: 0, maxValue: 30 }
};
const invoiceReminderTries = {
name: api_1.SettingName.INVOICE_REMINDER_MAX_TRIES,
value: 5,
settingRestriction: { minValue: 0, maxValue: 10 }
};
await settingsDoc.insertMany([
peeringTimeout,
allowAnonCommenting,
sendLoginJWTExpires,
resetPwdExpires,
invoiceReminderFreq,
invoiceReminderTries
]);
}
}
];
exports.LatestMigration = exports.Migrations[exports.Migrations.length - 1];
//# sourceMappingURL=migration.js.map