@technomoron/mail-magic 1.0.43 → 1.0.44
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/CHANGES +7 -0
- package/dist/esm/api/mailer.js +3 -0
- package/dist/esm/store/store.d.ts +1 -1
- package/dist/esm/store/store.js +5 -1
- package/dist/esm/util/utils.d.ts +7 -0
- package/dist/esm/util/utils.js +7 -0
- package/package.json +1 -1
package/CHANGES
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
Version 1.0.44 (2026-03-05)
|
|
5
|
+
|
|
6
|
+
- fix(autoreload): catch unhandled promise rejections from async `reload()` in `enableInitDataAutoReload` `onChange` callback.
|
|
7
|
+
- fix(mailer): validate that parsed `vars` is a non-null, non-array object after `JSON.parse`; return 400 for invalid types.
|
|
8
|
+
- docs(utils): add doc comment to `buildRequestMeta` clarifying it is informational and requires a trusted reverse proxy for reliable IP data.
|
|
9
|
+
- (Changes generated/assisted by Claude Code (profile: anthropic-claude-opus-4-6/high).)
|
|
10
|
+
|
|
4
11
|
Version 1.0.43 (2026-03-04)
|
|
5
12
|
|
|
6
13
|
- fix(security): add allowlist for custom email headers on `/v1/tx/message` to prevent header injection via arbitrary keys (e.g. `Bcc`, `From`, `Sender`).
|
package/dist/esm/api/mailer.js
CHANGED
|
@@ -89,6 +89,9 @@ export class MailerAPI extends ApiModule {
|
|
|
89
89
|
throw new ApiError({ code: 400, message: 'Invalid JSON provided in "vars"' });
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
if (!parsedVars || typeof parsedVars !== 'object' || Array.isArray(parsedVars)) {
|
|
93
|
+
throw new ApiError({ code: 400, message: '"vars" must be a JSON object' });
|
|
94
|
+
}
|
|
92
95
|
const thevars = parsedVars;
|
|
93
96
|
const { valid, invalid } = this.validateEmails(rcpt);
|
|
94
97
|
if (invalid.length > 0) {
|
|
@@ -18,7 +18,7 @@ type AutoReloadContext = {
|
|
|
18
18
|
config_filename: (name: string) => string;
|
|
19
19
|
print_debug: (msg: string) => void;
|
|
20
20
|
};
|
|
21
|
-
export declare function enableInitDataAutoReload(ctx: AutoReloadContext, reload: () => void): AutoReloadHandle | null;
|
|
21
|
+
export declare function enableInitDataAutoReload(ctx: AutoReloadContext, reload: () => void | Promise<void>): AutoReloadHandle | null;
|
|
22
22
|
export declare class mailStore {
|
|
23
23
|
private env;
|
|
24
24
|
vars: MailStoreVars;
|
package/dist/esm/store/store.js
CHANGED
|
@@ -38,8 +38,12 @@ export function enableInitDataAutoReload(ctx, reload) {
|
|
|
38
38
|
debounceTimer = setTimeout(() => {
|
|
39
39
|
debounceTimer = null;
|
|
40
40
|
ctx.print_debug('Config file changed, reloading...');
|
|
41
|
+
// reload() may be sync or async — try/catch handles a synchronous
|
|
42
|
+
// throw, while Promise.resolve().catch() handles an async rejection.
|
|
41
43
|
try {
|
|
42
|
-
reload()
|
|
44
|
+
Promise.resolve(reload()).catch((err) => {
|
|
45
|
+
ctx.print_debug(`Failed to reload config: ${err}`);
|
|
46
|
+
});
|
|
43
47
|
}
|
|
44
48
|
catch (err) {
|
|
45
49
|
ctx.print_debug(`Failed to reload config: ${err}`);
|
package/dist/esm/util/utils.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export declare function user_and_domain(domain_id: number): Promise<{
|
|
|
19
19
|
user: api_user;
|
|
20
20
|
domain: api_domain;
|
|
21
21
|
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Collect informational request metadata (client IP, IP chain, timestamp) for
|
|
24
|
+
* use in template rendering context. The values are **not** used for security
|
|
25
|
+
* decisions such as rate limiting — those rely on `getClientIp()` which is
|
|
26
|
+
* trust-proxy aware. For the IP chain to be meaningful the server must sit
|
|
27
|
+
* behind a trusted reverse proxy that sets the forwarded headers.
|
|
28
|
+
*/
|
|
22
29
|
export declare function buildRequestMeta(rawReq: unknown): RequestMeta;
|
|
23
30
|
export declare function decodeComponent(value: string | string[] | undefined): string;
|
|
24
31
|
export declare function getBodyValue(body: Record<string, unknown>, ...keys: string[]): string;
|
package/dist/esm/util/utils.js
CHANGED
|
@@ -60,6 +60,13 @@ function resolveHeader(headers, key) {
|
|
|
60
60
|
}
|
|
61
61
|
return undefined;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Collect informational request metadata (client IP, IP chain, timestamp) for
|
|
65
|
+
* use in template rendering context. The values are **not** used for security
|
|
66
|
+
* decisions such as rate limiting — those rely on `getClientIp()` which is
|
|
67
|
+
* trust-proxy aware. For the IP chain to be meaningful the server must sit
|
|
68
|
+
* behind a trusted reverse proxy that sets the forwarded headers.
|
|
69
|
+
*/
|
|
63
70
|
export function buildRequestMeta(rawReq) {
|
|
64
71
|
const req = (rawReq ?? {});
|
|
65
72
|
const headers = req.headers ?? {};
|