Skip to content

Commit 2f625be

Browse files
committed
[api] [refactor] Email now required + New pricing
* `User.email` is now a required field * Adds registration page for account name * Adds screen for upgrading legacy accounts * Legacy accounts must upgrade * API access will remain * Website access will be locked until register * Adds new pricing plans * Improves test coverage for signups / logins * Addresses: #265, #126
1 parent 562bcb8 commit 2f625be

32 files changed

+1328
-601
lines changed

lib/helpers/numberWithCommas.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function numberWithCommas (x) {
2+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
3+
}
4+
5+
module.exports = numberWithCommas;

lib/resources/servicePlan.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
11
module.exports = {
22
"free": {
33
"hits": 1000,
4-
"concurrency": 2
4+
"concurrency": 2,
5+
"cost": "$0.00"
56
},
67
"premium": {
78
"hits": 10000,
8-
"concurrency": 4
9+
"concurrency": 4,
10+
"stripe_label": 'BASIC_HOSTING_PLAN_10',
11+
"cost": "$10.00"
912
},
10-
"pro": {
13+
"advanced": {
1114
"hits": 50000,
12-
"concurrency": 10
15+
"concurrency": 16,
16+
"stripe_label": 'BASIC_HOSTING_PLAN_20',
17+
"cost": "$25.00"
18+
},
19+
"pro": {
20+
"hits": 100000,
21+
"concurrency": 8,
22+
"stripe_label": 'BASIC_HOSTING_PLAN_50',
23+
"cost": "$50.00"
1324
},
1425
"business": {
1526
"hits": 1000000,
16-
"concurrency": 50
27+
"concurrency": 32,
28+
"stripe_label": 'BASIC_HOSTING_PLAN_100',
29+
"cost": "$200.00"
1730
}
1831
};

lib/resources/user.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ user.property('env', 'object');
1111
user.property('referredBy', 'string');
1212

1313
// user.property('dedicatedSignup', 'object');
14-
user.schema.properties.email.required = false;
14+
user.schema.properties.name.required = false;
15+
user.schema.properties.email.required = true;
1516
user.schema.properties.password.required = false;
1617

1718
user.property('stripeID', 'string');
@@ -54,6 +55,7 @@ user.on('login', function (data) {
5455
name: "api-access-key",
5556
owner: data.name || data.username.toLowerCase()
5657
};
58+
// will only create key if it doesn't already exist
5759
keys.findOne(_query, function(err, key){
5860
if (err) {
5961
_query.id = data.id;
@@ -62,6 +64,12 @@ user.on('login', function (data) {
6264
});
6365
});
6466

67+
// when a user registers an account name
68+
user.on('register', function (data) {
69+
// TODO: create a new subdomain for that user ?
70+
// Remark: Instead of automatically adding subdomains, allow user to register it easily
71+
});
72+
6573
/* not working?
6674
user.after('auth', function (data, next) {
6775
console.log('after auth', data)

lib/server/routeHandlers/loginCallback.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var user = require('../../resources/user');
22
var metric = require('../../resources/metric');
33

4-
module['exports'] = function (req, res) {
4+
module['exports'] = function loginCallback (req, res) {
55

66
var referredBy = req.session.referredBy || "";
77
var redirectTo = req.session.redirectTo || "/services";
@@ -32,6 +32,10 @@ module['exports'] = function (req, res) {
3232
} catch(err) {
3333
// do nothing
3434
}
35+
36+
// what happens if we have a conflicting namespace here between github and hook.io?
37+
// i believe it will result in an error due to req.session.user already existing in hook.io data
38+
// todo: figure out a way for github users to register accounts if their github name is already taken by another user on hook.io
3539
user.create({
3640
name: req.session.user,
3741
email: mail,
@@ -49,7 +53,12 @@ module['exports'] = function (req, res) {
4953
} else {
5054
// assign paid status based on existing user document
5155
req.session.paidStatus = result[0].paidStatus;
56+
req.session.servicePlan = result[0].servicePlan || 'free';
5257
req.session.email = result[0].email;
58+
59+
// shouldn't this be assigned based on the github user name?
60+
61+
// req.session.user = result[0].name;
5362
req.session.hookAccessKey = result[0].hookAccessKey;
5463
user.emit('login', result[0]);
5564
var u = result[0];

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"mschema": "https://github.com/mschema/mschema/tarball/master",
4848
"mschema-forms": "https://github.com/mschema/mschema-forms/tarball/master",
4949
"mschema-rpc": "https://github.com/mschema/mschema-rpc/tarball/master",
50+
"ms": "2.0.0",
5051
"mustache": "^0.8.2",
5152
"nano": "^6.2.0",
5253
"node-slug": "0.0.2",

public/css/base.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,8 @@ label {
119119
margin-bottom: 30px;
120120
}
121121

122-
/* hide for now, too frequently popping up */
123122
.emailReminder {
124-
display: none;
123+
display: block;
125124
}
126125

127126
.emailReminder .content {

public/css/responsive.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ margin-top:0px;
189189

190190
/* small mobile :320px. */
191191
@media (max-width: 767px) {
192-
.container {width:300px}
192+
.container {width:100%}
193193
.header_nav{
194194
display:none;
195195
}

public/style.css

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,8 +2700,13 @@ span.member-role {
27002700

27012701
.button_set_plain {
27022702
text-align: right;
2703+
/*
27032704
margin: 20px 0px 0px;
27042705
padding: 8px 0px;
2706+
*/
2707+
padding: 0px;
2708+
margin: 0px;
2709+
width: 75px;
27052710
border-top: none;
27062711
}
27072712
.button_set_plain p {
@@ -2711,16 +2716,18 @@ span.member-role {
27112716
background: transparent;
27122717
border: 1px solid #d7d7d7;
27132718
color: #868686;
2714-
padding: 7px 18px 5px;
2719+
font-size: 16px;
2720+
/*padding: 7px 18px 5px;*/
27152721
}
27162722
.button_set_plain .newsl_button button span {
2717-
background: transparent;
2723+
/*background: transparent;*/
2724+
background-color: #0F99DE;
27182725
border: 1px solid #d7d7d7;
2719-
color: #868686;
2726+
color: #FFF;
27202727
}
27212728
.button_set_plain .newsl_button button:hover span {
27222729
border-color: #0F99DE;
2723-
background-color: #0F99DE;
2730+
background-color: #000;
27242731
color: #fff;
27252732
}
27262733
.button_set_plain .newsl_button {

scripts/tools/clear-all-billings.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
var config = require('../../config');
2+
3+
var billing = require('../../lib/resources/billing');
4+
var user = require('../../lib/resources/user');
5+
6+
var colors = require('colors');
7+
8+
billing.persist(config.couch);
9+
user.persist(config.couch);
10+
11+
user.findOne({
12+
name: 'bobby'
13+
}, function(err, _u){
14+
if(err) {
15+
throw err;
16+
}
17+
_u.servicePlan = "free";
18+
_u.save(function(err){
19+
if(err) {
20+
throw err;
21+
}
22+
clearBillings();
23+
})
24+
});
25+
26+
function clearBillings () {
27+
billing.find({ owner: 'bobby' }, function(err, results){
28+
29+
// billing.all(function(err, results){
30+
if(err) {
31+
throw err;
32+
}
33+
console.log(results)
34+
function destroy () {
35+
if (results.length === 0) {
36+
process.exit();
37+
}
38+
var result = results.pop();
39+
console.log(result.owner.toLowerCase())
40+
result.destroy(function(err, res){
41+
if (err) {
42+
throw err;
43+
}
44+
destroy();
45+
});
46+
}
47+
destroy();
48+
});
49+
}

0 commit comments

Comments
 (0)