|
|
@@ -45,26 +45,7 @@ import stepViews from '@/components/onboarding'
|
|
45
|
45
|
import SurveyCompleteView from './SurveyCompleteView.vue'
|
|
46
|
46
|
let sessionToken = null
|
|
47
|
47
|
let accessToken = null
|
|
48
|
|
-
|
|
49
|
|
-/* BRIAN'S NOTE:
|
|
50
|
|
-I'll need help here. The logic is getting confusing.
|
|
51
|
|
-
|
|
52
|
|
- 1. Right now both a session and access token are issued
|
|
53
|
|
- (session via Auth.vue, access from VerifyView.vue).
|
|
54
|
|
-
|
|
55
|
|
- 2. There is also a hashedEmail object on the backend's app state:
|
|
56
|
|
- {
|
|
57
|
|
- hashedEmailString: expiration_in_milliseconds,
|
|
58
|
|
- anotherhashedEmailString: expiration_in_milliseconds,
|
|
59
|
|
- }
|
|
60
|
|
-
|
|
61
|
|
- TODO: jwt, hashedEmail, cookie expiration should be the same
|
|
62
|
|
- 3. The session, access tokens all have jwt expirations as well as cookie expirations
|
|
63
|
|
-
|
|
64
|
|
- 4. Additionally, we have an expiration on each hashedEmail string...
|
|
65
|
|
- 5. All the data points to check are here...
|
|
66
|
|
- I just can't quite think straight as of 07/09/2023 at 01:53:22
|
|
67
|
|
-*/
|
|
|
48
|
+let currentProfileId = null
|
|
68
|
49
|
|
|
69
|
50
|
export default {
|
|
70
|
51
|
name: 'OnboardingView',
|
|
|
@@ -77,68 +58,34 @@ export default {
|
|
77
|
58
|
aspectQuestions: [],
|
|
78
|
59
|
responses: [],
|
|
79
|
60
|
currentStep: 0,
|
|
80
|
|
- currentProfileId: null,
|
|
81
|
61
|
survey: null,
|
|
82
|
62
|
invalidResponse: false,
|
|
83
|
|
- userEmail: null,
|
|
84
|
|
- emailIsRegistered: false,
|
|
85
|
63
|
authenticator: {},
|
|
86
|
64
|
}),
|
|
87
|
65
|
async created() {
|
|
88
|
66
|
this.survey = await surveyFactory.createSurvey()
|
|
89
|
67
|
this.authenticator = new Authenticator()
|
|
90
|
|
- // TODO: Once tokens are coming through headers, refactor all of this into methods, etc.
|
|
91
|
|
- // TODO: Consider switch/case() depending on what tokens exist/are valid...
|
|
92
|
|
- const sessionToken = this.grabStoredCookie('siimee_session')
|
|
93
|
|
- if (!sessionToken) {
|
|
94
|
|
- console.warn('WARNING :=> sessionToken not in stored Cookies')
|
|
95
|
|
- this.goToStep(0)
|
|
96
|
|
- }
|
|
97
|
|
- // const accessToken = this.grabStoredCookie('siimee_access')
|
|
98
|
|
- // if (!accessToken) {
|
|
99
|
|
- // check if sessionToken is valid jwt
|
|
100
|
|
- // // blow up
|
|
101
|
|
- // }
|
|
102
|
|
- let sessionData
|
|
103
|
|
- if (sessionToken) {
|
|
104
|
|
- sessionData = await this.authenticator.validateSession(sessionToken)
|
|
105
|
|
- console.log('sessionData :=>', sessionData)
|
|
106
|
|
- }
|
|
107
|
|
- // if (sessionData && !accessToken) {
|
|
108
|
|
- if (sessionData) {
|
|
109
|
|
- this.userEmail = sessionData.payload.email
|
|
110
|
|
- this.emailIsRegistered =
|
|
111
|
|
- // QUESTION: Would this logic also be needed in VerifyView??
|
|
112
|
|
- await this.authenticator.checkIfEmailIsRegistered(
|
|
113
|
|
- this.userEmail,
|
|
114
|
|
- )
|
|
115
|
|
- }
|
|
116
|
|
- // TODO: EVERY ROUTE WE HIT AFTER THIS HAS TO BE AUTHENTICATED
|
|
117
|
|
- // ACCESS TOKEN WORKS
|
|
118
|
|
- // START PROTECTING ALL ROUTES
|
|
119
|
|
- if (this.emailIsRegistered) {
|
|
120
|
|
- const user = await fetchUserByEmail(this.userEmail)
|
|
121
|
|
- const userId = user.user_id
|
|
122
|
|
- const profilesFromUserId = await fetchProfilesByUserId(userId)
|
|
123
|
|
- let profileId
|
|
124
|
|
- if (profilesFromUserId.length === 1) {
|
|
125
|
|
- profileId = profilesFromUserId[0].profile_id
|
|
126
|
|
- this.currentProfileId = profileId
|
|
127
|
|
- }
|
|
128
|
|
- // if (!profileId) {
|
|
129
|
|
- // throw new Error
|
|
130
|
|
- // }
|
|
131
|
|
- const profile = await fetchProfileByProfileId(profileId)
|
|
132
|
|
- profile.responses.forEach(response => {
|
|
133
|
|
- this.responses.push({
|
|
134
|
|
- response_key_id: response.response_key_id,
|
|
135
|
|
- val: response.val,
|
|
136
|
|
- })
|
|
137
|
|
- })
|
|
|
68
|
+ // TODO: Note that all this try/catch can be in a function instead,
|
|
|
69
|
+ // since it has to be done on created() and every step after 6...
|
|
|
70
|
+ sessionToken = this.grabStoredCookie('siimee_session')
|
|
|
71
|
+ accessToken = this.grabStoredCookie('siimee_access')
|
|
|
72
|
+ try {
|
|
|
73
|
+ await this.verifySessionToken(sessionToken)
|
|
|
74
|
+ const sessionData = await this.verifyAccessToken(accessToken)
|
|
|
75
|
+ await this.isEmailInRegistry(sessionData.payload.email)
|
|
|
76
|
+ const userId = await this.grabUserIdByEmail(
|
|
|
77
|
+ sessionData.payload.email,
|
|
|
78
|
+ )
|
|
|
79
|
+ const profileId = await this.grabProfileIdByUserId(userId)
|
|
|
80
|
+ // TODO: consider different implementation once
|
|
|
81
|
+ // updateAnswers() no longer relies on this
|
|
|
82
|
+ currentProfileId = profileId
|
|
|
83
|
+ this.responses = await this.grabResponsesByProfileId(profileId)
|
|
138
|
84
|
this.currentStep = this.responses.length + 3
|
|
139
|
85
|
this.goToStep(this.currentStep)
|
|
140
|
|
- } else {
|
|
141
|
|
- // TODO: CHECK SESSION
|
|
|
86
|
+ } catch (err) {
|
|
|
87
|
+ console.error('ERROR :=>', err)
|
|
|
88
|
+ this.goToStep(0)
|
|
142
|
89
|
}
|
|
143
|
90
|
},
|
|
144
|
91
|
methods: {
|
|
|
@@ -160,6 +107,75 @@ export default {
|
|
160
|
107
|
cookieKey in cookies ? cookies[`${cookieKey}`] : undefined
|
|
161
|
108
|
return cookieVal
|
|
162
|
109
|
},
|
|
|
110
|
+ async verifySessionToken(sessionToken) {
|
|
|
111
|
+ if (!sessionToken) {
|
|
|
112
|
+ console.warn('WARNING :=> sessionToken is not defined')
|
|
|
113
|
+ } else return await this.validateToken(sessionToken)
|
|
|
114
|
+ },
|
|
|
115
|
+ async verifyAccessToken(accessToken) {
|
|
|
116
|
+ if (!accessToken) {
|
|
|
117
|
+ console.warn('WARNING :=> accessToken is not defined')
|
|
|
118
|
+ } else return await this.validateToken(accessToken)
|
|
|
119
|
+ },
|
|
|
120
|
+ async validateToken(token) {
|
|
|
121
|
+ const validatedToken = await this.authenticator.validateSession(
|
|
|
122
|
+ token,
|
|
|
123
|
+ )
|
|
|
124
|
+ if (validatedToken.error) {
|
|
|
125
|
+ throw new Error(validatedToken.error)
|
|
|
126
|
+ } else {
|
|
|
127
|
+ return validatedToken
|
|
|
128
|
+ }
|
|
|
129
|
+ },
|
|
|
130
|
+ async isEmailInRegistry(email) {
|
|
|
131
|
+ const emailIsInRegistry =
|
|
|
132
|
+ await this.authenticator.checkIfEmailIsRegistered(email)
|
|
|
133
|
+ if (!emailIsInRegistry) {
|
|
|
134
|
+ throw new Error('Email Is NOT in Registry!')
|
|
|
135
|
+ } else return emailIsInRegistry // true
|
|
|
136
|
+ },
|
|
|
137
|
+ async grabUserIdByEmail(email) {
|
|
|
138
|
+ const user = await fetchUserByEmail(email)
|
|
|
139
|
+ if (!user) {
|
|
|
140
|
+ throw new Error('User NOT found by email')
|
|
|
141
|
+ } else return user.user_id
|
|
|
142
|
+ },
|
|
|
143
|
+ async grabProfileIdByUserId(userId) {
|
|
|
144
|
+ const profilesFromUserId = await fetchProfilesByUserId(userId)
|
|
|
145
|
+ if (profilesFromUserId.length === 1) {
|
|
|
146
|
+ return profilesFromUserId[0].profile_id
|
|
|
147
|
+ } else {
|
|
|
148
|
+ // TODO: Refactor once more is known on users with multiple profiles
|
|
|
149
|
+ console.error(
|
|
|
150
|
+ 'ERROR :=> Multiple Profiles for this User ID',
|
|
|
151
|
+ profilesFromUserId,
|
|
|
152
|
+ )
|
|
|
153
|
+ throw new Error('Multiple Profiles for this User ID')
|
|
|
154
|
+ }
|
|
|
155
|
+ },
|
|
|
156
|
+ async grabProfileByProfileId(profileId) {
|
|
|
157
|
+ const profile = await fetchProfileByProfileId(profileId)
|
|
|
158
|
+ if (!profile) {
|
|
|
159
|
+ throw new Error(`No Profile Found for profileId ${profileId}`)
|
|
|
160
|
+ } else {
|
|
|
161
|
+ return profile
|
|
|
162
|
+ }
|
|
|
163
|
+ },
|
|
|
164
|
+ async grabResponsesByProfileId(profileId) {
|
|
|
165
|
+ const responses = []
|
|
|
166
|
+ const profile = await this.grabProfileByProfileId(profileId)
|
|
|
167
|
+ if (!profile.responses.length) {
|
|
|
168
|
+ throw new Error(`No Responses Found for profileId ${profileId}`)
|
|
|
169
|
+ } else {
|
|
|
170
|
+ profile.responses.forEach(response => {
|
|
|
171
|
+ responses.push({
|
|
|
172
|
+ response_key_id: response.response_key_id,
|
|
|
173
|
+ val: response.val,
|
|
|
174
|
+ })
|
|
|
175
|
+ })
|
|
|
176
|
+ return responses
|
|
|
177
|
+ }
|
|
|
178
|
+ },
|
|
163
|
179
|
async updateAnswers(payload) {
|
|
164
|
180
|
if (payload) {
|
|
165
|
181
|
// this.invalidResponse = false
|
|
|
@@ -183,7 +199,7 @@ export default {
|
|
183
|
199
|
console.log('this.responses :=>', this.responses)
|
|
184
|
200
|
|
|
185
|
201
|
// sends latest survey response to db
|
|
186
|
|
- if (this.currentProfileId) {
|
|
|
202
|
+ if (currentProfileId) {
|
|
187
|
203
|
surveyFactory.addNewSurveyAnswer(
|
|
188
|
204
|
this.responses[this.responses.length - 1],
|
|
189
|
205
|
this.currentProfileId,
|