@datalayer/agent-runtimes 1.3.112 → 1.3.113

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.
@@ -133,6 +133,8 @@ export declare class PactPersonalAgent {
133
133
  }): Promise<Reply | StepUp>;
134
134
  private verifyReceipt;
135
135
  requestSignIn(user: string, scopes: string[]): Promise<SignIn>;
136
+ /** Ask once whether the person approved: the scopes granted, or `undefined` while pending. */
137
+ pollSignIn(user: string, signIn: SignIn): Promise<string[] | undefined>;
136
138
  /** Poll until the person approved; the scopes they actually granted. */
137
139
  finishSignIn(user: string, signIn: SignIn, intervalMs?: number, attempts?: number): Promise<string[]>;
138
140
  }
@@ -315,42 +315,48 @@ export class PactPersonalAgent {
315
315
  reference,
316
316
  };
317
317
  }
318
- /** Poll until the person approved; the scopes they actually granted. */
319
- async finishSignIn(user, signIn, intervalMs = 5000, attempts = 120) {
318
+ /** Ask once whether the person approved: the scopes granted, or `undefined` while pending. */
319
+ async pollSignIn(user, signIn) {
320
320
  const card = this.card;
321
321
  const deviceCode = this.pending.get(signIn.reference);
322
322
  if (!deviceCode) {
323
323
  throw new PactError('no sign-in pending under this reference');
324
324
  }
325
+ const answer = await this.fetch(card.delegation.tokenUrl, {
326
+ method: 'POST',
327
+ headers: {
328
+ Authorization: `Bearer ${await this.jwt(user)}`,
329
+ 'Content-Type': 'application/x-www-form-urlencoded',
330
+ },
331
+ body: new URLSearchParams({
332
+ grant_type: DEVICE_CODE_GRANT,
333
+ device_code: deviceCode,
334
+ client_id: this.options.issuer,
335
+ }).toString(),
336
+ });
337
+ const body = await answer.json();
338
+ if (body.error === 'authorization_pending' || body.error === 'slow_down') {
339
+ return undefined;
340
+ }
341
+ if (body.error) {
342
+ this.pending.delete(signIn.reference);
343
+ throw new PactError(`the sign-in ended: ${body.error}`);
344
+ }
345
+ const granted = String(body.scope ?? '')
346
+ .split(' ')
347
+ .filter(Boolean);
348
+ await this.delegations().put(card.interfaceUrl, user, body.access_token, granted);
349
+ this.pending.delete(signIn.reference);
350
+ return granted;
351
+ }
352
+ /** Poll until the person approved; the scopes they actually granted. */
353
+ async finishSignIn(user, signIn, intervalMs = 5000, attempts = 120) {
325
354
  for (let i = 0; i < attempts; i++) {
326
- const answer = await this.fetch(card.delegation.tokenUrl, {
327
- method: 'POST',
328
- headers: {
329
- Authorization: `Bearer ${await this.jwt(user)}`,
330
- 'Content-Type': 'application/x-www-form-urlencoded',
331
- },
332
- body: new URLSearchParams({
333
- grant_type: DEVICE_CODE_GRANT,
334
- device_code: deviceCode,
335
- client_id: this.options.issuer,
336
- }).toString(),
337
- });
338
- const body = await answer.json();
339
- if (body.error === 'authorization_pending' ||
340
- body.error === 'slow_down') {
341
- await new Promise(resolve => setTimeout(resolve, intervalMs));
342
- continue;
355
+ const granted = await this.pollSignIn(user, signIn);
356
+ if (granted) {
357
+ return granted;
343
358
  }
344
- if (body.error) {
345
- this.pending.delete(signIn.reference);
346
- throw new PactError(`the sign-in ended: ${body.error}`);
347
- }
348
- const granted = String(body.scope ?? '')
349
- .split(' ')
350
- .filter(Boolean);
351
- await this.delegations().put(card.interfaceUrl, user, body.access_token, granted);
352
- this.pending.delete(signIn.reference);
353
- return granted;
359
+ await new Promise(resolve => setTimeout(resolve, intervalMs));
354
360
  }
355
361
  throw new PactError('the person did not sign in in time');
356
362
  }
@@ -122,7 +122,7 @@ export async function signRequest(request, signer, options) {
122
122
  label,
123
123
  nonce: options.nonce ?? generateNonce(),
124
124
  signatureAgentKey: label,
125
- additionalComponents: (options.components ?? ['@method', '@path']).filter(name => name !== '@authority'),
125
+ additionalComponents: (options.components ?? ['@method', '@path', '@query']).filter(name => name !== '@authority'),
126
126
  });
127
127
  return {
128
128
  'Signature-Agent': agentHeader,
@@ -486,6 +486,27 @@ export interface AppPapSpec {
486
486
  connections: AppPapConnectionSpec[];
487
487
  company: AppPapCompanySpec;
488
488
  }
489
+ /**
490
+ * A business the application asks for each person over PACT 1.0
491
+ * (AGENT_PROTOCOLS PI-01): its domain, and the audience its Provider
492
+ * assigned. Always in each person's own name; never a credential.
493
+ */
494
+ export interface AppPactConnectionSpec {
495
+ /** Stable within the application: `support`. */
496
+ id: string;
497
+ /** The business's domain: `example.com`; its card is at `/.well-known/agent-card.json`. */
498
+ brand: string;
499
+ /** The audience the Brand's Provider assigned (PACT §3.1). */
500
+ audience: string;
501
+ /** `read`: asks as the application alone; `write`: also for the person, delegated. */
502
+ access: 'read' | 'write';
503
+ /** The Brand's scopes it may ask the person for: `orders:read`. */
504
+ scopes: string[];
505
+ }
506
+ /** PACT: the businesses it asks for each person. */
507
+ export interface AppPactSpec {
508
+ connections: AppPactConnectionSpec[];
509
+ }
489
510
  /** When an application acts alone, and when it asks. */
490
511
  export interface AppRuleSpec {
491
512
  /** The action, in the words a person reads. */
@@ -1044,6 +1065,8 @@ export interface AppSpec {
1044
1065
  connections: AppConnectionSpec[];
1045
1066
  /** Personal Agent Protocol; absent, the application has none. */
1046
1067
  pap?: AppPapSpec;
1068
+ /** PACT: the businesses it asks for each person (AGENT_PROTOCOLS PI-01). */
1069
+ pact?: AppPactSpec;
1047
1070
  rules: AppRuleSpec[];
1048
1071
  permissions: AppPermissionsSpec;
1049
1072
  interface: AppInterfaceSpec;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.3.112",
3
+ "version": "1.3.113",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",