Add route to send recovery email
This commit is contained in:
parent
26adcc2868
commit
4e9675c284
@ -54,11 +54,35 @@ final class SQLiteDatabase {
|
||||
self.playerNameForToken[token] = name
|
||||
return token
|
||||
}
|
||||
|
||||
/**
|
||||
Send a password reset email.
|
||||
|
||||
Possible errors:
|
||||
- `404`: Player name or email not found.
|
||||
*/
|
||||
func sendPasswordResetEmailIfPossible(name: PlayerName, in database: Database) async throws {
|
||||
guard let user = try await User.query(on: database).filter(\.$name == name).first() else {
|
||||
throw Abort(.notFound)
|
||||
}
|
||||
guard let email = user.recoveryEmail else {
|
||||
throw Abort(.notFound)
|
||||
}
|
||||
try await user.$resetRequest.load(on: database)
|
||||
if let request = user.resetRequest {
|
||||
request.renew()
|
||||
try await request.save(on: database)
|
||||
self.sendEmail(name: name, email: email, token: request.resetToken)
|
||||
} else {
|
||||
let reset = PasswordReset()
|
||||
try await user.$resetRequest.create(reset, on: database)
|
||||
self.sendEmail(name: name, email: email, token: reset.resetToken)
|
||||
}
|
||||
}
|
||||
|
||||
private func sendEmail(name: PlayerName, email: String, token: String) {
|
||||
let recipient = Mail.User(name: name, email: email)
|
||||
let url = "\(mailConfiguration.serverDomain)/player/reset?token=\(token)"
|
||||
let url = "\(mailConfiguration.serverDomain)/recovery.html?token=\(token)"
|
||||
let mail = Mail(
|
||||
from: mailSender,
|
||||
to: [recipient],
|
||||
@ -70,7 +94,7 @@ final class SQLiteDatabase {
|
||||
a reset of your account password has been requested for the Schafkopf Server at \(mailConfiguration.serverDomain).
|
||||
To choose a new password, click the following link:
|
||||
|
||||
<a href="\(url)">\(url)</a>
|
||||
\(url)
|
||||
|
||||
The link will expire in \(mailConfiguration.tokenExpiryDuration) minutes. If you didn't request the password reset, you don't have to do anything.
|
||||
|
||||
@ -80,7 +104,7 @@ final class SQLiteDatabase {
|
||||
"""
|
||||
)
|
||||
|
||||
self.smtp.send(mail) { (error) in
|
||||
smtp.send(mail) { (error) in
|
||||
if let error = error {
|
||||
print("Failed to send recovery email to \(email): \(error)")
|
||||
}
|
||||
|
@ -64,6 +64,25 @@ func registerPlayer(_ app: Application) {
|
||||
return try await server.registerPlayer(named: name, hash: hash, email: mail, in: request.db)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Request an email to reset the password of a player.
|
||||
|
||||
Headers:
|
||||
- `name`: The player name
|
||||
|
||||
Possible responses:
|
||||
- `200`: Success, email will be sent
|
||||
- `400`: Missing name header
|
||||
- `404`: Player name not found or no email registered
|
||||
*/
|
||||
func requestPlayerPasswordReset(_ app: Application) {
|
||||
app.post("player", "password", "reset") { request async throws -> HTTPResponseStatus in
|
||||
let name = try request.header(.name) // Error: 400
|
||||
try await server.sendPasswordResetEmailIfPossible(name: name, in: request.db)
|
||||
return .ok
|
||||
}
|
||||
}
|
||||
/**
|
||||
Delete a player.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user