{"id":18971181,"url":"https://github.com/dburles/meteor-two-factor","last_synced_at":"2025-04-19T15:08:48.466Z","repository":{"id":47749536,"uuid":"51881574","full_name":"dburles/meteor-two-factor","owner":"dburles","description":"🔐 Two factor authentication package for accounts-password","archived":false,"fork":false,"pushed_at":"2021-08-15T02:07:58.000Z","size":33,"stargazers_count":81,"open_issues_count":5,"forks_count":17,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-29T09:10:39.304Z","etag":null,"topics":["authentication","meteor","meteor-package","two-factor-authentication"],"latest_commit_sha":null,"homepage":"https://atmospherejs.com/dburles/two-factor","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dburles.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-17T00:30:29.000Z","updated_at":"2024-09-18T08:34:41.000Z","dependencies_parsed_at":"2022-07-22T02:18:20.281Z","dependency_job_id":null,"html_url":"https://github.com/dburles/meteor-two-factor","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dburles%2Fmeteor-two-factor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dburles%2Fmeteor-two-factor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dburles%2Fmeteor-two-factor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dburles%2Fmeteor-two-factor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dburles","download_url":"https://codeload.github.com/dburles/meteor-two-factor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249220839,"owners_count":21232421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","meteor","meteor-package","two-factor-authentication"],"created_at":"2024-11-08T14:59:44.530Z","updated_at":"2025-04-16T08:32:45.229Z","avatar_url":"https://github.com/dburles.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Meteor Two Factor\n\nSimple two factor authentication for accounts-password.\n\n## Table of Contents\n\n- [Installation](https://github.com/dburles/meteor-two-factor#installation)\n- [Prerequisites](https://github.com/dburles/meteor-two-factor#prerequisites)\n- [Example Application](https://github.com/dburles/meteor-two-factor#example-application)\n- [Usage](https://github.com/dburles/meteor-two-factor#example-application)\n  - [Client](https://github.com/dburles/meteor-two-factor#usage-client)\n  - [Server](https://github.com/dburles/meteor-two-factor#usage-server)\n- [API](https://github.com/dburles/meteor-two-factor#api)\n  - [Client](https://github.com/dburles/meteor-two-factor#api-client)\n    - [getAuthCode](https://github.com/dburles/meteor-two-factor#getauthcode)\n    - [getNewAuthCode](https://github.com/dburles/meteor-two-factor#getnewauthcode)\n    - [verifyAndLogin](https://github.com/dburles/meteor-two-factor#verifyandlogin)\n    - [isVerifying](https://github.com/dburles/meteor-two-factor#isverifying)\n    - [abort](https://github.com/dburles/meteor-two-factor#abort)\n  - [Server](https://github.com/dburles/meteor-two-factor#api-server)\n    - [sendCode](https://github.com/dburles/meteor-two-factor#sendcode)\n    - [options](https://github.com/dburles/meteor-two-factor#options)\n    - [validateLoginAttempt](https://github.com/dburles/meteor-two-factor#validateloginattempt-optional)\n    - [generateCode](https://github.com/dburles/meteor-two-factor#generatecode-optional)\n- [License](https://github.com/dburles/meteor-two-factor#license)\n\n## Installation\n\n```sh\n$ meteor add dburles:two-factor\n```\n\n## Prerequisites\n\nMake sure your project is using Meteor's `accounts-password` package, if not add it: `meteor add accounts-password`\n\n## Example Application\n\n[Simple example application](https://github.com/dburles/two-factor-example)\n\n## Usage\n\nClient and server usage examples.\n\n## Usage (Client)\n\nTypically you would call this method via your application login form event handler:\n\n```js\ntwoFactor.getAuthCode(user, password, error =\u003e {\n  if (error) {\n    // Handle the error\n  }\n  // Success!\n});\n```\n\nAfter calling `getAuthCode` if you wish, you can request a new authentication code:\n\n```js\ntwoFactor.getNewAuthCode(error =\u003e {\n  if (error) {\n    // Handle the error\n  }\n  // Success!\n});\n```\n\nThe following method is reactive and represents the state of authentication. Use it to display the interface to enter the authentication code:\n\n```js\nTracker.autorun(function() {\n  if (twoFactor.isVerifying()) {\n    console.log('Ready to enter authentication code!');\n  }\n});\n```\n\nCapture the authentication code and pass it to the following method to validate the code and log the user in:\n\n```js\ntwoFactor.verifyAndLogin(code, error =\u003e {\n  if (error) {\n    // Handle the error\n  }\n  // Success!\n});\n```\n\n## Usage (Server)\n\nAssign a function to `twoFactor.sendCode` that sends out the code. The example below sends the user an email:\n\n```js\ntwoFactor.sendCode = (user, code) =\u003e {\n  // Don't hold up the client\n  Meteor.defer(() =\u003e {\n    // Send code via email\n    Email.send({\n      to: user.email(), // Method attached using dburles:collection-helpers\n      from: 'noreply@example.com',\n      subject: 'Your authentication code',\n      text: `${code} is your authentication code.`\n    });\n  });\n};\n```\n\n**Optional functions:**\n\n```js\n// Optional\n// Conditionally allow regular or two-factor sign in\ntwoFactor.validateLoginAttempt = options =\u003e {\n  // If two factor auth isn't enabled for this user, allow regular sign in.\n  return !options.user.twoFactorEnabled;\n};\n```\n\n```js\n// Optional\ntwoFactor.generateCode = () =\u003e {\n  // return a random string\n};\n```\n\n**Security note:**\n\nUse [DDPRateLimiter](https://docs.meteor.com/api/methods.html#ddpratelimiter) to prevent verification code cracking\n\n```js\nimport { DDPRateLimiter } from 'meteor/ddp-rate-limiter';\n\nconst numberOfAttempts = 5;\nconst timeInterval = 60;\n\nDDPRateLimiter.addRule(\n  {\n    type: 'method',\n    userId: null,\n    clientAddress: null,\n    name(name) {\n      const methods = [\n        'twoFactor.verifyCodeAndLogin',\n        'twoFactor.getAuthenticationCode'\n      ];\n      return methods.includes(name);\n    },\n    connectionId() {\n      return true;\n    }\n  },\n  numberOfAttempts,\n  timeInterval * 1000\n);\n```\n\n## API\n\nThe following functions are attached to the `twoFactor` namespace. This may change somewhat for Meteor 1.3.\n\n## API (Client)\n\n### getAuthCode\n\n```\ngetAuthCode(user, password, [callback])\n```\n\nGenerates an authentication code. Once generated, (by default) a `twoFactorCode` field is added to the current user document. This function mirrors [Meteor.loginWithPassword](http://docs.meteor.com/#/full/meteor_loginwithpassword).\n\n**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.\n\n**password** The user's password.\n\n**callback** Optional callback. Called with no arguments on success, or with a single Error argument on failure.\n\n### getNewAuthCode\n\n```\ngetNewAuthCode([callback])\n```\n\nGenerates a new authentication code. Only functional while verifying.\n\n**callback** Optional callback. Called with no arguments on success, or with a single Error argument on failure.\n\n### verifyAndLogin\n\n```\nverifyAndLogin(code, [callback])\n```\n\nVerifies authentication code and logs in the user.\n\n**code** The authentication code.\n\n**callback** Optional callback. Called with no arguments on success, or with a single Error argument on failure.\n\n### isVerifying\n\n```\nisVerifying()\n```\n\nReactive function that indicates the current state between having generated an authentication code and awaiting verification.\n\n### abort\n\n```\nabort([callback])\n```\n\nCall this function while verifying if you wish to allow the user to sign in again.\n\n**callback** Optional callback. Called with no arguments on success, or with a single Error argument on failure.\n\n## API (Server)\n\n### sendCode\n\n```\nsendCode(user, code)\n```\n\nThis function is called after `getAuthCode` is successful.\n\n**user** The current user document.\n\n**code** The generated authentication code.\n\n### options\n\n```\ntwoFactor.options.fieldName = 'customFieldName';\n```\n\nSpecify the name of the field on the user document to write the authentication code. Defaults to `twoFactorCode`.\n\n### validateLoginAttempt (Optional)\n\n```\nvalidateLoginAttempt(options)\n```\n\nIf defined, this function is called within an `Accounts.validateLoginAttempt` callback.\nUse this to allow regular login under certain conditions.\n\n### generateCode (Optional)\n\nIf defined, this function is called to generate the random code instead of the default.\n\n### License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdburles%2Fmeteor-two-factor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdburles%2Fmeteor-two-factor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdburles%2Fmeteor-two-factor/lists"}