@geekapps/auth-nextjs 0.16.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/connections.d.ts +121 -67
- package/dist/connections.js +134 -957
- package/dist/connections.js.map +1 -1
- package/package.json +10 -3
package/dist/connections.d.ts
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
import { ClientOptions, Client } from 'openapi-fetch';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
* App Connections —
|
|
3
|
-
*
|
|
4
|
-
* Uma conexão liga um USUÁRIO desta app (X) a uma app alvo (Y). Ele a aprova
|
|
5
|
-
* uma vez no consent, escolhendo as ações liberadas e a organização dentro do
|
|
6
|
-
* Y sob a qual elas rodam. A chamada vai com o access token desse usuário (o
|
|
7
|
-
* da sessão, por padrão): é ele que diz ao proxy qual conexão usar.
|
|
4
|
+
* App Connections — agir como um usuário numa organização de OUTRA Application.
|
|
8
5
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* Uma conexão liga um USUÁRIO desta app (X) a uma organização da app alvo (Z)
|
|
7
|
+
* de que ele já é membro. Ele a aprova uma vez, no consent; o auth-server
|
|
8
|
+
* devolve a esta app um API token (`gka_…`). Daí em diante esta app guarda o
|
|
9
|
+
* token e o usa quando quiser — com ou sem o usuário logado, num cron, num
|
|
10
|
+
* workflow — trocando-o por um JWT curto que age COMO o usuário naquela
|
|
11
|
+
* organização (`getConnectionAccessToken`). As permissions são as do usuário
|
|
12
|
+
* na organização, hoje: mudou o role dele lá, a conexão muda junto; saiu da
|
|
13
|
+
* organização, ela para.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
+
* ⚠️ ATENÇÃO — o API token é uma credencial de longa duração.
|
|
16
|
+
* • Guarde-o cifrado, associado ao usuário que aprovou a conexão.
|
|
17
|
+
* • Use-o só para agir em nome DESSE usuário. Usar o token de A para atender
|
|
18
|
+
* um pedido de B dá a B o acesso de A à organização alvo.
|
|
19
|
+
* • Restringir quem pode disparar uma chamada, e o que ela pode pedir, é
|
|
20
|
+
* responsabilidade desta app: o auth-server não tem como saber.
|
|
21
|
+
* • Vazou? Revogue no dashboard do Geekapps Auth ou gire com `rotateConnectionToken`.
|
|
15
22
|
*/
|
|
16
|
-
/** Opções por chamada. Sem `userToken`, usa o access token do usuário logado na sessão. */
|
|
17
|
-
type ConnectionCallOptions = {
|
|
18
|
-
userToken?: string;
|
|
19
|
-
};
|
|
20
23
|
type AppConnectionsConfig = {
|
|
21
24
|
issuer?: string;
|
|
22
25
|
/** client_id/secret desta app (a consumidora, X). */
|
|
@@ -24,65 +27,23 @@ type AppConnectionsConfig = {
|
|
|
24
27
|
clientSecret?: string;
|
|
25
28
|
};
|
|
26
29
|
/**
|
|
27
|
-
* Preenchida por declaration merging no
|
|
28
|
-
* (`geekapps-connections
|
|
29
|
-
*
|
|
30
|
+
* Preenchida por declaration merging no `geekapps-connections/index.d.ts` que
|
|
31
|
+
* o SDK gera (em desenvolvimento) ou `npx geekapps-connections` escreve: uma
|
|
32
|
+
* chave por app conectável, com os `paths` do OpenAPI dela. Vazia aqui de
|
|
33
|
+
* propósito — quem sabe quais apps existem é o auth-server.
|
|
30
34
|
*/
|
|
31
35
|
interface GeekappsConnections {
|
|
32
36
|
}
|
|
33
|
-
/** Erro de uma chamada
|
|
37
|
+
/** Erro de uma chamada ao auth-server — carrega o status HTTP para dar pra tratar. */
|
|
34
38
|
declare class AppConnectionError extends Error {
|
|
35
39
|
readonly status: number;
|
|
36
40
|
readonly code: string | undefined;
|
|
37
41
|
readonly body: unknown;
|
|
38
42
|
constructor(message: string, status: number, code: string | undefined, body: unknown);
|
|
39
43
|
}
|
|
40
|
-
/**
|
|
41
|
-
* A chamada crua do proxy, para quando não há catálogo gerado. `targetAppId` é
|
|
42
|
-
* o client_id da app alvo e `actionKey` é a AppAction.key — o mesmo valor que
|
|
43
|
-
* aparece como scope no consent.
|
|
44
|
-
*/
|
|
45
|
-
declare function callAppConnection<T = unknown>(params: {
|
|
46
|
-
targetAppId: string;
|
|
47
|
-
actionKey: string;
|
|
48
|
-
payload?: unknown;
|
|
49
|
-
/** Access token do usuário dono da conexão. Padrão: o do usuário logado. */
|
|
50
|
-
userToken?: string;
|
|
51
|
-
config?: AppConnectionsConfig;
|
|
52
|
-
}): Promise<T>;
|
|
53
|
-
type ConnectionRegistryEntry = {
|
|
54
|
-
appId: string;
|
|
55
|
-
actions: Record<string, string>;
|
|
56
|
-
};
|
|
57
|
-
/** Chamado por arquivos gerados no formato antigo. Não é necessário no fluxo automático. */
|
|
58
|
-
declare function registerConnections(entries: Record<string, ConnectionRegistryEntry>): void;
|
|
59
|
-
/**
|
|
60
|
-
* Sem tipos gerados (primeira execução), qualquer `app.ação` é aceita. Assim
|
|
61
|
-
* que o SDK escreve `geekapps-connections.d.ts`, a interface estendida passa a
|
|
62
|
-
* valer e o TypeScript confere payload e retorno.
|
|
63
|
-
*/
|
|
64
|
-
type AppConnectionsClient = keyof GeekappsConnections extends never ? Record<string, Record<string, (payload?: unknown, options?: ConnectionCallOptions) => Promise<unknown>>> : GeekappsConnections;
|
|
65
|
-
/** Cliente com config explícita — para quem não usa as env vars padrão. */
|
|
66
|
-
declare function createAppConnections(config?: AppConnectionsConfig): AppConnectionsClient;
|
|
67
|
-
/** Catálogo explícito, como o gerado por `npx geekapps-connections` (`geekappsConnectionsCatalog`). */
|
|
68
|
-
type ConnectionsCatalog = Record<string, {
|
|
69
|
-
readonly appId: string;
|
|
70
|
-
readonly actions: Readonly<Record<string, string>>;
|
|
71
|
-
}>;
|
|
72
|
-
/**
|
|
73
|
-
* Opcional: usa um catálogo fixo em vez de consultar o auth-server. Útil em
|
|
74
|
-
* testes ou quando a app não pode falar com o servidor em runtime.
|
|
75
|
-
*
|
|
76
|
-
* const connections = defineAppConnections<GeekappsConnections>(geekappsConnectionsCatalog);
|
|
77
|
-
*/
|
|
78
|
-
declare function defineAppConnections<T>(catalog: ConnectionsCatalog, config?: AppConnectionsConfig): T;
|
|
79
|
-
/** Cliente padrão, lendo GEEKAPPS_AUTH_CLIENT_ID / _SECRET do ambiente. */
|
|
80
|
-
declare const appConnections: AppConnectionsClient;
|
|
81
44
|
type ConnectAppParams = {
|
|
82
|
-
/** client_id da app ALVO (a que
|
|
45
|
+
/** client_id da app ALVO (a que vai ser acessada). */
|
|
83
46
|
targetAppId: string;
|
|
84
|
-
/** AppAction.key das ações pedidas — as mesmas que aparecem no consent. */
|
|
85
|
-
actions: string[];
|
|
86
47
|
/** URL desta app que recebe o retorno do consent (rota que chama `completeAppConnection`). Precisa estar nos redirect URIs desta app. */
|
|
87
48
|
redirectUri: string;
|
|
88
49
|
/** Para onde `completeAppConnection` manda o usuário depois (padrão "/"). */
|
|
@@ -93,13 +54,26 @@ type ConnectAppParams = {
|
|
|
93
54
|
};
|
|
94
55
|
/**
|
|
95
56
|
* Inicia a conexão desta app com `targetAppId`: guarda PKCE/state em cookies
|
|
96
|
-
* httpOnly e redireciona para o consent
|
|
97
|
-
* Handler — não retorna (o
|
|
57
|
+
* httpOnly e redireciona para o consent, onde o usuário escolhe a organização
|
|
58
|
+
* e a validade. Chame de um Server Action ou Route Handler — não retorna (o
|
|
59
|
+
* `redirect` do Next interrompe a execução).
|
|
98
60
|
*/
|
|
99
61
|
declare function connectApp(params: ConnectAppParams): Promise<never>;
|
|
62
|
+
/** A conexão recém-criada. O `token` só aparece aqui, uma única vez. */
|
|
63
|
+
type AppConnectionToken = {
|
|
64
|
+
/** API token (`gka_…`). Guarde-o cifrado, associado ao usuário que aprovou. */
|
|
65
|
+
token: string;
|
|
66
|
+
connectionId: string;
|
|
67
|
+
/** null = sem expiração. */
|
|
68
|
+
expiresAt: string | null;
|
|
69
|
+
/** Organização da app alvo em que a conexão age. */
|
|
70
|
+
organizationId: string;
|
|
71
|
+
targetAppId: string;
|
|
72
|
+
};
|
|
100
73
|
/**
|
|
101
74
|
* Fecha o fluxo de `connectApp`. Chame no callback com o `code` e o `state`
|
|
102
|
-
* da query; devolve o `returnTo`
|
|
75
|
+
* da query; devolve o `returnTo` e a conexão, com o API token — a ÚNICA vez em
|
|
76
|
+
* que ele aparece, então persista-o antes de redirecionar. Lança
|
|
103
77
|
* AppConnectionError se o state não bater ou o auth-server recusar.
|
|
104
78
|
*/
|
|
105
79
|
declare function completeAppConnection(params: {
|
|
@@ -108,6 +82,86 @@ declare function completeAppConnection(params: {
|
|
|
108
82
|
config?: AppConnectionsConfig;
|
|
109
83
|
}): Promise<{
|
|
110
84
|
returnTo: string;
|
|
85
|
+
connection: AppConnectionToken;
|
|
86
|
+
}>;
|
|
87
|
+
/** Resultado de `getConnectionAccessToken`. */
|
|
88
|
+
type AppConnectionAccessToken = {
|
|
89
|
+
/** JWT curto: use em `Authorization: Bearer` contra a API da app alvo. */
|
|
90
|
+
accessToken: string;
|
|
91
|
+
/** Segundos até o JWT vencer. */
|
|
92
|
+
expiresIn: number;
|
|
93
|
+
organizationId: string;
|
|
94
|
+
targetAppId: string;
|
|
95
|
+
/** apiBaseUrl da app alvo, quando ela declarou uma. */
|
|
96
|
+
targetApiBaseUrl: string | null;
|
|
97
|
+
/** URL do OpenAPI da app alvo, quando ela declarou uma — fonte dos tipos. */
|
|
98
|
+
targetOpenApiUrl: string | null;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Troca o API token por um JWT curto que age como o usuário na organização da
|
|
102
|
+
* conexão. Não exige ninguém logado. O resultado fica em cache até perto de
|
|
103
|
+
* vencer, então pode ser chamado a cada requisição.
|
|
104
|
+
*
|
|
105
|
+
* Erros possíveis (`AppConnectionError.code`): `invalid_token`,
|
|
106
|
+
* `connection_inactive` (revogada), `connection_expired`,
|
|
107
|
+
* `membership_required` (o usuário saiu da organização).
|
|
108
|
+
*/
|
|
109
|
+
declare function getConnectionAccessToken(params: {
|
|
110
|
+
/** O API token guardado por esta app. */
|
|
111
|
+
connectionToken: string;
|
|
112
|
+
config?: AppConnectionsConfig;
|
|
113
|
+
}): Promise<AppConnectionAccessToken>;
|
|
114
|
+
/**
|
|
115
|
+
* Atalho: um `fetch` contra a API da app alvo já com o JWT da conexão. `path`
|
|
116
|
+
* é relativo ao `apiBaseUrl` da app alvo (ou uma URL absoluta).
|
|
117
|
+
*/
|
|
118
|
+
declare function connectionFetch(params: {
|
|
119
|
+
connectionToken: string;
|
|
120
|
+
path: string;
|
|
121
|
+
init?: RequestInit;
|
|
122
|
+
config?: AppConnectionsConfig;
|
|
123
|
+
}): Promise<Response>;
|
|
124
|
+
/**
|
|
125
|
+
* Cliente tipado para a API da app alvo, a partir do OpenAPI dela: o JWT da
|
|
126
|
+
* conexão é obtido, renovado e injetado a cada chamada.
|
|
127
|
+
*
|
|
128
|
+
* Os tipos de TODAS as apps conectáveis vêm de uma vez: em desenvolvimento o
|
|
129
|
+
* SDK baixa o OpenAPI de cada uma ao subir e escreve `geekapps-connections/`
|
|
130
|
+
* (ou rode `npx geekapps-connections`). Daí basta nomear a app:
|
|
131
|
+
*
|
|
132
|
+
* const billing = await createConnectionClient({ app: "billing", connectionToken });
|
|
133
|
+
* const { data } = await billing.GET("/charges", { params: { query: { limit: 10 } } });
|
|
134
|
+
*
|
|
135
|
+
* `app` só escolhe os tipos; a app alvo de verdade é a do token. Sem tipos
|
|
136
|
+
* gerados, passe os `paths` você mesmo: `createConnectionClient<paths>({ connectionToken })`.
|
|
137
|
+
*
|
|
138
|
+
* Requer o pacote `openapi-fetch` instalado na sua app.
|
|
139
|
+
*/
|
|
140
|
+
declare function createConnectionClient<App extends keyof GeekappsConnections>(params: ConnectionClientParams & {
|
|
141
|
+
app: App;
|
|
142
|
+
}): Promise<Client<GeekappsConnections[App] & {}>>;
|
|
143
|
+
declare function createConnectionClient<Paths extends {}>(params: ConnectionClientParams & {
|
|
144
|
+
app?: undefined;
|
|
145
|
+
}): Promise<Client<Paths>>;
|
|
146
|
+
type ConnectionClientParams = {
|
|
147
|
+
/** O API token guardado por esta app. */
|
|
148
|
+
connectionToken: string;
|
|
149
|
+
/** Sobrescreve o apiBaseUrl declarado pela app alvo. */
|
|
150
|
+
baseUrl?: string;
|
|
151
|
+
/** Demais opções do openapi-fetch (headers, querySerializer…). */
|
|
152
|
+
options?: Omit<ClientOptions, "baseUrl" | "fetch">;
|
|
153
|
+
config?: AppConnectionsConfig;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Gira o API token: o antigo deixa de valer na hora e o novo é devolvido (a
|
|
157
|
+
* validade da conexão não muda). Persista o novo no lugar do antigo.
|
|
158
|
+
*/
|
|
159
|
+
declare function rotateConnectionToken(params: {
|
|
160
|
+
connectionToken: string;
|
|
161
|
+
config?: AppConnectionsConfig;
|
|
162
|
+
}): Promise<{
|
|
163
|
+
token: string;
|
|
164
|
+
expiresAt: string | null;
|
|
111
165
|
}>;
|
|
112
166
|
|
|
113
|
-
export {
|
|
167
|
+
export { type AppConnectionAccessToken, AppConnectionError, type AppConnectionToken, type AppConnectionsConfig, type ConnectAppParams, type GeekappsConnections, completeAppConnection, connectApp, connectionFetch, createConnectionClient, getConnectionAccessToken, rotateConnectionToken };
|