Add native NixOS deployment and UI-managed provider credentials
This commit is contained in:
@@ -44,6 +44,8 @@ func New(a *app.App, assets fs.FS, publicURL string) (http.Handler, error) {
|
||||
s.mux.HandleFunc("POST /api/rebuild", func(w http.ResponseWriter, r *http.Request) { v, e := a.Rebuild(r.Context()); respond(w, v, e) })
|
||||
s.mux.HandleFunc("POST /api/sync", func(w http.ResponseWriter, r *http.Request) { v, e := a.Sync(r.Context()); respond(w, v, e) })
|
||||
s.mux.HandleFunc("POST /api/settings", s.settings)
|
||||
s.mux.HandleFunc("POST /api/settings/openrouter", s.openRouterKey)
|
||||
s.mux.HandleFunc("POST /api/settings/enablebanking", s.bankingSettings)
|
||||
s.mux.HandleFunc("POST /api/banking/authorize", s.authorize)
|
||||
s.mux.HandleFunc("GET /api/banking/callback", s.callback)
|
||||
s.mux.HandleFunc("GET /api/balances", func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -287,6 +289,61 @@ func (s *Server) settings(w http.ResponseWriter, r *http.Request) {
|
||||
v, e := s.app.SaveSettings(r.Context(), b)
|
||||
respond(w, v, e)
|
||||
}
|
||||
func (s *Server) openRouterKey(w http.ResponseWriter, r *http.Request) {
|
||||
var b struct {
|
||||
APIKey *string `json:"api_key"`
|
||||
}
|
||||
d := json.NewDecoder(io.LimitReader(r.Body, 1<<20))
|
||||
d.DisallowUnknownFields()
|
||||
// Decoder errors can quote request values. Never echo credential input.
|
||||
if d.Decode(&b) != nil || d.Decode(&struct{}{}) != io.EOF || b.APIKey == nil {
|
||||
respond(w, nil, errors.New("expected one JSON object with an api_key string"))
|
||||
return
|
||||
}
|
||||
v, e := s.app.SaveOpenRouterKey(r.Context(), *b.APIKey)
|
||||
respond(w, v, e)
|
||||
}
|
||||
func (s *Server) bankingSettings(w http.ResponseWriter, r *http.Request) {
|
||||
var b struct {
|
||||
AppID *string `json:"app_id"`
|
||||
PrivateKey *string `json:"private_key"`
|
||||
RedirectURL *string `json:"redirect_url"`
|
||||
Remove bool `json:"remove"`
|
||||
}
|
||||
d := json.NewDecoder(io.LimitReader(r.Body, 256<<10))
|
||||
d.DisallowUnknownFields()
|
||||
// Parsing failures must not echo uploaded private-key content.
|
||||
if d.Decode(&b) != nil || d.Decode(&struct{}{}) != io.EOF {
|
||||
respond(w, nil, errors.New("invalid Enable Banking configuration request"))
|
||||
return
|
||||
}
|
||||
if b.Remove {
|
||||
if b.AppID != nil || b.PrivateKey != nil || b.RedirectURL != nil {
|
||||
respond(w, nil, errors.New("remove cannot be combined with banking credentials"))
|
||||
return
|
||||
}
|
||||
v, e := s.app.RemoveBankingSettings(r.Context())
|
||||
respond(w, v, e)
|
||||
return
|
||||
}
|
||||
if b.AppID == nil || b.RedirectURL == nil {
|
||||
respond(w, nil, errors.New("Enable Banking application ID and callback URL are required"))
|
||||
return
|
||||
}
|
||||
scheme, host := "http", r.Host
|
||||
if r.TLS != nil {
|
||||
scheme = "https"
|
||||
}
|
||||
if s.origin != nil {
|
||||
scheme, host = s.origin.Scheme, s.origin.Host
|
||||
}
|
||||
if *b.RedirectURL != scheme+"://"+host+"/api/banking/callback" {
|
||||
respond(w, nil, errors.New("Enable Banking callback URL must match this application's origin and /api/banking/callback path"))
|
||||
return
|
||||
}
|
||||
v, e := s.app.SaveBankingSettings(r.Context(), *b.AppID, b.PrivateKey, *b.RedirectURL)
|
||||
respond(w, v, e)
|
||||
}
|
||||
func (s *Server) authorize(w http.ResponseWriter, r *http.Request) {
|
||||
var b struct {
|
||||
Institution string `json:"institution"`
|
||||
|
||||
Reference in New Issue
Block a user