[web] Add window. prefix to globals and add no-restricted-globals rule (#26422)

* Add `no-restricted-globals` eslint rule

Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>

* Change `self` to `window.self`

* Change `innerWidth` to `window.innerWidth`

* Change `confirm` to `window.confirm`

* Change `location` to `window.location`

* Use `location` from `useLocation` hook

* Use location from useLocation hook
Co-authored-by: Antoine <antoine.clausse@overleaf.com>

* Disable no-restricted-globals eslint rule for use of 'self'

* Use `confusing-browser-globals` from npm

* Prevent unexpected globals in workers, using `no-undef`

* Use `self` as a global in workers

* Use unexpected globals in workers, using `no-restricted-globals` in workers

---------

Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>
Co-authored-by: Rebeka <o.dekany@gmail.com>
GitOrigin-RevId: 526986799f5f2edf53c7d978fa85c1e98189565f
This commit is contained in:
Antoine Clausse
2025-06-23 11:09:08 +02:00
committed by Copybot
parent c6f8f4bec6
commit e6c64dfd77
7 changed files with 51 additions and 4 deletions

22
package-lock.json generated
View File

@@ -18024,6 +18024,13 @@
"proto-list": "~1.2.1"
}
},
"node_modules/confusing-browser-globals": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
"integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
"dev": true,
"license": "MIT"
},
"node_modules/connect-flash": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
@@ -45366,6 +45373,7 @@
"chartjs-plugin-datalabels": "^2.2.0",
"cheerio": "^1.0.0-rc.3",
"classnames": "^2.2.6",
"confusing-browser-globals": "^1.0.11",
"cookie-signature": "^1.2.1",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.41.0",
@@ -45392,6 +45400,7 @@
"formik": "^2.2.9",
"fuse.js": "^3.0.0",
"glob": "^7.1.6",
"globals": "^16.2.0",
"handlebars": "^4.7.8",
"handlebars-loader": "^1.7.3",
"html-webpack-plugin": "^5.5.3",
@@ -46342,6 +46351,19 @@
"node": ">=18.11.0"
}
},
"services/web/node_modules/globals": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz",
"integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"services/web/node_modules/google-auth-library": {
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.7.0.tgz",

View File

@@ -1,3 +1,7 @@
const _ = require('lodash')
const confusingBrowserGlobals = require('confusing-browser-globals')
const globals = require('globals')
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
@@ -19,6 +23,7 @@ module.exports = {
},
rules: {
'no-constant-binary-expression': 'error',
'no-restricted-globals': ['error', ...confusingBrowserGlobals],
// do not allow importing of implicit dependencies.
'import/no-extraneous-dependencies': 'error',
@@ -531,5 +536,17 @@ module.exports = {
'no-console': 'error',
},
},
{
files: ['**/*.worker.{js,ts}'],
rules: {
'no-restricted-globals': [
'error',
..._.difference(
Object.keys({ ...globals.browser, ...globals.node }),
Object.keys(globals.worker)
),
],
},
},
],
}

View File

@@ -8,6 +8,7 @@ import MaterialIcon from '@/shared/components/material-icon'
import { sendMB } from '@/infrastructure/event-tracking'
import { ReCaptcha2 } from '../../../../shared/components/recaptcha-2'
import { useRecaptcha } from '../../../../shared/hooks/use-recaptcha'
import { useLocation } from '@/shared/hooks/use-location'
import { postJSON } from '../../../../infrastructure/fetch-json'
import RecaptchaConditions from '@/shared/components/recaptcha-conditions'
@@ -25,6 +26,7 @@ export function AddSecondaryEmailPrompt() {
const [error, setError] = useState<AddSecondaryEmailError | undefined>()
const [isSubmitting, setIsSubmitting] = useState<boolean>(false)
const { ref: recaptchaRef, getReCaptchaToken } = useRecaptcha()
const location = useLocation()
if (!isReady) {
return null

View File

@@ -9,6 +9,7 @@ import MaterialIcon from '@/shared/components/material-icon'
import { sendMB } from '@/infrastructure/event-tracking'
import OLFormLabel from '@/features/ui/components/ol/ol-form-label'
import OLButton from '@/features/ui/components/ol/ol-button'
import { useLocation } from '@/shared/hooks/use-location'
type Feedback = {
type: 'input' | 'alert'
@@ -267,6 +268,7 @@ function ConfirmEmailSuccessfullForm({
successButtonText: string
redirectTo: string
}) {
const location = useLocation()
const submitHandler = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
location.assign(redirectTo)

View File

@@ -12,6 +12,7 @@ import { sendMB } from '@/infrastructure/event-tracking'
import LeaveProjectModal from './leave-project-modal'
import OLButton from '@/features/ui/components/ol/ol-button'
import { useLocation } from '@/shared/hooks/use-location'
function SharingUpdatesRoot() {
const [showModal, setShowModal] = useState(false)
@@ -20,6 +21,7 @@ function SharingUpdatesRoot() {
const { isLoading, isSuccess, isError, runAsync } = useAsync()
const projectId = getMeta('ol-project_id')
const location = useLocation()
const joinProject = useCallback(() => {
sendMB('notification-click', {
name: 'link-sharing-collaborator',
@@ -30,7 +32,7 @@ function SharingUpdatesRoot() {
location.assign(`/project/${projectId}`)
})
.catch(debugConsole.error)
}, [runAsync, projectId])
}, [runAsync, projectId, location])
const viewProject = useCallback(() => {
sendMB('notification-click', {
@@ -42,7 +44,7 @@ function SharingUpdatesRoot() {
location.assign(`/project/${projectId}`)
})
.catch(debugConsole.error)
}, [runAsync, projectId])
}, [runAsync, projectId, location])
const leaveProject = useCallback(() => {
sendMB('notification-click', {
@@ -54,7 +56,7 @@ function SharingUpdatesRoot() {
location.assign('/project')
})
.catch(debugConsole.error)
}, [runAsync, projectId])
}, [runAsync, projectId, location])
if (!isReady) {
return null

View File

@@ -78,7 +78,7 @@ function sentryReporter() {
const refererUrl = new URL(event.request.headers.Referer)
if (
refererUrl.hostname === location.hostname &&
refererUrl.hostname === window.location.hostname &&
refererUrl.pathname.startsWith('/read/')
) {
refererUrl.pathname = '/read/'

View File

@@ -278,6 +278,7 @@
"chartjs-plugin-datalabels": "^2.2.0",
"cheerio": "^1.0.0-rc.3",
"classnames": "^2.2.6",
"confusing-browser-globals": "^1.0.11",
"cookie-signature": "^1.2.1",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.41.0",
@@ -304,6 +305,7 @@
"formik": "^2.2.9",
"fuse.js": "^3.0.0",
"glob": "^7.1.6",
"globals": "^16.2.0",
"handlebars": "^4.7.8",
"handlebars-loader": "^1.7.3",
"html-webpack-plugin": "^5.5.3",