Add password reset model
This commit is contained in:
parent
e49cc9cb91
commit
16ab0fd6d3
18
Sources/App/Model/Migrations/PasswordResetMigration.swift
Normal file
18
Sources/App/Model/Migrations/PasswordResetMigration.swift
Normal file
@ -0,0 +1,18 @@
|
||||
import FluentSQLiteDriver
|
||||
|
||||
struct PasswordResetMigration: Migration {
|
||||
|
||||
func prepare(on database: FluentSQLiteDriver.Database) -> EventLoopFuture<Void> {
|
||||
database.schema(PasswordReset.schema)
|
||||
.id()
|
||||
.field(PasswordReset.Key.user.key, .uuid, .required, .references(User.schema, .id))
|
||||
.unique(on: PasswordReset.Key.user.key)
|
||||
.field(PasswordReset.Key.token.key, .string, .required)
|
||||
.field(PasswordReset.Key.expiry.key, .date, .required)
|
||||
.create()
|
||||
}
|
||||
|
||||
func revert(on database: FluentSQLiteDriver.Database) -> EventLoopFuture<Void> {
|
||||
database.schema(PasswordReset.schema).delete()
|
||||
}
|
||||
}
|
60
Sources/App/Model/PasswordReset.swift
Normal file
60
Sources/App/Model/PasswordReset.swift
Normal file
@ -0,0 +1,60 @@
|
||||
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() { }
|
||||
|
||||
/// Creates a new password reset.
|
||||
init(id: UUID? = nil, user: User) {
|
||||
self.id = id
|
||||
self.user = user
|
||||
self.resetToken = .newToken()
|
||||
self.expiryDate = Date().addingTimeInterval(15*60)
|
||||
}
|
||||
}
|
@ -52,6 +52,10 @@ final class User: Model {
|
||||
@OptionalParent(.table)
|
||||
var table: Table?
|
||||
|
||||
/// The optional password reset request associated with this user
|
||||
@OptionalChild(for: \.$user)
|
||||
var resetRequest: PasswordReset?
|
||||
|
||||
init() { }
|
||||
|
||||
/// Creates a new user.
|
||||
|
@ -28,6 +28,7 @@ public func configure(_ app: Application) throws {
|
||||
app.databases.use(.sqlite(.file(dbFile)), as: .sqlite)
|
||||
}
|
||||
app.migrations.add(UserTableMigration())
|
||||
app.migrations.add(PasswordResetMigration())
|
||||
|
||||
try app.autoMigrate().wait()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user