From 1e46b814da2f5c48d80fb5131b5e8ce58c49481f Mon Sep 17 00:00:00 2001 From: Daniel Nagano-Gerace Date: Sat, 6 Jul 2019 20:06:47 -0400 Subject: [PATCH 01/10] Updated ReadMe.md 1) Defined Library About 2) Defined Installation 3) Defined Methods 3a) Defined create method to register user to Twilio Verify 2.0 API 3b) Defined send method to send sms code to registered user through Twilio Verify 2.0 API 3c) Defined verify method to verify user code through Twilio Verify 2.0 API --- ReadMe.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index aaa8315..4e4b052 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1 +1,54 @@ -This is the two factor twilio library. +# What is Two-Factor? + +Two-Factor simplifies the process of implementing two-factor SMS authentication for your application. Two-Factor provides a simplified wrapper for Twilio’s verify API 2.0. + +Two-Factor comes out of the box with *one* constructor function and *three* primary methods to `create` your registered user, `send` your user a verification code, and `verify` your user's code. + +## Installation + +In your terminal, type: + + $ npm install --save two-factor + +If you have not already, make sure to sign up for a Twilio account to receive your API credentials. You can sign up for Twilio here: https://www.twilio.com/try-twilio. + +## Initialization + +In your application's backend, likely in an Express middleware controller (or wherever you manage authentication), require 'two-factor.' Then invoke the twoFactor function with your API credentials: ***your*** **Twilio Account SID** and ***your*** **Twilio Auth Token**. + + const twoFactor = require('two-factor'); + const client = twoFactor(*ACC_SID*, *AUTH_TOKEN*); + +The function will return an instance of a Two-Factor `client`. That `client` will have the `create`, `send`, and `verify` methods. + +## Two-Factor Methods + +### `create()` + +Provide two-factor with a user ID and a phone number associated with that user. + + client.create(*USER_ID*, *PHONE_NUMBER*); + +> Warning: Two-Factor currently only supports US phone numbers. + +`create` registers a new verification service with Twilio, which will allow your application to later send and verify codes to and from that phone number and user. + +### `send()` + +Once *your* user reaches the point in your app's login where you would like them to input the sms code: + + client.send(*USER_ID*); + +> Make sure that the user ID or username you pass as an argument is the same as the user ID you passed to `client.create()` + +`send` then routes through Twilio's API and sends an SMS containing the six-digit verification code to the phone number you associated with the user ID when you registered *your* user when you invoked `create`. + +### `verify()` + +Once your user inputs their six digit code, pass it into the verification method: + + client.verify(*USER_ID*, *SIX_DIGIT_CODE*) + +> Make sure that the *code* you pass is a `string`! NOT a `number`. + +`verify` will properly identify and `return` `true` if the code is valid, `false` if the code is invalid. From 0d053f6379b71cc71ced694418e83ac1b83bb930 Mon Sep 17 00:00:00 2001 From: Daniel Nagano-Gerace Date: Sat, 6 Jul 2019 20:33:56 -0400 Subject: [PATCH 02/10] Update ReadMe.md --- ReadMe.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReadMe.md b/ReadMe.md index 4e4b052..d673ace 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -18,6 +18,8 @@ In your application's backend, likely in an Express middleware controller (or wh const twoFactor = require('two-factor'); const client = twoFactor(*ACC_SID*, *AUTH_TOKEN*); + +> Optionally: you may pass a third parameter Mongo database connection URI so that your Twilio SID, your application's Twilio registered user IDs, their phone numbers are persistent inside your Mongo database. Initialize like so: `twoFactor(*ACC_SID*, *AUTH_TOKEN*, *MONGO_DB_URI*)`. Two-factor stores your SID, registered user IDs and phone numbers inside a collection on your passed in Mongo database under the name `two factor users` The function will return an instance of a Two-Factor `client`. That `client` will have the `create`, `send`, and `verify` methods. From 29bf762968b281e0208d6c81fc33857dd05b6e89 Mon Sep 17 00:00:00 2001 From: Daniel Nagano-Gerace Date: Sat, 6 Jul 2019 20:52:10 -0400 Subject: [PATCH 03/10] Changed name to Two-Auth 1) updated all instances of name to two-auth --- ReadMe.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index d673ace..f040ef3 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,37 +1,37 @@ -# What is Two-Factor? +# What is Two-Auth? -Two-Factor simplifies the process of implementing two-factor SMS authentication for your application. Two-Factor provides a simplified wrapper for Twilio’s verify API 2.0. +Two-Auth simplifies the process of implementing two-factor SMS authentication for your application. Two-Auth provides a simplified wrapper for Twilio’s verify API 2.0. -Two-Factor comes out of the box with *one* constructor function and *three* primary methods to `create` your registered user, `send` your user a verification code, and `verify` your user's code. +Two-Auth comes out of the box with *one* constructor function and *three* primary methods to `create` your registered user, `send` your user a verification code, and `verify` your user's code. ## Installation In your terminal, type: - $ npm install --save two-factor + $ npm install --save two-auth If you have not already, make sure to sign up for a Twilio account to receive your API credentials. You can sign up for Twilio here: https://www.twilio.com/try-twilio. ## Initialization -In your application's backend, likely in an Express middleware controller (or wherever you manage authentication), require 'two-factor.' Then invoke the twoFactor function with your API credentials: ***your*** **Twilio Account SID** and ***your*** **Twilio Auth Token**. +In your application's backend, likely in an Express middleware controller (or wherever you manage authentication), require 'two-auth.' Then invoke the twoAuth function with your API credentials: ***your*** **Twilio Account SID** and ***your*** **Twilio Auth Token**. - const twoFactor = require('two-factor'); - const client = twoFactor(*ACC_SID*, *AUTH_TOKEN*); - -> Optionally: you may pass a third parameter Mongo database connection URI so that your Twilio SID, your application's Twilio registered user IDs, their phone numbers are persistent inside your Mongo database. Initialize like so: `twoFactor(*ACC_SID*, *AUTH_TOKEN*, *MONGO_DB_URI*)`. Two-factor stores your SID, registered user IDs and phone numbers inside a collection on your passed in Mongo database under the name `two factor users` + const twoAuth = require('two-auth'); + const client = twoAuth(*ACC_SID*, *AUTH_TOKEN*); -The function will return an instance of a Two-Factor `client`. That `client` will have the `create`, `send`, and `verify` methods. +> Optionally: you may pass a third parameter Mongo database connection URI so that your Twilio SID, your application's Twilio registered user IDs, their phone numbers are persistent inside your Mongo database. Initialize like so: `twoAuth(*ACC_SID*, *AUTH_TOKEN*, *MONGO_DB_URI*)`. `twoAuth` stores your SID, registered user IDs and phone numbers inside a collection on your passed in Mongo database under the name `two auth users` -## Two-Factor Methods +The function will return an instance of a Two-Auth `client`. That `client` will have the `create`, `send`, and `verify` methods. + +## Two-Auth Methods ### `create()` -Provide two-factor with a user ID and a phone number associated with that user. +Provide two-auth with a user ID and a phone number associated with that user. client.create(*USER_ID*, *PHONE_NUMBER*); -> Warning: Two-Factor currently only supports US phone numbers. +> Warning: Two-Auth currently only supports US phone numbers. `create` registers a new verification service with Twilio, which will allow your application to later send and verify codes to and from that phone number and user. From c7c374a17d4a881c63ac2917c9a9ef3c8e375ac9 Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Sat, 6 Jul 2019 21:04:57 -0400 Subject: [PATCH 04/10] updated package.json --- __tests__/functions/create.js | 2 +- __tests__/functions/test-send.js | 50 +++++++++---------- __tests__/functions/verify.js | 82 ++++++++++++++++---------------- package.json | 20 ++++++-- 4 files changed, 82 insertions(+), 72 deletions(-) diff --git a/__tests__/functions/create.js b/__tests__/functions/create.js index 35ccf2b..65e5517 100644 --- a/__tests__/functions/create.js +++ b/__tests__/functions/create.js @@ -1,4 +1,4 @@ -const create = require("../functions/create"); +const create = require("../../functions/create"); describe("tests the create function", () => { class FakeClient { constructor(isError) { diff --git a/__tests__/functions/test-send.js b/__tests__/functions/test-send.js index 2420895..7a08a09 100644 --- a/__tests__/functions/test-send.js +++ b/__tests__/functions/test-send.js @@ -1,6 +1,6 @@ -const send = require('./../functions/send'); +const send = require("../../functions/send"); -describe('send unit tests', () => { +describe("send unit tests", () => { const sid = 1; const phone = 2; let mockVerificationCreate = jest.fn(); @@ -9,7 +9,7 @@ describe('send unit tests', () => { users: { test: { sid, - phone, + phone } }, send, @@ -17,55 +17,55 @@ describe('send unit tests', () => { verify: { services: () => ({ verifications: { - create: (obj) => { + create: obj => { mockVerificationCreate(); - return new Promise((resolve) => { + return new Promise(resolve => { resolve(obj); }); - }, - }, - }), - }, - }, + } + } + }) + } + } }; beforeEach(() => { mockVerificationCreate.mockClear(); - }) + }); - it('send should throw error upon sending to nonexistent user', () => { + it("send should throw error upon sending to nonexistent user", () => { try { - client.send('nonexistent'); + client.send("nonexistent"); } catch (err) { expect(err).toBeInstanceOf(Error); } }); - it('send should throw error upon nonexistent sid', () => { + it("send should throw error upon nonexistent sid", () => { try { - client.send('test'); + client.send("test"); } catch (err) { expect(err).toBeInstanceOf(Error); } }); - it('send should throw error upon nonexistent phone number', () => { + it("send should throw error upon nonexistent phone number", () => { try { - client.send('test'); + client.send("test"); } catch (err) { expect(err).toBeInstanceOf(Error); } - }) + }); - it('send should create a verification', () => { - client.send('test'); - client.send('test'); + it("send should create a verification", () => { + client.send("test"); + client.send("test"); expect(mockVerificationCreate.mock.calls.length).toBe(2); - }) + }); - it('send should be passing an object to the verification.create call containing phone number and channel', (done) => { - client.send('test').then((res) => { - expect(res).toEqual({ to: phone, channel: 'sms' }); + it("send should be passing an object to the verification.create call containing phone number and channel", done => { + client.send("test").then(res => { + expect(res).toEqual({ to: phone, channel: "sms" }); done(); }); }); diff --git a/__tests__/functions/verify.js b/__tests__/functions/verify.js index 058c3bc..f62716b 100644 --- a/__tests__/functions/verify.js +++ b/__tests__/functions/verify.js @@ -1,51 +1,51 @@ -const verify = require('../functions/verify') -//On client check verify +const verify = require("../../functions/verify"); +//On client check verify -describe('#verify', () => { -class FakeClient { +describe("#verify", () => { + class FakeClient { constructor(isError) { this.client = { - verify: { - services: () => ({ - verificationChecks: { - create: ({to, code}) => { - return new Promise((resolve,reject) => { - if(!isError) resolve({status: 'approved'}) - else reject({status: false }) - }) - } - } - }) + verify: { + services: () => ({ + verificationChecks: { + create: ({ to, code }) => { + return new Promise((resolve, reject) => { + if (!isError) resolve({ status: "approved" }); + else reject({ status: false }); + }); + } + } + }) } + }; + this.verify = verify; + this.users = { Zep: { sid: "Zep3246", phone: "3479087000" } }; } - this.verify = verify - this.users = {'Zep': {'sid':'Zep3246', 'phone':'3479087000'}} } -} - it('throws an error if this.users is empty', () => { - const fakeClient = new FakeClient(false) - // FakeClient.users = {} - return expect((fakeClient.verify('ian'))).rejects.toBeInstanceOf(Error) - }) + it("throws an error if this.users is empty", () => { + const fakeClient = new FakeClient(false); + // FakeClient.users = {} + return expect(fakeClient.verify("ian")).rejects.toBeInstanceOf(Error); + }); - it('throws an error if sid of the user not found', () => { - const fakeClient = new FakeClient(false) - fakeClient.users['Zep'].sid = null - // FakeClient.users = {} - return expect((fakeClient.verify('Zep'))).rejects.toBeInstanceOf(Error) - }) + it("throws an error if sid of the user not found", () => { + const fakeClient = new FakeClient(false); + fakeClient.users["Zep"].sid = null; + // FakeClient.users = {} + return expect(fakeClient.verify("Zep")).rejects.toBeInstanceOf(Error); + }); - it('throws an error if phone of the user not found', () => { - const fakeClient = new FakeClient(false) - fakeClient.users['Zep'].phone = null - // FakeClient.users = {} - return expect((fakeClient.verify('Zep'))).rejects.toBeInstanceOf(Error) - }) + it("throws an error if phone of the user not found", () => { + const fakeClient = new FakeClient(false); + fakeClient.users["Zep"].phone = null; + // FakeClient.users = {} + return expect(fakeClient.verify("Zep")).rejects.toBeInstanceOf(Error); + }); - it('status approved if the code matches', () => { - const fakeClient = new FakeClient(false) - - return expect((fakeClient.verify('Zep'))).resolves.toBeTruthy() - }) -}) + it("status approved if the code matches", () => { + const fakeClient = new FakeClient(false); + + return expect(fakeClient.verify("Zep")).resolves.toBeTruthy(); + }); +}); diff --git a/package.json b/package.json index d662fc4..3c1538b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "two-factor", + "name": "two-auth", "version": "1.0.0", "description": "This is the two factor twilio library.", "main": "index.js", @@ -10,9 +10,19 @@ "type": "git", "url": "git+https://github.com/two-factor/two-factor.git" }, - "keywords": [], - "author": "", - "license": "ISC", + "keywords": [ + "2fa", + "two-factor", + "two", + "two-factor-authentication", + "factor", + "authentication", + "twilio", + "two-factor", + "two factor authentication" + ], + "author": "Ryan Dang, Daniel Nagano-Gerace, Sierra Swaby, Giuseppe Valentino, Ian Geckeler", + "license": "MIT", "bugs": { "url": "https://github.com/two-factor/two-factor/issues" }, @@ -25,4 +35,4 @@ "dotenv": "^8.0.0", "jest": "^24.8.0" } -} +} \ No newline at end of file From 08d3ca39a37524d84f88cc4383647de7729a2eda Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Sat, 6 Jul 2019 21:19:25 -0400 Subject: [PATCH 05/10] removed deprecated tests for mongoose --- __tests__/mongoose/mongoose-create.js | 13 ------------- __tests__/mongoose/mongoose-send.js | 20 -------------------- __tests__/mongoose/mongoose-verify.js | 0 3 files changed, 33 deletions(-) delete mode 100644 __tests__/mongoose/mongoose-create.js delete mode 100644 __tests__/mongoose/mongoose-send.js delete mode 100644 __tests__/mongoose/mongoose-verify.js diff --git a/__tests__/mongoose/mongoose-create.js b/__tests__/mongoose/mongoose-create.js deleted file mode 100644 index 1c1a5c5..0000000 --- a/__tests__/mongoose/mongoose-create.js +++ /dev/null @@ -1,13 +0,0 @@ -require("dotenv").config(); - -// put tests here - -// const client = require("../index")( -// process.env.SID, -// process.env.AUTH, -// "mongodb://localhost/twofactortest" -// ); -// client -// .create("ian", "+17604207520") -// .then(user => console.log(user)) -// .catch(err => console.log(err)); diff --git a/__tests__/mongoose/mongoose-send.js b/__tests__/mongoose/mongoose-send.js deleted file mode 100644 index 99c930e..0000000 --- a/__tests__/mongoose/mongoose-send.js +++ /dev/null @@ -1,20 +0,0 @@ -require("dotenv").config(); - -// put tests here - -// const client = require("../index")( -// process.env.SID, -// process.env.AUTH, -// "mongodb://localhost/twofactortest" -// ); -// client -// .create("ian", "+17604207520") -// .then(user => { -// client.send("ian"); -// }) -// .catch(err => console.log(err)); - -// client -// .verify("ian", "415408") -// .then(res => console.log(res)) -// .catch(err => console.log(err)); diff --git a/__tests__/mongoose/mongoose-verify.js b/__tests__/mongoose/mongoose-verify.js deleted file mode 100644 index e69de29..0000000 From 83f4f227000fc7e152cf34fcf4733478000b9a9e Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Sat, 6 Jul 2019 21:22:15 -0400 Subject: [PATCH 06/10] 1.0.1 --- package-lock.json | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1b4e63f..eb8abeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "two-factor", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3c1538b..63166f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "two-auth", - "version": "1.0.0", + "version": "1.0.1", "description": "This is the two factor twilio library.", "main": "index.js", "scripts": { @@ -35,4 +35,4 @@ "dotenv": "^8.0.0", "jest": "^24.8.0" } -} \ No newline at end of file +} From fd613343231209e1ca18d1b4e4c4d0f180144cb2 Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Mon, 8 Jul 2019 10:21:28 -0400 Subject: [PATCH 07/10] modified package.json to reflect new version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 63166f8..1ac3775 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "two-auth", - "version": "1.0.1", + "version": "1.0.2", "description": "This is the two factor twilio library.", "main": "index.js", "scripts": { @@ -35,4 +35,4 @@ "dotenv": "^8.0.0", "jest": "^24.8.0" } -} +} \ No newline at end of file From f27458217f783753339a47dee799ad98ceadf445 Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Mon, 8 Jul 2019 11:55:14 -0400 Subject: [PATCH 08/10] added postgres support in index.js and created boilerplate file structure for create, send, and verify --- index.js | 73 ++++++++++++++++++- package-lock.json | 157 ++++++++++++++++++++++++++++++++++++---- package.json | 4 +- postgres/configure.js | 18 +++++ postgres/create.js | 15 ++++ postgres/createtable.js | 2 + postgres/send.js | 9 +++ postgres/verify.js | 9 +++ tests/create.js | 15 ++-- 9 files changed, 279 insertions(+), 23 deletions(-) create mode 100644 postgres/configure.js create mode 100644 postgres/create.js create mode 100644 postgres/createtable.js create mode 100644 postgres/send.js create mode 100644 postgres/verify.js diff --git a/index.js b/index.js index 4bc32df..69781a4 100644 --- a/index.js +++ b/index.js @@ -5,26 +5,57 @@ const create = require("./functions/create.js"); const send = require("./functions/send.js"); const verify = require("./functions/verify.js"); +// import mongoose functions const mongooseCreate = require("./mongoose/create"); const mongooseSend = require("./mongoose/send"); const mongooseVerify = require("./mongoose/verify"); - const userSchema = require("./mongoose/userSchema"); +//import postgres functions +const generatePool = require("./postgres/configure"); +const createTable = require("./postgres/createtable"); +const postgresCreate = require("./postgres/create"); +const postgresSend = require("./postgres/send"); +const postgresVerify = require("./postgres/verify"); + const connect = (AccSID, AuthToken, mongoURI = null) => { return new Client(AccSID, AuthToken, mongoURI); }; +// EXAMPLE CONFIG OBJECT +// options = { +// appName: "", +// connectionURI: null, +// isPostgres: null +// } class Client { - constructor(AccSID, AuthToken, mongoURI = null) { + constructor( + AccSID, + AuthToken, + options = { + appName: "", + connectionURI: null, + isPostgres: false + } + ) { + if (typeof options === "string") + throw new Error( + "Options config must be an object, as specified in the documentation." + ); + if (!options.hasOwnProperty("isPostgres")) { + options.isPostgres = false; + } + if (!options.hasOwnProperty("appName")) { + options.appName = ""; + } this.AccSID = AccSID; this.AuthToken = AuthToken; this.client = twilio(this.AccSID, this.AuthToken); this.users = {}; - if (mongoURI !== null) { + if (options.connectionURI !== null && options.isPostgres === false) { mongoose - .connect(mongoURI) + .connect(options.connectionURI) .then(db => { console.log("Two Factor successfully connected to Mongo"); }) @@ -35,6 +66,40 @@ class Client { this.create = mongooseCreate; this.send = mongooseSend; this.verify = mongooseVerify; + } else if (options.connectionURI !== null && options.isPostgres === true) { + // connect the database and assign a reference to it to our client object + const pgPool = generatePool(options.connectionURI); + let tableCreated = false; + this.pgConnect = function() { + return new Promise((resolve, reject) => { + // connection using created pool + pgPool.connect(function(err, database, done) { + if (err) reject(new Error("Error connecting to Postgres Pool.")); + if (!database) { + throw new Error("Could not find Database at Connection URI."); + } + // if table not created yet, create it and modify closure to reflect + if (tableCreated === false) { + database + .query(createTable) + .then(res => { + resolve(database, done); + tableCreated = true; + }) + .catch(e => + reject(new Error("Error connecting to Postgres Pool.")) + ); + } else { + resolve(database, done); + } + }); + }); + }; + + // assign the postgres functions to our client object + this.create = postgresCreate; + this.send = postgresSend; + this.verify = postgresVerify; } else { this.create = create; this.send = send; diff --git a/package-lock.json b/package-lock.json index eb8abeb..409c5bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "two-factor", - "version": "1.0.1", + "name": "two-auth", + "version": "1.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -888,6 +888,11 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -1655,7 +1660,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1676,12 +1682,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1696,17 +1704,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1823,7 +1834,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1835,6 +1847,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1849,6 +1862,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1856,12 +1870,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1880,6 +1896,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1960,7 +1977,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1972,6 +1990,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2057,7 +2076,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2093,6 +2113,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2112,6 +2133,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2155,12 +2177,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -3914,6 +3938,11 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -3974,6 +4003,67 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "pg": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.11.0.tgz", + "integrity": "sha512-YO4V7vCmEMGoF390LJaFaohWNKaA2ayoQOEZmiHVcAUF+YsRThpf/TaKCgSvsSE7cDm37Q/Cy3Gz41xiX/XjTw==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-pool": "^2.0.4", + "pg-types": "~2.0.0", + "pgpass": "1.x", + "semver": "4.3.2" + }, + "dependencies": { + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + } + } + }, + "pg-connection-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.1.0.tgz", + "integrity": "sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-hod2zYQxM8Gt482q+qONGTYcg/qVcV32VHVPtktbBJs0us3Dj7xibISw0BAAXVMCzt8A/jhfJvpZaxUlqtqs0g==" + }, + "pg-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.0.1.tgz", + "integrity": "sha512-b7y6QM1VF5nOeX9ukMQ0h8a9z89mojrBHXfJeSug4mhL0YpxNBm83ot2TROyoAmX/ZOX3UbwVO4EbH7i1ZZNiw==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -4015,6 +4105,29 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.4.tgz", + "integrity": "sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4635,6 +4748,14 @@ "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -4818,6 +4939,11 @@ "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -5226,6 +5352,11 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.1.tgz", "integrity": "sha1-kc1wiXdVNj66V8Et3uq0o0GmH2U=" }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index 1ac3775..db5acca 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,12 @@ "homepage": "https://github.com/two-factor/two-factor#readme", "dependencies": { "mongoose": "^5.6.3", + "pg": "^7.11.0", + "pg-connection-string": "^2.1.0", "twilio": "^3.33.0" }, "devDependencies": { "dotenv": "^8.0.0", "jest": "^24.8.0" } -} \ No newline at end of file +} diff --git a/postgres/configure.js b/postgres/configure.js new file mode 100644 index 0000000..60c1232 --- /dev/null +++ b/postgres/configure.js @@ -0,0 +1,18 @@ +var parse = require("pg-connection-string").parse; +const { Pool } = require("pg"); + +//function takes in a URI, returns a PG Pool + +function generatePool(connectionURI) { + const { user, port, host, database, password } = parse(connectionURI); + + return new Pool({ + user, + host, + database, + password, + port: port || 5432 + }); +} + +module.exports = generatePool; diff --git a/postgres/create.js b/postgres/create.js new file mode 100644 index 0000000..6564658 --- /dev/null +++ b/postgres/create.js @@ -0,0 +1,15 @@ +module.exports = function(userID, phone) { + return new Promise((resolve, reject) => { + this.pgConnect() + .then((pgDatabase, done) => { + // pgClient.query... blah blah logic + //invoke done before your resolve this promise + console.log("called create"); + done(); + }) + .catch((err, done) => { + //invoke done before you reject + reject(err); + }); + }); +}; diff --git a/postgres/createtable.js b/postgres/createtable.js new file mode 100644 index 0000000..8ec9d58 --- /dev/null +++ b/postgres/createtable.js @@ -0,0 +1,2 @@ +module.exports = + "CREATE TABLE twoauthusers (userID VARCHAR(255), sid VARCHAR(255), phone VARCHAR(255))"; diff --git a/postgres/send.js b/postgres/send.js new file mode 100644 index 0000000..c6bd97b --- /dev/null +++ b/postgres/send.js @@ -0,0 +1,9 @@ +module.exports = function(userID, phone) { + return new Promise((resolve, reject) => { + this.pgConnect() + .then(pgDatabase => { + // pgClient.query... blah blah logic + }) + .catch(err => reject(err)); + }); +}; diff --git a/postgres/verify.js b/postgres/verify.js new file mode 100644 index 0000000..c6bd97b --- /dev/null +++ b/postgres/verify.js @@ -0,0 +1,9 @@ +module.exports = function(userID, phone) { + return new Promise((resolve, reject) => { + this.pgConnect() + .then(pgDatabase => { + // pgClient.query... blah blah logic + }) + .catch(err => reject(err)); + }); +}; diff --git a/tests/create.js b/tests/create.js index 73d7b3a..a2edf16 100644 --- a/tests/create.js +++ b/tests/create.js @@ -1,7 +1,12 @@ -const Client = require("../index")(process.env.SID, process.env.AUTH); +const client = require("../index")(process.env.SID, process.env.AUTH, { + isPostgres: true, + connectionURI: "postgres://student:ilovetesting@localhost/twoauthtests" +}); -console.log("client is", Client); +client.create("ian", "+17604207520"); -Client.create("ian", "17604207520") - .then(user => console.log(user)) - .catch(err => console.log(err)); +// console.log("client is", Client); + +// Client.create("ian", "17604207520") +// .then(user => console.log(user)) +// .catch(err => console.log(err)); From f0aeefb7f780f28d059aae273f9a211179426da6 Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Mon, 8 Jul 2019 11:55:41 -0400 Subject: [PATCH 09/10] added bug fix where attempted to pass multiple things out of promise --- index.js | 4 ++-- postgres/create.js | 2 +- postgres/send.js | 10 ++++++++-- postgres/verify.js | 10 ++++++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 69781a4..a1f3a35 100644 --- a/index.js +++ b/index.js @@ -83,14 +83,14 @@ class Client { database .query(createTable) .then(res => { - resolve(database, done); + resolve({ database, done }); tableCreated = true; }) .catch(e => reject(new Error("Error connecting to Postgres Pool.")) ); } else { - resolve(database, done); + resolve({ database, done }); } }); }); diff --git a/postgres/create.js b/postgres/create.js index 6564658..998fd72 100644 --- a/postgres/create.js +++ b/postgres/create.js @@ -1,7 +1,7 @@ module.exports = function(userID, phone) { return new Promise((resolve, reject) => { this.pgConnect() - .then((pgDatabase, done) => { + .then(({ database, done }) => { // pgClient.query... blah blah logic //invoke done before your resolve this promise console.log("called create"); diff --git a/postgres/send.js b/postgres/send.js index c6bd97b..998fd72 100644 --- a/postgres/send.js +++ b/postgres/send.js @@ -1,9 +1,15 @@ module.exports = function(userID, phone) { return new Promise((resolve, reject) => { this.pgConnect() - .then(pgDatabase => { + .then(({ database, done }) => { // pgClient.query... blah blah logic + //invoke done before your resolve this promise + console.log("called create"); + done(); }) - .catch(err => reject(err)); + .catch((err, done) => { + //invoke done before you reject + reject(err); + }); }); }; diff --git a/postgres/verify.js b/postgres/verify.js index c6bd97b..998fd72 100644 --- a/postgres/verify.js +++ b/postgres/verify.js @@ -1,9 +1,15 @@ module.exports = function(userID, phone) { return new Promise((resolve, reject) => { this.pgConnect() - .then(pgDatabase => { + .then(({ database, done }) => { // pgClient.query... blah blah logic + //invoke done before your resolve this promise + console.log("called create"); + done(); }) - .catch(err => reject(err)); + .catch((err, done) => { + //invoke done before you reject + reject(err); + }); }); }; From 52562e401ff2aa99a347fd9f17bcdb3cd1b0bdd0 Mon Sep 17 00:00:00 2001 From: Ian Geckeler Date: Mon, 8 Jul 2019 12:09:56 -0400 Subject: [PATCH 10/10] added create if not exists funcitonality --- postgres/create.js | 2 +- postgres/createtable.js | 2 +- postgres/send.js | 2 +- postgres/verify.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/postgres/create.js b/postgres/create.js index 998fd72..8dc374a 100644 --- a/postgres/create.js +++ b/postgres/create.js @@ -4,11 +4,11 @@ module.exports = function(userID, phone) { .then(({ database, done }) => { // pgClient.query... blah blah logic //invoke done before your resolve this promise - console.log("called create"); done(); }) .catch((err, done) => { //invoke done before you reject + done(); reject(err); }); }); diff --git a/postgres/createtable.js b/postgres/createtable.js index 8ec9d58..918fcf2 100644 --- a/postgres/createtable.js +++ b/postgres/createtable.js @@ -1,2 +1,2 @@ module.exports = - "CREATE TABLE twoauthusers (userID VARCHAR(255), sid VARCHAR(255), phone VARCHAR(255))"; + "CREATE TABLE IF NOT EXISTS twoauthusers (userID VARCHAR(255), sid VARCHAR(255), phone VARCHAR(255))"; diff --git a/postgres/send.js b/postgres/send.js index 998fd72..8dc374a 100644 --- a/postgres/send.js +++ b/postgres/send.js @@ -4,11 +4,11 @@ module.exports = function(userID, phone) { .then(({ database, done }) => { // pgClient.query... blah blah logic //invoke done before your resolve this promise - console.log("called create"); done(); }) .catch((err, done) => { //invoke done before you reject + done(); reject(err); }); }); diff --git a/postgres/verify.js b/postgres/verify.js index 998fd72..8dc374a 100644 --- a/postgres/verify.js +++ b/postgres/verify.js @@ -4,11 +4,11 @@ module.exports = function(userID, phone) { .then(({ database, done }) => { // pgClient.query... blah blah logic //invoke done before your resolve this promise - console.log("called create"); done(); }) .catch((err, done) => { //invoke done before you reject + done(); reject(err); }); });