Parcourir la source

:construction: Successfully moved jwt into response headers and grabbed it on front end

tags/0.0.3^2
tomit4 il y a 3 ans
Parent
révision
adc4699286

+ 1
- 1
backend/lib/auth/strategies/jwt.js Voir le fichier

@@ -7,7 +7,7 @@ module.exports = options => {
7 7
             algorithms: ['HS256'],
8 8
         },
9 9
         validate: (decoded, request, h) => {
10
-            console.log('decoded :>>', decoded)
10
+            console.log('decoded :>>', decoded) // doesn't log to console...
11 11
             try {
12 12
                 // Check if the Access Token is Valid
13 13
                 // if (!accessTokenIsValid) {

+ 10
- 10
backend/lib/routes/user/getjwt.js Voir le fichier

@@ -19,19 +19,22 @@ module.exports = {
19 19
         ...pluginConfig.docs.get,
20 20
         tags: ['api'],
21 21
         auth: false,
22
-        cors: true,
22
+        cors: {
23
+            headers: ['Authorization'],
24
+            exposedHeaders: ['Authorization', 'Access-Control-Expose-Headers'],
25
+        },
23 26
         handler: async function (request, h) {
24 27
             const { userService } = request.server.services()
25 28
             const res = request.payload
26 29
             const token = await userService.createToken(res)
27
-            // TODO: Move logic adding initial three responses to here
28 30
             try {
29
-                // return h.state(token)
30
-                return {
31
+                const response = h.response({
31 32
                     ok: true,
32 33
                     handler: pluginConfig.handlerType,
33 34
                     data: token,
34
-                }
35
+                })
36
+                response.header('Authorization', token)
37
+                return response
35 38
             } catch (err) {
36 39
                 return {
37 40
                     ok: false,
@@ -46,11 +49,8 @@ module.exports = {
46 49
             failAction: 'log',
47 50
         },
48 51
         response: {
49
-            schema: Joi.object({
50
-                ok: Joi.bool(),
51
-                handler: Joi.string(),
52
-                data: Joi.string(),
53
-            }).label('get_jwt_res'),
52
+            // TODO: change back to accommodate new h.response return values
53
+            schema: Joi.any().label('get_jwt_res'),
54 54
             failAction: 'log',
55 55
         },
56 56
     },

+ 5
- 8
backend/lib/routes/user/validatesession.js Voir le fichier

@@ -1,5 +1,6 @@
1 1
 'use strict'
2 2
 
3
+const { plugin } = require('@hapi/inert')
3 4
 const Joi = require('joi')
4 5
 
5 6
 const pluginConfig = {
@@ -24,23 +25,19 @@ module.exports = {
24 25
         handler: async function (request, h) {
25 26
             const sessionToken = request.params.sessionToken
26 27
             const { userService } = request.server.services()
27
-            const sessionTokenIsValid = userService.validateToken(sessionToken)
28 28
             try {
29
+                const validatedSessionToken =
30
+                    userService.validateToken(sessionToken)
29 31
                 return {
30 32
                     ok: true,
31 33
                     handler: pluginConfig.handlerType,
32
-                    data: {
33
-                        isValid: sessionTokenIsValid.isValid,
34
-                        payload: sessionTokenIsValid.payload,
35
-                    },
34
+                    data: validatedSessionToken,
36 35
                 }
37 36
             } catch (err) {
38 37
                 return {
39 38
                     ok: false,
40 39
                     handler: pluginConfig.handlerType,
41
-                    data: {
42
-                        error: err,
43
-                    },
40
+                    data: err.message,
44 41
                 }
45 42
             }
46 43
         },

+ 7
- 11
backend/lib/services/user.js Voir le fichier

@@ -18,8 +18,8 @@ const hashEmail = async email => {
18 18
     try {
19 19
         return crypto.createHmac('sha256', '').update(email).digest('hex')
20 20
     } catch (err) {
21
-        console.error('ERROR :=>', err)
22
-        return undefined
21
+        // console.error('ERROR :=>', err)
22
+        throw new Error(err.message)
23 23
     }
24 24
 }
25 25
 const hasher = async (pwd, steak) => {
@@ -226,12 +226,12 @@ module.exports = class UserService extends Schmervice.Service {
226 226
     // createSessionToken(user, payload)
227 227
     // createAccessToken()
228 228
     //
229
-    createToken(user) {
229
+    createToken(data) {
230 230
         const key = this.server.registrations['main-app-plugin'].options.jwtKey
231 231
         const obj = {}
232 232
 
233
-        Object.assign(obj, { ...user })
234
-        return JWT.sign(obj, key)
233
+        Object.assign(obj, { ...data })
234
+        return JWT.sign(obj, key, { expiresIn: data.expires })
235 235
     }
236 236
 
237 237
     async registerSession(user, hashedEmail, token) {
@@ -254,15 +254,11 @@ module.exports = class UserService extends Schmervice.Service {
254 254
      * @returns {Token}
255 255
      */
256 256
     validateToken(token) {
257
-        console.log('token :=>', token)
258 257
         const key = this.server.registrations['main-app-plugin'].options.jwtKey
259 258
         try {
260
-            const decodedToken = JWT.verify(token, key)
261
-            console.log('decodedToken :=>', decodedToken)
262
-            return { isValid: true, payload: decodedToken }
259
+            return JWT.verify(token, key)
263 260
         } catch (err) {
264
-            console.error('ERROR :=>', err)
265
-            return { isValid: false, error: err.message }
261
+            throw new Error(err.message)
266 262
         }
267 263
     }
268 264
 

+ 1
- 2
frontend/src/components/onboarding/Auth.vue Voir le fichier

@@ -53,9 +53,8 @@ export default {
53 53
             await createProfileForUserId(newUserId, this.responses)
54 54
             const jwt = await this.authenticator.getJwt({
55 55
                 ...this.answered,
56
-                expiration: 60 * 10,
56
+                expires: 60 * 3,
57 57
             })
58
-            console.log('jwt :=>', jwt)
59 58
             document.cookie = `siimee_session=${jwt}; max-age=600; path=/; secure`
60 59
             await this.authenticator.sendAuthEmail(this.answered)
61 60
         } else {

+ 31
- 4
frontend/src/services/auth.service.js Voir le fichier

@@ -19,11 +19,38 @@ class Authenticator {
19 19
         const isVerified = await db.get(`/user/verify/${hashedEmail}`)
20 20
         return isVerified.hashesMatch
21 21
     }
22
+
22 23
     async getJwt(req) {
23
-        const jwt = await db.post('/user/getjwt', req)
24
-        // TODO: Move token into repsonse.headers
25
-        // return response.headers ?
26
-        return jwt
24
+        // TODO: Clean up, should be able to use TOJ's db.post function,
25
+        // may need custon db.postWithHeaders() func or something like that...
26
+        const response = await fetch('http://localhost:3001/api/user/getjwt', {
27
+            method: 'POST',
28
+            mode: 'cors',
29
+            cache: 'no-cache',
30
+            credentials: 'omit',
31
+            headers: {
32
+                'Content-Type': 'application/json',
33
+            },
34
+            redirect: 'manual',
35
+            referrerPolicy: 'no-referrer',
36
+            body: JSON.stringify({ payload: req, expires: 600 }),
37
+        }).then(response => {
38
+            return response
39
+        })
40
+        console.log('response.headers :=>', response.headers)
41
+        // TODO: consider cleaner way to convert headers into JS Object
42
+        const getHeaders = headers => {
43
+            const headerObj = {}
44
+            const keys = headers.keys()
45
+            let header = keys.next()
46
+            while (header.value) {
47
+                headerObj[header.value] = headers.get(header.value)
48
+                header = keys.next()
49
+            }
50
+            return headerObj
51
+        }
52
+        const headerObj = getHeaders(response.headers)
53
+        return headerObj['authorization']
27 54
     }
28 55
 
29 56
     async validateSession(sessionToken) {

+ 11
- 8
frontend/src/views/OnboardingView.vue Voir le fichier

@@ -70,21 +70,24 @@ export default {
70 70
         this.authenticator = new Authenticator()
71 71
         // TODO: Once tokens are coming through headers, refactor all of this into methods, etc.
72 72
         // TODO: Consider switch/case() depending on what tokens exist/are valid...
73
-        sessionToken = this.grabStoredCookie('siimee_session')
74
-        // if (!sessionToken) {
75
-        //     //
76
-        // }
77
-        // accessToken = this.grabStoredCookie('siimee_access_onboarding')
73
+        const sessionToken = this.grabStoredCookie('siimee_session')
74
+        if (!sessionToken) {
75
+            console.warn('WARNING :=> sessionToken not in stored Cookies')
76
+            this.goToStep(0)
77
+        }
78
+        // const accessToken = this.grabStoredCookie('siimee_access')
78 79
         // if (!accessToken) {
80
+        // check if sessionToken is valid jwt
79 81
         //     // blow up
80 82
         // }
81 83
         let sessionData
82 84
         if (sessionToken) {
83 85
             sessionData = await this.authenticator.validateSession(sessionToken)
86
+            console.log('sessionData :=>', sessionData)
84 87
         }
85
-        // if (sessionData.isValid && !accessToken) {
86
-        if (sessionData.isValid) {
87
-            this.userEmail = sessionData.payload.email
88
+        // if (sessionData && !accessToken) {
89
+        if (sessionData) {
90
+            this.userEmail = sessionData.email
88 91
             this.emailIsRegistered =
89 92
                 await this.authenticator.checkIfEmailIsRegistered(
90 93
                     this.userEmail,

+ 11
- 11
frontend/src/views/VerifyView.vue Voir le fichier

@@ -17,13 +17,14 @@ export default {
17 17
         const hashEmail = this.$route.params.email
18 18
 
19 19
         const hashesMatch = await this.authenticator.verifyAuthEmail(hashEmail)
20
+        const sessionToken = this.grabCookie('siimee_session')
20 21
         // TODO: Refactor, see methods below
21 22
         // if (!hashesMatch) {
22 23
         //     throw new Error('no record of hashed email in cache')
23 24
         //     this.$router.push('/onboarding')
24 25
         // }
26
+
25 27
         // TODO: THIS NEEDS TO BE SENT OVER TO verifyAuthEmail(hashEmail) in the headers
26
-        const sessionToken = this.grabCookie('siimee_session')
27 28
         // TODO: Refactor, see methods below
28 29
         // if (!sessionToken) {
29 30
         //     throw new Error('token doesn't exist)
@@ -32,15 +33,14 @@ export default {
32 33
 
33 34
         // TODO: Refactor to not nest, use try/catch/throw
34 35
         if (sessionToken) {
35
-            // NOTE: hits backend route and the backend route has to be /validateSession/
36
-            // if backend route succeeds, gives you access token
37
-            const accessToken = await this.authenticator.validateSession(
38
-                sessionToken,
39
-            )
40
-            // TODO: isValid logic needs to live on back end
41
-            if (accessToken.isValid && hashesMatch) {
42
-                // server needs to issue an ACCESS token here ( getToken() )
43
-                // const accessToken = await this.authenticator.getToken()
36
+            const validatedSessionToken =
37
+                await this.authenticator.validateSession(sessionToken)
38
+            if (validatedSessionToken && hashesMatch) {
39
+                // TODO: What payload does accessToken need in first param to getJwt?
40
+                const accessToken = await this.authenticator.getJwt({
41
+                    ...sessionToken,
42
+                    expires: 60 * 3,
43
+                })
44 44
                 document.cookie = `siimee_access=${accessToken}; max-age=600; path=/; secure`
45 45
                 this.$router.push('/onboarding')
46 46
             }
@@ -64,7 +64,7 @@ export default {
64 64
         async generateAccessToken() {
65 65
             const accessJwt = await this.authenticator.getJwt({
66 66
                 ...this.answers,
67
-                expiration: 60 * 3, // testing for now... extend to 1 hour?
67
+                expires: 60 * 3,
68 68
             })
69 69
             return accessJwt
70 70
         },

Chargement…
Annuler
Enregistrer