beech-api 3.9.0-beta.9-rc → 3.9.80

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.
Files changed (59) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1717 -1649
  3. package/index.js +2 -2
  4. package/package.json +92 -84
  5. package/packages/cli/beech +9 -10
  6. package/packages/cli/bin/beech-app.js +390 -390
  7. package/packages/cli/bin/beech-service.js +263 -170
  8. package/packages/cli/core/auth/Credentials.js +174 -174
  9. package/packages/cli/core/auth/Passport.js +664 -664
  10. package/packages/cli/core/auth/_Request.js +12 -12
  11. package/packages/cli/core/configure/_gitignore +16 -15
  12. package/packages/cli/core/configure/_sequelizerc +9 -9
  13. package/packages/cli/core/configure/app.config-basic.js +55 -55
  14. package/packages/cli/core/configure/app.config-sequelize.js +88 -88
  15. package/packages/cli/core/configure/beech.config.js +9 -9
  16. package/packages/cli/core/configure/global.config-basic.js +8 -8
  17. package/packages/cli/core/configure/global.config-sequelize.js +8 -8
  18. package/packages/cli/core/configure/jest.config.js +6 -6
  19. package/packages/cli/core/configure/jsconfig.json +8 -7
  20. package/packages/cli/core/configure/passport.config.js +97 -97
  21. package/packages/cli/core/databases/mysql.js +94 -95
  22. package/packages/cli/core/databases/sequelize.js +187 -188
  23. package/packages/cli/core/databases/test.js +250 -255
  24. package/packages/cli/core/file-walk/file-walk.js +35 -35
  25. package/packages/cli/core/generator/_endpoints +15 -15
  26. package/packages/cli/core/generator/_endpoints_basic +42 -42
  27. package/packages/cli/core/generator/_help +29 -19
  28. package/packages/cli/core/generator/_help_create +10 -10
  29. package/packages/cli/core/generator/_help_service +10 -10
  30. package/packages/cli/core/generator/_helpers +9 -9
  31. package/packages/cli/core/generator/_helpers_basic +166 -22
  32. package/packages/cli/core/generator/_models +6 -6
  33. package/packages/cli/core/generator/_models_basic +13 -13
  34. package/packages/cli/core/generator/_package +23 -19
  35. package/packages/cli/core/generator/_scheduler +32 -32
  36. package/packages/cli/core/generator/_spec +29 -29
  37. package/packages/cli/core/generator/index.js +1229 -992
  38. package/packages/cli/core/helpers/2fa.js +106 -106
  39. package/packages/cli/core/helpers/math.js +115 -115
  40. package/packages/cli/core/helpers/poolEntity.js +103 -103
  41. package/packages/cli/core/index.js +264 -266
  42. package/packages/cli/core/middleware/express/duplicateRequest.js +16 -16
  43. package/packages/cli/core/middleware/express/jwtCheckAllow.js +85 -85
  44. package/packages/cli/core/middleware/express/rateLimit.js +29 -29
  45. package/packages/cli/core/middleware/express/slowDown.js +2 -2
  46. package/packages/cli/core/middleware/index.js +6 -6
  47. package/packages/cli/core/middleware/origin/guard/advance.js +75 -75
  48. package/packages/cli/core/middleware/origin/whitelist/cors.js +94 -94
  49. package/packages/cli/core/services/http.express.js +481 -481
  50. package/packages/cli/core/test/check-node.js +21 -21
  51. package/packages/cli/core/test/utils.js +7 -7
  52. package/packages/cli/entry +10 -0
  53. package/packages/lib/index.js +6 -6
  54. package/packages/lib/src/endpoint.js +947 -885
  55. package/packages/lib/src/guard.js +60 -60
  56. package/packages/lib/src/salt.js +3 -3
  57. package/packages/lib/src/schema.js +96 -96
  58. package/packages/lib/src/specificExpress.js +7 -7
  59. package/packages/lib/src/user.js +271 -271
@@ -1,664 +1,664 @@
1
- const fs = require("fs");
2
- const passport_config_file = appRoot + "/passport.config.js";
3
- const md5 = require("md5");
4
- const secret = require("../../../lib/src/salt").salt;
5
- const { findPassportPk, checkAuthFields } = require("../helpers/poolEntity");
6
- const { Rand } = require("../helpers/math");
7
- const { QueryTypes } = require("sequelize");
8
-
9
- module.exports = {
10
- init() {
11
- return new Promise((resolve) => {
12
- try {
13
- var passport_config;
14
- const p1 = new Promise((resolve, reject) => {
15
- /**
16
- * Resolve ref:
17
- * [0=passport_file_exists, 1=jwt_allow, 2=db_passport_map_is_connect]
18
- *
19
- */
20
- if (fs.existsSync(passport_config_file)) {
21
- const { byPassCredentials, credentialsGuard } = require("./Credentials");
22
- passport_config = require(passport_config_file);
23
- // Check if the JWT is allow
24
- if (passport_config.jwt_allow === true) {
25
- // Check if the APP_KEY is allow
26
- if(passport_config.app_key_allow) {
27
- // All allow JWT & APP_KEY
28
- //global.Credentials = [credentialsGuard, byPassCredentials]; // perfect
29
- global.Credentials = (..._options) => {
30
- const [option_or_req, res, next] = _options;
31
- if (_options.length === 3) {
32
- // Used as: app.use(Credentials)
33
- return credentialsGuard(option_or_req, res, () => {
34
- return byPassCredentials(option_or_req, res, next);
35
- });
36
- } else if (_options.length === 0) {
37
- // Used as: app.use(Credentials())
38
- return [credentialsGuard, byPassCredentials];
39
- } else {
40
- // Used as: app.use(Credentials([...] ))
41
- return [credentialsGuard, byPassCredentials(option_or_req)];
42
- }
43
- };
44
- } else {
45
- // Only allow JWT
46
- global.Credentials = (..._options) => {
47
- const [option_or_req, res, next] = _options;
48
- if (_options.length === 3) {
49
- // Used as: app.use(Credentials)
50
- return byPassCredentials(option_or_req, res, next);
51
- } else if (_options.length === 0) {
52
- // Used as: app.use(Credentials())
53
- return byPassCredentials;
54
- } else {
55
- // Used as: app.use(Credentials([...]))
56
- return byPassCredentials(option_or_req);
57
- }
58
- };
59
- }
60
- // loop check db connect is true
61
- fs.readFile("./app.config.js", "utf-8", (err, data) => {
62
- if(err) {
63
- reject(err);
64
- } else {
65
- let mineConfDb = eval(data).database_config;
66
- mineConfDb.filter((e, k) => {
67
- if(e.name == passport_config.model.name) {
68
- if(e.is_connect) {
69
- resolve([true, true, true]);
70
- } else {
71
- // Database of Passport mapped is closed.
72
- resolve([true, true, false]);
73
- }
74
- } else {
75
- if(mineConfDb.length == k+1) {
76
- // Database of Passport mapped is Name not match.
77
- resolve([true, true, null]);
78
- }
79
- }
80
- });
81
- }
82
- });
83
- } else if (passport_config.app_key_allow === true) {
84
- // Only allow APP_KEY
85
- global.Credentials = (..._options) => {
86
- const [option_or_req, res, next] = _options;
87
- if (_options.length === 3) {
88
- // Used as: app.use(Credentials)
89
- return credentialsGuard(option_or_req, res, () => {
90
- return next();
91
- });
92
- } else if (_options.length === 0) {
93
- // Used as: app.use(Credentials())
94
- return [credentialsGuard];
95
-
96
- } else {
97
- // Used as: app.use(Credentials([...] ))
98
- return [credentialsGuard];
99
- }
100
- };
101
- // Resolve it
102
- resolve([true, false, null]);
103
- } else {
104
- // Neither APP_KEY nor JWT allow
105
- global.Credentials = (..._options) => {
106
- const [option_or_req, res, next] = _options;
107
- if (_options.length === 3) {
108
- // Used as: app.use(Credentials)
109
- return next();
110
- } else if (_options.length === 0) {
111
- // Used as: app.use(Credentials())
112
- return [];
113
- } else {
114
- // Used as: app.use(Credentials([...] ))
115
- return [];
116
- }
117
- };
118
- // Resolve it
119
- resolve([true, false, null]);
120
- }
121
- } else {
122
- // Passport config file not found
123
- global.Credentials = (..._options) => {
124
- const [option_or_req, res, next] = _options;
125
- if (_options.length === 3) {
126
- // Used as: app.use(Credentials)
127
- return next();
128
- } else {
129
- // Used as: app.use(Credentials() or Credentials([...] ))
130
- return [];
131
- }
132
- };
133
-
134
- // Old logic
135
- //const Requests = require("./_Request");
136
- //global.Credentials = (_options = {}, _res, _next) => [Requests.requests]; // ----> [Closed] TODO check passport.config file if not exists show error when file src/ using the JWT (maybe for show JWT is ON/OFF)
137
-
138
- // Resolve it
139
- resolve([false, null, null]);
140
- }
141
- });
142
- Promise.all([p1]).then(final => {
143
- // Checking passport file, allow, mapped
144
- if(final[0][0] && final[0][1] && final[0][2]) {
145
- var passport = require("passport")
146
- LocalStrategy = require("passport-local").Strategy,
147
- GoogleStrategy = require("passport-google-oauth").OAuth2Strategy,
148
- FacebookStrategy = require('passport-facebook').Strategy;
149
- var passportJWT = require("passport-jwt"),
150
- JWTStrategy = passportJWT.Strategy,
151
- ExtractJWT = passportJWT.ExtractJwt;
152
- // declare constant
153
- var passportUsernameField = passport_config.model.username_field || "username";
154
- var passportPasswordField = passport_config.model.password_field || "password";
155
- var passportTable = passport_config.model.table || "users";
156
- var pool = eval("sql." + passport_config.model.name);
157
- // Check your assign auth fields
158
- checkAuthFields(pool_base, pool, passportTable, passport_config.model.fields, (err, msg) => {
159
- if(err) {
160
- console.log("\n Error ", err);
161
- return;
162
- //throw err;
163
- } else {
164
- // find passport primary key
165
- findPassportPk(pool_base, pool, passportTable, passport_config.model.fields, (err, passportFields) => {
166
- if(err) {
167
- resolve([err, true, true, true]);
168
- } else {
169
- // Passport initial with token (encoder)
170
- passport.use(new LocalStrategy({
171
- usernameField: passportUsernameField,
172
- passwordField: passportPasswordField
173
- }, async (username, password, done) => {
174
- if (pool) {
175
- if (pool_base == "basic") {
176
- // pool base is MySQL
177
- pool.query("SELECT " + passportFields + " FROM ?? WHERE ?? = ? AND ?? = ?", [
178
- passportTable,
179
- passportUsernameField,
180
- username,
181
- passportPasswordField,
182
- md5(password + secret)
183
- ], (err, result) => {
184
- if (err) {
185
- return done(err, null);
186
- } else {
187
- return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
188
- }
189
- });
190
- } else if (pool_base == "sequelize") {
191
- // pool base is Sequelize
192
- try {
193
- let result = await pool.query("SELECT " + passportFields + " FROM " + passportTable + " WHERE " + passportUsernameField + " = :username AND " + passportPasswordField + " = :password", {
194
- replacements: {
195
- fields: passportFields,
196
- username: username,
197
- password: md5(password + secret)
198
- },
199
- type: QueryTypes.SELECT
200
- });
201
- return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
202
- } catch (error) {
203
- return done(error, null);
204
- }
205
- } else {
206
- return done({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
207
- }
208
- } else {
209
- return done(null, null, true);
210
- }
211
- }));
212
-
213
- // Passport jwt payload (decoder)
214
- passport.use(new JWTStrategy({
215
- jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
216
- secretOrKey: passport_config.secret
217
- }, async (jwtPayload, done) => {
218
- let pool = eval("sql." + passport_config.model.name);
219
- if (pool) {
220
- if (pool_base == "basic") {
221
- pool.query("SHOW KEYS FROM " + passportTable + " WHERE Key_name = 'PRIMARY'", (err, pk) => {
222
- if(err) {
223
- return done(err, null);
224
- } else {
225
- let fieldPk = pk[0].Column_name;
226
- // pool base is MySQL
227
- pool.query("SELECT " + passportFields + " FROM ?? WHERE " + fieldPk + " = ?", [
228
- passportTable,
229
- jwtPayload[fieldPk]
230
- ], (err, result) => {
231
- if (err) {
232
- return done(err, null);
233
- } else {
234
- return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
235
- }
236
- });
237
- }
238
- });
239
- } else if (pool_base == "sequelize") {
240
- // pool base is Sequelize
241
- try {
242
- // Function Find table primaryKey
243
- const findPkOfTable = () => {
244
- return new Promise(async (resolve, reject) => {
245
- try {
246
- const tableInfo = await pool.getQueryInterface().describeTable(String(passportTable));
247
- const primaryKeys = Object.entries(tableInfo).filter(([columnName, columnInfo]) => columnInfo.primaryKey).map(([columnName]) => columnName);
248
- if(primaryKeys.length) {
249
- resolve(primaryKeys);
250
- } else {
251
- resolve([Object.keys(tableInfo)[0]]);
252
- }
253
- } catch (error) {
254
- reject(`Query Interface ${error}`);
255
- }
256
- });
257
- }
258
- // Find table primaryKey
259
- findPkOfTable()
260
- .then((fieldPk) => {
261
- pool.query("SELECT " + passportFields + " FROM " + passportTable + " WHERE " + fieldPk + " = :pk", {
262
- replacements: {
263
- pk: + jwtPayload[fieldPk]
264
- },
265
- type: QueryTypes.SELECT,
266
- }).then((result) => {
267
- return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
268
- }).catch((err) => {
269
- return done(err, null);
270
- });
271
- }).catch(err => {
272
- return done(err, null);
273
- });
274
- } catch (error) {
275
- return done(error, null);
276
- }
277
- } else {
278
- return done({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
279
- }
280
- } else {
281
- return done(null, null, true);
282
- }
283
- }));
284
-
285
- // Declare head authentication enpoint for all strategy
286
- let auth_endpoint = (passport_config.auth_endpoint) ? (passport_config.auth_endpoint[ 0 ] === "/" ? passport_config.auth_endpoint : "/" + passport_config.auth_endpoint) : "/authentication";
287
- auth_endpoint = _publicPath_ + auth_endpoint.substr(1);
288
-
289
- /**
290
- * Passport Google Strategy
291
- *
292
- */
293
- let google_callbackURL = (passport_config.strategy.google.callbackURL) ? (passport_config.strategy.google.callbackURL[ 0 ] === "/" ? passport_config.strategy.google.callbackURL : "/" + passport_config.strategy.google.callbackURL) : "/google/callback";
294
- passport.use(new GoogleStrategy({
295
- clientID: passport_config.strategy.google.client_id,
296
- clientSecret: passport_config.strategy.google.client_secret,
297
- callbackURL: auth_endpoint + google_callbackURL
298
- }, (accessToken, refreshToken, profile, done) => {
299
- // find google user
300
- let googleIdField = (passport_config.strategy.google.local_profile_fields.google_id) ? passport_config.strategy.google.local_profile_fields.google_id : "google_id";
301
- this.findOrCreate(passport_config, "google", passportFields, passportTable, accessToken, refreshToken, profile, googleIdField, (err, res, dbFailed) => {
302
- if (err) {
303
- return done(err);
304
- } else {
305
- return done(err, res, dbFailed);
306
- }
307
- });
308
- }));
309
-
310
- /**
311
- * Passport Facebook Strategy
312
- *
313
- */
314
- let facebook_callbackURL = (passport_config.strategy.facebook.callbackURL) ? (passport_config.strategy.facebook.callbackURL[ 0 ] === "/" ? passport_config.strategy.facebook.callbackURL : "/" + passport_config.strategy.facebook.callbackURL) : "/facebook/callback";
315
- // merge fields permisions
316
- let allow_permisions_fields = [ ...new Set([ ...[ 'id', 'displayName', 'name', 'photos', 'email', 'location' ], ...(passport_config.strategy.facebook.profileFieldsAllow || []) ]) ];
317
- passport.use(new FacebookStrategy({
318
- clientID: passport_config.strategy.facebook.app_id,
319
- clientSecret: passport_config.strategy.facebook.app_secret,
320
- callbackURL: auth_endpoint + facebook_callbackURL,
321
- profileFields: allow_permisions_fields
322
- }, (accessToken, refreshToken, profile, done) => {
323
- // Check if the email permission is granted
324
- /**
325
- * Update : Permissions Reference for Meta Technologies APIs.
326
- * Starting on or after October 27, 2023, if your app requests permission to use an endpoint to access an app user’s data
327
- * Learn more : https://developers.facebook.com/docs/permissions
328
- *
329
- * From now! Disabled check if email permission granted
330
- */
331
- //if (!profile.emails || profile.emails.length === 0) {
332
- // return done(new Error('Email permission not granted.'));
333
- //}
334
- // find facebook user
335
- let faecbookIdField = (passport_config.strategy.facebook.local_profile_fields.facebook_id) ? passport_config.strategy.facebook.local_profile_fields.facebook_id : "facebook_id";
336
- this.findOrCreate(passport_config, "facebook", passportFields, passportTable, accessToken, refreshToken, profile, faecbookIdField, (err, res, dbFailed) => {
337
- if (err) {
338
- return done(err);
339
- } else {
340
- return done(err, res, dbFailed);
341
- }
342
- });
343
- }));
344
- // Everything is Perfectly
345
- resolve([null, true, true, true]);
346
- } // end if check err findPassportPk
347
- }); // end findPassportPk
348
- } // end checkAuthFields
349
- });
350
- } else if(final[0][0] && final[0][1] && final[0][2] === false) {
351
- // Database connection mapped is Closed.
352
- resolve([`Database connection name \`${passport_config.model.name}\` is CLOSED. Checking ON/OFF inside app.conifg.js file.`, true, true, false]);
353
- } else if(final[0][0] && final[0][1] && !final[0][2]) {
354
- // Passport Database connection name is NOT MATCH.
355
- resolve([`Connection name \`${passport_config.model.name}\` with Passport model name mapped is NOT MATCH. Checking name to match it.`, true, true, false]);
356
- } else if(final[0][0] && !final[0][1] && final[0][2] === null) {
357
- // JWT not allow
358
- resolve([null, true, false, null]);
359
- } else {
360
- // JWT file not found, Or JWT not intitialize.
361
- resolve([null, false, null, null]);
362
- } // end if check Resolve ref:
363
- }).catch(err => {
364
- throw err;
365
- });
366
- } catch (error) {
367
- throw error;
368
- }
369
- });
370
- },
371
- findOrCreate(passport_config, strategy_name, passportFields, passportTable, accessToken, refreshToken, profile, idField, cb) {
372
- let pool = eval("sql." + passport_config.model.name);
373
- if (pool) {
374
- this.query_one_where(pool, "SELECT " + passportFields + " FROM " + passportTable, idField, profile.id, async (err, result) => {
375
- if (err) {
376
- cb(err, null);
377
- } else {
378
- // declare data response
379
- let data = {};
380
- // prepare data for store
381
- let usr = passport_config.model.username_field || "username";
382
- let psw = passport_config.model.password_field || "password";
383
- let usrProfile = Rand(10);
384
- let md5Psw = md5(profile.id + secret);
385
- // check strategy name for store
386
- if (strategy_name == "google") {
387
- if (!result[ 0 ]) { // find not found and create
388
- // filter fields
389
- let fields = [].concat.apply([], [
390
- (passport_config.strategy.google.local_profile_fields.name) ? passport_config.strategy.google.local_profile_fields.name : null,
391
- (passport_config.strategy.google.local_profile_fields.email) ? passport_config.strategy.google.local_profile_fields.email : null,
392
- (passport_config.strategy.google.local_profile_fields.photos) ? passport_config.strategy.google.local_profile_fields.photos : null,
393
- (passport_config.strategy.google.local_profile_fields.locate) ? passport_config.strategy.google.local_profile_fields.locate : null
394
- ].filter((el) => el != null));
395
- // fileter values
396
- let values = [].concat.apply([], [
397
- (passport_config.strategy.google.local_profile_fields.name) ? profile.displayName : null,
398
- (passport_config.strategy.google.local_profile_fields.email) ? profile.emails[ 0 ].value : null,
399
- (passport_config.strategy.google.local_profile_fields.photos) ? profile.photos[ 0 ].value : null,
400
- (passport_config.strategy.google.local_profile_fields.locate) ? profile._json.locale : null
401
- ].filter((el) => el != null));
402
- // Store google profile
403
- if (pool_base == "basic") {
404
- // check null and remove it.
405
- let basicReplacement = new Set([
406
- passportTable,
407
- usr,
408
- psw,
409
- idField,
410
- fields,
411
- usrProfile,
412
- md5Psw,
413
- profile.id,
414
- values
415
- ]);
416
- delete basicReplacement.delete(null);
417
- basicReplacement = Array.from(basicReplacement).filter(e => JSON.stringify(e) !== '[]');
418
- // pool base is MySQL
419
- pool.query("INSERT INTO ??(??,??,??" + (fields.length ? ",??)" : ")") + " VALUES(?,?,?" + (values.length ? ",?)" : ")"), basicReplacement, (err, result) => {
420
- data.result = result;
421
- data.google = profile;
422
- cb(err, data);
423
- });
424
- } else if (pool_base == "sequelize") {
425
- // check null and remove it.
426
- let sequelizeReplacement = new Set([
427
- passportTable,
428
- usr,
429
- psw,
430
- idField,
431
- fields,
432
- usrProfile,
433
- md5Psw,
434
- profile.id,
435
- values
436
- ]);
437
- sequelizeReplacement = Array.from(sequelizeReplacement).filter(e => JSON.stringify(e) !== '[]');
438
- // pool base is Sequelize
439
- try {
440
- let result = await pool.query(`INSERT INTO ${passportTable}(${usr},${psw},${idField}${fields.length ? ',' + fields + ')' : ')'} VALUES(:usrProfile,:md5Psw,:profileId${values.length ? ',:values)' : ')'}`, {
441
- replacements: {
442
- usr: sequelizeReplacement[1],
443
- psw: sequelizeReplacement[2],
444
- idField: sequelizeReplacement[3],
445
- usrProfile: usrProfile,
446
- md5Psw: md5Psw,
447
- profileId: profile.id,
448
- values: values.length ? values : []
449
- },
450
- type: QueryTypes.INSERT
451
- });
452
- data.result = result;
453
- data.google = profile;
454
- cb(err, data);
455
- } catch (error) {
456
- if(pool.options.logging) {
457
- return cb(error, null);
458
- } else {
459
- if(error.sql) {
460
- delete error.sql;
461
- if(error.errors) {
462
- delete error.errors;
463
- }
464
- if(error.parent) {
465
- delete error.parent;
466
- }
467
- if(error.original) {
468
- delete error.original.sql;
469
- }
470
- if(error.parameters) {
471
- delete error.parameters;
472
- }
473
- return cb(error, null);
474
- } else {
475
- return cb(String(error), null);
476
- }
477
- }
478
- }
479
- } else {
480
- cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
481
- }
482
- } else { // find found
483
- let users = {};
484
- users.google = profile;
485
- users.google.accessToken = accessToken;
486
- users.google.refreshToken = refreshToken;
487
- users.user = result[ 0 ];
488
- cb(err, users);
489
- }
490
- } else if (strategy_name == "facebook") {
491
- // STEP 1: check email empty for username
492
- if(passport_config.strategy.facebook.local_profile_fields.email) { // Now support only Google, Because Facebook requests permission: https://developers.facebook.com/docs/permissions
493
- if(!profile.emails) {
494
- return cb(JSON.stringify({
495
- code: 500,
496
- status: "ERR_FACEBOOK_PROFILE_PERMISSIONS",
497
- error: "Facebook needed allow `email` and `public_profile` permisions: https://developers.facebook.com/docs/permissions"
498
- }), null);
499
- }
500
- }
501
- // STEP 2: find not found and create
502
- if (!result[ 0 ]) {
503
- // filter fields
504
- let fields = [].concat.apply([], [
505
- (passport_config.strategy.facebook.local_profile_fields.name) ? passport_config.strategy.facebook.local_profile_fields.name : null,
506
- (passport_config.strategy.facebook.local_profile_fields.email) ? passport_config.strategy.facebook.local_profile_fields.email : null,
507
- (passport_config.strategy.facebook.local_profile_fields.photos) ? passport_config.strategy.facebook.local_profile_fields.photos : null,
508
- (passport_config.strategy.facebook.local_profile_fields.locate) ? passport_config.strategy.facebook.local_profile_fields.locate : null
509
- ].filter((el) => el != null));
510
- // fileter values
511
- let values = [].concat.apply([], [
512
- (passport_config.strategy.facebook.local_profile_fields.name) ? profile.displayName : null,
513
- (passport_config.strategy.facebook.local_profile_fields.email) ? (profile.emails) ? profile.emails[ 0 ].value : null : null,
514
- (passport_config.strategy.facebook.local_profile_fields.photos) ? profile.photos[ 0 ].value : null,
515
- (passport_config.strategy.facebook.local_profile_fields.locate) ? profile._json.location.name : null
516
- ].filter((el) => el != null));
517
- // Store facebook profile
518
- if (pool_base == "basic") {
519
- // check null and remove it.
520
- let basicReplacement = new Set([
521
- passportTable,
522
- usr,
523
- psw,
524
- idField,
525
- fields,
526
- usrProfile,
527
- md5Psw,
528
- profile.id,
529
- values
530
- ]);
531
- delete basicReplacement.delete(null);
532
- basicReplacement = Array.from(basicReplacement).filter(e => JSON.stringify(e) !== '[]');
533
- // pool base is MySQL
534
- pool.query("INSERT INTO ??(??,??,??" + (fields.length ? ",??)" : ")") + " VALUES(?,?,?" + (values.length ? ",?)" : ")"), basicReplacement, (err, result) => {
535
- data.result = result;
536
- data.facebook = profile;
537
- cb(err, data);
538
- });
539
- } else if (pool_base == "sequelize") {
540
- // check null and remove it.
541
- let sequelizeReplacement = new Set([
542
- passportTable,
543
- usr,
544
- psw,
545
- idField,
546
- fields,
547
- usrProfile,
548
- md5Psw,
549
- profile.id,
550
- values
551
- ]);
552
- sequelizeReplacement = Array.from(sequelizeReplacement).filter(e => JSON.stringify(e) !== '[]');
553
- // pool base is Sequelize
554
- try {
555
- let result = await pool.query(`INSERT INTO ${passportTable}(${usr},${psw},${idField}${fields.length ? ',' + fields + ')' : ')'} VALUES(:usrProfile,:md5Psw,:profileId${values.length ? ',:values)' : ')'}`, {
556
- replacements: {
557
- usr: sequelizeReplacement[1],
558
- psw: sequelizeReplacement[2],
559
- idField: sequelizeReplacement[3],
560
- usrProfile: usrProfile,
561
- md5Psw: md5Psw,
562
- profileId: profile.id,
563
- values: values.length ? values : []
564
- },
565
- type: QueryTypes.INSERT
566
- });
567
- data.result = result;
568
- data.facebook = profile;
569
- cb(err, data);
570
- } catch (error) {
571
- if(pool.options.logging) {
572
- return cb(error, null);
573
- } else {
574
- if(error.sql) {
575
- delete error.sql;
576
- if(error.errors) {
577
- delete error.errors;
578
- }
579
- if(error.parent) {
580
- delete error.parent;
581
- }
582
- if(error.original) {
583
- delete error.original.sql;
584
- }
585
- if(error.parameters) {
586
- delete error.parameters;
587
- }
588
- return cb(error, null);
589
- } else {
590
- return cb(String(error), null);
591
- }
592
- }
593
- }
594
- } else {
595
- cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
596
- }
597
- } else { // find found
598
- let users = {};
599
- users.facebook = profile;
600
- users.facebook.accessToken = accessToken;
601
- users.facebook.refreshToken = refreshToken;
602
- users.user = result[ 0 ];
603
- cb(err, users);
604
- }
605
- }
606
- }
607
- });
608
- } else {
609
- cb(null, null, true);
610
- }
611
- },
612
- async query_one_where(pool, sql, field, id, cb) {
613
- try {
614
- if (pool_base == "basic") {
615
- // pool base is MySQL
616
- pool.query(sql + " WHERE ?? = ?", [ field, id ], (err, result) => {
617
- if (err) {
618
- return cb(err, null);
619
- } else {
620
- return cb(null, JSON.parse(JSON.stringify(result || null)));
621
- }
622
- });
623
- } else if (pool_base == "sequelize") {
624
- // pool base is Sequelize
625
- try {
626
- let result = await pool.query(`${sql} WHERE ${field} = :id`, {
627
- replacements: {
628
- id: id
629
- },
630
- type: QueryTypes.SELECT
631
- });
632
- return cb(null, JSON.parse(JSON.stringify(result || null)));
633
- } catch (error) {
634
- if(pool.options.logging) {
635
- return cb(error, null);
636
- } else {
637
- if(error.sql) {
638
- delete error.sql;
639
- if(error.errors) {
640
- delete error.errors;
641
- }
642
- if(error.parent) {
643
- delete error.parent;
644
- }
645
- if(error.original) {
646
- delete error.original.sql;
647
- }
648
- if(error.parameters) {
649
- delete error.parameters;
650
- }
651
- return cb(error, null);
652
- } else {
653
- return cb(String(error), null);
654
- }
655
- }
656
- }
657
- } else {
658
- return done({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
659
- }
660
- } catch (error) {
661
- cb(error, null);
662
- }
663
- },
664
- }
1
+ const fs = require("fs");
2
+ const passport_config_file = appRoot + "/passport.config.js";
3
+ const md5 = require("md5");
4
+ const secret = require("../../../lib/src/salt").salt;
5
+ const { findPassportPk, checkAuthFields } = require("../helpers/poolEntity");
6
+ const { Rand } = require("../helpers/math");
7
+ const { QueryTypes } = require("sequelize");
8
+
9
+ module.exports = {
10
+ init() {
11
+ return new Promise((resolve) => {
12
+ try {
13
+ var passport_config;
14
+ const p1 = new Promise((resolve, reject) => {
15
+ /**
16
+ * Resolve ref:
17
+ * [0=passport_file_exists, 1=jwt_allow, 2=db_passport_map_is_connect]
18
+ *
19
+ */
20
+ if (fs.existsSync(passport_config_file)) {
21
+ const { byPassCredentials, credentialsGuard } = require("./Credentials");
22
+ passport_config = require(passport_config_file);
23
+ // Check if the JWT is allow
24
+ if (passport_config.jwt_allow === true) {
25
+ // Check if the APP_KEY is allow
26
+ if(passport_config.app_key_allow) {
27
+ // All allow JWT & APP_KEY
28
+ //global.Credentials = [credentialsGuard, byPassCredentials]; // perfect
29
+ global.Credentials = (..._options) => {
30
+ const [option_or_req, res, next] = _options;
31
+ if (_options.length === 3) {
32
+ // Used as: app.use(Credentials)
33
+ return credentialsGuard(option_or_req, res, () => {
34
+ return byPassCredentials(option_or_req, res, next);
35
+ });
36
+ } else if (_options.length === 0) {
37
+ // Used as: app.use(Credentials())
38
+ return [credentialsGuard, byPassCredentials];
39
+ } else {
40
+ // Used as: app.use(Credentials([...] ))
41
+ return [credentialsGuard, byPassCredentials(option_or_req)];
42
+ }
43
+ };
44
+ } else {
45
+ // Only allow JWT
46
+ global.Credentials = (..._options) => {
47
+ const [option_or_req, res, next] = _options;
48
+ if (_options.length === 3) {
49
+ // Used as: app.use(Credentials)
50
+ return byPassCredentials(option_or_req, res, next);
51
+ } else if (_options.length === 0) {
52
+ // Used as: app.use(Credentials())
53
+ return byPassCredentials;
54
+ } else {
55
+ // Used as: app.use(Credentials([...]))
56
+ return byPassCredentials(option_or_req);
57
+ }
58
+ };
59
+ }
60
+ // loop check db connect is true
61
+ fs.readFile("./app.config.js", "utf-8", (err, data) => {
62
+ if(err) {
63
+ reject(err);
64
+ } else {
65
+ let mineConfDb = eval(data).database_config;
66
+ mineConfDb.filter((e, k) => {
67
+ if(e.name == passport_config.model.name) {
68
+ if(e.is_connect) {
69
+ resolve([true, true, true]);
70
+ } else {
71
+ // Database of Passport mapped is closed.
72
+ resolve([true, true, false]);
73
+ }
74
+ } else {
75
+ if(mineConfDb.length == k+1) {
76
+ // Database of Passport mapped is Name not match.
77
+ resolve([true, true, null]);
78
+ }
79
+ }
80
+ });
81
+ }
82
+ });
83
+ } else if (passport_config.app_key_allow === true) {
84
+ // Only allow APP_KEY
85
+ global.Credentials = (..._options) => {
86
+ const [option_or_req, res, next] = _options;
87
+ if (_options.length === 3) {
88
+ // Used as: app.use(Credentials)
89
+ return credentialsGuard(option_or_req, res, () => {
90
+ return next();
91
+ });
92
+ } else if (_options.length === 0) {
93
+ // Used as: app.use(Credentials())
94
+ return [credentialsGuard];
95
+
96
+ } else {
97
+ // Used as: app.use(Credentials([...] ))
98
+ return [credentialsGuard];
99
+ }
100
+ };
101
+ // Resolve it
102
+ resolve([true, false, null]);
103
+ } else {
104
+ // Neither APP_KEY nor JWT allow
105
+ global.Credentials = (..._options) => {
106
+ const [option_or_req, res, next] = _options;
107
+ if (_options.length === 3) {
108
+ // Used as: app.use(Credentials)
109
+ return next();
110
+ } else if (_options.length === 0) {
111
+ // Used as: app.use(Credentials())
112
+ return [];
113
+ } else {
114
+ // Used as: app.use(Credentials([...] ))
115
+ return [];
116
+ }
117
+ };
118
+ // Resolve it
119
+ resolve([true, false, null]);
120
+ }
121
+ } else {
122
+ // Passport config file not found
123
+ global.Credentials = (..._options) => {
124
+ const [option_or_req, res, next] = _options;
125
+ if (_options.length === 3) {
126
+ // Used as: app.use(Credentials)
127
+ return next();
128
+ } else {
129
+ // Used as: app.use(Credentials() or Credentials([...] ))
130
+ return [];
131
+ }
132
+ };
133
+
134
+ // Old logic
135
+ //const Requests = require("./_Request");
136
+ //global.Credentials = (_options = {}, _res, _next) => [Requests.requests]; // ----> [Closed] TODO check passport.config file if not exists show error when file src/ using the JWT (maybe for show JWT is ON/OFF)
137
+
138
+ // Resolve it
139
+ resolve([false, null, null]);
140
+ }
141
+ });
142
+ Promise.all([p1]).then(final => {
143
+ // Checking passport file, allow, mapped
144
+ if(final[0][0] && final[0][1] && final[0][2]) {
145
+ var passport = require("passport")
146
+ LocalStrategy = require("passport-local").Strategy,
147
+ GoogleStrategy = require("passport-google-oauth").OAuth2Strategy,
148
+ FacebookStrategy = require('passport-facebook').Strategy;
149
+ var passportJWT = require("passport-jwt"),
150
+ JWTStrategy = passportJWT.Strategy,
151
+ ExtractJWT = passportJWT.ExtractJwt;
152
+ // declare constant
153
+ var passportUsernameField = passport_config.model.username_field || "username";
154
+ var passportPasswordField = passport_config.model.password_field || "password";
155
+ var passportTable = passport_config.model.table || "users";
156
+ var pool = eval("sql." + passport_config.model.name);
157
+ // Check your assign auth fields
158
+ checkAuthFields(pool_base, pool, passportTable, passport_config.model.fields, (err, msg) => {
159
+ if(err) {
160
+ console.log("\n Error ", err);
161
+ return;
162
+ //throw err;
163
+ } else {
164
+ // find passport primary key
165
+ findPassportPk(pool_base, pool, passportTable, passport_config.model.fields, (err, passportFields) => {
166
+ if(err) {
167
+ resolve([err, true, true, true]);
168
+ } else {
169
+ // Passport initial with token (encoder)
170
+ passport.use(new LocalStrategy({
171
+ usernameField: passportUsernameField,
172
+ passwordField: passportPasswordField
173
+ }, async (username, password, done) => {
174
+ if (pool) {
175
+ if (pool_base == "basic") {
176
+ // pool base is MySQL
177
+ pool.query("SELECT " + passportFields + " FROM ?? WHERE ?? = ? AND ?? = ?", [
178
+ passportTable,
179
+ passportUsernameField,
180
+ username,
181
+ passportPasswordField,
182
+ md5(password + secret)
183
+ ], (err, result) => {
184
+ if (err) {
185
+ return done(err, null);
186
+ } else {
187
+ return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
188
+ }
189
+ });
190
+ } else if (pool_base == "sequelize") {
191
+ // pool base is Sequelize
192
+ try {
193
+ let result = await pool.query("SELECT " + passportFields + " FROM " + passportTable + " WHERE " + passportUsernameField + " = :username AND " + passportPasswordField + " = :password", {
194
+ replacements: {
195
+ fields: passportFields,
196
+ username: username,
197
+ password: md5(password + secret)
198
+ },
199
+ type: QueryTypes.SELECT
200
+ });
201
+ return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
202
+ } catch (error) {
203
+ return done(error, null);
204
+ }
205
+ } else {
206
+ return done({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
207
+ }
208
+ } else {
209
+ return done(null, null, true);
210
+ }
211
+ }));
212
+
213
+ // Passport jwt payload (decoder)
214
+ passport.use(new JWTStrategy({
215
+ jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
216
+ secretOrKey: passport_config.secret
217
+ }, async (jwtPayload, done) => {
218
+ let pool = eval("sql." + passport_config.model.name);
219
+ if (pool) {
220
+ if (pool_base == "basic") {
221
+ pool.query("SHOW KEYS FROM " + passportTable + " WHERE Key_name = 'PRIMARY'", (err, pk) => {
222
+ if(err) {
223
+ return done(err, null);
224
+ } else {
225
+ let fieldPk = pk[0].Column_name;
226
+ // pool base is MySQL
227
+ pool.query("SELECT " + passportFields + " FROM ?? WHERE " + fieldPk + " = ?", [
228
+ passportTable,
229
+ jwtPayload[fieldPk]
230
+ ], (err, result) => {
231
+ if (err) {
232
+ return done(err, null);
233
+ } else {
234
+ return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
235
+ }
236
+ });
237
+ }
238
+ });
239
+ } else if (pool_base == "sequelize") {
240
+ // pool base is Sequelize
241
+ try {
242
+ // Function Find table primaryKey
243
+ const findPkOfTable = () => {
244
+ return new Promise(async (resolve, reject) => {
245
+ try {
246
+ const tableInfo = await pool.getQueryInterface().describeTable(String(passportTable));
247
+ const primaryKeys = Object.entries(tableInfo).filter(([columnName, columnInfo]) => columnInfo.primaryKey).map(([columnName]) => columnName);
248
+ if(primaryKeys.length) {
249
+ resolve(primaryKeys);
250
+ } else {
251
+ resolve([Object.keys(tableInfo)[0]]);
252
+ }
253
+ } catch (error) {
254
+ reject(`Query Interface ${error}`);
255
+ }
256
+ });
257
+ }
258
+ // Find table primaryKey
259
+ findPkOfTable()
260
+ .then((fieldPk) => {
261
+ pool.query("SELECT " + passportFields + " FROM " + passportTable + " WHERE " + fieldPk + " = :pk", {
262
+ replacements: {
263
+ pk: + jwtPayload[fieldPk]
264
+ },
265
+ type: QueryTypes.SELECT,
266
+ }).then((result) => {
267
+ return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
268
+ }).catch((err) => {
269
+ return done(err, null);
270
+ });
271
+ }).catch(err => {
272
+ return done(err, null);
273
+ });
274
+ } catch (error) {
275
+ return done(error, null);
276
+ }
277
+ } else {
278
+ return done({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
279
+ }
280
+ } else {
281
+ return done(null, null, true);
282
+ }
283
+ }));
284
+
285
+ // Declare head authentication enpoint for all strategy
286
+ let auth_endpoint = (passport_config.auth_endpoint) ? (passport_config.auth_endpoint[ 0 ] === "/" ? passport_config.auth_endpoint : "/" + passport_config.auth_endpoint) : "/authentication";
287
+ auth_endpoint = _publicPath_ + auth_endpoint.substr(1);
288
+
289
+ /**
290
+ * Passport Google Strategy
291
+ *
292
+ */
293
+ let google_callbackURL = (passport_config.strategy.google.callbackURL) ? (passport_config.strategy.google.callbackURL[ 0 ] === "/" ? passport_config.strategy.google.callbackURL : "/" + passport_config.strategy.google.callbackURL) : "/google/callback";
294
+ passport.use(new GoogleStrategy({
295
+ clientID: passport_config.strategy.google.client_id,
296
+ clientSecret: passport_config.strategy.google.client_secret,
297
+ callbackURL: auth_endpoint + google_callbackURL
298
+ }, (accessToken, refreshToken, profile, done) => {
299
+ // find google user
300
+ let googleIdField = (passport_config.strategy.google.local_profile_fields.google_id) ? passport_config.strategy.google.local_profile_fields.google_id : "google_id";
301
+ this.findOrCreate(passport_config, "google", passportFields, passportTable, accessToken, refreshToken, profile, googleIdField, (err, res, dbFailed) => {
302
+ if (err) {
303
+ return done(err);
304
+ } else {
305
+ return done(err, res, dbFailed);
306
+ }
307
+ });
308
+ }));
309
+
310
+ /**
311
+ * Passport Facebook Strategy
312
+ *
313
+ */
314
+ let facebook_callbackURL = (passport_config.strategy.facebook.callbackURL) ? (passport_config.strategy.facebook.callbackURL[ 0 ] === "/" ? passport_config.strategy.facebook.callbackURL : "/" + passport_config.strategy.facebook.callbackURL) : "/facebook/callback";
315
+ // merge fields permisions
316
+ let allow_permisions_fields = [ ...new Set([ ...[ 'id', 'displayName', 'name', 'photos', 'email', 'location' ], ...(passport_config.strategy.facebook.profileFieldsAllow || []) ]) ];
317
+ passport.use(new FacebookStrategy({
318
+ clientID: passport_config.strategy.facebook.app_id,
319
+ clientSecret: passport_config.strategy.facebook.app_secret,
320
+ callbackURL: auth_endpoint + facebook_callbackURL,
321
+ profileFields: allow_permisions_fields
322
+ }, (accessToken, refreshToken, profile, done) => {
323
+ // Check if the email permission is granted
324
+ /**
325
+ * Update : Permissions Reference for Meta Technologies APIs.
326
+ * Starting on or after October 27, 2023, if your app requests permission to use an endpoint to access an app user’s data
327
+ * Learn more : https://developers.facebook.com/docs/permissions
328
+ *
329
+ * From now! Disabled check if email permission granted
330
+ */
331
+ //if (!profile.emails || profile.emails.length === 0) {
332
+ // return done(new Error('Email permission not granted.'));
333
+ //}
334
+ // find facebook user
335
+ let faecbookIdField = (passport_config.strategy.facebook.local_profile_fields.facebook_id) ? passport_config.strategy.facebook.local_profile_fields.facebook_id : "facebook_id";
336
+ this.findOrCreate(passport_config, "facebook", passportFields, passportTable, accessToken, refreshToken, profile, faecbookIdField, (err, res, dbFailed) => {
337
+ if (err) {
338
+ return done(err);
339
+ } else {
340
+ return done(err, res, dbFailed);
341
+ }
342
+ });
343
+ }));
344
+ // Everything is Perfectly
345
+ resolve([null, true, true, true]);
346
+ } // end if check err findPassportPk
347
+ }); // end findPassportPk
348
+ } // end checkAuthFields
349
+ });
350
+ } else if(final[0][0] && final[0][1] && final[0][2] === false) {
351
+ // Database connection mapped is Closed.
352
+ resolve([`Database connection name \`${passport_config.model.name}\` is CLOSED. Checking ON/OFF inside app.conifg.js file.`, true, true, false]);
353
+ } else if(final[0][0] && final[0][1] && !final[0][2]) {
354
+ // Passport Database connection name is NOT MATCH.
355
+ resolve([`Connection name \`${passport_config.model.name}\` with Passport model name mapped is NOT MATCH. Checking name to match it.`, true, true, false]);
356
+ } else if(final[0][0] && !final[0][1] && final[0][2] === null) {
357
+ // JWT not allow
358
+ resolve([null, true, false, null]);
359
+ } else {
360
+ // JWT file not found, Or JWT not intitialize.
361
+ resolve([null, false, null, null]);
362
+ } // end if check Resolve ref:
363
+ }).catch(err => {
364
+ throw err;
365
+ });
366
+ } catch (error) {
367
+ throw error;
368
+ }
369
+ });
370
+ },
371
+ findOrCreate(passport_config, strategy_name, passportFields, passportTable, accessToken, refreshToken, profile, idField, cb) {
372
+ let pool = eval("sql." + passport_config.model.name);
373
+ if (pool) {
374
+ this.query_one_where(pool, "SELECT " + passportFields + " FROM " + passportTable, idField, profile.id, async (err, result) => {
375
+ if (err) {
376
+ cb(err, null);
377
+ } else {
378
+ // declare data response
379
+ let data = {};
380
+ // prepare data for store
381
+ let usr = passport_config.model.username_field || "username";
382
+ let psw = passport_config.model.password_field || "password";
383
+ let usrProfile = Rand(10);
384
+ let md5Psw = md5(profile.id + secret);
385
+ // check strategy name for store
386
+ if (strategy_name == "google") {
387
+ if (!result[ 0 ]) { // find not found and create
388
+ // filter fields
389
+ let fields = [].concat.apply([], [
390
+ (passport_config.strategy.google.local_profile_fields.name) ? passport_config.strategy.google.local_profile_fields.name : null,
391
+ (passport_config.strategy.google.local_profile_fields.email) ? passport_config.strategy.google.local_profile_fields.email : null,
392
+ (passport_config.strategy.google.local_profile_fields.photos) ? passport_config.strategy.google.local_profile_fields.photos : null,
393
+ (passport_config.strategy.google.local_profile_fields.locate) ? passport_config.strategy.google.local_profile_fields.locate : null
394
+ ].filter((el) => el != null));
395
+ // fileter values
396
+ let values = [].concat.apply([], [
397
+ (passport_config.strategy.google.local_profile_fields.name) ? profile.displayName : null,
398
+ (passport_config.strategy.google.local_profile_fields.email) ? profile.emails[ 0 ].value : null,
399
+ (passport_config.strategy.google.local_profile_fields.photos) ? profile.photos[ 0 ].value : null,
400
+ (passport_config.strategy.google.local_profile_fields.locate) ? profile._json.locale : null
401
+ ].filter((el) => el != null));
402
+ // Store google profile
403
+ if (pool_base == "basic") {
404
+ // check null and remove it.
405
+ let basicReplacement = new Set([
406
+ passportTable,
407
+ usr,
408
+ psw,
409
+ idField,
410
+ fields,
411
+ usrProfile,
412
+ md5Psw,
413
+ profile.id,
414
+ values
415
+ ]);
416
+ delete basicReplacement.delete(null);
417
+ basicReplacement = Array.from(basicReplacement).filter(e => JSON.stringify(e) !== '[]');
418
+ // pool base is MySQL
419
+ pool.query("INSERT INTO ??(??,??,??" + (fields.length ? ",??)" : ")") + " VALUES(?,?,?" + (values.length ? ",?)" : ")"), basicReplacement, (err, result) => {
420
+ data.result = result;
421
+ data.google = profile;
422
+ cb(err, data);
423
+ });
424
+ } else if (pool_base == "sequelize") {
425
+ // check null and remove it.
426
+ let sequelizeReplacement = new Set([
427
+ passportTable,
428
+ usr,
429
+ psw,
430
+ idField,
431
+ fields,
432
+ usrProfile,
433
+ md5Psw,
434
+ profile.id,
435
+ values
436
+ ]);
437
+ sequelizeReplacement = Array.from(sequelizeReplacement).filter(e => JSON.stringify(e) !== '[]');
438
+ // pool base is Sequelize
439
+ try {
440
+ let result = await pool.query(`INSERT INTO ${passportTable}(${usr},${psw},${idField}${fields.length ? ',' + fields + ')' : ')'} VALUES(:usrProfile,:md5Psw,:profileId${values.length ? ',:values)' : ')'}`, {
441
+ replacements: {
442
+ usr: sequelizeReplacement[1],
443
+ psw: sequelizeReplacement[2],
444
+ idField: sequelizeReplacement[3],
445
+ usrProfile: usrProfile,
446
+ md5Psw: md5Psw,
447
+ profileId: profile.id,
448
+ values: values.length ? values : []
449
+ },
450
+ type: QueryTypes.INSERT
451
+ });
452
+ data.result = result;
453
+ data.google = profile;
454
+ cb(err, data);
455
+ } catch (error) {
456
+ if(pool.options.logging) {
457
+ return cb(error, null);
458
+ } else {
459
+ if(error.sql) {
460
+ delete error.sql;
461
+ if(error.errors) {
462
+ delete error.errors;
463
+ }
464
+ if(error.parent) {
465
+ delete error.parent;
466
+ }
467
+ if(error.original) {
468
+ delete error.original.sql;
469
+ }
470
+ if(error.parameters) {
471
+ delete error.parameters;
472
+ }
473
+ return cb(error, null);
474
+ } else {
475
+ return cb(String(error), null);
476
+ }
477
+ }
478
+ }
479
+ } else {
480
+ cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
481
+ }
482
+ } else { // find found
483
+ let users = {};
484
+ users.google = profile;
485
+ users.google.accessToken = accessToken;
486
+ users.google.refreshToken = refreshToken;
487
+ users.user = result[ 0 ];
488
+ cb(err, users);
489
+ }
490
+ } else if (strategy_name == "facebook") {
491
+ // STEP 1: check email empty for username
492
+ if(passport_config.strategy.facebook.local_profile_fields.email) { // Now support only Google, Because Facebook requests permission: https://developers.facebook.com/docs/permissions
493
+ if(!profile.emails) {
494
+ return cb(JSON.stringify({
495
+ code: 500,
496
+ status: "ERR_FACEBOOK_PROFILE_PERMISSIONS",
497
+ error: "Facebook needed allow `email` and `public_profile` permisions: https://developers.facebook.com/docs/permissions"
498
+ }), null);
499
+ }
500
+ }
501
+ // STEP 2: find not found and create
502
+ if (!result[ 0 ]) {
503
+ // filter fields
504
+ let fields = [].concat.apply([], [
505
+ (passport_config.strategy.facebook.local_profile_fields.name) ? passport_config.strategy.facebook.local_profile_fields.name : null,
506
+ (passport_config.strategy.facebook.local_profile_fields.email) ? passport_config.strategy.facebook.local_profile_fields.email : null,
507
+ (passport_config.strategy.facebook.local_profile_fields.photos) ? passport_config.strategy.facebook.local_profile_fields.photos : null,
508
+ (passport_config.strategy.facebook.local_profile_fields.locate) ? passport_config.strategy.facebook.local_profile_fields.locate : null
509
+ ].filter((el) => el != null));
510
+ // fileter values
511
+ let values = [].concat.apply([], [
512
+ (passport_config.strategy.facebook.local_profile_fields.name) ? profile.displayName : null,
513
+ (passport_config.strategy.facebook.local_profile_fields.email) ? (profile.emails) ? profile.emails[ 0 ].value : null : null,
514
+ (passport_config.strategy.facebook.local_profile_fields.photos) ? profile.photos[ 0 ].value : null,
515
+ (passport_config.strategy.facebook.local_profile_fields.locate) ? profile._json.location.name : null
516
+ ].filter((el) => el != null));
517
+ // Store facebook profile
518
+ if (pool_base == "basic") {
519
+ // check null and remove it.
520
+ let basicReplacement = new Set([
521
+ passportTable,
522
+ usr,
523
+ psw,
524
+ idField,
525
+ fields,
526
+ usrProfile,
527
+ md5Psw,
528
+ profile.id,
529
+ values
530
+ ]);
531
+ delete basicReplacement.delete(null);
532
+ basicReplacement = Array.from(basicReplacement).filter(e => JSON.stringify(e) !== '[]');
533
+ // pool base is MySQL
534
+ pool.query("INSERT INTO ??(??,??,??" + (fields.length ? ",??)" : ")") + " VALUES(?,?,?" + (values.length ? ",?)" : ")"), basicReplacement, (err, result) => {
535
+ data.result = result;
536
+ data.facebook = profile;
537
+ cb(err, data);
538
+ });
539
+ } else if (pool_base == "sequelize") {
540
+ // check null and remove it.
541
+ let sequelizeReplacement = new Set([
542
+ passportTable,
543
+ usr,
544
+ psw,
545
+ idField,
546
+ fields,
547
+ usrProfile,
548
+ md5Psw,
549
+ profile.id,
550
+ values
551
+ ]);
552
+ sequelizeReplacement = Array.from(sequelizeReplacement).filter(e => JSON.stringify(e) !== '[]');
553
+ // pool base is Sequelize
554
+ try {
555
+ let result = await pool.query(`INSERT INTO ${passportTable}(${usr},${psw},${idField}${fields.length ? ',' + fields + ')' : ')'} VALUES(:usrProfile,:md5Psw,:profileId${values.length ? ',:values)' : ')'}`, {
556
+ replacements: {
557
+ usr: sequelizeReplacement[1],
558
+ psw: sequelizeReplacement[2],
559
+ idField: sequelizeReplacement[3],
560
+ usrProfile: usrProfile,
561
+ md5Psw: md5Psw,
562
+ profileId: profile.id,
563
+ values: values.length ? values : []
564
+ },
565
+ type: QueryTypes.INSERT
566
+ });
567
+ data.result = result;
568
+ data.facebook = profile;
569
+ cb(err, data);
570
+ } catch (error) {
571
+ if(pool.options.logging) {
572
+ return cb(error, null);
573
+ } else {
574
+ if(error.sql) {
575
+ delete error.sql;
576
+ if(error.errors) {
577
+ delete error.errors;
578
+ }
579
+ if(error.parent) {
580
+ delete error.parent;
581
+ }
582
+ if(error.original) {
583
+ delete error.original.sql;
584
+ }
585
+ if(error.parameters) {
586
+ delete error.parameters;
587
+ }
588
+ return cb(error, null);
589
+ } else {
590
+ return cb(String(error), null);
591
+ }
592
+ }
593
+ }
594
+ } else {
595
+ cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
596
+ }
597
+ } else { // find found
598
+ let users = {};
599
+ users.facebook = profile;
600
+ users.facebook.accessToken = accessToken;
601
+ users.facebook.refreshToken = refreshToken;
602
+ users.user = result[ 0 ];
603
+ cb(err, users);
604
+ }
605
+ }
606
+ }
607
+ });
608
+ } else {
609
+ cb(null, null, true);
610
+ }
611
+ },
612
+ async query_one_where(pool, sql, field, id, cb) {
613
+ try {
614
+ if (pool_base == "basic") {
615
+ // pool base is MySQL
616
+ pool.query(sql + " WHERE ?? = ?", [ field, id ], (err, result) => {
617
+ if (err) {
618
+ return cb(err, null);
619
+ } else {
620
+ return cb(null, JSON.parse(JSON.stringify(result || null)));
621
+ }
622
+ });
623
+ } else if (pool_base == "sequelize") {
624
+ // pool base is Sequelize
625
+ try {
626
+ let result = await pool.query(`${sql} WHERE ${field} = :id`, {
627
+ replacements: {
628
+ id: id
629
+ },
630
+ type: QueryTypes.SELECT
631
+ });
632
+ return cb(null, JSON.parse(JSON.stringify(result || null)));
633
+ } catch (error) {
634
+ if(pool.options.logging) {
635
+ return cb(error, null);
636
+ } else {
637
+ if(error.sql) {
638
+ delete error.sql;
639
+ if(error.errors) {
640
+ delete error.errors;
641
+ }
642
+ if(error.parent) {
643
+ delete error.parent;
644
+ }
645
+ if(error.original) {
646
+ delete error.original.sql;
647
+ }
648
+ if(error.parameters) {
649
+ delete error.parameters;
650
+ }
651
+ return cb(error, null);
652
+ } else {
653
+ return cb(String(error), null);
654
+ }
655
+ }
656
+ }
657
+ } else {
658
+ return done({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
659
+ }
660
+ } catch (error) {
661
+ cb(error, null);
662
+ }
663
+ },
664
+ }