Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ RUN mix deps.compile
COPY priv priv
COPY lib lib
COPY assets assets
COPY mcp-server/package.json mcp-server/package.json

# Compile the release
RUN mix compile
Expand Down
14 changes: 13 additions & 1 deletion lib/loopctl/tenant_keys.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ defmodule Loopctl.TenantKeys do
secret_name = Secrets.audit_key_secret_name(slug)

case Secrets.get(secret_name) do
{:ok, key} ->
{:ok, encoded} ->
# Fly secrets store keys as base64 (set via FlyAdapter.set/2).
# Decode to raw bytes for :crypto.sign/5.
key = decode_key(encoded)
:ets.insert(@cache_table, {tenant_id, key, now + @ttl_seconds})
{:ok, key}

Expand All @@ -87,4 +90,13 @@ defmodule Loopctl.TenantKeys do
end
end
end

# Keys may be stored as base64 (FlyAdapter encodes) or raw bytes (test mocks).
# Try base64 decode first; if it fails, assume raw bytes.
defp decode_key(value) when is_binary(value) do
case Base.decode64(value) do
{:ok, raw} when byte_size(raw) == 32 -> raw
_ -> value
end
end
end
11 changes: 11 additions & 0 deletions lib/loopctl_web/controllers/redirect_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule LoopctlWeb.RedirectController do
@moduledoc """
Simple redirects for common URL aliases.
"""

use LoopctlWeb, :controller

def swagger(conn, _params) do
redirect(conn, to: "/swaggerui")
end
end
2 changes: 1 addition & 1 deletion lib/loopctl_web/controllers/route_discovery_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ defmodule LoopctlWeb.RouteDiscoveryController do
},

# OpenAPI spec
%{method: "GET", path: "/api/openapi", description: "Full OpenAPI 3.0 spec (Swagger)"},
%{method: "GET", path: "/api/v1/openapi", description: "Full OpenAPI 3.0 spec (Swagger)"},

# Superadmin endpoints
%{
Expand Down
5 changes: 5 additions & 0 deletions lib/loopctl_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ defmodule LoopctlWeb.Router do
get "/", OpenApiSpex.Plug.SwaggerUI, path: "/api/v1/openapi"
end

# Convenience alias — agents and humans commonly try /swagger
scope "/" do
get "/swagger", LoopctlWeb.RedirectController, :swagger
end

# Dev-only routes (dashboard, etc.)
if Application.compile_env(:loopctl, :dev_routes, false) do
end
Expand Down
Loading