L'app
Sincronizzazione tra dispositivi
Abilitare la sincronizzazione tra dispositivi, la cifratura e la chiave di recupero depositata dell'operatore
Questa pagina è tradotta automaticamente dalla documentazione in inglese.
Sulla tua istanza personale, openplate è un'app locale per impostazione predefinita: il tuo diario risiede nell'IndexedDB del browser sul dispositivo che usi, e nulla lo lascia finché non punti l'app su un server centrale. Spostare quel diario tra dispositivi è l'unica cosa che richiede un account, quindi risiede in un servizio separato, openplate-core, con la propria immagine, il proprio database e i propri segreti.
Sulla tua istanza personale la sincronizzazione è facoltativa. Se non la imposti, openplate non perde alcuna funzionalità. Sul servizio gestito ogni account si sincronizza, quindi il diario ha anche una copia cifrata sul server.
Cosa viaggia tra i tuoi dispositivi
Tutto ciò che il motore di sincronizzazione definisce un'entità viene unito riga per riga, quindi una modifica apportata su un dispositivo raggiunge gli altri e un'eliminazione effettuata su un dispositivo rimuove la riga sugli altri. A partire da questa versione, questo include i tuoi alimenti personali, il tuo registro alimentare, le voci del tuo peso, il tuo profilo e i tuoi obiettivi, i tuoi digiuni, la tua dispensa, la tua routine di digiuno e i contrassegni di attività e i premi associati alla serie. Anche i tuoi pasti salvati viaggiano, come elenco completo anziché riga per riga, che è l'ultima parte del diario ancora in attesa di un'unione riga per riga.
Anche le tue chiavi di condivisione e di ricerca viaggiano, in una parte sigillata del blob che i tuoi dispositivi possono aprire, così come può fare un operatore in possesso della tua chiave di recupero (vedi La cifratura e cosa conserva il gestore). Un medico a cui concedi l'accesso a un diario non può leggerla.
Tre cose non viaggiano mai, qualunque cosa tu attivi:
- Foto del piatto. Risiedono in un database separato sul dispositivo che le ha scattate, sono escluse dal payload di sincronizzazione e da ogni file di backup, e si cancellano automaticamente secondo la pianificazione che imposti.
- La chiave del tuo fornitore di IA. Risiede nel proprio database sul dispositivo in cui l'hai inserita e non viene inviata a nessuno se non al fornitore che hai scelto.
- Il registro di ciò che hai eliminato. Il tuo dispositivo registra le rimozioni eseguite per poter dimostrare che erano intenzionali, e tale elenco rimane sul dispositivo. Le rimozioni stesse viaggiano; l'elenco no.
Cosa serve
- Un'istanza in esecuzione di openplate-core: quella ospitata, la tua o qualsiasi server di terze parti che implementi il protocollo. Per eseguire la tua, usa
docker/topologies/compose.core.yml: consulta self-hosting.md e topologies.md. CORE_URLimpostata sull'app, che punta a quel servizio.- Una pagina sicura. L'accesso ricava le tue chiavi con la Web Crypto API del browser, che i browser offrono solo tramite
https://o sulocalhost. Vedi self-hosting.md. - Un account. Sulla tua istanza personale la registrazione avviene tramite invito, a meno che tu non imposti
OPEN_SIGNUP=true, quindi generi tu il primo: self-hosting.md.
Come attivarla
CORE_URL è l'unico interruttore.
- Non impostata (impostazione predefinita): nessuna interfaccia di sincronizzazione viene mostrata, e nessuna richiesta di sincronizzazione lascia mai l'app.
- Impostata: le schermate di sincronizzazione compaiono e comunicano con quell'URL. La sua origine viene aggiunta automaticamente a
connect-srcdella CSP di produzione: non hai bisogno diCSP_CONNECT_EXTRAa questo scopo.
Riavvia l'app dopo averla modificata. Rimuovi di nuovo l'impostazione e le schermate di sincronizzazione scompariranno e l'app smetterà di contattare il server. Il tuo diario locale rimane intatto in entrambi i casi.
Aggiunta di un secondo dispositivo: puntala allo stesso CORE_URL e accedi con lo stesso indirizzo email e la stessa password che hai usato sul primo. Questa è l'intera procedura, e non occorre copiare nulla dal primo dispositivo.
Deve essere un indirizzo raggiungibile da un browser. Il client di sincronizzazione gira nella pagina, quindi un nome host di compose come http://core:3000 non funziona: usa l'URL pubblico che i dispositivi dei tuoi utenti risolvono. Un valore non valido blocca l'avvio intenzionalmente, così un errore di battitura non può sembrare una "sincronizzazione disattivata silenziosamente".
La console di ricerca (/study)
L'app include sempre una route /study, che resta inerte su un'istanza ordinaria. Prende vita solo quando il server centrale con cui comunica ha SYNC_RESEARCH=true, ovvero disattivata per impostazione predefinita: un'istanza avviata senza toccare quel flag non esegue alcuno studio, non conserva alcun grafo di studio e non offre nulla a cui iscriversi. Leggi la .env.example di openplate-core prima di attivarlo: fa sì che il server conservi dati personali legati alla salute, un compito ben diverso dal custodire un diario cifrato.
La cifratura e cosa conserva il gestore
La tua password non lascia mai il tuo browser. Viene estesa con Argon2id e suddivisa da HKDF in rami indipendenti. Due rami restano sul dispositivo per decifrare la chiave dei dati e le tue impostazioni private. Un terzo ramo raggiunge il servizio come credenziale di accesso. Sono fratelli crittografici, non genitore e figlio, quindi possederne uno non svela nulla sugli altri. Il tuo diario viene cifrato sul dispositivo prima del caricamento e rimane cifrato durante il transito; il servizio memorizza testo cifrato opaco, e ciò che vede oltre a questo è un indirizzo email insieme a dimensioni e orari dei tuoi caricamenti.
Il gestore conserva una chiave di recupero. Al momento della registrazione l'app genera un codice di recupero, vi cifra la tua chiave dei dati e invia il codice al server, che lo conserva sigillato sotto un proprio segreto. Questo è ciò che fa restituire il tuo diario a "password dimenticata" anziché un account vuoto: il link di ripristino (inviato via email, o su un'istanza senza posta consegnato a te dal gestore) restituisce il codice al tuo browser, che lo usa per estrarre la chiave dei dati e cifrarla nuovamente con la nuova password.
Detto chiaramente, poiché è il compromesso scelto da questa architettura: il gestore di un'istanza può ripristinare, e quindi in linea di principio leggere, un diario presente su di essa. Su un'istanza che ospiti tu stesso, quel gestore sei tu. Su un'istanza gestita per te da un'organizzazione, quest'ultima vede già ogni foto del piatto che passa attraverso il suo proxy AI, quindi questo cambia la promessa meno di quanto sembri, ed è ciò che permette di ottenere un ripristino della password che non ti fa perdere i dati.
Prima di M192 non c'era alcun deposito, e il costo era opposto: una password dimenticata unita a un codice di recupero perso significava che i dati erano andati perduti, sia per noi sia per te, e l'app doveva mostrare il codice una sola volta chiedendo alla persona di conservarlo per sempre. Nessuno lo fa.
Le foto del piatto non fanno mai parte del payload di sincronizzazione. Restano sul dispositivo che le ha scattate, sono escluse dalle esportazioni JSON e, su un'istanza gestita, la copia che raggiunge il proxy AI viene letta una volta sola e il proxy non la memorizza. Una foto inviata insieme a una segnalazione di stima errata viene conservata dall'operatore per un periodo limitato.
Condivisione di un diario con un medico
Su un'istanza in cui il server centrale imposta SYNC_SHARING=true, una persona può consentire a un medico, come un dietista, di leggere il proprio diario. Il medico invia alla persona un link di connessione. La persona lo apre e digita i dodici caratteri che il medico legge a voce alta, così da rilevare una chiave errata prima di condividere qualsiasi cosa. La persona autorizza quindi la condivisione da Impostazioni → Condivisione: l'app cifra nuovamente la chiave dei dati sotto la chiave pubblica del medico e carica tale copia cifrata. Il browser del medico la decifra e mostra il diario all'indirizzo /shared. Il server archivia la copia cifrata e mai la chiave per aprirla. Una condivisione può essere revocata in qualsiasi momento. Un compartimento privato del diario custodisce le chiavi di condivisione e di ricerca della persona, e un medico non può mai aprirlo. Anche l'esportazione JSON contiene tali chiavi, in chiaro, così che un dispositivo ripristinato possa comunque aprire ciò che è stato condiviso con esso; self-hosting.md spiega cosa comporta questo per il file.
La stessa schermata include l'opzione per il pulse, un conteggio facoltativo a livello di istanza di pasti e scansioni; architecture.md indica cosa invia.
Cosa c'era qui prima: il gateway
Fino a M192 una persona poteva collegarsi a un gateway AI separato dallo stesso link di invito, e tale connessione viaggiava con l'account all'interno del compartimento sigillato. Il gateway non esiste più: il server centrale ha integrato il proxy AI, quindi su un'istanza gestita da un'organizzazione, un account autenticato dotato di quota esegue le scansioni attraverso l'unico server con cui già comunica, senza alcun passaggio di connessione da trasferire altrove. Un'istanza in Self-hosting resta invariata: una chiave configurata rimane sul dispositivo su cui è stata inserita.