@vulkano/core 1.20.2 → 1.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -53,6 +53,7 @@ module.exports = {
53
53
  const defaultProps = {
54
54
  sort: 'createdAt|DESC',
55
55
  searchBy: ['name'],
56
+ fields: ['name', 'age', 'active', 'createdAt', 'updatedAt'],
56
57
  filter: {
57
58
  active: true
58
59
  },
@@ -145,16 +146,45 @@ module.exports = {
145
146
 
146
147
  },
147
148
 
149
+ /**
150
+ * Before validate callback — runs before beforeSave, as part of obj.save()
151
+ * (create() above). Does NOT run for update()/delete(): Mongoose's update
152
+ * validators (runValidators) validate each changed path directly and never
153
+ * go through this callback, even when a validator rejects the value.
154
+ * @param {Callback} cb
155
+ */
156
+ beforeValidate(cb) {
157
+
158
+ console.log('Running callback before validate');
159
+
160
+ // All good!
161
+ cb();
162
+
163
+ },
164
+
165
+ /**
166
+ * Callback after validate
167
+ * @param {Callback} cb
168
+ */
169
+ afterValidate(cb) {
170
+
171
+ console.log('Running callback after validate');
172
+
173
+ // All good!
174
+ cb();
175
+
176
+ },
177
+
148
178
  /**
149
179
  * Before save callback
150
180
  * @param {Callback} cb
151
181
  */
152
182
  beforeSave(cb) {
153
183
 
154
- const data = this;
184
+ const doc = this;
155
185
 
156
186
  console.log('Running callback before save');
157
- console.log(data);
187
+ console.log(doc);
158
188
 
159
189
  // All good!
160
190
  cb();
@@ -165,10 +195,40 @@ module.exports = {
165
195
  * Callback after save
166
196
  * @param {Callback} cb
167
197
  */
168
- afterSave(data, cb) {
198
+ afterSave(doc, cb) {
169
199
 
170
200
  console.log('Running callback after save');
171
- console.log(data);
201
+ console.log(doc);
202
+
203
+ // All good!
204
+ cb();
205
+
206
+ },
207
+
208
+ /**
209
+ * Before findOneAndUpdate callback — runs on update() and delete() above,
210
+ * since both call Example.findOneAndUpdate() directly. `this` is the Query,
211
+ * not the document.
212
+ * @param {Callback} cb
213
+ */
214
+ beforeFindOneAndUpdate(cb) {
215
+
216
+ console.log('Running callback before findOneAndUpdate');
217
+
218
+ // All good!
219
+ cb();
220
+
221
+ },
222
+
223
+ /**
224
+ * Callback after findOneAndUpdate
225
+ * @param {Object} doc Updated document
226
+ * @param {Callback} cb
227
+ */
228
+ afterFindOneAndUpdate(doc, cb) {
229
+
230
+ console.log('Running callback after findOneAndUpdate');
231
+ console.log(doc);
172
232
 
173
233
  // All good!
174
234
  cb();
@@ -0,0 +1,55 @@
1
+ /* global app */
2
+
3
+ /**
4
+ * Alias Route Mappings
5
+ *
6
+ * Your routes map URLs to views and controllers.
7
+ *
8
+ * Notes: Vulkano automatically matches the URL to a controller
9
+ * and HTTP method (get, post, put, delete) ;)
10
+ *
11
+ * Example:
12
+ * - GET /users/ -> File: UsersController, Method: 'get': (req, res) => {}
13
+ * - GET /users/123 -> File: UsersController, Method: 'get :id': (req, res) => {}
14
+ * - POST /users/ -> File: UsersController, Method: 'post': (req, res) => {}
15
+ * - PUT /users/123 -> File: UsersController, Method: 'put :id': (req, res) => {}
16
+ * - DELETE /users/123 -> File: UsersController, Method: 'delete :id': (req, res) => {}
17
+ *
18
+ * With nested folders, the same rules apply:
19
+ * - GET /api/users/123 -> Folder: api -> File: UsersController, Method: 'get :id': (req, res) => {}
20
+ *
21
+ * But you can write your own routes manually :P
22
+ *
23
+ */
24
+
25
+ module.exports = {
26
+
27
+ // Routes as string - Simple and easy to use
28
+ '/about-me': 'AboutController.get',
29
+
30
+ // Catch-all for React/Vue Router (SPA)
31
+ '/admin*': 'AdminController.get',
32
+
33
+ // Routes as definition - Most flexible
34
+ '/test': (req, res) => {
35
+ res.json({ message: 'Hello, world!' });
36
+ },
37
+
38
+ // Routes as method - More Advanced
39
+ custom() {
40
+
41
+ app.vulkano.get('/test', (req, res) => {
42
+ res.json({ hello: 'world' });
43
+ });
44
+
45
+ app.vulkano.get('/test2', (req, res) => {
46
+ res.json({ hello: 'world2' });
47
+ });
48
+
49
+ app.vulkano.get('/test3', (req, res) => {
50
+ res.json({ hello: 'world3' });
51
+ });
52
+
53
+ }
54
+
55
+ };
@@ -0,0 +1,111 @@
1
+ /* global User, Auth, VSError */
2
+
3
+ const bcrypt = require('bcryptjs');
4
+
5
+ module.exports = {
6
+
7
+ SESSION_MS: 1000 * 60 * 60 * 24 * 365 * 10,
8
+
9
+ /**
10
+ * Verify a plain-text password against a stored hash.
11
+ * @param {String} plain
12
+ * @param {String} hash
13
+ * @returns {Boolean}
14
+ */
15
+ verifyPassword(plain, hash) {
16
+ return bcrypt.compareSync(`${process.env.SALT_KEY || ''}-${plain}`, hash);
17
+ },
18
+
19
+ /**
20
+ * Look up a user by email and verify their password. The only place in
21
+ * the model that explicitly loads the password hash.
22
+ * @param {String} email
23
+ * @param {String} password
24
+ * @returns {Promise<Object>} the authenticated User document
25
+ */
26
+ login({ email, password }) {
27
+
28
+ const normalizedEmail = String(email || '')
29
+ .toLowerCase()
30
+ .trim();
31
+
32
+ return User.findOne({ email: normalizedEmail, active: true })
33
+ .select('+password')
34
+ .then((user) => {
35
+
36
+ if (!user || !Auth.verifyPassword(password || '', user.password)) {
37
+ return VSError.reject('Invalid credentials', 401);
38
+ }
39
+
40
+ return Auth.setToken(user);
41
+ });
42
+
43
+ },
44
+
45
+ /**
46
+ * Generate token
47
+ * @param {Object} props
48
+ * @returns {Object}
49
+ */
50
+ setToken(u) {
51
+
52
+ const {
53
+ _id
54
+ } = u || {};
55
+
56
+ if (!_id) {
57
+ return VSError.reject('The user and/or password are incorrect', 400);
58
+ }
59
+
60
+ return Promise.resolve({
61
+
62
+ user: {
63
+ _id: u._id || '',
64
+ name: u.name || ''
65
+ },
66
+
67
+ token: Jwt.encode({
68
+ _id: u._id || '',
69
+ name: u.name || '',
70
+ email: u.email,
71
+ role: u.role || '',
72
+ expiration: Auth.SESSION_MS + Date.now()
73
+ })
74
+
75
+ });
76
+ },
77
+
78
+ /**
79
+ * Get current user logged
80
+ *
81
+ * @param {Object} auth
82
+ * @returns Promise
83
+ */
84
+ getCurrent(auth) {
85
+
86
+ const {
87
+ _id
88
+ } = auth || {};
89
+
90
+ if (!_id) {
91
+ return VSError.reject('Invalid token', 401);
92
+ }
93
+
94
+ return User
95
+ .getUser(_id)
96
+ .then( (u) => {
97
+
98
+ const {
99
+ active
100
+ } = u || {};
101
+
102
+ if (String(active || '') !== 'true' || !_id) {
103
+ return VSError.reject('Invalid ID. User not found', 401);
104
+ }
105
+
106
+ return u;
107
+
108
+ });
109
+
110
+ }
111
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vulkano/core",
3
- "version": "1.20.2",
3
+ "version": "1.22.1",
4
4
  "description": "A MVC framework using Express 4",
5
5
  "license": "MIT",
6
6
  "author": "Vulkano Team",
@@ -44,6 +44,7 @@
44
44
  "dependencies": {
45
45
  "@socket.io/mongo-adapter": "^0.4.0",
46
46
  "@socket.io/redis-adapter": "^8.3.0",
47
+ "bcryptjs": "^3.0.3",
47
48
  "compression": "^1.8.1",
48
49
  "connect-timeout": "^1.9.1",
49
50
  "cookie-parser": "^1.4.7",
@@ -69,4 +70,4 @@
69
70
  "socket.io-adapter": "^2.5.8",
70
71
  "undici": "^7.28.0"
71
72
  }
72
- }
73
+ }