From 912324f5600de0ecc801480e2eefa3d6d20a4871 Mon Sep 17 00:00:00 2001 From: Andrew Rumble Date: Wed, 22 Oct 2025 13:50:38 +0100 Subject: [PATCH] Convert to ESM GitOrigin-RevId: b58b02f9e9c8d47909e95c3ade8e1bf33ed46c80 --- .../Analytics/AccountMappingHelper.mjs | 2 +- .../Features/Analytics/AnalyticsManager.mjs | 21 ++++---- .../AnalyticsRegistrationSourceHelper.mjs | 6 +-- .../Features/Analytics/EmailChangeHelper.mjs | 9 ++-- .../src/Features/Analytics/RequestHelper.mjs | 6 +-- .../Analytics/UserAnalyticsIdCache.mjs | 8 ++-- .../Authentication/AuthenticationManager.mjs | 33 +++++++------ .../Authentication/HaveIBeenPwned.mjs | 15 +++--- .../Authentication/SessionManager.mjs | 4 +- .../Authorization/PublicAccessLevels.mjs | 2 +- .../src/Features/Authorization/Sources.mjs | 2 +- .../app/src/Features/Chat/ChatApiHandler.mjs | 9 ++-- .../CollaboratorsInviteGetter.mjs | 10 ++-- .../CollaboratorsInviteHelper.mjs | 4 +- .../src/Features/Compile/ClsiCacheHandler.mjs | 18 +++---- .../src/Features/Contacts/ContactManager.mjs | 10 ++-- .../src/Features/Docstore/DocstoreManager.mjs | 19 ++++---- .../src/Features/Documents/DocumentHelper.mjs | 3 +- .../Editor/EditorRealTimeController.mjs | 12 ++--- .../app/src/Features/Email/EmailBuilder.mjs | 20 ++++---- .../app/src/Features/Email/EmailHandler.mjs | 14 +++--- .../src/Features/Email/EmailOptionsHelper.mjs | 2 +- .../app/src/Features/Email/EmailSender.mjs | 20 ++++---- .../web/app/src/Features/Email/SpamSafe.mjs | 4 +- .../src/Features/Errors/HttpErrorHandler.mjs | 9 ++-- .../Features/FileStore/FileHashManager.mjs | 10 ++-- .../src/Features/Helpers/AsyncFormHelper.mjs | 6 +-- .../Features/Helpers/SafeHTMLSubstitution.mjs | 4 +- .../app/src/Features/Helpers/StringHelper.mjs | 2 +- .../app/src/Features/Helpers/UrlHelper.mjs | 6 +-- .../History/HistoryBackupDeletionHandler.mjs | 6 +-- .../Features/Institutions/InstitutionsAPI.mjs | 25 +++++----- .../Institutions/InstitutionsFeatures.mjs | 11 +++-- .../Institutions/InstitutionsHelper.mjs | 2 +- .../Features/Newsletter/MailChimpClient.mjs | 4 +- .../Features/Newsletter/MailChimpProvider.mjs | 14 +++--- .../Features/Newsletter/NewsletterManager.mjs | 6 +-- .../Notifications/NotificationsBuilder.mjs | 16 ++++--- .../Notifications/NotificationsHandler.mjs | 12 ++--- .../OnboardingDataCollectionManager.mjs | 12 ++--- .../Project/FolderStructureBuilder.mjs | 10 ++-- .../Features/Project/ProjectEditorHandler.mjs | 6 +-- .../src/Features/Project/ProjectHelper.mjs | 12 +++-- .../Project/ProjectOptionsHandler.mjs | 16 ++++--- .../Features/Project/ProjectUpdateHandler.mjs | 6 +-- .../web/app/src/Features/Project/SafePath.mjs | 2 +- .../Features/Publishers/PublishersGetter.mjs | 14 +++--- .../src/Features/Referal/ReferalFeatures.mjs | 10 ++-- .../src/Features/SplitTests/LocalsHelper.mjs | 2 +- .../Features/SplitTests/SplitTestCache.mjs | 8 ++-- .../Features/SplitTests/SplitTestHandler.mjs | 38 +++++++-------- .../Features/SplitTests/SplitTestManager.mjs | 12 ++--- .../SplitTests/SplitTestSessionHandler.mjs | 22 +++++---- .../SplitTests/SplitTestUserGetter.mjs | 8 ++-- .../Features/SplitTests/SplitTestUtils.mjs | 4 +- .../Features/Subscription/FeaturesHelper.mjs | 6 +-- .../Features/Subscription/FeaturesUpdater.mjs | 38 +++++++-------- .../Subscription/PaymentProviderEntities.mjs | 17 +++---- .../Features/Subscription/PlansLocator.mjs | 7 +-- .../Features/Subscription/RecurlyClient.mjs | 31 ++++++------ .../Features/Subscription/RecurlyMetrics.mjs | 4 +- .../Features/Subscription/RecurlyWrapper.mjs | 22 ++++----- .../Subscription/SubscriptionLocator.mjs | 17 +++---- .../Subscription/SubscriptionUpdater.mjs | 36 +++++++------- .../Subscription/UserFeaturesUpdater.mjs | 8 ++-- .../Subscription/V1SubscriptionManager.mjs | 17 +++---- .../web/app/src/Features/Tags/TagsHandler.mjs | 6 +-- .../TokenAccess/TokenAccessHandler.mjs | 29 ++++++----- .../src/Features/Uploads/ArchiveManager.mjs | 25 +++++----- .../src/Features/Uploads/FileTypeManager.mjs | 15 +++--- .../User/ThirdPartyIdentityManager.mjs | 22 ++++----- .../src/Features/User/UserAuditLogHandler.mjs | 12 ++--- .../web/app/src/Features/User/UserGetter.mjs | 32 ++++++------- .../src/Features/User/UserSessionsManager.mjs | 14 +++--- .../src/Features/User/UserSessionsRedis.mjs | 4 +- .../web/app/src/Features/User/UserUpdater.mjs | 48 +++++++++---------- .../UserMembershipEntityConfigs.mjs | 2 +- .../UserMembership/UserMembershipsHandler.mjs | 19 +++++--- 78 files changed, 515 insertions(+), 484 deletions(-) diff --git a/services/web/app/src/Features/Analytics/AccountMappingHelper.mjs b/services/web/app/src/Features/Analytics/AccountMappingHelper.mjs index 4568047d37..2361ea004f 100644 --- a/services/web/app/src/Features/Analytics/AccountMappingHelper.mjs +++ b/services/web/app/src/Features/Analytics/AccountMappingHelper.mjs @@ -116,7 +116,7 @@ function generateSubscriptionToStripeMapping( } } -module.exports = { +export default { extractAccountMappingsFromSubscription, generateV1Mapping, generateSubscriptionToRecurlyMapping, diff --git a/services/web/app/src/Features/Analytics/AnalyticsManager.mjs b/services/web/app/src/Features/Analytics/AnalyticsManager.mjs index 5f50d6fe35..272cf68497 100644 --- a/services/web/app/src/Features/Analytics/AnalyticsManager.mjs +++ b/services/web/app/src/Features/Analytics/AnalyticsManager.mjs @@ -1,13 +1,12 @@ -const SessionManager = require('../Authentication/SessionManager') -const UserAnalyticsIdCache = require('./UserAnalyticsIdCache') -const Settings = require('@overleaf/settings') -const Metrics = require('../../infrastructure/Metrics') -const Queues = require('../../infrastructure/Queues') -const crypto = require('crypto') -const _ = require('lodash') -const { expressify } = require('@overleaf/promise-utils') -const logger = require('@overleaf/logger') -const { createHash } = require('crypto') +import SessionManager from '../Authentication/SessionManager.mjs' +import UserAnalyticsIdCache from './UserAnalyticsIdCache.mjs' +import Settings from '@overleaf/settings' +import Metrics from '../../infrastructure/Metrics.js' +import Queues from '../../infrastructure/Queues.js' +import crypto, { createHash } from 'node:crypto' +import _ from 'lodash' +import { expressify } from '@overleaf/promise-utils' +import logger from '@overleaf/logger' if ( Settings.analytics?.enabled && @@ -450,7 +449,7 @@ async function analyticsIdMiddleware(req, res, next) { next() } -module.exports = { +export default { identifyUser, recordEventForSession, recordEventForUser, diff --git a/services/web/app/src/Features/Analytics/AnalyticsRegistrationSourceHelper.mjs b/services/web/app/src/Features/Analytics/AnalyticsRegistrationSourceHelper.mjs index 6166f0859e..4fdc6e42c9 100644 --- a/services/web/app/src/Features/Analytics/AnalyticsRegistrationSourceHelper.mjs +++ b/services/web/app/src/Features/Analytics/AnalyticsRegistrationSourceHelper.mjs @@ -1,5 +1,5 @@ -const AnalyticsManager = require('./AnalyticsManager') -const RequestHelper = require('./RequestHelper') +import AnalyticsManager from './AnalyticsManager.mjs' +import RequestHelper from './RequestHelper.mjs' function clearSource(session) { if (session) { @@ -88,7 +88,7 @@ function addUserProperties(userId, session) { } } -module.exports = { +export default { clearSource, setInbound, clearInbound, diff --git a/services/web/app/src/Features/Analytics/EmailChangeHelper.mjs b/services/web/app/src/Features/Analytics/EmailChangeHelper.mjs index b60274adfc..3b1bc5b665 100644 --- a/services/web/app/src/Features/Analytics/EmailChangeHelper.mjs +++ b/services/web/app/src/Features/Analytics/EmailChangeHelper.mjs @@ -1,6 +1,9 @@ // @ts-check -const UserGetter = require('../User/UserGetter') -const { registerEmailChange } = require('./AnalyticsManager') +import UserGetter from '../User/UserGetter.mjs' + +import AnalyticsManager from './AnalyticsManager.mjs' + +const { registerEmailChange } = AnalyticsManager /** * @typedef {object} EmailData @@ -115,7 +118,7 @@ function fillMissingEventData(eventData, emailData) { return eventData } -module.exports = { +export default { registerEmailUpdate, registerEmailCreation, registerEmailDeletion, diff --git a/services/web/app/src/Features/Analytics/RequestHelper.mjs b/services/web/app/src/Features/Analytics/RequestHelper.mjs index 08a6566f4c..b67cab0c93 100644 --- a/services/web/app/src/Features/Analytics/RequestHelper.mjs +++ b/services/web/app/src/Features/Analytics/RequestHelper.mjs @@ -1,5 +1,5 @@ -const RefererParser = require('referer-parser') -const { URL } = require('url') +import RefererParser from 'referer-parser' +import { URL } from 'node:url' const UTM_KEYS = [ 'utm_campaign', @@ -49,7 +49,7 @@ function parseReferrer(referrer, url) { return referrerValues } -module.exports = { +export default { UTM_KEYS, parseUtm, parseReferrer, diff --git a/services/web/app/src/Features/Analytics/UserAnalyticsIdCache.mjs b/services/web/app/src/Features/Analytics/UserAnalyticsIdCache.mjs index 97b4e80095..3a29f7fc43 100644 --- a/services/web/app/src/Features/Analytics/UserAnalyticsIdCache.mjs +++ b/services/web/app/src/Features/Analytics/UserAnalyticsIdCache.mjs @@ -1,6 +1,6 @@ -const UserGetter = require('../User/UserGetter') -const { CacheLoader } = require('cache-flow') -const { callbackify } = require('util') +import UserGetter from '../User/UserGetter.mjs' +import { CacheLoader } from 'cache-flow' +import { callbackify } from 'node:util' class UserAnalyticsIdCache extends CacheLoader { constructor() { @@ -28,4 +28,4 @@ const userAnalyticsIdCache = new UserAnalyticsIdCache() userAnalyticsIdCache.callbacks = { get: callbackify(userAnalyticsIdCache.get).bind(userAnalyticsIdCache), } -module.exports = userAnalyticsIdCache +export default userAnalyticsIdCache diff --git a/services/web/app/src/Features/Authentication/AuthenticationManager.mjs b/services/web/app/src/Features/Authentication/AuthenticationManager.mjs index 6ac510986c..c4455b7f51 100644 --- a/services/web/app/src/Features/Authentication/AuthenticationManager.mjs +++ b/services/web/app/src/Features/Authentication/AuthenticationManager.mjs @@ -1,24 +1,23 @@ -const Settings = require('@overleaf/settings') -const { User } = require('../../models/User') -const { db, ObjectId } = require('../../infrastructure/mongodb') -const bcrypt = require('bcrypt') -const EmailHelper = require('../Helpers/EmailHelper') -const { +import Settings from '@overleaf/settings' +import { User } from '../../models/User.js' +import { db, ObjectId } from '../../infrastructure/mongodb.js' +import bcrypt from 'bcrypt' +import EmailHelper from '../Helpers/EmailHelper.js' + +import { InvalidEmailError, InvalidPasswordError, ParallelLoginError, PasswordMustBeDifferentError, PasswordReusedError, -} = require('./AuthenticationErrors') -const { - callbackify, - callbackifyMultiResult, -} = require('@overleaf/promise-utils') -const HaveIBeenPwned = require('./HaveIBeenPwned') -const UserAuditLogHandler = require('../User/UserAuditLogHandler') -const logger = require('@overleaf/logger') -const DiffHelper = require('../Helpers/DiffHelper') -const Metrics = require('@overleaf/metrics') +} from './AuthenticationErrors.js' + +import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils' +import HaveIBeenPwned from './HaveIBeenPwned.mjs' +import UserAuditLogHandler from '../User/UserAuditLogHandler.mjs' +import logger from '@overleaf/logger' +import DiffHelper from '../Helpers/DiffHelper.js' +import Metrics from '@overleaf/metrics' const BCRYPT_ROUNDS = Settings.security.bcryptRounds || 12 const BCRYPT_MINOR_VERSION = Settings.security.bcryptMinorVersion || 'a' @@ -458,7 +457,7 @@ const AuthenticationManager = { }, } -module.exports = { +export default { _validatePasswordNotTooSimilar: AuthenticationManager._validatePasswordNotTooSimilar, // Private function exported for tests validateEmail: AuthenticationManager.validateEmail, diff --git a/services/web/app/src/Features/Authentication/HaveIBeenPwned.mjs b/services/web/app/src/Features/Authentication/HaveIBeenPwned.mjs index c400fc7b37..baf825397b 100644 --- a/services/web/app/src/Features/Authentication/HaveIBeenPwned.mjs +++ b/services/web/app/src/Features/Authentication/HaveIBeenPwned.mjs @@ -5,12 +5,13 @@ happy path or via an error (message or attributes). */ -const { callbackify } = require('util') -const { fetchString } = require('@overleaf/fetch-utils') -const crypto = require('crypto') -const Settings = require('@overleaf/settings') -const Metrics = require('@overleaf/metrics') -const logger = require('@overleaf/logger') +import { callbackify } from 'node:util' + +import { fetchString } from '@overleaf/fetch-utils' +import crypto from 'node:crypto' +import Settings from '@overleaf/settings' +import Metrics from '@overleaf/metrics' +import logger from '@overleaf/logger' const HEX_CHARS_UPPER = '1234567890ABCDEF' const API_ERROR = new Error('cannot contact HaveIBeenPwned api') @@ -118,7 +119,7 @@ function checkPasswordForReuseInBackground(password) { }) } -module.exports = { +export default { checkPasswordForReuse: callbackify(checkPasswordForReuse), checkPasswordForReuseInBackground, promises: { diff --git a/services/web/app/src/Features/Authentication/SessionManager.mjs b/services/web/app/src/Features/Authentication/SessionManager.mjs index a64ee98fe1..2552befd09 100644 --- a/services/web/app/src/Features/Authentication/SessionManager.mjs +++ b/services/web/app/src/Features/Authentication/SessionManager.mjs @@ -1,4 +1,4 @@ -const _ = require('lodash') +import _ from 'lodash' const SessionManager = { getSessionUser(session) { @@ -43,4 +43,4 @@ const SessionManager = { }, } -module.exports = SessionManager +export default SessionManager diff --git a/services/web/app/src/Features/Authorization/PublicAccessLevels.mjs b/services/web/app/src/Features/Authorization/PublicAccessLevels.mjs index 166dbd898f..9dbe5964a9 100644 --- a/services/web/app/src/Features/Authorization/PublicAccessLevels.mjs +++ b/services/web/app/src/Features/Authorization/PublicAccessLevels.mjs @@ -13,7 +13,7 @@ */ /** @type {import('./types').PublicAccessLevelsType} */ -module.exports = { +export default { READ_ONLY: 'readOnly', // LEGACY READ_AND_WRITE: 'readAndWrite', // LEGACY PRIVATE: 'private', diff --git a/services/web/app/src/Features/Authorization/Sources.mjs b/services/web/app/src/Features/Authorization/Sources.mjs index bfc3ef4d22..4e19ee2b78 100644 --- a/services/web/app/src/Features/Authorization/Sources.mjs +++ b/services/web/app/src/Features/Authorization/Sources.mjs @@ -1,7 +1,7 @@ // @ts-check /** @type {import('./types').SourcesType} */ -module.exports = { +export default { INVITE: 'invite', TOKEN: 'token', OWNER: 'owner', diff --git a/services/web/app/src/Features/Chat/ChatApiHandler.mjs b/services/web/app/src/Features/Chat/ChatApiHandler.mjs index 5f7dfbe3db..e14369ad12 100644 --- a/services/web/app/src/Features/Chat/ChatApiHandler.mjs +++ b/services/web/app/src/Features/Chat/ChatApiHandler.mjs @@ -1,8 +1,9 @@ // @ts-check -const { fetchJson, fetchNothing } = require('@overleaf/fetch-utils') -const settings = require('@overleaf/settings') -const { callbackify } = require('util') +import { fetchJson, fetchNothing } from '@overleaf/fetch-utils' + +import settings from '@overleaf/settings' +import { callbackify } from 'node:util' async function getThread(projectId, threadId) { return await fetchJson(chatApiUrl(`/project/${projectId}/thread/${threadId}`)) @@ -165,7 +166,7 @@ function chatApiUrl(path) { return new URL(path, settings.apis.chat.internal_url) } -module.exports = { +export default { getThread: callbackify(getThread), getThreadMessage: callbackify(getThreadMessage), getThreads: callbackify(getThreads), diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteGetter.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsInviteGetter.mjs index e3f692e74b..766f1f4708 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteGetter.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteGetter.mjs @@ -1,7 +1,7 @@ -const logger = require('@overleaf/logger') -const { ProjectInvite } = require('../../models/ProjectInvite') -const PrivilegeLevels = require('../Authorization/PrivilegeLevels') -const CollaboratorsInviteHelper = require('./CollaboratorsInviteHelper') +import logger from '@overleaf/logger' +import { ProjectInvite } from '../../models/ProjectInvite.js' +import PrivilegeLevels from '../Authorization/PrivilegeLevels.js' +import CollaboratorsInviteHelper from './CollaboratorsInviteHelper.mjs' async function getAllInvites(projectId) { logger.debug({ projectId }, 'fetching invites for project') @@ -39,7 +39,7 @@ async function getInviteByToken(projectId, tokenString) { return invite } -module.exports = { +export default { promises: { getAllInvites, getEditInviteCount, diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteHelper.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsInviteHelper.mjs index 305f93eac0..c10db1f9e9 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteHelper.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteHelper.mjs @@ -1,4 +1,4 @@ -const Crypto = require('crypto') +import Crypto from 'node:crypto' function generateToken() { const buffer = Crypto.randomBytes(24) @@ -11,7 +11,7 @@ function hashInviteToken(token) { .digest('hex') } -module.exports = { +export default { generateToken, hashInviteToken, } diff --git a/services/web/app/src/Features/Compile/ClsiCacheHandler.mjs b/services/web/app/src/Features/Compile/ClsiCacheHandler.mjs index 117aef65e8..fd30724768 100644 --- a/services/web/app/src/Features/Compile/ClsiCacheHandler.mjs +++ b/services/web/app/src/Features/Compile/ClsiCacheHandler.mjs @@ -1,14 +1,14 @@ -const _ = require('lodash') -const { +import _ from 'lodash' +import { fetchNothing, fetchRedirectWithResponse, RequestFailedError, -} = require('@overleaf/fetch-utils') -const logger = require('@overleaf/logger') -const Settings = require('@overleaf/settings') -const OError = require('@overleaf/o-error') -const { NotFoundError, InvalidNameError } = require('../Errors/Errors') -const Features = require('../../infrastructure/Features') +} from '@overleaf/fetch-utils' +import logger from '@overleaf/logger' +import Settings from '@overleaf/settings' +import OError from '@overleaf/o-error' +import { NotFoundError, InvalidNameError } from '../Errors/Errors.js' +import Features from '../../infrastructure/Features.js' const TIMEOUT = 4_000 @@ -263,7 +263,7 @@ async function prepareCacheSource( } } -module.exports = { +export default { TIMEOUT, getEgressLabel, clearCache, diff --git a/services/web/app/src/Features/Contacts/ContactManager.mjs b/services/web/app/src/Features/Contacts/ContactManager.mjs index be5bdce1fb..1afb40470c 100644 --- a/services/web/app/src/Features/Contacts/ContactManager.mjs +++ b/services/web/app/src/Features/Contacts/ContactManager.mjs @@ -1,7 +1,7 @@ -const { callbackify } = require('util') -const OError = require('@overleaf/o-error') -const { fetchJson } = require('@overleaf/fetch-utils') -const settings = require('@overleaf/settings') +import { callbackify } from 'node:util' +import OError from '@overleaf/o-error' +import { fetchJson } from '@overleaf/fetch-utils' +import settings from '@overleaf/settings' async function getContactIds(userId, options) { options = options ?? { limit: 50 } @@ -41,7 +41,7 @@ async function addContact(userId, contactId) { return body?.contact_ids || [] } -module.exports = { +export default { getContactIds: callbackify(getContactIds), addContact: callbackify(addContact), promises: { diff --git a/services/web/app/src/Features/Docstore/DocstoreManager.mjs b/services/web/app/src/Features/Docstore/DocstoreManager.mjs index 4074b90605..d6b58b40ab 100644 --- a/services/web/app/src/Features/Docstore/DocstoreManager.mjs +++ b/services/web/app/src/Features/Docstore/DocstoreManager.mjs @@ -1,11 +1,12 @@ -const { promisify } = require('util') -const { promisifyMultiResult, callbackify } = require('@overleaf/promise-utils') -const request = require('request').defaults({ jar: false }) -const OError = require('@overleaf/o-error') -const logger = require('@overleaf/logger') -const settings = require('@overleaf/settings') -const Errors = require('../Errors/Errors') -const { fetchJson } = require('@overleaf/fetch-utils') +import { promisify } from 'node:util' +import { promisifyMultiResult, callbackify } from '@overleaf/promise-utils' +import OError from '@overleaf/o-error' +import logger from '@overleaf/logger' +import settings from '@overleaf/settings' +import Errors from '../Errors/Errors.js' +import { fetchJson } from '@overleaf/fetch-utils' +import Request from 'request' +const request = Request.defaults({ jar: false }) const TIMEOUT = 30 * 1000 // request timeout @@ -303,7 +304,7 @@ function _operateOnProject(projectId, method, callback) { }) } -module.exports = { +export default { deleteDoc, getAllDocs, getAllDeletedDocs, diff --git a/services/web/app/src/Features/Documents/DocumentHelper.mjs b/services/web/app/src/Features/Documents/DocumentHelper.mjs index 959cc91de4..c7f60de38f 100644 --- a/services/web/app/src/Features/Documents/DocumentHelper.mjs +++ b/services/web/app/src/Features/Documents/DocumentHelper.mjs @@ -12,7 +12,8 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let DocumentHelper -module.exports = DocumentHelper = { + +export default DocumentHelper = { getTitleFromTexContent(content, maxContentToScan) { if (maxContentToScan == null) { maxContentToScan = 30000 diff --git a/services/web/app/src/Features/Editor/EditorRealTimeController.mjs b/services/web/app/src/Features/Editor/EditorRealTimeController.mjs index 086870e8f1..4574e3deda 100644 --- a/services/web/app/src/Features/Editor/EditorRealTimeController.mjs +++ b/services/web/app/src/Features/Editor/EditorRealTimeController.mjs @@ -10,19 +10,19 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ +import Settings from '@overleaf/settings' +import Metrics from '@overleaf/metrics' +import RedisWrapper from '../../infrastructure/RedisWrapper.js' +import os from 'node:os' +import crypto from 'node:crypto' let EditorRealTimeController -const Settings = require('@overleaf/settings') -const Metrics = require('@overleaf/metrics') -const RedisWrapper = require('../../infrastructure/RedisWrapper') const rclient = RedisWrapper.client('pubsub') -const os = require('os') -const crypto = require('crypto') const HOST = os.hostname() const RND = crypto.randomBytes(4).toString('hex') // generate a random key for this process let COUNT = 0 -module.exports = EditorRealTimeController = { +export default EditorRealTimeController = { emitToRoom(roomId, message, ...payload) { // create a unique message id using a counter const messageId = `web:${HOST}:${RND}-${COUNT++}` diff --git a/services/web/app/src/Features/Email/EmailBuilder.mjs b/services/web/app/src/Features/Email/EmailBuilder.mjs index c4845c8764..294a180a0d 100644 --- a/services/web/app/src/Features/Email/EmailBuilder.mjs +++ b/services/web/app/src/Features/Email/EmailBuilder.mjs @@ -1,12 +1,12 @@ -const _ = require('lodash') -const settings = require('@overleaf/settings') -const moment = require('moment') -const EmailMessageHelper = require('./EmailMessageHelper') -const StringHelper = require('../Helpers/StringHelper') -const BaseWithHeaderEmailLayout = require('./Layouts/BaseWithHeaderEmailLayout') -const SpamSafe = require('./SpamSafe') -const ctaEmailBody = require('./Bodies/cta-email') -const NoCTAEmailBody = require('./Bodies/NoCTAEmailBody') +import _ from 'lodash' +import settings from '@overleaf/settings' +import moment from 'moment' +import EmailMessageHelper from './EmailMessageHelper.js' +import StringHelper from '../Helpers/StringHelper.mjs' +import BaseWithHeaderEmailLayout from './Layouts/BaseWithHeaderEmailLayout.js' +import SpamSafe from './SpamSafe.mjs' +import ctaEmailBody from './Bodies/cta-email.js' +import NoCTAEmailBody from './Bodies/NoCTAEmailBody.js' function _emailBodyPlainText(content, opts, ctaEmail) { let emailBody = `${content.greeting(opts, true)}` @@ -1017,7 +1017,7 @@ function _formatUserNameAndEmail(user, placeholder) { return SpamSafe.safeEmail(user.email, placeholder) } -module.exports = { +export default { templates, ctaTemplate, NoCTAEmailTemplate, diff --git a/services/web/app/src/Features/Email/EmailHandler.mjs b/services/web/app/src/Features/Email/EmailHandler.mjs index f38ce2cc16..ae52acdb82 100644 --- a/services/web/app/src/Features/Email/EmailHandler.mjs +++ b/services/web/app/src/Features/Email/EmailHandler.mjs @@ -1,9 +1,9 @@ -const { callbackify } = require('util') -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const EmailBuilder = require('./EmailBuilder') -const EmailSender = require('./EmailSender') -const Queues = require('../../infrastructure/Queues') +import { callbackify } from 'node:util' +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import EmailBuilder from './EmailBuilder.mjs' +import EmailSender from './EmailSender.mjs' +import Queues from '../../infrastructure/Queues.js' const EMAIL_SETTINGS = Settings.email || {} @@ -32,7 +32,7 @@ function sendDeferredEmail(emailType, opts, delay) { }) } -module.exports = { +export default { sendEmail: callbackify(sendEmail), sendDeferredEmail, promises: { diff --git a/services/web/app/src/Features/Email/EmailOptionsHelper.mjs b/services/web/app/src/Features/Email/EmailOptionsHelper.mjs index e8245f796e..a988098c19 100644 --- a/services/web/app/src/Features/Email/EmailOptionsHelper.mjs +++ b/services/web/app/src/Features/Email/EmailOptionsHelper.mjs @@ -24,6 +24,6 @@ function linkOrUnlink(accountLinked, providerName, email) { } } -module.exports = { +export default { linkOrUnlink, } diff --git a/services/web/app/src/Features/Email/EmailSender.mjs b/services/web/app/src/Features/Email/EmailSender.mjs index e0b7a012b0..da32ebee8f 100644 --- a/services/web/app/src/Features/Email/EmailSender.mjs +++ b/services/web/app/src/Features/Email/EmailSender.mjs @@ -1,16 +1,16 @@ -const { callbackify } = require('util') -const logger = require('@overleaf/logger') -const metrics = require('@overleaf/metrics') -const Settings = require('@overleaf/settings') -const nodemailer = require('nodemailer') -const aws = require('@aws-sdk/client-ses') -const OError = require('@overleaf/o-error') -const { RateLimiter } = require('../../infrastructure/RateLimiter') -const _ = require('lodash') +import { callbackify } from 'node:util' +import logger from '@overleaf/logger' +import metrics from '@overleaf/metrics' +import Settings from '@overleaf/settings' +import nodemailer from 'nodemailer' +import aws from '@aws-sdk/client-ses' +import OError from '@overleaf/o-error' +import { RateLimiter } from '../../infrastructure/RateLimiter.js' +import _ from 'lodash' const EMAIL_SETTINGS = Settings.email || {} -module.exports = { +export default { sendEmail: callbackify(sendEmail), promises: { sendEmail, diff --git a/services/web/app/src/Features/Email/SpamSafe.mjs b/services/web/app/src/Features/Email/SpamSafe.mjs index 1c617977ee..608e7ea512 100644 --- a/services/web/app/src/Features/Email/SpamSafe.mjs +++ b/services/web/app/src/Features/Email/SpamSafe.mjs @@ -1,4 +1,4 @@ -const XRegExp = require('xregexp') +import XRegExp from 'xregexp' // A note about SAFE_REGEX: // We have to escape the escape characters because XRegExp compiles it first. @@ -69,4 +69,4 @@ const SpamSafe = { }, } -module.exports = SpamSafe +export default SpamSafe diff --git a/services/web/app/src/Features/Errors/HttpErrorHandler.mjs b/services/web/app/src/Features/Errors/HttpErrorHandler.mjs index e90d2491e9..5f8b348310 100644 --- a/services/web/app/src/Features/Errors/HttpErrorHandler.mjs +++ b/services/web/app/src/Features/Errors/HttpErrorHandler.mjs @@ -1,6 +1,6 @@ -const logger = require('@overleaf/logger') -const Settings = require('@overleaf/settings') -const { plainTextResponse } = require('../../infrastructure/Response') +import logger from '@overleaf/logger' +import Settings from '@overleaf/settings' +import { plainTextResponse } from '../../infrastructure/Response.js' function renderJSONError(res, message, info = {}) { if (info.message) { @@ -44,7 +44,8 @@ function handleGeneric400Error(req, res, statusCode, message, info = {}) { } let HttpErrorHandler -module.exports = HttpErrorHandler = { + +export default HttpErrorHandler = { handleErrorByStatusCode(req, res, err, statusCode) { const is400Error = statusCode >= 400 && statusCode < 500 const is500Error = statusCode >= 500 && statusCode < 600 diff --git a/services/web/app/src/Features/FileStore/FileHashManager.mjs b/services/web/app/src/Features/FileStore/FileHashManager.mjs index e90f93bc86..a402fe6d49 100644 --- a/services/web/app/src/Features/FileStore/FileHashManager.mjs +++ b/services/web/app/src/Features/FileStore/FileHashManager.mjs @@ -11,13 +11,13 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ +import crypto from 'node:crypto' +import logger from '@overleaf/logger' +import fs from 'node:fs' +import _ from 'lodash' let FileHashManager -const crypto = require('crypto') -const logger = require('@overleaf/logger') -const fs = require('fs') -const _ = require('lodash') -module.exports = FileHashManager = { +export default FileHashManager = { computeHash(filePath, callback) { if (callback == null) { callback = function () {} diff --git a/services/web/app/src/Features/Helpers/AsyncFormHelper.mjs b/services/web/app/src/Features/Helpers/AsyncFormHelper.mjs index 8b8a3b6875..3365c22646 100644 --- a/services/web/app/src/Features/Helpers/AsyncFormHelper.mjs +++ b/services/web/app/src/Features/Helpers/AsyncFormHelper.mjs @@ -1,8 +1,6 @@ -const { - acceptsJson, -} = require('../../infrastructure/RequestContentTypeDetection') +import { acceptsJson } from '../../infrastructure/RequestContentTypeDetection.js' -module.exports = { +export default { redirect, } diff --git a/services/web/app/src/Features/Helpers/SafeHTMLSubstitution.mjs b/services/web/app/src/Features/Helpers/SafeHTMLSubstitution.mjs index 4ae40d80f0..de8658d745 100644 --- a/services/web/app/src/Features/Helpers/SafeHTMLSubstitution.mjs +++ b/services/web/app/src/Features/Helpers/SafeHTMLSubstitution.mjs @@ -1,4 +1,4 @@ -const pug = require('pug-runtime') +import pug from 'pug-runtime' const SPLIT_REGEX = /<(\d+)>(.*?)<\/\1>/g @@ -40,7 +40,7 @@ function render(locale, components) { return output.join('') } -module.exports = { +export default { SPLIT_REGEX, render, } diff --git a/services/web/app/src/Features/Helpers/StringHelper.mjs b/services/web/app/src/Features/Helpers/StringHelper.mjs index 47f71df89f..a0d12150dc 100644 --- a/services/web/app/src/Features/Helpers/StringHelper.mjs +++ b/services/web/app/src/Features/Helpers/StringHelper.mjs @@ -15,7 +15,7 @@ const JSON_ESCAPE = { '\u2029': '\\u2029', } -module.exports = StringHelper = { +export default StringHelper = { // stringifies and escapes a json object for use in a script. This ensures that &, < and > characters are escaped, // along with quotes. This ensures that the string can be safely rendered into HTML. See rationale at: // https://api.rubyonrails.org/classes/ERB/Util.html#method-c-json_escape diff --git a/services/web/app/src/Features/Helpers/UrlHelper.mjs b/services/web/app/src/Features/Helpers/UrlHelper.mjs index cf686636b8..df9b7c7bad 100644 --- a/services/web/app/src/Features/Helpers/UrlHelper.mjs +++ b/services/web/app/src/Features/Helpers/UrlHelper.mjs @@ -1,5 +1,5 @@ -const Settings = require('@overleaf/settings') -const { URL } = require('url') +import Settings from '@overleaf/settings' +import { URL } from 'node:url' const PROTO = new URL(Settings.siteUrl).protocol @@ -28,7 +28,7 @@ function getSafeAdminDomainRedirect(path) { return Settings.adminUrl + (getSafeRedirectPath(path) || '/') } -module.exports = { +export default { getCanonicalURL, getSafeRedirectPath, getSafeAdminDomainRedirect, diff --git a/services/web/app/src/Features/History/HistoryBackupDeletionHandler.mjs b/services/web/app/src/Features/History/HistoryBackupDeletionHandler.mjs index 8df1bcdad8..282f14b48c 100644 --- a/services/web/app/src/Features/History/HistoryBackupDeletionHandler.mjs +++ b/services/web/app/src/Features/History/HistoryBackupDeletionHandler.mjs @@ -1,5 +1,5 @@ -const { fetchNothing } = require('@overleaf/fetch-utils') -const Settings = require('@overleaf/settings') +import { fetchNothing } from '@overleaf/fetch-utils' +import Settings from '@overleaf/settings' async function deleteProject(projectId) { if (!Settings.apis.historyBackupDeletion.enabled) return @@ -15,6 +15,6 @@ async function deleteProject(projectId) { }) } -module.exports = { +export default { deleteProject, } diff --git a/services/web/app/src/Features/Institutions/InstitutionsAPI.mjs b/services/web/app/src/Features/Institutions/InstitutionsAPI.mjs index 34cd2f9908..8400cdfa83 100644 --- a/services/web/app/src/Features/Institutions/InstitutionsAPI.mjs +++ b/services/web/app/src/Features/Institutions/InstitutionsAPI.mjs @@ -1,17 +1,16 @@ -const { callbackify } = require('util') -const OError = require('@overleaf/o-error') -const logger = require('@overleaf/logger') -const settings = require('@overleaf/settings') -const request = require('requestretry') -const { promisifyAll } = require('@overleaf/promise-utils') -const NotificationsBuilder = require('../Notifications/NotificationsBuilder') -const { +import { callbackify } from 'node:util' +import OError from '@overleaf/o-error' +import logger from '@overleaf/logger' +import settings from '@overleaf/settings' +import request from 'requestretry' +import { promisifyAll, promiseMapWithLimit } from '@overleaf/promise-utils' +import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs' +import { V1ConnectionError, InvalidInstitutionalEmailError, -} = require('../Errors/Errors') -const { fetchJson, fetchNothing } = require('@overleaf/fetch-utils') -const { promiseMapWithLimit } = require('@overleaf/promise-utils') -const Modules = require('../../infrastructure/Modules') +} from '../Errors/Errors.js' +import { fetchJson, fetchNothing } from '@overleaf/fetch-utils' +import Modules from '../../infrastructure/Modules.js' function _makeRequestOptions(options) { const requestOptions = { @@ -418,4 +417,4 @@ InstitutionsAPI.promises.removeAffiliation = removeAffiliation InstitutionsAPI.promises.getUsersNeedingReconfirmationsLapsedProcessed = getUsersNeedingReconfirmationsLapsedProcessed -module.exports = InstitutionsAPI +export default InstitutionsAPI diff --git a/services/web/app/src/Features/Institutions/InstitutionsFeatures.mjs b/services/web/app/src/Features/Institutions/InstitutionsFeatures.mjs index 0b33fe15d9..233525b33a 100644 --- a/services/web/app/src/Features/Institutions/InstitutionsFeatures.mjs +++ b/services/web/app/src/Features/Institutions/InstitutionsFeatures.mjs @@ -1,7 +1,7 @@ -const { callbackifyAll } = require('@overleaf/promise-utils') -const UserGetter = require('../User/UserGetter') -const PlansLocator = require('../Subscription/PlansLocator') -const Settings = require('@overleaf/settings') +import { callbackifyAll } from '@overleaf/promise-utils' +import UserGetter from '../User/UserGetter.mjs' +import PlansLocator from '../Subscription/PlansLocator.mjs' +import Settings from '@overleaf/settings' async function getInstitutionsFeatures(userId) { const planCode = await getInstitutionsPlan(userId) @@ -26,7 +26,8 @@ const InstitutionsFeatures = { getInstitutionsPlan, hasLicence, } -module.exports = { + +export default { promises: InstitutionsFeatures, ...callbackifyAll(InstitutionsFeatures), } diff --git a/services/web/app/src/Features/Institutions/InstitutionsHelper.mjs b/services/web/app/src/Features/Institutions/InstitutionsHelper.mjs index c4cb486264..723bd4d4d4 100644 --- a/services/web/app/src/Features/Institutions/InstitutionsHelper.mjs +++ b/services/web/app/src/Features/Institutions/InstitutionsHelper.mjs @@ -23,6 +23,6 @@ function emailHasLicence(emailData) { return affiliation.licence !== 'free' } -module.exports = { +export default { emailHasLicence, } diff --git a/services/web/app/src/Features/Newsletter/MailChimpClient.mjs b/services/web/app/src/Features/Newsletter/MailChimpClient.mjs index 525ef33189..492a2e6eb3 100644 --- a/services/web/app/src/Features/Newsletter/MailChimpClient.mjs +++ b/services/web/app/src/Features/Newsletter/MailChimpClient.mjs @@ -1,4 +1,4 @@ -const { fetchJson, fetchNothing } = require('@overleaf/fetch-utils') +import { fetchJson, fetchNothing } from '@overleaf/fetch-utils' class MailChimpClient { constructor(apiKey) { @@ -65,4 +65,4 @@ class MailChimpClient { } } -module.exports = MailChimpClient +export default MailChimpClient diff --git a/services/web/app/src/Features/Newsletter/MailChimpProvider.mjs b/services/web/app/src/Features/Newsletter/MailChimpProvider.mjs index 9310ce9e53..5f7f5163da 100644 --- a/services/web/app/src/Features/Newsletter/MailChimpProvider.mjs +++ b/services/web/app/src/Features/Newsletter/MailChimpProvider.mjs @@ -1,9 +1,9 @@ -const logger = require('@overleaf/logger') -const Settings = require('@overleaf/settings') -const crypto = require('crypto') -const OError = require('@overleaf/o-error') -const { callbackify } = require('util') -const MailChimpClient = require('./MailChimpClient') +import logger from '@overleaf/logger' +import Settings from '@overleaf/settings' +import crypto from 'node:crypto' +import OError from '@overleaf/o-error' +import { callbackify } from 'node:util' +import MailChimpClient from './MailChimpClient.mjs' function mailchimpIsConfigured() { return Settings.mailchimp != null && Settings.mailchimp.api_key != null @@ -29,7 +29,7 @@ function make(listName, listId) { } } -module.exports = { +export default { make, } diff --git a/services/web/app/src/Features/Newsletter/NewsletterManager.mjs b/services/web/app/src/Features/Newsletter/NewsletterManager.mjs index ebae9f288f..1b7f638c4a 100644 --- a/services/web/app/src/Features/Newsletter/NewsletterManager.mjs +++ b/services/web/app/src/Features/Newsletter/NewsletterManager.mjs @@ -1,9 +1,9 @@ -const Settings = require('@overleaf/settings') -const MailchimpProvider = require('./MailChimpProvider') +import Settings from '@overleaf/settings' +import MailchimpProvider from './MailChimpProvider.mjs' const provider = MailchimpProvider.make( 'newsletter', Settings.mailchimp ? Settings.mailchimp.list_id : null ) -module.exports = provider +export default provider diff --git a/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs b/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs index 42cc446f0a..cc1cba8886 100644 --- a/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs +++ b/services/web/app/src/Features/Notifications/NotificationsBuilder.mjs @@ -1,9 +1,11 @@ -const NotificationsHandler = require('./NotificationsHandler') -const { callbackifyAll } = require('@overleaf/promise-utils') -const { fetchJson } = require('@overleaf/fetch-utils') -const settings = require('@overleaf/settings') -const path = require('path') -const { ObjectId } = require('mongodb-legacy') +import NotificationsHandler from './NotificationsHandler.mjs' +import { callbackifyAll } from '@overleaf/promise-utils' +import { fetchJson } from '@overleaf/fetch-utils' +import settings from '@overleaf/settings' +import path from 'node:path' +import mongodb from 'mongodb-legacy' + +const { ObjectId } = mongodb function dropboxDuplicateProjectNames(userId) { return { @@ -279,4 +281,4 @@ NotificationsBuilder.promises = { tpdsFileLimit, } -module.exports = NotificationsBuilder +export default NotificationsBuilder diff --git a/services/web/app/src/Features/Notifications/NotificationsHandler.mjs b/services/web/app/src/Features/Notifications/NotificationsHandler.mjs index 4958ad89c6..7c0ce9cac6 100644 --- a/services/web/app/src/Features/Notifications/NotificationsHandler.mjs +++ b/services/web/app/src/Features/Notifications/NotificationsHandler.mjs @@ -1,8 +1,8 @@ -const settings = require('@overleaf/settings') -const request = require('request') -const logger = require('@overleaf/logger') -const _ = require('lodash') -const { promisifyAll } = require('@overleaf/promise-utils') +import settings from '@overleaf/settings' +import request from 'request' +import logger from '@overleaf/logger' +import _ from 'lodash' +import { promisifyAll } from '@overleaf/promise-utils' const notificationsApi = _.get(settings, ['apis', 'notifications', 'url']) const oneSecond = 1000 @@ -139,4 +139,4 @@ const NotificationsHandler = { } NotificationsHandler.promises = promisifyAll(NotificationsHandler) -module.exports = NotificationsHandler +export default NotificationsHandler diff --git a/services/web/app/src/Features/OnboardingDataCollection/OnboardingDataCollectionManager.mjs b/services/web/app/src/Features/OnboardingDataCollection/OnboardingDataCollectionManager.mjs index fb4fa84590..8359add440 100644 --- a/services/web/app/src/Features/OnboardingDataCollection/OnboardingDataCollectionManager.mjs +++ b/services/web/app/src/Features/OnboardingDataCollection/OnboardingDataCollectionManager.mjs @@ -1,8 +1,8 @@ -const { - OnboardingDataCollection, - OnboardingDataCollectionSchema, -} = require('../../models/OnboardingDataCollection') -const OError = require('@overleaf/o-error') +import OnboardingDataCollectionModel from '../../models/OnboardingDataCollection.js' +import OError from '@overleaf/o-error' + +const { OnboardingDataCollection, OnboardingDataCollectionSchema } = + OnboardingDataCollectionModel async function getOnboardingDataCollection(userId, projection = {}) { try { @@ -69,7 +69,7 @@ function deleteOnboardingDataCollection(id) { return OnboardingDataCollection.deleteOne({ _id: id }) } -module.exports = { +export default { getOnboardingDataCollection, upsertOnboardingDataCollection, deleteOnboardingDataCollection, diff --git a/services/web/app/src/Features/Project/FolderStructureBuilder.mjs b/services/web/app/src/Features/Project/FolderStructureBuilder.mjs index d091c71a0d..1cd7c34b9c 100644 --- a/services/web/app/src/Features/Project/FolderStructureBuilder.mjs +++ b/services/web/app/src/Features/Project/FolderStructureBuilder.mjs @@ -1,8 +1,10 @@ -const Path = require('path') -const OError = require('@overleaf/o-error') -const { ObjectId } = require('mongodb-legacy') +import Path from 'node:path' +import OError from '@overleaf/o-error' +import mongodb from 'mongodb-legacy' -module.exports = { buildFolderStructure } +const { ObjectId } = mongodb + +export default { buildFolderStructure } function buildFolderStructure(docEntries, fileEntries) { const builder = new FolderStructureBuilder() diff --git a/services/web/app/src/Features/Project/ProjectEditorHandler.mjs b/services/web/app/src/Features/Project/ProjectEditorHandler.mjs index f77d2c1b3d..e6b0af442a 100644 --- a/services/web/app/src/Features/Project/ProjectEditorHandler.mjs +++ b/services/web/app/src/Features/Project/ProjectEditorHandler.mjs @@ -1,8 +1,8 @@ +import _ from 'lodash' +import Path from 'node:path' let ProjectEditorHandler -const _ = require('lodash') -const Path = require('path') -module.exports = ProjectEditorHandler = { +export default ProjectEditorHandler = { trackChangesAvailable: false, buildProjectModelView( diff --git a/services/web/app/src/Features/Project/ProjectHelper.mjs b/services/web/app/src/Features/Project/ProjectHelper.mjs index f75a993577..40a39aa9ef 100644 --- a/services/web/app/src/Features/Project/ProjectHelper.mjs +++ b/services/web/app/src/Features/Project/ProjectHelper.mjs @@ -1,7 +1,9 @@ -// @ts-check -const { ObjectId } = require('mongodb-legacy') -const _ = require('lodash') -const Settings = require('@overleaf/settings') +import mongodb from 'mongodb-legacy' + +import _ from 'lodash' +import Settings from '@overleaf/settings' + +const { ObjectId } = mongodb /** * @import { MongoProject } from "./types" @@ -14,7 +16,7 @@ const ENGINE_TO_COMPILER_MAP = { lualatex: 'lualatex', } -module.exports = { +export default { compilerFromV1Engine, isArchived, isTrashed, diff --git a/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs b/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs index c0c11c396c..9d577fc35e 100644 --- a/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs +++ b/services/web/app/src/Features/Project/ProjectOptionsHandler.mjs @@ -1,11 +1,13 @@ -const { Project } = require('../../models/Project') -const settings = require('@overleaf/settings') -const { callbackify } = require('util') -const { db, ObjectId } = require('../../infrastructure/mongodb') -const Errors = require('../Errors/Errors') -const { ReturnDocument } = require('mongodb-legacy') +import { Project } from '../../models/Project.js' +import settings from '@overleaf/settings' +import { callbackify } from 'node:util' +import { db, ObjectId } from '../../infrastructure/mongodb.js' +import Errors from '../Errors/Errors.js' +import mongodb from 'mongodb-legacy' const safeCompilers = ['xelatex', 'pdflatex', 'latex', 'lualatex'] +const { ReturnDocument } = mongodb + const ProjectOptionsHandler = { async setCompiler(projectId, compiler) { if (!compiler) { @@ -92,7 +94,7 @@ const ProjectOptionsHandler = { }, } -module.exports = { +export default { setCompiler: callbackify(ProjectOptionsHandler.setCompiler), setImageName: callbackify(ProjectOptionsHandler.setImageName), setSpellCheckLanguage: callbackify( diff --git a/services/web/app/src/Features/Project/ProjectUpdateHandler.mjs b/services/web/app/src/Features/Project/ProjectUpdateHandler.mjs index ad9b914bc9..2352ef1ad1 100644 --- a/services/web/app/src/Features/Project/ProjectUpdateHandler.mjs +++ b/services/web/app/src/Features/Project/ProjectUpdateHandler.mjs @@ -1,5 +1,5 @@ -const { Project } = require('../../models/Project') -const { callbackify } = require('util') +import { Project } from '../../models/Project.js' +import { callbackify } from 'node:util' const ProjectUpdateHandler = { async markAsUpdated(projectId, lastUpdatedAt, lastUpdatedBy) { @@ -38,7 +38,7 @@ const ProjectUpdateHandler = { }, } -module.exports = { +export default { markAsUpdated: callbackify(ProjectUpdateHandler.markAsUpdated), markAsOpened: callbackify(ProjectUpdateHandler.markAsOpened), markAsInactive: callbackify(ProjectUpdateHandler.markAsInactive), diff --git a/services/web/app/src/Features/Project/SafePath.mjs b/services/web/app/src/Features/Project/SafePath.mjs index 10267f7857..4ff60e794e 100644 --- a/services/web/app/src/Features/Project/SafePath.mjs +++ b/services/web/app/src/Features/Project/SafePath.mjs @@ -132,4 +132,4 @@ prototype\ }) } -module.exports = load() +export default load() diff --git a/services/web/app/src/Features/Publishers/PublishersGetter.mjs b/services/web/app/src/Features/Publishers/PublishersGetter.mjs index 9167a70663..83e5135b21 100644 --- a/services/web/app/src/Features/Publishers/PublishersGetter.mjs +++ b/services/web/app/src/Features/Publishers/PublishersGetter.mjs @@ -1,9 +1,9 @@ -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const { fetchJson } = require('@overleaf/fetch-utils') -const { callbackify } = require('@overleaf/promise-utils') -const UserMembershipsHandler = require('../UserMembership/UserMembershipsHandler') -const UserMembershipEntityConfigs = require('../UserMembership/UserMembershipEntityConfigs') +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import { fetchJson } from '@overleaf/fetch-utils' +import { callbackify } from '@overleaf/promise-utils' +import UserMembershipsHandler from '../UserMembership/UserMembershipsHandler.mjs' +import UserMembershipEntityConfigs from '../UserMembership/UserMembershipEntityConfigs.mjs' async function getManagedPublishers(userId) { return await UserMembershipsHandler.promises.getEntitiesByUser( @@ -33,7 +33,7 @@ async function fetchV1Data(publisher) { } } -module.exports = { +export default { getManagedPublishers: callbackify(getManagedPublishers), promises: { getManagedPublishers, diff --git a/services/web/app/src/Features/Referal/ReferalFeatures.mjs b/services/web/app/src/Features/Referal/ReferalFeatures.mjs index 7f3e732a47..5ee8541786 100644 --- a/services/web/app/src/Features/Referal/ReferalFeatures.mjs +++ b/services/web/app/src/Features/Referal/ReferalFeatures.mjs @@ -1,7 +1,7 @@ -const _ = require('lodash') -const { callbackify } = require('util') -const { User } = require('../../models/User') -const Settings = require('@overleaf/settings') +import _ from 'lodash' +import { callbackify } from 'node:util' +import { User } from '../../models/User.js' +import Settings from '@overleaf/settings' const ReferalFeatures = { async getBonusFeatures(userId) { @@ -42,7 +42,7 @@ const ReferalFeatures = { }, } -module.exports = { +export default { getBonusFeatures: callbackify(ReferalFeatures.getBonusFeatures), promises: ReferalFeatures, } diff --git a/services/web/app/src/Features/SplitTests/LocalsHelper.mjs b/services/web/app/src/Features/SplitTests/LocalsHelper.mjs index 14bfa963d2..eec347d4c3 100644 --- a/services/web/app/src/Features/SplitTests/LocalsHelper.mjs +++ b/services/web/app/src/Features/SplitTests/LocalsHelper.mjs @@ -12,7 +12,7 @@ function setSplitTestInfo(locals, splitTestName, info) { locals.splitTestInfo[splitTestName] = info } -module.exports = { +export default { setSplitTestVariant, setSplitTestInfo, } diff --git a/services/web/app/src/Features/SplitTests/SplitTestCache.mjs b/services/web/app/src/Features/SplitTests/SplitTestCache.mjs index 4f81b451df..14e5369033 100644 --- a/services/web/app/src/Features/SplitTests/SplitTestCache.mjs +++ b/services/web/app/src/Features/SplitTests/SplitTestCache.mjs @@ -1,6 +1,6 @@ -const Metrics = require('@overleaf/metrics') -const SplitTestManager = require('./SplitTestManager') -const { CacheLoader } = require('cache-flow') +import Metrics from '@overleaf/metrics' +import SplitTestManager from './SplitTestManager.mjs' +import { CacheLoader } from 'cache-flow' class SplitTestCache extends CacheLoader { constructor() { @@ -24,4 +24,4 @@ class SplitTestCache extends CacheLoader { } } -module.exports = new SplitTestCache() +export default new SplitTestCache() diff --git a/services/web/app/src/Features/SplitTests/SplitTestHandler.mjs b/services/web/app/src/Features/SplitTests/SplitTestHandler.mjs index f475083ae0..df82b8074b 100644 --- a/services/web/app/src/Features/SplitTests/SplitTestHandler.mjs +++ b/services/web/app/src/Features/SplitTests/SplitTestHandler.mjs @@ -1,21 +1,21 @@ -const Metrics = require('@overleaf/metrics') -const UserUpdater = require('../User/UserUpdater') -const AnalyticsManager = require('../Analytics/AnalyticsManager') -const LocalsHelper = require('./LocalsHelper') -const crypto = require('crypto') -const _ = require('lodash') -const { callbackify } = require('util') -const SplitTestCache = require('./SplitTestCache') -const { SplitTest } = require('../../models/SplitTest') -const UserAnalyticsIdCache = require('../Analytics/UserAnalyticsIdCache') -const Features = require('../../infrastructure/Features') -const SplitTestUtils = require('./SplitTestUtils') -const Settings = require('@overleaf/settings') -const SessionManager = require('../Authentication/SessionManager') -const logger = require('@overleaf/logger') -const SplitTestSessionHandler = require('./SplitTestSessionHandler') -const SplitTestUserGetter = require('./SplitTestUserGetter') -const SplitTestManager = require('./SplitTestManager') +import Metrics from '@overleaf/metrics' +import UserUpdater from '../User/UserUpdater.mjs' +import AnalyticsManager from '../Analytics/AnalyticsManager.mjs' +import LocalsHelper from './LocalsHelper.mjs' +import crypto from 'node:crypto' +import _ from 'lodash' +import { callbackify } from 'node:util' +import SplitTestCache from './SplitTestCache.mjs' +import { SplitTest } from '../../models/SplitTest.js' +import UserAnalyticsIdCache from '../Analytics/UserAnalyticsIdCache.mjs' +import Features from '../../infrastructure/Features.js' +import SplitTestUtils from './SplitTestUtils.mjs' +import Settings from '@overleaf/settings' +import SessionManager from '../Authentication/SessionManager.mjs' +import logger from '@overleaf/logger' +import SplitTestSessionHandler from './SplitTestSessionHandler.mjs' +import SplitTestUserGetter from './SplitTestUserGetter.mjs' +import SplitTestManager from './SplitTestManager.mjs' /** * @import { Assignment } from "./types" @@ -799,7 +799,7 @@ function _isGradualRollout(featureFlag) { return !SplitTestUtils.getCurrentVersion(featureFlag).analyticsEnabled } -module.exports = { +export default { getPercentile, getAssignment: callbackify(getAssignment), getAssignmentForUser: callbackify(getAssignmentForUser), diff --git a/services/web/app/src/Features/SplitTests/SplitTestManager.mjs b/services/web/app/src/Features/SplitTests/SplitTestManager.mjs index d224a34e2d..587e75ef34 100644 --- a/services/web/app/src/Features/SplitTests/SplitTestManager.mjs +++ b/services/web/app/src/Features/SplitTests/SplitTestManager.mjs @@ -1,8 +1,8 @@ -const { SplitTest } = require('../../models/SplitTest') -const SplitTestUtils = require('./SplitTestUtils') -const OError = require('@overleaf/o-error') -const _ = require('lodash') -const { CacheFlow } = require('cache-flow') +import { SplitTest } from '../../models/SplitTest.js' +import SplitTestUtils from './SplitTestUtils.mjs' +import OError from '@overleaf/o-error' +import _ from 'lodash' +import { CacheFlow } from 'cache-flow' const ALPHA_PHASE = 'alpha' const BETA_PHASE = 'beta' @@ -531,7 +531,7 @@ function _mergeFlags(incomingTests, baseTests) { return mergedSet } -module.exports = { +export default { getSplitTest, getSplitTests, getRuntimeTests, diff --git a/services/web/app/src/Features/SplitTests/SplitTestSessionHandler.mjs b/services/web/app/src/Features/SplitTests/SplitTestSessionHandler.mjs index 52d13527cf..0f4ab589bb 100644 --- a/services/web/app/src/Features/SplitTests/SplitTestSessionHandler.mjs +++ b/services/web/app/src/Features/SplitTests/SplitTestSessionHandler.mjs @@ -1,12 +1,14 @@ -const { callbackify } = require('util') -const _ = require('lodash') -const { ObjectId } = require('mongodb-legacy') -const logger = require('@overleaf/logger') -const Metrics = require('@overleaf/metrics') -const SessionManager = require('../Authentication/SessionManager') -const SplitTestCache = require('./SplitTestCache') -const SplitTestUtils = require('./SplitTestUtils') -const SplitTestUserGetter = require('./SplitTestUserGetter') +import { callbackify } from 'node:util' +import _ from 'lodash' +import mongodb from 'mongodb-legacy' +import logger from '@overleaf/logger' +import Metrics from '@overleaf/metrics' +import SessionManager from '../Authentication/SessionManager.mjs' +import SplitTestCache from './SplitTestCache.mjs' +import SplitTestUtils from './SplitTestUtils.mjs' +import SplitTestUserGetter from './SplitTestUserGetter.mjs' + +const { ObjectId } = mongodb const CACHE_TOMBSTONE_SPLIT_TEST_NOT_ACTIVE_FOR_USER = null const TOKEN_SEP = ';' @@ -242,7 +244,7 @@ function _convertIdToBase64(id) { return new ObjectId(id).toString('base64') } -module.exports = { +export default { getAssignments: callbackify(getAssignments), appendAssignment: callbackify(appendAssignment), getCachedVariant, diff --git a/services/web/app/src/Features/SplitTests/SplitTestUserGetter.mjs b/services/web/app/src/Features/SplitTests/SplitTestUserGetter.mjs index cf6503c51c..2454a51f6c 100644 --- a/services/web/app/src/Features/SplitTests/SplitTestUserGetter.mjs +++ b/services/web/app/src/Features/SplitTests/SplitTestUserGetter.mjs @@ -1,6 +1,6 @@ -const { callbackify } = require('util') -const Metrics = require('@overleaf/metrics') -const UserGetter = require('../User/UserGetter') +import { callbackify } from 'node:util' +import Metrics from '@overleaf/metrics' +import UserGetter from '../User/UserGetter.mjs' async function getUser(id, splitTestName) { const projection = { @@ -22,7 +22,7 @@ async function getUser(id, splitTestName) { return user } -module.exports = { +export default { getUser: callbackify(getUser), promises: { getUser, diff --git a/services/web/app/src/Features/SplitTests/SplitTestUtils.mjs b/services/web/app/src/Features/SplitTests/SplitTestUtils.mjs index ef26dbec33..7627fa48ad 100644 --- a/services/web/app/src/Features/SplitTests/SplitTestUtils.mjs +++ b/services/web/app/src/Features/SplitTests/SplitTestUtils.mjs @@ -1,4 +1,4 @@ -const _ = require('lodash') +import _ from 'lodash' function getCurrentVersion(splitTest) { if (splitTest?.versions?.length > 0) { @@ -14,7 +14,7 @@ function getVersion(splitTest, versionNumber) { }) } -module.exports = { +export default { getCurrentVersion, getVersion, } diff --git a/services/web/app/src/Features/Subscription/FeaturesHelper.mjs b/services/web/app/src/Features/Subscription/FeaturesHelper.mjs index b948815477..a70a903f29 100644 --- a/services/web/app/src/Features/Subscription/FeaturesHelper.mjs +++ b/services/web/app/src/Features/Subscription/FeaturesHelper.mjs @@ -1,5 +1,5 @@ -const _ = require('lodash') -const Settings = require('@overleaf/settings') +import _ from 'lodash' +import Settings from '@overleaf/settings' /** * merges an array of feature sets to produce a final feature set @@ -113,7 +113,7 @@ function getMatchedFeatureSet(features) { return 'mixed' } -module.exports = { +export default { mergeFeatures, computeFeatureSet, isFeatureSetBetter, diff --git a/services/web/app/src/Features/Subscription/FeaturesUpdater.mjs b/services/web/app/src/Features/Subscription/FeaturesUpdater.mjs index 68a2f89cd3..ee75dfb017 100644 --- a/services/web/app/src/Features/Subscription/FeaturesUpdater.mjs +++ b/services/web/app/src/Features/Subscription/FeaturesUpdater.mjs @@ -1,21 +1,21 @@ -const _ = require('lodash') -const { callbackify } = require('util') -const { callbackifyMultiResult } = require('@overleaf/promise-utils') -const PlansLocator = require('./PlansLocator') -const SubscriptionLocator = require('./SubscriptionLocator') -const SubscriptionHelper = require('./SubscriptionHelper') -const UserFeaturesUpdater = require('./UserFeaturesUpdater') -const FeaturesHelper = require('./FeaturesHelper') -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const ReferalFeatures = require('../Referal/ReferalFeatures') -const V1SubscriptionManager = require('./V1SubscriptionManager') -const InstitutionsFeatures = require('../Institutions/InstitutionsFeatures') -const UserGetter = require('../User/UserGetter') -const AnalyticsManager = require('../Analytics/AnalyticsManager') -const Queues = require('../../infrastructure/Queues') -const Modules = require('../../infrastructure/Modules') -const { AI_ADD_ON_CODE } = require('./AiHelper') +import _ from 'lodash' +import { callbackify } from 'node:util' +import { callbackifyMultiResult } from '@overleaf/promise-utils' +import PlansLocator from './PlansLocator.mjs' +import SubscriptionLocator from './SubscriptionLocator.mjs' +import SubscriptionHelper from './SubscriptionHelper.js' +import UserFeaturesUpdater from './UserFeaturesUpdater.mjs' +import FeaturesHelper from './FeaturesHelper.mjs' +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import ReferalFeatures from '../Referal/ReferalFeatures.mjs' +import V1SubscriptionManager from './V1SubscriptionManager.mjs' +import InstitutionsFeatures from '../Institutions/InstitutionsFeatures.mjs' +import UserGetter from '../User/UserGetter.mjs' +import AnalyticsManager from '../Analytics/AnalyticsManager.mjs' +import Queues from '../../infrastructure/Queues.js' +import Modules from '../../infrastructure/Modules.js' +import { AI_ADD_ON_CODE } from './AiHelper.js' /** * Enqueue a job for refreshing features for the given user @@ -204,7 +204,7 @@ async function doSyncFromV1(v1UserId) { return refreshFeatures(user._id, 'sync-v1') } -module.exports = { +export default { featuresEpochIsCurrent, computeFeatures: callbackify(computeFeatures), refreshFeatures: callbackifyMultiResult(refreshFeatures, [ diff --git a/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs b/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs index 9485eb0656..c835ebca74 100644 --- a/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs +++ b/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs @@ -16,14 +16,15 @@ * @property {boolean} [isAiAssist] */ -const OError = require('@overleaf/o-error') -const { DuplicateAddOnError, AddOnNotPresentError } = require('./Errors') -const PlansLocator = require('./PlansLocator') -const SubscriptionHelper = require('./SubscriptionHelper') -const { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } = require('./AiHelper') +import OError from '@overleaf/o-error' + +import { DuplicateAddOnError, AddOnNotPresentError } from './Errors.js' +import PlansLocator from './PlansLocator.mjs' +import SubscriptionHelper from './SubscriptionHelper.js' +import { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } from './AiHelper.js' const MEMBERS_LIMIT_ADD_ON_CODE = 'additional-license' -class PaymentProviderSubscription { +export class PaymentProviderSubscription { /** * @param {object} props * @param {string} props.id @@ -644,7 +645,7 @@ class PaymentProviderCoupon { /** * An account in the payment provider */ -class PaymentProviderAccount { +export class PaymentProviderAccount { /** * @param {object} props * @param {string} props.code @@ -661,7 +662,7 @@ class PaymentProviderAccount { } } -module.exports = { +export default { MEMBERS_LIMIT_ADD_ON_CODE, PaymentProviderSubscription, PaymentProviderSubscriptionAddOn, diff --git a/services/web/app/src/Features/Subscription/PlansLocator.mjs b/services/web/app/src/Features/Subscription/PlansLocator.mjs index d4e6f8ff65..14243f759a 100644 --- a/services/web/app/src/Features/Subscription/PlansLocator.mjs +++ b/services/web/app/src/Features/Subscription/PlansLocator.mjs @@ -1,7 +1,8 @@ // @ts-check -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') +import Settings from '@overleaf/settings' + +import logger from '@overleaf/logger' /** * @typedef {import('../../../../types/subscription/plan').RecurlyPlanCode} RecurlyPlanCode @@ -173,7 +174,7 @@ function convertLegacyGroupPlanCodeToConsolidatedGroupPlanCodeIfNeeded( return { planCode: newPlanCode, quantity: Number(size) } } -module.exports = { +export default { ensurePlansAreSetupCorrectly, findLocalPlanInSettings, buildStripeLookupKey, diff --git a/services/web/app/src/Features/Subscription/RecurlyClient.mjs b/services/web/app/src/Features/Subscription/RecurlyClient.mjs index 610d932aa8..7849ca01ad 100644 --- a/services/web/app/src/Features/Subscription/RecurlyClient.mjs +++ b/services/web/app/src/Features/Subscription/RecurlyClient.mjs @@ -1,11 +1,20 @@ // @ts-check -const recurly = require('recurly') -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const OError = require('@overleaf/o-error') -const { callbackify } = require('util') -const UserGetter = require('../User/UserGetter') +import recurly from 'recurly' + +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import OError from '@overleaf/o-error' +import { callbackify } from 'node:util' +import UserGetter from '../User/UserGetter.mjs' +import PaymentProviderEntities from './PaymentProviderEntities.mjs' +import { + MissingBillingInfoError, + SubtotalLimitExceededError, +} from './Errors.js' +import RecurlyMetrics from './RecurlyMetrics.mjs' +import { isStandaloneAiAddOnPlanCode, AI_ADD_ON_CODE } from './AiHelper.js' + const { PaymentProviderSubscription, PaymentProviderSubscriptionAddOn, @@ -17,13 +26,7 @@ const { PaymentProviderCoupon, PaymentProviderAccount, PaymentProviderImmediateCharge, -} = require('./PaymentProviderEntities') -const { - MissingBillingInfoError, - SubtotalLimitExceededError, -} = require('./Errors') -const RecurlyMetrics = require('./RecurlyMetrics') -const { isStandaloneAiAddOnPlanCode, AI_ADD_ON_CODE } = require('./AiHelper') +} = PaymentProviderEntities /** * @import { PaymentProviderSubscriptionChangeRequest } from './PaymentProviderEntities' @@ -798,7 +801,7 @@ async function terminateSubscriptionByUuid(subscriptionUuid) { return subscription } -module.exports = { +export default { errors: recurly.errors, getAccountForUserId: callbackify(getAccountForUserId), diff --git a/services/web/app/src/Features/Subscription/RecurlyMetrics.mjs b/services/web/app/src/Features/Subscription/RecurlyMetrics.mjs index 1b709d7dc4..c12c108206 100644 --- a/services/web/app/src/Features/Subscription/RecurlyMetrics.mjs +++ b/services/web/app/src/Features/Subscription/RecurlyMetrics.mjs @@ -1,4 +1,4 @@ -const Metrics = require('@overleaf/metrics') +import Metrics from '@overleaf/metrics' /** * @param {number} status @@ -32,7 +32,7 @@ function recordMetricsFromResponse(response) { recordMetrics(response.status, rateLimit, rateLimitRemaining, rateLimitReset) } -module.exports = { +export default { recordMetrics, recordMetricsFromResponse, } diff --git a/services/web/app/src/Features/Subscription/RecurlyWrapper.mjs b/services/web/app/src/Features/Subscription/RecurlyWrapper.mjs index 3df5dc1db5..e44d930411 100644 --- a/services/web/app/src/Features/Subscription/RecurlyWrapper.mjs +++ b/services/web/app/src/Features/Subscription/RecurlyWrapper.mjs @@ -1,15 +1,15 @@ -const OError = require('@overleaf/o-error') -const { +import OError from '@overleaf/o-error' +import { fetchStringWithResponse, RequestFailedError, -} = require('@overleaf/fetch-utils') -const Settings = require('@overleaf/settings') -const xml2js = require('xml2js') -const logger = require('@overleaf/logger') -const Errors = require('../Errors/Errors') -const SubscriptionErrors = require('./Errors') -const { callbackify } = require('@overleaf/promise-utils') -const RecurlyMetrics = require('./RecurlyMetrics') +} from '@overleaf/fetch-utils' +import Settings from '@overleaf/settings' +import xml2js from 'xml2js' +import logger from '@overleaf/logger' +import Errors from '../Errors/Errors.js' +import SubscriptionErrors from './Errors.js' +import { callbackify } from '@overleaf/promise-utils' +import RecurlyMetrics from './RecurlyMetrics.mjs' /** * Updates the email address of a Recurly account @@ -911,7 +911,7 @@ RecurlyWrapper.promises = { updateAccountEmailAddress, } -module.exports = RecurlyWrapper +export default RecurlyWrapper function getCustomFieldsFromSubscriptionDetails(subscriptionDetails) { if (!subscriptionDetails.ITMCampaign) { diff --git a/services/web/app/src/Features/Subscription/SubscriptionLocator.mjs b/services/web/app/src/Features/Subscription/SubscriptionLocator.mjs index 12d2cf1648..d4aa4477c9 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionLocator.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionLocator.mjs @@ -2,13 +2,14 @@ * @import { AddOn } from '../../../../types/subscription/plan' */ -const { callbackifyAll } = require('@overleaf/promise-utils') -const { Subscription } = require('../../models/Subscription') -const SubscriptionHelper = require('./SubscriptionHelper') -const { DeletedSubscription } = require('../../models/DeletedSubscription') -const logger = require('@overleaf/logger') -const { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } = require('./AiHelper') -require('./GroupPlansData') // make sure dynamic group plans are loaded +import { callbackifyAll } from '@overleaf/promise-utils' + +import { Subscription } from '../../models/Subscription.js' +import SubscriptionHelper from './SubscriptionHelper.js' +import { DeletedSubscription } from '../../models/DeletedSubscription.js' +import logger from '@overleaf/logger' +import { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } from './AiHelper.js' +import './GroupPlansData.js' // make sure dynamic group plans are loaded const SubscriptionLocator = { async getUsersSubscription(userOrId) { @@ -215,7 +216,7 @@ const SubscriptionLocator = { }, } -module.exports = { +export default { ...callbackifyAll(SubscriptionLocator), promises: SubscriptionLocator, } diff --git a/services/web/app/src/Features/Subscription/SubscriptionUpdater.mjs b/services/web/app/src/Features/Subscription/SubscriptionUpdater.mjs index 9de194f262..39b1cf7025 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionUpdater.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionUpdater.mjs @@ -1,20 +1,20 @@ -const { db, ObjectId } = require('../../infrastructure/mongodb') -const { callbackify } = require('@overleaf/promise-utils') -const { Subscription } = require('../../models/Subscription') -const SubscriptionLocator = require('./SubscriptionLocator') -const PlansLocator = require('./PlansLocator') -const FeaturesUpdater = require('./FeaturesUpdater') -const FeaturesHelper = require('./FeaturesHelper') -const AnalyticsManager = require('../Analytics/AnalyticsManager') -const { DeletedSubscription } = require('../../models/DeletedSubscription') -const logger = require('@overleaf/logger') -const Features = require('../../infrastructure/Features') -const UserAuditLogHandler = require('../User/UserAuditLogHandler') -const UserUpdater = require('../User/UserUpdater') -const AccountMappingHelper = require('../Analytics/AccountMappingHelper') -const { SSOConfig } = require('../../models/SSOConfig') -const mongoose = require('../../infrastructure/Mongoose') -const Modules = require('../../infrastructure/Modules') +import { db, ObjectId } from '../../infrastructure/mongodb.js' +import { callbackify } from '@overleaf/promise-utils' +import { Subscription } from '../../models/Subscription.js' +import SubscriptionLocator from './SubscriptionLocator.mjs' +import PlansLocator from './PlansLocator.mjs' +import FeaturesUpdater from './FeaturesUpdater.mjs' +import FeaturesHelper from './FeaturesHelper.mjs' +import AnalyticsManager from '../Analytics/AnalyticsManager.mjs' +import { DeletedSubscription } from '../../models/DeletedSubscription.js' +import logger from '@overleaf/logger' +import Features from '../../infrastructure/Features.js' +import UserAuditLogHandler from '../User/UserAuditLogHandler.mjs' +import UserUpdater from '../User/UserUpdater.mjs' +import AccountMappingHelper from '../Analytics/AccountMappingHelper.mjs' +import { SSOConfig } from '../../models/SSOConfig.js' +import mongoose from '../../infrastructure/Mongoose.js' +import Modules from '../../infrastructure/Modules.js' /** * @typedef {import('../../../../types/subscription/dashboard/subscription').Subscription} Subscription @@ -553,7 +553,7 @@ async function voidRestorePoint(subscriptionId) { await setRestorePoint(subscriptionId, null, null, false) } -module.exports = { +export default { updateAdmin: callbackify(updateAdmin), syncSubscription: callbackify(syncSubscription), createNewSubscription: callbackify(createNewSubscription), diff --git a/services/web/app/src/Features/Subscription/UserFeaturesUpdater.mjs b/services/web/app/src/Features/Subscription/UserFeaturesUpdater.mjs index e29eb8e0e2..0fd61c791a 100644 --- a/services/web/app/src/Features/Subscription/UserFeaturesUpdater.mjs +++ b/services/web/app/src/Features/Subscription/UserFeaturesUpdater.mjs @@ -1,6 +1,6 @@ -const { User } = require('../../models/User') -const { callbackify } = require('util') -const Settings = require('@overleaf/settings') +import { User } from '../../models/User.js' +import { callbackify } from 'node:util' +import Settings from '@overleaf/settings' function _featuresChanged(newFeatures, featuresBefore) { for (const feature in newFeatures) { @@ -49,7 +49,7 @@ async function createFeaturesOverride(userId, featuresOverride) { ).exec() } -module.exports = { +export default { updateFeatures: callbackify(updateFeatures), overrideFeatures: callbackify(overrideFeatures), createFeaturesOverride: callbackify(createFeaturesOverride), diff --git a/services/web/app/src/Features/Subscription/V1SubscriptionManager.mjs b/services/web/app/src/Features/Subscription/V1SubscriptionManager.mjs index 6a852eb974..bc4d1a4b33 100644 --- a/services/web/app/src/Features/Subscription/V1SubscriptionManager.mjs +++ b/services/web/app/src/Features/Subscription/V1SubscriptionManager.mjs @@ -1,11 +1,10 @@ -let V1SubscriptionManager -const UserGetter = require('../User/UserGetter') -const request = require('requestretry') -const settings = require('@overleaf/settings') -const { V1ConnectionError, NotFoundError } = require('../Errors/Errors') -const { promisifyAll } = require('@overleaf/promise-utils') +import UserGetter from '../User/UserGetter.mjs' +import request from 'requestretry' +import settings from '@overleaf/settings' +import { V1ConnectionError, NotFoundError } from '../Errors/Errors.js' +import { promisifyAll } from '@overleaf/promise-utils' -module.exports = V1SubscriptionManager = { +const V1SubscriptionManager = { cancelV1Subscription(userId, callback) { V1SubscriptionManager._v1Request( userId, @@ -118,6 +117,8 @@ module.exports = V1SubscriptionManager = { }, } -module.exports.promises = promisifyAll(module.exports, { +V1SubscriptionManager.promises = promisifyAll(V1SubscriptionManager, { without: ['getGrandfatheredFeaturesForV1User'], }) + +export default V1SubscriptionManager diff --git a/services/web/app/src/Features/Tags/TagsHandler.mjs b/services/web/app/src/Features/Tags/TagsHandler.mjs index 65314c8d74..72bf9f79e0 100644 --- a/services/web/app/src/Features/Tags/TagsHandler.mjs +++ b/services/web/app/src/Features/Tags/TagsHandler.mjs @@ -1,5 +1,5 @@ -const { Tag } = require('../../models/Tag') -const { callbackify } = require('@overleaf/promise-utils') +import { Tag } from '../../models/Tag.js' +import { callbackify } from '@overleaf/promise-utils' const MAX_TAG_LENGTH = 50 @@ -133,7 +133,7 @@ async function addProjectToTags(userId, tagIds, projectId) { await Tag.updateMany(searchOps, insertOperation) } -module.exports = { +export default { getAllTags: callbackify(getAllTags), countTagsForProject: callbackify(countTagsForProject), getTagsForProject: callbackify(getTagsForProject), diff --git a/services/web/app/src/Features/TokenAccess/TokenAccessHandler.mjs b/services/web/app/src/Features/TokenAccess/TokenAccessHandler.mjs index 945bf96a74..05b350f789 100644 --- a/services/web/app/src/Features/TokenAccess/TokenAccessHandler.mjs +++ b/services/web/app/src/Features/TokenAccess/TokenAccessHandler.mjs @@ -1,15 +1,18 @@ -const { Project } = require('../../models/Project') -const PublicAccessLevels = require('../Authorization/PublicAccessLevels') -const PrivilegeLevels = require('../Authorization/PrivilegeLevels') -const { ObjectId } = require('mongodb-legacy') -const Metrics = require('@overleaf/metrics') -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const V1Api = require('../V1/V1Api') -const crypto = require('crypto') -const { callbackifyAll } = require('@overleaf/promise-utils') -const Analytics = require('../Analytics/AnalyticsManager') -const Features = require('../../infrastructure/Features') +import { Project } from '../../models/Project.js' +import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs' +import PrivilegeLevels from '../Authorization/PrivilegeLevels.js' +import mongodb from 'mongodb-legacy' +import Metrics from '@overleaf/metrics' +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import V1Api from '../V1/V1Api.js' +import crypto from 'node:crypto' +import { callbackifyAll } from '@overleaf/promise-utils' +import Analytics from '../Analytics/AnalyticsManager.mjs' +import Features from '../../infrastructure/Features.js' + +const { ObjectId } = mongodb + const READ_AND_WRITE_TOKEN_PATTERN = '([0-9]+[a-z]{6,12})' const READ_ONLY_TOKEN_PATTERN = '([a-z]{12})' @@ -337,7 +340,7 @@ const TokenAccessHandler = { }, } -module.exports = { +export default { ...TokenAccessHandler, ...callbackifyAll(TokenAccessHandler, { multiResult: { diff --git a/services/web/app/src/Features/Uploads/ArchiveManager.mjs b/services/web/app/src/Features/Uploads/ArchiveManager.mjs index fc81fdb4b3..6c3c470c85 100644 --- a/services/web/app/src/Features/Uploads/ArchiveManager.mjs +++ b/services/web/app/src/Features/Uploads/ArchiveManager.mjs @@ -12,20 +12,21 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const logger = require('@overleaf/logger') -const OError = require('@overleaf/o-error') -const metrics = require('@overleaf/metrics') -const fs = require('fs') -const Path = require('path') -const yauzl = require('yauzl') -const Settings = require('@overleaf/settings') -const { +import logger from '@overleaf/logger' + +import OError from '@overleaf/o-error' +import metrics from '@overleaf/metrics' +import fs from 'node:fs' +import Path from 'node:path' +import yauzl from 'yauzl' +import Settings from '@overleaf/settings' +import { InvalidZipFileError, EmptyZipFileError, ZipContentsTooLargeError, -} = require('./ArchiveErrors') -const _ = require('lodash') -const { promisifyAll } = require('@overleaf/promise-utils') +} from './ArchiveErrors.js' +import _ from 'lodash' +import { promisifyAll } from '@overleaf/promise-utils' const ONE_MEG = 1024 * 1024 @@ -267,4 +268,4 @@ const ArchiveManager = { } ArchiveManager.promises = promisifyAll(ArchiveManager) -module.exports = ArchiveManager +export default ArchiveManager diff --git a/services/web/app/src/Features/Uploads/FileTypeManager.mjs b/services/web/app/src/Features/Uploads/FileTypeManager.mjs index bd6f1d9e0d..bb489bcd92 100644 --- a/services/web/app/src/Features/Uploads/FileTypeManager.mjs +++ b/services/web/app/src/Features/Uploads/FileTypeManager.mjs @@ -1,11 +1,12 @@ // @ts-check -const fs = require('fs/promises') -const Path = require('path') -const { callbackify } = require('util') -const isUtf8 = require('utf-8-validate') -const Settings = require('@overleaf/settings') -const Minimatch = require('minimatch').Minimatch +import fs from 'node:fs/promises' + +import Path from 'node:path' +import { callbackify } from 'node:util' +import isUtf8 from 'utf-8-validate' +import Settings from '@overleaf/settings' +import { Minimatch } from 'minimatch' const FILE_IGNORE_MATCHER = new Minimatch(Settings.fileIgnorePattern, { // make the whole path matching case-insensitive (previously we were only @@ -110,7 +111,7 @@ function _detectEncoding(bytes) { return 'latin1' } -module.exports = { +export default { shouldIgnore, isEditable, getType: callbackify(getType), diff --git a/services/web/app/src/Features/User/ThirdPartyIdentityManager.mjs b/services/web/app/src/Features/User/ThirdPartyIdentityManager.mjs index 63622dc31e..65f3fa62c5 100644 --- a/services/web/app/src/Features/User/ThirdPartyIdentityManager.mjs +++ b/services/web/app/src/Features/User/ThirdPartyIdentityManager.mjs @@ -1,13 +1,13 @@ -const UserAuditLogHandler = require('../../../../app/src/Features/User/UserAuditLogHandler') -const EmailHandler = require('../../../../app/src/Features/Email/EmailHandler') -const EmailOptionsHelper = require('../../../../app/src/Features/Email/EmailOptionsHelper') -const Errors = require('../Errors/Errors') -const _ = require('lodash') -const logger = require('@overleaf/logger') -const settings = require('@overleaf/settings') -const { User } = require('../../../../app/src/models/User') -const { callbackify } = require('@overleaf/promise-utils') -const OError = require('@overleaf/o-error') +import UserAuditLogHandler from '../../../../app/src/Features/User/UserAuditLogHandler.mjs' +import EmailHandler from '../../../../app/src/Features/Email/EmailHandler.mjs' +import EmailOptionsHelper from '../../../../app/src/Features/Email/EmailOptionsHelper.mjs' +import Errors from '../Errors/Errors.js' +import _ from 'lodash' +import logger from '@overleaf/logger' +import settings from '@overleaf/settings' +import { User } from '../../../../app/src/models/User.js' +import { callbackify } from '@overleaf/promise-utils' +import OError from '@overleaf/o-error' const oauthProviders = settings.oauthProviders || {} @@ -214,4 +214,4 @@ ThirdPartyIdentityManager.promises = { unlink, } -module.exports = ThirdPartyIdentityManager +export default ThirdPartyIdentityManager diff --git a/services/web/app/src/Features/User/UserAuditLogHandler.mjs b/services/web/app/src/Features/User/UserAuditLogHandler.mjs index 0445363f01..be5ac971dd 100644 --- a/services/web/app/src/Features/User/UserAuditLogHandler.mjs +++ b/services/web/app/src/Features/User/UserAuditLogHandler.mjs @@ -1,8 +1,8 @@ -const OError = require('@overleaf/o-error') -const logger = require('@overleaf/logger') -const { UserAuditLogEntry } = require('../../models/UserAuditLogEntry') -const { callbackify } = require('util') -const SubscriptionLocator = require('../Subscription/SubscriptionLocator') +import OError from '@overleaf/o-error' +import logger from '@overleaf/logger' +import { UserAuditLogEntry } from '../../models/UserAuditLogEntry.js' +import { callbackify } from 'node:util' +import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs' function _canHaveNoIpAddressId(operation, info) { if (operation === 'join-group-subscription') return true @@ -98,4 +98,4 @@ const UserAuditLogHandler = { }, } -module.exports = UserAuditLogHandler +export default UserAuditLogHandler diff --git a/services/web/app/src/Features/User/UserGetter.mjs b/services/web/app/src/Features/User/UserGetter.mjs index d724d756b6..d2cbda1441 100644 --- a/services/web/app/src/Features/User/UserGetter.mjs +++ b/services/web/app/src/Features/User/UserGetter.mjs @@ -1,18 +1,18 @@ -const { callbackify } = require('util') -const { db } = require('../../infrastructure/mongodb') -const moment = require('moment') -const settings = require('@overleaf/settings') -const { - promises: InstitutionsAPIPromises, -} = require('../Institutions/InstitutionsAPI') -const InstitutionsHelper = require('../Institutions/InstitutionsHelper') -const Errors = require('../Errors/Errors') -const Features = require('../../infrastructure/Features') -const { User } = require('../../models/User') -const { normalizeQuery, normalizeMultiQuery } = require('../Helpers/Mongo') -const Modules = require('../../infrastructure/Modules') -const FeaturesHelper = require('../Subscription/FeaturesHelper') -const AsyncLocalStorage = require('../../infrastructure/AsyncLocalStorage') +import { callbackify } from 'node:util' +import { db } from '../../infrastructure/mongodb.js' +import moment from 'moment' +import settings from '@overleaf/settings' +import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs' +import InstitutionsHelper from '../Institutions/InstitutionsHelper.mjs' +import Errors from '../Errors/Errors.js' +import Features from '../../infrastructure/Features.js' +import { User } from '../../models/User.js' +import { normalizeQuery, normalizeMultiQuery } from '../Helpers/Mongo.js' +import Modules from '../../infrastructure/Modules.js' +import FeaturesHelper from '../Subscription/FeaturesHelper.mjs' +import AsyncLocalStorage from '../../infrastructure/AsyncLocalStorage.js' + +const InstitutionsAPIPromises = InstitutionsAPI.promises function _lastDayToReconfirm(emailData, institutionData) { const globalReconfirmPeriod = settings.reconfirmNotificationDays @@ -369,4 +369,4 @@ UserGetter.promises = { getWritefullData, } -module.exports = UserGetter +export default UserGetter diff --git a/services/web/app/src/Features/User/UserSessionsManager.mjs b/services/web/app/src/Features/User/UserSessionsManager.mjs index b8d51b9282..0f48732bab 100644 --- a/services/web/app/src/Features/User/UserSessionsManager.mjs +++ b/services/web/app/src/Features/User/UserSessionsManager.mjs @@ -1,8 +1,8 @@ -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const _ = require('lodash') -const { callbackifyAll } = require('@overleaf/promise-utils') -const UserSessionsRedis = require('./UserSessionsRedis') +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import _ from 'lodash' +import { callbackifyAll } from 'node:util' +import UserSessionsRedis from './UserSessionsRedis.mjs' const rclient = UserSessionsRedis.client() const UserSessionsManager = { @@ -161,7 +161,7 @@ const UserSessionsManager = { }, } -module.exports = { +export default { ...callbackifyAll(UserSessionsManager), - promises: UserSessionsManager, + promises: UserSessionsManager } diff --git a/services/web/app/src/Features/User/UserSessionsRedis.mjs b/services/web/app/src/Features/User/UserSessionsRedis.mjs index 689e4148c0..ff41eb6b15 100644 --- a/services/web/app/src/Features/User/UserSessionsRedis.mjs +++ b/services/web/app/src/Features/User/UserSessionsRedis.mjs @@ -1,4 +1,4 @@ -const RedisWrapper = require('../../infrastructure/RedisWrapper') +import RedisWrapper from '../../infrastructure/RedisWrapper.js' const rclient = RedisWrapper.client('websessions') const UserSessionsRedis = { @@ -10,4 +10,4 @@ const UserSessionsRedis = { return `UserSessions:{${user._id}}` }, } -module.exports = UserSessionsRedis +export default UserSessionsRedis diff --git a/services/web/app/src/Features/User/UserUpdater.mjs b/services/web/app/src/Features/User/UserUpdater.mjs index b015dbf739..b45eb9a31a 100644 --- a/services/web/app/src/Features/User/UserUpdater.mjs +++ b/services/web/app/src/Features/User/UserUpdater.mjs @@ -1,26 +1,26 @@ -const logger = require('@overleaf/logger') -const OError = require('@overleaf/o-error') -const { db } = require('../../infrastructure/mongodb') -const { normalizeQuery } = require('../Helpers/Mongo') -const { callbackify } = require('util') -const UserGetter = require('./UserGetter') -const InstitutionsAPI = require('../Institutions/InstitutionsAPI') -const Features = require('../../infrastructure/Features') -const FeaturesUpdater = require('../Subscription/FeaturesUpdater') -const EmailHandler = require('../Email/EmailHandler') -const EmailHelper = require('../Helpers/EmailHelper') -const Errors = require('../Errors/Errors') -const NewsletterManager = require('../Newsletter/NewsletterManager') -const UserAuditLogHandler = require('./UserAuditLogHandler') -const AnalyticsManager = require('../Analytics/AnalyticsManager') -const EmailChangeHelper = require('../Analytics/EmailChangeHelper') -const SubscriptionLocator = require('../Subscription/SubscriptionLocator') -const NotificationsBuilder = require('../Notifications/NotificationsBuilder') -const _ = require('lodash') -const Modules = require('../../infrastructure/Modules') -const UserSessionsManager = require('./UserSessionsManager') -const ThirdPartyIdentityManager = require('./ThirdPartyIdentityManager') -const AsyncLocalStorage = require('../../infrastructure/AsyncLocalStorage') +import logger from '@overleaf/logger' +import OError from '@overleaf/o-error' +import { db } from '../../infrastructure/mongodb.js' +import { normalizeQuery } from '../Helpers/Mongo.js' +import { callbackify } from 'node:util' +import UserGetter from './UserGetter.mjs' +import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs' +import Features from '../../infrastructure/Features.js' +import FeaturesUpdater from '../Subscription/FeaturesUpdater.mjs' +import EmailHandler from '../Email/EmailHandler.mjs' +import EmailHelper from '../Helpers/EmailHelper.js' +import Errors from '../Errors/Errors.js' +import NewsletterManager from '../Newsletter/NewsletterManager.mjs' +import UserAuditLogHandler from './UserAuditLogHandler.mjs' +import AnalyticsManager from '../Analytics/AnalyticsManager.mjs' +import EmailChangeHelper from '../Analytics/EmailChangeHelper.mjs' +import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs' +import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs' +import _ from 'lodash' +import Modules from '../../infrastructure/Modules.js' +import UserSessionsManager from './UserSessionsManager.mjs' +import ThirdPartyIdentityManager from './ThirdPartyIdentityManager.mjs' +import AsyncLocalStorage from '../../infrastructure/AsyncLocalStorage.js' async function _sendSecurityAlertPrimaryEmailChanged( userId, @@ -683,7 +683,7 @@ function _securityAlertPrimaryEmailChangedExtraRecipients( return Array.from(recipients) } -module.exports = { +export default { addAffiliationForNewUser: callbackify(addAffiliationForNewUser), addEmailAddress: callbackify(addEmailAddress), changeEmailAddress: callbackify(changeEmailAddress), diff --git a/services/web/app/src/Features/UserMembership/UserMembershipEntityConfigs.mjs b/services/web/app/src/Features/UserMembership/UserMembershipEntityConfigs.mjs index c65f38e952..6b20041b03 100644 --- a/services/web/app/src/Features/UserMembership/UserMembershipEntityConfigs.mjs +++ b/services/web/app/src/Features/UserMembership/UserMembershipEntityConfigs.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { group: { modelName: 'Subscription', readOnly: true, diff --git a/services/web/app/src/Features/UserMembership/UserMembershipsHandler.mjs b/services/web/app/src/Features/UserMembership/UserMembershipsHandler.mjs index cbd12e47cd..3e5239cdae 100644 --- a/services/web/app/src/Features/UserMembership/UserMembershipsHandler.mjs +++ b/services/web/app/src/Features/UserMembership/UserMembershipsHandler.mjs @@ -9,14 +9,19 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const async = require('async') -const { promisifyAll } = require('@overleaf/promise-utils') +import async from 'async' + +import { promisifyAll } from '@overleaf/promise-utils' +import UserMembershipEntityConfigs from './UserMembershipEntityConfigs.mjs' +import InstitutionModel from '../../models/Institution.js' +import SubscriptionModel from '../../models/Subscription.js' +import PublisherModel from '../../models/Publisher.js' + const EntityModels = { - Institution: require('../../models/Institution').Institution, - Subscription: require('../../models/Subscription').Subscription, - Publisher: require('../../models/Publisher').Publisher, + Institution: InstitutionModel.Institution, + Subscription: SubscriptionModel.Subscription, + Publisher: PublisherModel.Publisher, } -const UserMembershipEntityConfigs = require('./UserMembershipEntityConfigs') const UserMembershipsHandler = { removeUserFromAllEntities(userId, callback) { @@ -80,4 +85,4 @@ const UserMembershipsHandler = { } UserMembershipsHandler.promises = promisifyAll(UserMembershipsHandler) -module.exports = UserMembershipsHandler +export default UserMembershipsHandler