@adaptivestone/framework 2.15.4 → 3.0.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,75 @@
1
+ ### 3.0.1
2
+
3
+ [UPDATE] update deps
4
+ [UPDATE] getUserByTokens more logs
5
+
6
+ ### 3.0.0
7
+
8
+ [BREAKING] Mongoose v6. Than a lot of changes:[mongoDB drive changes](https://github.com/mongodb/node-mongodb-native/blob/4.0/docs/CHANGES_4.0.0.md), [Mongoose changes](https://mongoosejs.com/docs/migrating_to_6.html).
9
+ Notable changes from migration
10
+ Removed `execPopulate()`[link](https://mongoosejs.com/docs/migrating_to_6.html#removed-execpopulate)
11
+
12
+ ```js
13
+ // Document#populate() now returns a promise and is now no longer chainable.
14
+
15
+ //Replace
16
+ await doc.populate('path1').populate('path2').execPopulate();
17
+ // with
18
+ await doc.populate(['path1', 'path2']);
19
+ //Replace
20
+ await doc
21
+ .populate('path1', 'select1')
22
+ .populate('path2', 'select2')
23
+ .execPopulate();
24
+ // with
25
+ await doc.populate([
26
+ { path: 'path1', select: 'select1' },
27
+ { path: 'path2', select: 'select2' },
28
+ ]);
29
+ ```
30
+
31
+ [REMOVED] removed deprecated router handler string not allowed anymore. Use functions by itself
32
+ [REMOVED] removed deprecated someSecretSalt() on user model (use this.saltSecret instead)
33
+ [REMOVED] removed deprecated validate() on abstract controller and as result validator dependency. Use request validators instead
34
+ [REMOVED] removed deprecated isUseControllerNameForRouting() on abstract controller. Use getExpressPath() instead
35
+ [REMOVED] removed deprecated Base.loadFilesWithInheritance please use getFilesPathWithInheritance that produce almost the same output
36
+ [BREAKING] Removed "success" field on Auth contreoller. Please use http status instead
37
+ [BREAKING] Auth controller - "error" error responce renamed to "message"
38
+
39
+ ```js
40
+ // Before
41
+ {
42
+ error: 'Some error';
43
+ }
44
+ // After
45
+ {
46
+ message: 'Some error';
47
+ }
48
+ ```
49
+
50
+ [UPDATE] update deps
51
+ [UPDATE] winston console transport now using timestapms
52
+ [UPDATE] PrepareAppInfo middleware now a global one. Do not need to include it on every controller
53
+ [NEW] Request anso works with req.query, but req.body have bigger priority
54
+
55
+ ### 2.18.0
56
+
57
+ [UPDATE] update deps
58
+ [UPDATE] replace body-parser with express.json
59
+ [NEW] role middleware
60
+
61
+ ### 2.17.0
62
+
63
+ [UPDATE] update deps
64
+ [NEW] new env variable LOGGER_SENTRY_LEVEL (default=info)
65
+ [NEW] new env variable LOGGER_CONSOLE_ENABLE (default=true)
66
+ [BREAKING] on translation we changed i18next. Please convert files if you have plurals inside it https://i18next.github.io/i18next-v4-format-converter-web/
67
+
68
+ #### 2.16.0
69
+
70
+ [UPDATE] update deps
71
+ [NEW] begin adding type script definitions
72
+
1
73
  #### 2.15.4
2
74
 
3
75
  [UPDATE] update deps
package/README.md CHANGED
@@ -1 +1,3 @@
1
1
  # Adaptive stone node js framework
2
+
3
+ [https://framework.adaptivestone.com/](https://framework.adaptivestone.com/)
@@ -0,0 +1,14 @@
1
+ const AbstractCommand = require('../modules/AbstractCommand');
2
+ const ControllerManager = require('../controllers/index');
3
+
4
+ class Documentation extends AbstractCommand {
5
+ async run() {
6
+ const CM = new ControllerManager(this.app);
7
+ this.app.documentation = [];
8
+ await CM.initControllers({ folders: this.app.foldersConfig });
9
+ console.log(JSON.stringify(this.app.documentation));
10
+ return JSON.stringify(this.app.documentation);
11
+ }
12
+ }
13
+
14
+ module.exports = Documentation;
@@ -1,6 +1,10 @@
1
1
  const AbstractCommand = require('../modules/AbstractCommand');
2
2
 
3
3
  class DropIndex extends AbstractCommand {
4
+ static get description() {
5
+ return 'Drop indexes of model';
6
+ }
7
+
4
8
  async run() {
5
9
  if (!this.args.model) {
6
10
  this.logger.error('Please provide model name as "--model=BestUserModel"');
@@ -5,6 +5,10 @@ const fs = require('fs').promises;
5
5
  const AbstractCommand = require('../../modules/AbstractCommand');
6
6
 
7
7
  class CreateMigration extends AbstractCommand {
8
+ static get description() {
9
+ return 'Create new migration';
10
+ }
11
+
8
12
  async run() {
9
13
  if (!this.args.name) {
10
14
  return this.logger.error(
@@ -2,6 +2,10 @@
2
2
  const AbstractCommand = require('../../modules/AbstractCommand');
3
3
 
4
4
  class Migrate extends AbstractCommand {
5
+ static get description() {
6
+ return 'Run all pending migrations';
7
+ }
8
+
5
9
  async run() {
6
10
  const files = await this.getFilesPathWithInheritance(
7
11
  `${__dirname}/../../migrations`,
package/config/http.js CHANGED
@@ -1,7 +1,7 @@
1
1
  module.exports = {
2
2
  port: process.env.HTTP_PORT || 3300,
3
3
  hostname: process.env.HTTP_HOST || '0.0.0.0',
4
- // if you watn to use 'all' domains please copy this file to your app
4
+ // if you want to use 'all' domains please copy this file to your app
5
5
  // and set "corsDomains: '*'" (not a mistake, string instead of array)
6
6
  corsDomains: ['http://localhost:3000'],
7
7
  myDomain: process.env.HTTP_DOMAIN || 'http://localhost:3300',
package/config/i18n.js CHANGED
@@ -4,6 +4,6 @@ module.exports = {
4
4
  fallbackLng: 'en',
5
5
  // https://github.com/i18next/i18next-http-middleware#detector-options
6
6
  // in additional we have 'xLang' that detect language based on header 'xLang'
7
- langDetectionOders: ['xLang'], // from oreder option
7
+ langDetectionOders: ['xLang'], // from order option
8
8
  lookupQuerystring: 'lng', // string to detect language on query
9
9
  };
package/config/log.js CHANGED
@@ -4,9 +4,9 @@ module.exports = {
4
4
  transport: 'winston-transport-sentry-node',
5
5
  transportOptions: {
6
6
  sentry: {
7
- dsn: process.env.SENTRY_DSN,
7
+ dsn: process.env.LOGGER_SENTRY_DSN || process.env.SENTRY_DSN,
8
8
  },
9
- level: 'info',
9
+ level: process.env.LOGGER_SENTRY_LEVEL || 'info',
10
10
  },
11
11
  enable: process.env.LOGGER_SENTRY_ENABLE || false,
12
12
  },
@@ -14,8 +14,9 @@ module.exports = {
14
14
  transport: 'console',
15
15
  transportOptions: {
16
16
  level: process.env.LOGGER_CONSOLE_LEVEL || 'silly',
17
+ timestamp: true,
17
18
  },
18
- enable: true,
19
+ enable: process.env.LOGGER_CONSOLE_ENABLE || true,
19
20
  },
20
21
  ],
21
22
  };
@@ -1,6 +1,5 @@
1
1
  const yup = require('yup');
2
2
  const AbstractController = require('../modules/AbstractController');
3
- const PrepareAppInfo = require('../services/http/middleware/PrepareAppInfo');
4
3
  const GetUserByToken = require('../services/http/middleware/GetUserByToken');
5
4
  const RateLimiter = require('../services/http/middleware/RateLimiter');
6
5
 
@@ -74,33 +73,31 @@ class Auth extends AbstractController {
74
73
  req.appInfo.request.password, // we do a request casting
75
74
  );
76
75
  if (!user) {
77
- return res.status(400).json({ error: req.i18n.t('auth.errorUPValid') });
76
+ return res.status(400).json({ message: req.i18n.t('auth.errorUPValid') });
78
77
  }
79
78
  const { isAuthWithVefificationFlow } = this.app.getConfig('auth');
80
79
  if (isAuthWithVefificationFlow && !user.isVerified) {
81
80
  return res
82
81
  .status(400)
83
- .json({ error: req.i18n.t('email.notVerified'), notVerified: true });
82
+ .json({ message: req.i18n.t('email.notVerified'), notVerified: true });
84
83
  }
85
84
  const token = await user.generateToken();
86
85
 
87
- return res
88
- .status(200)
89
- .json({ success: true, token, user: user.getPublic() });
86
+ return res.status(200).json({ token, user: user.getPublic() });
90
87
  }
91
88
 
92
89
  async postRegister(req, res) {
93
90
  const User = req.appInfo.app.getModel('User');
94
91
  let user = await User.getUserByEmail(req.appInfo.request.email);
95
92
  if (user) {
96
- return res.status(400).json({ error: req.i18n.t('email.registered') });
93
+ return res.status(400).json({ message: req.i18n.t('email.registered') });
97
94
  }
98
95
  if (req.appInfo.request.nickName) {
99
96
  user = await User.findOne({ 'name.nick': req.appInfo.request.nickName });
100
97
  if (user) {
101
98
  return res
102
99
  .status(400)
103
- .json({ error: req.i18n.t('auth.nicknameExists') });
100
+ .json({ message: req.i18n.t('auth.nicknameExists') });
104
101
  }
105
102
  }
106
103
 
@@ -120,16 +117,16 @@ class Auth extends AbstractController {
120
117
  this.logger.error(e.message);
121
118
  });
122
119
  if (!answer) {
123
- return res.status(500).json({ success: false });
120
+ return res.status(500).json();
124
121
  }
125
122
  }
126
- return res.status(201).json({ success: true });
123
+ return res.status(201).json();
127
124
  }
128
125
 
129
126
  // eslint-disable-next-line class-methods-use-this
130
127
  async postLogout(req, res) {
131
128
  // todo remove token
132
- return res.status(200).json({ success: true });
129
+ return res.status(200).json();
133
130
  }
134
131
 
135
132
  async verifyUser(req, res) {
@@ -141,21 +138,19 @@ class Auth extends AbstractController {
141
138
  );
142
139
  } catch (e) {
143
140
  return res.status(400).json({
144
- success: false,
145
- error: req.i18n.t('email.alreadyVerifiedOrWrongToken'),
141
+ message: req.i18n.t('email.alreadyVerifiedOrWrongToken'),
146
142
  });
147
143
  }
148
144
  this.logger.debug(`Verify user user is :${user}`);
149
145
  if (!user) {
150
146
  return res.status(400).json({
151
- success: false,
152
- error: req.i18n.t('email.alreadyVerifiedOrWrongToken'),
147
+ message: req.i18n.t('email.alreadyVerifiedOrWrongToken'),
153
148
  });
154
149
  }
155
150
 
156
151
  user.isVerified = true;
157
152
  await user.save();
158
- return res.status(200).json({ success: true });
153
+ return res.status(200).json();
159
154
  }
160
155
 
161
156
  async sendPasswordRecoveryEmail(req, res) {
@@ -165,15 +160,13 @@ class Auth extends AbstractController {
165
160
  if (!user) {
166
161
  return res
167
162
  .status(400)
168
- .json({ success: false, error: req.i18n.t('auth.errorUExist') });
163
+ .json({ message: req.i18n.t('auth.errorUExist') });
169
164
  }
170
165
  await user.sendPasswordRecoveryEmail(req.i18n);
171
- return res.status(200).json({ success: true });
166
+ return res.status(200).json();
172
167
  } catch (e) {
173
168
  this.logger.error(e.message);
174
- return res
175
- .status(400)
176
- .json({ success: false, error: req.i18n.t('auth.errorUExist') });
169
+ return res.status(400).json({ message: req.i18n.t('auth.errorUExist') });
177
170
  }
178
171
  }
179
172
 
@@ -190,7 +183,7 @@ class Auth extends AbstractController {
190
183
  if (!user) {
191
184
  return res
192
185
  .status(400)
193
- .json({ success: false, error: req.i18n.t('password.wrongToken') });
186
+ .json({ message: req.i18n.t('password.wrongToken') });
194
187
  }
195
188
 
196
189
  this.logger.debug(`Password recovery user is :${user}`);
@@ -198,23 +191,21 @@ class Auth extends AbstractController {
198
191
  user.password = req.appInfo.request.password;
199
192
  user.isVerified = true;
200
193
  await user.save();
201
- return res.status(200).json({ success: true });
194
+ return res.status(200).json();
202
195
  }
203
196
 
204
197
  async sendVerification(req, res) {
205
198
  const User = this.app.getModel('User');
206
199
  const user = await User.getUserByEmail(req.appInfo.request.email);
207
200
  if (!user) {
208
- return res
209
- .status(400)
210
- .json({ success: false, error: req.i18n.t('auth.errorUExist') });
201
+ return res.status(400).json({ message: req.i18n.t('auth.errorUExist') });
211
202
  }
212
203
  await user.sendVerificationEmail(req.i18n);
213
- return res.status(200).json({ success: true });
204
+ return res.status(200).json();
214
205
  }
215
206
 
216
207
  static get middleware() {
217
- return new Map([['/*', [PrepareAppInfo, GetUserByToken, RateLimiter]]]);
208
+ return new Map([['/*', [GetUserByToken, RateLimiter]]]);
218
209
  }
219
210
  }
220
211
 
@@ -20,10 +20,8 @@ describe('auth', () => {
20
20
  });
21
21
 
22
22
  it('can create user', async () => {
23
- expect.assertions(2);
24
- const { status, body } = await request(
25
- global.server.app.httpServer.express,
26
- )
23
+ expect.assertions(1);
24
+ const { status } = await request(global.server.app.httpServer.express)
27
25
  .post('/auth/register')
28
26
  .send({
29
27
  email: userEmail,
@@ -31,7 +29,6 @@ describe('auth', () => {
31
29
  nickName: 'test',
32
30
  });
33
31
  expect(status).toBe(201);
34
- expect(body.success).toBe(true);
35
32
  });
36
33
 
37
34
  it('can NOT create SAME user', async () => {
@@ -71,7 +68,7 @@ describe('auth', () => {
71
68
  });
72
69
 
73
70
  it('can login with normal creds and verifyed email', async () => {
74
- expect.assertions(3);
71
+ expect.assertions(2);
75
72
 
76
73
  const user = await global.server.app
77
74
  .getModel('User')
@@ -88,14 +85,13 @@ describe('auth', () => {
88
85
  password: userPassword,
89
86
  });
90
87
  expect(status).toBe(200);
91
- expect(body.success).toBe(true);
92
88
  expect(body.token).toBeDefined();
93
89
  });
94
90
  });
95
91
 
96
92
  describe('isAuthWithVefificationFlow auth option', () => {
97
93
  it('can login with normal creds and NOT verifyed email is option isAuthWithVefificationFlow is set', async () => {
98
- expect.assertions(5);
94
+ expect.assertions(4);
99
95
 
100
96
  const { status } = await request(global.server.app.httpServer.express)
101
97
  .post('/auth/register')
@@ -129,7 +125,6 @@ describe('auth', () => {
129
125
  expect(status).toBe(201);
130
126
  expect(status2).toBe(400);
131
127
  expect(status3).toBe(200);
132
- expect(body.success).toBe(true);
133
128
  expect(body.token).toBeDefined();
134
129
  });
135
130
  });
@@ -1,5 +1,4 @@
1
1
  const AbstractController = require('../modules/AbstractController');
2
- const PrepareAppInfo = require('../services/http/middleware/PrepareAppInfo');
3
2
  const GetUserByToken = require('../services/http/middleware/GetUserByToken');
4
3
 
5
4
  class Home extends AbstractController {
@@ -22,7 +21,7 @@ class Home extends AbstractController {
22
21
  }
23
22
 
24
23
  static get middleware() {
25
- return new Map([['/*', [PrepareAppInfo, GetUserByToken]]]);
24
+ return new Map([['/*', [GetUserByToken]]]);
26
25
  }
27
26
  }
28
27
 
package/models/User.js CHANGED
@@ -12,16 +12,6 @@ class User extends AbstractModel {
12
12
  this.saltSecret = authConfig.saltSecret;
13
13
  }
14
14
 
15
- /**
16
- * @deprecated
17
- */
18
- get someSecretSalt() {
19
- this.logger.warn(
20
- 'someSecretSalt deprecatred and will be removed in future release. Please use "this.saltSecret" instead ',
21
- );
22
- return this.saltSecret;
23
- }
24
-
25
15
  initHooks() {
26
16
  this.mongooseSchema.pre('save', async function () {
27
17
  if (this.isModified('password')) {
@@ -69,6 +59,7 @@ class User extends AbstractModel {
69
59
  verificationTokens: [{ until: Date, token: String }],
70
60
  passwordRecoveryTokens: [{ until: Date, token: String }],
71
61
  permissions: [],
62
+ roles: [],
72
63
  isVerified: { type: Boolean, default: false },
73
64
  locale: { type: String, default: 'en' },
74
65
  languages: [String],
@@ -7,6 +7,10 @@ class AbstractCommand extends Base {
7
7
  this.commands = commands;
8
8
  }
9
9
 
10
+ static get description() {
11
+ return 'Command description';
12
+ }
13
+
10
14
  static get loggerGroup() {
11
15
  return 'command';
12
16
  }