ntfy-reverse-proxy 2.0.4 → 2.1.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 (193) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +10 -0
  3. package/build/src/cli/commands/config-io.d.ts +3 -3
  4. package/build/src/cli/commands/config-io.d.ts.map +1 -1
  5. package/build/src/cli/commands/config-io.js +1 -1
  6. package/build/src/cli/commands/config-io.js.map +1 -1
  7. package/build/src/cli/commands/context.d.ts +7 -7
  8. package/build/src/cli/commands/context.d.ts.map +1 -1
  9. package/build/src/cli/commands/context.js +1 -1
  10. package/build/src/cli/commands/context.js.map +1 -1
  11. package/build/src/cli/commands/deploy.d.ts +2 -2
  12. package/build/src/cli/commands/deploy.d.ts.map +1 -1
  13. package/build/src/cli/commands/deploy.js +72 -30
  14. package/build/src/cli/commands/deploy.js.map +1 -1
  15. package/build/src/cli/commands/generate.d.ts +2 -2
  16. package/build/src/cli/commands/generate.d.ts.map +1 -1
  17. package/build/src/cli/commands/generate.js +3 -3
  18. package/build/src/cli/commands/generate.js.map +1 -1
  19. package/build/src/cli/commands/server.d.ts +5 -5
  20. package/build/src/cli/commands/server.d.ts.map +1 -1
  21. package/build/src/cli/commands/server.js.map +1 -1
  22. package/build/src/cli/commands/settings.d.ts +3 -3
  23. package/build/src/cli/commands/settings.d.ts.map +1 -1
  24. package/build/src/cli/commands/settings.js.map +1 -1
  25. package/build/src/cli/commands/validate.d.ts +2 -2
  26. package/build/src/cli/commands/validate.d.ts.map +1 -1
  27. package/build/src/cli/commands/validate.js +3 -0
  28. package/build/src/cli/commands/validate.js.map +1 -1
  29. package/build/src/cli/index.d.ts +2 -2
  30. package/build/src/cli/index.d.ts.map +1 -1
  31. package/build/src/cli/index.js +4 -4
  32. package/build/src/cli/index.js.map +1 -1
  33. package/build/src/cli/menu/interactive.d.ts +2 -2
  34. package/build/src/cli/menu/interactive.d.ts.map +1 -1
  35. package/build/src/cli/menu/interactive.js +260 -94
  36. package/build/src/cli/menu/interactive.js.map +1 -1
  37. package/build/src/lib/regex.d.ts +4 -1
  38. package/build/src/lib/regex.d.ts.map +1 -1
  39. package/build/src/lib/regex.js +4 -1
  40. package/build/src/lib/regex.js.map +1 -1
  41. package/build/src/lib/schema.d.ts +24 -0
  42. package/build/src/lib/schema.d.ts.map +1 -1
  43. package/build/src/lib/schema.js +11 -2
  44. package/build/src/lib/schema.js.map +1 -1
  45. package/build/src/lib/utility.d.ts +2 -2
  46. package/build/src/lib/utility.d.ts.map +1 -1
  47. package/build/src/lib/utility.js +1 -1
  48. package/build/src/lib/utility.js.map +1 -1
  49. package/build/src/types/cli/commands/config-io.d.ts +12 -12
  50. package/build/src/types/cli/commands/context.d.ts +96 -58
  51. package/build/src/types/cli/commands/deploy.d.ts +342 -298
  52. package/build/src/types/cli/commands/generate.d.ts +40 -24
  53. package/build/src/types/cli/commands/server.d.ts +23 -23
  54. package/build/src/types/cli/commands/settings.d.ts +8 -8
  55. package/build/src/types/cli/commands/validate.d.ts +16 -16
  56. package/build/src/types/cli/index.d.ts +16 -20
  57. package/build/src/types/cli/menu/interactive.d.ts +233 -178
  58. package/build/src/types/lib/schema.d.ts +89 -81
  59. package/build/src/types/lib/utility.d.ts +4 -2
  60. package/build/src/types/shared.d.ts +85 -0
  61. package/build/src/types/tests/cli/commands/context.test.d.ts +102 -31
  62. package/build/src/types/tests/cli/commands/generate.test.d.ts +50 -4
  63. package/build/src/types/tests/cli/commands/server.test.d.ts +88 -23
  64. package/build/src/types/tests/cli/commands/settings.test.d.ts +65 -21
  65. package/build/src/types/tests/cli/commands/validate.test.d.ts +69 -8
  66. package/build/src/types/tests/cli/menu/interactive-integration.test.d.ts +99 -0
  67. package/build/src/types/tests/cli/menu/interactive.test.d.ts +275 -2
  68. package/build/src/types/tests/lib/schema.test.d.ts +258 -3
  69. package/build/src/types/tests/worker/index.test.d.ts +166 -8
  70. package/build/src/types/tests/worker/interpreters/ntfy-json.test.d.ts +94 -10
  71. package/build/src/types/tests/worker/interpreters/pfsense.test.d.ts +163 -4
  72. package/build/src/types/tests/worker/interpreters/plain-text.test.d.ts +67 -4
  73. package/build/src/types/tests/worker/interpreters/seerr.test.d.ts +138 -3
  74. package/build/src/types/tests/worker/interpreters/statuspage.test.d.ts +235 -30
  75. package/build/src/types/tests/worker/interpreters/synology.test.d.ts +61 -3
  76. package/build/src/types/tests/worker/interpreters/unifi.test.d.ts +93 -3
  77. package/build/src/types/tests/worker/landing/page.test.d.ts +73 -50
  78. package/build/src/types/tests/worker/pipeline/accumulate.test.d.ts +226 -15
  79. package/build/src/types/tests/worker/pipeline/authenticate.test.d.ts +148 -4
  80. package/build/src/types/tests/worker/pipeline/email.test.d.ts +82 -8
  81. package/build/src/types/tests/worker/pipeline/format.test.d.ts +112 -32
  82. package/build/src/types/tests/worker/pipeline/interpret.test.d.ts +109 -17
  83. package/build/src/types/tests/worker/pipeline/parse.test.d.ts +70 -5
  84. package/build/src/types/tests/worker/pipeline/receive.test.d.ts +156 -15
  85. package/build/src/types/tests/worker/pipeline/respond.test.d.ts +129 -10
  86. package/build/src/types/tests/worker/pipeline/route.test.d.ts +412 -74
  87. package/build/src/types/tests/worker/pipeline/send.test.d.ts +58 -23
  88. package/build/src/types/tests/worker/pipeline/split.test.d.ts +47 -9
  89. package/build/src/types/worker/handlers.d.ts +193 -0
  90. package/build/src/types/worker/index.d.ts +58 -203
  91. package/build/src/types/worker/interpreters/ntfy-json.d.ts +10 -10
  92. package/build/src/types/worker/interpreters/pfsense.d.ts +57 -49
  93. package/build/src/types/worker/interpreters/plain-text.d.ts +7 -7
  94. package/build/src/types/worker/interpreters/seerr.d.ts +63 -61
  95. package/build/src/types/worker/interpreters/statuspage.d.ts +201 -116
  96. package/build/src/types/worker/interpreters/synology.d.ts +48 -46
  97. package/build/src/types/worker/interpreters/unifi.d.ts +79 -54
  98. package/build/src/types/worker/landing/page.d.ts +30 -23
  99. package/build/src/types/worker/pipeline/accumulate.d.ts +46 -32
  100. package/build/src/types/worker/pipeline/authenticate.d.ts +94 -34
  101. package/build/src/types/worker/pipeline/email.d.ts +114 -50
  102. package/build/src/types/worker/pipeline/format.d.ts +31 -23
  103. package/build/src/types/worker/pipeline/interpret.d.ts +34 -34
  104. package/build/src/types/worker/pipeline/parse.d.ts +25 -19
  105. package/build/src/types/worker/pipeline/receive.d.ts +36 -34
  106. package/build/src/types/worker/pipeline/respond.d.ts +119 -63
  107. package/build/src/types/worker/pipeline/route.d.ts +33 -16
  108. package/build/src/types/worker/pipeline/send.d.ts +116 -79
  109. package/build/src/types/worker/pipeline/split.d.ts +21 -16
  110. package/build/src/worker/handlers.d.ts +5 -4
  111. package/build/src/worker/handlers.d.ts.map +1 -1
  112. package/build/src/worker/handlers.js +238 -202
  113. package/build/src/worker/handlers.js.map +1 -1
  114. package/build/src/worker/index.d.ts +2 -2
  115. package/build/src/worker/index.d.ts.map +1 -1
  116. package/build/src/worker/index.js +37 -9
  117. package/build/src/worker/index.js.map +1 -1
  118. package/build/src/worker/interpreters/ntfy-json.d.ts +2 -2
  119. package/build/src/worker/interpreters/ntfy-json.d.ts.map +1 -1
  120. package/build/src/worker/interpreters/ntfy-json.js.map +1 -1
  121. package/build/src/worker/interpreters/pfsense.d.ts +2 -2
  122. package/build/src/worker/interpreters/pfsense.d.ts.map +1 -1
  123. package/build/src/worker/interpreters/pfsense.js +20 -27
  124. package/build/src/worker/interpreters/pfsense.js.map +1 -1
  125. package/build/src/worker/interpreters/plain-text.d.ts +2 -2
  126. package/build/src/worker/interpreters/plain-text.d.ts.map +1 -1
  127. package/build/src/worker/interpreters/plain-text.js.map +1 -1
  128. package/build/src/worker/interpreters/seerr.d.ts +2 -2
  129. package/build/src/worker/interpreters/seerr.d.ts.map +1 -1
  130. package/build/src/worker/interpreters/seerr.js +16 -12
  131. package/build/src/worker/interpreters/seerr.js.map +1 -1
  132. package/build/src/worker/interpreters/statuspage.d.ts +2 -2
  133. package/build/src/worker/interpreters/statuspage.d.ts.map +1 -1
  134. package/build/src/worker/interpreters/statuspage.js +98 -47
  135. package/build/src/worker/interpreters/statuspage.js.map +1 -1
  136. package/build/src/worker/interpreters/synology.d.ts +2 -2
  137. package/build/src/worker/interpreters/synology.d.ts.map +1 -1
  138. package/build/src/worker/interpreters/synology.js +9 -5
  139. package/build/src/worker/interpreters/synology.js.map +1 -1
  140. package/build/src/worker/interpreters/unifi.d.ts +2 -2
  141. package/build/src/worker/interpreters/unifi.d.ts.map +1 -1
  142. package/build/src/worker/interpreters/unifi.js +34 -20
  143. package/build/src/worker/interpreters/unifi.js.map +1 -1
  144. package/build/src/worker/landing/page.d.ts +2 -2
  145. package/build/src/worker/landing/page.d.ts.map +1 -1
  146. package/build/src/worker/landing/page.js +4 -3
  147. package/build/src/worker/landing/page.js.map +1 -1
  148. package/build/src/worker/pipeline/accumulate.d.ts +5 -6
  149. package/build/src/worker/pipeline/accumulate.d.ts.map +1 -1
  150. package/build/src/worker/pipeline/accumulate.js +4 -11
  151. package/build/src/worker/pipeline/accumulate.js.map +1 -1
  152. package/build/src/worker/pipeline/authenticate.d.ts +2 -2
  153. package/build/src/worker/pipeline/authenticate.d.ts.map +1 -1
  154. package/build/src/worker/pipeline/authenticate.js +25 -7
  155. package/build/src/worker/pipeline/authenticate.js.map +1 -1
  156. package/build/src/worker/pipeline/email.d.ts +2 -2
  157. package/build/src/worker/pipeline/email.d.ts.map +1 -1
  158. package/build/src/worker/pipeline/email.js +34 -11
  159. package/build/src/worker/pipeline/email.js.map +1 -1
  160. package/build/src/worker/pipeline/format.d.ts +2 -3
  161. package/build/src/worker/pipeline/format.d.ts.map +1 -1
  162. package/build/src/worker/pipeline/format.js +2 -1
  163. package/build/src/worker/pipeline/format.js.map +1 -1
  164. package/build/src/worker/pipeline/interpret.d.ts +4 -3
  165. package/build/src/worker/pipeline/interpret.d.ts.map +1 -1
  166. package/build/src/worker/pipeline/interpret.js +7 -7
  167. package/build/src/worker/pipeline/interpret.js.map +1 -1
  168. package/build/src/worker/pipeline/parse.d.ts +2 -2
  169. package/build/src/worker/pipeline/parse.d.ts.map +1 -1
  170. package/build/src/worker/pipeline/parse.js +14 -7
  171. package/build/src/worker/pipeline/parse.js.map +1 -1
  172. package/build/src/worker/pipeline/receive.d.ts +2 -2
  173. package/build/src/worker/pipeline/receive.d.ts.map +1 -1
  174. package/build/src/worker/pipeline/receive.js +6 -6
  175. package/build/src/worker/pipeline/receive.js.map +1 -1
  176. package/build/src/worker/pipeline/respond.d.ts +2 -2
  177. package/build/src/worker/pipeline/respond.d.ts.map +1 -1
  178. package/build/src/worker/pipeline/respond.js +1 -1
  179. package/build/src/worker/pipeline/respond.js.map +1 -1
  180. package/build/src/worker/pipeline/route.d.ts +2 -3
  181. package/build/src/worker/pipeline/route.d.ts.map +1 -1
  182. package/build/src/worker/pipeline/route.js.map +1 -1
  183. package/build/src/worker/pipeline/send.d.ts +2 -2
  184. package/build/src/worker/pipeline/send.d.ts.map +1 -1
  185. package/build/src/worker/pipeline/send.js +80 -41
  186. package/build/src/worker/pipeline/send.js.map +1 -1
  187. package/build/src/worker/pipeline/split.d.ts +2 -2
  188. package/build/src/worker/pipeline/split.d.ts.map +1 -1
  189. package/build/src/worker/pipeline/split.js +4 -2
  190. package/build/src/worker/pipeline/split.js.map +1 -1
  191. package/package.json +11 -9
  192. package/build/src/types/tests/type-declarations.test.d.ts +0 -173
  193. package/build/src/types/worker/pipeline/shared.d.ts +0 -85
@@ -9,6 +9,15 @@ import { respond } from './pipeline/respond.js';
9
9
  import { route } from './pipeline/route.js';
10
10
  import { send } from './pipeline/send.js';
11
11
  import { split } from './pipeline/split.js';
12
+ function shouldNotifyError(ctx, category) {
13
+ if (ctx['error_topic'] === undefined) {
14
+ return false;
15
+ }
16
+ if (ctx['error_events'] === undefined) {
17
+ return true;
18
+ }
19
+ return ctx['error_events'].includes(category);
20
+ }
12
21
  async function handleRequest(request, config, kv) {
13
22
  try {
14
23
  const received = await receive(request, config['settings']['base_domain']);
@@ -17,7 +26,8 @@ async function handleRequest(request, config, kv) {
17
26
  }
18
27
  if (received['error'] !== undefined) {
19
28
  return new Response(JSON.stringify({
20
- status: 'error', message: received['error'],
29
+ status: 'error',
30
+ message: received['error'],
21
31
  }, null, 2), {
22
32
  status: 405,
23
33
  headers: { 'Content-Type': 'application/json' },
@@ -33,7 +43,8 @@ async function handleRequest(request, config, kv) {
33
43
  || routed['resolvedServers'] === undefined
34
44
  || routed['primaryServer'] === undefined) {
35
45
  return new Response(JSON.stringify({
36
- status: 'error', message: routed['error'] ?? 'No context found',
46
+ status: 'error',
47
+ message: routed['error'] ?? 'No context found',
37
48
  }, null, 2), {
38
49
  status: 404,
39
50
  headers: { 'Content-Type': 'application/json' },
@@ -43,30 +54,32 @@ async function handleRequest(request, config, kv) {
43
54
  const resolvedServers = routed['resolvedServers'];
44
55
  const primaryServer = routed['primaryServer'];
45
56
  const authResult = authenticate({
46
- type: 'http', ...(ctx['token'] !== undefined ? { token: ctx['token'] } : {}),
57
+ type: 'http',
58
+ ...((ctx['token'] !== undefined) ? { token: ctx['token'] } : {}),
47
59
  }, {
48
- authorization: received['headers'].get('authorization') ?? undefined, from: undefined,
60
+ authorization: received['headers'].get('authorization') ?? undefined,
61
+ from: undefined,
49
62
  });
50
63
  if (authResult['authenticated'] === false) {
51
- if (ctx['error_topic'] !== undefined) {
64
+ if (ctx['error_topic'] !== undefined && shouldNotifyError(ctx, 'authentication') === true) {
52
65
  try {
53
- const errorAttachmentHeaderEntries = [...received['headers'].entries()].map((entry) => {
54
- const entryName = entry[0];
55
- const entryValue = entry[1];
56
- if (entryName.toLowerCase() === 'authorization') {
66
+ const authErrorAttachmentHeaderEntries = [...received['headers'].entries()].map((entry) => {
67
+ const authEntryName = entry[0];
68
+ const authEntryValue = entry[1];
69
+ if (authEntryName.toLowerCase() === 'authorization') {
57
70
  return [
58
- entryName,
71
+ authEntryName,
59
72
  'REDACTED',
60
73
  ];
61
74
  }
62
75
  return [
63
- entryName,
64
- entryValue,
76
+ authEntryName,
77
+ authEntryValue,
65
78
  ];
66
79
  });
67
- const errorAttachmentHeaders = Object.fromEntries(errorAttachmentHeaderEntries);
68
- const errorAttachmentParsed = parse(received['rawBody'], received['headers']);
69
- const errorAttachmentData = {
80
+ const authErrorAttachmentHeaders = Object.fromEntries(authErrorAttachmentHeaderEntries);
81
+ const authErrorAttachmentParsed = parse(received['rawBody'], received['headers']);
82
+ const authErrorAttachmentData = {
70
83
  timestamp: new Date().toISOString(),
71
84
  error: {
72
85
  type: 'authentication',
@@ -80,20 +93,20 @@ async function handleRequest(request, config, kv) {
80
93
  request: {
81
94
  method: received['method'],
82
95
  url: received['url'],
83
- headers: errorAttachmentHeaders,
84
- ...(received['cfProperties'] !== undefined ? { cf: received['cfProperties'] } : {}),
96
+ headers: authErrorAttachmentHeaders,
97
+ ...((received['cfProperties'] !== undefined) ? { cf: received['cfProperties'] } : {}),
85
98
  },
86
99
  response: {
87
100
  status: 403,
88
101
  },
89
102
  body: {
90
- type: errorAttachmentParsed['type'],
91
- ...(errorAttachmentParsed['json'] !== undefined ? { json: errorAttachmentParsed['json'] } : {}),
92
- ...(errorAttachmentParsed['text'] !== undefined ? { text: errorAttachmentParsed['text'] } : {}),
103
+ type: authErrorAttachmentParsed['type'],
104
+ ...((authErrorAttachmentParsed['json'] !== undefined) ? { json: authErrorAttachmentParsed['json'] } : {}),
105
+ ...((authErrorAttachmentParsed['text'] !== undefined) ? { text: authErrorAttachmentParsed['text'] } : {}),
93
106
  },
94
107
  };
95
- const errorAttachmentJson = JSON.stringify(errorAttachmentData, null, 2);
96
- const errorAttachmentBuffer = new TextEncoder().encode(errorAttachmentJson).buffer;
108
+ const authErrorAttachmentJson = JSON.stringify(authErrorAttachmentData, null, 2);
109
+ const authErrorAttachmentBuffer = new TextEncoder().encode(authErrorAttachmentJson).buffer;
97
110
  await send({
98
111
  messages: [],
99
112
  servers: resolvedServers,
@@ -101,7 +114,7 @@ async function handleRequest(request, config, kv) {
101
114
  topic: ctx['error_topic'],
102
115
  mode: ctx['mode'],
103
116
  visitorIp: received['headers'].get('cf-connecting-ip') ?? undefined,
104
- attachment: errorAttachmentBuffer,
117
+ attachment: authErrorAttachmentBuffer,
105
118
  filename: 'error-debug.json',
106
119
  attachmentHeaders: { 'X-Title': 'Authentication Error' },
107
120
  });
@@ -110,7 +123,8 @@ async function handleRequest(request, config, kv) {
110
123
  }
111
124
  }
112
125
  return new Response(JSON.stringify({
113
- status: 'error', message: 'Unauthorized',
126
+ status: 'error',
127
+ message: 'Unauthorized',
114
128
  }, null, 2), {
115
129
  status: 403,
116
130
  headers: { 'Content-Type': 'application/json' },
@@ -119,7 +133,8 @@ async function handleRequest(request, config, kv) {
119
133
  const parsed = parse(received['rawBody'], received['headers']);
120
134
  if (parsed['type'] === 'unknown') {
121
135
  return new Response(JSON.stringify({
122
- status: 'error', message: 'Unknown content type',
136
+ status: 'error',
137
+ message: 'Unknown content type',
123
138
  }, null, 2), {
124
139
  status: 400,
125
140
  headers: { 'Content-Type': 'application/json' },
@@ -128,7 +143,9 @@ async function handleRequest(request, config, kv) {
128
143
  const rawBodyJsonStr = (parsed['json'] !== undefined) ? JSON.stringify(parsed['json']) : '';
129
144
  const rawBodyText = parsed['text'] ?? ((rawBodyJsonStr.length > 0) ? rawBodyJsonStr : undefined);
130
145
  const debugRawRequestStr = JSON.stringify({
131
- debug: 'raw_request', type: parsed['type'], body: rawBodyText ?? '(binary)',
146
+ debug: 'raw_request',
147
+ type: parsed['type'],
148
+ body: rawBodyText ?? '(binary)',
132
149
  });
133
150
  console.info(debugRawRequestStr);
134
151
  const input = parsed['json']
@@ -140,43 +157,43 @@ async function handleRequest(request, config, kv) {
140
157
  interpreted = await interpret(ctx['interpreter'], input, (kv !== undefined) ? { kv } : {});
141
158
  }
142
159
  catch (err) {
143
- const errorName = (err instanceof Error) ? err.name : 'Error';
144
- const errorMessage = (err instanceof Error) ? err.message : 'Unknown interpretation error';
145
- const errorStack = (err instanceof Error) ? err.stack : undefined;
146
- let errorIssues = undefined;
160
+ const interpretErrorName = (err instanceof Error) ? err.name : 'Error';
161
+ const interpretErrorMessage = (err instanceof Error) ? err.message : 'Unknown interpretation error';
162
+ const interpretErrorStack = (err instanceof Error) ? err.stack : undefined;
163
+ let interpretErrorIssues = undefined;
147
164
  if (err instanceof Error
148
165
  && err.name === 'ZodError'
149
166
  && 'issues' in err) {
150
- const errorIssuesRaw = Reflect.get(err, 'issues');
151
- if (Array.isArray(errorIssuesRaw) === true) {
152
- errorIssues = errorIssuesRaw;
167
+ const interpretErrorIssuesRaw = Reflect.get(err, 'issues');
168
+ if (Array.isArray(interpretErrorIssuesRaw) === true) {
169
+ interpretErrorIssues = interpretErrorIssuesRaw;
153
170
  }
154
171
  }
155
- if (ctx['error_topic'] !== undefined) {
172
+ if (ctx['error_topic'] !== undefined && shouldNotifyError(ctx, 'interpretation') === true) {
156
173
  try {
157
- const errorAttachmentHeaderEntries = [...received['headers'].entries()].map((entry) => {
158
- const entryName = entry[0];
159
- const entryValue = entry[1];
160
- if (entryName.toLowerCase() === 'authorization') {
174
+ const interpretErrorAttachmentHeaderEntries = [...received['headers'].entries()].map((entry) => {
175
+ const interpretEntryName = entry[0];
176
+ const interpretEntryValue = entry[1];
177
+ if (interpretEntryName.toLowerCase() === 'authorization') {
161
178
  return [
162
- entryName,
179
+ interpretEntryName,
163
180
  'REDACTED',
164
181
  ];
165
182
  }
166
183
  return [
167
- entryName,
168
- entryValue,
184
+ interpretEntryName,
185
+ interpretEntryValue,
169
186
  ];
170
187
  });
171
- const errorAttachmentHeaders = Object.fromEntries(errorAttachmentHeaderEntries);
172
- const errorAttachmentData = {
188
+ const interpretErrorAttachmentHeaders = Object.fromEntries(interpretErrorAttachmentHeaderEntries);
189
+ const interpretErrorAttachmentData = {
173
190
  timestamp: new Date().toISOString(),
174
191
  error: {
175
192
  type: 'interpretation',
176
- name: errorName,
177
- message: errorMessage,
178
- ...(errorStack !== undefined ? { stack: errorStack } : {}),
179
- ...(errorIssues !== undefined ? { issues: errorIssues } : {}),
193
+ name: interpretErrorName,
194
+ message: interpretErrorMessage,
195
+ ...((interpretErrorStack !== undefined) ? { stack: interpretErrorStack } : {}),
196
+ ...((interpretErrorIssues !== undefined) ? { issues: interpretErrorIssues } : {}),
180
197
  },
181
198
  context: {
182
199
  name: ctx['name'],
@@ -186,20 +203,20 @@ async function handleRequest(request, config, kv) {
186
203
  request: {
187
204
  method: received['method'],
188
205
  url: received['url'],
189
- headers: errorAttachmentHeaders,
190
- ...(received['cfProperties'] !== undefined ? { cf: received['cfProperties'] } : {}),
206
+ headers: interpretErrorAttachmentHeaders,
207
+ ...((received['cfProperties'] !== undefined) ? { cf: received['cfProperties'] } : {}),
191
208
  },
192
209
  response: {
193
210
  status: 422,
194
211
  },
195
212
  body: {
196
213
  type: parsed['type'],
197
- ...(parsed['json'] !== undefined ? { json: parsed['json'] } : {}),
198
- ...(parsed['text'] !== undefined ? { text: parsed['text'] } : {}),
214
+ ...((parsed['json'] !== undefined) ? { json: parsed['json'] } : {}),
215
+ ...((parsed['text'] !== undefined) ? { text: parsed['text'] } : {}),
199
216
  },
200
217
  };
201
- const errorAttachmentJson = JSON.stringify(errorAttachmentData, null, 2);
202
- const errorAttachmentBuffer = new TextEncoder().encode(errorAttachmentJson).buffer;
218
+ const interpretErrorAttachmentJson = JSON.stringify(interpretErrorAttachmentData, null, 2);
219
+ const interpretErrorAttachmentBuffer = new TextEncoder().encode(interpretErrorAttachmentJson).buffer;
203
220
  await send({
204
221
  messages: [],
205
222
  servers: resolvedServers,
@@ -207,7 +224,7 @@ async function handleRequest(request, config, kv) {
207
224
  topic: ctx['error_topic'],
208
225
  mode: ctx['mode'],
209
226
  visitorIp: received['headers'].get('cf-connecting-ip') ?? undefined,
210
- attachment: errorAttachmentBuffer,
227
+ attachment: interpretErrorAttachmentBuffer,
211
228
  filename: 'error-debug.json',
212
229
  attachmentHeaders: { 'X-Title': 'Interpretation Error' },
213
230
  });
@@ -216,7 +233,8 @@ async function handleRequest(request, config, kv) {
216
233
  }
217
234
  }
218
235
  return new Response(JSON.stringify({
219
- status: 'error', message: errorMessage,
236
+ status: 'error',
237
+ message: interpretErrorMessage,
220
238
  }, null, 2), {
221
239
  status: 422,
222
240
  headers: { 'Content-Type': 'application/json' },
@@ -263,11 +281,13 @@ async function handleRequest(request, config, kv) {
263
281
  return response;
264
282
  }
265
283
  catch (err) {
266
- const errorMessage = (err instanceof Error) ? err.message : 'Internal server error';
284
+ const fatalErrorMessage = (err instanceof Error) ? err.message : 'Internal server error';
267
285
  const body = (config['settings']['show_response_output'] === true) ? {
268
- status: 'error', message: errorMessage,
286
+ status: 'error',
287
+ message: fatalErrorMessage,
269
288
  } : {
270
- status: 'error', message: 'Internal server error',
289
+ status: 'error',
290
+ message: 'Internal server error',
271
291
  };
272
292
  return new Response(JSON.stringify(body, null, 2), {
273
293
  status: 500,
@@ -276,158 +296,174 @@ async function handleRequest(request, config, kv) {
276
296
  }
277
297
  }
278
298
  async function handleEmail(rawEmail, from, config, kv) {
279
- const parsed = await parseEmail(rawEmail);
280
- const debugRawEmailStr = JSON.stringify({
281
- debug: 'raw_email', from, to: parsed['to'], subject: parsed['subject'], rawEmail,
282
- });
283
- console.info(debugRawEmailStr);
284
- const recipientLocalPart = parsed['to'].split('@')[0] ?? '';
285
- const routed = route('email', recipientLocalPart, config);
286
- if (routed['error'] !== undefined
287
- || routed['context'] === undefined
288
- || routed['resolvedServers'] === undefined
289
- || routed['primaryServer'] === undefined) {
290
- return;
291
- }
292
- const ctx = routed['context'];
293
- const resolvedServers = routed['resolvedServers'];
294
- const primaryServer = routed['primaryServer'];
295
- const authResult = authenticate({
296
- type: 'email', ...(ctx['allowed_from'] !== undefined ? { allowed_from: ctx['allowed_from'] } : {}),
297
- }, {
298
- authorization: undefined, from,
299
- });
300
- if (authResult['authenticated'] === false) {
301
- if (ctx['error_topic'] !== undefined) {
302
- try {
303
- const errorAttachmentData = {
304
- timestamp: new Date().toISOString(),
305
- error: {
306
- type: 'authentication',
307
- message: authResult['reason'],
308
- },
309
- context: {
310
- name: ctx['name'],
311
- interpreter: ctx['interpreter'],
312
- stage: 'authentication',
313
- },
314
- email: {
315
- from,
316
- to: parsed['to'],
317
- subject: parsed['subject'],
318
- textBody: parsed['textBody'],
319
- },
320
- };
321
- const errorAttachmentJson = JSON.stringify(errorAttachmentData, null, 2);
322
- const errorAttachmentBuffer = new TextEncoder().encode(errorAttachmentJson).buffer;
323
- await send({
324
- messages: [],
325
- servers: resolvedServers,
326
- primaryServer,
327
- topic: ctx['error_topic'],
328
- mode: ctx['mode'],
329
- attachment: errorAttachmentBuffer,
330
- filename: 'error-debug.json',
331
- attachmentHeaders: { 'X-Title': 'Email Authentication Error' },
332
- });
333
- }
334
- catch {
335
- }
336
- }
337
- return;
338
- }
339
- const emailInput = {
340
- subject: parsed['subject'],
341
- textBody: parsed['textBody'],
342
- from: parsed['from'],
343
- to: parsed['to'],
344
- };
345
- let interpreted = undefined;
346
299
  try {
347
- interpreted = await interpret(ctx['interpreter'], emailInput, (kv !== undefined) ? { kv } : {});
348
- }
349
- catch (err) {
350
- const errorName = (err instanceof Error) ? err.name : 'Error';
351
- const errorMessage = (err instanceof Error) ? err.message : 'Unknown interpretation error';
352
- const errorStack = (err instanceof Error) ? err.stack : undefined;
353
- let errorIssues = undefined;
354
- if (err instanceof Error
355
- && err.name === 'ZodError'
356
- && 'issues' in err) {
357
- const errorIssuesRaw = Reflect.get(err, 'issues');
358
- if (Array.isArray(errorIssuesRaw) === true) {
359
- errorIssues = errorIssuesRaw;
300
+ const parsed = await parseEmail(rawEmail);
301
+ const debugRawEmailStr = JSON.stringify({
302
+ debug: 'raw_email',
303
+ from,
304
+ to: parsed['to'],
305
+ subject: parsed['subject'],
306
+ rawEmail,
307
+ });
308
+ console.info(debugRawEmailStr);
309
+ const recipientLocalPart = parsed['to'].split('@')[0] ?? '';
310
+ const routed = route('email', recipientLocalPart, config);
311
+ if (routed['error'] !== undefined
312
+ || routed['context'] === undefined
313
+ || routed['resolvedServers'] === undefined
314
+ || routed['primaryServer'] === undefined) {
315
+ return;
316
+ }
317
+ const ctx = routed['context'];
318
+ const resolvedServers = routed['resolvedServers'];
319
+ const primaryServer = routed['primaryServer'];
320
+ const authResult = authenticate({
321
+ type: 'email',
322
+ ...((ctx['allowed_from'] !== undefined) ? { allowed_from: ctx['allowed_from'] } : {}),
323
+ }, {
324
+ authorization: undefined,
325
+ from,
326
+ });
327
+ if (authResult['authenticated'] === false) {
328
+ if (ctx['error_topic'] !== undefined && shouldNotifyError(ctx, 'authentication') === true) {
329
+ try {
330
+ const authErrorAttachmentData = {
331
+ timestamp: new Date().toISOString(),
332
+ error: {
333
+ type: 'authentication',
334
+ message: authResult['reason'],
335
+ },
336
+ context: {
337
+ name: ctx['name'],
338
+ interpreter: ctx['interpreter'],
339
+ stage: 'authentication',
340
+ },
341
+ email: {
342
+ from,
343
+ to: parsed['to'],
344
+ subject: parsed['subject'],
345
+ textBody: parsed['textBody'],
346
+ },
347
+ };
348
+ const authErrorAttachmentJson = JSON.stringify(authErrorAttachmentData, null, 2);
349
+ const authErrorAttachmentBuffer = new TextEncoder().encode(authErrorAttachmentJson).buffer;
350
+ await send({
351
+ messages: [],
352
+ servers: resolvedServers,
353
+ primaryServer,
354
+ topic: ctx['error_topic'],
355
+ mode: ctx['mode'],
356
+ attachment: authErrorAttachmentBuffer,
357
+ filename: 'error-debug.json',
358
+ attachmentHeaders: { 'X-Title': 'Email Authentication Error' },
359
+ });
360
+ }
361
+ catch {
362
+ }
360
363
  }
364
+ return;
365
+ }
366
+ const emailInput = {
367
+ subject: parsed['subject'],
368
+ textBody: parsed['textBody'],
369
+ from: parsed['from'],
370
+ to: parsed['to'],
371
+ };
372
+ let interpreted = undefined;
373
+ try {
374
+ interpreted = await interpret(ctx['interpreter'], emailInput, (kv !== undefined) ? { kv } : {});
361
375
  }
362
- if (ctx['error_topic'] !== undefined) {
363
- try {
364
- const errorAttachmentData = {
365
- timestamp: new Date().toISOString(),
366
- error: {
367
- type: 'interpretation',
368
- name: errorName,
369
- message: errorMessage,
370
- ...(errorStack !== undefined ? { stack: errorStack } : {}),
371
- ...(errorIssues !== undefined ? { issues: errorIssues } : {}),
372
- },
373
- context: {
374
- name: ctx['name'],
375
- interpreter: ctx['interpreter'],
376
- stage: 'interpretation',
377
- },
378
- email: {
379
- from,
380
- to: parsed['to'],
381
- subject: parsed['subject'],
382
- textBody: parsed['textBody'],
383
- },
384
- };
385
- const errorAttachmentJson = JSON.stringify(errorAttachmentData, null, 2);
386
- const errorAttachmentBuffer = new TextEncoder().encode(errorAttachmentJson).buffer;
387
- await send({
388
- messages: [],
389
- servers: resolvedServers,
390
- primaryServer,
391
- topic: ctx['error_topic'],
392
- mode: ctx['mode'],
393
- attachment: errorAttachmentBuffer,
394
- filename: 'error-debug.json',
395
- attachmentHeaders: { 'X-Title': 'Email Interpretation Error' },
396
- });
376
+ catch (err) {
377
+ const errorName = (err instanceof Error) ? err.name : 'Error';
378
+ const errorMessage = (err instanceof Error) ? err.message : 'Unknown interpretation error';
379
+ const errorStack = (err instanceof Error) ? err.stack : undefined;
380
+ let errorIssues = undefined;
381
+ if (err instanceof Error
382
+ && err.name === 'ZodError'
383
+ && 'issues' in err) {
384
+ const errorIssuesRaw = Reflect.get(err, 'issues');
385
+ if (Array.isArray(errorIssuesRaw) === true) {
386
+ errorIssues = errorIssuesRaw;
387
+ }
397
388
  }
398
- catch {
389
+ if (ctx['error_topic'] !== undefined && shouldNotifyError(ctx, 'interpretation') === true) {
390
+ try {
391
+ const interpretErrorAttachmentData = {
392
+ timestamp: new Date().toISOString(),
393
+ error: {
394
+ type: 'interpretation',
395
+ name: errorName,
396
+ message: errorMessage,
397
+ ...((errorStack !== undefined) ? { stack: errorStack } : {}),
398
+ ...((errorIssues !== undefined) ? { issues: errorIssues } : {}),
399
+ },
400
+ context: {
401
+ name: ctx['name'],
402
+ interpreter: ctx['interpreter'],
403
+ stage: 'interpretation',
404
+ },
405
+ email: {
406
+ from,
407
+ to: parsed['to'],
408
+ subject: parsed['subject'],
409
+ textBody: parsed['textBody'],
410
+ },
411
+ };
412
+ const interpretErrorAttachmentJson = JSON.stringify(interpretErrorAttachmentData, null, 2);
413
+ const interpretErrorAttachmentBuffer = new TextEncoder().encode(interpretErrorAttachmentJson).buffer;
414
+ await send({
415
+ messages: [],
416
+ servers: resolvedServers,
417
+ primaryServer,
418
+ topic: ctx['error_topic'],
419
+ mode: ctx['mode'],
420
+ attachment: interpretErrorAttachmentBuffer,
421
+ filename: 'error-debug.json',
422
+ attachmentHeaders: { 'X-Title': 'Email Interpretation Error' },
423
+ });
424
+ }
425
+ catch {
426
+ }
399
427
  }
428
+ return;
400
429
  }
401
- return;
402
- }
403
- if (interpreted === null) {
404
- return;
430
+ if (interpreted === null) {
431
+ return;
432
+ }
433
+ if (interpreted['notification']['title'] === undefined) {
434
+ Reflect.set(interpreted['notification'], 'title', ctx['name']);
435
+ }
436
+ const formatted = format(interpreted['notification'], {
437
+ showVisitorInfo: ctx['show_visitor_info'],
438
+ });
439
+ const messages = split(formatted['body'], formatted['headers']);
440
+ const sendResult = await send({
441
+ messages,
442
+ servers: resolvedServers,
443
+ primaryServer,
444
+ topic: ctx['topic'],
445
+ mode: ctx['mode'],
446
+ attachment: interpreted['attachment'],
447
+ filename: interpreted['notification']['filename'],
448
+ });
449
+ const debugLogStr = JSON.stringify({
450
+ context: ctx['name'],
451
+ interpreter: ctx['interpreter'],
452
+ servers: sendResult['results'],
453
+ bodySize: formatted['body'].length,
454
+ parts: messages.length,
455
+ }, null, 2);
456
+ console.info(debugLogStr);
405
457
  }
406
- if (interpreted['notification']['title'] === undefined) {
407
- Reflect.set(interpreted['notification'], 'title', ctx['name']);
458
+ catch (err) {
459
+ const fatalErrorMessage = (err instanceof Error) ? err.message : 'Unknown error';
460
+ const fatalDebugStr = JSON.stringify({
461
+ debug: 'fatal_email_error',
462
+ error: fatalErrorMessage,
463
+ });
464
+ console.info(fatalDebugStr);
408
465
  }
409
- const formatted = format(interpreted['notification'], {
410
- showVisitorInfo: ctx['show_visitor_info'],
411
- });
412
- const messages = split(formatted['body'], formatted['headers']);
413
- const sendResult = await send({
414
- messages,
415
- servers: resolvedServers,
416
- primaryServer,
417
- topic: ctx['topic'],
418
- mode: ctx['mode'],
419
- attachment: interpreted['attachment'],
420
- filename: interpreted['notification']['filename'],
421
- });
422
- const debugLogStr = JSON.stringify({
423
- context: ctx['name'],
424
- interpreter: ctx['interpreter'],
425
- servers: sendResult['results'],
426
- bodySize: formatted['body'].length,
427
- parts: messages.length,
428
- }, null, 2);
429
- console.info(debugLogStr);
430
466
  return;
431
467
  }
432
- export { handleEmail, handleRequest, };
468
+ export { handleEmail, handleRequest, shouldNotifyError, };
433
469
  //# sourceMappingURL=handlers.js.map