diff --git a/client/admin/brewUtils/brewLookup/brewLookup.jsx b/client/admin/brewUtils/brewLookup/brewLookup.jsx index 50a2f2015..e5b585ced 100644 --- a/client/admin/brewUtils/brewLookup/brewLookup.jsx +++ b/client/admin/brewUtils/brewLookup/brewLookup.jsx @@ -1,3 +1,5 @@ +require('./brewLookup.less'); + const React = require('react'); const createClass = require('create-react-class'); const cx = require('classnames'); @@ -12,22 +14,43 @@ const BrewLookup = createClass({ }, getInitialState() { return { - query : '', - foundBrew : null, - searching : false, - error : null + query : '', + foundBrew : null, + searching : false, + error : null, + scriptCount : 0 }; }, handleChange(e){ this.setState({ query: e.target.value }); }, lookup(){ - this.setState({ searching: true, error: null }); + this.setState({ searching: true, error: null, scriptCount: 0 }); request.get(`/admin/lookup/${this.state.query}`) - .then((res)=>this.setState({ foundBrew: res.body })) + .then((res)=>{ + const foundBrew = res.body; + const scriptCheck = foundBrew?.text.match(/(<\/?s)cript/g); + this.setState({ + foundBrew : foundBrew, + scriptCount : scriptCheck?.length || 0, + }); + }) .catch((err)=>this.setState({ error: err })) - .finally(()=>this.setState({ searching: false })); + .finally(()=>{ + this.setState({ + searching : false + }); + }); + }, + + async cleanScript(){ + if(!this.state.foundBrew?.shareId) return; + + await request.put(`/admin/clean/script/${this.state.foundBrew.shareId}`) + .catch((err)=>{ this.setState({ error: err }); return; }); + + this.lookup(); }, renderFoundBrew(){ @@ -46,12 +69,23 @@ const BrewLookup = createClass({
Share Link
/share/{brew.shareId}
+
Created Time
+
{brew.createdAt ? Moment(brew.createdAt).toLocaleString() : 'No creation date'}
+
Last Updated
{Moment(brew.updatedAt).fromNow()}
Num of Views
{brew.views}
+ +
SCRIPT tags detected
+
{this.state.scriptCount}
+ {this.state.scriptCount > 0 && +
+ +
+ } ; }, diff --git a/client/admin/brewUtils/brewLookup/brewLookup.less b/client/admin/brewUtils/brewLookup/brewLookup.less new file mode 100644 index 000000000..da15e3a64 --- /dev/null +++ b/client/admin/brewUtils/brewLookup/brewLookup.less @@ -0,0 +1,6 @@ +.brewLookup { + .cleanButton { + display : inline-block; + width : 100%; + } +} \ No newline at end of file diff --git a/client/homebrew/brewRenderer/toolBar/toolBar.less b/client/homebrew/brewRenderer/toolBar/toolBar.less index 381e5eeed..c2f4ff148 100644 --- a/client/homebrew/brewRenderer/toolBar/toolBar.less +++ b/client/homebrew/brewRenderer/toolBar/toolBar.less @@ -13,6 +13,7 @@ height : auto; padding : 2px 0; font-family : 'Open Sans', sans-serif; + font-size : 13px; color : #CCCCCC; background-color : #555555; & > *:not(.toggleButton) { @@ -154,13 +155,6 @@ width : auto; min-width : 46px; height : 100%; - padding : 0 0px; - font-weight : unset; - color : inherit; - background-color : unset; - - &:not(button:has(i, svg)) { padding : 0 8px; } - &:hover { background-color : #444444; } &:focus { border : 1px solid #D3D3D3;outline : none;} &:disabled { diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 62ec6b37b..d29916a50 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -79,6 +79,7 @@ text-overflow : ellipsis; } button { + .colorButton(); padding : 0px 5px; color : white; background-color : black; @@ -138,16 +139,16 @@ margin-bottom : 15px; button { width : 100%; } button.publish { - .button(@blueLight); + .colorButton(@blueLight); } button.unpublish { - .button(@silver); + .colorButton(@silver); } } .delete.field .value { button { - .button(@red); + .colorButton(@red); } } .authors.field .value { diff --git a/package-lock.json b/package-lock.json index fa55c0329..64dd63e83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,11 +21,11 @@ "cookie-parser": "^1.4.7", "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.3", - "dompurify": "^3.1.7", + "dompurify": "^3.2.0", "expr-eval": "^2.0.2", "express": "^4.21.1", "express-async-handler": "^1.2.0", - "express-static-gzip": "2.1.8", + "express-static-gzip": "2.2.0", "fs-extra": "11.2.0", "idb-keyval": "^6.2.1", "js-yaml": "^4.1.0", @@ -33,13 +33,13 @@ "less": "^3.13.1", "lodash": "^4.17.21", "marked": "11.2.0", - "marked-emoji": "^1.4.2", + "marked-emoji": "^1.4.3", "marked-extended-tables": "^1.0.10", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.7.3", + "mongoose": "^8.8.1", "nanoid": "3.3.4", "nconf": "^0.12.1", "react": "^18.3.1", @@ -2872,6 +2872,7 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -3085,12 +3086,14 @@ "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", "dependencies": { "@types/webidl-conversions": "*" } @@ -4327,9 +4330,10 @@ } }, "node_modules/bson": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", - "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", + "license": "Apache-2.0", "engines": { "node": ">=16.20.1" } @@ -5455,9 +5459,10 @@ } }, "node_modules/dompurify": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", - "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.0.tgz", + "integrity": "sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ==", + "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/duplexer2": { "version": "0.1.4", @@ -6290,10 +6295,12 @@ "license": "MIT" }, "node_modules/express-static-gzip": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.8.tgz", - "integrity": "sha512-g8tiJuI9Y9Ffy59ehVXvqb0hhP83JwZiLxzanobPaMbkB5qBWA8nuVgd+rcd5qzH3GkgogTALlc0BaADYwnMbQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.2.0.tgz", + "integrity": "sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg==", + "license": "MIT", "dependencies": { + "parseurl": "^1.3.3", "serve-static": "^1.16.2" } }, @@ -10487,11 +10494,12 @@ } }, "node_modules/marked-emoji": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/marked-emoji/-/marked-emoji-1.4.2.tgz", - "integrity": "sha512-2sP+bp2z76dwbILzQ7ijy2PyjjAJR3iAZCzaNGThD2UijFUBeidkn6MoCdX/j47tPIcWt9nwnjqRQPd01ZrfdA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/marked-emoji/-/marked-emoji-1.4.3.tgz", + "integrity": "sha512-HDZx1VOmzu7XT2QNKWfrHGbNRMTWKj9XD78yrcH1madD30HpGLMODPOmKr/e7CA7NKKXkpXXNdndQn++ysXmHg==", + "license": "MIT", "peerDependencies": { - "marked": ">=4 <15" + "marked": ">=4 <16" } }, "node_modules/marked-extended-tables": { @@ -10576,7 +10584,8 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" }, "node_modules/meow": { "version": "13.2.0", @@ -10828,6 +10837,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "license": "Apache-2.0", "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^13.0.0" @@ -10837,6 +10847,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "license": "MIT", "dependencies": { "punycode": "^2.3.0" }, @@ -10848,6 +10859,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -10856,6 +10868,7 @@ "version": "13.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "license": "MIT", "dependencies": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -10865,13 +10878,14 @@ } }, "node_modules/mongoose": { - "version": "8.7.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.7.3.tgz", - "integrity": "sha512-Xl6+dzU5ZpEcDoJ8/AyrIdAwTY099QwpolvV73PIytpK13XqwllLq/9XeVzzLEQgmyvwBVGVgjmMrKbuezxrIA==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz", + "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==", + "license": "MIT", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.9.0", + "mongodb": "~6.10.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -10889,6 +10903,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -10902,6 +10917,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -10918,6 +10934,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -10932,6 +10949,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -10943,9 +10961,10 @@ } }, "node_modules/mongoose/node_modules/mongodb": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.9.0.tgz", - "integrity": "sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", + "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", + "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.7.0", @@ -13305,6 +13324,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" } diff --git a/package.json b/package.json index 70385aa35..7bdbb2b23 100644 --- a/package.json +++ b/package.json @@ -98,11 +98,11 @@ "cookie-parser": "^1.4.7", "create-react-class": "^15.7.0", "dedent-tabs": "^0.10.3", - "dompurify": "^3.1.7", + "dompurify": "^3.2.0", "expr-eval": "^2.0.2", "express": "^4.21.1", "express-async-handler": "^1.2.0", - "express-static-gzip": "2.1.8", + "express-static-gzip": "2.2.0", "fs-extra": "11.2.0", "idb-keyval": "^6.2.1", "js-yaml": "^4.1.0", @@ -110,13 +110,13 @@ "less": "^3.13.1", "lodash": "^4.17.21", "marked": "11.2.0", - "marked-emoji": "^1.4.2", + "marked-emoji": "^1.4.3", "marked-extended-tables": "^1.0.10", "marked-gfm-heading-id": "^3.2.0", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.7.3", + "mongoose": "^8.8.1", "nanoid": "3.3.4", "nconf": "^0.12.1", "react": "^18.3.1", diff --git a/server/admin.api.js b/server/admin.api.js index fd724b9f1..bc179ff7b 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -5,6 +5,10 @@ const Moment = require('moment'); const templateFn = require('../client/template.js'); const zlib = require('zlib'); +const HomebrewAPI = require('./homebrew.api.js'); +const asyncHandler = require('express-async-handler'); +const { splitTextStyleAndMetadata } = require('../shared/helpers.js'); + process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3'; @@ -66,23 +70,8 @@ router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ }); /* Searches for matching edit or share id, also attempts to partial match */ -router.get('/admin/lookup/:id', mw.adminOnly, async (req, res, next)=>{ - HomebrewModel.findOne({ - $or : [ - { editId: { $regex: req.params.id, $options: 'i' } }, - { shareId: { $regex: req.params.id, $options: 'i' } }, - ] - }).exec() - .then((brew)=>{ - if(!brew) // No document found - return res.status(404).json({ error: 'Document not found' }); - else - return res.json(brew); - }) - .catch((err)=>{ - console.error(err); - return res.status(500).json({ error: 'Internal Server Error' }); - }); +router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{ + return res.json(req.brew); }); /* Find 50 brews that aren't compressed yet */ @@ -100,6 +89,25 @@ router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ }); }); +/* Cleans `` from the "text" field of a brew */ +router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{ + console.log(`[ADMIN] Cleaning script tags from ShareID ${req.params.id}`); + + function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');}; + + const brew = req.brew; + + const properties = ['text', 'description', 'title']; + properties.forEach((property)=>{ + brew[property] = cleanText(brew[property]); + }); + + splitTextStyleAndMetadata(brew); + + req.body = brew; + + return await HomebrewAPI.updateBrew(req, res); +}); /* Compresses the "text" field of a brew to binary */ router.put('/admin/compress/:id', (req, res)=>{ @@ -144,7 +152,7 @@ router.get('/admin/notification/all', async (req, res, next)=>{ try { const notifications = await NotificationModel.getAll(); return res.json(notifications); - + } catch (error) { console.log('Error getting all notifications: ', error.message); return res.status(500).json({ message: error.message }); diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 9c4f55ef7..032d5d605 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -87,8 +87,18 @@ const api = { // Get relevant IDs for the brew const { id, googleId } = api.getId(req); + const accessMap = { + edit : { editId: id }, + share : { shareId: id }, + admin : { + $or : [ + { editId: id }, + { shareId: id }, + ] } + }; + // Try to find the document in the Homebrewery database -- if it doesn't exist, that's fine. - let stub = await HomebrewModel.get(accessType === 'edit' ? { editId: id } : { shareId: id }) + let stub = await HomebrewModel.get(accessMap[accessType]) .catch((err)=>{ if(googleId) { console.warn(`Unable to find document stub for ${accessType}Id ${id}`); @@ -301,9 +311,8 @@ const api = { req.params.id = currentTheme.theme; req.params.renderer = currentTheme.renderer; - } + } else { //=== Static Themes ===// - else { const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; completeSnippets.push(localSnippets); diff --git a/shared/naturalcrit/styles/core.less b/shared/naturalcrit/styles/core.less index c742ad7b1..21a2687bc 100644 --- a/shared/naturalcrit/styles/core.less +++ b/shared/naturalcrit/styles/core.less @@ -21,10 +21,7 @@ html,body, #reactRoot{ *{ box-sizing : border-box; } -button{ - .button(); -} -.button(@backgroundColor : @green){ +.colorButton(@backgroundColor : @green){ .animate(background-color); display : inline-block; padding : 0.6em 1.2em; diff --git a/shared/naturalcrit/styles/reset.less b/shared/naturalcrit/styles/reset.less index be5bffc7e..df5564a21 100644 --- a/shared/naturalcrit/styles/reset.less +++ b/shared/naturalcrit/styles/reset.less @@ -1,4 +1,4 @@ -:where(html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video){ +:where(html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,button,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video){ border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0 } @@ -25,3 +25,9 @@ :where(table){ border-collapse:collapse;border-spacing:0 } + +:where(button) { + background-color: unset; + text-transform: unset; + color: unset; +}