overleaf/services/web/app/src/Features/Subscription/V1SubscriptionManager.js
Jakob Ackermann 7f9fd00bda Merge pull request #5367 from overleaf/jpa-node-handle-callback-err
[misc] fix eslint violations for node/handle-callback-err

GitOrigin-RevId: 83a4900e8861010df1917bff49382bd9c93375bd
2021-10-28 08:03:26 +00:00

228 lines
6 KiB
JavaScript

/* eslint-disable
node/handle-callback-err,
max-len,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS103: Rewrite code to no longer use __guard__
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
let V1SubscriptionManager
const UserGetter = require('../User/UserGetter')
const request = require('requestretry')
const settings = require('@overleaf/settings')
const { V1ConnectionError, NotFoundError } = require('../Errors/Errors')
const { promisifyAll } = require('../../util/promises')
module.exports = V1SubscriptionManager = {
// Returned planCode = 'v1_pro' | 'v1_pro_plus' | 'v1_student' | 'v1_free' | null
// For this to work, we need plans in settings with plan-codes:
// - 'v1_pro'
// - 'v1_pro_plus'
// - 'v1_student'
// - 'v1_free'
getPlanCodeFromV1(userId, callback) {
if (callback == null) {
callback = function () {}
}
return V1SubscriptionManager._v1Request(
userId,
{
method: 'GET',
url(v1Id) {
return `/api/v1/sharelatex/users/${v1Id}/plan_code`
},
},
function (error, body, v1Id) {
if (error != null) {
return callback(error)
}
let planName = body != null ? body.plan_name : undefined
if (['pro', 'pro_plus', 'student', 'free'].includes(planName)) {
planName = `v1_${planName}`
} else {
// Throw away 'anonymous', etc as being equivalent to null
planName = null
}
return callback(null, planName, v1Id)
}
)
},
getSubscriptionsFromV1(userId, callback) {
if (callback == null) {
callback = function () {}
}
return V1SubscriptionManager._v1Request(
userId,
{
method: 'GET',
url(v1Id) {
return `/api/v1/sharelatex/users/${v1Id}/subscriptions`
},
},
callback
)
},
getSubscriptionStatusFromV1(userId, callback) {
if (callback == null) {
callback = function () {}
}
return V1SubscriptionManager._v1Request(
userId,
{
method: 'GET',
url(v1Id) {
return `/api/v1/sharelatex/users/${v1Id}/subscription_status`
},
},
callback
)
},
cancelV1Subscription(userId, callback) {
if (callback == null) {
callback = function () {}
}
return V1SubscriptionManager._v1Request(
userId,
{
method: 'DELETE',
url(v1Id) {
return `/api/v1/sharelatex/users/${v1Id}/subscription`
},
},
callback
)
},
v1IdForUser(userId, callback) {
if (callback == null) {
callback = function () {}
}
return UserGetter.getUser(
userId,
{ 'overleaf.id': 1 },
function (err, user) {
if (err != null) {
return callback(err)
}
const v1Id = __guard__(
user != null ? user.overleaf : undefined,
x => x.id
)
return callback(null, v1Id)
}
)
},
// v1 accounts created before migration to v2 had github and mendeley for free
// but these are now paid-for features for new accounts (v1id > cutoff)
getGrandfatheredFeaturesForV1User(v1Id) {
const cutoff = settings.v1GrandfatheredFeaturesUidCutoff
if (cutoff == null) {
return {}
}
if (v1Id == null) {
return {}
}
if (v1Id < cutoff) {
return settings.v1GrandfatheredFeatures || {}
} else {
return {}
}
},
_v1Request(userId, options, callback) {
if (callback == null) {
callback = function () {}
}
if (!settings.apis.v1.url) {
return callback(null, null)
}
return V1SubscriptionManager.v1IdForUser(userId, function (err, v1Id) {
if (err != null) {
return callback(err)
}
if (v1Id == null) {
return callback(null, null, null)
}
const url = options.url(v1Id)
const requestOptions = {
baseUrl: settings.apis.v1.url,
url,
method: options.method,
auth: {
user: settings.apis.v1.user,
pass: settings.apis.v1.pass,
sendImmediately: true,
},
json: true,
timeout: 15 * 1000,
}
if (options.method === 'GET') {
requestOptions.maxAttempts = 3
requestOptions.retryDelay = 500
} else {
requestOptions.maxAttempts = 0
}
request(requestOptions, function (error, response, body) {
if (error != null) {
return callback(
new V1ConnectionError({
message: 'no v1 connection',
info: { url },
}).withCause(error)
)
}
if (response && response.statusCode >= 500) {
return callback(
new V1ConnectionError({
message: 'error from v1',
info: {
status: response.statusCode,
body: body,
},
})
)
}
if (response.statusCode >= 200 && response.statusCode < 300) {
return callback(null, body, v1Id)
} else {
if (response.statusCode === 404) {
return callback(new NotFoundError(`v1 user not found: ${userId}`))
} else {
return callback(
new Error(
`non-success code from v1: ${response.statusCode} ${
options.method
} ${options.url(v1Id)}`
)
)
}
}
})
})
},
}
function __guard__(value, transform) {
return typeof value !== 'undefined' && value !== null
? transform(value)
: undefined
}
module.exports.promises = promisifyAll(module.exports, {
without: ['getGrandfatheredFeaturesForV1User'],
multiResult: {
getPlanCodeFromV1: ['planCode', 'v1Id'],
},
})