mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 08:06:13 +00:00
fix: keep push notifications working when a mailbox is shared with you
Stalwart refuses a push subscription's whole emailPush map as a `forbidden` SetError when it names a mailbox shared by ACL (0.16.16 and later, and 1.0), and 1.0 stops listing emailpush on such accounts. The app narrowed the map on any `forbidden`, including a refused method call, and put every account with folders in the first attempt, so 1.0 cost one refused call per install. Worse, a failed listing counted as "the server has no subscription" and dropped the key of a working registration, and any failed refresh - a network error, a timeout, rate limiting - started a replacement. - `jmap-result` gains `JMAPSetError` (a `JMAPMethodError` with the same name, carrying `properties`) and `isJMAPSetError`. `assertSetResult` throws it, so every refused object can be told apart from a refused call; existing `instanceof` checks and the outbox's name-based error classification are unchanged. - The emailPush map holds the primary account and the accounts whose `accountCapabilities` list `urn:ietf:params:jmap:emailpush`, which leaves ACL shares out up front on 1.0. On 0.16.16-0.16.23 the refused map still narrows to the accounts that look owned, then to the primary account, but only on a `forbidden` SetError. - A subscription ends only with a verified replacement, a user disable or the server's verdict: a failed listing aborts the run, and only a SetError on the refresh starts a replacement. Other failures leave the subscription and its key alone and the next run tries again. - `forbidden` and `overQuota` read as plain text in settings and the onboarding prompt, and settings says that mailboxes others share don't send background notifications. New strings in all 27 languages.
This commit is contained in:
@@ -14,6 +14,7 @@ import { SettingsSection, SettingItem, ToggleSwitch } from './settings-section';
|
||||
import { radius, spacing, typography, type ThemePalette } from '../../theme/tokens';
|
||||
import { useColors } from '../../theme/colors';
|
||||
import { useAuthStore } from '../../stores/auth-store';
|
||||
import { useEmailStore } from '../../stores/email-store';
|
||||
import { useLocaleStore } from '../../stores/locale-store';
|
||||
import { useSettingsStore } from '../../stores/settings-store';
|
||||
import {
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
isPushSupported,
|
||||
isValidRelayUrl,
|
||||
listPushDevices,
|
||||
mailAccountsWithoutPush,
|
||||
PushSetupError,
|
||||
readPushAccountIds,
|
||||
revokePushDevice,
|
||||
@@ -143,6 +145,26 @@ export function NotificationSettings() {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeAccountId, supported]);
|
||||
|
||||
// Stalwart pushes only the user's own mailboxes and their groups', so
|
||||
// mailboxes shared by other users stay silent in the background (they still
|
||||
// update while the app is open). Say so instead of leaving users to wonder.
|
||||
const mailboxes = useEmailStore((s) => s.mailboxes);
|
||||
const [sharedWithoutPush, setSharedWithoutPush] = useState(false);
|
||||
useEffect(() => {
|
||||
if (!supported || !client) {
|
||||
setSharedWithoutPush(false);
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
const accountIds = mailboxes.flatMap((m) => (m.isShared && m.accountId ? [m.accountId] : []));
|
||||
// Re-read after each enable run too: it may have added refused accounts.
|
||||
void mailAccountsWithoutPush(accountIds).then(
|
||||
(ids) => { if (!cancelled) setSharedWithoutPush(ids.length > 0); },
|
||||
() => undefined,
|
||||
);
|
||||
return () => { cancelled = true; };
|
||||
}, [supported, client, mailboxes, pushStatus.kind]);
|
||||
|
||||
const describeError = (error: unknown): string => {
|
||||
if (error instanceof PushSetupError) {
|
||||
const phase = PHASE_KEYS[error.phase];
|
||||
@@ -284,6 +306,15 @@ export function NotificationSettings() {
|
||||
</View>
|
||||
</SettingItem>
|
||||
|
||||
{sharedWithoutPush && (
|
||||
<Text style={styles.fieldDescription}>
|
||||
{t(
|
||||
'settings.notifications.push.shared_mailboxes_no_push',
|
||||
"Mailboxes others share with you don't send background notifications.",
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{upSupported && (
|
||||
<>
|
||||
<SettingItem
|
||||
|
||||
Reference in New Issue
Block a user