4
4
*/
5
5
6
6
const Boom = require ( '@hapi/boom' ) ;
7
+ const RE2 = require ( 're2' ) ;
8
+ const bytes = require ( '@forwardemail/bytes' ) ;
7
9
const isSANB = require ( 'is-string-and-not-blank' ) ;
8
10
const paginate = require ( 'koa-ctx-paginate' ) ;
9
11
const parser = require ( 'mongodb-query-parser' ) ;
@@ -13,6 +15,8 @@ const _ = require('#helpers/lodash');
13
15
const { Users } = require ( '#models' ) ;
14
16
const config = require ( '#config' ) ;
15
17
18
+ const REGEX_BYTES = new RE2 ( / ^ ( ( - | \+ ) ? ( \d + (?: \. \d + ) ? ) ) * ( k b | m b | g b | t b | p b ) $ / i) ;
19
+
16
20
const USER_SEARCH_PATHS = [
17
21
'email' ,
18
22
config . passport . fields . givenName ,
@@ -91,18 +95,54 @@ async function update(ctx) {
91
95
if ( ! user ) throw Boom . notFound ( ctx . translateError ( 'INVALID_USER' ) ) ;
92
96
const { body } = ctx . request ;
93
97
94
- user [ config . passport . fields . givenName ] =
95
- body [ config . passport . fields . givenName ] ;
96
- user [ config . passport . fields . familyName ] =
97
- body [ config . passport . fields . familyName ] ;
98
- user [ config . passport . fields . otpEnabled ] =
99
- body [ config . passport . fields . otpEnabled ] ;
100
- user . email = body . email ;
101
- user . group = body . group ;
98
+ if ( body [ config . passport . fields . givenName ] )
99
+ user [ config . passport . fields . givenName ] =
100
+ body [ config . passport . fields . givenName ] ;
101
+
102
+ if ( body [ config . passport . fields . familyName ] )
103
+ user [ config . passport . fields . familyName ] =
104
+ body [ config . passport . fields . familyName ] ;
105
+
106
+ if ( body [ config . passport . fields . otpEnabled ] )
107
+ user [ config . passport . fields . otpEnabled ] =
108
+ body [ config . passport . fields . otpEnabled ] ;
102
109
103
110
if ( boolean ( ! body [ config . passport . fields . otpEnabled ] ) )
104
111
user [ config . userFields . pendingRecovery ] = false ;
105
112
113
+ if ( body . email ) user . email = body . email ;
114
+
115
+ if ( body . group ) user . group = body . group ;
116
+
117
+ if ( isSANB ( body . has_passed_kyc ) )
118
+ user . has_passed_kyc = boolean ( body . has_passed_kyc ) ;
119
+
120
+ if ( body . max_quota_per_alias_per_alias ) {
121
+ // validate `body.max_quota_per_alias_per_alias` if a value was passed
122
+ if (
123
+ typeof body . max_quota_per_alias_per_alias !== 'undefined' &&
124
+ typeof body . max_quota_per_alias_per_alias !== 'string'
125
+ )
126
+ throw Boom . badRequest ( ctx . translateError ( 'INVALID_BYTES' ) ) ;
127
+
128
+ // indicates reset of the value
129
+ if ( body . max_quota_per_alias === '' ) {
130
+ body . max_quota_per_alias = Number . isFinite (
131
+ ctx . state . domain . max_quota_per_alias
132
+ )
133
+ ? ctx . state . domain . max_quota_per_alias
134
+ : config . maxQuotaPerAlias ;
135
+ } else if ( typeof body . max_quota_per_alias === 'string' ) {
136
+ // test against bytes regex
137
+ if ( ! REGEX_BYTES . test ( body . max_quota_per_alias ) )
138
+ throw Boom . badRequest ( ctx . translateError ( 'INVALID_BYTES' ) ) ;
139
+ // otherwise convert the value
140
+ body . max_quota_per_alias = bytes ( body . max_quota_per_alias ) ;
141
+ }
142
+ }
143
+
144
+ if ( body . smtp_limit ) user . smtp_limit = body . smtp_limit ;
145
+
106
146
await user . save ( ) ;
107
147
108
148
if ( user . id === ctx . state . user . id ) await ctx . login ( user ) ;
0 commit comments