satellite/{db,console}: support v2 app account set up
This change modifies the register endpoint handler to not require name for signups from the v2 app and adds a new endpoint for completing account information (e.g. name). This is to support the new signup and account setup flow of the v2 app. Issue: #6470 Change-Id: I256e1c804fcdbc8ce05aa82d6bc4b0263f55daa5
This commit is contained in:
parent
1ba314428f
commit
f749b8ff51
@ -52,7 +52,7 @@ func (server *Server) addUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
SignupPromoCode: input.SignupPromoCode,
|
SignupPromoCode: input.SignupPromoCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = user.IsValid()
|
err = user.IsValid(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendJSONError(w, "user data is not valid",
|
sendJSONError(w, "user data is not valid",
|
||||||
err.Error(), http.StatusBadRequest)
|
err.Error(), http.StatusBadRequest)
|
||||||
|
@ -331,6 +331,8 @@ func (a *Auth) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
SignupPromoCode: registerData.SignupPromoCode,
|
SignupPromoCode: registerData.SignupPromoCode,
|
||||||
ActivationCode: code,
|
ActivationCode: code,
|
||||||
SignupId: requestID,
|
SignupId: requestID,
|
||||||
|
// signup from the v2 app doesn't require name.
|
||||||
|
AllowNoName: strings.Contains(r.Referer(), "v2"),
|
||||||
},
|
},
|
||||||
secret,
|
secret,
|
||||||
)
|
)
|
||||||
@ -579,6 +581,25 @@ func (a *Auth) UpdateAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupAccount updates user's full name and short name.
|
||||||
|
func (a *Auth) SetupAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
var err error
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
var updatedInfo console.SetUpAccountRequest
|
||||||
|
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&updatedInfo)
|
||||||
|
if err != nil {
|
||||||
|
a.serveJSONError(ctx, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = a.service.SetupAccount(ctx, updatedInfo); err != nil {
|
||||||
|
a.serveJSONError(ctx, w, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetAccount gets authorized user and take it's params.
|
// GetAccount gets authorized user and take it's params.
|
||||||
func (a *Auth) GetAccount(w http.ResponseWriter, r *http.Request) {
|
func (a *Auth) GetAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
@ -305,6 +305,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, oidc
|
|||||||
authRouter.Use(server.withCORS)
|
authRouter.Use(server.withCORS)
|
||||||
authRouter.Handle("/account", server.withAuth(http.HandlerFunc(authController.GetAccount))).Methods(http.MethodGet, http.MethodOptions)
|
authRouter.Handle("/account", server.withAuth(http.HandlerFunc(authController.GetAccount))).Methods(http.MethodGet, http.MethodOptions)
|
||||||
authRouter.Handle("/account", server.withAuth(http.HandlerFunc(authController.UpdateAccount))).Methods(http.MethodPatch, http.MethodOptions)
|
authRouter.Handle("/account", server.withAuth(http.HandlerFunc(authController.UpdateAccount))).Methods(http.MethodPatch, http.MethodOptions)
|
||||||
|
authRouter.Handle("/account/setup", server.withAuth(http.HandlerFunc(authController.SetupAccount))).Methods(http.MethodPatch, http.MethodOptions)
|
||||||
authRouter.Handle("/account/change-email", server.withAuth(http.HandlerFunc(authController.ChangeEmail))).Methods(http.MethodPost, http.MethodOptions)
|
authRouter.Handle("/account/change-email", server.withAuth(http.HandlerFunc(authController.ChangeEmail))).Methods(http.MethodPost, http.MethodOptions)
|
||||||
authRouter.Handle("/account/change-password", server.withAuth(server.userIDRateLimiter.Limit(http.HandlerFunc(authController.ChangePassword)))).Methods(http.MethodPost, http.MethodOptions)
|
authRouter.Handle("/account/change-password", server.withAuth(server.userIDRateLimiter.Limit(http.HandlerFunc(authController.ChangePassword)))).Methods(http.MethodPost, http.MethodOptions)
|
||||||
authRouter.Handle("/account/freezestatus", server.withAuth(http.HandlerFunc(authController.GetFreezeStatus))).Methods(http.MethodGet, http.MethodOptions)
|
authRouter.Handle("/account/freezestatus", server.withAuth(http.HandlerFunc(authController.GetFreezeStatus))).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
@ -806,7 +806,7 @@ func (s *Service) CreateUser(ctx context.Context, user CreateUser, tokenSecret R
|
|||||||
captchaScore = score
|
captchaScore = score
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user.IsValid(); err != nil {
|
if err := user.IsValid(user.AllowNoName); err != nil {
|
||||||
// NOTE: error is already wrapped with an appropriated class.
|
// NOTE: error is already wrapped with an appropriated class.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1492,6 +1492,36 @@ func (s *Service) UpdateAccount(ctx context.Context, fullName string, shortName
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupAccount completes User's information.
|
||||||
|
func (s *Service) SetupAccount(ctx context.Context, requestData SetUpAccountRequest) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
user, err := s.getUserAndAuditLog(ctx, "update account")
|
||||||
|
if err != nil {
|
||||||
|
return Error.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate fullName
|
||||||
|
err = ValidateFullName(requestData.FullName)
|
||||||
|
if err != nil {
|
||||||
|
return ErrValidation.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.store.Users().Update(ctx, user.ID, UpdateUserRequest{
|
||||||
|
FullName: &requestData.FullName,
|
||||||
|
IsProfessional: &requestData.IsProfessional,
|
||||||
|
Position: requestData.Position,
|
||||||
|
CompanyName: requestData.CompanyName,
|
||||||
|
EmployeeCount: requestData.EmployeeCount,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return Error.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: track setup account
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ChangeEmail updates email for a given user.
|
// ChangeEmail updates email for a given user.
|
||||||
func (s *Service) ChangeEmail(ctx context.Context, newEmail string) (err error) {
|
func (s *Service) ChangeEmail(ctx context.Context, newEmail string) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
@ -115,18 +115,24 @@ type CreateUser struct {
|
|||||||
SignupPromoCode string `json:"signupPromoCode"`
|
SignupPromoCode string `json:"signupPromoCode"`
|
||||||
ActivationCode string `json:"-"`
|
ActivationCode string `json:"-"`
|
||||||
SignupId string `json:"-"`
|
SignupId string `json:"-"`
|
||||||
|
AllowNoName bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid checks CreateUser validity and returns error describing whats wrong.
|
// IsValid checks CreateUser validity and returns error describing whats wrong.
|
||||||
// The returned error has the class ErrValiation.
|
// The returned error has the class ErrValiation.
|
||||||
func (user *CreateUser) IsValid() error {
|
func (user *CreateUser) IsValid(allowNoName bool) error {
|
||||||
errgrp := errs.Group{}
|
errgrp := errs.Group{}
|
||||||
|
|
||||||
errgrp.Add(
|
errgrp.Add(
|
||||||
ValidateFullName(user.FullName),
|
|
||||||
ValidateNewPassword(user.Password),
|
ValidateNewPassword(user.Password),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if !allowNoName {
|
||||||
|
errgrp.Add(
|
||||||
|
ValidateFullName(user.FullName),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// validate email
|
// validate email
|
||||||
_, err := mail.ParseAddress(user.Email)
|
_, err := mail.ParseAddress(user.Email)
|
||||||
errgrp.Add(err)
|
errgrp.Add(err)
|
||||||
@ -283,6 +289,12 @@ type UpdateUserRequest struct {
|
|||||||
FullName *string
|
FullName *string
|
||||||
ShortName **string
|
ShortName **string
|
||||||
|
|
||||||
|
Position *string
|
||||||
|
CompanyName *string
|
||||||
|
WorkingOn *string
|
||||||
|
IsProfessional *bool
|
||||||
|
EmployeeCount *string
|
||||||
|
|
||||||
Email *string
|
Email *string
|
||||||
PasswordHash []byte
|
PasswordHash []byte
|
||||||
|
|
||||||
@ -328,3 +340,13 @@ type UpsertUserSettingsRequest struct {
|
|||||||
PassphrasePrompt *bool
|
PassphrasePrompt *bool
|
||||||
OnboardingStep *string
|
OnboardingStep *string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUpAccountRequest holds data for completing account setup.
|
||||||
|
type SetUpAccountRequest struct {
|
||||||
|
FullName string `json:"fullName"`
|
||||||
|
IsProfessional bool `json:"isProfessional"`
|
||||||
|
Position *string `json:"position"`
|
||||||
|
CompanyName *string `json:"companyName"`
|
||||||
|
EmployeeCount *string `json:"employeeCount"`
|
||||||
|
StorageNeeds *string `json:"storageNeeds"`
|
||||||
|
}
|
||||||
|
@ -630,6 +630,19 @@ func toUpdateUser(request console.UpdateUserRequest) (*dbx.User_Update_Fields, e
|
|||||||
update.SignupId = dbx.User_SignupId(*request.SignupId)
|
update.SignupId = dbx.User_SignupId(*request.SignupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if request.IsProfessional != nil {
|
||||||
|
update.IsProfessional = dbx.User_IsProfessional(*request.IsProfessional)
|
||||||
|
}
|
||||||
|
if request.Position != nil {
|
||||||
|
update.Position = dbx.User_Position(*request.Position)
|
||||||
|
}
|
||||||
|
if request.CompanyName != nil {
|
||||||
|
update.CompanyName = dbx.User_CompanyName(*request.CompanyName)
|
||||||
|
}
|
||||||
|
if request.EmployeeCount != nil {
|
||||||
|
update.EmployeeCount = dbx.User_EmployeeCount(*request.EmployeeCount)
|
||||||
|
}
|
||||||
|
|
||||||
return &update, nil
|
return &update, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,11 @@ func TestUpdateUser(t *testing.T) {
|
|||||||
FailedLoginCount: 1,
|
FailedLoginCount: 1,
|
||||||
LoginLockoutExpiration: time.Now().Truncate(time.Second),
|
LoginLockoutExpiration: time.Now().Truncate(time.Second),
|
||||||
DefaultPlacement: 13,
|
DefaultPlacement: 13,
|
||||||
|
|
||||||
|
IsProfessional: true,
|
||||||
|
Position: "Engineer",
|
||||||
|
CompanyName: "Storj",
|
||||||
|
EmployeeCount: "1-200",
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NotEqual(t, u.FullName, newInfo.FullName)
|
require.NotEqual(t, u.FullName, newInfo.FullName)
|
||||||
@ -104,6 +109,10 @@ func TestUpdateUser(t *testing.T) {
|
|||||||
require.NotEqual(t, u.FailedLoginCount, newInfo.FailedLoginCount)
|
require.NotEqual(t, u.FailedLoginCount, newInfo.FailedLoginCount)
|
||||||
require.NotEqual(t, u.LoginLockoutExpiration, newInfo.LoginLockoutExpiration)
|
require.NotEqual(t, u.LoginLockoutExpiration, newInfo.LoginLockoutExpiration)
|
||||||
require.NotEqual(t, u.DefaultPlacement, newInfo.DefaultPlacement)
|
require.NotEqual(t, u.DefaultPlacement, newInfo.DefaultPlacement)
|
||||||
|
require.NotEqual(t, u.IsProfessional, newInfo.IsProfessional)
|
||||||
|
require.NotEqual(t, u.Position, newInfo.Position)
|
||||||
|
require.NotEqual(t, u.CompanyName, newInfo.CompanyName)
|
||||||
|
require.NotEqual(t, u.EmployeeCount, newInfo.EmployeeCount)
|
||||||
|
|
||||||
// update just fullname
|
// update just fullname
|
||||||
updateReq := console.UpdateUserRequest{
|
updateReq := console.UpdateUserRequest{
|
||||||
@ -304,6 +313,26 @@ func TestUpdateUser(t *testing.T) {
|
|||||||
|
|
||||||
u.DefaultPlacement = newInfo.DefaultPlacement
|
u.DefaultPlacement = newInfo.DefaultPlacement
|
||||||
require.Equal(t, u, updatedUser)
|
require.Equal(t, u, updatedUser)
|
||||||
|
|
||||||
|
// update professional info
|
||||||
|
updateReq = console.UpdateUserRequest{
|
||||||
|
IsProfessional: &newInfo.IsProfessional,
|
||||||
|
Position: &newInfo.Position,
|
||||||
|
CompanyName: &newInfo.CompanyName,
|
||||||
|
EmployeeCount: &newInfo.EmployeeCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = users.Update(ctx, id, updateReq)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
updatedUser, err = users.Get(ctx, id)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
u.IsProfessional = newInfo.IsProfessional
|
||||||
|
u.Position = newInfo.Position
|
||||||
|
u.CompanyName = newInfo.CompanyName
|
||||||
|
u.EmployeeCount = newInfo.EmployeeCount
|
||||||
|
require.Equal(t, u, updatedUser)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user