package accountapiimp import ( "encoding/json" "errors" "net/http" "github.com/tech/sendico/pkg/api/http/response" "github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/model" "github.com/tech/sendico/pkg/mservice" "github.com/tech/sendico/pkg/mutil/mzap" "github.com/tech/sendico/server/interface/api/sresponse" "go.uber.org/zap" ) func (a *AccountAPI) updateEmployee(r *http.Request, account *model.Account, token *sresponse.TokenData) http.HandlerFunc { orgRef, err := a.getCurrentOrganizationRef(r) if err != nil { a.logger.Warn("Failed to get current organization", zap.Error(err), mzap.StorableRef(account)) return response.BadRequest(a.logger, a.Name(), "invalid_organization_context", "Invalid organization context") } // Validate user input var u model.AccountPublic if err := json.NewDecoder(r.Body).Decode(&u); err != nil { a.logger.Warn("Failed to decide profile update", zap.Error(err)) return response.Internal(a.logger, a.Name(), err) } ctx := r.Context() res, err := a.enf.Enforce(ctx, a.accountsPermissionRef, account.ID, orgRef, u.ID, model.ActionUpdate) if err != nil { a.logger.Warn("Failed to check employee update permission", zap.Error(err), mzap.StorableRef(account), mzap.ObjRef("employee_ref", u.ID)) return response.Auto(a.logger, a.Name(), err) } if !res { a.logger.Debug("Permission deined for employee update", mzap.StorableRef(account), mzap.ObjRef("employee_ref", u.ID)) return response.Auto(a.logger, a.Name(), merrors.AccessDenied(mservice.Accounts, string(model.ActionUpdate), u.ID)) } if u.Login == "" { a.logger.Debug("No email in request") return a.reportEmailMissing() } if u.Name == "" { a.logger.Debug("No name in request") return response.BadRequest(a.logger, a.Name(), "name_missing", "name is required") } var acc model.Account if err := a.db.Get(ctx, u.ID, &acc); err != nil { a.logger.Warn("Failed to fetch employee account", zap.Error(err), mzap.ObjRef("employee_ref", u.ID)) return response.Auto(a.logger, a.Name(), err) } if acc.Login != u.Login { // Change email address verificationToken, err := a.accService.UpdateLogin(ctx, &acc, u.Login) if err != nil { if errors.Is(err, merrors.ErrDataConflict) { a.logger.Debug("Duplicate login, denying change...", zap.Error(err), mzap.ObjRef("employee_ref", u.ID)) return a.reportDuplicateEmail() } a.logger.Warn("Error while updating login", zap.Error(err), mzap.ObjRef("employee_ref", u.ID)) return response.Internal(a.logger, a.Name(), err) } // Send verification email if err = a.sendWelcomeEmail(&acc, verificationToken); err != nil { a.logger.Warn("Failed to send verification email", zap.Error(err), mzap.StorableRef(&acc)) return response.Internal(a.logger, a.Name(), err) } } else { // Save the user acc.AccountPublic = u if err = a.db.Update(ctx, &acc); err != nil { a.logger.Warn("Failed to save account", zap.Error(err), mzap.StorableRef(&acc)) return response.Internal(a.logger, a.Name(), err) } } return sresponse.Account(a.logger, &acc, token) }