-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathuser.js
61 lines (54 loc) · 2.05 KB
/
user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
exports.createUser = createUser
exports.authUser = authUser
exports.checkSignedLogin = checkSignedLogin
var forum = require('./')
, pwhash = require('password-hash')
, crypto = require('crypto')
, config = forum.config
var USERNAME = /^\w+$/
function createUser(name, password, doc, cb) {
if (!USERNAME.test(name)) return cb(new Error('invalid username (allowed: '+USERNAME+')'))
if (password.length < 5) return cb(new Error("I don't want to force you to use a super-long password, but "+password.length+" chars is way too short"))
var docname = 'user:'+name
doc.name = name
doc.password = pwhash.generate(password, {algorithm: 'sha512'})
forum.db.store(docname, doc, function(err) {
if (err) return cb(err)
var loginProof = sign('validloginas:'+name)
cb(null, {proof: loginProof})
})
}
function authUser(name, password, _, cb) {
if (!USERNAME.test(name)) return cb(new Error('invalid username (allowed: '+USERNAME+')'))
var docname = 'user:'+name
forum.db.get(docname, function(err, doc) {
if (err && err.error === 'not_found') return cb(new Error("That username doesn't exist. Maybe you want to register a new account?"))
if (err) return cb(err)
if (!pwhash.verify(password, doc.password)) return cb(new Error('wrong password'))
var loginProof = sign('validloginas:'+name)
cb(null, {doc: doc, proof: loginProof})
})
}
function sign(str) {
if (!config.hmacSecret) throw new Error('hmac secret undefined')
var algo = crypto.createHmac('sha512', config.hmacSecret)
algo.update(str)
return algo.digest('hex')+':'+str
}
function unsign(str) {
if (!config.hmacSecret) throw new Error('hmac secret undefined')
str = str.split(':')
var signature = str[0]
str = str.slice(1).join(':')
var algo = crypto.createHmac('sha512', config.hmacSecret)
algo.update(str)
return (algo.digest('hex') === signature) ? str : null
}
function checkSignedLogin(str) {
str = unsign(str)
if (str == null) return null
str = str.split(':')
if (str[0] !== 'validloginas') return null
str = str.slice(1).join(':')
return str
}