Commit
+1227 -993 +/-26 browse
1 | diff --git a/Cargo.lock b/Cargo.lock |
2 | index 0d4e9d6..1b5bc64 100644 |
3 | --- a/Cargo.lock |
4 | +++ b/Cargo.lock |
5 | @@ -18,6 +18,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
6 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" |
7 | |
8 | [[package]] |
9 | + name = "aes" |
10 | + version = "0.8.4" |
11 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
12 | + checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" |
13 | + dependencies = [ |
14 | + "cfg-if", |
15 | + "cipher", |
16 | + "cpufeatures", |
17 | + ] |
18 | + |
19 | + [[package]] |
20 | name = "ahash" |
21 | version = "0.7.8" |
22 | source = "registry+https://github.com/rust-lang/crates.io-index" |
23 | @@ -91,9 +102,9 @@ dependencies = [ |
24 | |
25 | [[package]] |
26 | name = "anstream" |
27 | - version = "0.6.15" |
28 | + version = "0.6.17" |
29 | source = "registry+https://github.com/rust-lang/crates.io-index" |
30 | - checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" |
31 | + checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" |
32 | dependencies = [ |
33 | "anstyle", |
34 | "anstyle-parse", |
35 | @@ -106,43 +117,52 @@ dependencies = [ |
36 | |
37 | [[package]] |
38 | name = "anstyle" |
39 | - version = "1.0.8" |
40 | + version = "1.0.9" |
41 | source = "registry+https://github.com/rust-lang/crates.io-index" |
42 | - checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" |
43 | + checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" |
44 | |
45 | [[package]] |
46 | name = "anstyle-parse" |
47 | - version = "0.2.5" |
48 | + version = "0.2.6" |
49 | source = "registry+https://github.com/rust-lang/crates.io-index" |
50 | - checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" |
51 | + checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" |
52 | dependencies = [ |
53 | "utf8parse", |
54 | ] |
55 | |
56 | [[package]] |
57 | name = "anstyle-query" |
58 | - version = "1.1.1" |
59 | + version = "1.1.2" |
60 | source = "registry+https://github.com/rust-lang/crates.io-index" |
61 | - checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" |
62 | + checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" |
63 | dependencies = [ |
64 | - "windows-sys 0.52.0", |
65 | + "windows-sys 0.59.0", |
66 | ] |
67 | |
68 | [[package]] |
69 | name = "anstyle-wincon" |
70 | - version = "3.0.4" |
71 | + version = "3.0.6" |
72 | source = "registry+https://github.com/rust-lang/crates.io-index" |
73 | - checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" |
74 | + checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" |
75 | dependencies = [ |
76 | "anstyle", |
77 | - "windows-sys 0.52.0", |
78 | + "windows-sys 0.59.0", |
79 | ] |
80 | |
81 | [[package]] |
82 | name = "anyhow" |
83 | - version = "1.0.89" |
84 | + version = "1.0.91" |
85 | source = "registry+https://github.com/rust-lang/crates.io-index" |
86 | - checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" |
87 | + checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" |
88 | + |
89 | + [[package]] |
90 | + name = "arbitrary" |
91 | + version = "1.3.2" |
92 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
93 | + checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" |
94 | + dependencies = [ |
95 | + "derive_arbitrary", |
96 | + ] |
97 | |
98 | [[package]] |
99 | name = "arrayvec" |
100 | @@ -167,7 +187,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" |
101 | dependencies = [ |
102 | "proc-macro2", |
103 | "quote", |
104 | - "syn 2.0.79", |
105 | + "syn 2.0.85", |
106 | ] |
107 | |
108 | [[package]] |
109 | @@ -216,6 +236,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
110 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" |
111 | |
112 | [[package]] |
113 | + name = "aws-lc-rs" |
114 | + version = "1.10.0" |
115 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
116 | + checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d" |
117 | + dependencies = [ |
118 | + "aws-lc-sys", |
119 | + "mirai-annotations", |
120 | + "paste", |
121 | + "zeroize", |
122 | + ] |
123 | + |
124 | + [[package]] |
125 | + name = "aws-lc-sys" |
126 | + version = "0.22.0" |
127 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
128 | + checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972" |
129 | + dependencies = [ |
130 | + "bindgen", |
131 | + "cc", |
132 | + "cmake", |
133 | + "dunce", |
134 | + "fs_extra", |
135 | + "libc", |
136 | + "paste", |
137 | + ] |
138 | + |
139 | + [[package]] |
140 | name = "axum" |
141 | version = "0.7.7" |
142 | source = "registry+https://github.com/rust-lang/crates.io-index" |
143 | @@ -229,7 +276,7 @@ dependencies = [ |
144 | "http 1.1.0", |
145 | "http-body 1.0.1", |
146 | "http-body-util", |
147 | - "hyper 1.4.1", |
148 | + "hyper 1.5.0", |
149 | "hyper-util", |
150 | "itoa", |
151 | "matchit", |
152 | @@ -304,7 +351,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" |
153 | dependencies = [ |
154 | "proc-macro2", |
155 | "quote", |
156 | - "syn 2.0.79", |
157 | + "syn 2.0.85", |
158 | ] |
159 | |
160 | [[package]] |
161 | @@ -424,6 +471,25 @@ dependencies = [ |
162 | ] |
163 | |
164 | [[package]] |
165 | + name = "ayllu-mail" |
166 | + version = "0.2.1" |
167 | + dependencies = [ |
168 | + "async-trait", |
169 | + "axum", |
170 | + "ayllu_config", |
171 | + "ayllu_database", |
172 | + "clap 4.5.20", |
173 | + "clap_complete", |
174 | + "futures", |
175 | + "maitred", |
176 | + "serde", |
177 | + "thiserror", |
178 | + "tokio", |
179 | + "tracing", |
180 | + "tracing-subscriber", |
181 | + ] |
182 | + |
183 | + [[package]] |
184 | name = "ayllu_api" |
185 | version = "0.2.1" |
186 | dependencies = [ |
187 | @@ -540,6 +606,29 @@ dependencies = [ |
188 | ] |
189 | |
190 | [[package]] |
191 | + name = "bindgen" |
192 | + version = "0.69.5" |
193 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
194 | + checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" |
195 | + dependencies = [ |
196 | + "bitflags 2.6.0", |
197 | + "cexpr", |
198 | + "clang-sys", |
199 | + "itertools 0.12.1", |
200 | + "lazy_static", |
201 | + "lazycell", |
202 | + "log", |
203 | + "prettyplease", |
204 | + "proc-macro2", |
205 | + "quote", |
206 | + "regex", |
207 | + "rustc-hash", |
208 | + "shlex", |
209 | + "syn 2.0.85", |
210 | + "which", |
211 | + ] |
212 | + |
213 | + [[package]] |
214 | name = "bit-set" |
215 | version = "0.5.3" |
216 | source = "registry+https://github.com/rust-lang/crates.io-index" |
217 | @@ -630,9 +719,9 @@ dependencies = [ |
218 | |
219 | [[package]] |
220 | name = "bytemuck" |
221 | - version = "1.18.0" |
222 | + version = "1.19.0" |
223 | source = "registry+https://github.com/rust-lang/crates.io-index" |
224 | - checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" |
225 | + checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" |
226 | |
227 | [[package]] |
228 | name = "byteorder" |
229 | @@ -642,9 +731,30 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" |
230 | |
231 | [[package]] |
232 | name = "bytes" |
233 | - version = "1.7.2" |
234 | + version = "1.8.0" |
235 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
236 | + checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" |
237 | + |
238 | + [[package]] |
239 | + name = "bzip2" |
240 | + version = "0.4.4" |
241 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
242 | + checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" |
243 | + dependencies = [ |
244 | + "bzip2-sys", |
245 | + "libc", |
246 | + ] |
247 | + |
248 | + [[package]] |
249 | + name = "bzip2-sys" |
250 | + version = "0.1.11+1.0.8" |
251 | source = "registry+https://github.com/rust-lang/crates.io-index" |
252 | - checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" |
253 | + checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" |
254 | + dependencies = [ |
255 | + "cc", |
256 | + "libc", |
257 | + "pkg-config", |
258 | + ] |
259 | |
260 | [[package]] |
261 | name = "caseless" |
262 | @@ -658,9 +768,9 @@ dependencies = [ |
263 | |
264 | [[package]] |
265 | name = "cc" |
266 | - version = "1.1.29" |
267 | + version = "1.1.31" |
268 | source = "registry+https://github.com/rust-lang/crates.io-index" |
269 | - checksum = "58e804ac3194a48bb129643eb1d62fcc20d18c6b8c181704489353d13120bcd1" |
270 | + checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" |
271 | dependencies = [ |
272 | "jobserver", |
273 | "libc", |
274 | @@ -668,12 +778,31 @@ dependencies = [ |
275 | ] |
276 | |
277 | [[package]] |
278 | + name = "cexpr" |
279 | + version = "0.6.0" |
280 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
281 | + checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" |
282 | + dependencies = [ |
283 | + "nom", |
284 | + ] |
285 | + |
286 | + [[package]] |
287 | name = "cfg-if" |
288 | version = "1.0.0" |
289 | source = "registry+https://github.com/rust-lang/crates.io-index" |
290 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" |
291 | |
292 | [[package]] |
293 | + name = "charset" |
294 | + version = "0.1.5" |
295 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
296 | + checksum = "f1f927b07c74ba84c7e5fe4db2baeb3e996ab2688992e39ac68ce3220a677c7e" |
297 | + dependencies = [ |
298 | + "base64 0.22.1", |
299 | + "encoding_rs", |
300 | + ] |
301 | + |
302 | + [[package]] |
303 | name = "chrono" |
304 | version = "0.4.38" |
305 | source = "registry+https://github.com/rust-lang/crates.io-index" |
306 | @@ -711,6 +840,27 @@ dependencies = [ |
307 | ] |
308 | |
309 | [[package]] |
310 | + name = "cipher" |
311 | + version = "0.4.4" |
312 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
313 | + checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" |
314 | + dependencies = [ |
315 | + "crypto-common", |
316 | + "inout", |
317 | + ] |
318 | + |
319 | + [[package]] |
320 | + name = "clang-sys" |
321 | + version = "1.8.1" |
322 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
323 | + checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" |
324 | + dependencies = [ |
325 | + "glob", |
326 | + "libc", |
327 | + "libloading", |
328 | + ] |
329 | + |
330 | + [[package]] |
331 | name = "clap" |
332 | version = "2.34.0" |
333 | source = "registry+https://github.com/rust-lang/crates.io-index" |
334 | @@ -750,9 +900,9 @@ dependencies = [ |
335 | |
336 | [[package]] |
337 | name = "clap_complete" |
338 | - version = "4.5.33" |
339 | + version = "4.5.35" |
340 | source = "registry+https://github.com/rust-lang/crates.io-index" |
341 | - checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" |
342 | + checksum = "07a13ab5b8cb13dbe35e68b83f6c12f9293b2f601797b71bc9f23befdb329feb" |
343 | dependencies = [ |
344 | "clap 4.5.20", |
345 | ] |
346 | @@ -766,7 +916,7 @@ dependencies = [ |
347 | "heck", |
348 | "proc-macro2", |
349 | "quote", |
350 | - "syn 2.0.79", |
351 | + "syn 2.0.85", |
352 | ] |
353 | |
354 | [[package]] |
355 | @@ -776,6 +926,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
356 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" |
357 | |
358 | [[package]] |
359 | + name = "cmake" |
360 | + version = "0.1.51" |
361 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
362 | + checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" |
363 | + dependencies = [ |
364 | + "cc", |
365 | + ] |
366 | + |
367 | + [[package]] |
368 | name = "color_quant" |
369 | version = "1.1.0" |
370 | source = "registry+https://github.com/rust-lang/crates.io-index" |
371 | @@ -783,9 +942,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" |
372 | |
373 | [[package]] |
374 | name = "colorchoice" |
375 | - version = "1.0.2" |
376 | + version = "1.0.3" |
377 | source = "registry+https://github.com/rust-lang/crates.io-index" |
378 | - checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" |
379 | + checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" |
380 | |
381 | [[package]] |
382 | name = "comrak" |
383 | @@ -844,6 +1003,12 @@ dependencies = [ |
384 | ] |
385 | |
386 | [[package]] |
387 | + name = "constant_time_eq" |
388 | + version = "0.3.1" |
389 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
390 | + checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" |
391 | + |
392 | + [[package]] |
393 | name = "convert_case" |
394 | version = "0.6.0" |
395 | source = "registry+https://github.com/rust-lang/crates.io-index" |
396 | @@ -1030,7 +1195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
397 | checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" |
398 | dependencies = [ |
399 | "quote", |
400 | - "syn 2.0.79", |
401 | + "syn 2.0.85", |
402 | ] |
403 | |
404 | [[package]] |
405 | @@ -1054,7 +1219,7 @@ dependencies = [ |
406 | "proc-macro2", |
407 | "quote", |
408 | "strsim 0.11.1", |
409 | - "syn 2.0.79", |
410 | + "syn 2.0.85", |
411 | ] |
412 | |
413 | [[package]] |
414 | @@ -1065,7 +1230,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" |
415 | dependencies = [ |
416 | "darling_core", |
417 | "quote", |
418 | - "syn 2.0.79", |
419 | + "syn 2.0.85", |
420 | ] |
421 | |
422 | [[package]] |
423 | @@ -1108,6 +1273,12 @@ dependencies = [ |
424 | ] |
425 | |
426 | [[package]] |
427 | + name = "deflate64" |
428 | + version = "0.1.9" |
429 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
430 | + checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" |
431 | + |
432 | + [[package]] |
433 | name = "der" |
434 | version = "0.7.9" |
435 | source = "registry+https://github.com/rust-lang/crates.io-index" |
436 | @@ -1129,6 +1300,17 @@ dependencies = [ |
437 | ] |
438 | |
439 | [[package]] |
440 | + name = "derive_arbitrary" |
441 | + version = "1.3.2" |
442 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
443 | + checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" |
444 | + dependencies = [ |
445 | + "proc-macro2", |
446 | + "quote", |
447 | + "syn 2.0.85", |
448 | + ] |
449 | + |
450 | + [[package]] |
451 | name = "derive_builder" |
452 | version = "0.20.2" |
453 | source = "registry+https://github.com/rust-lang/crates.io-index" |
454 | @@ -1146,7 +1328,7 @@ dependencies = [ |
455 | "darling", |
456 | "proc-macro2", |
457 | "quote", |
458 | - "syn 2.0.79", |
459 | + "syn 2.0.85", |
460 | ] |
461 | |
462 | [[package]] |
463 | @@ -1156,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
464 | checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" |
465 | dependencies = [ |
466 | "derive_builder_core", |
467 | - "syn 2.0.79", |
468 | + "syn 2.0.85", |
469 | ] |
470 | |
471 | [[package]] |
472 | @@ -1228,6 +1410,17 @@ dependencies = [ |
473 | ] |
474 | |
475 | [[package]] |
476 | + name = "displaydoc" |
477 | + version = "0.2.5" |
478 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
479 | + checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" |
480 | + dependencies = [ |
481 | + "proc-macro2", |
482 | + "quote", |
483 | + "syn 2.0.85", |
484 | + ] |
485 | + |
486 | + [[package]] |
487 | name = "dlib" |
488 | version = "0.5.2" |
489 | source = "registry+https://github.com/rust-lang/crates.io-index" |
490 | @@ -1267,6 +1460,12 @@ dependencies = [ |
491 | ] |
492 | |
493 | [[package]] |
494 | + name = "dunce" |
495 | + version = "1.0.5" |
496 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
497 | + checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" |
498 | + |
499 | + [[package]] |
500 | name = "dwrote" |
501 | version = "0.11.2" |
502 | source = "registry+https://github.com/rust-lang/crates.io-index" |
503 | @@ -1300,10 +1499,19 @@ dependencies = [ |
504 | ] |
505 | |
506 | [[package]] |
507 | + name = "email_address" |
508 | + version = "0.2.9" |
509 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
510 | + checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" |
511 | + dependencies = [ |
512 | + "serde", |
513 | + ] |
514 | + |
515 | + [[package]] |
516 | name = "encoding_rs" |
517 | - version = "0.8.34" |
518 | + version = "0.8.35" |
519 | source = "registry+https://github.com/rust-lang/crates.io-index" |
520 | - checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" |
521 | + checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" |
522 | dependencies = [ |
523 | "cfg-if", |
524 | ] |
525 | @@ -1324,6 +1532,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
526 | checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" |
527 | |
528 | [[package]] |
529 | + name = "enum-as-inner" |
530 | + version = "0.6.1" |
531 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
532 | + checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" |
533 | + dependencies = [ |
534 | + "heck", |
535 | + "proc-macro2", |
536 | + "quote", |
537 | + "syn 2.0.85", |
538 | + ] |
539 | + |
540 | + [[package]] |
541 | name = "enum-ordinalize" |
542 | version = "3.1.15" |
543 | source = "registry+https://github.com/rust-lang/crates.io-index" |
544 | @@ -1333,7 +1553,7 @@ dependencies = [ |
545 | "num-traits", |
546 | "proc-macro2", |
547 | "quote", |
548 | - "syn 2.0.79", |
549 | + "syn 2.0.85", |
550 | ] |
551 | |
552 | [[package]] |
553 | @@ -1462,13 +1682,13 @@ checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" |
554 | |
555 | [[package]] |
556 | name = "flume" |
557 | - version = "0.11.0" |
558 | + version = "0.11.1" |
559 | source = "registry+https://github.com/rust-lang/crates.io-index" |
560 | - checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" |
561 | + checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" |
562 | dependencies = [ |
563 | "futures-core", |
564 | "futures-sink", |
565 | - "spin", |
566 | + "spin 0.9.8", |
567 | ] |
568 | |
569 | [[package]] |
570 | @@ -1529,7 +1749,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" |
571 | dependencies = [ |
572 | "proc-macro2", |
573 | "quote", |
574 | - "syn 2.0.79", |
575 | + "syn 2.0.85", |
576 | ] |
577 | |
578 | [[package]] |
579 | @@ -1565,6 +1785,12 @@ dependencies = [ |
580 | ] |
581 | |
582 | [[package]] |
583 | + name = "fs_extra" |
584 | + version = "1.3.0" |
585 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
586 | + checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" |
587 | + |
588 | + [[package]] |
589 | name = "funty" |
590 | version = "2.0.0" |
591 | source = "registry+https://github.com/rust-lang/crates.io-index" |
592 | @@ -1637,7 +1863,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" |
593 | dependencies = [ |
594 | "proc-macro2", |
595 | "quote", |
596 | - "syn 2.0.79", |
597 | + "syn 2.0.85", |
598 | ] |
599 | |
600 | [[package]] |
601 | @@ -1690,6 +1916,26 @@ dependencies = [ |
602 | ] |
603 | |
604 | [[package]] |
605 | + name = "gethostname" |
606 | + version = "0.2.3" |
607 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
608 | + checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" |
609 | + dependencies = [ |
610 | + "libc", |
611 | + "winapi", |
612 | + ] |
613 | + |
614 | + [[package]] |
615 | + name = "gethostname" |
616 | + version = "0.4.3" |
617 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
618 | + checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" |
619 | + dependencies = [ |
620 | + "libc", |
621 | + "windows-targets 0.48.5", |
622 | + ] |
623 | + |
624 | + [[package]] |
625 | name = "getrandom" |
626 | version = "0.2.15" |
627 | source = "registry+https://github.com/rust-lang/crates.io-index" |
628 | @@ -1772,9 +2018,9 @@ dependencies = [ |
629 | |
630 | [[package]] |
631 | name = "grep-searcher" |
632 | - version = "0.1.13" |
633 | + version = "0.1.14" |
634 | source = "registry+https://github.com/rust-lang/crates.io-index" |
635 | - checksum = "ba536ae4f69bec62d8839584dd3153d3028ef31bb229f04e09fb5a9e5a193c54" |
636 | + checksum = "b9b6c14b3fc2e0a107d6604d3231dec0509e691e62447104bc385a46a7892cda" |
637 | dependencies = [ |
638 | "bstr", |
639 | "encoding_rs", |
640 | @@ -1909,6 +2155,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
641 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" |
642 | |
643 | [[package]] |
644 | + name = "hickory-proto" |
645 | + version = "0.24.1" |
646 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
647 | + checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" |
648 | + dependencies = [ |
649 | + "async-trait", |
650 | + "cfg-if", |
651 | + "data-encoding", |
652 | + "enum-as-inner", |
653 | + "futures-channel", |
654 | + "futures-io", |
655 | + "futures-util", |
656 | + "idna 0.4.0", |
657 | + "ipnet", |
658 | + "once_cell", |
659 | + "rand", |
660 | + "ring 0.16.20", |
661 | + "rustls 0.21.12", |
662 | + "rustls-pemfile 1.0.4", |
663 | + "thiserror", |
664 | + "tinyvec", |
665 | + "tokio", |
666 | + "tokio-rustls 0.24.1", |
667 | + "tracing", |
668 | + "url", |
669 | + ] |
670 | + |
671 | + [[package]] |
672 | + name = "hickory-resolver" |
673 | + version = "0.24.1" |
674 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
675 | + checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" |
676 | + dependencies = [ |
677 | + "cfg-if", |
678 | + "futures-util", |
679 | + "hickory-proto", |
680 | + "ipconfig", |
681 | + "lru-cache", |
682 | + "once_cell", |
683 | + "parking_lot 0.12.3", |
684 | + "rand", |
685 | + "resolv-conf", |
686 | + "rustls 0.21.12", |
687 | + "smallvec", |
688 | + "thiserror", |
689 | + "tokio", |
690 | + "tokio-rustls 0.24.1", |
691 | + "tracing", |
692 | + ] |
693 | + |
694 | + [[package]] |
695 | name = "hkdf" |
696 | version = "0.12.4" |
697 | source = "registry+https://github.com/rust-lang/crates.io-index" |
698 | @@ -1936,6 +2233,17 @@ dependencies = [ |
699 | ] |
700 | |
701 | [[package]] |
702 | + name = "hostname" |
703 | + version = "0.3.1" |
704 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
705 | + checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" |
706 | + dependencies = [ |
707 | + "libc", |
708 | + "match_cfg", |
709 | + "winapi", |
710 | + ] |
711 | + |
712 | + [[package]] |
713 | name = "http" |
714 | version = "0.2.12" |
715 | source = "registry+https://github.com/rust-lang/crates.io-index" |
716 | @@ -2020,9 +2328,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" |
717 | |
718 | [[package]] |
719 | name = "hyper" |
720 | - version = "0.14.30" |
721 | + version = "0.14.31" |
722 | source = "registry+https://github.com/rust-lang/crates.io-index" |
723 | - checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" |
724 | + checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" |
725 | dependencies = [ |
726 | "bytes", |
727 | "futures-channel", |
728 | @@ -2044,9 +2352,9 @@ dependencies = [ |
729 | |
730 | [[package]] |
731 | name = "hyper" |
732 | - version = "1.4.1" |
733 | + version = "1.5.0" |
734 | source = "registry+https://github.com/rust-lang/crates.io-index" |
735 | - checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" |
736 | + checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" |
737 | dependencies = [ |
738 | "bytes", |
739 | "futures-channel", |
740 | @@ -2071,12 +2379,12 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" |
741 | dependencies = [ |
742 | "futures-util", |
743 | "http 1.1.0", |
744 | - "hyper 1.4.1", |
745 | + "hyper 1.5.0", |
746 | "hyper-util", |
747 | - "rustls", |
748 | + "rustls 0.23.15", |
749 | "rustls-pki-types", |
750 | "tokio", |
751 | - "tokio-rustls", |
752 | + "tokio-rustls 0.26.0", |
753 | "tower-service", |
754 | ] |
755 | |
756 | @@ -2087,7 +2395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
757 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" |
758 | dependencies = [ |
759 | "bytes", |
760 | - "hyper 0.14.30", |
761 | + "hyper 0.14.31", |
762 | "native-tls", |
763 | "tokio", |
764 | "tokio-native-tls", |
765 | @@ -2101,7 +2409,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" |
766 | dependencies = [ |
767 | "bytes", |
768 | "http-body-util", |
769 | - "hyper 1.4.1", |
770 | + "hyper 1.5.0", |
771 | "hyper-util", |
772 | "native-tls", |
773 | "tokio", |
774 | @@ -2120,7 +2428,7 @@ dependencies = [ |
775 | "futures-util", |
776 | "http 1.1.0", |
777 | "http-body 1.0.1", |
778 | - "hyper 1.4.1", |
779 | + "hyper 1.5.0", |
780 | "pin-project-lite", |
781 | "socket2", |
782 | "tokio", |
783 | @@ -2159,6 +2467,16 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" |
784 | |
785 | [[package]] |
786 | name = "idna" |
787 | + version = "0.4.0" |
788 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
789 | + checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" |
790 | + dependencies = [ |
791 | + "unicode-bidi", |
792 | + "unicode-normalization", |
793 | + ] |
794 | + |
795 | + [[package]] |
796 | + name = "idna" |
797 | version = "0.5.0" |
798 | source = "registry+https://github.com/rust-lang/crates.io-index" |
799 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" |
800 | @@ -2240,6 +2558,15 @@ dependencies = [ |
801 | ] |
802 | |
803 | [[package]] |
804 | + name = "inout" |
805 | + version = "0.1.3" |
806 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
807 | + checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" |
808 | + dependencies = [ |
809 | + "generic-array", |
810 | + ] |
811 | + |
812 | + [[package]] |
813 | name = "instant" |
814 | version = "0.1.13" |
815 | source = "registry+https://github.com/rust-lang/crates.io-index" |
816 | @@ -2249,6 +2576,18 @@ dependencies = [ |
817 | ] |
818 | |
819 | [[package]] |
820 | + name = "ipconfig" |
821 | + version = "0.3.2" |
822 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
823 | + checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" |
824 | + dependencies = [ |
825 | + "socket2", |
826 | + "widestring", |
827 | + "windows-sys 0.48.0", |
828 | + "winreg", |
829 | + ] |
830 | + |
831 | + [[package]] |
832 | name = "ipnet" |
833 | version = "2.10.1" |
834 | source = "registry+https://github.com/rust-lang/crates.io-index" |
835 | @@ -2270,6 +2609,15 @@ dependencies = [ |
836 | ] |
837 | |
838 | [[package]] |
839 | + name = "itertools" |
840 | + version = "0.12.1" |
841 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
842 | + checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" |
843 | + dependencies = [ |
844 | + "either", |
845 | + ] |
846 | + |
847 | + [[package]] |
848 | name = "itoa" |
849 | version = "1.0.11" |
850 | source = "registry+https://github.com/rust-lang/crates.io-index" |
851 | @@ -2317,7 +2665,7 @@ dependencies = [ |
852 | "convert_case", |
853 | "proc-macro2", |
854 | "quote", |
855 | - "syn 2.0.79", |
856 | + "syn 2.0.85", |
857 | ] |
858 | |
859 | [[package]] |
860 | @@ -2326,14 +2674,20 @@ version = "1.5.0" |
861 | source = "registry+https://github.com/rust-lang/crates.io-index" |
862 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" |
863 | dependencies = [ |
864 | - "spin", |
865 | + "spin 0.9.8", |
866 | ] |
867 | |
868 | [[package]] |
869 | + name = "lazycell" |
870 | + version = "1.3.0" |
871 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
872 | + checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" |
873 | + |
874 | + [[package]] |
875 | name = "libc" |
876 | - version = "0.2.159" |
877 | + version = "0.2.161" |
878 | source = "registry+https://github.com/rust-lang/crates.io-index" |
879 | - checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" |
880 | + checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" |
881 | |
882 | [[package]] |
883 | name = "libgit2-sys" |
884 | @@ -2419,70 +2773,190 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
885 | checksum = "53e225b3fa0a8bd5562c8833b1a32afa88761c4e661d3177b8cdc4e13cbf078e" |
886 | dependencies = [ |
887 | "ahash 0.8.11", |
888 | - "bitflags 2.6.0", |
889 | - "const-str", |
890 | - "cssparser", |
891 | - "cssparser-color", |
892 | - "dashmap 5.5.3", |
893 | - "data-encoding", |
894 | - "getrandom", |
895 | - "itertools", |
896 | - "lazy_static", |
897 | - "lightningcss-derive", |
898 | - "parcel_selectors", |
899 | - "parcel_sourcemap", |
900 | - "paste", |
901 | - "pathdiff", |
902 | - "rayon", |
903 | + "bitflags 2.6.0", |
904 | + "const-str", |
905 | + "cssparser", |
906 | + "cssparser-color", |
907 | + "dashmap 5.5.3", |
908 | + "data-encoding", |
909 | + "getrandom", |
910 | + "itertools 0.10.5", |
911 | + "lazy_static", |
912 | + "lightningcss-derive", |
913 | + "parcel_selectors", |
914 | + "parcel_sourcemap", |
915 | + "paste", |
916 | + "pathdiff", |
917 | + "rayon", |
918 | + "serde", |
919 | + "smallvec", |
920 | + ] |
921 | + |
922 | + [[package]] |
923 | + name = "lightningcss-derive" |
924 | + version = "1.0.0-alpha.43" |
925 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
926 | + checksum = "84c12744d1279367caed41739ef094c325d53fb0ffcd4f9b84a368796f870252" |
927 | + dependencies = [ |
928 | + "convert_case", |
929 | + "proc-macro2", |
930 | + "quote", |
931 | + "syn 1.0.109", |
932 | + ] |
933 | + |
934 | + [[package]] |
935 | + name = "linked-hash-map" |
936 | + version = "0.5.6" |
937 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
938 | + checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" |
939 | + |
940 | + [[package]] |
941 | + name = "linux-raw-sys" |
942 | + version = "0.4.14" |
943 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
944 | + checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" |
945 | + |
946 | + [[package]] |
947 | + name = "litrs" |
948 | + version = "0.4.1" |
949 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
950 | + checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" |
951 | + |
952 | + [[package]] |
953 | + name = "lock_api" |
954 | + version = "0.4.12" |
955 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
956 | + checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" |
957 | + dependencies = [ |
958 | + "autocfg", |
959 | + "scopeguard", |
960 | + ] |
961 | + |
962 | + [[package]] |
963 | + name = "lockfree-object-pool" |
964 | + version = "0.1.6" |
965 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
966 | + checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" |
967 | + |
968 | + [[package]] |
969 | + name = "log" |
970 | + version = "0.4.22" |
971 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
972 | + checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" |
973 | + |
974 | + [[package]] |
975 | + name = "lru-cache" |
976 | + version = "0.1.2" |
977 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
978 | + checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" |
979 | + dependencies = [ |
980 | + "linked-hash-map", |
981 | + ] |
982 | + |
983 | + [[package]] |
984 | + name = "lzma-rs" |
985 | + version = "0.3.0" |
986 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
987 | + checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" |
988 | + dependencies = [ |
989 | + "byteorder", |
990 | + "crc", |
991 | + ] |
992 | + |
993 | + [[package]] |
994 | + name = "mail-auth" |
995 | + version = "0.5.0" |
996 | + source = "git+https://github.com/stalwartlabs/mail-auth.git?branch=main#9cadc33fc096545f003399ca5169543539cd1434" |
997 | + dependencies = [ |
998 | + "ahash 0.8.11", |
999 | + "flate2", |
1000 | + "hickory-resolver", |
1001 | + "lru-cache", |
1002 | + "mail-builder", |
1003 | + "mail-parser", |
1004 | + "parking_lot 0.12.3", |
1005 | + "ring 0.17.8", |
1006 | + "rustls-pemfile 2.2.0", |
1007 | "serde", |
1008 | - "smallvec", |
1009 | + "serde_json", |
1010 | + "zip", |
1011 | ] |
1012 | |
1013 | [[package]] |
1014 | - name = "lightningcss-derive" |
1015 | - version = "1.0.0-alpha.43" |
1016 | + name = "mail-builder" |
1017 | + version = "0.3.2" |
1018 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1019 | - checksum = "84c12744d1279367caed41739ef094c325d53fb0ffcd4f9b84a368796f870252" |
1020 | + checksum = "25f5871d5270ed80f2ee750b95600c8d69b05f8653ad3be913b2ad2e924fefcb" |
1021 | dependencies = [ |
1022 | - "convert_case", |
1023 | - "proc-macro2", |
1024 | - "quote", |
1025 | - "syn 1.0.109", |
1026 | + "gethostname 0.4.3", |
1027 | ] |
1028 | |
1029 | [[package]] |
1030 | - name = "linked-hash-map" |
1031 | - version = "0.5.6" |
1032 | + name = "mail-parser" |
1033 | + version = "0.9.4" |
1034 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1035 | - checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" |
1036 | + checksum = "93c3b9e5d8b17faf573330bbc43b37d6e918c0a3bf8a88e7d0a220ebc84af9fc" |
1037 | + dependencies = [ |
1038 | + "encoding_rs", |
1039 | + "serde", |
1040 | + ] |
1041 | |
1042 | [[package]] |
1043 | - name = "linux-raw-sys" |
1044 | - version = "0.4.14" |
1045 | + name = "maildir" |
1046 | + version = "0.6.4" |
1047 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1048 | - checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" |
1049 | + checksum = "879a6ae6743ab8219fdee64a569094485bfe18434e82b78b27fac5cce09e1437" |
1050 | + dependencies = [ |
1051 | + "gethostname 0.2.3", |
1052 | + "mailparse", |
1053 | + ] |
1054 | |
1055 | [[package]] |
1056 | - name = "litrs" |
1057 | - version = "0.4.1" |
1058 | + name = "mailparse" |
1059 | + version = "0.14.1" |
1060 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1061 | - checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" |
1062 | + checksum = "2d096594926cab442e054e047eb8c1402f7d5b2272573b97ba68aa40629f9757" |
1063 | + dependencies = [ |
1064 | + "charset", |
1065 | + "data-encoding", |
1066 | + "quoted_printable", |
1067 | + ] |
1068 | |
1069 | [[package]] |
1070 | - name = "lock_api" |
1071 | - version = "0.4.12" |
1072 | - source = "registry+https://github.com/rust-lang/crates.io-index" |
1073 | - checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" |
1074 | + name = "maitred" |
1075 | + version = "0.1.0" |
1076 | + source = "git+https://ayllu-forge.org/ayllu/maitred?branch=main#87fff6c5a73e751a916ea97ec7e689ebd7ec71e3" |
1077 | dependencies = [ |
1078 | - "autocfg", |
1079 | - "scopeguard", |
1080 | + "async-trait", |
1081 | + "base64 0.22.1", |
1082 | + "bytes", |
1083 | + "crossbeam-deque", |
1084 | + "email_address", |
1085 | + "futures", |
1086 | + "mail-auth", |
1087 | + "mail-builder", |
1088 | + "mail-parser", |
1089 | + "maildir", |
1090 | + "md5", |
1091 | + "proxy-header", |
1092 | + "rustls 0.23.15", |
1093 | + "rustls-pemfile 2.2.0", |
1094 | + "smtp-proto", |
1095 | + "stringprep", |
1096 | + "thiserror", |
1097 | + "tokio", |
1098 | + "tokio-rustls 0.26.0", |
1099 | + "tokio-stream", |
1100 | + "tokio-util", |
1101 | + "tracing", |
1102 | + "url", |
1103 | ] |
1104 | |
1105 | [[package]] |
1106 | - name = "log" |
1107 | - version = "0.4.22" |
1108 | + name = "match_cfg" |
1109 | + version = "0.1.0" |
1110 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1111 | - checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" |
1112 | + checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" |
1113 | |
1114 | [[package]] |
1115 | name = "matchers" |
1116 | @@ -2516,6 +2990,12 @@ dependencies = [ |
1117 | ] |
1118 | |
1119 | [[package]] |
1120 | + name = "md5" |
1121 | + version = "0.7.0" |
1122 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1123 | + checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" |
1124 | + |
1125 | + [[package]] |
1126 | name = "memchr" |
1127 | version = "2.7.4" |
1128 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1129 | @@ -2523,9 +3003,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" |
1130 | |
1131 | [[package]] |
1132 | name = "memmap2" |
1133 | - version = "0.9.4" |
1134 | + version = "0.9.5" |
1135 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1136 | - checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" |
1137 | + checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" |
1138 | dependencies = [ |
1139 | "libc", |
1140 | ] |
1141 | @@ -2575,6 +3055,12 @@ dependencies = [ |
1142 | ] |
1143 | |
1144 | [[package]] |
1145 | + name = "mirai-annotations" |
1146 | + version = "1.12.0" |
1147 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1148 | + checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" |
1149 | + |
1150 | + [[package]] |
1151 | name = "native-tls" |
1152 | version = "0.2.12" |
1153 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1154 | @@ -2719,7 +3205,7 @@ dependencies = [ |
1155 | "kinded", |
1156 | "proc-macro2", |
1157 | "quote", |
1158 | - "syn 2.0.79", |
1159 | + "syn 2.0.85", |
1160 | "urlencoding", |
1161 | ] |
1162 | |
1163 | @@ -2762,9 +3248,9 @@ dependencies = [ |
1164 | |
1165 | [[package]] |
1166 | name = "openssl" |
1167 | - version = "0.10.66" |
1168 | + version = "0.10.68" |
1169 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1170 | - checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" |
1171 | + checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" |
1172 | dependencies = [ |
1173 | "bitflags 2.6.0", |
1174 | "cfg-if", |
1175 | @@ -2783,7 +3269,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" |
1176 | dependencies = [ |
1177 | "proc-macro2", |
1178 | "quote", |
1179 | - "syn 2.0.79", |
1180 | + "syn 2.0.85", |
1181 | ] |
1182 | |
1183 | [[package]] |
1184 | @@ -2794,9 +3280,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" |
1185 | |
1186 | [[package]] |
1187 | name = "openssl-sys" |
1188 | - version = "0.9.103" |
1189 | + version = "0.9.104" |
1190 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1191 | - checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" |
1192 | + checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" |
1193 | dependencies = [ |
1194 | "cc", |
1195 | "libc", |
1196 | @@ -2966,9 +3452,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" |
1197 | |
1198 | [[package]] |
1199 | name = "pathdiff" |
1200 | - version = "0.2.1" |
1201 | + version = "0.2.2" |
1202 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1203 | - checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" |
1204 | + checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" |
1205 | |
1206 | [[package]] |
1207 | name = "pathfinder_geometry" |
1208 | @@ -2990,6 +3476,16 @@ dependencies = [ |
1209 | ] |
1210 | |
1211 | [[package]] |
1212 | + name = "pbkdf2" |
1213 | + version = "0.12.2" |
1214 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1215 | + checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" |
1216 | + dependencies = [ |
1217 | + "digest", |
1218 | + "hmac", |
1219 | + ] |
1220 | + |
1221 | + [[package]] |
1222 | name = "pem-rfc7468" |
1223 | version = "0.7.0" |
1224 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1225 | @@ -3006,9 +3502,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" |
1226 | |
1227 | [[package]] |
1228 | name = "pest" |
1229 | - version = "2.7.13" |
1230 | + version = "2.7.14" |
1231 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1232 | - checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" |
1233 | + checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" |
1234 | dependencies = [ |
1235 | "memchr", |
1236 | "thiserror", |
1237 | @@ -3017,9 +3513,9 @@ dependencies = [ |
1238 | |
1239 | [[package]] |
1240 | name = "pest_derive" |
1241 | - version = "2.7.13" |
1242 | + version = "2.7.14" |
1243 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1244 | - checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" |
1245 | + checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" |
1246 | dependencies = [ |
1247 | "pest", |
1248 | "pest_generator", |
1249 | @@ -3027,22 +3523,22 @@ dependencies = [ |
1250 | |
1251 | [[package]] |
1252 | name = "pest_generator" |
1253 | - version = "2.7.13" |
1254 | + version = "2.7.14" |
1255 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1256 | - checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" |
1257 | + checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" |
1258 | dependencies = [ |
1259 | "pest", |
1260 | "pest_meta", |
1261 | "proc-macro2", |
1262 | "quote", |
1263 | - "syn 2.0.79", |
1264 | + "syn 2.0.85", |
1265 | ] |
1266 | |
1267 | [[package]] |
1268 | name = "pest_meta" |
1269 | - version = "2.7.13" |
1270 | + version = "2.7.14" |
1271 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1272 | - checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" |
1273 | + checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" |
1274 | dependencies = [ |
1275 | "once_cell", |
1276 | "pest", |
1277 | @@ -3118,7 +3614,7 @@ dependencies = [ |
1278 | "phf_shared 0.11.2", |
1279 | "proc-macro2", |
1280 | "quote", |
1281 | - "syn 2.0.79", |
1282 | + "syn 2.0.85", |
1283 | ] |
1284 | |
1285 | [[package]] |
1286 | @@ -3141,29 +3637,29 @@ dependencies = [ |
1287 | |
1288 | [[package]] |
1289 | name = "pin-project" |
1290 | - version = "1.1.6" |
1291 | + version = "1.1.7" |
1292 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1293 | - checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" |
1294 | + checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" |
1295 | dependencies = [ |
1296 | "pin-project-internal", |
1297 | ] |
1298 | |
1299 | [[package]] |
1300 | name = "pin-project-internal" |
1301 | - version = "1.1.6" |
1302 | + version = "1.1.7" |
1303 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1304 | - checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" |
1305 | + checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" |
1306 | dependencies = [ |
1307 | "proc-macro2", |
1308 | "quote", |
1309 | - "syn 2.0.79", |
1310 | + "syn 2.0.85", |
1311 | ] |
1312 | |
1313 | [[package]] |
1314 | name = "pin-project-lite" |
1315 | - version = "0.2.14" |
1316 | + version = "0.2.15" |
1317 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1318 | - checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" |
1319 | + checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" |
1320 | |
1321 | [[package]] |
1322 | name = "pin-utils" |
1323 | @@ -3292,15 +3788,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
1324 | checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" |
1325 | |
1326 | [[package]] |
1327 | + name = "prettyplease" |
1328 | + version = "0.2.25" |
1329 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1330 | + checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" |
1331 | + dependencies = [ |
1332 | + "proc-macro2", |
1333 | + "syn 2.0.85", |
1334 | + ] |
1335 | + |
1336 | + [[package]] |
1337 | name = "proc-macro2" |
1338 | - version = "1.0.87" |
1339 | + version = "1.0.89" |
1340 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1341 | - checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" |
1342 | + checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" |
1343 | dependencies = [ |
1344 | "unicode-ident", |
1345 | ] |
1346 | |
1347 | [[package]] |
1348 | + name = "proxy-header" |
1349 | + version = "0.1.2" |
1350 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1351 | + checksum = "dc1493f63ddddfba840c3169e997c2905d09538ace72d64e84af6324c6e0e065" |
1352 | + |
1353 | + [[package]] |
1354 | name = "ptr_meta" |
1355 | version = "0.1.4" |
1356 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1357 | @@ -3321,6 +3833,12 @@ dependencies = [ |
1358 | ] |
1359 | |
1360 | [[package]] |
1361 | + name = "quick-error" |
1362 | + version = "1.2.3" |
1363 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1364 | + checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" |
1365 | + |
1366 | + [[package]] |
1367 | name = "quick-xml" |
1368 | version = "0.32.0" |
1369 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1370 | @@ -3369,6 +3887,12 @@ dependencies = [ |
1371 | ] |
1372 | |
1373 | [[package]] |
1374 | + name = "quoted_printable" |
1375 | + version = "0.5.1" |
1376 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1377 | + checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73" |
1378 | + |
1379 | + [[package]] |
1380 | name = "radium" |
1381 | version = "0.7.0" |
1382 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1383 | @@ -3455,9 +3979,9 @@ dependencies = [ |
1384 | |
1385 | [[package]] |
1386 | name = "regex" |
1387 | - version = "1.11.0" |
1388 | + version = "1.11.1" |
1389 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1390 | - checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" |
1391 | + checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" |
1392 | dependencies = [ |
1393 | "aho-corasick 1.1.3", |
1394 | "memchr", |
1395 | @@ -3520,7 +4044,7 @@ dependencies = [ |
1396 | "h2 0.3.26", |
1397 | "http 0.2.12", |
1398 | "http-body 0.4.6", |
1399 | - "hyper 0.14.30", |
1400 | + "hyper 0.14.31", |
1401 | "hyper-tls 0.5.0", |
1402 | "ipnet", |
1403 | "js-sys", |
1404 | @@ -3561,7 +4085,7 @@ dependencies = [ |
1405 | "http 1.1.0", |
1406 | "http-body 1.0.1", |
1407 | "http-body-util", |
1408 | - "hyper 1.4.1", |
1409 | + "hyper 1.5.0", |
1410 | "hyper-rustls", |
1411 | "hyper-tls 0.6.0", |
1412 | "hyper-util", |
1413 | @@ -3590,6 +4114,31 @@ dependencies = [ |
1414 | ] |
1415 | |
1416 | [[package]] |
1417 | + name = "resolv-conf" |
1418 | + version = "0.7.0" |
1419 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1420 | + checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" |
1421 | + dependencies = [ |
1422 | + "hostname", |
1423 | + "quick-error", |
1424 | + ] |
1425 | + |
1426 | + [[package]] |
1427 | + name = "ring" |
1428 | + version = "0.16.20" |
1429 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1430 | + checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" |
1431 | + dependencies = [ |
1432 | + "cc", |
1433 | + "libc", |
1434 | + "once_cell", |
1435 | + "spin 0.5.2", |
1436 | + "untrusted 0.7.1", |
1437 | + "web-sys", |
1438 | + "winapi", |
1439 | + ] |
1440 | + |
1441 | + [[package]] |
1442 | name = "ring" |
1443 | version = "0.17.8" |
1444 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1445 | @@ -3599,8 +4148,8 @@ dependencies = [ |
1446 | "cfg-if", |
1447 | "getrandom", |
1448 | "libc", |
1449 | - "spin", |
1450 | - "untrusted", |
1451 | + "spin 0.9.8", |
1452 | + "untrusted 0.9.0", |
1453 | "windows-sys 0.52.0", |
1454 | ] |
1455 | |
1456 | @@ -3672,6 +4221,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
1457 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" |
1458 | |
1459 | [[package]] |
1460 | + name = "rustc-hash" |
1461 | + version = "1.1.0" |
1462 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1463 | + checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" |
1464 | + |
1465 | + [[package]] |
1466 | name = "rustc_version" |
1467 | version = "0.4.1" |
1468 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1469 | @@ -3695,14 +4250,28 @@ dependencies = [ |
1470 | |
1471 | [[package]] |
1472 | name = "rustls" |
1473 | - version = "0.23.14" |
1474 | + version = "0.21.12" |
1475 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1476 | + checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" |
1477 | + dependencies = [ |
1478 | + "log", |
1479 | + "ring 0.17.8", |
1480 | + "rustls-webpki 0.101.7", |
1481 | + "sct", |
1482 | + ] |
1483 | + |
1484 | + [[package]] |
1485 | + name = "rustls" |
1486 | + version = "0.23.15" |
1487 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1488 | - checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" |
1489 | + checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" |
1490 | dependencies = [ |
1491 | + "aws-lc-rs", |
1492 | + "log", |
1493 | "once_cell", |
1494 | - "ring", |
1495 | + "ring 0.17.8", |
1496 | "rustls-pki-types", |
1497 | - "rustls-webpki", |
1498 | + "rustls-webpki 0.102.8", |
1499 | "subtle", |
1500 | "zeroize", |
1501 | ] |
1502 | @@ -3727,9 +4296,19 @@ dependencies = [ |
1503 | |
1504 | [[package]] |
1505 | name = "rustls-pki-types" |
1506 | - version = "1.9.0" |
1507 | + version = "1.10.0" |
1508 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1509 | - checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" |
1510 | + checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" |
1511 | + |
1512 | + [[package]] |
1513 | + name = "rustls-webpki" |
1514 | + version = "0.101.7" |
1515 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1516 | + checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" |
1517 | + dependencies = [ |
1518 | + "ring 0.17.8", |
1519 | + "untrusted 0.9.0", |
1520 | + ] |
1521 | |
1522 | [[package]] |
1523 | name = "rustls-webpki" |
1524 | @@ -3737,16 +4316,17 @@ version = "0.102.8" |
1525 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1526 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" |
1527 | dependencies = [ |
1528 | - "ring", |
1529 | + "aws-lc-rs", |
1530 | + "ring 0.17.8", |
1531 | "rustls-pki-types", |
1532 | - "untrusted", |
1533 | + "untrusted 0.9.0", |
1534 | ] |
1535 | |
1536 | [[package]] |
1537 | name = "rustversion" |
1538 | - version = "1.0.17" |
1539 | + version = "1.0.18" |
1540 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1541 | - checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" |
1542 | + checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" |
1543 | |
1544 | [[package]] |
1545 | name = "ryu" |
1546 | @@ -3779,6 +4359,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
1547 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" |
1548 | |
1549 | [[package]] |
1550 | + name = "sct" |
1551 | + version = "0.7.1" |
1552 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1553 | + checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" |
1554 | + dependencies = [ |
1555 | + "ring 0.17.8", |
1556 | + "untrusted 0.9.0", |
1557 | + ] |
1558 | + |
1559 | + [[package]] |
1560 | name = "seahash" |
1561 | version = "4.1.0" |
1562 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1563 | @@ -3815,22 +4405,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" |
1564 | |
1565 | [[package]] |
1566 | name = "serde" |
1567 | - version = "1.0.210" |
1568 | + version = "1.0.213" |
1569 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1570 | - checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" |
1571 | + checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" |
1572 | dependencies = [ |
1573 | "serde_derive", |
1574 | ] |
1575 | |
1576 | [[package]] |
1577 | name = "serde_derive" |
1578 | - version = "1.0.210" |
1579 | + version = "1.0.213" |
1580 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1581 | - checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" |
1582 | + checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" |
1583 | dependencies = [ |
1584 | "proc-macro2", |
1585 | "quote", |
1586 | - "syn 2.0.79", |
1587 | + "syn 2.0.85", |
1588 | ] |
1589 | |
1590 | [[package]] |
1591 | @@ -3848,9 +4438,9 @@ dependencies = [ |
1592 | |
1593 | [[package]] |
1594 | name = "serde_json" |
1595 | - version = "1.0.128" |
1596 | + version = "1.0.132" |
1597 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1598 | - checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" |
1599 | + checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" |
1600 | dependencies = [ |
1601 | "itoa", |
1602 | "memchr", |
1603 | @@ -3916,7 +4506,7 @@ dependencies = [ |
1604 | "darling", |
1605 | "proc-macro2", |
1606 | "quote", |
1607 | - "syn 2.0.79", |
1608 | + "syn 2.0.85", |
1609 | ] |
1610 | |
1611 | [[package]] |
1612 | @@ -4037,6 +4627,15 @@ dependencies = [ |
1613 | ] |
1614 | |
1615 | [[package]] |
1616 | + name = "smtp-proto" |
1617 | + version = "0.1.5" |
1618 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1619 | + checksum = "51b8ad3dd187f0d4debab02ad65405a9919d6a4f7bce25bd64a258781063a53a" |
1620 | + dependencies = [ |
1621 | + "serde", |
1622 | + ] |
1623 | + |
1624 | + [[package]] |
1625 | name = "socket2" |
1626 | version = "0.5.7" |
1627 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1628 | @@ -4048,6 +4647,12 @@ dependencies = [ |
1629 | |
1630 | [[package]] |
1631 | name = "spin" |
1632 | + version = "0.5.2" |
1633 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1634 | + checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" |
1635 | + |
1636 | + [[package]] |
1637 | + name = "spin" |
1638 | version = "0.9.8" |
1639 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1640 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" |
1641 | @@ -4115,7 +4720,7 @@ dependencies = [ |
1642 | "once_cell", |
1643 | "paste", |
1644 | "percent-encoding", |
1645 | - "rustls", |
1646 | + "rustls 0.23.15", |
1647 | "rustls-pemfile 2.2.0", |
1648 | "serde", |
1649 | "serde_json", |
1650 | @@ -4141,7 +4746,7 @@ dependencies = [ |
1651 | "quote", |
1652 | "sqlx-core", |
1653 | "sqlx-macros-core", |
1654 | - "syn 2.0.79", |
1655 | + "syn 2.0.85", |
1656 | ] |
1657 | |
1658 | [[package]] |
1659 | @@ -4164,7 +4769,7 @@ dependencies = [ |
1660 | "sqlx-mysql", |
1661 | "sqlx-postgres", |
1662 | "sqlx-sqlite", |
1663 | - "syn 2.0.79", |
1664 | + "syn 2.0.85", |
1665 | "tempfile", |
1666 | "tokio", |
1667 | "url", |
1668 | @@ -4330,9 +4935,9 @@ dependencies = [ |
1669 | |
1670 | [[package]] |
1671 | name = "syn" |
1672 | - version = "2.0.79" |
1673 | + version = "2.0.85" |
1674 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1675 | - checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" |
1676 | + checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" |
1677 | dependencies = [ |
1678 | "proc-macro2", |
1679 | "quote", |
1680 | @@ -4544,22 +5149,22 @@ dependencies = [ |
1681 | |
1682 | [[package]] |
1683 | name = "thiserror" |
1684 | - version = "1.0.64" |
1685 | + version = "1.0.65" |
1686 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1687 | - checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" |
1688 | + checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" |
1689 | dependencies = [ |
1690 | "thiserror-impl", |
1691 | ] |
1692 | |
1693 | [[package]] |
1694 | name = "thiserror-impl" |
1695 | - version = "1.0.64" |
1696 | + version = "1.0.65" |
1697 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1698 | - checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" |
1699 | + checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" |
1700 | dependencies = [ |
1701 | "proc-macro2", |
1702 | "quote", |
1703 | - "syn 2.0.79", |
1704 | + "syn 2.0.85", |
1705 | ] |
1706 | |
1707 | [[package]] |
1708 | @@ -4652,9 +5257,9 @@ dependencies = [ |
1709 | |
1710 | [[package]] |
1711 | name = "tokio" |
1712 | - version = "1.40.0" |
1713 | + version = "1.41.0" |
1714 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1715 | - checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" |
1716 | + checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" |
1717 | dependencies = [ |
1718 | "backtrace", |
1719 | "bytes", |
1720 | @@ -4676,7 +5281,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" |
1721 | dependencies = [ |
1722 | "proc-macro2", |
1723 | "quote", |
1724 | - "syn 2.0.79", |
1725 | + "syn 2.0.85", |
1726 | ] |
1727 | |
1728 | [[package]] |
1729 | @@ -4691,11 +5296,21 @@ dependencies = [ |
1730 | |
1731 | [[package]] |
1732 | name = "tokio-rustls" |
1733 | + version = "0.24.1" |
1734 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1735 | + checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" |
1736 | + dependencies = [ |
1737 | + "rustls 0.21.12", |
1738 | + "tokio", |
1739 | + ] |
1740 | + |
1741 | + [[package]] |
1742 | + name = "tokio-rustls" |
1743 | version = "0.26.0" |
1744 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1745 | checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" |
1746 | dependencies = [ |
1747 | - "rustls", |
1748 | + "rustls 0.23.15", |
1749 | "rustls-pki-types", |
1750 | "tokio", |
1751 | ] |
1752 | @@ -4725,6 +5340,7 @@ dependencies = [ |
1753 | "futures-core", |
1754 | "pin-project-lite", |
1755 | "tokio", |
1756 | + "tokio-util", |
1757 | ] |
1758 | |
1759 | [[package]] |
1760 | @@ -4737,6 +5353,8 @@ dependencies = [ |
1761 | "futures-core", |
1762 | "futures-io", |
1763 | "futures-sink", |
1764 | + "futures-util", |
1765 | + "hashbrown 0.14.5", |
1766 | "pin-project-lite", |
1767 | "slab", |
1768 | "tokio", |
1769 | @@ -4849,7 +5467,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" |
1770 | dependencies = [ |
1771 | "proc-macro2", |
1772 | "quote", |
1773 | - "syn 2.0.79", |
1774 | + "syn 2.0.85", |
1775 | ] |
1776 | |
1777 | [[package]] |
1778 | @@ -5018,12 +5636,9 @@ dependencies = [ |
1779 | |
1780 | [[package]] |
1781 | name = "unicase" |
1782 | - version = "2.7.0" |
1783 | + version = "2.8.0" |
1784 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1785 | - checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" |
1786 | - dependencies = [ |
1787 | - "version_check", |
1788 | - ] |
1789 | + checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" |
1790 | |
1791 | [[package]] |
1792 | name = "unicode-bidi" |
1793 | @@ -5072,6 +5687,12 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" |
1794 | |
1795 | [[package]] |
1796 | name = "untrusted" |
1797 | + version = "0.7.1" |
1798 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1799 | + checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" |
1800 | + |
1801 | + [[package]] |
1802 | + name = "untrusted" |
1803 | version = "0.9.0" |
1804 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1805 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" |
1806 | @@ -5083,7 +5704,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
1807 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" |
1808 | dependencies = [ |
1809 | "form_urlencoded", |
1810 | - "idna", |
1811 | + "idna 0.5.0", |
1812 | "percent-encoding", |
1813 | "serde", |
1814 | ] |
1815 | @@ -5102,9 +5723,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" |
1816 | |
1817 | [[package]] |
1818 | name = "uuid" |
1819 | - version = "1.10.0" |
1820 | + version = "1.11.0" |
1821 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1822 | - checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" |
1823 | + checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" |
1824 | |
1825 | [[package]] |
1826 | name = "valuable" |
1827 | @@ -5189,7 +5810,7 @@ dependencies = [ |
1828 | "once_cell", |
1829 | "proc-macro2", |
1830 | "quote", |
1831 | - "syn 2.0.79", |
1832 | + "syn 2.0.85", |
1833 | "wasm-bindgen-shared", |
1834 | ] |
1835 | |
1836 | @@ -5223,7 +5844,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" |
1837 | dependencies = [ |
1838 | "proc-macro2", |
1839 | "quote", |
1840 | - "syn 2.0.79", |
1841 | + "syn 2.0.85", |
1842 | "wasm-bindgen-backend", |
1843 | "wasm-bindgen-shared", |
1844 | ] |
1845 | @@ -5291,6 +5912,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
1846 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" |
1847 | |
1848 | [[package]] |
1849 | + name = "which" |
1850 | + version = "4.4.2" |
1851 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1852 | + checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" |
1853 | + dependencies = [ |
1854 | + "either", |
1855 | + "home", |
1856 | + "once_cell", |
1857 | + "rustix", |
1858 | + ] |
1859 | + |
1860 | + [[package]] |
1861 | name = "whoami" |
1862 | version = "1.5.2" |
1863 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1864 | @@ -5301,6 +5934,12 @@ dependencies = [ |
1865 | ] |
1866 | |
1867 | [[package]] |
1868 | + name = "widestring" |
1869 | + version = "1.1.0" |
1870 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1871 | + checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" |
1872 | + |
1873 | + [[package]] |
1874 | name = "winapi" |
1875 | version = "0.3.9" |
1876 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1877 | @@ -5599,7 +6238,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" |
1878 | dependencies = [ |
1879 | "proc-macro2", |
1880 | "quote", |
1881 | - "syn 2.0.79", |
1882 | + "syn 2.0.85", |
1883 | ] |
1884 | |
1885 | [[package]] |
1886 | @@ -5607,3 +6246,88 @@ name = "zeroize" |
1887 | version = "1.8.1" |
1888 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1889 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" |
1890 | + dependencies = [ |
1891 | + "zeroize_derive", |
1892 | + ] |
1893 | + |
1894 | + [[package]] |
1895 | + name = "zeroize_derive" |
1896 | + version = "1.4.2" |
1897 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1898 | + checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" |
1899 | + dependencies = [ |
1900 | + "proc-macro2", |
1901 | + "quote", |
1902 | + "syn 2.0.85", |
1903 | + ] |
1904 | + |
1905 | + [[package]] |
1906 | + name = "zip" |
1907 | + version = "2.2.0" |
1908 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1909 | + checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" |
1910 | + dependencies = [ |
1911 | + "aes", |
1912 | + "arbitrary", |
1913 | + "bzip2", |
1914 | + "constant_time_eq", |
1915 | + "crc32fast", |
1916 | + "crossbeam-utils", |
1917 | + "deflate64", |
1918 | + "displaydoc", |
1919 | + "flate2", |
1920 | + "hmac", |
1921 | + "indexmap 2.6.0", |
1922 | + "lzma-rs", |
1923 | + "memchr", |
1924 | + "pbkdf2", |
1925 | + "rand", |
1926 | + "sha1", |
1927 | + "thiserror", |
1928 | + "time", |
1929 | + "zeroize", |
1930 | + "zopfli", |
1931 | + "zstd", |
1932 | + ] |
1933 | + |
1934 | + [[package]] |
1935 | + name = "zopfli" |
1936 | + version = "0.8.1" |
1937 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1938 | + checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" |
1939 | + dependencies = [ |
1940 | + "bumpalo", |
1941 | + "crc32fast", |
1942 | + "lockfree-object-pool", |
1943 | + "log", |
1944 | + "once_cell", |
1945 | + "simd-adler32", |
1946 | + ] |
1947 | + |
1948 | + [[package]] |
1949 | + name = "zstd" |
1950 | + version = "0.13.2" |
1951 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1952 | + checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" |
1953 | + dependencies = [ |
1954 | + "zstd-safe", |
1955 | + ] |
1956 | + |
1957 | + [[package]] |
1958 | + name = "zstd-safe" |
1959 | + version = "7.2.1" |
1960 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1961 | + checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" |
1962 | + dependencies = [ |
1963 | + "zstd-sys", |
1964 | + ] |
1965 | + |
1966 | + [[package]] |
1967 | + name = "zstd-sys" |
1968 | + version = "2.0.13+zstd.1.5.6" |
1969 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
1970 | + checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" |
1971 | + dependencies = [ |
1972 | + "cc", |
1973 | + "pkg-config", |
1974 | + ] |
1975 | diff --git a/Cargo.toml b/Cargo.toml |
1976 | index 180d60a..dad91ef 100644 |
1977 | --- a/Cargo.toml |
1978 | +++ b/Cargo.toml |
1979 | @@ -9,7 +9,7 @@ members = [ |
1980 | "crates/database", |
1981 | "ayllu", |
1982 | # "ayllu-build", |
1983 | - # "ayllu-mail", |
1984 | + "ayllu-mail", |
1985 | # "ayllu-xmpp", |
1986 | "quipu" |
1987 | , "ayllu-jobs", "crates/timeutil"] |
1988 | diff --git a/ayllu-mail/Cargo.toml b/ayllu-mail/Cargo.toml |
1989 | index 3c050f6..221411b 100644 |
1990 | --- a/ayllu-mail/Cargo.toml |
1991 | +++ b/ayllu-mail/Cargo.toml |
1992 | @@ -7,9 +7,8 @@ edition = "2021" |
1993 | name = "ayllu-mail" |
1994 | |
1995 | [dependencies] |
1996 | - ayllu_api = {path = "../crates/api"} |
1997 | ayllu_config = {path = "../crates/config"} |
1998 | - ayllu_rpc = {path = "../crates/rpc"} |
1999 | + ayllu_database = {path = "../crates/database"} |
2000 | |
2001 | serde = { version = "1.0.188", features = ["derive"] } |
2002 | clap = { version = "4.4.6", features = ["derive"] } |
2003 | @@ -17,9 +16,12 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } |
2004 | tracing = "0.1.37" |
2005 | tokio = { version = "1.33.0", features = ["full"] } |
2006 | futures = "0.3.28" |
2007 | - melib = { git = "https://ayllu-forge.org/meli/meli", branch = "master" } |
2008 | - mailpot = { git = "https://ayllu-forge.org/ayllu/mailpot", branch = "main" } |
2009 | - maitred = { git = "https://ayllu-forge.org/ayllu/maitred", branch = "main" } |
2010 | clap_complete = "4.4.5" |
2011 | - anyhow = "1.0.78" |
2012 | axum = "0.7.5" |
2013 | + thiserror = "1.0.65" |
2014 | + async-trait = "0.1.83" |
2015 | + |
2016 | + [dependencies.maitred] |
2017 | + git = "https://ayllu-forge.org/ayllu/maitred" |
2018 | + branch = "main" |
2019 | + features = ["auth", "server"] |
2020 | diff --git a/ayllu-mail/src/config.rs b/ayllu-mail/src/config.rs |
2021 | index dc05a68..7f86cba 100644 |
2022 | --- a/ayllu-mail/src/config.rs |
2023 | +++ b/ayllu-mail/src/config.rs |
2024 | @@ -3,10 +3,10 @@ use std::path::PathBuf; |
2025 | use serde::{Deserialize, Serialize}; |
2026 | |
2027 | use ayllu_config::{data_dir, runtime_dir, Configurable}; |
2028 | - use mailpot::{Configuration as MailPotConfig, SendMail}; |
2029 | |
2030 | pub const EXAMPLE_CONFIG: &str = include_str!("../../config.example.toml"); |
2031 | |
2032 | + |
2033 | #[derive(Serialize, Deserialize, Clone)] |
2034 | pub struct Database { |
2035 | pub migrate: Option<bool>, |
2036 | @@ -31,178 +31,56 @@ impl Default for Database { |
2037 | } |
2038 | } |
2039 | |
2040 | - /// PostPolicy |
2041 | - #[derive(Deserialize, Serialize, Clone, Debug, Default)] |
2042 | - pub enum PostPolicy { |
2043 | - AnnounceOnly, |
2044 | - SubscriptionOnly, |
2045 | - ApprovalNeeded, |
2046 | - Open, |
2047 | - #[default] |
2048 | - Custom, |
2049 | - } |
2050 | - |
2051 | - #[derive(Deserialize, Serialize, Clone, Debug, Default, PartialEq, Eq)] |
2052 | - pub enum SubscriptionPolicyKind { |
2053 | - Request, |
2054 | - Open, |
2055 | - Manual, |
2056 | - #[default] |
2057 | - Custom, |
2058 | - } |
2059 | - |
2060 | - /// SubscriptionPolicy |
2061 | - #[derive(Deserialize, Serialize, Clone, Debug, Default)] |
2062 | - pub struct SubscriptionPolicy { |
2063 | - pub send_confirmation: bool, |
2064 | - pub kind: SubscriptionPolicyKind, |
2065 | - } |
2066 | - |
2067 | #[derive(Deserialize, Serialize, Clone, Debug, Default)] |
2068 | pub struct MailingList { |
2069 | - pub id: String, |
2070 | - pub name: Option<String>, |
2071 | + pub name: String, |
2072 | pub address: String, |
2073 | pub description: Option<String>, |
2074 | pub topics: Vec<String>, |
2075 | - pub post_policy: PostPolicy, |
2076 | - pub subscription_policy: SubscriptionPolicy, |
2077 | - } |
2078 | - |
2079 | - #[derive(Deserialize, Serialize, Clone, Debug)] |
2080 | - pub struct Http { |
2081 | - #[serde(default = "Http::default_address")] |
2082 | - pub address: String, |
2083 | } |
2084 | |
2085 | - impl Http { |
2086 | - fn default_address() -> String { |
2087 | - String::from("127.0.0.1:32001") |
2088 | - } |
2089 | + #[derive(Clone, Default, Serialize, Deserialize)] |
2090 | + pub struct Dkim { |
2091 | + pub enabled: Option<bool>, |
2092 | } |
2093 | |
2094 | - impl Default for Http { |
2095 | - fn default() -> Self { |
2096 | - Http { |
2097 | - address: Http::default_address(), |
2098 | - } |
2099 | - } |
2100 | - } |
2101 | - |
2102 | - #[derive(Deserialize, Serialize, Clone, Debug)] |
2103 | - pub struct NginxAuth { |
2104 | - /// address to listen on for ngx_mail_auth_http_module requests |
2105 | - #[serde(default = "NginxAuth::default_address")] |
2106 | - pub listen: String, |
2107 | - /// hostname of your smtp server |
2108 | - #[serde(default = "NginxAuth::default_host")] |
2109 | - pub host: String, |
2110 | - /// port your smtp server is listening on |
2111 | - #[serde(default = "NginxAuth::default_port")] |
2112 | - pub port: u16, |
2113 | - /// An array of domains that the mail server may accept mail for, if not |
2114 | - /// specified mail to any domain will be accepted. |
2115 | - pub domains: Option<Vec<String>>, |
2116 | - } |
2117 | - |
2118 | - impl NginxAuth { |
2119 | - fn default_host() -> String { |
2120 | - String::from("127.0.0.1") |
2121 | - } |
2122 | - |
2123 | - fn default_port() -> u16 { |
2124 | - 2525 |
2125 | - } |
2126 | - |
2127 | - fn default_address() -> String { |
2128 | - String::from("127.0.0.1:32001") |
2129 | - } |
2130 | + #[derive(Clone, Default, Serialize, Deserialize)] |
2131 | + pub struct Spf { |
2132 | + pub enabled: Option<bool>, |
2133 | } |
2134 | |
2135 | - impl Default for NginxAuth { |
2136 | - fn default() -> Self { |
2137 | - NginxAuth { |
2138 | - host: NginxAuth::default_host(), |
2139 | - port: NginxAuth::default_port(), |
2140 | - listen: NginxAuth::default_address(), |
2141 | - domains: None, |
2142 | - } |
2143 | - } |
2144 | + #[derive(Clone, Default, Serialize, Deserialize)] |
2145 | + pub struct Tls { |
2146 | + pub certificate: PathBuf, |
2147 | + pub key: PathBuf, |
2148 | } |
2149 | |
2150 | - #[derive(Serialize, Deserialize, Clone)] |
2151 | + #[derive(Clone, Default, Serialize, Deserialize)] |
2152 | pub struct Mail { |
2153 | - #[serde(default = "Mail::default_socket_path")] |
2154 | - pub socket_path: String, |
2155 | - #[serde(default = "Database::default")] |
2156 | - pub database: Database, |
2157 | - #[serde(default = "Mail::default_sendmail_command")] |
2158 | - pub sendmail_command: String, |
2159 | + #[serde(default = "Mail::default_address")] |
2160 | + pub address: String, |
2161 | + pub dkim: Dkim, |
2162 | + pub spf: Spf, |
2163 | + pub tls: Option<Tls>, |
2164 | + pub proxy_protocol: Option<bool>, |
2165 | pub lists: Vec<MailingList>, |
2166 | - #[serde(default = "Mail::default_postfix_user")] |
2167 | - pub postfix_user: String, |
2168 | - #[serde(default = "Mail::default_postfix_user")] |
2169 | - pub postfix_group: String, |
2170 | - #[serde(default = "NginxAuth::default")] |
2171 | - pub nginx_auth: NginxAuth, |
2172 | } |
2173 | |
2174 | impl Mail { |
2175 | - fn default_socket_path() -> String { |
2176 | - runtime_dir().to_str().unwrap().to_string() + "/ayllu-mail.sock" |
2177 | - } |
2178 | - |
2179 | - fn default_sendmail_command() -> String { |
2180 | - String::from("/usr/bin/false") |
2181 | - } |
2182 | - |
2183 | - fn default_postfix_user() -> String { |
2184 | - String::from("ayllu") |
2185 | - } |
2186 | - } |
2187 | - |
2188 | - impl Default for Mail { |
2189 | - fn default() -> Self { |
2190 | - Mail { |
2191 | - socket_path: Mail::default_socket_path(), |
2192 | - database: Database::default(), |
2193 | - sendmail_command: Mail::default_sendmail_command(), |
2194 | - lists: Vec::new(), |
2195 | - postfix_user: Mail::default_postfix_user(), |
2196 | - postfix_group: Mail::default_postfix_user(), |
2197 | - nginx_auth: NginxAuth::default(), |
2198 | - } |
2199 | + pub fn default_address() -> String { |
2200 | + String::from("127.0.0.1:30025") |
2201 | } |
2202 | } |
2203 | |
2204 | #[derive(Serialize, Deserialize, Clone)] |
2205 | pub struct Config { |
2206 | pub sysadmin: Option<String>, |
2207 | + pub database: Database, |
2208 | pub log_level: String, |
2209 | #[serde(default = "Mail::default")] |
2210 | pub mail: Mail, |
2211 | - #[serde(default = "NginxAuth::default")] |
2212 | - pub smtp: NginxAuth, |
2213 | } |
2214 | |
2215 | - impl Config { |
2216 | - pub fn mailpot_config(&self) -> MailPotConfig { |
2217 | - let data_path = self |
2218 | |
2219 | - .database |
2220 | - .path |
2221 | - .parent() |
2222 | - .expect("cannot resolve data path"); |
2223 | - MailPotConfig { |
2224 | - send_mail: SendMail::ShellCommand(self.mail.sendmail_command.clone()), |
2225 | - data_path: data_path.to_path_buf(), |
2226 | - db_path: self.mail.database.path.clone(), |
2227 | - administrators: self |
2228 | - .sysadmin |
2229 | - .clone() |
2230 | - .map_or(vec![], |admin| vec![admin.clone()]), |
2231 | - } |
2232 | - } |
2233 | - } |
2234 | + impl Config {} |
2235 | |
2236 | impl Configurable for Config {} |
2237 | diff --git a/ayllu-mail/src/declarative.rs b/ayllu-mail/src/declarative.rs |
2238 | deleted file mode 100644 |
2239 | index 6a842a7..0000000 |
2240 | --- a/ayllu-mail/src/declarative.rs |
2241 | +++ /dev/null |
2242 | @@ -1,123 +0,0 @@ |
2243 | - use std::collections::HashMap; |
2244 | - |
2245 | - use mailpot::{ |
2246 | - models::{changesets::MailingListChangeset, MailingList, PostPolicy, SubscriptionPolicy}, |
2247 | - Connection, Result as MpResult, |
2248 | - }; |
2249 | - use tracing::log; |
2250 | - |
2251 | - use crate::{config, config::Config}; |
2252 | - |
2253 | - /// ensure the mailing lists in the global config are available |
2254 | - pub fn initialize(cfg: &Config) -> MpResult<()> { |
2255 | - let db = Connection::open_or_create_db(cfg.mailpot_config())?.trusted(); |
2256 | - |
2257 | - let mut lists_by_id: HashMap<String, i64> = HashMap::new(); |
2258 | - let mut managed_lists: Vec<String> = Vec::new(); |
2259 | - |
2260 | - for list in db.lists()? { |
2261 | - lists_by_id.insert(list.id.clone(), list.pk); |
2262 | - } |
2263 | - |
2264 | - // create missing lists |
2265 | - |
2266 | - for list in cfg.mail.lists.iter() { |
2267 | - log::info!("configuring mailing list: {} [{}]", list.id, list.address); |
2268 | - if !lists_by_id.contains_key(&list.id) { |
2269 | - log::info!("creating mailing list: {}", list.address); |
2270 | - let db_list = db.create_list(MailingList { |
2271 | - pk: -1, |
2272 | - name: list.name.clone().unwrap_or(list.id.clone()), |
2273 | - id: list.id.clone(), |
2274 | - address: list.address.clone(), |
2275 | - topics: list.topics.clone(), |
2276 | - description: list.description.clone(), |
2277 | - archive_url: None, |
2278 | - })?; |
2279 | - lists_by_id.insert(db_list.id.clone(), db_list.pk); |
2280 | - } else { |
2281 | - let pk = *lists_by_id.get(&list.id).unwrap(); |
2282 | - // ensure the configuration is consistent |
2283 | - db.update_list(MailingListChangeset { |
2284 | - pk, |
2285 | - // TODO: topics cannot be updated? |
2286 | - description: list |
2287 | - .description |
2288 | - .as_ref() |
2289 | - .map(|description| Some(description.clone())), |
2290 | - ..Default::default() |
2291 | - })?; |
2292 | - } |
2293 | - managed_lists.push(list.id.clone()); |
2294 | - } |
2295 | - |
2296 | - // set policies |
2297 | - |
2298 | - for list in cfg.mail.lists.iter() { |
2299 | - let list_pk = *lists_by_id.get(&list.id).unwrap(); |
2300 | - let post_policy = PostPolicy { |
2301 | - pk: 0, |
2302 | - list: list_pk, |
2303 | - announce_only: matches!(list.post_policy, config::PostPolicy::AnnounceOnly), |
2304 | - subscription_only: matches!(list.post_policy, config::PostPolicy::SubscriptionOnly), |
2305 | - approval_needed: matches!(list.post_policy, config::PostPolicy::ApprovalNeeded), |
2306 | - open: matches!(list.post_policy, config::PostPolicy::Open), |
2307 | - custom: matches!(list.post_policy, config::PostPolicy::Custom), |
2308 | - }; |
2309 | - log::info!("setting post policy: {:?}", list.post_policy); |
2310 | - db.set_list_post_policy(post_policy)?; |
2311 | - |
2312 | - let sub_policy = SubscriptionPolicy { |
2313 | - pk: 0, |
2314 | - list: list_pk, |
2315 | - send_confirmation: list.subscription_policy.send_confirmation, |
2316 | - open: matches!( |
2317 | - list.subscription_policy.kind, |
2318 | - config::SubscriptionPolicyKind::Open |
2319 | - ), |
2320 | - manual: matches!( |
2321 | - list.subscription_policy.kind, |
2322 | - config::SubscriptionPolicyKind::Manual |
2323 | - ), |
2324 | - request: matches!( |
2325 | - list.subscription_policy.kind, |
2326 | - config::SubscriptionPolicyKind::Request |
2327 | - ), |
2328 | - custom: matches!( |
2329 | - list.subscription_policy.kind, |
2330 | - config::SubscriptionPolicyKind::Custom |
2331 | - ), |
2332 | - }; |
2333 | - |
2334 | - log::info!( |
2335 | - "setting subscription policy: {:?}", |
2336 | - list.subscription_policy |
2337 | - ); |
2338 | - |
2339 | - db.set_list_subscription_policy(sub_policy)?; |
2340 | - } |
2341 | - |
2342 | - let extras: Vec<&String> = lists_by_id |
2343 | - .keys() |
2344 | - .filter(|name| !managed_lists.contains(name)) |
2345 | - .collect(); |
2346 | - |
2347 | - if !extras.is_empty() { |
2348 | - log::info!("database contains the following superfluous lists:"); |
2349 | - extras.iter().for_each(|extra| { |
2350 | - log::info!("List: {}", extra); |
2351 | - }); |
2352 | - for extra in extras.iter() { |
2353 | - log::info!("disabling mailing list: {}", extra); |
2354 | - let pk = *lists_by_id.get(&extra.to_string()).unwrap(); |
2355 | - db.update_list(MailingListChangeset { |
2356 | - pk, |
2357 | - enabled: Some(false), |
2358 | - hidden: Some(true), |
2359 | - ..Default::default() |
2360 | - })?; |
2361 | - } |
2362 | - } |
2363 | - |
2364 | - Ok(()) |
2365 | - } |
2366 | diff --git a/ayllu-mail/src/error.rs b/ayllu-mail/src/error.rs |
2367 | new file mode 100644 |
2368 | index 0000000..cdbbbb0 |
2369 | --- /dev/null |
2370 | +++ b/ayllu-mail/src/error.rs |
2371 | @@ -0,0 +1,9 @@ |
2372 | + use maitred::ServerError; |
2373 | + |
2374 | + #[derive(Debug, thiserror::Error)] |
2375 | + pub enum Error { |
2376 | + #[error("SMTP Server Error: {0}")] |
2377 | + Maitred(#[from] ServerError), |
2378 | + #[error("Database: {0}")] |
2379 | + Database(#[from] ayllu_database::Error), |
2380 | + } |
2381 | diff --git a/ayllu-mail/src/mail_utils.rs b/ayllu-mail/src/mail_utils.rs |
2382 | new file mode 100644 |
2383 | index 0000000..0396fd0 |
2384 | --- /dev/null |
2385 | +++ b/ayllu-mail/src/mail_utils.rs |
2386 | @@ -0,0 +1,21 @@ |
2387 | + use maitred::mail_parser::{Address, HeaderValue, Message}; |
2388 | + |
2389 | + pub fn reply_to(message: &Message) -> Option<Address<'static>> { |
2390 | + let address = match message.headers().iter().find(|header| { |
2391 | + let name = header.name().to_lowercase(); |
2392 | + if name == "in-reply-to" { |
2393 | + return true; |
2394 | + } |
2395 | + false |
2396 | + }) { |
2397 | + Some(header) => { |
2398 | + if let HeaderValue::Address(address) = &header.value { |
2399 | + Some(address.clone().into_owned()) |
2400 | + } else { |
2401 | + None |
2402 | + } |
2403 | + } |
2404 | + None => None, |
2405 | + }; |
2406 | + address |
2407 | + } |
2408 | diff --git a/ayllu-mail/src/main.rs b/ayllu-mail/src/main.rs |
2409 | index ef7c926..277876e 100644 |
2410 | --- a/ayllu-mail/src/main.rs |
2411 | +++ b/ayllu-mail/src/main.rs |
2412 | @@ -1,26 +1,15 @@ |
2413 | - use std::io::{stdin, stdout, Read, Write}; |
2414 | + use std::io::stdout; |
2415 | use std::path::PathBuf; |
2416 | - use std::process::{Command as SystemCommand, Stdio}; |
2417 | use std::str::FromStr; |
2418 | |
2419 | - use anyhow::{format_err, Error, Result}; |
2420 | use clap::{arg, Command, CommandFactory, Parser, Subcommand}; |
2421 | use clap_complete::{generate, Generator, Shell}; |
2422 | - use mailpot::models::{DbVal, MailingList, PostPolicy}; |
2423 | - use mailpot::{ |
2424 | - melib::Envelope, |
2425 | - postfix::PostfixConfiguration, |
2426 | - queue::{Queue, QueueEntry}, |
2427 | - transaction::TransactionBehavior, |
2428 | - Connection, |
2429 | - }; |
2430 | - use tokio::{runtime::Builder as TokioBuilder, task::LocalSet}; |
2431 | - use tracing::{log, Level}; |
2432 | + |
2433 | + use tracing::Level; |
2434 | |
2435 | mod config; |
2436 | - mod declarative; |
2437 | - /// implements https://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#protocol |
2438 | - mod nginx_auth; |
2439 | + mod error; |
2440 | + mod mail_utils; |
2441 | mod server; |
2442 | |
2443 | #[derive(Parser)] |
2444 | @@ -44,14 +33,6 @@ struct Cli { |
2445 | command: Commands, |
2446 | } |
2447 | |
2448 | - #[derive(Subcommand, Debug, PartialEq)] |
2449 | - enum Postfix { |
2450 | - /// Generate service line entry for Postfix master.cf |
2451 | - MasterCf {}, |
2452 | - /// Generate transport maps for Postfix |
2453 | - Maps {}, |
2454 | - } |
2455 | - |
2456 | #[derive(Subcommand, Debug)] |
2457 | enum Commands { |
2458 | /// generate autocomplete commands for common shells |
2459 | @@ -62,17 +43,8 @@ enum Commands { |
2460 | /// Configuration options. |
2461 | #[clap(subcommand)] |
2462 | Config(ayllu_config::Command), |
2463 | - /// run the rpc server and mailing list manager |
2464 | + /// Run the mail server |
2465 | Serve {}, |
2466 | - /// post a new message into the mail queue from stdin |
2467 | - Post {}, |
2468 | - /// send all queued messages to their recipients |
2469 | - Send {}, |
2470 | - /// generate a postfix configuration |
2471 | - Postfix { |
2472 | - #[command(subcommand)] |
2473 | - command: Postfix, |
2474 | - }, |
2475 | } |
2476 | |
2477 | fn print_completions<G: Generator>(gen: G, cmd: &mut Command) { |
2478 | @@ -89,23 +61,10 @@ fn init_logger(level: Level) { |
2479 | tracing::info!("logger initialized"); |
2480 | } |
2481 | |
2482 | - #[allow(clippy::type_complexity)] |
2483 | - fn main() -> Result<(), Box<dyn std::error::Error>> { |
2484 | + #[tokio::main] |
2485 | + async fn main() -> Result<(), Box<dyn std::error::Error>> { |
2486 | let cli = Cli::parse(); |
2487 | let mut mail_cfg: config::Config = ayllu_config::Reader::load(cli.config.as_deref())?; |
2488 | - if let Some(db_path) = cli.database { |
2489 | - mail_cfg.mail.database.path.clone_from(&db_path); |
2490 | - } |
2491 | - // ensure the database path exists since mailpot doesn't create it for us |
2492 | - std::fs::create_dir_all( |
2493 | - mail_cfg |
2494 | |
2495 | - .database |
2496 | - .path |
2497 | - .parent() |
2498 | - .expect("db path has no parent"), |
2499 | - )?; |
2500 | - declarative::initialize(&mail_cfg)?; |
2501 | match cli.command { |
2502 | Commands::Complete { shell } => { |
2503 | let mut cmd = Cli::command(); |
2504 | @@ -117,133 +76,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { |
2505 | Commands::Serve {} => { |
2506 | init_logger(cli.level.unwrap_or(Level::from_str(&mail_cfg.log_level)?)); |
2507 | let cfg = mail_cfg.clone(); |
2508 | - let http_cfg = cfg.clone(); |
2509 | - std::thread::spawn(move || { |
2510 | - TokioBuilder::new_current_thread() |
2511 | - .enable_all() |
2512 | - .build() |
2513 | - .unwrap() |
2514 | - .block_on(async move { nginx_auth::serve(http_cfg).await }); |
2515 | - }); |
2516 | - TokioBuilder::new_current_thread() |
2517 | - .enable_all() |
2518 | - .build() |
2519 | - .unwrap() |
2520 | - .block_on(async move { LocalSet::new().run_until(server::serve(&cfg)).await })?; |
2521 | - } |
2522 | - Commands::Post {} => { |
2523 | - init_logger(cli.level.unwrap_or(Level::from_str(&mail_cfg.log_level)?)); |
2524 | - let mut input = String::new(); |
2525 | - stdin().read_to_string(&mut input)?; |
2526 | - let envelope = Envelope::from_bytes(input.as_bytes(), None)?; |
2527 | - let mut db = Connection::open_or_create_db(mail_cfg.mailpot_config())?.trusted(); |
2528 | - let tx = db.transaction(TransactionBehavior::Exclusive)?; |
2529 | - tx.post(&envelope, input.as_bytes(), false)?; |
2530 | - tx.commit()?; |
2531 | - } |
2532 | - Commands::Send {} => { |
2533 | - init_logger(cli.level.unwrap_or(Level::from_str(&mail_cfg.log_level)?)); |
2534 | - let mut db = Connection::open_or_create_db(mail_cfg.mailpot_config())?.trusted(); |
2535 | - let tx = db.transaction(TransactionBehavior::Exclusive)?; |
2536 | - let messages = tx.queue(Queue::Out)?; |
2537 | - let mut failed: Vec<QueueEntry> = Vec::with_capacity(messages.len()); |
2538 | - fn submit(cmd: &str, msg: &QueueEntry) -> Result<()> { |
2539 | - let mut child = SystemCommand::new("sh") |
2540 | - .arg("-c") |
2541 | - .arg(cmd) |
2542 | - .env("TO_ADDRESS", msg.to_addresses.clone()) |
2543 | - .stdout(Stdio::piped()) |
2544 | - .stdin(Stdio::piped()) |
2545 | - .stderr(Stdio::piped()) |
2546 | - .spawn()?; |
2547 | - let mut stdin = child |
2548 | - .stdin |
2549 | - .take() |
2550 | - .ok_or_else(|| format_err!("failed to attach to stdin"))?; |
2551 | - |
2552 | - let builder = std::thread::Builder::new(); |
2553 | - |
2554 | - std::thread::scope(|s| { |
2555 | - let handler = builder.spawn_scoped(s, move || { |
2556 | - stdin |
2557 | - .write_all(&msg.message) |
2558 | - .expect("Failed to write to stdin"); |
2559 | - })?; |
2560 | - |
2561 | - handler.join().map_err(|_| { |
2562 | - format_err!( |
2563 | - "Could not join with IPC communication thread for SMTP ShellCommand \ |
2564 | - process" |
2565 | - ) |
2566 | - })?; |
2567 | - let result = child.wait_with_output()?; |
2568 | - if !result.status.success() { |
2569 | - return Err(format_err!( |
2570 | - "sendmail proccess failed with exit code: {:?}\n{}", |
2571 | - result.status.code(), |
2572 | - String::from_utf8(result.stderr).unwrap() |
2573 | - )); |
2574 | - } |
2575 | - Ok::<(), Error>(()) |
2576 | - })?; |
2577 | - Ok(()) |
2578 | - } |
2579 | - for message in messages { |
2580 | - if let Err(err) = submit(&mail_cfg.mail.sendmail_command, &message) { |
2581 | - log::error!( |
2582 | - "error sending message: {}\n{}", |
2583 | - message.message_id, |
2584 | - err.to_string() |
2585 | - ); |
2586 | - failed.push(message.0); |
2587 | - } |
2588 | - } |
2589 | - for mut message in failed { |
2590 | - message.queue = Queue::Deferred; |
2591 | - tx.insert_to_queue(message)?; |
2592 | - } |
2593 | - tx.commit()?; |
2594 | - } |
2595 | - Commands::Postfix { command } => { |
2596 | - let this_exe = std::env::current_exe().unwrap(); |
2597 | - let cfg = PostfixConfiguration { |
2598 | - user: std::borrow::Cow::from(mail_cfg.mail.postfix_user.clone()), |
2599 | - binary_path: this_exe, |
2600 | - ..Default::default() |
2601 | - }; |
2602 | - match command { |
2603 | - Postfix::MasterCf {} => { |
2604 | - print!( |
2605 | - "{}", |
2606 | - cfg.generate_master_cf_entry( |
2607 | - &mail_cfg.mailpot_config(), |
2608 | - cli.config |
2609 | - .expect("need to specify an absolute path to your config file") |
2610 | - .as_path() |
2611 | - ) |
2612 | - ); |
2613 | - } |
2614 | - Postfix::Maps {} => { |
2615 | - let mut db = |
2616 | - Connection::open_or_create_db(mail_cfg.mailpot_config())?.trusted(); |
2617 | - let tx = db.transaction(TransactionBehavior::Exclusive)?; |
2618 | - let lists: Result< |
2619 | - Vec<(DbVal<MailingList>, Option<DbVal<PostPolicy>>)>, |
2620 | - mailpot::Error, |
2621 | - > = tx |
2622 | - .lists()? |
2623 | - .iter() |
2624 | - .map(|list| { |
2625 | - let policy = tx.list_post_policy(list.1)?; |
2626 | - Ok((list.clone(), policy)) |
2627 | - }) |
2628 | - .collect(); |
2629 | - let maps = cfg.generate_maps(lists?.as_slice()); |
2630 | - print!("{}", maps); |
2631 | - } |
2632 | - } |
2633 | + server::serve(&cfg).await? |
2634 | } |
2635 | } |
2636 | - |
2637 | Ok(()) |
2638 | } |
2639 | diff --git a/ayllu-mail/src/nginx_auth.rs b/ayllu-mail/src/nginx_auth.rs |
2640 | deleted file mode 100644 |
2641 | index f4fad42..0000000 |
2642 | --- a/ayllu-mail/src/nginx_auth.rs |
2643 | +++ /dev/null |
2644 | @@ -1,88 +0,0 @@ |
2645 | - use std::sync::Arc; |
2646 | - |
2647 | - use axum::{ |
2648 | - body::Body, |
2649 | - extract::{Request, State}, |
2650 | - http::{header::ToStrError, HeaderValue, StatusCode}, |
2651 | - response::Response, |
2652 | - routing::get, |
2653 | - Router, |
2654 | - }; |
2655 | - use melib::email::parser::address::address; |
2656 | - |
2657 | - use crate::config::Config; |
2658 | - |
2659 | - fn to_str_err(e: ToStrError) -> StatusCode { |
2660 | - tracing::error!("error reading header: {}", e.to_string()); |
2661 | - StatusCode::BAD_REQUEST |
2662 | - } |
2663 | - |
2664 | - async fn handle( |
2665 | - State(cfg): State<Arc<Config>>, |
2666 | - req: Request, |
2667 | - ) -> Result<Response<Body>, StatusCode> { |
2668 | - tracing::info!("processing new SMTP authentication request with headers:"); |
2669 | - req.headers().iter().for_each(|(key, value)| { |
2670 | - tracing::info!("{:?}: {:?}", key, value); |
2671 | - }); |
2672 | - let auth_cfg = cfg.mail.nginx_auth.clone(); |
2673 | - let domains = auth_cfg.domains.unwrap_or(Vec::new()); |
2674 | - if let Some(helo) = req.headers().get("auth-smtp-helo") { |
2675 | - let helo = helo.to_str().map_err(to_str_err)?; |
2676 | - if !domains.is_empty() && !domains.contains(&helo.to_string()) { |
2677 | - tracing::warn!("domain {} is not authroized", helo); |
2678 | - return Err(StatusCode::UNAUTHORIZED); |
2679 | - } |
2680 | - } else { |
2681 | - tracing::warn!("missing auth-smtp-helo header"); |
2682 | - }; |
2683 | - if let Some(to) = req.headers().get("auth-smtp-to") { |
2684 | - let recipient = to.to_str().map_err(to_str_err)?; |
2685 | - let recipient = recipient.trim_start_matches("RCPT TO:"); |
2686 | - let recipient_addr = address(recipient.as_bytes()).map_err(|e| { |
2687 | - tracing::warn!("cannot parse mail address: {:?}", e); |
2688 | - StatusCode::BAD_REQUEST |
2689 | - })?; |
2690 | - let recipient_addr = recipient_addr.1; |
2691 | - if let Some(fqdn) = recipient_addr.get_fqdn() { |
2692 | - if !domains.is_empty() && !domains.contains(&fqdn) { |
2693 | - tracing::warn!("mail is not permitted to be sent to domain: {}", fqdn); |
2694 | - return Err(StatusCode::UNAUTHORIZED); |
2695 | - } |
2696 | - } else { |
2697 | - tracing::warn!("recipient address has not FQDN"); |
2698 | - return Err(StatusCode::BAD_REQUEST); |
2699 | - } |
2700 | - } else { |
2701 | - tracing::warn!("missing auth-smtp-to header"); |
2702 | - return Err(StatusCode::BAD_REQUEST); |
2703 | - } |
2704 | - let mut res = Response::new(Body::empty()); |
2705 | - let headers = res.headers_mut(); |
2706 | - headers.insert("Auth-Status", HeaderValue::from_static("OK")); |
2707 | - headers.insert( |
2708 | - "Auth-Server", |
2709 | - HeaderValue::from_str(&cfg.smtp.host).expect("invalid downstream smtp server"), |
2710 | - ); |
2711 | - headers.insert( |
2712 | - "Auth-Port", |
2713 | - HeaderValue::from_str(&cfg.smtp.port.to_string()).unwrap(), |
2714 | - ); |
2715 | - Ok(res) |
2716 | - } |
2717 | - |
2718 | - /// Simple HTTP server implementing Nginx's ngx_mail_auth_http protocol |
2719 | - /// https://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#protocol |
2720 | - /// which is used to authenticate and redirect requests to an e-mail server. |
2721 | - /// The primary use case for this is to avoid exposing Postfix directly to |
2722 | - /// the internet and proxy SMTP requests via Nginx. This also enables |
2723 | - /// termination of TLS with Nginx. |
2724 | - pub async fn serve(cfg: Config) { |
2725 | - let listen_addr = cfg.mail.nginx_auth.listen.clone(); |
2726 | - let app = Router::new() |
2727 | - .route("/", get(handle)) |
2728 | - .with_state(Arc::new(cfg.clone())); |
2729 | - tracing::info!("nginx_auth module listing @ {}", listen_addr); |
2730 | - let listener = tokio::net::TcpListener::bind(listen_addr).await.unwrap(); |
2731 | - axum::serve(listener, app).await.unwrap(); |
2732 | - } |
2733 | diff --git a/ayllu-mail/src/server.rs b/ayllu-mail/src/server.rs |
2734 | index a23bf72..6f94384 100644 |
2735 | --- a/ayllu-mail/src/server.rs |
2736 | +++ b/ayllu-mail/src/server.rs |
2737 | @@ -1,242 +1,66 @@ |
2738 | - use std::error::Error as StdError; |
2739 | - use std::path::Path; |
2740 | - |
2741 | - use anyhow::Result; |
2742 | - use mailpot::{ |
2743 | - models::{DbVal, Post}, |
2744 | - Configuration, Connection, Error as MailpotError, |
2745 | - }; |
2746 | - use melib::Envelope; |
2747 | - use tracing::log::info; |
2748 | + use maitred::delivery::{Delivery, DeliveryError}; |
2749 | + use maitred::mail_parser::Message; |
2750 | + use maitred::milter::MilterFunc; |
2751 | + use maitred::server::Server; |
2752 | + use maitred::session::Envelope; |
2753 | |
2754 | use crate::config::Config; |
2755 | + use crate::error::Error; |
2756 | |
2757 | - use ayllu_api::{ |
2758 | - error::ApiError, |
2759 | - mail::{MailingList, Message, Server as MailServer, Thread}, |
2760 | - }; |
2761 | - |
2762 | - use ayllu_rpc::{ |
2763 | - futures::prelude::*, |
2764 | - init_socket, spawn, |
2765 | - tarpc::{ |
2766 | - context::Context, |
2767 | - serde_transport::unix, |
2768 | - server::{BaseChannel, Channel}, |
2769 | - tokio_serde::formats::Bincode, |
2770 | - }, |
2771 | - }; |
2772 | - |
2773 | - fn is_patch(subject: &str) -> bool { |
2774 | - subject.contains("[PATCH]") || subject.contains("[patch]") |
2775 | - } |
2776 | + use ayllu_database::{mail::MailExt, Builder, Wrapper as Database}; |
2777 | |
2778 | - fn to_api_error(e: MailpotError) -> ApiError { |
2779 | - ApiError::Message(e.to_string()) |
2780 | + pub struct DbStore { |
2781 | + db: Database, |
2782 | } |
2783 | |
2784 | - fn to_message(post: &DbVal<Post>) -> Message { |
2785 | - let envelope = Envelope::from_bytes(&post.message, None).unwrap(); |
2786 | - let text = envelope |
2787 | - .body_bytes(&post.message) |
2788 | - .text(melib::attachment_types::Text::Rfc822); |
2789 | - let body = String::from_utf8(post.message.to_vec()).unwrap(); |
2790 | - Message { |
2791 | - id: post.pk, |
2792 | - message_id: post.message_id.clone(), |
2793 | - timestamp: post.timestamp, |
2794 | - from: envelope.from[0].get_email(), |
2795 | - address: post.address.clone(), |
2796 | - subject: envelope.subject.clone(), |
2797 | - body, |
2798 | - text, |
2799 | - is_patch: envelope.subject.map_or(false, |subject| is_patch(&subject)), |
2800 | + impl DbStore { |
2801 | + pub fn new(db: Database) -> Self { |
2802 | + DbStore { db } |
2803 | } |
2804 | } |
2805 | |
2806 | - #[derive(Clone)] |
2807 | - struct ServerImpl { |
2808 | - mailpot_config: Configuration, |
2809 | - } |
2810 | - |
2811 | - // BUG: these are all read-only functions but mailpot requires trusted() |
2812 | - |
2813 | - impl MailServer for ServerImpl { |
2814 | - #[doc = r" return all managed mailing lists"] |
2815 | - async fn lists(self, _context: Context) -> Result<Vec<MailingList>, ApiError> { |
2816 | - let db = Connection::open_or_create_db(self.mailpot_config.clone()) |
2817 | - .map_err(to_api_error)? |
2818 | - .trusted(); |
2819 | - Ok(db |
2820 | - .lists() |
2821 | - .map_err(|e| ApiError::Message(e.to_string()))? |
2822 | - .iter() |
2823 | - .map(|db_val| MailingList { |
2824 | - id: db_val.id.clone(), |
2825 | - name: db_val.name.clone(), |
2826 | - request_address: db_val.request_subaddr().clone(), |
2827 | - address: db_val.address.clone(), |
2828 | - description: db_val |
2829 | - .description |
2830 | - .as_ref() |
2831 | - .map_or(String::new(), |desc| desc.clone()), |
2832 | - topics: db_val.topics.clone(), |
2833 | - }) |
2834 | - .collect()) |
2835 | - } |
2836 | - |
2837 | - #[doc = r" list all of the threads associated with a mailing list"] |
2838 | - async fn list_threads( |
2839 | - self, |
2840 | - _context: Context, |
2841 | - id: String, |
2842 | - _offset: i64, |
2843 | - _limit: i64, |
2844 | - ) -> Result<Vec<Thread>, ApiError> { |
2845 | - let db = Connection::open_or_create_db(self.mailpot_config.clone()) |
2846 | - .map_err(to_api_error)? |
2847 | - .trusted(); |
2848 | - let list = db |
2849 | - .list_by_id(&id) |
2850 | - .map_err(to_api_error)? |
2851 | - .ok_or(ApiError::NotFound(format!( |
2852 | - "no mailing list with id {} exists", |
2853 | - id |
2854 | - )))?; |
2855 | - let posts = db.list_posts(list.pk, None).map_err(to_api_error)?; |
2856 | - // TODO: add a new database method to only return posts without |
2857 | - // reply headers to save cpu cycles |
2858 | - let posts: Vec<&DbVal<Post>> = posts |
2859 | - .iter() |
2860 | - .filter(|post| { |
2861 | - let envelope = Envelope::from_bytes(&post.0.message, None).unwrap(); |
2862 | - envelope.in_reply_to.is_none() |
2863 | - }) |
2864 | - .collect(); |
2865 | - let mut threads: Vec<Thread> = Vec::with_capacity(posts.len()); |
2866 | - for post in posts.iter() { |
2867 | - let replies = db |
2868 | - .list_thread(list.pk, &post.message_id) |
2869 | - .map_err(to_api_error)?; |
2870 | - let first = to_message(post); |
2871 | - let has_patch = first.is_patch; |
2872 | - threads.push(Thread { |
2873 | - first, |
2874 | - n_replies: replies.len() as i64, |
2875 | - has_patch, |
2876 | - }); |
2877 | + #[async_trait::async_trait] |
2878 | + impl Delivery for DbStore { |
2879 | + async fn deliver(&self, message: &Envelope) -> Result<(), DeliveryError> { |
2880 | + println!("RCPT TO: {:?}", message.rcpt_to); |
2881 | + for header in message.body.headers() { |
2882 | + println!("HEADER: {}: {:?}", header.name(), header.value()); |
2883 | } |
2884 | - Ok(threads) |
2885 | + Ok(()) |
2886 | } |
2887 | + } |
2888 | |
2889 | - #[doc = r" list all of the responses associated with a post starting from messageId"] |
2890 | - async fn read_thread( |
2891 | - self, |
2892 | - _context: Context, |
2893 | - id: String, |
2894 | - message_id: String, |
2895 | - _offset: i64, |
2896 | - _limit: i64, |
2897 | - ) -> Result<Vec<Message>, ApiError> { |
2898 | - let db = Connection::open_or_create_db(self.mailpot_config.clone()) |
2899 | - .map_err(to_api_error)? |
2900 | - .trusted(); |
2901 | - let list = db |
2902 | - .list_by_id(&id) |
2903 | - .map_err(to_api_error)? |
2904 | - .ok_or(ApiError::NotFound(format!( |
2905 | - "no mailing list with id {} exists", |
2906 | - id |
2907 | - )))?; |
2908 | - let mut posts: Vec<Message> = Vec::new(); |
2909 | - // Read the initial post |
2910 | - let first_post = db |
2911 | - .list_post_by_message_id(list.pk, &message_id) |
2912 | - .map_err(to_api_error)? |
2913 | - .ok_or(ApiError::NotFound(format!( |
2914 | - "no post with id {} exists", |
2915 | - list.pk |
2916 | - )))?; |
2917 | - posts.push(to_message(&first_post)); |
2918 | - // then all of it's replies |
2919 | - let replies = db.list_thread(list.pk, &message_id).map_err(to_api_error)?; |
2920 | - for (_, post) in replies.iter() { |
2921 | - posts.push(to_message(post)); |
2922 | - } |
2923 | - Ok(posts) |
2924 | - } |
2925 | + pub async fn serve(config: &Config) -> Result<(), Error> { |
2926 | + let db = Builder::default() |
2927 | + .url(config.database.path.to_str().unwrap()) |
2928 | + .log_queries(config.log_level == "DEBUG") |
2929 | + .read_only(true) |
2930 | + .build() |
2931 | + .await?; |
2932 | + let db_store = DbStore::new(db); |
2933 | + let mail_config = &config.mail; |
2934 | + // initialize maildirs before starting |
2935 | + let mut mail_server = Server::default() |
2936 | + .address(&mail_config.address) |
2937 | + .with_milter(MilterFunc(|message: &Message<'static>| { |
2938 | + let message = message.clone(); |
2939 | + async move { Ok(message.to_owned()) } |
2940 | + })) |
2941 | + .with_delivery(db_store) |
2942 | + .dkim_verification(mail_config.dkim.enabled.is_some_and(|enabled| enabled)) |
2943 | + .spf_verification(mail_config.spf.enabled.is_some_and(|enabled| enabled)); |
2944 | |
2945 | - #[doc = r" read a single post"] |
2946 | - async fn read_post( |
2947 | - self, |
2948 | - _context: Context, |
2949 | - id: String, |
2950 | - message_id: String, |
2951 | - ) -> Result<Message, ApiError> { |
2952 | - let db = Connection::open_or_create_db(self.mailpot_config.clone()) |
2953 | - .map_err(to_api_error)? |
2954 | - .trusted(); |
2955 | - let list = db |
2956 | - .list_by_id(&id) |
2957 | - .map_err(to_api_error)? |
2958 | - .ok_or(ApiError::NotFound(format!( |
2959 | - "no mailing list with id {} exists", |
2960 | - id |
2961 | - )))?; |
2962 | - let post = db |
2963 | - .list_post_by_message_id(list.pk, &message_id) |
2964 | - .map_err(to_api_error)? |
2965 | - .ok_or(ApiError::NotFound(format!( |
2966 | - "no post with id {}", |
2967 | - message_id |
2968 | - )))?; |
2969 | - Ok(to_message(&post)) |
2970 | + if let Some(tls_config) = mail_config.tls.as_ref() { |
2971 | + tracing::info!("TLS enabled"); |
2972 | + mail_server = mail_server.with_certificates(&tls_config.key, &tls_config.certificate); |
2973 | + // session_opts = session_opts.starttls_enabled(true); |
2974 | } |
2975 | |
2976 | - #[doc = r" export one or more messages in mbox format"] |
2977 | - async fn export( |
2978 | - self, |
2979 | - _context: Context, |
2980 | - id: String, |
2981 | - message_id: Option<String>, |
2982 | - as_thread: bool, |
2983 | - ) -> Result<Vec<u8>, ApiError> { |
2984 | - let db = Connection::open_or_create_db(self.mailpot_config.clone()) |
2985 | - .map_err(to_api_error)? |
2986 | - .trusted(); |
2987 | - let list = db |
2988 | - .list_by_id(&id) |
2989 | - .map_err(to_api_error)? |
2990 | - .ok_or(ApiError::NotFound(format!( |
2991 | - "no mailing list with id {} exists", |
2992 | - id |
2993 | - )))?; |
2994 | - let buf = db |
2995 | - .export_mbox(list.pk, message_id.as_deref(), as_thread) |
2996 | - .map_err(to_api_error)?; |
2997 | - Ok(buf) |
2998 | - } |
2999 | - } |
3000 | + if mail_config.proxy_protocol.is_some_and(|enabled| enabled) { |
3001 | + mail_server = mail_server.proxy_protocol(true); |
3002 | + }; |
3003 | |
3004 | - pub async fn serve(cfg: &Config) -> Result<(), Box<dyn StdError>> { |
3005 | - let socket_path = Path::new(&cfg.mail.socket_path); |
3006 | - init_socket(socket_path)?; |
3007 | - info!("mail server listening @ {:?}", socket_path); |
3008 | - let mut listener = unix::listen(socket_path, Bincode::default).await?; |
3009 | - listener.config_mut().max_frame_length(usize::MAX); |
3010 | - listener |
3011 | - // Ignore accept errors. |
3012 | - .filter_map(|r| future::ready(r.ok())) |
3013 | - .map(BaseChannel::with_defaults) |
3014 | - .map(move |channel| { |
3015 | - let server = ServerImpl { |
3016 | - mailpot_config: cfg.mailpot_config(), |
3017 | - }; |
3018 | - channel.execute(server.serve()).for_each(spawn) |
3019 | - }) |
3020 | - // Max 10 channels. |
3021 | - .buffer_unordered(10) |
3022 | - .for_each(|_| async {}) |
3023 | - .await; |
3024 | + // mail_server = mail_server.with_session_opts(session_opts); |
3025 | + mail_server.listen().await?; |
3026 | Ok(()) |
3027 | } |
3028 | diff --git a/ayllu/src/config.rs b/ayllu/src/config.rs |
3029 | index 78ed315..47ebf6f 100644 |
3030 | --- a/ayllu/src/config.rs |
3031 | +++ b/ayllu/src/config.rs |
3032 | @@ -177,11 +177,11 @@ impl Xmpp { |
3033 | |
3034 | #[derive(Deserialize, Serialize, Clone, Debug, Default)] |
3035 | pub struct MailingList { |
3036 | - pub id: String, |
3037 | - pub name: Option<String>, |
3038 | + pub name: String, |
3039 | pub address: String, |
3040 | pub description: Option<String>, |
3041 | pub topics: Vec<String>, |
3042 | + pub request_address: String, |
3043 | // pub post_policy: PostPolicy, |
3044 | // pub subscription_policy: SubscriptionPolicy, |
3045 | } |
3046 | diff --git a/ayllu/src/web2/error.rs b/ayllu/src/web2/error.rs |
3047 | index 4f20162..2b40dfb 100644 |
3048 | --- a/ayllu/src/web2/error.rs |
3049 | +++ b/ayllu/src/web2/error.rs |
3050 | @@ -20,6 +20,8 @@ pub enum Error { |
3051 | Message(String), |
3052 | #[error("Resource not found: {0}")] |
3053 | NotFound(String), |
3054 | + #[error("Component not enabled: {0}")] |
3055 | + ComponentNotEnabled(String) |
3056 | } |
3057 | |
3058 | impl IntoResponse for Error { |
3059 | diff --git a/ayllu/src/web2/middleware/error.rs b/ayllu/src/web2/middleware/error.rs |
3060 | index 57edae0..03bbdf3 100644 |
3061 | --- a/ayllu/src/web2/middleware/error.rs |
3062 | +++ b/ayllu/src/web2/middleware/error.rs |
3063 | @@ -25,6 +25,7 @@ pub async fn middleware( |
3064 | let status_code = match error { |
3065 | Error::Message(_) => StatusCode::INTERNAL_SERVER_ERROR, |
3066 | Error::NotFound(_) => StatusCode::NOT_FOUND, |
3067 | + Error::ComponentNotEnabled(_) => StatusCode::INTERNAL_SERVER_ERROR, |
3068 | }; |
3069 | // reload the theme since the middleware may not have ran yet |
3070 | let loader = Loader { |
3071 | diff --git a/ayllu/src/web2/routes/mail.rs b/ayllu/src/web2/routes/mail.rs |
3072 | index 5052cbf..76550ad 100644 |
3073 | --- a/ayllu/src/web2/routes/mail.rs |
3074 | +++ b/ayllu/src/web2/routes/mail.rs |
3075 | @@ -7,15 +7,15 @@ use axum::{ |
3076 | }; |
3077 | use serde::{Deserialize, Serialize}; |
3078 | |
3079 | - use crate::highlight::Highlighter; |
3080 | - use crate::web2::error::Error; |
3081 | use crate::web2::middleware::template::Template; |
3082 | use crate::web2::navigation; |
3083 | + use crate::{config::Config, highlight::Highlighter}; |
3084 | + use crate::{config::Mail, web2::error::Error}; |
3085 | use ayllu_rpc::tarpc::context; |
3086 | |
3087 | #[derive(Deserialize)] |
3088 | pub struct Params { |
3089 | - pub list_id: String, |
3090 | + pub list_name: String, |
3091 | pub thread_id: Option<String>, |
3092 | pub message_id: Option<String>, |
3093 | } |
3094 | @@ -42,21 +42,16 @@ struct Message { |
3095 | pub is_patch: bool, |
3096 | } |
3097 | |
3098 | - #[derive(Debug, Serialize, Default, PartialEq)] |
3099 | - struct List { |
3100 | - pub id: String, |
3101 | - pub name: String, |
3102 | - pub description: Option<String>, |
3103 | - pub address: String, |
3104 | - pub topics: Vec<String>, |
3105 | - pub request_address: String, |
3106 | - } |
3107 | - |
3108 | pub async fn lists( |
3109 | + Extension(cfg): Extension<Config>, |
3110 | Extension((templates, mut ctx)): Extension<Template>, |
3111 | ) -> Result<Html<String>, Error> { |
3112 | ctx.insert("title", "lists"); |
3113 | ctx.insert("nav_elements", &navigation::global("mail", true)); |
3114 | + let mail_cfg = cfg |
3115 | |
3116 | + .ok_or(Error::ComponentNotEnabled(String::from("mail")))?; |
3117 | + ctx.insert("lists", &mail_cfg.lists.clone()); |
3118 | // let mail_client = initiator.mail.unwrap(); |
3119 | // let rpc_lists = mail_client.lists(context::current()).await??; |
3120 | // ctx.insert("lists", &rpc_lists); |
3121 | @@ -67,14 +62,28 @@ pub async fn lists( |
3122 | |
3123 | #[debug_handler] |
3124 | pub async fn threads( |
3125 | + Extension(cfg): Extension<Config>, |
3126 | Path(params): Path<Params>, |
3127 | // Extension(db): Extension<Arc<Database>>, |
3128 | Extension((templates, mut ctx)): Extension<Template>, |
3129 | ) -> Result<Html<String>, Error> { |
3130 | - Err(Error::NotFound(format!( |
3131 | - "no mailing list with id: {} exists", |
3132 | - params.list_id |
3133 | - ))) |
3134 | + ctx.insert("title", "lists"); |
3135 | + ctx.insert("nav_elements", &navigation::global("mail", true)); |
3136 | + let mail_cfg = cfg |
3137 | |
3138 | + .ok_or(Error::ComponentNotEnabled(String::from("mail")))?; |
3139 | + let mailing_list = mail_cfg |
3140 | + .lists |
3141 | + .iter() |
3142 | + .find(|list| list.name == params.list_name) |
3143 | + .ok_or(Error::NotFound(params.list_name))?; |
3144 | + ctx.insert("list", &mailing_list); |
3145 | + |
3146 | + // FIXME |
3147 | + let threads: Vec<Thread> = Vec::new(); |
3148 | + ctx.insert("threads", &threads); |
3149 | + let body = templates.render("threads.html", &ctx)?; |
3150 | + Ok(Html(body)) |
3151 | // let mailing_list = lists.iter().find(|list| list.id == params.list_id); |
3152 | // if let Some(mailing_list) = mailing_list { |
3153 | // ctx.insert("title", &format!("list {}", mailing_list.name)); |
3154 | @@ -106,8 +115,8 @@ pub async fn thread( |
3155 | Extension((templates, mut ctx)): Extension<Template>, |
3156 | ) -> Result<Html<String>, Error> { |
3157 | Err(Error::NotFound(format!( |
3158 | - "no mailing list with id: {} exists", |
3159 | - params.list_id |
3160 | + "no mailing list with name: {} exists", |
3161 | + params.list_name |
3162 | ))) |
3163 | // let client = initiator.mail.unwrap(); |
3164 | // let lists = client.lists(context::current()).await??; |
3165 | @@ -163,8 +172,8 @@ pub async fn message( |
3166 | Extension((templates, mut ctx)): Extension<Template>, |
3167 | ) -> Result<Html<String>, Error> { |
3168 | Err(Error::NotFound(format!( |
3169 | - "no mailing list with id: {} exists", |
3170 | - params.list_id |
3171 | + "no mailing list with name: {} exists", |
3172 | + params.list_name |
3173 | ))) |
3174 | // let client = initiator.mail.unwrap(); |
3175 | // let lists = client.lists(context::current()).await??; |
3176 | @@ -200,8 +209,8 @@ pub async fn message( |
3177 | |
3178 | pub async fn export(Path(params): Path<Params>) -> Result<Response, Error> { |
3179 | Err(Error::NotFound(format!( |
3180 | - "no mailing list with id: {} exists", |
3181 | - params.list_id |
3182 | + "no mailing list with name: {} exists", |
3183 | + params.list_name |
3184 | ))) |
3185 | // let client = initiator.mail.unwrap(); |
3186 | // let lists = client.lists(context::current()).await??; |
3187 | diff --git a/ayllu/src/web2/server.rs b/ayllu/src/web2/server.rs |
3188 | index f03b1f1..324bdf8 100644 |
3189 | --- a/ayllu/src/web2/server.rs |
3190 | +++ b/ayllu/src/web2/server.rs |
3191 | @@ -146,15 +146,15 @@ pub async fn serve(cfg: &Config) -> Result<(), Box<dyn Error>> { |
3192 | "/mail", |
3193 | Router::new() |
3194 | .route("/", routing::get(mail::lists)) |
3195 | - .route("/:list_id", routing::get(mail::threads)) |
3196 | - .route("/export/:list_id", routing::get(mail::export)) |
3197 | - .route("/export/:list_id/:thread_id", routing::get(mail::export)) |
3198 | + .route("/:list_name", routing::get(mail::threads)) |
3199 | + .route("/export/:list_name", routing::get(mail::export)) |
3200 | + .route("/export/:list_name/:thread_id", routing::get(mail::export)) |
3201 | .route( |
3202 | - "/export/:list_id/:thread_id/:message_id", |
3203 | + "/export/:list_name/:thread_id/:message_id", |
3204 | routing::get(mail::export), |
3205 | ) |
3206 | - .route("/thread/:list_id/:message_id", routing::get(mail::thread)) |
3207 | - .route("/message/:list_id/:message_id", routing::get(mail::message)) |
3208 | + .route("/thread/:list_name/:message_id", routing::get(mail::thread)) |
3209 | + .route("/message/:list_name/:message_id", routing::get(mail::message)) |
3210 | .layer(from_fn_with_state( |
3211 | Arc::new((cfg.clone(), themes.clone())), |
3212 | template::middleware, |
3213 | diff --git a/ayllu/themes/default/templates/base.html b/ayllu/themes/default/templates/base.html |
3214 | index e68a222..b71fcc3 100644 |
3215 | --- a/ayllu/themes/default/templates/base.html |
3216 | +++ b/ayllu/themes/default/templates/base.html |
3217 | @@ -24,7 +24,7 @@ |
3218 | </div> |
3219 | </main> |
3220 | <footer> |
3221 | - Rendered {%- if render_time %} in ({{ render_time }} ms){%- endif %} @ {{ current_time }} |
3222 | + Rendered {%- if render_time %}in ({{ render_time }} ms){%- endif %} @ {{ current_time }} |
3223 | </footer> |
3224 | </body> |
3225 | </html> |
3226 | diff --git a/ayllu/themes/default/templates/blob.html b/ayllu/themes/default/templates/blob.html |
3227 | index d78942a..e880df9 100644 |
3228 | --- a/ayllu/themes/default/templates/blob.html |
3229 | +++ b/ayllu/themes/default/templates/blob.html |
3230 | @@ -4,9 +4,9 @@ |
3231 | <section> |
3232 | {{ macros::navigation(items=subnav_elements, title="Blob") }} |
3233 | <section class="info-bar"> |
3234 | - {%- if hint -%} |
3235 | - <span class="hint" style="color: {{ color }}">{{ hint }}</span> |
3236 | - {%- endif -%} |
3237 | + {%- if hint -%} |
3238 | + <span class="hint" style="color: {{ color }}">{{ hint }}</span> |
3239 | + {%- endif -%} |
3240 | <span>{{ file_name }}</span> |
3241 | <span class="right">{{ file_mode | filemode }} {{ file_size | human_bytes }}</span> |
3242 | </section> |
3243 | diff --git a/ayllu/themes/default/templates/index.html b/ayllu/themes/default/templates/index.html |
3244 | index 1fdcc6e..7b1ab65 100644 |
3245 | --- a/ayllu/themes/default/templates/index.html |
3246 | +++ b/ayllu/themes/default/templates/index.html |
3247 | @@ -34,7 +34,7 @@ |
3248 | {%- if repo.is_mirror %} <span class="tiny-highlight">[mirror]</span> {%- endif -%} |
3249 | </div> |
3250 | </td> |
3251 | - <td>{{ repo.description | truncate(length=50, end="...")}}</td> |
3252 | + <td>{{ repo.description | truncate(length=50, end="...") }}</td> |
3253 | <td>{{ repo.age }}</td> |
3254 | <td class="collapse">{{ repo.activity }}</td> |
3255 | </tr> |
3256 | diff --git a/ayllu/themes/default/templates/lists.html b/ayllu/themes/default/templates/lists.html |
3257 | index ad55e09..d91cef2 100644 |
3258 | --- a/ayllu/themes/default/templates/lists.html |
3259 | +++ b/ayllu/themes/default/templates/lists.html |
3260 | @@ -2,18 +2,26 @@ |
3261 | {% extends "base.html" %} |
3262 | {% block content %} |
3263 | <h1>Mailing Lists</h1> |
3264 | - <div class="stretch"> |
3265 | - {% for list in lists %} |
3266 | - <section class="card"> |
3267 | - <article class="segmented-4"> |
3268 | - <div> |
3269 | - <a href="/mail/{{ list.id }}">{{ list.name }} [{{ list.id }}]</a> |
3270 | - </div> |
3271 | - <div>{{ list.description }}</div> |
3272 | - <div>{{ list.address }}</div> |
3273 | - <div>▃▅▇▇▁▅▃▅▅▃▅▁▁</div> |
3274 | - </article> |
3275 | - </section> |
3276 | - {% endfor %} |
3277 | - </div> |
3278 | + <section> |
3279 | + <table class="data-table"> |
3280 | + <thead> |
3281 | + <tr> |
3282 | + <th>Name</th> |
3283 | + <th>Description</th> |
3284 | + <th>Address</th> |
3285 | + </tr> |
3286 | + </thead> |
3287 | + <tbody> |
3288 | + {% for list in lists %} |
3289 | + <tr> |
3290 | + <td> |
3291 | + <a href="/mail/{{ list.name }}">{{ list.name }} [{{ list.id }}]</a> |
3292 | + </td> |
3293 | + <td>{{ list.description }}</td> |
3294 | + <td>{{ list.address }}</td> |
3295 | + </tr> |
3296 | + {% endfor %} |
3297 | + </tbody> |
3298 | + </table> |
3299 | + </section> |
3300 | {% endblock %} |
3301 | diff --git a/ayllu/themes/default/templates/threads.html b/ayllu/themes/default/templates/threads.html |
3302 | index c45476a..57fd7a1 100644 |
3303 | --- a/ayllu/themes/default/templates/threads.html |
3304 | +++ b/ayllu/themes/default/templates/threads.html |
3305 | @@ -14,18 +14,18 @@ |
3306 | </br> |
3307 | <h4>Subscribe</h4> |
3308 | <p> |
3309 | - Send an e-mail to <a href="mailto:{{ request_address }}?subject=subscribe">{{ request_address }}</a> with the following subject: <code>subscribe</code> |
3310 | + Send an e-mail to <a href="mailto:{{ list.request_address }}?subject=subscribe">{{ list.request_address }}</a> with the following subject: <code>subscribe</code> |
3311 | </p> |
3312 | <h4>Unsubscribe</h4> |
3313 | <p> |
3314 | - Send an e-mail to <a href="mailto:{{ request_address }}?subject=unsubscribe">{{ request_address }}</a> with the following subject: <code>unsubscribe</code> |
3315 | + Send an e-mail to <a href="mailto:{{ list.request_address }}?subject=unsubscribe">{{ list.request_address }}</a> with the following subject: <code>unsubscribe</code> |
3316 | </p> |
3317 | <h4>Export List</h4> |
3318 | <p> |
3319 | - <a href="/mail/export/{{ list.id }}">mbox</a> |
3320 | + <a href="/mail/export/{{ list.name }}">mbox</a> |
3321 | </p> |
3322 | </div> |
3323 | - <h4>Messages</h4> |
3324 | + <h4>Threads</h4> |
3325 | <div class="stretch"> |
3326 | {% for thread in threads %} |
3327 | <section class="card"> |
3328 | diff --git a/contrib/demo.neomuttrc b/contrib/demo.neomuttrc |
3329 | new file mode 100644 |
3330 | index 0000000..5cf6e57 |
3331 | --- /dev/null |
3332 | +++ b/contrib/demo.neomuttrc |
3333 | @@ -0,0 +1,55 @@ |
3334 | + # vim: set filetype=neomuttrc : |
3335 | + |
3336 | + set mbox_type=Maildir |
3337 | + set folder="./mail/demo@example.org" |
3338 | + set spoolfile=+ |
3339 | + |
3340 | + set mbox_type=Maildir |
3341 | + set folder="./mail/demo2@example.org" |
3342 | + set spoolfile=+ |
3343 | + |
3344 | + set realname = 'Demo User 1' |
3345 | + set from = demo-1@example.org |
3346 | + |
3347 | + set smtp_url=smtp://127.0.0.1:30025 |
3348 | + set ssl_starttls = no |
3349 | + set ssl_force_tls = false |
3350 | + |
3351 | + set sidebar_visible |
3352 | + set sidebar_format = "%B%<F? [%F]>%* %<N?%N/>%S" |
3353 | + # set mail_check_stats |
3354 | + |
3355 | + color normal default default # Text is "Text" |
3356 | + color index color2 default ~N # New Messages are Green |
3357 | + color index color1 default ~F # Flagged messages are Red |
3358 | + color index color13 default ~T # Tagged Messages are Red |
3359 | + color index color1 default ~D # Messages to delete are Red |
3360 | + color attachment color5 default # Attachments are Pink |
3361 | + color signature color8 default # Signatures are Surface 2 |
3362 | + color search color4 default # Highlighted results are Blue |
3363 | + |
3364 | + color indicator default color8 # currently highlighted message Surface 2=Background Text=Foreground |
3365 | + color error color1 default # error messages are Red |
3366 | + color status color15 default # status line "Subtext 0" |
3367 | + color tree color15 default # thread tree arrows Subtext 0 |
3368 | + color tilde color15 default # blank line padding Subtext 0 |
3369 | + |
3370 | + color hdrdefault color13 default # default headers Pink |
3371 | + color header color13 default "^From:" |
3372 | + color header color13 default "^Subject:" |
3373 | + |
3374 | + color quoted color15 default # Subtext 0 |
3375 | + color quoted1 color7 default # Subtext 1 |
3376 | + color quoted2 color8 default # Surface 2 |
3377 | + color quoted3 color0 default # Surface 1 |
3378 | + color quoted4 color0 default |
3379 | + color quoted5 color0 default |
3380 | + |
3381 | + color body color2 default [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+ # email addresses Green |
3382 | + color body color2 default (https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+ # URLs Green |
3383 | + color body color4 default (^|[[:space:]])\\*[^[:space:]]+\\*([[:space:]]|$) # *bold* text Blue |
3384 | + color body color4 default (^|[[:space:]])_[^[:space:]]+_([[:space:]]|$) # _underlined_ text Blue |
3385 | + color body color4 default (^|[[:space:]])/[^[:space:]]+/([[:space:]]|$) # /italic/ text Blue |
3386 | + |
3387 | + color sidebar_flagged color1 default # Mailboxes with flagged mails are Red |
3388 | + color sidebar_new color10 default # Mailboxes with new mail are Green |
3389 | diff --git a/crates/database/queries/mail_create.sql b/crates/database/queries/mail_create.sql |
3390 | new file mode 100644 |
3391 | index 0000000..8b13789 |
3392 | --- /dev/null |
3393 | +++ b/crates/database/queries/mail_create.sql |
3394 | @@ -0,0 +1 @@ |
3395 | + |
3396 | diff --git a/crates/database/src/lib.rs b/crates/database/src/lib.rs |
3397 | index c1e8a1e..0ceda9f 100644 |
3398 | --- a/crates/database/src/lib.rs |
3399 | +++ b/crates/database/src/lib.rs |
3400 | @@ -10,6 +10,7 @@ use tracing::log; |
3401 | pub mod contributors; |
3402 | pub mod jobs; |
3403 | pub mod languages; |
3404 | + pub mod mail; |
3405 | pub mod stats; |
3406 | |
3407 | pub type Error = SqlxError; |
3408 | diff --git a/crates/database/src/mail.rs b/crates/database/src/mail.rs |
3409 | new file mode 100644 |
3410 | index 0000000..1bef062 |
3411 | --- /dev/null |
3412 | +++ b/crates/database/src/mail.rs |
3413 | @@ -0,0 +1,59 @@ |
3414 | + use async_trait::async_trait; |
3415 | + use serde::{Deserialize, Serialize}; |
3416 | + |
3417 | + use crate::Error; |
3418 | + use crate::Wrapper as Database; |
3419 | + |
3420 | + #[derive(Clone, Default, Serialize, Deserialize)] |
3421 | + pub struct Thread(Vec<Message>); |
3422 | + |
3423 | + impl Thread { |
3424 | + pub fn has_patch(&self) -> bool { |
3425 | + todo!() |
3426 | + } |
3427 | + } |
3428 | + |
3429 | + #[derive(Clone, Default, Serialize, Deserialize)] |
3430 | + pub struct Message {} |
3431 | + |
3432 | + impl Message { |
3433 | + pub fn is_patch(&self) -> bool { |
3434 | + todo!() |
3435 | + } |
3436 | + } |
3437 | + |
3438 | + #[async_trait] |
3439 | + pub trait MailExt { |
3440 | + async fn create_message( |
3441 | + &self, |
3442 | + mail_from: &str, |
3443 | + message_id: &str, |
3444 | + message_to: &[&str], |
3445 | + message_body: &[u8], |
3446 | + reply_to: Option<&str>, |
3447 | + ) -> Result<i64, Error>; |
3448 | + async fn read_message(&self, message_id: &str) -> Result<Message, Error>; |
3449 | + async fn list_thread(&self, message_id: &str) -> Result<Thread, Error>; |
3450 | + } |
3451 | + |
3452 | + #[async_trait] |
3453 | + impl MailExt for Database { |
3454 | + async fn create_message( |
3455 | + &self, |
3456 | + mail_from: &str, |
3457 | + message_id: &str, |
3458 | + message_to: &[&str], |
3459 | + message_body: &[u8], |
3460 | + reply_to: Option<&str>, |
3461 | + ) -> Result<i64, Error> { |
3462 | + todo!() |
3463 | + } |
3464 | + |
3465 | + async fn read_message(&self, message_id: &str) -> Result<Message, Error> { |
3466 | + todo!() |
3467 | + } |
3468 | + |
3469 | + async fn list_thread(&self, message_id: &str) -> Result<Thread, Error> { |
3470 | + todo!() |
3471 | + } |
3472 | + } |
3473 | diff --git a/scripts/neomutt.sh b/scripts/neomutt.sh |
3474 | new file mode 100755 |
3475 | index 0000000..a7a8058 |
3476 | --- /dev/null |
3477 | +++ b/scripts/neomutt.sh |
3478 | @@ -0,0 +1,5 @@ |
3479 | + #!/bin/sh |
3480 | + |
3481 | + mkdir -p mail/demo@example.org |
3482 | + |
3483 | + neomutt -F contrib/demo.neomuttrc |
3484 | diff --git a/scripts/send_test_email.sh b/scripts/send_test_email.sh |
3485 | new file mode 100755 |
3486 | index 0000000..55bd149 |
3487 | --- /dev/null |
3488 | +++ b/scripts/send_test_email.sh |
3489 | @@ -0,0 +1,12 @@ |
3490 | + #!/bin/sh |
3491 | + # Generate a patch of the current HEAD for testing purposes |
3492 | + |
3493 | + SMTP_TARGET="127.0.0.1:30025" |
3494 | + |
3495 | + git send-email \ |
3496 | + --8bit-encoding UTF8 \ |
3497 | + --to dev@ayllu-forge.org \ |
3498 | + --from hello@ayllu-forge.org \ |
3499 | + --subject "Ayllu Test Patch" \ |
3500 | + --smtp-server "$SMTP_TARGET" \ |
3501 | + HEAD^ |