# `MishkaCmsCoreWeb.ReturnTo`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core_web/return_to.ex#L5)

Where a sign-in goes back to, as a token this application signed.

A page that sends a visitor to `/auth` with the address to come back to puts that address in the
URL, and it then travels through the sign-in and register form actions and through the
`sign_in_with_token` handoff before `MishkaCmsCoreWeb.AuthController` redirects to it. Everything
on that road is writable by whoever is walking it, so a `return_to` taken at its word would make
`/auth` the front door of a phishing site.

Nothing here parses what arrives. `sign/2` takes a path the router itself matched — built with
`~p`, never assembled from a parameter — and returns a `Phoenix.Token`; `verify/2` hands that
exact path back, and hands back nothing for a token that was tampered with, signed with another
secret or salt, signed too long ago, or never a token at all. A plain path is never a token, so
`?return_to=/en/members` and `?return_to=https://evil.example` are refused alike, and the caller
sends whoever cannot be verified home.

# `context`

```elixir
@type context() :: Plug.Conn.t() | Phoenix.LiveView.Socket.t() | module()
```

Whatever names the endpoint holding the secret: a conn, a socket, or the endpoint itself

# `sign`

```elixir
@spec sign(context(), term()) :: String.t() | nil
```

Signs a same-site path into the opaque token that travels as `return_to`.

Same-site is exactly what `Phoenix.Controller.redirect/2` will hand out: a single leading `/`, and
none of the characters a browser's URL parser strips or reinterprets or a response header cannot
carry. That is a rule about what a browser does with an address, not about how the address reads,
so an escaped `/%2F/elsewhere.example` is a page of this site and is signed as one — nothing on
the way to the browser turns that escape into another origin.

Returns `nil` for anything else, so the sign-in it starts simply has nowhere to come back to.

# `verify`

```elixir
@spec verify(context(), term()) :: String.t() | nil
```

Gives back the path a token was signed for, or `nil` when it cannot be verified.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
