Skip to content

chore: kickoff release - #4200

Merged
harsh62 merged 6 commits into
releasefrom
main
Apr 21, 2026
Merged

chore: kickoff release#4200
harsh62 merged 6 commits into
releasefrom
main

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

kickoff release

harsh62 and others added 6 commits April 16, 2026 11:58
#4137)

Co-authored-by: Harsh <6162866+harsh62@users.noreply.github.com>
The `permittedQueryParamCharacters` allowlist in `RESTOperationRequestUtils`
rejected characters that are valid per RFC 3986 and accepted by AppSync and
API Gateway (e.g. `@`, `:`, and sub-delims). The pre-#4137 validator was a
no-op in practice, so the issue only surfaced after #4137 tightened the
check and broke integration tests that exercised common values like
`hello@email.com` and ISO-8601 timestamps.

Align with Amplify JS and Amplify Android, which delegate query string
encoding to the platform URL API and do not maintain a custom allowlist.
`URLComponents` handles canonical percent-encoding when the URL is
assembled, and the SigV4 signer operates on decoded values.

- Remove `permittedQueryParamCharacters` and the inner validation helper.
- `prepareQueryParamsForSigning` no longer throws.
- Drop `testConstructURLRequestFailsWithInvalidQueryParams` (no longer the
  plugin's responsibility; SDK handles invalid UTF-16).
- Add `testConstructURLWithRFC3986QueryCharacters` to pin acceptance of
  `@` and `:` in query values.
The workflow build cache key was `Amplify-<platform>-<xcode-version>-build-cache`,
which is stable per platform+Xcode forever. When `aws-sdk-swift` (or any SPM
dependency) is bumped, `Package.resolved` changes and newly-generated source
references symbols in modules like `SmithyXML` that do not exist in the cached
`AWSClientRuntime.framework` from a prior commit. The result is linker errors
such as:

    Undefined symbol: static SmithyXML.Reader.from(data: Foundation.Data) -> Reader
    Undefined symbol: type metadata accessor for SmithyXML.Reader
    Ld .../AWSClientRuntime.framework/AWSClientRuntime

The SPM dependencies cache already includes `hashFiles('Package.resolved')` in
its key, so it self-invalidates correctly. Apply the same pattern to the build
cache key so a `Package.resolved` change moves to a fresh cache bucket, and
stale buckets expire naturally under GitHub's cache LRU.

Updates every workflow that reads or writes the build cache:
- build_scheme.yml
- run_integration_tests.yml
- run_unit_tests.yml
- integ_test_auth_webauthn.yml
- integ_test_push_notifications.yml

The save step in build_scheme.yml uses `steps.build-cache.outputs.cache-primary-key`,
so it automatically writes to the new hashed bucket. The existing "Delete the old
build cache" step continues to remove only the matching bucket before overwriting.
…t runs (#4198)

PR #4195 keyed the build cache on Package.resolved, which fixed cross-dependency
poisoning. A second failure mode remained: the cache was populated exclusively
by `build_scheme.yml` building `Amplify-Package` on main. Integration test
schemes that link additional frameworks (e.g. SmithyXML via Predictions, S3
via Storage) restored that cache and then failed to link:

    Undefined symbol: static SmithyXML.Reader.from(data: Foundation.Data) throws -> SmithyXML.Reader
    Undefined symbol: type metadata accessor for SmithyXML.Reader

Root cause: one platform-scoped bucket was shared across schemes with
different module graphs. Fix by scoping the cache per scheme and having
each test workflow save its own bucket on main after a successful run.

Changes:

- Append ${{ inputs.scheme }} to the build cache key in build_scheme.yml,
  run_integration_tests.yml, run_unit_tests.yml. Add literal scheme name
  in integ_test_auth_webauthn.yml (AuthWebAuthnApp) and integ_test_push_
  notifications.yml (PushNotificationHostApp / PushNotificationWatchTests).
- Add a `cache/save` step at the end of each test workflow (integration
  and unit) gated on `github.ref_name == 'main'` and a successful test run,
  so each scheme populates its own cache bucket on main.

The save steps only run on main, so PR branches continue to consume caches
without producing them. GitHub's per-repo cache LRU will evict least-
recently-used buckets as the per-scheme footprint grows.
…4196)

* fix(auth): Use original user input as device metadata keychain key

The device metadata keychain key was derived from SignedInData.username,
which is parsed from the JWT access token. Cognito returns different
username claims depending on the auth flow: USER_PASSWORD_AUTH returns
the internal sub-style UUID while USER_SRP_AUTH returns the user alias
(email, phone, etc). This caused device metadata stored during one flow
to be unretrievable during another, resulting in duplicate device IDs
on every login when switching between auth flows.

Thread the original user-typed username (inputUsername) through
SignedInData, RespondToAuthChallenge, and the parseResponse/
sendRespondToAuth helper chain so that ConfirmDevice always stores
device metadata under the same key that InitializeSignInFlow will use
for retrieval on subsequent logins.

The inputUsername field is optional on both structs to maintain
backwards compatibility with existing keychain-persisted data.

* test(auth): Add unit and integration tests for device key persistence fix

Unit tests (12 tests):
- SignedInData Codable backwards compatibility (decode without inputUsername)
- SignedInData and AmplifyCredentials round-trip with inputUsername
- RespondToAuthChallenge inputUsername encode/decode
- parseResponse threading of inputUsername to confirmDevice, finalizeSignIn, challenge events
- VerifyPasswordSRP forwarding inputUsername through confirmDevice
- VerifySignInChallenge forwarding challenge.inputUsername through confirmDevice

Integration tests (2 tests):
- Device ID persists across sign-out/sign-in cycles (no duplicates)
- Device count remains stable across multiple sign-in cycles

* test(auth): Add cross-flow integration tests for device key persistence

Add integration tests that explicitly switch between USER_PASSWORD_AUTH
and USER_SRP_AUTH flows to verify device key persists across flow changes:
- testDeviceKeyPersistsFromUserPasswordToUserSRP
- testDeviceKeyPersistsFromUserSRPToUserPassword
- testDeviceKeyStableAcrossAlternatingAuthFlows (4 cycles alternating)
- testDeviceKeyPersistsAcrossSignOutSignIn (same flow baseline)

Each test uses AWSAuthSignInOptions(authFlowType:) to explicitly select
the auth flow per sign-in attempt.

* chore(auth): Add integration test to Xcode project target membership

Add DeviceKeyPersistenceIntegrationTests.swift to all 3 AuthIntegrationTests
build phases in the AuthHostApp Xcode project so the tests are discoverable
by xcodebuild test-without-building.

* chore: Fix trailing whitespace in RESTRequestUtilsTests

Pre-existing swiftformat violation on blank lines.

* fix(auth): Address review feedback on inputUsername

- Add inputUsername to SignedInData.debugDictionary
- Change SignedInData.inputUsername from var to let (has explicit init)
- Keep RespondToAuthChallenge.inputUsername as var since it relies on
  synthesized memberwise init with implicit nil default

* fix(auth): Normalize device metadata keychain key to lowercase

Cognito normalizes usernames to lowercase in JWT claims, but the
user-typed input preserves original casing. This caused a keychain
key mismatch when storing device metadata with inputUsername (mixed
case) and retrieving with the JWT username (lowercase).

Lowercase the username in generateDeviceMetadataKey — the single
funnel point for all device metadata store/retrieve/remove operations.
@github-actions
github-actions Bot requested a review from a team as a code owner April 21, 2026 21:27
@harsh62
harsh62 merged commit 1a430e3 into release Apr 21, 2026
165 of 167 checks passed
@harsh62
harsh62 temporarily deployed to IntegrationTest April 21, 2026 22:00 — with GitHub Actions Inactive
@harsh62
harsh62 temporarily deployed to IntegrationTest April 21, 2026 22:00 — with GitHub Actions Inactive
@harsh62
harsh62 temporarily deployed to IntegrationTest April 21, 2026 22:00 — with GitHub Actions Inactive
@harsh62
harsh62 temporarily deployed to IntegrationTest April 21, 2026 22:00 — with GitHub Actions Inactive
@harsh62
harsh62 temporarily deployed to IntegrationTest April 21, 2026 22:00 — with GitHub Actions Inactive
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