Skip to content

Commit d7b1184

Browse files
committed
Merge pull request #627 from flovilmart/mail-adapter
Email Validation
2 parents d9f1e00 + 28d1a8a commit d7b1184

34 files changed

+1931
-163
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"commander": "^2.9.0",
2727
"deepcopy": "^0.6.1",
2828
"express": "^4.13.4",
29+
"mailgun-js": "^0.7.7",
2930
"mime": "^1.3.4",
3031
"mongodb": "~2.1.0",
3132
"multer": "^1.1.0",

public_html/invalid_link.html

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!DOCTYPE html>
2+
<!-- This page is displayed when someone navigates to a verify email or reset password link
3+
but their security token is wrong. This can either mean the user has clicked on a
4+
stale link (i.e. re-click on a password reset link after resetting their password) or
5+
(rarely) this could be a sign of a malicious user trying to tamper with your app.
6+
-->
7+
<html>
8+
<head>
9+
<title>Invalid Link</title>
10+
<style type='text/css'>
11+
.container {
12+
border-width: 0px;
13+
display: block;
14+
font: inherit;
15+
font-family: 'Helvetica Neue', Helvetica;
16+
font-size: 16px;
17+
height: 30px;
18+
line-height: 16px;
19+
margin: 45px 0px 0px 45px;
20+
padding: 0px 8px 0px 8px;
21+
position: relative;
22+
vertical-align: baseline;
23+
}
24+
25+
h1, h2, h3, h4, h5 {
26+
color: #0067AB;
27+
display: block;
28+
font: inherit;
29+
font-family: 'Open Sans', 'Helvetica Neue', Helvetica;
30+
font-size: 30px;
31+
font-weight: 600;
32+
height: 30px;
33+
line-height: 30px;
34+
margin: 0 0 15px 0;
35+
padding: 0 0 0 0;
36+
}
37+
</style>
38+
<body>
39+
<div class="container">
40+
<h1>Invalid Link</h1>
41+
</div>
42+
</body>
43+
</html>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<!-- This page is displayed whenever someone has successfully reset their password.
4+
Pro and Enterprise accounts may edit this page and tell Parse to use that custom
5+
version in their Parse app. See the App Settigns page for more information.
6+
This page will be called with the query param 'username'
7+
-->
8+
<head>
9+
<title>Password Reset</title>
10+
<style type='text/css'>
11+
h1 {
12+
color: #0067AB;
13+
display: block;
14+
font: inherit;
15+
font-family: 'Open Sans', 'Helvetica Neue', Helvetica;
16+
font-size: 30px;
17+
font-weight: 600;
18+
height: 30px;
19+
line-height: 30px;
20+
margin: 45px 0px 0px 45px;
21+
padding: 0px 8px 0px 8px;
22+
}
23+
</style>
24+
<body>
25+
<h1>Successfully updated your password!</h1>
26+
</body>
27+
</html>

public_html/verify_email_success.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<!-- This page is displayed whenever someone has successfully reset their password.
4+
Pro and Enterprise accounts may edit this page and tell Parse to use that custom
5+
version in their Parse app. See the App Settigns page for more information.
6+
This page will be called with the query param 'username'
7+
-->
8+
<head>
9+
<title>Email Verification</title>
10+
<style type='text/css'>
11+
h1 {
12+
color: #0067AB;
13+
display: block;
14+
font: inherit;
15+
font-family: 'Open Sans', 'Helvetica Neue', Helvetica;
16+
font-size: 30px;
17+
font-weight: 600;
18+
height: 30px;
19+
line-height: 30px;
20+
margin: 45px 0px 0px 45px;
21+
padding: 0px 8px 0px 8px;
22+
}
23+
</style>
24+
<body>
25+
<h1>Successfully verified your email!</h1>
26+
</body>
27+
</html>

spec/AdapterLoader.spec.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
var loadAdapter = require("../src/Adapters/AdapterLoader").loadAdapter;
33
var FilesAdapter = require("../src/Adapters/Files/FilesAdapter").default;
44

5-
describe("AdaptableController", ()=>{
5+
describe("AdapterLoader", ()=>{
66

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

1010
var adapter = loadAdapter({
1111
adapter: adapterPath,
12-
key: "value",
13-
foo: "bar"
12+
options: {
13+
key: "value",
14+
foo: "bar"
15+
}
1416
});
1517

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

2628
expect(adapter instanceof Object).toBe(true);
27-
expect(adapter.options).toBe(adapterPath);
2829
done();
2930
});
3031

@@ -65,4 +66,22 @@ describe("AdaptableController", ()=>{
6566
expect(adapter).toBe(originalAdapter);
6667
done();
6768
});
69+
70+
it("should fail loading an improperly configured adapter", (done) => {
71+
var Adapter = function(options) {
72+
if (!options.foo) {
73+
throw "foo is required for that adapter";
74+
}
75+
}
76+
var adapterOptions = {
77+
param: "key",
78+
doSomething: function() {}
79+
};
80+
81+
expect(() => {
82+
var adapter = loadAdapter(adapterOptions, Adapter);
83+
expect(adapter).toEqual(adapterOptions);
84+
}).not.toThrow("foo is required for that adapter");
85+
done();
86+
});
6887
});

spec/MockAdapter.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module.exports = function(options) {
2-
this.options = options;
3-
}
2+
return {
3+
options: options
4+
};
5+
};

spec/MockEmailAdapter.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
sendVerificationEmail: () => Promise.resolve(),
3+
sendPasswordResetEmail: () => Promise.resolve(),
4+
sendMail: () => Promise.resolve()
5+
}

spec/MockEmailAdapterWithOptions.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = options => {
2+
if (!options) {
3+
throw "Options were not provided"
4+
}
5+
return {
6+
sendVerificationEmail: () => Promise.resolve(),
7+
sendPasswordResetEmail: () => Promise.resolve(),
8+
sendMail: () => Promise.resolve()
9+
}
10+
}

spec/OneSignalPushAdapter.spec.js

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11

22
var OneSignalPushAdapter = require('../src/Adapters/Push/OneSignalPushAdapter');
33
var classifyInstallations = require('../src/Adapters/Push/PushAdapterUtils').classifyInstallations;
4+
5+
// Make mock config
6+
var pushConfig = {
7+
oneSignalAppId:"APP ID",
8+
oneSignalApiKey:"API KEY"
9+
};
10+
411
describe('OneSignalPushAdapter', () => {
512
it('can be initialized', (done) => {
6-
// Make mock config
7-
var pushConfig = {
8-
oneSignalAppId:"APP ID",
9-
oneSignalApiKey:"API KEY"
10-
};
1113

1214
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
1315

@@ -17,9 +19,17 @@ describe('OneSignalPushAdapter', () => {
1719
expect(senderMap.android instanceof Function).toBe(true);
1820
done();
1921
});
22+
23+
it('cannot be initialized if options are missing', (done) => {
24+
25+
expect(() => {
26+
new OneSignalPushAdapter();
27+
}).toThrow("Trying to initialize OneSignalPushAdapter without oneSignalAppId or oneSignalApiKey");
28+
done();
29+
});
2030

2131
it('can get valid push types', (done) => {
22-
var oneSignalPushAdapter = new OneSignalPushAdapter();
32+
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
2333

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

5767

5868
it('can send push notifications', (done) => {
59-
var oneSignalPushAdapter = new OneSignalPushAdapter();
69+
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
6070

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

110120
it("can send iOS notifications", (done) => {
111-
var oneSignalPushAdapter = new OneSignalPushAdapter();
121+
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
112122
var sendToOneSignal = jasmine.createSpy('sendToOneSignal');
113123
oneSignalPushAdapter.sendToOneSignal = sendToOneSignal;
114124

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

137147
it("can send Android notifications", (done) => {
138-
var oneSignalPushAdapter = new OneSignalPushAdapter();
148+
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
139149
var sendToOneSignal = jasmine.createSpy('sendToOneSignal');
140150
oneSignalPushAdapter.sendToOneSignal = sendToOneSignal;
141151

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

159169
it("can post the correct data", (done) => {
160-
var pushConfig = {
161-
oneSignalAppId:"APP ID",
162-
oneSignalApiKey:"API KEY"
163-
};
170+
164171
var oneSignalPushAdapter = new OneSignalPushAdapter(pushConfig);
165172

166173
var write = jasmine.createSpy('write');

spec/ParseGlobalConfig.spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22

33
var request = require('request');
44
var Parse = require('parse/node').Parse;
5-
var DatabaseAdapter = require('../src/DatabaseAdapter');
6-
7-
let database = DatabaseAdapter.getDatabaseConnection('test', 'test_');
5+
let Config = require('../src/Config');
86

97
describe('a GlobalConfig', () => {
108
beforeEach(function(done) {
11-
database.rawCollection('_GlobalConfig')
9+
let config = new Config('test');
10+
config.database.rawCollection('_GlobalConfig')
1211
.then(coll => coll.updateOne({ '_id': 1}, { $set: { params: { companies: ['US', 'DK'] } } }, { upsert: true }))
1312
.then(done());
1413
});
@@ -61,7 +60,8 @@ describe('a GlobalConfig', () => {
6160
});
6261

6362
it('failed getting config when it is missing', (done) => {
64-
database.rawCollection('_GlobalConfig')
63+
let config = new Config('test');
64+
config.database.rawCollection('_GlobalConfig')
6565
.then(coll => coll.deleteOne({ '_id': 1}, {}, {}))
6666
.then(_ => {
6767
request.get({

0 commit comments

Comments
 (0)