mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 21:13:36 +00:00
register-queue: Add push_devices in response.
This commit adds a `push_devices` dictionary to `POST /register` response, keyed with push account ID, where each entry describes the user's push device's registration status and error code (if registration failed).
This commit is contained in:
committed by
Tim Abbott
parent
6a4b06b6f4
commit
afe6986991
@@ -49,6 +49,7 @@ from zerver.lib.narrow_predicate import check_narrow_for_events
|
||||
from zerver.lib.navigation_views import get_navigation_views_for_user
|
||||
from zerver.lib.onboarding_steps import get_next_onboarding_steps
|
||||
from zerver.lib.presence import get_presence_for_user, get_presences_for_realm
|
||||
from zerver.lib.push_notifications import get_push_devices
|
||||
from zerver.lib.realm_icon import realm_icon_url
|
||||
from zerver.lib.realm_logo import get_realm_logo_source, get_realm_logo_url
|
||||
from zerver.lib.scheduled_messages import (
|
||||
@@ -918,6 +919,9 @@ def fetch_initial_state_data(
|
||||
# abuse.
|
||||
state["giphy_api_key"] = settings.GIPHY_API_KEY if settings.GIPHY_API_KEY else ""
|
||||
|
||||
if want("push_device"):
|
||||
state["push_devices"] = {} if user_profile is None else get_push_devices(user_profile)
|
||||
|
||||
if user_profile is None:
|
||||
# To ensure we have the correct user state set.
|
||||
assert state["is_admin"] is False
|
||||
|
||||
@@ -9,7 +9,7 @@ from collections.abc import Iterable, Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from email.headerregistry import Address
|
||||
from functools import cache
|
||||
from typing import TYPE_CHECKING, Any, Optional, TypeAlias, Union
|
||||
from typing import TYPE_CHECKING, Any, Literal, Optional, TypeAlias, Union
|
||||
|
||||
import lxml.html
|
||||
import orjson
|
||||
@@ -25,7 +25,7 @@ from firebase_admin import exceptions as firebase_exceptions
|
||||
from firebase_admin import initialize_app as firebase_initialize_app
|
||||
from firebase_admin import messaging as firebase_messaging
|
||||
from firebase_admin.messaging import UnregisteredError as FCMUnregisteredError
|
||||
from typing_extensions import override
|
||||
from typing_extensions import TypedDict, override
|
||||
|
||||
from analytics.lib.counts import COUNT_STATS, do_increment_logging_stat
|
||||
from zerver.actions.realm_settings import (
|
||||
@@ -54,6 +54,7 @@ from zerver.models import (
|
||||
AbstractPushDeviceToken,
|
||||
ArchivedMessage,
|
||||
Message,
|
||||
PushDevice,
|
||||
PushDeviceToken,
|
||||
Realm,
|
||||
Recipient,
|
||||
@@ -1586,3 +1587,21 @@ class HostnameAlreadyInUseBouncerError(JsonableError):
|
||||
# This message is not read by any of the client apps, just potentially displayed
|
||||
# via server administration tools, so it doesn't need translations.
|
||||
return "A server with hostname {hostname} already exists"
|
||||
|
||||
|
||||
class PushDeviceInfoDict(TypedDict):
|
||||
status: Literal["active", "pending", "failed"]
|
||||
error_code: str | None
|
||||
|
||||
|
||||
def get_push_devices(user_profile: UserProfile) -> dict[str, PushDeviceInfoDict]:
|
||||
# We intentionally don't try to save a database query
|
||||
# if `push_notifications_configured()` is False, in order to avoid
|
||||
# risk of clients deleting their Account records if the server
|
||||
# has its mobile notifications configuration temporarily disabled.
|
||||
rows = PushDevice.objects.filter(user=user_profile)
|
||||
|
||||
return {
|
||||
str(row.push_account_id): {"status": row.status, "error_code": row.error_code}
|
||||
for row in rows
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ from zerver.models.presence import UserPresence as UserPresence
|
||||
from zerver.models.presence import UserStatus as UserStatus
|
||||
from zerver.models.push_notifications import AbstractPushDevice as AbstractPushDevice
|
||||
from zerver.models.push_notifications import AbstractPushDeviceToken as AbstractPushDeviceToken
|
||||
from zerver.models.push_notifications import PushDevice as PushDevice
|
||||
from zerver.models.push_notifications import PushDeviceToken as PushDeviceToken
|
||||
from zerver.models.realm_audit_logs import AbstractRealmAuditLog as AbstractRealmAuditLog
|
||||
from zerver.models.realm_audit_logs import RealmAuditLog as RealmAuditLog
|
||||
|
||||
@@ -17339,6 +17339,40 @@ paths:
|
||||
before using this API key.
|
||||
|
||||
**Changes**: Added in Zulip 4.0 (feature level 47).
|
||||
push_devices:
|
||||
type: object
|
||||
description: |
|
||||
Present if `push_device` is present in `fetch_event_types`.
|
||||
|
||||
Dictionary where each entry describes the user's push device's
|
||||
registration status and error code (if registration failed).
|
||||
|
||||
**Changes**: New in Zulip 11.0 (feature level ZF-1653f2).
|
||||
additionalProperties:
|
||||
description: |
|
||||
`{push_account_id}`: Dictionary containing the details of
|
||||
a push device with the push account ID as the key.
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
description: |
|
||||
The push account's registration status.
|
||||
Either `"active"`, `"pending"`, or `"failed"`.
|
||||
error_code:
|
||||
type: string
|
||||
nullable: true
|
||||
description: |
|
||||
The error code returned when registration to bouncer fails, `null` otherwise.
|
||||
|
||||
Either `"INVALID_BOUNCER_PUBLIC_KEY"`, `"BAD_REQUEST"`, or `"REQUEST_EXPIRED"`.
|
||||
|
||||
The client should use these error codes to fix the issue which led to registration
|
||||
failure and retry.
|
||||
|
||||
- `"INVALID_BOUNCER_PUBLIC_KEY"` - Inform the user to update app.
|
||||
- `"REQUEST_EXPIRED` - Retry with a fresh payload.
|
||||
enable_desktop_notifications:
|
||||
deprecated: true
|
||||
type: boolean
|
||||
|
||||
@@ -1241,7 +1241,7 @@ class FetchQueriesTest(ZulipTestCase):
|
||||
self.login_user(user)
|
||||
|
||||
with (
|
||||
self.assert_database_query_count(47),
|
||||
self.assert_database_query_count(48),
|
||||
mock.patch("zerver.lib.events.always_want") as want_mock,
|
||||
):
|
||||
fetch_initial_state_data(user, realm=user.realm)
|
||||
@@ -1260,6 +1260,7 @@ class FetchQueriesTest(ZulipTestCase):
|
||||
navigation_views=1,
|
||||
onboarding_steps=1,
|
||||
presence=1,
|
||||
push_device=1,
|
||||
# 2 of the 3 queries here are a single query that is used
|
||||
# for all the 'realm', 'stream', 'subscription'
|
||||
# and 'realm_user_groups' event types.
|
||||
|
||||
@@ -117,6 +117,7 @@ class HomeTest(ZulipTestCase):
|
||||
"password_max_length",
|
||||
"presences",
|
||||
"presence_last_update_id",
|
||||
"push_devices",
|
||||
"queue_id",
|
||||
"realm_allow_edit_history",
|
||||
"realm_allow_message_editing",
|
||||
@@ -285,7 +286,7 @@ class HomeTest(ZulipTestCase):
|
||||
|
||||
# Verify succeeds once logged-in
|
||||
with (
|
||||
self.assert_database_query_count(57),
|
||||
self.assert_database_query_count(58),
|
||||
patch("zerver.lib.cache.cache_set") as cache_mock,
|
||||
):
|
||||
result = self._get_home_page(stream="Denmark")
|
||||
@@ -593,7 +594,7 @@ class HomeTest(ZulipTestCase):
|
||||
# Verify number of queries for Realm admin isn't much higher than for normal users.
|
||||
self.login("iago")
|
||||
with (
|
||||
self.assert_database_query_count(56),
|
||||
self.assert_database_query_count(57),
|
||||
patch("zerver.lib.cache.cache_set") as cache_mock,
|
||||
):
|
||||
result = self._get_home_page()
|
||||
@@ -625,7 +626,7 @@ class HomeTest(ZulipTestCase):
|
||||
self._get_home_page()
|
||||
|
||||
# Then for the second page load, measure the number of queries.
|
||||
with self.assert_database_query_count(52):
|
||||
with self.assert_database_query_count(53):
|
||||
result = self._get_home_page()
|
||||
|
||||
# Do a sanity check that our new streams were in the payload.
|
||||
|
||||
Reference in New Issue
Block a user