@burnt-labs/expo-satya-attest 0.2.1 → 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 +8 -0
- package/PUBLISHING.md +2 -2
- package/README.md +3 -3
- package/android/build.gradle +2 -2
- package/build/SatyaAttest.types.d.ts +5 -0
- package/build/SatyaAttest.types.d.ts.map +1 -1
- package/build/SatyaAttest.types.js.map +1 -1
- package/build/SatyaProviderAttestButton.d.ts.map +1 -1
- package/build/SatyaProviderAttestButton.js +90 -11
- package/build/SatyaProviderAttestButton.js.map +1 -1
- package/build/providerPolicy.d.ts +2 -1
- package/build/providerPolicy.d.ts.map +1 -1
- package/build/providerPolicy.js +9 -2
- package/build/providerPolicy.js.map +1 -1
- package/build/providerWebview.d.ts +8 -4
- package/build/providerWebview.d.ts.map +1 -1
- package/build/providerWebview.js +18 -8
- package/build/providerWebview.js.map +1 -1
- package/build/providers.json +10 -11
- package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64/libsatya_ffi.a +0 -0
- package/ios/SatyaAttest.podspec +1 -1
- package/package.json +2 -1
- package/src/SatyaAttest.types.ts +5 -0
- package/src/SatyaProviderAttestButton.tsx +111 -12
- package/src/providerPolicy.ts +11 -1
- package/src/providerWebview.ts +18 -8
- package/src/providers.json +10 -11
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.
|
|
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.
|
|
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.
|
|
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.
|
|
208
|
-
npm install git+https://github.com/<owner>/<sdk-repo>.git#v0.2.
|
|
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
|
|
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'expo.modules.satyaattest'
|
|
7
|
-
version = '0.2.
|
|
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.2.
|
|
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":"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;
|
|
1
|
+
{"version":3,"file":"SatyaProviderAttestButton.d.ts","sourceRoot":"","sources":["../src/SatyaProviderAttestButton.tsx"],"names":[],"mappings":"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"}
|
|
@@ -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
|
-
|
|
339
|
-
|
|
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(
|
|
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
|
|
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:
|
|
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
|
}
|