Compare commits

...
4 Commits
Author SHA1 Message Date
luzadev b74a0a53ec v1.7.11: fix definitivo BlackHole — ad-hoc codesign del bundle
Causa root: MusicTools.app ha il permesso TCC microfono, ma quando
lancia ffmpeg come subprocess macOS tratta ffmpeg come binario non
firmato distinto -> AVFoundation apre il device senza errore ma
restituisce solo silenzio.

Fix in build_macos.py: dopo PyInstaller + Info.plist, applico
`codesign --force --deep --sign -` ad-hoc su tutto il bundle.
La firma e' "free" (no Developer ID) ma rende l'app un singolo
team coerente per TCC, quindi il permesso del main si propaga
anche a ffmpeg/ffprobe/yt-dlp.
2026-06-09 21:29:30 +02:00
luzadev 415175ec4d v1.7.10: fix registrazione BlackHole muta (device by name)
QuickTime registrava da BlackHole, MusicTools no: il bug era che
list_input_devices passava al record l'index AVFoundation, ma
l'index puo' rinumerarsi tra l'elenco e l'apertura (iPhone in
continuita', Multi-Output Device, hot-plug). Quando ffmpeg apriva
:<index> col numero sbagliato, registrava silenzio dal device
"vero" mappato a quel numero.

Fix: in _list_macos uso il NOME del device come id (es.
"BlackHole 2ch"). ffmpeg AVFoundation accetta sia :<index> sia
:<name> ed il nome e' stabile. Aggiunto campo 'index' solo per
log/diagnostica. Nessun cambio Windows (gia' faceva by-name).
2026-06-09 20:58:51 +02:00
luzadev d8349fb79f v1.7.9: fix permessi microfono macOS (BlackHole non funzionava)
Senza NSMicrophoneUsageDescription nell'Info.plist macOS NEGA
silenziosamente l'accesso al microfono (incluso BlackHole come
dispositivo input) e l'app non compare nemmeno in Impostazioni di
Sistema > Privacy e sicurezza > Microfono, quindi l'utente non puo
nemmeno autorizzarla manualmente.

Aggiunto patch_info_plist() in build_macos.py che dopo PyInstaller
aggiunge via PlistBuddy:
- NSMicrophoneUsageDescription (causa primaria)
- CFBundleIdentifier stabile (com.djluza.musictools)
- LSApplicationCategoryType = music
2026-06-09 20:13:41 +02:00
luzadev 1414c5199c Legal: aggiornati ToS/Refund/Privacy per i 4 piani + Spotify Premium
terms.html:
- §9: aggiunto paragrafo su credenziali Spotify Web API che richiedono
  account Spotify Premium (policy aggiornata da Spotify, non da noi);
  fallback brano singolo non richiede Premium.
- §12: sostituito il vecchio prezzo unico 39,90 € con i 4 piani
  (Basic 2,99 / Pro 5,99 / Premium 9,99 / Annual 49,90), limiti
  giornalieri, regola reset Europe/Rome, rinnovo vs una-tantum.
- §13: chiarito che recesso 14gg vale per il primo acquisto; rinnovi
  mensili interrompibili via disdetta.

refund.html: aggiunte differenze per piano, sezione disdetta dashboard
Lemon Squeezy, disclaimer Spotify.

privacy.html: aggiunti come dati trattati piano/order_id/subscription_id/
contatore download giornaliero (90gg di retention); rimosso riferimento
errato a Cloudflare (legacy).
2026-06-09 20:11:57 +02:00
6 changed files with 146 additions and 19 deletions

No files matched your search

+90
View File
@@ -238,6 +238,8 @@ def run_pyinstaller():
app_path = DIST_DIR / "MusicTools.app" app_path = DIST_DIR / "MusicTools.app"
if app_path.exists(): if app_path.exists():
log(f"Build completata: {app_path}") log(f"Build completata: {app_path}")
patch_info_plist(app_path)
adhoc_codesign(app_path)
# Mostra dimensione # Mostra dimensione
size = sum(f.stat().st_size for f in app_path.rglob("*") if f.is_file()) size = sum(f.stat().st_size for f in app_path.rglob("*") if f.is_file())
log(f"Dimensione: {size / 1024 / 1024:.0f} MB") log(f"Dimensione: {size / 1024 / 1024:.0f} MB")
@@ -249,6 +251,94 @@ def run_pyinstaller():
log(f"Trovata directory: {alt}") log(f"Trovata directory: {alt}")
def patch_info_plist(app_path):
"""Aggiunge le chiavi TCC (Transparency, Consent and Control) richieste
da macOS nel bundle .app, altrimenti macOS nega silenziosamente l'accesso
al microfono e l'app NON compare in Impostazioni > Privacy e sicurezza.
Senza NSMicrophoneUsageDescription, qualsiasi tentativo di ffmpeg di
aprire un dispositivo audio (incluso BlackHole) viene rifiutato dal
sistema e non viene mostrato nessun prompt all'utente.
"""
info_plist = app_path / "Contents" / "Info.plist"
if not info_plist.exists():
log("ATTENZIONE: Info.plist non trovato, skip patch TCC")
return
pb = "/usr/libexec/PlistBuddy"
# Helper: aggiungi una chiave; se gia presente sovrascrivila.
def add_or_set(key, value, ptype="string"):
# Tenta Add; se esiste, fa Set.
r = subprocess.run(
[pb, "-c", f'Add :{key} {ptype} "{value}"', str(info_plist)],
capture_output=True, text=True,
)
if r.returncode != 0 and "already exists" in (r.stderr + r.stdout).lower():
subprocess.run(
[pb, "-c", f'Set :{key} "{value}"', str(info_plist)],
check=True,
)
log("Patching Info.plist con le chiavi TCC...")
add_or_set(
"NSMicrophoneUsageDescription",
"MusicTools usa il microfono per registrare l'audio del sistema "
"(ad esempio tramite BlackHole o un altro dispositivo loopback).",
)
# Sicurezza extra: dichiarare bundle identifier stabile aiuta il
# database TCC a riconoscere coerentemente l'app tra le sessioni.
add_or_set("CFBundleIdentifier", "com.djluza.musictools")
add_or_set("LSApplicationCategoryType", "public.app-category.music")
log("Info.plist aggiornato.")
def adhoc_codesign(app_path):
"""Ad-hoc codesign dell'intero bundle .app.
Senza una firma coerente, macOS tratta ffmpeg (subprocess bundled)
come binario separato dal main MusicTools per TCC: ffmpeg apre il
dispositivo audio senza errore ma riceve solo silenzio perche' il
sistema non gli concede il permesso microfono ereditato.
`codesign --force --deep --sign -` applica una firma ad-hoc (gratis,
senza Developer ID) a tutti i binari nested. Per macOS questo rende
l'app un singolo "team" coerente, e il permesso TCC concesso al
main si propaga anche a ffmpeg/ffprobe/yt-dlp.
"""
log("Ad-hoc codesign del bundle (per TCC microfono ereditato)...")
try:
# Rimuovi vecchie firme che potrebbero confondere codesign --deep
subprocess.run(
["xattr", "-cr", str(app_path)],
capture_output=True,
)
subprocess.run(
["codesign", "--remove-signature", "--deep", str(app_path)],
capture_output=True,
)
result = subprocess.run(
["codesign", "--force", "--deep", "--sign", "-",
"--timestamp=none", str(app_path)],
capture_output=True, text=True,
)
if result.returncode != 0:
log(f"ATTENZIONE: codesign fallito: {result.stderr.strip()}")
else:
log("Codesign ad-hoc completato.")
# Verifica
verify = subprocess.run(
["codesign", "--verify", "--deep", "--strict", str(app_path)],
capture_output=True, text=True,
)
if verify.returncode == 0:
log("Verifica firma OK.")
else:
log(f"NOTA: verifica firma con warning: {verify.stderr.strip()}")
except FileNotFoundError:
log("ATTENZIONE: 'codesign' non trovato nel PATH, skip ad-hoc signing")
# ========================================================================= # =========================================================================
# Main # Main
# ========================================================================= # =========================================================================
+1 -1
View File
@@ -5,7 +5,7 @@ import os
import sys import sys
from pathlib import Path from pathlib import Path
VERSION = "v1.7.8" VERSION = "v1.7.11"
APP_NAME = "MusicTools" APP_NAME = "MusicTools"
+14 -2
View File
@@ -73,7 +73,14 @@ def _is_virtual(name: str) -> bool:
def _list_macos(ffmpeg: str) -> list[dict]: def _list_macos(ffmpeg: str) -> list[dict]:
"""Parsa l'output di `ffmpeg -f avfoundation -list_devices true -i ""`. """Parsa l'output di `ffmpeg -f avfoundation -list_devices true -i ""`.
L'output va su stderr.""" L'output va su stderr.
IMPORTANTE: come 'id' usiamo il NOME del device (non l'index numerico).
AVFoundation rinumera silenziosamente i device quando cambia il set di
hardware collegato (es. iPhone in continuita', Multi-Output Device, ecc).
Il nome e' invece stabile; ffmpeg AVFoundation accetta sia ':<index>'
sia ':<name>' come specifica del device input.
"""
try: try:
proc = subprocess.run( proc = subprocess.run(
[ffmpeg, "-hide_banner", "-f", "avfoundation", [ffmpeg, "-hide_banner", "-f", "avfoundation",
@@ -105,7 +112,12 @@ def _list_macos(ffmpeg: str) -> list[dict]:
if not m: if not m:
continue continue
idx, name = m.group(1), m.group(2).strip() idx, name = m.group(1), m.group(2).strip()
devices.append({"id": idx, "name": name, "is_virtual": _is_virtual(name)}) devices.append({
"id": name, # nome stabile (vedi docstring)
"index": idx, # solo informativo per debug
"name": name,
"is_virtual": _is_virtual(name),
})
return devices return devices
+9 -7
View File
@@ -21,7 +21,7 @@
<main class="legal-doc"> <main class="legal-doc">
<h1>Informativa Privacy</h1> <h1>Informativa Privacy</h1>
<p class="updated">Ultimo aggiornamento: 8 giugno 2026</p> <p class="updated">Ultimo aggiornamento: 9 giugno 2026</p>
<h2>1. Titolare del trattamento</h2> <h2>1. Titolare del trattamento</h2>
<p>Luciano Zappacosta — email <a href="mailto:info@djluza.com">info@djluza.com</a>.</p> <p>Luciano Zappacosta — email <a href="mailto:info@djluza.com">info@djluza.com</a>.</p>
@@ -30,24 +30,26 @@
<ul> <ul>
<li><strong>Email</strong>: associata all'acquisto. Usata per inviare la chiave di licenza, comunicazioni di servizio e supporto.</li> <li><strong>Email</strong>: associata all'acquisto. Usata per inviare la chiave di licenza, comunicazioni di servizio e supporto.</li>
<li><strong>Chiave di licenza, device_id, nome dispositivo, versione app</strong>: salvati nel database licenze per gestire le attivazioni (max 3 dispositivi) e impedire abusi.</li> <li><strong>Chiave di licenza, device_id, nome dispositivo, versione app</strong>: salvati nel database licenze per gestire le attivazioni (max 3 dispositivi) e impedire abusi.</li>
<li><strong>Piano sottoscritto, id ordine e id sottoscrizione Lemon Squeezy, data scadenza/rinnovo</strong>: necessari per applicare correttamente le funzioni del piano (Basic/Pro/Premium/Annual) e gestire rinnovi, disdette, rimborsi.</li>
<li><strong>Contatore download giornaliero</strong>: numero aggregato di download effettuati ogni giorno (azzerato a mezzanotte ora di Roma). Serve esclusivamente ad applicare i limiti del piano (10/30/150 al giorno). Non vengono registrati URL ne' titoli dei brani scaricati.</li>
<li><strong>Dati di pagamento</strong>: gestiti esclusivamente da Lemon Squeezy Inc. L'Editore non vede ne' conserva i dati della carta.</li> <li><strong>Dati di pagamento</strong>: gestiti esclusivamente da Lemon Squeezy Inc. L'Editore non vede ne' conserva i dati della carta.</li>
</ul> </ul>
<h2>3. Finalita' e base giuridica</h2> <h2>3. Finalita' e base giuridica</h2>
<ul> <ul>
<li>Esecuzione del contratto (consegna della licenza, supporto, aggiornamenti) — art. 6(1)(b) GDPR.</li> <li>Esecuzione del contratto (consegna della licenza, gestione del piano sottoscritto, rinnovi, supporto, aggiornamenti) — art. 6(1)(b) GDPR.</li>
<li>Adempimenti fiscali e contabili — art. 6(1)(c) GDPR.</li> <li>Adempimenti fiscali e contabili — art. 6(1)(c) GDPR.</li>
<li>Sicurezza del software (verifica anti-abuso delle attivazioni) — interesse legittimo, art. 6(1)(f) GDPR.</li> <li>Sicurezza del software e applicazione dei limiti del piano (verifica anti-abuso delle attivazioni, contatore giornaliero) — interesse legittimo, art. 6(1)(f) GDPR.</li>
</ul> </ul>
<h2>4. Conservazione</h2> <h2>4. Conservazione</h2>
<p>I dati di licenza vengono conservati per tutta la durata del prodotto e fino a 5 anni dopo la disattivazione, per adempimenti fiscali. I log tecnici (revalidate) sono conservati per 30 giorni.</p> <p>I dati di licenza vengono conservati per tutta la durata del prodotto e fino a 5 anni dopo la disattivazione, per adempimenti fiscali. I log tecnici (revalidate) sono conservati per 30 giorni. Il contatore download giornaliero viene mantenuto per 90 giorni e poi cancellato.</p>
<h2>5. Terze parti</h2> <h2>5. Terze parti</h2>
<ul> <ul>
<li><strong>Lemon Squeezy Inc.</strong> — Merchant of Record, processore di pagamento.</li> <li><strong>Lemon Squeezy Inc.</strong> — Merchant of Record, processore di pagamento, gestione abbonamenti.</li>
<li><strong>Cloudflare Inc.</strong> — hosting infrastruttura backend (Workers, D1, R2, Pages).</li> <li><strong>Resend Inc.</strong> — invio email transazionali (consegna chiave di licenza, comunicazioni di servizio).</li>
<li><strong>Resend Inc.</strong> — invio email transazionali.</li> <li><strong>Provider di hosting self-managed</strong> — i dati di licenza e il backend API sono ospitati su server gestiti dall'Editore. I dati non vengono condivisi con altri fornitori cloud.</li>
</ul> </ul>
<p>Tutte queste aziende rispettano standard internazionali di protezione dati e operano con clausole contrattuali standard ove richiesto.</p> <p>Tutte queste aziende rispettano standard internazionali di protezione dati e operano con clausole contrattuali standard ove richiesto.</p>
+16 -5
View File
@@ -21,20 +21,31 @@
<main class="legal-doc"> <main class="legal-doc">
<h1>Politica rimborsi</h1> <h1>Politica rimborsi</h1>
<p class="updated">Ultimo aggiornamento: 8 giugno 2026</p> <p class="updated">Ultimo aggiornamento: 9 giugno 2026</p>
<h2>Garanzia 14 giorni</h2> <h2>Garanzia 14 giorni sul primo acquisto</h2>
<p>Hai 14 giorni di tempo dall'acquisto per chiedere il rimborso completo, senza fornire motivazioni. La richiesta si effettua scrivendo a <a href="mailto:info@djluza.com">info@djluza.com</a> dall'email usata per l'acquisto.</p> <p>Hai <strong>14 giorni</strong> di tempo dal <strong>primo acquisto</strong> per chiedere il rimborso completo, senza fornire motivazioni. Vale per tutti i piani: Basic, Pro, Premium e Annual.</p>
<p>La richiesta si effettua scrivendo a <a href="mailto:info@djluza.com">info@djluza.com</a> dall'email usata per l'acquisto.</p>
<h2>Cosa succede dopo</h2> <h2>Differenze per piano</h2>
<ul>
<li><strong>Basic / Pro / Premium</strong> (mensili): puoi disdire l'abbonamento <strong>in qualsiasi momento</strong> dalla dashboard di Lemon Squeezy o scrivendoci. La disdetta interrompe il rinnovo successivo; la licenza resta attiva fino alla scadenza del periodo gia pagato. Il rimborso integrale e' previsto solo entro 14 giorni dal primo addebito. <strong>I rinnovi successivi al primo non sono rimborsabili</strong> ma sono interrompibili con disdetta.</li>
<li><strong>Annual</strong> (una tantum, 49,90 € per 12 mesi): rimborso integrale entro 14 giorni dall'acquisto. Oltre tale termine non e' previsto rimborso parziale per il tempo residuo.</li>
</ul>
<h2>Cosa succede dopo la richiesta</h2>
<ol> <ol>
<li>Riceverai una risposta entro 48 ore lavorative.</li> <li>Riceverai una risposta entro 48 ore lavorative.</li>
<li>Il rimborso viene processato da Lemon Squeezy sullo stesso metodo di pagamento usato per l'acquisto. Tempi tipici: 5-10 giorni lavorativi.</li> <li>Il rimborso viene processato da Lemon Squeezy sullo stesso metodo di pagamento usato per l'acquisto. Tempi tipici: 5-10 giorni lavorativi.</li>
<li>La tua chiave di licenza viene revocata. L'app smette di funzionare al successivo controllo online.</li> <li>La tua chiave di licenza viene revocata. L'app smette di funzionare al successivo controllo online.</li>
</ol> </ol>
<h2>Come disdire un abbonamento mensile</h2>
<p>Se sei oltre i 14 giorni e vuoi solo non rinnovare, accedi alla tua dashboard Lemon Squeezy (link nella ricevuta) e clicca "Cancel subscription". In alternativa scrivici a <a href="mailto:info@djluza.com">info@djluza.com</a> e la disattiviamo per te.</p>
<h2>Limitazioni</h2> <h2>Limitazioni</h2>
<p>Trascorsi 14 giorni dall'acquisto non e' piu' possibile chiedere il rimborso, salvo nei casi di malfunzionamento grave del software non risolvibile entro 30 giorni dalla segnalazione.</p> <p>Trascorsi 14 giorni dal primo acquisto non e' piu' possibile chiedere il rimborso integrale, salvo nei casi di malfunzionamento grave del software non risolvibile entro 30 giorni dalla segnalazione.</p>
<p>Spotify potrebbe modificare in qualsiasi momento le proprie API o le condizioni di accesso (es. richiedere un account Premium per generare le credenziali). Tali modifiche di terze parti non costituiscono titolo per il rimborso del piano MusicTools acquistato. La sezione "Esclusione di garanzie" dei <a href="/legal/terms.html">Termini di servizio</a> si applica integralmente.</p>
<h2>Domande?</h2> <h2>Domande?</h2>
<p>Scrivici a <a href="mailto:info@djluza.com">info@djluza.com</a>: siamo persone vere, rispondiamo entro un giorno lavorativo.</p> <p>Scrivici a <a href="mailto:info@djluza.com">info@djluza.com</a>: siamo persone vere, rispondiamo entro un giorno lavorativo.</p>
+16 -4
View File
@@ -38,7 +38,7 @@
<main class="legal-doc"> <main class="legal-doc">
<h1>Termini di servizio e Licenza d'uso</h1> <h1>Termini di servizio e Licenza d'uso</h1>
<p class="updated">Ultimo aggiornamento: 8 giugno 2026</p> <p class="updated">Ultimo aggiornamento: 9 giugno 2026</p>
<div class="warn-box"> <div class="warn-box">
<p><strong>Leggi attentamente.</strong> Acquistando, installando o usando MusicTools accetti i presenti Termini. Se non li accetti, non installare ne' usare il software.</p> <p><strong>Leggi attentamente.</strong> Acquistando, installando o usando MusicTools accetti i presenti Termini. Se non li accetti, non installare ne' usare il software.</p>
@@ -163,6 +163,7 @@
<li>Compatibilita' con qualsiasi versione corrente o futura di sistemi operativi, piattaforme online o formati di file.</li> <li>Compatibilita' con qualsiasi versione corrente o futura di sistemi operativi, piattaforme online o formati di file.</li>
</ul> </ul>
<p>Le piattaforme di origine (Spotify, YouTube, ecc.) possono modificare in qualsiasi momento le proprie API, formati o politiche, rendendo il Software temporaneamente o permanentemente inutilizzabile per certe funzioni. L'Editore non garantisce alcuna continuita' funzionale.</p> <p>Le piattaforme di origine (Spotify, YouTube, ecc.) possono modificare in qualsiasi momento le proprie API, formati o politiche, rendendo il Software temporaneamente o permanentemente inutilizzabile per certe funzioni. L'Editore non garantisce alcuna continuita' funzionale.</p>
<p><strong>Credenziali Spotify Web API:</strong> per scaricare playlist e album interi da Spotify il Software richiede che l'Utente generi proprie chiavi API (Client ID e Client Secret) dalla Spotify Developer Dashboard e le configuri all'interno del Software. Spotify, in seguito ad aggiornamenti della propria policy, consente la creazione di tali credenziali esclusivamente agli utenti con <strong>account Spotify Premium</strong> attivo. L'Editore non e' in alcun modo affiliato a Spotify, non fornisce, vende o rivende account Spotify, non puo' garantire l'accessibilita' o il funzionamento delle API Spotify per gli account Free, e non e' responsabile per limitazioni, sospensioni o ban applicati da Spotify alle credenziali dell'Utente. I download di singoli brani da Spotify, basati su metadati pubblici, non richiedono credenziali API ne' un abbonamento Premium.</p>
<h2 id="s10">10. Limitazione di responsabilita</h2> <h2 id="s10">10. Limitazione di responsabilita</h2>
<p>Nei limiti massimi consentiti dalla legge applicabile, in nessun caso l'Editore sara' responsabile verso l'Utente o verso terzi per:</p> <p>Nei limiti massimi consentiti dalla legge applicabile, in nessun caso l'Editore sara' responsabile verso l'Utente o verso terzi per:</p>
@@ -185,14 +186,25 @@
<li>Qualsiasi attivita' illecita compiuta dall'Utente tramite il Software.</li> <li>Qualsiasi attivita' illecita compiuta dall'Utente tramite il Software.</li>
</ul> </ul>
<h2 id="s12">12. Pagamenti e fatturazione</h2> <h2 id="s12">12. Piani, prezzi e fatturazione</h2>
<p>I pagamenti sono gestiti da <strong>Lemon Squeezy Inc.</strong>, che opera come Merchant of Record (MoR). Lemon Squeezy emette la ricevuta/fattura fiscale, gestisce l'IVA secondo la giurisdizione del cliente (regime MOSS UE) e fornisce assistenza per problematiche di pagamento.</p> <p>I pagamenti sono gestiti da <strong>Lemon Squeezy Inc.</strong>, che opera come Merchant of Record (MoR). Lemon Squeezy emette la ricevuta/fattura fiscale, gestisce l'IVA secondo la giurisdizione del cliente (regime MOSS UE) e fornisce assistenza per problematiche di pagamento.</p>
<p>Prezzo pubblicato: <strong>39,90 € una tantum</strong> (IVA inclusa secondo paese di residenza dell'Utente).</p> <p>Il Software e' commercializzato in quattro piani, ciascuno con prezzi indicati IVA inclusa secondo paese di residenza dell'Utente:</p>
<ul>
<li><strong>Basic</strong> &mdash; 2,99 € / mese (abbonamento). Include il download di brani audio fino a 10 al giorno; non include video, registrazione, editor metadati, upgrade libreria.</li>
<li><strong>Pro</strong> &mdash; 5,99 € / mese (abbonamento). Include audio + video + registrazione + editor metadati + upgrade libreria, fino a 30 download al giorno.</li>
<li><strong>Premium</strong> &mdash; 9,99 € / mese (abbonamento). Stesse funzioni del Pro con limite di 150 download al giorno.</li>
<li><strong>Annual</strong> &mdash; 49,90 € una tantum. Tutte le funzioni sbloccate, nessun limite giornaliero, validita' 12 (dodici) mesi dalla data di acquisto. Non si rinnova automaticamente.</li>
</ul>
<p><strong>Limiti giornalieri:</strong> il contatore si azzera ogni giorno a mezzanotte ora di Roma (Europe/Rome). I download non utilizzati non si cumulano.</p>
<p><strong>Abbonamenti mensili (Basic, Pro, Premium):</strong> si rinnovano automaticamente alla data di addebito mensile fino a disdetta dell'Utente, che puo' essere effettuata in qualsiasi momento dalla dashboard Lemon Squeezy o scrivendo a <a href="mailto:info@djluza.com">info@djluza.com</a>. La disdetta interrompe il rinnovo successivo; la Licenza resta attiva fino alla scadenza del periodo gia pagato.</p>
<p><strong>Piano Annual (una tantum):</strong> il pagamento e' singolo e copre 12 mesi consecutivi. Allo scadere, la Licenza diventa inattiva e per continuare a utilizzare il Software l'Utente puo' acquistare nuovamente un piano a sua scelta.</p>
<p>L'Utente puo' passare a un piano superiore (upgrade) o inferiore (downgrade) in qualsiasi momento. Il prorata viene gestito secondo le regole di Lemon Squeezy.</p>
<h2 id="s13">13. Diritto di recesso e rimborsi</h2> <h2 id="s13">13. Diritto di recesso e rimborsi</h2>
<p>Ai sensi del Codice del Consumo (D.lgs. 206/2005) e del Regolamento UE sui consumatori, l'Utente ha diritto di recedere dal contratto entro <strong>14 (quattordici) giorni</strong> dall'acquisto, senza fornire motivazioni.</p> <p>Ai sensi del Codice del Consumo (D.lgs. 206/2005) e del Regolamento UE sui consumatori, l'Utente ha diritto di recedere dal contratto entro <strong>14 (quattordici) giorni</strong> dal primo acquisto, senza fornire motivazioni. Il diritto di recesso si applica al primo addebito; non si applica ai rinnovi successivi di un abbonamento mensile, per i quali resta possibile la disdetta come previsto al §12.</p>
<p>La richiesta va inviata a <a href="mailto:info@djluza.com">info@djluza.com</a> dall'email usata per l'acquisto. Il rimborso viene processato da Lemon Squeezy sullo stesso metodo di pagamento; tempi tipici 5-10 giorni lavorativi.</p> <p>La richiesta va inviata a <a href="mailto:info@djluza.com">info@djluza.com</a> dall'email usata per l'acquisto. Il rimborso viene processato da Lemon Squeezy sullo stesso metodo di pagamento; tempi tipici 5-10 giorni lavorativi.</p>
<p>A seguito del rimborso, la Licenza viene revocata e il Software smettera' di funzionare al successivo controllo online.</p> <p>A seguito del rimborso, la Licenza viene revocata e il Software smettera' di funzionare al successivo controllo online.</p>
<p>L'Utente non puo' richiedere il rimborso dell'importo gia pagato per i mesi di abbonamento gia consumati. Il piano Annual, in caso di recesso entro 14 giorni, viene rimborsato interamente; oltre tale termine non e' previsto rimborso parziale per il tempo residuo.</p>
<h2 id="s14">14. Aggiornamenti e supporto</h2> <h2 id="s14">14. Aggiornamenti e supporto</h2>
<p>L'Editore si impegna a mantenere il Software funzionante e a rilasciare aggiornamenti gratuiti per tutta la durata commerciale del prodotto. Non e' garantito un calendario specifico di rilascio.</p> <p>L'Editore si impegna a mantenere il Software funzionante e a rilasciare aggiornamenti gratuiti per tutta la durata commerciale del prodotto. Non e' garantito un calendario specifico di rilascio.</p>