/* 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('request') 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 (err, planCode, v1Id) {} } 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 (err, subscriptions, v1Id) {} } return V1SubscriptionManager._v1Request( userId, { method: 'GET', url(v1Id) { return `/api/v1/sharelatex/users/${v1Id}/subscriptions` }, }, callback ) }, getSubscriptionStatusFromV1(userId, callback) { if (callback == null) { callback = function (err, status) {} } 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 (err) {} } return V1SubscriptionManager._v1Request( userId, { method: 'DELETE', url(v1Id) { return `/api/v1/sharelatex/users/${v1Id}/subscription` }, }, callback ) }, v1IdForUser(userId, callback) { if (callback == null) { callback = function (err, v1Id) {} } 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 (err, body, v1Id) {} } 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) return request( { 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, }, 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'], }, })