# Tauri

> Una aplicación de escritorio con Tauri es una instancia de navegador. Con un detalle.


```bash
npm install @andco/sdk @andco/sdk-react
```

Para el SDK, una ventana de Tauri **es** un navegador: tiene `window`, tiene `fetch` y tiene almacenamiento. Se usa el constructor de navegador y no hay un camino especial para escritorio.

```ts title="src/andco.ts"
import { createAndcoInstanceForBrowser } from "@andco/sdk/browser";

export const andco = createAndcoInstanceForBrowser({
  clientId: import.meta.env.VITE_ANDCO_CLIENT_ID,
  redirectTo: import.meta.env.VITE_ANDCO_REDIRECT_TO,
  initialScopes: ["openid", "email", "profile"],
});
```

## El detalle: qué es `redirectTo`

Aquí está la única decisión propia de Tauri. Tu aplicación no vive en `https://tuapp.com`, así que hay que resolver a dónde vuelve la autorización. Hay dos formas y conviene elegir a conciencia.

### Una página de retorno alojada

La autorización vuelve a una URL tuya en la web, que reenvía a la aplicación con un esquema profundo.

```ts
redirectTo: "https://tuapp.com/desktop/callback";
```

Es lo más simple de registrar y funciona en todas las plataformas, a costa de depender de que tu sitio esté disponible.

### Un servidor loopback

La autorización vuelve a `127.0.0.1` en un puerto que la aplicación abre para la ocasión, igual que una herramienta de terminal.

```ts
import { AndcoCliPresenter } from "@andco/sdk/cli";

const andco = createAndcoInstanceForBrowser({
  clientId,
  redirectTo: "http://127.0.0.1:0/callback",
  presenter: new AndcoCliPresenter({ open: (url) => openInSystemBrowser(url.href) }),
});
```

La autorización ocurre en el navegador del sistema —donde la persona ya puede tener sesión— y vuelve a tu aplicación. Requiere que `127.0.0.1` esté registrado como callback.

## Abrir el navegador del sistema

En escritorio suele ser mejor que la autorización ocurra en el navegador del sistema y no en la ventana de la aplicación: ahí es donde la persona tiene sus sesiones y sus gestores de contraseñas.

```ts
import { openUrl } from "@tauri-apps/plugin-opener";

const presenter = new AndcoCliPresenter({ open: (url) => openUrl(url.href) });
```

## Dónde se guarda la sesión

Por omisión, en `sessionStorage`, que desaparece al cerrar la ventana. Para una aplicación de escritorio casi siempre quieres que persista, y preferiblemente cifrada:

```ts
import type { AndcoStorage } from "@andco/sdk";
import { Store } from "@tauri-apps/plugin-store";

const store = await Store.load("andco.json");

const storage: AndcoStorage = {
  async getItem(key) {
    return (await store.get<string>(key)) ?? null;
  },
  async setItem(key, value) {
    await store.set(key, value);
    await store.save();
  },
  async removeItem(key) {
    await store.delete(key);
    await store.save();
  },
};
```

El almacenamiento puede ser asíncrono, así que el almacén de Tauri encaja sin envoltorios.

## Varias ventanas

Si tu aplicación abre más de una ventana con la misma sesión, entrega un `lock` que sea compartido entre ellas. Los refresh tokens rotan: dos ventanas renovando a la vez invalidan una la credencial de la otra.

## La política de seguridad de contenido

La ventana tiene que poder llegar al servidor de autorización y a la API. Si tu `csp` en `tauri.conf.json` es restrictiva —y debería serlo— agrega los orígenes de Andco a `connect-src`, y el de los widgets a `frame-src` si usas el botón hospedado.
