diff --git a/core/passport.js b/core/passport.js index a057267..51f7b9d 100644 --- a/core/passport.js +++ b/core/passport.js @@ -5,13 +5,25 @@ const { Strategy: JWTStrategy} = require('passport-jwt'); const models = require('./models'); const securityHelper = require('../helpers/security.helper'); +const authService = require('../modules/auth/auth.service'); +/** + * Validación sobre firebase + */ +var admin = require('firebase-admin'); +var serviceAccount = require('../firebase-key.json'); +admin.initializeApp({ + credential: admin.credential.cert(serviceAccount), + databaseURL: "https://app-lqdvi-v2.firebaseio.com" +}); passport.serializeUser((user, done) => { + console.log('serializarUsuario'); done(null, user.id); }); passport.deserializeUser((id, done) => { + console.log('desserializarUsuario'); models.User.findById(id, (err, user) => { done(err, user); }); @@ -20,16 +32,14 @@ passport.deserializeUser((id, done) => { /** * Sign in using Email and Password. */ -const localOptions = { +const localEmailOptions = { usernameField: 'email', - passwordField: 'password' + passwordField: 'password', } -passport.use('local', new LocalStrategy(localOptions, async (email, password, done) => { +passport.use('local-email', new LocalStrategy(localEmailOptions, async (email, password, done) => { try { - const user = await models.User.findOne({ - where: { email }, - }); + const user = await authService.extraMethods.findUser({ email }); if (_.isNull(user)) { return done(null, false, { message: 'User not found' }) @@ -48,6 +58,44 @@ passport.use('local', new LocalStrategy(localOptions, async (email, password, do } })); + +/** + * Register using phone. + */ +const localPhoneOptions = { + usernameField: 'phone', + passwordField: 'fbuid', + } + +passport.use('local-phone', new LocalStrategy(localPhoneOptions, async (phone, fbuid, done) => { + try { + const user = await authService.extraMethods.findUser({ phone, fbuid }); + + if (_.isNull(user)) { + admin.auth().getUserByPhoneNumber(phone) + .then(function(userRecord) { + if (userRecord && userRecord.toJSON().uid == fbuid) { + console.log(userRecord.toJSON()); + console.log('DEBO COMPROBAR EL ESTADO DEL MOVIL SI ESTA HABILITADO O NO'); + const user = authService.extraMethods.createUser({phone, fbuid}); + console.log('dar de alta el usuario') + } + else { + console.log("Me quieres engañar "); + return done(null, false, { message: 'User not validate in fb' }) + } + }) + .catch(function (error) { + return done(null, user, error); + }) + } else { + return done(null, user, { message: 'User found' }); + } + } catch (error) { + return done(null, false, error); + } +})); + // JWT passport.use('jwt', new JWTStrategy(securityHelper.jwtOptions, async (jwtPayload, done) => { try { diff --git a/core/router.js b/core/router.js index ec20d46..bb39ffd 100644 --- a/core/router.js +++ b/core/router.js @@ -22,12 +22,12 @@ module.exports = function () { description: 'Welcome, this is the API for the application.' }); }); - + glob.sync("**/*.routes.js", globOptions) .forEach(function (file) { router.use('/v2', require(file)); }); - + return router; } diff --git a/firebase-key.json b/firebase-key.json new file mode 100755 index 0000000..545837e --- /dev/null +++ b/firebase-key.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "app-lqdvi-v2", + "private_key_id": "fcbc32506a4b848e597c2cb6fa3e0600edb9c6e4", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDA3Ck9wFW06+8h\nw0V1wxWwdGP5/EIRoTEWCWNnUtZZEmhAdqAMDtt25pRyxdLe5GMnG7GkF1YULJbr\n0qpKnEAv0zgbHRF3dR1ZgyF0fRGSXbpPCTVsJiqdbuSwhBjjawq2tXn9Au7ElExa\nhVV6wDCRNDDjNUYri3AWq4oV9zdWt5PKNHL2VvTtkaJIvouKJzIXHzqWvQme7eep\nKtLMw0UE9qqdrd147lT6R+uVGBg6dv+C71oQHnccOdnSwH0gn3QjP/9H2LbGr4Ck\nbIfrNc7L/kj/zFXOs1mEjMMBv2MI2loXKejDSk5vlR9sGtoFuNtQtCHwclsCOSFt\nqw6y5EYnAgMBAAECggEAN8jW4wY5pEHkYws1EbmSkf4wlvQI9kl+RcYEazQSTSRe\nZFsLs0Eu6OcMRGCFPLSqG3tOuEyJuP8mzmKaoEcu58Z8QZd4YGnPSf98k1HD3ebf\nh5H90mD9zZjwbEBhZJKnQC8g8HbDMrhEl6Bel8l0ouOKSoYz3E+SZfRLVkwyRRIG\nU1aBrpC7XAfao/EcL30ui132xZyGB69zcjrE4erO0MX4VgKveQbD3xgmLalcqJwv\nnw5dBc+FCkRtlN5o04PfELxX4ZPjJ79tt7Dm0qCpgZDza49JgNMW98iv14jitUzJ\nwDQTRnyCDABh58KiaTMcy1vYI69xa3uTkNZ11bkLQQKBgQD3cb5BAAJ/k5pKRggX\n4AmzdeuvIQCztEXsH27H9guNcrd3ZdikdRghnOCtxa/51U53IbE2Sh9XDqlpz1mf\n6BL4nFDn9SaX4wq86TC654GFQdv0iOqBoCir9ue6iJNN/GGMBOMiPA2/sZtO67eW\nE5YhJ9D8ZXc6IMBvIxyWFN7NwQKBgQDHh0OgfVtagDAmCiFOJbs8FclWADwibyuc\nMykOheIeTnMthPiNDR/quborZjLU/cMvL3jDHKQ8B9huwNumOXNuLt8luFIwBJty\nZfbD3xft3gS91XqlZMLtaxPZpKPz2hYV7DkMYUctsqjxgvdy+Jqid14PDq0++FJB\nQ//rxnnd5wKBgQDSM4zUeOama8QhHlbXuVlkW2ModZe8EQNpL9aTBYAQ3Afg5OLh\n6hriyvrOg+YXDM5IQ5XgMZ1n/iuKmDthrOsYyOmt8sKjOpsvmcTssaeEhUsN85WL\nInwKgYefHVBNan2PTcOJnIxtcLonk/R0CBV7+u/8yVE8TwBKKQCqufX/wQKBgQCv\nAgKcIzfcknEo/FuoGso2cnmNGFmmblIXCHyrg10I7hByTZ5gwbFMBam4ZUSSsx3f\nJklLAbU//jWlNz2xd9S6QRxzDk/wVCowViTyOpzXg5QvGa8goNekvPXFQXaY7aHP\nismjBTQUbg9m/lOioVGozQBQPrRQdihXnJg9qnG74wKBgQCDo/1cAnHRAFVd5N6s\nfMDwWSfEwA0CgRFHkI1VaTkNMFM0FU6zwdR20AigZX5Kqhe1ZbyLMr8beVHZHSsq\ncP8sOVASPEUYFDiQ//MTFT3D/Sy7LZofHK8O3Fr8CqOZWyvPbuzuvzzgWaDNawEO\n987LMdYXa0ltrwoaec8NSivaAw==\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-bkks5@app-lqdvi-v2.iam.gserviceaccount.com", + "client_id": "104083247388089731991", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-bkks5%40app-lqdvi-v2.iam.gserviceaccount.com" +} diff --git a/helpers/security.helper.js b/helpers/security.helper.js index 37da9ea..51cda5d 100644 --- a/helpers/security.helper.js +++ b/helpers/security.helper.js @@ -7,6 +7,7 @@ const config = require('../config'); const privateKEY = fs.readFileSync(path.join(__dirname, '..', 'private.key'), 'utf8'); const publicKEY = fs.readFileSync(path.join(__dirname, '..', 'public.key'), 'utf8'); + const signOptions = { issuer: 'Fundación LQDVI', subject: 'info@loquedeverdadimporta.org', diff --git a/middlewares/accessValidator.js b/middlewares/accessValidator.js index e1ba954..e1b28d6 100644 --- a/middlewares/accessValidator.js +++ b/middlewares/accessValidator.js @@ -4,7 +4,8 @@ const passport = require('passport'); const httpStatus = require('http-status'); const compose = require('../helpers/middleware.helper'); -const isRegisteredUser = passport.authenticate('local', { session: false }); +const isRegisteredUserEmail = passport.authenticate('local-email', { session: false }); +const isRegisteredUserPhone = passport.authenticate('local-phone', { session: false }); const isLoggedUser = passport.authenticate('jwt', { session: false }); const isAdministratorUser = compose([isLoggedUser, (req, res, next) => { @@ -18,7 +19,8 @@ const isAdministratorUser = compose([isLoggedUser, ]); module.exports = { - isRegisteredUser, + isRegisteredUserEmail, + isRegisteredUserPhone, isLoggedUser, isAdministratorUser }; \ No newline at end of file diff --git a/modules/auth/auth.controller.js b/modules/auth/auth.controller.js index 67e778c..10ea7ed 100644 --- a/modules/auth/auth.controller.js +++ b/modules/auth/auth.controller.js @@ -39,8 +39,27 @@ async function login(req, res, next) { controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res) } } - + +async function register(req, res, next) { + try { + const data = { + phone: req.user.phone, + platform: req.body.platform, + }; + //console.log(req); + console.log("Recoger datos del movil y guardar token en devices "); + res.json({ + token: securityHelper.generateToken(data), + user: data, + }); + + } catch (error) { + controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res) + } +} + module.exports = { login, + register, MODULE_NAME } \ No newline at end of file diff --git a/modules/auth/auth.routes.js b/modules/auth/auth.routes.js index ea49620..d6c0e8b 100644 --- a/modules/auth/auth.routes.js +++ b/modules/auth/auth.routes.js @@ -13,10 +13,16 @@ const AccessValidator = require('../../middlewares/accessValidator'); routes.post('/auth', SchemaValidator(authValidation.LoginInputType, true), - AccessValidator.isRegisteredUser, + AccessValidator.isRegisteredUserEmail, authController.login, ); +routes.post('/register', + SchemaValidator(authValidation.RegisterInputType, true), + AccessValidator.isRegisteredUserPhone, + authController.register, +); + routes.get('/pepepe', AccessValidator.isLoggedUser, function (req, res, next) { res.send(req.user.email); diff --git a/modules/auth/auth.service.js b/modules/auth/auth.service.js index ee178aa..d5e3d2b 100644 --- a/modules/auth/auth.service.js +++ b/modules/auth/auth.service.js @@ -2,16 +2,25 @@ //const JwtHelper = require('../../helpers/jwt.helper'); const models = require('../../core/models'); -function findOne(params) { - return models.User.findOne({ - where: params - }) +const extraMethods = { + + findUser: async (params, context) => { + return await models.User.findOne({ + where: params + }); + }, + + createUser: async (params, context) => { +// return models.sequelize.transaction(async transaction => { + //const result = await models.User.create(params, { transaction }); + const result = await models.User.create(params); + return result; +// }); + }, } module.exports = { - findOne, - login: async (params) => { - - - } -} \ No newline at end of file + extraMethods +}; + + diff --git a/modules/auth/auth.validations.js b/modules/auth/auth.validations.js index 190095f..66a519a 100644 --- a/modules/auth/auth.validations.js +++ b/modules/auth/auth.validations.js @@ -2,7 +2,12 @@ const Joi = require('joi'); const LoginInputType = Joi.object().keys({ email: Joi.string().email().required(), - password: Joi.string().required() + password: Joi.string().required(), +}); + +const RegisterInputType = Joi.object().keys({ + phone: Joi.string().required(), + fbuid: Joi.string().required(), }); const LoginOutputType = Joi.object().keys({ @@ -12,5 +17,6 @@ const LoginOutputType = Joi.object().keys({ module.exports = { LoginInputType, + RegisterInputType, LoginOutputType }; diff --git a/modules/auth/user.model.js b/modules/auth/user.model.js index 5729347..4ed5823 100644 --- a/modules/auth/user.model.js +++ b/modules/auth/user.model.js @@ -16,15 +16,15 @@ module.exports = function (sequelize, DataTypes) { }, email: { type: DataTypes.STRING, - allowNull: false, - unique: true, - validate: { isEmail: true } +// allowNull: false, +// unique: true, +// validate: { isEmail: true } }, password: { type: DataTypes.STRING, - allowNull: false, +// allowNull: false, }, - fbid: { + fbuid: { type: DataTypes.STRING, }, name: { @@ -69,8 +69,10 @@ module.exports = function (sequelize, DataTypes) { User.beforeCreate(async function (model, options) { - const encrypted = await generateHashPassword(model.password) - model.password = encrypted; + if (model.password) { + const encrypted = await generateHashPassword(model.password) + model.password = encrypted; + } return model; }); diff --git a/modules/events/event.model.js b/modules/events/event.model.js new file mode 100644 index 0000000..c830e41 --- /dev/null +++ b/modules/events/event.model.js @@ -0,0 +1,103 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const Event = sequelize.define('Event', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + allowNull: false, + }, + description: { + type: DataTypes.STRING, + }, + date: { + type: DataTypes.DATE, + allowNull: false, + }, + init_avalible_date: { + type: DataTypes.DATE, + }, + end_avalible_date: { + type: DataTypes.DATE, + }, + gmt: { + type: DataTypes.INTEGER, + defaultValue: 1, + }, + assistants: { + type: DataTypes.INTEGER, + }, + confirmed: { + type: DataTypes.INTEGER, + }, + allow_multiple: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + multiple_limit: { + type: DataTypes.INTEGER, + }, + allow_overflow: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + overflow_eventId: { + type: DataTypes.UUID, + foreignKey: true, + }, + state: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: 'borrador' + }, + typeId: { + type: DataTypes.UUID, + foreignKey: true, + }, + schedule: { + type: DataTypes.TEXT, + }, + venueId: { + type: DataTypes.UUID, + foreignKey: true, + }, + url_streaming: { + type: DataTypes.STRING, + }, + url_poll: { + type: DataTypes.STRING, + }, + url_registration: { + type: DataTypes.STRING, + }, + user_id: { + type: DataTypes.UUID, + foreignKey: true, + }, + }, { + tableName: 'events', + freezeTableName: true, + timestamps: true, + }); + + Event.associate = function (models) { + Event.OverflowEvent = Event.belongsTo(models.Event, { foreignKey: 'overflow_eventId' }); + Event.EventType = Event.belongsTo(models.EventType, { foreignKey: 'typeId' }); + Event.UserCreate = Event.belongsTo(models.User, { foreignKey: 'userId' }); + Event.Venue = Event.belongsTo(models.Venue, { foreignKey: 'venueId' }); + + Event.Multimedias = Event.belongsToMany(models.Multimedia, { + through: models.MultimediaEvent, + foreignKey: 'eventId' + }); + + }; + + return Event; +}; \ No newline at end of file diff --git a/modules/events/event_type.model.js b/modules/events/event_type.model.js new file mode 100644 index 0000000..ee0f9f8 --- /dev/null +++ b/modules/events/event_type.model.js @@ -0,0 +1,27 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const EventType = sequelize.define('EventType', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + }, + tittle: { + type: DataTypes.STRING, + }, + }, { + tableName: 'event_types', + freezeTableName: true, + timestamps: true, + }); + + EventType.associate = function (models) { + EventType.Events = EventType.hasMany(models.Event, { foreignKey: 'typeId' }); + }; + + return EventType; +}; \ No newline at end of file diff --git a/modules/events/venue.model.js b/modules/events/venue.model.js new file mode 100644 index 0000000..bd9dbe2 --- /dev/null +++ b/modules/events/venue.model.js @@ -0,0 +1,49 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const Venue = sequelize.define('Venue', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + }, + description: { + type: DataTypes.STRING, + }, + address: { + type: DataTypes.STRING, + }, + city: { + type: DataTypes.STRING, + }, + country: { + type: DataTypes.STRING, + }, + state: { + type: DataTypes.STRING, + }, + postal_core: { + type: DataTypes.STRING, + }, + accessibility: { + type: DataTypes.STRING, + }, + gmt: { + type: DataTypes.INTEGER, + defaultValue: 1, + }, + }, { + tableName: 'venues', + freezeTableName: true, + timestamps: true, + }); + + Venue.associate = function (models) { + Venue.Events = Venue.hasMany(models.Event, { foreignKey: 'venueId' }); + }; + + return Venue; +}; \ No newline at end of file diff --git a/modules/multimedia/multimedia.model.js b/modules/multimedia/multimedia.model.js new file mode 100644 index 0000000..0bae928 --- /dev/null +++ b/modules/multimedia/multimedia.model.js @@ -0,0 +1,50 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const Multimedia = sequelize.define('Multimedia', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + }, + description: { + type: DataTypes.STRING, + }, + typeId: { + type: DataTypes.UUID, + foreignKey: true, + }, + provider: { + type: DataTypes.STRING, + }, + code: { + type: DataTypes.STRING, + }, + url: { + type: DataTypes.STRING, + }, + userId: { + type: DataTypes.UUID, + foreignKey: true, + }, + }, { + tableName: 'multimedias', + freezeTableName: true, + timestamps: true, + }); + + Multimedia.associate = function (models) { + Multimedia.MultimediaType = Multimedia.belongsTo(models.MultimediaType, { foreignKey: 'typeId' }); + Multimedia.UserCreate = Multimedia.belongsTo(models.User, { foreignKey: 'userId' }); + + Multimedia.Events = Multimedia.belongsToMany(models.Event, { + through: models.MultimediaEvent, + foreignKey: 'multimediaId' + }); + }; + + return Multimedia; +}; \ No newline at end of file diff --git a/modules/multimedia/multimedia_events.model.js b/modules/multimedia/multimedia_events.model.js new file mode 100644 index 0000000..c09101e --- /dev/null +++ b/modules/multimedia/multimedia_events.model.js @@ -0,0 +1,25 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const MultimediaEvent = sequelize.define('MultimediaEvent', { + multimediaId: { + type: DataTypes.UUID, + primaryKey: true, + allowNull: false, + }, + eventId: { + type: DataTypes.UUID, + primaryKey: true, + allowNull: false, + }, + type: { + type: DataTypes.STRING, + }, + }, { + tableName: 'multimedia_events', + freezeTableName: true, + timestamps: true, + }); + + return MultimediaEvent; +}; \ No newline at end of file diff --git a/modules/multimedia/multimedia_types.model.js b/modules/multimedia/multimedia_types.model.js new file mode 100644 index 0000000..d65f620 --- /dev/null +++ b/modules/multimedia/multimedia_types.model.js @@ -0,0 +1,27 @@ +'use strict'; + +module.exports = function (sequelize, DataTypes) { + const MultimediaType = sequelize.define('MultimediaType', { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + }, + description: { + type: DataTypes.STRING, + }, + }, { + tableName: 'multimedia_types', + freezeTableName: true, + timestamps: true, + }); + +// EventType.associate = function (models) { +// EventType.Events = EventType.hasMany(models.Event, { foreignKey: 'typeId' }); +// }; + + return MultimediaType; +}; \ No newline at end of file diff --git a/package.json b/package.json index 3cbb950..580a078 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "crypto": "^1.0.1", "express": "^4.16.4", "express-validation": "^1.0.2", + "firebase-admin": "^8.1.0", "fs": "^0.0.1-security", "fs-extra": "^7.0.1", "helmet": "^3.16.0", diff --git a/server.js b/server.js index f76a825..db24351 100644 --- a/server.js +++ b/server.js @@ -65,7 +65,7 @@ try { //logger.info(`Version: ${this.config.info.strapi} (node v${this.config.info.node})`); logger.info('To shut down your server, press + C at any time'); logger.info(`⚡️ Server: http://${currentState.host}:${currentState.port}`); - + }); }); } catch (err) {