github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/web/bitwarden/settings.go (about)

     1  package bitwarden
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  
     7  	"github.com/cozy/cozy-stack/model/bitwarden"
     8  	"github.com/cozy/cozy-stack/model/bitwarden/settings"
     9  	"github.com/cozy/cozy-stack/model/permission"
    10  	"github.com/cozy/cozy-stack/pkg/consts"
    11  	"github.com/cozy/cozy-stack/web/middlewares"
    12  	"github.com/labstack/echo/v4"
    13  )
    14  
    15  // https://github.com/bitwarden/jslib/blob/master/common/src/models/response/globalDomainResponse.ts
    16  type globalDomainsReponse struct {
    17  	Type     int      `json:"Type"`
    18  	Domains  []string `json:"Domains"`
    19  	Excluded bool     `json:"Excluded"`
    20  }
    21  
    22  // https://github.com/bitwarden/jslib/blob/master/common/src/models/response/domainsResponse.ts
    23  type domainsResponse struct {
    24  	EquivalentDomains       [][]string             `json:"EquivalentDomains"`
    25  	GlobalEquivalentDomains []globalDomainsReponse `json:"GlobalEquivalentDomains"`
    26  	Object                  string                 `json:"Object"`
    27  }
    28  
    29  func newDomainsResponse(setting *settings.Settings) *domainsResponse {
    30  	globals := make([]globalDomainsReponse, 0, len(bitwarden.GlobalDomains))
    31  	for k, v := range bitwarden.GlobalDomains {
    32  		excluded := false
    33  		for _, domain := range setting.GlobalEquivalentDomains {
    34  			if bitwarden.GlobalEquivalentDomainsType(domain) == k {
    35  				excluded = true
    36  				break
    37  			}
    38  		}
    39  		globals = append(globals, globalDomainsReponse{
    40  			Type:     int(k),
    41  			Domains:  v,
    42  			Excluded: excluded,
    43  		})
    44  	}
    45  	return &domainsResponse{
    46  		EquivalentDomains:       setting.EquivalentDomains,
    47  		GlobalEquivalentDomains: globals,
    48  		Object:                  "domains",
    49  	}
    50  }
    51  
    52  // GetDomains is the handler for listing the domains in settings.
    53  func GetDomains(c echo.Context) error {
    54  	inst := middlewares.GetInstance(c)
    55  	if err := middlewares.AllowWholeType(c, permission.GET, consts.BitwardenProfiles); err != nil {
    56  		return c.JSON(http.StatusUnauthorized, echo.Map{
    57  			"error": "invalid token",
    58  		})
    59  	}
    60  	setting, err := settings.Get(inst)
    61  	if err != nil {
    62  		return err
    63  	}
    64  
    65  	domains := newDomainsResponse(setting)
    66  	return c.JSON(http.StatusOK, domains)
    67  }
    68  
    69  // UpdateDomains is the handler for updating the domains in settings.
    70  func UpdateDomains(c echo.Context) error {
    71  	inst := middlewares.GetInstance(c)
    72  	if err := middlewares.AllowWholeType(c, permission.PUT, consts.BitwardenProfiles); err != nil {
    73  		return c.JSON(http.StatusUnauthorized, echo.Map{
    74  			"error": "invalid token",
    75  		})
    76  	}
    77  
    78  	var req struct {
    79  		Equivalent [][]string `json:"equivalentDomains"`
    80  		Global     []int      `json:"globalEquivalentDomains"`
    81  	}
    82  	if err := json.NewDecoder(c.Request().Body).Decode(&req); err != nil {
    83  		return c.JSON(http.StatusBadRequest, echo.Map{
    84  			"error": "invalid JSON",
    85  		})
    86  	}
    87  
    88  	setting, err := settings.Get(inst)
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	setting.EquivalentDomains = req.Equivalent
    94  	setting.GlobalEquivalentDomains = req.Global
    95  	if err := setting.Save(inst); err != nil {
    96  		return c.JSON(http.StatusInternalServerError, echo.Map{
    97  			"error": err.Error(),
    98  		})
    99  	}
   100  
   101  	domains := newDomainsResponse(setting)
   102  	return c.JSON(http.StatusOK, domains)
   103  }