ooo containing html
This commit is contained in:
@@ -135,8 +135,21 @@ mailboxesRouter.get('/:email/rules', async (req, res) => {
|
||||
mailboxesRouter.put('/:email/rules', async (req, res) => {
|
||||
const email = normalizeEmail(req.params.email);
|
||||
ensureDomain(req, domainFromEmail(email));
|
||||
const body = z.object({ ooo_active: z.boolean().optional(), ooo_message: z.string().optional(), forwards: z.array(z.string().email()).optional() }).parse(req.body);
|
||||
const saved = await dynamo.putRules({ email_address: email, ooo_active: body.ooo_active, ooo_message: body.ooo_message, forwards: body.forwards });
|
||||
const body = z.object({
|
||||
ooo_active: z.boolean().optional(),
|
||||
ooo_message: z.string().optional(),
|
||||
// 'text' or 'html'. Stored as-is in DynamoDB so the email worker can
|
||||
// pick the correct Content-Type when sending the auto-reply.
|
||||
ooo_content_type: z.enum(['text', 'html']).optional(),
|
||||
forwards: z.array(z.string().email()).optional(),
|
||||
}).parse(req.body);
|
||||
const saved = await dynamo.putRules({
|
||||
email_address: email,
|
||||
ooo_active: body.ooo_active,
|
||||
ooo_message: body.ooo_message,
|
||||
ooo_content_type: body.ooo_content_type,
|
||||
forwards: body.forwards,
|
||||
});
|
||||
await audit(req.user!.email, 'mailbox.rules_update', 'mailbox', email, saved, req.ip);
|
||||
res.json(saved);
|
||||
});
|
||||
|
||||
@@ -7,7 +7,9 @@ export interface EmailRule {
|
||||
email_address: string;
|
||||
ooo_active?: boolean;
|
||||
ooo_message?: string;
|
||||
ooo_content_type?: string;
|
||||
// 'text' or 'html' — kept consistent with the config-email app that
|
||||
// shares the same DynamoDB table so both apps interpret it the same way.
|
||||
ooo_content_type?: 'text' | 'html';
|
||||
forwards?: string[];
|
||||
}
|
||||
|
||||
@@ -16,6 +18,13 @@ export interface BlockList {
|
||||
blocked_patterns: string[];
|
||||
}
|
||||
|
||||
// Tolerate legacy values that may already exist in DynamoDB.
|
||||
function normalizeContentType(v: unknown): 'text' | 'html' {
|
||||
const s = String(v ?? '').toLowerCase();
|
||||
if (s === 'html' || s === 'text/html') return 'html';
|
||||
return 'text';
|
||||
}
|
||||
|
||||
export class DynamoRulesService {
|
||||
private doc = DynamoDBDocumentClient.from(new DynamoDBClient({ region: config.awsRegion }), {
|
||||
marshallOptions: { removeUndefinedValues: true },
|
||||
@@ -24,7 +33,14 @@ export class DynamoRulesService {
|
||||
async getRules(email: string): Promise<EmailRule> {
|
||||
const email_address = normalizeEmail(email);
|
||||
const resp = await this.doc.send(new GetCommand({ TableName: config.rulesTable, Key: { email_address } }));
|
||||
return (resp.Item as EmailRule) ?? { email_address, ooo_active: false, ooo_message: '', ooo_content_type: 'text/plain', forwards: [] };
|
||||
const item = resp.Item as EmailRule | undefined;
|
||||
if (!item) {
|
||||
return { email_address, ooo_active: false, ooo_message: '', ooo_content_type: 'text', forwards: [] };
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
ooo_content_type: normalizeContentType(item.ooo_content_type),
|
||||
};
|
||||
}
|
||||
|
||||
async putRules(rule: EmailRule): Promise<EmailRule> {
|
||||
@@ -32,7 +48,7 @@ export class DynamoRulesService {
|
||||
email_address: normalizeEmail(rule.email_address),
|
||||
ooo_active: !!rule.ooo_active,
|
||||
ooo_message: rule.ooo_message ?? '',
|
||||
ooo_content_type: rule.ooo_content_type ?? 'text/plain',
|
||||
ooo_content_type: normalizeContentType(rule.ooo_content_type),
|
||||
forwards: (rule.forwards ?? []).map(normalizeEmail).filter(Boolean),
|
||||
};
|
||||
await this.doc.send(new PutCommand({ TableName: config.rulesTable, Item: item }));
|
||||
@@ -57,4 +73,4 @@ export class DynamoRulesService {
|
||||
await this.doc.send(new PutCommand({ TableName: config.blockedTable, Item: item }));
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user