Giter Site home page Giter Site logo

dburles / meteor-two-factor Goto Github PK

View Code? Open in Web Editor NEW
81.0 5.0 16.0 33 KB

๐Ÿ” Two factor authentication package for accounts-password

Home Page: https://atmospherejs.com/dburles/two-factor

License: MIT License

JavaScript 100.00%
meteor meteor-package authentication two-factor-authentication

meteor-two-factor's Introduction

Meteor Two Factor

Simple two factor authentication for accounts-password.

Table of Contents

Installation

$ meteor add dburles:two-factor

Prerequisites

Make sure your project is using Meteor's accounts-password package, if not add it: meteor add accounts-password

Example Application

Simple example application

Usage

Client and server usage examples.

Usage (Client)

Typically you would call this method via your application login form event handler:

twoFactor.getAuthCode(user, password, error => {
  if (error) {
    // Handle the error
  }
  // Success!
});

After calling getAuthCode if you wish, you can request a new authentication code:

twoFactor.getNewAuthCode(error => {
  if (error) {
    // Handle the error
  }
  // Success!
});

The following method is reactive and represents the state of authentication. Use it to display the interface to enter the authentication code:

Tracker.autorun(function() {
  if (twoFactor.isVerifying()) {
    console.log('Ready to enter authentication code!');
  }
});

Capture the authentication code and pass it to the following method to validate the code and log the user in:

twoFactor.verifyAndLogin(code, error => {
  if (error) {
    // Handle the error
  }
  // Success!
});

Usage (Server)

Assign a function to twoFactor.sendCode that sends out the code. The example below sends the user an email:

twoFactor.sendCode = (user, code) => {
  // Don't hold up the client
  Meteor.defer(() => {
    // Send code via email
    Email.send({
      to: user.email(), // Method attached using dburles:collection-helpers
      from: '[email protected]',
      subject: 'Your authentication code',
      text: `${code} is your authentication code.`
    });
  });
};

Optional functions:

// Optional
// Conditionally allow regular or two-factor sign in
twoFactor.validateLoginAttempt = options => {
  // If two factor auth isn't enabled for this user, allow regular sign in.
  return !options.user.twoFactorEnabled;
};
// Optional
twoFactor.generateCode = () => {
  // return a random string
};

Security note:

Use DDPRateLimiter to prevent verification code cracking

import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';

const numberOfAttempts = 5;
const timeInterval = 60;

DDPRateLimiter.addRule(
  {
    type: 'method',
    userId: null,
    clientAddress: null,
    name(name) {
      const methods = [
        'twoFactor.verifyCodeAndLogin',
        'twoFactor.getAuthenticationCode'
      ];
      return methods.includes(name);
    },
    connectionId() {
      return true;
    }
  },
  numberOfAttempts,
  timeInterval * 1000
);

API

The following functions are attached to the twoFactor namespace. This may change somewhat for Meteor 1.3.

API (Client)

getAuthCode

getAuthCode(user, password, [callback])

Generates an authentication code. Once generated, (by default) a twoFactorCode field is added to the current user document. This function mirrors Meteor.loginWithPassword.

user Either a string interpreted as a username or an email; or an object with a single key: email, username or id. Username or email match in a case insensitive manner.

password The user's password.

callback Optional callback. Called with no arguments on success, or with a single Error argument on failure.

getNewAuthCode

getNewAuthCode([callback])

Generates a new authentication code. Only functional while verifying.

callback Optional callback. Called with no arguments on success, or with a single Error argument on failure.

verifyAndLogin

verifyAndLogin(code, [callback])

Verifies authentication code and logs in the user.

code The authentication code.

callback Optional callback. Called with no arguments on success, or with a single Error argument on failure.

isVerifying

isVerifying()

Reactive function that indicates the current state between having generated an authentication code and awaiting verification.

abort

abort([callback])

Call this function while verifying if you wish to allow the user to sign in again.

callback Optional callback. Called with no arguments on success, or with a single Error argument on failure.

API (Server)

sendCode

sendCode(user, code)

This function is called after getAuthCode is successful.

user The current user document.

code The generated authentication code.

options

twoFactor.options.fieldName = 'customFieldName';

Specify the name of the field on the user document to write the authentication code. Defaults to twoFactorCode.

validateLoginAttempt (Optional)

validateLoginAttempt(options)

If defined, this function is called within an Accounts.validateLoginAttempt callback. Use this to allow regular login under certain conditions.

generateCode (Optional)

If defined, this function is called to generate the random code instead of the default.

License

MIT

meteor-two-factor's People

Contributors

dburles avatar storytellercz avatar vbelolapotkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

meteor-two-factor's Issues

How can validateLoginAttempt work to allow password-only login?

I've got meteor-two-factor working, it's great -- but I need to have a person be able to log in without 2FA. I've gone over this and tried a bunch of things, but it seems to me that this line in verifyCodeAndLogin on the server side

if (options.code !== user[fieldName]) {

rejects login for lacking 2FA before validateLoginAttempt has ever been called by Accounts_attemptLogin() a few lines later. My code asks for email and password, and when you submit, calls getAuthCode, then shows the 2FA code input field. But no call to validateLoginAttempt has occurred yet when the code asks for the 2FA code, and as mentioned, submitting an empty or wrong 2FA code fails.

What am I missing here? Does anyone have this working? Thanks!

getNewAuthCode results in error

The following event results in an error. The normal code generation works perfectly

'click #resend-security-code'(e) {
      e.preventDefault();
      twoFactor.getNewAuthCode(error => {
        if (error) {
          bootbox.alert(error.reason);
          this.state.securityBtnCheckWaiting = false;

        }
      });
    }

Exception in delivering result of invoking 'twoFactor.getAuthenticationCode': TypeError: handlerCb is not a function

suggestions

  • 1. The getAuthCode user argument should be object with username or email property. Cause current way deny us to use @ in username.
  • 2. Add functions/methods for more usecases - for example fire method which generate code for logged in user. So we can put just some actions behind 2way auth. Could be useful for password changes etc... too.
  • 3. And also put the function which check the code directly into twoFactor server side object, so we can use it in our own methods which handle functionality behind already logged in user for functionality which need to be behind code check.

I can prepare PR if needed.

twoFactorVerifyCodeAndLogin AND aldeed:collection2-core Compatibility

Hi David ,

First, thank you for your job, your 2FA plugin works great !
Since two days ago, I tried to implement the aldeed:collection2-core plugin (pretty mainstream in meteor dev...). Here's my issue :

The creation of a user works & the new schema is attached to the user.
But I'm unable to log in my account: the first login step works great, I receive the code, but the verify step give me a 403 error
Error: Invalid code [403] at [object Object].twoFactorVerifyCodeAndLogin (packages/dburles:two-factor/server.js:87:13)
So this line is:

      if (options.code !== user[fieldName]) {                                                                // 86
        throw new Meteor.Error(403, "Invalid code");                                                         // 87
      }                                                                                                                            // 88

At the end of my user schema, if I comment the last line
Meteor.users.attachSchema(Schema.User);
everything is back to normal - like a charm. But obviously, the new user schema is not attached to the user...

Any idea of what is going on ?
Help me Obi Wan Kanobi.


In details, in the Method twoFactor.verifyCodeAndLogin :

  • At start:
userId : null
params : [{"user":{"email":"[email protected]"},"password":"passpass","code":"234926"}]

  • the find on users return:
coll : users
func : find
selector : {"emails.address":"[email protected]"}

-the fetch on users return:

coll : users
selector : {"emails.address":"[email protected]"}
func : fetch
cursor : true
limit : 1
docsFetched : 1
docSize : 516
  • then the error:
message: Invalid code [403] 
stack:
Error: Invalid code [403]
    at [object Object].twoFactorVerifyCodeAndLogin (packages/dburles:two-factor/server.js:87:13)
    at [object Object].methodMap.(anonymous function) (packages/meteorhacks_kadira.js:2731:30)
    at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1711:12)
    at packages/ddp-server/livedata_server.js:711:19
    at [object Object]._.extend.withValue (packages/meteor.js:1122:17)
    at packages/ddp-server/livedata_server.js:709:40
    at [object Object]._.extend.withValue (packages/meteor.js:1122:17)
    at packages/ddp-server/livedata_server.js:707:46
    at Session.method (packages/ddp-server/livedata_server.js:681:23)
    at packages/meteorhacks_kadira.js:2619:38

Login forbidden on 1.1.2

Upgrade from 1.1.1 to 1.1.2 will cause login forbidden after sending verification code.
Login forbidden is thrown by meteor.

I downgraded to 1.1.1 and everything work like expected.

Help on regular sign in

Hi again @dburles,

You helped me a month ago with a compatibility issue with aldeed:collection2-core: thanks.

Sorry for this newbie question (not an issue...), but I can't understand how on server side, allowing regular sign in.
I can't figure how to define the twoFactorEnabled property. And how to set my options?

// Optional
// Conditionally allow regular or two-factor sign in
twoFactor.validateLoginAttempt = options => {
  return !! options.user.twoFactorEnabled;
};

My idea is to allow regular login for the users who don't have a phone number (profile.phone): cause in my App, the code is sended by sms.
Can you help me?
Thanks in advance for reading me so far.

verifyAndLogin -> Match.where error

Hello! I found your package very useful, thank you for it!
But I got a problem I can't find a way to solve.

For created user instead of logginWithPassword after email and password submit I want to confirm his email for signIn:

-> I'm using getAuthCode instead of ligginWithPassword:
screen shot 2018-03-21 at 10 00 04

-> afterwards I can get user and code in sendCode:
screen shot 2018-03-21 at 10 03 41

-> then, I'm getting email with a link to my component where I can read token from route:
screen shot 2018-03-21 at 10 04 58

-> after I'm following the link where my verification component trying to veryfyAndLogin
screen shot 2018-03-21 at 10 06 44

=> but I'm getting error:
screen shot 2018-03-21 at 10 08 25

I think that selector doesn't have access to state and can't provide such data as 'user' and 'password' to login. I think that I don't understand it properly and hope on your help!

Will be glad to contact in telegram if smth.
My contacts: +375(29)182-52-97 / chelovekdrakon.

Sincerely Fiodar Morau.

twoFactor.validateLoginAttempt not firing

Hello,

My app has 2 account types allowed:

  • Google OAuth based for specific domains
  • Password based where 2FA is enabled with your package.

I am trying to put some logic in validateLoginAttempt which doesn't seem to be firing based except if it is resume login attempt. Am I doing something wrong?
It also seems that Accounts.onLogin callback does not fire at all for accounts through 2FA. Is that expected?

Please let me know.

thanks !

Great stuff otherwise, thanks for putting this together !
Antoine

suggestion: allow canceling login process

Add client API method for canceling verification process:
IMO it has to do two things:

  1. clear twoFactorCode value in the user doc (on the server)
  2. reset isVerifying state

This will allow new login attempt with another account.

can create PR if help needed

Login forbidden

When I create my custom login method I get Login Forbidden while using this package.

What could be the problem?

Use as well the default meteor loginWithPassword

Hi, thanks for the great works you have done making this package.
I'd like to know if is possible to use the default Meteor.loginWithPassword in conjunction while using this package whitin a project. Actually when I try to create two different login sections, one using two-factor and one using the default Meteor login, I get a login forbidden error using Meteor.loginWithPassword.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.