@andco/better-auth

Andco como proveedor OAuth genérico dentro de Better Auth.

bash
npm install @andco/sdk @andco/better-auth better-auth

Conecta Andco a Better Auth reutilizando la configuración de protocolo del SDK en vez de armar una segunda a partir de los mismos endpoints.

createAndcoOAuthProvider

ts
import { createAndcoOAuthProvider } from "@andco/better-auth";
import { createAndcoInstanceForServer } from "@andco/sdk/server";
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";

const andco = createAndcoInstanceForServer({
  clientId: process.env.ANDCO_CLIENT_ID!,
  clientSecret: process.env.ANDCO_CLIENT_SECRET!,
});

export const auth = betterAuth({
  plugins: [
    genericOAuth({
      config: [
        createAndcoOAuthProvider({
          providerId: "andco",
          client: andco,
        }),
      ],
    }),
  ],
});

Devuelve una configuración de proveedor genérico con los endpoints, client_secret_basic, PKCE y el mapeo de perfil ya resueltos.

Rechaza un perfil de UserInfo sin correo, porque Better Auth lo exige y fallar aquí es más claro que crear un usuario a medias. Cuando UserInfo no trae nombre, usa el correo.

createAndcoAuthorizationURL

ts
import { createAndcoAuthorizationURL } from "@andco/better-auth";

const url = await createAndcoAuthorizationURL({
  authorizationUrl: urlFromBetterAuth,
  client: andco,
  authorizations: [
    {
      resource: "https://firmaya.andco.cl/api",
      orgId: "1",
      authorizationDetails: [{ type: "…", actions: ["create"], locations: ["https://firmaya.andco.cl/api"] }],
    },
  ],
  loginHint: "persona@ejemplo.cl",
});

Toma la URL de autorización que Better Auth ya armó y le aplica la política de transporte de Andco: si lleva parámetros sensibles —login_hint, authorization_details— o queda demasiado larga, la empuja por PAR y devuelve solo la referencia.

Eso importa porque login_hint es el correo de una persona y authorization_details describe permisos concretos: ninguno debe quedar en el historial del navegador, en un Referer ni en los registros de un proxy.

Si la PAR falla, lanza AndCoPushedAuthorizationError.

Ampliar permisos después

ts
const url = await createAndcoAuthorizationURL({
  authorizationUrl: urlFromBetterAuth,
  client: andco,
  authorizations: [{ resource, orgId, authorizationDetails }],
});

Una autorización solo de RAR —sin scopes— también es válida: es la forma de pedir permiso sobre un recurso concreto sin ampliar el Grant de identidad.