57 lines
1.4 KiB
Swift
57 lines
1.4 KiB
Swift
import Dependencies
|
|
import DependenciesMacros
|
|
import Fluent
|
|
import Vapor
|
|
|
|
extension DependencyValues {
|
|
var users: UserDB {
|
|
get { self[UserDB.self] }
|
|
set { self[UserDB.self] = newValue }
|
|
}
|
|
}
|
|
|
|
@DependencyClient
|
|
struct UserDB: Sendable {
|
|
var create: @Sendable (User.Create) async throws -> User.DTO
|
|
var delete: @Sendable (User.IDValue) async throws -> Void
|
|
var fetchAll: @Sendable () async throws -> [User.DTO]
|
|
var login: @Sendable (User) async throws -> UserToken
|
|
}
|
|
|
|
extension UserDB: TestDependencyKey {
|
|
static let testValue: UserDB = Self()
|
|
|
|
static func live(database db: any Database) -> Self {
|
|
self.init(
|
|
create: { model in
|
|
guard model.password == model.confirmPassword else {
|
|
throw Abort(.badRequest, reason: "Passwords did not match.")
|
|
}
|
|
let user = try User(
|
|
username: model.username,
|
|
email: model.email,
|
|
passwordHash: Bcrypt.hash(model.password)
|
|
)
|
|
try await user.save(on: db)
|
|
return user.toDTO()
|
|
|
|
},
|
|
delete: { id in
|
|
guard let user = try await User.find(id, on: db) else {
|
|
throw Abort(.notFound)
|
|
}
|
|
try await user.delete(on: db)
|
|
|
|
},
|
|
fetchAll: {
|
|
try await User.query(on: db).all().map { $0.toDTO() }
|
|
},
|
|
login: { user in
|
|
let token = try user.generateToken()
|
|
try await token.save(on: db)
|
|
return token
|
|
}
|
|
)
|
|
}
|
|
}
|