diff --git a/services/web/app/src/Features/Subscription/SubscriptionUpdater.js b/services/web/app/src/Features/Subscription/SubscriptionUpdater.js index 7fee0f1a58..a9bf0e44b9 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionUpdater.js +++ b/services/web/app/src/Features/Subscription/SubscriptionUpdater.js @@ -10,6 +10,7 @@ const { DeletedSubscription } = require('../../models/DeletedSubscription') const logger = require('@overleaf/logger') const Features = require('../../infrastructure/Features') const UserAuditLogHandler = require('../User/UserAuditLogHandler') +const { SSOConfig } = require('../../models/SSOConfig') /** * Change the admin of the given subscription. @@ -257,15 +258,35 @@ async function updateSubscriptionFromRecurly( if (recurlySubscription.state === 'expired') { const hasManagedUsersFeature = Features.hasFeature('saas') && subscription?.managedUsersEnabled + + // 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) { - // If a payment lapses and if the group is managed, as a temporary measure we need to - // make sure that the group continues as-is and no destructive actions are taken. logger.warn( { subscriptionId: subscription._id }, - 'expired subscription has managedUsers feature, skipping deletion' + 'expired subscription has managedUsers feature enabled, skipping deletion' ) } else { - await deleteSubscription(subscription, requesterData) + 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) { + logger.warn( + { subscriptionId: subscription._id }, + 'expired subscription has groupSSO feature enabled, skipping deletion' + ) + } else { + await deleteSubscription(subscription, requesterData) + } } return } diff --git a/services/web/test/unit/src/Subscription/SubscriptionUpdaterTests.js b/services/web/test/unit/src/Subscription/SubscriptionUpdaterTests.js index f2abc445af..0ad660e19f 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionUpdaterTests.js +++ b/services/web/test/unit/src/Subscription/SubscriptionUpdaterTests.js @@ -77,6 +77,13 @@ describe('SubscriptionUpdater', function () { exec: sinon.stub().resolves(this.subscription), }) + this.SSOConfigModel = class {} + this.SSOConfigModel.findOne = sinon.stub().returns({ + lean: sinon.stub().returns({ + exec: sinon.stub().resolves({ enabled: true }), + }), + }) + this.SubscriptionLocator = { promises: { getUsersSubscription: sinon.stub(), @@ -158,6 +165,7 @@ describe('SubscriptionUpdater', function () { '../../models/Subscription': { Subscription: this.SubscriptionModel, }, + '../../models/SSOConfig': { SSOConfig: this.SSOConfigModel }, './UserFeaturesUpdater': this.UserFeaturesUpdater, './SubscriptionLocator': this.SubscriptionLocator, '@overleaf/settings': this.Settings, @@ -284,7 +292,7 @@ describe('SubscriptionUpdater', function () { }) }) - it('should not remove the subscription when expired if it has "managedUsers" feature', async function () { + it('should not remove the subscription when expired if it has Managed Users enabled', async function () { this.Features.hasFeature.withArgs('saas').returns(true) this.subscription.managedUsersEnabled = true @@ -297,6 +305,19 @@ describe('SubscriptionUpdater', function () { this.SubscriptionModel.deleteOne.should.not.have.been.called }) + it('should not remove the subscription when expired if it has Group SSO enabled', async function () { + this.Features.hasFeature.withArgs('saas').returns(true) + this.subscription.ssoConfig = new ObjectId('abc123abc123') + + this.recurlySubscription.state = 'expired' + await this.SubscriptionUpdater.promises.updateSubscriptionFromRecurly( + this.recurlySubscription, + this.subscription, + {} + ) + this.SubscriptionModel.deleteOne.should.not.have.been.called + }) + it('should update all the users features', async function () { this.subscription.member_ids = this.allUserIds await this.SubscriptionUpdater.promises.updateSubscriptionFromRecurly(