mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 16:22:44 +00:00
Initial Commit. All seems to be working...?
EditPage.jsx and GoogleActions.js need to be cleaned up and shortened...
This commit is contained in:
@@ -55,7 +55,7 @@ module.exports = {
|
||||
'array-bracket-spacing' : ['warn', 'never'],
|
||||
'arrow-spacing' : ['warn', { before: false, after: false }],
|
||||
'comma-spacing' : ['warn', { before: false, after: true }],
|
||||
'indent' : ['warn', 'tab'],
|
||||
'indent' : ['warn', 'tab', { 'MemberExpression': 'off' }],
|
||||
'keyword-spacing' : ['warn', {
|
||||
before : true,
|
||||
after : true,
|
||||
|
||||
BIN
client/homebrew/googleDrive.png
Normal file
BIN
client/homebrew/googleDrive.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
BIN
client/homebrew/googleDriveMono.png
Normal file
BIN
client/homebrew/googleDriveMono.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -2,17 +2,33 @@ const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
|
||||
module.exports = function(props){
|
||||
if(global.account){
|
||||
return <Nav.item href={`/user/${global.account.username}`} color='yellow' icon='fa-user'>
|
||||
{global.account.username}
|
||||
const Account = createClass({
|
||||
|
||||
getInitialState : function() {
|
||||
return {
|
||||
url : ''
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount : function(){
|
||||
if(typeof window !== 'undefined'){
|
||||
this.setState({
|
||||
url : window.location.href
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render : function(){
|
||||
if(global.account){
|
||||
return <Nav.item href={`/user/${global.account.username}`} color='yellow' icon='fa-user'>
|
||||
{global.account.username}
|
||||
</Nav.item>;
|
||||
}
|
||||
|
||||
return <Nav.item href={`http://naturalcrit.com/login?redirect=${this.state.url}`} color='teal' icon='fa-sign-in'>
|
||||
login
|
||||
</Nav.item>;
|
||||
}
|
||||
let url = '';
|
||||
if(typeof window !== 'undefined'){
|
||||
url = window.location.href;
|
||||
}
|
||||
return <Nav.item href={`http://naturalcrit.com/login?redirect=${url}`} color='teal' icon='fa-sign-in'>
|
||||
login
|
||||
</Nav.item>;
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = Account;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable max-lines */
|
||||
require('./editPage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
@@ -20,8 +21,10 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
|
||||
const SAVE_TIMEOUT = 3000;
|
||||
const googleDriveActive = require('../../googleDrive.png');
|
||||
const googleDriveInactive = require('../../googleDriveMono.png');
|
||||
|
||||
const SAVE_TIMEOUT = 3000;
|
||||
|
||||
const EditPage = createClass({
|
||||
getDefaultProps : function() {
|
||||
@@ -32,6 +35,7 @@ const EditPage = createClass({
|
||||
editId : null,
|
||||
createdAt : null,
|
||||
updatedAt : null,
|
||||
gDrive : false,
|
||||
|
||||
title : '',
|
||||
description : '',
|
||||
@@ -49,13 +53,19 @@ const EditPage = createClass({
|
||||
|
||||
isSaving : false,
|
||||
isPending : false,
|
||||
saveGoogle : this.props.brew.googleId ? true : false,
|
||||
errors : null,
|
||||
htmlErrors : Markdown.validate(this.props.brew.text),
|
||||
url : ''
|
||||
};
|
||||
},
|
||||
savedBrew : null,
|
||||
|
||||
componentDidMount : function(){
|
||||
this.setState({
|
||||
url : window.location.href
|
||||
});
|
||||
|
||||
this.trySave();
|
||||
window.onbeforeunload = ()=>{
|
||||
if(this.state.isSaving || this.state.isPending){
|
||||
@@ -74,7 +84,6 @@ const EditPage = createClass({
|
||||
document.removeEventListener('keydown', this.handleControlKeys);
|
||||
},
|
||||
|
||||
|
||||
handleControlKeys : function(e){
|
||||
if(!(e.ctrlKey || e.metaKey)) return;
|
||||
const S_KEY = 83;
|
||||
@@ -126,7 +135,13 @@ const EditPage = createClass({
|
||||
}
|
||||
},
|
||||
|
||||
save : function(){
|
||||
toggleGoogleStorage : function(){
|
||||
this.setState((prevState)=>({
|
||||
saveGoogle : !prevState.saveGoogle
|
||||
}));
|
||||
},
|
||||
|
||||
save : async function(){
|
||||
if(this.debounceSave && this.debounceSave.cancel) this.debounceSave.cancel();
|
||||
|
||||
this.setState((prevState)=>({
|
||||
@@ -135,22 +150,104 @@ const EditPage = createClass({
|
||||
htmlErrors : Markdown.validate(prevState.brew.text)
|
||||
}));
|
||||
|
||||
request
|
||||
.put(`/api/${this.props.brew.editId}`)
|
||||
.send(this.state.brew)
|
||||
.end((err, res)=>{
|
||||
if(err){
|
||||
this.setState({
|
||||
errors : err,
|
||||
});
|
||||
} else {
|
||||
this.savedBrew = res.body;
|
||||
this.setState({
|
||||
isPending : false,
|
||||
isSaving : false,
|
||||
});
|
||||
}
|
||||
});
|
||||
const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
|
||||
|
||||
if(this.state.saveGoogle) {
|
||||
if(transfer) {
|
||||
const res = await request
|
||||
.post('/api/newGoogle/')
|
||||
.send(this.state.brew)
|
||||
.catch((err)=>{
|
||||
console.log(err.status === 401
|
||||
? 'Not signed in!'
|
||||
: 'Error Saving to Google!');
|
||||
this.setState({ errors: err });
|
||||
});
|
||||
|
||||
if(!res) { return; }
|
||||
|
||||
console.log('Deleting Local Copy');
|
||||
await request.delete(`/api/${this.state.brew.editId}`)
|
||||
.send()
|
||||
.catch((err)=>{
|
||||
console.log('Error deleting Local Copy');
|
||||
});
|
||||
|
||||
this.savedBrew = res.body;
|
||||
history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID
|
||||
} else {
|
||||
const res = await request
|
||||
.put(`/api/updateGoogle/${this.state.brew.editId}`)
|
||||
.send(this.state.brew)
|
||||
.catch((err)=>{
|
||||
console.log(err.status === 401
|
||||
? 'Not signed in!'
|
||||
: 'Error Saving to Google!');
|
||||
this.setState({ errors: err });
|
||||
return;
|
||||
});
|
||||
|
||||
this.savedBrew = res.body.brew;
|
||||
}
|
||||
} else {
|
||||
console.log('Saving Locally');
|
||||
if(transfer) {
|
||||
console.log('Moving to Local Storage');
|
||||
const res = await request.post('/api')
|
||||
.send(this.state.brew)
|
||||
.catch((err)=>{
|
||||
console.log('Error creating Local Copy');
|
||||
this.setState({ errors: err });
|
||||
return;
|
||||
});
|
||||
|
||||
await request.get(`/api/removeGoogle/${this.state.brew.googleId}${this.state.brew.editId}`)
|
||||
.send()
|
||||
.catch((err)=>{
|
||||
console.log('Error Deleting Google Brew');
|
||||
});
|
||||
|
||||
console.log('GOT THIS SAVED BREW:');
|
||||
console.log(res);
|
||||
this.savedBrew = res.body;
|
||||
history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID
|
||||
} else {
|
||||
console.log('Updating existing local copy');
|
||||
const res = await request
|
||||
.put(`/api/update/${this.state.brew.editId}`)
|
||||
.send(this.state.brew)
|
||||
.catch((err)=>{
|
||||
console.log('Error Updating Local Brew');
|
||||
this.setState({ errors: err });
|
||||
return;
|
||||
});
|
||||
|
||||
this.savedBrew = res.body;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Finished saving. About to merge saved brew with current');
|
||||
this.setState((prevState)=>({
|
||||
brew : _.merge({}, prevState.brew, {
|
||||
googleId : this.savedBrew.googleId ? this.savedBrew.googleId : null,
|
||||
editId : this.savedBrew.editId,
|
||||
}),
|
||||
isPending : false,
|
||||
isSaving : false,
|
||||
}));
|
||||
},
|
||||
|
||||
renderGoogleDriveIcon : function(){
|
||||
if(this.state.saveGoogle) {
|
||||
return <Nav.item className='googleDriveStorage' onClick={this.toggleGoogleStorage}>
|
||||
<img src={googleDriveActive} alt='googleDriveActive' />
|
||||
</Nav.item>;
|
||||
} else {
|
||||
return <Nav.item className='googleDriveStorage' onClick={this.toggleGoogleStorage}>
|
||||
<img src={googleDriveInactive} alt='googleDriveInactive' />
|
||||
</Nav.item>;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
renderSaveButton : function(){
|
||||
@@ -161,6 +258,19 @@ const EditPage = createClass({
|
||||
errMsg += `\`\`\`\n${JSON.stringify(this.state.errors.response.error, null, ' ')}\n\`\`\``;
|
||||
} catch (e){}
|
||||
|
||||
if(this.state.errors.status == '401'){
|
||||
return <Nav.item className='save error' icon='fa-warning'>
|
||||
Oops!
|
||||
<div className='errorContainer'>
|
||||
You must be signed in to a Google account
|
||||
to save this to Google Drive!<br />
|
||||
Sign in <a target='_blank' rel='noopener noreferrer'
|
||||
href={`http://naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||
here</a>.
|
||||
</div>
|
||||
</Nav.item>;
|
||||
}
|
||||
|
||||
return <Nav.item className='save error' icon='fa-warning'>
|
||||
Oops!
|
||||
<div className='errorContainer'>
|
||||
@@ -183,6 +293,7 @@ const EditPage = createClass({
|
||||
return <Nav.item className='save saved'>saved.</Nav.item>;
|
||||
}
|
||||
},
|
||||
|
||||
renderNavbar : function(){
|
||||
return <Navbar>
|
||||
<Nav.section>
|
||||
@@ -190,6 +301,7 @@ const EditPage = createClass({
|
||||
</Nav.section>
|
||||
|
||||
<Nav.section>
|
||||
{this.renderGoogleDriveIcon()}
|
||||
{this.renderSaveButton()}
|
||||
<ReportIssue />
|
||||
<Nav.item newTab={true} href={`/share/${this.props.brew.shareId}`} color='teal' icon='fa-share-alt'>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
top : 29px;
|
||||
left : -20px;
|
||||
z-index : 1000;
|
||||
width : 120px;
|
||||
padding : 8px;
|
||||
width : 135px;
|
||||
padding : 6px;
|
||||
background-color : #333;
|
||||
a{
|
||||
color : @teal;
|
||||
@@ -24,4 +24,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.googleDriveStorage img{
|
||||
height : 20px;
|
||||
padding : 0px;
|
||||
margin : -5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ const NewPage = createClass({
|
||||
getInitialState : function() {
|
||||
return {
|
||||
metadata : {
|
||||
gDrive : false,
|
||||
title : '',
|
||||
description : '',
|
||||
tags : '',
|
||||
@@ -32,11 +33,13 @@ const NewPage = createClass({
|
||||
systems : []
|
||||
},
|
||||
|
||||
text : '',
|
||||
isSaving : false,
|
||||
errors : []
|
||||
text : '',
|
||||
isSaving : false,
|
||||
saveGoogle : (global.account.googleId ? true : false),
|
||||
errors : []
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount : function() {
|
||||
const storage = localStorage.getItem(KEY);
|
||||
if(storage){
|
||||
@@ -80,12 +83,30 @@ const NewPage = createClass({
|
||||
localStorage.setItem(KEY, text);
|
||||
},
|
||||
|
||||
save : function(){
|
||||
save : async function(){
|
||||
this.setState({
|
||||
isSaving : true
|
||||
});
|
||||
|
||||
request.post('/api')
|
||||
console.log('saving new brew');
|
||||
|
||||
if(this.state.saveGoogle) {
|
||||
const res = await request
|
||||
.post('/api/newGoogle/')
|
||||
.send(_.merge({}, this.state.metadata, { text: this.state.text }))
|
||||
.catch((err)=>{
|
||||
console.log(err.status === 401
|
||||
? 'Not signed in!'
|
||||
: 'Error Creating New Google Brew!');
|
||||
this.setState({ isSaving: false });
|
||||
return;
|
||||
});
|
||||
|
||||
const brew = res.body;
|
||||
localStorage.removeItem(KEY);
|
||||
window.location = `/edit/${brew.googleId}${brew.editId}`;
|
||||
} else {
|
||||
request.post('/api')
|
||||
.send(_.merge({}, this.state.metadata, {
|
||||
text : this.state.text
|
||||
}))
|
||||
@@ -101,6 +122,8 @@ const NewPage = createClass({
|
||||
localStorage.removeItem(KEY);
|
||||
window.location = `/edit/${brew.editId}`;
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
renderSaveButton : function(){
|
||||
|
||||
@@ -45,6 +45,17 @@ const SharePage = createClass({
|
||||
}
|
||||
},
|
||||
|
||||
renderSourceButton : function() {
|
||||
let shareLink = this.props.brew.shareId;
|
||||
if(this.props.brew.googleId) {
|
||||
shareLink = this.props.brew.googleId + shareLink;
|
||||
}
|
||||
|
||||
return <Nav.item href={`/source/${shareLink}`} color='teal' icon='fa-code'>
|
||||
source
|
||||
</Nav.item>;
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='sharePage page'>
|
||||
<Meta name='robots' content='noindex, nofollow' />
|
||||
@@ -55,9 +66,7 @@ const SharePage = createClass({
|
||||
|
||||
<Nav.section>
|
||||
<PrintLink shareId={this.props.brew.shareId} />
|
||||
<Nav.item href={`/source/${this.props.brew.shareId}`} color='teal' icon='fa-code'>
|
||||
source
|
||||
</Nav.item>
|
||||
{this.renderSourceButton()}
|
||||
<RecentNavItem brew={this.props.brew} storageKey='view' />
|
||||
<Account />
|
||||
</Nav.section>
|
||||
|
||||
@@ -6,6 +6,8 @@ const cx = require('classnames');
|
||||
const moment = require('moment');
|
||||
const request = require('superagent');
|
||||
|
||||
const googleDriveIcon = require('../../../googleDrive.png');
|
||||
|
||||
const BrewItem = createClass({
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -27,11 +29,19 @@ const BrewItem = createClass({
|
||||
if(!confirm('Are you REALLY sure? You will lose editor access to this document.')) return;
|
||||
}
|
||||
|
||||
request.delete(`/api/${this.props.brew.editId}`)
|
||||
.send()
|
||||
.end(function(err, res){
|
||||
location.reload();
|
||||
});
|
||||
if(this.props.brew.googleId) {
|
||||
request.get(`/api/removeGoogle/${this.props.brew.googleId}${this.props.brew.editId}`)
|
||||
.send()
|
||||
.end(function(err, res){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
request.delete(`/api/${this.props.brew.editId}`)
|
||||
.send()
|
||||
.end(function(err, res){
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
renderDeleteBrewLink : function(){
|
||||
@@ -41,14 +51,41 @@ const BrewItem = createClass({
|
||||
<i className='fa fa-trash' />
|
||||
</a>;
|
||||
},
|
||||
|
||||
renderEditLink : function(){
|
||||
if(!this.props.brew.editId) return;
|
||||
|
||||
return <a href={`/edit/${this.props.brew.editId}`} target='_blank' rel='noopener noreferrer'>
|
||||
let editLink = this.props.brew.editId;
|
||||
if(this.props.brew.googleId) {
|
||||
editLink = this.props.brew.googleId + editLink;
|
||||
}
|
||||
|
||||
return <a href={`/edit/${editLink}`} target='_blank' rel='noopener noreferrer'>
|
||||
<i className='fa fa-pencil' />
|
||||
</a>;
|
||||
},
|
||||
|
||||
renderShareLink : 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={`/share/${shareLink}`} target='_blank' rel='noopener noreferrer'>
|
||||
<i className='fa fa-share-alt' />
|
||||
</a>;
|
||||
},
|
||||
|
||||
renderGoogleDriveIcon : function(){
|
||||
if(!this.props.brew.gDrive) return;
|
||||
|
||||
return <span>
|
||||
<img className='googleDriveIcon' src={googleDriveIcon} alt='googleDriveIcon' />
|
||||
</span>;
|
||||
},
|
||||
|
||||
render : function(){
|
||||
const brew = this.props.brew;
|
||||
return <div className='brewItem'>
|
||||
@@ -66,12 +103,11 @@ const BrewItem = createClass({
|
||||
<span>
|
||||
<i className='fa fa-refresh' /> {moment(brew.updatedAt).fromNow()}
|
||||
</span>
|
||||
{this.renderGoogleDriveIcon()}
|
||||
</div>
|
||||
|
||||
<div className='links'>
|
||||
<a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>
|
||||
<i className='fa fa-share-alt' />
|
||||
</a>
|
||||
{this.renderShareLink()}
|
||||
{this.renderEditLink()}
|
||||
{this.renderDeleteBrewLink()}
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
box-sizing : border-box;
|
||||
overflow : hidden;
|
||||
width : 48%;
|
||||
min-height : 80px;
|
||||
margin-right : 15px;
|
||||
margin-bottom : 15px;
|
||||
padding : 5px 15px 5px 8px;
|
||||
@@ -55,6 +56,14 @@
|
||||
&:hover{
|
||||
opacity : 1;
|
||||
}
|
||||
i{
|
||||
cursor : pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.googleDriveIcon {
|
||||
height : 20px;
|
||||
padding : 0px;
|
||||
margin : -5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ const BrewItem = require('./brewItem/brewItem.jsx');
|
||||
const UserPage = createClass({
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
username : '',
|
||||
brews : []
|
||||
username : '',
|
||||
brews : [],
|
||||
googleBrews : []
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
264
package-lock.json
generated
264
package-lock.json
generated
@@ -1732,6 +1732,14 @@
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
|
||||
},
|
||||
"abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"requires": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
@@ -1782,6 +1790,29 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz",
|
||||
"integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ=="
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
|
||||
"integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
|
||||
"requires": {
|
||||
"debug": "4"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
|
||||
@@ -1937,6 +1968,11 @@
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"arrify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
|
||||
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
@@ -2087,6 +2123,11 @@
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
|
||||
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
|
||||
},
|
||||
"binary-extensions": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
|
||||
@@ -2487,6 +2528,11 @@
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
@@ -3018,6 +3064,11 @@
|
||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
||||
"dev": true
|
||||
},
|
||||
"deep-object-diff": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.0.tgz",
|
||||
"integrity": "sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw=="
|
||||
},
|
||||
"defer-to-connect": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
|
||||
@@ -3193,6 +3244,14 @@
|
||||
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
|
||||
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
|
||||
},
|
||||
"ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
@@ -3553,6 +3612,11 @@
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||
},
|
||||
"events": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
|
||||
@@ -3648,6 +3712,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||
@@ -3755,6 +3824,11 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
|
||||
"integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
|
||||
},
|
||||
"fast-text-encoding": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
|
||||
"integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig=="
|
||||
},
|
||||
"fbjs": {
|
||||
"version": "0.8.16",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
|
||||
@@ -3894,6 +3968,39 @@
|
||||
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
||||
"dev": true
|
||||
},
|
||||
"gaxios": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.1.0.tgz",
|
||||
"integrity": "sha512-DDTn3KXVJJigtz+g0J3vhcfbDbKtAroSTxauWsdnP57sM5KZ3d2c/3D9RKFJ86s43hfw6WULg6TXYw/AYiBlpA==",
|
||||
"requires": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"is-stream": "^2.0.0",
|
||||
"node-fetch": "^2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"gcp-metadata": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.1.4.tgz",
|
||||
"integrity": "sha512-5J/GIH0yWt/56R3dNaNWPGQ/zXsZOddYECfJaqxFWgrZ9HC2Kvc5vl9upOgUUHKzURjAVf2N+f6tEJiojqXUuA==",
|
||||
"requires": {
|
||||
"gaxios": "^3.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"gensync": {
|
||||
"version": "1.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
|
||||
@@ -3955,6 +4062,52 @@
|
||||
"type-fest": "^0.8.1"
|
||||
}
|
||||
},
|
||||
"google-auth-library": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.0.6.tgz",
|
||||
"integrity": "sha512-fWYdRdg55HSJoRq9k568jJA1lrhg9i2xgfhVIMJbskUmbDpJGHsbv9l41DGhCDXM21F9Kn4kUwdysgxSYBYJUw==",
|
||||
"requires": {
|
||||
"arrify": "^2.0.0",
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"fast-text-encoding": "^1.0.0",
|
||||
"gaxios": "^3.0.0",
|
||||
"gcp-metadata": "^4.1.0",
|
||||
"gtoken": "^5.0.0",
|
||||
"jws": "^4.0.0",
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"google-p12-pem": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.2.tgz",
|
||||
"integrity": "sha512-tbjzndQvSIHGBLzHnhDs3cL4RBjLbLXc2pYvGH+imGVu5b4RMAttUTdnmW2UH0t11QeBTXZ7wlXPS7hrypO/tg==",
|
||||
"requires": {
|
||||
"node-forge": "^0.9.0"
|
||||
}
|
||||
},
|
||||
"googleapis": {
|
||||
"version": "59.0.0",
|
||||
"resolved": "https://registry.npmjs.org/googleapis/-/googleapis-59.0.0.tgz",
|
||||
"integrity": "sha512-GV/E4KRN89a4GxSk7D7cwUfRYgcJHR05sOgm/WGdwc/u8dxNXG5lWmz9gF5ZwFGk2yKtVxL4VZNn4zBuZ6rmGg==",
|
||||
"requires": {
|
||||
"google-auth-library": "^6.0.0",
|
||||
"googleapis-common": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"googleapis-common": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-4.4.0.tgz",
|
||||
"integrity": "sha512-Bgrs8/1OZQFFIfVuX38L9t48rPAkVUXttZy6NzhhXxFOEMSHgfFIjxou7RIXOkBHxmx2pVwct9WjKkbnqMYImQ==",
|
||||
"requires": {
|
||||
"extend": "^3.0.2",
|
||||
"gaxios": "^3.0.0",
|
||||
"google-auth-library": "^6.0.0",
|
||||
"qs": "^6.7.0",
|
||||
"url-template": "^2.0.8",
|
||||
"uuid": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
|
||||
@@ -3978,6 +4131,24 @@
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
|
||||
},
|
||||
"gtoken": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.3.tgz",
|
||||
"integrity": "sha512-Nyd1wZCMRc2dj/mAD0LlfQLcAO06uKdpKJXvK85SGrF5+5+Bpfil9u/2aw35ltvEHjvl0h5FMKN5knEU+9JrOg==",
|
||||
"requires": {
|
||||
"gaxios": "^3.0.0",
|
||||
"google-p12-pem": "^3.0.0",
|
||||
"jws": "^4.0.0",
|
||||
"mime": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mime": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
|
||||
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
@@ -4154,6 +4325,30 @@
|
||||
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
||||
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
|
||||
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
|
||||
"requires": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.21",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz",
|
||||
@@ -4553,6 +4748,14 @@
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
||||
},
|
||||
"json-bigint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||
"requires": {
|
||||
"bignumber.js": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
|
||||
@@ -4622,6 +4825,25 @@
|
||||
"object.assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"jwa": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||
"requires": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"requires": {
|
||||
"jwa": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"jwt-simple": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/jwt-simple/-/jwt-simple-0.5.6.tgz",
|
||||
@@ -4783,6 +5005,14 @@
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
@@ -5203,9 +5433,9 @@
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "2.1.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz",
|
||||
"integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA=="
|
||||
"version": "3.1.12",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz",
|
||||
"integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A=="
|
||||
},
|
||||
"nanomatch": {
|
||||
"version": "1.2.13",
|
||||
@@ -5269,6 +5499,11 @@
|
||||
"is-stream": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node-forge": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz",
|
||||
"integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ=="
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "1.1.60",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz",
|
||||
@@ -6591,14 +6826,6 @@
|
||||
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
|
||||
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg=="
|
||||
},
|
||||
"shortid": {
|
||||
"version": "2.2.15",
|
||||
"resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.15.tgz",
|
||||
"integrity": "sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==",
|
||||
"requires": {
|
||||
"nanoid": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"side-channel": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.3.tgz",
|
||||
@@ -7496,6 +7723,11 @@
|
||||
"prepend-http": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"url-template": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
||||
"integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
|
||||
},
|
||||
"use": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
@@ -7519,6 +7751,11 @@
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
|
||||
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
|
||||
@@ -7856,6 +8093,11 @@
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
|
||||
|
||||
@@ -50,19 +50,20 @@
|
||||
"create-react-class": "^15.6.3",
|
||||
"express": "^4.17.1",
|
||||
"fs-extra": "9.0.1",
|
||||
"googleapis": "59.0.0",
|
||||
"jwt-simple": "^0.5.6",
|
||||
"less": "^3.12.2",
|
||||
"lodash": "^4.17.20",
|
||||
"marked": "^0.3.19",
|
||||
"moment": "^2.27.0",
|
||||
"mongoose": "^5.10.0",
|
||||
"nanoid": "3.1.12",
|
||||
"nconf": "^0.10.0",
|
||||
"prop-types": "15.7.2",
|
||||
"query-string": "6.13.1",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router-dom": "5.2.0",
|
||||
"shortid": "^2.2.15",
|
||||
"superagent": "^6.0.0",
|
||||
"vitreum": "github:calculuschild/vitreum#21a8e1c9421f1d3a3b474c12f480feb2fbd28c5b"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const fs = require('fs-extra');
|
||||
const Proj = require('./project.json');
|
||||
|
||||
const { pack } = require('vitreum');
|
||||
const { pack, watchFile, livereload } = require('vitreum');
|
||||
const isDev = !!process.argv.find((arg)=>arg=='--dev');
|
||||
|
||||
const lessTransform = require('vitreum/transforms/less.js');
|
||||
@@ -29,3 +29,12 @@ pack('./client/homebrew/homebrew.jsx', {
|
||||
})
|
||||
.then(build)
|
||||
.catch(console.error);
|
||||
|
||||
|
||||
//In development set up a watch server and livereload
|
||||
if(isDev){
|
||||
livereload('./build');
|
||||
watchFile('./server.js', {
|
||||
watch : ['./homebrew'] // Watch additional folders if you want
|
||||
});
|
||||
}
|
||||
|
||||
110
server.js
110
server.js
@@ -3,6 +3,9 @@ const jwt = require('jwt-simple');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
const homebrewApi = require('./server/homebrew.api.js');
|
||||
const GoogleActions = require('./server/googleActions.js');
|
||||
|
||||
app.use(express.static(`${__dirname}/build`));
|
||||
app.use(require('body-parser').json({ limit: '25mb' }));
|
||||
app.use(require('cookie-parser')());
|
||||
@@ -24,21 +27,30 @@ mongoose.connection.on('error', ()=>{
|
||||
throw 'Can not connect to Mongo';
|
||||
});
|
||||
|
||||
|
||||
//Account Middleware
|
||||
app.use((req, res, next)=>{
|
||||
if(req.cookies && req.cookies.nc_session){
|
||||
try {
|
||||
req.account = jwt.decode(req.cookies.nc_session, config.get('secret'));
|
||||
//console.log("Just loaded up JWT from cookie:");
|
||||
//console.log(req.account);
|
||||
} catch (e){}
|
||||
}
|
||||
|
||||
req.config = {
|
||||
googleClientId : config.get('googleClientId'),
|
||||
googleClientSecret : config.get('googleClientSecret')
|
||||
};
|
||||
return next();
|
||||
});
|
||||
|
||||
|
||||
app.use(require('./server/homebrew.api.js'));
|
||||
app.use(homebrewApi);
|
||||
|
||||
app.use(require('./server/admin.api.js'));
|
||||
|
||||
//app.use('/user',require('./server/user.routes.js'));
|
||||
|
||||
|
||||
const HomebrewModel = require('./server/homebrew.model.js').model;
|
||||
const welcomeText = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg.md', 'utf8');
|
||||
@@ -53,57 +65,112 @@ app.get('/robots.txt', (req, res)=>{
|
||||
|
||||
//Source page
|
||||
app.get('/source/:id', (req, res)=>{
|
||||
HomebrewModel.get({ shareId: req.params.id })
|
||||
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('googleApiKey'), googleId, shareId, 'share')
|
||||
.then((brew)=>{
|
||||
const text = brew.text.replaceAll('<', '<').replaceAll('>', '>');
|
||||
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');
|
||||
return res.status(400).send('Can\'t get brew from Google');
|
||||
});
|
||||
} else {
|
||||
HomebrewModel.get({ shareId: req.params.id })
|
||||
.then((brew)=>{
|
||||
const text = brew.text.replaceAll('<', '<').replaceAll('>', '>');
|
||||
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');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//User Page
|
||||
app.get('/user/:username', (req, res, next)=>{
|
||||
app.get('/user/:username', async (req, res, next)=>{
|
||||
const fullAccess = req.account && (req.account.username == req.params.username);
|
||||
HomebrewModel.getByUser(req.params.username, fullAccess)
|
||||
.then((brews)=>{
|
||||
req.brews = brews;
|
||||
return next();
|
||||
})
|
||||
|
||||
let googleBrews = [];
|
||||
|
||||
if(req.account.googleId){
|
||||
console.log('GETTING DATA FOR USER PAGE');
|
||||
googleBrews = await GoogleActions.listGoogleBrews(req, res)
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
const brews = await HomebrewModel.getByUser(req.params.username, fullAccess)
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
if(googleBrews) {
|
||||
req.brews = _.concat(brews, googleBrews);
|
||||
} else {req.brews = brews;}
|
||||
|
||||
return next();
|
||||
});
|
||||
|
||||
//Edit Page
|
||||
app.get('/edit/:id', (req, res, next)=>{
|
||||
HomebrewModel.get({ editId: req.params.id })
|
||||
if(req.params.id.length > 12) {
|
||||
const googleId = req.params.id.slice(0, -12);
|
||||
const editId = req.params.id.slice(-12);
|
||||
GoogleActions.readFileMetadata(config.get('googleApiKey'), googleId, editId, 'edit')
|
||||
.then((brew)=>{
|
||||
req.brew = brew.sanatize();
|
||||
req.brew = brew; //TODO Need to sanitize later
|
||||
return next();
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
return res.status(400).send(`Can't get that`);
|
||||
return res.status(400).send('Can\'t get brew from Google');
|
||||
});
|
||||
} else {
|
||||
HomebrewModel.get({ editId: req.params.id })
|
||||
.then((brew)=>{
|
||||
req.brew = brew.sanatize();
|
||||
return next();
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
return res.status(400).send(`Can't get that`);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//Share Page
|
||||
app.get('/share/:id', (req, res, next)=>{
|
||||
HomebrewModel.get({ shareId: req.params.id })
|
||||
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('googleApiKey'), googleId, shareId, 'share')
|
||||
.then((brew)=>{
|
||||
return brew.increaseView();
|
||||
})
|
||||
.then((brew)=>{
|
||||
req.brew = brew.sanatize(true);
|
||||
req.brew = brew; //TODO Need to sanitize later
|
||||
return next();
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
return res.status(400).send(`Can't get that`);
|
||||
return res.status(400).send('Can\'t get brew from Google');
|
||||
});
|
||||
} else {
|
||||
HomebrewModel.get({ shareId: req.params.id })
|
||||
.then((brew)=>{
|
||||
return brew.increaseView();
|
||||
})
|
||||
.then((brew)=>{
|
||||
req.brew = brew.sanatize(true);
|
||||
return next();
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
return res.status(400).send(`Can't get that`);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//Print Page
|
||||
@@ -131,10 +198,11 @@ app.use((req, res)=>{
|
||||
changelog : changelogText,
|
||||
brew : req.brew,
|
||||
brews : req.brews,
|
||||
googleBrews : req.googleBrews,
|
||||
account : req.account,
|
||||
};
|
||||
templateFn('homebrew', props)
|
||||
.then((page)=>res.send(page))
|
||||
.then((page)=>{console.log('^--- END OF REQUEST ---^'); res.send(page);})
|
||||
.catch((err)=>{
|
||||
console.log(err);
|
||||
return res.sendStatus(500);
|
||||
|
||||
432
server/googleActions.js
Normal file
432
server/googleActions.js
Normal file
@@ -0,0 +1,432 @@
|
||||
/* eslint-disable max-lines */
|
||||
const _ = require('lodash');
|
||||
const { google } = require('googleapis');
|
||||
const { nanoid } = require('nanoid');
|
||||
const token = require('./token.js');
|
||||
const config = require('nconf')
|
||||
.argv()
|
||||
.env({ lowerCase: true }) // Load environment variables
|
||||
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
|
||||
.file('defaults', { file: 'config/default.json' });
|
||||
|
||||
//let oAuth2Client;
|
||||
|
||||
GoogleActions = {
|
||||
|
||||
authCheck : (account, res)=>{
|
||||
console.log('RUNNING AUTH CHECK');
|
||||
|
||||
if(!account || !account.googleId){ // If not signed into Google
|
||||
const err = new Error('Not Signed In');
|
||||
err.status = 401;
|
||||
throw err;
|
||||
}
|
||||
|
||||
const oAuth2Client = new google.auth.OAuth2(
|
||||
config.get('googleClientId'),
|
||||
config.get('googleClientSecret'),
|
||||
'/auth/google/redirect'
|
||||
);
|
||||
|
||||
oAuth2Client.setCredentials({
|
||||
access_token : account.googleAccessToken, //Comment out to refresh token
|
||||
refresh_token : account.googleRefreshToken
|
||||
});
|
||||
|
||||
oAuth2Client.on('tokens', (tokens)=>{
|
||||
if(tokens.refresh_token) {
|
||||
account.googleRefreshToken = tokens.refresh_token;
|
||||
}
|
||||
account.googleAccessToken = tokens.access_token;
|
||||
const JWTToken = token.generateAccessToken(account);
|
||||
console.log('Updated Access Token');
|
||||
|
||||
//Save updated token to cookie
|
||||
res.cookie('nc_session', JWTToken, { maxAge: 1000*60*60*24*365, path: '/', sameSite: 'lax' });
|
||||
//res.cookie('nc_session', JWTToken, {maxAge: 1000*60*60*24*365, path: '/', sameSite: 'lax', domain: '.naturalcrit.com'});
|
||||
});
|
||||
|
||||
return oAuth2Client;
|
||||
},
|
||||
|
||||
getGoogleFolder : async (req, res)=>{
|
||||
console.log('getting google folder');
|
||||
oAuth2Client = GoogleActions.authCheck(req.account, res);
|
||||
|
||||
const drive = google.drive({ version: 'v3', auth: oAuth2Client });
|
||||
|
||||
fileMetadata = {
|
||||
'name' : 'Homebrewery',
|
||||
'mimeType' : 'application/vnd.google-apps.folder'
|
||||
};
|
||||
|
||||
const obj = await drive.files.list({
|
||||
q : 'mimeType = \'application/vnd.google-apps.folder\''
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error searching Google Drive Folders');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
let folderId;
|
||||
|
||||
if(obj.data.files.length == 0){
|
||||
console.log('no folders found'); // CREATE APP FOLDER
|
||||
|
||||
const obj = await drive.files.create({
|
||||
resource : fileMetadata
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error creating google app folder');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
console.log('created new drive folder with ID:');
|
||||
console.log(obj.data.id);
|
||||
folderId = obj.data.id;
|
||||
} else {
|
||||
folderId = obj.data.files[0].id;
|
||||
}
|
||||
|
||||
return folderId;
|
||||
},
|
||||
|
||||
getGoogleFolderNew : async (auth)=>{
|
||||
console.log('getting google folder');
|
||||
const drive = google.drive({ version: 'v3', auth: auth });
|
||||
|
||||
fileMetadata = {
|
||||
'name' : 'Homebrewery',
|
||||
'mimeType' : 'application/vnd.google-apps.folder'
|
||||
};
|
||||
|
||||
const obj = await drive.files.list({
|
||||
q : 'mimeType = \'application/vnd.google-apps.folder\''
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error searching Google Drive Folders');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
let folderId;
|
||||
|
||||
if(obj.data.files.length == 0){
|
||||
console.log('no folders found'); // CREATE APP FOLDER
|
||||
|
||||
const obj = await drive.files.create({
|
||||
resource : fileMetadata
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error creating google app folder');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
console.log('created new drive folder with ID:');
|
||||
console.log(obj.data.id);
|
||||
folderId = obj.data.id;
|
||||
} else {
|
||||
folderId = obj.data.files[0].id;
|
||||
}
|
||||
|
||||
return folderId;
|
||||
},
|
||||
|
||||
listGoogleBrews : async (req, res)=>{
|
||||
|
||||
oAuth2Client = GoogleActions.authCheck(req.account, res);
|
||||
|
||||
const drive = google.drive({ version: 'v3', auth: oAuth2Client });
|
||||
|
||||
const obj = await drive.files.list({
|
||||
pageSize : 100,
|
||||
fields : 'nextPageToken, files(id, name, modifiedTime, properties)',
|
||||
q : 'mimeType != \'application/vnd.google-apps.folder\' and trashed = false'
|
||||
})
|
||||
.catch((err)=>{
|
||||
return console.error(`Error Listing Google Brews: ${err}`);
|
||||
});
|
||||
|
||||
if(obj.data.files.length) {
|
||||
console.log('List Google Brews:');
|
||||
obj.data.files.map((file)=>{
|
||||
console.log(`${file.name} (${file.id})`);
|
||||
});
|
||||
} else {
|
||||
console.log('No files found.');
|
||||
}
|
||||
|
||||
const brews = obj.data.files.map((file)=>{
|
||||
return {
|
||||
text : '',
|
||||
shareId : file.properties.shareId,
|
||||
editId : file.properties.editId,
|
||||
createdAt : null,
|
||||
updatedAt : file.modifiedTime,
|
||||
gDrive : true,
|
||||
googleId : file.id,
|
||||
|
||||
title : file.properties.title,
|
||||
description : '',
|
||||
tags : '',
|
||||
published : false,
|
||||
authors : [req.account.username], //TODO: properly save and load authors to google drive
|
||||
systems : []
|
||||
};
|
||||
});
|
||||
|
||||
return brews;
|
||||
},
|
||||
|
||||
existsGoogleBrew : async (auth, id)=>{
|
||||
const drive = google.drive({ version: 'v3', auth: auth });
|
||||
|
||||
const result = await drive.files.get({ fileId: id })
|
||||
.catch((err)=>{
|
||||
return false;
|
||||
});
|
||||
|
||||
if(result){return true;}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
updateGoogleBrew : async (req, res)=>{
|
||||
oAuth2Client = GoogleActions.authCheck(req.account, res);
|
||||
|
||||
const drive = google.drive({ version: 'v3', auth: oAuth2Client });
|
||||
const brew = req.body;
|
||||
|
||||
const media = {
|
||||
mimeType : 'text/plain',
|
||||
body : brew.text
|
||||
};
|
||||
|
||||
let obj;
|
||||
|
||||
//CHECK IF FILE ALREADY EXISTS
|
||||
if(await GoogleActions.existsGoogleBrew(oAuth2Client, req.body.googleId) == true) {
|
||||
//IF SO, JUST UPDATE EXISTING FILE
|
||||
const fileMetadata = {
|
||||
'name' : `${brew.title}.txt`,
|
||||
'properties' : { //AppProperties is not accessible
|
||||
'shareId' : brew.shareId,
|
||||
'editId' : brew.editId,
|
||||
'title' : brew.title,
|
||||
}
|
||||
};
|
||||
|
||||
obj = await drive.files.update({
|
||||
fileId : req.body.googleId,
|
||||
resource : fileMetadata,
|
||||
media : media
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error saving to google');
|
||||
console.error(err);
|
||||
//return res.status(500).send('Error while saving');
|
||||
});
|
||||
} else {
|
||||
//IF NOT, CREATE NEW FILE
|
||||
const folderId = await GoogleActions.getGoogleFolder(req, res);
|
||||
const fileMetadata = {
|
||||
'name' : `${brew.title}.txt`,
|
||||
'parents' : [folderId],
|
||||
'properties' : { //AppProperties is not accessible
|
||||
'shareId' : nanoid(12),
|
||||
'editId' : nanoid(12),
|
||||
'title' : brew.title,
|
||||
}
|
||||
};
|
||||
|
||||
obj = await drive.files.create({
|
||||
resource : fileMetadata,
|
||||
media : media
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error saving to google');
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
if(obj) {
|
||||
//Update permissions
|
||||
const permissions = {
|
||||
'type' : 'anyone',
|
||||
'role' : 'writer',
|
||||
};
|
||||
|
||||
await drive.permissions.create({
|
||||
resource : permissions,
|
||||
fileId : obj.data.id,
|
||||
fields : 'id',
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error updating permissions');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
response = {
|
||||
brew : brew,
|
||||
googleId : obj.data.id
|
||||
};
|
||||
|
||||
return res.status(200).send(response);
|
||||
}
|
||||
},
|
||||
|
||||
newGoogleBrew : async (auth, brew)=>{
|
||||
console.log('CREATE GOOGLE BREW');
|
||||
const drive = google.drive({ version: 'v3', auth: auth });
|
||||
|
||||
const media = {
|
||||
mimeType : 'text/plain',
|
||||
body : brew.text
|
||||
};
|
||||
|
||||
const folderId = await GoogleActions.getGoogleFolderNew(auth);
|
||||
|
||||
const fileMetadata = {
|
||||
'name' : `${brew.title}.txt`,
|
||||
'parents' : [folderId],
|
||||
'properties' : { //AppProperties is not accessible
|
||||
'shareId' : nanoid(12),
|
||||
'editId' : nanoid(12),
|
||||
'title' : brew.title,
|
||||
}
|
||||
};
|
||||
|
||||
const obj = await drive.files.create({
|
||||
resource : fileMetadata,
|
||||
media : media
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error saving to google');
|
||||
console.error(err);
|
||||
return res.status(500).send('Error while creating google brew');
|
||||
});
|
||||
|
||||
if(!obj) return;
|
||||
|
||||
const permissions = {
|
||||
'type' : 'anyone',
|
||||
'role' : 'writer',
|
||||
};
|
||||
|
||||
await drive.permissions.create({
|
||||
resource : permissions,
|
||||
fileId : obj.data.id,
|
||||
fields : 'id',
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error updating permissions');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
const newHomebrew = {
|
||||
text : brew.text,
|
||||
shareId : fileMetadata.properties.shareId,
|
||||
editId : fileMetadata.properties.editId,
|
||||
createdAt : null,
|
||||
updatedAt : null,
|
||||
gDrive : true,
|
||||
googleId : obj.data.id,
|
||||
|
||||
title : brew.title,
|
||||
description : '',
|
||||
tags : '',
|
||||
published : false,
|
||||
authors : [],
|
||||
systems : []
|
||||
};
|
||||
|
||||
return newHomebrew;
|
||||
},
|
||||
|
||||
readFileMetadata : async (auth, id, accessId, accessType)=>{
|
||||
const drive = google.drive({ version: 'v3', auth });
|
||||
|
||||
const obj = await drive.files.get({
|
||||
fileId : id,
|
||||
fields : 'properties'
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error loading from Google');
|
||||
console.error(err);
|
||||
return;
|
||||
});
|
||||
|
||||
console.log(`ACCESS TYPE: ${accessType}`);
|
||||
|
||||
if(obj) {
|
||||
if(accessType == 'edit' && obj.data.properties.editId != accessId){
|
||||
throw ('Edit ID does not match');
|
||||
} else if(accessType == 'share' && obj.data.properties.shareId != accessId){
|
||||
throw ('Share ID does not match');
|
||||
}
|
||||
|
||||
const file = await drive.files.get({
|
||||
fileId : id,
|
||||
alt : 'media'
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error getting file contents from Google');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
const brew = {
|
||||
text : file.data,
|
||||
shareId : obj.data.properties.shareId,
|
||||
editId : obj.data.properties.editId,
|
||||
createdAt : null,
|
||||
updatedAt : null,
|
||||
gDrive : true,
|
||||
googleId : id,
|
||||
|
||||
title : obj.data.properties.title,
|
||||
description : '',
|
||||
tags : '',
|
||||
published : false,
|
||||
authors : [],
|
||||
systems : []
|
||||
};
|
||||
|
||||
return (brew);
|
||||
}
|
||||
},
|
||||
|
||||
deleteGoogleBrew : async (req, res, id)=>{
|
||||
|
||||
console.log('trying to delete google brew');
|
||||
oAuth2Client = GoogleActions.authCheck(req.account, res);
|
||||
const drive = google.drive({ version: 'v3', auth: oAuth2Client });
|
||||
|
||||
const googleId = id.slice(0, -12);
|
||||
const accessId = id.slice(-12);
|
||||
|
||||
const obj = await drive.files.get({
|
||||
fileId : googleId,
|
||||
fields : 'properties'
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error loading from Google');
|
||||
console.error(err);
|
||||
return;
|
||||
});
|
||||
|
||||
if(obj && obj.data.properties.editId != accessId) {
|
||||
throw ('Not authorized to delete this Google brew');
|
||||
}
|
||||
|
||||
await drive.files.delete({
|
||||
fileId : googleId
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Can\'t delete Google file');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
return res.status(200).send();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = GoogleActions;
|
||||
@@ -2,6 +2,7 @@ const _ = require('lodash');
|
||||
const HomebrewModel = require('./homebrew.model.js').model;
|
||||
const router = require('express').Router();
|
||||
const zlib = require('zlib');
|
||||
const GoogleActions = require('./googleActions.js');
|
||||
|
||||
// const getTopBrews = (cb) => {
|
||||
// HomebrewModel.find().sort({ views: -1 }).limit(5).exec(function(err, brews) {
|
||||
@@ -20,17 +21,22 @@ const getGoodBrewTitle = (text)=>{
|
||||
};
|
||||
|
||||
const newBrew = (req, res)=>{
|
||||
const authors = (req.account) ? [req.account.username] : [];
|
||||
const brew = req.body;
|
||||
brew.authors = (req.account) ? [req.account.username] : [];
|
||||
|
||||
const newHomebrew = new HomebrewModel(_.merge({},
|
||||
req.body,
|
||||
{ authors: authors }
|
||||
));
|
||||
|
||||
if(!newHomebrew.title) {
|
||||
newHomebrew.title = getGoodBrewTitle(newHomebrew.text);
|
||||
if(!brew.title) {
|
||||
brew.title = getGoodBrewTitle(brew.text);
|
||||
}
|
||||
|
||||
delete brew.editId;
|
||||
delete brew.shareId;
|
||||
delete brew.googleId;
|
||||
|
||||
console.log('creating new local file using this data:');
|
||||
console.log(brew);
|
||||
const newHomebrew = new HomebrewModel(brew);
|
||||
console.log('this is the new local homebrew');
|
||||
console.log(newHomebrew);
|
||||
// Compress brew text to binary before saving
|
||||
newHomebrew.textBin = zlib.deflateRawSync(newHomebrew.text);
|
||||
// Delete the non-binary text field since it's not needed anymore
|
||||
@@ -41,11 +47,17 @@ const newBrew = (req, res)=>{
|
||||
console.error(err, err.toString(), err.stack);
|
||||
return res.status(500).send(`Error while creating new brew, ${err.toString()}`);
|
||||
}
|
||||
return res.json(obj);
|
||||
|
||||
console.log('NEW BREW. gOING TO RETURN THIS:');
|
||||
obj = obj.toObject();
|
||||
obj.gDrive = false;
|
||||
console.log(obj);
|
||||
return res.status(200).send(obj);
|
||||
});
|
||||
};
|
||||
|
||||
const updateBrew = (req, res)=>{
|
||||
console.log('UPDATE LOCAL');
|
||||
HomebrewModel.get({ editId: req.params.id })
|
||||
.then((brew)=>{
|
||||
brew = _.merge(brew, req.body);
|
||||
@@ -62,8 +74,13 @@ const updateBrew = (req, res)=>{
|
||||
brew.markModified('authors');
|
||||
brew.markModified('systems');
|
||||
|
||||
console.log('saving this brew');
|
||||
console.log(brew);
|
||||
|
||||
brew.save((err, obj)=>{
|
||||
if(err) throw err;
|
||||
console.log('sending this updated brew:');
|
||||
console.log(obj);
|
||||
return res.status(200).send(obj);
|
||||
});
|
||||
})
|
||||
@@ -103,11 +120,41 @@ const deleteBrew = (req, res)=>{
|
||||
});
|
||||
};
|
||||
|
||||
newGoogleBrew = async (req, res, next)=>{
|
||||
let oAuth2Client;
|
||||
|
||||
console.log('newGoogleBrew (API)');
|
||||
|
||||
try { oAuth2Client = GoogleActions.authCheck(req.account, res); } catch (err) { return res.status(err.status).send(err.message); }
|
||||
|
||||
const brew = req.body;
|
||||
brew.authors = (req.account) ? [req.account.username] : [];
|
||||
|
||||
if(!brew.title) {
|
||||
brew.title = getGoodBrewTitle(brew.text);
|
||||
}
|
||||
|
||||
delete brew.editId;
|
||||
delete brew.shareId;
|
||||
delete brew.googleId;
|
||||
|
||||
req.body = brew;
|
||||
|
||||
console.log(oAuth2Client);
|
||||
|
||||
const newHomebrew = await GoogleActions.newGoogleBrew(oAuth2Client, brew);
|
||||
|
||||
return res.status(200).send(newHomebrew);
|
||||
};
|
||||
|
||||
router.post('/api', newBrew);
|
||||
router.post('/api/newGoogle/', newGoogleBrew);
|
||||
router.put('/api/:id', updateBrew);
|
||||
router.put('/api/update/:id', updateBrew);
|
||||
router.put('/api/updateGoogle/:id', (req, res)=>{GoogleActions.updateGoogleBrew(req, res);});
|
||||
router.delete('/api/:id', deleteBrew);
|
||||
router.get('/api/remove/:id', deleteBrew);
|
||||
router.get('/api/removeGoogle/:id', (req, res)=>{GoogleActions.deleteGoogleBrew(req, res, req.params.id);});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const shortid = require('shortid');
|
||||
const { nanoid } = require('nanoid');
|
||||
const _ = require('lodash');
|
||||
const zlib = require('zlib');
|
||||
|
||||
const HomebrewSchema = mongoose.Schema({
|
||||
shareId : { type: String, default: shortid.generate, index: { unique: true } },
|
||||
editId : { type: String, default: shortid.generate, index: { unique: true } },
|
||||
shareId : { type: String, default: nanoid(12), index: { unique: true } },
|
||||
editId : { type: String, default: nanoid(12), index: { unique: true } },
|
||||
title : { type: String, default: '' },
|
||||
text : { type: String, default: '' },
|
||||
textBin : { type: Buffer },
|
||||
@@ -24,7 +24,6 @@ const HomebrewSchema = mongoose.Schema({
|
||||
}, { versionKey: false });
|
||||
|
||||
|
||||
|
||||
HomebrewSchema.methods.sanatize = function(full=false){
|
||||
const brew = this.toJSON();
|
||||
delete brew._id;
|
||||
@@ -35,7 +34,6 @@ HomebrewSchema.methods.sanatize = function(full=false){
|
||||
return brew;
|
||||
};
|
||||
|
||||
|
||||
HomebrewSchema.methods.increaseView = function(){
|
||||
return new Promise((resolve, reject)=>{
|
||||
this.lastViewed = new Date();
|
||||
@@ -47,8 +45,6 @@ HomebrewSchema.methods.increaseView = function(){
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
HomebrewSchema.statics.get = function(query){
|
||||
return new Promise((resolve, reject)=>{
|
||||
Homebrew.find(query, (err, brews)=>{
|
||||
@@ -77,11 +73,9 @@ HomebrewSchema.statics.getByUser = function(username, allowAccess=false){
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
const Homebrew = mongoose.model('Homebrew', HomebrewSchema);
|
||||
|
||||
module.exports = {
|
||||
schema : HomebrewSchema,
|
||||
model : Homebrew,
|
||||
};
|
||||
};
|
||||
|
||||
36
server/token.js
Normal file
36
server/token.js
Normal file
@@ -0,0 +1,36 @@
|
||||
const jwt = require('jwt-simple');
|
||||
|
||||
// Load configuration values
|
||||
const config = require('nconf')
|
||||
.argv()
|
||||
.env({ lowerCase: true }) // Load environment variables
|
||||
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
|
||||
.file('defaults', { file: 'config/default.json' });
|
||||
|
||||
// Generate an Access Token for the given User ID
|
||||
const generateAccessToken = (account)=>{
|
||||
const payload = account;
|
||||
|
||||
// When the token was issued
|
||||
payload.issued = (new Date());
|
||||
// Which service issued the Token
|
||||
payload.issuer = config.get('authentication_token_issuer');
|
||||
// Which service is the token intended for
|
||||
payload.audience = config.get('authentication_token_audience');
|
||||
// The signing key for signing the token
|
||||
delete payload.password;
|
||||
delete payload._id;
|
||||
|
||||
console.log('THE PAYLOAD');
|
||||
console.log(payload);
|
||||
|
||||
const secret = config.get('authentication_token_secret');
|
||||
|
||||
const token = jwt.encode(payload, secret);
|
||||
|
||||
return token;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
generateAccessToken : generateAccessToken
|
||||
};
|
||||
Reference in New Issue
Block a user