Conversation
#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.
harsh62
approved these changes
Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
kickoff release