mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-31 13:02:38 +00:00
Merge branch 'master' into localSnippetEditor
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import supertest from 'supertest';
|
||||
import HBApp from './app.js';
|
||||
import {model as NotificationModel } from './notifications.model.js';
|
||||
import { model as NotificationModel } from './notifications.model.js';
|
||||
|
||||
|
||||
// Mimic https responses to avoid being redirected all the time
|
||||
@@ -16,7 +16,7 @@ describe('Tests for admin api', ()=>{
|
||||
const testNotifications = ['a', 'b'];
|
||||
|
||||
jest.spyOn(NotificationModel, 'find')
|
||||
.mockImplementationOnce(() => {
|
||||
.mockImplementationOnce(()=>{
|
||||
return { exec: jest.fn().mockResolvedValue(testNotifications) };
|
||||
});
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('Tests for admin api', ()=>{
|
||||
expect(response.body).toEqual(savedNotification);
|
||||
});
|
||||
|
||||
it('should handle error adding a notification without dismissKey', async () => {
|
||||
it('should handle error adding a notification without dismissKey', async ()=>{
|
||||
const inputNotification = {
|
||||
title : 'Test Notification',
|
||||
text : 'This is a test notification',
|
||||
@@ -75,7 +75,7 @@ describe('Tests for admin api', ()=>{
|
||||
|
||||
const response = await app
|
||||
.post('/admin/notification/add')
|
||||
.set('Authorization', 'Basic ' + Buffer.from('admin:password3').toString('base64'))
|
||||
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
|
||||
.send(inputNotification);
|
||||
|
||||
expect(response.status).toBe(500);
|
||||
@@ -86,14 +86,14 @@ describe('Tests for admin api', ()=>{
|
||||
const dismissKey = 'testKey';
|
||||
|
||||
jest.spyOn(NotificationModel, 'findOneAndDelete')
|
||||
.mockImplementationOnce((key) => {
|
||||
.mockImplementationOnce((key)=>{
|
||||
return { exec: jest.fn().mockResolvedValue(key) };
|
||||
});
|
||||
const response = await app
|
||||
.delete(`/admin/notification/delete/${dismissKey}`)
|
||||
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`);
|
||||
|
||||
expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({'dismissKey': 'testKey'});
|
||||
expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' });
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual({ dismissKey: 'testKey' });
|
||||
});
|
||||
@@ -102,14 +102,14 @@ describe('Tests for admin api', ()=>{
|
||||
const dismissKey = 'testKey';
|
||||
|
||||
jest.spyOn(NotificationModel, 'findOneAndDelete')
|
||||
.mockImplementationOnce(() => {
|
||||
.mockImplementationOnce(()=>{
|
||||
return { exec: jest.fn().mockResolvedValue() };
|
||||
});
|
||||
const response = await app
|
||||
.delete(`/admin/notification/delete/${dismissKey}`)
|
||||
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`);
|
||||
|
||||
expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({'dismissKey': 'testKey'});
|
||||
expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' });
|
||||
expect(response.status).toBe(500);
|
||||
expect(response.body).toEqual({ message: 'Notification not found' });
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ const version = packageJSON.version;
|
||||
import _ from 'lodash';
|
||||
import jwt from 'jwt-simple';
|
||||
import express from 'express';
|
||||
import yaml from 'js-yaml';
|
||||
import config from './config.js';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
@@ -70,13 +69,11 @@ const corsOptions = {
|
||||
'https://homebrewery-stage.herokuapp.com',
|
||||
];
|
||||
|
||||
if(isLocalEnvironment) {
|
||||
allowedOrigins.push('http://localhost:8000', 'http://localhost:8010');
|
||||
}
|
||||
const localNetworkRegex = /^http:\/\/(localhost|127\.0\.0\.1|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[0-1])\.\d+\.\d+):\d+$/;
|
||||
|
||||
const herokuRegex = /^https:\/\/(?:homebrewery-pr-\d+\.herokuapp\.com|naturalcrit-pr-\d+\.herokuapp\.com)$/; // Matches any Heroku app
|
||||
|
||||
if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin)) {
|
||||
if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin) || (isLocalEnvironment && localNetworkRegex.test(origin))) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
console.log(origin, 'not allowed');
|
||||
@@ -352,7 +349,7 @@ app.get('/user/:username', async (req, res, next)=>{
|
||||
app.put('/api/user/rename', async (req, res)=>{
|
||||
const { username, newUsername } = req.body;
|
||||
const ownAccount = req.account && (req.account.username == newUsername);
|
||||
|
||||
|
||||
if(!username || !newUsername)
|
||||
return res.status(400).json({ error: 'Username and newUsername are required.' });
|
||||
if(!ownAccount)
|
||||
|
||||
@@ -27,12 +27,12 @@ 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
|
||||
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 = {
|
||||
@@ -177,8 +177,8 @@ const GoogleActions = {
|
||||
mimeType : 'text/plain',
|
||||
body : brew.text
|
||||
},
|
||||
headers: {
|
||||
'X-Forwarded-For': userIp, // Set the X-Forwarded-For header
|
||||
headers : {
|
||||
'X-Forwarded-For' : userIp, // Set the X-Forwarded-For header
|
||||
},
|
||||
retryConfig
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ const api = {
|
||||
const accessMap = {
|
||||
edit : { editId: id },
|
||||
share : { shareId: id },
|
||||
admin : { $or : [{ editId: id }, { shareId: id }] }
|
||||
admin : { $or: [{ editId: id }, { shareId: id }] }
|
||||
};
|
||||
|
||||
// Try to find the document in the Homebrewery database -- if it doesn't exist, that's fine.
|
||||
@@ -189,6 +189,7 @@ const api = {
|
||||
`${text}`;
|
||||
return text;
|
||||
},
|
||||
|
||||
getGoodBrewTitle : (text)=>{
|
||||
const tokens = Markdown.marked.lexer(text);
|
||||
return (tokens.find((token)=>token.type === 'heading' || token.type === 'paragraph')?.text || 'No Title')
|
||||
@@ -302,7 +303,7 @@ const api = {
|
||||
|
||||
currentTheme = req.brew;
|
||||
splitTextStyleAndMetadata(currentTheme);
|
||||
if(!currentTheme.tags.some(tag => tag === "meta:theme" || tag === "meta:Theme"))
|
||||
if(!currentTheme.tags.some((tag)=>tag === 'meta:theme' || tag === 'meta:Theme'))
|
||||
throw { brewId: req.params.id, name: 'Invalid Theme Selected', message: 'Selected theme does not have the meta:theme tag', status: 422, HBErrorCode: '10' };
|
||||
themeName ??= currentTheme.title;
|
||||
themeAuthor ??= currentTheme.authors?.[0];
|
||||
|
||||
@@ -63,7 +63,7 @@ HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, f
|
||||
|
||||
const Homebrew = mongoose.model('Homebrew', HomebrewSchema);
|
||||
|
||||
export {
|
||||
export {
|
||||
HomebrewSchema as schema,
|
||||
Homebrew as model
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user