Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
This removes
- an unclear fuzzy syntax that had been incorrectly accepted by our
`<time:…>` Markdown extension and could not be reproducibly parsed
without a specific Python library (even the UNIX timestamp part did
not work reliably: some UNIX timestamps were instead parsed as
YYYYMMDD);
- a fundamentally ambiguous ad-hoc list of three-letter timezone
abbreviations that we had needed to manually disambiguate by some kind
of subjective popularity;
- an unpleasant dependency of the `pg_backup_and_purge` script that we
had needed to install system-wide because there might not be a
virtualenv set up.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Switch the topic summarization integration from the litellm wrapper
library to the OpenAI Python SDK directly. The SDK can be pointed at
any OpenAI-compatible endpoint via a new TOPIC_SUMMARIZATION_API_BASE
setting, so provider/model strings like "groq/llama-3.3-70b-versatile"
become a plain model name plus a base URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Anders Kaseorg <anders@zulip.com>
Django's EmailValidator permits anything in U+00A1..U+FFFF as a
domain-label character, which lets bidirectional format characters
like U+202C and U+200F slip through. Addresses with those trailing
characters then reach the send_email worker, where Django's SMTP
path IDNA-encodes the domain and crashes with UnicodeError.
Validate against IDNA 2008 up front. This also rejects RFC 5321
address-literal domains like user@[192.168.0.1], which we don't
want to attempt delivery to.
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
4c3aa4c007 migrated the GET
/users/{user_id_or_email}/presence endpoint to return only the modern
format (active_timestamp and idle_timestamp). The assumption that the
endpoint had no significant consumers turned out to be wrong: the
Zulip web app itself was a consumer (in user_card_popover, where it
caused a "Failed to parse presence API response" error for any
currently active user), and there are likely third-party integrations
relying on the legacy format as well.
Restore the legacy website and aggregated dictionaries alongside the
new modern fields, so existing clients keep working. Clients should
migrate to the modern fields, which is now phrased as a recommendation
rather than a breaking change in the API and self-hosted upgrade
notes.
Additionally, add a top-level server_timestamp field to the response,
matching the behavior of other presence endpoints. This lets clients
compute presence-status age against the server's clock rather than
guessing with the local clock.
Refactor the view to query UserPresence once and format both the
modern and legacy presence dicts from the same row, rather than
issuing two queries that fetch the same data.
The user_groups read and write endpoints were unintentionally blocked
to bot users by the @require_member_or_admin decorator (renamed to
@require_human_non_guest_user in #37927). This prevented bot
integrations from using groups as an ACL mechanism, and from
managing groups they had created.
Switch the seven @require_human_non_guest_user-decorated endpoints in
zerver/views/user_groups.py and the inner decorator in
require_user_group_create_permission (which gates POST
/user_groups/create) to @require_non_guest_user. Guest users remain
blocked.
This also permits a leaked bot API key to create groups and manage
the ones the bot owns. Per discussion on chat.zulip.org, that does
not escalate to any security-sensitive operation; a follow-up may
revisit the default value of can_create_user_groups for new
organizations, which is orthogonal.
Discussed on chat.zulip.org:
https://chat.zulip.org/#narrow/channel/378-api-design/topic/GET.20.2Fuser_groups.2F.3Cid.3E.2Fmembers.2F.3Cuser_id.3E.20not.20accessible.20to.20bo
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add video/quicktime as a supported MIME type for inline video previews,
enabling .mov (QuickTime) files to render with the existing
message_inline_video HTML.
QuickTime is a container format, and whether a given .mov file actually
plays depends on which codec combinations the browser supports inside
it. Chrome, Safari, and Edge accept most common combinations; Firefox
plays .mov files whose codecs match those it already supports for MP4
(primarily H.264 / AAC) and rejects the rest. For the files a browser
can't decode, attach an error handler that hides the preview element
while leaving the download link in the surrounding <a> tag available
as a fallback.
Fixes#29728.
Co-Authored-By: Henrik Holst <6200749+hholst80@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Non-bot accounts have no reason to use these endpoints, or the
BotStorageData model, so we now enforce that restriction explicitly
with new require_bot_user decorator on the view functions.
Co-authored-by: Lauryn Menard <lauryn@zulip.com>
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
Regenerating a user's API key didn't delete the Device records
for the user which resulted in server keep sending E2EE push
notifications to those devices whose session had just been revoked.
This commit fixes the bug.
Signed-off-by: Prakhar Pratyush <prakhar@zulip.com>
When a user is deleted via `manage.py delete_user`, the replacement
dummy user profile now has `is_deleted=True`. This field is exposed
in the API user objects (only present when `true`) so that clients
can distinguish permanently deleted users from deactivated ones.
Updates the empty narrow banner for all of the "channels" narrows
to not suggest "starting a conversation" since new conversations
cannot be started in archived channels and, if public or web-public
channels don't exist, then the user cannot start a conversation in
one.
Fixes#32506.
Co-authored-by: Kumar Aniket <sachinaniket2004@gmail.com>
Co-authored-by: whilstsomebody <whilstsomebody@gmail.com>
Co-authored-by: Lauryn Menard <lauryn@zulip.com>
This commit replaces the manual substring matching in
`get_device_browser` and `get_device_os` with `ua_parser`
library.
This gives more accurate results and eliminates the need
to manually maintain parsing heuristics.
Profiling:
1 Million iterations on 28 unique User Agents:
* To extract only browser data `ua_parser.parse_user_agent`
takes around "0.70 µs"
* To extract OS information `ua_parser.parse_os` takes
around "0.72 µs`
Fixes#13098.
Signed-off-by: Prakhar Pratyush <prakhar@zulip.com>
The GET /users/{user_id_or_email}/presence endpoint now always returns
presence data in the modern format, with active_timestamp and
idle_timestamp fields.
Previously, the legacy format was returned by default (with website
and aggregated keys), and a slim_presence parameter was needed to
opt in to the modern format. Since the legacy format is slated for
full removal, there is no reason to support it from this endpoint.
Fixes#36710.
And convert its type from `Callable` to `str`.
It's type was previously set to a string in the frontend, and validator
functions in the backend, which were never called.
The `user` object was temporarily restored to reaction
events in zulip#33009 to maintain compatibility with mobile
clients.
As the Zulip mobile app has fully migrated to using the
`user_id` field, this commit permanently removes the `user`
object from reaction events.
When a client successfully registers for E2EE push notifications,
automatically remove any matching legacy PushDeviceToken and
RemotePushDeviceToken registration with the same token for the user.
Signed-off-by: Prakhar Pratyush <prakhar@zulip.com>
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
Replace the undocumented integer-only idle_queue_timeout parameter
on `POST /register` with a documented parameter that accepts
either a positive integer (seconds) or the string "mobile" to use
the server's recommended timeout for mobile clients (currently
12 hours).
The parameter resolution (None → default 10 min, "mobile" → 12h,
capped at 7 days) happens in ClientDescriptor.__init__, and the
resolved value is sent back through the Tornado response as
idle_queue_timeout_secs, which is included in the `POST /register`
response so clients know the effective timeout.
Signed-off-by: Prakhar Pratyush <prakhar@zulip.com>
Previously, if the user toggles the preview mode in the compose box before
an image/GIF in the drafted message has been uploaded and thumbnailed,
then the loading indicator shown in the preview of the message will never update.
To address this issue, this commit adds a new cheap endpoint to return the
status of the thumbnail generation. This endpoint will be polled by the compose
box to update the loading indicator.
fixes part of #32961.