Meteor: Limiting DDP Connections with ddp-rate-limiter package - javascript

I am trying to prevent a user to be able to call a Meteor method too often with the Meteor package ddp-rate-limiter (For example to prevent spamming or a DOS attack), but I can not get it to work.
Does anybody have an idea?
server/ddpRateLimiter.js:
Meteor.methods({
dosAttack: function() {console.log("dos");}
});
var preventDosAttack= {
userId: function() {return true;},
type: 'method',
method: 'dosAttack'
}
DDPRateLimiter.addRule(preventDosAttack, 5, 1000);
With this code I can still run the method from the client console as often as I want to. (Tested with a for loop 100 times)
You can find the entire sourcecode here: opensource project
And this certain commit here: commit
Thank you very much for your help,
Max

My mistake is simple: It is not 'method': 'dosAttack' but 'name': 'dosAttack'. Seems like the example in the documentation MeteorDoc DDPRateLimiter does the same mistake. I created an issue on the meteor GitHub page

Rate limiting is now offered as a vendor-supported Meteor package. I've recently used it to create Meteor Candy, the admin panel for Meteor. Here's how I did it.
First, add the package:
meteor add ddp-rate-limiter.
Second, define the method:
Meteor.methods({
myFancyMethod: function () {
return true;
}
})
Finally, define the rate limiting rules for it:
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
var requestLimit = 5;
var requestTimeout = 5000;
DDPRateLimiter.addRule({
type: "method",
name: "myFancyMethod",
}, requestLimit, requestTimeout);

Related

Cloud Build Trigger returns 14 UNAVAILABLE: 502:Bad Gateway

Using the JavaScript library, NodeJS-CloudBuild we've been able to write a Cloud Function that triggers a new Cloud Build whenever we need.
It's been stable for a few months, but starting monday, we've been getting an inconsistent error whenever we call the function:
Error: 14 UNAVAILABLE: 502:Bad Gateway
The code sample is pretty simple, taken straight from the repository but with our variables.
// Creates a client
const cb = new CloudBuildClient();
// Starts a build against the branch provided.
const [resp] = await cb.runBuildTrigger({
projectId,
triggerId,
source: {
projectId,
dir: './',
branchName,
},
});
console.info(`triggered build for ${triggerId}`);
I'm not sure what changed recently to cause these return errors. It works fine when doing a "manual" trigger from the Cloud build dashboard, too.
It's been solved upstream. It wasn't the library's fault.

sails.js how to call a REST API from a script using restler or not?

I haven't figured out how to get a response from restler in sails.js script. The goal is to import some data each day from a REST API to my database. So I chose to use sails.js script to be able to crontab the call.
When I search what I could use to contact the API. I saw a topic about restler which seem pretty easy to use.
Sadly when I try it I cannot catch the response from the API, I use this basic example
module.exports = {
friendlyName: 'test',
description: 'this is a test',
fn: async function () {
sails.log('Running custom shell script... (`sails run test`)');
var rest = require('restler');
rest.get('http://google.com').on('complete', function(result) {
sails.log("In callback")
if (result instanceof Error) {
sails.log('Error:', result.message);
this.retry(5000); // try again after 5 sec
} else {
sails.log(result);
}
});
sails.log('finished');
}
};
When I run the script this is what I get
info: Initializing hook... (`api/hooks/custom`)
info: Initializing `apianalytics` hook... (requests to monitored routes will be logged!)
info: ·• Auto-migrating... (alter)
info: Hold tight, this could take a moment.
info: ✓ Auto-migration complete.
debug: Running custom shell script... (`sails run test`)
debug: finished
I try other method and other URL too, but apparently I never get in the callback.
So I assume that the script doesn't "wait" the .on('complete') before continuing his execution.
I know, and use, on the database call .then to avoiding that, I think this is called a 'promise'. So from what I understand the problem is around that but sadly after searching, I don't find any answer to solve my issue.
I am not married to restler, and if another and better solution exists don't hesitate, the goal is again to get the content from a REST API from sails.js script.
Thank you for the time you take to answer my question.

How to set a Angular config var to set server address?

How can I do some centralized solution to store strings on AngularJS? I've asked a similar question regarding NodeJS, but I don't know how to use the same approach to Angular as I've used to Node.
I've thought of 2 approaches:
1 - Setting a Angular Constant
app.constant('config',
{
serverUrl: 'http://localhost:8080'
});
This is my actual solution, but it comes with the downside that I need to update my code with the server address every time I send the code to the cloud.
2 - Using something like Node's process.env
And I have no idea how.
3 - Using something like require('./config.js')
I'm thinking on the Node like approach. Don't know how.
Well, is there a good, effective way of accomplishing this?
I do not think that there is one right answer. I prefer your first approach:
app.constant('config',
{
serverUrl: 'http://localhost:8080'
});
It is because I think about node.js backend and angular frontend as separete applications. For example I can add to node.js second version of api and connect other angular application (or event in another technology) to new api, but also use old angular app with previous api version.
In short in my opinion it is more flexible
Edit:
So, I need to update this line everytime I upload my come to Git
I don't add configuration file to repository. I create example config file which we add to repository. But actual config is ignored.
Edit2:
In one of mine project we use this module https://www.npmjs.com/package/gulp-ng-constant for build app.constant from config.json
This is how we switch the server url without rewriting it every time
var hostname = window.location.hostname;
if (hostname.indexOf("our.live.url") > -1) {
usedEnvironment = availableEnvironments.LIVE;
} else if (hostname.indexOf("localhost") > -1) {
usedEnvironment = availableEnvironments.LOCAL;
} else {
usedEnvironment = availableEnvironments.TEST;
}
switch (usedEnvironment) {
case availableEnvironments.LIVE:
angular.module('app')
.value('apiHost', 'https://our.live.backend.com');
angular.module('app')
.value('IntercomConfig', {
Enabled: true,
AppId: ''
});
break;
case availableEnvironments.TEST:
angular.module('app')
.value('apiHost', 'our.test.backend');
angular.module('app')
.value('IntercomConfig', {
Enabled: false,
});
break;
default:
angular.module('app')
.value('apiHost', 'http://localhost:8080');
angular.module('app')
.value('IntercomConfig', {
Enabled: false,
});
}

Running background tasks in Meteor.js

This is my scenario:
1. Scrape some data every X minutes from example.com
2. Insert it to Mongodb database
3. Subscribe for this data in Meteor App.
Because, currently I am not very good at Meteor this is what I am going to do:
1. Write scraper script for example.com in Python or PHP.
2. Run script every X minutes with cronjob.
3. Insert it to Mongodb.
Is it possible to do it completely with Meteor without using Python or PHP? How can I handle task that runs every X minutes?
There are Cron like systems such as percolate:synced-cron for Meteor. There, you could register a job using Later.js syntax similar to this example taken from the percolate:synced-cron readme file:
SyncedCron.add({
name: 'Crunch some important numbers for the marketing department',
schedule: function(parser) {
// parser is a later.parse object
return parser.text('every 2 hours');
},
job: function() {
var numbersCrunched = CrushSomeNumbers();
return numbersCrunched;
}
});
If you want to rely on an OS level cron job, you could just provide an HTTP endpoint in your Meteor.js application that you could then access through curl at the chosen time.
I can suggest Steve Jobs, my new package for scheduling background jobs in Meteor.
You can use the register, replicate, and remove actions
// Register the job
Jobs.register({
dataScraper: function (arg) {
var data = getData()
if (data) {
this.replicate({
in: {
minutes: 5
}
});
this.remove(); // or, this.success(data)
} else {
this.reschedule({
in: {
minutes: 5
}
})
}
}
})
// Schedule the job to run on Meteor startup
// `singular` ensures that there is only pending job with the same configuration
Meteor.startup(function () {
Jobs.run("dataScraper", {
in: {
minutes: 5
},
singular: true
})
})
Depending on your preference, you can store the result in the database, as part of the jobs history, or remove it entirely.

Number of visitors to my webpage

I am trying to create a webpage using meteor which records the number of visitors to the webpage. The webpage should record and display the number of people who visited the webpage.I am just a beginner to meteor and web design ,i have no experience whatsoever in using meteor and this is my first attempt. So any help is appreciated. Thank you in advance.
You can also run AWstats
http://awstats.sourceforge.net/
and install tutorial here:
http://www.youtube.com/watch?v=dOF4MDn_TI0
you can have something like this
collections\system.js
this.System = new Meteor.Collection('system');
Meteor.methods({
pageViewInc: function() {
System.update({ config: true }, { $inc: { 'stats.pageviews': 1 } });
}
});
if (Meteor.isServer) {
isSystemExist = System.findOne({ config: true });
if (!isSystemExist) {
options = {
stats: {
pageviews: 0
},
config: true
};
System.insert options
}
}
and somewhere you can have a function use to Meteor.call 'pageViewInc'
if u use Meteor-Iron-Router
you can have call in 'after' callback
Meteor.call('pageViewInc');
you can make similar method to Posts Collection.
or there's a meteor-collection-hooks packages
it has after findOne hook you can do it by server side.

Categories