Files
webmail/lib/admin/restriction-keys.ts
T
Linus Rath 65e3d0d2d4 feat: let admins set an organisation signature with user details per domain or group #908
Admins write an HTML and a plain-text signature with placeholders on
Organisation > Signatures, per scope. Users fill in the details it asks
for once, under Settings > Account. Without a lock it is the default for
addresses without a signature of their own; locked or hidden, it
replaces every signature.

- `lib/org-signature.ts` fills the templates: values escaped, lines whose
  placeholders are all empty dropped
- the composer applies it right before the plugin signature, so new mail,
  replies, forwards, re-opened drafts, plain text and identity swaps all
  take it the way they take an identity signature; quick reply too
- a send finaliser puts a locked signature back once when it was deleted
- the identity editor shows the filled-in signature read-only with "Set
  by your organisation" when locked, and no editor when hidden
- `signatureDetails` is a synced setting
2026-10-28 02:23:55 +01:00

59 lines
3.8 KiB
TypeScript

/**
* Every setting an admin can lock, hide or limit (SettingRestriction in
* lib/admin/types.ts), with where the admin panel offers it. The User policy
* page lists the ones with page `policy`; each Organisation page lists its
* own next to the settings they belong to. New user-facing options add their
* key here instead of a lock flag of their own.
*/
import type { AdminPageId } from './admin-nav';
export interface RestrictionKeyDef {
key: string;
label: string;
/** One sentence for the admin: what locking or hiding it does for users. */
description?: string;
category: string;
type: 'boolean' | 'number' | 'enum';
allowedValues?: string[];
/** The admin page that lists it. */
page: AdminPageId;
/** Which of locked, hidden and allowed values make sense for it. */
modes?: ReadonlyArray<'locked' | 'hidden' | 'allowedValues'>;
}
export const RESTRICTION_KEYS: readonly RestrictionKeyDef[] = [
{ key: 'fontSize', label: 'Font Size', category: 'Appearance', type: 'enum', allowedValues: ['small', 'medium', 'large'], page: 'policy' },
{ key: 'density', label: 'Density', category: 'Appearance', type: 'enum', allowedValues: ['compact', 'regular', 'spacious'], page: 'policy' },
{ key: 'interfaceLayout', label: 'Interface Layout', category: 'Appearance', type: 'enum', allowedValues: ['default', 'mountain-view'], page: 'policy' },
{ key: 'animationsEnabled', label: 'Animations', category: 'Appearance', type: 'boolean', page: 'policy' },
{ key: 'markAsReadDelay', label: 'Mark as Read Delay', category: 'Email', type: 'number', page: 'policy' },
{ key: 'deleteAction', label: 'Delete Action', category: 'Email', type: 'enum', allowedValues: ['trash', 'trash-and-read', 'permanent'], page: 'policy' },
{ key: 'showPreview', label: 'Show Preview', category: 'Email', type: 'boolean', page: 'policy' },
{ key: 'mailLayout', label: 'Mail Layout', category: 'Email', type: 'enum', allowedValues: ['split', 'focus', 'horizontal'], page: 'policy' },
{ key: 'emailsPerPage', label: 'Emails Per Page', category: 'Email', type: 'number', page: 'policy' },
{ key: 'externalContentPolicy', label: 'External Content Policy', category: 'Email', type: 'enum', allowedValues: ['allow', 'block', 'ask'], page: 'policy' },
{ key: 'sendConfirmation', label: 'Send Confirmation', category: 'Composer', type: 'boolean', page: 'policy' },
{ key: 'defaultReplyMode', label: 'Default Reply Mode', category: 'Composer', type: 'enum', allowedValues: ['reply', 'reply-all'], page: 'policy' },
{ key: 'autoSelectReplyIdentity', label: 'Auto-select Reply Identity', category: 'Composer', type: 'boolean', page: 'policy' },
{ key: 'replyIdentityMatch', label: 'Reply Identity Matching', category: 'Composer', type: 'enum', allowedValues: ['exact', 'domain'], page: 'policy' },
{ key: 'plainTextMode', label: 'Plain Text Only', category: 'Composer', type: 'boolean', page: 'policy' },
{ key: 'emailNotificationsEnabled', label: 'Email Notifications', category: 'Notifications', type: 'boolean', page: 'policy' },
{ key: 'calendarNotificationsEnabled', label: 'Calendar Notifications', category: 'Notifications', type: 'boolean', page: 'policy' },
{ key: 'pushNotifyInboxOnly', label: 'Inbox-only Push Notifications', category: 'Notifications', type: 'boolean', page: 'policy' },
{ key: 'debugMode', label: 'Debug Mode', category: 'Advanced', type: 'boolean', page: 'policy' },
{
key: 'signature',
label: 'Signatures',
description: "Lock: users can't change signatures, and the organisation signature replaces their own. Hide: users get no signature editor at all.",
category: 'Composer',
type: 'boolean',
page: 'org-signatures',
modes: ['locked', 'hidden'],
},
];
export function restrictionKeysForPage(page: AdminPageId): RestrictionKeyDef[] {
return RESTRICTION_KEYS.filter((def) => def.page === page);
}