defmodule GlificWeb.Router do @moduledoc """ a default gateway for all the external requests """ use GlificWeb, :router @dialyzer {:nowarn_function, __checks__: 0} use Appsignal.Plug use GlificWeb.InjectOban pipeline :browser do plug(:accepts, ["html"]) plug(:fetch_session) plug(:fetch_live_flash) plug(:put_root_layout, {GlificWeb.LayoutView, :root}) plug(:protect_from_forgery) plug(:put_secure_browser_headers) plug(Pow.Plug.Session, otp_app: :glific) end scope path: "/feature-flags" do # ensure that this is protected once we have authentication in place pipe_through([:browser, :auth]) forward("/", FunWithFlags.UI.Router, namespace: "feature-flags") end pipeline :api do plug(:accepts, ["json"]) plug(GlificWeb.APIAuthPlug, otp_app: :glific) plug(GlificWeb.RateLimitPlug) # plug :debug_response end pipeline :api_protected do plug(Pow.Plug.RequireAuthenticated, error_handler: GlificWeb.APIAuthErrorHandler) plug(GlificWeb.ContextPlug) end # Glific Authentication routes scope "/api/v1", GlificWeb.API.V1, as: :api_v1 do pipe_through(:api) resources("/registration", RegistrationController, singleton: true, only: [:create]) post("/registration/send-otp", RegistrationController, :send_otp) post("/registration/reset-password", RegistrationController, :reset_password) resources("/session", SessionController, singleton: true, only: [:create, :delete]) post("/session/renew", SessionController, :renew) post("/onboard/setup", OnboardController, :setup) end # Enables LiveDashboard only for development # # If you want to use the LiveDashboard in production, you should put # it behind authentication and allow only admins to access it. # If your application does not have an admins-only section yet, # you can use Plug.BasicAuth to set up some basic authentication # as long as you are also using SSL (which you should anyway). import Phoenix.LiveDashboard.Router scope "/" do pipe_through([:browser, :auth]) live_dashboard("/dashboard", metrics: GlificWeb.Telemetry, ecto_repos: [Glific.Repo]) end scope "/", GlificWeb do pipe_through([:browser]) live("/liveview", StatsLive) end # Custom stack for Absinthe scope "/" do pipe_through([:api, :api_protected]) forward("/api", Absinthe.Plug, schema: GlificWeb.Schema) end # BSP webhooks scope "/", GlificWeb do forward("/gupshup", Providers.Gupshup.Plugs.Shunt) forward("/airtel", Providers.Airtel.Plugs.Shunt) forward("/gupshup-enterprise", Providers.Gupshup.Enterprise.Plugs.Shunt) end # """ # Third party webhook except BSPs. Ideally we should have merge the BSPs also in this scope. # But since the BSP is a primary webhooks for this application We kept it separated. # """ scope "/webhook", GlificWeb do post("/stripe", StripeController, :stripe_webhook) get("/exotel/optin", ExotelController, :optin) end # """ # All the flow editor routes which is used while designing the flow. # """ scope "/flow-editor", GlificWeb.Flows do pipe_through([:api, :api_protected]) get("/groups", FlowEditorController, :groups) post("/groups", FlowEditorController, :groups_post) get("/labels", FlowEditorController, :labels) post("/labels", FlowEditorController, :labels_post) get("/channels", FlowEditorController, :channels) get("/classifiers", FlowEditorController, :classifiers) get("/ticketers", FlowEditorController, :ticketers) get("/resthooks", FlowEditorController, :resthooks) get("/templates", FlowEditorController, :templates) get("/interactive-templates", FlowEditorController, :interactive_templates) get("/interactive-templates/*vars", FlowEditorController, :interactive_template) get("/languages", FlowEditorController, :languages) get("/environment", FlowEditorController, :environment) get("/recipients", FlowEditorController, :recipients) get("/activity", FlowEditorController, :activity) get("/flows/*vars", FlowEditorController, :flows) get("/revisions/*vars", FlowEditorController, :revisions) get("/recents/*vars", FlowEditorController, :recents) post("/revisions/*vars", FlowEditorController, :save_revisions) get("/globals", FlowEditorController, :globals) get("/fields", FlowEditorController, :fields) post("/fields", FlowEditorController, :fields_post) get("/completion", FlowEditorController, :completion) get("/validate-media", FlowEditorController, :validate_media) get("/attachments-enabled", FlowEditorController, :attachments_enabled) post("/flow-attachment", FlowEditorController, :flow_attachment) get("/sheets", FlowEditorController, :sheets) end if Mix.env() in [:dev, :test] do scope "/" do pipe_through([:api, :api_protected]) forward( "/graphiql", Absinthe.Plug.GraphiQL, schema: GlificWeb.Schema, interface: :playground ) end end @doc """ implement basic authentication for live dashboard and oban pro """ @spec auth(any(), any()) :: any() def auth(conn, _opts) do username = Application.fetch_env!(:glific, :auth_username) password = Application.fetch_env!(:glific, :auth_password) Plug.BasicAuth.basic_auth(conn, username: username, password: password) end end