migrations.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Anytime you change the schema of one of the collection in a non-backward
  2. // compatible way you have to write a migration in this file using the following
  3. // API:
  4. //
  5. // Migrations.add(name, migrationCallback, optionalOrder);
  6. // In the context of migration functions we don't want to validate database
  7. // mutation queries against the current (ie, latest) collection schema. Doing
  8. // that would work at the time we write the migration but would break in the
  9. // future when we'll update again the concerned collection schema.
  10. //
  11. // To prevent this bug we always have to set the `validate` option to false. We
  12. // generally use the shorthandlers defined below.
  13. var noValidate = { validate: false };
  14. var noValidateMulti = _.extend(noValidate, { multi: true });
  15. Migrations.add('board-background-color', function() {
  16. var defaultColor = '#16A085';
  17. Boards.update({
  18. background: {
  19. $exists: false
  20. }
  21. }, {
  22. $set: {
  23. background: {
  24. type: 'color',
  25. color: defaultColor
  26. }
  27. }
  28. }, noValidateMulti);
  29. });
  30. Migrations.add('lowercase-board-permission', function() {
  31. _.forEach(['Public', 'Private'], function(permission) {
  32. Boards.update(
  33. { permission: permission },
  34. { $set: { permission: permission.toLowerCase() } },
  35. noValidateMulti
  36. );
  37. });
  38. });
  39. // Security migration: see https://github.com/libreboard/libreboard/issues/99
  40. Migrations.add('change-attachments-type-for-non-images', function() {
  41. var newTypeForNonImage = 'application/octet-stream';
  42. Attachments.find().forEach(function(file) {
  43. if (! file.isImage()) {
  44. Attachments.update(file._id, {
  45. $set: {
  46. 'original.type': newTypeForNonImage,
  47. 'copies.attachments.type': newTypeForNonImage
  48. }
  49. }, noValidate);
  50. }
  51. });
  52. });
  53. Migrations.add('card-covers', function() {
  54. Cards.find().forEach(function(card) {
  55. var cover = Attachments.findOne({ cardId: card._id, cover: true });
  56. if (cover) {
  57. Cards.update(card._id, {$set: {coverId: cover._id}}, noValidate);
  58. }
  59. });
  60. Attachments.update({}, {$unset: {cover: ''}}, noValidateMulti);
  61. });
  62. Migrations.add('use-css-class-for-boards-colors', function() {
  63. var associationTable = {
  64. '#27AE60': 'nephritis',
  65. '#C0392B': 'pomegranate',
  66. '#2980B9': 'belize',
  67. '#8E44AD': 'wisteria',
  68. '#2C3E50': 'midnight',
  69. '#E67E22': 'pumpkin'
  70. };
  71. Boards.find().forEach(function(board) {
  72. var oldBoardColor = board.background.color;
  73. var newBoardColor = associationTable[oldBoardColor];
  74. Boards.update(board._id, {
  75. $set: { color: newBoardColor },
  76. $unset: { background: '' }
  77. }, noValidate);
  78. });
  79. });
  80. Migrations.add('denormalize-star-number-per-board', function() {
  81. Boards.find().forEach(function(board) {
  82. var nStars = Users.find({'profile.starredBoards': board._id}).count();
  83. Boards.update(board._id, {$set: {stars: nStars}}, noValidate);
  84. });
  85. });
  86. // We want to keep a trace of former members so we can efficiently publish their
  87. // infos in the general board publication.
  88. Migrations.add('add-member-isactive-field', function() {
  89. Boards.find({}, {fields: {members: 1}}).forEach(function(board) {
  90. var allUsersWithSomeActivity = _.chain(
  91. Activities.find({boardId: board._id}, {fields:{userId:1}}).fetch())
  92. .pluck('userId')
  93. .uniq()
  94. .value();
  95. var currentUsers = _.pluck(board.members, 'userId');
  96. var formerUsers = _.difference(allUsersWithSomeActivity, currentUsers);
  97. var newMemberSet = [];
  98. _.forEach(board.members, function(member) {
  99. member.isActive = true;
  100. newMemberSet.push(member);
  101. });
  102. _.forEach(formerUsers, function(userId) {
  103. newMemberSet.push({
  104. userId: userId,
  105. isAdmin: false,
  106. isActive: false
  107. });
  108. });
  109. Boards.update(board._id, {$set: {members: newMemberSet}}, noValidate);
  110. });
  111. });