@adonis-agora/authkit-server 0.86.0 → 0.87.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/README.md +2 -2
- package/build/index.d.ts +1 -2
- package/build/index.js +0 -1
- package/build/src/agents/config.d.ts +1 -1
- package/build/src/agents/delegation_service.js +1 -1
- package/build/src/agents/poppy/client_registry.d.ts +5 -0
- package/build/src/agents/poppy/client_registry.js +35 -1
- package/build/src/agents/poppy/config.d.ts +111 -80
- package/build/src/agents/poppy/config.js +55 -35
- package/build/src/agents/poppy/dpop.d.ts +2 -2
- package/build/src/agents/poppy/dpop.js +3 -3
- package/build/src/agents/poppy/email_code_sign_in.d.ts +4 -4
- package/build/src/agents/poppy/email_code_sign_in.js +5 -5
- package/build/src/agents/poppy/errors.d.ts +7 -2
- package/build/src/agents/poppy/errors.js +5 -2
- package/build/src/agents/poppy/resource.d.ts +30 -25
- package/build/src/agents/poppy/resource.js +24 -20
- package/build/src/agents/poppy/safe_fetch.js +8 -2
- package/build/src/agents/poppy/service.d.ts +69 -62
- package/build/src/agents/poppy/service.js +540 -546
- package/build/src/agents/poppy/session_jwt.d.ts +30 -0
- package/build/src/agents/poppy/session_jwt.js +133 -0
- package/build/src/agents/poppy/store.d.ts +17 -22
- package/build/src/agents/poppy/store.js +22 -30
- package/build/src/agents/poppy/web_session.d.ts +23 -16
- package/build/src/agents/poppy/web_session.js +42 -24
- package/build/src/host/admin_sessions_service.js +3 -3
- package/build/src/host/controllers/account_apps_controller.js +1 -1
- package/build/src/host/controllers/poppy_consent_controller.d.ts +2 -2
- package/build/src/host/controllers/poppy_consent_controller.js +2 -2
- package/build/src/host/controllers/poppy_controller.d.ts +19 -11
- package/build/src/host/controllers/poppy_controller.js +93 -68
- package/build/src/host/csrf.d.ts +2 -4
- package/build/src/host/csrf.js +2 -3
- package/build/src/host/register_auth_host.js +10 -5
- package/build/src/schema/ensure.js +14 -9
- package/package.json +3 -3
|
@@ -4,10 +4,11 @@ import type { PoppyClient, PoppyClientRegistry } from './client_registry.js';
|
|
|
4
4
|
import type { PoppyLimiter, PoppyPrincipalBase, PoppyReplayStore, ResolvedPoppyConfig } from './config.js';
|
|
5
5
|
import { type DpopNonceSource } from './dpop.js';
|
|
6
6
|
import type { PoppyStore, RequestRow } from './store.js';
|
|
7
|
-
export declare const JWT_BEARER_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
8
7
|
export declare const DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
8
|
+
export declare const MEDIATED_SIGN_IN_GRANT = "https://personalagentprotocol.org/grant/mediated-sign-in";
|
|
9
|
+
export declare const MEDIATED_SIGN_IN_EXTENSION = "mediated-sign-in";
|
|
9
10
|
export declare const CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
|
|
10
|
-
export declare const
|
|
11
|
+
export declare const POPPY_PROTOCOL_VERSION = "0.3";
|
|
11
12
|
/** URLs públicas do authorization server Poppy. */
|
|
12
13
|
export interface PoppyUrls {
|
|
13
14
|
origin: string;
|
|
@@ -20,29 +21,25 @@ export interface PoppyUrls {
|
|
|
20
21
|
deviceAuthorization: string;
|
|
21
22
|
/** Tela do device flow (`verification_uri`). */
|
|
22
23
|
device: string;
|
|
23
|
-
mediated: string;
|
|
24
24
|
browserSession: string;
|
|
25
25
|
discovery: string;
|
|
26
26
|
}
|
|
27
27
|
/** Deriva as URLs da ORIGEM do issuer configurado — nunca do Host da request. */
|
|
28
28
|
export declare function poppyUrls(oidcIssuer: string, prefix: string): PoppyUrls;
|
|
29
|
-
/** Resposta do token endpoint (§4.
|
|
29
|
+
/** Resposta do token endpoint (§4.7, RFC 6749 §5.1). */
|
|
30
30
|
export interface PoppyTokenResponse {
|
|
31
31
|
access_token: string;
|
|
32
32
|
token_type: 'DPoP' | 'Bearer';
|
|
33
33
|
expires_in: number;
|
|
34
34
|
scope: string;
|
|
35
|
-
session_id: string;
|
|
36
|
-
signed_in: boolean;
|
|
37
35
|
refresh_token?: string;
|
|
38
|
-
refresh_token_expires_in?: number;
|
|
39
36
|
}
|
|
40
|
-
/** Ponte com o oidc-provider para os tokens Bearer de MCP (§
|
|
37
|
+
/** Ponte com o oidc-provider para os tokens Bearer de MCP (§7). */
|
|
41
38
|
export interface PoppyMcpBridge {
|
|
42
39
|
/** `url` é um servidor MCP deste app (de `apis` ou do registro de resources)? */
|
|
43
40
|
isMcpResource(url: string): boolean;
|
|
44
41
|
/**
|
|
45
|
-
* Emite o Bearer de
|
|
42
|
+
* Emite o Bearer de um sign-in como access token do oidc-provider,
|
|
46
43
|
* para que a integração MCP existente (`AccessToken.find`) o aceite. `null` =
|
|
47
44
|
* sem ponte (o token fica só no store do Poppy).
|
|
48
45
|
*/
|
|
@@ -79,9 +76,9 @@ export interface PoppyRequestInput {
|
|
|
79
76
|
headers: Record<string, string | string[] | undefined>;
|
|
80
77
|
}
|
|
81
78
|
export interface PoppyVerifyOptions {
|
|
82
|
-
/** Scopes exigidos (todos).
|
|
79
|
+
/** Scopes exigidos (todos). Sem access token: challenge 401; sem o scope: `insufficient_scope`. */
|
|
83
80
|
scopes?: string[];
|
|
84
|
-
/** Exige
|
|
81
|
+
/** Exige acesso à conta (um access token). */
|
|
85
82
|
signedIn?: boolean;
|
|
86
83
|
/**
|
|
87
84
|
* `resource` exigido por este endpoint. Default: derivado da URL contra
|
|
@@ -89,19 +86,22 @@ export interface PoppyVerifyOptions {
|
|
|
89
86
|
*/
|
|
90
87
|
resource?: string | null;
|
|
91
88
|
}
|
|
92
|
-
export type PoppyAuthError = '
|
|
89
|
+
export type PoppyAuthError = 'invalid_session' | 'invalid_token' | 'insufficient_scope' | 'invalid_dpop_proof' | 'use_dpop_nonce';
|
|
93
90
|
export type PoppyVerifyResult = {
|
|
94
91
|
ok: true;
|
|
95
92
|
principal: PoppyPrincipalBase;
|
|
96
|
-
|
|
93
|
+
/** Grant (refresh token) do access token — `null` deslogado. */
|
|
94
|
+
grantId: string | null;
|
|
97
95
|
} | {
|
|
98
96
|
ok: false;
|
|
99
|
-
status: 401 | 403;
|
|
100
|
-
|
|
97
|
+
status: 400 | 401 | 403 | 429;
|
|
98
|
+
/** `null`: challenge sem código (§7, falta o access token) ou limite de taxa (§5.6). */
|
|
99
|
+
error: PoppyAuthError | null;
|
|
101
100
|
description: string;
|
|
102
101
|
scope?: string;
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
/** `null` nos erros que vão no corpo (`invalid_session`) e no 429. */
|
|
103
|
+
wwwAuthenticate: string | null;
|
|
104
|
+
/** Headers extras (`DPoP-Nonce`, `Retry-After`). */
|
|
105
105
|
headers: Record<string, string>;
|
|
106
106
|
};
|
|
107
107
|
/** Pedido Direct aguardando o usuário na tela de consentimento. */
|
|
@@ -138,29 +138,17 @@ export interface PoppyGrantSummary {
|
|
|
138
138
|
updatedAt: Date;
|
|
139
139
|
expiresAt: Date;
|
|
140
140
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} & PoppyTokenResponse) | {
|
|
144
|
-
status: 'code_required';
|
|
145
|
-
sign_in_id: string;
|
|
146
|
-
code: {
|
|
147
|
-
sent_to: string;
|
|
148
|
-
};
|
|
149
|
-
expires_at: string;
|
|
150
|
-
} | {
|
|
151
|
-
status: 'failed';
|
|
152
|
-
} | {
|
|
153
|
-
status: 'expired';
|
|
154
|
-
};
|
|
155
|
-
export interface PoppyBrowserSessionResult {
|
|
141
|
+
/** O que a entrada de um navegador autorizou (§6, passo 3). */
|
|
142
|
+
export interface PoppyBrowserJoin {
|
|
156
143
|
sessionId: string;
|
|
157
144
|
clientId: string;
|
|
158
145
|
userId: string;
|
|
146
|
+
/** Conta autorizada no passo 2; `null` = entrada sem access token. */
|
|
159
147
|
accountId: string | null;
|
|
148
|
+
grantId: string | null;
|
|
160
149
|
scopes: string[];
|
|
161
|
-
returnTo: string;
|
|
162
150
|
}
|
|
163
|
-
/** Estado atual de
|
|
151
|
+
/** Estado atual de um navegador que entrou numa Session (§6, "The cookie"). */
|
|
164
152
|
export interface PoppySessionState {
|
|
165
153
|
active: boolean;
|
|
166
154
|
sessionId: string;
|
|
@@ -182,10 +170,10 @@ export declare const POPPY_ENDPOINTS_SLOT: unique symbol;
|
|
|
182
170
|
export declare function registeredConversationProtocols(): {
|
|
183
171
|
type: string;
|
|
184
172
|
endpoint: string;
|
|
185
|
-
|
|
173
|
+
access?: 'session' | 'signed_in';
|
|
186
174
|
}[];
|
|
187
175
|
/**
|
|
188
|
-
* @experimental Poppy (Personal Agent Protocol) Draft 0.
|
|
176
|
+
* @experimental Poppy (Personal Agent Protocol) Draft 0.3 — pode mudar de forma incompatível enquanto a spec for draft.
|
|
189
177
|
*/
|
|
190
178
|
export declare class PoppyService {
|
|
191
179
|
#private;
|
|
@@ -202,25 +190,28 @@ export declare class PoppyService {
|
|
|
202
190
|
id: string;
|
|
203
191
|
description: string;
|
|
204
192
|
}[];
|
|
193
|
+
/** `www.{domínio}` não é a empresa (§3.1): a descoberta redireciona para o domínio (§3). */
|
|
194
|
+
discoveryRedirect(requestHost: string): string | null;
|
|
205
195
|
/** `/.well-known/poppy.json` (§3) para o domínio pedido; `null` = domínio que não é nosso. */
|
|
206
196
|
discoveryDocument(requestHost: string): Record<string, unknown> | null;
|
|
207
|
-
/**
|
|
197
|
+
/** `/.well-known/oauth-protected-resource` do domínio (§3.2, RFC 9728): aponta o issuer. */
|
|
198
|
+
protectedResourceMetadata(requestHost: string): Record<string, unknown> | null;
|
|
199
|
+
/** RFC 8414 com `protected_resources` (§3.2). */
|
|
208
200
|
authorizationServerMetadata(): Record<string, unknown>;
|
|
209
201
|
/**
|
|
210
|
-
* `private_key_jwt` (
|
|
211
|
-
*
|
|
212
|
-
* chamado (ou o token endpoint/issuer), `exp` curto, `jti` único.
|
|
202
|
+
* `private_key_jwt` (§4.1, RFC 7523): `client_assertion` assinada por uma chave do `jwks_uri`,
|
|
203
|
+
* `iss` = `sub` = `client_id`, `aud` = o issuer como UMA string, curta, com `iat` e `jti` únicos.
|
|
213
204
|
*/
|
|
214
|
-
authenticateClient(form: Record<string, unknown
|
|
215
|
-
/** `POST token_endpoint` (§4.2
|
|
216
|
-
token(form: Record<string, unknown>, dpopHeader: string | string[] | undefined): Promise<PoppyTokenResponse>;
|
|
205
|
+
authenticateClient(form: Record<string, unknown>): Promise<PoppyClient>;
|
|
206
|
+
/** `POST token_endpoint` (§4.2–§4.4, §4.7, extensão Mediated Sign-In). */
|
|
207
|
+
token(form: Record<string, unknown>, dpopHeader: string | string[] | undefined, ctx?: HttpContext): Promise<PoppyTokenResponse>;
|
|
217
208
|
/** `POST device_authorization_endpoint` (§4.6). */
|
|
218
209
|
deviceAuthorization(form: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
219
|
-
/** `POST revocation_endpoint` (§4.
|
|
210
|
+
/** `POST revocation_endpoint` (§4.6, RFC 7009). */
|
|
220
211
|
revoke(form: Record<string, unknown>): Promise<void>;
|
|
221
212
|
/**
|
|
222
|
-
* Revoga um
|
|
223
|
-
* deslogadas (§
|
|
213
|
+
* Revoga um refresh token (grant): os access tokens dele morrem junto (RFC 7009 §2.1), as
|
|
214
|
+
* Sessions continuam deslogadas (§5.5) e os Bearer de MCP no oidc-provider também caem.
|
|
224
215
|
*/
|
|
225
216
|
revokeGrant(grantId: string): Promise<void>;
|
|
226
217
|
/**
|
|
@@ -255,31 +246,47 @@ export declare class PoppyService {
|
|
|
255
246
|
approved: string[] | null;
|
|
256
247
|
clientId: string;
|
|
257
248
|
} | null>;
|
|
258
|
-
/** `POST auth.mediated.endpoint` — já autenticado pelo Session Token (DPoP). */
|
|
259
|
-
mediatedStart(principal: PoppyPrincipalBase, jkt: string | null, body: unknown, ctx: HttpContext): Promise<PoppyMediatedResponse>;
|
|
260
|
-
/** `POST {mediated}/{sign_in_id}` com o código de uso único. */
|
|
261
|
-
mediatedCode(principal: PoppyPrincipalBase, jkt: string | null, signInId: string, body: unknown): Promise<PoppyMediatedResponse | null>;
|
|
262
249
|
/**
|
|
263
|
-
* Verifica
|
|
264
|
-
*
|
|
250
|
+
* Verifica uma request às APIs/conversas do app: o header `Poppy-Session` (§5.3) e, se houver, o
|
|
251
|
+
* access token (`Authorization: Bearer|DPoP`, com a prova DPoP). Um `sid` novo começa uma Session
|
|
252
|
+
* deslogada; a request é logada só quando traz access token. Nunca lê token da URL (§5.6).
|
|
265
253
|
*/
|
|
266
254
|
verifyAccess(input: PoppyRequestInput, options?: PoppyVerifyOptions): Promise<PoppyVerifyResult>;
|
|
255
|
+
/** Passo 1: gera o código de uso único e o valor do cookie que o prende a este navegador. */
|
|
256
|
+
startBrowserJoin(): Promise<{
|
|
257
|
+
code: string;
|
|
258
|
+
cookie: string;
|
|
259
|
+
maxAge: number;
|
|
260
|
+
}>;
|
|
261
|
+
/**
|
|
262
|
+
* Passo 2: o agente autoriza o código, com o header da Session e, se logado, o access token.
|
|
263
|
+
* `{ ok: true }` = 204; um código inválido lança `invalid_request`.
|
|
264
|
+
*/
|
|
265
|
+
authorizeBrowserJoin(input: PoppyRequestInput, code: unknown): Promise<Extract<PoppyVerifyResult, {
|
|
266
|
+
ok: false;
|
|
267
|
+
}> | {
|
|
268
|
+
ok: true;
|
|
269
|
+
}>;
|
|
267
270
|
/**
|
|
268
|
-
*
|
|
269
|
-
*
|
|
271
|
+
* Passo 3: o navegador submete o código. O primeiro envio o consome, qualquer que seja o
|
|
272
|
+
* resultado; `null` = sem cookie para a Session (página de erro).
|
|
270
273
|
*/
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
|
|
274
|
+
completeBrowserJoin(code: unknown, cookie: unknown): Promise<PoppyBrowserJoin | null>;
|
|
275
|
+
/** O cookie age pela conta e pelos scopes do passo 2, enquanto o refresh token viver (§6). */
|
|
276
|
+
browserState(marker: {
|
|
277
|
+
sessionId: string;
|
|
278
|
+
accountId?: string | null;
|
|
279
|
+
grantId?: string | null;
|
|
280
|
+
scopes?: string[];
|
|
281
|
+
}): Promise<PoppySessionState | null>;
|
|
274
282
|
listGrants(accountId: string): Promise<PoppyGrantSummary[]>;
|
|
275
|
-
/** Desconectar o agente pela conta (§
|
|
283
|
+
/** Desconectar o agente pela conta (§5.5): revoga um refresh token DA CONTA. */
|
|
276
284
|
revokeAccountGrant(accountId: string, grantId: string): Promise<boolean>;
|
|
277
|
-
/** Revoga todos os
|
|
285
|
+
/** Revoga todos os refresh tokens da conta (sair de tudo, conta suspensa…). */
|
|
278
286
|
revokeAllAccountGrants(accountId: string): Promise<number>;
|
|
279
287
|
/**
|
|
280
|
-
* Bloqueio pelo console admin: revoga todos os
|
|
281
|
-
*
|
|
282
|
-
* Devolve quantos Account Tokens estavam vivos.
|
|
288
|
+
* Bloqueio pelo console admin: revoga todos os refresh tokens do agente (todas as contas) e
|
|
289
|
+
* encerra as Sessions dele — param na próxima request. Devolve quantos estavam vivos.
|
|
283
290
|
*/
|
|
284
291
|
disconnectClient(clientId: string): Promise<number>;
|
|
285
292
|
}
|