#4061·Mailu

API: /api/v1/alias/me endpoints return 500 for the API-token caller (flask.g.user never set)

Author: maximilizeCreated Jul 5, 2026Updated Jul 28, 2026

Environment & Version

  • Found by reading the code at master (HEAD 8061788); reproduced headless against the admin app, so it is not deployment-specific.
  • Version: master

Description

The anonymous-alias "me" endpoints — GET /api/v1/alias/me, DELETE /api/v1/alias/me/<alias>, PATCH /api/v1/alias/me/<alias> (core/admin/mailu/api/v1/alias.py) — return HTTP 500 for the normal API-token caller.

Each handler resolves the caller with:

python
user_email = flask.g.user.email if hasattr(flask.g, 'user') else flask_login.current_user.email

but they are decorated with @common.api_token_authorization, which validates the global API_TOKEN and never sets flask.g.user (only common.user_token_authorization does). So with a Bearer token flask.g.user is unset, the fallback hits flask_login.current_user (an AnonymousUserMixin with no .email), and the request raises AttributeError → 500.

Their sibling POST /api/alias/random/new (api/simplelogin.py) — which shares the same flask.g.user model — is decorated with @common.user_token_authorization, which suggests the /me endpoints were meant to use that decorator too and got the admin-token one by copy-paste from the other alias endpoints.

Replication Steps

GET /api/v1/alias/me with Authorization: Bearer <API_TOKEN> and no session cookie.

Reproduced headless (in-memory SQLite, no mailstack):

python
def test_alias_me_with_bearer_token(app, client):
    with app.app_context():
        rv = client.get('/api/v1/alias/me',
                        headers={'Authorization': f'Bearer {app.config["API_TOKEN"]}'})
        assert rv.status_code == 500

Observed behaviour

AttributeError: 'AnonymousUserMixin' object has no attribute 'email' → HTTP 500.

Expected behaviour

A defined response for the intended authentication (the caller's own aliases, or a clean 401/403), not a 500.

Question / proposed fix

The flask.g.user usage and the /random/new sibling both point to @common.user_token_authorization (per-user Authentication: email:token) as the intended auth for /me. Should these three endpoints use it? Since this changes an endpoint's authentication I'd rather confirm the intended auth first; I'll then open a PR switching the decorator with a headless regression test.