Skip to main content

max / audiofiles

Fix trial expiry: reject unparseable dates, check remaining days Return 0 days remaining (expired) instead of 30 when the trial date cannot be parsed. Check trial_days_remaining > 0 before granting access, so expired trials no longer bypass the license gate. Wire unsafe_mode DB config into browser on vault switch/create. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-04-26 19:40 UTC
Commit: 60f1d015859bff5ec70b7e891f3719f4a586c0fe
Parent: 8139585
2 files changed, +22 insertions, -5 deletions
@@ -216,7 +216,7 @@ pub fn save_trial(config_dir: &Path, state: &TrialState) -> io::Result<()> {
216 216 /// Calculate days remaining in the trial (goes negative after day 30).
217 217 pub fn trial_days_remaining(trial: &TrialState) -> i64 {
218 218 let Ok(first) = chrono::DateTime::parse_from_rfc3339(&trial.first_launch_date) else {
219 - return 30;
219 + return 0;
220 220 };
221 221 let elapsed = chrono::Utc::now().signed_duration_since(first);
222 222 30 - elapsed.num_days()
@@ -482,9 +482,10 @@ impl AudioFilesApp {
482 482 }
483 483 };
484 484
485 - let screen = resolve_initial_screen(&vault_registry, &license_status, trial_state.is_some());
485 + let has_active_trial = trial_state.as_ref().is_some_and(|t| license::trial_days_remaining(t) > 0);
486 + let screen = resolve_initial_screen(&vault_registry, &license_status, has_active_trial);
486 487
487 - let licensed_or_trial = matches!(&license_status, license::LicenseStatus::Licensed(_)) || trial_state.is_some();
488 + let licensed_or_trial = matches!(&license_status, license::LicenseStatus::Licensed(_)) || has_active_trial;
488 489
489 490 let (data_dir, browser, error, sync_manager, license_cache) =
490 491 match (&vault_registry, &license_status) {
@@ -497,7 +498,7 @@ impl AudioFilesApp {
497 498 (data_dir, browser, error, sync_manager, Some(cache.clone()))
498 499 }
499 500 // Registry exists, unlicensed but in trial → open the active vault (no sync)
500 - (Some(reg), license::LicenseStatus::Unlicensed) if trial_state.is_some() => {
501 + (Some(reg), license::LicenseStatus::Unlicensed) if has_active_trial => {
501 502 let data_dir = reg.active.clone();
502 503 let _ = std::fs::create_dir_all(&data_dir);
503 504 let (browser, error) = init_browser(&data_dir, shared.clone(), &vault_name_for_path(reg, &data_dir));
@@ -567,6 +568,16 @@ impl AudioFilesApp {
567 568 self.screen = AppScreen::Browser;
568 569 self.sync_vault_list_to_browser();
569 570 self.sync_license_to_browser();
571 + // Read unsafe_mode from the vault's DB and run integrity check
572 + if let Some(ref mut browser) = self.browser {
573 + browser.settings.is_unsafe_mode = browser
574 + .backend
575 + .get_config("unsafe_mode")
576 + .ok()
577 + .flatten()
578 + .is_some_and(|v| v == "1");
579 + browser.check_unsafe_integrity();
580 + }
570 581 }
571 582
572 583 /// Push license info into the browser settings state.
@@ -1151,10 +1162,16 @@ impl AudioFilesApp {
1151 1162 self.switch_vault(path);
1152 1163 return;
1153 1164 }
1154 - VaultAction::CreateVault { name, path } => {
1165 + VaultAction::CreateVault { name, path, unsafe_mode } => {
1155 1166 let switch_path = path.clone();
1156 1167 if self.with_vault_registry(|reg| vault::create_vault(reg, &name, &path)) {
1157 1168 self.switch_vault(switch_path);
1169 + if unsafe_mode {
1170 + if let Some(ref mut browser) = self.browser {
1171 + let _ = browser.backend.set_config("unsafe_mode", "1");
1172 + browser.settings.is_unsafe_mode = true;
1173 + }
1174 + }
1158 1175 return;
1159 1176 }
1160 1177 }