How to customise email transports - javascript

As I understood Meteor internally uses nodemailer to send emails and creates the corresponding transport based on the defined MAIL_URL environment property.
We have implemented an EmailSenderService which creates several different nodemailer transports. It uses the account settings defined as settings for production mode and a hardcoded ethereal account for development mode.
I wonder if and how it is possible to change the internal Meteor email handling to use our application specific EmailSenderService to send all kind of emails especially the ones send via the account-password package (e.g. enrollment- and forgot-password-emails). My idea is to redirect the calls to the central Email.send function to our EmailSenderService instead of calling the Meteor internal logic.
Thank you for thinking along and any upcoming ideas and hints...

You've got a few options:
1. Monkeypatch Email.send
As #iiro says, you can just monkey patch the Email module by replacing the send method with your own.
Email.send = function (options) {
return EmailSenderService.send(options);
}
2. Replace the email package with a local version
If Meteor finds a package of the same name in the packages/ directory of your project, it will use that one over it's own implementation. Documentation
3. Use undocumented features to hook into Email.send
EDIT: I didn't see that EmailTest isn't exported. So this only works by making a local copy like in option 2.
Looking at the source of the email package, there's a hook which is run at the start of Email.send and allows you to prevent the default execution by returning false. You could use this like so:
EmailTest.hookSend(function (options) {
EmailSenderService.send(options)
return false; // To stop default sending behaviour
});

Related

Hide/Disable firebase functions for client

I am new to firebase and wondering how to disable specific functions for the client to manually put in the browsers console.
Example:
function createRoomDB(roomID, name, mode, start, length, aname, opcount, secrettoken) {
firebase.database().ref('rooms/' + roomID).set({
name: name,
mode: mode,
start: start,
length: length,
aname: aname,
opcount: opcount,
secrettoken: secrettoken
});
}
(The names have nothing to do with my question.)
Long story short: I don't want users to simply use this command to create new data. I know that you can't hide code on front-end, but what are the easiest and most efficient ways to disable this hell of a backdoor?
I am planning to host this application on GitHub pages.
Since your code can access the database, there is no way to prevent other code that runs on the same environment to also access the database.
This means you have two options:
Make sure all code (no matter who wrote it) only can perform authorized operations on the database.
Run the code in a different environment.
For the first option, you'll want to look into Firebase security rules, which automatically run server-side and can enforce most requirements.
For the second option, you could for example run the code in Cloud Functions for Firebase, and call that from your API. This allows you to hide any secret values and code in a trusted environment, but does mean that you'll need to ensure only authorized users can call that Cloud Function.

How to run a script on a newly created EC2 instance via AWS SDK?

I'm currently using AWS's Javascript SDK to launch custom EC2 instances and so far so good.
But now, I need these instances to be able to run some tasks when they are created, for example, clone a repo from Github, install a software stack and configure some services.
This is meant to emulate a similar behaviour I have for local virtual machine deployment. In this case, I run some provisioning scripts with Ansible that get the job done.
For my use case, which would be the best option amongst AWS's different services to achieve this using AWS's Javascript SDK?
Is there anyway I could maybe have a template script to which I passed along some runtime obtained variables to execute some tasks in the instance I just created? I read about user-data but I can't figure out how that wraps with AWS's SDK. Also, it doesn't seem to be customisable.
At the end of the day, I think I need a way to use the SDK to do this:
"On the newly created instance, run this script that is stored in such place, replacing these
placeholder values in the script with these I'm giving you now"
Any hints?
As Mark B. stated, UserData is the way to go for executing commands on instance launch. As you tagged the question with javascript here's an example on passing this in the ec2.runInstances command:
let AWS = require('aws-sdk')
let ec2 = new AWS.EC2({region: 'YOUR_REGION'})
// Example commands to create a folder, a file and delete it
let commands = [
'#!/usr/bin/env bash',
'mkdir /home/ubuntu/test',
'touch /home/ubuntu/test/examplefile',
'rm -rf /home/ubuntu/test'
];
let params = {
...YOUR PARAMS HERE...
UserData: new Buffer(commands.join("\n")).toString('base64')
}
// You need to encode it with Base64 for it to be executed by the userdata interpreter
ec2.runInstances(params).promise().then(res => { console.log(res); })
When you launch the new instances you can provide the user-data at that time, in the same AWS SDK/API call. That's the best place to put any server initialization code.
The only other way to kick off a script on the instance via the SDK is via the SSM service's Run Command feature. But that requires the instance to already have the AWS SSM agent installed. This is great for remote server administration, but user-data is more appropriate for initializing an instance on first boot.

Meteor: How can I get useraccounts package to write a new user doc into a remote collection?

I'm using the packages accounts-password and useraccounts:bootstrap and it all works fine, meaning the sign-on form creates a new doc in the Meteor.users collection. But I don't want any collection on the client facing app, hence I do have a second app running to which I successfully connect via DDP.connect() and I can exchange all necessary docs/collections via pub/sub and calling methods on the remote app.
The only thing that doesn't work is the useraccount doc. I've used (on the client app):
remote.subscribe('users', Meteor.userId(), function() {
});
and (on the remote app):
Meteor.publish('users', function() {
return Meteor.users.find({});
});
even though I'm not sure if there is a pub/sub already included in the package. Still, the doc is written to the local (client) app and not to the remote app.
How can I achieve this?
useraccounts:core simply makes use of Accounts.createUser on the server side (see this line) within a method called from the client-side (see this another line).
So the new user object is created from the server side and not from the client (though it flows all the way down to the client thanks to the DDP and default users subscriptions...).
If you're really looking to change the defaul behaviour provided by the Meteor core Accounts packages (accounts-base, accounts-password in this case...) you should try to override the Accounts.createUser method which is were all begins...
In any case be warned that the current user is published to the client by default: see these lines
Finally, to prevent useraccounts:core to use the Accounts API you could try to override the AtCreateUserServer method and deal with the creation of a new user on a remote application inside there.
Package accounts-base provide such functionality.
The accounts-base package exports two constructors, called AccountsClient and AccountsServer, which are used to create the Accounts object that is available on the client and the server, respectively.
Nevertheless, these two constructors can be instantiated more than once, to create multiple independent connections between different accounts servers and their clients, in more complicated authentication situations.
Documentation: Accounts (multi-server)

How to make per user base logging with hapi js

I am using winston logging framework and logging on basis of log level, but now i am facing difficulties in tracking down bugs. So we decided to make logging on per user basis, and this is where i ran into problem.
What i want to acheive?
log file for every user will be generated on every hour. (We can skip every hour constraint in this thread) and every user has unique identifier 'uid'.
What i have?
I have followed architecture as used here 'https://github.com/agendor/sample-hapi-rest-api'. Some additional lib modules exist too.
Currently i am using winston library (but i can afford to replace this if needed).
Brief introduction of flow
Currently, i have access to request object in handler function only, but i want to log events in DAO, library functions too ( on per user basis). 'Uid' is available to me in handler function in request object as i put uid in request in authentication middleware.
My solution (which is not elegant)
pass request object ( or only uid) to every function and log (using winston) event. Custom transport will determine where (in which file, on basis of uid) to put the log.
Certainly, this is not elegant way as every function must have uid parameter in order to log event, which seems bad.
What i want from you?
A better, elegant approach which is scalable too.
Related post: https://github.com/hapijs/discuss/issues/51
Try taking a look at Continuation-Local Storage:
https://github.com/othiym23/node-continuation-local-storage
Heres a good article on implementing it within express:
https://datahero.com/blog/2014/05/22/node-js-preserving-data-across-async-callbacks/

How to customize the OData server using JayData?

I'm quite new to JayData, so this may sound like a stupid question.
I've read the OData server tutorial here: http://jaydata.org/blog/install-your-own-odata-server-with-nodejs-and-mongodb - it is very impressive that one can set up an OData provider just like that. However the tutorial did not go into details about how to customize the provider.
I'd be interested in seeing how I can set it up with a custom database and how I can add a layer of authentication/authorization to the OData server. What I mean is, not every user may have permissions to every entity and not every user has the permission to add new entities.
How would I handle such use cases with JayData?
Thanks in advance for your answers!
UPDATE:
Here are two posts that will get you started:
How to use the odata-server npm module
How to set up authentication/authorization
The $data.createODataServer method frequently used in the posts is a convenience method that hides the connect/express pipleline from you. To interact with the pipeline examine the method body of $data.createODataServer function found in node_modules/odata-server folder.
Disregard text below
Authentication must be solved with the connect pipeline there are planty of middleware for that.
For authorization EntityContext constructor accepts an authorization function that must be promise aware.
The all-allow authorizator looks like this.
function checkPerm(access, user, entitysets, callback) {
var pHandler = new $data.PromiseHandler();
var clbWrapper = pHandler.createCallback(callback);
var pHandlerResult = pHandler.getPromise();
clbWrapper.success(true); // this grants a joker rw permission to everyone
//consult user, entitySet and acces to decide on success/error
//since you return a promise you can call async stuff (will not be fast though)
return pHandlerResult;
}
I have to consult with one of the team members on the syntax that let you pass this into the build up process - but I can confirm this is doable and is supported. I'll get back with the answer ASAP.
Having authenticated the user you can also use EntityContext Level Events to intercept Read/Update/Create/Delete operations.
$data.EntityContext.extend({
MySet: { type: $data.EntitySet, elementType: Foobar,
beforeDelete: function(items) {
//if delete was in batch you'll get multiple items
//check items here,access this.request.user
return false // deny access
}
});
And there is a declarative way, you can annotate Role names with permissions on entity sets, this requirest that your user object actually has a roles field with an array of role names.
I too have been researching oData recently and as we develop our platform in both node and C# naturally looked at JayStorm. From my understanding of the technical details of JayStorm the whole capability of Connect and Express are available to make this topic possible. We use Restify to provide the private API of our platform and there we have written numerous middleware modules for exactly this case.
We are using JayData for our OData Service layer also, and i have implemnment a very simple basic authentication with it.
Since the JayData is using Express, so we can leverage Express' features. For Basic Auth, the simplest way is:
app.use(c.session({ secret: 'session key' }));
// Authenticator
app.use(c.basicAuth('admin', 'admin'));
app.use("/odata.svc", $data.JayService.OData.Utils.simpleBodyReader());
you also can refer to this article for more detail for authentication with Express: http://blog.modulus.io/nodejs-and-express-basic-authentication
Thanks.
I wrote that blogpost, I work for JayData.
What do you mean by custom database?
We have written a middleware for authentication and authorization but it is not open source. We might release it later.
We have a service called JayStorm, it has a free version, maybe that is good for you.
We probably will release an appliance version of it.

Categories

Resources