import Foundation import FluentSQLiteDriver import Crypto private extension FieldProperty { convenience init(_ key: PasswordReset.Key) { self.init(key: key.key) } } private extension ParentProperty { convenience init(_ key: PasswordReset.Key) { self.init(key: key.key) } } extension PasswordReset.Key { var key: FieldKey { .init(stringLiteral: rawValue) } } final class PasswordReset: Model { /// The name of the SQLite table static let schema = "reset" enum Key: String { case id = "id" case user = "user" case token = "token" case expiry = "expiry" } /// The unique identifier for the reset request @ID(key: .id) var id: UUID? /// The user associated with the reset request @Parent(.user) var user: User /// The random reset token issued with the email @Field(.token) var resetToken: String /// The time when the reset token expires and can't be used anymore @Field(.expiry) var expiryDate: Date init() { self.resetToken = .newToken() self.expiryDate = Self.currentExpiryDate() } func renew() { self.resetToken = .newToken() self.expiryDate = Self.currentExpiryDate() } /// Creates a new password reset. init(id: UUID? = nil, user: User) { self.id = id self.$user.id = user.id! self.resetToken = .newToken() self.expiryDate = Self.currentExpiryDate() } private static func currentExpiryDate() -> Date { Date().addingTimeInterval(15*60) } }