import Fluent import Vapor struct UserController: RouteCollection { func boot(routes: RoutesBuilder) throws { routes.group("login") { login in login.post(use: query) } routes.group("register") { register in register.post(use: create) } routes.group("unregister") { unregister in unregister.delete(use: delete) } } func query(req: Request) async throws -> HTTPStatus { let record = try await User.query(on: req.db) .filter(\.$username == req.content.get(at: "username") ?? {throw Abort(.badRequest)}()) .first() ?? {throw Abort(.unauthorized)}() let successful = try req.password.verify(req.content.get(at: "password") ?? {throw Abort(.badRequest)}(), created: record.password) if successful { req.session.data["user"] = record.username return .ok } return .unauthorized } func create(req: Request) async throws -> HTTPStatus { guard let username: String = try req.content.get(at: "username") else {throw Abort(.badRequest)} guard let password: String = try req.content.get(at: "password") else {throw Abort(.badRequest)} let hash: String = try req.password.hash(password) let user = User(username: username, password: hash) try await user.save(on: req.db) // auto login after register req.session.data["user"] = username return .ok } // unused, I don't think this needs to exists, but it's here just in case it does func delete(req: Request) async throws -> HTTPStatus { guard let user = try await User.find(req.parameters.get("id"), on: req.db) else { throw Abort(.notFound) } try await user.delete(on: req.db) return .noContent } }