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
|
self.playerNameForToken[token] = name
|
||||||
return token
|
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) {
|
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)
|
||||||
let url = "\(mailConfiguration.serverDomain)/player/reset?token=\(token)"
|
let url = "\(mailConfiguration.serverDomain)/recovery.html?token=\(token)"
|
||||||
let mail = Mail(
|
let mail = Mail(
|
||||||
from: mailSender,
|
from: mailSender,
|
||||||
to: [recipient],
|
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).
|
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:
|
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.
|
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 {
|
if let error = error {
|
||||||
print("Failed to send recovery email to \(email): \(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)
|
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.
|
Delete a player.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user