[web] Send email to support when skipping deleting pro group subscription (#19971)

* Move group SSO enabled check up

So that we have this available when managed users is enabled. This will be useful in the following commit.

* Notify support when subscription deletion skipped

* Fix rebase conflicts

---------

Co-authored-by: mserranom <mserranom@gmail.com>
GitOrigin-RevId: 8a4abe0742ab6a1c6b15bb17b5cc4863a11010b2
This commit is contained in:
Jessica Lawshe 2024-11-11 03:52:41 -06:00 committed by Copybot
parent 7f675ac006
commit 4d8a6c5c9d
2 changed files with 123 additions and 17 deletions

View file

@ -11,6 +11,8 @@ const logger = require('@overleaf/logger')
const Features = require('../../infrastructure/Features')
const UserAuditLogHandler = require('../User/UserAuditLogHandler')
const { SSOConfig } = require('../../models/SSOConfig')
const Modules = require('../../infrastructure/Modules')
const Settings = require('@overleaf/settings')
/**
* Change the admin of the given subscription.
@ -249,6 +251,29 @@ async function _deleteAndReplaceSubscriptionFromRecurly(
)
}
async function _notifySupportSubscriptionDeletionSkipped(
subscription,
recurlySubscription,
hasGroupSSOEnabled
) {
const adminUrl = `${Settings.adminUrl + '/admin/user/' + subscription.admin_id}`
const groupUrl = `${Settings.adminUrl + '/admin/group/' + subscription._id}`
let message = `\n**Recurly account:** <a href="${recurlySubscription?.account?.url}">${recurlySubscription?.account?.url}</a>`
message += `\n**Group admin:** <a href="${adminUrl}">${adminUrl}</a>`
message += `\n**Group:** <a href="${groupUrl}">${groupUrl}</a>`
message += `\n**Managed users enabled:** ${subscription?.managedUsersEnabled}`
message += `\n**SSO enabled:** ${hasGroupSSOEnabled}`
const data = {
subject: 'Skipped deleting pro group subscription',
inbox: 'support',
tags: 'Group subscription',
message,
}
await Modules.promises.hooks.fire('sendSupportRequest', data)
}
async function updateSubscriptionFromRecurly(
recurlySubscription,
subscription,
@ -258,6 +283,18 @@ async function updateSubscriptionFromRecurly(
const hasManagedUsersFeature =
Features.hasFeature('saas') && subscription?.managedUsersEnabled
let hasGroupSSOEnabled = false
if (subscription?.ssoConfig) {
const ssoConfig = await SSOConfig.findOne({
_id: subscription.ssoConfig._id || subscription.ssoConfig,
})
.lean()
.exec()
if (ssoConfig.enabled) {
hasGroupSSOEnabled = true
}
}
// If a payment lapses and if the group is managed or has group SSO, as a temporary measure we need to
// make sure that the group continues as-is and no destructive actions are taken.
if (hasManagedUsersFeature) {
@ -265,28 +302,39 @@ async function updateSubscriptionFromRecurly(
{ subscriptionId: subscription._id },
'expired subscription has managedUsers feature enabled, skipping deletion'
)
} else {
let hasGroupSSOEnabled = false
if (subscription?.ssoConfig) {
const ssoConfig = await SSOConfig.findOne({
_id: subscription.ssoConfig._id || subscription.ssoConfig,
})
.lean()
.exec()
if (ssoConfig.enabled) {
hasGroupSSOEnabled = true
}
}
if (hasGroupSSOEnabled) {
try {
await _notifySupportSubscriptionDeletionSkipped(
subscription,
recurlySubscription,
hasGroupSSOEnabled
)
} catch (e) {
logger.warn(
{ subscriptionId: subscription._id },
'expired subscription has groupSSO feature enabled, skipping deletion'
'unable to send notification to support that subscription deletion was skipped'
)
} else {
await deleteSubscription(subscription, requesterData)
}
} else if (hasGroupSSOEnabled) {
logger.warn(
{ subscriptionId: subscription._id },
'expired subscription has groupSSO feature enabled, skipping deletion'
)
try {
await _notifySupportSubscriptionDeletionSkipped(
subscription,
recurlySubscription,
hasGroupSSOEnabled
)
} catch (e) {
logger.warn(
{ subscriptionId: subscription._id },
'unable to send notification to support that subscription deletion was skipped'
)
}
} else {
await deleteSubscription(subscription, requesterData)
}
return
}
const updatedPlanCode = recurlySubscription.plan.plan_code

View file

@ -13,6 +13,9 @@ describe('SubscriptionUpdater', function () {
plan: {
plan_code: this.recurlyPlan.planCode,
},
account: {
url: 'test_url',
},
}
this.adminUser = { _id: (this.adminuser_id = '5208dd34438843e2db000007') }
@ -26,6 +29,7 @@ describe('SubscriptionUpdater', function () {
save: sinon.stub().resolves(),
planCode: 'student_or_something',
recurlySubscription_id: 'abc123def456fab789',
managedUsersEnabled: false,
}
this.user_id = this.adminuser_id
@ -120,6 +124,7 @@ describe('SubscriptionUpdater', function () {
},
},
],
adminUrl: 'test_admin_url',
}
this.UserFeaturesUpdater = {
@ -177,6 +182,13 @@ describe('SubscriptionUpdater', function () {
'../Analytics/AnalyticsManager': this.AnalyticsManager,
'../../infrastructure/Features': this.Features,
'../User/UserAuditLogHandler': this.UserAuditLogHandler,
'../../infrastructure/Modules': (this.Modules = {
promises: {
hooks: {
fire: sinon.stub().resolves(),
},
},
}),
},
})
})
@ -316,6 +328,52 @@ describe('SubscriptionUpdater', function () {
{}
)
this.SubscriptionModel.deleteOne.should.not.have.been.called
const adminUrl = `${this.Settings.adminUrl + '/admin/user/' + this.subscription.admin_id}`
const groupUrl = `${this.Settings.adminUrl + '/admin/group/' + this.subscription._id}`
let message = `\n**Recurly account:** <a href="${this.recurlySubscription?.account?.url}">${this.recurlySubscription.account?.url}</a>`
message += `\n**Group admin:** <a href="${adminUrl}">${adminUrl}</a>`
message += `\n**Group:** <a href="${groupUrl}">${groupUrl}</a>`
message += `\n**Managed users enabled:** false`
message += `\n**SSO enabled:** true`
expect(this.Modules.promises.hooks.fire).to.have.been.calledOnce
expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
'sendSupportRequest',
{
subject: 'Skipped deleting pro group subscription',
inbox: 'support',
tags: 'Group subscription',
message,
}
)
})
it('should not remove the subscription when expired if it has managed users is enabled', async function () {
this.Features.hasFeature.withArgs('saas').returns(true)
this.subscription.managedUsersEnabled = true
this.recurlySubscription.state = 'expired'
await this.SubscriptionUpdater.promises.updateSubscriptionFromRecurly(
this.recurlySubscription,
this.subscription,
{}
)
this.SubscriptionModel.deleteOne.should.not.have.been.called
const adminUrl = `${this.Settings.adminUrl + '/admin/user/' + this.subscription.admin_id}`
const groupUrl = `${this.Settings.adminUrl + '/admin/group/' + this.subscription._id}`
let message = `\n**Recurly account:** <a href="${this.recurlySubscription?.account?.url}">${this.recurlySubscription.account?.url}</a>`
message += `\n**Group admin:** <a href="${adminUrl}">${adminUrl}</a>`
message += `\n**Group:** <a href="${groupUrl}">${groupUrl}</a>`
message += `\n**Managed users enabled:** true`
message += `\n**SSO enabled:** false`
expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
'sendSupportRequest',
{
subject: 'Skipped deleting pro group subscription',
inbox: 'support',
tags: 'Group subscription',
message,
}
)
})
it('should update all the users features', async function () {