fluxmail 0.4.1 → 0.6.0
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.
- package/README.md +6 -4
- package/dist/accounts/defaultGoogleOAuth.d.ts +4 -0
- package/dist/accounts/defaultGoogleOAuth.d.ts.map +1 -0
- package/dist/accounts/defaultGoogleOAuth.js +7 -0
- package/dist/accounts/defaultGoogleOAuth.js.map +1 -0
- package/dist/accounts/gmailConnection.js +2 -2
- package/dist/accounts/gmailConnection.js.map +1 -1
- package/dist/accounts/googleAuth.d.ts +16 -9
- package/dist/accounts/googleAuth.d.ts.map +1 -1
- package/dist/accounts/googleAuth.js +52 -20
- package/dist/accounts/googleAuth.js.map +1 -1
- package/dist/accounts/microsoftAuth.d.ts +5 -2
- package/dist/accounts/microsoftAuth.d.ts.map +1 -1
- package/dist/accounts/microsoftAuth.js +25 -22
- package/dist/accounts/microsoftAuth.js.map +1 -1
- package/dist/accounts/registry.d.ts +11 -9
- package/dist/accounts/registry.d.ts.map +1 -1
- package/dist/accounts/registry.js +169 -98
- package/dist/accounts/registry.js.map +1 -1
- package/dist/auth.d.ts +106 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +455 -0
- package/dist/auth.js.map +1 -0
- package/dist/authorization.d.ts +9 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +23 -0
- package/dist/authorization.js.map +1 -0
- package/dist/cli.d.ts +15 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1096 -403
- package/dist/cli.js.map +1 -1
- package/dist/cliInstances.d.ts +51 -0
- package/dist/cliInstances.d.ts.map +1 -0
- package/dist/cliInstances.js +237 -0
- package/dist/cliInstances.js.map +1 -0
- package/dist/cliMail.d.ts +9 -0
- package/dist/cliMail.d.ts.map +1 -0
- package/dist/cliMail.js +450 -0
- package/dist/cliMail.js.map +1 -0
- package/dist/config.d.ts +95 -118
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +351 -286
- package/dist/config.js.map +1 -1
- package/dist/configMigration.d.ts +8 -0
- package/dist/configMigration.d.ts.map +1 -0
- package/dist/configMigration.js +234 -0
- package/dist/configMigration.js.map +1 -0
- package/dist/context.d.ts +8 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +29 -8
- package/dist/context.js.map +1 -1
- package/dist/deploymentConfig.d.ts +190 -0
- package/dist/deploymentConfig.d.ts.map +1 -0
- package/dist/deploymentConfig.js +539 -0
- package/dist/deploymentConfig.js.map +1 -0
- package/dist/http/admin.d.ts +75 -3
- package/dist/http/admin.d.ts.map +1 -1
- package/dist/http/admin.js +347 -79
- package/dist/http/admin.js.map +1 -1
- package/dist/http/app.d.ts +4 -1
- package/dist/http/app.d.ts.map +1 -1
- package/dist/http/app.js +119 -63
- package/dist/http/app.js.map +1 -1
- package/dist/http/identity.d.ts +114 -0
- package/dist/http/identity.d.ts.map +1 -0
- package/dist/http/identity.js +936 -0
- package/dist/http/identity.js.map +1 -0
- package/dist/http/operationRoutes.d.ts +8 -0
- package/dist/http/operationRoutes.d.ts.map +1 -0
- package/dist/http/operationRoutes.js +13 -0
- package/dist/http/operationRoutes.js.map +1 -0
- package/dist/http/rest.d.ts +16 -4
- package/dist/http/rest.d.ts.map +1 -1
- package/dist/http/rest.js +213 -71
- package/dist/http/rest.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/instanceConfig.d.ts +36 -0
- package/dist/instanceConfig.d.ts.map +1 -0
- package/dist/instanceConfig.js +157 -0
- package/dist/instanceConfig.js.map +1 -0
- package/dist/licensing/activation.d.ts +2 -1
- package/dist/licensing/activation.d.ts.map +1 -1
- package/dist/licensing/activation.js +2 -3
- package/dist/licensing/activation.js.map +1 -1
- package/dist/licensing/entitlements.d.ts.map +1 -1
- package/dist/licensing/entitlements.js +2 -2
- package/dist/licensing/entitlements.js.map +1 -1
- package/dist/licensing/refresher.d.ts +6 -1
- package/dist/licensing/refresher.d.ts.map +1 -1
- package/dist/licensing/refresher.js +18 -7
- package/dist/licensing/refresher.js.map +1 -1
- package/dist/logging.d.ts +87 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +612 -0
- package/dist/logging.js.map +1 -0
- package/dist/mcp/buildServer.d.ts +3 -1
- package/dist/mcp/buildServer.d.ts.map +1 -1
- package/dist/mcp/buildServer.js +27 -24
- package/dist/mcp/buildServer.js.map +1 -1
- package/dist/permissions.d.ts +1 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +10 -4
- package/dist/permissions.js.map +1 -1
- package/dist/scheduler/sendScheduler.d.ts +4 -3
- package/dist/scheduler/sendScheduler.d.ts.map +1 -1
- package/dist/scheduler/sendScheduler.js +15 -3
- package/dist/scheduler/sendScheduler.js.map +1 -1
- package/dist/service/emailService.d.ts +10 -17
- package/dist/service/emailService.d.ts.map +1 -1
- package/dist/service/emailService.js +28 -38
- package/dist/service/emailService.js.map +1 -1
- package/dist/storage/adminAudit.d.ts +15 -2
- package/dist/storage/adminAudit.d.ts.map +1 -1
- package/dist/storage/adminAudit.js +22 -27
- package/dist/storage/adminAudit.js.map +1 -1
- package/dist/storage/apiKeys.d.ts +8 -8
- package/dist/storage/apiKeys.d.ts.map +1 -1
- package/dist/storage/apiKeys.js +16 -11
- package/dist/storage/apiKeys.js.map +1 -1
- package/dist/storage/db.d.ts +596 -31
- package/dist/storage/db.d.ts.map +1 -1
- package/dist/storage/db.js +383 -45
- package/dist/storage/db.js.map +1 -1
- package/dist/storage/fileLock.d.ts +7 -0
- package/dist/storage/fileLock.d.ts.map +1 -0
- package/dist/storage/fileLock.js +183 -0
- package/dist/storage/fileLock.js.map +1 -0
- package/dist/storage/gmailConnectionGrants.d.ts +3 -4
- package/dist/storage/gmailConnectionGrants.d.ts.map +1 -1
- package/dist/storage/gmailConnectionGrants.js +6 -6
- package/dist/storage/gmailConnectionGrants.js.map +1 -1
- package/dist/storage/members.d.ts +11 -0
- package/dist/storage/members.d.ts.map +1 -1
- package/dist/storage/members.js +70 -6
- package/dist/storage/members.js.map +1 -1
- package/dist/telemetry.d.ts +17 -2
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +34 -19
- package/dist/telemetry.js.map +1 -1
- package/dist/updateNotifier.d.ts +18 -0
- package/dist/updateNotifier.d.ts.map +1 -0
- package/dist/updateNotifier.js +128 -0
- package/dist/updateNotifier.js.map +1 -0
- package/package.json +38 -5
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { chmodSync, closeSync, existsSync, fsyncSync, linkSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { parse, stringify } from 'smol-toml';
|
|
6
|
+
import { withFileLock } from './storage/fileLock.js';
|
|
7
|
+
export const DEPLOYMENT_REFERENCE = {
|
|
8
|
+
dataDir: {
|
|
9
|
+
canonicalName: 'deployment.data_dir',
|
|
10
|
+
env: 'FLUXMAIL_DATA_DIR',
|
|
11
|
+
type: 'path',
|
|
12
|
+
validation: 'Filesystem path',
|
|
13
|
+
defaultValue: '~/.fluxmail (/data in Docker)',
|
|
14
|
+
description: 'Directory for the SQLite database, deployment configuration, and generated encryption key.',
|
|
15
|
+
restartRequired: true,
|
|
16
|
+
},
|
|
17
|
+
dbPath: {
|
|
18
|
+
canonicalName: 'storage.database_path',
|
|
19
|
+
env: 'FLUXMAIL_DB_PATH',
|
|
20
|
+
toml: 'storage.database_path',
|
|
21
|
+
type: 'path',
|
|
22
|
+
validation: 'Non-empty filesystem path',
|
|
23
|
+
defaultValue: '<data dir>/fluxmail.db',
|
|
24
|
+
description: 'Override the SQLite database path.',
|
|
25
|
+
restartRequired: true,
|
|
26
|
+
},
|
|
27
|
+
encryptionKey: {
|
|
28
|
+
canonicalName: 'deployment.encryption_key',
|
|
29
|
+
env: 'FLUXMAIL_ENCRYPTION_KEY',
|
|
30
|
+
type: 'secret',
|
|
31
|
+
validation: 'Exactly 64 hexadecimal characters',
|
|
32
|
+
defaultValue: 'generated automatically',
|
|
33
|
+
description: 'A 64-character hexadecimal key used to encrypt credentials and instance secrets.',
|
|
34
|
+
secret: true,
|
|
35
|
+
restartRequired: true,
|
|
36
|
+
},
|
|
37
|
+
port: {
|
|
38
|
+
canonicalName: 'server.port',
|
|
39
|
+
env: 'FLUXMAIL_PORT',
|
|
40
|
+
toml: 'server.port',
|
|
41
|
+
type: 'integer',
|
|
42
|
+
validation: 'Integer from 1 through 65535',
|
|
43
|
+
defaultValue: '8977',
|
|
44
|
+
description: 'HTTP server port.',
|
|
45
|
+
restartRequired: true,
|
|
46
|
+
},
|
|
47
|
+
publicUrl: {
|
|
48
|
+
canonicalName: 'server.public_url',
|
|
49
|
+
env: 'FLUXMAIL_PUBLIC_URL',
|
|
50
|
+
toml: 'server.public_url',
|
|
51
|
+
type: 'url',
|
|
52
|
+
validation: 'HTTP or HTTPS URL without credentials, query, or fragment',
|
|
53
|
+
defaultValue: 'http://localhost:<FLUXMAIL_PORT>',
|
|
54
|
+
description: 'Public base URL used for HTTP APIs and hosted OAuth callbacks.',
|
|
55
|
+
restartRequired: true,
|
|
56
|
+
},
|
|
57
|
+
trustProxy: {
|
|
58
|
+
canonicalName: 'server.trust_proxy',
|
|
59
|
+
env: 'FLUXMAIL_TRUST_PROXY',
|
|
60
|
+
toml: 'server.trust_proxy',
|
|
61
|
+
type: 'boolean',
|
|
62
|
+
validation: 'Boolean',
|
|
63
|
+
defaultValue: 'false',
|
|
64
|
+
description: 'Trust forwarded protocol and client address headers from a reverse proxy.',
|
|
65
|
+
restartRequired: true,
|
|
66
|
+
},
|
|
67
|
+
oauthPort: {
|
|
68
|
+
canonicalName: 'oauth.local.port',
|
|
69
|
+
env: 'FLUXMAIL_OAUTH_PORT',
|
|
70
|
+
toml: 'oauth.local.port',
|
|
71
|
+
type: 'integer',
|
|
72
|
+
validation: 'Integer from 1 through 65535',
|
|
73
|
+
defaultValue: '8976',
|
|
74
|
+
description: 'Port for the local OAuth callback listener.',
|
|
75
|
+
restartRequired: true,
|
|
76
|
+
},
|
|
77
|
+
oauthHost: {
|
|
78
|
+
canonicalName: 'oauth.local.host',
|
|
79
|
+
env: 'FLUXMAIL_OAUTH_HOST',
|
|
80
|
+
toml: 'oauth.local.host',
|
|
81
|
+
type: 'string',
|
|
82
|
+
validation: 'Non-empty bind host or address',
|
|
83
|
+
defaultValue: '127.0.0.1',
|
|
84
|
+
description: 'Bind address for the local OAuth callback listener.',
|
|
85
|
+
restartRequired: true,
|
|
86
|
+
},
|
|
87
|
+
maxAttachmentBytes: {
|
|
88
|
+
canonicalName: 'server.max_attachment_mb',
|
|
89
|
+
env: 'FLUXMAIL_MAX_ATTACHMENT_MB',
|
|
90
|
+
toml: 'server.max_attachment_mb',
|
|
91
|
+
type: 'integer',
|
|
92
|
+
validation: 'Integer from 1 through 25',
|
|
93
|
+
defaultValue: '10',
|
|
94
|
+
description: 'Largest decoded attachment returned through MCP or REST, from 1 through 25 MB.',
|
|
95
|
+
restartRequired: true,
|
|
96
|
+
},
|
|
97
|
+
logLevel: {
|
|
98
|
+
canonicalName: 'logging.level',
|
|
99
|
+
env: 'FLUXMAIL_LOG_LEVEL',
|
|
100
|
+
toml: 'logging.level',
|
|
101
|
+
type: 'string',
|
|
102
|
+
validation: 'info, warn, error, or off',
|
|
103
|
+
defaultValue: 'info',
|
|
104
|
+
description: 'Minimum severity retained by the bounded local logger.',
|
|
105
|
+
restartRequired: true,
|
|
106
|
+
},
|
|
107
|
+
logDestination: {
|
|
108
|
+
canonicalName: 'logging.destination',
|
|
109
|
+
env: 'FLUXMAIL_LOG_DESTINATION',
|
|
110
|
+
toml: 'logging.destination',
|
|
111
|
+
type: 'string',
|
|
112
|
+
validation: 'both, file, or console',
|
|
113
|
+
defaultValue: 'both',
|
|
114
|
+
description: 'Write local logs to both the rotating file and console, or choose file or console.',
|
|
115
|
+
restartRequired: true,
|
|
116
|
+
},
|
|
117
|
+
licenseServerUrl: {
|
|
118
|
+
canonicalName: 'licensing.server_url',
|
|
119
|
+
env: 'FLUXMAIL_LICENSE_SERVER_URL',
|
|
120
|
+
toml: 'licensing.server_url',
|
|
121
|
+
type: 'url',
|
|
122
|
+
validation: 'HTTP or HTTPS URL',
|
|
123
|
+
defaultValue: 'https://fluxmail.ai',
|
|
124
|
+
description: 'License validation service override used for development and testing.',
|
|
125
|
+
documented: false,
|
|
126
|
+
restartRequired: true,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
const CONFIG_LOCK_TIMEOUT_MS = 5_000;
|
|
130
|
+
const CONFIG_LOCK_STALE_MS = 30_000;
|
|
131
|
+
const BYTES_PER_MEGABYTE = 1024 * 1024;
|
|
132
|
+
export const DEFAULT_MAX_ATTACHMENT_BYTES = 10 * BYTES_PER_MEGABYTE;
|
|
133
|
+
export const HARD_MAX_ATTACHMENT_BYTES = 25 * BYTES_PER_MEGABYTE;
|
|
134
|
+
export function expandHome(value) {
|
|
135
|
+
if (value === '~')
|
|
136
|
+
return homedir();
|
|
137
|
+
if (value.startsWith('~/'))
|
|
138
|
+
return path.join(homedir(), value.slice(2));
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
141
|
+
export function resolveDataDirectory(env = process.env) {
|
|
142
|
+
const configured = env.FLUXMAIL_DATA_DIR;
|
|
143
|
+
return configured ? expandHome(configured) : path.join(homedir(), '.fluxmail');
|
|
144
|
+
}
|
|
145
|
+
function readToml(file) {
|
|
146
|
+
if (!existsSync(file))
|
|
147
|
+
return {};
|
|
148
|
+
let parsed;
|
|
149
|
+
try {
|
|
150
|
+
parsed = parse(readFileSync(file, 'utf8'));
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
throw new Error(`Could not parse ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
154
|
+
}
|
|
155
|
+
validateTomlKeys(parsed, file);
|
|
156
|
+
return parsed;
|
|
157
|
+
}
|
|
158
|
+
const ALLOWED_TOML_KEYS = new Set([
|
|
159
|
+
'storage',
|
|
160
|
+
'storage.database_path',
|
|
161
|
+
'server',
|
|
162
|
+
'server.port',
|
|
163
|
+
'server.public_url',
|
|
164
|
+
'server.trust_proxy',
|
|
165
|
+
'server.max_attachment_mb',
|
|
166
|
+
'oauth',
|
|
167
|
+
'oauth.local',
|
|
168
|
+
'oauth.local.host',
|
|
169
|
+
'oauth.local.port',
|
|
170
|
+
'logging',
|
|
171
|
+
'logging.level',
|
|
172
|
+
'logging.destination',
|
|
173
|
+
'licensing',
|
|
174
|
+
'licensing.server_url',
|
|
175
|
+
]);
|
|
176
|
+
const TOML_TABLE_KEYS = new Set(['storage', 'server', 'oauth', 'oauth.local', 'logging', 'licensing']);
|
|
177
|
+
function isTomlTable(value) {
|
|
178
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);
|
|
179
|
+
}
|
|
180
|
+
function validateTomlKeys(table, file, prefix = '') {
|
|
181
|
+
for (const [key, value] of Object.entries(table)) {
|
|
182
|
+
const dotted = prefix ? `${prefix}.${key}` : key;
|
|
183
|
+
if (!ALLOWED_TOML_KEYS.has(dotted))
|
|
184
|
+
throw new Error(`Unknown setting "${dotted}" in ${file}`);
|
|
185
|
+
const nested = isTomlTable(value);
|
|
186
|
+
if (TOML_TABLE_KEYS.has(dotted) && !nested)
|
|
187
|
+
throw new Error(`"${dotted}" must be a TOML table in ${file}`);
|
|
188
|
+
if (nested)
|
|
189
|
+
validateTomlKeys(value, file, dotted);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function tomlValue(table, dotted) {
|
|
193
|
+
let value = table;
|
|
194
|
+
for (const part of dotted.split('.')) {
|
|
195
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
196
|
+
return undefined;
|
|
197
|
+
value = value[part];
|
|
198
|
+
}
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
function sourceValue(env, table, setting) {
|
|
202
|
+
const reference = DEPLOYMENT_REFERENCE[setting];
|
|
203
|
+
if (env[reference.env] !== undefined)
|
|
204
|
+
return { value: env[reference.env], source: 'environment' };
|
|
205
|
+
const tomlName = reference.toml;
|
|
206
|
+
const fromToml = tomlName ? tomlValue(table, tomlName) : undefined;
|
|
207
|
+
if (fromToml !== undefined)
|
|
208
|
+
return { value: fromToml, source: 'toml' };
|
|
209
|
+
return { value: undefined, source: 'default' };
|
|
210
|
+
}
|
|
211
|
+
function stringValue(name, input, fallback) {
|
|
212
|
+
if (input === undefined)
|
|
213
|
+
return fallback;
|
|
214
|
+
if (typeof input !== 'string')
|
|
215
|
+
throw new Error(`${name} must be a string`);
|
|
216
|
+
return input;
|
|
217
|
+
}
|
|
218
|
+
function pathValue(name, input, fallback) {
|
|
219
|
+
return nonEmptyStringValue(name, input, fallback);
|
|
220
|
+
}
|
|
221
|
+
function nonEmptyStringValue(name, input, fallback) {
|
|
222
|
+
const value = stringValue(name, input, fallback);
|
|
223
|
+
if (!value.trim())
|
|
224
|
+
throw new Error(`${name} cannot be empty.`);
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
function portValue(name, input, fallback) {
|
|
228
|
+
if (input === undefined)
|
|
229
|
+
return fallback;
|
|
230
|
+
const value = typeof input === 'number' ? input : Number(input);
|
|
231
|
+
if (!Number.isInteger(value) || value < 1 || value > 65_535) {
|
|
232
|
+
throw new Error(`${name} must be an integer between 1 and 65535, got "${String(input)}"`);
|
|
233
|
+
}
|
|
234
|
+
return value;
|
|
235
|
+
}
|
|
236
|
+
function booleanValue(name, input, fallback) {
|
|
237
|
+
if (input === undefined)
|
|
238
|
+
return fallback;
|
|
239
|
+
if (typeof input === 'boolean')
|
|
240
|
+
return input;
|
|
241
|
+
if (typeof input === 'string') {
|
|
242
|
+
const normalized = input.trim().toLowerCase();
|
|
243
|
+
if (normalized === '1' || normalized === 'true')
|
|
244
|
+
return true;
|
|
245
|
+
if (normalized === '0' || normalized === 'false')
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
throw new Error(`${name} must be 0, 1, false, or true, got "${String(input)}"`);
|
|
249
|
+
}
|
|
250
|
+
function maxAttachmentValue(input) {
|
|
251
|
+
if (input === undefined)
|
|
252
|
+
return DEFAULT_MAX_ATTACHMENT_BYTES;
|
|
253
|
+
const value = typeof input === 'number' ? input : Number(input);
|
|
254
|
+
const maximum = HARD_MAX_ATTACHMENT_BYTES / BYTES_PER_MEGABYTE;
|
|
255
|
+
if (!Number.isInteger(value) || value < 1 || value > maximum) {
|
|
256
|
+
throw new Error(`FLUXMAIL_MAX_ATTACHMENT_MB must be an integer between 1 and ${maximum}, got "${String(input)}"`);
|
|
257
|
+
}
|
|
258
|
+
return value * BYTES_PER_MEGABYTE;
|
|
259
|
+
}
|
|
260
|
+
function logLevelValue(input) {
|
|
261
|
+
const value = nonEmptyStringValue('FLUXMAIL_LOG_LEVEL', input, 'info').trim().toLowerCase();
|
|
262
|
+
if (value !== 'info' && value !== 'warn' && value !== 'error' && value !== 'off') {
|
|
263
|
+
throw new Error(`FLUXMAIL_LOG_LEVEL must be info, warn, error, or off, got "${value}"`);
|
|
264
|
+
}
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
function logDestinationValue(input) {
|
|
268
|
+
const value = nonEmptyStringValue('FLUXMAIL_LOG_DESTINATION', input, 'both').trim().toLowerCase();
|
|
269
|
+
if (value !== 'both' && value !== 'file' && value !== 'console') {
|
|
270
|
+
throw new Error(`FLUXMAIL_LOG_DESTINATION must be both, file, or console, got "${value}"`);
|
|
271
|
+
}
|
|
272
|
+
return value;
|
|
273
|
+
}
|
|
274
|
+
function publicUrlValue(input, port) {
|
|
275
|
+
const value = stringValue('FLUXMAIL_PUBLIC_URL', input, `http://localhost:${port}`).replace(/\/+$/, '');
|
|
276
|
+
let parsed;
|
|
277
|
+
try {
|
|
278
|
+
parsed = new URL(value);
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
throw new Error(`FLUXMAIL_PUBLIC_URL must be a valid HTTP or HTTPS URL, got "${value}"`);
|
|
282
|
+
}
|
|
283
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
284
|
+
throw new Error(`FLUXMAIL_PUBLIC_URL must use HTTP or HTTPS, got "${parsed.protocol}"`);
|
|
285
|
+
}
|
|
286
|
+
if (parsed.username || parsed.password)
|
|
287
|
+
throw new Error('FLUXMAIL_PUBLIC_URL cannot contain embedded credentials');
|
|
288
|
+
if (parsed.search || parsed.hash)
|
|
289
|
+
throw new Error('FLUXMAIL_PUBLIC_URL cannot contain a query string or fragment');
|
|
290
|
+
return value;
|
|
291
|
+
}
|
|
292
|
+
export function deploymentTomlValuesFromEnvironment(env) {
|
|
293
|
+
const values = {};
|
|
294
|
+
if (env.FLUXMAIL_DB_PATH !== undefined) {
|
|
295
|
+
values.dbPath = stringValue('FLUXMAIL_DB_PATH', env.FLUXMAIL_DB_PATH, '');
|
|
296
|
+
}
|
|
297
|
+
if (env.FLUXMAIL_PORT !== undefined) {
|
|
298
|
+
values.port = portValue('FLUXMAIL_PORT', env.FLUXMAIL_PORT, 8977);
|
|
299
|
+
}
|
|
300
|
+
if (env.FLUXMAIL_PUBLIC_URL !== undefined) {
|
|
301
|
+
values.publicUrl = publicUrlValue(env.FLUXMAIL_PUBLIC_URL, values.port ?? 8977);
|
|
302
|
+
}
|
|
303
|
+
if (env.FLUXMAIL_TRUST_PROXY !== undefined) {
|
|
304
|
+
values.trustProxy = booleanValue('FLUXMAIL_TRUST_PROXY', env.FLUXMAIL_TRUST_PROXY, false);
|
|
305
|
+
}
|
|
306
|
+
if (env.FLUXMAIL_OAUTH_PORT !== undefined) {
|
|
307
|
+
values.oauthPort = portValue('FLUXMAIL_OAUTH_PORT', env.FLUXMAIL_OAUTH_PORT, 8976);
|
|
308
|
+
}
|
|
309
|
+
if (env.FLUXMAIL_OAUTH_HOST !== undefined) {
|
|
310
|
+
values.oauthHost = stringValue('FLUXMAIL_OAUTH_HOST', env.FLUXMAIL_OAUTH_HOST, '127.0.0.1');
|
|
311
|
+
}
|
|
312
|
+
if (env.FLUXMAIL_MAX_ATTACHMENT_MB !== undefined) {
|
|
313
|
+
values.maxAttachmentMb = maxAttachmentValue(env.FLUXMAIL_MAX_ATTACHMENT_MB) / BYTES_PER_MEGABYTE;
|
|
314
|
+
}
|
|
315
|
+
if (env.FLUXMAIL_LOG_LEVEL !== undefined) {
|
|
316
|
+
values.logLevel = logLevelValue(env.FLUXMAIL_LOG_LEVEL);
|
|
317
|
+
}
|
|
318
|
+
if (env.FLUXMAIL_LOG_DESTINATION !== undefined) {
|
|
319
|
+
values.logDestination = logDestinationValue(env.FLUXMAIL_LOG_DESTINATION);
|
|
320
|
+
}
|
|
321
|
+
if (env.FLUXMAIL_LICENSE_SERVER_URL !== undefined) {
|
|
322
|
+
values.licenseServerUrl = stringValue('FLUXMAIL_LICENSE_SERVER_URL', env.FLUXMAIL_LICENSE_SERVER_URL, '');
|
|
323
|
+
}
|
|
324
|
+
return values;
|
|
325
|
+
}
|
|
326
|
+
export function readSecretEnvironment(env, name, options = {}) {
|
|
327
|
+
const configuredDirect = env[name];
|
|
328
|
+
const direct = options.blank === 'unset' && configuredDirect !== undefined && !configuredDirect.trim()
|
|
329
|
+
? undefined
|
|
330
|
+
: configuredDirect;
|
|
331
|
+
const file = env[`${name}_FILE`];
|
|
332
|
+
if (direct !== undefined && file !== undefined) {
|
|
333
|
+
throw new Error(`Set only one of ${name} and ${name}_FILE`);
|
|
334
|
+
}
|
|
335
|
+
if (direct !== undefined) {
|
|
336
|
+
if (!direct)
|
|
337
|
+
throw new Error(`${name} cannot be empty`);
|
|
338
|
+
return { value: direct, source: 'environment' };
|
|
339
|
+
}
|
|
340
|
+
if (file !== undefined) {
|
|
341
|
+
if (!path.isAbsolute(file))
|
|
342
|
+
throw new Error(`${name}_FILE must be an absolute path`);
|
|
343
|
+
let value;
|
|
344
|
+
try {
|
|
345
|
+
value = readFileSync(file, 'utf8').replace(/\r?\n$/, '');
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
throw new Error(`Could not read ${name}_FILE: ${error instanceof Error ? error.message : String(error)}`);
|
|
349
|
+
}
|
|
350
|
+
if (!value)
|
|
351
|
+
throw new Error(`${name}_FILE points to an empty file`);
|
|
352
|
+
return { value, source: 'environment-file' };
|
|
353
|
+
}
|
|
354
|
+
return {};
|
|
355
|
+
}
|
|
356
|
+
function decodeEncryptionKey(value, message) {
|
|
357
|
+
if (!/^[0-9a-fA-F]{64}$/.test(value))
|
|
358
|
+
throw new Error(message);
|
|
359
|
+
return Buffer.from(value, 'hex');
|
|
360
|
+
}
|
|
361
|
+
function tryRestrictPermissions(file) {
|
|
362
|
+
try {
|
|
363
|
+
chmodSync(file, 0o600);
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// The subsequent read or write reports actionable permission failures.
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function trySyncDirectory(directory) {
|
|
370
|
+
let descriptor;
|
|
371
|
+
try {
|
|
372
|
+
descriptor = openSync(directory, 'r');
|
|
373
|
+
fsyncSync(descriptor);
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// Some filesystems do not support directory fsync.
|
|
377
|
+
}
|
|
378
|
+
finally {
|
|
379
|
+
if (descriptor !== undefined)
|
|
380
|
+
closeSync(descriptor);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function resolveEncryptionKey(dataDir, env, generateIfMissing) {
|
|
384
|
+
const configured = readSecretEnvironment(env, 'FLUXMAIL_ENCRYPTION_KEY');
|
|
385
|
+
if (configured.value) {
|
|
386
|
+
return {
|
|
387
|
+
value: decodeEncryptionKey(configured.value, 'FLUXMAIL_ENCRYPTION_KEY must be exactly 64 hex characters (32 bytes)'),
|
|
388
|
+
source: configured.source,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const keyPath = path.join(dataDir, 'encryption.key');
|
|
392
|
+
if (existsSync(keyPath)) {
|
|
393
|
+
tryRestrictPermissions(keyPath);
|
|
394
|
+
return {
|
|
395
|
+
value: decodeEncryptionKey(readFileSync(keyPath, 'utf8').trim(), `Corrupt encryption key at ${keyPath}`),
|
|
396
|
+
source: 'stored',
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
if (!generateIfMissing)
|
|
400
|
+
return { value: Buffer.alloc(0), source: 'default' };
|
|
401
|
+
return withFileLock(path.join(dataDir, '.encryption-key.lock'), {
|
|
402
|
+
timeoutMs: CONFIG_LOCK_TIMEOUT_MS,
|
|
403
|
+
staleMs: CONFIG_LOCK_STALE_MS,
|
|
404
|
+
description: `the encryption key at ${keyPath}`,
|
|
405
|
+
}, () => {
|
|
406
|
+
if (existsSync(keyPath)) {
|
|
407
|
+
tryRestrictPermissions(keyPath);
|
|
408
|
+
return {
|
|
409
|
+
value: decodeEncryptionKey(readFileSync(keyPath, 'utf8').trim(), `Corrupt encryption key at ${keyPath}`),
|
|
410
|
+
source: 'stored',
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const value = randomBytes(32);
|
|
414
|
+
const temporary = path.join(dataDir, `.encryption.key.${process.pid}.${randomBytes(6).toString('hex')}.tmp`);
|
|
415
|
+
let descriptor;
|
|
416
|
+
try {
|
|
417
|
+
descriptor = openSync(temporary, 'wx', 0o600);
|
|
418
|
+
writeFileSync(descriptor, `${value.toString('hex')}\n`, 'utf8');
|
|
419
|
+
fsyncSync(descriptor);
|
|
420
|
+
closeSync(descriptor);
|
|
421
|
+
descriptor = undefined;
|
|
422
|
+
renameSync(temporary, keyPath);
|
|
423
|
+
trySyncDirectory(dataDir);
|
|
424
|
+
return { value, source: 'generated' };
|
|
425
|
+
}
|
|
426
|
+
finally {
|
|
427
|
+
if (descriptor !== undefined)
|
|
428
|
+
closeSync(descriptor);
|
|
429
|
+
rmSync(temporary, { force: true });
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
export function configTomlPath(dataDir) {
|
|
434
|
+
return path.join(dataDir, 'config.toml');
|
|
435
|
+
}
|
|
436
|
+
export function resolveDeploymentConfig(options) {
|
|
437
|
+
const baseEnvironment = options.env ?? process.env;
|
|
438
|
+
const dataDirRaw = baseEnvironment.FLUXMAIL_DATA_DIR;
|
|
439
|
+
const dataDir = resolveDataDirectory(baseEnvironment);
|
|
440
|
+
mkdirSync(dataDir, { recursive: true });
|
|
441
|
+
const environment = { ...baseEnvironment };
|
|
442
|
+
const configFile = configTomlPath(dataDir);
|
|
443
|
+
const table = readToml(configFile);
|
|
444
|
+
const sources = {};
|
|
445
|
+
sources.dataDir = dataDirRaw !== undefined ? 'environment' : 'default';
|
|
446
|
+
const deploymentValue = (setting) => {
|
|
447
|
+
const resolved = sourceValue(environment, table, setting);
|
|
448
|
+
sources[setting] = resolved.source;
|
|
449
|
+
return resolved.value;
|
|
450
|
+
};
|
|
451
|
+
const dbRaw = pathValue('FLUXMAIL_DB_PATH', deploymentValue('dbPath'), path.join(dataDir, 'fluxmail.db'));
|
|
452
|
+
const portNumber = portValue('FLUXMAIL_PORT', deploymentValue('port'), 8977);
|
|
453
|
+
const publicUrl = deploymentValue('publicUrl');
|
|
454
|
+
const trustProxy = deploymentValue('trustProxy');
|
|
455
|
+
const oauthPort = deploymentValue('oauthPort');
|
|
456
|
+
const oauthHost = deploymentValue('oauthHost');
|
|
457
|
+
const maxAttachment = deploymentValue('maxAttachmentBytes');
|
|
458
|
+
const logLevel = deploymentValue('logLevel');
|
|
459
|
+
const logDestination = deploymentValue('logDestination');
|
|
460
|
+
const licenseServer = deploymentValue('licenseServerUrl');
|
|
461
|
+
const encryption = resolveEncryptionKey(dataDir, environment, options.generateEncryptionKey !== false);
|
|
462
|
+
sources.encryptionKey = encryption.source;
|
|
463
|
+
return {
|
|
464
|
+
dataDir,
|
|
465
|
+
dbPath: expandHome(dbRaw),
|
|
466
|
+
encryptionKey: encryption.value,
|
|
467
|
+
port: portNumber,
|
|
468
|
+
publicUrl: publicUrlValue(publicUrl, portNumber),
|
|
469
|
+
publicUrlConfigured: publicUrl !== undefined,
|
|
470
|
+
trustProxy: booleanValue('FLUXMAIL_TRUST_PROXY', trustProxy, false),
|
|
471
|
+
oauthPort: portValue('FLUXMAIL_OAUTH_PORT', oauthPort, 8976),
|
|
472
|
+
oauthHost: nonEmptyStringValue('FLUXMAIL_OAUTH_HOST', oauthHost, '127.0.0.1'),
|
|
473
|
+
maxAttachmentBytes: maxAttachmentValue(maxAttachment),
|
|
474
|
+
logLevel: logLevelValue(logLevel),
|
|
475
|
+
logDestination: logDestinationValue(logDestination),
|
|
476
|
+
licenseServerUrl: stringValue('FLUXMAIL_LICENSE_SERVER_URL', licenseServer, options.defaultLicenseServerUrl).replace(/\/+$/, ''),
|
|
477
|
+
configFile,
|
|
478
|
+
environment,
|
|
479
|
+
sources,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
export function ensureDeploymentEncryptionKey(deployment) {
|
|
483
|
+
if (deployment.encryptionKey.length)
|
|
484
|
+
return deployment;
|
|
485
|
+
const encryption = resolveEncryptionKey(deployment.dataDir, deployment.environment, true);
|
|
486
|
+
return {
|
|
487
|
+
...deployment,
|
|
488
|
+
encryptionKey: encryption.value,
|
|
489
|
+
sources: { ...deployment.sources, encryptionKey: encryption.source },
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
export function deploymentToml(values = {}) {
|
|
493
|
+
return stringify({
|
|
494
|
+
storage: values.dbPath ? { database_path: values.dbPath } : {},
|
|
495
|
+
server: {
|
|
496
|
+
port: values.port ?? 8977,
|
|
497
|
+
...(values.publicUrl ? { public_url: values.publicUrl } : {}),
|
|
498
|
+
trust_proxy: values.trustProxy ?? false,
|
|
499
|
+
max_attachment_mb: values.maxAttachmentMb ?? 10,
|
|
500
|
+
},
|
|
501
|
+
oauth: { local: { host: values.oauthHost ?? '127.0.0.1', port: values.oauthPort ?? 8976 } },
|
|
502
|
+
logging: { level: values.logLevel ?? 'info', destination: values.logDestination ?? 'both' },
|
|
503
|
+
...(values.licenseServerUrl ? { licensing: { server_url: values.licenseServerUrl } } : {}),
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
export function writeDeploymentConfig(file, content, options = {}) {
|
|
507
|
+
const directory = path.dirname(file);
|
|
508
|
+
mkdirSync(directory, { recursive: true });
|
|
509
|
+
const temporary = path.join(directory, `.config.toml.${process.pid}.${randomBytes(6).toString('hex')}.tmp`);
|
|
510
|
+
let descriptor;
|
|
511
|
+
try {
|
|
512
|
+
descriptor = openSync(temporary, 'wx', 0o600);
|
|
513
|
+
writeFileSync(descriptor, content.endsWith('\n') ? content : `${content}\n`, 'utf8');
|
|
514
|
+
fsyncSync(descriptor);
|
|
515
|
+
closeSync(descriptor);
|
|
516
|
+
descriptor = undefined;
|
|
517
|
+
if (options.exclusive) {
|
|
518
|
+
try {
|
|
519
|
+
linkSync(temporary, file);
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
if (error.code === 'EEXIST')
|
|
523
|
+
throw new Error(`${file} already exists`);
|
|
524
|
+
throw error;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
renameSync(temporary, file);
|
|
529
|
+
}
|
|
530
|
+
tryRestrictPermissions(file);
|
|
531
|
+
trySyncDirectory(directory);
|
|
532
|
+
}
|
|
533
|
+
finally {
|
|
534
|
+
if (descriptor !== undefined)
|
|
535
|
+
closeSync(descriptor);
|
|
536
|
+
rmSync(temporary, { force: true });
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
//# sourceMappingURL=deploymentConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploymentConfig.js","sourceRoot":"","sources":["../src/deploymentConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAkB,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAyDrD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,OAAO,EAAE;QACP,aAAa,EAAE,qBAAqB;QACpC,GAAG,EAAE,mBAAmB;QACxB,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,iBAAiB;QAC7B,YAAY,EAAE,+BAA+B;QAC7C,WAAW,EAAE,4FAA4F;QACzG,eAAe,EAAE,IAAI;KACtB;IACD,MAAM,EAAE;QACN,aAAa,EAAE,uBAAuB;QACtC,GAAG,EAAE,kBAAkB;QACvB,IAAI,EAAE,uBAAuB;QAC7B,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,2BAA2B;QACvC,YAAY,EAAE,wBAAwB;QACtC,WAAW,EAAE,oCAAoC;QACjD,eAAe,EAAE,IAAI;KACtB;IACD,aAAa,EAAE;QACb,aAAa,EAAE,2BAA2B;QAC1C,GAAG,EAAE,yBAAyB;QAC9B,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,mCAAmC;QAC/C,YAAY,EAAE,yBAAyB;QACvC,WAAW,EAAE,kFAAkF;QAC/F,MAAM,EAAE,IAAI;QACZ,eAAe,EAAE,IAAI;KACtB;IACD,IAAI,EAAE;QACJ,aAAa,EAAE,aAAa;QAC5B,GAAG,EAAE,eAAe;QACpB,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,8BAA8B;QAC1C,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,mBAAmB;QAChC,eAAe,EAAE,IAAI;KACtB;IACD,SAAS,EAAE;QACT,aAAa,EAAE,mBAAmB;QAClC,GAAG,EAAE,qBAAqB;QAC1B,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,KAAK;QACX,UAAU,EAAE,2DAA2D;QACvE,YAAY,EAAE,kCAAkC;QAChD,WAAW,EAAE,gEAAgE;QAC7E,eAAe,EAAE,IAAI;KACtB;IACD,UAAU,EAAE;QACV,aAAa,EAAE,oBAAoB;QACnC,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,SAAS;QACrB,YAAY,EAAE,OAAO;QACrB,WAAW,EAAE,2EAA2E;QACxF,eAAe,EAAE,IAAI;KACtB;IACD,SAAS,EAAE;QACT,aAAa,EAAE,kBAAkB;QACjC,GAAG,EAAE,qBAAqB;QAC1B,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,8BAA8B;QAC1C,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,6CAA6C;QAC1D,eAAe,EAAE,IAAI;KACtB;IACD,SAAS,EAAE;QACT,aAAa,EAAE,kBAAkB;QACjC,GAAG,EAAE,qBAAqB;QAC1B,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,gCAAgC;QAC5C,YAAY,EAAE,WAAW;QACzB,WAAW,EAAE,qDAAqD;QAClE,eAAe,EAAE,IAAI;KACtB;IACD,kBAAkB,EAAE;QAClB,aAAa,EAAE,0BAA0B;QACzC,GAAG,EAAE,4BAA4B;QACjC,IAAI,EAAE,0BAA0B;QAChC,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,2BAA2B;QACvC,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,gFAAgF;QAC7F,eAAe,EAAE,IAAI;KACtB;IACD,QAAQ,EAAE;QACR,aAAa,EAAE,eAAe;QAC9B,GAAG,EAAE,oBAAoB;QACzB,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,2BAA2B;QACvC,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,wDAAwD;QACrE,eAAe,EAAE,IAAI;KACtB;IACD,cAAc,EAAE;QACd,aAAa,EAAE,qBAAqB;QACpC,GAAG,EAAE,0BAA0B;QAC/B,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,wBAAwB;QACpC,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,oFAAoF;QACjG,eAAe,EAAE,IAAI;KACtB;IACD,gBAAgB,EAAE;QAChB,aAAa,EAAE,sBAAsB;QACrC,GAAG,EAAE,6BAA6B;QAClC,IAAI,EAAE,sBAAsB;QAC5B,IAAI,EAAE,KAAK;QACX,UAAU,EAAE,mBAAmB;QAC/B,YAAY,EAAE,qBAAqB;QACnC,WAAW,EAAE,uEAAuE;QACpF,UAAU,EAAE,KAAK;QACjB,eAAe,EAAE,IAAI;KACtB;CACyE,CAAC;AAE7E,MAAM,sBAAsB,GAAG,KAAK,CAAC;AACrC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAAC;AACvC,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,GAAG,kBAAkB,CAAC;AACpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,kBAAkB,CAAC;AAEjE,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,OAAO,EAAE,CAAC;IACpC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACvE,MAAM,UAAU,GAAG,GAAG,CAAC,iBAAiB,CAAC;IACzC,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,SAAS;IACT,uBAAuB;IACvB,QAAQ;IACR,aAAa;IACb,mBAAmB;IACnB,oBAAoB;IACpB,0BAA0B;IAC1B,OAAO;IACP,aAAa;IACb,kBAAkB;IAClB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,qBAAqB;IACrB,WAAW;IACX,sBAAsB;CACvB,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AAEvG,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC;AAC1G,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAgB,EAAE,IAAY,EAAE,MAAM,GAAG,EAAE;IACnE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACjD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,IAAI,MAAM,6BAA6B,IAAI,EAAE,CAAC,CAAC;QAC3G,IAAI,MAAM;YAAE,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB,EAAE,MAAc;IACjD,IAAI,KAAK,GAAY,KAAK,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAClF,KAAK,GAAI,KAAiC,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAClB,GAAsB,EACtB,KAAgB,EAChB,OAA8B;IAE9B,MAAM,SAAS,GAA6B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC1E,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAClG,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC;IAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACvE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAc,EAAE,QAAgB;IACjE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAC3E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,KAAc,EAAE,QAAgB;IAC/D,OAAO,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY,EAAE,KAAc,EAAE,QAAgB;IACzE,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,KAAc,EAAE,QAAgB;IAC/D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iDAAiD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,KAAc,EAAE,QAAiB;IACnE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAC7D,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uCAAuC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,4BAA4B,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,yBAAyB,GAAG,kBAAkB,CAAC;IAC/D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,+DAA+D,OAAO,UAAU,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpH,CAAC;IACD,OAAO,KAAK,GAAG,kBAAkB,CAAC;AACpC,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,MAAM,KAAK,GAAG,mBAAmB,CAAC,oBAAoB,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5F,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CAAC,8DAA8D,KAAK,GAAG,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,MAAM,KAAK,GAAG,mBAAmB,CAAC,0BAA0B,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClG,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,iEAAiE,KAAK,GAAG,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,IAAY;IAClD,MAAM,KAAK,GAAG,WAAW,CAAC,qBAAqB,EAAE,KAAK,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxG,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+DAA+D,KAAK,GAAG,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,oDAAoD,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACnH,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnH,OAAO,KAAK,CAAC;AACf,CAAC;AAeD,MAAM,UAAU,mCAAmC,CAAC,GAAsB;IACxE,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,IAAI,GAAG,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,kBAAkB,EAAE,GAAG,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC,eAAe,EAAE,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,GAAG,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,GAAG,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,sBAAsB,EAAE,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,GAAG,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,qBAAqB,EAAE,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,GAAG,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC,qBAAqB,EAAE,GAAG,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,GAAG,CAAC,0BAA0B,KAAK,SAAS,EAAE,CAAC;QACjD,MAAM,CAAC,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,kBAAkB,CAAC;IACnG,CAAC;IACD,IAAI,GAAG,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,GAAG,CAAC,wBAAwB,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,CAAC,cAAc,GAAG,mBAAmB,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,GAAG,CAAC,2BAA2B,KAAK,SAAS,EAAE,CAAC;QAClD,MAAM,CAAC,gBAAgB,GAAG,WAAW,CAAC,6BAA6B,EAAE,GAAG,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,GAAsB,EACtB,IAAY,EACZ,UAAyC,EAAE;IAE3C,MAAM,gBAAgB,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GACV,OAAO,CAAC,KAAK,KAAK,OAAO,IAAI,gBAAgB,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE;QACrF,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,gBAAgB,CAAC;IACvB,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,QAAQ,IAAI,OAAO,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC;QACxD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,gCAAgC,CAAC,CAAC;QACrF,IAAI,KAAa,CAAC;QAClB,IAAI,CAAC;YACH,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5G,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,+BAA+B,CAAC,CAAC;QACpE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa,EAAE,OAAe;IACzD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB;IACzC,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACtC,SAAS,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;IACrD,CAAC;YAAS,CAAC;QACT,IAAI,UAAU,KAAK,SAAS;YAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAAe,EACf,GAAsB,EACtB,iBAA0B;IAE1B,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;IACzE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,mBAAmB,CACxB,UAAU,CAAC,KAAK,EAChB,sEAAsE,CACvE;YACD,MAAM,EAAE,UAAU,CAAC,MAAO;SAC3B,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO;YACL,KAAK,EAAE,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,6BAA6B,OAAO,EAAE,CAAC;YACxG,MAAM,EAAE,QAAQ;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,iBAAiB;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC7E,OAAO,YAAY,CACjB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,EAC1C;QACE,SAAS,EAAE,sBAAsB;QACjC,OAAO,EAAE,oBAAoB;QAC7B,WAAW,EAAE,yBAAyB,OAAO,EAAE;KAChD,EACD,GAAG,EAAE;QACH,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,sBAAsB,CAAC,OAAO,CAAC,CAAC;YAChC,OAAO;gBACL,KAAK,EAAE,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,6BAA6B,OAAO,EAAE,CAAC;gBACxG,MAAM,EAAE,QAAiB;aAC1B,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7G,IAAI,UAA8B,CAAC;QACnC,IAAI,CAAC;YACH,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC9C,aAAa,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAChE,SAAS,CAAC,UAAU,CAAC,CAAC;YACtB,SAAS,CAAC,UAAU,CAAC,CAAC;YACtB,UAAU,GAAG,SAAS,CAAC;YACvB,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC/B,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAoB,EAAE,CAAC;QACjD,CAAC;gBAAS,CAAC;YACT,IAAI,UAAU,KAAK,SAAS;gBAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAIvC;IACC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACnD,MAAM,UAAU,GAAG,eAAe,CAAC,iBAAiB,CAAC;IACrD,MAAM,OAAO,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,MAAM,WAAW,GAAsB,EAAE,GAAG,eAAe,EAAE,CAAC;IAC9D,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,EAAiD,CAAC;IAClE,OAAO,CAAC,OAAO,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAEvE,MAAM,eAAe,GAAG,CAAC,OAA8B,EAAW,EAAE;QAClE,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;QACnC,OAAO,QAAQ,CAAC,KAAK,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,SAAS,CAAC,kBAAkB,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;IAC1G,MAAM,UAAU,GAAG,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,aAAa,GAAG,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;IAE1D,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,qBAAqB,KAAK,KAAK,CAAC,CAAC;IACvG,OAAO,CAAC,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC;IAE1C,OAAO;QACL,OAAO;QACP,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC;QACzB,aAAa,EAAE,UAAU,CAAC,KAAK;QAC/B,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC;QAChD,mBAAmB,EAAE,SAAS,KAAK,SAAS;QAC5C,UAAU,EAAE,YAAY,CAAC,sBAAsB,EAAE,UAAU,EAAE,KAAK,CAAC;QACnE,SAAS,EAAE,SAAS,CAAC,qBAAqB,EAAE,SAAS,EAAE,IAAI,CAAC;QAC5D,SAAS,EAAE,mBAAmB,CAAC,qBAAqB,EAAE,SAAS,EAAE,WAAW,CAAC;QAC7E,kBAAkB,EAAE,kBAAkB,CAAC,aAAa,CAAC;QACrD,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;QACjC,cAAc,EAAE,mBAAmB,CAAC,cAAc,CAAC;QACnD,gBAAgB,EAAE,WAAW,CAC3B,6BAA6B,EAC7B,aAAa,EACb,OAAO,CAAC,uBAAuB,CAChC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrB,UAAU;QACV,WAAW;QACX,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,UAA4B;IACxE,IAAI,UAAU,CAAC,aAAa,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC;IACvD,MAAM,UAAU,GAAG,oBAAoB,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC1F,OAAO;QACL,GAAG,UAAU;QACb,aAAa,EAAE,UAAU,CAAC,KAAK;QAC/B,OAAO,EAAE,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,MAAM,EAAE;KACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAA+B,EAAE;IAC9D,OAAO,SAAS,CAAC;QACf,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;QAC9D,MAAM,EAAE;YACN,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI;YACzB,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,WAAW,EAAE,MAAM,CAAC,UAAU,IAAI,KAAK;YACvC,iBAAiB,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE;SAChD;QACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,IAAI,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,EAAE,EAAE;QAC3F,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,cAAc,IAAI,MAAM,EAAE;QAC3F,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3F,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,OAAe,EAAE,UAAmC,EAAE;IACxG,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5G,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9C,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,EAAE,MAAM,CAAC,CAAC;QACrF,SAAS,CAAC,UAAU,CAAC,CAAC;QACtB,SAAS,CAAC,UAAU,CAAC,CAAC;QACtB,UAAU,GAAG,SAAS,CAAC;QACvB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iBAAiB,CAAC,CAAC;gBAClG,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC7B,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;YAAS,CAAC;QACT,IAAI,UAAU,KAAK,SAAS;YAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}
|
package/dist/http/admin.d.ts
CHANGED
|
@@ -1,21 +1,93 @@
|
|
|
1
1
|
import { type OpenAPIHono } from '@hono/zod-openapi';
|
|
2
2
|
import type { AccountRegistry } from '../accounts/registry.js';
|
|
3
|
-
import type
|
|
4
|
-
import type
|
|
3
|
+
import { type ConfigurationService, type FluxmailConfig } from '../config.js';
|
|
4
|
+
import { type LicenseController } from '../licensing/refresher.js';
|
|
5
5
|
import type { FluxmailDb } from '../storage/db.js';
|
|
6
|
+
import { type Logger } from '../logging.js';
|
|
6
7
|
export declare const ADMIN_BODY_LIMIT: number;
|
|
7
8
|
export declare const ADMIN_CONNECTION_TIMEOUT_MS = 30000;
|
|
9
|
+
export declare const adminOperationRoutes: {
|
|
10
|
+
readonly createConnection: {
|
|
11
|
+
readonly method: "post";
|
|
12
|
+
readonly path: "/api/v1/admin/connections";
|
|
13
|
+
readonly operationId: "createAdministrativeConnection";
|
|
14
|
+
};
|
|
15
|
+
readonly testImapConnection: {
|
|
16
|
+
readonly method: "post";
|
|
17
|
+
readonly path: "/api/v1/admin/imap/tests";
|
|
18
|
+
readonly operationId: "testAdministrativeImapConnection";
|
|
19
|
+
};
|
|
20
|
+
readonly updateImapFolders: {
|
|
21
|
+
readonly method: "patch";
|
|
22
|
+
readonly path: "/api/v1/admin/accounts/{accountId}/imap/folders";
|
|
23
|
+
readonly operationId: "updateAdministrativeImapFolders";
|
|
24
|
+
};
|
|
25
|
+
readonly listApiKeys: {
|
|
26
|
+
readonly method: "get";
|
|
27
|
+
readonly path: "/api/v1/admin/api-keys";
|
|
28
|
+
readonly operationId: "listAdministrativeApiKeys";
|
|
29
|
+
};
|
|
30
|
+
readonly createApiKey: {
|
|
31
|
+
readonly method: "post";
|
|
32
|
+
readonly path: "/api/v1/admin/api-keys";
|
|
33
|
+
readonly operationId: "createAdministrativeApiKey";
|
|
34
|
+
};
|
|
35
|
+
readonly updateApiKey: {
|
|
36
|
+
readonly method: "patch";
|
|
37
|
+
readonly path: "/api/v1/admin/api-keys/{keyId}";
|
|
38
|
+
readonly operationId: "updateAdministrativeApiKey";
|
|
39
|
+
};
|
|
40
|
+
readonly revokeApiKey: {
|
|
41
|
+
readonly method: "delete";
|
|
42
|
+
readonly path: "/api/v1/admin/api-keys/{keyId}";
|
|
43
|
+
readonly operationId: "revokeAdministrativeApiKey";
|
|
44
|
+
};
|
|
45
|
+
readonly getOauthApps: {
|
|
46
|
+
readonly method: "get";
|
|
47
|
+
readonly path: "/api/v1/admin/oauth-apps";
|
|
48
|
+
readonly operationId: "getAdministrativeOAuthApps";
|
|
49
|
+
};
|
|
50
|
+
readonly putOauthApp: {
|
|
51
|
+
readonly method: "put";
|
|
52
|
+
readonly path: "/api/v1/admin/oauth-apps/{provider}";
|
|
53
|
+
readonly operationId: "putAdministrativeOAuthApp";
|
|
54
|
+
};
|
|
55
|
+
readonly deleteOauthApp: {
|
|
56
|
+
readonly method: "delete";
|
|
57
|
+
readonly path: "/api/v1/admin/oauth-apps/{provider}";
|
|
58
|
+
readonly operationId: "deleteAdministrativeOAuthApp";
|
|
59
|
+
};
|
|
60
|
+
readonly getLicense: {
|
|
61
|
+
readonly method: "get";
|
|
62
|
+
readonly path: "/api/v1/admin/license";
|
|
63
|
+
readonly operationId: "getAdministrativeLicense";
|
|
64
|
+
};
|
|
65
|
+
readonly activateLicense: {
|
|
66
|
+
readonly method: "post";
|
|
67
|
+
readonly path: "/api/v1/admin/license/activate";
|
|
68
|
+
readonly operationId: "activateAdministrativeLicense";
|
|
69
|
+
};
|
|
70
|
+
readonly deactivateLicense: {
|
|
71
|
+
readonly method: "delete";
|
|
72
|
+
readonly path: "/api/v1/admin/license";
|
|
73
|
+
readonly operationId: "deactivateAdministrativeLicense";
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
export declare function adminOperationId(method: string, path: string): string | undefined;
|
|
8
77
|
export interface AdminConnectionSecurity {
|
|
9
78
|
remoteAddress?: string;
|
|
10
79
|
encrypted?: boolean;
|
|
11
80
|
}
|
|
12
|
-
export declare function administrationUsesHttps(request: Request, connection?: AdminConnectionSecurity): boolean;
|
|
81
|
+
export declare function administrationUsesHttps(request: Request, connection?: AdminConnectionSecurity, trustProxy?: boolean): boolean;
|
|
82
|
+
export declare function requestClientAddress(request: Request, connection?: AdminConnectionSecurity, trustProxy?: boolean): string;
|
|
13
83
|
export declare function requestBodyExceedsLimit(request: Request, limit?: number): Promise<boolean>;
|
|
14
84
|
export interface AdminApiDeps {
|
|
15
85
|
config: FluxmailConfig;
|
|
86
|
+
configuration: ConfigurationService;
|
|
16
87
|
db: FluxmailDb;
|
|
17
88
|
registry?: AccountRegistry;
|
|
18
89
|
licenseController?: LicenseController;
|
|
90
|
+
logger?: Logger;
|
|
19
91
|
}
|
|
20
92
|
export declare function registerAdminRoutes(app: OpenAPIHono<any>, deps: AdminApiDeps): void;
|
|
21
93
|
//# sourceMappingURL=admin.d.ts.map
|