Skip to content

@last1id/sdk-react-native — CHANGELOG

0.1.1

Docs only. Production issuer is https://auth.last1.id. client_id accepts the App ID slug or the Client ID UUID.

0.1.0 (initial release)

First public version. Companion to @last1id/sdk@^0.3.0.

Added

  • createExpoSecureStoreAdapter(SecureStore, options?) — wraps an injected expo-secure-store module as a SecureTokenStore. Defaults to WHEN_UNLOCKED_THIS_DEVICE_ONLY Keychain accessibility (survives reboots, not included in iCloud Keychain backup).
  • createMemoryTokenStore(seed?) — in-memory store for tests and "don't remember me" sessions. Includes _dump() for snapshot assertions.
  • loadSecureLast1Client(options) — restore a primed Last1Client from previously-stored tokens. Returns null when no refresh token is stored (render Connect CTA). Returned client has onTokensRefreshed pre-wired to persist rotated pairs back to the same store. Tolerates accessToken missing but refreshToken present (e.g. force-killed mid-refresh) by seeding a sentinel that triggers refresh on first request.
  • beginPkceFlow(options) — builds the authorize URL + PKCE pair + state + nonce. Always includes offline_access in the requested scopes so a refresh token is actually issued. Caller hands authorizeUrl to expo-web-browser.
  • completePkceFlow(options) — exchanges the authorization code for tokens, persists to the supplied store, decodes the id_token payload to stash identityId (best-effort, unverified — partner backend handles signature verification), and returns a primed Last1Client. Surfaces Last1AuthError when the server forgets to issue a refresh token (a sign the consumer omitted offline_access).
  • clearSecureLast1Tokens(options) — wipes every stored key under the prefix. Idempotent. Use for explicit logout/unlink and as the recovery path from a Last1AuthError.
  • Re-exports Last1Client, Last1AuthError, Last1HttpError from the base SDK so consumers only need one import line.

Security defaults

  • Keychain class: WHEN_UNLOCKED_THIS_DEVICE_ONLY (survives reboots, requires device unlock to read, NOT in iCloud Keychain backup).
  • No biometric gate on refresh-token reads — backgrounded silent refresh would otherwise demand FaceID at the wrong moment.
  • Persist failures are swallowed: a transient secure-store write error doesn't break the parent request. The onAuthError callback (if provided) gets { kind: "persist_failed", error } so partners can log; the in-memory pair is still good for the current session.
  • No AsyncStorage fallback. Refresh tokens never touch plaintext storage.

Tests

22 vitest cases covering: - Storage adapter round-trips + expo-secure-store delegation - PKCE handle shape + offline_access auto-inclusion - Cold-boot restore + crash-recovery sentinel - Token rotation persisting to storage - Multi-tenant prefix isolation - id_token payload decoding tolerant of malformed input - Last1AuthError on missing refresh_token from server - clearSecureLast1Tokens prefix-scoped + idempotent