@hadoku/task-ui-components 4.22.5 → 4.23.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.
@@ -56,6 +56,10 @@ const WHOAMI_GLOBAL = '__hadokuWhoami'
56
56
  *
57
57
  * `passkeys` (edge-router ≥ 2026-10-28) counts the passkeys that sign this
58
58
  * session in. Absent means unknown, never none.
59
+ *
60
+ * `serviceGrants` (edge-router ≥ 2026-10-31) counts the service identities
61
+ * this person may mint their own credentials for; Service access shows only
62
+ * above zero.
59
63
  */
60
64
  interface WhoamiBody {
61
65
  valid?: boolean
@@ -64,6 +68,7 @@ interface WhoamiBody {
64
68
  contentLevel?: number
65
69
  maxContentLevel?: number
66
70
  passkeys?: number
71
+ serviceGrants?: number
67
72
  }
68
73
 
69
74
  // Hard timeout on every settings request. Without it, a request throttled by
@@ -293,6 +298,17 @@ export interface SignInClient {
293
298
  signInWithPasskey?: (opts?: { signal?: AbortSignal }) => Promise<SignInResult>
294
299
  /** Saves a passkey for the signed-in person on this device. Throws Error(message). */
295
300
  addPasskey?: (opts?: { signal?: AbortSignal }) => Promise<{ saved: boolean; passkeys: number }>
301
+ /** A fresh passkey tap from the signed-in person; the assertion to post. Throws Error(message). */
302
+ stepUpPasskey?: (opts?: { signal?: AbortSignal }) => Promise<PasskeyAssertion>
303
+ }
304
+
305
+ /** What `stepUpPasskey` resolves to: the WebAuthn assertion, base64url fields. */
306
+ export interface PasskeyAssertion {
307
+ id: string
308
+ clientDataJSON: string
309
+ authenticatorData: string
310
+ signature: string
311
+ userHandle: string | null
296
312
  }
297
313
 
298
314
  export function loadSignInClient(): Promise<SignInClient | null> {
@@ -308,6 +324,10 @@ export function loadSignInClient(): Promise<SignInClient | null> {
308
324
  addPasskey:
309
325
  typeof m.addPasskey === 'function'
310
326
  ? (m.addPasskey as SignInClient['addPasskey'])
327
+ : undefined,
328
+ stepUpPasskey:
329
+ typeof m.stepUpPasskey === 'function'
330
+ ? (m.stepUpPasskey as SignInClient['stepUpPasskey'])
311
331
  : undefined
312
332
  }
313
333
  : null,
@@ -353,6 +373,8 @@ export interface SettingsSnapshot {
353
373
  content: ContentLevelState | null
354
374
  /** Passkeys that sign this person in; null = unknown (older edge, host-supplied identity). */
355
375
  passkeys: number | null
376
+ /** Service identities this person may mint for; 0 when unknown. */
377
+ serviceGrants: number
356
378
  }
357
379
 
358
380
  /** Identity the host already knows, so we don't ask the server for it again. */
@@ -432,7 +454,12 @@ async function resolveSettings(hints: SettingsPrefetchHints): Promise<SettingsSn
432
454
  contentPromise,
433
455
  bodyPromise
434
456
  ])
435
- return { identity, content, passkeys: passkeysFromWhoami(body) }
457
+ return {
458
+ identity,
459
+ content,
460
+ passkeys: passkeysFromWhoami(body),
461
+ serviceGrants: body?.valid && typeof body.serviceGrants === 'number' ? body.serviceGrants : 0
462
+ }
436
463
  }
437
464
 
438
465
  function passkeysFromWhoami(body: WhoamiBody | null): number | null {