| 
									
										
										
										
											2018-05-24 12:19:51 +01:00
										 |  |  | import loopback from 'loopback'; | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  | import jwt from 'jsonwebtoken'; | 
					
						
							|  |  |  | import { isBefore } from 'date-fns'; | 
					
						
							| 
									
										
										
										
											2018-05-24 12:19:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-31 16:04:04 +01:00
										 |  |  | import { homeLocation } from '../../../config/env'; | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  | import { wrapHandledError } from '../utils/create-handled-error'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-29 12:12:15 +00:00
										 |  |  | // We need to tunnel through a proxy path set up within
 | 
					
						
							|  |  |  | // the gatsby app, at this time, that path is /internal
 | 
					
						
							|  |  |  | const whiteListRE = new RegExp([ | 
					
						
							|  |  |  |   '^/internal/n/', | 
					
						
							|  |  |  |   '^/internal/p\??' | 
					
						
							|  |  |  | ].join('|')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  | export default () => function authorizeByJWT(req, res, next) { | 
					
						
							|  |  |  |   const path = req.path.split('/')[1]; | 
					
						
							| 
									
										
										
										
											2018-11-29 12:12:15 +00:00
										 |  |  |   if (/^external$|^internal$/.test(path) && !whiteListRE.test(req.path)) { | 
					
						
							| 
									
										
										
										
											2018-05-24 12:19:51 +01:00
										 |  |  |     const cookie = req.signedCookies && req.signedCookies['jwt_access_token'] || | 
					
						
							|  |  |  |       req.cookie && req.cookie['jwt_access_token']; | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  |     if (!cookie) { | 
					
						
							|  |  |  |       throw wrapHandledError( | 
					
						
							|  |  |  |         new Error('Access token is required for this request'), | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           type: 'info', | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  |           redirect: `${homeLocation}/signin`, | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  |           message: 'Access token is required for this request', | 
					
						
							|  |  |  |           status: 403 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     let token; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       token = jwt.verify(cookie, process.env.JWT_SECRET); | 
					
						
							|  |  |  |     } catch (err) { | 
					
						
							|  |  |  |       throw wrapHandledError( | 
					
						
							|  |  |  |         new Error(err.message), | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           type: 'info', | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  |           redirect: `${homeLocation}/signin`, | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  |           message: 'Your access token is invalid', | 
					
						
							|  |  |  |           status: 403 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-24 12:19:51 +01:00
										 |  |  |     const { accessToken: {created, ttl, userId }} = token; | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  |     const valid = isBefore(Date.now(), Date.parse(created) + ttl); | 
					
						
							|  |  |  |     if (!valid) { | 
					
						
							|  |  |  |       throw wrapHandledError( | 
					
						
							|  |  |  |         new Error('Access token is no longer vaild'), | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           type: 'info', | 
					
						
							| 
									
										
										
										
											2018-08-29 20:52:41 +01:00
										 |  |  |           redirect: `${homeLocation}/signin`, | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  |           message: 'Access token is no longer vaild', | 
					
						
							|  |  |  |           status: 403 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-24 12:19:51 +01:00
										 |  |  |     if (!req.user) { | 
					
						
							|  |  |  |       const User = loopback.getModelByType('User'); | 
					
						
							|  |  |  |       return User.findById(userId) | 
					
						
							|  |  |  |       .then(user => { | 
					
						
							|  |  |  |         if (user) { | 
					
						
							| 
									
										
										
										
											2018-05-24 16:58:00 +01:00
										 |  |  |           user.points = user.progressTimestamps.length; | 
					
						
							| 
									
										
										
										
											2018-05-24 12:19:51 +01:00
										 |  |  |           req.user = user; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .then(next) | 
					
						
							|  |  |  |       .catch(next); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return next(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-23 21:10:56 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return next(); | 
					
						
							|  |  |  | }; |