From c93b75558c4e7149670deca3f59e2ddbf5d4b515 Mon Sep 17 00:00:00 2001 From: Jacek Radko Date: Fri, 11 Oct 2024 05:00:31 -0500 Subject: [PATCH 1/2] chore(repo): Single prettier version and consistent package.json (#4316) --- .changeset/witty-beds-double.md | 2 + .prettierrc | 8 +- .../templates/astro-hybrid/package.json | 10 +-- integration/templates/astro-node/package.json | 10 +-- integration/templates/expo-web/package.json | 16 ++-- .../templates/tanstack-router/package.json | 2 +- package-lock.json | 61 ++++++++++----- package.json | 11 +-- packages/astro/package.json | 76 +++++++++---------- packages/dev-cli/package.json | 14 ++-- packages/expo/package.json | 8 +- packages/sdk-node/package.json | 1 - packages/ui/package.json | 12 +-- packages/upgrade/package.json | 10 +-- 14 files changed, 131 insertions(+), 110 deletions(-) create mode 100644 .changeset/witty-beds-double.md diff --git a/.changeset/witty-beds-double.md b/.changeset/witty-beds-double.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/witty-beds-double.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.prettierrc b/.prettierrc index f6b714300b..bcb1ab38ed 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,12 +1,12 @@ { - "printWidth": 120, - "singleAttributePerLine": true, "arrowParens": "avoid", "bracketSpacing": true, "jsxSingleQuote": true, + "plugins": ["prettier-plugin-packagejson", "prettier-plugin-tailwindcss"], + "printWidth": 120, "semi": true, + "singleAttributePerLine": true, "singleQuote": true, "tabWidth": 2, - "trailingComma": "all", - "plugins": ["prettier-plugin-tailwindcss"] + "trailingComma": "all" } diff --git a/integration/templates/astro-hybrid/package.json b/integration/templates/astro-hybrid/package.json index e483d2dfdb..310e6cb42e 100644 --- a/integration/templates/astro-hybrid/package.json +++ b/integration/templates/astro-hybrid/package.json @@ -1,18 +1,18 @@ { "name": "astro-clerk-hybrid-playground", - "type": "module", "version": "0.0.1", + "type": "module", "scripts": { - "dev": "astro dev", - "start": "astro dev --port $PORT", + "astro": "astro", "build": "astro check && astro build", + "dev": "astro dev", "preview": "astro preview --port $PORT", - "astro": "astro" + "start": "astro dev --port $PORT" }, "dependencies": { "@astrojs/check": "^0.9.4", - "@astrojs/react": "^3.6.2", "@astrojs/node": "^8.3.4", + "@astrojs/react": "^3.6.2", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "astro": "^4.15.11", diff --git a/integration/templates/astro-node/package.json b/integration/templates/astro-node/package.json index 5d130bbbbd..3749e0d426 100644 --- a/integration/templates/astro-node/package.json +++ b/integration/templates/astro-node/package.json @@ -1,19 +1,19 @@ { "name": "astro-clerk-playground", - "type": "module", "version": "0.0.1", + "type": "module", "scripts": { - "dev": "astro dev", - "start": "astro dev --port $PORT", + "astro": "astro", "build": "astro check && astro build", + "dev": "astro dev", "preview": "astro preview --port $PORT", - "astro": "astro" + "start": "astro dev --port $PORT" }, "dependencies": { "@astrojs/check": "^0.9.4", + "@astrojs/node": "^8.3.4", "@astrojs/react": "^3.6.2", "@astrojs/tailwind": "^5.1.1", - "@astrojs/node": "^8.3.4", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "astro": "^4.15.11", diff --git a/integration/templates/expo-web/package.json b/integration/templates/expo-web/package.json index 297aacd58c..75e11a2c66 100644 --- a/integration/templates/expo-web/package.json +++ b/integration/templates/expo-web/package.json @@ -1,12 +1,13 @@ { "name": "expo-web", - "main": "expo-router/entry", "version": "1.0.0", + "private": true, + "main": "expo-router/entry", "scripts": { - "dev": "RCT_METRO_PORT=$PORT expo start --web --port $PORT", "build": "expo export -p web", - "start": "npx serve dist --single", - "lint": "expo lint" + "dev": "RCT_METRO_PORT=$PORT expo start --web --port $PORT", + "lint": "expo lint", + "start": "npx serve dist --single" }, "jest": { "preset": "jest-expo" @@ -30,8 +31,8 @@ "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.9", "react-native-screens": "~3.31.1", - "react-native-web": "~0.19.6", - "react-native-url-polyfill": "^2.0.0" + "react-native-url-polyfill": "^2.0.0", + "react-native-web": "~0.19.6" }, "devDependencies": { "@babel/core": "^7.20.0", @@ -42,6 +43,5 @@ "jest-expo": "~51.0.3", "react-test-renderer": "18.2.0", "typescript": "~5.6.2" - }, - "private": true + } } diff --git a/integration/templates/tanstack-router/package.json b/integration/templates/tanstack-router/package.json index e10226a00c..ed0b9c1009 100644 --- a/integration/templates/tanstack-router/package.json +++ b/integration/templates/tanstack-router/package.json @@ -3,8 +3,8 @@ "private": true, "type": "module", "scripts": { - "dev": "vite --port=$PORT", "build": "vite build", + "dev": "vite --port=$PORT", "serve": "vite preview --port=$PORT", "start": "vite" }, diff --git a/package-lock.json b/package-lock.json index 3fee897bdd..84fa66707a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,8 @@ "jest-chrome": "^0.8.0", "jest-environment-jsdom": "^29.3.1", "lint-staged": "^14.0.1", - "prettier": "^3.3.2", + "prettier": "^3.3.3", + "prettier-plugin-packagejson": "^2.5.3", "prettier-plugin-tailwindcss": "^0.6.3", "publint": "^0.2.4", "react": "18.3.1", @@ -8773,6 +8774,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@playwright/test": { "version": "1.44.1", "dev": true, @@ -25679,6 +25692,8 @@ }, "node_modules/get-stdin": { "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "license": "MIT", "engines": { "node": ">=12" @@ -25767,6 +25782,8 @@ }, "node_modules/git-hooks-list": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-3.1.0.tgz", + "integrity": "sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==", "license": "MIT", "funding": { "url": "https://github.com/fisker/git-hooks-list?sponsor=1" @@ -35626,6 +35643,8 @@ }, "node_modules/prettier": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "devOptional": true, "license": "MIT", "bin": { @@ -35639,11 +35658,13 @@ } }, "node_modules/prettier-plugin-packagejson": { - "version": "2.4.6", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.3.tgz", + "integrity": "sha512-ATMEEXr+ywls1kgrZEWl4SBPEm0uDdyDAjyNzUC0/Z8WZTD3RqbJcQDR+Dau+wYkW9KHK6zqQIsFyfn+9aduWg==", "license": "MIT", "dependencies": { - "sort-package-json": "2.6.0", - "synckit": "0.8.5" + "sort-package-json": "2.10.1", + "synckit": "0.9.2" }, "peerDependencies": { "prettier": ">= 1.16.0" @@ -38321,10 +38342,14 @@ }, "node_modules/sort-object-keys": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", + "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", "license": "MIT" }, "node_modules/sort-package-json": { - "version": "2.6.0", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-2.10.1.tgz", + "integrity": "sha512-d76wfhgUuGypKqY72Unm5LFnMpACbdxXsLPcL27pOsSrmVqH3PztFp1uq+Z22suk15h7vXmTesuh2aEjdCqb5w==", "license": "MIT", "dependencies": { "detect-indent": "^7.0.1", @@ -38333,6 +38358,7 @@ "git-hooks-list": "^3.0.0", "globby": "^13.1.2", "is-plain-obj": "^4.1.0", + "semver": "^7.6.0", "sort-object-keys": "^1.1.3" }, "bin": { @@ -38341,6 +38367,8 @@ }, "node_modules/sort-package-json/node_modules/detect-indent": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.1.tgz", + "integrity": "sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==", "license": "MIT", "engines": { "node": ">=12.20" @@ -38348,6 +38376,8 @@ }, "node_modules/sort-package-json/node_modules/detect-newline": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-4.0.1.tgz", + "integrity": "sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -38358,6 +38388,8 @@ }, "node_modules/sort-package-json/node_modules/is-plain-obj": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "license": "MIT", "engines": { "node": ">=12" @@ -39262,7 +39294,9 @@ "license": "MIT" }, "node_modules/synckit": { - "version": "0.9.0", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", "license": "MIT", "dependencies": { "@pkgr/core": "^0.1.0", @@ -47386,7 +47420,6 @@ "@types/node": "^18.19.33", "nock": "^13.0.7", "npm-run-all": "^4.1.5", - "prettier": "^2.5.0", "tsup": "*", "typescript": "*" }, @@ -47394,20 +47427,6 @@ "node": ">=18.17.0" } }, - "packages/sdk-node/node_modules/prettier": { - "version": "2.8.8", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "packages/sdk-node/node_modules/tslib": { "version": "2.4.1", "license": "0BSD" diff --git a/package.json b/package.json index af2464e790..2c3d65b1ca 100644 --- a/package.json +++ b/package.json @@ -31,20 +31,20 @@ "test": "FORCE_COLOR=1 turbo test --concurrency=${TURBO_CONCURRENCY:-80%}", "test:cache:clear": "FORCE_COLOR=1 turbo test:cache:clear --continue --concurrency=${TURBO_CONCURRENCY:-80%}", "test:integration:ap-flows": "npm run test:integration:base -- --grep @ap-flows", + "test:integration:astro": "E2E_APP_ID=astro.* npm run test:integration:base -- --grep @astro", "test:integration:base": "npx playwright test --config integration/playwright.config.ts", "test:integration:cleanup": "npx playwright test --config integration/playwright.cleanup.config.ts", "test:integration:deployment:nextjs": "npx playwright test --config integration/playwright.deployments.config.ts", "test:integration:elements": "E2E_APP_ID=elements.* npm run test:integration:base -- --grep @elements", + "test:integration:expo-web": "E2E_APP_ID=expo.expo-web npm run test:integration:base -- --grep @expo-web", "test:integration:express": "E2E_APP_ID=express.* npm run test:integration:base -- --grep @express", "test:integration:generic": "E2E_APP_ID=react.vite.*,next.appRouter.withEmailCodes* npm run test:integration:base -- --grep @generic", "test:integration:nextjs": "E2E_APP_ID=next.appRouter.* npm run test:integration:base -- --grep @nextjs", - "test:integration:astro": "E2E_APP_ID=astro.* npm run test:integration:base -- --grep @astro", - "test:integration:expo-web": "E2E_APP_ID=expo.expo-web npm run test:integration:base -- --grep @expo-web", "test:integration:quickstart": "E2E_APP_ID=quickstart.* npm run test:integration:base -- --grep @quickstart", + "test:integration:remix": "echo 'placeholder'", "test:integration:sessions": "npm run test:integration:base -- --grep @sessions", - "test:integration:tanstack-start": "E2E_APP_ID=tanstack.start npm run test:integration:base -- --grep @tanstack-start", "test:integration:tanstack-router": "E2E_APP_ID=tanstack.router npm run test:integration:base -- --grep @tanstack-router", - "test:integration:remix": "echo 'placeholder'", + "test:integration:tanstack-start": "E2E_APP_ID=tanstack.start npm run test:integration:base -- --grep @tanstack-start", "turbo:clean": "turbo daemon clean", "update:lockfile": "npm run nuke && npm install -D --arch=x64 --platform=linux turbo && npm install -D --arch=arm64 --platform=darwin turbo", "version": "changeset version && npm install --package-lock-only --engine-strict=false", @@ -90,7 +90,8 @@ "jest-chrome": "^0.8.0", "jest-environment-jsdom": "^29.3.1", "lint-staged": "^14.0.1", - "prettier": "^3.3.2", + "prettier": "^3.3.3", + "prettier-plugin-packagejson": "^2.5.3", "prettier-plugin-tailwindcss": "^0.6.3", "publint": "^0.2.4", "react": "18.3.1", diff --git a/packages/astro/package.json b/packages/astro/package.json index a4a8a77b06..4bdcd16220 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,18 +1,7 @@ { "name": "@clerk/astro", - "description": "Clerk SDK for Astro", "version": "1.3.13", - "type": "module", - "license": "MIT", - "author": "Clerk", - "homepage": "https://clerk.com/", - "repository": { - "type": "git", - "url": "git+https://github.com/clerk/javascript.git", - "directory": "packages/astro" - }, - "module": "./dist/index.js", - "types": "./dist/index.d.ts", + "description": "Clerk SDK for Astro", "keywords": [ "auth", "authentication", @@ -24,29 +13,27 @@ "astro-component", "withastro" ], - "sideEffects": false, + "homepage": "https://clerk.com/", "bugs": { "url": "https://github.com/clerk/javascript/issues" }, - "scripts": { - "dev": "tsup --watch --onSuccess \"npm run build:dts\"", - "build": "tsup --onSuccess \"npm run build:dts\" && npm run copy:components", - "build:dts": "tsc --emitDeclarationOnly --declaration", - "copy:components": "rm -rf ./components && mkdir -p ./components/ && cp -r ./src/astro-components/* ./components/ && cp ./src/types.ts ./", - "lint": "eslint src/", - "lint:attw": "attw --pack . --ignore-rules no-resolution cjs-resolves-to-esm internal-resolution-error", - "lint:publint": "npm run copy:components && publint", - "publish:local": "npx yalc push --replace --sig" + "repository": { + "type": "git", + "url": "git+https://github.com/clerk/javascript.git", + "directory": "packages/astro" + }, + "license": "MIT", + "author": "Clerk", + "sideEffects": false, + "type": "module", + "imports": { + "#async-local-storage": { + "workerd": "./dist/async-local-storage.server.js", + "browser": "./dist/async-local-storage.client.js", + "node": "./dist/async-local-storage.server.js", + "default": "./dist/async-local-storage.server.js" + } }, - "files": [ - "dist", - "client", - "server", - "internal", - "components", - "env.d.ts", - "types.ts" - ], "exports": { ".": { "types": "./dist/index.d.ts", @@ -72,13 +59,26 @@ "./components": "./components/index.ts", "./package.json": "./package.json" }, - "imports": { - "#async-local-storage": { - "workerd": "./dist/async-local-storage.server.js", - "browser": "./dist/async-local-storage.client.js", - "node": "./dist/async-local-storage.server.js", - "default": "./dist/async-local-storage.server.js" - } + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "client", + "server", + "internal", + "components", + "env.d.ts", + "types.ts" + ], + "scripts": { + "build": "tsup --onSuccess \"npm run build:dts\" && npm run copy:components", + "build:dts": "tsc --emitDeclarationOnly --declaration", + "copy:components": "rm -rf ./components && mkdir -p ./components/ && cp -r ./src/astro-components/* ./components/ && cp ./src/types.ts ./", + "dev": "tsup --watch --onSuccess \"npm run build:dts\"", + "lint": "eslint src/", + "lint:attw": "attw --pack . --ignore-rules no-resolution cjs-resolves-to-esm internal-resolution-error", + "lint:publint": "npm run copy:components && publint", + "publish:local": "npx yalc push --replace --sig" }, "dependencies": { "@clerk/backend": "1.13.9", diff --git a/packages/dev-cli/package.json b/packages/dev-cli/package.json index 38f94fdd95..86dae0acc0 100644 --- a/packages/dev-cli/package.json +++ b/packages/dev-cli/package.json @@ -1,10 +1,7 @@ { "name": "@clerk/dev-cli", - "description": "CLI tool designed to simplify the process of iterating on packages within the clerk/javascript repository", "version": "0.0.8", - "license": "MIT", - "type": "module", - "author": "Clerk", + "description": "CLI tool designed to simplify the process of iterating on packages within the clerk/javascript repository", "homepage": "https://clerk.com/", "bugs": { "url": "https://github.com/clerk/javascript/issues" @@ -14,13 +11,13 @@ "url": "git+https://github.com/clerk/javascript.git", "directory": "packages/dev-cli" }, + "license": "MIT", + "author": "Clerk", + "type": "module", "main": "bin/cli.js", "bin": { "clerk-dev": "bin/cli.js" }, - "engines": { - "node": ">=18.17.0" - }, "scripts": { "lint": "eslint src/" }, @@ -36,6 +33,9 @@ "@types/node": "^20.14.8", "typescript": "*" }, + "engines": { + "node": ">=18.17.0" + }, "publishConfig": { "access": "public" } diff --git a/packages/expo/package.json b/packages/expo/package.json index 7ff1dd8ad2..d545598131 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -81,15 +81,15 @@ "expo-local-authentication": ">=13.5.0", "expo-secure-store": ">=12.4.0", "expo-web-browser": ">=12.5.0", - "react-native": ">=0.73", "react": ">=18", - "react-dom": ">=18" + "react-dom": ">=18", + "react-native": ">=0.73" }, "peerDependenciesMeta": { - "expo-secure-store": { + "expo-local-authentication": { "optional": true }, - "expo-local-authentication": { + "expo-secure-store": { "optional": true } }, diff --git a/packages/sdk-node/package.json b/packages/sdk-node/package.json index 3547a0d19b..d55225e247 100644 --- a/packages/sdk-node/package.json +++ b/packages/sdk-node/package.json @@ -64,7 +64,6 @@ "@types/node": "^18.19.33", "nock": "^13.0.7", "npm-run-all": "^4.1.5", - "prettier": "^2.5.0", "tsup": "*", "typescript": "*" }, diff --git a/packages/ui/package.json b/packages/ui/package.json index aada6836b4..4c18ca7e07 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -2,17 +2,17 @@ "name": "@clerk/ui", "version": "0.1.9", "private": true, + "repository": { + "type": "git", + "url": "git+https://github.com/clerk/javascript.git", + "directory": "packages/ui" + }, "license": "MIT", "author": { "name": "Clerk, Inc.", "email": "support@clerk.com", "url": "git+https://github.com/clerk/javascript.git" }, - "repository": { - "type": "git", - "url": "git+https://github.com/clerk/javascript.git", - "directory": "packages/ui" - }, "exports": { "./contexts": { "import": { @@ -41,9 +41,9 @@ ], "scripts": { "build": "tsup", + "bundlewatch": "npx bundlewatch --config bundlewatch.config.json", "dev": "tsup --watch", "dev:theme-builder": "concurrently \"npm run dev\" \"cd theme-builder && npm run dev\"", - "bundlewatch": "npx bundlewatch --config bundlewatch.config.json", "test": "vitest" }, "dependencies": { diff --git a/packages/upgrade/package.json b/packages/upgrade/package.json index 0b5b73c8b1..7dea16c548 100644 --- a/packages/upgrade/package.json +++ b/packages/upgrade/package.json @@ -1,6 +1,11 @@ { "name": "@clerk/upgrade", "version": "1.0.9", + "repository": { + "type": "git", + "url": "git+https://github.com/clerk/javascript.git", + "directory": "packages/upgrade" + }, "license": "MIT", "type": "module", "main": "dist/cli.js", @@ -17,11 +22,6 @@ "lint": "eslint src/", "lint:publint": "publint" }, - "repository": { - "type": "git", - "url": "git+https://github.com/clerk/javascript.git", - "directory": "packages/upgrade" - }, "babel": { "presets": [ "@babel/preset-react" From 6ef3ec6b56ddb1c9c51e9a6c9648de0b0f8c1777 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 11 Oct 2024 13:08:28 +0300 Subject: [PATCH 2/2] fix(clerk-js): Update isAllowedRedirectOrigin to handle malformed or protocol-relative URLs (#4317) --- .changeset/blue-pumpkins-travel.md | 5 +++ .../clerk-js/src/utils/__tests__/url.test.ts | 6 +++ packages/clerk-js/src/utils/url.ts | 40 +++++++++---------- 3 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 .changeset/blue-pumpkins-travel.md diff --git a/.changeset/blue-pumpkins-travel.md b/.changeset/blue-pumpkins-travel.md new file mode 100644 index 0000000000..13cbb83449 --- /dev/null +++ b/.changeset/blue-pumpkins-travel.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": patch +--- + +Correctly handle malformed or protocol-relative URLs before navigating to cross-origin URLs diff --git a/packages/clerk-js/src/utils/__tests__/url.test.ts b/packages/clerk-js/src/utils/__tests__/url.test.ts index 79b9a8a7d6..6d90443ddc 100644 --- a/packages/clerk-js/src/utils/__tests__/url.test.ts +++ b/packages/clerk-js/src/utils/__tests__/url.test.ts @@ -472,6 +472,12 @@ describe('isAllowedRedirectOrigin', () => { // regexp ['https://www.clerk.com/foo?hello=1', [/https:\/\/www\.clerk\.com/], true], ['https://test.clerk.com/foo?hello=1', [/https:\/\/www\.clerk\.com/], false], + // malformed or protocol-relative URLs + ['http:evil.com', [/https:\/\/www\.clerk\.com/], false], + ['https:evil.com', [/https:\/\/www\.clerk\.com/], false], + ['http//evil.com', [/https:\/\/www\.clerk\.com/], false], + ['https//evil.com', [/https:\/\/www\.clerk\.com/], false], + ['//evil.com', [/https:\/\/www\.clerk\.com/], false], ]; const warnMock = jest.spyOn(logger, 'warnOnce'); diff --git a/packages/clerk-js/src/utils/url.ts b/packages/clerk-js/src/utils/url.ts index b5bd222624..971d670123 100644 --- a/packages/clerk-js/src/utils/url.ts +++ b/packages/clerk-js/src/utils/url.ts @@ -241,15 +241,29 @@ export function relativeToAbsoluteUrl(url: string, origin: string | URL): string return new URL(url, origin).href; } -export function isRelativeUrl(val: unknown): val is string { +export function isRelativeUrl(val: string): boolean { if (val !== val && !val) { return false; } + + if (val.startsWith('//') || val.startsWith('http/') || val.startsWith('https/')) { + // Protocol-relative URL; consider it absolute. + return false; + } + try { - const temp = new URL(val as string, DUMMY_URL_BASE); - return temp.origin === DUMMY_URL_BASE; - } catch (e) { + // If this does not throw, it's a valid absolute URL + new URL(val); return false; + } catch (e) { + try { + // If this does not throw, it's a valid relative URL + new URL(val, DUMMY_URL_BASE); + return true; + } catch (e) { + // Invalid URL case + return false; + } } } @@ -344,12 +358,11 @@ export const isAllowedRedirectOrigin = return true; } - const url = new URL(_url, DUMMY_URL_BASE); - const isRelativeUrl = url.origin === DUMMY_URL_BASE; - if (isRelativeUrl) { + if (isRelativeUrl(_url)) { return true; } + const url = new URL(_url, DUMMY_URL_BASE); const isAllowed = allowedRedirectOrigins .map(origin => (typeof origin === 'string' ? globs.toRegexp(trimTrailingSlash(origin)) : origin)) .some(origin => origin.test(trimTrailingSlash(url.origin))); @@ -380,16 +393,3 @@ export function createAllowedRedirectOrigins( return origins; } - -export const isCrossOrigin = (url: string | URL, origin: string | URL = window.location.origin): boolean => { - try { - if (isRelativeUrl(url)) { - return false; - } - const urlOrigin = new URL(url).origin; - const originOrigin = new URL(origin).origin; - return urlOrigin !== originOrigin; - } catch (e) { - return false; - } -};