Skip to main content

lb_rs/
lib.rs

1//! The library that underlies most things [lockbook](https://lockbook.net).
2//!
3//! All lockbook clients
4//! (iOS, linux, etc) rely on this library to perform cryptography, offline edits, and
5//! reconciliation of data between our server, other clients, and other devices.
6//!
7//! Our server relies on this library for checking signatures, and validating whether tree
8//! modifications are valid / authorized.
9//!
10//! - Most clients / integrators will be interested in the functions attached to the [Lb] struct.
11//!   See the [service] module for evolving this functionality.
12//! - The [model] module contains the specification of our data structures and contracts between
13//!   components.
14//! - The [blocking] module contains blocking variants of all [Lb] functions for consumers without
15//!   async runtimes.
16//! - The [io] module contains interactions with disk and network.
17
18#[macro_use]
19extern crate tracing;
20
21pub mod blocking;
22pub mod io;
23pub mod ipc;
24pub mod macros;
25pub mod model;
26pub mod service;
27pub mod subscribers;
28#[cfg(target_family = "wasm")]
29pub mod wasm;
30
31#[derive(Clone)]
32pub struct Lb {
33    pub local: Arc<OnceLock<LocalLb>>,
34    pub remote: Option<Arc<RemoteLb>>,
35    pub config: Config,
36}
37
38#[derive(Clone)]
39pub struct LocalLb {
40    pub config: Config,
41    pub user_last_seen: Arc<RwLock<Instant>>,
42    pub keychain: Keychain,
43    pub db: LbDb,
44    pub docs: AsyncDocs,
45    pub client: Network,
46    pub events: EventSubs,
47    pub status: StatusUpdater,
48    pub syncer: Syncer,
49    #[cfg(not(target_family = "wasm"))]
50    pub search: SearchIndex,
51}
52
53impl LocalLb {
54    #[instrument(level = "info", skip_all, err(Debug))]
55    pub async fn init(config: Config) -> LbResult<Self> {
56        let docs = AsyncDocs::from(&config);
57        let db_cfg = db_rs::Config::in_folder(&config.writeable_path);
58        // an flock held across iOS suspend causes 0xdead10cc, iOS has no IPC yet
59        #[cfg(target_os = "ios")]
60        let db_cfg = db_rs::Config { fs_locks: false, ..db_cfg };
61        let db = CoreDb::init(db_cfg).map_err(|err| LbErrKind::Unexpected(format!("{err:#?}")))?;
62        let keychain = Keychain::from(db.account.get());
63        let db = Arc::new(RwLock::new(db));
64        let client = Network::default();
65        #[cfg(not(target_family = "wasm"))]
66        let search = SearchIndex::default();
67
68        let status = StatusUpdater::default();
69        let syncer = Default::default();
70        let events = EventSubs::default();
71        let user_last_seen = Arc::new(RwLock::new(Instant::now()));
72
73        let result = Self {
74            config,
75            keychain,
76            db,
77            docs,
78            client,
79            syncer,
80            events,
81            status,
82            user_last_seen,
83            #[cfg(not(target_family = "wasm"))]
84            search,
85        };
86
87        #[cfg(not(target_family = "wasm"))]
88        {
89            result.setup_syncer();
90            result.setup_search();
91            result.setup_status().await?;
92        }
93
94        Ok(result)
95    }
96}
97
98impl Lb {
99    pub async fn init(config: Config) -> LbResult<Self> {
100        let local: Arc<OnceLock<LocalLb>> = Arc::new(OnceLock::new());
101        let init_err = match LocalLb::init(config.clone()).await {
102            Ok(loc) => {
103                logging::init(&loc.config)?;
104                ipc::spawn_host(loc.clone());
105                let _ = local.set(loc);
106                return Ok(Self { local, remote: None, config });
107            }
108            Err(err) => err,
109        };
110        if let Some(remote) = ipc::connect_guest(&config).await {
111            return Ok(Self { local, remote: Some(remote), config });
112        }
113        Err(init_err)
114    }
115}
116
117impl Lb {
118    pub async fn create_account(
119        &self, username: &str, api_url: &str, welcome_doc: bool,
120    ) -> LbResult<Account> {
121        if let Some(local) = self.local.get() {
122            return local.create_account(username, api_url, welcome_doc).await;
123        }
124        let account = self
125            .call::<Account>(Request::CreateAccount {
126                username: username.to_string(),
127                api_url: api_url.to_string(),
128                welcome_doc,
129            })
130            .await?;
131        self.cache_account_on_remote(&account);
132        Ok(account)
133    }
134
135    pub async fn import_account(&self, key: &str, api_url: Option<&str>) -> LbResult<Account> {
136        if let Some(local) = self.local.get() {
137            return local.import_account(key, api_url).await;
138        }
139        let account = self
140            .call::<Account>(Request::ImportAccount {
141                key: key.to_string(),
142                api_url: api_url.map(|s| s.to_string()),
143            })
144            .await?;
145        self.cache_account_on_remote(&account);
146        Ok(account)
147    }
148
149    pub async fn import_account_private_key_v1(&self, account: Account) -> LbResult<Account> {
150        if let Some(local) = self.local.get() {
151            return local.import_account_private_key_v1(account).await;
152        }
153        let account = self
154            .call::<Account>(Request::ImportAccountPrivateKeyV1 { account })
155            .await?;
156        self.cache_account_on_remote(&account);
157        Ok(account)
158    }
159
160    pub async fn import_account_phrase(
161        &self, phrase: [&str; 24], api_url: &str,
162    ) -> LbResult<Account> {
163        if let Some(local) = self.local.get() {
164            return local.import_account_phrase(phrase, api_url).await;
165        }
166        let account = self
167            .call::<Account>(Request::ImportAccountPhrase {
168                phrase: phrase.iter().map(|s| s.to_string()).collect(),
169                api_url: api_url.to_string(),
170            })
171            .await?;
172        self.cache_account_on_remote(&account);
173        Ok(account)
174    }
175
176    fn cache_account_on_remote(&self, account: &Account) {
177        if let Some(remote) = &self.remote {
178            remote.cache_account(account.clone());
179        }
180    }
181
182    pub async fn delete_account(&self) -> LbResult<()> {
183        if let Some(local) = self.local.get() {
184            return local.delete_account().await;
185        }
186        self.call(Request::DeleteAccount).await
187    }
188
189    pub fn get_account(&self) -> LbResult<Account> {
190        if let Some(local) = self.local.get() {
191            return local.get_account().cloned();
192        }
193        self.remote
194            .as_ref()
195            .expect("get_account: remote must be set when local is unset")
196            .get_account()
197            .cloned()
198    }
199
200    pub async fn suggested_docs(&self, settings: RankingWeights) -> LbResult<Vec<Uuid>> {
201        if let Some(local) = self.local.get() {
202            return local.suggested_docs(settings).await;
203        }
204        self.call(Request::SuggestedDocs { settings }).await
205    }
206
207    pub async fn clear_suggested(&self) -> LbResult<()> {
208        if let Some(local) = self.local.get() {
209            return local.clear_suggested().await;
210        }
211        self.call(Request::ClearSuggested).await
212    }
213
214    pub async fn clear_suggested_id(&self, id: Uuid) -> LbResult<()> {
215        if let Some(local) = self.local.get() {
216            return local.clear_suggested_id(id).await;
217        }
218        self.call(Request::ClearSuggestedId { id }).await
219    }
220
221    pub fn app_foregrounded(&self) {
222        if let Some(local) = self.local.get() {
223            local.app_foregrounded();
224            return;
225        }
226        if let Some(remote) = &self.remote {
227            let r = Arc::clone(remote);
228            tokio::spawn(async move {
229                let _ = r.try_call::<()>(Request::AppForegrounded).await;
230            });
231        }
232    }
233
234    pub async fn disappear_account(&self, username: &str) -> LbResult<()> {
235        if let Some(local) = self.local.get() {
236            return local.disappear_account(username).await;
237        }
238        self.call(Request::DisappearAccount { username: username.to_string() })
239            .await
240    }
241
242    pub async fn disappear_file(&self, id: Uuid) -> LbResult<()> {
243        if let Some(local) = self.local.get() {
244            return local.disappear_file(id).await;
245        }
246        self.call(Request::DisappearFile { id }).await
247    }
248
249    pub async fn list_users(&self, filter: Option<AccountFilter>) -> LbResult<Vec<Username>> {
250        if let Some(local) = self.local.get() {
251            return local.list_users(filter).await;
252        }
253        self.call(Request::ListUsers { filter }).await
254    }
255
256    pub async fn get_account_info(&self, identifier: AccountIdentifier) -> LbResult<AccountInfo> {
257        if let Some(local) = self.local.get() {
258            return local.get_account_info(identifier).await;
259        }
260        self.call(Request::GetAccountInfo { identifier }).await
261    }
262
263    pub async fn validate_account(&self, username: &str) -> LbResult<AdminValidateAccount> {
264        if let Some(local) = self.local.get() {
265            return local.validate_account(username).await;
266        }
267        self.call(Request::AdminValidateAccount { username: username.to_string() })
268            .await
269    }
270
271    pub async fn validate_server(&self) -> LbResult<AdminValidateServer> {
272        if let Some(local) = self.local.get() {
273            return local.validate_server().await;
274        }
275        self.call(Request::AdminValidateServer).await
276    }
277
278    pub async fn file_info(&self, id: Uuid) -> LbResult<AdminFileInfoResponse> {
279        if let Some(local) = self.local.get() {
280            return local.file_info(id).await;
281        }
282        self.call(Request::AdminFileInfo { id }).await
283    }
284
285    pub async fn rebuild_index(&self, index: ServerIndex) -> LbResult<()> {
286        if let Some(local) = self.local.get() {
287            return local.rebuild_index(index).await;
288        }
289        self.call(Request::RebuildIndex { index }).await
290    }
291
292    pub async fn set_user_tier(&self, username: &str, info: AdminSetUserTierInfo) -> LbResult<()> {
293        if let Some(local) = self.local.get() {
294            return local.set_user_tier(username, info).await;
295        }
296        self.call(Request::SetUserTier { username: username.to_string(), info })
297            .await
298    }
299
300    pub async fn upgrade_account_stripe(&self, account_tier: StripeAccountTier) -> LbResult<()> {
301        if let Some(local) = self.local.get() {
302            return local.upgrade_account_stripe(account_tier).await;
303        }
304        self.call(Request::UpgradeAccountStripe { account_tier })
305            .await
306    }
307
308    pub async fn upgrade_account_google_play(
309        &self, purchase_token: &str, account_id: &str,
310    ) -> LbResult<()> {
311        if let Some(local) = self.local.get() {
312            return local
313                .upgrade_account_google_play(purchase_token, account_id)
314                .await;
315        }
316        self.call(Request::UpgradeAccountGooglePlay {
317            purchase_token: purchase_token.to_string(),
318            account_id: account_id.to_string(),
319        })
320        .await
321    }
322
323    pub async fn upgrade_account_app_store(
324        &self, original_transaction_id: String, app_account_token: String,
325    ) -> LbResult<()> {
326        if let Some(local) = self.local.get() {
327            return local
328                .upgrade_account_app_store(original_transaction_id, app_account_token)
329                .await;
330        }
331        self.call(Request::UpgradeAccountAppStore { original_transaction_id, app_account_token })
332            .await
333    }
334
335    pub async fn cancel_subscription(&self) -> LbResult<()> {
336        if let Some(local) = self.local.get() {
337            return local.cancel_subscription().await;
338        }
339        self.call(Request::CancelSubscription).await
340    }
341
342    pub async fn get_subscription_info(&self) -> LbResult<Option<SubscriptionInfo>> {
343        if let Some(local) = self.local.get() {
344            return local.get_subscription_info().await;
345        }
346        self.call(Request::GetSubscriptionInfo).await
347    }
348
349    #[cfg(not(target_family = "wasm"))]
350    pub async fn recent_panic(&self) -> LbResult<bool> {
351        if let Some(local) = self.local.get() {
352            return local.recent_panic().await;
353        }
354        self.call(Request::RecentPanic).await
355    }
356
357    #[cfg(not(target_family = "wasm"))]
358    pub async fn write_panic_to_file(&self, error_header: String, bt: String) -> LbResult<String> {
359        if let Some(local) = self.local.get() {
360            return local.write_panic_to_file(error_header, bt).await;
361        }
362        self.call(Request::WritePanicToFile { error_header, bt })
363            .await
364    }
365
366    #[cfg(not(target_family = "wasm"))]
367    pub async fn debug_info(&self, os_info: String, check_docs: bool) -> LbResult<DebugInfo> {
368        if let Some(local) = self.local.get() {
369            return local.debug_info(os_info, check_docs).await;
370        }
371        self.call(Request::DebugInfo { os_info, check_docs }).await
372    }
373
374    pub async fn read_document(
375        &self, id: Uuid, user_activity: bool,
376    ) -> LbResult<DecryptedDocument> {
377        if let Some(local) = self.local.get() {
378            return local.read_document(id, user_activity).await;
379        }
380        self.call(Request::ReadDocument { id, user_activity }).await
381    }
382
383    pub async fn write_document(&self, id: Uuid, content: &[u8]) -> LbResult<()> {
384        if let Some(local) = self.local.get() {
385            return local.write_document(id, content).await;
386        }
387        self.call(Request::WriteDocument { id, content: content.to_vec() })
388            .await
389    }
390
391    pub async fn read_document_with_hmac(
392        &self, id: Uuid, user_activity: bool,
393    ) -> LbResult<(Option<DocumentHmac>, DecryptedDocument)> {
394        if let Some(local) = self.local.get() {
395            return local.read_document_with_hmac(id, user_activity).await;
396        }
397        self.call(Request::ReadDocumentWithHmac { id, user_activity })
398            .await
399    }
400
401    pub async fn safe_write(
402        &self, id: Uuid, old_hmac: Option<DocumentHmac>, content: Vec<u8>,
403    ) -> LbResult<DocumentHmac> {
404        if let Some(local) = self.local.get() {
405            return local.safe_write(id, old_hmac, content).await;
406        }
407        self.call(Request::SafeWrite { id, old_hmac, content })
408            .await
409    }
410
411    pub async fn create_file(
412        &self, name: &str, parent: &Uuid, file_type: FileType,
413    ) -> LbResult<File> {
414        if let Some(local) = self.local.get() {
415            return local.create_file(name, parent, file_type).await;
416        }
417        self.call::<File>(Request::CreateFile {
418            name: name.to_string(),
419            parent: *parent,
420            file_type,
421        })
422        .await
423    }
424
425    pub async fn rename_file(&self, id: &Uuid, new_name: &str) -> LbResult<()> {
426        if let Some(local) = self.local.get() {
427            return local.rename_file(id, new_name).await;
428        }
429        self.call(Request::RenameFile { id: *id, new_name: new_name.to_string() })
430            .await
431    }
432
433    pub async fn move_file(&self, id: &Uuid, new_parent: &Uuid) -> LbResult<()> {
434        if let Some(local) = self.local.get() {
435            return local.move_file(id, new_parent).await;
436        }
437        self.call(Request::MoveFile { id: *id, new_parent: *new_parent })
438            .await
439    }
440
441    pub async fn delete(&self, id: &Uuid) -> LbResult<()> {
442        if let Some(local) = self.local.get() {
443            return local.delete(id).await;
444        }
445        self.call(Request::Delete { id: *id }).await
446    }
447
448    pub async fn root(&self) -> LbResult<File> {
449        if let Some(local) = self.local.get() {
450            return local.root().await;
451        }
452        self.call(Request::Root).await
453    }
454
455    pub async fn list_metadatas(&self) -> LbResult<Vec<File>> {
456        if let Some(local) = self.local.get() {
457            return local.list_metadatas().await;
458        }
459        self.call(Request::ListMetadatas).await
460    }
461
462    pub async fn get_children(&self, id: &Uuid) -> LbResult<Vec<File>> {
463        if let Some(local) = self.local.get() {
464            return local.get_children(id).await;
465        }
466        self.call(Request::GetChildren { id: *id }).await
467    }
468
469    pub async fn get_and_get_children_recursively(&self, id: &Uuid) -> LbResult<Vec<File>> {
470        if let Some(local) = self.local.get() {
471            return local.get_and_get_children_recursively(id).await;
472        }
473        self.call(Request::GetAndGetChildrenRecursively { id: *id })
474            .await
475    }
476
477    pub async fn get_file_by_id(&self, id: Uuid) -> LbResult<File> {
478        if let Some(local) = self.local.get() {
479            return local.get_file_by_id(id).await;
480        }
481        self.call(Request::GetFileById { id }).await
482    }
483
484    pub async fn get_file_link_url(&self, id: Uuid) -> LbResult<String> {
485        if let Some(local) = self.local.get() {
486            return local.get_file_link_url(id).await;
487        }
488        self.call(Request::GetFileLinkUrl { id }).await
489    }
490
491    pub async fn local_changes(&self) -> Vec<Uuid> {
492        if let Some(local) = self.local.get() {
493            return local.local_changes().await;
494        }
495        self.call::<_>(Request::LocalChanges)
496            .await
497            .unwrap_or_default()
498    }
499
500    pub async fn test_repo_integrity(&self, check_docs: bool) -> LbResult<Vec<Warning>> {
501        if let Some(local) = self.local.get() {
502            return local.test_repo_integrity(check_docs).await;
503        }
504        self.call(Request::TestRepoIntegrity { check_docs }).await
505    }
506
507    pub async fn create_link_at_path(&self, path: &str, target_id: Uuid) -> LbResult<File> {
508        if let Some(local) = self.local.get() {
509            return local.create_link_at_path(path, target_id).await;
510        }
511        self.call(Request::CreateLinkAtPath { path: path.to_string(), target_id })
512            .await
513    }
514
515    pub async fn create_at_path(&self, path: &str) -> LbResult<File> {
516        if let Some(local) = self.local.get() {
517            return local.create_at_path(path).await;
518        }
519        self.call(Request::CreateAtPath { path: path.to_string() })
520            .await
521    }
522
523    pub async fn get_by_path(&self, path: &str) -> LbResult<File> {
524        if let Some(local) = self.local.get() {
525            return local.get_by_path(path).await;
526        }
527        self.call(Request::GetByPath { path: path.to_string() })
528            .await
529    }
530
531    pub async fn get_path_by_id(&self, id: Uuid) -> LbResult<String> {
532        if let Some(local) = self.local.get() {
533            return local.get_path_by_id(id).await;
534        }
535        self.call(Request::GetPathById { id }).await
536    }
537
538    pub async fn list_paths(&self, filter: Option<Filter>) -> LbResult<Vec<String>> {
539        if let Some(local) = self.local.get() {
540            return local.list_paths(filter).await;
541        }
542        self.call(Request::ListPaths { filter }).await
543    }
544
545    pub async fn list_paths_with_ids(
546        &self, filter: Option<Filter>,
547    ) -> LbResult<Vec<(Uuid, String)>> {
548        if let Some(local) = self.local.get() {
549            return local.list_paths_with_ids(filter).await;
550        }
551        self.call(Request::ListPathsWithIds { filter }).await
552    }
553
554    pub async fn share_file(&self, id: Uuid, username: &str, mode: ShareMode) -> LbResult<()> {
555        if let Some(local) = self.local.get() {
556            return local.share_file(id, username, mode).await;
557        }
558        self.call(Request::ShareFile { id, username: username.to_string(), mode })
559            .await
560    }
561
562    pub async fn get_pending_shares(&self) -> LbResult<Vec<File>> {
563        if let Some(local) = self.local.get() {
564            return local.get_pending_shares().await;
565        }
566        self.call(Request::GetPendingShares).await
567    }
568
569    pub async fn get_pending_share_files(&self) -> LbResult<Vec<File>> {
570        if let Some(local) = self.local.get() {
571            return local.get_pending_share_files().await;
572        }
573        self.call(Request::GetPendingShareFiles).await
574    }
575
576    pub async fn known_usernames(&self) -> LbResult<Vec<String>> {
577        if let Some(local) = self.local.get() {
578            return local.known_usernames().await;
579        }
580        self.call(Request::KnownUsernames).await
581    }
582
583    pub async fn reject_share(&self, id: &Uuid) -> LbResult<()> {
584        if let Some(local) = self.local.get() {
585            return local.reject_share(id).await;
586        }
587        self.call(Request::RejectShare { id: *id }).await
588    }
589
590    pub async fn pin_file(&self, id: Uuid) -> LbResult<()> {
591        if let Some(local) = self.local.get() {
592            return local.pin_file(id).await;
593        }
594        self.call(Request::PinFile { id }).await
595    }
596
597    pub async fn unpin_file(&self, id: Uuid) -> LbResult<()> {
598        if let Some(local) = self.local.get() {
599            return local.unpin_file(id).await;
600        }
601        self.call(Request::UnpinFile { id }).await
602    }
603
604    pub async fn list_pinned(&self) -> LbResult<Vec<Uuid>> {
605        if let Some(local) = self.local.get() {
606            return local.list_pinned().await;
607        }
608        self.call(Request::ListPinned).await
609    }
610
611    pub async fn get_usage(&self) -> LbResult<UsageMetrics> {
612        if let Some(local) = self.local.get() {
613            return local.get_usage().await;
614        }
615        self.call(Request::GetUsage).await
616    }
617
618    pub async fn sync(&self) -> LbResult<()> {
619        if let Some(local) = self.local.get() {
620            return local.sync().await;
621        }
622        self.call(Request::Sync).await
623    }
624
625    pub async fn status(&self) -> Status {
626        if let Some(local) = self.local.get() {
627            return local.status().await;
628        }
629        self.call::<_>(Request::Status).await.unwrap_or_default()
630    }
631
632    pub async fn get_last_synced(&self) -> LbResult<i64> {
633        if let Some(local) = self.local.get() {
634            return local.get_last_synced().await;
635        }
636        self.call(Request::GetLastSynced).await
637    }
638
639    pub async fn get_last_synced_human(&self) -> LbResult<String> {
640        if let Some(local) = self.local.get() {
641            return local.get_last_synced_human().await;
642        }
643        self.call(Request::GetLastSyncedHuman).await
644    }
645
646    pub fn config(&self) -> &Config {
647        &self.config
648    }
649
650    pub fn subscribe(&self) -> tokio::sync::broadcast::Receiver<service::events::Event> {
651        if let Some(local) = self.local.get() {
652            return local.subscribe();
653        }
654        self.remote
655            .as_ref()
656            .expect("subscribe: remote must be set when local is unset")
657            .subscribe()
658    }
659
660    pub fn get_timestamp_human_string(&self, timestamp: i64) -> String {
661        use basic_human_duration::ChronoHumanDuration;
662        if timestamp != 0 {
663            time::Duration::milliseconds(crate::model::clock::get_time().0 - timestamp)
664                .format_human()
665                .to_string()
666        } else {
667            "never".to_string()
668        }
669    }
670
671    #[cfg(not(target_family = "wasm"))]
672    pub async fn search(&self, input: &str, cfg: SearchConfig) -> LbResult<Vec<SearchResult>> {
673        if let Some(local) = self.local.get() {
674            return local.search(input, cfg).await;
675        }
676        self.call(Request::Search { input: input.to_string(), cfg })
677            .await
678    }
679
680    #[cfg(not(target_family = "wasm"))]
681    pub async fn build_index(&self) -> LbResult<()> {
682        if let Some(local) = self.local.get() {
683            return local.build_index().await;
684        }
685        self.call(Request::BuildIndex).await
686    }
687
688    #[cfg(not(target_family = "wasm"))]
689    pub async fn reload_search_index(&self) -> LbResult<()> {
690        if let Some(local) = self.local.get() {
691            return local.reload_search_index();
692        }
693        self.call(Request::ReloadSearchIndex).await
694    }
695}
696pub fn get_code_version() -> &'static str {
697    env!("CARGO_PKG_VERSION")
698}
699
700pub static DEFAULT_API_LOCATION: &str = "https://app.lockbook.net";
701pub static CORE_CODE_VERSION: &str = env!("CARGO_PKG_VERSION");
702
703use crate::io::CoreDb;
704use crate::ipc::client::RemoteLb;
705use crate::subscribers::syncer::Syncer;
706use db_rs::Db;
707#[cfg(not(target_family = "wasm"))]
708use subscribers::search::SearchIndex;
709
710use crate::service::logging;
711use io::LbDb;
712use io::docs::AsyncDocs;
713use io::network::Network;
714use model::core_config::Config;
715pub use model::errors::{LbErrKind, LbResult};
716use service::events::EventSubs;
717use service::keychain::Keychain;
718use std::sync::{Arc, OnceLock};
719use subscribers::status::StatusUpdater;
720use tokio::sync::RwLock;
721pub use uuid::Uuid;
722use web_time::Instant;
723
724use crate::ipc::protocol::Request;
725use crate::model::account::{Account, Username};
726use crate::model::api::{
727    AccountFilter, AccountIdentifier, AccountInfo, AdminFileInfoResponse, AdminSetUserTierInfo,
728    AdminValidateAccount, AdminValidateServer, ServerIndex, StripeAccountTier, SubscriptionInfo,
729};
730use crate::model::crypto::DecryptedDocument;
731use crate::model::errors::Warning;
732use crate::model::file::{File, ShareMode};
733use crate::model::file_metadata::{DocumentHmac, FileType};
734use crate::model::path_ops::Filter;
735use crate::service::activity::RankingWeights;
736#[cfg(not(target_family = "wasm"))]
737use crate::service::debug::DebugInfo;
738use crate::service::usage::UsageMetrics;
739#[cfg(not(target_family = "wasm"))]
740use crate::subscribers::search::{SearchConfig, SearchResult};
741use crate::subscribers::status::Status;