Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 39538
1
###
2
Account Creation (and Deletion)
3
###
4
5
async = require('async')
6
7
message = require('smc-util/message')
8
client_lib = require('smc-util/client')
9
misc = require('smc-util/misc')
10
{required, defaults} = misc
11
12
auth = require('./auth')
13
14
exports.is_valid_password = is_valid_password = (password) ->
15
[valid, reason] = client_lib.is_valid_password(password)
16
if not valid
17
return [valid, reason]
18
return [true, '']
19
20
exports.create_account = (opts) ->
21
opts = defaults opts,
22
client : required
23
mesg : required
24
database : required
25
logger : undefined
26
host : undefined
27
port : undefined
28
sign_in : false # if true, the newly created user will also be signed in; only makes sense for browser clients!
29
cb : undefined
30
id = opts.mesg.id
31
account_id = null
32
dbg = (m) -> opts.logger?("create_account (#{opts.mesg.email_address}): #{m}")
33
tm = misc.walltime()
34
if opts.mesg.email_address?
35
opts.mesg.email_address = misc.lower_email_address(opts.mesg.email_address)
36
37
if not opts.mesg.first_name? or not opts.mesg.last_name?
38
opts.cb?("first and last name must be defined")
39
return
40
async.series([
41
(cb) ->
42
dbg("run tests on generic validity of input")
43
# issues_with_create_account also does check is_valid_password!
44
issues = client_lib.issues_with_create_account(opts.mesg)
45
46
# TODO -- only uncomment this for easy testing to allow any password choice.
47
# the client test suite will then fail, which is good, so we are reminded to comment this out before release!
48
# delete issues['password']
49
50
if misc.len(issues) > 0
51
cb(issues)
52
else
53
cb()
54
55
(cb) ->
56
# Make sure this ip address hasn't requested too many accounts recently,
57
# just to avoid really nasty abuse, but still allow for demo registration
58
# behind a single router.
59
dbg("make sure not too many accounts were created from the given ip")
60
opts.database.count_accounts_created_by
61
ip_address : opts.client.ip_address
62
age_s : 60*30
63
cb : (err, n) ->
64
if err
65
cb(other:err)
66
else if n > 150
67
cb(other:"Too many accounts are being created from the ip address #{opts.client.ip_address}; try again later.")
68
else
69
cb()
70
(cb) ->
71
dbg("query database to determine whether the email address is available")
72
opts.database.account_exists
73
email_address : opts.mesg.email_address
74
cb : (error, not_available) ->
75
if error
76
cb(other:"Unable to create account. Please try later. -- #{misc.to_json(error)}")
77
else if not_available
78
cb(email_address:"This e-mail address is already taken.")
79
else
80
cb()
81
82
(cb) ->
83
dbg("check that account is not banned")
84
opts.database.is_banned_user
85
email_address : opts.mesg.email_address
86
cb : (err, is_banned) ->
87
if err
88
cb(other:"Unable to create account. Please try later.")
89
else if is_banned
90
cb(email_address:"This e-mail address is banned.")
91
else
92
cb()
93
(cb) ->
94
dbg("check if a registration token is required")
95
opts.database.get_server_setting
96
name : 'account_creation_token'
97
cb : (err, token) =>
98
if not token
99
cb()
100
else
101
if token != opts.mesg.token
102
cb(token:"Incorrect registration token.")
103
else
104
cb()
105
(cb) ->
106
dbg("create new account")
107
opts.database.create_account
108
first_name : opts.mesg.first_name
109
last_name : opts.mesg.last_name
110
email_address : opts.mesg.email_address
111
password_hash : auth.password_hash(opts.mesg.password)
112
created_by : opts.client.ip_address
113
cb: (error, result) ->
114
if error
115
cb(other:"Unable to create account right now. Please try later.")
116
else
117
account_id = result
118
cb()
119
# log to db -- no need to make client wait for this:
120
opts.database.log
121
event : 'create_account'
122
value :
123
account_id : account_id
124
first_name : opts.mesg.first_name
125
last_name : opts.mesg.last_name
126
email_address : opts.mesg.email_address
127
created_by : opts.client.ip_address
128
(cb) ->
129
dbg("check for account creation actions")
130
opts.database.do_account_creation_actions
131
email_address : opts.mesg.email_address
132
account_id : account_id
133
cb : cb
134
(cb) ->
135
if not opts.sign_in
136
cb(); return
137
dbg("set remember_me cookie...")
138
# so that proxy server will allow user to connect and
139
# download images, etc., the very first time right after they make a new account.
140
opts.client.remember_me
141
email_address : opts.mesg.email_address
142
account_id : account_id
143
cb : cb
144
(cb) ->
145
if not opts.sign_in
146
cb(); return
147
dbg("send message back to user that they are logged in as the new user (in #{misc.walltime(tm)}seconds)")
148
mesg1 = message.signed_in
149
id : opts.mesg.id
150
account_id : account_id
151
email_address : opts.mesg.email_address
152
first_name : opts.mesg.first_name
153
last_name : opts.mesg.last_name
154
remember_me : false
155
hub : opts.host + ':' + opts.port
156
opts.client.signed_in(mesg1)
157
opts.client.push_to_client(mesg1)
158
cb()
159
], (reason) ->
160
if reason
161
dbg("send message to user that there was an error (in #{misc.walltime(tm)}seconds) -- #{misc.to_json(reason)}")
162
opts.client.push_to_client(message.account_creation_failed(id:id, reason:reason))
163
cb?("error creating account -- #{misc.to_json(reason)}")
164
else
165
opts.client.push_to_client(message.account_created(id:id, account_id:account_id))
166
cb?()
167
)
168
169
exports.delete_account = (opts) ->
170
opts = defaults opts,
171
client : undefined
172
mesg : required
173
database : required
174
logger : undefined
175
cb : undefined
176
177
opts.logger?("delete_account(opts.mesg.account_id)")
178
179
opts.database.mark_account_deleted
180
account_id : opts.mesg.account_id
181
cb : (err) =>
182
opts.client?.push_to_client(message.account_deleted(id:opts.mesg.id, error:err))
183
opts.cb?(err)
184
185