Skip to content

Update approov_service_flutter_httpclient to ^3.5.8 and await initialize - #13

Merged
charlesoj6205 merged 2 commits into
mainfrom
feature/update-service-layer-versions
Sep 29, 2026
Merged

charlesoj6205 merged 2 commits into
mainfrom
feature/update-service-layer-versions

Conversation

@charlesoj6205

@charlesoj6205 charlesoj6205 commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Changes

  • approov_service_flutter_httpclient → ^3.5.8 (latest on pub.dev) in README.md, SHAPES-EXAMPLE.md and example/pubspec.yaml. Before this PR, these three files did not agree (^3.5.5, ^3.4.1 and ^3.4.1).
  • example/lib/main.dart: main() is now async and calls WidgetsFlutterBinding.ensureInitialized(). The commented Approov lines now read await ApproovService.initialize(...), in main() and in the isolate.
  • README.md and SHAPES-EXAMPLE.md show the await form and explain why it is necessary.

Why await is necessary

In 3.5.8, a successful initialize() resets the service configuration (_resetServiceStateAfterSuccessfulInitialization() clears the substitution headers). The reset runs after the native initialization returns. The example and docs called initialize() without await and then called addSubstitutionHeader() at once, so the reset deleted the header. 3.5.6 has no such reset. See the 3.5.8 upgrade notes in the service layer CHANGELOG.

Testing

On an Android 17 emulator with 3.5.8, secrets-protection flow, fake config string:

Code Result
initialize() without await (old docs) The header was deleted. The request went out with the placeholder, and the server returned "400: Bad Request invalid api key".
await initialize() (this PR) The header stayed registered, and the layer tried the substitution. Same result in the background isolate.

flutter analyze on the committed example, as shipped and with all Approov lines uncommented, reports no new findings.

Known issue (not caused by this PR)

The example pins Kotlin 1.8.22 in example/android/settings.gradle.kts. Current stable Flutter (3.41.6) cannot build it with any service layer version. The tests used Kotlin 2.1.0 in a local copy only.

Refs approov/core-project-approov#647

🤖 Generated with Claude Code

Align README, SHAPES-EXAMPLE and the example app on the current pub.dev
release. The three files previously disagreed (^3.5.5 vs ^3.4.1); the
example lockfile already resolved to 3.5.6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the documented/sample dependency version for approov_service_flutter_httpclient to match the latest published package version and align the quickstart documentation with the already-resolved lockfile version used by the example.

Changes:

  • Bump referenced approov_service_flutter_httpclient version to ^3.5.6 in the main README.
  • Update the Shapes tutorial snippet to ^3.5.6 for consistency.
  • Update the commented dependency hint in example/pubspec.yaml to ^3.5.6.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
SHAPES-EXAMPLE.md Updates the tutorial dependency snippet to ^3.5.6.
README.md Updates the documented dependency version to ^3.5.6.
example/pubspec.yaml Updates the commented Approov dependency version to ^3.5.6.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

In 3.5.8, a successful initialize() resets the service configuration.
The example and docs called initialize() without await and then called
addSubstitutionHeader(), so the reset deleted the header and the request
went out with the placeholder API key.

- Change the version to ^3.5.8 in example/pubspec.yaml, README.md and
  SHAPES-EXAMPLE.md.
- Make main() async, call WidgetsFlutterBinding.ensureInitialized() and
  await initialize() in main() and in the isolate.
- Show the await form in README.md and SHAPES-EXAMPLE.md.

Tested on an Android 17 emulator with 3.5.8: without await, the server
returned "invalid api key" and no substitution was attempted. With
await, the substitution header stayed registered in the root isolate
and in the background isolate.

Refs approov/core-project-approov#647

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@charlesoj6205 charlesoj6205 changed the title Update Approov service layer to latest published versions Update approov_service_flutter_httpclient to ^3.5.8 and await initialize Sep 29, 2026
@charlesoj6205

Copy link
Copy Markdown
Contributor Author

Test with a real Approov account — 2026-09-29

Tested at commit 6b1aa3b on a development Approov account, with shapes.approov.io added as a protected API and the secure string shapes_api_key_placeholder defined.

  • App: example with all Approov lines uncommented as the guide says: await ApproovService.initialize(...), addSubstitutionHeader("api-key", null), the v3 endpoint and the shapes_api_key_placeholder key. So one request tests the Approov token and the secret substitution.
  • Device: Android 17 emulator, force-passed because emulators fail attestation. Package resolved: approov_service_flutter_httpclient 3.5.8.
Path Result
Shape (root isolate) 200: OK, Rectangle (approoved and api key valid)
Shape (Isolate) Circle (approoved and api key valid)

"api key valid" shows that the placeholder was replaced with the real API key, so the await change keeps the substitution header in both isolates. Before the force-pass, the same build got ApproovRejectionException: Header substitution for api-key: REJECTED, which also shows that the header was still registered.

Local build note: the example needed Kotlin 2.1.0 to build with Flutter 3.41.6 (see the description). That change is not in this PR.

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The README initialization snippet omits the required asynchronous main and Flutter binding setup.

Review effort: Balanced
Findings: 1 Low severity

Open (1)

Comment thread README.md
import 'package:approov_service_flutter_httpclient/approov_service_flutter_httpclient.dart';
...
ApproovService.initialize('<enter-your-config-string-here>');
await ApproovService.initialize('<enter-your-config-string-here>');
@charlesoj6205
charlesoj6205 merged commit c1e562c into main Sep 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants