overleaf/services/web/app/src/Features/Subscription/GroupSSOHandler.js
Jessica Lawshe 8a741b89f2 Merge pull request #16082 from overleaf/jel-group-sso-already-linked
[web] Fix projection when checking if user is already enrolled in SSO

GitOrigin-RevId: eebe645cba2f911783f1b2a636a4fc51a8f6107b
2023-12-05 09:04:29 +00:00

83 lines
2.1 KiB
JavaScript

const { SSOConfig } = require('../../models/SSOConfig')
const UserAuditLogHandler = require('../User/UserAuditLogHandler')
const UserUpdater = require('../User/UserUpdater')
const SAMLIdentityManager = require('../User/SAMLIdentityManager')
const { User } = require('../../models/User')
const Errors = require('../Errors/Errors')
async function checkUserCanEnrollInSubscription(userId, subscription) {
const ssoConfig = await SSOConfig.findById(subscription?.ssoConfig).exec()
if (!ssoConfig?.enabled) {
throw new Errors.SAMLGroupSSODisabledError()
}
const userIsMember = subscription.member_ids.some(
memberId => memberId.toString() === userId.toString()
)
if (!userIsMember) {
throw new Errors.SAMLGroupSSOLoginIdentityNotFoundError()
}
const user = await User.findOne({ _id: userId }, { enrollment: 1 }).exec()
const userIsEnrolled = user.enrollment?.sso?.some(
enrollment => enrollment.groupId.toString() === subscription._id.toString()
)
if (userIsEnrolled) {
throw new Errors.SAMLIdentityExistsError()
}
}
async function enrollInSubscription(
userId,
subscription,
externalUserId,
userIdAttribute,
auditLog
) {
await checkUserCanEnrollInSubscription(userId, subscription)
const providerId = `ol-group-subscription-id:${subscription._id.toString()}`
const userBySamlIdentifier = await SAMLIdentityManager.getUser(
providerId,
externalUserId,
userIdAttribute
)
if (userBySamlIdentifier) {
throw new Errors.SAMLIdentityExistsError()
}
const samlIdentifiers = {
externalUserId,
userIdAttribute,
providerId,
}
await UserUpdater.promises.updateUser(userId, {
$push: {
samlIdentifiers,
'enrollment.sso': {
groupId: subscription._id,
linkedAt: new Date(),
primary: true,
},
},
})
await UserAuditLogHandler.promises.addEntry(
userId,
'group-sso-link',
auditLog.initiatorId,
auditLog.ipAddress,
samlIdentifiers
)
}
module.exports = {
promises: {
checkUserCanEnrollInSubscription,
enrollInSubscription,
},
}