diff --git a/ReadMe.md b/ReadMe.md index aaa8315..f040ef3 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1 +1,56 @@ -This is the two factor twilio library. +# What is Two-Auth? + +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-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-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-auth.' Then invoke the twoAuth function with your API credentials: ***your*** **Twilio Account SID** and ***your*** **Twilio Auth Token**. + + const twoAuth = require('two-auth'); + const client = twoAuth(*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: `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` + +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-auth with a user ID and a phone number associated with that user. + + client.create(*USER_ID*, *PHONE_NUMBER*); + +> 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. + +### `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. 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/__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 diff --git a/index.js b/index.js index 4bc32df..a1f3a35 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 1b4e63f..409c5bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "two-factor", - "version": "1.0.0", + "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 d662fc4..db5acca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "two-factor", - "version": "1.0.0", + "name": "two-auth", + "version": "1.0.2", "description": "This is the two factor twilio library.", "main": "index.js", "scripts": { @@ -10,15 +10,27 @@ "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" }, "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": { 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..8dc374a --- /dev/null +++ b/postgres/create.js @@ -0,0 +1,15 @@ +module.exports = function(userID, phone) { + return new Promise((resolve, reject) => { + this.pgConnect() + .then(({ database, done }) => { + // pgClient.query... blah blah logic + //invoke done before your resolve this promise + done(); + }) + .catch((err, done) => { + //invoke done before you reject + done(); + reject(err); + }); + }); +}; diff --git a/postgres/createtable.js b/postgres/createtable.js new file mode 100644 index 0000000..918fcf2 --- /dev/null +++ b/postgres/createtable.js @@ -0,0 +1,2 @@ +module.exports = + "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 new file mode 100644 index 0000000..8dc374a --- /dev/null +++ b/postgres/send.js @@ -0,0 +1,15 @@ +module.exports = function(userID, phone) { + return new Promise((resolve, reject) => { + this.pgConnect() + .then(({ database, done }) => { + // pgClient.query... blah blah logic + //invoke done before your resolve this promise + done(); + }) + .catch((err, done) => { + //invoke done before you reject + done(); + reject(err); + }); + }); +}; diff --git a/postgres/verify.js b/postgres/verify.js new file mode 100644 index 0000000..8dc374a --- /dev/null +++ b/postgres/verify.js @@ -0,0 +1,15 @@ +module.exports = function(userID, phone) { + return new Promise((resolve, reject) => { + this.pgConnect() + .then(({ database, done }) => { + // pgClient.query... blah blah logic + //invoke done before your resolve this promise + done(); + }) + .catch((err, done) => { + //invoke done before you reject + done(); + 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));