I'm really not sure what the issue is here. Maybe I don't understand the publish/subscribe docs enough.
In my server directory:
Meteor.publish("kudos", function () {
return Kudos.find({});
});
In my client directory:
Meteor.startup(function(){
Meteor.subscribe("kudos");
});
Template.launchsection.kudos = function () {
return Kudos.find({});
};
When I run this, I get an error of Kudos is not defined for the line that returns Kudos.find({});.
What am I missing?
Specifically, you need to write Kudos = new Meteor.Collection("kudos") in both your client and server directory.
Make sure that you define the Schema in a js file which is executed on both, client and server. A file Schema.js in the root folder of your meteor app should do the trick. Have a look at this question.
Hope that helps! :)
Related
Is it possible to call the meteor functions from php. i need to call like this for integrate the new package on my site. the package in meteor js.
If it is possible please give the example for this
This is quite a simple one! In php you can do something with a http call such as file_get_contents("http://yoursite.com/api/yourfunction?variableOne=1");
Or even curl if you want
And in Meteor (assuming you understand Iron Router and server side routes) do something like
Router.route( "/api/yourfunction", function() { var variableOne = this.request.header.variableOne;
this.response.statusCode = 200; //Post your status code
this.response.end();}, { where: "server" });
If you are making a CORS request, remember to allow access to cross servers (don't use the wildcard *)
this.response.setHeader( 'access-control-allow-origin', '*' );
Edit: Did this answer help? If so please rate it
I am quite new to Meteor and I am trying to remove the insecure app. I have getting the above message. I have stripped down my code to the most basic. The function seems to run because I get console.log output (both hello's), but I still get the message and any changes I try to make to the database do not work.
My event code is:
Template.body.events({
'submit .new-user': function(event){
console.log("hello");
Meteor.call("addUser");
}
)};
The call...
Meteor.methods({
addUser: function(){
console.log("Hello");
}
});
Put your methods in the server folder.
If you leave the methods in any other place, the insecurity still persists.
Meteor has a convention where any code that’s placed within a folder named “server” will only run on the server. This is where we’d place the project’s methods, and the Meteor.publish statement.
from Tips on structuring meteor apps
I want to verify that I am placing my Iron Router code in the correct location. Right now I have it stored in lib/router.js, which means the code is shared on the client and server. Is that correct?
Also, some of my routes require admin status, such as:
Router.route('/manage', function () {
if ($.inArray('admin', Meteor.user().roles) > -1) {
this.render('manage');
} else {
this.render('403_forbidden');
}
});
Is that code safe in its current location? I am also interested in knowing how I can test these kinds of security holes so that I don't have to ask in the future.
Thanks
As to location of router.js ...
Yes, you want it to be available on both the client and server. So putting inside the /lib directory is fine. Really, you can put it anywhere other the the /client or /server directories.
FWIW, in most projects I've looked at, router.js is stored in the top-level project directory. Possibly this is to avoid load order issues (i.e. if the router has some dependencies on files in /lib, /client, or /server, which will generally be loaded before top-level files), or possibly its because everyone I've looked at is working off the same boilerplate code. Check out the Meteor official docs if you want to know more about load order.
As for your admin question, that route should be OK. You can test it by opening up a client side console like firebug and trying something like :
Meteor.users.update(Meteor.userId(), {$set: {roles: ['admin']}});
I believe users can only update fields in the Meteor.users.profile, so this should fail. If it doesn't, you can just add the following deny rule (in client + server);
Meteor.users.deny({
update: function() {
return true;
}
});
I just don't know exactly what I should put on the server side and what on the client side. I understand that the templates goes on the client side. But what about the javascript code? Can you give me an example of some code going on the server side?
You can write all your business logic and complex database operations in your server side code. Typically the code you don't want to serve to the client.
For example.
Method calls
# client-side
Template.post.events({
"click #add-post": function(e) {
var post, post_object;
post = $("#post-message").val().trim();
post_object = {
user_id: Meteor.userId(),
post: post
};
Meteor.call("create_post", post_object,(function(error, response) {
if(error){
..do something
}else{
.. do something else
});
);
}
});
# server-side
Meteor.methods({
create_post: function(post_object) {
return Posts.insert(post_object);
}
});
publish / subscribe
# common
Posts = new Mongo.Collection("posts");
# client-side
Meteor.subscribe("posts");
# server-side
Meteor.publish("posts", function(limit) {
return Posts.find({
user_id: this.userId
});
});
Html, css and Template managers should go into the client-side code. Meteor methods and publishers should go into the server-side code. Read more about structuring the app and data security in official docs.
Here is an example for a collection: Declare, publish and subscribe to it.
Server and client (any directory except private, client, or server, don't use public for that too), declare the collection:
Rocks = new Meteor.Collection('rocks');
Server-side (server directory or in a Meteor.isServer condition) ,publish the collection:
Meteor.publish('allRocks', function()
{
return Rocks.find();
}
Client-side (client directory or in a Meteor.isClient condition), subscribe to the publication:
Meteor.subscribe('allRocks');
You can find a lot of examples in the documentation or in this blog (Discover Meteor).
Edit: For more precision according to OP's question... All code is shared by default (executed by both the server and the client). However, files in the server and private directory will never be sent to the client.
if create a directory named client that goes only to client.
if you create a directory named server that goes only to server.
every thing else you code goes to client and server both. (even if
you use Meteor.isServer check)
you can read more about directory structure here.
You use Meteor.isClient and Meteor.isServer to load the code in the proper place.
Using the folder:
server - goes to the server duh!
client - goes to the client duh!
both - shared code
Everything that is placed outside client or server, is loaded on both places.
When you create Meteor package you've to add manually the files and specify where it should be loaded, example:
api.add_files(['my-packages.js', 'another-file.js'], 'client');
api.add_files(['server/methods.js'], 'server');
On this example althouhg you have a server folder, it doesn't mean that it be placed in the server, in the package scenario.
Something you've code that is going to run on the client and server but some functionalities might only be present at server or client.
Example:
ImageManager = {
uploadImageToAmazonS3 : function(){
if(Meteor.isServer){
//your code goes here
//YOU DON'T WANT TO SEND YOUR AMAZON PRIVATE KEY TO THE CLIENT
//BAD THINGS CAN HAPPEN LIKE A HUGE BILL
var amazonCredentials = Config.amazon.secretKey;
}
else{
throw new Error("You can't call this on the client.");
}
}
}
This a scenario where you can add functions that the client can do like: resizeImage, cropImage, etc and the server can also do this, this is shared code. Send a Private API KEY to the client is out of question but this file will be shared by the server and client.
Documentation: http://docs.meteor.com/#/basic/Meteor-isServer
According to the documentation this doesn't prevent the code from being sent to client, it simply won't run.
With this approach an attack knows how things work at the server and might try an attack vector based on the code that you sent to the him.
The best option here is extend the ImageManager only on the server. On the client this function shouldn't even exist or you can simply add a function throwing an error: "Not available".
I'm working on a Meteor app (a port from a PHP project) and I need to be able to run commands on my app from the server for various operations like clearing caches, aggregating data, etc. These commands need to be run from shell scripts and crontab. I've seen other people ask this question and apparently there's no official way to do it yet.
I read a suggestion of using Meteor methods and just calling them from the client's JS console with a password. This doesn't solve my problem of running them from the CLI, but it did give me an idea:
Would it be possible to use a headless browser (like PhantomJS) to connect to my app and execute Meteor.call() to simulate a CLI tool with arguments passed to the method? If possible, does anyone know how I might accomplish this?
Thanks!
EDIT: Updated to use Iron Router, the successor to Meteor Router.
There's no need for a headless browser or anything complicated. Use Meteorite to install Iron Router and define a server-side route:
Router.map(function () {
this.route('clearCache', {
where: 'server',
action: function () {
// Your cache-clearing code goes here.
}
});
});
Then have your cronjob trigger an HTTP GET request to that URI:
curl http://yoursite.com/clearCache
When the Meteor server receives the GET request, the router will execute your code.
For a little bit of security, add a check for a password:
Router.map(function () {
this.route('clearCache', {
path: '/clearCache/:password',
where: 'server',
action: function () {
if (this.params.password == '2d1QZuK3R3a7fe46FX8huj517juvzciem73') {
// Your cache-clearing code goes here.
}
}
});
});
And have your cronjob add that password to the URI:
curl http://yoursite.com/clearCache/2d1QZuK3R3a7fe46FX8huj517juvzciem73
Original Post:
There's no need for a headless browser or anything complicated. Use Meteorite to install Meteor Router and define a server-side route:
Meteor.Router.add('/clearCache', function() {
// Your cache-clearing code goes here.
});
Then have your cronjob trigger an HTTP GET request to that URI:
curl http://yoursite.com/clearCache
When the Meteor server receives the GET request, the router will execute your code.
For a little bit of security, add a check for a password:
Meteor.Router.add('/clearCache/:password', function(password) {
if (password == '2d1QZuK3R3a7fe46FX8huj517juvzciem73') {
// Your cache-clearing code goes here.
}
});
And have your cronjob add that password to the URI:
curl http://yoursite.com/clearCache/2d1QZuK3R3a7fe46FX8huj517juvzciem73
Check out this Meteor app, which does exactly that:
http://meteor-shell.meteor.com/
Why do you need a CLI tool when you could just store some scripts on the server and execute them from an admin interface in your Meteor app?
Got the same question yesterday. Found this Package, but have not yet tried it
https://github.com/practicalmeteor/meteor-mcli
Overview
A meteor package and command line tools for creating and running
command line / cli programs with meteor.
Incentive
To be able to reuse the same code of your meteor app in your command
line programs, instead of having to create a separate node / npm code
base with lot's of code duplicated from your meteor app.