From df05b33e828c9a4a062df9f63fbc2ad938f54f3a Mon Sep 17 00:00:00 2001 From: vjrj Date: Thu, 11 Jan 2018 12:28:55 +0100 Subject: [PATCH] Fix in IPGeocode (download, and fallback). Schema improvements --- README.md | 6 ++- .../api/ActiveFires/server/publications.js | 4 +- imports/api/Subscriptions/Subscriptions.js | 7 ++- imports/api/Users/Users.js | 3 +- imports/startup/server/IPGeocoder.js | 20 ++++++-- imports/startup/server/migrations.js | 48 ++++++++++++++++++- 6 files changed, 77 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5d2adc6..d727be7 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ A boilerplate for products. [Read the Documentation](http://cleverbeagle.com/pup) ---- +#### GeoIP -Need help and want to stay accountable building your product? [Check out Clever Beagle](http://cleverbeagle.com). +Configure mirror and cron on geoip database. See http://dev.maxmind.com/geoip/geoip2/geolite2/ + +--- diff --git a/imports/api/ActiveFires/server/publications.js b/imports/api/ActiveFires/server/publications.js index 701e9a1..1af883f 100644 --- a/imports/api/ActiveFires/server/publications.js +++ b/imports/api/ActiveFires/server/publications.js @@ -121,7 +121,7 @@ Meteor.publish('activefiresmyloc', function activeInMyLoc(zoom, lat, lng, height if (lat && lng) { return activefires(zoom, lat, lng, height, width); } - const location = localize(); + const geo = localize(); // console.log(`${location.latitude}, ${location.longitude}`); - return activefires(zoom, location.latitude, location.longitude, height, width); + return activefires(zoom, geo.location.latitude, geo.location.longitude, height, width); }); diff --git a/imports/api/Subscriptions/Subscriptions.js b/imports/api/Subscriptions/Subscriptions.js index b039ba1..9bc1d6f 100644 --- a/imports/api/Subscriptions/Subscriptions.js +++ b/imports/api/Subscriptions/Subscriptions.js @@ -1,7 +1,9 @@ /* eslint-disable consistent-return */ +/* eslint-disable import/no-absolute-path */ import { Mongo } from 'meteor/mongo'; import SimpleSchema from 'simpl-schema'; +import { defaultCreatedAt, defaultUpdateAt } from '/imports/api/Utility/Utils.js'; const Subscriptions = new Mongo.Collection('subscriptions', { idGeneration: 'MONGO' }); @@ -74,8 +76,11 @@ Subscriptions.schema = new SimpleSchema({ 'location.lon': Number, geo: LocationSchema, distance: Number, + chatId: { type: Number, optional: true }, // only in 'telegram' type owner: String, - type: String + type: String, + createdAt: defaultCreatedAt, + updatedAt: defaultUpdateAt }); Subscriptions.attachSchema(Subscriptions.schema); diff --git a/imports/api/Users/Users.js b/imports/api/Users/Users.js index f89aced..34ade38 100644 --- a/imports/api/Users/Users.js +++ b/imports/api/Users/Users.js @@ -1,5 +1,6 @@ /* eslint-disable consistent-return */ /* eslint-disable import/no-absolute-path */ + import { Meteor } from 'meteor/meteor'; import SimpleSchema from 'simpl-schema'; import { defaultCreatedAt, defaultUpdateAt } from '/imports/api/Utility/Utils.js'; @@ -105,7 +106,7 @@ const schemaUser = new SimpleSchema({ 'name.first': String, 'name.last': String, */ lang: { type: String, optional: true }, - telegramChatId: { type: Number, optional: true }, + telegramChatId: { type: SimpleSchema.Integer, optional: true }, telegramUsername: { type: String, optional: true }, telegramFirstName: { type: String, optional: true }, telegramLanguageCode: { type: String, optional: true }, diff --git a/imports/startup/server/IPGeocoder.js b/imports/startup/server/IPGeocoder.js index e145311..70e5395 100644 --- a/imports/startup/server/IPGeocoder.js +++ b/imports/startup/server/IPGeocoder.js @@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor'; import maxmind from 'maxmind'; +import fs from 'fs'; process.env.HTTP_FORWARDED_COUNT = Meteor.settings.private.proxies_count; if (!Meteor.isDevelopment) { @@ -17,7 +18,14 @@ function isPrivateIP(ip) { (parts[0] === '192' && parts[1] === '168'); } -const IPGeocoder = maxmind.openSync(`${process.env.PWD}/private/GeoLite2-City.mmdb`); +const dbpath = '/usr/local/share/maxmind-geolite2/GeoLite2-City.mmdb'; +// const dbpath = `${process.env.PWD}/private/GeoLite2-City.mmdb`; + +if (!fs.existsSync(dbpath)) { + console.error(`Maxmind db not found ${dbpath}, download via cron with https://www.npmjs.com/package/maxmind-geolite2-mirror`); +} + +const IPGeocoder = maxmind.openSync(dbpath); export default IPGeocoder; // Warning: Meteor cannot access to this.connection with arrow functions @@ -37,9 +45,13 @@ export function localize() { // TODO: cron download GeoLite-City // http://dev.maxmind.com/geoip/geoip2/geolite2/ - const location = IPGeocoder.get(clientIP); - // console.log(location); - return location; + const geo = IPGeocoder.get(clientIP); + // console.warn(geo); + if (geo.location && geo.location.latitude && geo.location.longitude) { + return geo; + } + // geoIP fallback, Madrid + return { location: { latitude: 40.4146500, longitude: -3.7004000 } }; } Meteor.methods({ diff --git a/imports/startup/server/migrations.js b/imports/startup/server/migrations.js index 14e7546..80c255d 100644 --- a/imports/startup/server/migrations.js +++ b/imports/startup/server/migrations.js @@ -1,6 +1,9 @@ /* global Migrations */ /* eslint-disable import/no-absolute-path */ import { Meteor } from 'meteor/meteor'; +import { Accounts } from 'meteor/accounts-base'; +import randomHex from 'crypto-random-hex'; +import UserSubsToFiresCollection from '/imports/api/Subscriptions/Subscriptions'; Meteor.startup(() => { // https://github.com/percolatestudio/meteor-migrations @@ -25,7 +28,50 @@ Meteor.startup(() => { } }); + Migrations.add({ + version: 2, + up: function migrateSubsForeignKey() { + UserSubsToFiresCollection.find({ owner: null }).forEach((sub) => { + console.log(`Migrating subs of chatId: ${sub.chatId}`); + const subsUser = Meteor.users.findOne({ telegramChatId: sub.chatId }); + if (subsUser) { + console.log(`Migrating linking to user: ${JSON.stringify(subsUser)}`); + UserSubsToFiresCollection.update({ _id: sub._id }, { $set: { owner: subsUser._id } }); + } else { + // create user with chatId and def language + const username = `tel${sub.chatId.toString().replace(/^-/, '')}`; + console.log(`Linking to new user: ${username}`); + const newUserId = Accounts.createUser({ + username, + password: randomHex(50), + profile: { name: {} } + }); + Meteor.users.update({ _id: newUserId }, { + $set: { + emails: [], + roles: ['user'], + telegramChatId: sub.chatId, + lang: 'es' + } + }); + UserSubsToFiresCollection.update({ _id: sub._id }, { $set: { owner: newUserId } }); + } + }); + } + }); + + Migrations.add({ + version: 3, + up: function emptySubsTypes() { + UserSubsToFiresCollection.find({ type: null }).forEach((sub) => { + UserSubsToFiresCollection.update({ _id: sub._id }, { $set: { type: 'telegram' } }); + }); + } + }); + + + // Set createdAt in users & subs Migrations.migrateTo('latest'); - // Migrations.migrateTo('1,rerun'); + // Migrations.migrateTo('2,rerun'); });