Skip to content

Commit

Permalink
Merge pull request #5 from js-accounts/sessions
Browse files Browse the repository at this point in the history
Add sessions support
  • Loading branch information
TimMikeladze authored and Aetherall committed Mar 13, 2018
1 parent 4b7c8fd commit 1c685b6
Show file tree
Hide file tree
Showing 4 changed files with 792 additions and 551 deletions.
34 changes: 17 additions & 17 deletions packages/accounts-mongo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,31 @@
},
"homepage": "https://github.com/js-accounts/mongo",
"devDependencies": {
"babel-cli": "^6.16.0",
"babel-core": "^6.17.0",
"babel-cli": "^6.22.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.0.0",
"babel-loader": "^6.2.5",
"babel-plugin-transform-async-to-generator": "^6.16.0",
"babel-plugin-transform-flow-strip-types": "^6.21.0",
"babel-plugin-transform-object-rest-spread": "^6.20.2",
"babel-preset-es2015": "^6.16.0",
"babel-plugin-transform-async-to-generator": "^6.22.0",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"coveralls": "^2.11.14",
"eslint": "^3.7.1",
"eslint-config-airbnb": "^12.0.0",
"eslint-config-airbnb-base": "^9.0.0",
"eslint-plugin-flowtype": "^2.29.1",
"eslint": "^3.13.1",
"eslint-config-airbnb": "^14.0.0",
"eslint-config-airbnb-base": "^11.0.1",
"eslint-plugin-flowtype": "^2.30.0",
"eslint-plugin-import": "^2.0.1",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.3.0",
"eslint-plugin-jsx-a11y": "^3.0.2",
"eslint-plugin-react": "^6.9.0",
"flow-bin": "^0.37.4",
"jest": "^18.0.0",
"jest": "^18.1.0",
"webpack": "^1.14.0",
"webpack-node-externals": "^1.5.4"
},
"dependencies": {
"@accounts/common": "^0.0.1",
"@accounts/server": "^0.0.1",
"lodash": "^4.17.3",
"mongodb": "^2.2.16"
"@accounts/common": "^0.0.2",
"@accounts/server": "^0.0.2",
"lodash": "^4.17.4",
"mongodb": "^2.2.21"
}
}
63 changes: 56 additions & 7 deletions packages/accounts-mongo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { encryption } from '@accounts/server';
import type {
CreateUserType,
UserObjectType,
SessionType,
} from '@accounts/common';

export type MongoOptionsType = {
collectionName: string,
sessionCollectionName: string,
timestamps: {
createdAt: string,
updatedAt: string,
Expand All @@ -34,10 +36,12 @@ class Mongo {
// TODO definition for mongodb connection object
db: any;
collection: any;
sessionCollection: any;

constructor(db: any, options: MongoOptionsType) {
const defaultOptions = {
collectionName: 'users',
sessionCollectionName: 'sessions',
timestamps: {
createdAt: 'createdAt',
updatedAt: 'updatedAt',
Expand All @@ -49,17 +53,19 @@ class Mongo {
}
this.db = db;
this.collection = this.db.collection(this.options.collectionName);
this.sessionCollection = this.db.collection(this.options.sessionCollectionName);
}

async setupIndexes(): Promise<void> {
await this.collection.createIndex('username', { unique: 1, sparse: 1 });
await this.collection.createIndex('emails.address', { unique: 1, sparse: 1 });
}

async createUser(options: CreateUserType): Promise<UserObjectType> {
async createUser(options: CreateUserType): Promise<string> {
const user: MongoUserObjectType = {
services: {},
[this.options.timestamps.createdAt]: Date.now(),
[this.options.timestamps.updatedAt]: Date.now(),
};
if (options.password) {
user.services.password = { bcrypt: await encryption.hashPassword(options.password) };
Expand All @@ -71,7 +77,7 @@ class Mongo {
user.emails = [{ address: options.email.toLowerCase(), verified: false }];
}
const ret = await this.collection.insertOne(user);
return ret.ops[0];
return ret.ops[0]._id;
}

findUserById(userId: string): Promise<?UserObjectType> {
Expand All @@ -88,10 +94,10 @@ class Mongo {

async findPasswordHash(userId: string): Promise<?string> {
const user = await this.findUserById(userId);
if (!user) {
throw new Error('User not found');
if (user) {
return user.services.password.bcrypt;
}
return user.services.password.bcrypt;
return null;
}

async addEmail(userId: string, newEmail: string, verified: boolean): Promise<void> {
Expand All @@ -102,6 +108,7 @@ class Mongo {
verified,
},
},
$set: { [this.options.timestamps.updatedAt]: Date.now() },
});
if (ret.result.nModified === 0) {
throw new Error('User not found');
Expand All @@ -111,6 +118,7 @@ class Mongo {
async removeEmail(userId: string, email: string): Promise<void> {
const ret = await this.collection.update({ _id: userId }, {
$pull: { emails: { address: email.toLowerCase() } },
$set: { [this.options.timestamps.updatedAt]: Date.now() },
});
if (ret.result.nModified === 0) {
throw new Error('User not found');
Expand All @@ -119,7 +127,10 @@ class Mongo {

async setUsername(userId: string, newUsername: string): Promise<void> {
const ret = await this.collection.update({ _id: userId }, {
$set: { username: newUsername },
$set: {
username: newUsername,
[this.options.timestamps.updatedAt]: Date.now(),
},
});
if (ret.result.nModified === 0) {
throw new Error('User not found');
Expand All @@ -128,12 +139,50 @@ class Mongo {

async setPasssword(userId: string, newPassword: string): Promise<void> {
const ret = await this.collection.update({ _id: userId }, {
$set: { 'services.password.bcrypt': await encryption.hashPassword(newPassword) },
$set: {
'services.password.bcrypt': await encryption.hashPassword(newPassword),
[this.options.timestamps.updatedAt]: Date.now(),
},
});
if (ret.result.nModified === 0) {
throw new Error('User not found');
}
}

async createSession(userId: string, ip: string, userAgent: string): Promise<string> {
const ret = await this.sessionCollection.insertOne({
userId,
userAgent,
ip,
valid: true,
[this.options.timestamps.createdAt]: Date.now(),
[this.options.timestamps.updatedAt]: Date.now(),
});
return ret.ops[0]._id;
}

async updateSession(sessionId: string, ip: string, userAgent: string): Promise<void> {
await this.sessionCollection.update({ _id: sessionId }, {
$set: {
ip,
userAgent,
[this.options.timestamps.updatedAt]: Date.now(),
},
});
}

async invalidateSession(sessionId: string): Promise<void> {
await this.sessionCollection.update({ _id: sessionId }, {
$set: {
valid: false,
[this.options.timestamps.updatedAt]: Date.now(),
},
});
}

findSessionById(sessionId: string): Promise<?SessionType> {
return this.sessionCollection.findOne({ _id: sessionId });
}
}

export default Mongo;
Loading

0 comments on commit 1c685b6

Please sign in to comment.