@vulkano/core 0.1.0
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/.eslintignore +8 -0
- package/.gitattributes +108 -0
- package/.nvmrc +1 -0
- package/LICENSE +9 -0
- package/README.md +121 -0
- package/bootstrap/responses.js +32 -0
- package/bootstrap/server.js +619 -0
- package/bootstrap/services.js +42 -0
- package/bun.lockb +0 -0
- package/controllers/ScaffoldController.js +108 -0
- package/controllers/controllers.js +149 -0
- package/database/models.js +90 -0
- package/database/mongodb.js +232 -0
- package/database/scaffold.js +118 -0
- package/init.js +254 -0
- package/libs/Crontab.js +19 -0
- package/libs/Encrypter.js +45 -0
- package/libs/Filter.js +55 -0
- package/libs/Jwt.js +220 -0
- package/libs/VSError.js +33 -0
- package/libs/filters/ltrim.js +24 -0
- package/libs/filters/number.js +14 -0
- package/libs/filters/objectId.js +14 -0
- package/libs/filters/prefix.js +22 -0
- package/libs/filters/rtrim.js +24 -0
- package/libs/filters/saveinteger.js +21 -0
- package/libs/filters/suffix.js +19 -0
- package/libs/filters/trim.js +15 -0
- package/libs/i18n.js +51 -0
- package/package.json +67 -0
- package/responses/vsr.js +87 -0
package/init.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap.js
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const dotenv = require('dotenv');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const moment = require('moment');
|
|
9
|
+
const merge = require('deepmerge');
|
|
10
|
+
const _ = require('underscore');
|
|
11
|
+
const Promise = require('bluebird');
|
|
12
|
+
const v8 = require('v8');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
|
|
15
|
+
global.app = {};
|
|
16
|
+
global._ = _;
|
|
17
|
+
global.Promise = Promise;
|
|
18
|
+
|
|
19
|
+
if (!global.ABS_PATH) {
|
|
20
|
+
global.ABS_PATH = path.resolve(__dirname, '');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!global.APP_PATH) {
|
|
24
|
+
global.APP_PATH = path.join(__dirname, '../app');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!global.PUBLIC_PATH) {
|
|
28
|
+
global.PUBLIC_PATH = path.join(__dirname, '../public');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
global.CORE_PATH = path.join(__dirname, '');
|
|
32
|
+
|
|
33
|
+
if (!fs.existsSync(APP_PATH)) {
|
|
34
|
+
console.log('the global var APP_PATH or directory not found');
|
|
35
|
+
global.APP_PATH = path.resolve(__dirname, '');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!fs.existsSync(PUBLIC_PATH)) {
|
|
39
|
+
console.log('the global var PUBLIC_PATH or directory not found');
|
|
40
|
+
global.PUBLIC_PATH = path.resolve(__dirname, '');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Read Dontenv config
|
|
44
|
+
dotenv.config();
|
|
45
|
+
|
|
46
|
+
// Include all api config
|
|
47
|
+
const config = require('include-all')({
|
|
48
|
+
dirname: `${APP_PATH}/config`,
|
|
49
|
+
filter: /(.+)\.js$/,
|
|
50
|
+
optional: true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Get package.json information
|
|
54
|
+
const pkg = require(`${CORE_PATH}/package.json`);
|
|
55
|
+
const appPkg = require(`${ABS_PATH}/package.json`);
|
|
56
|
+
|
|
57
|
+
// Environment
|
|
58
|
+
const NODE_ENV = (process.env.NODE_ENV || 'development').toLowerCase();
|
|
59
|
+
|
|
60
|
+
app.PRODUCTION = NODE_ENV === 'production' ? true : false;
|
|
61
|
+
|
|
62
|
+
const {
|
|
63
|
+
views,
|
|
64
|
+
local,
|
|
65
|
+
env
|
|
66
|
+
} = config || {};
|
|
67
|
+
|
|
68
|
+
// NODE_ENV
|
|
69
|
+
const environmentConfig = env ? env[NODE_ENV] || {} : {};
|
|
70
|
+
|
|
71
|
+
// Merge Settings
|
|
72
|
+
const settings = {
|
|
73
|
+
...config.settings,
|
|
74
|
+
views: views?.config || ''
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// All config merged (default, NODE_ENV (folder env), local.js file)
|
|
78
|
+
const allConfig = merge.all([
|
|
79
|
+
// General Config
|
|
80
|
+
config || {},
|
|
81
|
+
|
|
82
|
+
// Settings Config
|
|
83
|
+
{ settings },
|
|
84
|
+
|
|
85
|
+
// Environment Config
|
|
86
|
+
environmentConfig,
|
|
87
|
+
|
|
88
|
+
// Local Config
|
|
89
|
+
local || {}
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
delete allConfig.env;
|
|
93
|
+
delete allConfig.local;
|
|
94
|
+
|
|
95
|
+
// General Settings
|
|
96
|
+
app.config = allConfig;
|
|
97
|
+
|
|
98
|
+
// Package Config
|
|
99
|
+
app.pkg = pkg;
|
|
100
|
+
|
|
101
|
+
// Include all components
|
|
102
|
+
require('./bootstrap/services')();
|
|
103
|
+
require('./database/mongodb')();
|
|
104
|
+
|
|
105
|
+
const controllers = require('./controllers/controllers')();
|
|
106
|
+
const server = require('./bootstrap/server');
|
|
107
|
+
|
|
108
|
+
const colors = {
|
|
109
|
+
reset: '\x1b[0m',
|
|
110
|
+
bright: '\x1b[1m',
|
|
111
|
+
dim: '\x1b[2m',
|
|
112
|
+
underscore: '\x1b[4m',
|
|
113
|
+
blink: '\x1b[5m',
|
|
114
|
+
reverse: '\x1b[7m',
|
|
115
|
+
hidden: '\x1b[8m',
|
|
116
|
+
fg: {
|
|
117
|
+
black: '\x1b[30m',
|
|
118
|
+
red: '\x1b[31m',
|
|
119
|
+
green: '\x1b[32m',
|
|
120
|
+
yellow: '\x1b[33m',
|
|
121
|
+
blue: '\x1b[34m',
|
|
122
|
+
magenta: '\x1b[35m',
|
|
123
|
+
cyan: '\x1b[36m',
|
|
124
|
+
white: '\x1b[37m',
|
|
125
|
+
crimson: '\x1b[38m' // Scarlet
|
|
126
|
+
},
|
|
127
|
+
bg: {
|
|
128
|
+
black: '\x1b[40m',
|
|
129
|
+
red: '\x1b[41m',
|
|
130
|
+
green: '\x1b[42m',
|
|
131
|
+
yellow: '\x1b[43m',
|
|
132
|
+
blue: '\x1b[44m',
|
|
133
|
+
magenta: '\x1b[45m',
|
|
134
|
+
cyan: '\x1b[46m',
|
|
135
|
+
white: '\x1b[47m',
|
|
136
|
+
crimson: '\x1b[48m'
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
function startVulkano() {
|
|
141
|
+
|
|
142
|
+
console.log('');
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log(`${colors.fg.magenta}------------------------------------------`, colors.reset);
|
|
145
|
+
console.log('');
|
|
146
|
+
console.log(colors.fg.cyan, ' 🌋', colors.reset);
|
|
147
|
+
console.log(colors.fg.cyan, ` APP VERSION ${appPkg.version}`, colors.reset);
|
|
148
|
+
console.log(colors.fg.cyan, ` VULKANO ${pkg.version}`, colors.reset);
|
|
149
|
+
console.log('');
|
|
150
|
+
console.log(colors.fg.blue, '🔗 https://github.com/vulkanojs/vulkano', colors.reset);
|
|
151
|
+
console.log(colors.fg.cyan, '☕ https://buymeacoffee.com/argordmel', colors.reset);
|
|
152
|
+
console.log('');
|
|
153
|
+
console.log(`${colors.fg.magenta}------------------------------------------`, colors.reset);
|
|
154
|
+
|
|
155
|
+
// Routes
|
|
156
|
+
app.routes = controllers;
|
|
157
|
+
|
|
158
|
+
// Server Config
|
|
159
|
+
app.server = {
|
|
160
|
+
...server,
|
|
161
|
+
...app.config.settings
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Server Routes
|
|
165
|
+
app.server.routes = {
|
|
166
|
+
...app.config.routes
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const {
|
|
170
|
+
bootstrap
|
|
171
|
+
} = config;
|
|
172
|
+
|
|
173
|
+
if (!bootstrap || typeof bootstrap !== 'function') {
|
|
174
|
+
console.log('Missing the boostrap file to start app: app/config/bootstrap.js');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
bootstrap( (callbackAfterInitVulkano) => {
|
|
179
|
+
|
|
180
|
+
// Start Express
|
|
181
|
+
app.server.start( () => {
|
|
182
|
+
|
|
183
|
+
const {
|
|
184
|
+
sockets,
|
|
185
|
+
settings: configSettings,
|
|
186
|
+
redis
|
|
187
|
+
} = app.config || {};
|
|
188
|
+
|
|
189
|
+
const {
|
|
190
|
+
database
|
|
191
|
+
} = configSettings || {};
|
|
192
|
+
|
|
193
|
+
const {
|
|
194
|
+
connection
|
|
195
|
+
} = database || {};
|
|
196
|
+
|
|
197
|
+
const connectionToShow = connection && process.env.MONGO_URI ? 'MONGO_URI' : connection;
|
|
198
|
+
|
|
199
|
+
const serverConfig = [];
|
|
200
|
+
|
|
201
|
+
const nodeVersion = process.version.match(/^v(\d+\.\d+\.\d+)/)[1];
|
|
202
|
+
const portText = String(app.server.get('port') || 8000).padEnd(nodeVersion.length, ' ');
|
|
203
|
+
const socketText = (sockets.enabled ? 'YES' : 'NO').padEnd(nodeVersion.length - 3, ' ');
|
|
204
|
+
|
|
205
|
+
serverConfig.push(` PORT: ${colors.fg.green}${portText}${colors.reset}`);
|
|
206
|
+
serverConfig.push(' | ');
|
|
207
|
+
serverConfig.push(` ENV: ${app.PRODUCTION ? colors.fg.red : colors.fg.green}${env}${colors.reset}`);
|
|
208
|
+
|
|
209
|
+
console.log(serverConfig.join(''));
|
|
210
|
+
|
|
211
|
+
const totalHeapSize = v8.getHeapStatistics().total_available_size;
|
|
212
|
+
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
|
|
213
|
+
|
|
214
|
+
const nodeConfig = [];
|
|
215
|
+
nodeConfig.push(` NODE: ${colors.fg.green}${nodeVersion}${colors.reset}`);
|
|
216
|
+
nodeConfig.push(' | ');
|
|
217
|
+
nodeConfig.push(' MAX MEM: ', `${colors.fg.green}${totalHeapSizeGb} GB${colors.reset}`);
|
|
218
|
+
console.log(nodeConfig.join(''));
|
|
219
|
+
|
|
220
|
+
const startUpConfig = [];
|
|
221
|
+
if (sockets.redis && redis && redis.enabled) {
|
|
222
|
+
startUpConfig.push(' SOCKETS: ', `${colors.fg.green}${socketText}${colors.reset}`);
|
|
223
|
+
} else {
|
|
224
|
+
startUpConfig.push(' SOCKETS: ', `${colors.fg.green}${socketText}${colors.reset}`);
|
|
225
|
+
}
|
|
226
|
+
startUpConfig.push(' | ');
|
|
227
|
+
startUpConfig.push(` STARTUP: ${colors.fg.green}${moment(moment().diff(global.START_TIME)).format('ss.SSS')} sec${colors.reset}`);
|
|
228
|
+
console.log(startUpConfig.join(''));
|
|
229
|
+
|
|
230
|
+
const dbConfig = [];
|
|
231
|
+
if (redis && redis.enabled) {
|
|
232
|
+
dbConfig.push(' REDIS: ', `${colors.fg.green}YES ${colors.reset}`);
|
|
233
|
+
} else {
|
|
234
|
+
dbConfig.push(' REDIS: ', `${colors.fg.green}NO ${colors.reset}`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
dbConfig.push(' | ');
|
|
238
|
+
dbConfig.push(' DB: ', connection ? `${colors.fg.green}${connectionToShow}${colors.reset}` : `${colors.fg.blue}The connection is empty${colors.reset}`);
|
|
239
|
+
console.log(dbConfig.join(''));
|
|
240
|
+
|
|
241
|
+
console.log(`${colors.fg.magenta}--------------------------------------`, colors.reset);
|
|
242
|
+
|
|
243
|
+
// Run custom callback after init vulkano
|
|
244
|
+
if (callbackAfterInitVulkano && typeof callbackAfterInitVulkano === 'function') {
|
|
245
|
+
callbackAfterInitVulkano();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
module.exports = startVulkano;
|
package/libs/Crontab.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const Cron = require('cron').CronJob;
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
|
|
5
|
+
schedule(start, task, end, timeZone) {
|
|
6
|
+
|
|
7
|
+
const config = {
|
|
8
|
+
cronTime: start,
|
|
9
|
+
onTick: task || ( () => {} ),
|
|
10
|
+
onComplete: end || ( () => {} ),
|
|
11
|
+
timeZone: timeZone || 'America/New_York',
|
|
12
|
+
start: true
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
return new Cron(config);
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const crypto = require('crypto');
|
|
2
|
+
|
|
3
|
+
class Encrypter {
|
|
4
|
+
|
|
5
|
+
constructor(encryptionKey) {
|
|
6
|
+
|
|
7
|
+
this.algorithm = 'aes-256-cbc';
|
|
8
|
+
this.key = crypto.scryptSync(encryptionKey, 'salt', 32);
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
encrypt(clearText) {
|
|
13
|
+
|
|
14
|
+
const iv = crypto.randomBytes(16);
|
|
15
|
+
const cipher = crypto.createCipheriv(this.algorithm, this.key, iv);
|
|
16
|
+
const encrypted = cipher.update(clearText, 'utf8', 'hex');
|
|
17
|
+
|
|
18
|
+
return [
|
|
19
|
+
encrypted + cipher.final('hex'),
|
|
20
|
+
Buffer.from(iv).toString('hex'),
|
|
21
|
+
].join('|');
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
dencrypt(encryptedText) {
|
|
26
|
+
|
|
27
|
+
const [encrypted, iv] = encryptedText.split('|');
|
|
28
|
+
|
|
29
|
+
if (!iv) {
|
|
30
|
+
throw new VSError('IV not found', 500);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const decipher = crypto.createDecipheriv(
|
|
34
|
+
this.algorithm,
|
|
35
|
+
this.key,
|
|
36
|
+
Buffer.from(iv, 'hex')
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8');
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = Encrypter;
|
package/libs/Filter.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter
|
|
3
|
+
*
|
|
4
|
+
* Filter.get(' custom string', 'trim');
|
|
5
|
+
* return 'custom
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
// Include all api controllers
|
|
11
|
+
const coreFilters = require('include-all')({
|
|
12
|
+
dirname: path.join(CORE_PATH, '/libs/filters'),
|
|
13
|
+
filter: /(.+)\.js$/,
|
|
14
|
+
optional: true
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const appFilters = require('include-all')({
|
|
18
|
+
dirname: path.join(APP_PATH, '/services/filters'),
|
|
19
|
+
filter: /(.+)\.js$/,
|
|
20
|
+
optional: true
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const allFilters = { ...coreFilters, ...appFilters };
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
|
|
27
|
+
get(str, filters, opts) {
|
|
28
|
+
|
|
29
|
+
let result = null;
|
|
30
|
+
|
|
31
|
+
if (Array.isArray(filters)) {
|
|
32
|
+
filters.forEach((filter) => {
|
|
33
|
+
const f = Filter.load(filter);
|
|
34
|
+
result = (!f) ? '' : f.exec(str, opts);
|
|
35
|
+
});
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const f = Filter.load(filters);
|
|
40
|
+
return (!f) ? '' : f.exec(str, opts);
|
|
41
|
+
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
load(filter) {
|
|
45
|
+
|
|
46
|
+
if (!allFilters[filter]) {
|
|
47
|
+
console.error('FILTER', filter, 'NOT FOUND INTO /app/services/filters');
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return allFilters[filter];
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
};
|
package/libs/Jwt.js
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
const { expressjwt: JWT } = require('express-jwt');
|
|
2
|
+
const jwtSimple = require('jwt-simple');
|
|
3
|
+
const moment = require('moment');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get JWT config
|
|
9
|
+
*
|
|
10
|
+
* @returns {Object}
|
|
11
|
+
*/
|
|
12
|
+
getConfig() {
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
jwt,
|
|
16
|
+
// Express config folder in app/confg/express
|
|
17
|
+
express
|
|
18
|
+
} = app.config || {};
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
jwt: expressJwt,
|
|
22
|
+
} = express || {};
|
|
23
|
+
|
|
24
|
+
return jwt || expressJwt || {};
|
|
25
|
+
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Init JWT for Express
|
|
30
|
+
*
|
|
31
|
+
* @param {Object} opts
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
init(opts) {
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
key,
|
|
38
|
+
algorithms
|
|
39
|
+
} = this.getConfig();
|
|
40
|
+
|
|
41
|
+
const config = {
|
|
42
|
+
|
|
43
|
+
algorithms: algorithms || ['HS256'],
|
|
44
|
+
|
|
45
|
+
secret: key,
|
|
46
|
+
|
|
47
|
+
getToken: (req) => this.getToken(req)
|
|
48
|
+
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return JWT({ ...config, ...opts });
|
|
52
|
+
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get token from request
|
|
57
|
+
*
|
|
58
|
+
* @param {Express} req
|
|
59
|
+
* @returns {String}
|
|
60
|
+
*/
|
|
61
|
+
getToken(req) {
|
|
62
|
+
|
|
63
|
+
const {
|
|
64
|
+
header,
|
|
65
|
+
queryParameter,
|
|
66
|
+
cookieName
|
|
67
|
+
} = this.getConfig();
|
|
68
|
+
|
|
69
|
+
// Get Token via HTTP header
|
|
70
|
+
const headerToken = req.headers[header] || req.headers[header.toUpperCase()] || null;
|
|
71
|
+
|
|
72
|
+
// Get Token via Cookie
|
|
73
|
+
const cookieToken = req.cookies && req.cookies[cookieName]
|
|
74
|
+
? req.cookies[cookieName]
|
|
75
|
+
: null;
|
|
76
|
+
|
|
77
|
+
// Get Token via Query Parameter
|
|
78
|
+
const queryToken = req.query && req.query[queryParameter]
|
|
79
|
+
? req.query[queryParameter]
|
|
80
|
+
: null;
|
|
81
|
+
|
|
82
|
+
// Current Token
|
|
83
|
+
const token = headerToken || cookieToken || queryToken || null;
|
|
84
|
+
|
|
85
|
+
// Decode Token
|
|
86
|
+
const hasData = this.decode(token);
|
|
87
|
+
|
|
88
|
+
// Return only if token is valid
|
|
89
|
+
return hasData ? token : null;
|
|
90
|
+
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Encode token
|
|
95
|
+
*
|
|
96
|
+
* @param {String} data
|
|
97
|
+
* @returns {Object}
|
|
98
|
+
*/
|
|
99
|
+
encode(data) {
|
|
100
|
+
|
|
101
|
+
const {
|
|
102
|
+
key
|
|
103
|
+
} = this.getConfig();
|
|
104
|
+
|
|
105
|
+
const Encrypt = new Encrypter(`${key}-JWT`);
|
|
106
|
+
const payload = Encrypt.encrypt(JSON.stringify({ data }));
|
|
107
|
+
|
|
108
|
+
return jwtSimple.encode(payload, key);
|
|
109
|
+
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Decode token
|
|
114
|
+
*
|
|
115
|
+
* @param {String} token
|
|
116
|
+
* @param {String} customKey Optional Key
|
|
117
|
+
* @returns {Object}
|
|
118
|
+
*/
|
|
119
|
+
decode(token, customKey) {
|
|
120
|
+
|
|
121
|
+
const {
|
|
122
|
+
key
|
|
123
|
+
} = this.getConfig();
|
|
124
|
+
|
|
125
|
+
let data = {};
|
|
126
|
+
try {
|
|
127
|
+
|
|
128
|
+
const payload = jwtSimple.decode(token, customKey || key);
|
|
129
|
+
data = this.decrypt(payload);
|
|
130
|
+
|
|
131
|
+
} catch (e) {
|
|
132
|
+
console.log('Invalid Token');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const {
|
|
136
|
+
expiration
|
|
137
|
+
} = data || {};
|
|
138
|
+
|
|
139
|
+
const now = moment().format('x');
|
|
140
|
+
|
|
141
|
+
// Token expired
|
|
142
|
+
if (expiration && ( Number(now) > Number(expiration) )) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Expiration must be required
|
|
147
|
+
if (!expiration) {
|
|
148
|
+
console.log('JWT Without expiration date');
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return data;
|
|
153
|
+
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Decryp Token
|
|
158
|
+
*
|
|
159
|
+
* @param {String} str
|
|
160
|
+
* @returns {String}
|
|
161
|
+
*/
|
|
162
|
+
decrypt(str) {
|
|
163
|
+
|
|
164
|
+
const {
|
|
165
|
+
key
|
|
166
|
+
} = this.getConfig();
|
|
167
|
+
|
|
168
|
+
const Encrypt = new Encrypter(`${key}-JWT`);
|
|
169
|
+
|
|
170
|
+
let data = null;
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
|
|
174
|
+
const r = JSON.parse(Encrypt.dencrypt(str));
|
|
175
|
+
|
|
176
|
+
const {
|
|
177
|
+
data: result
|
|
178
|
+
} = r || {};
|
|
179
|
+
|
|
180
|
+
data = result;
|
|
181
|
+
|
|
182
|
+
} catch (e) {
|
|
183
|
+
data = null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return data;
|
|
187
|
+
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Decode token from SocketIO
|
|
192
|
+
*
|
|
193
|
+
* @param {Socket} socket
|
|
194
|
+
* @returns {Object}
|
|
195
|
+
*/
|
|
196
|
+
socket(socket) {
|
|
197
|
+
|
|
198
|
+
const {
|
|
199
|
+
token
|
|
200
|
+
} = socket.handshake.auth || {};
|
|
201
|
+
|
|
202
|
+
if (token === null || typeof token === 'undefined' || !token) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const data = this.decode(token);
|
|
207
|
+
|
|
208
|
+
const {
|
|
209
|
+
_id
|
|
210
|
+
} = data || {};
|
|
211
|
+
|
|
212
|
+
if (!_id) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return data;
|
|
217
|
+
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
};
|
package/libs/VSError.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const Promise = require('bluebird');
|
|
2
|
+
|
|
3
|
+
function VSError(msg, code, props) {
|
|
4
|
+
|
|
5
|
+
Error.captureStackTrace(this, this.constructor);
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
stack
|
|
9
|
+
} = props || {};
|
|
10
|
+
|
|
11
|
+
this.message = msg;
|
|
12
|
+
this.statusCode = code || 500;
|
|
13
|
+
this.customProps = props || {};
|
|
14
|
+
|
|
15
|
+
if (app.PRODUCTION || stack === false ) {
|
|
16
|
+
delete this.stack;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Not Found Object
|
|
22
|
+
VSError.notFound = (n) => {
|
|
23
|
+
const name = n || 'Object';
|
|
24
|
+
return Promise.reject(new VSError(`${name} Not Found`, 404));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Reject request
|
|
28
|
+
VSError.reject = (text, status, props) => Promise.reject(new VSError(text, status, props));
|
|
29
|
+
|
|
30
|
+
// Extending of native error object
|
|
31
|
+
require('util').inherits(VSError, Error);
|
|
32
|
+
|
|
33
|
+
module.exports = VSError;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter ltrim
|
|
3
|
+
*
|
|
4
|
+
* Filter.get('custom string', 'ltrim', 'cus');
|
|
5
|
+
* return 'tom string'
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
module.exports = {
|
|
9
|
+
|
|
10
|
+
exec: (_str, opt) => {
|
|
11
|
+
let str = _str || '';
|
|
12
|
+
if (opt) {
|
|
13
|
+
while (str.charAt(0) === opt) {
|
|
14
|
+
str = str.substr(1, str.length - 1);
|
|
15
|
+
}
|
|
16
|
+
} else {
|
|
17
|
+
while (str.charAt(0) === ' ') {
|
|
18
|
+
str = str.substr(1, str.length - 1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return str;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter Object ID
|
|
3
|
+
*
|
|
4
|
+
* Filter.get('new ObjectId("aiuijdñjñ8987987")', 'objectId');
|
|
5
|
+
* return 'aiuijdñjñ8987987'
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
module.exports = {
|
|
9
|
+
|
|
10
|
+
exec: (_id) => {
|
|
11
|
+
return String(_id || '').replace(/ObjectId\("(.*)"\)/, '$1');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter prefix
|
|
3
|
+
*
|
|
4
|
+
* Filter.get('custom string', 'prefix', '/');
|
|
5
|
+
* return '/custom string'
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
module.exports = {
|
|
9
|
+
|
|
10
|
+
exec: (_str, opt) => {
|
|
11
|
+
|
|
12
|
+
const str = _str || '';
|
|
13
|
+
|
|
14
|
+
if (str.indexOf(opt) === 0) {
|
|
15
|
+
return str;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return opt + str;
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
};
|