Skip to content

Commit b9d60aa

Browse files
authored
Merge pull request #818 from fourcube/fix/issue-810-validate-usernames
Validate usernames before creating accounts.
2 parents c7ee4aa + 958d2e0 commit b9d60aa

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lib/requests/create-account-request.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class CreateAccountRequest extends AuthRequest {
124124
let accountManager = this.accountManager
125125

126126
return Promise.resolve(userAccount)
127+
.then(this.cancelIfUsernameInvalid.bind(this))
127128
.then(this.cancelIfAccountExists.bind(this))
128129
.then(this.createAccountStorage.bind(this))
129130
.then(this.saveCredentialsFor.bind(this))
@@ -186,6 +187,26 @@ class CreateAccountRequest extends AuthRequest {
186187
return userAccount
187188
})
188189
}
190+
191+
/**
192+
* Check if a username is a valid slug.
193+
*
194+
* @param userAccount {UserAccount} Instance of the account to be created
195+
*
196+
* @throws {Error} If errors were encountering while validating the
197+
* username.
198+
*
199+
* @return {Promise<UserAccount>} Chainable
200+
*/
201+
cancelIfUsernameInvalid (userAccount) {
202+
if (!userAccount.username || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(userAccount.username)) {
203+
const error = new Error('Invalid username')
204+
error.status = 400
205+
throw error
206+
}
207+
208+
return userAccount
209+
}
189210
}
190211

191212
/**

test/unit/create-account-request-test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,48 @@ describe('CreateAccountRequest', () => {
8484
done()
8585
})
8686
})
87+
88+
it('should return a 400 error if a username is invalid', () => {
89+
let accountManager = AccountManager.from({ host })
90+
let locals = { authMethod: defaults.auth, accountManager, oidc: { users: {} } }
91+
92+
accountManager.accountExists = sinon.stub().returns(Promise.resolve(false))
93+
94+
const invalidUsernames = [
95+
'-',
96+
'-a',
97+
'a-',
98+
'9-',
99+
'alice--bob',
100+
'alice bob'
101+
]
102+
103+
let invalidUsernamesCount = 0
104+
105+
const requests = invalidUsernames.map((username) => {
106+
let aliceData = {
107+
username: username, password: '1234'
108+
}
109+
110+
let req = HttpMocks.createRequest({ app: { locals }, body: aliceData })
111+
let request = CreateAccountRequest.fromParams(req, res)
112+
113+
return request.createAccount()
114+
.then(() => {
115+
throw new Error('should not happen')
116+
})
117+
.catch(err => {
118+
invalidUsernamesCount++
119+
expect(err.message).to.match(/Invalid username/)
120+
expect(err.status).to.equal(400)
121+
})
122+
})
123+
124+
return Promise.all(requests)
125+
.then(() => {
126+
expect(invalidUsernamesCount).to.eq(invalidUsernames.length)
127+
})
128+
})
87129
})
88130
})
89131

0 commit comments

Comments
 (0)