All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.2.1 - 2026-08-05

Added

  • Magpie.Auth.TokenServer no longer requires a refresh token at startup. A server started without one sits in an unconfigured state — calls return a pattern-matchable {:error, %Magpie.Error{summary: "no_refresh_token"}} without touching the network — and the new set_refresh_token/3 configures it (or replaces the token, for re-authorization) at any time, discarding any cached access token unless a valid access_token/expires_at pair is seeded. Fresh installs whose token arrives through the OAuth callback now work from a plain static supervision tree
  • Magpie.Auth.authorize_url/2 accepts extra_params: (keyword list or map) for additional Dropbox authorization params such as force_reapprove, locale, require_role and disable_signup. Params the function already sets cannot be overridden — collisions raise ArgumentError

0.2.0 - 2026-08-05

OAuth 2 support. Dropbox access tokens expire after ~4 hours, so a static token is not enough for anything that runs unattended — Magpie now handles the whole flow and keeps tokens fresh on its own.

Added

  • Magpie.Auth — OAuth 2 flow helpers: authorize_url/2 (offline access by default), pkce_pair/0 and pkce_challenge/1 for public apps, exchange_code/3 and refresh/3
  • Magpie.Auth.Token — token struct with an absolute expires_at computed from Dropbox's expires_in
  • Magpie.Auth.TokenProvider — behaviour that decouples the client from where tokens live, with two implementations: Magpie.Auth.StaticToken and Magpie.Auth.TokenServer
  • Magpie.Auth.TokenServer — supervised token holder that refreshes proactively (configurable :refresh_margin, default 300s), serializes concurrent refreshes into a single request, survives failed refreshes and can persist tokens through an :on_refresh callback
  • Magpie.Client.new/1 accepts a refresh token (refresh_token:/app_key: + app_secret: or pkce: true, starting a linked TokenServer) or an explicit token_provider: {module, arg}
  • Transparent recovery from expired tokens: requests rejected with HTTP 401 expired_access_token are refreshed and replayed once. Streamed upload bodies cannot be replayed and are not retried — the proactive refresh covers them
  • OAuth guide on HexDocs: getting a refresh token from the App Console, the web redirect flow, PKCE, supervision, persistence and custom providers

Changed

  • Magpie.Client gained a token_provider field; access_token is kept and Magpie.Client.new("ACCESS_TOKEN") behaves exactly as before
  • Magpie.Error.new/2 uses the OAuth error field (e.g. "invalid_grant") as the error summary when there is no error_summary

0.1.0 - 2026-08-01

First release of Magpie 🐦 — a modern, actively maintained Elixir client for the Dropbox API v2, born as a rewrite of the unmaintained elixir_dropbox package (see the Origin section of the README).

Added

Changed

  • HTTP client migrated from HTTPoison/Poison to Req/Jason
  • Every call now returns {:ok, result} or {:error, %Magpie.Error{}}
  • Deprecated Dropbox endpoints migrated to their current versions: move_v2, search_v2 (+ search/continue_v2), copy_batch_v2 (+ check_v2), upload_session/finish_batch_v2 and create_shared_link_with_settings
  • Default endpoint URLs are built in — consumer configuration is optional

Fixed

Deprecated

  • The legacy /paper/docs/* wrappers (Magpie.Paper.*) remain for compatibility, but the whole Paper API is deprecated by Dropbox — prefer Magpie.Files.Paper