0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-02 08:32:41 +00:00

Merge branch 'master' into localSnippetEditor

This commit is contained in:
David Bolack
2024-11-12 18:42:50 -06:00
10 changed files with 148 additions and 73 deletions

View File

@@ -1,3 +1,5 @@
require('./brewLookup.less');
const React = require('react'); const React = require('react');
const createClass = require('create-react-class'); const createClass = require('create-react-class');
const cx = require('classnames'); const cx = require('classnames');
@@ -12,22 +14,43 @@ const BrewLookup = createClass({
}, },
getInitialState() { getInitialState() {
return { return {
query : '', query : '',
foundBrew : null, foundBrew : null,
searching : false, searching : false,
error : null error : null,
scriptCount : 0
}; };
}, },
handleChange(e){ handleChange(e){
this.setState({ query: e.target.value }); this.setState({ query: e.target.value });
}, },
lookup(){ lookup(){
this.setState({ searching: true, error: null }); this.setState({ searching: true, error: null, scriptCount: 0 });
request.get(`/admin/lookup/${this.state.query}`) 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 })) .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(){ renderFoundBrew(){
@@ -46,12 +69,23 @@ const BrewLookup = createClass({
<dt>Share Link</dt> <dt>Share Link</dt>
<dd><a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>/share/{brew.shareId}</a></dd> <dd><a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>/share/{brew.shareId}</a></dd>
<dt>Created Time</dt>
<dd>{brew.createdAt ? Moment(brew.createdAt).toLocaleString() : 'No creation date'}</dd>
<dt>Last Updated</dt> <dt>Last Updated</dt>
<dd>{Moment(brew.updatedAt).fromNow()}</dd> <dd>{Moment(brew.updatedAt).fromNow()}</dd>
<dt>Num of Views</dt> <dt>Num of Views</dt>
<dd>{brew.views}</dd> <dd>{brew.views}</dd>
<dt>SCRIPT tags detected</dt>
<dd>{this.state.scriptCount}</dd>
</dl> </dl>
{this.state.scriptCount > 0 &&
<div className='cleanButton'>
<button onClick={this.cleanScript}>CLEAN BREW</button>
</div>
}
</div>; </div>;
}, },

View File

@@ -0,0 +1,6 @@
.brewLookup {
.cleanButton {
display : inline-block;
width : 100%;
}
}

View File

@@ -13,6 +13,7 @@
height : auto; height : auto;
padding : 2px 0; padding : 2px 0;
font-family : 'Open Sans', sans-serif; font-family : 'Open Sans', sans-serif;
font-size : 13px;
color : #CCCCCC; color : #CCCCCC;
background-color : #555555; background-color : #555555;
& > *:not(.toggleButton) { & > *:not(.toggleButton) {
@@ -154,13 +155,6 @@
width : auto; width : auto;
min-width : 46px; min-width : 46px;
height : 100%; 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; } &:hover { background-color : #444444; }
&:focus { border : 1px solid #D3D3D3;outline : none;} &:focus { border : 1px solid #D3D3D3;outline : none;}
&:disabled { &:disabled {

View File

@@ -79,6 +79,7 @@
text-overflow : ellipsis; text-overflow : ellipsis;
} }
button { button {
.colorButton();
padding : 0px 5px; padding : 0px 5px;
color : white; color : white;
background-color : black; background-color : black;
@@ -138,16 +139,16 @@
margin-bottom : 15px; margin-bottom : 15px;
button { width : 100%; } button { width : 100%; }
button.publish { button.publish {
.button(@blueLight); .colorButton(@blueLight);
} }
button.unpublish { button.unpublish {
.button(@silver); .colorButton(@silver);
} }
} }
.delete.field .value { .delete.field .value {
button { button {
.button(@red); .colorButton(@red);
} }
} }
.authors.field .value { .authors.field .value {

72
package-lock.json generated
View File

@@ -21,11 +21,11 @@
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",
"create-react-class": "^15.7.0", "create-react-class": "^15.7.0",
"dedent-tabs": "^0.10.3", "dedent-tabs": "^0.10.3",
"dompurify": "^3.1.7", "dompurify": "^3.2.0",
"expr-eval": "^2.0.2", "expr-eval": "^2.0.2",
"express": "^4.21.1", "express": "^4.21.1",
"express-async-handler": "^1.2.0", "express-async-handler": "^1.2.0",
"express-static-gzip": "2.1.8", "express-static-gzip": "2.2.0",
"fs-extra": "11.2.0", "fs-extra": "11.2.0",
"idb-keyval": "^6.2.1", "idb-keyval": "^6.2.1",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
@@ -33,13 +33,13 @@
"less": "^3.13.1", "less": "^3.13.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"marked": "11.2.0", "marked": "11.2.0",
"marked-emoji": "^1.4.2", "marked-emoji": "^1.4.3",
"marked-extended-tables": "^1.0.10", "marked-extended-tables": "^1.0.10",
"marked-gfm-heading-id": "^3.2.0", "marked-gfm-heading-id": "^3.2.0",
"marked-smartypants-lite": "^1.0.2", "marked-smartypants-lite": "^1.0.2",
"markedLegacy": "npm:marked@^0.3.19", "markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1", "moment": "^2.30.1",
"mongoose": "^8.7.3", "mongoose": "^8.8.1",
"nanoid": "3.3.4", "nanoid": "3.3.4",
"nconf": "^0.12.1", "nconf": "^0.12.1",
"react": "^18.3.1", "react": "^18.3.1",
@@ -2872,6 +2872,7 @@
"version": "1.1.9", "version": "1.1.9",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
"integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
"license": "MIT",
"dependencies": { "dependencies": {
"sparse-bitfield": "^3.0.3" "sparse-bitfield": "^3.0.3"
} }
@@ -3085,12 +3086,14 @@
"node_modules/@types/webidl-conversions": { "node_modules/@types/webidl-conversions": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", "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": { "node_modules/@types/whatwg-url": {
"version": "11.0.5", "version": "11.0.5",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
"integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
"license": "MIT",
"dependencies": { "dependencies": {
"@types/webidl-conversions": "*" "@types/webidl-conversions": "*"
} }
@@ -4327,9 +4330,10 @@
} }
}, },
"node_modules/bson": { "node_modules/bson": {
"version": "6.8.0", "version": "6.9.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz",
"integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==",
"license": "Apache-2.0",
"engines": { "engines": {
"node": ">=16.20.1" "node": ">=16.20.1"
} }
@@ -5455,9 +5459,10 @@
} }
}, },
"node_modules/dompurify": { "node_modules/dompurify": {
"version": "3.1.7", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.0.tgz",
"integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==" "integrity": "sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ==",
"license": "(MPL-2.0 OR Apache-2.0)"
}, },
"node_modules/duplexer2": { "node_modules/duplexer2": {
"version": "0.1.4", "version": "0.1.4",
@@ -6290,10 +6295,12 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/express-static-gzip": { "node_modules/express-static-gzip": {
"version": "2.1.8", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.8.tgz", "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.2.0.tgz",
"integrity": "sha512-g8tiJuI9Y9Ffy59ehVXvqb0hhP83JwZiLxzanobPaMbkB5qBWA8nuVgd+rcd5qzH3GkgogTALlc0BaADYwnMbQ==", "integrity": "sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg==",
"license": "MIT",
"dependencies": { "dependencies": {
"parseurl": "^1.3.3",
"serve-static": "^1.16.2" "serve-static": "^1.16.2"
} }
}, },
@@ -10487,11 +10494,12 @@
} }
}, },
"node_modules/marked-emoji": { "node_modules/marked-emoji": {
"version": "1.4.2", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/marked-emoji/-/marked-emoji-1.4.2.tgz", "resolved": "https://registry.npmjs.org/marked-emoji/-/marked-emoji-1.4.3.tgz",
"integrity": "sha512-2sP+bp2z76dwbILzQ7ijy2PyjjAJR3iAZCzaNGThD2UijFUBeidkn6MoCdX/j47tPIcWt9nwnjqRQPd01ZrfdA==", "integrity": "sha512-HDZx1VOmzu7XT2QNKWfrHGbNRMTWKj9XD78yrcH1madD30HpGLMODPOmKr/e7CA7NKKXkpXXNdndQn++ysXmHg==",
"license": "MIT",
"peerDependencies": { "peerDependencies": {
"marked": ">=4 <15" "marked": ">=4 <16"
} }
}, },
"node_modules/marked-extended-tables": { "node_modules/marked-extended-tables": {
@@ -10576,7 +10584,8 @@
"node_modules/memory-pager": { "node_modules/memory-pager": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "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": { "node_modules/meow": {
"version": "13.2.0", "version": "13.2.0",
@@ -10828,6 +10837,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz",
"integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@types/whatwg-url": "^11.0.2", "@types/whatwg-url": "^11.0.2",
"whatwg-url": "^13.0.0" "whatwg-url": "^13.0.0"
@@ -10837,6 +10847,7 @@
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
"integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
"license": "MIT",
"dependencies": { "dependencies": {
"punycode": "^2.3.0" "punycode": "^2.3.0"
}, },
@@ -10848,6 +10859,7 @@
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"license": "BSD-2-Clause",
"engines": { "engines": {
"node": ">=12" "node": ">=12"
} }
@@ -10856,6 +10868,7 @@
"version": "13.0.0", "version": "13.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz",
"integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
"license": "MIT",
"dependencies": { "dependencies": {
"tr46": "^4.1.1", "tr46": "^4.1.1",
"webidl-conversions": "^7.0.0" "webidl-conversions": "^7.0.0"
@@ -10865,13 +10878,14 @@
} }
}, },
"node_modules/mongoose": { "node_modules/mongoose": {
"version": "8.7.3", "version": "8.8.1",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.7.3.tgz", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz",
"integrity": "sha512-Xl6+dzU5ZpEcDoJ8/AyrIdAwTY099QwpolvV73PIytpK13XqwllLq/9XeVzzLEQgmyvwBVGVgjmMrKbuezxrIA==", "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==",
"license": "MIT",
"dependencies": { "dependencies": {
"bson": "^6.7.0", "bson": "^6.7.0",
"kareem": "2.6.3", "kareem": "2.6.3",
"mongodb": "6.9.0", "mongodb": "~6.10.0",
"mpath": "0.9.0", "mpath": "0.9.0",
"mquery": "5.0.0", "mquery": "5.0.0",
"ms": "2.1.3", "ms": "2.1.3",
@@ -10889,6 +10903,7 @@
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"optional": true, "optional": true,
"peer": true, "peer": true,
"dependencies": { "dependencies": {
@@ -10902,6 +10917,7 @@
"version": "5.1.3", "version": "5.1.3",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz",
"integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==",
"license": "Apache-2.0",
"optional": true, "optional": true,
"peer": true, "peer": true,
"dependencies": { "dependencies": {
@@ -10918,6 +10934,7 @@
"version": "5.3.0", "version": "5.3.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz",
"integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==",
"license": "Apache-2.0",
"optional": true, "optional": true,
"peer": true, "peer": true,
"dependencies": { "dependencies": {
@@ -10932,6 +10949,7 @@
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"license": "MIT",
"optional": true, "optional": true,
"peer": true, "peer": true,
"dependencies": { "dependencies": {
@@ -10943,9 +10961,10 @@
} }
}, },
"node_modules/mongoose/node_modules/mongodb": { "node_modules/mongoose/node_modules/mongodb": {
"version": "6.9.0", "version": "6.10.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.9.0.tgz", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz",
"integrity": "sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA==", "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==",
"license": "Apache-2.0",
"dependencies": { "dependencies": {
"@mongodb-js/saslprep": "^1.1.5", "@mongodb-js/saslprep": "^1.1.5",
"bson": "^6.7.0", "bson": "^6.7.0",
@@ -13305,6 +13324,7 @@
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
"license": "MIT",
"dependencies": { "dependencies": {
"memory-pager": "^1.0.2" "memory-pager": "^1.0.2"
} }

View File

@@ -98,11 +98,11 @@
"cookie-parser": "^1.4.7", "cookie-parser": "^1.4.7",
"create-react-class": "^15.7.0", "create-react-class": "^15.7.0",
"dedent-tabs": "^0.10.3", "dedent-tabs": "^0.10.3",
"dompurify": "^3.1.7", "dompurify": "^3.2.0",
"expr-eval": "^2.0.2", "expr-eval": "^2.0.2",
"express": "^4.21.1", "express": "^4.21.1",
"express-async-handler": "^1.2.0", "express-async-handler": "^1.2.0",
"express-static-gzip": "2.1.8", "express-static-gzip": "2.2.0",
"fs-extra": "11.2.0", "fs-extra": "11.2.0",
"idb-keyval": "^6.2.1", "idb-keyval": "^6.2.1",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
@@ -110,13 +110,13 @@
"less": "^3.13.1", "less": "^3.13.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"marked": "11.2.0", "marked": "11.2.0",
"marked-emoji": "^1.4.2", "marked-emoji": "^1.4.3",
"marked-extended-tables": "^1.0.10", "marked-extended-tables": "^1.0.10",
"marked-gfm-heading-id": "^3.2.0", "marked-gfm-heading-id": "^3.2.0",
"marked-smartypants-lite": "^1.0.2", "marked-smartypants-lite": "^1.0.2",
"markedLegacy": "npm:marked@^0.3.19", "markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1", "moment": "^2.30.1",
"mongoose": "^8.7.3", "mongoose": "^8.8.1",
"nanoid": "3.3.4", "nanoid": "3.3.4",
"nconf": "^0.12.1", "nconf": "^0.12.1",
"react": "^18.3.1", "react": "^18.3.1",

View File

@@ -5,6 +5,10 @@ const Moment = require('moment');
const templateFn = require('../client/template.js'); const templateFn = require('../client/template.js');
const zlib = require('zlib'); 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_USER = process.env.ADMIN_USER || 'admin';
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3'; 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 */ /* Searches for matching edit or share id, also attempts to partial match */
router.get('/admin/lookup/:id', mw.adminOnly, async (req, res, next)=>{ router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{
HomebrewModel.findOne({ return res.json(req.brew);
$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' });
});
}); });
/* Find 50 brews that aren't compressed yet */ /* Find 50 brews that aren't compressed yet */
@@ -100,6 +89,25 @@ router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{
}); });
}); });
/* Cleans `<script` and `</script>` 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 */ /* Compresses the "text" field of a brew to binary */
router.put('/admin/compress/:id', (req, res)=>{ router.put('/admin/compress/:id', (req, res)=>{

View File

@@ -87,8 +87,18 @@ const api = {
// Get relevant IDs for the brew // Get relevant IDs for the brew
const { id, googleId } = api.getId(req); 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. // 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)=>{ .catch((err)=>{
if(googleId) { if(googleId) {
console.warn(`Unable to find document stub for ${accessType}Id ${id}`); console.warn(`Unable to find document stub for ${accessType}Id ${id}`);
@@ -301,9 +311,8 @@ const api = {
req.params.id = currentTheme.theme; req.params.id = currentTheme.theme;
req.params.renderer = currentTheme.renderer; req.params.renderer = currentTheme.renderer;
} } else {
//=== Static Themes ===// //=== Static Themes ===//
else {
const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client 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\");`; const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`;
completeSnippets.push(localSnippets); completeSnippets.push(localSnippets);

View File

@@ -21,10 +21,7 @@ html,body, #reactRoot{
*{ *{
box-sizing : border-box; box-sizing : border-box;
} }
button{ .colorButton(@backgroundColor : @green){
.button();
}
.button(@backgroundColor : @green){
.animate(background-color); .animate(background-color);
display : inline-block; display : inline-block;
padding : 0.6em 1.2em; padding : 0.6em 1.2em;

View File

@@ -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 border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0
} }
@@ -25,3 +25,9 @@
:where(table){ :where(table){
border-collapse:collapse;border-spacing:0 border-collapse:collapse;border-spacing:0
} }
:where(button) {
background-color: unset;
text-transform: unset;
color: unset;
}