overleaf/services/web/app/coffee/Features/Subscription/V1SubscriptionManager.coffee
Simon Detheridge 48995d2d44 Don't add old v1 features for new accounts
Introduces the notion of v1 'grandfathered features', specifically Gihub and Mendeley integration. This allows us to create new v1 accounts for new users without them automatically getting the new features.

Requires a settings change in `settings.web.sl.coffee` to disable these features by default for v1 accounts.

bug: overleaf/sharelatex#1014
2018-10-12 17:45:57 +01:00

88 lines
3 KiB
CoffeeScript

UserGetter = require "../User/UserGetter"
request = require "request"
settings = require "settings-sharelatex"
logger = require "logger-sharelatex"
{ V1ConnectionError } = require "../Errors/Errors"
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=(err, planCode, v1Id)->) ->
logger.log {userId}, "[V1SubscriptionManager] fetching v1 plan for user"
V1SubscriptionManager._v1Request userId, {
method: 'GET',
url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/plan_code"
}, (error, body, v1Id) ->
return callback(error) if error?
planName = body?.plan_name
logger.log {userId, planName, body}, "[V1SubscriptionManager] fetched v1 plan for user"
if planName in ['pro', 'pro_plus', 'student', 'free']
planName = "v1_#{planName}"
else
# Throw away 'anonymous', etc as being equivalent to null
planName = null
return callback(null, planName)
notifyV1OfFeaturesChange: (userId, callback = (error) ->) ->
V1SubscriptionManager._v1Request userId, {
method: 'POST',
url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/sync"
}, callback
getSubscriptionsFromV1: (userId, callback=(err, subscriptions, v1Id) ->) ->
V1SubscriptionManager._v1Request userId, {
method: 'GET',
url: (v1Id) -> "/api/v1/sharelatex/users/#{v1Id}/subscriptions"
}, callback
v1IdForUser: (userId, callback=(err, v1Id) ->) ->
UserGetter.getUser userId, {'overleaf.id': 1}, (err, user) ->
return callback(err) if err?
v1Id = user?.overleaf?.id
if !v1Id?
logger.log {userId}, "[V1SubscriptionManager] no v1 id found for user"
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) ->
cutoff = settings.v1GrandfatheredFeaturesUidCutoff
return {} if !cutoff?
return {} if !v1Id?
if (v1Id < cutoff)
return settings.v1GrandfatheredFeatures or {}
else
return {}
_v1Request: (userId, options, callback=(err, body, v1Id)->) ->
if !settings?.apis?.v1
return callback null, null
V1SubscriptionManager.v1IdForUser userId, (err, v1Id) ->
return callback(err) if err?
return callback(null, null) if !v1Id?
request {
baseUrl: settings.apis.v1.url
url: options.url(v1Id)
method: options.method
auth:
user: settings.apis.v1.user
pass: settings.apis.v1.pass
sendImmediately: true
json: true,
timeout: 5 * 1000
}, (error, response, body) ->
if error?
# Specially handle no connection err, so warning can be shown
error = new V1ConnectionError('No V1 connection') if error.code == 'ECONNREFUSED'
return callback(error)
if 200 <= response.statusCode < 300
return callback null, body, v1Id
else
return callback new Error("non-success code from v1: #{response.statusCode}")