Преглед изворни кода

:construction: Closer and closer still to finalizing auth

tags/0.0.3^2
tomit4 пре 3 година
родитељ
комит
389d3fd836

+ 5
- 1
backend/lib/routes/user/create-profile.js Прегледај датотеку

@@ -67,10 +67,14 @@ module.exports = {
67 67
                 }
68 68
                 /** Grab payload info */
69 69
                 const res = request.payload
70
+                /** Don't log password in response table */
71
+                const resWithoutPass = res.filter(r => {
72
+                    return r.response_key_id !== 9
73
+                })
70 74
                 const profile =
71 75
                     await profileService.saveResponsesCreateProfileFor(
72 76
                         userId,
73
-                        res,
77
+                        resWithoutPass,
74 78
                     )
75 79
                 return h
76 80
                     .response({

+ 1
- 1
backend/lib/services/user.js Прегледај датотеку

@@ -206,6 +206,7 @@ module.exports = class UserService extends Schmervice.Service {
206 206
                 email: user.email,
207 207
                 name: user.name,
208 208
                 seeking: user.seeking,
209
+                profile_id: user.profile_id,
209 210
             },
210 211
             {
211 212
                 key: key,
@@ -227,7 +228,6 @@ module.exports = class UserService extends Schmervice.Service {
227 228
     validateToken(token) {
228 229
         const key = this.server.registrations['main-app-plugin'].options.jwtKey
229 230
         const decodedToken = Jwt.token.decode(token)
230
-        console.log('decodedToken :=>', decodedToken)
231 231
         // NOTE: reveals email...perhaps unhashed email belongs here instead...
232 232
         try {
233 233
             Jwt.token.verify(decodedToken, key)

+ 19
- 13
frontend/src/components/onboarding/Auth.vue Прегледај датотеку

@@ -34,30 +34,36 @@ export default {
34 34
             default: () => {},
35 35
         },
36 36
     },
37
-    emits: ['update-answers', 'set-pid'],
37
+    emits: ['update-answers'],
38 38
     data: () => ({
39 39
         authenticator: {},
40 40
     }),
41 41
     async created() {
42
-        // establishes new user and emits it up to onboarding for login purposes
42
+        // Establishes New User And Sends Auth Email
43 43
         this.authenticator = new Authenticator()
44
-        if (this.survey.hasMinResponsesToCreateProfile(this.answered)) {
45
-            const newUser = await signupUser(this.answered)
44
+        if (this.survey.hasMinResponsesToCreateProfile(this.responses)) {
45
+            const userPass = this.responses.find(
46
+                response => response.response_key_id === 9,
47
+            )
48
+            const newUser = await signupUser({
49
+                ...this.answered,
50
+                password: userPass.val,
51
+            })
46 52
             const newUserId = newUser.user_id
47
-            await createProfileForUserId(newUserId, this.responses)
53
+            const newProfile = await createProfileForUserId(
54
+                newUserId,
55
+                this.responses,
56
+            )
48 57
             const jwt = await this.authenticator.generateJwt({
49 58
                 ...this.answered,
50 59
                 expiration: 60 * 10,
60
+                profile_id: newProfile.profile_id,
51 61
             })
52
-            document.cookie = `siimee_jwt=${jwt}; path=/verify`
62
+            document.cookie = `siimee_jwt=${jwt}; path=/verify; secure`
63
+            await this.authenticator.sendAuthEmail(this.answered)
64
+        } else {
65
+            console.error('ERROR :=>')
53 66
         }
54
-
55
-        // sets jwt authentication cookie to be used in VerifyView.vue and
56
-        // OnboardingView.vue
57
-        // TODO: Instead of having this.answered here, simply pass profile_id?
58
-
59
-        // sends authentication email
60
-        await this.authenticator.sendAuthEmail(this.answered)
61 67
     },
62 68
     methods: {
63 69
         // TODO: remove test button above and use a watcher instead to emit this

+ 7
- 8
frontend/src/entities/survey/survey.js Прегледај датотеку

@@ -44,14 +44,13 @@ class Survey extends _baseRecord {
44 44
     }
45 45
 
46 46
     hasMinResponsesToCreateProfile(responses) {
47
-        if (
48
-            responses.name &&
49
-            responses.email &&
50
-            responses.seeking &&
51
-            responses.password
52
-        ) {
53
-            return true
54
-        } else return false
47
+        const neededResponseKeys = [8, 7, 11, 9]
48
+        const hasNeededResponseKey = responses => {
49
+            return responses.every(response => {
50
+                neededResponseKeys.includes(response.response_key_id)
51
+            })
52
+        }
53
+        return hasNeededResponseKey
55 54
     }
56 55
 
57 56
     validateAnswer(payload) {

+ 31
- 41
frontend/src/views/OnboardingView.vue Прегледај датотеку

@@ -18,7 +18,6 @@ main.view--onboarding
18 18
                 :surveyStepsCount='survey.steps.length'
19 19
                 @handle-submit='onSubmit'
20 20
                 @update-answers='updateAnswers'
21
-                @set-pid='setPid'
22 21
                 v-if='step && currentStep == i'
23 22
             ) 
24 23
         .invalidResponseMessage(
@@ -31,7 +30,7 @@ main.view--onboarding
31 30
             p(v-if='currentStep != 0') You have completed: {{ currentStep }} / {{ survey.steps.length }} survey steps
32 31
 
33 32
     article(v-else)
34
-        SurveyCompleteView(:answers='answered' :surveySteps='survey.steps')
33
+        SurveyCompleteView(:answers='answered' :surveySteps='survey.steps' :currentProfileId='currentProfileId')
35 34
 </template>
36 35
 
37 36
 <script>
@@ -57,15 +56,14 @@ export default {
57 56
         survey: null,
58 57
         currentProfileId: null,
59 58
         invalidResponse: false,
60
-        // TODO: CURRENTLY WORKING ON**
61 59
         authenticator: {},
62 60
         sessionToken: '',
63 61
         accessToken: '',
64 62
     }),
65 63
     computed: {
66
-        // NOTE: perhaps start this off as returning nothing
67
-        // and then add currentProfile in created()?
68
-        profile: () => currentProfile,
64
+        cP() {
65
+            return currentProfile ? currentProfile : null
66
+        },
69 67
     },
70 68
     async created() {
71 69
         this.survey = await surveyFactory.createSurvey()
@@ -74,25 +72,34 @@ export default {
74 72
         if (document.cookie.length) {
75 73
             // TODO: Remove this this.answered section when:
76 74
             // SurveyCompleteView calls all responses from db
77
-            // BUG: NEEDS BROWSER REFRESH TO BE HIT
78
-            const siimeeAnswers = JSON.parse(
79
-                this.grabCookie(document.cookie, 'siimee_answered'),
80
-            )
81
-            this.sessionToken = this.grabCookie(
75
+            // BUG: NEEDS BROWSER REFRESH TO SEE UPDATED COOKIES
76
+            const siimeeAnswered = this.grabCookie(
82 77
                 document.cookie,
83
-                'siimee_session',
84
-            )
85
-            const sessionTokenIsValid = await this.authenticator.validateJwt(
86
-                this.sessionToken,
78
+                'siimee_answered',
87 79
             )
88
-            this.accessToken = this.grabCookie(document.cookie, 'siimee_access')
89
-            if (sessionTokenIsValid.isValid) {
90
-                this.answered = {
91
-                    name: siimeeAnswers.name,
92
-                    email: siimeeAnswers.email,
93
-                    seeking: siimeeAnswers.seeking,
80
+            if (siimeeAnswered) {
81
+                const siimeeAnswers = JSON.parse(
82
+                    this.grabCookie(document.cookie, 'siimee_answered'),
83
+                )
84
+                this.sessionToken = this.grabCookie(
85
+                    document.cookie,
86
+                    'siimee_session',
87
+                )
88
+                const sessionTokenIsValid =
89
+                    await this.authenticator.validateJwt(this.sessionToken)
90
+                this.accessToken = this.grabCookie(
91
+                    document.cookie,
92
+                    'siimee_access',
93
+                )
94
+                if (sessionTokenIsValid.isValid) {
95
+                    this.answered = {
96
+                        name: siimeeAnswers.name,
97
+                        email: siimeeAnswers.email,
98
+                        seeking: siimeeAnswers.seeking,
99
+                    }
100
+                    this.currentProfileId = siimeeAnswers.profile_id
101
+                    this.goToStep(6)
94 102
                 }
95
-                this.goToStep(6)
96 103
             } else this.goToStep(0)
97 104
         }
98 105
     },
@@ -106,6 +113,7 @@ export default {
106 113
             }
107 114
             this.currentStep = num
108 115
         },
116
+        // TODO: Refactor to use cookie's max-age attribute instead of network call for jwt auth
109 117
         async validateAccessToken() {
110 118
             const validatedAccessToken = await this.authenticator.validateJwt(
111 119
                 this.accessToken,
@@ -138,7 +146,6 @@ export default {
138 146
             return cookieKey in cookies ? cookies[`${cookieKey}`] : undefined
139 147
         },
140 148
         async updateAnswers(payload) {
141
-            // null payload is passed on splash page
142 149
             if (payload) {
143 150
                 // this.invalidResponse = false
144 151
                 const k = payload.question.survey_stage
@@ -150,7 +157,7 @@ export default {
150 157
                 }
151 158
 
152 159
                 // once validated, don't log password in answered object
153
-                // this.answered[k] = k === 'password' ? undefined : payload.input
160
+                this.answered[k] = k === 'password' ? undefined : payload.input
154 161
 
155 162
                 // formats initial responses for response table
156 163
                 const response = {}
@@ -174,23 +181,6 @@ export default {
174 181
                 this.goToStep(this.currentStep + 1)
175 182
             }
176 183
         },
177
-        // NOTE: Brought in from App.vue, might not be necessary...
178
-        // Allows for login after initial email sign up is set
179
-        async setPid(profileId) {
180
-            if (currentProfile.isLoggedIn) {
181
-                currentProfile.logout()
182
-            }
183
-            // ERROR: this._profile is undefinedin login service
184
-            this.profile.id = await currentProfile.login(
185
-                profileId,
186
-                this.$waveui.notify,
187
-            )
188
-            console.log('---')
189
-
190
-            // Change if survey isn't complete...
191
-            // const toRoute = { name: 'HomeView' }
192
-            // this.$router.push(toRoute)
193
-        },
194 184
     },
195 185
 }
196 186
 </script>

+ 7
- 6
frontend/src/views/VerifyView.vue Прегледај датотеку

@@ -5,6 +5,9 @@
5 5
 </template>
6 6
 
7 7
 <script>
8
+// NOTE: If the httponly flag is to be used with these cookies,
9
+// this file will need to be rewritten as an .html file due to the way
10
+// that Hapi sets cookies via the h.state() method
8 11
 import { Authenticator } from '../services/auth.service.js'
9 12
 export default {
10 13
     name: 'VerifyView',
@@ -17,7 +20,7 @@ export default {
17 20
         const hashEmail = this.$route.params.email
18 21
 
19 22
         // TODO: generate a token on the backend here and have it sent over in
20
-        // the headers intead of setting it directly with document.cookie
23
+        // the headers intead of setting it directly with document.cookie (see note above)
21 24
 
22 25
         const hashesMatch = await this.authenticator.verifyAuthEmail(hashEmail)
23 26
         const siimeeToken = this.grabToken(document.cookie)
@@ -27,12 +30,10 @@ export default {
27 30
         this.answers = jwt.payload
28 31
         const accessToken = await this.generateAccessToken()
29 32
         if (jwt.isValid && hashesMatch) {
30
-            // TODO: establish session access token cookie here
31 33
             const siimeeAnswers = JSON.stringify(this.answers)
32
-            document.cookie = `siimee_answered=${siimeeAnswers} ; path=/onboarding; secure`
33
-            // TODO: for session/access cookies, make sure to set http only flag and expiration
34
-            document.cookie = `siimee_session=${siimeeToken} ; path=/onboarding; secure`
35
-            document.cookie = `siimee_access=${accessToken}; path=/onboarding; secure`
34
+            document.cookie = `siimee_answered=${siimeeAnswers}; max-age=360 ; path=/onboarding; secure`
35
+            document.cookie = `siimee_session=${siimeeToken} ; max-age=360 ; path=/onboarding; secure`
36
+            document.cookie = `siimee_access=${accessToken}; max-age=360 ; path=/onboarding; secure`
36 37
             this.$router.push('/onboarding')
37 38
         }
38 39
         // else {

Loading…
Откажи
Сачувај