Merge pull request #17569 from overleaf/tm-account-suspension

Add the ability to suspend user accounts

GitOrigin-RevId: 5e57f29941434c78a47354baca83527213f9b9b5
This commit is contained in:
Thomas 2024-03-21 11:38:13 +01:00 committed by Copybot
parent 92b4ff75dc
commit 811173d32d
8 changed files with 61 additions and 0 deletions

View file

@ -121,6 +121,10 @@ const AuthenticationController = {
return AsyncFormHelper.redirect(req, res, '/login')
} // OAuth2 'state' mismatch
if (user.suspended) {
return AsyncFormHelper.redirect(req, res, '/account-suspended')
}
if (Settings.adminOnlyLogin && !hasAdminAccess(user)) {
return res.status(403).json({
message: { type: 'error', text: 'Admin only panel' },

View file

@ -196,7 +196,18 @@ async function settingsPage(req, res) {
})
}
async function accountSuspended(req, res) {
if (SessionManager.isUserLoggedIn(req.session)) {
return res.redirect('/project')
}
res.render('user/accountSuspended', {
title: 'your_account_is_suspended',
})
}
const UserPagesController = {
accountSuspended: expressify(accountSuspended),
registerPage(req, res) {
const sharedProjectData = {
project_name: req.query.project_name,

View file

@ -196,6 +196,7 @@ const UserSchema = new Schema(
splitTests: Schema.Types.Mixed,
analyticsId: { type: String },
completedTutorials: Schema.Types.Mixed,
suspended: { type: Boolean },
},
{ minimize: false }
)

View file

@ -224,6 +224,8 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
AuthenticationController.passportLogin
)
webRouter.get('/account-suspended', UserPagesController.accountSuspended)
if (Settings.enableLegacyLogin) {
AuthenticationController.addEndpointToLoginWhitelist('/login/legacy')
webRouter.get('/login/legacy', UserPagesController.loginPage)

View file

@ -0,0 +1,14 @@
extends ../layout-marketing
block vars
- var suppressNavbar = true
- var suppressFooter = true
- metadata.robotsNoindexNofollow = true
block content
main.content.content-alt#main-content
.container-custom-sm.mx-auto
.card
h3 #{translate('your_account_is_suspended')}
p #{translate('sorry_this_account_has_been_suspended')}
p !{translate('please_contact_us_if_you_think_this_is_in_error', {}, [{name: 'a', attrs: {href: `mailto:${settings.adminEmail}`}}])}

View file

@ -1335,6 +1335,7 @@
"please_confirm_email": "Please confirm your email __emailAddress__ by clicking on the link in the confirmation email ",
"please_confirm_your_email_before_making_it_default": "Please confirm your email before making it the primary.",
"please_contact_support_to_makes_change_to_your_plan": "Please <0>contact support</0> to make changes to your plan",
"please_contact_us_if_you_think_this_is_in_error": "Please <0>contact us</0> if you think this is in error.",
"please_enter_confirmation_code": "Please enter your confirmation code",
"please_enter_email": "Please enter your email address",
"please_get_in_touch": "Please get in touch",
@ -1714,6 +1715,7 @@
"sorry_detected_sales_restricted_region": "Sorry, weve detected that you are in a region from which we cannot presently accept payments. If you think youve received this message in error, please <a href=\"__link__\">contact us</a> with details of your location, and we will look into this for you. We apologize for the inconvenience.",
"sorry_something_went_wrong_opening_the_document_please_try_again": "Sorry, an unexpected error occurred when trying to open this content on Overleaf. Please try again.",
"sorry_the_connection_to_the_server_is_down": "Sorry, the connection to the server is down.",
"sorry_this_account_has_been_suspended": "Sorry, this account has been suspended.",
"sorry_your_table_cant_be_displayed_at_the_moment": "Sorry, your table cant be displayed at the moment.",
"sorry_your_token_expired": "Sorry, your token expired",
"sort_by": "Sort by",
@ -2209,6 +2211,7 @@
"youll_need_to_ask_the_github_repository_owner": "Youll need to ask the GitHub repository owner (<0>__repoOwnerEmail__</0>) to reconnect the project.",
"youll_no_longer_need_to_remember_credentials": "Youll no longer need to remember a separate email address and password. Instead, you will use single-sign on to login to Overleaf. <0>Read more about SSO</0>.",
"your_account_is_managed_by_admin_cant_join_additional_group": "Your __appName__ account is managed by your current group admin (__admin__). This means you cant join additional group subscriptions. <0>Read more about Managed Users.</0>",
"your_account_is_suspended": "Your account is suspended",
"your_affiliation_is_confirmed": "Your <0>__institutionName__</0> affiliation is confirmed.",
"your_browser_does_not_support_this_feature": "Sorry, your browser doesnt support this feature. Please update your browser to its latest version.",
"your_compile_timed_out": "Your compile timed out",

View file

@ -237,6 +237,10 @@ class User {
UserModel.updateOne({ _id: this.id }, { emails }, callback)
}
setSuspended(suspended, callback) {
UserModel.updateOne({ _id: this.id }, { suspended }, callback)
}
logout(callback) {
this.getCsrfToken(error => {
if (error != null) {

View file

@ -1188,6 +1188,28 @@ describe('AuthenticationController', function () {
})
})
describe('when user account is suspended', function () {
beforeEach(function () {
this.req.session = {}
this.user.suspended = true
})
it('should not log in and instead redirect to suspended account page', function () {
this.AuthenticationController.finishLogin(
this.user,
this.req,
this.res,
this.next
)
sinon.assert.notCalled(this.req.login)
sinon.assert.calledWith(
this.AsyncFormHelper.redirect,
this.req,
this.res,
'/account-suspended'
)
})
})
describe('preFinishLogin hook', function () {
it('call hook and proceed', function () {
this.Modules.hooks.fire = sinon.stub().yields(null, [])