Skip to content

Commit

Permalink
Merge pull request #23 from two-factor/mongo
Browse files Browse the repository at this point in the history
added first iteration of mongoose functionality to lib
  • Loading branch information
starkspark authored Jul 7, 2019
2 parents c6edb35 + 0bd996a commit 1c8c6b2
Show file tree
Hide file tree
Showing 14 changed files with 364 additions and 94 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
node_modules
.env
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions __tests__/mongoose/mongoose-create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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));
20 changes: 20 additions & 0 deletions __tests__/mongoose/mongoose-send.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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));
Empty file.
35 changes: 29 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
const twilio = require("twilio");
const mongoose = require("mongoose");

const create = require("./functions/create.js");
const send = require("./functions/send.js");
const verify = require("./functions/verify.js");

const connect = (AccSID, AuthToken) => {
return new Client(AccSID, AuthToken);
const mongooseCreate = require("./mongoose/create");
const mongooseSend = require("./mongoose/send");
const mongooseVerify = require("./mongoose/verify");

const userSchema = require("./mongoose/userSchema");

const connect = (AccSID, AuthToken, mongoURI = null) => {
return new Client(AccSID, AuthToken, mongoURI);
};

class Client {
constructor(AccSID, AuthToken) {
constructor(AccSID, AuthToken, mongoURI = null) {
this.AccSID = AccSID;
this.AuthToken = AuthToken;
this.client = twilio(this.AccSID, this.AuthToken);
this.users = {};
this.create = create;
this.send = send;
this.verify = verify;

if (mongoURI !== null) {
mongoose
.connect(mongoURI)
.then(db => {
console.log("Two Factor successfully connected to Mongo");
})
.catch(err => {
throw new Error("Two Factor Unable to connect to Mongo");
});
this.TwoFactorUser = mongoose.model("TwoFactorUser", userSchema);
this.create = mongooseCreate;
this.send = mongooseSend;
this.verify = mongooseVerify;
} else {
this.create = create;
this.send = send;
this.verify = verify;
}
}
}

Expand Down
38 changes: 38 additions & 0 deletions mongoose/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Takes in a userID and phone number associated with that user
// returns a promise
// if resolved, adds a user Object with the userId, sid, and phone associated with the service for that user...
// returns a reference to that object
// if rejected, throws error from verify API
function create(userID, phone) {
const client = this.client;
const users = this.users;
const TwoFactorUser = this.TwoFactorUser;

return new Promise((resolve, reject) => {
if (typeof phone !== "string") {
reject(new Error("typeof phone must be string"));
}
if (phone.substring(0, 2) !== "+1") {
reject(new Error("phone must be string formatted as such: +1XXXXXXXXXX"));
}
client.verify.services
.create({ friendlyName: `Service for ${userID}` })
.then(service => {
const { sid } = service;
TwoFactorUser.create({
userID,
sid,
phone
})
.then(user => {
resolve(user);
})
.catch(err => {
reject(err);
});
})
.catch(err => reject(new Error(String(err))));
});
}

module.exports = create;
39 changes: 39 additions & 0 deletions mongoose/send.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// send takes in a userID
// it searches through users object to find sid and phone number
// then uses twilio api to send text message
// returns a promise
function send(userID) {
const users = this.users;
const client = this.client;
const TwoFactorUser = this.TwoFactorUser;
return new Promise((resolve, reject) => {
TwoFactorUser.findOne({ userID: userID })
.then(user => {
const { sid, phone } = user;
if (!sid) reject(new Error("SID Error: No SID exists for this user."));
if (!phone)
reject(
new Error(
"Phone Number Error: No phone number exists for this user."
)
);

client.verify
.services(sid)
.verifications.create({
to: phone,
channel: "sms"
})
.then(verification => {
resolve(verification);
})
.catch(err => reject(err));
})
.catch(err => {
reject(err);
//"userID Error: This userID has not been created yet."
});
});
}

module.exports = send;
9 changes: 9 additions & 0 deletions mongoose/userSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { Schema } = require("mongoose");

const userSchema = new Schema({
userID: String,
sid: String,
phone: String
});

module.exports = userSchema;
39 changes: 39 additions & 0 deletions mongoose/verify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// takes in a username and code
// checks whether that code is valid for that username
// returns a promise
// if there is a formatting error, promise rejects
// if there is no error, resolves to be the status of the verification
// status is true if verification succeeded, false if verification failed

function verify(userID, code) {
const TwoFactorUser = this.TwoFactorUser;
return new Promise((resolve, reject) => {
TwoFactorUser.findOne({ userID })
.then(user => {
const { sid, phone } = user;
if (!sid) reject(new Error("SID Error: No SID exists for this user."));
if (!phone)
reject(
new Error(
"Phone Number Error: No phone number exists for this user."
)
);

return this.client.verify
.services(sid)
.verificationChecks.create({
to: phone,
code
})
.then(verification => {
if (verification.status === "approved") resolve(true);
return reject(false);
});
})
.catch(err => {
reject(false);
});
});
}

module.exports = verify;
Loading

0 comments on commit 1c8c6b2

Please sign in to comment.