Home

Awesome

tcs_node_auth

Build Status Build Status NPM version

Easy to use authentication with activation by mail

This Modules makes it easy to create a secure email user login with verification and save crypted password.

Features

Register sequence

Register sequence

<!--http://www.websequencediagrams.com/?lz=VXNlci0-ZXhwcmVzcy5qczogc3RhcnQgc2lnbmluCm5vdGUgb3ZlciAAFg0AGAUgZm9ybQoAMQotPnRjc19ub2RlX2F1dGg6IHJlZ2lzdGVyAEAGcmlnaHQgb2YgABcPLgAfCCggbWFpbCwgY2IgKQoAPg0tPlVzZXI6IFNlbmQAIAUKAIElEmNsaWNrIG9uIGxpbmsAehxnZXRUb2tlAIFVBwB9GQAfCCggdG9rZW4AgQEWAIIsDAAiBURhdGEAgh4XcGFzc3dvcmQAghYhYWN0aXZhdGUAghgfAB8IAIEYCQBZCACBCSJ1c2VyAIEPG2NyZWF0ZSBzZXNzaW9uCg&s=napkin-->

Forgot password sequence

Forgot password sequence

<!--http://www.websequencediagrams.com/?lz=VXNlci0-ZXhwcmVzcy5qczogc3RhcnQgZm9yZ290IHBhc3N3b3JkCm5vdGUgb3ZlciAAIAwAFw8gZm9ybQoAQwotPnRjc19ub2RlX2F1dGgAKAgARwZyaWdodCBvZiAAFQ8uAHUGKCBtYWlsLCBjYiApCgA6DS0-VXNlcjogU2VuZAAgBQoAgTMSY2xpY2sgb24gbGluawB2HGdldFRva2VuAHUfAB8IKCB0b2tlbgCBARYAgjoMACIFRGF0YQCCIxcAggopYWN0aXZhdGUAghYfAB8IAIEYCQCDMggAgQkidXNlcgCBDxtjcmVhdGUgc2Vzc2lvbgo&s=napkin-->

Change mail sequence

Forgot password sequence

<!--http://www.websequencediagrams.com/?lz=VXNlci0-ZXhwcmVzcy5qczogc3RhcnQgY2hhbmdlIG1haWwKbm90ZSBvdmVyIAAcDAAXCyBmb3JtCgA7Ci0-dGNzX25vZGVfYXV0aAAkCE0ARAlyaWdodCBvZiAAGQ8uAB8KKCBjdXJyZW50X2VtYWlsLCBuZXcAAwhjYiApCgBWDS0-VXNlcjogU2VuZACBLwYAgUcSY2xpY2sgb24gbGluawCBEhxhY3RpdmF0ZQCBDR8AHwgoIHRva2VuAIEQBwCBQx0AgRoFbm9maWZpY2F0aW9uAII5BnRvIG9sZCAAgmgGAIFJDwCDDwx1c2VyRGF0YQCCehhyZWF0ZSBzZXNzaW9uCg&s=napkin-->

Install

npm install tcs_node_auth

Example

// import express
var express = require( "express" )

// import your favorite database driver and create the UserStore
// This is just a dummy Driver to return some data
var DbPlaceholder = {
	find: function( q, cb ){if( q.email == "exists@test.de"){ cb( null, { email: "exists@test.de", id: 42 } ); }else{ cb( null );} },
	createOrUpdateByMail: function( mail, data, cb ){cb( null, { email: mail, id: 23 } );},
	updateByMail:function( email, data, cb ){if( email == "exists@test.de"){cb( null, { email: data.email, id: 42 } );}else{cb( null );}}
}

var UserStore = {
	// implement the method to get a user by mail
	getUserCredentials: function( email, callback ){ 
		DbPlaceholder.find( { email: email }, function( err, dbUser ){
			if( err ){ callback( err ); return }
			if( dbUser != void(0) ){
				callback( new Error( "mail-not-found" ) ) 
			} else {
				callback( null, dbUser.password, dbUser ) 
			}
		});
	},
	// implement the method to check if a mail allready exists
	checkUserEmail: function( email, options, callback ){ 
		DbPlaceholder.find( { email: email }, function( err, dbUser ){
			if( err ){ callback( err ); return }
			if( dbUser != void(0) ){
				callback( null, true ) 
			} else {
				callback( null, false ) 
			}
		});
	},
	// implement the method to create a new user after a succesfull activation
	setUserCredentials: function( email, passwordcypt, isRegister, callback ){ 
		DbPlaceholder.createOrUpdateByMail( email, { email: email, password: passwordcypt }, function( err, dbUser ){
			if( err ){ callback( err ); return }
			callback( null, dbUser ) 
		});
	},
	// implement the method to change a mail by mail
	setUserMail: function(  current_email, new_email, callback ){ 
		DbPlaceholder.updateByMail( current_email, { email: new_email }, function( err, dbUser ){
			if( err ){ callback( err ); return }
			callback( null, dbUser ) 
		});
	},
	// implement the method to generate the activation mail content
	getMailContent: function( type, tokenOrNewmail, options, callback ){
		switch( type ){
			case "register":
				_mail = {
					subject: "Welcome to my app",
					body: "Visit http://www.myapp.com/activation/" + tokenOrNewmail + " to activate your account." 
				}
				break;
			case "forgot":
				_mail = {
					subject: "Reset your password for my app",
					body: "Visit http://www.myapp.com/activation/" + tokenOrNewmail + " to change your account password." 
				}
				break;
			case "changemail":
				_mail = {
					subject: "Confirm your new mail",
					body: "Visit http://www.myapp.com/activation/" + tokenOrNewmail + " to confirm your changed mail." 
				}
				break;
			case "notifyoldmail":
				_mail = {
					subject: "Your mail has been changed",
					body: "This is just a notification send to you after your mail has been cghanged to `" + tokenOrNewmail + "`." 
				}
				break;
		}
		callback( null, _mail )
		return
	}
}

// init the AuthApp
var AuthApp = require( "tcs_node_auth" );
_config = {
	mailAppId: "mymailappid",
	mailConfig: {
		simulate: true, // Example useage: use the simulated version to create a console out instead of sending a mail.
		senderemail: "no-reply@myapp.com"
	}
};
var authHelper = new AuthApp( UserStore, _config )

// init and configure express
var app = express();
app
	.use(express.bodyParser())
	.use(express.cookieParser())
	.use(express.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }}));


// define the express routes

// login endpoint
app.post( "/login", function( req, res ){
	// call the login method
	authHelper.login( req.body.email, req.body.password, function( err, userData ){
		if( err ){ res.send( 500, err );return }
		// create youre session
		req.session._user = userData;
		res.redirect( "/app.html" );
	});
});

// register endpoint
app.post( "/activation/register", function( req, res ){
	// call the register method
	authHelper.register( req.body.email, function( err ){
		if( err ){ res.send( 500, err );return }
		// output a info page
		res.send( "render: waitforactivation" );
	});
});

// forgot token endpoint
app.post( "/activation/forgot", function( req, res ){
	// call the forgot method
	authHelper.forgot( req.body.email, function( err ){
		if( err ){ res.send( 500, err );return }
		// output a info page
		res.send( "render: waitforactivation" );
	});
});

// change mail endpoint
app.post( "/activation/changemail", function( req, res ){
	// call the changemail method
	authHelper.changeMail( req.body.current_email, req.body.new_email, function( err ){
		if( err ){ res.send( 500, err );return }
		// output a info page
		res.send( "render: waitforactivation" );
	});
});

// read the content of a token
app.get( "/activation/:token", function( req, res ){
	// call the getToken method
	authHelper.getToken( req.params.token, function( err, tokenData ){
		// render a page for an invalid or expired token
		if( err && err.name == "token-not-found" ){ res.send( "render: invalidtoken" );return }
		// output an error
		if( err ){ res.send( 500, err );return }
		console.log(tokenData);
		res.send( "render: do somthing with the token" );
	});
});

// a general endpoint to handle all generated tokens
app.post( "/activation/create/:token", function( req, res ){
	// call the activate method
	authHelper.activate( req.params.token, req.body.password, function( err, userData ){
		if( err ){ res.send( 500, err );return }
		// create youre session
		req.session._user = userData;
		res.send( "render/redirect: app" );
	});
});

app.listen( 8080 )

Initialize

to create the AuthApp call new with the configuared UserStore and the module configuration.

new AuthApp( UserStore, config )

####Config-Options:

Methods

AuthApp.login( email, password, callback )

Invoke a user login.

This method make use of the UserStore.getUserCredentials( email, callback ) Method.

####Arguments:

Parameter for callback( error, userData )

AuthApp.register( email [, options], callback )

Create a user login request.

This method make use of the UserStore.checkUserEmail( email, options, callback ) and UserStore.getMailContent( type, link, options, callback ) Methods.

####Arguments:

Parameter for callback( error )

AuthApp.forgotPassword( email [, options], callback )

Create a request to send a user forgot password mail.

This method make use of the UserStore.checkUserEmail( email, options, callback ) and UserStore.getMailContent( type, link, options, callback ) Methods.

####Arguments:

Parameter for callback( error )

AuthApp.changeMail( current_email ,new_email [, options], callback )

Create a request to to change an existing email. The new email will get a Message with the token link. After a succesfull change the old emial will receice a notification message.

This method make use of the UserStore.checkUserEmail( email, options, callback ), UserStore.setUserMail( current_email, new_email, callback ) and UserStore.getMailContent( type, link, options, callback ) Methods.

####Arguments:

Parameter for callback( error )

AuthApp.getToken( token, callback )

Check if a token exists.

####Arguments:

Parameter for callback( error, email )

AuthApp.activate( token, password[, options], callback )

Use an existing token and create a user. This method make use of the UserStore.setUserCredentials() Method.

####Arguments:

Parameter for callback( error, userData, tokenData )

Events

connect

Fired on the connect event of redis

disconnect

Fired on a redis disconnection

error

Fired on a redis general connection error

ready

Fired until the module is ready to use. Before redis has been connected and the the userStore has been checked.

login

Fired after a succesfull login.

####Parameter:

register

Fired after created a new register token.

####Parameter:

forgot

Fired after created a new forgot token.

####Parameter:

changemail

Fired after created a new changemail token.

####Parameter:

activated

Fired after a token has been processed.

####Parameter:

mail

Fired after a succesfull login.

####Parameter:

User Store

UserStore.getUserCredentials( email, callback )

Get the users password and session data by email

####Arguments:

Parameter for callback( error, password, userData )

UserStore.checkUserEmail( email, options, callback )

Check if a email is existent in your database.

Arguments:

Parameter for callback( error, exists )

UserStore.setUserCredentials( email, passwordcypt, callback )

Create a basic user with email and password.

Arguments:

Parameter for callback( error, userData )

UserStore.setUserMail( current_email, new_email, callback )

Change the email of a user by the current email.

Arguments:

Parameter for callback( error, userData )

UserStore.getMailContent( type, token, options, callback )

Get the content data for a mail.

Arguments:

Parameter for callback( error, contentData )

Release History

VersionDateDescription
v0.4.02013-12-16Option to force emails to lowercase.
v0.3.32013-11-22Fixed token clear after changemail + added some testcases
v0.3.22013-11-21Fixed token-mail receiver in changemail method
v0.3.12013-11-21Added options to UserStore.checkUserEmail( email, options, callback )
v0.3.02013-11-15Deactivating mail service by setting mailAppId = false. Added isRegister argument to UserStore.setUserCredentials.
v0.2.22013-11-04Bugfix for debuggin config and fixed example.js to a woking version
v0.2.12013-11-04Fixed readme
v0.2.02013-10-31Added .changeMail() Method
v0.1.02013-10-30Initial commit

Related Projects

NameDescription
tcs_node_mail_clientModule to simply send mails by using the TCS mail Webservice (node-tcs-de)

The MIT License (MIT)

Copyright © 2013 Mathias Peter, http://www.tcs.de

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.