# @andco/passport

> La estrategia de Passport construida sobre la configuración del SDK.


```bash
npm install @andco/sdk @andco/passport passport
```

## AndCoStrategy.create

```ts
import { AndCoStrategy } from "@andco/passport";

passport.use(
  "andco",
  AndCoStrategy.create(
    {
      client: andco,
      callbackURL: new URL("/auth/callback", process.env.APP_ORIGIN),
      scope: ["email", "profile"],
    },
    verify,
  ),
);
```

Es una fábrica y no un constructor porque la estrategia necesita la descripción que el servidor de autorización publica de sí mismo. Esa descripción se lee del servidor, pero al construir el SDK y no en tiempo de ejecución, así que `create` es síncrona y no hace ninguna petición.

| Opción | Qué es |
| --- | --- |
| `client` | la instancia confidencial creada con `@andco/sdk/server` |
| `callbackURL` | la URL registrada exacta |
| `name` | el nombre de la estrategia. Por omisión `"andco"` |
| `sessionKey` | la clave de sesión donde Passport guarda el estado y el PKCE |
| `scope` | los scopes por omisión cuando una ruta no los indica |
| `authorizationTransport` | fuerza petición directa o PAR |

Se construye sobre la implementación oficial de `openid-client/passport`, de modo que el protocolo no se reescribe y la configuración es la misma del SDK.

## Autorizaciones por ruta

```ts
app.get(
  "/auth/andco/banco",
  passport.authenticate("andco", {
    scope: ["email", "bank_accounts:read"],
    loginHint: "persona@ejemplo.cl",
    authorizations: [{ resourceServerId: "bank", resource: "https://bank.andco.cl" }],
  }),
);
```

Cuando la petición lleva `loginHint` o contribuciones de autorización, la estrategia usa PAR: ni el correo de una persona ni el detalle de los permisos deben quedar en el historial ni en los registros.

## El verify

```ts
const verify = (tokens, done) => {
  const rest = andco.with(tokens.access_token).rest;
  void rest.http.GET("/userinfo").then(({ data, error }) => {
    if (error) return done(error);
    done(null, { ...data, andco: { accessToken: tokens.access_token, refreshToken: tokens.refresh_token } });
  });
};
```

Si no pasas uno, `AndCoStrategy.defaultVerify(oauth)` hace exactamente esto: lee el perfil mínimo y no toca ningún recurso privilegiado.

## AndCoPassportUser

```ts
import { AndCoPassportUser } from "@andco/passport";

const user = AndCoPassportUser.unwrap(request.user);
```

Comprueba que `request.user` tenga la forma que el resto de tu código espera y lanza un `TypeError` claro si no. Con una petición anónima devuelve `undefined` en vez de fallar.
