@rndmjoker/proton-mcp 0.4.13 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +138 -21
  2. package/dist/browser/channel.d.ts +76 -0
  3. package/dist/browser/channel.js +162 -0
  4. package/dist/browser/channel.js.map +1 -0
  5. package/dist/browser/client.d.ts +50 -0
  6. package/dist/browser/client.js +284 -0
  7. package/dist/browser/client.js.map +1 -0
  8. package/dist/browser/connector.d.ts +15 -0
  9. package/dist/browser/connector.js +26 -0
  10. package/dist/browser/connector.js.map +1 -0
  11. package/dist/browser/host.d.ts +50 -0
  12. package/dist/browser/host.js +258 -0
  13. package/dist/browser/host.js.map +1 -0
  14. package/dist/browser/messages.d.ts +163 -0
  15. package/dist/browser/messages.js +338 -0
  16. package/dist/browser/messages.js.map +1 -0
  17. package/dist/browser/paths.d.ts +51 -0
  18. package/dist/browser/paths.js +92 -0
  19. package/dist/browser/paths.js.map +1 -0
  20. package/dist/browser/setup.d.ts +42 -0
  21. package/dist/browser/setup.js +170 -0
  22. package/dist/browser/setup.js.map +1 -0
  23. package/dist/filters/order.d.ts +66 -0
  24. package/dist/filters/order.js +108 -0
  25. package/dist/filters/order.js.map +1 -0
  26. package/dist/filters/sieve.d.ts +184 -0
  27. package/dist/filters/sieve.js +1312 -0
  28. package/dist/filters/sieve.js.map +1 -0
  29. package/dist/instances.d.ts +58 -0
  30. package/dist/instances.js +145 -0
  31. package/dist/instances.js.map +1 -0
  32. package/dist/mail/compose.d.ts +10 -0
  33. package/dist/mail/compose.js.map +1 -1
  34. package/dist/mail/record.d.ts +36 -0
  35. package/dist/mail/record.js +74 -0
  36. package/dist/mail/record.js.map +1 -0
  37. package/dist/permissions.d.ts +139 -0
  38. package/dist/permissions.js +355 -0
  39. package/dist/permissions.js.map +1 -0
  40. package/dist/server.js +330 -16
  41. package/dist/server.js.map +1 -1
  42. package/dist/session.d.ts +12 -0
  43. package/dist/session.js +23 -0
  44. package/dist/session.js.map +1 -1
  45. package/dist/settings.d.ts +81 -11
  46. package/dist/settings.js +160 -25
  47. package/dist/settings.js.map +1 -1
  48. package/dist/tools/confirm.d.ts +4 -2
  49. package/dist/tools/confirm.js +12 -3
  50. package/dist/tools/confirm.js.map +1 -1
  51. package/dist/tools/failures.d.ts +6 -8
  52. package/dist/tools/failures.js +36 -17
  53. package/dist/tools/failures.js.map +1 -1
  54. package/dist/tools/filter-tools.d.ts +82 -0
  55. package/dist/tools/filter-tools.js +729 -0
  56. package/dist/tools/filter-tools.js.map +1 -0
  57. package/dist/tools/filters.d.ts +8 -1
  58. package/dist/tools/filters.js +24 -12
  59. package/dist/tools/filters.js.map +1 -1
  60. package/dist/tools/format.d.ts +15 -0
  61. package/dist/tools/format.js +4 -3
  62. package/dist/tools/format.js.map +1 -1
  63. package/dist/tools/guidance.js +12 -7
  64. package/dist/tools/guidance.js.map +1 -1
  65. package/dist/tools/interface.d.ts +20 -6
  66. package/dist/tools/interface.js +40 -16
  67. package/dist/tools/interface.js.map +1 -1
  68. package/dist/tools/send.d.ts +9 -0
  69. package/dist/tools/send.js +51 -9
  70. package/dist/tools/send.js.map +1 -1
  71. package/dist/tools/sign-in-required.d.ts +15 -2
  72. package/dist/tools/sign-in-required.js +30 -2
  73. package/dist/tools/sign-in-required.js.map +1 -1
  74. package/dist/web/layout.d.ts +12 -5
  75. package/dist/web/layout.js +32 -9
  76. package/dist/web/layout.js.map +1 -1
  77. package/dist/web/pages.d.ts +4 -2
  78. package/dist/web/pages.js +10 -9
  79. package/dist/web/pages.js.map +1 -1
  80. package/dist/web/pending.d.ts +9 -6
  81. package/dist/web/pending.js +9 -7
  82. package/dist/web/pending.js.map +1 -1
  83. package/dist/web/preview-server.d.ts +33 -0
  84. package/dist/web/preview-server.js +102 -0
  85. package/dist/web/preview-server.js.map +1 -0
  86. package/dist/web/sections.d.ts +86 -1
  87. package/dist/web/sections.js +290 -7
  88. package/dist/web/sections.js.map +1 -1
  89. package/dist/web/security.d.ts +48 -13
  90. package/dist/web/security.js +68 -16
  91. package/dist/web/security.js.map +1 -1
  92. package/dist/web/server.d.ts +81 -24
  93. package/dist/web/server.js +478 -117
  94. package/dist/web/server.js.map +1 -1
  95. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Shows a message waiting for confirmation, from the server that holds it.
3
+ *
4
+ * Until 2026-11-05 this was a page of the interface. Since then every running
5
+ * server shares one interface at a fixed address, served by whichever started
6
+ * first, but a waiting message lives only in the memory of the server that
7
+ * asked about it. Handing it to the server behind the interface would send
8
+ * decrypted mail from one process to another for the sake of a page. So each
9
+ * server shows its own, on a port the operating system picks.
10
+ *
11
+ * What protects the page: it listens on loopback only, refuses any Host header
12
+ * that is not this machine, and finds a message only by the digest of its
13
+ * recipients, subject and body, which nobody can produce without knowing all
14
+ * three already. It serves nothing else, has no form and no button, and keeps
15
+ * the interface's content security policy, which also governs the sandboxed
16
+ * frame the message is drawn in.
17
+ */
18
+ import { createServer } from 'node:http';
19
+ import { isAllowedHost, securityHeaders } from './security.js';
20
+ import { pendingPage, noPendingPage } from './pending.js';
21
+ import { rejectionPage } from './pages.js';
22
+ const BIND_ADDRESS = '127.0.0.1';
23
+ /** A digest as `digestOf` writes it: SHA-256 in hexadecimal. */
24
+ const DIGEST = /^[0-9a-f]{64}$/;
25
+ export class PreviewServer {
26
+ #server;
27
+ #port = 0;
28
+ #options;
29
+ constructor(options) {
30
+ this.#options = options;
31
+ }
32
+ get running() {
33
+ return this.#server?.listening === true;
34
+ }
35
+ /** The address of one waiting message, or nothing while not running. */
36
+ urlFor(digest) {
37
+ if (!this.running || !DIGEST.test(digest))
38
+ return undefined;
39
+ return `http://${BIND_ADDRESS}:${this.#port}/pending/${digest}`;
40
+ }
41
+ async start() {
42
+ if (this.running)
43
+ return;
44
+ const server = createServer((request, response) => {
45
+ try {
46
+ this.#handle(request, response);
47
+ }
48
+ catch {
49
+ this.#send(response, 500, 'Internal error.', 'text/plain; charset=utf-8');
50
+ }
51
+ });
52
+ server.headersTimeout = 10_000;
53
+ server.requestTimeout = 30_000;
54
+ await new Promise((resolve, reject) => {
55
+ server.once('error', reject);
56
+ // Port 0: the operating system picks a free one. Nobody types this
57
+ // address; it travels in the confirmation.
58
+ server.listen(0, BIND_ADDRESS, () => {
59
+ server.removeListener('error', reject);
60
+ resolve();
61
+ });
62
+ });
63
+ const address = server.address();
64
+ this.#port = typeof address === 'object' && address ? address.port : 0;
65
+ this.#server = server;
66
+ }
67
+ async stop() {
68
+ const server = this.#server;
69
+ this.#server = undefined;
70
+ if (!server)
71
+ return;
72
+ server.closeIdleConnections();
73
+ server.closeAllConnections();
74
+ await new Promise((resolve) => server.close(() => resolve()));
75
+ }
76
+ #send(response, status, body, type = 'text/html; charset=utf-8') {
77
+ response.writeHead(status, { ...securityHeaders(), 'Content-Type': type });
78
+ response.end(body);
79
+ }
80
+ #handle(request, response) {
81
+ if (request.method !== 'GET') {
82
+ this.#send(response, 405, rejectionPage());
83
+ return;
84
+ }
85
+ if (!isAllowedHost(request.headers.host)) {
86
+ this.#options.notify?.('preview refused a request for a foreign host');
87
+ this.#send(response, 404, rejectionPage());
88
+ return;
89
+ }
90
+ const path = new URL(request.url ?? '/', `http://${BIND_ADDRESS}`).pathname;
91
+ const digest = path.startsWith('/pending/') ? path.slice('/pending/'.length) : undefined;
92
+ if (!digest || !DIGEST.test(digest)) {
93
+ this.#send(response, 404, rejectionPage());
94
+ return;
95
+ }
96
+ // A digest nobody is holding gives the empty page rather than a refusal,
97
+ // because the ordinary reason to land here is having answered already.
98
+ const waiting = this.#options.getPending(digest);
99
+ this.#send(response, 200, waiting ? pendingPage({ ...waiting, disclaimer: 'plain' }) : noPendingPage('plain'));
100
+ }
101
+ }
102
+ //# sourceMappingURL=preview-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-server.js","sourceRoot":"","sources":["../../src/web/preview-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAA0D,MAAM,WAAW,CAAA;AAChG,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAoB,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,MAAM,YAAY,GAAG,WAAW,CAAA;AAEhC,gEAAgE;AAChE,MAAM,MAAM,GAAG,gBAAgB,CAAA;AAS/B,MAAM,OAAO,aAAa;IACxB,OAAO,CAAoB;IAC3B,KAAK,GAAG,CAAC,CAAA;IACA,QAAQ,CAAsB;IAEvC,YAAY,OAA6B;QACvC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;IACzB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,KAAK,IAAI,CAAA;IACzC,CAAC;IAED,wEAAwE;IACxE,MAAM,CAAC,MAAc;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,SAAS,CAAA;QAC3D,OAAO,UAAU,YAAY,IAAI,IAAI,CAAC,KAAK,YAAY,MAAM,EAAE,CAAA;IACjE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QACxB,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;YAChD,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAAA;YAC3E,CAAC;QACH,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,cAAc,GAAG,MAAM,CAAA;QAC9B,MAAM,CAAC,cAAc,GAAG,MAAM,CAAA;QAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAC5B,mEAAmE;YACnE,2CAA2C;YAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE;gBAClC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBACtC,OAAO,EAAE,CAAA;YACX,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;QAChC,IAAI,CAAC,KAAK,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACtE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QACxB,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,CAAC,oBAAoB,EAAE,CAAA;QAC7B,MAAM,CAAC,mBAAmB,EAAE,CAAA;QAC5B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACrE,CAAC;IAED,KAAK,CAAC,QAAwB,EAAE,MAAc,EAAE,IAAY,EAAE,IAAI,GAAG,0BAA0B;QAC7F,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,GAAG,eAAe,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAA;QAC1E,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;IAED,OAAO,CAAC,OAAwB,EAAE,QAAwB;QACxD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,8CAA8C,CAAC,CAAA;YACtE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAA;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACxF,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,yEAAyE;QACzE,uEAAuE;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAChD,IAAI,CAAC,KAAK,CACR,QAAQ,EACR,GAAG,EACH,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CACpF,CAAA;IACH,CAAC;CACF"}
@@ -14,7 +14,8 @@ import { type DisclaimerState } from './layout.js';
14
14
  import type { StoreKind } from '../credentials/store.js';
15
15
  /** What every section needs to draw itself. */
16
16
  interface Common {
17
- token: string;
17
+ /** True while a PIN is set: then every form that changes something asks for it. */
18
+ pinRequired?: boolean;
18
19
  error?: string;
19
20
  notice?: string;
20
21
  /**
@@ -24,6 +25,17 @@ interface Common {
24
25
  */
25
26
  disclaimer: DisclaimerState;
26
27
  }
28
+ /** One running server, as the overview lists it. Never a password. */
29
+ export interface ServerSummary {
30
+ pid: number;
31
+ version: string;
32
+ startedAt: number;
33
+ signedIn: boolean;
34
+ address?: string;
35
+ storeTitle?: string;
36
+ /** True for the server that shows this page. */
37
+ servesInterface: boolean;
38
+ }
27
39
  export interface OverviewData extends Common {
28
40
  connected: boolean;
29
41
  address?: string;
@@ -37,6 +49,20 @@ export interface OverviewData extends Common {
37
49
  bridgeHost: string;
38
50
  bridgeImapPort: number;
39
51
  bridgeSmtpPort: number;
52
+ /** Every server running on this machine, this one included. */
53
+ servers?: ServerSummary[];
54
+ /** Tools whose level differs from the default, with that level in words. */
55
+ departures?: Array<{
56
+ tool: string;
57
+ level: string;
58
+ }>;
59
+ /** The recipient added to every message sent, when one is. */
60
+ record?: {
61
+ address: string;
62
+ mode: 'cc' | 'bcc';
63
+ };
64
+ /** What a filter from an assistant may do beyond filing and flags. */
65
+ filterActions?: string[];
40
66
  }
41
67
  /**
42
68
  * The first page, and the only one that answers "is this working".
@@ -102,4 +128,63 @@ export interface MailboxData extends Common {
102
128
  * answer nobody asked for would hand it over unasked.
103
129
  */
104
130
  export declare function mailboxSection(data: MailboxData): string;
131
+ /** One tool as the permissions page shows it. */
132
+ export interface ToolLevelView {
133
+ tool: string;
134
+ group: string;
135
+ level: 'off' | 'ask' | 'act';
136
+ /** The levels this tool offers. Only the sending tools and proposing a filter can ask. */
137
+ options: Array<'off' | 'ask' | 'act'>;
138
+ /** Set in the environment or by read-only mode, and so not changeable here. */
139
+ fixed: boolean;
140
+ /** Where the level comes from, in words. */
141
+ source: string;
142
+ /** True when the level differs from the default. */
143
+ departs?: boolean;
144
+ }
145
+ /** The bounds on sending without asking, each with whether the environment fixed it. */
146
+ export interface LimitsView {
147
+ allowed: string[];
148
+ maxPerHour?: number;
149
+ until?: string;
150
+ fixed: {
151
+ allowed: boolean;
152
+ maxPerHour: boolean;
153
+ until: boolean;
154
+ };
155
+ }
156
+ /** The recipient added to every message sent, as the page shows it. */
157
+ export interface RecordView {
158
+ address?: string;
159
+ mode?: 'cc' | 'bcc';
160
+ /** Set in the environment, and so not changeable here. */
161
+ fixed: boolean;
162
+ }
163
+ /** What a filter from an assistant may do beyond filing and flags, as the page shows it. */
164
+ export interface FilterActionsView {
165
+ allowed: string[];
166
+ /** Set in the environment, and so not changeable here. */
167
+ fixed: boolean;
168
+ }
169
+ export interface PermissionsData extends Common {
170
+ csrfPin: string;
171
+ csrfLevels?: string;
172
+ csrfLimits?: string;
173
+ csrfRecord?: string;
174
+ csrfFilterActions?: string;
175
+ tools?: ToolLevelView[];
176
+ limits?: LimitsView;
177
+ record?: RecordView;
178
+ filterActions?: FilterActionsView;
179
+ }
180
+ /**
181
+ * What the assistant may do, and who may change that.
182
+ *
183
+ * The PIN comes first on this page because everything else on it depends on
184
+ * it. Without one, the settings here are only as safe as every program on this
185
+ * machine, the assistant included: it can open this address with a browser
186
+ * tool as easily as the user can. The page says so plainly instead of leaving
187
+ * it to be discovered.
188
+ */
189
+ export declare function permissionsSection(data: PermissionsData): string;
105
190
  export {};
@@ -10,7 +10,8 @@
10
10
  *
11
11
  * The counterpart is pages.ts, which holds what comes before signing in.
12
12
  */
13
- import { layout, escapeHtml, formatDuration, errorBanner, noticeBanner, } from './layout.js';
13
+ import { layout, escapeHtml, formatDuration, errorBanner, noticeBanner, pinField, } from './layout.js';
14
+ import { UNLOCKABLE, UNLOCKABLE_TEXT } from '../filters/sieve.js';
14
15
  /**
15
16
  * A wall-clock time in the locale and timezone of the machine running the
16
17
  * server, because the page is rendered there and carries no script to adjust
@@ -28,11 +29,42 @@ function frame(section, title, data, body) {
28
29
  return layout({
29
30
  title,
30
31
  section,
31
- token: data.token,
32
32
  disclaimer: data.disclaimer,
33
33
  body: `${errorBanner(data.error)}${noticeBanner(data.notice)}${body}`,
34
34
  });
35
35
  }
36
+ /**
37
+ * The running servers, one row each.
38
+ *
39
+ * Every client session starts its own server, and all of them share this page.
40
+ * A sign-in kept only in the memory of the server that shows the page ("this
41
+ * session only" or an encrypted file still being open) does not reach the
42
+ * others, and this table is where that becomes visible rather than puzzling.
43
+ */
44
+ function serverTable(servers) {
45
+ if (!servers || servers.length === 0)
46
+ return '';
47
+ const rows = servers
48
+ .map((server) => {
49
+ const who = server.signedIn
50
+ ? `signed in as ${escapeHtml(server.address ?? 'unknown')}` +
51
+ (server.storeTitle ? `, kept in ${escapeHtml(server.storeTitle)}` : '')
52
+ : 'not signed in';
53
+ const mark = server.servesInterface ? ' <span class="state good">shows this page</span>' : '';
54
+ return (`<tr><td><code>${server.pid}</code>${mark}</td><td>${who}</td>` +
55
+ `<td>${escapeHtml(server.version)}</td><td>${escapeHtml(formatTime(server.startedAt))}</td></tr>`);
56
+ })
57
+ .join('\n');
58
+ return `<h2>Running servers (${servers.length})</h2>
59
+ <div class="card"><table>
60
+ <tr><th>Process</th><th>Sign-in</th><th>Version</th><th>Started</th></tr>
61
+ ${rows}
62
+ </table>
63
+ <p class="hint">Each assistant session starts its own server, and all of them share this page and
64
+ its settings. A password kept in the system keyring or in a file reaches every one of them. One kept
65
+ for this session only, or in an encrypted file opened here, stays with the server that shows this
66
+ page.</p></div>`;
67
+ }
36
68
  /**
37
69
  * The first page, and the only one that answers "is this working".
38
70
  *
@@ -52,6 +84,20 @@ export function overviewSection(data) {
52
84
  row('Bridge IMAP', `${data.bridgeHost}:${data.bridgeImapPort}`),
53
85
  row('Bridge SMTP', `${data.bridgeHost}:${data.bridgeSmtpPort}`),
54
86
  row('This interface', `127.0.0.1:${data.webPort}`),
87
+ row('Changes here', data.pinRequired
88
+ ? '<span class="state good">need the PIN</span>'
89
+ : '<span class="state bad">anything on this machine can make them, the assistant included</span>', true),
90
+ row('Assistant permissions', !data.departures || data.departures.length === 0
91
+ ? 'as by default: sending and changing filters ask first, deleting and switching filters is off, everything else acts'
92
+ : data.departures.map((d) => `${d.tool}: ${d.level}`).join(', ')),
93
+ row('Filters may also', data.filterActions && data.filterActions.length > 0
94
+ ? `<span class="state bad">${escapeHtml(UNLOCKABLE.filter((action) => data.filterActions.includes(action))
95
+ .map((action) => UNLOCKABLE_TEXT[action].title.toLowerCase())
96
+ .join(', '))}</span>`
97
+ : 'nothing beyond filing and flags', true),
98
+ row('Copy of everything sent', data.record
99
+ ? `<span class="state bad">${escapeHtml(data.record.address)} (${data.record.mode === 'cc' ? 'Cc' : 'Bcc'})</span>`
100
+ : 'none', true),
55
101
  row('Server running for', formatDuration(data.uptimeMs)),
56
102
  ];
57
103
  const counters = [];
@@ -66,7 +112,8 @@ export function overviewSection(data) {
66
112
  interface: it is for configuration and state, not a mail client.</p>
67
113
 
68
114
  <div class="card"><table>${rows.join('\n')}</table></div>
69
- ${counters.length > 0 ? `<h2>Mailbox counts</h2>\n<div class="card"><table>${counters.join('\n')}</table></div>` : ''}`);
115
+ ${counters.length > 0 ? `<h2>Mailbox counts</h2>\n<div class="card"><table>${counters.join('\n')}</table></div>` : ''}
116
+ ${serverTable(data.servers)}`);
70
117
  }
71
118
  /** Ports, the pinned certificate, and the button that tries the Bridge. */
72
119
  export function bridgeSection(data) {
@@ -74,7 +121,7 @@ export function bridgeSection(data) {
74
121
  ? `<p class="hint">The ports come from the environment (<code>BRIDGE_IMAP_PORT</code> or
75
122
  <code>BRIDGE_SMTP_PORT</code>), so they are not changed here. An explicit setting stays
76
123
  explicit.</p>`
77
- : `<form method="post" action="/settings?token=${escapeHtml(data.token)}">
124
+ : `<form method="post" action="/settings">
78
125
  <input type="hidden" name="csrf" value="${escapeHtml(data.csrfSettings)}">
79
126
  <label for="imapPort">IMAP port</label>
80
127
  <input id="imapPort" name="imapPort" type="text" inputmode="numeric"
@@ -86,6 +133,7 @@ export function bridgeSection(data) {
86
133
  that is not running. You find the real ones in the Bridge under settings. The host is not
87
134
  changeable here on purpose: it would be a field that sends your Bridge password to another
88
135
  machine.</p>
136
+ ${pinField(data.pinRequired === true)}
89
137
  <button type="submit">Save ports</button>
90
138
  </form>`;
91
139
  const certificate = data.certificate
@@ -107,7 +155,7 @@ to. The host stays at <code>${escapeHtml(data.bridgeHost)}</code> and cannot be
107
155
 
108
156
  <h2>Connection test</h2>
109
157
  <div class="card">
110
- <form method="post" action="/test-connection?token=${escapeHtml(data.token)}">
158
+ <form method="post" action="/test-connection">
111
159
  <input type="hidden" name="csrf" value="${escapeHtml(data.csrfTest)}">
112
160
  <p>Checks that the Bridge answers on the ports below and accepts the stored credentials.</p>
113
161
  <button type="submit">Test the connection</button>
@@ -133,10 +181,11 @@ ${row('Kept in', data.storeTitle ?? 'nowhere yet')}
133
181
 
134
182
  <h2>Sign out</h2>
135
183
  <div class="card">
136
- <form method="post" action="/sign-out?token=${escapeHtml(data.token)}">
184
+ <form method="post" action="/sign-out">
137
185
  <input type="hidden" name="csrf" value="${escapeHtml(data.csrfSignOut)}">
138
186
  <p>Removes the stored credentials from wherever they are kept, everywhere at once, and
139
- disconnects.</p>
187
+ disconnects. Every running server signs out with it.</p>
188
+ ${pinField(data.pinRequired === true)}
140
189
  <button type="submit" class="danger">Sign out and forget credentials</button>
141
190
  </form>
142
191
  </div>`);
@@ -209,4 +258,238 @@ ${part.map((m) => `<tr><td><code>${escapeHtml(m.path)}</code></td></tr>`).join('
209
258
  exactly one, from labels, where it can carry any number.</p>
210
259
  ${sections || '<div class="card"><p class="hint">No mailboxes were returned.</p></div>'}`);
211
260
  }
261
+ /**
262
+ * What a filter may do beyond filing and flags: one switch per action, all off
263
+ * by default (Tobi, 06.11.2026). The extension has the same switches in its
264
+ * popup, and an action needs both, so a program that reaches only one of the
265
+ * two cannot allow it.
266
+ */
267
+ function filterActionsForm(data) {
268
+ const view = data.filterActions;
269
+ if (!view)
270
+ return '';
271
+ const rows = UNLOCKABLE.map((action) => {
272
+ const on = view.allowed.includes(action);
273
+ const text = UNLOCKABLE_TEXT[action];
274
+ const control = view.fixed
275
+ ? `<strong>${on ? 'allowed' : 'not allowed'}</strong>`
276
+ : `<input type="checkbox" id="action-${action}" name="action:${action}" value="on"${on ? ' checked' : ''}>`;
277
+ return (`<tr><td>${control}</td><td><label for="action-${action}">${escapeHtml(text.title)}</label></td>` +
278
+ `<td class="hint">${escapeHtml(text.risk)}</td></tr>`);
279
+ }).join('\n');
280
+ const allowed = UNLOCKABLE.filter((action) => view.allowed.includes(action));
281
+ const noPin = data.pinRequired ? '' : '<br><strong>No PIN is set</strong>, so the assistant could also have switched this on itself.';
282
+ const cost = allowed.length
283
+ ? `<div class="error"><strong>An assistant may set up filters that ${escapeHtml(allowed.map((action) => UNLOCKABLE_TEXT[action].title.toLowerCase()).join(', '))}.</strong> A single message can then ask for such a rule, and it keeps acting long after the
284
+ conversation. With ask first you still see each one in the window of the extension before it is saved.${noPin}</div>`
285
+ : '';
286
+ const intro = `<p>A filter an assistant proposes may always file mail into folders and labels and set or clear
287
+ the read and star flags. Anything more is up to you, one action at a time. Not allowed, which is the default,
288
+ the assistant can neither set it up nor change, apply or switch on a filter that does it.</p>`;
289
+ const table = `<table>
290
+ <tr><th></th><th>Action</th><th>What it costs</th></tr>
291
+ ${rows}
292
+ </table>`;
293
+ const after = `<p class="hint">The browser extension has the same switches in its popup, and an action needs
294
+ both. Forwarding is not among them: Proton does not run it in filters, and its own forwarding setting is out
295
+ of reach of these tools. Proton's check of a script and its spam guard stay in place whatever is allowed.</p>`;
296
+ if (view.fixed) {
297
+ return `<h2>What a filter may do</h2>
298
+ <div class="card">${cost}${intro}${table}
299
+ <p class="hint">Set in the environment (<code>PROTON_MCP_FILTER_ACTIONS</code>), so it is not changed here.</p>${after}</div>`;
300
+ }
301
+ return `<h2>What a filter may do</h2>
302
+ <div class="card">
303
+ ${cost}
304
+ ${intro}
305
+ <form method="post" action="/permissions/filter-actions">
306
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfFilterActions ?? '')}">
307
+ ${table}
308
+ ${after}
309
+ ${pinField(data.pinRequired === true)}
310
+ <button type="submit">Save what filters may do</button>
311
+ </form>
312
+ </div>`;
313
+ }
314
+ /** The copy of everything sent: who gets it, and the form to change it. */
315
+ function recordForm(data) {
316
+ const record = data.record;
317
+ if (!record)
318
+ return '';
319
+ const now = record.address
320
+ ? `<p>Every message sent through this server also goes to <code>${escapeHtml(record.address)}</code>
321
+ as ${record.mode === 'cc' ? 'Cc, visible to every recipient' : 'Bcc, invisible to the other recipients'}.</p>`
322
+ : '<p>No copy is added.</p>';
323
+ if (record.fixed) {
324
+ return `<h2>A copy of everything sent</h2>
325
+ <div class="card">${now}<p class="hint">Set in the environment (<code>PROTON_MCP_COPY_TO</code>), so it is
326
+ not changed here.</p></div>`;
327
+ }
328
+ return `<h2>A copy of everything sent</h2>
329
+ <div class="card">
330
+ ${now}
331
+ <form method="post" action="/permissions/record">
332
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfRecord ?? '')}">
333
+ <label for="copyTo">Address</label>
334
+ <input id="copyTo" name="address" type="text" autocomplete="off" spellcheck="false"
335
+ value="${escapeHtml(record.address ?? '')}" placeholder="archive@example.com">
336
+ <label for="copyAs">As</label>
337
+ <select id="copyAs" name="mode">
338
+ <option value="bcc"${record.mode !== 'cc' ? ' selected' : ''}>Bcc: a record the recipients do not see</option>
339
+ <option value="cc"${record.mode === 'cc' ? ' selected' : ''}>Cc: visible to every recipient</option>
340
+ </select>
341
+ <p class="hint">Added to every message every sending tool sends, before the question is asked, so it is
342
+ part of what you confirm, and the question names it as coming from this setting. Nothing the
343
+ assistant passes removes it. Leave the address empty to add nothing.</p>
344
+ ${pinField(data.pinRequired === true)}
345
+ <button type="submit">Save the copy</button>
346
+ </form>
347
+ </div>`;
348
+ }
349
+ const LEVEL_NAMES = {
350
+ off: 'off',
351
+ ask: 'ask first',
352
+ act: 'act on its own',
353
+ };
354
+ /** The table of tools with a choice for each, or the fixed value where the environment decided. */
355
+ function levelTable(data) {
356
+ if (!data.tools || data.tools.length === 0)
357
+ return '';
358
+ const rows = data.tools
359
+ .map((tool) => {
360
+ const choice = tool.fixed
361
+ ? `<strong>${escapeHtml(LEVEL_NAMES[tool.level])}</strong> <span class="hint">(${escapeHtml(tool.source)})</span>`
362
+ : `<select name="level:${escapeHtml(tool.tool)}" aria-label="${escapeHtml(tool.tool)}">` +
363
+ tool.options
364
+ .map((option) => `<option value="${option}"${option === tool.level ? ' selected' : ''}>${escapeHtml(LEVEL_NAMES[option])}</option>`)
365
+ .join('') +
366
+ '</select>';
367
+ return `<tr><td><code>${escapeHtml(tool.tool)}</code></td><td>${escapeHtml(tool.group)}</td><td>${choice}</td></tr>`;
368
+ })
369
+ .join('\n');
370
+ const autonomous = data.tools.filter((tool) => tool.level === 'act' && tool.options.includes('ask'));
371
+ const sending = autonomous.filter((tool) => tool.group !== 'filters');
372
+ const filters = autonomous.filter((tool) => tool.group === 'filters');
373
+ const names = (tools) => `${tools.map((t) => escapeHtml(t.tool)).join(', ')} ${tools.length === 1 ? 'acts' : 'act'} without asking.`;
374
+ const noPin = data.pinRequired ? '' : '<br><strong>No PIN is set</strong>, so the assistant could also have switched this on itself.';
375
+ const cost = (sending.length
376
+ ? `<div class="error"><strong>${names(sending)}</strong> Your private mail, text written by
377
+ strangers and a way out are then together with no person in between: a single message can ask for
378
+ your mailbox to be forwarded, and nobody would see it happen. Bound it below where you can.${noPin}</div>`
379
+ : '') +
380
+ (filters.length
381
+ ? `<div class="error"><strong>${names(filters)}</strong> A single message can then ask for a rule
382
+ that files mail away from you or marks it as read, and the rule keeps acting long after the conversation.
383
+ Applying one changes the mail that is already there, all of it at once. What a filter may do beyond filing
384
+ and flags is set below, and the extension asks for the same in its popup, where it also lists every
385
+ change.${noPin}</div>`
386
+ : '');
387
+ return `<h2>What the assistant may do</h2>
388
+ <div class="card">
389
+ ${cost}
390
+ <form method="post" action="/permissions/levels">
391
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfLevels ?? '')}">
392
+ <table>
393
+ <tr><th>Tool</th><th>Group</th><th>Level</th></tr>
394
+ ${rows}
395
+ </table>
396
+ <p class="hint"><strong>off</strong> takes a tool away from the assistant entirely.
397
+ <strong>ask first</strong> makes it ask you before acting: the sending tools through your client, the
398
+ filter tools in a window of the browser extension. Both do this by default. <strong>act on its own</strong> lets it go ahead. A level set in the server's
399
+ environment wins over this page and is shown here as fixed.</p>
400
+ ${pinField(data.pinRequired === true)}
401
+ <button type="submit">Save the levels</button>
402
+ </form>
403
+ </div>`;
404
+ }
405
+ /** The optional bounds on sending without asking. */
406
+ function limitsForm(data) {
407
+ const limits = data.limits;
408
+ if (!limits)
409
+ return '';
410
+ const fixedNote = (fixed) => (fixed ? ' <span class="hint">(set in the environment)</span>' : '');
411
+ const allowed = limits.fixed.allowed
412
+ ? `<p><code>${escapeHtml(limits.allowed.join(', ') || 'anyone')}</code>${fixedNote(true)}</p>`
413
+ : `<textarea id="allowed" name="allowed" rows="4">${escapeHtml(limits.allowed.join('\n'))}</textarea>`;
414
+ const max = limits.fixed.maxPerHour
415
+ ? `<p><code>${escapeHtml(String(limits.maxPerHour ?? 'no limit'))}</code>${fixedNote(true)}</p>`
416
+ : `<input id="maxPerHour" name="maxPerHour" type="text" inputmode="numeric" value="${escapeHtml(limits.maxPerHour === undefined ? '' : String(limits.maxPerHour))}">`;
417
+ const until = limits.fixed.until
418
+ ? `<p><code>${escapeHtml(limits.until ?? 'none')}</code>${fixedNote(true)}</p>`
419
+ : `<input id="until" name="until" type="date" value="${escapeHtml(limits.until ?? '')}">`;
420
+ return `<h2>Bounds on sending without asking</h2>
421
+ <div class="card">
422
+ <form method="post" action="/permissions/limits">
423
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfLimits ?? '')}">
424
+ <label for="allowed">Permitted recipients</label>
425
+ ${allowed}
426
+ <p class="hint">One per line: a full address, or a domain written as <code>@example.com</code>. Empty
427
+ means anyone. A message to anyone else asks first instead.</p>
428
+ <label for="maxPerHour">At most this many per hour</label>
429
+ ${max}
430
+ <p class="hint">Counted per running server. Beyond it, sending asks first again. Empty means no limit.</p>
431
+ <label for="until">Until this day</label>
432
+ ${until}
433
+ <p class="hint">After this day, sending asks first again until you set a new one. Empty means no end.</p>
434
+ <p class="hint">Every bound is optional. A send outside one asks you instead of failing.</p>
435
+ ${pinField(data.pinRequired === true)}
436
+ <button type="submit">Save the bounds</button>
437
+ </form>
438
+ </div>`;
439
+ }
440
+ /**
441
+ * What the assistant may do, and who may change that.
442
+ *
443
+ * The PIN comes first on this page because everything else on it depends on
444
+ * it. Without one, the settings here are only as safe as every program on this
445
+ * machine, the assistant included: it can open this address with a browser
446
+ * tool as easily as the user can. The page says so plainly instead of leaving
447
+ * it to be discovered.
448
+ */
449
+ export function permissionsSection(data) {
450
+ const pin = data.pinRequired
451
+ ? `<p>A PIN is set. Every change in this interface asks for it.</p>
452
+ <form method="post" action="/pin">
453
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfPin)}">
454
+ <input type="hidden" name="action" value="change">
455
+ ${pinField(true)}
456
+ <label for="next">New PIN</label>
457
+ <input id="next" name="next" type="password" autocomplete="new-password">
458
+ <label for="nextRepeat">New PIN again</label>
459
+ <input id="nextRepeat" name="nextRepeat" type="password" autocomplete="new-password">
460
+ <button type="submit">Change the PIN</button>
461
+ </form>
462
+ <form method="post" action="/pin">
463
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfPin)}">
464
+ <input type="hidden" name="action" value="remove">
465
+ ${pinField(true)}
466
+ <button type="submit" class="danger">Remove the PIN</button>
467
+ </form>`
468
+ : `<div class="error">No PIN is set. Anything running on this machine can change the settings
469
+ here, and so can an assistant with a browser tool, which may then allow itself more than you meant
470
+ to.</div>
471
+ <form method="post" action="/pin">
472
+ <input type="hidden" name="csrf" value="${escapeHtml(data.csrfPin)}">
473
+ <input type="hidden" name="action" value="set">
474
+ <label for="next">PIN</label>
475
+ <input id="next" name="next" type="password" autocomplete="new-password">
476
+ <label for="nextRepeat">PIN again</label>
477
+ <input id="nextRepeat" name="nextRepeat" type="password" autocomplete="new-password">
478
+ <p class="hint">At least 6 characters. It is stored only as a salted hash and never shown to the
479
+ assistant. Type it only into a tab you are using yourself: a tab an assistant is driving at that
480
+ moment can read what is typed into it. A forgotten PIN is removed by deleting the line
481
+ <code>"pin"</code> from the settings file.</p>
482
+ <button type="submit">Set the PIN</button>
483
+ </form>`;
484
+ return frame('permissions', 'Permissions', data, `<h1>Permissions</h1>
485
+ <p class="lead">What an assistant may do through this server, and who may change that. Settings
486
+ made here apply to every running server at once.</p>
487
+
488
+ <h2>PIN</h2>
489
+ <div class="card">${pin}</div>
490
+ ${levelTable(data)}
491
+ ${filterActionsForm(data)}
492
+ ${limitsForm(data)}
493
+ ${recordForm(data)}`);
494
+ }
212
495
  //# sourceMappingURL=sections.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../src/web/sections.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../src/web/sections.ts"],"names":[],"mappings":"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"}