diff --git a/services/web/app/src/Features/Project/ProjectListController.mjs b/services/web/app/src/Features/Project/ProjectListController.mjs
index 8c173e0f6d..c8031150c7 100644
--- a/services/web/app/src/Features/Project/ProjectListController.mjs
+++ b/services/web/app/src/Features/Project/ProjectListController.mjs
@@ -115,7 +115,7 @@ async function projectListPage(req, res, next) {
})
const user = await User.findById(
userId,
- `email emails features alphaProgram betaProgram lastPrimaryEmailCheck labsProgram signUpDate${
+ `email emails features alphaProgram betaProgram lastPrimaryEmailCheck signUpDate${
isSaas ? ' enrollment writefull completedTutorials' : ''
}`
)
diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js
index 33f65c97e3..0744e7c6b9 100644
--- a/services/web/config/settings.defaults.js
+++ b/services/web/config/settings.defaults.js
@@ -972,7 +972,6 @@ module.exports = {
editorLeftMenuManageTemplate: [],
oauth2Server: [],
managedGroupSubscriptionEnrollmentNotification: [],
- userNotifications: [],
managedGroupEnrollmentInvite: [],
ssoCertificateInfo: [],
v1ImportDataScreen: [],
diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json
index 9c48a99cdc..29e3fe1b16 100644
--- a/services/web/frontend/extracted-translations.json
+++ b/services/web/frontend/extracted-translations.json
@@ -555,7 +555,6 @@
"get_collaborative_benefits": "",
"get_discounted_plan": "",
"get_dropbox_sync": "",
- "get_early_access_to_ai": "",
"get_error_assist": "",
"get_exclusive_access_to_labs": "",
"get_full_project_history": "",
@@ -564,7 +563,6 @@
"get_in_touch": "",
"get_more_compile_time": "",
"get_most_subscription_by_checking_features": "",
- "get_some_texnical_assistance": "",
"get_symbol_palette": "",
"get_track_changes": "",
"git": "",
diff --git a/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx b/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx
index b42ad87347..0f638aaa08 100644
--- a/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx
+++ b/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx
@@ -1,4 +1,4 @@
-import { JSXElementConstructor, useState, ElementType } from 'react'
+import { JSXElementConstructor, useState } from 'react'
import Common from './groups/common'
import Institution from './groups/institution'
import ConfirmEmail from './groups/confirm-email'
@@ -23,11 +23,6 @@ const [enrollmentNotificationModule] = importOverleafModules(
const [usGovBannerModule] = importOverleafModules('usGovBanner')
-const moduleNotifications = importOverleafModules('userNotifications') as {
- import: { default: ElementType }
- path: string
-}[]
-
const EnrollmentNotification: JSXElementConstructor<{
groupId: string
groupName: string
@@ -95,11 +90,6 @@ function UserNotifications() {
setDismissedWritefull(true)
}}
/>
- {moduleNotifications.map(({ import: { default: Component }, path }) => (
-
- ))}
-
- {isDeprecatedBrowser() && }
)
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index c5dbd30031..f14e226c86 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -792,7 +792,6 @@
"get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline",
"get_discounted_plan": "Get discounted plan",
"get_dropbox_sync": "Get Dropbox Sync",
- "get_early_access_to_ai": "Get early access to the new AI Error Assistant in Overleaf Labs",
"get_error_assist": "Get Error Assist",
"get_exclusive_access_to_labs": "Get exclusive access to early-stage experiments when you join Overleaf Labs. All we ask in return is your honest feedback to help us develop and improve.",
"get_full_project_history": "Get full project history",
@@ -803,7 +802,6 @@
"get_involved": "Get involved",
"get_more_compile_time": "Get more compile time",
"get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__’s features0>.",
- "get_some_texnical_assistance": "Get some TeXnical assistance from AI to fix errors in your project.",
"get_symbol_palette": "Get Symbol Palette",
"get_the_best_overleaf_experience": "Get the best Overleaf experience",
"get_the_best_writing_experience": "Get the best writing experience",
diff --git a/services/web/scripts/remove_feature_from_all_users.mjs b/services/web/scripts/remove_feature_from_all_users.mjs
new file mode 100644
index 0000000000..fe53bda39a
--- /dev/null
+++ b/services/web/scripts/remove_feature_from_all_users.mjs
@@ -0,0 +1,53 @@
+import {
+ db,
+ READ_PREFERENCE_SECONDARY,
+} from '../app/src/infrastructure/mongodb.js'
+import parseArgs from 'minimist'
+
+async function _removeFeatureFromAllUsers(feature, commit) {
+ let removals = 0
+ const query = {}
+ query[`features.${feature}`] = true
+ const usersWithFeature = db.users.find(query, {
+ readPreference: READ_PREFERENCE_SECONDARY,
+ })
+
+ const update = {}
+ update[`features.${feature}`] = false
+ while (await usersWithFeature.hasNext()) {
+ const user = await usersWithFeature.next()
+ if (commit) {
+ await db.users.findOneAndUpdate({ _id: user._id }, { $set: update })
+ }
+ removals++
+ }
+ console.log(`removed ${feature} from ${removals} users`)
+ if (!commit) {
+ console.log(
+ 'this was a dry run, pass --commit to remove features from users'
+ )
+ }
+}
+
+async function main() {
+ const argv = parseArgs(process.argv.slice(2), {
+ string: ['feature'],
+ boolean: ['commit'],
+ unknown: function (arg) {
+ console.error('unrecognised argument', arg)
+ process.exit(1)
+ },
+ })
+ const feature = argv.feature
+ const commit = argv.commit || false
+ await _removeFeatureFromAllUsers(feature, commit)
+}
+
+try {
+ await main()
+ console.log('Done')
+ process.exit(0)
+} catch (error) {
+ console.error(error)
+ process.exit(1)
+}