settlin:accounts-phone

v1.0.6Published 8 years ago

This package has not had recent updates. Please investigate it's current state before committing to using it in your project.

Accounts-Phone

Phone and OTP based login for Meteor.

Installation

In a Meteor app directory, enter:

$ meteor add settlin:accounts-phone

The database

In accordance with the current emails field used by accounts-password, we use phones field in the user document: {phones: [{number, verified: false}]}. The otp is stored in services.phone.otp.

The flow

Use a simple Meteor method,

1function sendOtpViaSms(otp) {.....} // the function through which you send sms
2
3Meteor.methods({
4	sendOtpForLogin: function(to) {
5		if (Meteor.isClient) return null;
6
7		// otp must be generated on the server and never revealed to the client
8		check(to, String);
9
10		let user = Meteor.users.findOne({'phones.number': to});
11
12		// if there is no user with the given phone number, we create a new one.
13		// Accounts.createUser is available only on the server and creates a new user with two fields: `phones` and `services`. It ensures that the phone numbers are always unique for users.
14		if (!user) user = {_id: Accounts.createUserWithPhone({phone: to})};
15
16		// send otp as sms
17		let otp = Math.round(Random.fraction() * 100000);
18
19		// Accounts.setPhoneOtp sets the otp in the `__otps` collection: {phone, otp, purpose: '__login__'}.
20		Accounts.setPhoneOtp(user._id, otp);
21	},
22});

Use this method to send otp whenever needed. Next, take the otp from the user and call,

Meteor.loginWithPhone({phone, otp}, callback);

This method works as any other Meteor.loginWith<Service> method.

Simple API

Server

1Meteor.otps; // the collection that contains otps in the form {phone, otp, purpose, createdAt} with an index created by: Meteor.otps._ensureIndex({phone: 1, purpose: 1}, {unique: true, name: 'phoneAndPurpose'});
2// not available on client
3
4/**
5 * @summary Set the otp for a user.
6 * @locus Server
7 * @param {String} userId The id of the user to update.
8 * @param {String} otp OTP
9 * @returns {Void} null
10 */
11Accounts.setPhoneOtp = function(userId, otp) {...};
12
13/**
14 * @summary Add a phone number for a user. Use this instead of directly
15 * updating the database. The operation will fail if there is a different user
16 * with same phone.
17 * @locus Server
18 * @param {String} userId The ID of the user to update.
19 * @param {String} newPhone A new phone number for the user.
20 * @param {Boolean} [verified] Optional - whether the new phone number should
21 * be marked as verified. Defaults to false.
22 * @returns {Void} null
23 */
24Accounts.addPhone = function(userId, newPhone, verified) {...};
25
26/**
27 * @summary Remove an phone number for a user. Use this instead of updating
28 * the database directly.
29 * @locus Server
30 * @param {String} userId The ID of the user to update.
31 * @param {String} phone The phone number to remove.
32 * @returns {Void} null
33 */
34Accounts.removePhone = function(userId, phone) {...};
35
36/**
37 * @summary Create a user directly on the server. Unlike the client version, this does not log you in as this user after creation.
38 * @locus Server
39 * @param {Object} options Object with arguments. Needs just {phone: String} for now.
40 * @returns {String} userId The newly created user's _id
41 */
42Accounts.createUserWithPhone = function(options) {...};
43
44/**
45 * @summary finds user by doing a phone number search. Throws error if multiple found.
46 * @param {String} phone phone number.
47 * @return {Object} user document
48 */
49Accounts.findUserByPhone = function(phone) {...};

Client

1/**
2 * @summary Log the user in with a password.
3 * @locus Client
4 * @param {Object} options phone and otp
5 * @param {Function} [callback] Optional callback. Called with no arguments on success,
6 *      or with a single `Error` argument on failure.
7 * @return {Void} null
8 */
9Meteor.loginWithPhone = function(options, callback) {...};

both

1/**
2 * @summary Log the user in with a password.
3 * @locus Both
4 * @param {String}  phone phone number
5 * @return {String} sanitized phone number. Tweaked for Indian numbers, but works for other countries as well. Uses https://github.com/settlin/phoneparser.git
6 */
7
8Accounts.sanitizePhone = function(phone) {...};

If you need a phone + password login, use https://github.com/okland/accounts-phone.