DripDrop.Channels.Helpers (DripDrop v0.1.0)

Copy Markdown View Source

Shared helpers for provider implementations.

Summary

Functions

Reads a credential from either an adapter or credential map.

Removes keys whose values are nil.

Verifies an HMAC-SHA256 hex signature against a key + payload pair.

Normalizes an HTTP provider response into the channel delivery contract.

Resolves the recipient for a channel from payload overrides or enrollment data.

Returns configured Req options for channel provider HTTP calls.

Constant-time comparison of two binaries that also guards size mismatch.

Returns true when timestamp is within max_seconds of reference (default now).

Functions

credential(adapter, key, default \\ nil)

@spec credential(map(), atom() | binary(), term()) :: term()

Reads a credential from either an adapter or credential map.

drop_nil_values(map)

@spec drop_nil_values(map()) :: map()

Removes keys whose values are nil.

hmac_sha256_verify(key, payload, signature_hex)

@spec hmac_sha256_verify(binary(), iodata(), binary()) :: boolean()

Verifies an HMAC-SHA256 hex signature against a key + payload pair.

provider_result(arg, provider, message_id_fun)

@spec provider_result(
  {:ok, %{status: integer(), body: term()}} | {:error, term()},
  atom(),
  (term() -> binary() | nil)
) :: {:ok, map()} | {:error, map()}

Normalizes an HTTP provider response into the channel delivery contract.

recipient(enrollment, payload, channel)

@spec recipient(term(), map(), binary() | atom()) :: binary() | nil

Resolves the recipient for a channel from payload overrides or enrollment data.

request_options(adapter)

@spec request_options(map()) :: keyword()

Returns configured Req options for channel provider HTTP calls.

Tests and host applications can provide options globally through config :dripdrop, :channel_req_options or per adapter through adapter.config["req_options"].

secure_compare(left, right)

@spec secure_compare(binary(), binary()) :: boolean()

Constant-time comparison of two binaries that also guards size mismatch.

Plug.Crypto.secure_compare/2 requires equal byte sizes; this wrapper folds the size check into the comparison so callers can compare a candidate signature directly without leaking length information.

within_skew?(timestamp, max_seconds, reference \\ nil)

@spec within_skew?(term(), pos_integer(), DateTime.t() | nil) :: boolean()

Returns true when timestamp is within max_seconds of reference (default now).

Accepts unix timestamps as integer or string and ISO 8601 strings. Used to reject replayed webhook deliveries.