0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-26 05:12:39 +00:00

Merge branch 'master' into dependabot/npm_and_yarn/nanoid-3.1.21

This commit is contained in:
Trevor Buckner
2021-03-12 22:32:52 -05:00
committed by GitHub
7 changed files with 147 additions and 68 deletions

View File

@@ -63,6 +63,9 @@ const SharePage = createClass({
<Nav.item href={`/source/${this.processShareId()}`} color='teal' icon='fas fa-code'>
source
</Nav.item>
<Nav.item href={`/download/${this.processShareId()}`} color='red' icon='fas fa-download'>
download
</Nav.item>
<RecentNavItem brew={this.props.brew} storageKey='view' />
<Account />
</Nav.section>

View File

@@ -78,6 +78,19 @@ const BrewItem = createClass({
</a>;
},
renderDownloadLink : function(){
if(!this.props.brew.shareId) return;
let shareLink = this.props.brew.shareId;
if(this.props.brew.googleId) {
shareLink = this.props.brew.googleId + shareLink;
}
return <a href={`/download/${shareLink}`}>
<i className='fas fa-download' />
</a>;
},
renderGoogleDriveIcon : function(){
if(!this.props.brew.gDrive) return;
@@ -109,6 +122,7 @@ const BrewItem = createClass({
<div className='links'>
{this.renderShareLink()}
{this.renderEditLink()}
{this.renderDownloadLink()}
{this.renderDeleteBrewLink()}
</div>
</div>;

View File

@@ -7,7 +7,7 @@
box-sizing : border-box;
overflow : hidden;
width : 48%;
min-height : 80px;
min-height : 105px;
margin-right : 15px;
margin-bottom : 15px;
padding : 5px 15px 5px 8px;

110
package-lock.json generated
View File

@@ -58,16 +58,16 @@
"integrity": "sha512-VhgqKOWYVm7lQXlvbJnWOzwfAQATd2nV52koT0HZ/LdDH0m4DUDwkKYsH+IwpXb+bKPyBJzawA4I6nBKqZcpQw=="
},
"@babel/core": {
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.8.tgz",
"integrity": "sha512-oYapIySGw1zGhEFRd6lzWNLWFX2s5dA/jm+Pw/+59ZdXtjyIuwlXbrId22Md0rgZVop+aVoqow2riXhBLNyuQg==",
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.10.tgz",
"integrity": "sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==",
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/generator": "^7.13.9",
"@babel/helper-compilation-targets": "^7.13.10",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helpers": "^7.13.0",
"@babel/parser": "^7.13.4",
"@babel/helpers": "^7.13.10",
"@babel/parser": "^7.13.10",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0",
@@ -85,10 +85,20 @@
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.8.tgz",
"integrity": "sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog=="
},
"@babel/generator": {
"version": "7.13.9",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz",
"integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==",
"requires": {
"@babel/types": "^7.13.0",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-compilation-targets": {
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz",
"integrity": "sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A==",
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz",
"integrity": "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==",
"requires": {
"@babel/compat-data": "^7.13.8",
"@babel/helper-validator-option": "^7.12.17",
@@ -96,20 +106,10 @@
"semver": "^6.3.0"
}
},
"@babel/helper-validator-identifier": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
"integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
},
"@babel/types": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
"integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
"lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
}
"@babel/parser": {
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.10.tgz",
"integrity": "sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ=="
},
"convert-source-map": {
"version": "1.7.0",
@@ -580,30 +580,13 @@
}
},
"@babel/helpers": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.0.tgz",
"integrity": "sha512-aan1MeFPxFacZeSz6Ld7YZo5aPuqnKlD7+HZY75xQsueczFccP9A7V05+oe0XpLwHK3oLorPe9eaAUljL7WEaQ==",
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz",
"integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==",
"requires": {
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0"
},
"dependencies": {
"@babel/helper-validator-identifier": {
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
"integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
},
"@babel/types": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
"integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
"lodash": "^4.17.19",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/highlight": {
@@ -1888,18 +1871,18 @@
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
"@types/mongodb": {
"version": "3.6.8",
"resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.8.tgz",
"integrity": "sha512-8qNbL5/GFrljXc/QijcuQcUMYZ1iWNcqnJ6tneROwbfU0LsAjQ9bmq3aHi5lWXM4cyBPd2F/n9INAk/pZZttHw==",
"version": "3.6.9",
"resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.9.tgz",
"integrity": "sha512-2XSGr/+IOKeFQ5tU9ATcIiIr7bpHqWyOXNGLOOhp0kg2NnfEvoKZF1SZ25j4zvJRqM2WeSUjfWSvymFJ3HBGJQ==",
"requires": {
"@types/bson": "*",
"@types/node": "*"
}
},
"@types/node": {
"version": "14.14.31",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz",
"integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g=="
"version": "14.14.33",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.33.tgz",
"integrity": "sha512-oJqcTrgPUF29oUP8AsUqbXGJNuPutsetaa9kTQAQce5Lx5dTYWV02ScBiT/k1BX/Z7pKeqedmvp39Wu4zR7N7g=="
},
"JSONStream": {
"version": "1.3.5",
@@ -5478,9 +5461,9 @@
}
},
"mongoose": {
"version": "5.11.18",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.11.18.tgz",
"integrity": "sha512-RsrPR9nhkXZbO3ml0DcmdbfeMvFNhgFrP81S6o1P+lFnDTNEKYnGNRCIL+ojD69wj7H5jJaAdZ0SJ5IlKxCHqw==",
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.0.tgz",
"integrity": "sha512-s0Qpgf5lOk3AXtKnE+FA0HZhFKa2hesGVcTmx1wfTQ+7Q7ph0E79B6KUp1ZQERQyCwuE8WQ4wWllEhd7VPkxOg==",
"requires": {
"@types/mongodb": "^3.5.27",
"bson": "^1.1.4",
@@ -6592,6 +6575,14 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sanitize-filename": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
"requires": {
"truncate-utf8-bytes": "^1.0.0"
}
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
@@ -7333,6 +7324,14 @@
"nopt": "~1.0.10"
}
},
"truncate-utf8-bytes": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
"integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
"requires": {
"utf8-byte-length": "^1.0.1"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -7589,6 +7588,11 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
"utf8-byte-length": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
"integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
},
"util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",

View File

@@ -40,7 +40,7 @@
]
},
"dependencies": {
"@babel/core": "^7.13.8",
"@babel/core": "^7.13.10",
"@babel/preset-env": "^7.13.9",
"@babel/preset-react": "^7.12.13",
"body-parser": "^1.19.0",
@@ -56,7 +56,7 @@
"less": "^3.13.1",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"mongoose": "^5.11.18",
"mongoose": "^5.12.0",
"nanoid": "3.1.21",
"markedLegacy": "npm:marked@^0.3.19",
"marked": "2.0.1",
@@ -67,6 +67,7 @@
"react-dom": "^16.14.0",
"react-frame-component": "4.1.3",
"react-router-dom": "5.2.0",
"sanitize-filename": "1.6.3",
"superagent": "^6.1.0",
"vitreum": "github:calculuschild/vitreum#21a8e1c9421f1d3a3b474c12f480feb2fbd28c5b"
},

View File

@@ -1,4 +1,4 @@
/*eslint max-lines: ["warn", {"max": 250, "skipBlankLines": true, "skipComments": true}]*/
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
const _ = require('lodash');
const jwt = require('jwt-simple');
const express = require('express');
@@ -7,6 +7,7 @@ const app = express();
const homebrewApi = require('./server/homebrew.api.js');
const GoogleActions = require('./server/googleActions.js');
const serveCompressedStaticAssets = require('./server/static-assets.mv.js');
const sanitizeFilename = require('sanitize-filename');
app.use('/', serveCompressedStaticAssets(`${__dirname}/build`));
@@ -64,6 +65,7 @@ app.get('/robots.txt', (req, res)=>{
return res.sendFile(`${__dirname}/robots.txt`);
});
//Source page
app.get('/source/:id', (req, res)=>{
if(req.params.id.length > 12) {
@@ -71,8 +73,13 @@ app.get('/source/:id', (req, res)=>{
const shareId = req.params.id.slice(-12);
GoogleActions.readFileMetadata(config.get('google_api_key'), googleId, shareId, 'share')
.then((brew)=>{
const text = brew.text.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
return res.send(`<code><pre style="white-space: pre-wrap;">${text}</pre></code>`);
const replaceStrings = { '&': '&amp;', '<': '&lt;', '>': '&gt;' };
let text = brew.text;
for (const replaceStr in replaceStrings) {
text = text.replaceAll(replaceStr, replaceStrings[replaceStr]);
}
text = `<code><pre style="white-space: pre-wrap;">${text}</pre></code>`;
res.status(200).send(text);
})
.catch((err)=>{
console.log(err);
@@ -80,14 +87,60 @@ app.get('/source/:id', (req, res)=>{
});
} else {
HomebrewModel.get({ shareId: req.params.id })
.then((brew)=>{
const text = brew.text.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
return res.send(`<code><pre style="white-space: pre-wrap;">${text}</pre></code>`);
})
.catch((err)=>{
console.log(err);
return res.status(404).send('Could not find Homebrew with that id');
.then((brew)=>{
const replaceStrings = { '&': '&amp;', '<': '&lt;', '>': '&gt;' };
let text = brew.text;
for (const replaceStr in replaceStrings) {
text = text.replaceAll(replaceStr, replaceStrings[replaceStr]);
}
text = `<code><pre style="white-space: pre-wrap;">${text}</pre></code>`;
res.status(200).send(text);
})
.catch((err)=>{
console.log(err);
return res.status(404).send('Could not find Homebrew with that id');
});
}
});
//Download brew source page
app.get('/download/:id', (req, res)=>{
const prefix = 'HB - ';
if(req.params.id.length > 12) {
const googleId = req.params.id.slice(0, -12);
const shareId = req.params.id.slice(-12);
GoogleActions.readFileMetadata(config.get('google_api_key'), googleId, shareId, 'share')
.then((brew)=>{
let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', '');
if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; };
res.set({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/plain',
'Content-Disposition' : `attachment; filename="${fileName}.txt"`
});
res.status(200).send(brew.text);
})
.catch((err)=>{
console.log(err);
return res.status(400).send('Can\'t get brew from Google');
});
} else {
HomebrewModel.get({ shareId: req.params.id })
.then((brew)=>{
let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', '');
if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; };
res.set({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/plain',
'Content-Disposition' : `attachment; filename="${fileName}.txt"`
});
res.status(200).send(brew.text);
})
.catch((err)=>{
console.log(err);
return res.status(404).send('Could not find Homebrew with that id');
});
}
});

View File

@@ -259,8 +259,12 @@ GoogleActions = {
throw ('Share ID does not match');
}
//Access actual file with service account. Just api key is causing "automated query" errors.
const keys = JSON.parse(config.get('service_account'));
//Access file using service account. Using API key only causes "automated query" lockouts after a while.
const keys = typeof(config.get('service_account')) == 'string' ?
JSON.parse(config.get('service_account')) :
config.get('service_account');
const serviceAuth = google.auth.fromJSON(keys);
serviceAuth.scopes = ['https://www.googleapis.com/auth/drive'];