v0.4.1
Hardening for CentralRestAuthClient and runCentralApprovalRecheck, found
reviewing an orphaned duplicate of the 0.4.0 work (#14,
closed as a dead duplicate) against what actually shipped
(#15):
- The bearer-token origin check no longer allows a loopback
http://URL.
Tests pointhttpClientat a mock instead of relaxing the runtime check,
since the token would otherwise ride in clear over any origin matching
localhost/127.0.0.1/::1. getCustomToken's request URL is now built from the base URL's parsed path
plus the callable name as a normalized path segment, instead of string
concatenation, so a trailing slash, query, or fragment on
centralFunctionsBaseUrlcan no longer misdirect the request.CentralRestAuthClient.close()no longer closes a caller-supplied
httpClient. It previously closed it viaFirebaseAuthSession.close()
regardless of who owned it.- A 200 response from the callable with an unexpected shape (no
result
key) now throwsCentralAuthExceptioninstead of an uncaughtTypeError. runCentralApprovalRecheckdistinguishes a malformed persisted session
(deleted, reported assessionRevoked) from a transient failure
(deferred), and no longer reports a recheck asdeferredafter the
callable has already succeeded andonApproved's side effects have
already run -- a failure persisting the rotated session now surfaces as a
real exception instead of being misreported as inconclusive.TimeoutHttpClientno longer follows redirects automatically, so a
same-host or subdomain redirect can no longer carry theAuthorization
bearer token to it. This also coversgetCustomToken's own request and
everyFirebaseAuthSessionrequest (sign-in, token refresh, display-name
update, provider linking) directly, since both apps that use this package
inject their ownhttpClientinstead of this package's
TimeoutHttpClient, so the fix could not rely on that wrapper alone.FirebaseAuthSession.restore(and soCentralRestAuthClient.restore) now
treats a wrong-typed persisted field (auidthat decoded to something
other than a string, for example) the same as a missing one -- returns
null instead of throwing aTypeError-- so a caller reading a malformed
local blob does not have to catch aTypeErrorto find out.