@tutao/node-mimimi 277.250414.1 → 284.250428.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutao/node-mimimi",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "284.250428.2",
|
|
4
4
|
"main": "./dist/binding.js",
|
|
5
5
|
"types": "./dist/binding.d.ts",
|
|
6
6
|
"napi": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@tutao/otest": "
|
|
16
|
+
"@tutao/otest": "284.250428.2",
|
|
17
17
|
"@napi-rs/cli": "3.0.0-alpha.68",
|
|
18
18
|
"typescript": "5.3.3",
|
|
19
19
|
"zx": "8.1.5"
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"version": "napi version"
|
|
31
31
|
},
|
|
32
32
|
"optionalDependencies": {
|
|
33
|
-
"@tutao/node-mimimi-win32-x64-msvc": "
|
|
34
|
-
"@tutao/node-mimimi-linux-x64-gnu": "
|
|
35
|
-
"@tutao/node-mimimi-darwin-universal": "
|
|
33
|
+
"@tutao/node-mimimi-win32-x64-msvc": "284.250428.2",
|
|
34
|
+
"@tutao/node-mimimi-linux-x64-gnu": "284.250428.2",
|
|
35
|
+
"@tutao/node-mimimi-darwin-universal": "284.250428.2"
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -156,6 +156,7 @@ impl From<MailContact> for MailAddress {
|
|
|
156
156
|
name: value.name,
|
|
157
157
|
contact: None,
|
|
158
158
|
_finalIvs: Default::default(),
|
|
159
|
+
_errors: Default::default(),
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
}
|
|
@@ -578,9 +579,10 @@ impl ImportableMail {
|
|
|
578
579
|
.into_iter()
|
|
579
580
|
.map(|reply_to| EncryptedMailAddress {
|
|
580
581
|
_id: Some(tutasdk::CustomId::from_custom_string(FIXED_CUSTOM_ID)),
|
|
581
|
-
_finalIvs: Default::default(),
|
|
582
582
|
name: reply_to.name,
|
|
583
583
|
address: reply_to.mail_address,
|
|
584
|
+
_finalIvs: Default::default(),
|
|
585
|
+
_errors: Default::default(),
|
|
584
586
|
})
|
|
585
587
|
.collect();
|
|
586
588
|
|
|
@@ -605,7 +607,6 @@ impl ImportableMail {
|
|
|
605
607
|
_format: 0,
|
|
606
608
|
ownerEncSessionKey: owner_enc_sk,
|
|
607
609
|
ownerKeyVersion: owner_enc_sk_version,
|
|
608
|
-
_finalIvs: Default::default(),
|
|
609
610
|
compressedHeaders: headers_string,
|
|
610
611
|
subject,
|
|
611
612
|
compressedBodyText: html_body_text,
|
|
@@ -632,7 +633,8 @@ impl ImportableMail {
|
|
|
632
633
|
inReplyTo: in_reply_to,
|
|
633
634
|
references,
|
|
634
635
|
importedAttachments: vec![],
|
|
635
|
-
_errors:
|
|
636
|
+
_errors: Default::default(),
|
|
637
|
+
_finalIvs: Default::default(),
|
|
636
638
|
}
|
|
637
639
|
}
|
|
638
640
|
}
|
|
@@ -653,10 +655,7 @@ impl ImportableMail {
|
|
|
653
655
|
pub fn from_parsed_message(parsed_message: &mail_parser::Message) -> Self {
|
|
654
656
|
let subject = parsed_message.subject().unwrap_or_default().to_string();
|
|
655
657
|
|
|
656
|
-
let date = parsed_message
|
|
657
|
-
.date()
|
|
658
|
-
.as_ref()
|
|
659
|
-
.map(|date_time| DateTime::from_millis(date_time.to_timestamp() as u64 * 1000));
|
|
658
|
+
let date = get_importable_date_time(parsed_message);
|
|
660
659
|
|
|
661
660
|
let name_as_address_if_empty_address = |mut address: MailContact| -> MailContact {
|
|
662
661
|
if address.mail_address.is_empty() && !address.name.is_empty() {
|
|
@@ -770,6 +769,22 @@ impl ImportableMail {
|
|
|
770
769
|
}
|
|
771
770
|
}
|
|
772
771
|
|
|
772
|
+
/**
|
|
773
|
+
* convert the "Date:" header value from the parsed message to something we can import.
|
|
774
|
+
* if the value isn't valid (parser returned -1 or the value doesn't fit in an u64
|
|
775
|
+
* when converted to milliseconds), we'll use midnight, 1st of January 1970 as a default.
|
|
776
|
+
*/
|
|
777
|
+
fn get_importable_date_time(message: &mail_parser::Message) -> Option<DateTime> {
|
|
778
|
+
message
|
|
779
|
+
.date()
|
|
780
|
+
.map(mail_parser::DateTime::to_timestamp)
|
|
781
|
+
.map(|timestamp| timestamp.max(0))
|
|
782
|
+
.into_iter()
|
|
783
|
+
.filter_map(|millis| (millis as u64).checked_mul(1000))
|
|
784
|
+
.map(DateTime::from_millis)
|
|
785
|
+
.next()
|
|
786
|
+
}
|
|
787
|
+
|
|
773
788
|
#[cfg(test)]
|
|
774
789
|
mod mime_string_to_importable_mail_test;
|
|
775
790
|
#[cfg(test)]
|
package/src/importer/messages.rs
CHANGED
|
@@ -65,6 +65,8 @@ pub struct MailImportMessage {
|
|
|
65
65
|
pub enum PreparationError {
|
|
66
66
|
/// Can not create a native Rest client
|
|
67
67
|
NoNativeRestClient,
|
|
68
|
+
/// Can not create a native file client
|
|
69
|
+
NoNativeFileClient,
|
|
68
70
|
/// some error occurred while reading import directory
|
|
69
71
|
CannotReadOldStateId,
|
|
70
72
|
/// Error when trying to resume the session passed from client
|
|
@@ -134,6 +136,7 @@ impl From<PreparationError> for napi::Error {
|
|
|
134
136
|
fn from(prep_err: PreparationError) -> Self {
|
|
135
137
|
let code = match prep_err {
|
|
136
138
|
PreparationError::NoNativeRestClient => "NoNativeRestClient",
|
|
139
|
+
PreparationError::NoNativeFileClient => "NoNativeFileClient",
|
|
137
140
|
PreparationError::CannotReadOldStateId => "ImportDirectoryPreparation",
|
|
138
141
|
PreparationError::LoginError => "LoginError",
|
|
139
142
|
PreparationError::FailedToReadEmls => "FailedToReadEmls",
|
package/src/importer.rs
CHANGED
|
@@ -19,6 +19,7 @@ use crate::importer::messages::{
|
|
|
19
19
|
ImportErrorKind, ImportOkKind, MailImportErrorMessage, PreparationError,
|
|
20
20
|
};
|
|
21
21
|
use crate::importer_api::TutaCredentials;
|
|
22
|
+
use tutasdk::bindings::native_file_client::NativeFileClient;
|
|
22
23
|
use tutasdk::entities::generated::tutanota::{
|
|
23
24
|
ImportMailGetIn, ImportMailPostIn, ImportMailPostOut, ImportMailState,
|
|
24
25
|
};
|
|
@@ -234,7 +235,7 @@ impl ImportEssential {
|
|
|
234
235
|
ownerKeyVersion: owner_enc_sk_for_import_state_get.version as i64,
|
|
235
236
|
totalMails: total_importable_mails,
|
|
236
237
|
targetMailFolder: target_mailset,
|
|
237
|
-
_errors:
|
|
238
|
+
_errors: Default::default(),
|
|
238
239
|
_finalIvs: Default::default(),
|
|
239
240
|
};
|
|
240
241
|
|
|
@@ -308,6 +309,7 @@ impl Importer {
|
|
|
308
309
|
}
|
|
309
310
|
|
|
310
311
|
pub(super) async fn create_sdk(
|
|
312
|
+
config_directory: &str,
|
|
311
313
|
tuta_credentials: TutaCredentials,
|
|
312
314
|
) -> Result<Arc<LoggedInSdk>, PreparationError> {
|
|
313
315
|
let base_url = tuta_credentials.api_url.clone();
|
|
@@ -315,14 +317,19 @@ impl Importer {
|
|
|
315
317
|
log::error!("Can not create new native rest client: {e:?}");
|
|
316
318
|
PreparationError::NoNativeRestClient
|
|
317
319
|
})?;
|
|
320
|
+
let file_client = NativeFileClient::try_new(config_directory.into()).map_err(|e| {
|
|
321
|
+
log::error!("Can not create new native rest client: {e:?}");
|
|
322
|
+
PreparationError::NoNativeRestClient
|
|
323
|
+
})?;
|
|
318
324
|
|
|
319
|
-
let logged_in_sdk =
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
325
|
+
let logged_in_sdk =
|
|
326
|
+
tutasdk::Sdk::new(base_url, Arc::new(rest_client), Arc::new(file_client))
|
|
327
|
+
.login(tuta_credentials.into())
|
|
328
|
+
.await
|
|
329
|
+
.map_err(|e| {
|
|
330
|
+
log::error!("Can not login to sdk: {e:?}");
|
|
331
|
+
PreparationError::LoginError
|
|
332
|
+
})?;
|
|
326
333
|
|
|
327
334
|
Ok(logged_in_sdk)
|
|
328
335
|
}
|
|
@@ -366,7 +373,7 @@ impl Importer {
|
|
|
366
373
|
fs_email_client: FileImport::new(eml_files_to_import),
|
|
367
374
|
};
|
|
368
375
|
|
|
369
|
-
let logged_in_sdk = Self::create_sdk(tuta_credentials).await?;
|
|
376
|
+
let logged_in_sdk = Self::create_sdk(&config_directory, tuta_credentials).await?;
|
|
370
377
|
let remote_import_state = logged_in_sdk
|
|
371
378
|
.mail_facade()
|
|
372
379
|
.get_crypto_entity_client()
|
|
@@ -775,6 +782,21 @@ pub mod tests {
|
|
|
775
782
|
assert_eq!(remote_state.successfulMails, 1);
|
|
776
783
|
}
|
|
777
784
|
|
|
785
|
+
#[cfg_attr(
|
|
786
|
+
not(feature = "test-with-local-http-server"),
|
|
787
|
+
ignore = "require local http server."
|
|
788
|
+
)]
|
|
789
|
+
#[tokio::test]
|
|
790
|
+
async fn can_import_single_eml_file_with_invalid_date() {
|
|
791
|
+
let importer = init_file_importer(vec!["brokendate.eml"]).await;
|
|
792
|
+
importer.start_stateful_import().await.unwrap();
|
|
793
|
+
|
|
794
|
+
let remote_state = importer.essentials.load_remote_state().await.unwrap();
|
|
795
|
+
assert_eq!(remote_state.status, ImportStatus::Finished as i64);
|
|
796
|
+
assert_eq!(remote_state.failedMails, 0);
|
|
797
|
+
assert_eq!(remote_state.successfulMails, 1);
|
|
798
|
+
}
|
|
799
|
+
|
|
778
800
|
#[test]
|
|
779
801
|
fn max_request_size_in_test_is_different() {
|
|
780
802
|
assert_eq!(1024 * 5, MAX_REQUEST_SIZE);
|
package/src/importer_api.rs
CHANGED
|
@@ -238,7 +238,7 @@ impl ImporterApi {
|
|
|
238
238
|
let import_directory =
|
|
239
239
|
FileImport::prepare_file_import(config_directory, mailbox_id, source_paths)?;
|
|
240
240
|
|
|
241
|
-
let logged_in_sdk = Importer::create_sdk(tuta_credentials).await?;
|
|
241
|
+
let logged_in_sdk = Importer::create_sdk(config_directory, tuta_credentials).await?;
|
|
242
242
|
Importer::create_new_file_importer(
|
|
243
243
|
logged_in_sdk,
|
|
244
244
|
target_owner_group,
|
package/src/test_utils.rs
CHANGED
|
@@ -3,6 +3,7 @@ use crate::importer::Importer;
|
|
|
3
3
|
use std::fs;
|
|
4
4
|
use std::path::PathBuf;
|
|
5
5
|
use std::sync::{Arc, Mutex};
|
|
6
|
+
use tutasdk::bindings::test_file_client::TestFileClient;
|
|
6
7
|
use tutasdk::entities::generated::tutanota::MailFolder;
|
|
7
8
|
use tutasdk::folder_system::MailSetKind;
|
|
8
9
|
use tutasdk::net::native_rest_client::NativeRestClient;
|
|
@@ -48,6 +49,7 @@ pub async fn init_file_importer(source_paths: Vec<&str>) -> Importer {
|
|
|
48
49
|
let logged_in_sdk = Sdk::new(
|
|
49
50
|
"http://localhost:9000".to_string(),
|
|
50
51
|
Arc::new(NativeRestClient::try_new().unwrap()),
|
|
52
|
+
Arc::new(TestFileClient::default()),
|
|
51
53
|
)
|
|
52
54
|
.create_session(IMPORTED_MAIL_ADDRESS, IMPORTED_MAIL_ADDRESS_PASSKEY)
|
|
53
55
|
.await
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Content-Type: text/plain; charset=iso-8859-1; format=flowed
|
|
2
|
+
Content-Transfer-Encoding: 8bit
|
|
3
|
+
To: sorry@noemail.eu
|
|
4
|
+
From: noreply@noemail.eu
|
|
5
|
+
Date: Fri, Dec 14 2001 16:05:48 -0800
|
|
6
|
+
MIME-Version: 1.0
|
|
7
|
+
Subject: Broken date
|
|
8
|
+
|
|
9
|
+
This mail contains a date header that doesn't conform to the standard.
|