This repository has been archived by the owner on Jan 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
postUser.js
134 lines (123 loc) · 3.54 KB
/
postUser.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
const Nano = require('nano')
const debug = require('debug')('choirless')
const kuuid = require('kuuid')
const sha256 = require('./lib/sha256.js')
let nano = null
let db = null
const userExists = async (email) => {
const query = {
selector: {
email: email
}
}
const result = await db.find(query)
return (result.docs && result.docs.length > 0)
}
// create/edit a user
// Parameters:
// - userId - the id of the user to edit (or blank to create new one)
// - name - name of user
// - password - password of user
// - email - email of user
const postUser = async (opts) => {
// connect to db - reuse connection if present
if (!db) {
nano = Nano(process.env.COUCH_URL)
db = nano.db.use(process.env.COUCH_USERS_DATABASE)
}
// extract parameters
const userId = opts.userId
let doc = {}
// check userType is valid
if (opts.userType && !['regular', 'admin'].includes(opts.userType)) {
return {
body: { ok: false, message: 'invalid userType' },
statusCode: 400,
headers: { 'Content-Type': 'application/json' }
}
}
// is this a request to edit an existing user
if (userId) {
try {
debug('postUser fetch user', userId)
doc = await db.get(userId)
// infer userType if missing
doc.userType = doc.userType ? doc.userType : 'regular'
doc.name = opts.name ? opts.name : doc.name
doc.userType = opts.userType ? opts.userType : doc.userType
// if the email address is being changed, make sure it's not already taken
if (opts.email && opts.email !== doc.email) {
if (await userExists(opts.email)) {
return {
body: { ok: false, message: 'duplicate user' },
statusCode: 409,
headers: { 'Content-Type': 'application/json' }
}
}
}
doc.email = opts.email ? opts.email : doc.email
if (opts.password) {
doc.salt = kuuid.id()
doc.password = sha256(doc.salt + opts.password)
}
doc.verified = !!opts.verified
} catch (e) {
return {
body: { ok: false, message: 'user not found' },
statusCode: 404,
headers: { 'Content-Type': 'application/json' }
}
}
} else {
// new user creation
if (!opts.name || !opts.password || !opts.email) {
return {
body: { ok: false, message: 'missing mandatory parameters name/password/email' },
statusCode: 400,
headers: { 'Content-Type': 'application/json' }
}
}
// first check that user with this email doesn't already exist
if (await userExists(opts.email)) {
return {
body: { ok: false, message: 'duplicate user' },
statusCode: 409,
headers: { 'Content-Type': 'application/json' }
}
}
// create user
const id = kuuid.id()
const salt = kuuid.id()
const now = new Date()
doc = {
_id: id,
type: 'user',
userId: id,
userType: opts.userType ? opts.userType : 'regular',
name: opts.name,
email: opts.email,
salt: salt,
password: sha256(salt + opts.password),
verified: false,
createdOn: now.toISOString()
}
}
// write user to database
let statusCode = 200
let body = null
try {
debug('postUser write user', doc)
const response = await db.insert(doc)
body = { ok: true, userId: response.id }
} catch (e) {
body = { ok: false }
statusCode = 404
}
// return API response
return {
body: body,
statusCode: statusCode,
headers: { 'Content-Type': 'application/json' }
}
}
module.exports = postUser