The existing terminology carries negative sentiment that can be interpreted in a racial or sense. Updating the name to have no potential for such a connection. Co-authored-by: Justin Rogers <justrog@gmail.com>
		
			
				
	
	
		
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { isEmpty } from 'lodash';
 | |
| 
 | |
| import { getUserById as _getUserById } from '../utils/user-stats';
 | |
| import {
 | |
|   getAccessTokenFromRequest,
 | |
|   errorTypes,
 | |
|   authHeaderNS
 | |
| } from '../utils/getSetAccessToken';
 | |
| import { homeLocation } from '../../../config/env';
 | |
| import { jwtSecret as _jwtSecret } from '../../../config/secrets';
 | |
| 
 | |
| import { wrapHandledError } from '../utils/create-handled-error';
 | |
| 
 | |
| const authRE = /^\/auth\//;
 | |
| const confirmEmailRE = /^\/confirm-email$/;
 | |
| const newsShortLinksRE = /^\/n\/|^\/p\//;
 | |
| const publicUserRE = /^\/api\/users\/get-public-profile$/;
 | |
| const publicUsernameRE = /^\/api\/users\/exists$/;
 | |
| const resubscribeRE = /^\/resubscribe\//;
 | |
| const showCertRE = /^\/certificate\/showCert\//;
 | |
| // note: signin may not have a trailing slash
 | |
| const signinRE = /^\/signin/;
 | |
| const statusRE = /^\/status\/ping$/;
 | |
| const unsubscribedRE = /^\/unsubscribed\//;
 | |
| const unsubscribeRE = /^\/u\/|^\/unsubscribe\/|^\/ue\//;
 | |
| const updateHooksRE = /^\/hooks\/update-paypal$|^\/hooks\/update-stripe$/;
 | |
| 
 | |
| // note: this would be replaced by webhooks later
 | |
| const donateRE = /^\/donate\/charge-stripe$/;
 | |
| 
 | |
| const _pathsAllowedREs = [
 | |
|   authRE,
 | |
|   confirmEmailRE,
 | |
|   newsShortLinksRE,
 | |
|   publicUserRE,
 | |
|   publicUsernameRE,
 | |
|   resubscribeRE,
 | |
|   showCertRE,
 | |
|   signinRE,
 | |
|   statusRE,
 | |
|   unsubscribedRE,
 | |
|   unsubscribeRE,
 | |
|   updateHooksRE,
 | |
|   donateRE
 | |
| ];
 | |
| 
 | |
| export function isAllowedPath(path, pathsAllowedREs = _pathsAllowedREs) {
 | |
|   return pathsAllowedREs.some(re => re.test(path));
 | |
| }
 | |
| 
 | |
| export default ({ jwtSecret = _jwtSecret, getUserById = _getUserById } = {}) =>
 | |
|   function requestAuthorisation(req, res, next) {
 | |
|     const { path } = req;
 | |
|     if (!isAllowedPath(path)) {
 | |
|       const { accessToken, error, jwt } = getAccessTokenFromRequest(
 | |
|         req,
 | |
|         jwtSecret
 | |
|       );
 | |
|       if (!accessToken && error === errorTypes.noTokenFound) {
 | |
|         throw wrapHandledError(
 | |
|           new Error('Access token is required for this request'),
 | |
|           {
 | |
|             type: 'info',
 | |
|             redirect: `${homeLocation}/signin`,
 | |
|             message: 'Access token is required for this request',
 | |
|             status: 403
 | |
|           }
 | |
|         );
 | |
|       }
 | |
|       if (!accessToken && error === errorTypes.invalidToken) {
 | |
|         throw wrapHandledError(new Error('Access token is invalid'), {
 | |
|           type: 'info',
 | |
|           redirect: `${homeLocation}/signin`,
 | |
|           message: 'Your access token is invalid',
 | |
|           status: 403
 | |
|         });
 | |
|       }
 | |
|       if (!accessToken && error === errorTypes.expiredToken) {
 | |
|         throw wrapHandledError(new Error('Access token is no longer valid'), {
 | |
|           type: 'info',
 | |
|           redirect: `${homeLocation}/signin`,
 | |
|           message: 'Access token is no longer valid',
 | |
|           status: 403
 | |
|         });
 | |
|       }
 | |
|       res.set(authHeaderNS, jwt);
 | |
|       if (isEmpty(req.user)) {
 | |
|         const { userId } = accessToken;
 | |
|         return getUserById(userId)
 | |
|           .then(user => {
 | |
|             if (user) {
 | |
|               req.user = user;
 | |
|             }
 | |
|             return;
 | |
|           })
 | |
|           .then(next)
 | |
|           .catch(next);
 | |
|       } else {
 | |
|         return Promise.resolve(next());
 | |
|       }
 | |
|     }
 | |
|     return Promise.resolve(next());
 | |
|   };
 |