FeaturesUpdater.coffee 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. async = require("async")
  2. PlansLocator = require("./PlansLocator")
  3. _ = require("underscore")
  4. SubscriptionLocator = require("./SubscriptionLocator")
  5. UserFeaturesUpdater = require("./UserFeaturesUpdater")
  6. Settings = require("settings-sharelatex")
  7. logger = require("logger-sharelatex")
  8. ReferalFeatures = require("../Referal/ReferalFeatures")
  9. V1SubscriptionManager = require("./V1SubscriptionManager")
  10. oneMonthInSeconds = 60 * 60 * 24 * 30
  11. module.exports = FeaturesUpdater =
  12. refreshFeatures: (user_id, notifyV1 = true, callback = () ->)->
  13. if typeof notifyV1 == 'function'
  14. callback = notifyV1
  15. notifyV1 = true
  16. if notifyV1
  17. V1SubscriptionManager.notifyV1OfFeaturesChange user_id, (error) ->
  18. if error?
  19. logger.err {err: error, user_id}, "error notifying v1 about updated features"
  20. jobs =
  21. individualFeatures: (cb) -> FeaturesUpdater._getIndividualFeatures user_id, cb
  22. groupFeatureSets: (cb) -> FeaturesUpdater._getGroupFeatureSets user_id, cb
  23. v1Features: (cb) -> FeaturesUpdater._getV1Features user_id, cb
  24. bonusFeatures: (cb) -> ReferalFeatures.getBonusFeatures user_id, cb
  25. async.series jobs, (err, results)->
  26. if err?
  27. logger.err err:err, user_id:user_id,
  28. "error getting subscription or group for refreshFeatures"
  29. return callback(err)
  30. {individualFeatures, groupFeatureSets, v1Features, bonusFeatures} = results
  31. logger.log {user_id, individualFeatures, groupFeatureSets, v1Features, bonusFeatures}, 'merging user features'
  32. featureSets = groupFeatureSets.concat [individualFeatures, v1Features, bonusFeatures]
  33. features = _.reduce(featureSets, FeaturesUpdater._mergeFeatures, Settings.defaultFeatures)
  34. logger.log {user_id, features}, 'updating user features'
  35. UserFeaturesUpdater.updateFeatures user_id, features, callback
  36. _getIndividualFeatures: (user_id, callback = (error, features = {}) ->) ->
  37. SubscriptionLocator.getUsersSubscription user_id, (err, sub)->
  38. callback err, FeaturesUpdater._subscriptionToFeatures(sub)
  39. _getGroupFeatureSets: (user_id, callback = (error, featureSets = []) ->) ->
  40. SubscriptionLocator.getGroupSubscriptionsMemberOf user_id, (err, subs) ->
  41. callback err, (subs or []).map FeaturesUpdater._subscriptionToFeatures
  42. _getV1Features: (user_id, callback = (error, features = {}) ->) ->
  43. V1SubscriptionManager.getPlanCodeFromV1 user_id, (err, planCode) ->
  44. callback err, FeaturesUpdater._planCodeToFeatures(planCode)
  45. _mergeFeatures: (featuresA, featuresB) ->
  46. features = Object.assign({}, featuresA)
  47. for key, value of featuresB
  48. # Special merging logic for non-boolean features
  49. if key == 'compileGroup'
  50. if features['compileGroup'] == 'priority' or featuresB['compileGroup'] == 'priority'
  51. features['compileGroup'] = 'priority'
  52. else
  53. features['compileGroup'] = 'standard'
  54. else if key == 'collaborators'
  55. if features['collaborators'] == -1 or featuresB['collaborators'] == -1
  56. features['collaborators'] = -1
  57. else
  58. features['collaborators'] = Math.max(
  59. features['collaborators'] or 0,
  60. featuresB['collaborators'] or 0
  61. )
  62. else if key == 'compileTimeout'
  63. features['compileTimeout'] = Math.max(
  64. features['compileTimeout'] or 0,
  65. featuresB['compileTimeout'] or 0
  66. )
  67. else
  68. # Boolean keys, true is better
  69. features[key] = features[key] or featuresB[key]
  70. return features
  71. _subscriptionToFeatures: (subscription) ->
  72. FeaturesUpdater._planCodeToFeatures(subscription?.planCode)
  73. _planCodeToFeatures: (planCode) ->
  74. if !planCode?
  75. return {}
  76. plan = PlansLocator.findLocalPlanInSettings planCode
  77. if !plan?
  78. return {}
  79. else
  80. return plan.features