Convert registration to async
This commit is contained in:
parent
8b89ebcccb
commit
7ef5da08d0
@ -32,11 +32,22 @@ final class SQLiteDatabase {
|
|||||||
self.mailConfiguration = mail
|
self.mailConfiguration = mail
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerPlayer(named name: PlayerName, hash: PasswordHash, in database: Database) -> EventLoopFuture<SessionToken> {
|
func registerPlayer(named name: PlayerName, hash: PasswordHash, email: String?, in database: Database) async throws -> SessionToken {
|
||||||
User.query(on: database).filter(\.$name == name).first()
|
if let email {
|
||||||
.guard({ $0 == nil }, else: Abort(.conflict)).flatMap { _ in
|
let user = try await User
|
||||||
let user = User(name: name, hash: hash)
|
.query(on: database)
|
||||||
return user.create(on: database).map {
|
.filter(\.$recoveryEmail == email)
|
||||||
|
.first()
|
||||||
|
if user != nil {
|
||||||
|
throw Abort(.conflict)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if try await User.query(on: database).filter(\.$name == name).first() != nil {
|
||||||
|
throw Abort(.conflict)
|
||||||
|
}
|
||||||
|
let user = User(name: name, hash: hash, email: email)
|
||||||
|
try await user.create(on: database)
|
||||||
|
|
||||||
// Create a new token and store it for the user
|
// Create a new token and store it for the user
|
||||||
let token = SessionToken.newToken()
|
let token = SessionToken.newToken()
|
||||||
self.sessionTokenForPlayer[name] = token
|
self.sessionTokenForPlayer[name] = token
|
||||||
@ -44,7 +55,6 @@ final class SQLiteDatabase {
|
|||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private func sendEmail(name: PlayerName, email: String, token: String) {
|
private func sendEmail(name: PlayerName, email: String, token: String) {
|
||||||
let recipient = Mail.User(name: name, email: email)
|
let recipient = Mail.User(name: name, email: email)
|
||||||
|
@ -63,11 +63,12 @@ final class User: Model {
|
|||||||
init() { }
|
init() { }
|
||||||
|
|
||||||
/// Creates a new user.
|
/// Creates a new user.
|
||||||
init(id: UUID? = nil, name: String, hash: String) {
|
init(id: UUID? = nil, name: String, hash: String, email: String? = nil) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.passwordHash = hash
|
self.passwordHash = hash
|
||||||
self.points = 0
|
self.points = 0
|
||||||
|
self.recoveryEmail = email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,20 +50,18 @@ func routes(_ app: Application) throws {
|
|||||||
- `424`: The password could not be hashed
|
- `424`: The password could not be hashed
|
||||||
*/
|
*/
|
||||||
func registerPlayer(_ app: Application) {
|
func registerPlayer(_ app: Application) {
|
||||||
app.post("player", "register") { req -> EventLoopFuture<SessionToken> in
|
app.post("player", "register") { request async throws -> SessionToken in
|
||||||
let name = try req.header(.name)
|
let name = try request.header(.name)
|
||||||
let password = try req.header(.password)
|
let hash = try request.hashedPassword() // errors: 400, 424
|
||||||
let mail = req.optionalHeader(.email)?.trimmed.nonEmpty
|
let mail = request.optionalHeader(.email)?.trimmed.nonEmpty
|
||||||
|
|
||||||
guard name.count < maximumPlayerNameLength,
|
guard name.count < maximumPlayerNameLength else {
|
||||||
password.count < maximumPasswordLength else {
|
|
||||||
throw Abort(.notAcceptable) // 406
|
throw Abort(.notAcceptable) // 406
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash = try req.hashedPassword() // errors: 400, 424
|
|
||||||
|
|
||||||
// Can throw conflict (409)
|
// Can throw conflict (409)
|
||||||
return server.registerPlayer(named: name, hash: hash, in: req.db)
|
// if either the player exists, or the email is already in use
|
||||||
|
return try await server.registerPlayer(named: name, hash: hash, email: mail, in: request.db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user