diff --git a/index.html b/index.html
index 8449f5f..8889a1c 100644
--- a/index.html
+++ b/index.html
@@ -74,6 +74,27 @@
let storedAccount = localStorage.getItem("account") || "default";
let userInfo = JSON.parse(localStorage.getItem("userInfo") || "null");
+ // If we have an API key but no userInfo, fetch it from the server
+ if (storedApiKey && !userInfo) {
+ fetch(`${apiBaseUrl}/userinfo`, {
+ headers: { "Authorization": `Bearer ${storedApiKey}` }
+ })
+ .then(response => response.json())
+ .then(userData => {
+ userInfo = {email: userData.email || "Utilisateur connecté"};
+ localStorage.setItem("userInfo", JSON.stringify(userInfo));
+ renderLoginSection();
+ })
+ .catch(e => {
+ console.error("Error fetching user info:", e);
+ // If we can't fetch user info, proceed with rendering
+ renderLoginSection();
+ });
+ } else {
+ // Render the login section normally
+ renderLoginSection();
+ }
+
// Handle the static "abc" key case - removed for security
/*
if (storedApiKey === "abc" && !userInfo) {
@@ -101,41 +122,56 @@
localStorage.setItem("apikey", accessToken);
storedApiKey = accessToken;
- // Get user info from the token
- try {
- // First, try to parse as JWT
- const tokenParts = accessToken.split('.');
- let userData = {};
-
- if (tokenParts.length === 3) {
- // Standard JWT format
- const payload = tokenParts[1];
- if (payload) {
- // Add padding if needed
- const paddedPayload = payload.padEnd(payload.length + (4 - payload.length % 4) % 4, '=');
- const decodedPayload = atob(paddedPayload);
- userData = JSON.parse(decodedPayload);
- }
- } else {
- // Non-JWT token, treat as opaque token
- console.log("Non-JWT token received, using default user info");
- userData = {email: "utilisateur@" + window.location.hostname};
- }
-
+ // Get user info from the userinfo endpoint
+ fetch(`${apiBaseUrl}/userinfo`, {
+ headers: { "Authorization": `Bearer ${accessToken}` }
+ })
+ .then(response => response.json())
+ .then(userData => {
userInfo = {email: userData.email || "Utilisateur connecté"};
localStorage.setItem("userInfo", JSON.stringify(userInfo));
- } catch (e) {
- console.error("Error decoding token:", e);
- // Fallback to a generic user object
- userInfo = {email: "Utilisateur connecté"};
- localStorage.setItem("userInfo", JSON.stringify(userInfo));
- }
+
+ // Update UI
+ renderLoginSection();
+ })
+ .catch(e => {
+ console.error("Error fetching user info:", e);
+ // Fallback to parsing token as JWT
+ try {
+ // First, try to parse as JWT
+ const tokenParts = accessToken.split('.');
+ let userData = {};
+
+ if (tokenParts.length === 3) {
+ // Standard JWT format
+ const payload = tokenParts[1];
+ if (payload) {
+ // Add padding if needed
+ const paddedPayload = payload.padEnd(payload.length + (4 - payload.length % 4) % 4, '=');
+ const decodedPayload = atob(paddedPayload);
+ userData = JSON.parse(decodedPayload);
+ }
+ } else {
+ // Non-JWT token, treat as opaque token
+ console.log("Non-JWT token received, using default user info");
+ userData = {email: "utilisateur@" + window.location.hostname};
+ }
+
+ userInfo = {email: userData.email || "Utilisateur connecté"};
+ localStorage.setItem("userInfo", JSON.stringify(userInfo));
+ } catch (parseError) {
+ console.error("Error decoding token:", parseError);
+ // Fallback to a generic user object
+ userInfo = {email: "Utilisateur connecté"};
+ localStorage.setItem("userInfo", JSON.stringify(userInfo));
+ }
+
+ // Update UI
+ renderLoginSection();
+ });
// Remove token from URL
window.history.replaceState({}, document.title, "/");
-
- // Update UI
- renderLoginSection();
}
function renderLoginSection() {
@@ -153,9 +189,8 @@
eventFilters.style.display = "block";
updateAccountOptions();
- if (storedApiKey) {
- fetchEvents(storedApiKey, storedAccount);
- }
+ // Don't automatically fetch events on page load
+ // Wait for user to explicitly select an account or click fetch
} else {
// User is not logged in
connectedUser.style.display = "none";
@@ -216,15 +251,35 @@
}
accountSelect.innerHTML = '';
+
+ // If no accounts are available, add a default option
+ if (accounts.length === 0) {
+ const option = document.createElement("option");
+ option.value = "default";
+ option.textContent = "Default";
+ accountSelect.appendChild(option);
+ return;
+ }
+
+ // Add all available accounts
accounts.forEach(account => {
const option = document.createElement("option");
option.value = account.name;
option.textContent = account.label;
- if (account.name === storedAccount) {
- option.selected = true;
- }
accountSelect.appendChild(option);
});
+
+ // Select the stored account if it exists, otherwise select the first account
+ let accountToSelect = storedAccount;
+ if (!accounts.some(account => account.name === storedAccount)) {
+ accountToSelect = accounts[0].name;
+ // Update stored account
+ storedAccount = accountToSelect;
+ localStorage.setItem("account", accountToSelect);
+ }
+
+ // Set the selected account in the dropdown
+ accountSelect.value = accountToSelect;
})
.catch(error => {
console.error("Erreur lors du chargement des comptes:", error);
@@ -268,12 +323,28 @@
return;
}
if (!response.ok) {
- return response.json().then(errorData => {
- console.error("Schedule error response:", errorData);
- throw new Error(`HTTP error! status: ${response.status}, message: ${errorData.detail || 'Unknown error'}`);
+ // Try to parse error response as JSON, but handle plain text as well
+ return response.text().then(errorText => {
+ let errorMessage = 'Unknown error';
+ try {
+ const errorData = JSON.parse(errorText);
+ errorMessage = errorData.detail || errorData.message || errorText;
+ } catch (e) {
+ // If parsing fails, use the raw text
+ errorMessage = errorText || 'Unknown error';
+ }
+ console.error("Schedule error response:", errorText);
+ throw new Error(`HTTP error! status: ${response.status}, message: ${errorMessage}`);
});
}
- return response.json();
+ return response.text().then(text => {
+ try {
+ return JSON.parse(text);
+ } catch (e) {
+ console.error("Invalid JSON response:", text);
+ throw new Error("Le serveur a renvoyé une réponse invalide. Veuillez réessayer.");
+ }
+ });
})
.then(data => {
if (data) {
diff --git a/myice/myice.py b/myice/myice.py
index 4691b58..c838220 100755
--- a/myice/myice.py
+++ b/myice/myice.py
@@ -635,7 +635,16 @@ def refresh_data():
return r.json()
except json.JSONDecodeError:
# If direct parsing fails, try with sanitization
- return json.loads(sanitize_json_response(r.text))
+ sanitized = sanitize_json_response(r.text)
+ try:
+ return json.loads(sanitized)
+ except json.JSONDecodeError:
+ # If sanitization also fails, log the raw response for debugging
+ print(
+ f"Failed to parse response as JSON. Raw response: {r.text[:500]}..."
+ )
+ # Return an empty dict to avoid breaking the API
+ return {}
@app.command("mobile-login")
diff --git a/myice/webapi.py b/myice/webapi.py
index 5dfa24d..350de8e 100644
--- a/myice/webapi.py
+++ b/myice/webapi.py
@@ -276,7 +276,10 @@ async def schedule(
config_section=account
)
except Exception as e:
- raise HTTPException(400, detail=f"Configuration error: {str(e)}")
+ raise HTTPException(
+ 400,
+ detail=f"Configuration error: {str(e)}. Available accounts: isaac, leonard",
+ )
try:
if existing_token:
@@ -296,6 +299,9 @@ async def schedule(
return []
except Exception as e:
print(f"Error fetching schedule: {e}")
+ import traceback
+
+ traceback.print_exc()
# Return empty array instead of throwing an error
return []