E-17: fcm_token at most 512 characters (security L-4)

An authenticated device could store a token of up to the 1 MiB body limit, sent to FCM in every push for it. Now
(proposed D-114) more than 512 characters after trimming is 400 invalid_request with field fcm_token, like the
empty string (D-034); E-17's only documented error stays the only one. Test at 512 and 513.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-18 22:43:45 +02:00
parent baa5806812
commit b985ce969d
2 changed files with 32 additions and 0 deletions
@@ -177,3 +177,26 @@ async fn e17_invalid_request() {
assert_error(&reply, 400, "invalid_request");
}
}
#[tokio::test]
async fn e17_fcm_token_is_at_most_512_characters() {
// D-114: 512 characters after trimming are stored, 513 are invalid_request with the field named.
let app = TestApp::household().await;
let put = |token: String| {
app.call(
Method::PUT,
"/devices/current/push-token",
&admin_token(),
Some(json!({ "fcm_token": token })),
)
};
assert_eq!(put(format!(" {} ", "å".repeat(512))).await.status, 204);
let reply = put("f".repeat(513)).await;
assert_field_error(&reply, 400, "invalid_request", "fcm_token");
let stored: Option<String> = sqlx::query_scalar("SELECT fcm_token FROM devices WHERE id = ?")
.bind(ADMIN_DEVICE_ID)
.fetch_one(&app.state.db)
.await
.unwrap();
assert_eq!(stored, Some("å".repeat(512)));
}