Files
jmap-webmail/package.json
T
Matthieu MALVACHE d33309a8b6 fix(security): escape quotes in plain-text linkifier, bump vulnerable deps
Plain-text email bodies were escaped for <, >, & but not " or ', and the
URL linkifier regex captured every non-whitespace character up to the
next <. A URL containing a double or single quote broke out of the
href attribute in the rendered anchor, allowing arbitrary event handlers
to be injected into otherwise plain-text mail. Reported by @rathlinus.

Extract a shared plainTextToSafeHtml helper in lib/email-sanitization.ts
that escapes all five HTML-significant characters in the correct order
before linkification, and route both email-viewer and thread view
through it. Add tests that parse the output and assert no onmouseover
attribute lands on the anchor element.

Also bump dependencies flagged by npm audit: next 16.2.4 (DoS in Server
Components), next-intl 4.9.1 (open redirect), dompurify 3.4.0
(FORBID_TAGS bypass); picomatch/vite/brace-expansion resolve
transitively. npm audit is clean.

Bump version to 1.4.1.
2026-04-16 22:47:15 +02:00

80 lines
2.1 KiB
JSON

{
"name": "jmap-webmail",
"version": "1.4.1",
"private": true,
"description": "A modern JMAP webmail client built for Stalwart Mail Server",
"author": "Matthieu MALVACHE <matthieu@root.cloud>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/root-fr/jmap-webmail.git"
},
"homepage": "https://github.com/root-fr/jmap-webmail",
"bugs": {
"url": "https://github.com/root-fr/jmap-webmail/issues"
},
"keywords": [
"jmap",
"webmail",
"stalwart",
"email",
"nextjs",
"react",
"typescript"
],
"scripts": {
"dev": "next dev --turbopack",
"build": "next build --turbopack",
"start": "next start",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepare": "husky",
"typecheck": "tsc --noEmit",
"seed:demo": "npx tsx scripts/seed-demo.ts",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
},
"dependencies": {
"@tanstack/react-virtual": "^3.13.18",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"dompurify": "^3.4.0",
"lucide-react": "^0.575.0",
"next": "^16.2.4",
"next-intl": "^4.9.1",
"react": "^19.2.1",
"react-dom": "^19.2.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"zustand": "^5.0.9"
},
"devDependencies": {
"@eslint/js": "^9.39.3",
"@playwright/test": "^1.58.2",
"@tailwindcss/postcss": "^4",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.1",
"@types/node": "^25.2.3",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.49.0",
"@typescript-eslint/parser": "^8.49.0",
"@vitejs/plugin-react": "^5.1.2",
"@vitest/ui": "^4.0.18",
"eslint": "^9.39.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"flatted": "^3.4.2",
"globals": "^17.0.0",
"husky": "^9.1.7",
"jsdom": "^28.1.0",
"tailwindcss": "^4.1.17",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
}
}