Files
webmail/lib/plugin-sandbox/account-kind.ts
T
Linus Rath a69d7eee33 feat: let plugins work with team mailboxes: list filters, row badge icons, account info and message conditions
What the team inbox plugin needs, kept general for other plugins:

- `api.ui.setListFilters`: keyword filters drawn as chips in the list
  header of the folders they apply to (by account kind and folder
  role). A chip the user turns on is ANDed into the folder's query and
  comes off with one click; a keyword change a filter tests loads the
  list again (ui:message-list).
- Actions get `accounts`, `hasKeyword` and `notKeyword`, so a button
  shows only on messages of group accounts, or of a keyword state; the
  click of message-row-actions and reader-actions carries the message's
  `accountId`.
- `api.email.updateKeywords`: several keywords in one change, through
  the list for a listed message (email:write).
- `api.user.getSelf`, `getMailAccounts` and `findPeople`: the user's own
  account id (Stalwart's principal id), which accounts are group
  accounts, and people from the directory (account:read).
- `api.accountData`: a plugin's own entry in a mail account's shared
  Inbox metadata on Stalwart 1.0 (email:read / email:write).
- Row badges take an `icon`.
2026-10-28 06:39:57 +01:00

31 lines
1.6 KiB
TypeScript

// What kind of mail account a message or folder belongs to, for plugins: the
// user's own, a group account (a team mailbox the user is a member of) or a
// mailbox another user shared. Stalwart names a group account by the group's
// address, and the policy subject already lists the addresses of the user's
// group accounts, checked against the principal type (lib/admin/policy-subject.ts).
import type { IJMAPClient } from '@/lib/jmap/client-interface';
import { subjectForAccount } from '@/lib/org/account-subjects';
export type MailAccountKind = 'personal' | 'group' | 'shared';
export const MAIL_ACCOUNT_KINDS: readonly MailAccountKind[] = ['personal', 'group', 'shared'];
type KindClient = Pick<IJMAPClient, 'getAccountId'> & Partial<Pick<IJMAPClient, 'getAccountInfo'>>;
/**
* The kind of the JMAP account `accountId` reached through `client`, the
* client of the login `loginId` (the active login when not given). No
* account, or the login's own, is personal. Until the login's group list has
* loaded, a group account counts as shared.
*/
export function mailAccountKind(client: KindClient | null | undefined, accountId: string | null | undefined, loginId?: string | null): MailAccountKind {
if (!client || !accountId || accountId === client.getAccountId()) return 'personal';
const info = typeof client.getAccountInfo === 'function' ? client.getAccountInfo(accountId) : null;
if (!info) return 'shared';
if (info.isPersonal) return 'personal';
const name = info.name.trim().toLowerCase();
const groups = subjectForAccount(loginId)?.groups ?? [];
return name && groups.includes(name) ? 'group' : 'shared';
}