mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 16:22:44 +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.`,
|
||||
|
||||
// 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
|
||||
'50' : dedent`
|
||||
## 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 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 };
|
||||
},
|
||||
//Get array of any of this user's brews tagged with `meta:theme`
|
||||
|
||||
@@ -99,18 +99,87 @@ describe('Tests for api', ()=>{
|
||||
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', ()=>{
|
||||
const { id, googleId } = api.getId({
|
||||
params : {
|
||||
id : 'abcdefgh'
|
||||
id : 'abcdefghijkl'
|
||||
},
|
||||
body : {
|
||||
googleId : '12345'
|
||||
googleId : '123456789012345678901234567890123'
|
||||
}
|
||||
});
|
||||
|
||||
expect(id).toEqual('abcdefgh');
|
||||
expect(googleId).toEqual('12345');
|
||||
expect(id).toEqual('abcdefghijkl');
|
||||
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', ()=>{
|
||||
|
||||
@@ -5,21 +5,16 @@ import config from './config.js';
|
||||
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
|
||||
payload.issued = (new Date()); // When the token was issued
|
||||
payload.issuer = config.get('authentication_token_issuer'); // Which service issued the Token
|
||||
payload.audience = config.get('authentication_token_audience'); // Which service is the token intended for
|
||||
const secret = config.get('authentication_token_secret'); // The signing key for signing the token
|
||||
|
||||
delete payload.password;
|
||||
delete payload._id;
|
||||
|
||||
const secret = config.get('authentication_token_secret');
|
||||
|
||||
const token = jwt.encode(payload, secret);
|
||||
|
||||
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