From 5b7bcf042c618e62c13564a292ccccbdf640f1ab Mon Sep 17 00:00:00 2001 From: abidos Date: Sat, 30 May 2026 13:29:28 +0200 Subject: [PATCH] fix: make email token extraction case-insensitive (#12460) Resolves forgejo/forgejo#12436 Uppercase the token before verification as verification is case-sensitive. Some mail clients might've lower cased. Co-authored-by: Abidos Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12460 Reviewed-by: Gusted --- services/mailer/token/token.go | 2 +- tests/integration/incoming_email_test.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/services/mailer/token/token.go b/services/mailer/token/token.go index f3d7286cb0..eca6637cde 100644 --- a/services/mailer/token/token.go +++ b/services/mailer/token/token.go @@ -82,7 +82,7 @@ func CreateToken(ht HandlerType, user *user_model.User, data []byte) (string, er // ExtractToken extracts the action/user tuple from the token and verifies the content func ExtractToken(ctx context.Context, token string) (HandlerType, *user_model.User, []byte, error) { - data, err := encodingWithoutPadding.DecodeString(token) + data, err := encodingWithoutPadding.DecodeString(util.ToUpperASCII(token)) if err != nil { return UnknownHandlerType, nil, nil, err } diff --git a/tests/integration/incoming_email_test.go b/tests/integration/incoming_email_test.go index 40a501b0cf..c9876a63dd 100644 --- a/tests/integration/incoming_email_test.go +++ b/tests/integration/incoming_email_test.go @@ -76,6 +76,22 @@ func TestIncomingEmail(t *testing.T) { assert.Equal(t, payload, p) }) + t.Run("Lowercase token", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + payload := []byte{1, 2, 3, 4, 5} + + token, err := token_service.CreateToken(token_service.ReplyHandlerType, user, payload) + require.NoError(t, err) + assert.NotEmpty(t, token) + + ht, u, p, err := token_service.ExtractToken(db.DefaultContext, strings.ToLower(token)) + require.NoError(t, err) + assert.Equal(t, token_service.ReplyHandlerType, ht) + assert.Equal(t, user.ID, u.ID) + assert.Equal(t, payload, p) + }) + tokenEncoding := base32.StdEncoding.WithPadding(base32.NoPadding) t.Run("Deprecated token version", func(t *testing.T) { defer tests.PrintCurrentTest(t)()