From f9b58676bb1372d2b4bc5b0e1ba79715e4191fd2 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Mon, 6 Jan 2025 19:28:14 -0500 Subject: [PATCH] feat: Working login form with htmx. --- Resources/Views/index.leaf | 6 ++--- Resources/Views/logged-in.leaf | 10 +++++--- Resources/Views/login.leaf | 24 +++++++---------- Sources/App/Models/User.swift | 2 +- Sources/App/routes.swift | 47 ++++++++++++++++++++++++++-------- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/Resources/Views/index.leaf b/Resources/Views/index.leaf index 8a2c7b0..a15d9dd 100644 --- a/Resources/Views/index.leaf +++ b/Resources/Views/index.leaf @@ -9,10 +9,10 @@

#(title)

-
+ >
diff --git a/Resources/Views/logged-in.leaf b/Resources/Views/logged-in.leaf index 2785db0..0118492 100644 --- a/Resources/Views/logged-in.leaf +++ b/Resources/Views/logged-in.leaf @@ -1,3 +1,7 @@ -
-

We're in!

-
+

We're in!

+ diff --git a/Resources/Views/login.leaf b/Resources/Views/login.leaf index 4b7e7ab..54a6b62 100644 --- a/Resources/Views/login.leaf +++ b/Resources/Views/login.leaf @@ -1,15 +1,9 @@ -
- -
+
+ + +
+ + +
+ +
diff --git a/Sources/App/Models/User.swift b/Sources/App/Models/User.swift index cd87ef3..9eb7b61 100644 --- a/Sources/App/Models/User.swift +++ b/Sources/App/Models/User.swift @@ -80,7 +80,7 @@ extension User { } extension User: ModelAuthenticatable { - static let usernameKey = \User.$email + static let usernameKey = \User.$username static let passwordHashKey = \User.$passwordHash func verify(password: String) throws -> Bool { diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index d1880e1..26db2b9 100644 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -2,32 +2,52 @@ import Fluent import Vapor func routes(_ app: Application) throws { - let redirectMiddleware = User.redirectMiddleware { req in - "login?next=\(req.url.path)" - } - - let protected = app.grouped(User.sessionAuthenticator(), redirectMiddleware, User.guardMiddleware()) - let credentialsProtected = protected.grouped(User.credentialsAuthenticator()) + let redirectMiddleware = User.redirectMiddleware(path: "login") + // let protected = app.grouped(redirectMiddleware) + let credentialsProtected = app.grouped(User.credentialsAuthenticator(), redirectMiddleware) app.get { req async throws in try await req.view.render("index", ["title": "HHE - Purchase Orders"]) } - app.get("login") { req async throws in + app.get("login") { req async throws -> View in req.logger.info("login") return try await req.view.render("login") } - credentialsProtected.post("login") { req async throws -> View in - req.logger.info("login POST") + app.post("logout") { req async throws -> View in + req.auth.logout(User.self) + return try await req.view.render("login") + } + + app.post("login") { req async throws -> View in + let content = try req.content.decode(UserForm.self) + guard let user = try await User.query(on: req.db) + .filter(\.$username == content.username) + .first() + else { + throw Abort(.badRequest, reason: "User not found.") + } + + guard try user.verify(password: content.password) else { + throw Abort(.unauthorized, reason: "Invalid password.") + } + req.auth.login(user) + + req.logger.debug("User: \(user.toDTO())") return try await req.view.render("logged-in") } - credentialsProtected.get("body") { req async throws in - req.logger.info("body") + credentialsProtected.get("home") { req async throws in + req.logger.info("home") return try await req.view.render("logged-in") } + // TODO: Remove. + credentialsProtected.get("logged-in") { _ in + "Hello, logged-in!" + } + // app.get("index") { req async throws -> View in // // } @@ -38,3 +58,8 @@ func routes(_ app: Application) throws { try app.register(collection: ApiController()) } + +struct UserForm: Content { + let username: String + let password: String +}