aboutsummaryrefslogtreecommitdiff
path: root/services/docker/mail-server/relay/config.ts
diff options
context:
space:
mode:
Diffstat (limited to 'services/docker/mail-server/relay/config.ts')
-rw-r--r--services/docker/mail-server/relay/config.ts89
1 files changed, 45 insertions, 44 deletions
diff --git a/services/docker/mail-server/relay/config.ts b/services/docker/mail-server/relay/config.ts
index 55d71fa..d58b163 100644
--- a/services/docker/mail-server/relay/config.ts
+++ b/services/docker/mail-server/relay/config.ts
@@ -1,97 +1,99 @@
-import { transformProperties } from "./util.ts";
-
export const APP_PREFIX = "crupest";
-export const APP_NAME = "mailserver";
+export const APP_NAME = "mail-server";
-interface ConfigItemDef {
- env: string;
+export interface ConfigItemDefinition {
description: string;
default?: string;
secret?: boolean;
}
-export const CONFIG_DEFS = {
+export const CONFIG_DEFINITIONS = {
mailDomain: {
- env: "MAIL_DOMAIN",
description: "the part after `@` of an address",
},
dataPath: {
- env: "DATA_PATH",
description: "path to save app persistent data",
},
ldaPath: {
- env: "LDA_PATH",
description: "full path of lda executable",
"default": "/dovecot/libexec/dovecot/dovecot-lda",
},
inboundFallback: {
- env: "INBOUND_FALLBACK",
- description: "comma separated addresses used as fallback receipts",
+ description: "comma separated addresses used as fallback recipients",
"default": "",
},
- awsRegion: { env: "AWS_REGION", description: "aws region" },
- awsAccessKeyId: { env: "AWS_USER", description: "aws access key id" },
- awsSecretAccessKey: {
- env: "AWS_PASSWORD",
+ awsInboundPath: {
+ description: "(random set) path for aws sns",
+ },
+ awsInboundKey: {
+ description: "(random set) http header Authorization for aws sns",
+ },
+ awsRegion: {
+ description: "aws region",
+ },
+ awsUser: {
+ description: "aws access key id",
+ },
+ awsPassword: {
description: "aws secret access key",
secret: true,
},
awsMailBucket: {
- env: "AWS_MAIL_BUCKET",
description: "aws s3 bucket saving raw mails",
secret: true,
},
-} as const satisfies Record<string, ConfigItemDef>;
+} as const satisfies Record<string, ConfigItemDefinition>;
-type ConfigDefs = typeof CONFIG_DEFS;
-type ConfigKey = keyof ConfigDefs;
+type ConfigDefinitions = typeof CONFIG_DEFINITIONS;
+type ConfigNames = keyof ConfigDefinitions;
type ConfigMap = {
- [K in ConfigKey]: ConfigItemDef & { value: string };
+ [K in ConfigNames]: ConfigDefinitions[K] & {
+ readonly env: string;
+ readonly value: string;
+ };
};
-function getFullEnvKey(key: string): string {
- return `${APP_PREFIX.toUpperCase()}_${APP_NAME.toUpperCase()}_${key}`;
-}
-
-function resolveAppConfigItem(def: ConfigItemDef): string {
- const envKey = getFullEnvKey(def.env);
- const value = Deno.env.get(envKey);
- if (value != null) return value;
- if (def.default != null) return def.default;
- throw new Error(
- `Required env ${envKey} (${def.description}) is not set.`,
- );
+function resolveConfig(): ConfigMap {
+ const result: Record<string, ConfigMap[ConfigNames]> = {};
+ for (const [name, def] of Object.entries(CONFIG_DEFINITIONS)) {
+ const env = `${APP_PREFIX}-${APP_NAME}-${
+ name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase())
+ }`.replaceAll("-", "_").toUpperCase();
+ const value = Deno.env.get(env) ?? (def as ConfigItemDefinition).default;
+ if (value == null) {
+ throw new Error(`Required env ${env} (${def.description}) is not set.`);
+ }
+ result[name] = { ...def, env, value };
+ }
+ return result as ConfigMap;
}
export class Config {
- #config = transformProperties(
- CONFIG_DEFS,
- (def) => ({ ...def, value: resolveAppConfigItem(def) }),
- ) as ConfigMap;
+ #config = resolveConfig();
readonly HTTP_HOST = "0.0.0.0";
readonly HTTP_PORT = 2345;
readonly SMTP_HOST = "127.0.0.1";
readonly SMTP_PORT = 2346;
- get<K extends ConfigKey>(key: K): ConfigMap[K] {
+ getAllConfig<K extends ConfigNames>(key: K): ConfigMap[K] {
return this.#config[key];
}
- getValue(key: ConfigKey): string {
- return this.get(key).value;
+ get(key: ConfigNames): string {
+ return this.getAllConfig(key).value;
}
- getValueList(key: ConfigKey, separator: string = ","): string[] {
- const value = this.getValue(key);
+ getList(key: ConfigNames, separator: string = ","): string[] {
+ const value = this.get(key);
if (value.length === 0) return [];
return value.split(separator);
}
[Symbol.for("Deno.customInspect")]() {
return Object.entries(this.#config).map(([key, item]) =>
- `${key} [env: ${getFullEnvKey(item.env)}]: ${
- item.secret === true ? "***" : item.value
+ `${key} [env: ${item.env}]: ${
+ (item as ConfigItemDefinition).secret === true ? "***" : item.value
}`
).join("\n");
}
@@ -99,4 +101,3 @@ export class Config {
const config = new Config();
export default config;
-export const getConfigValue = config.getValue.bind(config);