@burnt-labs/expo-satya-attest 0.2.0 → 0.2.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## 0.2.2 - 2026-06-11
4
+
5
+ - Fixed provider WebView login flows that could continuously refresh while the user was still on a login or SSO host.
6
+ - Added a provider login-ready gate for endpoints that return an empty 200 response before authentication, so native replay waits for authenticated content.
7
+ - Added optional verifier bearer-token support for provider policy refresh and backend artifact verification.
8
+ - Updated Garmin profile capture to use the authenticated proxy endpoint and ship without local debug logging.
package/PUBLISHING.md CHANGED
@@ -267,7 +267,7 @@ GitHub release tarball smoke test:
267
267
 
268
268
  ```bash
269
269
  cd /private/tmp/SatyaSmoke
270
- npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v0.2.0/burnt-labs-expo-satya-attest-0.2.0.tgz
270
+ npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v0.2.2/burnt-labs-expo-satya-attest-0.2.2.tgz
271
271
  npx expo install react-native-webview
272
272
  ```
273
273
 
@@ -275,7 +275,7 @@ For a raw Git install, publish the SDK from a dedicated repo or a subtree/split
275
275
  where the SDK package is at the Git root:
276
276
 
277
277
  ```bash
278
- npm install github:<owner>/<sdk-repo>#v0.2.0
278
+ npm install github:<owner>/<sdk-repo>#v0.2.2
279
279
  ```
280
280
 
281
281
  Do not document a normal monorepo Git URL as plug-and-play unless the Git ref has
package/README.md CHANGED
@@ -196,7 +196,7 @@ is a release tarball produced by `npm pack`, because it contains the same files
196
196
  would publish:
197
197
 
198
198
  ```bash
199
- npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v0.2.0/burnt-labs-expo-satya-attest-0.2.0.tgz
199
+ npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v0.2.2/burnt-labs-expo-satya-attest-0.2.2.tgz
200
200
  npx expo install react-native-webview
201
201
  ```
202
202
 
@@ -204,8 +204,8 @@ Installing from a Git ref also works when that ref has the SDK package at the re
204
204
  root, such as a dedicated SDK repo or a subtree/split branch:
205
205
 
206
206
  ```bash
207
- npm install github:<owner>/<sdk-repo>#v0.2.0
208
- npm install git+https://github.com/<owner>/<sdk-repo>.git#v0.2.0
207
+ npm install github:<owner>/<sdk-repo>#v0.2.2
208
+ npm install git+https://github.com/<owner>/<sdk-repo>.git#v0.2.2
209
209
  npx expo install react-native-webview
210
210
  ```
211
211
 
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'expo.modules.satyaattest'
7
- version = '0.1.0'
7
+ version = '0.2.2'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.satyaattest"
11
11
  defaultConfig {
12
12
  versionCode 1
13
- versionName "0.1.0"
13
+ versionName "0.2.2"
14
14
  // StrongBox key attestation needs API 28+; basic Keystore attestation API 24+.
15
15
  minSdkVersion 24
16
16
  }
@@ -7,6 +7,11 @@ export interface SatyaTransportConfig {
7
7
  notaryUrl: string;
8
8
  trustedNotaryKeys?: string[];
9
9
  enableLogging?: boolean;
10
+ /**
11
+ * Optional bearer token for verifier HTTP calls such as provider-policy refresh and
12
+ * backend artifact verification. This token is not sent to provider replay requests.
13
+ */
14
+ verifierBearerToken?: string;
10
15
  /**
11
16
  * Google Cloud project NUMBER (not the project id) for Play Integrity classic
12
17
  * requests on Android. When > 0 the native module requests a real Play Integrity
@@ -1 +1 @@
1
- {"version":3,"file":"SatyaAttest.types.d.ts","sourceRoot":"","sources":["../src/SatyaAttest.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SatyaAttest.types.d.ts","sourceRoot":"","sources":["../src/SatyaAttest.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SatyaAttest.types.js","sourceRoot":"","sources":["../src/SatyaAttest.types.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,uEAAuE;AAkVvE,6CAA6C;AAC7C,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF","sourcesContent":["// Public types for expo-satya-attest. These mirror the SATYA-W artifact contract\n// and the Flutter plugin's client API so the two stay interchangeable.\n\n// The mock and webview-observed modes were removed as insecure: mock produces a\n// canned value with no real connection, and webview-observed signs an app-asserted\n// value the page/JS can tamper with. Only the certificate-pinned native replay tier\n// remains.\n\n/** Artifact mode as it appears in the JSON (`mode` / `statement.mode`). */\nexport type SatyaArtifactMode = 'native-pinned-observed';\n\n/** Lifecycle phases emitted as scripted progress by {@link SatyaMobileClient}. */\nexport type SatyaPhase =\n | 'init'\n | 'witnessEnrollment'\n | 'notaryChallenge'\n | 'witnessTlsSetup'\n | 'tlsHandshake'\n | 'recordExchange'\n | 'selectiveReveal'\n | 'witnessFinalize'\n | 'notaryFinalize'\n | 'verified'\n | 'failed';\n\n/** Transport/runtime config passed to the client (serialized to `configJson`). */\nexport interface SatyaTransportConfig {\n notaryUrl: string;\n trustedNotaryKeys?: string[];\n enableLogging?: boolean;\n /**\n * Google Cloud project NUMBER (not the project id) for Play Integrity classic\n * requests on Android. When > 0 the native module requests a real Play Integrity\n * token bound to the witness key; 0 (the default) keeps the honest dev fallback\n * (no token → the verifier fails closed under a pass-2 policy). Ignored on iOS.\n */\n cloudProjectNumber?: number;\n}\n\n/** A single scripted progress event. */\nexport interface SatyaProgress {\n phase: SatyaPhase;\n message: string;\n /** 0..1 */\n percent: number;\n}\n\n/** A selectable provider from the catalog. */\nexport interface SatyaProviderEndpointRef {\n id: string;\n method: string;\n url: string;\n responseType?: string;\n}\n\nexport interface SatyaProviderRef {\n label: string;\n description: string;\n providerId: string;\n iconUrl?: string;\n endpoints?: SatyaProviderEndpointRef[];\n}\n\nexport interface SatyaProviderRegistry {\n schemaVersion?: string;\n providers: SatyaProviderTemplate[];\n}\n\nexport interface SatyaProviderRegistryUrlSource {\n /**\n * HTTPS URL returning a JSON object with `{ schemaVersion, providers }`.\n * `http://` is rejected unless `allowInsecureHttp` is explicitly set for local/dev use.\n */\n url: string;\n /**\n * Optional request headers for private registries. Prefer bearer tokens over credentials\n * in the URL; registry URLs with username/password are rejected by the SDK.\n */\n headers?: Record<string, string>;\n /** Request timeout in milliseconds. Defaults to 15000. */\n timeoutMs?: number;\n /** Maximum response body size in bytes. Defaults to 524288. */\n maxBytes?: number;\n /**\n * Allows `http://` registry URLs. Keep this false outside local development; provider\n * registry contents decide which hosts and templates the SDK will replay.\n */\n allowInsecureHttp?: boolean;\n}\n\nexport type SatyaProviderRegistrySource =\n | SatyaProviderRegistry\n | { registry: SatyaProviderRegistry }\n | SatyaProviderRegistryUrlSource;\n\nexport type SatyaProviderInjection = string | string[];\n\n/**\n * A single response-body reveal that the native replay extracts into a disclosed claim.\n *\n * - `json`: read the value at `path` (a `$.a.b[0].c` JSON path) from a JSON body.\n * - `regex`: match `pattern` against the raw response body (HTML, text, or JSON) and\n * disclose capture `group` (defaults to 1; may be a numbered index or a named group).\n * - `jsonRegex`: read the string value at `path` from a JSON body, then match `pattern`\n * against it and disclose capture `group`.\n *\n * `regex` and `jsonRegex` require an explicit `alias`.\n */\nexport interface ResponseRevealRule {\n alias: string;\n type: 'json' | 'regex' | 'jsonRegex';\n path?: string;\n pattern?: string;\n group?: number | string;\n}\n\nexport interface SatyaProviderLogin {\n url: string;\n [key: string]: unknown;\n}\n\nexport interface SatyaProviderEndpoint {\n id: string;\n url: string;\n method: string;\n headers: string[];\n responseType: string;\n requestMatchRules: Record<string, unknown>[];\n revealRules: Record<string, unknown>[];\n /**\n * When true, the SDK actively fires this endpoint's request from inside the managed\n * WebView (via an injected `fetch`) once the user is logged in, instead of waiting for\n * the page to make the call. Capture is gated on a 2xx response, so it never triggers\n * the native replay before login. Use for cookie-authenticated APIs that no page calls\n * on its own (e.g. Reddit/Spotify/Roblox profile APIs).\n */\n triggerFromInjection?: boolean;\n /**\n * Extra request headers for the injected active fetch (only used with\n * `triggerFromInjection`). Values may be literals or `{{cookie:NAME}}` templates resolved\n * from `document.cookie` at fire time (for non-httpOnly CSRF/app-id headers). Header\n * names are automatically added to the request-header allowlist for native replay.\n */\n injectionHeaders?: Record<string, string>;\n /** Request body for the injected active fetch (POST/PUT/PATCH endpoints). */\n requestBody?: string;\n /**\n * HTTPS page on the proof origin to navigate to when the active fetch is stuck on a\n * sibling subdomain (e.g. after login Spotify lands on `open.spotify.com` but the API is\n * on `www.spotify.com`). Prefer a stable signed-in page that itself loads the proof API.\n * Defaults to the proof origin root (`https://<host>/`) when omitted.\n */\n injectionLandingUrl?: string;\n /** Poll interval in ms for the active fetch (default 2000, bounded 500..15000). */\n injectionPollMs?: number;\n /** Max active-fetch attempts before giving up (default 60, bounded 1..300). */\n injectionMaxAttempts?: number;\n /**\n * Replay the URL the WebView actually fetched, instead of the fixed template `url`. Use for\n * endpoints whose path has a dynamic segment (e.g. a user id, like Garmin's\n * `/userprofile-service/socialProfile/{userId}`) so native replay hits the real per-user URL.\n * The captured URL is still constrained to the pinned host and the endpoint's match rules.\n */\n replayCapturedUrl?: boolean;\n [key: string]: unknown;\n}\n\nexport interface SatyaProviderTemplate {\n schemaVersion: string;\n providerId: string;\n name: string;\n iconUrl?: string;\n login: SatyaProviderLogin;\n auth?: Record<string, unknown>;\n endpoints: SatyaProviderEndpoint[];\n selectedEndpointId?: string;\n /** SDK-normalized compatibility fields used by native replay. */\n label?: string;\n description?: string;\n displayName?: string;\n version?: string;\n target?: {\n scheme: 'https';\n host: string;\n port: number;\n };\n webLogin?: {\n startUrl: string;\n callbackUrl?: string;\n oauthHosts?: string[];\n };\n userAgent?: {\n ios?: string | null;\n android?: string | null;\n } | null;\n /**\n * Provider-owned JavaScript to run inside the managed WebView on every page,\n * alongside the SDK request interceptor. Provider registries are trusted policy:\n * do not load this field from an untrusted source.\n */\n injection?: SatyaProviderInjection | null;\n proofTarget?: {\n method: string;\n url: string;\n requestMatchRules: Record<string, unknown>[];\n revealRules: Record<string, unknown>[];\n [key: string]: unknown;\n };\n privacyPolicy?: {\n allowedRequestHeaders: string[];\n /**\n * JSON paths the proof may read from the response body. Subset of\n * {@link ResponseRevealRule}s whose type is `json` or `jsonRegex`. Kept for\n * backward compatibility; native extraction prefers `allowedResponseReveals`.\n */\n allowedResponseBodyJsonPaths: string[];\n /**\n * Structured response reveals the native replay extracts into disclosed claims.\n * Supports JSON paths plus regex (over the raw HTML/text/JSON body) and jsonRegex\n * (a JSON-path-selected value run through a regex).\n */\n allowedResponseReveals?: ResponseRevealRule[];\n };\n tlsPolicy?: {\n requireTls13: boolean;\n allowZeroRtt: boolean;\n allowResumption: boolean;\n allowKeyUpdate: boolean;\n preferredCipher: string;\n maxSentBytes: number;\n maxRecvBytes: number;\n };\n tlsIdentityPolicy: {\n expectedSni: string;\n allowedAlpn?: string[];\n spkiSha256Hex?: string | null;\n spkiSha256B64Pins?: string[];\n tlsTrustStorePolicy?: 'web-pki-os-roots-no-user-roots';\n userRootsAllowed?: false;\n redirectPolicyId?: string;\n };\n templateGovernance: {\n templateHash: string;\n parserHash: string;\n fixtureSetHash?: string;\n governancePolicyVersion?: string;\n providerActivationState?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface SatyaProviderPolicy {\n providerId: string;\n host: string;\n templateHash: string;\n parserHash: string;\n providerActivationState: string;\n spkiSha256B64Pins: string[];\n}\n\nexport interface CapturedProviderRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: string | null;\n}\n\nexport interface CapturedProviderResponse {\n url: string;\n status: number;\n headers: Record<string, string>;\n body?: string | null;\n}\n\nexport interface NativeReplayTlsEvidence {\n serverCertChainSha256Hex: string;\n sni: string;\n alpn: string;\n tlsVersion: string;\n tlsTrustStorePolicy: 'web-pki-os-roots-no-user-roots';\n userRootsAllowed: false;\n matchedSpkiSha256B64?: string | null;\n expectedSpkiPinsB64: string[];\n}\n\nexport interface NativeReplayClaim {\n name: string;\n sourcePath: string;\n value: unknown;\n}\n\nexport interface NativeReplayObservation {\n providerId: string;\n templateHash: string;\n host: string;\n method: string;\n pathAndQuery: string;\n statusCode: number;\n finalUrl: string;\n contentType?: string | null;\n contentEncoding?: string | null;\n responseSha256Hex: string;\n claims: NativeReplayClaim[];\n tlsEvidence: NativeReplayTlsEvidence;\n}\n\n/** Structured verifier outcome returned by the Rust core. */\nexport interface VerifyResult {\n ok: boolean;\n attestationId: string;\n mode: string;\n platformTier: string;\n /** `dev-local` for the mock tier, `dev-device` for attested/simulator tiers. */\n policy: string;\n disclosedUsername?: string | null;\n error?: string | null;\n}\n\n/**\n * The decoded SATYA-W artifact. Only the commonly-read fields are typed; the rest\n * of the (camelCase) graph is preserved under the index signature.\n */\nexport interface SatyaArtifact {\n schemaVersion: string;\n attestationId: string;\n createdAtUtc: string;\n mode: SatyaArtifactMode;\n statement: Record<string, unknown>;\n semanticStatement: Record<string, unknown>;\n /** Legacy/full artifact disclosure. Compact native replay artifacts use disclosedClaims instead. */\n disclosure?: Record<string, unknown>;\n witnessCommitment: Record<string, unknown>;\n witnessSignature: Record<string, unknown>;\n notarySignature: Record<string, unknown>;\n /** Legacy operational metrics. New proof artifacts omit this field. */\n telemetry?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/** Error thrown by the high-level client. */\nexport class SatyaError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SatyaError';\n }\n}\n"]}
1
+ {"version":3,"file":"SatyaAttest.types.js","sourceRoot":"","sources":["../src/SatyaAttest.types.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,uEAAuE;AAuVvE,6CAA6C;AAC7C,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF","sourcesContent":["// Public types for expo-satya-attest. These mirror the SATYA-W artifact contract\n// and the Flutter plugin's client API so the two stay interchangeable.\n\n// The mock and webview-observed modes were removed as insecure: mock produces a\n// canned value with no real connection, and webview-observed signs an app-asserted\n// value the page/JS can tamper with. Only the certificate-pinned native replay tier\n// remains.\n\n/** Artifact mode as it appears in the JSON (`mode` / `statement.mode`). */\nexport type SatyaArtifactMode = 'native-pinned-observed';\n\n/** Lifecycle phases emitted as scripted progress by {@link SatyaMobileClient}. */\nexport type SatyaPhase =\n | 'init'\n | 'witnessEnrollment'\n | 'notaryChallenge'\n | 'witnessTlsSetup'\n | 'tlsHandshake'\n | 'recordExchange'\n | 'selectiveReveal'\n | 'witnessFinalize'\n | 'notaryFinalize'\n | 'verified'\n | 'failed';\n\n/** Transport/runtime config passed to the client (serialized to `configJson`). */\nexport interface SatyaTransportConfig {\n notaryUrl: string;\n trustedNotaryKeys?: string[];\n enableLogging?: boolean;\n /**\n * Optional bearer token for verifier HTTP calls such as provider-policy refresh and\n * backend artifact verification. This token is not sent to provider replay requests.\n */\n verifierBearerToken?: string;\n /**\n * Google Cloud project NUMBER (not the project id) for Play Integrity classic\n * requests on Android. When > 0 the native module requests a real Play Integrity\n * token bound to the witness key; 0 (the default) keeps the honest dev fallback\n * (no token → the verifier fails closed under a pass-2 policy). Ignored on iOS.\n */\n cloudProjectNumber?: number;\n}\n\n/** A single scripted progress event. */\nexport interface SatyaProgress {\n phase: SatyaPhase;\n message: string;\n /** 0..1 */\n percent: number;\n}\n\n/** A selectable provider from the catalog. */\nexport interface SatyaProviderEndpointRef {\n id: string;\n method: string;\n url: string;\n responseType?: string;\n}\n\nexport interface SatyaProviderRef {\n label: string;\n description: string;\n providerId: string;\n iconUrl?: string;\n endpoints?: SatyaProviderEndpointRef[];\n}\n\nexport interface SatyaProviderRegistry {\n schemaVersion?: string;\n providers: SatyaProviderTemplate[];\n}\n\nexport interface SatyaProviderRegistryUrlSource {\n /**\n * HTTPS URL returning a JSON object with `{ schemaVersion, providers }`.\n * `http://` is rejected unless `allowInsecureHttp` is explicitly set for local/dev use.\n */\n url: string;\n /**\n * Optional request headers for private registries. Prefer bearer tokens over credentials\n * in the URL; registry URLs with username/password are rejected by the SDK.\n */\n headers?: Record<string, string>;\n /** Request timeout in milliseconds. Defaults to 15000. */\n timeoutMs?: number;\n /** Maximum response body size in bytes. Defaults to 524288. */\n maxBytes?: number;\n /**\n * Allows `http://` registry URLs. Keep this false outside local development; provider\n * registry contents decide which hosts and templates the SDK will replay.\n */\n allowInsecureHttp?: boolean;\n}\n\nexport type SatyaProviderRegistrySource =\n | SatyaProviderRegistry\n | { registry: SatyaProviderRegistry }\n | SatyaProviderRegistryUrlSource;\n\nexport type SatyaProviderInjection = string | string[];\n\n/**\n * A single response-body reveal that the native replay extracts into a disclosed claim.\n *\n * - `json`: read the value at `path` (a `$.a.b[0].c` JSON path) from a JSON body.\n * - `regex`: match `pattern` against the raw response body (HTML, text, or JSON) and\n * disclose capture `group` (defaults to 1; may be a numbered index or a named group).\n * - `jsonRegex`: read the string value at `path` from a JSON body, then match `pattern`\n * against it and disclose capture `group`.\n *\n * `regex` and `jsonRegex` require an explicit `alias`.\n */\nexport interface ResponseRevealRule {\n alias: string;\n type: 'json' | 'regex' | 'jsonRegex';\n path?: string;\n pattern?: string;\n group?: number | string;\n}\n\nexport interface SatyaProviderLogin {\n url: string;\n [key: string]: unknown;\n}\n\nexport interface SatyaProviderEndpoint {\n id: string;\n url: string;\n method: string;\n headers: string[];\n responseType: string;\n requestMatchRules: Record<string, unknown>[];\n revealRules: Record<string, unknown>[];\n /**\n * When true, the SDK actively fires this endpoint's request from inside the managed\n * WebView (via an injected `fetch`) once the user is logged in, instead of waiting for\n * the page to make the call. Capture is gated on a 2xx response, so it never triggers\n * the native replay before login. Use for cookie-authenticated APIs that no page calls\n * on its own (e.g. Reddit/Spotify/Roblox profile APIs).\n */\n triggerFromInjection?: boolean;\n /**\n * Extra request headers for the injected active fetch (only used with\n * `triggerFromInjection`). Values may be literals or `{{cookie:NAME}}` templates resolved\n * from `document.cookie` at fire time (for non-httpOnly CSRF/app-id headers). Header\n * names are automatically added to the request-header allowlist for native replay.\n */\n injectionHeaders?: Record<string, string>;\n /** Request body for the injected active fetch (POST/PUT/PATCH endpoints). */\n requestBody?: string;\n /**\n * HTTPS page on the proof origin to navigate to when the active fetch is stuck on a\n * sibling subdomain (e.g. after login Spotify lands on `open.spotify.com` but the API is\n * on `www.spotify.com`). Prefer a stable signed-in page that itself loads the proof API.\n * Defaults to the proof origin root (`https://<host>/`) when omitted.\n */\n injectionLandingUrl?: string;\n /** Poll interval in ms for the active fetch (default 2000, bounded 500..15000). */\n injectionPollMs?: number;\n /** Max active-fetch attempts before giving up (default 60, bounded 1..300). */\n injectionMaxAttempts?: number;\n /**\n * Replay the URL the WebView actually fetched, instead of the fixed template `url`. Use for\n * endpoints whose path has a dynamic segment (e.g. a user id, like Garmin's\n * `/userprofile-service/socialProfile/{userId}`) so native replay hits the real per-user URL.\n * The captured URL is still constrained to the pinned host and the endpoint's match rules.\n */\n replayCapturedUrl?: boolean;\n [key: string]: unknown;\n}\n\nexport interface SatyaProviderTemplate {\n schemaVersion: string;\n providerId: string;\n name: string;\n iconUrl?: string;\n login: SatyaProviderLogin;\n auth?: Record<string, unknown>;\n endpoints: SatyaProviderEndpoint[];\n selectedEndpointId?: string;\n /** SDK-normalized compatibility fields used by native replay. */\n label?: string;\n description?: string;\n displayName?: string;\n version?: string;\n target?: {\n scheme: 'https';\n host: string;\n port: number;\n };\n webLogin?: {\n startUrl: string;\n callbackUrl?: string;\n oauthHosts?: string[];\n };\n userAgent?: {\n ios?: string | null;\n android?: string | null;\n } | null;\n /**\n * Provider-owned JavaScript to run inside the managed WebView on every page,\n * alongside the SDK request interceptor. Provider registries are trusted policy:\n * do not load this field from an untrusted source.\n */\n injection?: SatyaProviderInjection | null;\n proofTarget?: {\n method: string;\n url: string;\n requestMatchRules: Record<string, unknown>[];\n revealRules: Record<string, unknown>[];\n [key: string]: unknown;\n };\n privacyPolicy?: {\n allowedRequestHeaders: string[];\n /**\n * JSON paths the proof may read from the response body. Subset of\n * {@link ResponseRevealRule}s whose type is `json` or `jsonRegex`. Kept for\n * backward compatibility; native extraction prefers `allowedResponseReveals`.\n */\n allowedResponseBodyJsonPaths: string[];\n /**\n * Structured response reveals the native replay extracts into disclosed claims.\n * Supports JSON paths plus regex (over the raw HTML/text/JSON body) and jsonRegex\n * (a JSON-path-selected value run through a regex).\n */\n allowedResponseReveals?: ResponseRevealRule[];\n };\n tlsPolicy?: {\n requireTls13: boolean;\n allowZeroRtt: boolean;\n allowResumption: boolean;\n allowKeyUpdate: boolean;\n preferredCipher: string;\n maxSentBytes: number;\n maxRecvBytes: number;\n };\n tlsIdentityPolicy: {\n expectedSni: string;\n allowedAlpn?: string[];\n spkiSha256Hex?: string | null;\n spkiSha256B64Pins?: string[];\n tlsTrustStorePolicy?: 'web-pki-os-roots-no-user-roots';\n userRootsAllowed?: false;\n redirectPolicyId?: string;\n };\n templateGovernance: {\n templateHash: string;\n parserHash: string;\n fixtureSetHash?: string;\n governancePolicyVersion?: string;\n providerActivationState?: string;\n };\n [key: string]: unknown;\n}\n\nexport interface SatyaProviderPolicy {\n providerId: string;\n host: string;\n templateHash: string;\n parserHash: string;\n providerActivationState: string;\n spkiSha256B64Pins: string[];\n}\n\nexport interface CapturedProviderRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n body?: string | null;\n}\n\nexport interface CapturedProviderResponse {\n url: string;\n status: number;\n headers: Record<string, string>;\n body?: string | null;\n}\n\nexport interface NativeReplayTlsEvidence {\n serverCertChainSha256Hex: string;\n sni: string;\n alpn: string;\n tlsVersion: string;\n tlsTrustStorePolicy: 'web-pki-os-roots-no-user-roots';\n userRootsAllowed: false;\n matchedSpkiSha256B64?: string | null;\n expectedSpkiPinsB64: string[];\n}\n\nexport interface NativeReplayClaim {\n name: string;\n sourcePath: string;\n value: unknown;\n}\n\nexport interface NativeReplayObservation {\n providerId: string;\n templateHash: string;\n host: string;\n method: string;\n pathAndQuery: string;\n statusCode: number;\n finalUrl: string;\n contentType?: string | null;\n contentEncoding?: string | null;\n responseSha256Hex: string;\n claims: NativeReplayClaim[];\n tlsEvidence: NativeReplayTlsEvidence;\n}\n\n/** Structured verifier outcome returned by the Rust core. */\nexport interface VerifyResult {\n ok: boolean;\n attestationId: string;\n mode: string;\n platformTier: string;\n /** `dev-local` for the mock tier, `dev-device` for attested/simulator tiers. */\n policy: string;\n disclosedUsername?: string | null;\n error?: string | null;\n}\n\n/**\n * The decoded SATYA-W artifact. Only the commonly-read fields are typed; the rest\n * of the (camelCase) graph is preserved under the index signature.\n */\nexport interface SatyaArtifact {\n schemaVersion: string;\n attestationId: string;\n createdAtUtc: string;\n mode: SatyaArtifactMode;\n statement: Record<string, unknown>;\n semanticStatement: Record<string, unknown>;\n /** Legacy/full artifact disclosure. Compact native replay artifacts use disclosedClaims instead. */\n disclosure?: Record<string, unknown>;\n witnessCommitment: Record<string, unknown>;\n witnessSignature: Record<string, unknown>;\n notarySignature: Record<string, unknown>;\n /** Legacy operational metrics. New proof artifacts omit this field. */\n telemetry?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/** Error thrown by the high-level client. */\nexport class SatyaError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SatyaError';\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SatyaProviderAttestButton.d.ts","sourceRoot":"","sources":["../src/SatyaProviderAttestButton.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SatyaProviderAttestButton.d.ts","sourceRoot":"","sources":["../src/SatyaProviderAttestButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAcjF,OAAO,EACL,uBAAuB,EAGvB,UAAU,EAEV,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAkEvE,KAAK,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAmBrE,MAAM,MAAM,sBAAsB,GAC9B,MAAM,GACN,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,UAAU,GACV,QAAQ,GACR,WAAW,GACX,UAAU,CAAC;AAEf,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,sBAAsB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,8BAA+B,SAAQ,aAAa;IACnE,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,2BAA2B,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,8BAA8B,CAAC;IACvD,eAAe,EAAE,oBAAoB,CAAC;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC3D,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,EAAE,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAChG,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,8BAA8B,KAAK,IAAI,CAAC;IAC9D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAiBD,wBAAgB,yBAAyB,CAAC,EACxC,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,QAAQ,EACR,qBAAwC,EACxC,eAAe,EACf,MAAM,EAAE,cAAc,EACtB,aAAqB,EACrB,WAAoC,EACpC,QAAgB,EAChB,UAAU,EACV,mBAA0B,EAC1B,gBAAgB,EAAE,eAAe,EACjC,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,QAAQ,GACT,EAAE,8BAA8B,qBAiiChC"}
@@ -6,6 +6,31 @@ import { SatyaMobileClient } from './SatyaMobileClient';
6
6
  import { fetchVerifierProviderPolicy, validateProviderPolicyForTemplate } from './providerPolicy';
7
7
  import { loadProviderRegistry, requestMatchesProviderTemplate, requireProviderTemplate, validateProviderTemplate, withProviderSpkiPins, } from './providerRegistry';
8
8
  import { buildActiveFetchScript, buildProviderDocumentStartScript, buildProviderPopupBridgeScript, buildProviderWebViewScript, } from './providerWebview';
9
+ // Native-replay host retarget (see Garmin connectapi): capture the SPA's request on the
10
+ // browser-reachable cookie host, then rewrite it to the pinned API host and inject the DI
11
+ // bearer so the native (non-CORS, non-Cloudflare) pinned replay can run. The replay host is
12
+ // fixed by trusted template config (`toHost` == pinned expectedSni); only the path comes from
13
+ // the captured (match-rule-constrained) request.
14
+ function rewriteForNativeReplay(request, template, bearer) {
15
+ const proof = template.proofTarget;
16
+ const rw = proof?.nativeReplayRewrite;
17
+ let url = request.url;
18
+ const headers = { ...request.headers };
19
+ if (rw?.fromHost && rw?.toHost) {
20
+ const fromBase = `https://${rw.fromHost}`;
21
+ if (url.startsWith(fromBase)) {
22
+ let rest = url.slice(fromBase.length);
23
+ if (rw.stripPathPrefix && rest.startsWith(rw.stripPathPrefix)) {
24
+ rest = rest.slice(rw.stripPathPrefix.length);
25
+ }
26
+ url = `https://${rw.toHost}${rest}`;
27
+ }
28
+ }
29
+ if (proof?.nativeReplayInjectBearer && bearer) {
30
+ headers.authorization = `Bearer ${bearer}`;
31
+ }
32
+ return { ...request, url, headers };
33
+ }
9
34
  const EMPTY_BROWSER_CHROME = {
10
35
  url: '',
11
36
  title: '',
@@ -29,6 +54,13 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
29
54
  // For `triggerFromInjection` endpoints: the last matching request seen, held until its
30
55
  // response arrives 2xx (login gate) before the native replay is allowed to run.
31
56
  const pendingRequestRef = useRef(null);
57
+ // DI bearer token lifted from the live provider session (e.g. Garmin connectapi), injected
58
+ // into the native replay request for hosts that require Authorization: Bearer.
59
+ const bearerRef = useRef(null);
60
+ // Login-signal gate: provider `injection` posts `__satyaReady` once the proof endpoint
61
+ // returns authenticated content. Some endpoints (e.g. Garmin /proxy/socialProfile) return
62
+ // 200 with an empty body pre-login, which a status-only 2xx gate can't distinguish.
63
+ const loggedInRef = useRef(false);
32
64
  const [modalVisible, setModalVisible] = useState(false);
33
65
  const [phase, setPhase] = useState('idle');
34
66
  const [percent, setPercent] = useState(0);
@@ -84,6 +116,8 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
84
116
  replayStartedRef.current = false;
85
117
  htmlCaptureFetchedRef.current.clear();
86
118
  pendingRequestRef.current = null;
119
+ bearerRef.current = null;
120
+ loggedInRef.current = false;
87
121
  setRunning(true);
88
122
  setCapturedRequest(null);
89
123
  setError(null);
@@ -207,7 +241,7 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
207
241
  providerId: template.providerId,
208
242
  });
209
243
  try {
210
- backendVerify = await postBackendVerifier(transportConfig.notaryUrl, outcome.raw);
244
+ backendVerify = await postBackendVerifier(transportConfig.notaryUrl, outcome.raw, transportConfig.verifierBearerToken);
211
245
  }
212
246
  catch (cause) {
213
247
  const message = cause instanceof Error ? cause.message : String(cause);
@@ -335,15 +369,16 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
335
369
  });
336
370
  }, [emitProgress, providerId, providerTemplate?.providerId, resolved?.template.providerId]);
337
371
  const captureAndReplay = useCallback((request, template) => {
338
- setCapturedRequest(request);
339
- onRequestCaptured?.(request, template);
372
+ const replayRequest = rewriteForNativeReplay(request, template, bearerRef.current);
373
+ setCapturedRequest(replayRequest);
374
+ onRequestCaptured?.(replayRequest, template);
340
375
  emitProgress({
341
376
  phase: 'requestCaptured',
342
377
  message: `Matched ${providerDisplayName(template)} request captured`,
343
378
  percent: 0.08,
344
379
  providerId: template.providerId,
345
380
  });
346
- runReplay(request, template).catch(fail);
381
+ runReplay(replayRequest, template).catch(fail);
347
382
  }, [emitProgress, fail, onRequestCaptured, runReplay]);
348
383
  const handleMessage = useCallback((event) => {
349
384
  invokeWebViewCallback(webViewProps?.onMessage, event);
@@ -384,6 +419,30 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
384
419
  }
385
420
  if (!resolved || replayStartedRef.current)
386
421
  return;
422
+ // DI bearer lifted from the live session by the provider `injection`. Store it, and if a
423
+ // matching request is already held waiting on it, release it to the native replay now.
424
+ if (message.type === '__satyaBearer') {
425
+ const tok = message.data;
426
+ if (tok)
427
+ bearerRef.current = tok;
428
+ const held = pendingRequestRef.current;
429
+ if (held && bearerRef.current) {
430
+ pendingRequestRef.current = null;
431
+ captureAndReplay(held, resolved.template);
432
+ }
433
+ return;
434
+ }
435
+ // Login confirmed by the provider `injection` (the proof endpoint returned authenticated
436
+ // content). Release any held request to the native replay now.
437
+ if (message.type === '__satyaReady') {
438
+ loggedInRef.current = true;
439
+ const held = pendingRequestRef.current;
440
+ if (held) {
441
+ pendingRequestRef.current = null;
442
+ captureAndReplay(held, resolved.template);
443
+ }
444
+ return;
445
+ }
387
446
  const isActiveFetch = !!resolved.template.proofTarget?.triggerFromInjection;
388
447
  // Response-gated capture for `triggerFromInjection` endpoints: the injected active
389
448
  // fetch fires the request repeatedly; only a 2xx response (i.e. the user is logged in)
@@ -395,11 +454,15 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
395
454
  const pending = pendingRequestRef.current;
396
455
  if (!pending)
397
456
  return;
398
- const ok = typeof response?.status === 'number' &&
399
- response.status >= 200 &&
400
- response.status < 300;
457
+ const ok = typeof response?.status === 'number' && response.status >= 200 && response.status < 300;
401
458
  if (!ok || !responseUrlMatchesRequest(response?.url, pending.url))
402
459
  return;
460
+ // Some endpoints return 200 with an empty body pre-login (Garmin /proxy/socialProfile);
461
+ // when the endpoint opts into `requireLoginSignal`, wait for the injection's
462
+ // `__satyaReady` (authenticated content seen) before releasing the replay.
463
+ const requireLoginSignal = !!resolved.template.proofTarget?.requireLoginSignal;
464
+ if (requireLoginSignal && !loggedInRef.current)
465
+ return;
403
466
  pendingRequestRef.current = null;
404
467
  captureAndReplay(pending, resolved.template);
405
468
  return;
@@ -413,6 +476,14 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
413
476
  pendingRequestRef.current = message.data;
414
477
  return;
415
478
  }
479
+ const requireLoginSignal = !!resolved.template.proofTarget?.requireLoginSignal;
480
+ if (requireLoginSignal && !loggedInRef.current) {
481
+ // The provider `injection` polls the proof endpoint (which returns 200-empty pre-login)
482
+ // and posts `__satyaReady` once it sees authenticated content. Hold the latest matching
483
+ // request until then, then replay it.
484
+ pendingRequestRef.current = message.data;
485
+ return;
486
+ }
416
487
  captureAndReplay(message.data, resolved.template);
417
488
  }, [
418
489
  captureAndReplay,
@@ -685,7 +756,7 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
685
756
  // Android Modals render edge-to-edge (content under the status bar / notch), and
686
757
  // react-native's SafeAreaView applies no top inset there — so pad the chrome down by the
687
758
  // status-bar height. iOS keeps 0 (SafeAreaView already insets the notch).
688
- const topInset = Platform.OS === 'android' ? StatusBar.currentHeight ?? 24 : 0;
759
+ const topInset = Platform.OS === 'android' ? (StatusBar.currentHeight ?? 24) : 0;
689
760
  return (<>
690
761
  <Pressable style={[styles.button, (disabled || running || modalVisible) && styles.buttonDisabled]} disabled={disabled || running || modalVisible} onPress={openFlow}>
691
762
  {running ? <ActivityIndicator color="#ffffff" style={styles.buttonSpinner}/> : null}
@@ -796,7 +867,7 @@ export function SatyaProviderAttestButton({ providerId, endpointId, providerTemp
796
867
  <View style={styles.errorIconWrap}>
797
868
  <Text style={styles.errorIconGlyph}>!</Text>
798
869
  </View>
799
- <Text style={styles.overlayTitle}>Couldn{'’'}t verify your account</Text>
870
+ <Text style={styles.overlayTitle}>Couldn't verify your account</Text>
800
871
  <Text style={styles.overlaySubtitle}>{friendlyError(error)}</Text>
801
872
  <Pressable style={styles.primaryAction} onPress={openFlow}>
802
873
  <Text style={styles.primaryActionText}>Try again</Text>
@@ -828,6 +899,7 @@ async function resolveProvider(providerId, providerTemplate, providerRegistrySou
828
899
  const policy = await fetchVerifierProviderPolicy({
829
900
  notaryUrl: transportConfig.notaryUrl,
830
901
  providerId: base.providerId,
902
+ bearerToken: transportConfig.verifierBearerToken,
831
903
  });
832
904
  validateProviderPolicyForTemplate(policy, base);
833
905
  const template = withProviderSpkiPins(base, policy.spkiSha256B64Pins);
@@ -938,11 +1010,11 @@ function validateTemplateForReplay(template) {
938
1010
  }
939
1011
  return null;
940
1012
  }
941
- async function postBackendVerifier(notaryUrl, artifactJson) {
1013
+ async function postBackendVerifier(notaryUrl, artifactJson, bearerToken) {
942
1014
  const url = backendVerifierUrl(notaryUrl);
943
1015
  const response = await fetch(url, {
944
1016
  method: 'POST',
945
- headers: { 'content-type': 'application/json' },
1017
+ headers: verifierRequestHeaders(bearerToken),
946
1018
  body: artifactJson,
947
1019
  });
948
1020
  const text = await response.text();
@@ -982,6 +1054,13 @@ async function postBackendVerifier(notaryUrl, artifactJson) {
982
1054
  };
983
1055
  }
984
1056
  }
1057
+ function verifierRequestHeaders(bearerToken) {
1058
+ const headers = { 'content-type': 'application/json' };
1059
+ const token = bearerToken?.trim();
1060
+ if (token)
1061
+ headers.authorization = `Bearer ${token}`;
1062
+ return headers;
1063
+ }
985
1064
  function backendVerifierUrl(notaryUrl) {
986
1065
  return `${notaryUrl.replace(/\/+$/, '')}/v1/artifacts/verify`;
987
1066
  }