89 lines
2.2 KiB
Swift
89 lines
2.2 KiB
Swift
import Fluent
|
|
import Foundation
|
|
import Vapor
|
|
|
|
func routes(_ app: Application) throws {
|
|
app.get { req in
|
|
let output = try await req.view.render("login")
|
|
return output
|
|
}
|
|
|
|
app.get("loggedIn") { req -> View in
|
|
guard let user = try await req.currentUser(withProsAndCons: true) else {
|
|
throw Abort(.badRequest)
|
|
}
|
|
return try await req.view.render(
|
|
"loggedIn",
|
|
LoggedInContext(name: user.displayName, prosAndCons: user.prosAndCons)
|
|
)
|
|
}
|
|
|
|
app.get("submitProOrCon") { req in
|
|
let params = try req.query.decode(SubmitProOrCon.self)
|
|
guard let userId = req.userId else {
|
|
throw Abort(.unauthorized)
|
|
}
|
|
try checkForBadWords(in: params.description)
|
|
let proOrCon = ProCon(type: params.type, description: params.description, userId: userId)
|
|
try await proOrCon.save(on: req.db)
|
|
return req.redirect(to: "loggedIn")
|
|
}
|
|
|
|
app.get("login") { req in
|
|
let params = try req.query.decode(LoginParams.self)
|
|
req.logger.info("params: \(params)")
|
|
try checkForBadWords(in: params.displayName)
|
|
let user = User(displayName: params.displayName)
|
|
try await user.save(on: req.db)
|
|
req.session.data["userId"] = user.id?.uuidString
|
|
return req.redirect(to: "loggedIn")
|
|
}
|
|
}
|
|
|
|
private extension Request {
|
|
|
|
var userId: UUID? {
|
|
guard let userIdString = session.data["userId"],
|
|
let userId = UUID(uuidString: userIdString)
|
|
else {
|
|
return nil
|
|
}
|
|
return userId
|
|
}
|
|
|
|
func currentUser(withProsAndCons: Bool) async throws -> User? {
|
|
guard let userId = userId else {
|
|
return nil
|
|
}
|
|
|
|
var query = User.query(on: db).filter(\.$id == userId)
|
|
if withProsAndCons {
|
|
query = query.with(\.$prosAndCons)
|
|
}
|
|
return try await query.first()
|
|
}
|
|
}
|
|
|
|
struct DisplayNameError: Error {}
|
|
|
|
struct LoginParams: Content {
|
|
let displayName: String
|
|
}
|
|
|
|
struct SubmitProOrCon: Content {
|
|
let type: ProCon.ProConType
|
|
let description: String
|
|
}
|
|
|
|
struct LoggedInContext: Encodable {
|
|
let name: String
|
|
let pros: [ProCon]
|
|
let cons: [ProCon]
|
|
|
|
init(name: String, prosAndCons: [ProCon]) {
|
|
self.name = name
|
|
self.cons = prosAndCons.filter { $0.type == .con }
|
|
self.pros = prosAndCons.filter { $0.type == .pro }
|
|
}
|
|
}
|