summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-08-24 03:48:17 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-08-24 04:51:24 -0400
commit4eb63b8adda4559df3dadcf721e2bb0d1f65a01f (patch)
tree4fc62e30770ec84be431a5dabc2aead3eaad88f9
parent1a0ee4af6538b5486d35730d480d00ca4d9edafb (diff)
Stop returning body data from `POST /api/auth/login`.
As with `/api/setup`, the response was an ad-hoc choice, which we are not using and which constrains future development just by existing.
-rw-r--r--docs/api/authentication.md26
-rw-r--r--src/invite/handlers/accept/test.rs7
-rw-r--r--src/setup/handlers/setup/test.rs7
-rw-r--r--src/test/fixtures/cookie.rs4
-rw-r--r--src/token/app.rs16
-rw-r--r--src/user/handlers/login/mod.rs8
-rw-r--r--src/user/handlers/login/test.rs7
-rw-r--r--src/user/handlers/password/test.rs7
8 files changed, 38 insertions, 44 deletions
diff --git a/docs/api/authentication.md b/docs/api/authentication.md
index fbd5959..7694609 100644
--- a/docs/api/authentication.md
+++ b/docs/api/authentication.md
@@ -71,32 +71,15 @@ The request must have the following fields:
<!-- This prose is duplicated by 03-initial-setup.md and in 04-invitations.md, with small changes for context. If you edit it here, edit it there, too. -->
-This endpoint will respond with a status of
-`200 Okay` when successful. The body of the response will be a JSON object describing the authenticated user:
-
-```json
-{
- "id": "Uabcd1234",
- "name": "Andrea"
-}
-```
-
-The response will include the following fields:
-
-| Field | Type | Description |
-| :----- | :----- | :----------------------------- |
-| `id` | string | The authenticated user's ID. |
-| `name` | string | The authenticated user's name. |
+This endpoint will respond with a status of `204 No Content` when successful.
-The response will include a `Set-Cookie` header for the
-`identity` cookie, providing the client with a newly-minted identity token associated with the user identified in the request. This token's value must be kept confidential.
+The response will include a `Set-Cookie` header for the `identity` cookie, providing the client with a newly-minted identity token associated with the user identified in the request. This token's value must be kept confidential.
The cookie will expire if it is not used regularly.
### Authentication failure
-This endpoint will respond with a status of
-`401 Unauthorized` if the login name and password do not correspond to an existing user.
+This endpoint will respond with a status of `401 Unauthorized` if the login name and password do not correspond to an existing user.
## `POST /api/auth/logout`
@@ -114,8 +97,7 @@ The request must be an empty JSON object.
This endpoint will respond with a status of `204 No Content` when successful.
-The response will include a `Set-Cookie` header that clears the
-`identity` cookie. Regardless of whether the client clears the cookie, the service also invalidates the token.
+The response will include a `Set-Cookie` header that clears the `identity` cookie. Regardless of whether the client clears the cookie, the service also invalidates the token.
## `POST /api/password`
diff --git a/src/invite/handlers/accept/test.rs b/src/invite/handlers/accept/test.rs
index cb13900..7139985 100644
--- a/src/invite/handlers/accept/test.rs
+++ b/src/invite/handlers/accept/test.rs
@@ -47,11 +47,16 @@ async fn valid_invite() {
// Verify that the given credentials can log in
- let (login, _) = app
+ let secret = app
.tokens()
.login(&name, &password, &fixtures::now())
.await
.expect("credentials given on signup are valid");
+ let (_, login) = app
+ .tokens()
+ .validate(&secret, &fixtures::now())
+ .await
+ .expect("validating a newly-issued token secret succeeds");
assert_eq!(response, login);
}
diff --git a/src/setup/handlers/setup/test.rs b/src/setup/handlers/setup/test.rs
index 69e44c2..4a37690 100644
--- a/src/setup/handlers/setup/test.rs
+++ b/src/setup/handlers/setup/test.rs
@@ -34,11 +34,16 @@ async fn fresh_instance() {
// Verify that the given credentials can log in
- let (login, _) = app
+ let secret = app
.tokens()
.login(&name, &password, &fixtures::now())
.await
.expect("credentials given on signup are valid");
+ let (_, login) = app
+ .tokens()
+ .validate(&secret, &fixtures::now())
+ .await
+ .expect("validating a newly-issued token secret succeeds");
assert_eq!(name, login.name);
}
diff --git a/src/test/fixtures/cookie.rs b/src/test/fixtures/cookie.rs
index 41779db..f5a32a6 100644
--- a/src/test/fixtures/cookie.rs
+++ b/src/test/fixtures/cookie.rs
@@ -18,13 +18,13 @@ pub async fn logged_in(
now: &RequestedAt,
) -> IdentityCookie {
let (name, password) = credentials;
- let (_, token) = app
+ let secret = app
.tokens()
.login(name, password, now)
.await
.expect("should succeed given known-valid credentials");
- IdentityCookie::new().set(token)
+ IdentityCookie::new().set(secret)
}
pub fn secret(identity: &IdentityCookie) -> Secret {
diff --git a/src/token/app.rs b/src/token/app.rs
index 49f9a45..7d70534 100644
--- a/src/token/app.rs
+++ b/src/token/app.rs
@@ -32,7 +32,7 @@ impl<'a> Tokens<'a> {
name: &Name,
password: &Password,
login_at: &DateTime,
- ) -> Result<(User, Secret), LoginError> {
+ ) -> Result<Secret, LoginError> {
let mut tx = self.db.begin().await?;
let (user, stored_hash) = tx
.auth()
@@ -47,18 +47,16 @@ impl<'a> Tokens<'a> {
// if the account is deleted during that time.
tx.commit().await?;
- let snapshot = user.as_snapshot().ok_or(LoginError::Rejected)?;
+ user.as_snapshot().ok_or(LoginError::Rejected)?;
- let token = if stored_hash.verify(password)? {
+ if stored_hash.verify(password)? {
let mut tx = self.db.begin().await?;
- let token = tx.tokens().issue(&user, login_at).await?;
+ let secret = tx.tokens().issue(&user, login_at).await?;
tx.commit().await?;
- token
+ Ok(secret)
} else {
- Err(LoginError::Rejected)?
- };
-
- Ok((snapshot, token))
+ Err(LoginError::Rejected)
+ }
}
pub async fn change_password(
diff --git a/src/user/handlers/login/mod.rs b/src/user/handlers/login/mod.rs
index da88885..d3e0e8c 100644
--- a/src/user/handlers/login/mod.rs
+++ b/src/user/handlers/login/mod.rs
@@ -7,11 +7,11 @@ use axum::{
use crate::{
app::App,
clock::RequestedAt,
+ empty::Empty,
error::Internal,
name::Name,
password::Password,
token::{app, extract::IdentityCookie},
- user::User,
};
#[cfg(test)]
@@ -22,14 +22,14 @@ pub async fn handler(
RequestedAt(now): RequestedAt,
identity: IdentityCookie,
Json(request): Json<Request>,
-) -> Result<(IdentityCookie, Json<User>), Error> {
- let (user, secret) = app
+) -> Result<(IdentityCookie, Empty), Error> {
+ let secret = app
.tokens()
.login(&request.name, &request.password, &now)
.await
.map_err(Error)?;
let identity = identity.set(secret);
- Ok((identity, Json(user)))
+ Ok((identity, Empty))
}
#[derive(serde::Deserialize)]
diff --git a/src/user/handlers/login/test.rs b/src/user/handlers/login/test.rs
index b8f24f6..bdd1957 100644
--- a/src/user/handlers/login/test.rs
+++ b/src/user/handlers/login/test.rs
@@ -1,6 +1,6 @@
use axum::extract::{Json, State};
-use crate::{test::fixtures, token::app};
+use crate::{empty::Empty, test::fixtures, token::app};
#[tokio::test]
async fn correct_credentials() {
@@ -17,14 +17,13 @@ async fn correct_credentials() {
name: name.clone(),
password,
};
- let (identity, Json(response)) =
+ let (identity, Empty) =
super::handler(State(app.clone()), logged_in_at, identity, Json(request))
.await
.expect("logged in with valid credentials");
// Verify the return value's basic structure
- assert_eq!(name, response.name);
let secret = identity
.secret()
.expect("logged in with valid credentials issues an identity cookie");
@@ -38,7 +37,7 @@ async fn correct_credentials() {
.await
.expect("identity secret is valid");
- assert_eq!(response, validated_login);
+ assert_eq!(name, validated_login.name);
}
#[tokio::test]
diff --git a/src/user/handlers/password/test.rs b/src/user/handlers/password/test.rs
index 42e41d8..278d27b 100644
--- a/src/user/handlers/password/test.rs
+++ b/src/user/handlers/password/test.rs
@@ -58,10 +58,15 @@ async fn password_change() {
assert!(matches!(login_err, LoginError::Rejected));
// Verify that our new password is valid
- let (login, _) = app
+ let secret = app
.tokens()
.login(&name, &to, &fixtures::now())
.await
.expect("logging in with the new password should succeed");
+ let (_, login) = app
+ .tokens()
+ .validate(&secret, &fixtures::now())
+ .await
+ .expect("validating a newly-issued token secret succeeds");
assert_eq!(identity.user, login);
}