migrations.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 disable the schema validation and
  12. // argument transformations. We generally use the shorthandlers defined below.
  13. var noValidate = {
  14. validate: false,
  15. filter: false,
  16. autoConvert: false,
  17. removeEmptyStrings: false,
  18. getAutoValues: false
  19. };
  20. var noValidateMulti = _.extend(noValidate, { multi: true });
  21. Migrations.add('board-background-color', function() {
  22. var defaultColor = '#16A085';
  23. Boards.update({
  24. background: {
  25. $exists: false
  26. }
  27. }, {
  28. $set: {
  29. background: {
  30. type: 'color',
  31. color: defaultColor
  32. }
  33. }
  34. }, noValidateMulti);
  35. });
  36. Migrations.add('lowercase-board-permission', function() {
  37. _.forEach(['Public', 'Private'], function(permission) {
  38. Boards.update(
  39. { permission: permission },
  40. { $set: { permission: permission.toLowerCase() } },
  41. noValidateMulti
  42. );
  43. });
  44. });
  45. // Security migration: see https://github.com/libreboard/libreboard/issues/99
  46. Migrations.add('change-attachments-type-for-non-images', function() {
  47. var newTypeForNonImage = 'application/octet-stream';
  48. Attachments.find().forEach(function(file) {
  49. if (! file.isImage()) {
  50. Attachments.update(file._id, {
  51. $set: {
  52. 'original.type': newTypeForNonImage,
  53. 'copies.attachments.type': newTypeForNonImage
  54. }
  55. }, noValidate);
  56. }
  57. });
  58. });
  59. Migrations.add('card-covers', function() {
  60. Cards.find().forEach(function(card) {
  61. var cover = Attachments.findOne({ cardId: card._id, cover: true });
  62. if (cover) {
  63. Cards.update(card._id, {$set: {coverId: cover._id}}, noValidate);
  64. }
  65. });
  66. Attachments.update({}, {$unset: {cover: ''}}, noValidateMulti);
  67. });
  68. Migrations.add('use-css-class-for-boards-colors', function() {
  69. var associationTable = {
  70. '#27AE60': 'nephritis',
  71. '#C0392B': 'pomegranate',
  72. '#2980B9': 'belize',
  73. '#8E44AD': 'wisteria',
  74. '#2C3E50': 'midnight',
  75. '#E67E22': 'pumpkin'
  76. };
  77. Boards.find().forEach(function(board) {
  78. var oldBoardColor = board.background.color;
  79. var newBoardColor = associationTable[oldBoardColor];
  80. Boards.update(board._id, {
  81. $set: { color: newBoardColor },
  82. $unset: { background: '' }
  83. }, noValidate);
  84. });
  85. });
  86. Migrations.add('denormalize-star-number-per-board', function() {
  87. Boards.find().forEach(function(board) {
  88. var nStars = Users.find({'profile.starredBoards': board._id}).count();
  89. Boards.update(board._id, {$set: {stars: nStars}}, noValidate);
  90. });
  91. });
  92. // We want to keep a trace of former members so we can efficiently publish their
  93. // infos in the general board publication.
  94. Migrations.add('add-member-isactive-field', function() {
  95. Boards.find({}, {fields: {members: 1}}).forEach(function(board) {
  96. var allUsersWithSomeActivity = _.chain(
  97. Activities.find({boardId: board._id}, {fields:{userId:1}}).fetch())
  98. .pluck('userId')
  99. .uniq()
  100. .value();
  101. var currentUsers = _.pluck(board.members, 'userId');
  102. var formerUsers = _.difference(allUsersWithSomeActivity, currentUsers);
  103. var newMemberSet = [];
  104. _.forEach(board.members, function(member) {
  105. member.isActive = true;
  106. newMemberSet.push(member);
  107. });
  108. _.forEach(formerUsers, function(userId) {
  109. newMemberSet.push({
  110. userId: userId,
  111. isAdmin: false,
  112. isActive: false
  113. });
  114. });
  115. Boards.update(board._id, {$set: {members: newMemberSet}}, noValidate);
  116. });
  117. });