Merge pull request #6099 from overleaf/jpa-recurly-redirect

[web] put hosted recurly pages behind a redirect

GitOrigin-RevId: 51a45dbcc0b74f1f1ae14eda9ed19a733e2d1334
This commit is contained in:
Timothée Alby 2021-12-14 14:26:07 +01:00 committed by Copybot
parent e225f6e8d7
commit 5eed78a3e8
4 changed files with 54 additions and 16 deletions

View file

@ -1017,6 +1017,7 @@ const RecurlyWrapper = {
}
RecurlyWrapper.promises = {
getSubscription: promisify(RecurlyWrapper.getSubscription),
updateAccountEmailAddress: promisify(updateAccountEmailAddress),
}

View file

@ -482,6 +482,17 @@ async function refreshUserFeatures(req, res) {
res.sendStatus(200)
}
async function redirectToHostedPage(req, res) {
const userId = SessionManager.getLoggedInUserId(req.session)
const { pageType } = req.params
const url = await SubscriptionViewModelBuilder.promises.getRedirectToHostedPage(
userId,
pageType
)
logger.warn({ userId, pageType }, 'redirecting to recurly hosted page')
res.redirect(url)
}
module.exports = {
plansPage: expressify(plansPage),
paymentPage: expressify(paymentPage),
@ -501,4 +512,5 @@ module.exports = {
extendTrial: expressify(extendTrial),
recurlyNotificationParser,
refreshUserFeatures: expressify(refreshUserFeatures),
redirectToHostedPage: expressify(redirectToHostedPage),
}

View file

@ -47,6 +47,12 @@ module.exports = {
SubscriptionController.canceledSubscription
)
webRouter.get(
'/user/subscription/recurly/:pageType',
AuthenticationController.requireLogin(),
SubscriptionController.redirectToHostedPage
)
webRouter.delete(
'/subscription/group/user',
AuthenticationController.requireLogin(),

View file

@ -11,23 +11,44 @@ const _ = require('underscore')
const async = require('async')
const SubscriptionHelper = require('./SubscriptionHelper')
const { promisify } = require('../../util/promises')
const { InvalidError, NotFoundError } = require('../Errors/Errors')
function buildHostedLink(type) {
return `/user/subscription/recurly/${type}`
}
async function getRedirectToHostedPage(userId, pageType) {
if (!['billing-details', 'account-management'].includes(pageType)) {
throw new InvalidError('unexpected page type')
}
const personalSubscription = await SubscriptionLocator.getUsersSubscription(
userId
)
const recurlySubscriptionId = personalSubscription?.recurlySubscription_id
if (!recurlySubscriptionId) {
throw new NotFoundError('not a recurly subscription')
}
const recurlySubscription = await RecurlyWrapper.promises.getSubscription(
recurlySubscriptionId,
{ includeAccount: true }
)
function buildHostedLink(recurlySubscription, type) {
const recurlySubdomain = Settings.apis.recurly.subdomain
const hostedLoginToken = recurlySubscription.account.hosted_login_token
if (!hostedLoginToken) {
throw new Error('recurly account does not have hosted login token')
}
let path = ''
if (type === 'billingDetails') {
if (pageType === 'billing-details') {
path = 'billing_info/edit?ht='
}
if (hostedLoginToken && recurlySubdomain) {
return [
'https://',
recurlySubdomain,
'.recurly.com/account/',
path,
hostedLoginToken,
].join('')
}
return [
'https://',
recurlySubdomain,
'.recurly.com/account/',
path,
hostedLoginToken,
].join('')
}
function buildUsersSubscriptionViewModel(user, callback) {
@ -178,11 +199,8 @@ function buildUsersSubscriptionViewModel(user, callback) {
taxRate: recurlySubscription.tax_rate
? parseFloat(recurlySubscription.tax_rate._)
: 0,
billingDetailsLink: buildHostedLink(
recurlySubscription,
'billingDetails'
),
accountManagementLink: buildHostedLink(recurlySubscription),
billingDetailsLink: buildHostedLink('billing-details'),
accountManagementLink: buildHostedLink('account-management'),
additionalLicenses,
totalLicenses,
nextPaymentDueAt: SubscriptionFormatters.formatDate(
@ -335,5 +353,6 @@ module.exports = {
buildPlansList,
promises: {
buildUsersSubscriptionViewModel: promisify(buildUsersSubscriptionViewModel),
getRedirectToHostedPage,
},
}