Skip to content

Commit dde6efb

Browse files
pradelAetherall
authored andcommitted
Merge pull request #57 from accounts-js/feature/token-session
changes for token based sessions
1 parent a7d1541 commit dde6efb

File tree

5 files changed

+137
-87
lines changed

5 files changed

+137
-87
lines changed

packages/accounts-mongo/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ lib/
22
node_modules/
33
coverage/
44
npm-debug.log
5+
yarn-error.log
56
.idea
67
lib-es6

packages/accounts-mongo/__tests__/index.ts

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import * as mongodb from 'mongodb';
22
// tslint:disable-next-line
33
import { ObjectID } from 'mongodb';
4+
import { randomBytes } from 'crypto';
45
import Mongo from '../src';
56

6-
let mongo;
7+
const generateRandomToken = (length: number = 43): string =>
8+
randomBytes(length).toString('hex');
9+
10+
let mongo: Mongo;
711
let db: mongodb.Db;
812
let client: mongodb.MongoClient;
913
const user = {
@@ -549,17 +553,18 @@ describe('Mongo', () => {
549553

550554
describe('createSession', () => {
551555
it('should create session', async () => {
552-
const sessionId = await mongo.createSession(
553-
session.userId,
554-
session.ip,
555-
session.userAgent
556-
);
556+
const token = generateRandomToken();
557+
const sessionId = await mongo.createSession(session.userId, token, {
558+
ip: session.ip,
559+
userAgent: session.userAgent,
560+
});
557561
const ret = await mongo.findSessionById(sessionId);
558562
expect(ret).toBeTruthy();
559563
expect(ret._id).toBeTruthy();
560564
expect(ret.userId).toEqual(session.userId);
561565
expect(ret.ip).toEqual(session.ip);
562566
expect(ret.userAgent).toEqual(session.userAgent);
567+
expect(ret.token).toEqual(token);
563568
expect(ret.valid).toEqual(true);
564569
expect(ret.createdAt).toBeTruthy();
565570
expect(ret.createdAt).toEqual(new Date(ret.createdAt).getTime());
@@ -568,10 +573,11 @@ describe('Mongo', () => {
568573

569574
it('should create session with extra data', async () => {
570575
const impersonatorUserId = '789';
576+
const token = generateRandomToken();
571577
const sessionId = await mongo.createSession(
572578
session.userId,
573-
session.ip,
574-
session.userAgent,
579+
token,
580+
{ ip: session.ip, userAgent: session.userAgent },
575581
{ impersonatorUserId }
576582
);
577583
const ret = await mongo.findSessionById(sessionId);
@@ -581,6 +587,7 @@ describe('Mongo', () => {
581587
expect(ret.ip).toEqual(session.ip);
582588
expect(ret.userAgent).toEqual(session.userAgent);
583589
expect(ret.valid).toEqual(true);
590+
expect(ret.token).toEqual(token);
584591
expect(ret.createdAt).toEqual(new Date(ret.createdAt).getTime());
585592
expect(ret.updatedAt).toBeTruthy();
586593
expect(ret.extraData).toEqual({ impersonatorUserId });
@@ -618,6 +625,23 @@ describe('Mongo', () => {
618625
});
619626
});
620627

628+
describe('findSessionByToken', () => {
629+
it('should return null for not found session', async () => {
630+
const ret = await mongo.findSessionByToken('589871d1c9393d445745a57c');
631+
expect(ret).not.toBeTruthy();
632+
});
633+
634+
it('should find session', async () => {
635+
const token = generateRandomToken();
636+
const sessionId = await mongo.createSession(session.userId, token, {
637+
ip: session.ip,
638+
userAgent: session.userAgent,
639+
});
640+
const ret = await mongo.findSessionByToken(token);
641+
expect(ret).toBeTruthy();
642+
});
643+
});
644+
621645
describe('findSessionById', () => {
622646
it('should return null for not found session', async () => {
623647
const ret = await mongo.findSessionById('589871d1c9393d445745a57c');
@@ -640,18 +664,22 @@ describe('Mongo', () => {
640664
});
641665

642666
it('should update session', async () => {
643-
const sessionId = await mongo.createSession(
644-
session.userId,
645-
session.ip,
646-
session.userAgent
647-
);
667+
const token = generateRandomToken();
668+
const sessionId = await mongo.createSession(session.userId, token, {
669+
ip: session.ip,
670+
userAgent: session.userAgent,
671+
});
648672
await delay(10);
649-
await mongo.updateSession(sessionId, 'new ip', 'new user agent');
673+
await mongo.updateSession(sessionId, {
674+
ip: 'new ip',
675+
userAgent: 'new user agent',
676+
});
650677
const ret = await mongo.findSessionById(sessionId);
651678
expect(ret.userId).toEqual(session.userId);
652679
expect(ret.ip).toEqual('new ip');
653680
expect(ret.userAgent).toEqual('new user agent');
654681
expect(ret.valid).toEqual(true);
682+
expect(ret.token).toEqual(token);
655683
expect(ret.createdAt).toBeTruthy();
656684
expect(ret.updatedAt).toBeTruthy();
657685
expect(ret.createdAt).not.toEqual(ret.updatedAt);
@@ -667,11 +695,11 @@ describe('Mongo', () => {
667695
});
668696

669697
it('invalidates a session', async () => {
670-
const sessionId = await mongo.createSession(
671-
session.userId,
672-
session.ip,
673-
session.userAgent
674-
);
698+
const token = generateRandomToken();
699+
const sessionId = await mongo.createSession(session.userId, token, {
700+
ip: session.ip,
701+
userAgent: session.userAgent,
702+
});
675703
await delay(10);
676704
await mongo.invalidateSession(sessionId);
677705
const ret = await mongo.findSessionById(sessionId);
@@ -684,13 +712,13 @@ describe('Mongo', () => {
684712
it('invalidates all sessions', async () => {
685713
const sessionId1 = await mongo.createSession(
686714
session.userId,
687-
session.ip,
688-
session.userAgent
715+
generateRandomToken(),
716+
{ ip: session.ip, userAgent: session.userAgent }
689717
);
690718
const sessionId2 = await mongo.createSession(
691719
session.userId,
692-
session.ip,
693-
session.userAgent
720+
generateRandomToken(),
721+
{ ip: session.ip, userAgent: session.userAgent }
694722
);
695723
await delay(10);
696724
await mongo.invalidateAllSessions(session.userId);

packages/accounts-mongo/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"scripts": {
88
"start": "tsc --watch",
99
"compile": "tsc",
10-
"test": "yarn lint && yarn coverage && yarn prettier-diff",
10+
"test":
11+
"yarn lint && yarn coverage && yarn prettier-diff && yarn run compile",
1112
"testonly": "jest --forceExit",
1213
"lint": "tslint -c tslint.json '{src,__tests__}/**/*.ts'",
1314
"prettier": "prettier '{src,__tests__}/**/*.ts' 'README.md'",
@@ -34,8 +35,7 @@
3435
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
3536
},
3637
"testRegex": "./__tests__/.*.ts$",
37-
"moduleFileExtensions": ["ts", "js"],
38-
"mapCoverage": true
38+
"moduleFileExtensions": ["ts", "js"]
3939
},
4040
"repository": {
4141
"type": "git",
@@ -48,13 +48,13 @@
4848
},
4949
"homepage": "https://github.com/js-accounts/mongo",
5050
"devDependencies": {
51-
"@accounts/common": "0.1.0-beta.2",
52-
"@accounts/server": "0.1.0-beta.2",
51+
"@accounts/common": "0.1.0-beta.3",
52+
"@accounts/server": "0.1.0-beta.3",
5353
"@accounts/tslint-config-accounts": "0.0.6",
5454
"@types/jest": "22.2.0",
5555
"@types/lodash": "4.14.104",
5656
"@types/mongodb": "3.0.7",
57-
"@types/node": "8.9.4",
57+
"@types/node": "9.4.6",
5858
"codecov": "3.0.0",
5959
"coveralls": "3.0.0",
6060
"husky": "0.14.3",
@@ -66,8 +66,8 @@
6666
"typescript": "2.7.2"
6767
},
6868
"peerDependencies": {
69-
"@accounts/common": "^0.1.0-beta.0",
70-
"@accounts/server": "^0.1.0-beta.0"
69+
"@accounts/common": "^0.1.0-beta.3",
70+
"@accounts/server": "^0.1.0-beta.3"
7171
},
7272
"dependencies": {
7373
"lodash": "^4.17.4",

packages/accounts-mongo/src/mongo.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ObjectID, Db, Collection } from 'mongodb';
22
import { get } from 'lodash';
33
import { CreateUserType, UserObjectType, SessionType } from '@accounts/common';
4-
import { DBInterface } from '@accounts/server';
4+
import { DBInterface, ConnectionInformationsType } from '@accounts/server';
55

66
export interface MongoOptionsType {
77
// The users collection name, default 'users'.
@@ -86,6 +86,10 @@ export class Mongo implements DBInterface {
8686
}
8787

8888
public async setupIndexes(): Promise<void> {
89+
await this.sessionCollection.createIndex('token', {
90+
unique: true,
91+
sparse: true,
92+
});
8993
await this.collection.createIndex('username', {
9094
unique: true,
9195
sparse: true,
@@ -346,14 +350,15 @@ export class Mongo implements DBInterface {
346350

347351
public async createSession(
348352
userId: string,
349-
ip?: string,
350-
userAgent?: string,
353+
token: string,
354+
connection: ConnectionInformationsType = {},
351355
extraData?: object
352356
): Promise<string> {
353357
const session = {
354358
userId,
355-
userAgent,
356-
ip,
359+
token,
360+
userAgent: connection.userAgent,
361+
ip: connection.ip,
357362
extraData,
358363
valid: true,
359364
[this.options.timestamps.createdAt]: this.options.dateProvider(),
@@ -370,8 +375,7 @@ export class Mongo implements DBInterface {
370375

371376
public async updateSession(
372377
sessionId: string,
373-
ip: string,
374-
userAgent: string
378+
connection: ConnectionInformationsType
375379
): Promise<void> {
376380
// tslint:disable-next-line variable-name
377381
const _id = this.options.convertSessionIdToMongoObjectId
@@ -381,8 +385,8 @@ export class Mongo implements DBInterface {
381385
{ _id },
382386
{
383387
$set: {
384-
ip,
385-
userAgent,
388+
userAgent: connection.userAgent,
389+
ip: connection.ip,
386390
[this.options.timestamps.updatedAt]: this.options.dateProvider(),
387391
},
388392
}
@@ -417,12 +421,24 @@ export class Mongo implements DBInterface {
417421
);
418422
}
419423

420-
public findSessionById(sessionId: string): Promise<SessionType | null> {
424+
public async findSessionByToken(token: string): Promise<SessionType | null> {
425+
const session = await this.sessionCollection.findOne({ token });
426+
if (session) {
427+
session.id = session._id;
428+
}
429+
return session;
430+
}
431+
432+
public async findSessionById(sessionId: string): Promise<SessionType | null> {
421433
// tslint:disable-next-line variable-name
422434
const _id = this.options.convertSessionIdToMongoObjectId
423435
? toMongoID(sessionId)
424436
: sessionId;
425-
return this.sessionCollection.findOne({ _id });
437+
const session = await this.sessionCollection.findOne({ _id });
438+
if (session) {
439+
session.id = session._id;
440+
}
441+
return session;
426442
}
427443

428444
public async addEmailVerificationToken(

0 commit comments

Comments
 (0)