27 Commits

Author SHA1 Message Date
Gernot Schulz
05844b8e08 Merge pull request #29540 from overleaf/gs-jenkins-pr-build-tags-remote
Check if Jenkins checkout revision exists on remote

GitOrigin-RevId: cb110f5479836ccbfd1a62f501210dee6606d37e
2025-11-06 09:07:23 +00:00
Borja
7f96e9504e Revert "Writefull refactor bootstrapping (#29306)" (#29542)
This reverts commit 6de05eb695579dc08cb5ee6ddf30c243cc2ff86a.

GitOrigin-RevId: 1fe00bd95b2ce437f91b38667e4d787d49c36902
2025-11-06 09:07:14 +00:00
Andrew Rumble
f5eb8e9ba4 Update paths
GitOrigin-RevId: 5bc9bccf2cd10631cb88412f426a8e3c73c9f689
2025-11-06 09:07:09 +00:00
Andrew Rumble
5914c9ff09 Update paths
GitOrigin-RevId: 298e3de065fbab3703e90a3d56a89c448fe164e2
2025-11-06 09:06:57 +00:00
Andrew Rumble
b5216af8f7 Convert to ESM
GitOrigin-RevId: 097bc45d500b4d2538ee49d60a597619579419a5
2025-11-06 09:06:52 +00:00
Andrew Rumble
ed966e1392 Rename files
GitOrigin-RevId: 1cb1e8929018da4cdc0cf01746511fd6e4243a1b
2025-11-06 09:06:47 +00:00
Antoine Clausse
25993cb858 [web] Add script to check for wrongly removed confirmed emails (#29532)
* [web] Add script to check for wrongly removed confirmed emails

* List emails that were added again

* Use `trackProgress`

* Prettier logs

* Add `READ_PREFERENCE_SECONDARY`

* Check `change-primary-email`

* Add check with `confirm-email` should be always empty, but let's check

* Update services/web/scripts/check_removed_emails.mjs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
GitOrigin-RevId: 4f83d69cffd0aec2c5d1201f1f6130eacdbb2e39
2025-11-06 09:06:42 +00:00
David
fd96baaf05 Merge pull request #29536 from overleaf/dp-fix-logo
Fix overleaf logo color on ds nav

GitOrigin-RevId: c48ed09339aa1af03bdbad29e76d8cdb74260f0c
2025-11-06 09:06:37 +00:00
roo hutton
2e11f2c7b7 Merge pull request #29394 from overleaf/rh-compile-timeout-modal
Add compile timeout modal for compile-timeout-target-plans test

GitOrigin-RevId: b352cb239742aa7ffbef7f3cd5c65ac719569ebf
2025-11-06 09:06:29 +00:00
David
faceb90593 Merge pull request #29290 from overleaf/dp-dashboard-dark-2
Dark mode for DS nav

GitOrigin-RevId: fb8ad9ec45e88c39810421d11ecc69ab874121ce
2025-11-06 09:06:24 +00:00
Brian Gough
d10cdb96b3 Merge pull request #29530 from overleaf/revert-29472-mfb-from-joi-to-zod-real-time
Revert "Mfb from joi to zod real time"

GitOrigin-RevId: 3bb8b01c692083c1b15d8a53066c01f0ec7af8f6
2025-11-06 09:06:19 +00:00
Andrew Rumble
da91e15aa0 Export everything from PaymentProviderEntities
This improves the type inference in modules that check the types.

GitOrigin-RevId: c8ffc1f7c04fbbc097758b1bc1e63ea33e52d3ba
2025-11-06 09:06:14 +00:00
Andrew Rumble
c7c15b2066 Split tests into sequential and parallel projects
Sequential tests need to be run without parallelism because they rely on
a database fixture that can have side effects.

GitOrigin-RevId: b614cbe4dbaf2319e681d5607a0a64cbbed8c021
2025-11-06 09:06:06 +00:00
Andrew Rumble
4f02a85aa4 Update paths
GitOrigin-RevId: 399c594dd1bbf739d91874df6be3b70e57fe01e3
2025-11-06 09:05:57 +00:00
Andrew Rumble
93b7274ea6 Convert tests to ESM
GitOrigin-RevId: 03bd4db8cddc548706439edd7f6db0bc3e7ed9d3
2025-11-06 09:05:51 +00:00
Andrew Rumble
912324f560 Convert to ESM
GitOrigin-RevId: b58b02f9e9c8d47909e95c3ade8e1bf33ed46c80
2025-11-06 09:05:47 +00:00
Andrew Rumble
0f4d5a7be6 Rename files
GitOrigin-RevId: 80b975b03ebca16328b84fabf11e71bbea87c8bc
2025-11-06 09:05:41 +00:00
Borja
1a511b14a4 Writefull refactor bootstrapping (#29306)
GitOrigin-RevId: 6de05eb695579dc08cb5ee6ddf30c243cc2ff86a
2025-11-05 09:07:09 +00:00
Maria Florencia Besteiro Gonzalez
820ce8ad1c Merge pull request #29472 from overleaf/mfb-from-joi-to-zod-real-time
Mfb from joi to zod real time

GitOrigin-RevId: 657c18bae01eaeea76bf308579a7bea1388253d6
2025-11-05 09:07:04 +00:00
Jakob Ackermann
3586b37491 [web] Remove clsi-cache-prompt/survey, split-tests and events (#29510)
* [web] Remove clsi-cache-prompt/survey and split-tests

* [web] Remove initial 50/50 clsi-cache split-test

* [web] Remove synctex-downloaded-from-cache event

* [web] Remove fallback-to-clsi-cache event

* [saas-e2e] fix tests with clsi-cache enabled

GitOrigin-RevId: b5cf2ab073dc866fe398b81fd5afe46422134c80
2025-11-05 09:06:59 +00:00
David
6aa9e5c855 Merge pull request #29496 from overleaf/dp-remove-new-editor-old-logs
Move all new editor users to new logs

GitOrigin-RevId: 224a4476eddb6576eaa04086a68b6579650a1bc5
2025-11-05 09:06:50 +00:00
David
d48518e01d Merge pull request #29495 from overleaf/dp-remove-new-logs-position
Remove error logs from new editor rail

GitOrigin-RevId: 9d0b134345b63618334c5507089debf2df104274
2025-11-05 09:06:45 +00:00
Jakob Ackermann
5140fff347 [clsi] gracefully handle fast exit of synctex/wordcount containers (#29505)
* [clsi] gracefully handle fast exit of synctex/wordcount containers

* [clsi] do not change container options in-place for logging

GitOrigin-RevId: 0b685310a3c72f8f46125fefaa30c1ddb19e7b07
2025-11-05 09:06:40 +00:00
Jakob Ackermann
6691c5dc05 [monorepo] enable mongo notablescan for all services but web (#29497)
* [migrations] make old migrations compatible with --notablescan in mongo

Re-running the migration for db.users.emails.reversedHostname on all
Server Pro/CE users will not be harmfull.

* [monorepo] enable mongo notablescan for all services but web

GitOrigin-RevId: e2a710c9de08de9ac2aa9df1f3082d5f1c33ea05
2025-11-05 09:06:35 +00:00
Antoine Clausse
2ebc411db4 [web] Create a first implementation of the CIAM version of the email confirmation page (#29432)
* Move `main#main-content.content.content-alt` into a React component (`ContentLayout`)

* Create the CIAM variant of `RegistrationConfirmEmailForm`

* `bin/run web npm run extract-translations`

* Use `CiamLayout` in the Storybook demo

* Add `SplitTestProvider` in tests

* Fix Storybook: Wrap `RegistrationConfirmEmailForm` Story in `onboarding-confirm-email`

* Refactor SCSS files:

- only imports in all.scss
- split .storybook-layout and .storybook-enabled
- extract ciam-spacing.scss

GitOrigin-RevId: f4a214a0978423a1621dd8f60bf459af7b8f877e
2025-11-05 09:06:30 +00:00
Miguel Serrano
a4d9d5789a [web] Add User logs to Group Audit Logs view (#29480)
* Revert "Revert "[web] Add User logs to Group Audit Logs view (#29155)" (#29479)"

This reverts commit 40a1516ab9cec690d0487a0a870b9fab17598d60.

* Fix `managedUsersEnabled` flag in frontend

GitOrigin-RevId: ae3edf5bcbc01ec46bc18028e758d3364072c307
2025-11-05 09:06:25 +00:00
Jakob Ackermann
78d7178c08 [web] fix gallery templates e2e tests (#29508)
GitOrigin-RevId: ba8a1ddfd56b3221db92e2869e0852fd4c7a4348
2025-11-05 09:06:20 +00:00
488 changed files with 18160 additions and 18135 deletions

View File

@@ -52,7 +52,7 @@ services:
user: root
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -10,6 +10,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
working_dir: /overleaf/services/chat
environment:
MOCHA_GREP: ${MOCHA_GREP}
@@ -50,7 +51,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -176,29 +176,35 @@ const DockerRunner = {
return callback(error)
}
DockerRunner.waitForContainer(name, timeout, (error, exitCode) => {
if (error != null) {
return callback(error)
DockerRunner.waitForContainer(
name,
timeout,
options,
(error, exitCode) => {
if (error != null) {
return callback(error)
}
if (exitCode === 137) {
// exit status from kill -9
const err = new Error('terminated')
err.terminated = true
return callback(err)
}
if (exitCode === 1) {
// exit status from chktex
const err = new Error('exited')
err.code = exitCode
return callback(err)
}
containerReturned = true
logger.debug(
// The seccomp policy is very large. Avoid logging it. _.omit deep clones.
{ exitCode, options: _.omit(options, 'HostConfig.SecurityOpt') },
'docker container has exited'
)
callbackIfFinished()
}
if (exitCode === 137) {
// exit status from kill -9
const err = new Error('terminated')
err.terminated = true
return callback(err)
}
if (exitCode === 1) {
// exit status from chktex
const err = new Error('exited')
err.code = exitCode
return callback(err)
}
containerReturned = true
if (options != null && options.HostConfig != null) {
options.HostConfig.SecurityOpt = null
}
logger.debug({ exitCode, options }, 'docker container has exited')
callbackIfFinished()
})
)
}
)
},
@@ -429,7 +435,7 @@ const DockerRunner = {
})
},
waitForContainer(containerId, timeout, _callback) {
waitForContainer(containerId, timeout, options, _callback) {
const callback = _.once(_callback)
const container = dockerode.getContainer(containerId)
@@ -445,6 +451,14 @@ const DockerRunner = {
logger.debug({ containerId }, 'waiting for docker container')
container.wait((error, res) => {
if (error?.statusCode === 404 && options.HostConfig.AutoRemove) {
logger.debug(
{ containerId },
'auto-destroy container destroyed before starting to wait'
)
clearTimeout(timeoutId)
return callback(null, 0)
}
if (error != null) {
clearTimeout(timeoutId)
logger.warn({ err: error, containerId }, 'error waiting for container')

View File

@@ -514,7 +514,7 @@ describe('DockerRunner', function () {
sinon.spy(this.DockerRunner, 'startContainer')
this.DockerRunner.waitForContainer = sinon
.stub()
.callsArgWith(2, null, (this.exitCode = 42))
.callsArgWith(3, null, (this.exitCode = 42))
return this.DockerRunner._runAndWaitForContainer(
this.options,
this.volumes,
@@ -675,6 +675,7 @@ describe('DockerRunner', function () {
return this.DockerRunner.waitForContainer(
this.containerId,
this.timeout,
{},
this.callback
)
})
@@ -691,6 +692,49 @@ describe('DockerRunner', function () {
})
})
describe('when the container is removed before waiting', function () {
const err = new Error('not found')
err.statusCode = 404
beforeEach(function () {
this.container.wait = sinon.stub().yields(err)
})
describe('AutoRemove not set', function () {
beforeEach(function () {
this.DockerRunner.waitForContainer(
this.containerId,
this.timeout,
{ HostConfig: {} },
this.callback
)
})
it('should wait for the container', function () {
this.getContainer.calledWith(this.containerId).should.equal(true)
this.container.wait.called.should.equal(true)
})
it('should call the callback with the error', function () {
this.callback.calledWith(err).should.equal(true)
})
})
describe('AutoRemove=true', function () {
beforeEach(function () {
this.DockerRunner.waitForContainer(
this.containerId,
this.timeout,
{ HostConfig: { AutoRemove: true } },
this.callback
)
})
it('should wait for the container', function () {
this.getContainer.calledWith(this.containerId).should.equal(true)
this.container.wait.called.should.equal(true)
})
it('should call the callback with exit code 0', function () {
this.callback.calledWith(null, 0).should.equal(true)
})
})
})
return describe('when the container does not return before the timeout', function () {
beforeEach(function (done) {
this.container.wait = function (callback) {
@@ -703,6 +747,7 @@ describe('DockerRunner', function () {
return this.DockerRunner.waitForContainer(
this.containerId,
this.timeout,
{},
(...args) => {
this.callback(...Array.from(args || []))
return done()

View File

@@ -52,7 +52,7 @@ services:
user: root
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -10,6 +10,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
working_dir: /overleaf/services/contacts
environment:
MOCHA_GREP: ${MOCHA_GREP}
@@ -50,7 +51,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -5,6 +5,7 @@ import { expect } from 'chai'
import { ObjectId } from 'mongodb'
import { cleanupTestDatabase } from '../../../app/js/mongodb.js'
import * as ContactManager from '../../../app/js/ContactManager.js'
import '../../acceptance/js/MongoHelper.js'
describe('ContactManager', function () {
beforeEach(cleanupTestDatabase)

View File

@@ -57,7 +57,7 @@ services:
user: root
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -10,6 +10,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
working_dir: /overleaf/services/docstore
environment:
MOCHA_GREP: ${MOCHA_GREP}
@@ -55,7 +56,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -71,7 +71,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -10,6 +10,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
working_dir: /overleaf/services/document-updater
environment:
MOCHA_GREP: ${MOCHA_GREP}
@@ -69,7 +70,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -95,7 +95,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -16,6 +16,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
working_dir: /overleaf/services/history-v1
environment:
MOCHA_GREP: ${MOCHA_GREP}
@@ -99,7 +100,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -20,7 +20,8 @@ async function setupPostgresDatabase() {
async function setupMongoDatabase() {
this.timeout(60_000)
await promisify(exec)(
`cd ../../tools/migrations && npm run migrations -- migrate -t server-ce`
// Run saas migrations for backup indexes
`cd ../../tools/migrations && npm run migrations -- migrate -t saas`
)
}

View File

@@ -55,7 +55,7 @@ services:
user: root
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -10,6 +10,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
- ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
working_dir: /overleaf/services/notifications
environment:
@@ -52,7 +53,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -71,7 +71,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -10,6 +10,7 @@ services:
- ../../node_modules:/overleaf/node_modules
- ../../libraries:/overleaf/libraries
- ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
- ../../tools/migrations:/overleaf/tools/migrations
working_dir: /overleaf/services/project-history
environment:
MOCHA_GREP: ${MOCHA_GREP}
@@ -69,7 +70,7 @@ services:
mongo:
image: mongo:8.0.11
command: --replSet overleaf
command: --replSet overleaf --notablescan
volumes:
- ../../bin/shared/mongodb-init-replica-set.js:/docker-entrypoint-initdb.d/mongodb-init-replica-set.js
- ../../bin/shared/mongodb-docker-entrypoint-wait.sh:/mongodb-docker-entrypoint-wait.sh

View File

@@ -12,6 +12,11 @@ export const defaultSplitTestsArgTypes = {
},
options: ['enabled'],
},
uniaccessphase1: {
description: 'Enable CIAM designs',
control: { type: 'select' as const },
options: ['default', 'enabled'],
},
}
export const withSplitTests = <ArgTypes = typeof defaultSplitTestsArgTypes,>(

View File

@@ -30,9 +30,21 @@ pipeline {
script {
def relevantCommitHash
if (env.CHANGE_BRANCH) {
echo "PR build detected. Jenkins checked out a merge commit: ${GIT_COMMIT}"
relevantCommitHash = sh(script: 'git rev-parse HEAD^1', returnStdout: true).trim()
echo "Found actual branch commit: ${relevantCommitHash}"
def commitExistsOnRemote = sh(script: "git branch --remotes --contains ${GIT_COMMIT}", returnStdout: true).trim()
if (commitExistsOnRemote) {
echo "PR build detected, but commit exists on remote. Using ${GIT_COMMIT}"
relevantCommitHash = "${GIT_COMMIT}"
} else {
def parentCommits = sh(script: 'git rev-parse HEAD^@', returnStdout: true).trim().split('\n')
if (parentCommits.size() >= 2) {
echo "PR build detected. Jenkins checked out a merge commit: ${GIT_COMMIT} (parents: ${parentCommits.join(', ')})"
relevantCommitHash = parentCommits[0]
echo "Using first parent (branch commit): ${relevantCommitHash}"
} else {
echo "WARN: PR build detected, but ${GIT_COMMIT} is neither a merge commit, nor does it exist on the remote."
relevantCommitHash = "${GIT_COMMIT}"
}
}
} else {
echo "Branch build detected. Using commit: ${GIT_COMMIT}"
relevantCommitHash = "${GIT_COMMIT}"

View File

@@ -5,7 +5,7 @@ import Modules from './app/src/infrastructure/Modules.js'
import metrics from '@overleaf/metrics'
import Settings from '@overleaf/settings'
import logger from '@overleaf/logger'
import PlansLocator from './app/src/Features/Subscription/PlansLocator.js'
import PlansLocator from './app/src/Features/Subscription/PlansLocator.mjs'
import HistoryManager from './app/src/Features/History/HistoryManager.mjs'
import SiteAdminHandler from './app/src/infrastructure/SiteAdminHandler.mjs'
import http from 'node:http'

View File

@@ -116,7 +116,7 @@ function generateSubscriptionToStripeMapping(
}
}
module.exports = {
export default {
extractAccountMappingsFromSubscription,
generateV1Mapping,
generateSubscriptionToRecurlyMapping,

View File

@@ -1,10 +1,10 @@
import metrics from '@overleaf/metrics'
import AnalyticsManager from './AnalyticsManager.js'
import SessionManager from '../Authentication/SessionManager.js'
import AnalyticsManager from './AnalyticsManager.mjs'
import SessionManager from '../Authentication/SessionManager.mjs'
import GeoIpLookup from '../../infrastructure/GeoIpLookup.mjs'
import Features from '../../infrastructure/Features.js'
import { expressify } from '@overleaf/promise-utils'
import AccountMappingHelper from './AccountMappingHelper.js'
import AccountMappingHelper from './AccountMappingHelper.mjs'
async function registerSalesforceMapping(req, res, next) {
if (!Features.hasFeature('analytics')) {

View File

@@ -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,

View File

@@ -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,

View File

@@ -1,7 +1,7 @@
import logger from '@overleaf/logger'
import OError from '@overleaf/o-error'
import AnalyticsRegistrationSourceHelper from './AnalyticsRegistrationSourceHelper.js'
import SessionManager from '../../Features/Authentication/SessionManager.js'
import AnalyticsRegistrationSourceHelper from './AnalyticsRegistrationSourceHelper.mjs'
import SessionManager from '../../Features/Authentication/SessionManager.mjs'
function setSource(medium, source) {
return function (req, res, next) {

View File

@@ -1,6 +1,6 @@
import _ from 'lodash'
import RequestHelper from './RequestHelper.js'
import AnalyticsManager from './AnalyticsManager.js'
import RequestHelper from './RequestHelper.mjs'
import AnalyticsManager from './AnalyticsManager.mjs'
import querystring from 'node:querystring'
import { URL } from 'node:url'
import Settings from '@overleaf/settings'

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -1,8 +1,8 @@
import AuthenticationManager from './AuthenticationManager.js'
import SessionManager from './SessionManager.js'
import AuthenticationManager from './AuthenticationManager.mjs'
import SessionManager from './SessionManager.mjs'
import OError from '@overleaf/o-error'
import LoginRateLimiter from '../Security/LoginRateLimiter.js'
import UserUpdater from '../User/UserUpdater.js'
import UserUpdater from '../User/UserUpdater.mjs'
import Metrics from '@overleaf/metrics'
import logger from '@overleaf/logger'
import querystring from 'node:querystring'
@@ -10,15 +10,15 @@ import Settings from '@overleaf/settings'
import basicAuth from 'basic-auth'
import tsscmp from 'tsscmp'
import UserHandler from '../User/UserHandler.mjs'
import UserSessionsManager from '../User/UserSessionsManager.js'
import Analytics from '../Analytics/AnalyticsManager.js'
import UserSessionsManager from '../User/UserSessionsManager.mjs'
import Analytics from '../Analytics/AnalyticsManager.mjs'
import passport from 'passport'
import NotificationsBuilder from '../Notifications/NotificationsBuilder.js'
import UrlHelper from '../Helpers/UrlHelper.js'
import AsyncFormHelper from '../Helpers/AsyncFormHelper.js'
import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs'
import UrlHelper from '../Helpers/UrlHelper.mjs'
import AsyncFormHelper from '../Helpers/AsyncFormHelper.mjs'
import _ from 'lodash'
import UserAuditLogHandler from '../User/UserAuditLogHandler.js'
import AnalyticsRegistrationSourceHelper from '../Analytics/AnalyticsRegistrationSourceHelper.js'
import UserAuditLogHandler from '../User/UserAuditLogHandler.mjs'
import AnalyticsRegistrationSourceHelper from '../Analytics/AnalyticsRegistrationSourceHelper.mjs'
import { acceptsJson } from '../../infrastructure/RequestContentTypeDetection.js'
import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
import Modules from '../../infrastructure/Modules.js'
@@ -394,7 +394,7 @@ const AuthenticationController = {
const middleware = async (req, res, next) => {
const Oauth2Server = (
await import(
'../../../../modules/oauth2-server/app/src/Oauth2Server.js'
'../../../../modules/oauth2-server/app/src/Oauth2Server.mjs'
)
).default

View File

@@ -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,

View File

@@ -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: {

View File

@@ -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

View File

@@ -6,12 +6,12 @@ import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import { User } from '../../models/User.js'
import PrivilegeLevels from './PrivilegeLevels.js'
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.js'
import PublicAccessLevels from './PublicAccessLevels.js'
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
import PublicAccessLevels from './PublicAccessLevels.mjs'
import Errors from '../Errors/Errors.js'
import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
import Settings from '@overleaf/settings'
import ChatApiHandler from '../Chat/ChatApiHandler.js'
import ChatApiHandler from '../Chat/ChatApiHandler.mjs'
const { hasAdminAccess, getAdminCapabilities } = AdminAuthorizationHelper
const { ObjectId } = mongodb

View File

@@ -3,13 +3,13 @@ import logger from '@overleaf/logger'
import mongodb from 'mongodb-legacy'
import Errors from '../Errors/Errors.js'
import HttpErrorHandler from '../Errors/HttpErrorHandler.js'
import HttpErrorHandler from '../Errors/HttpErrorHandler.mjs'
import AuthenticationController from '../Authentication/AuthenticationController.mjs'
import SessionManager from '../Authentication/SessionManager.js'
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
import { expressify } from '@overleaf/promise-utils'
import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
import UrlHelper from '../Helpers/UrlHelper.js'
import UrlHelper from '../Helpers/UrlHelper.mjs'
const { ObjectId } = mongodb

View File

@@ -13,7 +13,7 @@
*/
/** @type {import('./types').PublicAccessLevelsType} */
module.exports = {
export default {
READ_ONLY: 'readOnly', // LEGACY
READ_AND_WRITE: 'readAndWrite', // LEGACY
PRIVATE: 'private',

View File

@@ -1,7 +1,7 @@
// @ts-check
/** @type {import('./types').SourcesType} */
module.exports = {
export default {
INVITE: 'invite',
TOKEN: 'token',
OWNER: 'owner',

View File

@@ -1,9 +1,9 @@
import BetaProgramHandler from './BetaProgramHandler.mjs'
import OError from '@overleaf/o-error'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import logger from '@overleaf/logger'
import SessionManager from '../Authentication/SessionManager.js'
import SplitTestSessionHandler from '../SplitTests/SplitTestSessionHandler.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import SplitTestSessionHandler from '../SplitTests/SplitTestSessionHandler.mjs'
import { expressify } from '@overleaf/promise-utils'
async function optIn(req, res) {

View File

@@ -1,7 +1,7 @@
import { callbackify } from 'node:util'
import metrics from '@overleaf/metrics'
import UserUpdater from '../User/UserUpdater.js'
import AnalyticsManager from '../Analytics/AnalyticsManager.js'
import UserUpdater from '../User/UserUpdater.mjs'
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
async function optIn(userId) {
await UserUpdater.promises.updateUser(userId, { $set: { betaProgram: true } })

View File

@@ -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),

View File

@@ -1,8 +1,8 @@
import { expressify } from '@overleaf/promise-utils'
import Modules from '../../infrastructure/Modules.js'
import ChatApiHandler from './ChatApiHandler.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import SessionManager from '../Authentication/SessionManager.js'
import ChatApiHandler from './ChatApiHandler.mjs'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import SessionManager from '../Authentication/SessionManager.mjs'
import UserInfoManager from '../User/UserInfoManager.mjs'
import UserInfoController from '../User/UserInfoController.mjs'
import ChatManager from './ChatManager.mjs'

View File

@@ -1,5 +1,5 @@
import UserInfoController from '../User/UserInfoController.mjs'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import { callbackify } from '@overleaf/promise-utils'
async function injectUserInfoIntoThreads(threads) {

View File

@@ -1,17 +1,17 @@
import OError from '@overleaf/o-error'
import HttpErrorHandler from '../../Features/Errors/HttpErrorHandler.js'
import HttpErrorHandler from '../../Features/Errors/HttpErrorHandler.mjs'
import mongodb from 'mongodb-legacy'
import CollaboratorsHandler from './CollaboratorsHandler.mjs'
import CollaboratorsGetter from './CollaboratorsGetter.mjs'
import OwnershipTransferHandler from './OwnershipTransferHandler.mjs'
import SessionManager from '../Authentication/SessionManager.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import TagsHandler from '../Tags/TagsHandler.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import TagsHandler from '../Tags/TagsHandler.mjs'
import Errors from '../Errors/Errors.js'
import logger from '@overleaf/logger'
import { expressify } from '@overleaf/promise-utils'
import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.js'
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
import LimitationsManager from '../Subscription/LimitationsManager.mjs'
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'

View File

@@ -1,6 +1,6 @@
import { callbackify } from 'node:util'
import { Project } from '../../models/Project.js'
import EmailHandler from '../Email/EmailHandler.js'
import EmailHandler from '../Email/EmailHandler.mjs'
import Settings from '@overleaf/settings'
const CollaboratorsEmailHandler = {

View File

@@ -5,12 +5,12 @@ import pLimit from 'p-limit'
import mongodb from 'mongodb-legacy'
import OError from '@overleaf/o-error'
import { Project } from '../../models/Project.js'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import PublicAccessLevels from '../Authorization/PublicAccessLevels.js'
import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
import Errors from '../Errors/Errors.js'
import ProjectEditorHandler from '../Project/ProjectEditorHandler.js'
import Sources from '../Authorization/Sources.js'
import ProjectEditorHandler from '../Project/ProjectEditorHandler.mjs'
import Sources from '../Authorization/Sources.mjs'
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
const { ObjectId } = mongodb

View File

@@ -3,13 +3,13 @@ import OError from '@overleaf/o-error'
import { Project } from '../../models/Project.js'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import logger from '@overleaf/logger'
import ContactManager from '../Contacts/ContactManager.js'
import ContactManager from '../Contacts/ContactManager.mjs'
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
import CollaboratorsGetter from './CollaboratorsGetter.mjs'
import Errors from '../Errors/Errors.js'
import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
export default {
userIsTokenMember: callbackify(userIsTokenMember),

View File

@@ -1,15 +1,15 @@
import ProjectGetter from '../Project/ProjectGetter.mjs'
import LimitationsManager from '../Subscription/LimitationsManager.mjs'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import CollaboratorsGetter from './CollaboratorsGetter.mjs'
import CollaboratorsInviteHandler from './CollaboratorsInviteHandler.mjs'
import CollaboratorsInviteGetter from './CollaboratorsInviteGetter.js'
import CollaboratorsInviteGetter from './CollaboratorsInviteGetter.mjs'
import logger from '@overleaf/logger'
import Settings from '@overleaf/settings'
import EmailHelper from '../Helpers/EmailHelper.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import AnalyticsManager from '../Analytics/AnalyticsManager.js'
import SessionManager from '../Authentication/SessionManager.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
import SessionManager from '../Authentication/SessionManager.mjs'
import { RateLimiter } from '../../infrastructure/RateLimiter.js'
import { z, zz, validateReq } from '../../infrastructure/Validation.js'
import { expressify } from '@overleaf/promise-utils'

View File

@@ -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,

View File

@@ -3,11 +3,11 @@ import { ProjectInvite } from '../../models/ProjectInvite.js'
import logger from '@overleaf/logger'
import CollaboratorsEmailHandler from './CollaboratorsEmailHandler.mjs'
import CollaboratorsHandler from './CollaboratorsHandler.mjs'
import CollaboratorsInviteGetter from './CollaboratorsInviteGetter.js'
import CollaboratorsInviteHelper from './CollaboratorsInviteHelper.js'
import UserGetter from '../User/UserGetter.js'
import CollaboratorsInviteGetter from './CollaboratorsInviteGetter.mjs'
import CollaboratorsInviteHelper from './CollaboratorsInviteHelper.mjs'
import UserGetter from '../User/UserGetter.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import NotificationsBuilder from '../Notifications/NotificationsBuilder.js'
import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs'
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
import LimitationsManager from '../Subscription/LimitationsManager.mjs'
import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'

View File

@@ -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,
}

View File

@@ -1,16 +1,16 @@
import logger from '@overleaf/logger'
import { Project } from '../../models/Project.js'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import CollaboratorsHandler from './CollaboratorsHandler.mjs'
import EmailHandler from '../Email/EmailHandler.js'
import EmailHandler from '../Email/EmailHandler.mjs'
import Errors from '../Errors/Errors.js'
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
import AnalyticsManager from '../Analytics/AnalyticsManager.js'
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
import OError from '@overleaf/o-error'
import TagsHandler from '../Tags/TagsHandler.js'
import TagsHandler from '../Tags/TagsHandler.mjs'
import { promiseMapWithLimit } from '@overleaf/promise-utils'
export default {

View File

@@ -9,7 +9,7 @@ import logger from '@overleaf/logger'
import ClsiCacheManager from './ClsiCacheManager.mjs'
import CompileController from './CompileController.mjs'
import { expressify } from '@overleaf/promise-utils'
import ClsiCacheHandler from './ClsiCacheHandler.js'
import ClsiCacheHandler from './ClsiCacheHandler.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import { MeteredStream } from '@overleaf/stream-utils'
import Metrics from '@overleaf/metrics'

View File

@@ -1,13 +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')
} 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
@@ -64,6 +65,8 @@ function getEgressLabel(fsPath) {
* @return {Promise<void>}
*/
async function clearCache(projectId, userId) {
if (!Features.hasFeature('saas')) return
let path = `/project/${projectId}`
if (userId) {
path += `/user/${userId}`
@@ -260,7 +263,7 @@ async function prepareCacheSource(
}
}
module.exports = {
export default {
TIMEOUT,
getEgressLabel,
clearCache,

View File

@@ -1,13 +1,13 @@
import _ from 'lodash'
import { NotFoundError, ResourceGoneError } from '../Errors/Errors.js'
import ClsiCacheHandler from './ClsiCacheHandler.js'
import ClsiCacheHandler from './ClsiCacheHandler.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import SplitTestHandler from '../SplitTests/SplitTestHandler.js'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import Settings from '@overleaf/settings'
import { fetchJson, RequestFailedError } from '@overleaf/fetch-utils'
import Metrics from '@overleaf/metrics'
import Features from '../../infrastructure/Features.js'
/**
* Get the most recent build and metadata
@@ -179,19 +179,7 @@ async function prepareClsiCache(
userId,
{ sourceProjectId, templateId, templateVersionId }
) {
const { variant } = await SplitTestHandler.promises.getAssignmentForUser(
userId,
'populate-clsi-cache'
)
if (variant !== 'enabled') {
// Pre-populate the cache for the users in the split-test for prompts.
const { variant } = await SplitTestHandler.promises.getAssignmentForUser(
userId,
'populate-clsi-cache-for-prompt'
)
if (variant !== 'enabled') return
}
if (!Features.hasFeature('saas')) return
const features = await UserGetter.promises.getUserFeatures(userId)
if (features.compileGroup !== 'priority') return

View File

@@ -19,10 +19,10 @@ import ClsiFormatChecker from './ClsiFormatChecker.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import Metrics from '@overleaf/metrics'
import Errors from '../Errors/Errors.js'
import ClsiCacheHandler from './ClsiCacheHandler.js'
import ClsiCacheHandler from './ClsiCacheHandler.mjs'
import HistoryManager from '../History/HistoryManager.mjs'
import SplitTestHandler from '../SplitTests/SplitTestHandler.js'
import AnalyticsManager from '../Analytics/AnalyticsManager.js'
import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
const ClsiCookieManager = ClsiCookieManagerFactory(
Settings.apis.clsi?.backendGroupName

View File

@@ -9,18 +9,19 @@ import ClsiManager from './ClsiManager.mjs'
import logger from '@overleaf/logger'
import Settings from '@overleaf/settings'
import Errors from '../Errors/Errors.js'
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import { RateLimiter } from '../../infrastructure/RateLimiter.js'
import Validation from '../../infrastructure/Validation.js'
import ClsiCookieManagerFactory from './ClsiCookieManager.mjs'
import Path from 'node:path'
import AnalyticsManager from '../Analytics/AnalyticsManager.js'
import SplitTestHandler from '../SplitTests/SplitTestHandler.js'
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
import { expressify } from '@overleaf/promise-utils'
import {
fetchStreamWithResponse,
RequestFailedError,
} from '@overleaf/fetch-utils'
import Features from '../../infrastructure/Features.js'
const { z, zz, validateReq } = Validation
const ClsiCookieManager = ClsiCookieManagerFactory(
@@ -64,45 +65,11 @@ async function _getSplitTestOptions(req, res) {
} catch (e) {}
const editorReq = { ...req, query }
// Lookup the clsi-cache flag in the backend.
// We may need to turn off the feature on a short notice, without requiring
// all users to reload their editor page to disable the feature.
const { variant: populateClsiCacheVariant } =
await SplitTestHandler.promises.getAssignment(
editorReq,
res,
'populate-clsi-cache'
)
let populateClsiCache = populateClsiCacheVariant === 'enabled'
let compileFromClsiCache = populateClsiCache // use same split-test
let clsiCachePromptVariant = 'default'
if (!populateClsiCache) {
// Pre-populate the cache for the users in the split-test for prompts.
// Keep the compile from cache disabled for now.
const { variant } = await SplitTestHandler.promises.getAssignment(
editorReq,
res,
'populate-clsi-cache-for-prompt'
)
;({ variant: clsiCachePromptVariant } =
await SplitTestHandler.promises.getAssignment(
editorReq,
res,
'clsi-cache-prompt'
))
populateClsiCache = variant === 'enabled'
compileFromClsiCache = populateClsiCache
}
const pdfDownloadDomain = Settings.pdfDownloadDomain
if (!req.query.enable_pdf_caching) {
// The frontend does not want to do pdf caching.
return {
compileFromClsiCache,
populateClsiCache,
clsiCachePromptVariant,
pdfDownloadDomain,
enablePdfCaching: false,
}
@@ -120,18 +87,12 @@ async function _getSplitTestOptions(req, res) {
if (!enablePdfCaching) {
// Skip the lookup of the chunk size when caching is not enabled.
return {
compileFromClsiCache,
populateClsiCache,
clsiCachePromptVariant,
pdfDownloadDomain,
enablePdfCaching: false,
}
}
const pdfCachingMinChunkSize = await getPdfCachingMinChunkSize(editorReq, res)
return {
compileFromClsiCache,
populateClsiCache,
clsiCachePromptVariant,
pdfDownloadDomain,
enablePdfCaching,
pdfCachingMinChunkSize,
@@ -145,11 +106,10 @@ async function _syncTeX(req, res, direction, validatedOptions) {
if (!buildId?.match(/^[a-f0-9-]+$/)) throw new Error('invalid ?buildId')
const userId = CompileController._getUserIdForCompile(req)
const { compileFromClsiCache } = await _getSplitTestOptions(req, res)
try {
const body = await CompileManager.promises.syncTeX(projectId, userId, {
direction,
compileFromClsiCache,
compileFromClsiCache: Features.hasFeature('saas'),
validatedOptions: {
...validatedOptions,
editorId,
@@ -220,16 +180,12 @@ const _CompileController = {
options.incrementalCompilesEnabled = true
}
let {
compileFromClsiCache,
populateClsiCache,
clsiCachePromptVariant,
enablePdfCaching,
pdfCachingMinChunkSize,
pdfDownloadDomain,
} = await _getSplitTestOptions(req, res)
options.compileFromClsiCache = compileFromClsiCache
options.populateClsiCache = populateClsiCache
let { enablePdfCaching, pdfCachingMinChunkSize, pdfDownloadDomain } =
await _getSplitTestOptions(req, res)
if (Features.hasFeature('saas')) {
options.compileFromClsiCache = true
options.populateClsiCache = true
}
options.enablePdfCaching = enablePdfCaching
if (enablePdfCaching) {
options.pdfCachingMinChunkSize = pdfCachingMinChunkSize
@@ -301,11 +257,6 @@ const _CompileController = {
compileGroup: limits?.compileGroup,
clsiServerId,
clsiCacheShard,
clsiCachePromptVariant: ['alpha', 'priority'].includes(
limits?.compileGroup
)
? clsiCachePromptVariant
: 'default',
validationProblems,
stats,
timings,

View File

@@ -3,11 +3,11 @@ import Settings from '@overleaf/settings'
import RedisWrapper from '../../infrastructure/RedisWrapper.js'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import ProjectRootDocManager from '../Project/ProjectRootDocManager.mjs'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import ClsiManager from './ClsiManager.mjs'
import Metrics from '@overleaf/metrics'
import { RateLimiter } from '../../infrastructure/RateLimiter.js'
import UserAnalyticsIdCache from '../Analytics/UserAnalyticsIdCache.js'
import UserAnalyticsIdCache from '../Analytics/UserAnalyticsIdCache.mjs'
import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
let CompileManager
const rclient = RedisWrapper.client('clsi_recently_compiled')

View File

@@ -1,6 +1,6 @@
import SessionManager from '../Authentication/SessionManager.js'
import ContactManager from './ContactManager.js'
import UserGetter from '../User/UserGetter.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import ContactManager from './ContactManager.mjs'
import UserGetter from '../User/UserGetter.mjs'
import Modules from '../../infrastructure/Modules.js'
import { expressify } from '@overleaf/promise-utils'

View File

@@ -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: {

View File

@@ -1,5 +1,5 @@
import AuthenticationController from '../Authentication/AuthenticationController.mjs'
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import ContactController from './ContactController.mjs'
import Settings from '@overleaf/settings'

View File

@@ -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,

View File

@@ -1,4 +1,4 @@
import ChatApiHandler from '../Chat/ChatApiHandler.js'
import ChatApiHandler from '../Chat/ChatApiHandler.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import ProjectLocator from '../Project/ProjectLocator.mjs'
import ProjectEntityHandler from '../Project/ProjectEntityHandler.mjs'

View File

@@ -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

View File

@@ -2,12 +2,12 @@ import logger from '@overleaf/logger'
import OError from '@overleaf/o-error'
import Metrics from '@overleaf/metrics'
import ProjectEntityUpdateHandler from '../Project/ProjectEntityUpdateHandler.mjs'
import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.js'
import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.mjs'
import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
import ProjectDeleter from '../Project/ProjectDeleter.mjs'
import EditorRealTimeController from './EditorRealTimeController.js'
import EditorRealTimeController from './EditorRealTimeController.mjs'
import async from 'async'
import PublicAccessLevels from '../Authorization/PublicAccessLevels.js'
import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
import { promisifyAll } from '@overleaf/promise-utils'
const EditorController = {

View File

@@ -2,11 +2,11 @@ import ProjectDeleter from '../Project/ProjectDeleter.mjs'
import EditorController from './EditorController.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
import ProjectEditorHandler from '../Project/ProjectEditorHandler.js'
import ProjectEditorHandler from '../Project/ProjectEditorHandler.mjs'
import Metrics from '@overleaf/metrics'
import CollaboratorsInviteGetter from '../Collaborators/CollaboratorsInviteGetter.js'
import CollaboratorsInviteGetter from '../Collaborators/CollaboratorsInviteGetter.mjs'
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import Errors from '../Errors/Errors.js'
import { expressify } from '@overleaf/promise-utils'
import Settings from '@overleaf/settings'

View File

@@ -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++}`

View File

@@ -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,

View File

@@ -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: {

View File

@@ -24,6 +24,6 @@ function linkOrUnlink(accountLinked, providerName, email) {
}
}
module.exports = {
export default {
linkOrUnlink,
}

View File

@@ -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,

View File

@@ -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

View File

@@ -1,8 +1,8 @@
import { isZodErrorLike, fromZodError } from 'zod-validation-error'
import Errors from './Errors.js'
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import SamlLogHandler from '../SamlLog/SamlLogHandler.mjs'
import HttpErrorHandler from './HttpErrorHandler.js'
import HttpErrorHandler from './HttpErrorHandler.mjs'
import { plainTextResponse } from '../../infrastructure/Response.js'
import { expressifyErrorHandler } from '@overleaf/promise-utils'

View File

@@ -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

View File

@@ -11,7 +11,7 @@
*/
import ExportsHandler from './ExportsHandler.mjs'
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import logger from '@overleaf/logger'
export default {

View File

@@ -16,7 +16,7 @@ import ProjectGetter from '../Project/ProjectGetter.mjs'
import ProjectHistoryHandler from '../Project/ProjectHistoryHandler.mjs'
import ProjectLocator from '../Project/ProjectLocator.mjs'
import ProjectRootDocManager from '../Project/ProjectRootDocManager.mjs'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import logger from '@overleaf/logger'
import settings from '@overleaf/settings'
import async from 'async'

View File

@@ -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 () {}

View File

@@ -1,7 +1,7 @@
import logger from '@overleaf/logger'
import fs from 'node:fs'
import Async from 'async'
import FileHashManager from './FileHashManager.js'
import FileHashManager from './FileHashManager.mjs'
import HistoryManager from '../History/HistoryManager.mjs'
import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
import { File } from '../../models/File.js'

View File

@@ -1,11 +1,10 @@
import RedisWrapper from '../../infrastructure/RedisWrapper.js'
import settings from '@overleaf/settings'
import logger from '@overleaf/logger'
import UserGetter from '../User/UserGetter.js'
import {
SmokeTestFailure,
runSmokeTests,
} from './../../../../test/smoke/src/SmokeTests.js'
import UserGetter from '../User/UserGetter.mjs'
import SmokeTests from './../../../../test/smoke/src/SmokeTests.mjs'
const { SmokeTestFailure, runSmokeTests } = SmokeTests
const rclient = RedisWrapper.client('health_check')

View File

@@ -1,7 +1,7 @@
import Settings from '@overleaf/settings'
import Modules from '../../infrastructure/Modules.js'
import { expressify } from '@overleaf/promise-utils'
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import logger from '@overleaf/logger'
export default {

View File

@@ -1,8 +1,6 @@
const {
acceptsJson,
} = require('../../infrastructure/RequestContentTypeDetection')
import { acceptsJson } from '../../infrastructure/RequestContentTypeDetection.js'
module.exports = {
export default {
redirect,
}

View File

@@ -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,
}

View File

@@ -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

View File

@@ -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,

View File

@@ -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,
}

View File

@@ -15,8 +15,8 @@ import {
} from '@overleaf/fetch-utils'
import settings from '@overleaf/settings'
import SessionManager from '../Authentication/SessionManager.js'
import UserGetter from '../User/UserGetter.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import UserGetter from '../User/UserGetter.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import Errors from '../Errors/Errors.js'
import HistoryManager from './HistoryManager.mjs'

View File

@@ -8,9 +8,9 @@ import {
import fs from 'node:fs'
import settings from '@overleaf/settings'
import OError from '@overleaf/o-error'
import UserGetter from '../User/UserGetter.js'
import UserGetter from '../User/UserGetter.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import HistoryBackupDeletionHandler from './HistoryBackupDeletionHandler.js'
import HistoryBackupDeletionHandler from './HistoryBackupDeletionHandler.mjs'
import { db, waitForDb } from '../../infrastructure/mongodb.js'
import Metrics from '@overleaf/metrics'
import { NotFoundError } from '../Errors/Errors.js'

View File

@@ -2,7 +2,7 @@ import ProjectGetter from '../Project/ProjectGetter.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import HistoryManager from '../History/HistoryManager.mjs'
import * as RealTimeHandler from '../References/RealTime/RealTimeHandler.mjs'
import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.js'
import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.mjs'
import {
NotFoundError,
FoundConnectedClientsError,

View File

@@ -5,8 +5,8 @@ import OError from '@overleaf/o-error'
import logger from '@overleaf/logger'
import HistoryManager from '../History/HistoryManager.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import DocstoreManager from '../Docstore/DocstoreManager.js'
import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.js'
import DocstoreManager from '../Docstore/DocstoreManager.mjs'
import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.mjs'
import mongodb from '../../infrastructure/mongodb.js'
const { db, ObjectId, READ_PREFERENCE_SECONDARY } = mongodb

View File

@@ -3,17 +3,17 @@ import Path from 'node:path'
import FileWriter from '../../infrastructure/FileWriter.js'
import Metrics from '../../infrastructure/Metrics.js'
import FileSystemImportManager from '../Uploads/FileSystemImportManager.mjs'
import FileTypeManager from '../Uploads/FileTypeManager.js'
import FileTypeManager from '../Uploads/FileTypeManager.mjs'
import EditorController from '../Editor/EditorController.mjs'
import Errors from '../Errors/Errors.js'
import moment from 'moment'
import { callbackifyAll } from '@overleaf/promise-utils'
import ProjectLocator from '../Project/ProjectLocator.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import ChatApiHandler from '../Chat/ChatApiHandler.js'
import DocstoreManager from '../Docstore/DocstoreManager.js'
import ChatApiHandler from '../Chat/ChatApiHandler.mjs'
import DocstoreManager from '../Docstore/DocstoreManager.mjs'
import logger from '@overleaf/logger'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import ChatManager from '../Chat/ChatManager.mjs'
import OError from '@overleaf/o-error'
import ProjectGetter from '../Project/ProjectGetter.mjs'

View File

@@ -1,9 +1,9 @@
import OError from '@overleaf/o-error'
import logger from '@overleaf/logger'
import DocstoreManager from '../Docstore/DocstoreManager.js'
import DocstoreManager from '../Docstore/DocstoreManager.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import ProjectUpdateHandler from '../Project/ProjectUpdateHandler.js'
import ProjectUpdateHandler from '../Project/ProjectUpdateHandler.mjs'
import { Project } from '../../models/Project.js'
import Modules from '../../infrastructure/Modules.js'
import { READ_PREFERENCE_SECONDARY } from '../../infrastructure/mongodb.js'

View File

@@ -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

View File

@@ -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),
}

View File

@@ -1,7 +1,7 @@
import { promisify, callbackify } from 'node:util'
import UserGetter from '../User/UserGetter.js'
import UserMembershipsHandler from '../UserMembership/UserMembershipsHandler.js'
import UserMembershipEntityConfigs from '../UserMembership/UserMembershipEntityConfigs.js'
import UserGetter from '../User/UserGetter.mjs'
import UserMembershipsHandler from '../UserMembership/UserMembershipsHandler.mjs'
import UserMembershipEntityConfigs from '../UserMembership/UserMembershipEntityConfigs.mjs'
async function getCurrentAffiliations(userId) {
const fullEmails = await UserGetter.promises.getUserFullEmails(userId)

View File

@@ -23,6 +23,6 @@ function emailHasLicence(emailData) {
return affiliation.licence !== 'free'
}
module.exports = {
export default {
emailHasLicence,
}

View File

@@ -3,13 +3,13 @@ import mongodb from 'mongodb-legacy'
import Settings from '@overleaf/settings'
import logger from '@overleaf/logger'
import { fetchJson } from '@overleaf/fetch-utils'
import InstitutionsAPI from './InstitutionsAPI.js'
import FeaturesUpdater from '../Subscription/FeaturesUpdater.js'
import FeaturesHelper from '../Subscription/FeaturesHelper.js'
import UserGetter from '../User/UserGetter.js'
import NotificationsBuilder from '../Notifications/NotificationsBuilder.js'
import NotificationsHandler from '../Notifications/NotificationsHandler.js'
import SubscriptionLocator from '../Subscription/SubscriptionLocator.js'
import InstitutionsAPI from './InstitutionsAPI.mjs'
import FeaturesUpdater from '../Subscription/FeaturesUpdater.mjs'
import FeaturesHelper from '../Subscription/FeaturesHelper.mjs'
import UserGetter from '../User/UserGetter.mjs'
import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs'
import NotificationsHandler from '../Notifications/NotificationsHandler.mjs'
import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs'
import { Institution } from '../../models/Institution.js'
import { Subscription } from '../../models/Subscription.js'
import OError from '@overleaf/o-error'

View File

@@ -10,10 +10,10 @@
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
import SessionManager from '../Authentication/SessionManager.js'
import SessionManager from '../Authentication/SessionManager.mjs'
import Settings from '@overleaf/settings'
import _ from 'lodash'
import AnalyticsManager from '../../../../app/src/Features/Analytics/AnalyticsManager.js'
import AnalyticsManager from '../../../../app/src/Features/Analytics/AnalyticsManager.mjs'
import LinkedFilesHandler from './LinkedFilesHandler.mjs'
import LinkedFilesErrors from './LinkedFilesErrors.mjs'
import {
@@ -23,7 +23,7 @@ import {
import Modules from '../../infrastructure/Modules.js'
import { plainTextResponse } from '../../infrastructure/Response.js'
import { z, zz, validateReq } from '../../infrastructure/Validation.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import { expressify } from '@overleaf/promise-utils'
import ProjectOutputFileAgent from './ProjectOutputFileAgent.mjs'
import ProjectFileAgent from './ProjectFileAgent.mjs'

View File

@@ -12,7 +12,7 @@
*/
import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
import ProjectLocator from '../Project/ProjectLocator.mjs'
import DocstoreManager from '../Docstore/DocstoreManager.js'
import DocstoreManager from '../Docstore/DocstoreManager.mjs'
import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
import _ from 'lodash'
import LinkedFilesHandler from './LinkedFilesHandler.mjs'

View File

@@ -2,7 +2,7 @@ import logger from '@overleaf/logger'
import urlValidator from 'valid-url'
import LinkedFilesErrors from './LinkedFilesErrors.mjs'
import LinkedFilesHandler from './LinkedFilesHandler.mjs'
import UrlHelper from '../Helpers/UrlHelper.js'
import UrlHelper from '../Helpers/UrlHelper.mjs'
import { fetchStream, RequestFailedError } from '@overleaf/fetch-utils'
import { callbackify } from '@overleaf/promise-utils'
import { FileTooLargeError } from '../Errors/Errors.js'

View File

@@ -1,5 +1,5 @@
import OError from '@overleaf/o-error'
import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import MetaHandler from './MetaHandler.mjs'
import logger from '@overleaf/logger'
import { expressify } from '@overleaf/promise-utils'

Some files were not shown because too many files have changed in this diff Show More