PaperTiger.Plugs.UnflattenParams (PaperTiger v1.0.2)

Copy Markdown View Source

Converts Stripe's form-encoded nested parameters into proper nested maps.

Stripe's API uses bracket notation for nested parameters in form-encoded requests. This plug transforms them into nested Elixir maps.

Examples

# Single-level nesting
card[number]=4242424242424242
=> %{card: %{number: "4242424242424242"}}

# Multi-level nesting
payment_method_data[billing_details][name]=John Doe
=> %{payment_method_data: %{billing_details: %{name: "John Doe"}}}

# Arrays
expand[]=customer
expand[]=subscription
=> %{expand: ["customer", "subscription"]}

# Metadata
metadata[user_id]=123
metadata[session_id]=abc
=> %{metadata: %{user_id: "123", session_id: "abc"}}

Usage

# In router
plug PaperTiger.Plugs.UnflattenParams

Summary

Functions

Converts maps with numeric string keys to lists.

Parses a key like "card[number]" into ["card", "number"].

Puts a value into a nested map structure with depth tracking for DoS protection.

Transforms flat params with bracket notation into nested maps.

Functions

convert_indexed_maps_to_lists(value)

Converts maps with numeric string keys to lists.

DoS Protection

Validates that array indices are within reasonable bounds (max: 1000) to prevent memory exhaustion from sparse arrays like items[999999].

Examples

convert_indexed_maps_to_lists(%{"0" => "a", "1" => "b"})
=> ["a", "b"]

convert_indexed_maps_to_lists(%{items: %{"0" => %{price: "p1"}, "1" => %{price: "p2"}}})
=> %{items: [%{price: "p1"}, %{price: "p2"}]}

parse_key(key)

Parses a key like "card[number]" into ["card", "number"].

put_nested(map, arg2, value, depth)

Puts a value into a nested map structure with depth tracking for DoS protection.

Examples

put_nested(%{}, ["card", "number"], "4242", 0)
=> %{card: %{number: "4242"}}

put_nested(%{}, ["expand", ""], "customer", 0)
=> %{expand: ["customer"]}

unflatten_params(params)

Transforms flat params with bracket notation into nested maps.

DoS Protection

Enforces limits to prevent denial-of-service attacks:

  • Maximum nesting depth: 10
  • Maximum array index: 1000
  • Maximum parameters: 1000