Better random (#213)

* randomString: generate a securely random string.

Also, support lengths > 12 in case that's ever needed.

This is used in at least one case (creating device tokens for users)
where it seems important that the output is unpredictable.

* Try harder to create unique usernames.

The previous version added 16 bits of entropy to the username, which
isn't all that much. Due to the birthday paradox, it would be enough to
create ~256 users with the same prefix to get a collision.

Trying that would probably fail later on, and not create security
issues... but it just seems better to be on the safe side here.
This commit is contained in:
Jonas Wagner 2022-05-15 22:13:07 +02:00 committed by GitHub
parent c85b806bc1
commit c9f3644988
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 6 deletions

View File

@ -1,7 +1,11 @@
export const randomString = (length = 12) =>
Math.random()
.toString(16)
.substring(2, length + 2)
// Returns a cryptographically random hexadecimal string of length `length`
// (thus containing 4*`length` bits of entropy).
export const randomString = (length = 12) => {
const bytes = new Uint8Array(Math.ceil(length / 2))
crypto.getRandomValues(bytes)
const hex = bytes.reduce((s, b) => s + ('0' + b.toString(16)).slice(-2), '')
return hex.substring(0, length)
}
export function genHash(str: string) {
// xmur3

View File

@ -42,8 +42,7 @@ export const createUser = functions
const name = cleanDisplayName(rawName)
let username = cleanUsername(name)
const sameNameUser = await getUserByUsername(username)
if (sameNameUser) {
while (await getUserByUsername(username)) {
username += randomString(4)
}