-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Print proper error when disallowed * Add server side tests
- Loading branch information
Tomasz Przytuła
committed
Jan 27, 2018
1 parent
2dfc57d
commit e8037c9
Showing
15 changed files
with
396 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
.idea | ||
.idea | ||
.npm | ||
.vscode | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.idea | ||
.npm | ||
.git | ||
.vscode | ||
node_modules | ||
test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,21 @@ | ||
{ | ||
"name": "tprzytula:remember-me", | ||
"version": "0.1.0", | ||
"description": "Extension for Meteor account-base package with the implementation of rememberMe", | ||
"license": "MIT", | ||
"author": "Tomasz Przytuła <[email protected]>", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/tprzytulacc/Meteor-Remember-Me" | ||
}, | ||
"keywords": [ | ||
"meteor", | ||
"rememberme", | ||
"autologin", | ||
"login" | ||
], | ||
"homepage": "https://github.com/tprzytulacc/Meteor-Remember-Me" | ||
} | ||
"name": "rememberMe", | ||
"version": "0.1.1", | ||
"description": "Extension for Meteor account-base package with the implementation of rememberMe", | ||
"license": "MIT", | ||
"author": "Tomasz Przytuła <[email protected]>", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/tprzytulacc/Meteor-Remember-Me" | ||
}, | ||
"keywords": [ | ||
"meteor", | ||
"rememberme", | ||
"autologin", | ||
"login" | ||
], | ||
"homepage": "https://github.com/tprzytulacc/Meteor-Remember-Me", | ||
"scripts": { | ||
"test": "meteor test-packages ./ --driver-package meteortesting:mocha" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const login = require('./tests/login'); | ||
const method = require('./tests/method'); | ||
const resume = require('./tests/resume'); | ||
|
||
/** | ||
* Server-side test cases. | ||
*/ | ||
describe('server', () => { | ||
login(); | ||
method(); | ||
resume(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
const { chai } = require('meteor/practicalmeteor:chai'); | ||
const Authenticator = require('../../../server/authenticator').default; | ||
const LoginAttemptGenerator = require('../utils/loginAttemptGenerator'); | ||
|
||
const expect = chai.expect; | ||
const type = 'password'; | ||
|
||
module.exports = () => { | ||
/** | ||
* Those tests are covering a basic user login attempt. | ||
* The attempt is invoked if the user is logging for the first | ||
* time by using methods such as Meteor.loginWithPassword. | ||
*/ | ||
describe('login attempt', () => { | ||
/** | ||
* The attempt can be disallowed already from the previously | ||
* ran validators. It can be a validator directly from the Meteor core | ||
* saying that the password is wrong but also another one created by the developer. | ||
* | ||
* In this case there is no need to validate the attempt anymore. | ||
* It should be instantly disallowed again. | ||
*/ | ||
it('should not pass if the attempt is already disallowed', () => { | ||
const loginAttemptGenerator = new LoginAttemptGenerator({ type }); | ||
let loginAttempt = loginAttemptGenerator.getLoginAttempt(); | ||
loginAttempt.allowed = false; | ||
const authenticator = new Authenticator(loginAttempt); | ||
const { result, resultCode, reason } = authenticator.validateAttempt(); | ||
expect(result).to.be.equal(false); | ||
expect(resultCode).to.be.equal(-1); | ||
expect(reason).to.be.equal('Attempt disallowed by Meteor'); | ||
}); | ||
|
||
/** | ||
* The dependency logic should not affect normal login attempts. | ||
* Because of that if the previously ran validations succeeded the | ||
* dependency should also let it pass further. | ||
*/ | ||
it('should pass if the attempt is allowed', () => { | ||
const loginAttemptGenerator = new LoginAttemptGenerator({ type }); | ||
let loginAttempt = loginAttemptGenerator.getLoginAttempt(); | ||
loginAttempt.allowed = true; | ||
const authenticator = new Authenticator(loginAttempt); | ||
const { result, resultCode, reason } = authenticator.validateAttempt(); | ||
expect(result).to.be.equal(true); | ||
expect(resultCode).to.be.equal(0); | ||
expect(reason).to.be.equal('Validation passed'); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const RememberMe = require('meteor/tprzytula:remember-me'); | ||
const { chai } = require('meteor/practicalmeteor:chai'); | ||
|
||
const rememberMeMethod = 'tprzytula:rememberMe-update'; | ||
const getMeteorMethods = () => Meteor.default_server.method_handlers; | ||
const checkIfMeteorMethodExists = name => name in getMeteorMethods(); | ||
|
||
module.exports = () => { | ||
/** | ||
* The dependency is significantly affecting how the login system works. | ||
* I'm against the idea of dependencies which are running automatically | ||
* without the developer knowledge. There are situations where developers | ||
* are leaving not used dependencies in the list. In this case it can be | ||
* hard for them to debug and find the reason for their login system | ||
* to work differently than the normal one should. | ||
*/ | ||
describe('remember-me method', () => { | ||
/** | ||
* Having this dependency installed should not invoke it. | ||
* The main method used for the communication client <> server | ||
* should not exist. | ||
*/ | ||
it('should not exist by default', () => { | ||
const doesExist = checkIfMeteorMethodExists(rememberMeMethod); | ||
expect(doesExist).to.be.equal(false); | ||
}); | ||
|
||
/** | ||
* After activating the functionality a new meteor method | ||
* should be created. From now all users are being able to | ||
* invoke the 'tprzytula:rememberMe-update' method. | ||
*/ | ||
it('should exist after activating the functionality', () => { | ||
RememberMe.activate(); | ||
const doesExist = checkIfMeteorMethodExists(rememberMeMethod); | ||
expect(doesExist).to.be.equal(true); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
const { chai } = require('meteor/practicalmeteor:chai'); | ||
const TestUser = require('../utils/testUser'); | ||
const Authenticator = require('../../../server/authenticator').default; | ||
const LoginAttemptGenerator = require('../utils/loginAttemptGenerator') | ||
|
||
const expect = chai.expect; | ||
const type = 'resume'; | ||
const resume = 'token'; | ||
const testUser = new TestUser({ | ||
username: 'resume-test', | ||
password: 'resume-test' | ||
}); | ||
|
||
module.exports = () => { | ||
/** | ||
* Those tests are covering the autologin attempt. | ||
* The attempt is invoked by the core of the meteor accounts. | ||
* Every time a previously logged in user reconnects to the system | ||
* there is a "resume" attempt sent. | ||
* | ||
* This dependency did allow the user to decide during the login | ||
* if he want to have the rememberMe flag set on true or false. | ||
* This setting will have an importance of the decision being made during resume. | ||
*/ | ||
describe('resume attempt', () => { | ||
/** | ||
* In case of an user logging in with rememberMe the resume | ||
* attempt should be allowed. This covers a situation where user | ||
* is being logged with rememberMe and then restarts the application. | ||
* The user should stay logged in. | ||
*/ | ||
it('should pass if user does have rememberMe', () => { | ||
testUser.setLoginToken({ resume, rememberMe: true }); | ||
const loginAttemptGenerator = new LoginAttemptGenerator({ type, resume }); | ||
const loginAttempt = loginAttemptGenerator.getLoginAttempt(); | ||
const authenticator = new Authenticator(loginAttempt); | ||
const { result, resultCode, reason } = authenticator.validateAttempt(); | ||
expect(result).to.be.equal(true); | ||
expect(resultCode).to.be.equal(0); | ||
expect(reason).to.be.equal('Validation passed'); | ||
}); | ||
|
||
/** | ||
* In case of an user logging in without rememberMe the resume | ||
* attempt should not be allowed. This covers a situation where user | ||
* is being logged without rememberMe and then restarts the application. | ||
* The user should be logged out. | ||
*/ | ||
it('should not pass if user does not have rememberMe', () => { | ||
testUser.setLoginToken({ resume, rememberMe: false }); | ||
const loginAttemptGenerator = new LoginAttemptGenerator({ type, resume }); | ||
const loginAttempt = loginAttemptGenerator.getLoginAttempt(); | ||
const authenticator = new Authenticator(loginAttempt); | ||
const { result, resultCode, reason } = authenticator.validateAttempt(); | ||
expect(result).to.be.equal(false); | ||
expect(resultCode).to.be.equal(-2); | ||
expect(reason).to.be.equal('Resume not allowed when user does not have remember me'); | ||
}); | ||
|
||
/** | ||
* Important thing to keep in mind is that Meteor's login system does not know | ||
* when the user is starting the app from the scratch or just lost the internet. | ||
* It's not intended to logout an user without rememberMe every time he will lose | ||
* the internet connection. | ||
* | ||
* To avoid this situation the user from now is sending also 'loggedAtLeastOnce: true' | ||
* flag if he already logged once in ongoing device session. | ||
*/ | ||
describe('connection loss', () => { | ||
/** | ||
* If the user already had a successfull login attempt during his device session | ||
* then he should stay logged in no matter the rememberMe setting after the reconnect. | ||
* Validates if user stays online with rememberMe being set to 'false'. | ||
*/ | ||
it('should pass for the same session as previous login when without rememberMe', () => { | ||
testUser.setLoginToken({ resume, rememberMe: false }); | ||
const loginAttemptGenerator = new LoginAttemptGenerator({ type, resume }); | ||
loginAttemptGenerator.addMethodArgument({ loggedAtLeastOnce: true }); | ||
const loginAttempt = loginAttemptGenerator.getLoginAttempt(); | ||
const authenticator = new Authenticator(loginAttempt); | ||
const { result, resultCode, reason } = authenticator.validateAttempt(); | ||
expect(result).to.be.equal(true); | ||
expect(resultCode).to.be.equal(0); | ||
expect(reason).to.be.equal('Validation passed'); | ||
}); | ||
|
||
/** | ||
* If the user already had a successfull login attempt during his device session | ||
* then he should stay logged in no matter the rememberMe setting after the reconnect. | ||
* Validates if user stays online with rememberMe being set to 'true'. | ||
*/ | ||
it('should pass for the same session as previous login when with rememberMe', () => { | ||
testUser.setLoginToken({ resume, rememberMe: true }); | ||
const loginAttemptGenerator = new LoginAttemptGenerator({ type, resume }); | ||
loginAttemptGenerator.addMethodArgument({ loggedAtLeastOnce: true }); | ||
const loginAttempt = loginAttemptGenerator.getLoginAttempt(); | ||
const authenticator = new Authenticator(loginAttempt); | ||
const { result, resultCode, reason } = authenticator.validateAttempt(); | ||
expect(result).to.be.equal(true); | ||
expect(resultCode).to.be.equal(0); | ||
expect(reason).to.be.equal('Validation passed'); | ||
}); | ||
}); | ||
}); | ||
}; |
Oops, something went wrong.