From f6d3bd543fe8f302e1c06e572714345b269d78e6 Mon Sep 17 00:00:00 2001 From: Abhinav Raut Date: Sat, 30 Aug 2025 18:46:37 +0530 Subject: [PATCH] refactor: consolidate public config into single endpoint, move settings behind auth - remove OIDC enabled endpoint --- cmd/config.go | 63 +++++++++++++++++++++++ cmd/handlers.go | 6 ++- cmd/oidc.go | 10 ---- frontend/src/api/index.js | 4 +- frontend/src/main.js | 2 +- frontend/src/views/auth/UserLoginView.vue | 4 +- internal/oidc/oidc.go | 20 ++----- internal/oidc/queries.sql | 4 -- 8 files changed, 75 insertions(+), 38 deletions(-) create mode 100644 cmd/config.go diff --git a/cmd/config.go b/cmd/config.go new file mode 100644 index 0000000..55e8253 --- /dev/null +++ b/cmd/config.go @@ -0,0 +1,63 @@ +package main + +import ( + "encoding/json" + + "github.com/abhinavxd/libredesk/internal/envelope" + "github.com/zerodha/fastglue" +) + +// handleGetConfig returns the public configuration needed for app initialization, this includes minimal app settings and enabled SSO providers (without secrets). +func handleGetConfig(r *fastglue.Request) error { + var app = r.Context.(*App) + + // Get app settings + settingsJSON, err := app.setting.GetByPrefix("app") + if err != nil { + return sendErrorEnvelope(r, err) + } + + // Unmarshal settings + var settings map[string]any + if err := json.Unmarshal(settingsJSON, &settings); err != nil { + app.lo.Error("error unmarshalling settings", "err", err) + return sendErrorEnvelope(r, envelope.NewError(envelope.GeneralError, app.i18n.Ts("globals.messages.errorFetching", "name", app.i18n.T("globals.terms.setting")), nil)) + } + + // Filter to only include public fields needed for initial app load + publicSettings := map[string]any{ + "app.lang": settings["app.lang"], + "app.favicon_url": settings["app.favicon_url"], + "app.logo_url": settings["app.logo_url"], + "app.site_name": settings["app.site_name"], + } + + // Get all OIDC providers + oidcProviders, err := app.oidc.GetAll() + if err != nil { + return sendErrorEnvelope(r, err) + } + + // Filter for enabled providers and remove client_secret + enabledProviders := make([]map[string]any, 0) + for _, provider := range oidcProviders { + if provider.Enabled { + providerMap := map[string]any{ + "id": provider.ID, + "name": provider.Name, + "provider": provider.Provider, + "provider_url": provider.ProviderURL, + "client_id": provider.ClientID, + "logo": provider.ProviderLogoURL, + "enabled": provider.Enabled, + "redirect_uri": provider.RedirectURI, + } + enabledProviders = append(enabledProviders, providerMap) + } + } + + // Add SSO providers to the response + publicSettings["sso_providers"] = enabledProviders + + return r.SendEnvelope(publicSettings) +} diff --git a/cmd/handlers.go b/cmd/handlers.go index 6d80308..fef09ad 100644 --- a/cmd/handlers.go +++ b/cmd/handlers.go @@ -23,18 +23,20 @@ func initHandlers(g *fastglue.Fastglue, hub *ws.Hub) { // i18n. g.GET("/api/v1/lang/{lang}", handleGetI18nLang) + // Public config for app initialization. + g.GET("/api/v1/config", handleGetConfig) + // Media. g.GET("/uploads/{uuid}", auth(handleServeMedia)) g.POST("/api/v1/media", auth(handleMediaUpload)) // Settings. - g.GET("/api/v1/settings/general", handleGetGeneralSettings) + g.GET("/api/v1/settings/general", auth(handleGetGeneralSettings)) g.PUT("/api/v1/settings/general", perm(handleUpdateGeneralSettings, "general_settings:manage")) g.GET("/api/v1/settings/notifications/email", perm(handleGetEmailNotificationSettings, "notification_settings:manage")) g.PUT("/api/v1/settings/notifications/email", perm(handleUpdateEmailNotificationSettings, "notification_settings:manage")) // OpenID connect single sign-on. - g.GET("/api/v1/oidc/enabled", handleGetAllEnabledOIDC) g.GET("/api/v1/oidc", perm(handleGetAllOIDC, "oidc:manage")) g.POST("/api/v1/oidc", perm(handleCreateOIDC, "oidc:manage")) g.GET("/api/v1/oidc/{id}", perm(handleGetOIDC, "oidc:manage")) diff --git a/cmd/oidc.go b/cmd/oidc.go index 13fa252..bb2dcdb 100644 --- a/cmd/oidc.go +++ b/cmd/oidc.go @@ -11,16 +11,6 @@ import ( "github.com/zerodha/fastglue" ) -// handleGetAllEnabledOIDC returns all enabled OIDC records i.e. all OIDC configurable available for login with client secret stripped. -func handleGetAllEnabledOIDC(r *fastglue.Request) error { - app := r.Context.(*App) - out, err := app.oidc.GetAllEnabled() - if err != nil { - return sendErrorEnvelope(r, err) - } - return r.SendEnvelope(out) -} - // handleGetAllOIDC returns all OIDC records func handleGetAllOIDC(r *fastglue.Request) error { app := r.Context.(*App) diff --git a/frontend/src/api/index.js b/frontend/src/api/index.js index 5023f9b..8c3b6b2 100644 --- a/frontend/src/api/index.js +++ b/frontend/src/api/index.js @@ -122,7 +122,7 @@ const createOIDC = (data) => 'Content-Type': 'application/json' } }) -const getAllEnabledOIDC = () => http.get('/api/v1/oidc/enabled') +const getConfig = () => http.get('/api/v1/config') const getAllOIDC = () => http.get('/api/v1/oidc') const getOIDC = (id) => http.get(`/api/v1/oidc/${id}`) const updateOIDC = (id, data) => @@ -514,7 +514,7 @@ export default { updateSettings, createOIDC, getAllOIDC, - getAllEnabledOIDC, + getConfig, getOIDC, updateOIDC, deleteOIDC, diff --git a/frontend/src/main.js b/frontend/src/main.js index aec0730..862be1d 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -18,7 +18,7 @@ const setFavicon = (url) => { } async function initApp () { - const settings = (await api.getSettings('general')).data.data + const settings = (await api.getConfig()).data.data const emitter = mitt() const lang = settings['app.lang'] || 'en' const langMessages = await api.getLanguage(lang) diff --git a/frontend/src/views/auth/UserLoginView.vue b/frontend/src/views/auth/UserLoginView.vue index 9ac8b6e..decec17 100644 --- a/frontend/src/views/auth/UserLoginView.vue +++ b/frontend/src/views/auth/UserLoginView.vue @@ -159,8 +159,8 @@ onMounted(async () => { const fetchOIDCProviders = async () => { try { - const resp = await api.getAllEnabledOIDC() - oidcProviders.value = resp.data.data + const resp = await api.getConfig() + oidcProviders.value = resp.data.data.sso_providers || [] } catch (error) { emitter.emit(EMITTER_EVENTS.SHOW_TOAST, { variant: 'destructive', diff --git a/internal/oidc/oidc.go b/internal/oidc/oidc.go index 6cd822c..2b477ac 100644 --- a/internal/oidc/oidc.go +++ b/internal/oidc/oidc.go @@ -38,10 +38,9 @@ type Opts struct { // queries contains prepared SQL queries. type queries struct { - GetAllOIDC *sqlx.Stmt `query:"get-all-oidc"` - GetAllEnabled *sqlx.Stmt `query:"get-all-enabled"` - GetOIDC *sqlx.Stmt `query:"get-oidc"` - InsertOIDC *sqlx.Stmt `query:"insert-oidc"` + GetAllOIDC *sqlx.Stmt `query:"get-all-oidc"` + GetOIDC *sqlx.Stmt `query:"get-oidc"` + InsertOIDC *sqlx.Stmt `query:"insert-oidc"` UpdateOIDC *sqlx.Stmt `query:"update-oidc"` DeleteOIDC *sqlx.Stmt `query:"delete-oidc"` } @@ -111,19 +110,6 @@ func (o *Manager) GetAll() ([]models.OIDC, error) { return oidc, nil } -// GetAllEnabled retrieves all enabled oidc. -func (o *Manager) GetAllEnabled() ([]models.OIDC, error) { - var oidc = make([]models.OIDC, 0) - if err := o.q.GetAllEnabled.Select(&oidc); err != nil { - o.lo.Error("error fetching oidc", "error", err) - return oidc, envelope.NewError(envelope.GeneralError, o.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.oidcProvider}"), nil) - } - for i := range oidc { - oidc[i].SetProviderLogo() - } - return oidc, nil -} - // Create adds a new oidc. func (o *Manager) Create(oidc models.OIDC) (models.OIDC, error) { var createdOIDC models.OIDC diff --git a/internal/oidc/queries.sql b/internal/oidc/queries.sql index d428f39..b1a41bd 100644 --- a/internal/oidc/queries.sql +++ b/internal/oidc/queries.sql @@ -1,10 +1,6 @@ -- name: get-all-oidc SELECT id, created_at, updated_at, name, provider_url, client_id, client_secret, enabled, provider FROM oidc order by updated_at desc; --- name: get-all-enabled --- Skips the `client_secret` and returns all enabled OIDC configurations for login -SELECT id, name, enabled, provider, client_id, updated_at FROM oidc WHERE enabled = true order by updated_at desc; - -- name: get-oidc SELECT id, created_at, updated_at, name, provider_url, client_id, client_secret, enabled, provider FROM oidc WHERE id = $1;