Explorar el Código

:recycle: fixing login form | returning profiles for user from api | logging in before setting profile_id

jwt
j hace 3 años
padre
commit
c6b060a8ad

+ 18
- 10
backend/lib/routes/user/login.js Ver fichero

@@ -45,9 +45,9 @@ module.exports = {
45 45
         ...pluginConfig.opts,
46 46
         handler: async function (request, h) {
47 47
             try {
48
-                const { userService } = request.services()
48
+                const { userService, profileService } =
49
+                    request.server.services()
49 50
                 const res = request.payload
50
-
51 51
                 // Callback to use as transaction
52 52
                 const login = async txn => {
53 53
                     return await userService.login(
@@ -60,18 +60,25 @@ module.exports = {
60 60
                 }
61 61
 
62 62
                 // Bound context from your plugin server declaration
63
-                const user = await h.context.transaction(login)
64
-
65
-                const token = userService.createToken(user)
66
-
63
+                const userAuth = await h.context.transaction(login)
64
+                const token = userService.createToken(userAuth)
67 65
                 const response = h.response('success')
68
-                console.log('response :>> ', response)
69
-                response.header('Authorization', token)
70
-                response.state('token', token, pluginConfig.cookieOpts)
66
+
67
+                const email = userAuth.user_email
68
+                const user = await userService.findByEmail(email)
69
+                const type = user.is_poster == 1 ? 'poster' : 'seeker'
70
+                const profiles = await profileService.getCompleteProfilesFor(
71
+                    user.user_id,
72
+                    type,
73
+                )
71 74
                 return {
72 75
                     ok: true,
73 76
                     handler: pluginConfig.handlerType,
74
-                    data: { user_email: user.user_email, jwtToken: token },
77
+                    data: {
78
+                        profiles,
79
+                        user_email: user.user_email,
80
+                        jwtToken: token,
81
+                    },
75 82
                 }
76 83
             } catch (err) {
77 84
                 console.error(err)
@@ -91,6 +98,7 @@ module.exports = {
91 98
                     data: Joi.object({
92 99
                         user_email: Joi.string(),
93 100
                         jwtToken: Joi.string(),
101
+                        profiles: Joi.array(),
94 102
                     }),
95 103
                 }).label('login_res'),
96 104
                 409: Joi.object({

+ 3
- 3
backend/lib/services/profile/index.js Ver fichero

@@ -71,7 +71,7 @@ module.exports = class ProfileService extends Schmervice.Service {
71 71
     async getCompleteProfilesFor(userId, type) {
72 72
         const { Profile } = this.server.models()
73 73
         await this._setTagLookup()
74
-
74
+        console.log('userId :>> ', userId)
75 75
         const dedupedProfileIds = await this._getProfileIdsForUserId(userId)
76 76
 
77 77
         const profilesEntries = await Profile.query()
@@ -357,8 +357,8 @@ module.exports = class ProfileService extends Schmervice.Service {
357 357
         await this._setTagLookup()
358 358
         let associations = groupingId
359 359
             ? await TagAssociation.query()
360
-                .where('grouping_id', groupingId)
361
-                .andWhere('profile_id', profileId)
360
+                  .where('grouping_id', groupingId)
361
+                  .andWhere('profile_id', profileId)
362 362
             : await TagAssociation.query().andWhere('profile_id', profileId)
363 363
         return associations
364 364
             .map(assoc => ({

+ 15
- 1
backend/lib/services/user.js Ver fichero

@@ -20,6 +20,21 @@ module.exports = class UserService extends Schmervice.Service {
20 20
         }
21 21
     }
22 22
 
23
+    /**
24
+     * Use knex to find users with email column
25
+     * @param {string} email
26
+     * @param {*} txn
27
+     * @returns
28
+     */
29
+    async findByEmail(email) {
30
+        const { User } = this.server.models()
31
+
32
+        return await User.query()
33
+            .throwIfNotFound()
34
+            .first()
35
+            .where({ user_email: email })
36
+    }
37
+
23 38
     /**
24 39
      * Use knex to find users with id column
25 40
      * @param {number} id
@@ -117,7 +132,6 @@ module.exports = class UserService extends Schmervice.Service {
117 132
      */
118 133
     async login({ email, password }, txn) {
119 134
         const { User, Auth } = this.server.models()
120
-
121 135
         const user = await Auth.query(txn)
122 136
             .throwIfNotFound()
123 137
             .first()

+ 8395
- 10
backend/package-lock.json
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 27
- 7
frontend/src/App.vue Ver fichero

@@ -1,5 +1,5 @@
1 1
 <template lang="pug">
2
-w-app 
2
+w-app
3 3
     TopNav(@on-open='openDrawer = !openDrawer')
4 4
 
5 5
     w-drawer(v-model='openDrawer')
@@ -40,6 +40,11 @@ export default {
40 40
          * using the login form
41 41
          */
42 42
         if (DEV_MODE) {
43
+            this.autoLogin()
44
+        }
45
+    },
46
+    methods: {
47
+        async autoLogin() {
43 48
             console.info('===============================================')
44 49
             console.info('-                   SIIMEE                    -')
45 50
             console.info('-----------------------------------------------')
@@ -47,25 +52,40 @@ export default {
47 52
             console.info('[Siimee App]: Starting application...')
48 53
             console.info('-----------------------------------------------')
49 54
             await this.setPid(DEV_PID)
50
-        }
51
-    },
52
-    methods: {
55
+        },
53 56
         /**
54 57
          * Sync up this components state with
55 58
          * the currentProfile handler
56 59
          */
57
-        async setPid(profileId) {
60
+        async setPid(form) {
58 61
             if (currentProfile.isLoggedIn) {
59 62
                 currentProfile.logout()
60 63
             }
61 64
 
62
-            await currentProfile.login(profileId, this.$waveui.notify)
63 65
             console.log('---')
66
+            const { profiles } = await currentProfile.login(
67
+                form.email,
68
+                form.password,
69
+            )
64 70
 
65 71
             /**
66 72
              * Default to the HomeView and alter as needed (side-effects!)
67 73
              */
68
-            const toRoute = { name: 'HomeView' }
74
+            let toRoute = { name: 'HomeView' }
75
+
76
+            if (profiles.length) {
77
+                const profile = profiles[0]
78
+                await currentProfile.setup(
79
+                    profile.profile_id,
80
+                    this.$waveui.notify,
81
+                )
82
+            } else {
83
+                console.warn(
84
+                    `[Login] No profiles associated with ${form.email}`,
85
+                )
86
+                toRoute = { name: 'OnboardingView' }
87
+            }
88
+
69 89
             this.$router.push(toRoute)
70 90
         },
71 91
     },

+ 1
- 1
frontend/src/entities/survey/survey.js Ver fichero

@@ -35,7 +35,7 @@ class Survey extends _baseRecord {
35 35
         /**  Fields */
36 36
         this.steps = [...questionSteps] // ! required
37 37
         this.aspectQuestions = _formatAspectQuestions(this.steps)
38
-        console.log('this.aspectQuestions: ', JSON.stringify(this.aspectQuestions))
38
+        // console.log('this.aspectQuestions: ', JSON.stringify(this.aspectQuestions))
39 39
     }
40 40
 
41 41
     isValid() {

+ 7
- 7
frontend/src/router/guards.js Ver fichero

@@ -2,7 +2,7 @@ import { currentProfile } from '../services'
2 2
 
3 3
 const DEV_MODE = import.meta.env.VITE_DEV == 'true'
4 4
 
5
-async function log(to) {
5
+const log = async to => {
6 6
     if (DEV_MODE) {
7 7
         if (!currentProfile.isLoggedIn || !currentProfile.isComplete) {
8 8
             console.info(
@@ -17,18 +17,18 @@ const checkLoginStatus = (destination, nextCb) => {
17 17
     log(destination)
18 18
     if (DEV_MODE) {
19 19
         nextCb()
20
-    } else if (
21
-        destination.meta.requiresCompleteProfile &&
22
-        !currentProfile.isLoggedIn &&
23
-        !currentProfile.isComplete
24
-    ) {
25
-        nextCb('onboarding')
26 20
     } else if (
27 21
         destination.meta.requiresCompleteProfile &&
28 22
         destination.meta.requiresAuth &&
29 23
         !currentProfile.isLoggedIn
30 24
     ) {
31 25
         nextCb('login')
26
+    } else if (
27
+        destination.meta.requiresCompleteProfile &&
28
+        !currentProfile.isLoggedIn &&
29
+        !currentProfile.isComplete
30
+    ) {
31
+        nextCb('onboarding')
32 32
     } else {
33 33
         nextCb()
34 34
     }

+ 11
- 4
frontend/src/services/login.service.js Ver fichero

@@ -7,6 +7,7 @@ import {
7 7
     fetchProfileByProfileId,
8 8
     Chatter,
9 9
     StonkAlert,
10
+    loginUser,
10 11
 } from '../services/index.js'
11 12
 import { surveyFactory } from '../utils/index.js'
12 13
 
@@ -76,12 +77,18 @@ class Login {
76 77
      * @param {number} profileId
77 78
      * @returns {number} stored reactive id
78 79
      */
79
-    async login(profileId, cb) {
80
-        this._loading.value = true
80
+    async login(email, password) {
81 81
         // First check if profile exists
82
-        console.warn('[Login Service warn]: Logging in:', profileId)
83
-
82
+        console.warn('[Login Service warn]: Logging in:', email)
83
+        const res = await loginUser({ email, password })
84
+        if (res) {
85
+            console.warn(`[Login Service warn] Logging in: Succeeded!`)
86
+        }
87
+        return res
88
+    }
89
+    async setup(profileId, cb) {
84 90
         // TODO: You can probably use this call to get responses, groupings and tags
91
+        this._loading.value = true
85 92
         this._profile = await fetchProfileByProfileId(profileId)
86 93
         this.id.value = this._profile.profile_id
87 94
 

+ 6
- 2
frontend/src/services/user.service.js Ver fichero

@@ -1,4 +1,5 @@
1 1
 import { db } from '../utils/db.js'
2
+const SERVICE = 'user'
2 3
 
3 4
 /**
4 5
  * Signup a new user
@@ -10,7 +11,10 @@ const signupUser = async user => {
10 11
         user_email: user.email,
11 12
         is_poster: user.seeking == 'position' ? 0 : 1,
12 13
     }
13
-    return await db.post(`/user/signup`, payload)
14
+    return await db.post(`/${SERVICE}/signup`, payload)
14 15
 }
15 16
 
16
-export { signupUser }
17
+const loginUser = async ({ email, password }) => {
18
+    return await db.post(`/${SERVICE}/login`, { user_email: email, password })
19
+}
20
+export { signupUser, loginUser }

+ 9
- 1
frontend/src/utils/db.js Ver fichero

@@ -1,8 +1,13 @@
1 1
 const domain = 'localhost'
2
+const gui_port = 3000
2 3
 const port = 3001
3 4
 const httpProtocol = `http`
4 5
 const prefix = 'api'
5
-const remote = `${httpProtocol}://${domain}:${port}/${prefix}`
6
+const backend_host = `${domain}:${port}`
7
+const host = `${domain}:${gui_port}`
8
+const origin = `${httpProtocol}://${host}/`
9
+const remote = `${httpProtocol}://${backend_host}/${prefix}`
10
+const referrer = origin
6 11
 
7 12
 const headerTemplate = {
8 13
     method: null,
@@ -14,6 +19,9 @@ const headerTemplate = {
14 19
         // 'Content-Type': 'application/x-www-form-urlencoded',
15 20
     },
16 21
     redirect: 'manual', // manual, *follow, error
22
+    host,
23
+    origin,
24
+    referrer,
17 25
     referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
18 26
     body: null, // body data type must match "Content-Type" header
19 27
 }

+ 6
- 4
frontend/src/utils/survey.js Ver fichero

@@ -18,7 +18,7 @@ const promptToComponent = {
18 18
     image: 'FormInput',
19 19
     // distance: 'FormInput',
20 20
     blurb: 'FormInput',
21
-    aspects: 'Aspects'
21
+    aspects: 'Aspects',
22 22
 }
23 23
 /**
24 24
  * Make a step from match or step information
@@ -63,12 +63,14 @@ class SurveyFactory {
63 63
             }
64 64
             const responseKeyLike = formatStep(match, step)
65 65
             const withComponent = associateWithComponent(responseKeyLike)
66
-            console.log('withComponent :>> ', withComponent)
66
+            // console.log('withComponent :>> ', withComponent)
67 67
             return withComponent
68 68
         })
69
-        // temporary extra condition in filter 
69
+        // temporary extra condition in filter
70 70
         let unseen = this.questionsFromDb.filter(
71
-            q => !seenIds.includes(q.response_key_id) && [1,2,3,4,5,6].includes(q.response_key_id),
71
+            q =>
72
+                !seenIds.includes(q.response_key_id) &&
73
+                [1, 2, 3, 4, 5, 6].includes(q.response_key_id),
72 74
         )
73 75
         return [...stepsInCommon, ...unseen]
74 76
     }

+ 20
- 5
frontend/src/views/LoginView.vue Ver fichero

@@ -1,20 +1,35 @@
1 1
 <template lang="pug">
2 2
 main.view--login
3
-
4 3
     article.pa12
5 4
         form
6
-            w-input.mb4(label="User E-mail" tile outline v-model="form.profileId" inner-icon-left='icon-envelope')
7
-            w-input(label="Password" type="password" tile outline inner-icon-left='icon-eye')
5
+            w-input.mb4(
6
+                inner-icon-left='icon-envelope'
7
+                label='User E-mail'
8
+                outline
9
+                tile
10
+                v-model='form.email'
11
+            )
12
+            w-input(
13
+                inner-icon-left='icon-eye'
14
+                label='Password'
15
+                outline
16
+                tile
17
+                v-model='form.password'
18
+            )
8 19
 
9 20
             //- Emit up an event so we can sync App pid with currentProfile.id
10
-            w-button.xs12.mt12(@click="$emit('updatePid', form.profileId)" type="submit") submit
21
+            w-button.xs12.mt12(
22
+                @click.prevent.stop='$emit("updatePid", form)'
23
+                type='submit'
24
+            ) submit
11 25
 </template>
12 26
 
13 27
 <script>
14 28
 export default {
15 29
     data: () => ({
16 30
         form: {
17
-            profileId: null,
31
+            email: null,
32
+            password: null,
18 33
         },
19 34
     }),
20 35
 }

Loading…
Cancelar
Guardar