mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-08 18:22:40 +00:00
Merge branch 'master' into dependabot/npm_and_yarn/prod-dependencies-b017ff4ab1
This commit is contained in:
@@ -176,6 +176,26 @@ const errorIndex = (props)=>{
|
|||||||
|
|
||||||
If the selected brew is your document, you may designate it as a theme by adding the \`theme:meta\` tag.`,
|
If the selected brew is your document, you may designate it as a theme by adding the \`theme:meta\` tag.`,
|
||||||
|
|
||||||
|
// ID validation error
|
||||||
|
'11' : dedent`
|
||||||
|
## No Homebrewery document could be found.
|
||||||
|
|
||||||
|
The server could not locate the Homebrewery document. The Brew ID failed the validation check.
|
||||||
|
|
||||||
|
:
|
||||||
|
|
||||||
|
**Brew ID:** ${props.brew.brewId}`,
|
||||||
|
|
||||||
|
// Google ID validation error
|
||||||
|
'12' : dedent`
|
||||||
|
## No Google document could be found.
|
||||||
|
|
||||||
|
The server could not locate the Google document. The Google ID failed the validation check.
|
||||||
|
|
||||||
|
:
|
||||||
|
|
||||||
|
**Brew ID:** ${props.brew.brewId}`,
|
||||||
|
|
||||||
//account page when account is not defined
|
//account page when account is not defined
|
||||||
'50' : dedent`
|
'50' : dedent`
|
||||||
## You are not signed in
|
## You are not signed in
|
||||||
|
|||||||
66
server/forcessl.mw.spec.js
Normal file
66
server/forcessl.mw.spec.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import forceSSL from './forcessl.mw';
|
||||||
|
|
||||||
|
describe('Tests for ForceSSL middleware', ()=>{
|
||||||
|
let originalEnv;
|
||||||
|
let nextFn;
|
||||||
|
|
||||||
|
let req = {};
|
||||||
|
let res = {};
|
||||||
|
|
||||||
|
beforeEach(()=>{
|
||||||
|
originalEnv = process.env.NODE_ENV;
|
||||||
|
nextFn = jest.fn();
|
||||||
|
|
||||||
|
req = {
|
||||||
|
header : ()=>{ return 'http'; },
|
||||||
|
get : ()=>{ return 'test'; },
|
||||||
|
url : 'URL'
|
||||||
|
};
|
||||||
|
|
||||||
|
res = {
|
||||||
|
redirect : jest.fn()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(()=>{
|
||||||
|
process.env.NODE_ENV = originalEnv;
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not redirect when NODE_ENV is set to local', ()=>{
|
||||||
|
process.env.NODE_ENV = 'local';
|
||||||
|
|
||||||
|
forceSSL(null, null, nextFn);
|
||||||
|
|
||||||
|
expect(res.redirect).not.toHaveBeenCalled();
|
||||||
|
expect(nextFn).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not redirect when NODE_ENV is set to docker', ()=>{
|
||||||
|
process.env.NODE_ENV = 'docker';
|
||||||
|
|
||||||
|
forceSSL(null, null, nextFn);
|
||||||
|
|
||||||
|
expect(res.redirect).not.toHaveBeenCalled();
|
||||||
|
expect(nextFn).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect with 302 when header is not HTTPS and NODE_ENV is not local or docker', ()=>{
|
||||||
|
process.env.NODE_ENV = 'test';
|
||||||
|
|
||||||
|
forceSSL(req, res, nextFn);
|
||||||
|
|
||||||
|
expect(res.redirect).toHaveBeenCalledWith(302, 'https://testURL');
|
||||||
|
expect(nextFn).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not redirect when header is HTTPS and NODE_ENV is not local or docker', ()=>{
|
||||||
|
process.env.NODE_ENV = 'test';
|
||||||
|
req.header = ()=>{ return 'https'; };
|
||||||
|
|
||||||
|
forceSSL(req, res, nextFn);
|
||||||
|
|
||||||
|
expect(res.redirect).not.toHaveBeenCalled();
|
||||||
|
expect(nextFn).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -48,6 +48,20 @@ const api = {
|
|||||||
}
|
}
|
||||||
id = id.slice(googleId.length);
|
id = id.slice(googleId.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ID Validation Checks
|
||||||
|
// Homebrewery ID
|
||||||
|
// Typically 12 characters, but the DB shows a range of 7 to 14 characters
|
||||||
|
if(!id.match(/^[A-Za-z0-9_-]{7,14}$/)){
|
||||||
|
throw { name: 'ID Error', message: 'Invalid ID', status: 404, HBErrorCode: '11', brewId: id };
|
||||||
|
}
|
||||||
|
// Google ID
|
||||||
|
// Typically 33 characters, old format is 44 - always starts with a 1
|
||||||
|
// Managed by Google, may change outside of our control, so any length between 33 and 44 is acceptable
|
||||||
|
if(googleId && !googleId.match(/^1(?:[A-Za-z0-9+\/]{32,43})$/)){
|
||||||
|
throw { name: 'Google ID Error', message: 'Invalid ID', status: 404, HBErrorCode: '12', brewId: id };
|
||||||
|
}
|
||||||
|
|
||||||
return { id, googleId };
|
return { id, googleId };
|
||||||
},
|
},
|
||||||
//Get array of any of this user's brews tagged with `meta:theme`
|
//Get array of any of this user's brews tagged with `meta:theme`
|
||||||
|
|||||||
@@ -99,18 +99,87 @@ describe('Tests for api', ()=>{
|
|||||||
expect(googleId).toBeUndefined();
|
expect(googleId).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw if id is too short', ()=>{
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
api.getId({
|
||||||
|
params : {
|
||||||
|
id : 'abcd'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(err).toEqual({ HBErrorCode: '11', brewId: 'abcd', message: 'Invalid ID', name: 'ID Error', status: 404 });
|
||||||
|
});
|
||||||
|
|
||||||
it('should return id and google id from request body', ()=>{
|
it('should return id and google id from request body', ()=>{
|
||||||
const { id, googleId } = api.getId({
|
const { id, googleId } = api.getId({
|
||||||
params : {
|
params : {
|
||||||
id : 'abcdefgh'
|
id : 'abcdefghijkl'
|
||||||
},
|
},
|
||||||
body : {
|
body : {
|
||||||
googleId : '12345'
|
googleId : '123456789012345678901234567890123'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(id).toEqual('abcdefgh');
|
expect(id).toEqual('abcdefghijkl');
|
||||||
expect(googleId).toEqual('12345');
|
expect(googleId).toEqual('123456789012345678901234567890123');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw invalid - google id right length but does not match pattern', ()=>{
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
api.getId({
|
||||||
|
params : {
|
||||||
|
id : 'abcdefghijkl'
|
||||||
|
},
|
||||||
|
body : {
|
||||||
|
googleId : '012345678901234567890123456789012'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(err).toEqual({ HBErrorCode: '12', brewId: 'abcdefghijkl', message: 'Invalid ID', name: 'Google ID Error', status: 404 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw invalid - google id too short (32 char)', ()=>{
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
api.getId({
|
||||||
|
params : {
|
||||||
|
id : 'abcdefghijkl'
|
||||||
|
},
|
||||||
|
body : {
|
||||||
|
googleId : '12345678901234567890123456789012'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(err).toEqual({ HBErrorCode: '12', brewId: 'abcdefghijkl', message: 'Invalid ID', name: 'Google ID Error', status: 404 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw invalid - google id too long (45 char)', ()=>{
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
api.getId({
|
||||||
|
params : {
|
||||||
|
id : 'abcdefghijkl'
|
||||||
|
},
|
||||||
|
body : {
|
||||||
|
googleId : '123456789012345678901234567890123456789012345'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(err).toEqual({ HBErrorCode: '12', brewId: 'abcdefghijkl', message: 'Invalid ID', name: 'Google ID Error', status: 404 });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 12-char id and google id from params', ()=>{
|
it('should return 12-char id and google id from params', ()=>{
|
||||||
|
|||||||
@@ -5,21 +5,16 @@ import config from './config.js';
|
|||||||
const generateAccessToken = (account)=>{
|
const generateAccessToken = (account)=>{
|
||||||
const payload = account;
|
const payload = account;
|
||||||
|
|
||||||
// When the token was issued
|
payload.issued = (new Date()); // When the token was issued
|
||||||
payload.issued = (new Date());
|
payload.issuer = config.get('authentication_token_issuer'); // Which service issued the Token
|
||||||
// Which service issued the Token
|
payload.audience = config.get('authentication_token_audience'); // Which service is the token intended for
|
||||||
payload.issuer = config.get('authentication_token_issuer');
|
const secret = config.get('authentication_token_secret'); // The signing key for signing the token
|
||||||
// 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.password;
|
||||||
delete payload._id;
|
delete payload._id;
|
||||||
|
|
||||||
const secret = config.get('authentication_token_secret');
|
|
||||||
|
|
||||||
const token = jwt.encode(payload, secret);
|
const token = jwt.encode(payload, secret);
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default generateAccessToken;
|
export default generateAccessToken;
|
||||||
|
|||||||
27
server/token.spec.js
Normal file
27
server/token.spec.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { expect, jest } from '@jest/globals';
|
||||||
|
import config from './config.js';
|
||||||
|
|
||||||
|
import generateAccessToken from './token';
|
||||||
|
|
||||||
|
describe('Tests for Token', ()=>{
|
||||||
|
it('Get token', ()=>{
|
||||||
|
|
||||||
|
// Mock the Config module, so we aren't grabbing actual secrets for testing
|
||||||
|
jest.mock('./config.js');
|
||||||
|
config.get = jest.fn((param)=>{
|
||||||
|
// The requested key name will be reflected to the output
|
||||||
|
return param;
|
||||||
|
});
|
||||||
|
|
||||||
|
const account = {};
|
||||||
|
|
||||||
|
const token = generateAccessToken(account);
|
||||||
|
|
||||||
|
// If these tests fail, the config mock has failed
|
||||||
|
expect(account).toHaveProperty('issuer', 'authentication_token_issuer');
|
||||||
|
expect(account).toHaveProperty('audience', 'authentication_token_audience');
|
||||||
|
|
||||||
|
// Because the inputs are fixed, this JWT key should be static
|
||||||
|
expect(typeof token).toBe('string');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user