Merge branch 'master' of wopr.rodax-software.com:lqdvi/app2-api

This commit is contained in:
David Arranz 2019-08-05 09:42:07 +02:00
commit 4f72adecc4
57 changed files with 1536 additions and 603 deletions

View File

@ -9,7 +9,6 @@ function extractFindOptions(req, res, targetAttributes) {
})
}
console.log(result);
return result;
}
@ -90,8 +89,6 @@ function _find(modelMaybeThunk, options = {}) {
findOptions = parseFindOptions(findOptions, targetAttributes);
console.log(findOptions);
return Promise.resolve(options.before(findOptions, req, res))
.then(findOptions => {
return model[isList ? 'fetchAll' : 'fetch'](findOptions);

View File

@ -60,7 +60,6 @@ const generateControllers = (service, extraControllers = {}, options = {}) => {
count: (config) => {
return async(req, res, next) => {
const params = extractParamsFromRequest(req, res, _options.params.count);
try {
const result = await service.count(params, buildContext(req, config));
return handleResultResponse(result, null, params, res);

View File

@ -21,7 +21,8 @@ const sequelize = new Sequelize(
config.database.password,
config.database, {
dialect: 'mysql',
operatorAliases: false
operatorAliases: false,
logging: false,
}
);

View File

@ -45,6 +45,7 @@ passport.use('local-email', new LocalStrategy(localEmailOptions, async (email, p
if (_.isNull(user)) {
return done(null, false, { message: 'User not found' })
} else {
var password_encoded = crypto.createHash('sha512').update(password).digest('hex');
const isPasswordValid = await user.comparePassword(password_encoded);
if (!isPasswordValid) {
@ -76,13 +77,17 @@ passport.use('local-phone', new LocalStrategy(localPhoneOptions, async (phone, f
if (userRecord.toJSON().disabled)
return done(null, false, { message: 'User disabled in fb' })
else
return done(null, true, { message: 'Register user' });
return done(null, userRecord.toJSON(), { message: 'Register user' });
}
else
return done(null, false, { message: 'User not validate in fb' });
})
.catch(function (error) {
//Servicio firebase caido o no funciona pero devuelvo el usuario
const user = {
phone: phone,
fbuid: fbuid
};
return done(null, user, error);
})
} catch (error) {
@ -94,25 +99,24 @@ passport.use('local-phone', new LocalStrategy(localPhoneOptions, async (phone, f
// JWT
passport.use('jwt', new CustomStrategy(async (req, done) => {
const token = ((req && req.headers && req.headers['x-access-token']) ? req.headers['x-access-token'] : null);
console.log(token);
if (!token) {
return done(null, false, { message: 'Unauthorized'});
return done(null, false, { message: 'Unauthorized. Token missing.'});
}
const result = securityHelper.verify(token);
if (result) {
console.log(result);
//recuperamos el usuario de la petición
let user = await authService.extraMethods.findUser({ phone: result.phone});
if (user){
user = user.toJSON();
return done(null, user, { message: 'Logged in Successfully' });
}
else
return done(null, false, { message: 'Unauthorized' });
return done(null, false, { message: 'Unauthorized. User not found.' });
}
else {
return done(null, false, { message: 'Unauthorized' });
return done(null, false, { message: 'Unauthorized. Invalid token.' });
}
}));

View File

@ -3,6 +3,7 @@
const express = require('express');
const glob = require('glob');
const path = require('path');
const { apicache } = require('../middlewares/cache');
const modulesDir = path.resolve(__dirname + '/../modules/')
const globOptions = {
@ -12,6 +13,8 @@ const globOptions = {
absolute: true,
}
module.exports = function () {
const router = express.Router({ mergeParams: true });
@ -22,7 +25,24 @@ module.exports = function () {
description: 'Welcome, this is the API for the application.'
});
});
// APICACHE
// route to display cache index
router.get('/v2/cache/index', (req, res) => {
res.json(apicache.getIndex())
});
// route to clear target group
router.get('/v2/cache/clear/:target?', (req, res) => {
res.json(apicache.clear(req.params.target))
});
// Resto de rutas
glob.sync("**/*.routes.js", globOptions)
.forEach(function (file) {
router.use('/v2', require(file));

View File

@ -3,16 +3,38 @@ const cdnHelper = require('./cdn.helper');
const valuesComposer = (values) => (values) ? values.map(value => ({id: value.id, name: value.name,})): values;
const citiesComposer = (city) => {
if (city) {
return {
...city,
image: cdnHelper.getCDNCityMediaUrl(city.city),
};
}
else return city;
}
const commentComposer = (comment, context) => {
if (comment.user) {
comment.user_name = comment.user.name + '---';
comment.profile_picture = cdnHelper.getCDNMediaUrl(comment.user.profile_picture);
}else {
comment.user_name = comment.nameUserOld;
comment.profile_picture = cdnHelper.getCDNMediaUrl(comment.profile_pictureOld);
}
delete comment.nameUserOld;
delete comment.profile_pictureOld;
delete comment.userId;
delete comment.user;
return Object.assign({},
comment);
};
const commentsComposer = (comments) => {
if (comments) {
return comments.map(comment => ({
...comment,
userId: undefined,
user: {
...comment.user,
profile_picture: cdnHelper.getCDNMediaUrl(comment.user.profile_picture)
}
...commentComposer(comment)
}));
}
else return comments;
@ -133,5 +155,7 @@ const entityComposer = (entity, context) => {
module.exports = {
entityComposer,
speakerComposer,
eventComposer
eventComposer,
commentComposer,
citiesComposer
}

View File

@ -76,8 +76,8 @@ function setPaginationInfo(totalCount, res) {
const params = extractParamsFromRequest(null, res);
console.log('>>>>>>>>>>>>>>>>>>>>>>>>> params antes de setPaginationInfo');
console.log(params);
//console.log('>>>>>>>>>>>>>>>>>>>>>>>>> params antes de setPaginationInfo');
//console.log(params);
if (params.paginate) {
const
page = (params.paginate && params.paginate.page) ? params.paginate.page : null,
@ -86,7 +86,7 @@ function setPaginationInfo(totalCount, res) {
if (params.paginate.hasNextPages(count)) {
const nextPage = params.paginate.href();
res.set('Link', nextPage + '; rel=next');
res.set('Link-Next-Page', nextPage + '; rel=next');
res.set('Pagination-Next-Page', true);
} else {
res.set('Pagination-Next-Page', false);

134
helpers/mailchimp.helper.js Normal file
View File

@ -0,0 +1,134 @@
const Mailchimp = require('mailchimp-api-v3');
const mailchimp_key = "7d4ffd805bdb43a34f0806c0d2970e73-us3";
//moment = require('moment'),
// _ = require('lodash'),
// conf = require('../conf');
//var logger = require("../helpers/logger");
const mailchimp = new Mailchimp(mailchimp_key);
function getLists() {
return new Promise(function (resolve, reject) {
console.log('voy a llamar a la API');
mailchimp.get('/lists', {
fields: 'lists.id,lists.name',
sort_field: 'date_created',
sort_dir: 'DESC',
since_date_created: moment("2019-02-14").format("YYYY-MM-DD"),
})
.then(function (results) {
resolve(results.lists);
})
.catch(function (error) {
reject(error)
})
});
};
/*
function getMembers(listId) {
return new Promise(function (resolve, reject) {
logger.debug('getMembers => ', '/lists/' + listId + '/members');
mailchimp.get('/lists/' + listId + '/members', {
fields: 'members.id,members.email_address,members.merge_fields',
})
.then(function (results) {
resolve(results.members);
})
.catch(function (error) {
reject(error)
})
});
}
function getMember(listId, data) {
return new Promise(function (resolve, reject) {
logger.debug('getMember => ', '/search-members', listId, ' email: ' + data.email);
mailchimp.get('/search-members', {
list_id: listId,
query: data.email,
fields: ['email_address'],
})
.then(function (results) {
if (results && results.exact_matches && (results.exact_matches.total_items == 1)) {
logger.debug('getMember => ', results.exact_matches.members[0].id);
resolve(results.exact_matches.members[0]);
}
else reject();
})
.catch(function (error) {
reject(error)
})
});
}
*/
function addMember(listId, member) {
return new Promise(function (resolve, reject) {
// logger.debug('addMember => ', '/lists/' + listId + '/members', ' email: ' + member.email);
console.log('addMember => ', '/lists/' + listId + '/members', ' email: ' + member.email);
var member2 = {
EMAIL: member.email,
FNAME: member.name,
LNAME: member.surname,
SOURCE: member.source,
RESERCODE: member.reservation_code,
TICKETCODE: member.code_ticket,
VALIDATED: member.validated,
COLOR: member.color,
DESCOLOR: member.description,
ENTITYNAME: member.entityId,
USERID: member.userId
}
mailchimp.post('/lists/' + listId + '/members', {
email_address: member2.EMAIL,
merge_fields: member2,
status: 'subscribed'
})
.then(function (results) {
console.log('addMember => ', member.EMAIL, results.id, results.statusCode);
resolve(results);
})
.catch(function (error) {
console.log('addMember => ', error.title, error.status);
if ((error.status == 400) && (error.title == 'Member Exists')) {
resolve(getMember(listId, member));
} else {
reject(error);
}
})
});
};
/*
function deleteMember(listId, memberId) {
return new Promise(function (resolve, reject) {
logger.debug('deleteMember => ', '/lists/' + listId + '/members/' + memberId);
mailchimp.delete('/lists/' + listId + '/members/' + memberId)
.then(function (results) {
resolve(results);
})
.catch(function (error) {
if (error.status == 404) { // Miembro no existe
resolve({})
} else {
reject(error);
}
})
});
}
*/
module.exports.getLists = getLists;
//module.exports.getMembers = getMembers;
module.exports.addMember = addMember;
//module.exports.deleteMember = deleteMember;

184
helpers/qr.helper.js Normal file
View File

@ -0,0 +1,184 @@
var _ = require('lodash');
var QRCode = require('qrcode');
/* params = {
code: 'xxxx',
name: 'xxxx',
surname: 'xxxx',
color: '#ff',
} */
module.exports.getInscriptionQRCode = function (params) {
return new Promise(function (resolve, reject) {
var texto = _.padStart(params.code, 4, '0') + '\n' + params.name + ' ' + params.surname;
var options = {
errorCorrectionLevel: 'M',
}
if (params.color) {
options = _.assign(options, {
color: {
light: (params.color) ? colourNameToHex(params.color) : "#000000",
dark: "#ffffff"
}
})
};
QRCode.toDataURL(texto, options, function (err, qrcode) {
if (err) resolve('');
//console.log(qrcode);
resolve(qrcode);
});
})
};
function colourNameToHex(colour) {
var colours = {
"aliceblue": "#f0f8ff",
"antiquewhite": "#faebd7",
"aqua": "#00ffff",
"aquamarine": "#7fffd4",
"azure": "#f0ffff",
"beige": "#f5f5dc",
"bisque": "#ffe4c4",
"blanchedalmond": "#ffebcd",
"blue": "#0000ff",
"blueviolet": "#8a2be2",
"brown": "#a52a2a",
"burlywood": "#deb887",
"cadetblue": "#5f9ea0",
"chartreuse": "#7fff00",
"chocolate": "#d2691e",
"coral": "#ff7f50",
"cornflowerblue": "#6495ed",
"cornsilk": "#fff8dc",
"crimson": "#dc143c",
"cyan": "#00ffff",
"darkblue": "#00008b",
"darkcyan": "#008b8b",
"darkgoldenrod": "#b8860b",
"darkgray": "#a9a9a9",
"darkgreen": "#006400",
"darkkhaki": "#bdb76b",
"darkmagenta": "#8b008b",
"darkolivegreen": "#556b2f",
"darkorange": "#ff8c00",
"darkorchid": "#9932cc",
"darkred": "#8b0000",
"darksalmon": "#e9967a",
"darkseagreen": "#8fbc8f",
"darkslateblue": "#483d8b",
"darkslategray": "#2f4f4f",
"darkturquoise": "#00ced1",
"darkviolet": "#9400d3",
"deeppink": "#ff1493",
"deepskyblue": "#00bfff",
"dimgray": "#696969",
"dodgerblue": "#1e90ff",
"firebrick": "#b22222",
"floralwhite": "#fffaf0",
"forestgreen": "#228b22",
"fuchsia": "#ff00ff",
"gainsboro": "#dcdcdc",
"ghostwhite": "#f8f8ff",
"gold": "#ffd700",
"goldenrod": "#daa520",
"gray": "#808080",
"green": "#008000",
"greenyellow": "#adff2f",
"honeydew": "#f0fff0",
"hotpink": "#ff69b4",
"indianred ": "#cd5c5c",
"indigo": "#4b0082",
"ivory": "#fffff0",
"khaki": "#f0e68c",
"lavender": "#e6e6fa",
"lavenderblush": "#fff0f5",
"lawngreen": "#7cfc00",
"lemonchiffon": "#fffacd",
"lightblue": "#add8e6",
"lightcoral": "#f08080",
"lightcyan": "#e0ffff",
"lightgoldenrodyellow": "#fafad2",
"lightgrey": "#d3d3d3",
"lightgreen": "#90ee90",
"lightpink": "#ffb6c1",
"lightsalmon": "#ffa07a",
"lightseagreen": "#20b2aa",
"lightskyblue": "#87cefa",
"lightslategray": "#778899",
"lightsteelblue": "#b0c4de",
"lightyellow": "#ffffe0",
"lime": "#00ff00",
"limegreen": "#32cd32",
"linen": "#faf0e6",
"magenta": "#ff00ff",
"maroon": "#800000",
"mediumaquamarine": "#66cdaa",
"mediumblue": "#0000cd",
"mediumorchid": "#ba55d3",
"mediumpurple": "#9370d8",
"mediumseagreen": "#3cb371",
"mediumslateblue": "#7b68ee",
"mediumspringgreen": "#00fa9a",
"mediumturquoise": "#48d1cc",
"mediumvioletred": "#c71585",
"midnightblue": "#191970",
"mintcream": "#f5fffa",
"mistyrose": "#ffe4e1",
"moccasin": "#ffe4b5",
"navajowhite": "#ffdead",
"navy": "#000080",
"oldlace": "#fdf5e6",
"olive": "#808000",
"olivedrab": "#6b8e23",
"orange": "#ffa500",
"orangered": "#ff4500",
"orchid": "#da70d6",
"palegoldenrod": "#eee8aa",
"palegreen": "#98fb98",
"paleturquoise": "#afeeee",
"palevioletred": "#d87093",
"papayawhip": "#ffefd5",
"peachpuff": "#ffdab9",
"peru": "#cd853f",
"pink": "#ffc0cb",
"plum": "#dda0dd",
"powderblue": "#b0e0e6",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#ff0000",
"rosybrown": "#bc8f8f",
"royalblue": "#4169e1",
"saddlebrown": "#8b4513",
"salmon": "#fa8072",
"sandybrown": "#f4a460",
"seagreen": "#2e8b57",
"seashell": "#fff5ee",
"sienna": "#a0522d",
"silver": "#c0c0c0",
"skyblue": "#87ceeb",
"slateblue": "#6a5acd",
"slategray": "#708090",
"snow": "#fffafa",
"springgreen": "#00ff7f",
"steelblue": "#4682b4",
"tan": "#d2b48c",
"teal": "#008080",
"thistle": "#d8bfd8",
"tomato": "#ff6347",
"turquoise": "#40e0d0",
"violet": "#ee82ee",
"wheat": "#f5deb3",
"whitesmoke": "#f5f5f5",
"yellow": "#ffff00",
"yellowgreen": "#9acd32"
};
if (typeof colours[colour.toLowerCase()] != 'undefined')
return colours[colour.toLowerCase()];
return "#000000";
}

View File

@ -76,10 +76,10 @@ const _verify = (token, options) => {
algorithm: ["RS256"]
};
console.log('_VERIFY - SECURiTY.HELPERRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR');
console.log('token: ', token);
console.log('publicKEY: ', publicKEY);
console.log('verifyOptions: ', verifyOptions);
//console.log('_VERIFY - SECURiTY.HELPERRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR');
//console.log('token: ', token);
//console.log('publicKEY: ', publicKEY);
//console.log('verifyOptions: ', verifyOptions);
try {
return jwt.verify(token, publicKEY, verifyOptions);
@ -107,7 +107,16 @@ module.exports = {
},
isValidPassword: async (password, candidate) => {
console.log('aaaaaaaaaaaaaaaaaaa3');
console.log(password);
console.log(candidate);
result = await bCrypt.compareSync(candidate, password);
console.log('resultado');
console.log(result);
result = true;
return result;
},

View File

@ -87,7 +87,7 @@ const parseParamsToFindOptions = (params) => {
// Paginate
if (params.paginate) {
result.offset = params.paginate.limit * (params.paginate.page - 1);
result.limit = result.offset + params.paginate.limit;
result.limit = params.paginate.limit; // result.offset + params.paginate.limit;
}
// Order
@ -151,6 +151,14 @@ const generateService = (model, extraMethods = {}, options = defaultOptions) =>
return defaultService.fetchAssociation(params, context)
} else {
const findOptions = parseParamsToFindOptions(params);
// Necesario para el cálculo del count
// https://github.com/sequelize/sequelize/issues/10557
findOptions.distinct = true;
// findOptions.col = model.primaryKey;
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
console.log(findOptions);
const result = await model.scope(context.scopes).findAndCountAll(findOptions);
if (extraMethods.afterFetchAll) {

View File

@ -2,6 +2,27 @@ const config = require('../config');
const Vimeo = require('vimeo').Vimeo;
const client = new Vimeo(config.vimeo.CLIENT_ID, config.vimeo.CLIENT_SECRET, config.vimeo.ACCESS_TOKEN);
function getIframeSource(iframeHtml) {
const groups = iframeHtml.match(/\<iframe.+src\=(?:\"|\')(.+?)(?:\"|\')/);
return groups[1];
}
function extractInformation(vimeoResponse) {
return {
duration: vimeoResponse.duration,
name: vimeoResponse.name,
description: vimeoResponse.description,
link: vimeoResponse.link,
type: vimeoResponse.type,
stats: vimeoResponse.stats,
download: vimeoResponse.download,
pictures: vimeoResponse.pictures,
embed: getIframeSource(vimeoResponse.embed.html)
}
}
function getVimeoVideoInfo(videoId) {
return new Promise(function(resolve, reject) {
client.request({
@ -9,10 +30,14 @@ function getVimeoVideoInfo(videoId) {
path: '/videos/' + videoId
}, function (error, body, status_code, headers) {
if (error) {
console.log(error);
console.error(error);
resolve({})
} else {
resolve(body);
if (body.status !== 'available') {
resolve({})
} else {
resolve(extractInformation(body));
}
}
})
});

View File

@ -1,22 +1,24 @@
const apicache = require('apicache');
const redis = require('redis');
let cacheWithRedis = apicache
.options({
const cacheWithRedis = apicache
.options({
debug: true,
defaultDuration: '1 hour',
redisClient: redis.createClient()
})
.middleware;
defaultDuration: '1 minute',
//redisClient: redis.createClient(),
//appendKey: (req, res) => req.user ? req.user.id : '',
});
const cacheMiddleware = cacheWithRedis.middleware;
// higher-order function returns false for responses of other status codes (e.g. 403, 404, 500, etc)
const onlyStatus200 = (req, res) => res.statusCode === 200
const cacheSuccesses = cacheWithRedis('1 hour', onlyStatus200);
const cache1year = cacheWithRedis('1 year', onlyStatus200);
const cacheSuccesses = (time) => { return cacheMiddleware(time, onlyStatus200) };
module.exports = {
apicache: cacheWithRedis,
cacheMiddleware,
cacheSuccesses,
cache1year
}

View File

@ -38,6 +38,44 @@ async function login(req, res, next) {
}
}
async function login2(req, res, next) {
try {
res.status(httpStatus.OK).json({
// token: tokens.token,
// refreshToken: tokens.refreshToken,
// user: data,
})
} catch (error) {
controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res)
}
}
async function loginWithPhone(req, res, next) {
try {
console.log(req.user);
const findOptions = {
phone: req.user.phoneNumber,
fbuid: req.user.uid
};
//Comprobamos si el usuario ya existe en nuestro sistema
let _user = await authService.extraMethods.findUser(findOptions);
const tokenData = {
id: _user.id,
email: _user.email,
phone: _user.phone,
fbuid: _user.fbuid,
};
const tokens = securityHelper.generateToken(tokenData);
_user.token = tokens.token;
return controllerHelper.handleResultResponse(_user, null, req.params, res, httpStatus.OK);
} catch (error) {
return controllerHelper.handleErrorResponse(MODULE_NAME, login.name, error, res)
}
}
async function register(req, res, next) {
function cleanAdminData(user) {
@ -73,17 +111,17 @@ async function register(req, res, next) {
newUser = await authService.extraMethods.createUser(data);
} catch (error) {
console.log(error);
console.error(error);
controllerHelper.handleErrorResponse(MODULE_NAME, register.name, error, res);
}
};
if (newUser)
newUser = cleanAdminData(newUser.toJSON());
newUser = cleanAdminData(newUser);
newUser.token = tokens.token;
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
console.log(newUser);
//console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
//console.log(newUser);
return controllerHelper.handleResultResponse(newUser, null, req.params, res, httpStatus.OK);
}
@ -104,7 +142,7 @@ async function regenerateToken(req, res, next) {
const result = { token: tokens.token };
return controllerHelper.handleResultResponse(result, null, req.params, res, httpStatus.OK);
} catch(error) {
controllerHelper.handleErrorResponse(MODULE_NAME, regenerateToken.name, error, res);
return controllerHelper.handleErrorResponse(MODULE_NAME, regenerateToken.name, error, res);
}
} else {
return controllerHelper.handleResultResponse(null, null, req.params, res, httpStatus.UNAUTHORIZED);
@ -130,6 +168,8 @@ async function rejectToken(req, res, next) {
module.exports = {
login,
login2,
loginWithPhone,
register,
regenerateToken,
rejectToken,

View File

@ -12,17 +12,32 @@ const AccessValidator = require('../../middlewares/accessValidator');
//const postHandler = new ModelHandler(models.Post);
routes.post('/auth',
SchemaValidator(authValidation.LoginInputType, true),
SchemaValidator(authValidation.LoginWinEmailInputType, true),
AccessValidator.isRegisteredUserEmail,
authController.login,
);
routes.get('/auth',
// SchemaValidator(authValidation.LoginInputType, true),
// AccessValidator.isRegisteredUserEmail,
authController.login2,
);
// Registro de usuario a partir del usuario de Firebase y
// los datos del formulario.
routes.post('/register',
SchemaValidator(authValidation.RegisterInputType, true),
AccessValidator.isRegisteredUserPhone,
authController.register,
);
routes.get('/loginWithPhone',
SchemaValidator(authValidation.LoginWithPhoneInputType, true),
AccessValidator.isRegisteredUserPhone,
authController.loginWithPhone,
);
routes.get('/pepepe', AccessValidator.isLoggedUser,
function (req, res, next) {
res.send(req.user.email);

View File

@ -6,7 +6,8 @@ const extraMethods = {
findUser: async (params, context) => {
return await models.User.findOne({
where: params
where: params,
raw: true, // <- para evitar tener que hacer .toJson al final
});
},

View File

@ -5,6 +5,16 @@ const LoginInputType = Joi.object().keys({
password: Joi.string().required(),
});
const LoginWithPhoneInputType = Joi.object().keys({
phone: Joi.string().required(),
fbuid: Joi.string().required(),
});
const LoginWithEmailInputType = Joi.object().keys({
email: Joi.string().email().required(),
password: Joi.string().required(),
});
const RegisterInputType = Joi.object().keys({
phone: Joi.string().required(),
email: Joi.string().required(),
@ -21,7 +31,8 @@ const LoginOutputType = Joi.object().keys({
module.exports = {
LoginInputType,
LoginWithPhoneInputType,
LoginWithEmailInputType,
RegisterInputType,
LoginOutputType
};

View File

@ -16,7 +16,7 @@ const MODULE_NAME = '[blog.controller]';
// Success Messages
//const VG_CT_VIDEOGAME_DELETED_SUCCESSFULLY = 'Videogame deleted successfully';
const blogCommentsService = generateCommentService(models.Post.Comments);
//const blogCommentsService = generateCommentService(models.Post.Comments);
const controllerOptions = {
MODULE_NAME,

View File

@ -35,15 +35,21 @@ module.exports = function (sequelize, DataTypes) {
through: models.PostCategory,
foreignKey: 'postId'
});
//Post.Comments = Post.hasMany(models.Comment, { foreignKey: 'postId' });
//Post.Reactions = Post.hasMany(models.PostReaction, { foreignKey: 'postId' });
//Post.User = Post.belongsTo(models.User, { foreignKey: 'userId' });
/*
Post.Multimedias = Post.belongsToMany(models.MultimediaFile, {
through: models.MultimediaPost,
foreignKey: 'postId'
});
*/
//OJO antes de force comentar
// OJO GENERA UN FOREIGN KEY Con eventos y habrá ID de otras entidades que no exitan en la tabla eventos, porque son post o speakers
Post.Multimedias = Post.hasMany(models.Multimedia, {
foreignKey: 'entityId',
as: { singular: 'multimedia', plural: 'multimedias' }
});
Post.Comments = Post.hasMany(models.Comment, {
foreignKey: 'entityId',
as: { singular: 'comment', plural: 'comments' }
});
};
return Post;
};

View File

@ -0,0 +1,15 @@
'use strict';
const generateControllers = require('../../core/controllers');
const commentService = require('./comment.service');
const { extractParamsFromRequest, handleErrorResponse, handleResultResponse } = require('../../helpers/controller.helper');
// Module Name
const MODULE_NAME = '[comment.controller]';
const controllerOptions = { MODULE_NAME };
const extraControllers = {
};
module.exports = generateControllers(commentService, extraControllers, controllerOptions);

View File

@ -17,49 +17,53 @@ module.exports = function (sequelize, DataTypes) {
type: DataTypes.STRING,
allowNull: false
},
/*entity: {
type: DataTypes.VIRTUAL,
get: function () {
const name = this.get('entityName');
const id = this.get('entityId');
let modelName = '';
switch (name) {
case 'post':
modelName = 'Post';
break;
case 'speaker':
modelName = 'Speaker'
break;
case 'event':
modelName = 'Event';
break;
default:
break;
}
return sequelize.models[modelName].findOne(id);
}
}*/
nameUserOld: {
type: DataTypes.STRING(125),
},
profile_pictureOld: {
type: DataTypes.STRING(255),
},
}, {
indexes: [{
unique: false,
fields: ['entityId']
}],
tableName: 'comments',
freezeTableName: true,
timestamps: true,
});
indexes: [{
unique: false,
fields: ['entityId']
}],
tableName: 'comments',
freezeTableName: true,
timestamps: true,
defaultScope: {
include: [{
model: sequelize.models.User,
as: 'user',
attributes: ['name', 'surname', 'profile_picture'],
}]
},
});
Comment.addScope('onlyEvents', () => {
return {
where: {
entityName: 'event'
}
}
});
Comment.addScope('onlySpeakers', () => {
return {
where: {
entityName: 'speaker'
}
}
});
Comment.associate = function (models) {
Comment.User = Comment.belongsTo(models.User, { foreignKey: 'userId', constraints: false, as: 'user' });
//Comment.Conference = Comment.belongsTo(models.Conference, { foreignKey: 'conferenceId', constraints: false });
//Comment.Post = Comment.belongsTo(models.Post, { foreignKey: 'postId', constraints: false });
//Comment.Speaker = Comment.belongsTo(models.Speaker, { foreignKey: 'speakerId', constraints: false });
};
return Comment;
};

View File

@ -0,0 +1,55 @@
const routes = require('express').Router();
const { isAdministratorUser, isLoggedUser } = require('../../middlewares/accessValidator');
const SchemaValidator = require('../../middlewares/schemaValidator');
const PaginateMiddleware = require('../../middlewares/paginate');
const FieldMiddleware = require('../../middlewares/fields');
const SortMiddleware = require('../../middlewares/sort');
//const entityValidation = require('./entity.validations');
const commentController = require('./comment.controller');
const generalInvalidFields = [
];
routes.get('/comments',
isLoggedUser,
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
}),
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "createdAt" }),
commentController.find({
scopes: ['defaultScope'],
}),
);
routes.get('/comments/events',
isLoggedUser,
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
}),
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "createdAt" }),
commentController.find({
scopes: ['defaultScope', 'onlyEvents'],
}),
);
routes.get('/comments/speakers',
isLoggedUser,
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
}),
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "createdAt" }),
commentController.find({
scopes: ['defaultScope', 'onlySpeakers'],
}),
);
module.exports = routes;

View File

@ -1,10 +1,35 @@
/* global Post */
/* global Comment */
'use strict';
const _ = require('lodash');
const { generateService, parseParamsToFindOptions } = require('../../helpers/service.helper');
const models = require('../../core/models');
const { commentComposer } = require('../../helpers/composes.helper');
const extraMethods = {}
const extraMethods = {
afterFetchAll: (result, params, context) => {
if (!result.count) {
return result;
}
let rows = result.rows.map(row => row.toJSON());
rows = rows.map(comment => commentComposer(comment, context));
return {
count: rows.length,
rows: rows
}
},
/*
afterFetchOne: (result, params, context) => {
if (result)
result = result.toJSON();
return eventComposer(result, context);
},
*/
}
module.exports = generateService(models.Comment, extraMethods);
module.exports = (model) => generateService(model, extraMethods);

View File

@ -1,6 +1,7 @@
'use strict';
const httpStatus = require('http-status');
const generateControllers = require('../../core/controllers');
const QRHelper = require('../../helpers/qr.helper');
const eventService = require('./event.service');
const eventReservationService = require('./events_reservations.service');
const eventInscriptionService = require('./events_inscriptions.service');
@ -25,13 +26,13 @@ const extraControllers = {
const eventId = params.params.id;
const encodedInvitationCode = params.params.encodedInvitationCode;
const registrationCode = encodedInvitationCode; //Buffer.from(req.params.encodedInvitationCode, 'base64').toString('ascii');
const registrationCode = Buffer.from(req.params.encodedInvitationCode, 'base64').toString('ascii');
try {
const result = await eventReservationService._getReservaByCode(eventId, registrationCode);
handleResultResponse(!!result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
return handleResultResponse(!!result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
} catch(error) {
handleErrorResponse(MODULE_NAME, 'checkReservationCode', error, res)
return handleErrorResponse(MODULE_NAME, 'checkReservationCode', error, res)
}
},
@ -51,33 +52,76 @@ const extraControllers = {
if (eventId) {
try {
const result = await eventInscriptionService._getInscriptionByEventAndUser(eventId, userId);
handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
return handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
} catch (error) {
handleErrorResponse(MODULE_NAME, 'getInscriptions', error, res)
return handleErrorResponse(MODULE_NAME, 'getInscriptions', error, res)
}
}
else{
try {
const result = await eventInscriptionService._getInscriptionsUser(userId);
handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
return handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
} catch (error) {
handleErrorResponse(MODULE_NAME, 'getInscriptions', error, res)
return handleErrorResponse(MODULE_NAME, 'getInscriptions', error, res)
}
}
},
getInscriptionsOfNextEventsCount: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, {});
const userId = req.user.id;
try {
const result = await eventInscriptionService._getInscriptionsOfNextEventsUser(userId);
console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
return handleResultResponse({ count: result }, null, params, res, httpStatus.OK);
} catch (error) {
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaa');
return handleErrorResponse(MODULE_NAME, 'getInscriptionsOfNextEventsCount', error, res)
}
},
getInscription: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, {});
const inscriptionId = params.params.id;
const userId = req.user.id;
try {
let inscription = await eventInscriptionService._getInscriptionById(inscriptionId);
if (!inscription) {
return handleResultResponse("Inscripción no encontrada", null, params, res, httpStatus.NOT_FOUND);
} else if (inscription.userId !== userId) {
return handleResultResponse("Inscripción no encontrada", null, params, res, httpStatus.NOT_FOUND);
}
inscription = await inscription.toJSON();
const qrConfig = {
name: req.user.name,
surname: req.user.surname,
code: inscription.code_ticket,
color: (inscription.level && inscription.level.color) ? inscription.level.color : null,
}
inscription.code_ticket_qr = await QRHelper.getInscriptionQRCode(qrConfig);
return handleResultResponse(inscription, null, params, res, httpStatus.OK);
} catch (error) {
return handleResultResponse("Error al buscar la inscripción", null, params, res, httpStatus.NOT_FOUND);
}
},
deleteInscription: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, {});
const user = req.user;
const inscriptionId = params.params.id;
try
{
try {
const inscription = await eventInscriptionService._getInscriptionById(inscriptionId);
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>><Inscripcion a borrar:');
console.log(inscription);
if (!inscription)
if (!inscription || (inscription.userId !== user.id))
return handleResultResponse("Inscription no encontrada", null, params, res, httpStatus.NOT_FOUND);
//Borramos inscripcion y descontamos asistentes
@ -334,8 +378,22 @@ console.log('actualizo confirmados de la nueva reserva');
return handleErrorResponse(MODULE_NAME, 'createInscription', error, res);
}
const marketingListOfInscription = dataInscription.event.marketing_list;
/*
if (dataInscription.inscription.reservationId)
marketingListOfInscription = dataInscription.reservation.marketingList
else if (dataInscription.inscription.overflowEventId)
marketingListOfInscription = (await _getEvent(dataInscription.inscription.overflowEventId)).marketingList;
else
marketingListOfInscription = dataInscription.event.marketingList;
*/
eventInscriptionService._addMember(marketingListOfInscription, dataUser.userResult.user, dataInscription.inscription, dataInscription.reservation)
return handleResultResponse(await dataInscription.inscription.toJSON(), null, params, res, httpStatus.CREATED)
/*
if (invitationCode) {
_getLevelAndPartner()
@ -362,6 +420,34 @@ console.log('actualizo confirmados de la nueva reserva');
.catch(_handleError);
}
*/
},
getQRCodeInscription: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, {});
const inscriptionId = params.params.id;
const userId = req.user.id;
try {
const inscription = await eventInscriptionService._getInscriptionById(inscriptionId);
if (!inscription) {
return handleResultResponse("Inscription no encontrada", null, params, res, httpStatus.NOT_FOUND);
} else if (inscription.userId !== userId) {
return handleResultResponse("Inscription no encontrada", null, params, res, httpStatus.NOT_FOUND);
}
const qrConfig = {
name: req.user.name,
surname: req.user.surname,
code: inscription.code_ticket,
color: (inscription.level && inscription.level.color) ? inscription.level.color : null,
}
const qrCode = await QRHelper.getInscriptionQRCode(qrConfig);
return handleResultResponse(qrCode, null, params, res, httpStatus.OK);
} catch (error) {
return handleResultResponse("Error al buscar la inscripción", null, params, res, httpStatus.NOT_FOUND);
}
},

View File

@ -3,6 +3,39 @@ const moment = require('moment');
const Sequelize = require('sequelize');
moment.locale('es');
const getStateCode = (event) => {
var currentDate = moment().utc(),
initDate = moment.utc(event.ini_date),
endDate = moment.utc(event.end_date),
init_availableDate = moment.utc(event.init_available_date),
end_availableDate = moment.utc(event.end_available_date);
if (moment(currentDate).isBetween(initDate, endDate)) {
return 'current_event';
} else {
if (moment(endDate).isBefore(currentDate)) {
return 'closed_event';
} else {
if (moment(currentDate).isBefore(init_availableDate)){
return 'future_registrations'
} else {
if (moment(currentDate).isBetween(init_availableDate, end_availableDate)) {
return (event.sold_out == 1) ? 'waitinglist_open' : 'registrations_open';
}
else {
if (moment(currentDate).isAfter(end_availableDate))
return 'closed_registrations'
else
return 'N/A';
}
}
}
};
};
const getStateText = (event) => {
var currentDate = moment().utc(),
initDate = moment.utc(event.ini_date),
@ -16,10 +49,19 @@ const getStateText = (event) => {
if (moment(endDate).isBefore(currentDate)) {
return 'Congreso finalizado';
} else {
if (moment(currentDate).isBetween(init_availableDate, end_availableDate)) {
return (event.sold_out == 1) ? 'Inscripciones abiertas a lista de espera' : 'Inscripciones abiertas';
} else {
if (moment(currentDate).isBefore(init_availableDate)) {
return 'Inscripciones a partir del ' + moment(init_availableDate).format('D [de] MMMM');
} else {
if (moment(currentDate).isBetween(init_availableDate, end_availableDate)) {
return (event.sold_out == 1) ? 'Inscripciones abiertas a lista de espera' : 'Inscripciones abiertas';
}
else {
if (moment(currentDate).isAfter(end_availableDate))
return 'Inscripciones cerradas'
else
return 'N/A';
}
}
}
};
@ -95,6 +137,12 @@ module.exports = function (sequelize, DataTypes) {
allowNull: false,
defaultValue: 'draft'
},
stateCode: {
type: Sequelize.VIRTUAL(Sequelize.STRING, ['init_date', 'end_date', 'init_available_date', 'end_available_date', 'sold_out']),
get: function () {
return getStateCode(this);
},
},
stateText: {
type: Sequelize.VIRTUAL(Sequelize.STRING, ['init_date', 'end_date', 'init_available_date', 'end_available_date', 'sold_out']),
get: function () {
@ -109,6 +157,9 @@ module.exports = function (sequelize, DataTypes) {
type: DataTypes.UUID,
foreignKey: true,
},
city: {
type: DataTypes.STRING,
},
url_streaming: {
type: DataTypes.STRING,
},
@ -133,14 +184,14 @@ module.exports = function (sequelize, DataTypes) {
defaultScope: {
where: {
state: 'publish'
state: 'publish',
typeId: { [Sequelize.Op.ne]: 2 },
},
include: [{
model: sequelize.models.EventType,
as: 'type',
attributes: ['name', 'title'],
}]
},
});
@ -155,22 +206,15 @@ module.exports = function (sequelize, DataTypes) {
Event.Details = Event.hasMany(models.EventDetail, { foreignKey: 'eventId', as: "details" });
//OJOJOJOJOJOJOJJOJ
//OJO antes de force comentar
// OJO GENERA UN FOREIGN KEY Con eventos y habrá ID de otras entidades que no exitan en la tabla eventos, porque son post o speakers
// Event.Comments = Event.hasMany(models.Comment, {
// foreignKey: 'entityId',
// scope: {
// entityName: 'event'
// },
// as: "comments"
// });
// Event.Multimedias = Event.hasMany(models.Multimedia, {
// foreignKey: 'entityId',
// scope: {
// entityName: 'event'
// },
// as: { singular: 'multimedia', plural: 'multimedias' }});
Event.Comments = Event.hasMany(models.Comment, {
foreignKey: 'entityId',
scope: {
entityName: 'event'
},
as: "comments"
});
Event.Multimedias = Event.hasMany(models.Multimedia, {
foreignKey: 'entityId',
@ -243,7 +287,7 @@ module.exports = function (sequelize, DataTypes) {
model: sequelize.models.MultimediaFile,
as: "multimediaFile"
}]
}]
}]
}]
}]
}
@ -296,5 +340,24 @@ module.exports = function (sequelize, DataTypes) {
},
});
Event.addScope('CitiesOfEvents', () => {
return {
group: ['city'],
attributes: ['city', [sequelize.fn('COUNT', sequelize.col('id')), 'ediciones']]
}
});
Event.addScope('onlyOfCity', (city) => {
return {
where: {
city: {
[Sequelize.Op.eq]: city
}
},
}
});
return Event;
};

View File

@ -3,6 +3,7 @@ const routes = require('express').Router();
const { isAdministratorUser, isLoggedUser } = require('../../middlewares/accessValidator');
const SchemaValidator = require('../../middlewares/schemaValidator');
const { cacheSuccesses } = require('../../middlewares/cache');
const PaginateMiddleware = require('../../middlewares/paginate');
const FieldMiddleware = require('../../middlewares/fields');
const SortMiddleware = require('../../middlewares/sort');
@ -25,11 +26,27 @@ routes.get('/events',
}),
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "-init_date" }),
eventController.find({
scopes: ['defaultScope', 'includeVenue', 'includeMultimedias'],
}),
(req, res, next) => {
if (!req.body.city)
return eventController.find({
scopes: ['defaultScope', 'includeVenue', 'includeMultimedias', 'includeSpeakers'],
})(req, res, next)
else
return eventController.find({
scopes: ['defaultScope', 'includeVenue', 'includeMultimedias', 'includeSpeakers', { method: ['onlyOfCity', req.body.city] }]
})(req, res, next);
}
);
routes.get('/events/cities',
isLoggedUser,
SortMiddleware.middleware({ default: "city" }),
eventController.find({
scopes: ['CitiesOfEvents']
})
);
routes.get('/events/next',
isLoggedUser,
FieldMiddleware.middleware({
@ -42,7 +59,7 @@ routes.get('/events/next',
}),
);
routes.get('/events/past',
routes.get('/events/past', cacheSuccesses('24 hours'),
isLoggedUser,
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
@ -84,7 +101,6 @@ routes.get('/events/:id',
invalidFields: generalInvalidFields
}),
(req, res, next) => {
console.log(req.user.id);
return eventController.findOne({
scopes: ['defaultScope', 'includeVenue', 'includeMultimedias', 'includeSpeakers', { method: ['includeInscription', req.user.id] }]
})(req, res, next)
@ -121,12 +137,62 @@ routes.get('/events/:id/inscriptions',
eventController.getInscriptions,
);
// Esto da todas las inscripciones de un usuario
routes.get('/me/inscriptions/count',
isLoggedUser,
/*(req, res, next) => {
req.apicacheGroup = req.user.id;
next();
},
cacheSuccesses('1 hour'),*/
eventController.getInscriptionsOfNextEventsCount,
);
// Esto da todas las inscripciones de un usuario
routes.get('/me/inscriptions',
isLoggedUser,
/*(req, res, next) => {
req.apicacheGroup = req.user.id;
next();
},
cacheSuccesses('1 hour'),*/
eventController.getInscriptions,
);
// Esto da la inscripción de un usuario
routes.get('/me/inscriptions/:id',
isLoggedUser,
/*(req, res, next) => {
req.apicacheGroup = req.user.id;
next();
},
cacheSuccesses('1 hour'),*/
eventController.getInscription,
);
// Inscription QR Code
routes.get('/me/inscriptions/:id/qr', isLoggedUser,
//cacheSuccesses('1 hour'),
eventController.getQRCodeInscription,
);
/*router.get('/:conferenceId/inscription/:userId/qrimage', function (req, res) {
conference.getInscriptionQRCode(req.params.conferenceId, req.params.userId, function (result, status) {
if (result && result.data) {
var buffer = new Buffer(result.data.split(",")[1], 'base64');
res.writeHead(status, {
'Content-Type': 'image/png',
'Content-Length': buffer.length
});
res.end(buffer);
} else {
res.status(200).end('')
}
});
});*/
// Hacer una inscripción
routes.post('/events/:id/inscriptions',
isLoggedUser,

View File

@ -6,7 +6,7 @@ const moment = require('moment');
const { generateService, parseParamsToFindOptions } = require('../../helpers/service.helper');
const Sequelize = require('sequelize');
const models = require('../../core/models');
const { eventComposer } = require('../../helpers/composes.helper');
const { citiesComposer, eventComposer } = require('../../helpers/composes.helper');
const extraMethods = {
@ -17,12 +17,17 @@ const extraMethods = {
}
let rows = result.rows.map(row => row.toJSON());
rows = rows.map(event => eventComposer(event, context));
if (context.scopes.includes('CitiesOfEvents'))
rows = rows.map(city => citiesComposer(city, context))
else
rows = rows.map(event => eventComposer(event, context));
return {
count: rows.length,
rows: rows
}
},
afterFetchOne: (result, params, context) => {
@ -50,9 +55,9 @@ const extraMethods = {
where: { id: eventId }
})
.then(function (result) {
const aaa = result[0];
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaa');
console.log(aaa);
//const aaa = result[0];
//console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaa');
//console.log(aaa);
resolve((result[0] === 1));
})
.catch(function (error) {
@ -71,9 +76,9 @@ const extraMethods = {
where: { id: eventId }
})
.then(function (result) {
const aaa = result[0];
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaa');
console.log(aaa);
//const aaa = result[0];
//console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaa');
//console.log(aaa);
resolve((result[0] === 1));
})
.catch(function (error) {

View File

@ -81,7 +81,8 @@ module.exports = function (sequelize, DataTypes) {
include: [{
model: sequelize.models.Event,
as: 'event',
attributes: ['id', 'name', 'description', 'campaign_text', 'init_date'],
attributes: ['id', 'name', 'description', 'campaign_text', 'init_date', 'end_date', 'init_available_date',
'end_available_date', 'stateCode', 'stateText'],
include: [{
model: sequelize.models.Venue,
as: 'venue',

View File

@ -5,6 +5,10 @@ const _ = require('lodash');
const moment = require('moment');
const { generateService, parseParamsToFindOptions } = require('../../helpers/service.helper');
const models = require('../../core/models');
const marketing = require('../../helpers/mailchimp.helper')
const Sequelize = require('sequelize');
moment.locale('es');
function generateNewCodeTicket() {
@ -31,10 +35,10 @@ function generateNewCodeTicket() {
const extraMethods = {
_getInscriptionById: (Id) => {
return models.EventInscription.findOne({
_getInscriptionById: (id) => {
return models.EventInscription.scope('includeEventAndVenue').findOne({
where: {
id: Id,
id: id,
},
})
},
@ -59,6 +63,18 @@ const extraMethods = {
})
},
_getInscriptionsOfNextEventsUser: (userId) => {
return models.EventInscription.count({
include: [{ model: models.Event,
as: 'event',
where: {
end_date: {[Sequelize.Op.gte]: moment().utc()},
}
}],
where: { userId: userId },
});
},
//Nos devuelve el número de inscripciones confirmadas para ese evento sin tener en cuenta reservas
_getCountInscriptionsWithoutReservationAndOverflow: (eventId) => {
return models.EventInscription.count({
@ -132,6 +148,45 @@ const extraMethods = {
}
});
},
_addMember: (marketingListId, user, inscription, reservation) => {
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasddddddmemberrrrr1');
console.log(user);
var member = {
email: user.email,
name: user.name,
surname: user.surname,
source: inscription.source,
reservation_code: (reservation) ? reservation.reservation_code : null,
code_ticket: inscription.code_ticket,
validated: inscription.validated,
color: (reservation) ? reservation.color : 'white',
description: (reservation) ? reservation.description : 'entrada libre',
entityId: (reservation) ? reservation.entityId : user.entityId,
userId: user.id
}
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasddddddmemberrrrr1');
console.log(marketingListId, member.validated);
return new Promise(function (resolve, reject) {
if (!marketingListId || !member.validated) {
resolve(member)
} else {
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasddddddmemberrrrr2');
marketing.addMember(marketingListId, member)
.then(function (result) {
member = result;
resolve(member);
})
.catch(function (error) {
reject(error)
});
}
});
},
};

View File

@ -23,33 +23,6 @@ module.exports = function (sequelize, DataTypes) {
type: DataTypes.STRING,
allowNull: false,
},
/*entity: {
type: DataTypes.VIRTUAL,
get: function() {
const name = this.get('entityName');
const id = this.get('entityId');
let modelName = '';
switch (name) {
case 'post':
modelName = 'Post';
break;
case 'speaker':
modelName = 'Speaker'
break;
case 'event':
modelName = 'Event';
break;
default:
break;
}
return sequelize.models[modelName].findByPk(id).then(function(result) { return result });
}
}*/
}, {
indexes: [{
unique: false,

View File

@ -13,7 +13,7 @@ const SortMiddleware = require('../../middlewares/sort');
const multimediaController = require('./multimedia.controller');
routes.get('/multimedias', //cacheSuccesses,
routes.get('/multimedias', //cacheSuccesses('24 hours'),
PaginateMiddleware.middleware(),
//SortMiddleware.middleware({ default: "init_available_date" }),
multimediaController.find({
@ -21,7 +21,7 @@ routes.get('/multimedias', //cacheSuccesses,
})
);
routes.get('/multimedias/:id', //cacheSuccesses,
routes.get('/multimedias/:id', //cacheSuccesses('24 hours'),
//PaginateMiddleware.middleware(),
//SortMiddleware.middleware({ default: "init_available_date" }),
multimediaController.findOne({

View File

@ -17,7 +17,6 @@ const extraMethods = {
}
const multimedia = result.toJSON();
console.log(multimedia);
if (multimedia.provider === 'vimeo') {
multimedia.providerInfo = await providerComposer(multimedia);

View File

@ -14,7 +14,7 @@ const generalInvalidFields = [
'userId', 'createdAt', 'updatedAt',
];
routes.get('/multimediafiles', cacheSuccesses,
routes.get('/multimediafiles', cacheSuccesses('24 hours'),
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
}),
@ -25,7 +25,7 @@ routes.get('/multimediafiles', cacheSuccesses,
})
);
routes.get('/multimediafiles/:id', cacheSuccesses,
routes.get('/multimediafiles/:id', cacheSuccesses('24 hours'),
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
}),

View File

@ -17,7 +17,7 @@ const extraMethods = {
}
const multimedia = result.toJSON();
console.log(multimedia);
if (multimedia.provider === 'vimeo') {
multimedia.providerInfo = await providerComposer(multimedia);

View File

@ -84,7 +84,7 @@ module.exports = function (sequelize, DataTypes) {
Speaker.EventDetails = Speaker.hasMany(models.EventDetail, { foreignKey: 'speakerId', as: "eventdetails" });
Speaker.Questions = Speaker.hasMany(models.EventQuestion, { foreignKey: 'speakerId', as: "questions" });
//OJOJOJOJOJOJOJJOJ
//OJO antes de force comentar
// OJO GENERA UN FOREIGN KEY Con eventos y habrá ID de otras entidades que no exitan en la tabla eventos, porque son post o speakers
Speaker.Multimedias = Speaker.hasMany(models.Multimedia, {
foreignKey: 'entityId',
@ -119,7 +119,7 @@ module.exports = function (sequelize, DataTypes) {
include: [{
model: sequelize.models.MultimediaFile,
as: "multimediaFile"
}]
}]
},
]
}

View File

@ -16,14 +16,14 @@ const generalInvalidFields = [
// Todos los ponentes
routes.get('/speakers',
isLoggedUser,
//isLoggedUser,
FieldMiddleware.middleware({
invalidFields: generalInvalidFields
}),
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "name" }),
speakerController.find({
scopes: ['defaultScope', 'includeValues'],
scopes: ['defaultScope', 'includeValues', 'includeMultimedias'],
})
);

View File

@ -18,7 +18,7 @@ const extraMethods = {
rows = rows.map(speaker => speakerComposer(speaker, context));
return {
count: rows.length,
count: result.count,
rows: rows
}
},

View File

@ -19,7 +19,8 @@ module.exports = function (sequelize, DataTypes) {
Value.Speakers = Value.belongsToMany(models.Speaker, {
through: models.SpeakerValue,
foreignKey: 'valueId'
foreignKey: 'valueId',
as: 'speakers'
});
};

View File

@ -17,7 +17,7 @@ routes.get('/values',
}),*/
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "name" }),
valueController.find
valueController.find()
);
routes.get('/values/:id',
@ -25,17 +25,18 @@ routes.get('/values/:id',
FieldMiddleware.middleware({
invalidFields: ['createdAt']
}),
valueController.findOne
valueController.findOne()
);
routes.get('/values/:id/speakers',
(req, res, next) => {
req.params.association = 'Speakers';
req.params.association = 'speakers';
next();
},
valueController.find,
valueController.find(),
);
//routes.get('/values/:id/:association',
//isLoggedUser,
/*FieldMiddleware.middleware({

View File

@ -35,7 +35,6 @@ function findModelAssociationByForeignIdentifier(model, foreignId) {
Object.keys(model.associations).forEach((key) => {
if (model.association[key].foreignIdentifier === foreignId) {
console.log('encontrado');
const accessors = model.association[key].accessors;
return {
name: model.association[key].as,

View File

@ -3,21 +3,34 @@ const routes = require('express').Router();
const { isAdministratorUser, isLoggedUser } = require('../../middlewares/accessValidator');
const SchemaValidator = require('../../middlewares/schemaValidator');
/*const PaginateMiddleware = require('../../middlewares/paginate');
const FieldMiddleware = require('../../middlewares/fields');*/
//const SortMiddleware = require('../../middlewares/sort');
//const PaginateMiddleware = require('../../middlewares/paginate');
//const FieldMiddleware = require('../../middlewares/fields');
const SortMiddleware = require('../../middlewares/sort');
const VenueValidation = require('./venue.validations');
const venueController = require('./venue.controller');
routes.get('/venues',
//SortMiddleware.middleware({ default: "name" }),
venueController.find({})
isLoggedUser,
//SortMiddleware.middleware({ default: "name" }),
venueController.find()
);
//routes.get('/venues', isLoggedUser, SortMiddleware.middleware({ default: "name" }), venueController.find);
//routes.get('/venues/:id', isLoggedUser, venueController.findOne);
//routes.get('/venues/:id',
//isLoggedUser,
//venueController.findOne();
/*
routes.get('/venues/:id/events',
//isLoggedUser,
//SortMiddleware.middleware({ default: "name" }),
(req, res, next) => {
req.params.association = 'Events';
next();
},
venueController.find());
*/
routes.post('/venues/', SchemaValidator(VenueValidation.VenueInputType, true), venueController.create);
//routes.put('/venues/:id', isAdministratorUser, venueController.update);
//routes.delete('/venues/:id', isAdministratorUser, venueController.delete);

View File

@ -5,6 +5,8 @@ const _ = require('lodash');
const { generateService, parseParamsToFindOptions } = require('../../helpers/service.helper');
const models = require('../../core/models');
const extraMethods = {};
const extraMethods = {
};
module.exports = generateService(models.Venue, extraMethods);

View File

@ -51,12 +51,14 @@
"passport-local": "^1.0.0",
"path": "^0.12.7",
"pino": "^4.7.1",
"qrcode": "^1.4.1",
"rand-token": "^0.4.0",
"redis": "^2.8.0",
"response-time": "^2.3.2",
"sequelize": "^5.6.1",
"vimeo": "^2.1.1",
"vm": "^0.1.0",
"winston": "^3.2.1"
"winston": "^3.2.1",
"mailchimp-api-v3": "^1.12.0"
}
}

File diff suppressed because one or more lines are too long

View File

@ -8,8 +8,6 @@ script-carga-bd-envents_venues_aux.sql
script-carga-bd-speaker_types.sql
script-carga-bd-entidades.sql
insert into lqdvi_v2.entities_entities_types (entityid, typeid, createdAt, updatedAt)
select id, '76b17163-a167-11e9-a57c-000c295f0f58', now(), now() from `entities`
insert into lqdvi_v2.`multimedia_files` (id, name, description, type, provider, code, url, createdAt, userId, updatedAt)
SELECT a.id, a.title, a.description, 'video', a.provider, a.code, a.url, a.created, '0939bb2a-d33d-4290-ac81-fc9faa1c015e', now()
@ -34,6 +32,9 @@ FROM lqdvi.speaker;
insert into lqdvi_v2.speakers_values (speakerid, valueId, createdAt, updatedAt)
SELECT speakerid, valueid, now(), now() FROM lqdvi.`speaker-value`;
//insertamos los videos relacionados
insert into lqdvi_v2.`multimedias` (id, entityId, entityName, multimediafileId, type, createdAt, updatedAt)
SELECT UUID() as ID, conferenceId as eventID, 'event', videoId as multimediafileid, 'relacion', now(), now()
@ -120,37 +121,6 @@ FROM lqdvi.partner a
left join lqdvi.level b on (b.partnerId = a.id);
//INSERTAMOS LAS ENTIDADES
insert into lqdvi_v2.entities
(id, name, state, createdAt, updatedAt, contact_person, contact_email )
SELECT UUID() as ID, name, 'ff', now(), now(), contact_name, contact_email
FROM lqdvi.partner;
//ASIGNAMOS QUE SON PARTNERS
insert into lqdvi_v2.entities_entities_types
(entityid, typeid, createdAt, updatedAt)
select id, '32d6306a-aa02-11e9-a553-000c295f0f58', now(), now()
from lqdvi_v2.entities
where state = 'ff';
update lqdvi_v2.entities
set state = 'publish'
where state = 'ff';
//OJO ASIGNAMOS EVENTO SEVILLA PARA PRUEBA, ESTE DEBE SER LUEGO LA CORUÑA
update lqdvi_v2.events_reservations
set eventID = '5f772798-5616-4663-a661-b6484dd11bd7';
//ENLAZAMOS CON LAS RESERVAS
//Metemos las preguntas de los congresos
insert into lqdvi_v2.events_questions (id, eventId, speakerId, anonimous, answered, discared, answer, userId, createdAt, updatedAt)
SELECT UUID() as ID, conferenceId, speakerId, anonymous, answered, discared, content, '0939bb2a-d33d-4290-ac81-fc9faa1c015e', created, now() FROM lqdvi.question;
//COMENTARIOS.....
insert into lqdvi_v2.comments (id, entityId, entityname, content, createdAt, updatedAt, userId)
@ -160,5 +130,28 @@ FROM lqdvi.`speaker-comment`;
insert into lqdvi_v2.events_reservations (id, init_available_date, end_available_date, gmt, state,
assistants, confirmed, sold_out, allow_multiple, multiple_limit,
description, reservation_code, color, allow_overflow, overflow_reservationId, marketing_list, createdat, updatedAt, userID, entityId, eventId)
SELECT UUID() as ID, '2019-09-03 00:00:00', '2019-10-03 22:00:00', 2, 'publish',
lqdvi.level.assistants, lqdvi.level.confirmed, lqdvi.level.sold_out, 0, 0,
lqdvi.level.name, lqdvi.level.invitation_code, lqdvi.level.color, 1, null, null,
now(), now(), '0939bb2a-d33d-4290-ac81-fc9faa1c015e', '6c2df93f-af83-11e9-aa90-000c295f0f58','5f772798-5616-4663-a661-b6484dd11bd7'
FROM lqdvi.level
where lqdvi.level.partnerId = '2851f45a-287a-41cc-8258-d50ffe02699b'
insert into events (id, name, description, init_date, init_available_date, end_available_date, gmt,
assistants, confirmed, sold_out, allow_multiple, state, typeid, venueId, userId,
createdAt, updatedAt)
select UUID() as ID, 'Lista de espera - Sevilla 2019', description, now(), init_available_date, end_available_date, gmt,
10000, 0, 0, 0, state, 2, venueId, userId, createdAt, updatedAt
from lqdvi_v2.events
where id = '5f772798-5616-4663-a661-b6484dd11bd7'

File diff suppressed because one or more lines are too long

View File

@ -1,81 +0,0 @@
-- MySQL dump 10.13 Distrib 5.7.26, for Linux (x86_64)
--
-- Host: localhost Database: lqdvi_v2
-- ------------------------------------------------------
-- Server version 5.7.26-0ubuntu0.16.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `entities`
--
DROP TABLE IF EXISTS `entities`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `entities` (
`id` char(36) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`name` varchar(255) NOT NULL,
`state` varchar(45) NOT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `entities_entities_types`
--
DROP TABLE IF EXISTS `entities_entities_types`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `entities_entities_types` (
`entityId` char(36) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`typeId` char(36) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`entityId`,`typeId`),
UNIQUE KEY `entities_entities_types_entityId_typeId_unique` (`entityId`,`typeId`),
KEY `typeId` (`typeId`),
CONSTRAINT `entities_entities_types_ibfk_1` FOREIGN KEY (`entityId`) REFERENCES `entities` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `entities_entities_types_ibfk_2` FOREIGN KEY (`typeId`) REFERENCES `entities_types` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `entities_types`
--
DROP TABLE IF EXISTS `entities_types`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `entities_types` (
`id` char(36) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`name` varchar(255) NOT NULL,
`alias` varchar(45) NOT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-07-10 13:14:45

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,37 +0,0 @@
-- MySQL dump 10.13 Distrib 5.7.26, for Linux (x86_64)
--
-- Host: localhost Database: lqdvi_v2
-- ------------------------------------------------------
-- Server version 5.7.26-0ubuntu0.16.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Dumping data for table `entities_types`
--
LOCK TABLES `entities_types` WRITE;
/*!40000 ALTER TABLE `entities_types` DISABLE KEYS */;
INSERT INTO `entities_types` VALUES ('32d6306a-aa02-11e9-a553-000c295f0f58','ENTIDADES PATROCINADORAS COLABORADORAS','partner','2019-07-08 12:02:15','2019-07-08 12:02:15'),('76b17163-a167-11e9-a57c-000c295f0f58','ENTIDADES EDUCATIVAS COLABORADORAS','college','2019-07-08 12:02:15','2019-07-08 12:02:15');
/*!40000 ALTER TABLE `entities_types` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-07-19 10:52:18

118
venues-events.sql Normal file

File diff suppressed because one or more lines are too long

171
yarn.lock
View File

@ -325,12 +325,17 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
ansi-regex@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
ansi-styles@^3.2.1:
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
@ -617,6 +622,11 @@ camelcase@^4.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
camelcase@^5.0.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
camelize@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
@ -725,6 +735,15 @@ cli-width@^2.0.0:
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
cliui@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
dependencies:
string-width "^3.1.0"
strip-ansi "^5.2.0"
wrap-ansi "^5.1.0"
cls-bluebird@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.1.0.tgz#37ef1e080a8ffb55c2f4164f536f1919e7968aee"
@ -1010,6 +1029,11 @@ debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "^2.1.1"
decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@ -1098,6 +1122,11 @@ dicer@^0.3.0:
dependencies:
streamsearch "0.1.2"
dijkstrajs@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b"
integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs=
dns-prefetch-control@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2"
@ -1200,6 +1229,11 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
enabled@1.0.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93"
@ -1567,6 +1601,13 @@ finalhandler@1.1.1:
statuses "~1.4.0"
unpipe "~1.0.0"
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
dependencies:
locate-path "^3.0.0"
firebase-admin@^8.1.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/firebase-admin/-/firebase-admin-8.2.0.tgz#d2ff17fc427f7db5e9b1ee897bdf9c0c26773cc0"
@ -1732,6 +1773,11 @@ generate-function@^2.3.1:
dependencies:
is-property "^1.0.2"
get-caller-file@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
@ -2347,6 +2393,11 @@ isarray@1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
isarray@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isemail@3.x.x:
version "3.2.0"
resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c"
@ -2501,6 +2552,14 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
locate-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
dependencies:
p-locate "^3.0.0"
path-exists "^3.0.0"
lodash.at@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.at/-/lodash.at-4.6.0.tgz#93cdce664f0a1994ea33dd7cd40e23afd11b0ff8"
@ -3108,6 +3167,25 @@ p-finally@^1.0.0:
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
p-limit@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2"
integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==
dependencies:
p-try "^2.0.0"
p-locate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
dependencies:
p-limit "^2.0.0"
p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
package-json@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed"
@ -3167,6 +3245,11 @@ path-dirname@^1.0.0:
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
@ -3239,6 +3322,11 @@ pluralize@^7.0.0:
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
pngjs@^3.3.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
posix-character-classes@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
@ -3336,6 +3424,16 @@ punycode@2.x.x:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qrcode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.1.tgz#2126814985d0dbbd9aee050fc523d319c6a7dc3b"
integrity sha512-3JhHQJkKqJL4PfoM6t+B40f0GWv9eNJAJmuNx2X/sHEOLvMyvEPN8GfbdN1qmr19O8N2nLraOzeWjXocHz1S4w==
dependencies:
dijkstrajs "^1.0.1"
isarray "^2.0.1"
pngjs "^3.3.0"
yargs "^13.2.4"
qs@6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@ -3500,6 +3598,16 @@ repeat-string@^1.6.1:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
require-uncached@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
@ -3694,7 +3802,7 @@ serve-static@1.13.2:
parseurl "~1.3.2"
send "0.16.2"
set-blocking@~2.0.0:
set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
@ -3904,6 +4012,15 @@ string-width@^1.0.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
string-width@^3.0.0, string-width@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
dependencies:
emoji-regex "^7.0.1"
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string_decoder@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
@ -3937,6 +4054,13 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.0"
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@ -4288,6 +4412,11 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@ -4344,6 +4473,15 @@ wordwrap@~1.0.0:
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
wrap-ansi@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
dependencies:
ansi-styles "^3.2.0"
string-width "^3.0.0"
strip-ansi "^5.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@ -4390,6 +4528,11 @@ xtend@~4.0.1:
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
@ -4399,3 +4542,27 @@ yallist@^3.0.0, yallist@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
yargs-parser@^13.1.1:
version "13.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs@^13.2.4:
version "13.3.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"
integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==
dependencies:
cliui "^5.0.0"
find-up "^3.0.0"
get-caller-file "^2.0.1"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^3.0.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.1.1"