Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email Validation #627

Merged
merged 9 commits into from
Mar 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"commander": "^2.9.0",
"deepcopy": "^0.6.1",
"express": "^4.13.4",
"mailgun-js": "^0.7.7",
"mime": "^1.3.4",
"mongodb": "~2.1.0",
"multer": "^1.1.0",
Expand Down
43 changes: 43 additions & 0 deletions public_html/invalid_link.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<!-- This page is displayed when someone navigates to a verify email or reset password link
but their security token is wrong. This can either mean the user has clicked on a
stale link (i.e. re-click on a password reset link after resetting their password) or
(rarely) this could be a sign of a malicious user trying to tamper with your app.
-->
<html>
<head>
<title>Invalid Link</title>
<style type='text/css'>
.container {
border-width: 0px;
display: block;
font: inherit;
font-family: 'Helvetica Neue', Helvetica;
font-size: 16px;
height: 30px;
line-height: 16px;
margin: 45px 0px 0px 45px;
padding: 0px 8px 0px 8px;
position: relative;
vertical-align: baseline;
}

h1, h2, h3, h4, h5 {
color: #0067AB;
display: block;
font: inherit;
font-family: 'Open Sans', 'Helvetica Neue', Helvetica;
font-size: 30px;
font-weight: 600;
height: 30px;
line-height: 30px;
margin: 0 0 15px 0;
padding: 0 0 0 0;
}
</style>
<body>
<div class="container">
<h1>Invalid Link</h1>
</div>
</body>
</html>
27 changes: 27 additions & 0 deletions public_html/password_reset_success.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<!-- This page is displayed whenever someone has successfully reset their password.
Pro and Enterprise accounts may edit this page and tell Parse to use that custom
version in their Parse app. See the App Settigns page for more information.
This page will be called with the query param 'username'
-->
<head>
<title>Password Reset</title>
<style type='text/css'>
h1 {
color: #0067AB;
display: block;
font: inherit;
font-family: 'Open Sans', 'Helvetica Neue', Helvetica;
font-size: 30px;
font-weight: 600;
height: 30px;
line-height: 30px;
margin: 45px 0px 0px 45px;
padding: 0px 8px 0px 8px;
}
</style>
<body>
<h1>Successfully updated your password!</h1>
</body>
</html>
27 changes: 27 additions & 0 deletions public_html/verify_email_success.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<!-- This page is displayed whenever someone has successfully reset their password.
Pro and Enterprise accounts may edit this page and tell Parse to use that custom
version in their Parse app. See the App Settigns page for more information.
This page will be called with the query param 'username'
-->
<head>
<title>Email Verification</title>
<style type='text/css'>
h1 {
color: #0067AB;
display: block;
font: inherit;
font-family: 'Open Sans', 'Helvetica Neue', Helvetica;
font-size: 30px;
font-weight: 600;
height: 30px;
line-height: 30px;
margin: 45px 0px 0px 45px;
padding: 0px 8px 0px 8px;
}
</style>
<body>
<h1>Successfully verified your email!</h1>
</body>
</html>
27 changes: 23 additions & 4 deletions spec/AdapterLoader.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
var loadAdapter = require("../src/Adapters/AdapterLoader").loadAdapter;
var FilesAdapter = require("../src/Adapters/Files/FilesAdapter").default;

describe("AdaptableController", ()=>{
describe("AdapterLoader", ()=>{

it("should instantiate an adapter from string in object", (done) => {
var adapterPath = require('path').resolve("./spec/MockAdapter");

var adapter = loadAdapter({
adapter: adapterPath,
key: "value",
foo: "bar"
options: {
key: "value",
foo: "bar"
}
});

expect(adapter instanceof Object).toBe(true);
Expand All @@ -24,7 +26,6 @@ describe("AdaptableController", ()=>{
var adapter = loadAdapter(adapterPath);

expect(adapter instanceof Object).toBe(true);
expect(adapter.options).toBe(adapterPath);
done();
});

Expand Down Expand Up @@ -65,4 +66,22 @@ describe("AdaptableController", ()=>{
expect(adapter).toBe(originalAdapter);
done();
});

it("should fail loading an improperly configured adapter", (done) => {
var Adapter = function(options) {
if (!options.foo) {
throw "foo is required for that adapter";
}
}
var adapterOptions = {
param: "key",
doSomething: function() {}
};

expect(() => {
var adapter = loadAdapter(adapterOptions, Adapter);
expect(adapter).toEqual(adapterOptions);
}).not.toThrow("foo is required for that adapter");
done();
});
});
6 changes: 4 additions & 2 deletions spec/MockAdapter.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module.exports = function(options) {
this.options = options;
}
return {
options: options
};
};
5 changes: 5 additions & 0 deletions spec/MockEmailAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
sendVerificationEmail: () => Promise.resolve(),
sendPasswordResetEmail: () => Promise.resolve(),
sendMail: () => Promise.resolve()
}
10 changes: 10 additions & 0 deletions spec/MockEmailAdapterWithOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = options => {
if (!options) {
throw "Options were not provided"
}
return {
sendVerificationEmail: () => Promise.resolve(),
sendPasswordResetEmail: () => Promise.resolve(),
sendMail: () => Promise.resolve()
}
}
33 changes: 20 additions & 13 deletions spec/OneSignalPushAdapter.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@

var OneSignalPushAdapter = require('../src/Adapters/Push/OneSignalPushAdapter');
var classifyInstallations = require('../src/Adapters/Push/PushAdapterUtils').classifyInstallations;

// Make mock config
var pushConfig = {
oneSignalAppId:"APP ID",
oneSignalApiKey:"API KEY"
};

describe('OneSignalPushAdapter', () => {
it('can be initialized', (done) => {
// Make mock config
var pushConfig = {
oneSignalAppId:"APP ID",
oneSignalApiKey:"API KEY"
};

var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);

Expand All @@ -17,9 +19,17 @@ describe('OneSignalPushAdapter', () => {
expect(senderMap.android instanceof Function).toBe(true);
done();
});

it('cannot be initialized if options are missing', (done) => {

expect(() => {
new OneSignalPushAdapter();
}).toThrow("Trying to initialize OneSignalPushAdapter without oneSignalAppId or oneSignalApiKey");
done();
});

it('can get valid push types', (done) => {
var oneSignalPushAdapter = new OneSignalPushAdapter();
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);

expect(oneSignalPushAdapter.getValidPushTypes()).toEqual(['ios', 'android']);
done();
Expand Down Expand Up @@ -56,7 +66,7 @@ describe('OneSignalPushAdapter', () => {


it('can send push notifications', (done) => {
var oneSignalPushAdapter = new OneSignalPushAdapter();
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);

// Mock android ios senders
var androidSender = jasmine.createSpy('send')
Expand Down Expand Up @@ -108,7 +118,7 @@ describe('OneSignalPushAdapter', () => {
});

it("can send iOS notifications", (done) => {
var oneSignalPushAdapter = new OneSignalPushAdapter();
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
var sendToOneSignal = jasmine.createSpy('sendToOneSignal');
oneSignalPushAdapter.sendToOneSignal = sendToOneSignal;

Expand All @@ -135,7 +145,7 @@ describe('OneSignalPushAdapter', () => {
});

it("can send Android notifications", (done) => {
var oneSignalPushAdapter = new OneSignalPushAdapter();
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
var sendToOneSignal = jasmine.createSpy('sendToOneSignal');
oneSignalPushAdapter.sendToOneSignal = sendToOneSignal;

Expand All @@ -157,10 +167,7 @@ describe('OneSignalPushAdapter', () => {
});

it("can post the correct data", (done) => {
var pushConfig = {
oneSignalAppId:"APP ID",
oneSignalApiKey:"API KEY"
};

var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);

var write = jasmine.createSpy('write');
Expand Down
10 changes: 5 additions & 5 deletions spec/ParseGlobalConfig.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

var request = require('request');
var Parse = require('parse/node').Parse;
var DatabaseAdapter = require('../src/DatabaseAdapter');

let database = DatabaseAdapter.getDatabaseConnection('test', 'test_');
let Config = require('../src/Config');

describe('a GlobalConfig', () => {
beforeEach(function(done) {
database.rawCollection('_GlobalConfig')
let config = new Config('test');
config.database.rawCollection('_GlobalConfig')
.then(coll => coll.updateOne({ '_id': 1}, { $set: { params: { companies: ['US', 'DK'] } } }, { upsert: true }))
.then(done());
});
Expand Down Expand Up @@ -61,7 +60,8 @@ describe('a GlobalConfig', () => {
});

it('failed getting config when it is missing', (done) => {
database.rawCollection('_GlobalConfig')
let config = new Config('test');
config.database.rawCollection('_GlobalConfig')
.then(coll => coll.deleteOne({ '_id': 1}, {}, {}))
.then(_ => {
request.get({
Expand Down
7 changes: 6 additions & 1 deletion spec/ParseUser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ describe('Parse.User testing', () => {
success: function(user) {
Parse.User.logIn("non_existent_user", "asdf3",
expectError(Parse.Error.OBJECT_NOT_FOUND, done));
},
error: function(err) {
console.error(err);
fail("Shit should not fail");
done();
}
});
});
Expand Down Expand Up @@ -1704,7 +1709,7 @@ describe('Parse.User testing', () => {
done();
});
});

it('test parse user become', (done) => {
var sessionToken = null;
Parse.Promise.as().then(function() {
Expand Down
86 changes: 86 additions & 0 deletions spec/PublicAPI.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

var request = require('request');

describe("public API", () => {
beforeEach(done => {
setServerConfiguration({
serverURL: 'http://localhost:8378/1',
appId: 'test',
appName: 'unused',
javascriptKey: 'test',
dotNetKey: 'windows',
clientKey: 'client',
restAPIKey: 'rest',
masterKey: 'test',
collectionPrefix: 'test_',
fileKey: 'test',
publicServerURL: 'http://localhost:8378/1'
});
done();
})
it("should get invalid_link.html", (done) => {
request('http://localhost:8378/1/apps/invalid_link.html', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(200);
done();
});
});

it("should get choose_password", (done) => {
request('http://localhost:8378/1/apps/choose_password?id=test', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(200);
done();
});
});

it("should get verify_email_success.html", (done) => {
request('http://localhost:8378/1/apps/verify_email_success.html', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(200);
done();
});
});

it("should get password_reset_success.html", (done) => {
request('http://localhost:8378/1/apps/password_reset_success.html', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(200);
done();
});
});
});

describe("public API without publicServerURL", () => {
beforeEach(done => {
setServerConfiguration({
serverURL: 'http://localhost:8378/1',
appId: 'test',
appName: 'unused',
javascriptKey: 'test',
dotNetKey: 'windows',
clientKey: 'client',
restAPIKey: 'rest',
masterKey: 'test',
collectionPrefix: 'test_',
fileKey: 'test',
});
done();
})
it("should get 404 on verify_email", (done) => {
request('http://localhost:8378/1/apps/test/verify_email', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(404);
done();
});
});

it("should get 404 choose_password", (done) => {
request('http://localhost:8378/1/apps/choose_password?id=test', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(404);
done();
});
});

it("should get 404 on request_password_reset", (done) => {
request('http://localhost:8378/1/apps/test/request_password_reset', (err, httpResponse, body) => {
expect(httpResponse.statusCode).toBe(404);
done();
});
});
});
Loading