Summary
hawcx_flutter_sdk emits an authorization code that no published Hawcx backend client can exchange. Flutter customers currently have no supported way to complete backend verification.
Every published Hawcx backend client requires a PKCE code_verifier alongside the authorization code. The Flutter SDK never produces one.
Evidence
The Flutter SDK emits no verifier. In the published hawcx_flutter_sdk 1.0.5 archive from pub.dev, lib/ contains zero references to codeVerifier or code_verifier. AuthorizationCodePayload (lib/src/models/events.dart:185) carries code and expiresIn only.
Every backend client requires one.
| Client |
Call |
Behaviour without a verifier |
@hawcx/oauth-client 5.2.0 |
exchangeCode(code, codeVerifier) |
throws TokenExchangeError: codeVerifier is required |
@hawcx/oauth-client 5.2.0, legacy mode |
new HawcxOAuth({ configId, baseUrl }) then exchangeCode |
same guard, same throw |
| Java |
new TokenRequest(configId, authCode, codeVerifier) |
no verifier-less constructor exists |
From published @hawcx/oauth-client@5.2.0, dist/oauth.js:
async exchangeCode(code, codeVerifier, redirectUri, expectedNonce) {
if (!code)
throw new errors_1.TokenExchangeError('code is required');
if (!codeVerifier)
throw new errors_1.TokenExchangeError('codeVerifier is required');
const body = new URLSearchParams();
body.append('grant_type', 'authorization_code');
body.append('code', code);
body.append('code_verifier', codeVerifier);
The guard is unconditional. Legacy mode relaxes iss and aud verification but not this.
How this surfaced
The Flutter docs page carried a Node/Express backend snippet importing exchangeCodeForTokenAndClaims, OAuthExchangeError and JWTVerificationError from @hawcx/oauth-client. None of the three has ever existed in that package. Tracked as B7 on hawcx/sdk_docs#81.
The obvious fix was to swap them for the real symbols (HawcxOAuth, TokenExchangeError, TokenVerificationError). That fix does not work: the corrected snippet needs a codeVerifier the Flutter SDK does not emit, so it would throw on the first call. The fabricated symbols were hiding a real product gap.
React Native contrast
React Native has the same legacy defect but a way out. @hawcx/react-native-sdk types the legacy AuthorizationCodePayload as { code, expiresIn } and references codeVerifier only in its V6 files (src/v6Types.ts, src/v6Normalization.ts, ios/HawcxV6BridgeSupport.swift, android/.../v6/HawcxV6Bridge.kt). The V6 flow generates PKCE natively and returns codeVerifier in the completed payload, so a V6 React Native app can exchange normally.
Flutter has no V6 equivalent, in the SDK or in the docs.
Impact
Any Flutter customer following the documented flow reaches step 6, sending the code to their backend, and cannot proceed. There is no workaround at the SDK level.
Suggested resolution
Either surface a PKCE codeVerifier on the Flutter authorization-code payload the way the React Native V6 bridge does, or ship a Flutter V6 flow. Whichever lands, the docs page needs a matching update.
Docs status
The unimplementable snippet has been removed from both mobile pages rather than left to mislead. The Flutter page now states the constraint and points at support; the React Native page points at the V6 flow. Branch docs/fix-b7-mobile-backend on hawcx/sdk_docs, not yet pushed.
The contract-check CI harness on sdk_docs catches this class automatically: it verifies every symbol the docs import against the published package entry point.
Summary
hawcx_flutter_sdkemits an authorization code that no published Hawcx backend client can exchange. Flutter customers currently have no supported way to complete backend verification.Every published Hawcx backend client requires a PKCE
code_verifieralongside the authorization code. The Flutter SDK never produces one.Evidence
The Flutter SDK emits no verifier. In the published
hawcx_flutter_sdk1.0.5 archive from pub.dev,lib/contains zero references tocodeVerifierorcode_verifier.AuthorizationCodePayload(lib/src/models/events.dart:185) carriescodeandexpiresInonly.Every backend client requires one.
@hawcx/oauth-client5.2.0exchangeCode(code, codeVerifier)TokenExchangeError: codeVerifier is required@hawcx/oauth-client5.2.0, legacy modenew HawcxOAuth({ configId, baseUrl })thenexchangeCodenew TokenRequest(configId, authCode, codeVerifier)From published
@hawcx/oauth-client@5.2.0,dist/oauth.js:The guard is unconditional. Legacy mode relaxes
issandaudverification but not this.How this surfaced
The Flutter docs page carried a Node/Express backend snippet importing
exchangeCodeForTokenAndClaims,OAuthExchangeErrorandJWTVerificationErrorfrom@hawcx/oauth-client. None of the three has ever existed in that package. Tracked as B7 on hawcx/sdk_docs#81.The obvious fix was to swap them for the real symbols (
HawcxOAuth,TokenExchangeError,TokenVerificationError). That fix does not work: the corrected snippet needs acodeVerifierthe Flutter SDK does not emit, so it would throw on the first call. The fabricated symbols were hiding a real product gap.React Native contrast
React Native has the same legacy defect but a way out.
@hawcx/react-native-sdktypes the legacyAuthorizationCodePayloadas{ code, expiresIn }and referencescodeVerifieronly in its V6 files (src/v6Types.ts,src/v6Normalization.ts,ios/HawcxV6BridgeSupport.swift,android/.../v6/HawcxV6Bridge.kt). The V6 flow generates PKCE natively and returnscodeVerifierin the completed payload, so a V6 React Native app can exchange normally.Flutter has no V6 equivalent, in the SDK or in the docs.
Impact
Any Flutter customer following the documented flow reaches step 6, sending the code to their backend, and cannot proceed. There is no workaround at the SDK level.
Suggested resolution
Either surface a PKCE
codeVerifieron the Flutter authorization-code payload the way the React Native V6 bridge does, or ship a Flutter V6 flow. Whichever lands, the docs page needs a matching update.Docs status
The unimplementable snippet has been removed from both mobile pages rather than left to mislead. The Flutter page now states the constraint and points at support; the React Native page points at the V6 flow. Branch
docs/fix-b7-mobile-backendon hawcx/sdk_docs, not yet pushed.The
contract-checkCI harness on sdk_docs catches this class automatically: it verifies every symbol the docs import against the published package entry point.