From ff9a75f6b62660de84c63f3ce4db66fa555e1c70 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 26 Sep 2024 19:00:07 -0400 Subject: [PATCH 01/19] Remove duplicate error logs for google drive update / new Errors are now logged once in the central error handler in app.js --- server/app.js | 2 +- server/googleActions.js | 1 - server/homebrew.api.js | 21 ++++++--------------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/server/app.js b/server/app.js index 02075d31d..c922f0ff7 100644 --- a/server/app.js +++ b/server/app.js @@ -498,7 +498,7 @@ app.use(async (err, req, res, next)=>{ err.originalUrl = req.originalUrl; console.error(err); - if(err.originalUrl?.startsWith('/api/')) { + if(err.originalUrl?.startsWith('/api')) { // console.log('API error'); res.status(err.status || err.response?.status || 500).send(err); return; diff --git a/server/googleActions.js b/server/googleActions.js index 93367248e..09e51b0bd 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -172,7 +172,6 @@ const GoogleActions = { }) .catch((err)=>{ console.log('Error saving to google'); - console.error(err); throw (err); }); diff --git a/server/homebrew.api.js b/server/homebrew.api.js index f15376af7..22e2cee7b 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -242,11 +242,8 @@ const api = { let googleId, saved; if(saveToGoogle) { - googleId = await api.newGoogleBrew(req.account, newHomebrew, res) - .catch((err)=>{ - console.error(err); - res.status(err?.status || err?.response?.status || 500).send(err?.message || err); - }); + googleId = await api.newGoogleBrew(req.account, newHomebrew, res); + if(!googleId) return; api.excludeStubProps(newHomebrew); newHomebrew.googleId = googleId; @@ -351,19 +348,13 @@ const api = { brew.googleId = undefined; } else if(!brew.googleId && saveToGoogle) { // If we don't have a google id and the user wants to save to google, create the google brew and set the google id on the brew - brew.googleId = await api.newGoogleBrew(req.account, api.excludeGoogleProps(brew), res) - .catch((err)=>{ - console.error(err); - res.status(err.status || err.response.status).send(err.message || err); - }); + brew.googleId = await api.newGoogleBrew(req.account, api.excludeGoogleProps(brew), res); + if(!brew.googleId) return; } else if(brew.googleId) { // If the google id exists and no other actions are being performed, update the google brew - const updated = await GoogleActions.updateGoogleBrew(api.excludeGoogleProps(brew)) - .catch((err)=>{ - console.error(err); - res.status(err?.response?.status || 500).send(err); - }); + const updated = await GoogleActions.updateGoogleBrew(api.excludeGoogleProps(brew)); + if(!updated) return; } From c8424e0b1016462d7da239e3e8b8589169bd17d4 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 26 Sep 2024 19:12:19 -0400 Subject: [PATCH 02/19] Remove test that no longer applies --- server/homebrew.api.spec.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 6e7c36641..30a006972 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -560,16 +560,6 @@ brew`); views : 0 }); }); - - it('should handle google error', async()=>{ - google.newGoogleBrew = jest.fn(()=>{ - throw 'err'; - }); - await api.newBrew({ body: { text: 'asdf', title: '' }, query: { saveToGoogle: true }, account: { username: 'test user' } }, res); - - expect(res.status).toHaveBeenCalledWith(500); - expect(res.send).toHaveBeenCalledWith('err'); - }); }); describe('deleteGoogleBrew', ()=>{ From e260eb09113329157f4e61b527be2879cebc1dc8 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 26 Sep 2024 19:14:16 -0400 Subject: [PATCH 03/19] Raise timeout to 10 s. No need to be stingy here... Can lower back down if this works. --- client/homebrew/pages/editPage/editPage.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 39a6d1931..792b1971e 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -29,7 +29,7 @@ const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpe const googleDriveIcon = require('../../googleDrive.svg'); -const SAVE_TIMEOUT = 3000; +const SAVE_TIMEOUT = 10000; const EditPage = createClass({ displayName : 'EditPage', From ea656e51195b139c1ece9ee56afac88cd8eed111 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 29 Sep 2024 00:15:26 -0400 Subject: [PATCH 04/19] Issue notice --- .../notificationPopup/notificationPopup.jsx | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx index aa45bbb8e..e223e5012 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx @@ -4,7 +4,7 @@ const _ = require('lodash'); import Dialog from '../../../components/dialog.jsx'; -const DISMISS_KEY = 'dismiss_notification04-09-24'; +const DISMISS_KEY = 'dismiss_notification28-09-24'; const DISMISS_BUTTON = ; const NotificationPopup = ()=>{ @@ -15,6 +15,31 @@ const NotificationPopup = ()=>{ This website is always improving and we are still adding new features and squashing bugs. Keep the following in mind:
    +
  • + Known issue with saving/creating Google Drive files
    + We are aware of + an issue with saving to Google Drive as of Sept 29 2024 01:50 UTC and are working on a fix. + This appears to be an intermittent error with Google in the last few days and may + take some time to resolve. +



    + Brews saved to Google Drive are not lost and can still be viewed, just not updated. + You can also access them via your Google Drive interface in the /Hombrewery folder. +



    + If you need to urgently edit documents, you can detatch them from your Google Drive + by transferring them to our Homebrewery storage. To do this, click the colored Google Drive + icon next to the save button when on an edit page; you can transfer them back later, + but this should allow you to edit while this issue is ongoing. +



    + If you are experiencing errors creating new documents, you can similarly change your + account settings to create new brews by default in the Homebrewery storage. Click + your username and then "account", then change the "default save location". +
  • +
  • Search brews with our new page!
    We have been working very hard in making this possible, now you can share your work and look at it in the new Vault page! From 8ab6a8599d49e94f3fc94bcc00cfb19db640af8d Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 29 Sep 2024 21:47:45 -0400 Subject: [PATCH 05/19] Use personal auth if logged in via google. --- server/googleActions.js | 6 ++++-- server/homebrew.api.js | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/server/googleActions.js b/server/googleActions.js index 09e51b0bd..b042a00e6 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -147,8 +147,10 @@ const GoogleActions = { return brews; }, - updateGoogleBrew : async (brew)=>{ - const drive = googleDrive.drive({ version: 'v3', auth: defaultAuth }); + updateGoogleBrew : async (brew, auth = defaultAuth)=>{ + const drive = googleDrive.drive({ version: 'v3', auth: auth }); + + console.log(auth == defaultAuth ? 'UPDATE w SERVICEACC' : 'UPDATE w USERACC') await drive.files.update({ fileId : brew.googleId, diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 22e2cee7b..0f2283c2b 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -353,7 +353,7 @@ const api = { if(!brew.googleId) return; } else if(brew.googleId) { // If the google id exists and no other actions are being performed, update the google brew - const updated = await GoogleActions.updateGoogleBrew(api.excludeGoogleProps(brew)); + const updated = await api.updateGoogleBrew(req.account, api.excludeGoogleProps(brew), res); if(!updated) return; } @@ -397,6 +397,15 @@ const api = { res.status(200).send(saved); }, + + updateGoogleBrew : async (account, brew, res)=>{ + let oAuth2Client; + if(account.googleId) + oAuth2Client = GoogleActions.authCheck(account, res); + + return await GoogleActions.updateGoogleBrew(brew, oAuth2Client); + }, + deleteGoogleBrew : async (account, id, editId, res)=>{ const auth = await GoogleActions.authCheck(account, res); await GoogleActions.deleteGoogleBrew(auth, id, editId); From 68895bdca2baa09b7c21572ebfd6aa6a8e34d303 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 29 Sep 2024 23:37:26 -0400 Subject: [PATCH 06/19] Rate limit `/api` requests from each IP address 100 requests each 5 minutes. --- client/homebrew/navbar/error-navitem.jsx | 11 +++++++++++ package-lock.json | 16 ++++++++++++++++ package.json | 1 + server/homebrew.api.js | 12 ++++++++++++ 4 files changed, 40 insertions(+) diff --git a/client/homebrew/navbar/error-navitem.jsx b/client/homebrew/navbar/error-navitem.jsx index 5dd5c1eb9..264d528ef 100644 --- a/client/homebrew/navbar/error-navitem.jsx +++ b/client/homebrew/navbar/error-navitem.jsx @@ -116,6 +116,17 @@ const ErrorNavItem = createClass({ ; } + if(HBErrorCode === '55') { + return + Oops! +
    + Looks like there are too many requests + from this IP address in a short time. + Please try again after a few minutes. +
    +
    ; + } + return Oops!
    diff --git a/package-lock.json b/package-lock.json index ed0cbf1f1..701592890 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "expr-eval": "^2.0.2", "express": "^4.19.2", "express-async-handler": "^1.2.0", + "express-rate-limit": "^7.4.0", "express-static-gzip": "2.1.7", "fs-extra": "11.2.0", "js-yaml": "^4.1.0", @@ -6352,6 +6353,21 @@ "integrity": "sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==", "license": "MIT" }, + "node_modules/express-rate-limit": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.0.tgz", + "integrity": "sha512-v1204w3cXu5gCDmAvgvzI6qjzZzoMWKnyVDk3ACgfswTQLYiGen+r8w0VnXnGMmzEN/g8fwIQ4JrFFd4ZP6ssg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "4 || 5 || ^5.0.0-beta.1" + } + }, "node_modules/express-static-gzip": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.7.tgz", diff --git a/package.json b/package.json index 8248f4304..6926097a9 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "expr-eval": "^2.0.2", "express": "^4.19.2", "express-async-handler": "^1.2.0", + "express-rate-limit": "^7.4.0", "express-static-gzip": "2.1.7", "fs-extra": "11.2.0", "js-yaml": "^4.1.0", diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 0f2283c2b..1891e2791 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -9,6 +9,7 @@ const yaml = require('js-yaml'); const asyncHandler = require('express-async-handler'); const { nanoid } = require('nanoid'); const { splitTextStyleAndMetadata } = require('../shared/helpers.js'); +const rateLimit = require('express-rate-limit'); const { DEFAULT_BREW, DEFAULT_BREW_LOAD } = require('./brewDefaults.js'); @@ -24,6 +25,16 @@ const isStaticTheme = (renderer, themeName)=>{ // }); // }; +// Define rate limiter options +const rateLimiter = rateLimit({ + timeWindow : 5 * 60 * 1000, // 5 minutes window + max : 100, // limit each IP to 100 requests per timeWindow + handler: (req, res, next) => { + console.log(`Rate limiting user ${req.account?.username}`); + throw { HBErrorCode: '55', status: 429, message: 'Too many requests from this IP, please try again after 5 minutes'}; + } +}); + const MAX_TITLE_LENGTH = 100; const api = { @@ -473,6 +484,7 @@ const api = { } }; +router.use('/api', rateLimiter); router.use('/api', require('./middleware/check-client-version.js')); router.post('/api', asyncHandler(api.newBrew)); router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew)); From 32fa2729470f27b10532c24af3bcb2d6546eb280 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 00:03:27 -0400 Subject: [PATCH 07/19] reduce rate limit to 60 requests in 5 minutes --- server/homebrew.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 1891e2791..9eb97c601 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -28,7 +28,7 @@ const isStaticTheme = (renderer, themeName)=>{ // Define rate limiter options const rateLimiter = rateLimit({ timeWindow : 5 * 60 * 1000, // 5 minutes window - max : 100, // limit each IP to 100 requests per timeWindow + max : 60, // limit each IP to 100 requests per timeWindow handler: (req, res, next) => { console.log(`Rate limiting user ${req.account?.username}`); throw { HBErrorCode: '55', status: 429, message: 'Too many requests from this IP, please try again after 5 minutes'}; From a7361f8450512830b7ef67f524d79fcd0b10f445 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 00:14:37 -0400 Subject: [PATCH 08/19] add delay between get and update --- server/homebrew.api.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 9eb97c601..cfd6dd2e2 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -35,6 +35,15 @@ const rateLimiter = rateLimit({ } }); +// Define the delay middleware function +const delayMiddleware = (delay) => { + return (req, res, next) => { + setTimeout(() => { + next(); + }, delay); + }; +}; + const MAX_TITLE_LENGTH = 100; const api = { @@ -488,7 +497,7 @@ router.use('/api', rateLimiter); router.use('/api', require('./middleware/check-client-version.js')); router.post('/api', asyncHandler(api.newBrew)); router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew)); -router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew)); +router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), delayMiddleware(1000), asyncHandler(api.updateBrew)); router.delete('/api/:id', asyncHandler(api.deleteBrew)); router.get('/api/remove/:id', asyncHandler(api.deleteBrew)); router.get('/api/theme/:renderer/:id', asyncHandler(api.getThemeBundle)); From 3a6750613bbe628f3a28f5ec42b5074ca78e4ee3 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 00:31:58 -0400 Subject: [PATCH 09/19] express proxy settings --- server/app.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/app.js b/server/app.js index c922f0ff7..fef433d59 100644 --- a/server/app.js +++ b/server/app.js @@ -30,6 +30,10 @@ const sanitizeBrew = (brew, accessType)=>{ return brew; }; +app.set('trust proxy', 1 /* number of proxies between user and server */) +app.get('/ip', (request, response) => response.send(request.ip)) + + app.use('/', serveCompressedStaticAssets(`build`)); app.use(require('./middleware/content-negotiation.js')); app.use(require('body-parser').json({ limit: '25mb' })); From 66433d9e7721fd3d0c231b62fdeef0b5c25b0f8c Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 00:45:10 -0400 Subject: [PATCH 10/19] 5 requests --- server/homebrew.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index cfd6dd2e2..e1fa0e089 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -28,7 +28,7 @@ const isStaticTheme = (renderer, themeName)=>{ // Define rate limiter options const rateLimiter = rateLimit({ timeWindow : 5 * 60 * 1000, // 5 minutes window - max : 60, // limit each IP to 100 requests per timeWindow + max : 5, // limit each IP to 100 requests per timeWindow handler: (req, res, next) => { console.log(`Rate limiting user ${req.account?.username}`); throw { HBErrorCode: '55', status: 429, message: 'Too many requests from this IP, please try again after 5 minutes'}; From 40925253bdcb23945b3dff6445467cc44ae3e92e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 00:59:30 -0400 Subject: [PATCH 11/19] autosave to 16 seconds --- client/homebrew/pages/editPage/editPage.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 792b1971e..4d7741000 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -29,7 +29,7 @@ const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpe const googleDriveIcon = require('../../googleDrive.svg'); -const SAVE_TIMEOUT = 10000; +const SAVE_TIMEOUT = 16000; const EditPage = createClass({ displayName : 'EditPage', From e9c45b216cb26cb34d11948442cc03d30b601a3e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 08:31:39 -0400 Subject: [PATCH 12/19] Add retryconfig and forward user ip --- server/googleActions.js | 18 +++++++++++++++--- server/homebrew.api.js | 6 +++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/server/googleActions.js b/server/googleActions.js index b042a00e6..4cba4d8ca 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -25,6 +25,15 @@ if(!config.get('service_account')){ const defaultAuth = serviceAuth || config.get('google_api_key'); +const retryConfig = { + retry: 3, // Number of retry attempts + retryDelay: 100, // Initial delay in milliseconds + retryDelayMultiplier: 2, // Multiplier for exponential backoff + maxRetryDelay: 32000, // Maximum delay in milliseconds + httpMethodsToRetry: ['PATCH'], // Only retry PATCH requests + statusCodesToRetry: [[429, 429]], // Only retry on 429 status code +}; + const GoogleActions = { authCheck : (account, res, updateTokens=true)=>{ @@ -147,9 +156,8 @@ const GoogleActions = { return brews; }, - updateGoogleBrew : async (brew, auth = defaultAuth)=>{ + updateGoogleBrew : async (brew, auth = defaultAuth, userIp)=>{ const drive = googleDrive.drive({ version: 'v3', auth: auth }); - console.log(auth == defaultAuth ? 'UPDATE w SERVICEACC' : 'UPDATE w USERACC') await drive.files.update({ @@ -170,7 +178,11 @@ const GoogleActions = { media : { mimeType : 'text/plain', body : brew.text - } + }, + headers: { + 'X-Forwarded-For': userIp, // Set the X-Forwarded-For header + }, + retryConfig }) .catch((err)=>{ console.log('Error saving to google'); diff --git a/server/homebrew.api.js b/server/homebrew.api.js index e1fa0e089..9546e8266 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -373,7 +373,7 @@ const api = { if(!brew.googleId) return; } else if(brew.googleId) { // If the google id exists and no other actions are being performed, update the google brew - const updated = await api.updateGoogleBrew(req.account, api.excludeGoogleProps(brew), res); + const updated = await api.updateGoogleBrew(req.account, api.excludeGoogleProps(brew), res, req); if(!updated) return; } @@ -418,12 +418,12 @@ const api = { res.status(200).send(saved); }, - updateGoogleBrew : async (account, brew, res)=>{ + updateGoogleBrew : async (account, brew, res, req)=>{ let oAuth2Client; if(account.googleId) oAuth2Client = GoogleActions.authCheck(account, res); - return await GoogleActions.updateGoogleBrew(brew, oAuth2Client); + return await GoogleActions.updateGoogleBrew(brew, oAuth2Client, req.ip); }, deleteGoogleBrew : async (account, id, editId, res)=>{ From e7e35294c6f162664866bbfdb1436b65c482f044 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 30 Sep 2024 10:59:43 -0400 Subject: [PATCH 13/19] disable rate limiter --- server/homebrew.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 9546e8266..5adbc40cf 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -493,7 +493,7 @@ const api = { } }; -router.use('/api', rateLimiter); +// router.use('/api', rateLimiter); router.use('/api', require('./middleware/check-client-version.js')); router.post('/api', asyncHandler(api.newBrew)); router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew)); From c33b44855a29979fdeab05cd102767eb45f3097f Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 1 Oct 2024 12:17:30 -0400 Subject: [PATCH 14/19] Go back to service account for brew updates --- server/homebrew.api.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 5adbc40cf..b231dd0cc 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -419,11 +419,11 @@ const api = { }, updateGoogleBrew : async (account, brew, res, req)=>{ - let oAuth2Client; - if(account.googleId) - oAuth2Client = GoogleActions.authCheck(account, res); + //let oAuth2Client; + //if(account.googleId) + // oAuth2Client = GoogleActions.authCheck(account, res); - return await GoogleActions.updateGoogleBrew(brew, oAuth2Client, req.ip); + return await GoogleActions.updateGoogleBrew(brew, undefined, req.ip); }, deleteGoogleBrew : async (account, id, editId, res)=>{ From 0e2962071098c9955da3b56a8237cef9726e12bb Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 1 Oct 2024 14:13:15 -0400 Subject: [PATCH 15/19] Remove delayMiddleware and ratelimiter --- server/homebrew.api.js | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index b231dd0cc..601fe8758 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -25,25 +25,6 @@ const isStaticTheme = (renderer, themeName)=>{ // }); // }; -// Define rate limiter options -const rateLimiter = rateLimit({ - timeWindow : 5 * 60 * 1000, // 5 minutes window - max : 5, // limit each IP to 100 requests per timeWindow - handler: (req, res, next) => { - console.log(`Rate limiting user ${req.account?.username}`); - throw { HBErrorCode: '55', status: 429, message: 'Too many requests from this IP, please try again after 5 minutes'}; - } -}); - -// Define the delay middleware function -const delayMiddleware = (delay) => { - return (req, res, next) => { - setTimeout(() => { - next(); - }, delay); - }; -}; - const MAX_TITLE_LENGTH = 100; const api = { @@ -493,11 +474,10 @@ const api = { } }; -// router.use('/api', rateLimiter); router.use('/api', require('./middleware/check-client-version.js')); router.post('/api', asyncHandler(api.newBrew)); router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew)); -router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), delayMiddleware(1000), asyncHandler(api.updateBrew)); +router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew)); router.delete('/api/:id', asyncHandler(api.deleteBrew)); router.get('/api/remove/:id', asyncHandler(api.deleteBrew)); router.get('/api/theme/:renderer/:id', asyncHandler(api.getThemeBundle)); From 0110c6afed4b62e3afd7ef42d49c3fd016cb6af9 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 1 Oct 2024 15:06:11 -0400 Subject: [PATCH 16/19] Remove duplicate error log for googleActions.list --- server/app.js | 24 +++++++----------------- server/googleActions.js | 2 -- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/server/app.js b/server/app.js index fef433d59..04b3c3486 100644 --- a/server/app.js +++ b/server/app.js @@ -379,22 +379,12 @@ app.get('/account', asyncHandler(async (req, res, next)=>{ let googleCount = []; if(req.account) { if(req.account.googleId) { - try { - auth = await GoogleActions.authCheck(req.account, res, false); - } catch (e) { - auth = undefined; - console.log('Google auth check failed!'); - console.log(e); - } - if(auth.credentials.access_token) { - try { - googleCount = await GoogleActions.listGoogleBrews(auth); - } catch (e) { - googleCount = undefined; - console.log('List Google files failed!'); - console.log(e); - } - } + auth = await GoogleActions.authCheck(req.account, res, false) + + googleCount = await GoogleActions.listGoogleBrews(auth) + .catch((err)=>{ + console.error(err); + }); } const query = { authors: req.account.username, googleId: { $exists: false } }; @@ -408,7 +398,7 @@ app.get('/account', asyncHandler(async (req, res, next)=>{ username : req.account.username, issued : req.account.issued, googleId : Boolean(req.account.googleId), - authCheck : Boolean(req.account.googleId && auth.credentials.access_token), + authCheck : Boolean(req.account.googleId && auth?.credentials.access_token), mongoCount : mongoCount, googleCount : googleCount?.length }; diff --git a/server/googleActions.js b/server/googleActions.js index 4cba4d8ca..953ae27fb 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -121,9 +121,7 @@ const GoogleActions = { }) .catch((err)=>{ console.log(`Error Listing Google Brews`); - console.error(err); throw (err); - //TODO: Should break out here, but continues on for some reason. }); fileList.push(...obj.data.files); NextPageToken = obj.data.nextPageToken; From 1a325fb3c5bd7723d2611fe9e9b775191d6135f6 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Tue, 1 Oct 2024 22:25:17 -0400 Subject: [PATCH 17/19] New notification --- .../notificationPopup/notificationPopup.jsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx index e223e5012..9cdaf2ff6 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx @@ -4,7 +4,7 @@ const _ = require('lodash'); import Dialog from '../../../components/dialog.jsx'; -const DISMISS_KEY = 'dismiss_notification28-09-24'; +const DISMISS_KEY = 'dismiss_notification01-10-24'; const DISMISS_BUTTON = ; const NotificationPopup = ()=>{ @@ -22,10 +22,13 @@ const NotificationPopup = ()=>{ fontSize: '1.0em' }}> Known issue with saving/creating Google Drive files
    - We are aware of - an issue with saving to Google Drive as of Sept 29 2024 01:50 UTC and are working on a fix. - This appears to be an intermittent error with Google in the last few days and may - take some time to resolve. + Dear users. The + issue with saving to Google Drive has resurfaced as of Oct 1, 2024 22:00 UTC. +



    + Earlier we submitted a bug report to Google and have all but confirmed the issue + lies on Google's end and the disruption has been affecting multiple other + organizations besides us. Unfortunately, it means reliable interaction with + Google remains out of our control until they can resolve their issue.



    Brews saved to Google Drive are not lost and can still be viewed, just not updated. You can also access them via your Google Drive interface in the /Hombrewery folder. From 487a574f50a41c1ebbcd46f337699142e1690c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Fri, 4 Oct 2024 22:18:11 +0200 Subject: [PATCH 18/19] initital fix --- client/homebrew/navbar/recent.navitem.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/homebrew/navbar/recent.navitem.jsx b/client/homebrew/navbar/recent.navitem.jsx index 431bdd8df..a6cbbf406 100644 --- a/client/homebrew/navbar/recent.navitem.jsx +++ b/client/homebrew/navbar/recent.navitem.jsx @@ -36,7 +36,7 @@ const RecentItems = createClass({ //== Add current brew to appropriate recent items list (depending on storageKey) ==// if(this.props.storageKey == 'edit'){ let editId = this.props.brew.editId; - if(this.props.brew.googleId){ + if(this.props.brew.googleId && !this.props.brew.stubbed){ editId = `${this.props.brew.googleId}${this.props.brew.editId}`; } edited = _.filter(edited, (brew)=>{ @@ -51,7 +51,7 @@ const RecentItems = createClass({ } if(this.props.storageKey == 'view'){ let shareId = this.props.brew.shareId; - if(this.props.brew.googleId){ + if(this.props.brew.googleId && !this.props.brew.stubbed){ shareId = `${this.props.brew.googleId}${this.props.brew.shareId}`; } viewed = _.filter(viewed, (brew)=>{ @@ -83,7 +83,7 @@ const RecentItems = createClass({ let edited = JSON.parse(localStorage.getItem(EDIT_KEY) || '[]'); if(this.props.storageKey == 'edit') { let prevEditId = prevProps.brew.editId; - if(prevProps.brew.googleId){ + if(prevProps.brew.googleId && !this.props.brew.stubbed){ prevEditId = `${prevProps.brew.googleId}${prevProps.brew.editId}`; } @@ -91,7 +91,7 @@ const RecentItems = createClass({ return brew.id !== prevEditId; }); let editId = this.props.brew.editId; - if(this.props.brew.googleId){ + if(this.props.brew.googleId && !this.props.brew.stubbed){ editId = `${this.props.brew.googleId}${this.props.brew.editId}`; } edited.unshift({ From 2a523c4955d8d6b6dc30e811326fb16a0ba59cc7 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 6 Oct 2024 15:48:10 -0400 Subject: [PATCH 19/19] Fix links to google drive files in user page User page was not marking Google Brews as "stubbed" if the brew belongs to another users' Google Drive or your own credentials are expired (it searches the current user drive for google files and checks if those are stubbed) This now sets *every* file found on Mongo as "Stubbed", whether the Drive file belongs to the current user or not. --- server/app.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/app.js b/server/app.js index 04b3c3486..40ab193d9 100644 --- a/server/app.js +++ b/server/app.js @@ -242,6 +242,8 @@ app.get('/user/:username', async (req, res, next)=>{ console.log(err); }); + brews.forEach(brew => brew.stubbed = true); //All brews from MongoDB are "stubbed" + if(ownAccount && req?.account?.googleId){ const auth = await GoogleActions.authCheck(req.account, res); let googleBrews = await GoogleActions.listGoogleBrews(auth) @@ -249,12 +251,12 @@ app.get('/user/:username', async (req, res, next)=>{ console.error(err); }); + // If stub matches file from Google, use Google metadata over stub metadata if(googleBrews && googleBrews.length > 0) { for (const brew of brews.filter((brew)=>brew.googleId)) { const match = googleBrews.findIndex((b)=>b.editId === brew.editId); if(match !== -1) { brew.googleId = googleBrews[match].googleId; - brew.stubbed = true; brew.pageCount = googleBrews[match].pageCount; brew.renderer = googleBrews[match].renderer; brew.version = googleBrews[match].version; @@ -263,6 +265,7 @@ app.get('/user/:username', async (req, res, next)=>{ } } + //Remaining unstubbed google brews display current user as author googleBrews = googleBrews.map((brew)=>({ ...brew, authors: [req.account.username] })); brews = _.concat(brews, googleBrews); }