Procházet zdrojové kódy

:sparkles: adding services via schmervice

master
TOJ před 5 roky
rodič
revize
65cd4a467d

+ 14
- 1
backend/lib/plugins/user.js Zobrazit soubor

1
+const Schmervice = require('@hapipal/schmervice');
1
 const Schwifty = require('@hapipal/schwifty');
2
 const Schwifty = require('@hapipal/schwifty');
2
 const Jwt = require('@hapi/jwt');
3
 const Jwt = require('@hapi/jwt');
3
 const JwtStrategy = require('../auth/strategies/jwt')
4
 const JwtStrategy = require('../auth/strategies/jwt')
19
         server.auth.strategy('default_jwt', 'jwt', jwtOptions)
20
         server.auth.strategy('default_jwt', 'jwt', jwtOptions)
20
         server.auth.default('default_jwt')
21
         server.auth.default('default_jwt')
21
 
22
 
23
+
24
+        await server.register(Schmervice)
25
+        server.registerService(
26
+            class MathService extends Schmervice.Service {
27
+                add(x, y) {
28
+                    this.server.log(['math-service'], 'Adding')
29
+                    return Number(x) + Number(y)
30
+                }
31
+            }
32
+        )
33
+
22
         await server.route(UserCurrentRoute)
34
         await server.route(UserCurrentRoute)
23
         await server.route(UserLoginRoute)
35
         await server.route(UserLoginRoute)
24
     }
36
     }
25
-}
37
+}
38
+

+ 2
- 0
backend/lib/routes/user/login.js Zobrazit soubor

32
     handler: async (request, h) => {
32
     handler: async (request, h) => {
33
         try {
33
         try {
34
             const { user: { email, password } } = request.payload
34
             const { user: { email, password } } = request.payload
35
+            const { mathService } = request.services()
36
+            console.log(mathService.add(10, 1))
35
             // const { userService, displayService } = request.services();
37
             // const { userService, displayService } = request.services();
36
 
38
 
37
             // const login = async (txn) => {
39
             // const login = async (txn) => {

+ 79
- 0
backend/lib/services/user.js Zobrazit soubor

1
+'use strict';
2
+
3
+const Util = require('util');
4
+const Jwt = require('@hapi/jwt');
5
+const Schmervice = require('@hapipal/schmervice');
6
+const SecurePassword = require('secure-password');
7
+
8
+module.exports = class UserService extends Schmervice.Service {
9
+    constructor(...args) {
10
+        super(...args)
11
+        const pwd = new SecurePassword()
12
+        this.pwd = {
13
+            hash: Util.promisify(pwd.hash.bind(pwd)),
14
+            verify: Util.promisify(pwd.verify.bind(pwd))
15
+        }
16
+    }
17
+    async findById(id, txn) {
18
+        const { User } = this.server.models()
19
+        return await User.query(txn).throwIfNotFound().findById(id)
20
+    }
21
+    async findByUsername(username, txn) {
22
+        const { User } = this.server.models()
23
+
24
+        return await User.query(txn).throwIfNotFound().first().where({ username })
25
+    }
26
+    async signup({ password, ...userInfo }, txn) {
27
+        const { User } = this.server.models()
28
+        const { id } = await User.query(txn).insert(userInfo)
29
+        await this.changePassword(id, password, txn)
30
+        return id
31
+    }
32
+    async update(id, { password, ...userInfo }, txn) {
33
+        const { User } = this.server.models()
34
+
35
+        if (Object.keys(userInfo).length > 0) {
36
+            await User.query(txn).throwIfNotFound().where({ id }).patch(userInfo)
37
+        }
38
+
39
+        if (password) {
40
+            await this.changePassword(id, password, txn)
41
+        }
42
+
43
+        return id
44
+    }
45
+    async login({ email, password }, txn) {
46
+        const { User } = this.server.models()
47
+
48
+        const user = await User.query(txn).throwIfNotFound().first().where({
49
+            email: User.raw('? collate nocase', email)
50
+        })
51
+
52
+        const passwordCheck = await this.pwd.verify(Buffer.from(password), user.password)
53
+
54
+        if (passwordCheck === SecurePassword.VALID_NEEDS_REHASH) {
55
+            await this.changePassword(user.id, password, txn)
56
+        }
57
+        else if (passwordCheck !== SecurePassword.VALID) {
58
+            throw User.createNotFoundError()
59
+        }
60
+
61
+        return user
62
+    }
63
+    createToken(id) {
64
+        return Jwt.token.generate({ id }, {
65
+            key: this.options.jwtKey,
66
+            algorithm: 'HS256'
67
+        }, {
68
+            ttlSec: 7 * 24 * 60 * 60 // 7 days
69
+        })
70
+    }
71
+    async changePassword(id, password, txn) {
72
+        const { User } = this.server.models()
73
+
74
+        await User.query(txn).throwIfNotFound().where({ id }).patch({
75
+            password: await this.pwd.hash(Buffer.from(password))
76
+        })
77
+        return id
78
+    }
79
+}

+ 87
- 1
backend/package-lock.json Zobrazit soubor

15
         "@hapi/jwt": "^2.0.1",
15
         "@hapi/jwt": "^2.0.1",
16
         "@hapi/vision": "^6.0.1",
16
         "@hapi/vision": "^6.0.1",
17
         "@hapipal/confidence": "^6.0.1",
17
         "@hapipal/confidence": "^6.0.1",
18
+        "@hapipal/schmervice": "^2.0.0",
18
         "@hapipal/schwifty": "^6.0.0",
19
         "@hapipal/schwifty": "^6.0.0",
19
         "dotenv": "^10.0.0",
20
         "dotenv": "^10.0.0",
20
         "exiting": "^6.0.1",
21
         "exiting": "^6.0.1",
22
         "joi": "^17.4.0",
23
         "joi": "^17.4.0",
23
         "knex": "^0.21.19",
24
         "knex": "^0.21.19",
24
         "mysql": "^2.18.1",
25
         "mysql": "^2.18.1",
25
-        "objection": "^2.2.15"
26
+        "objection": "^2.2.15",
27
+        "secure-password": "^4.0.0"
26
       },
28
       },
27
       "devDependencies": {
29
       "devDependencies": {
28
         "nodemon": "^2.0.7"
30
         "nodemon": "^2.0.7"
401
         "confidence": "bin/confidence"
403
         "confidence": "bin/confidence"
402
       }
404
       }
403
     },
405
     },
406
+    "node_modules/@hapipal/schmervice": {
407
+      "version": "2.0.0",
408
+      "resolved": "https://registry.npmjs.org/@hapipal/schmervice/-/schmervice-2.0.0.tgz",
409
+      "integrity": "sha512-EmQLVM4MdPXCw1iijqfG0gQXnawYsPypagdEFMo5c0kf637Sjj7x5DjDOMN2Qmce+tIm2Nv70vrSk6qfrJW3qw==",
410
+      "dependencies": {
411
+        "@hapi/hoek": "9.x.x"
412
+      },
413
+      "engines": {
414
+        "node": ">=12"
415
+      },
416
+      "peerDependencies": {
417
+        "@hapi/hapi": ">=19 <21"
418
+      }
419
+    },
404
     "node_modules/@hapipal/schwifty": {
420
     "node_modules/@hapipal/schwifty": {
405
       "version": "6.0.0",
421
       "version": "6.0.0",
406
       "resolved": "https://registry.npmjs.org/@hapipal/schwifty/-/schwifty-6.0.0.tgz",
422
       "resolved": "https://registry.npmjs.org/@hapipal/schwifty/-/schwifty-6.0.0.tgz",
2576
         "node": ">= 0.6"
2592
         "node": ">= 0.6"
2577
       }
2593
       }
2578
     },
2594
     },
2595
+    "node_modules/nanoassert": {
2596
+      "version": "1.1.0",
2597
+      "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz",
2598
+      "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40="
2599
+    },
2579
     "node_modules/nanomatch": {
2600
     "node_modules/nanomatch": {
2580
       "version": "1.2.13",
2601
       "version": "1.2.13",
2581
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
2602
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
2602
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
2623
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
2603
       "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
2624
       "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
2604
     },
2625
     },
2626
+    "node_modules/node-gyp-build": {
2627
+      "version": "4.2.3",
2628
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
2629
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
2630
+      "bin": {
2631
+        "node-gyp-build": "bin.js",
2632
+        "node-gyp-build-optional": "optional.js",
2633
+        "node-gyp-build-test": "build-test.js"
2634
+      }
2635
+    },
2605
     "node_modules/nodemon": {
2636
     "node_modules/nodemon": {
2606
       "version": "2.0.7",
2637
       "version": "2.0.7",
2607
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
2638
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
3147
         "ret": "~0.1.10"
3178
         "ret": "~0.1.10"
3148
       }
3179
       }
3149
     },
3180
     },
3181
+    "node_modules/secure-password": {
3182
+      "version": "4.0.0",
3183
+      "resolved": "https://registry.npmjs.org/secure-password/-/secure-password-4.0.0.tgz",
3184
+      "integrity": "sha512-B268T/tx+hq7q85KH6gonEqK/lhrLhNtzYzqojuMtBPVFBtwiIwxqF+4yr9POsJu5cIxbJyM66eYfXZiPZUXRA==",
3185
+      "dependencies": {
3186
+        "nanoassert": "^1.0.0",
3187
+        "sodium-native": "^3.1.1"
3188
+      }
3189
+    },
3150
     "node_modules/semver": {
3190
     "node_modules/semver": {
3151
       "version": "5.7.1",
3191
       "version": "5.7.1",
3152
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
3192
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
3396
         "node": ">=0.10.0"
3436
         "node": ">=0.10.0"
3397
       }
3437
       }
3398
     },
3438
     },
3439
+    "node_modules/sodium-native": {
3440
+      "version": "3.2.1",
3441
+      "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.2.1.tgz",
3442
+      "integrity": "sha512-EgDZ/Z7PxL2kCasKk7wnRkV8W9kvwuIlHuHXAxkQm3FF0MgVsjyLBXGjSRGhjE6u7rhSpk3KaMfFM23bfMysIQ==",
3443
+      "hasInstallScript": true,
3444
+      "dependencies": {
3445
+        "ini": "^1.3.5",
3446
+        "node-gyp-build": "^4.2.0"
3447
+      }
3448
+    },
3399
     "node_modules/source-map": {
3449
     "node_modules/source-map": {
3400
       "version": "0.6.1",
3450
       "version": "0.6.1",
3401
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
3451
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
4393
         "joi": "17.x.x"
4443
         "joi": "17.x.x"
4394
       }
4444
       }
4395
     },
4445
     },
4446
+    "@hapipal/schmervice": {
4447
+      "version": "2.0.0",
4448
+      "resolved": "https://registry.npmjs.org/@hapipal/schmervice/-/schmervice-2.0.0.tgz",
4449
+      "integrity": "sha512-EmQLVM4MdPXCw1iijqfG0gQXnawYsPypagdEFMo5c0kf637Sjj7x5DjDOMN2Qmce+tIm2Nv70vrSk6qfrJW3qw==",
4450
+      "requires": {
4451
+        "@hapi/hoek": "9.x.x"
4452
+      }
4453
+    },
4396
     "@hapipal/schwifty": {
4454
     "@hapipal/schwifty": {
4397
       "version": "6.0.0",
4455
       "version": "6.0.0",
4398
       "resolved": "https://registry.npmjs.org/@hapipal/schwifty/-/schwifty-6.0.0.tgz",
4456
       "resolved": "https://registry.npmjs.org/@hapipal/schwifty/-/schwifty-6.0.0.tgz",
6046
         "sqlstring": "2.3.1"
6104
         "sqlstring": "2.3.1"
6047
       }
6105
       }
6048
     },
6106
     },
6107
+    "nanoassert": {
6108
+      "version": "1.1.0",
6109
+      "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz",
6110
+      "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40="
6111
+    },
6049
     "nanomatch": {
6112
     "nanomatch": {
6050
       "version": "1.2.13",
6113
       "version": "1.2.13",
6051
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
6114
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
6069
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
6132
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
6070
       "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
6133
       "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
6071
     },
6134
     },
6135
+    "node-gyp-build": {
6136
+      "version": "4.2.3",
6137
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
6138
+      "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
6139
+    },
6072
     "nodemon": {
6140
     "nodemon": {
6073
       "version": "2.0.7",
6141
       "version": "2.0.7",
6074
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
6142
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
6482
         "ret": "~0.1.10"
6550
         "ret": "~0.1.10"
6483
       }
6551
       }
6484
     },
6552
     },
6553
+    "secure-password": {
6554
+      "version": "4.0.0",
6555
+      "resolved": "https://registry.npmjs.org/secure-password/-/secure-password-4.0.0.tgz",
6556
+      "integrity": "sha512-B268T/tx+hq7q85KH6gonEqK/lhrLhNtzYzqojuMtBPVFBtwiIwxqF+4yr9POsJu5cIxbJyM66eYfXZiPZUXRA==",
6557
+      "requires": {
6558
+        "nanoassert": "^1.0.0",
6559
+        "sodium-native": "^3.1.1"
6560
+      }
6561
+    },
6485
     "semver": {
6562
     "semver": {
6486
       "version": "5.7.1",
6563
       "version": "5.7.1",
6487
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
6564
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
6682
         }
6759
         }
6683
       }
6760
       }
6684
     },
6761
     },
6762
+    "sodium-native": {
6763
+      "version": "3.2.1",
6764
+      "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.2.1.tgz",
6765
+      "integrity": "sha512-EgDZ/Z7PxL2kCasKk7wnRkV8W9kvwuIlHuHXAxkQm3FF0MgVsjyLBXGjSRGhjE6u7rhSpk3KaMfFM23bfMysIQ==",
6766
+      "requires": {
6767
+        "ini": "^1.3.5",
6768
+        "node-gyp-build": "^4.2.0"
6769
+      }
6770
+    },
6685
     "source-map": {
6771
     "source-map": {
6686
       "version": "0.6.1",
6772
       "version": "0.6.1",
6687
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
6773
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",

+ 3
- 1
backend/package.json Zobrazit soubor

17
     "@hapi/jwt": "^2.0.1",
17
     "@hapi/jwt": "^2.0.1",
18
     "@hapi/vision": "^6.0.1",
18
     "@hapi/vision": "^6.0.1",
19
     "@hapipal/confidence": "^6.0.1",
19
     "@hapipal/confidence": "^6.0.1",
20
+    "@hapipal/schmervice": "^2.0.0",
20
     "@hapipal/schwifty": "^6.0.0",
21
     "@hapipal/schwifty": "^6.0.0",
21
     "dotenv": "^10.0.0",
22
     "dotenv": "^10.0.0",
22
     "exiting": "^6.0.1",
23
     "exiting": "^6.0.1",
24
     "joi": "^17.4.0",
25
     "joi": "^17.4.0",
25
     "knex": "^0.21.19",
26
     "knex": "^0.21.19",
26
     "mysql": "^2.18.1",
27
     "mysql": "^2.18.1",
27
-    "objection": "^2.2.15"
28
+    "objection": "^2.2.15",
29
+    "secure-password": "^4.0.0"
28
   },
30
   },
29
   "devDependencies": {
31
   "devDependencies": {
30
     "nodemon": "^2.0.7"
32
     "nodemon": "^2.0.7"

Načítá se…
Zrušit
Uložit