Skip to content

Commit 3cdfae4

Browse files
authored
Merge pull request #3942 from naturalcrit/re-author-brews-on-batch
Create backend batch re-author framework
2 parents 57cb334 + a927569 commit 3cdfae4

File tree

5 files changed

+101
-20
lines changed

5 files changed

+101
-20
lines changed

package-lock.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"classnames": "^2.5.1",
9292
"codemirror": "^5.65.6",
9393
"cookie-parser": "^1.4.7",
94+
"cors": "^2.8.5",
9495
"create-react-class": "^15.7.0",
9596
"dedent-tabs": "^0.10.3",
9697
"dompurify": "^3.2.3",

server/app.js

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Set working directory to project root
33
import { dirname } from 'path';
44
import { fileURLToPath } from 'url';
5-
import packageJSON from './../package.json' with { type: "json" };
5+
import packageJSON from './../package.json' with { type: 'json' };
66

77
const __dirname = dirname(fileURLToPath(import.meta.url));
88
process.chdir(`${__dirname}/..`);
@@ -26,7 +26,7 @@ import serveCompressedStaticAssets from './static-assets.mv.js';
2626
import sanitizeFilename from 'sanitize-filename';
2727
import asyncHandler from 'express-async-handler';
2828
import templateFn from '../client/template.js';
29-
import {model as HomebrewModel } from './homebrew.model.js';
29+
import { model as HomebrewModel } from './homebrew.model.js';
3030

3131
import { DEFAULT_BREW } from './brewDefaults.js';
3232
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
@@ -47,22 +47,59 @@ const sanitizeBrew = (brew, accessType)=>{
4747
return brew;
4848
};
4949

50-
app.set('trust proxy', 1 /* number of proxies between user and server */)
50+
app.set('trust proxy', 1 /* number of proxies between user and server */);
5151

5252
app.use('/', serveCompressedStaticAssets(`build`));
5353
app.use(contentNegotiation);
5454
app.use(bodyParser.json({ limit: '25mb' }));
5555
app.use(cookieParser());
5656
app.use(forceSSL);
5757

58+
import cors from 'cors';
59+
60+
const nodeEnv = config.get('node_env');
61+
const isLocalEnvironment = config.get('local_environments').includes(nodeEnv);
62+
63+
const corsOptions = {
64+
origin : (origin, callback)=>{
65+
66+
const allowedOrigins = [
67+
'https://homebrewery.naturalcrit.com',
68+
'https://naturalcrit.com',
69+
'https://naturalcrit-stage.herokuapp.com',
70+
'https://homebrewery-stage.herokuapp.com',
71+
];
72+
73+
if(isLocalEnvironment) {
74+
allowedOrigins.push('http://localhost:8000', 'http://localhost:8010');
75+
}
76+
77+
const herokuRegex = /^https:\/\/(?:homebrewery-pr-\d+\.herokuapp\.com|naturalcrit-pr-\d+\.herokuapp\.com)$/; // Matches any Heroku app
78+
79+
if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin)) {
80+
callback(null, true);
81+
} else {
82+
console.log(origin, 'not allowed');
83+
callback(new Error('Not allowed by CORS, if you think this is an error, please contact us'));
84+
}
85+
},
86+
methods : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
87+
credentials : true,
88+
};
89+
90+
app.use(cors(corsOptions));
91+
5892
//Account Middleware
5993
app.use((req, res, next)=>{
94+
console.log('passing through acc middleware, checking for cookies now: does cookies exist? ', !!req.cookies, ', ok, does the session cookie exist? ', !!req.cookies.nc_session);
6095
if(req.cookies && req.cookies.nc_session){
6196
try {
6297
req.account = jwt.decode(req.cookies.nc_session, config.get('secret'));
6398
//console.log("Just loaded up JWT from cookie:");
6499
//console.log(req.account);
65-
} catch (e){}
100+
} catch (e){
101+
console.log(e);
102+
}
66103
}
67104

68105
req.config = {
@@ -273,7 +310,7 @@ app.get('/user/:username', async (req, res, next)=>{
273310
console.log(err);
274311
});
275312

276-
brews.forEach(brew => brew.stubbed = true); //All brews from MongoDB are "stubbed"
313+
brews.forEach((brew)=>brew.stubbed = true); //All brews from MongoDB are "stubbed"
277314

278315
if(ownAccount && req?.account?.googleId){
279316
const auth = await GoogleActions.authCheck(req.account, res);
@@ -312,6 +349,37 @@ app.get('/user/:username', async (req, res, next)=>{
312349
return next();
313350
});
314351

352+
//Change author name on brews
353+
app.put('/api/user/rename', async (req, res)=>{
354+
const { username, newUsername } = req.body;
355+
356+
//this next logs will be removed in a next PR, as i need to get this live to test if req.account is created when passing the request from naturalcrit.com
357+
358+
console.log(`is user ${req.account.username} equal to ${username}? ${req.account.username === username} ${req.account.username === username && 'then add the damn auth for renaming!'}`);
359+
console.log('renaming');
360+
361+
if(!username || !newUsername) {
362+
return res.status(400).json({ error: 'Username and newUsername are required.' });
363+
}
364+
try {
365+
const brews = await HomebrewModel.getByUser(username, true, ['authors']);
366+
const renamePromises = brews.map(async (brew)=>{
367+
const updatedAuthors = brew.authors.map((author)=>author === username ? newUsername : author
368+
);
369+
return HomebrewModel.updateOne(
370+
{ _id: brew._id },
371+
{ $set: { authors: updatedAuthors } }
372+
);
373+
});
374+
await Promise.all(renamePromises);
375+
376+
return res.json({ success: true, message: `Brews for ${username} renamed to ${newUsername}.` });
377+
} catch (error) {
378+
console.error('Error renaming brews:', error);
379+
return res.status(500).json({ error: 'Failed to rename brews.' });
380+
}
381+
});
382+
315383
//Edit Page
316384
app.get('/edit/:id', asyncHandler(getBrew('edit')), asyncHandler(async(req, res, next)=>{
317385
req.brew = req.brew.toObject ? req.brew.toObject() : req.brew;
@@ -399,7 +467,7 @@ app.get('/share/:id', asyncHandler(getBrew('share')), asyncHandler(async (req, r
399467
app.get('/account', asyncHandler(async (req, res, next)=>{
400468
const data = {};
401469
data.title = 'Account Information Page';
402-
470+
403471
if(!req.account) {
404472
res.set('WWW-Authenticate', 'Bearer realm="Authorization Required"');
405473
const error = new Error('No valid account');
@@ -413,7 +481,7 @@ app.get('/account', asyncHandler(async (req, res, next)=>{
413481
let googleCount = [];
414482
if(req.account) {
415483
if(req.account.googleId) {
416-
auth = await GoogleActions.authCheck(req.account, res, false)
484+
auth = await GoogleActions.authCheck(req.account, res, false);
417485

418486
googleCount = await GoogleActions.listGoogleBrews(auth)
419487
.catch((err)=>{
@@ -448,8 +516,6 @@ app.get('/account', asyncHandler(async (req, res, next)=>{
448516
return next();
449517
}));
450518

451-
const nodeEnv = config.get('node_env');
452-
const isLocalEnvironment = config.get('local_environments').includes(nodeEnv);
453519
// Local only
454520
if(isLocalEnvironment){
455521
// Login
@@ -477,8 +543,8 @@ app.get('/vault', asyncHandler(async(req, res, next)=>{
477543

478544
//Send rendered page
479545
app.use(asyncHandler(async (req, res, next)=>{
480-
if (!req.route) return res.redirect('/'); // Catch-all for invalid routes
481-
546+
if(!req.route) return res.redirect('/'); // Catch-all for invalid routes
547+
482548
const page = await renderPage(req, res);
483549
if(!page) return;
484550
res.send(page);

server/homebrew.api.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,11 @@ const api = {
467467
}
468468
};
469469

470-
router.use('/api', checkClientVersion);
471-
router.post('/api', asyncHandler(api.newBrew));
472-
router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
473-
router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
474-
router.delete('/api/:id', asyncHandler(api.deleteBrew));
475-
router.get('/api/remove/:id', asyncHandler(api.deleteBrew));
470+
router.post('/api', checkClientVersion, asyncHandler(api.newBrew));
471+
router.put('/api/:id', checkClientVersion, asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
472+
router.put('/api/update/:id', checkClientVersion, asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
473+
router.delete('/api/:id', checkClientVersion, asyncHandler(api.deleteBrew));
474+
router.get('/api/remove/:id', checkClientVersion, asyncHandler(api.deleteBrew));
476475
router.get('/api/theme/:renderer/:id', asyncHandler(api.getThemeBundle));
477476

478477
export default api;
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import packageJSON from '../../package.json' with { type: "json" };
2-
const version = packageJSON.version;
1+
import packageJSON from '../../package.json' with { type: 'json' };
32

43
export default (req, res, next)=>{
54
const userVersion = req.get('Homebrewery-Version');
5+
const version = packageJSON.version;
66

7-
if(userVersion != version) {
7+
if(userVersion !== version) {
88
return res.status(412).send({
99
message : `Client version ${userVersion} is out of date. Please save your changes elsewhere and refresh to pick up client version ${version}.`
1010
});
1111
}
1212

1313
next();
1414
};
15+

0 commit comments

Comments
 (0)