fix(magic): robust device parsing, dashboard only protects current device

This commit is contained in:
chahinebrini 2026-06-17 02:29:35 +02:00
parent 37f3173539
commit 026c319b30
2 changed files with 23 additions and 40 deletions

View File

@ -86,12 +86,11 @@
<div class="w-16 h-16 mx-auto rounded-2xl bg-blue-50 flex items-center justify-center mb-4"> <div class="w-16 h-16 mx-auto rounded-2xl bg-blue-50 flex items-center justify-center mb-4">
<UIcon name="i-heroicons-shield-exclamation" class="w-8 h-8 text-[var(--rebreak-primary)]" /> <UIcon name="i-heroicons-shield-exclamation" class="w-8 h-8 text-[var(--rebreak-primary)]" />
</div> </div>
<h3 class="text-lg font-bold text-gray-900">Dieses Gerät ist nicht registriert</h3> <h3 class="text-lg font-bold text-gray-900">Dieses Gerät ist nicht geschützt</h3>
<p class="text-sm text-gray-500 mt-1 mb-4">Füge es hinzu, um den Schutz zu aktivieren.</p> <p class="text-sm text-gray-500 mt-1 mb-4">Aktiviere den Schutz für das Gerät, auf dem Magic läuft.</p>
<div class="flex justify-center gap-3"> <UButton color="primary" icon="i-heroicons-shield-check" to="/desktop-enroll">
<UButton color="primary" icon="i-heroicons-device-phone-mobile" to="/detect">iPhone / iPad</UButton> Dieses Gerät schützen
<UButton color="neutral" variant="soft" icon="i-heroicons-computer-desktop" to="/desktop-enroll">Diesen Computer</UButton> </UButton>
</div>
</div> </div>
</section> </section>
@ -133,29 +132,6 @@
</div> </div>
</section> </section>
<!-- Add device shortcuts -->
<section class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<UButton
color="primary"
variant="soft"
size="lg"
block
icon="i-heroicons-device-phone-mobile"
to="/detect"
>
iPhone / iPad hinzufügen
</UButton>
<UButton
color="neutral"
variant="soft"
size="lg"
block
icon="i-heroicons-computer-desktop"
to="/desktop-enroll"
>
Diesen Computer schützen
</UButton>
</section>
</div> </div>
<DeviceDetailSheet <DeviceDetailSheet

View File

@ -55,13 +55,18 @@ pub struct MagicDeviceInfo {
pub release_requested_at: Option<String>, pub release_requested_at: Option<String>,
#[serde(rename = "releaseAvailableAt")] #[serde(rename = "releaseAvailableAt")]
pub release_available_at: Option<String>, pub release_available_at: Option<String>,
#[serde(rename = "cooldownUntil")] #[serde(default, rename = "cooldownUntil")]
pub cooldown_until: Option<String>, pub cooldown_until: Option<String>,
#[serde(default = "default_active_status")]
pub status: String, pub status: String,
#[serde(rename = "lastSeenAt")] #[serde(default, rename = "lastSeenAt")]
pub last_seen_at: Option<String>, pub last_seen_at: Option<String>,
} }
fn default_active_status() -> String {
"active".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatusResponse { pub struct StatusResponse {
pub active: bool, pub active: bool,
@ -338,17 +343,19 @@ impl MagicApiClient {
response: reqwest::Response, response: reqwest::Response,
) -> AppResult<T> { ) -> AppResult<T> {
let status = response.status(); let status = response.status();
if status.is_success() { let body = response
response
.json::<T>()
.await
.map_err(|e| AppError::new(format!("Failed to parse response: {}", e)))
} else {
let text = response
.text() .text()
.await .await
.unwrap_or_else(|_| "Unknown error".to_string()); .unwrap_or_else(|_| "<failed to read body>".to_string());
Err(AppError::new(format!("HTTP {}: {}", status, text))) if status.is_success() {
serde_json::from_str::<T>(&body).map_err(|e| {
AppError::new(format!(
"Failed to parse response: {} | body={}",
e, body
))
})
} else {
Err(AppError::new(format!("HTTP {}: {}", status, body)))
} }
} }
} }