diff --git a/lib/n8n_openai_adapter/router.ex b/lib/n8n_openai_adapter/router.ex index 92fdf8325a..648a0af80f 100644 --- a/lib/n8n_openai_adapter/router.ex +++ b/lib/n8n_openai_adapter/router.ex @@ -145,6 +145,18 @@ defmodule N8nOpenaiAdapter.Router do # --- Admin API (separate ADMIN_API_KEY) --- + get "/admin" do + case authorize_admin!(conn) do + {:halt, conn} -> + conn + + conn -> + conn + |> put_resp_content_type("text/html") + |> send_resp(200, admin_page()) + end + end + get "/admin/agents" do case authorize_admin!(conn) do {:halt, conn} -> @@ -255,4 +267,111 @@ defmodule N8nOpenaiAdapter.Router do end end end + + # Self-contained admin page: lists agents and lets you add/remove them via + # the admin API. Uses the ADMIN_API_KEY (entered in the page) as the Bearer + # token for the /admin/agents calls. + defp admin_page do + """ + + + + + + n8n OpenAI Adapter — Agents + + + +

n8n OpenAI Adapter — Agents

+

Manage which n8n chat agents are exposed as OpenAI models.

+ + + + + +

Add / update agent

+ + + + + + +
+ +

Configured agents

+
ModelWebhook
+ + + + + """ + end end diff --git a/test/router_test.exs b/test/router_test.exs index e810a52943..69da3162a0 100644 --- a/test/router_test.exs +++ b/test/router_test.exs @@ -63,6 +63,26 @@ defmodule N8nOpenaiAdapter.RouterTest do assert conn.status == 400 end + test "GET /admin serves the web admin page (admin key)" do + conn = + conn(:get, "/admin") + |> put_req_header("authorization", "Bearer test-admin-key") + |> Router.call(Router.init([])) + + assert conn.status == 200 + assert conn.resp_body =~ "n8n OpenAI Adapter" + assert conn.resp_body =~ "admin/agents" + end + + test "GET /admin rejects a non-admin key" do + conn = + conn(:get, "/admin") + |> put_req_header("authorization", "Bearer test-key") + |> Router.call(Router.init([])) + + assert conn.status == 401 + end + # --- Admin API --- test "GET /admin/agents lists agents (admin key)" do