V1SubscriptionManager.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* eslint-disable
  2. handle-callback-err,
  3. max-len,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * DS103: Rewrite code to no longer use __guard__
  11. * DS207: Consider shorter variations of null checks
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. let V1SubscriptionManager
  15. const UserGetter = require('../User/UserGetter')
  16. const request = require('request')
  17. const settings = require('settings-sharelatex')
  18. const { V1ConnectionError, NotFoundError } = require('../Errors/Errors')
  19. module.exports = V1SubscriptionManager = {
  20. // Returned planCode = 'v1_pro' | 'v1_pro_plus' | 'v1_student' | 'v1_free' | null
  21. // For this to work, we need plans in settings with plan-codes:
  22. // - 'v1_pro'
  23. // - 'v1_pro_plus'
  24. // - 'v1_student'
  25. // - 'v1_free'
  26. getPlanCodeFromV1(userId, callback) {
  27. if (callback == null) {
  28. callback = function(err, planCode, v1Id) {}
  29. }
  30. return V1SubscriptionManager._v1Request(
  31. userId,
  32. {
  33. method: 'GET',
  34. url(v1Id) {
  35. return `/api/v1/sharelatex/users/${v1Id}/plan_code`
  36. }
  37. },
  38. function(error, body, v1Id) {
  39. if (error != null) {
  40. return callback(error)
  41. }
  42. let planName = body != null ? body.plan_name : undefined
  43. if (['pro', 'pro_plus', 'student', 'free'].includes(planName)) {
  44. planName = `v1_${planName}`
  45. } else {
  46. // Throw away 'anonymous', etc as being equivalent to null
  47. planName = null
  48. }
  49. return callback(null, planName, v1Id)
  50. }
  51. )
  52. },
  53. getSubscriptionsFromV1(userId, callback) {
  54. if (callback == null) {
  55. callback = function(err, subscriptions, v1Id) {}
  56. }
  57. return V1SubscriptionManager._v1Request(
  58. userId,
  59. {
  60. method: 'GET',
  61. url(v1Id) {
  62. return `/api/v1/sharelatex/users/${v1Id}/subscriptions`
  63. }
  64. },
  65. callback
  66. )
  67. },
  68. getSubscriptionStatusFromV1(userId, callback) {
  69. if (callback == null) {
  70. callback = function(err, status) {}
  71. }
  72. return V1SubscriptionManager._v1Request(
  73. userId,
  74. {
  75. method: 'GET',
  76. url(v1Id) {
  77. return `/api/v1/sharelatex/users/${v1Id}/subscription_status`
  78. }
  79. },
  80. callback
  81. )
  82. },
  83. cancelV1Subscription(userId, callback) {
  84. if (callback == null) {
  85. callback = function(err) {}
  86. }
  87. return V1SubscriptionManager._v1Request(
  88. userId,
  89. {
  90. method: 'DELETE',
  91. url(v1Id) {
  92. return `/api/v1/sharelatex/users/${v1Id}/subscription`
  93. }
  94. },
  95. callback
  96. )
  97. },
  98. v1IdForUser(userId, callback) {
  99. if (callback == null) {
  100. callback = function(err, v1Id) {}
  101. }
  102. return UserGetter.getUser(userId, { 'overleaf.id': 1 }, function(
  103. err,
  104. user
  105. ) {
  106. if (err != null) {
  107. return callback(err)
  108. }
  109. const v1Id = __guard__(
  110. user != null ? user.overleaf : undefined,
  111. x => x.id
  112. )
  113. return callback(null, v1Id)
  114. })
  115. },
  116. // v1 accounts created before migration to v2 had github and mendeley for free
  117. // but these are now paid-for features for new accounts (v1id > cutoff)
  118. getGrandfatheredFeaturesForV1User(v1Id) {
  119. const cutoff = settings.v1GrandfatheredFeaturesUidCutoff
  120. if (cutoff == null) {
  121. return {}
  122. }
  123. if (v1Id == null) {
  124. return {}
  125. }
  126. if (v1Id < cutoff) {
  127. return settings.v1GrandfatheredFeatures || {}
  128. } else {
  129. return {}
  130. }
  131. },
  132. _v1Request(userId, options, callback) {
  133. if (callback == null) {
  134. callback = function(err, body, v1Id) {}
  135. }
  136. if (!settings.apis.v1.url) {
  137. return callback(null, null)
  138. }
  139. return V1SubscriptionManager.v1IdForUser(userId, function(err, v1Id) {
  140. if (err != null) {
  141. return callback(err)
  142. }
  143. if (v1Id == null) {
  144. return callback(null, null, null)
  145. }
  146. const url = options.url(v1Id)
  147. return request(
  148. {
  149. baseUrl: settings.apis.v1.url,
  150. url,
  151. method: options.method,
  152. auth: {
  153. user: settings.apis.v1.user,
  154. pass: settings.apis.v1.pass,
  155. sendImmediately: true
  156. },
  157. json: true,
  158. timeout: 15 * 1000
  159. },
  160. function(error, response, body) {
  161. if (error != null) {
  162. return callback(
  163. new V1ConnectionError({
  164. message: 'no v1 connection',
  165. info: { url }
  166. }).withCause(error)
  167. )
  168. }
  169. if (response && response.statusCode >= 500) {
  170. return callback(
  171. new V1ConnectionError({
  172. message: 'error from v1',
  173. info: {
  174. status: response.statusCode,
  175. body: body
  176. }
  177. })
  178. )
  179. }
  180. if (response.statusCode >= 200 && response.statusCode < 300) {
  181. return callback(null, body, v1Id)
  182. } else {
  183. if (response.statusCode === 404) {
  184. return callback(new NotFoundError(`v1 user not found: ${userId}`))
  185. } else {
  186. return callback(
  187. new Error(
  188. `non-success code from v1: ${response.statusCode} ${
  189. options.method
  190. } ${options.url(v1Id)}`
  191. )
  192. )
  193. }
  194. }
  195. }
  196. )
  197. })
  198. }
  199. }
  200. function __guard__(value, transform) {
  201. return typeof value !== 'undefined' && value !== null
  202. ? transform(value)
  203. : undefined
  204. }