@burnt-labs/expo-satya-attest 0.2.1 → 0.2.4
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 +12 -11
- package/README.md +7 -7
- 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/Info.plist +19 -0
- package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64/libsatya_ffi.a +0 -0
- package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/Headers/module.modulemap +7 -0
- package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/Headers/satya_ffi.swift +989 -0
- package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/Headers/satya_ffiFFI.h +585 -0
- package/ios/Frameworks/libsatya_ffi-rs.xcframework/ios-arm64_x86_64-simulator/libsatya_ffi.a +0 -0
- package/ios/SatyaAttest.podspec +1 -1
- package/package.json +3 -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
|
@@ -59,7 +59,7 @@ Build them from the module directory:
|
|
|
59
59
|
```bash
|
|
60
60
|
cd platform_sdks/expo-satya-attest
|
|
61
61
|
npm run build:native:android
|
|
62
|
-
npm run build:native:ios
|
|
62
|
+
SATYA_IOS_INCLUDE_SIMULATOR=1 npm run build:native:ios
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
iOS artifacts can only be built on macOS with Xcode command line tools. Android artifacts
|
|
@@ -72,10 +72,9 @@ diagnostic unstripped iOS build:
|
|
|
72
72
|
SATYA_IOS_STRIP=0 npm run build:native:ios
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
path.
|
|
75
|
+
Publishing builds include the physical-device `arm64` slice plus simulator slices so
|
|
76
|
+
Expo development clients can install the SDK in simulator fallback flows. The real App
|
|
77
|
+
Attest path still only works on physical devices.
|
|
79
78
|
|
|
80
79
|
## Release Checks
|
|
81
80
|
|
|
@@ -100,6 +99,7 @@ npm run clean
|
|
|
100
99
|
npm run build
|
|
101
100
|
npm run lint
|
|
102
101
|
npm run test:providers
|
|
102
|
+
npm run test:publishing-workflows
|
|
103
103
|
npm run check:example
|
|
104
104
|
npm run check:native-artifacts
|
|
105
105
|
npm run check:pack
|
|
@@ -113,6 +113,7 @@ What each check covers:
|
|
|
113
113
|
| `clean` + `build` | Rebuilds TypeScript output in `build/`. |
|
|
114
114
|
| `lint` | Runs ESLint over `src/`. |
|
|
115
115
|
| `test:providers` | Validates provider ids, template hashes, parser hashes, request match rules, HTTPS proof URLs, SNI, and SPKI pins. |
|
|
116
|
+
| `test:publishing-workflows` | Confirms publish workflows build iOS artifacts with simulator slices and matching Rust targets. |
|
|
116
117
|
| `check:example` | Type-checks the Expo example when its dependencies are installed. |
|
|
117
118
|
| `check:native-artifacts` | Fails if Android `.so`, generated Kotlin, iOS XCFramework, or generated Swift glue are missing. |
|
|
118
119
|
| `check:pack` | Runs `npm pack --dry-run --json` and verifies the actual tarball contents. |
|
|
@@ -267,7 +268,7 @@ GitHub release tarball smoke test:
|
|
|
267
268
|
|
|
268
269
|
```bash
|
|
269
270
|
cd /private/tmp/SatyaSmoke
|
|
270
|
-
npm install https://github.com/<owner>/<repo>/releases/download/expo-satya-attest-v0.2.
|
|
271
|
+
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
272
|
npx expo install react-native-webview
|
|
272
273
|
```
|
|
273
274
|
|
|
@@ -275,7 +276,7 @@ For a raw Git install, publish the SDK from a dedicated repo or a subtree/split
|
|
|
275
276
|
where the SDK package is at the Git root:
|
|
276
277
|
|
|
277
278
|
```bash
|
|
278
|
-
npm install github:<owner>/<sdk-repo>#v0.2.
|
|
279
|
+
npm install github:<owner>/<sdk-repo>#v0.2.2
|
|
279
280
|
```
|
|
280
281
|
|
|
281
282
|
Do not document a normal monorepo Git URL as plug-and-play unless the Git ref has
|
|
@@ -294,8 +295,8 @@ Keep watching:
|
|
|
294
295
|
- `npm run check:pack` for npm tarball and unpacked package size.
|
|
295
296
|
- Whether every release includes only the ABIs you actually support.
|
|
296
297
|
|
|
297
|
-
Current
|
|
298
|
-
|
|
298
|
+
Current local iOS output includes only device `arm64` unless you opt in explicitly.
|
|
299
|
+
Publish workflows and release builds should use:
|
|
299
300
|
|
|
300
301
|
```bash
|
|
301
302
|
SATYA_IOS_INCLUDE_SIMULATOR=1 npm run build:native:ios
|
|
@@ -307,8 +308,8 @@ For Apple-Silicon-simulator-only fallback builds:
|
|
|
307
308
|
SATYA_IOS_SIMULATOR_TARGETS="aarch64-apple-ios-sim" npm run build:native:ios
|
|
308
309
|
```
|
|
309
310
|
|
|
310
|
-
|
|
311
|
-
|
|
311
|
+
Simulator slices are only for simulator fallback and development-client installability;
|
|
312
|
+
they are not useful for real App Attest verification.
|
|
312
313
|
|
|
313
314
|
If the tarball becomes too large for npm or painful for app installs, the next design
|
|
314
315
|
step is a binary-release model:
|
package/README.md
CHANGED
|
@@ -68,10 +68,10 @@ npm run build:native:ios
|
|
|
68
68
|
npm run build:native:android
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
`build:native:ios` strips local/debug symbols from the XCFramework
|
|
72
|
-
physical-device `arm64` iOS slice by default
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
`build:native:ios` strips local/debug symbols from the XCFramework. Local builds include
|
|
72
|
+
the physical-device `arm64` iOS slice by default; publishing builds set
|
|
73
|
+
`SATYA_IOS_INCLUDE_SIMULATOR=1` so simulator fallback slices ship too. See
|
|
74
|
+
[`PUBLISHING.md`](./PUBLISHING.md) for release and binary-size knobs.
|
|
75
75
|
|
|
76
76
|
Build TypeScript after editing `src/*.ts` or `src/*.tsx`:
|
|
77
77
|
|
|
@@ -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.4'
|
|
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.4"
|
|
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
|
}
|