diff --git a/bff/api/account.go b/bff/api/account.go deleted file mode 100644 index 1f0d341..0000000 --- a/bff/api/account.go +++ /dev/null @@ -1,243 +0,0 @@ -package api - -import ( - "database/sql" - "errors" - "net/http" - "time" - - "github.com/gin-gonic/gin" - db "github.com/itsscb/df/bff/db/sqlc" - "github.com/itsscb/df/bff/token" -) - -type createAccountRequest struct { - Passwordhash string `binding:"required" json:"passwordhash"` - Email string `binding:"required" json:"email"` - SecretKey string `binding:"required" json:"secret_key"` -} - -func (server *Server) createAccount(ctx *gin.Context) { - var req createAccountRequest - if err := ctx.ShouldBindJSON(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - arg := db.CreateAccountTxParams{ - CreateAccountParams: db.CreateAccountParams{ - Passwordhash: req.Passwordhash, - Email: req.Email, - SecretKey: sql.NullString{ - Valid: req.SecretKey != "", - String: req.SecretKey, - }, - }, - AfterCreate: func(a db.Account) error { return nil }, - } - - account, err := server.store.CreateAccountTx(ctx, arg) - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - ctx.JSON(http.StatusOK, account) -} - -type getAccountRequest struct { - ID uint64 `uri:"id" binding:"required,min=1" json:"id"` -} - -func (server *Server) getAccount(ctx *gin.Context) { - var req getAccountRequest - - if err := ctx.ShouldBindUri(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - account, err := server.store.GetAccount(ctx, req.ID) - if err != nil { - if err == sql.ErrNoRows { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) - if account.ID != authPayload.AccountID { - err := errors.New("account doesn't belong to the authenticated user") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - ctx.JSON(http.StatusOK, account) -} - -type listAccountRequest struct { - PageID int32 `form:"page_id" binding:"required,min=1"` - PageSize int32 `form:"page_size" binding:"required,min=5,max=50"` -} - -func (server *Server) listAccounts(ctx *gin.Context) { - var req listAccountRequest - - if err := ctx.ShouldBindQuery(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) - - account, err := server.store.GetAccount(ctx, authPayload.AccountID) - if err != nil { - if err == sql.ErrNoRows { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - if account.PermissionLevel < 1 { - err := errors.New("only for admin users") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - arg := db.ListAccountsParams{ - Limit: req.PageSize, - Offset: (req.PageID - 1) * req.PageSize, - } - - accounts, err := server.store.ListAccounts(ctx, arg) - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - ctx.JSON(http.StatusOK, accounts) -} - -type updateAccountPrivacyRequest struct { - ID uint64 `binding:"required" json:"ID"` - PrivacyAccepted *bool `binding:"required" json:"privacy_accepted"` -} - -func (server *Server) updateAccountPrivacy(ctx *gin.Context) { - var req updateAccountPrivacyRequest - if err := ctx.ShouldBindJSON(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - account, err := server.store.GetAccount(ctx, req.ID) - if err != nil { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) - if account.ID != authPayload.AccountID { - err := errors.New("account doesn't belong to the authenticated user") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - account_info, err := server.store.UpdateAccountPrivacyTx(ctx, db.UpdateAccountPrivacyTxParams{ - ID: req.ID, - Changer: account.Email, - PrivacyAccepted: req.PrivacyAccepted, - }) - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - ctx.JSON(http.StatusOK, account_info) -} - -type updateAccountInfoRequest struct { - ID uint64 `binding:"required" json:"ID"` - NewPassword string `json:"new_password"` - Firstname string `json:"firstname"` - Lastname string `json:"lastname"` - Birthday time.Time `json:"birthday"` - Email string `json:"email"` - Phone string `json:"phone"` - City string `json:"city"` - Zip string `json:"zip"` - Street string `json:"street"` - Country string `json:"country"` -} - -func (server *Server) updateAccountInfo(ctx *gin.Context) { - var req updateAccountInfoRequest - if err := ctx.ShouldBindJSON(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - account, err := server.store.GetAccount(ctx, req.ID) - if err != nil { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - - authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) - if account.ID != authPayload.AccountID { - err := errors.New("account doesn't belong to the authenticated user") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - arg := db.UpdateAccountInfoTxParams{ - AccountID: req.ID, - Changer: account.Email, - Firstname: sql.NullString{ - String: req.Firstname, - Valid: req.Firstname != "", - }, - Lastname: sql.NullString{ - String: req.Lastname, - Valid: req.Lastname != "", - }, - Birthday: sql.NullTime{ - Time: req.Birthday, - Valid: req.Birthday != time.Time{}, - }, - City: sql.NullString{ - String: req.City, - Valid: req.City != "", - }, - Zip: sql.NullString{ - String: req.Zip, - Valid: req.Zip != "", - }, - Street: sql.NullString{ - String: req.Street, - Valid: req.Street != "", - }, - Country: sql.NullString{ - String: req.Country, - Valid: req.Country != "", - }, - Phone: sql.NullString{ - String: req.Phone, - Valid: req.Phone != "", - }, - } - - account_info, err := server.store.UpdateAccountInfoTx(ctx, arg) - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - ctx.JSON(http.StatusOK, account_info) -} diff --git a/bff/api/account_test.go b/bff/api/account_test.go deleted file mode 100644 index 31b2a6d..0000000 --- a/bff/api/account_test.go +++ /dev/null @@ -1,930 +0,0 @@ -package api - -import ( - "bytes" - "context" - "database/sql" - "encoding/json" - "fmt" - "io" - "net/http" - "net/http/httptest" - "reflect" - "testing" - "time" - - "github.com/gin-gonic/gin" - mockdb "github.com/itsscb/df/bff/db/mock" - db "github.com/itsscb/df/bff/db/sqlc" - "github.com/itsscb/df/bff/token" - "github.com/itsscb/df/bff/util" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" -) - -var timestamp = time.Now() - -type eqCreateAccountTxParamsMatcher struct { - arg db.CreateAccountTxParams - password string - user db.Account -} - -func (expected eqCreateAccountTxParamsMatcher) Matches(x interface{}) bool { - actualArg, ok := x.(db.CreateAccountTxParams) - if !ok { - return false - } - - err := util.CheckPassword(expected.password, actualArg.Passwordhash) - if err != nil { - return false - } - - expected.arg.Passwordhash = actualArg.Passwordhash - if !reflect.DeepEqual(expected.arg.CreateAccountParams, actualArg.CreateAccountParams) { - return false - } - - err = actualArg.AfterCreate(expected.user) - return err == nil -} - -func (e eqCreateAccountTxParamsMatcher) String() string { - return fmt.Sprintf("matches arg %v and password %v", e.arg, e.password) -} - -func EqCreateAccountTxParams(arg db.CreateAccountTxParams, password string, user db.Account) gomock.Matcher { - return eqCreateAccountTxParamsMatcher{arg, password, user} -} - -func TestCreateAccountAPI(t *testing.T) { - account, password := randomAccount() - - // fn := func(db.Account) error { return nil} - - testCases := []struct { - name string - body gin.H - setupAuth func(t *testing.T, request *http.Request, tokenMaker token.Maker) - buildStubs func(store *mockdb.MockStore) - checkResponse func(recorder *httptest.ResponseRecorder) - }{ - { - name: "OK", - body: gin.H{ - "passwordhash": account.Passwordhash, - "email": account.Email, - "secret_key": account.SecretKey, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - arg := db.CreateAccountTxParams{ - CreateAccountParams: db.CreateAccountParams{ - Passwordhash: account.Passwordhash, - Email: account.Email, - SecretKey: account.SecretKey, - }, - AfterCreate: func(a db.Account) error { return nil }, - } - - store.EXPECT(). - CreateAccountTx(gomock.Any(), EqCreateAccountTxParams(arg, password, account)). - Times(1). - Return(account, nil) - - // store.EXPECT(). - // CreateAccountTx(gomock.Any(), gomock.Eq(arg)). - // Times(1). - // Return(account, nil) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - requireBodyMatchAccount(t, recorder.Body, account) - }, - }, - // { - // name: "NoAuthorization", - // body: gin.H{ - // "passwordhash": account.Passwordhash, - // "privacy_accepted": account.PrivacyAccepted.Bool, - // "firstname": account.Firstname, - // "lastname": account.Lastname, - // "birthday": account.Birthday, - // "email": account.Email, - // "city": account.City, - // "zip": account.Zip, - // "street": account.Street, - // "country": account.Country, - // "phone": account.Phone.String, - // "creator": account.Email, - // }, - // setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - // }, - // buildStubs: func(store *mockdb.MockStore) { - // store.EXPECT(). - // CreateAccountTx(gomock.Any(), gomock.Any()). - // Times(0) - // }, - // checkResponse: func(recorder *httptest.ResponseRecorder) { - // require.Equal(t, http.StatusUnauthorized, recorder.Code) - // }, - // }, - { - name: "BadRequest", - body: gin.H{ - "email": account.Email, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - CreateAccountTx(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - { - name: "InternalServerError", - body: gin.H{ - "passwordhash": account.Passwordhash, - "email": account.Email, - "secret_key": account.SecretKey.String, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - CreateAccountTx(gomock.Any(), gomock.Any()). - Times(1). - Return(db.Account{}, sql.ErrConnDone) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusInternalServerError, recorder.Code) - }, - }, - } - - for i := range testCases { - tc := testCases[i] - - t.Run(tc.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - store := mockdb.NewMockStore(ctrl) - tc.buildStubs(store) - - server, err := NewServer(config, store, nil) - require.NoError(t, err) - - recorder := httptest.NewRecorder() - - // Marshal body data to JSON - data, err := json.Marshal(tc.body) - require.NoError(t, err) - - url := "/accounts" - request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data)) - require.NoError(t, err) - - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) - tc.checkResponse(recorder) - }) - } -} - -func TestGetAccountAPI(t *testing.T) { - account, _ := randomAccount() - - testCases := []struct { - name string - accountID uint64 - setupAuth func(t *testing.T, request *http.Request, tokenMaker token.Maker) - buildStubs func(store *mockdb.MockStore) - checkResponse func(t *testing.T, recorder *httptest.ResponseRecorder) - }{ - { - name: "OK", - accountID: account.ID, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - requireBodyMatchAccount(t, recorder.Body, account) - }, - }, - { - name: "UnauthorizedUser", - accountID: account.ID, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, 2, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "NoAuthorization", - accountID: account.ID, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "NotFound", - accountID: account.ID, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(db.Account{}, sql.ErrNoRows) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusNotFound, recorder.Code) - }, - }, - { - name: "InternalError", - accountID: account.ID, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(db.Account{}, sql.ErrConnDone) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusInternalServerError, recorder.Code) - }, - }, - { - name: "InvalidID", - accountID: 0, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - } - - for i := range testCases { - tc := testCases[i] - - t.Run(tc.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - store := mockdb.NewMockStore(ctrl) - tc.buildStubs(store) - - server, err := NewServer(config, store, nil) - require.NoError(t, err) - recorder := httptest.NewRecorder() - - url := fmt.Sprintf("/accounts/%d", tc.accountID) - request, err := http.NewRequest(http.MethodGet, url, nil) - require.NoError(t, err) - - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) - tc.checkResponse(t, recorder) - }) - } -} - -func TestUpdateAccountInfoTxAPI(t *testing.T) { - account, _ := randomAccount() - newLastname := util.RandomName() - - testCases := []struct { - name string - body gin.H - accountID string - setupAuth func(t *testing.T, request *http.Request, tokenMaker token.Maker) - buildStubs func(store *mockdb.MockStore) - checkResponse func(recorder *httptest.ResponseRecorder) - }{ - // { - // name: "OK_PasswordHash", - // body: gin.H{ - // "id": account.ID, - // "passwordhash": newPassword, - // "changer": changer, - // }, - // setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - // addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.Email, time.Minute) - // }, - // buildStubs: func(store *mockdb.MockStore) { - // var err error - // accountTemp := account - // accountTemp.Passwordhash, err = util.HashPassword(newPassword) - // require.NoError(t, err) - // accountTemp.Changer = changer - // arg := db.UpdateAccountInfoTxParams{ - // ID: account.ID, - // Passwordhash: sql.NullString{ - // Valid: true, - // String: newPassword, - // }, - // Changer: changer, - // } - - // store.EXPECT(). - // UpdateAccountInfoTx(gomock.Any(), gomock.Eq(arg)). - // Times(1). - // Return(accountTemp, nil) - // }, - // checkResponse: func(recorder *httptest.ResponseRecorder) { - // require.Equal(t, http.StatusOK, recorder.Code) - - // accountTemp := account - // accountTemp.Passwordhash = newPassword - // accountTemp.Changer = changer - - // requireBodyMatchAccount(t, recorder.Body, accountTemp) - // }, - // }, - { - name: "OK_Lastname", - body: gin.H{ - "id": account.ID, - "lastname": newLastname, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - arg := db.UpdateAccountInfoTxParams{ - AccountID: account.ID, - Lastname: sql.NullString{ - Valid: true, - String: newLastname, - }, - Changer: account.Email, - } - - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) - - store.EXPECT(). - UpdateAccountInfoTx(gomock.Any(), gomock.Eq(arg)). - Times(1). - Return(account, nil) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - requireBodyMatchAccount(t, recorder.Body, account) - }, - }, - { - name: "NoAuthorization", - body: gin.H{ - "id": account.ID, - "lastname": newLastname, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - CreateAccount(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "BadRequest", - body: gin.H{ - "email": account.Email, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - CreateAccount(gomock.Any(), gomock.Any()). - Times(0). - Return(db.Account{}, sql.ErrConnDone) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - } - - for i := range testCases { - tc := testCases[i] - - t.Run(tc.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - store := mockdb.NewMockStore(ctrl) - tc.buildStubs(store) - - server, err := NewServer(config, store, nil) - require.NoError(t, err) - - recorder := httptest.NewRecorder() - - // Marshal body data to JSON - data, err := json.Marshal(tc.body) - require.NoError(t, err) - - url := "/accounts" - request, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(data)) - require.NoError(t, err) - - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) - tc.checkResponse(recorder) - }) - } -} - -func TestListAccountsAPI(t *testing.T) { - - n := 5 - accounts := make([]db.Account, n) - for i := 0; i < n; i++ { - accounts[i], _ = randomAccount() - } - account := accounts[1] - - type Query struct { - pageID int - pageSize int - } - - testCases := []struct { - name string - query Query - setupAuth func(t *testing.T, request *http.Request, tokenMaker token.Maker) - buildStubs func(store *mockdb.MockStore) - checkResponse func(recorder *httptest.ResponseRecorder) - }{ - { - name: "OK", - query: Query{ - pageID: 1, - pageSize: n, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - arg := db.ListAccountsParams{ - Limit: int32(n), - Offset: 0, - } - - accountAdmin := account - accountAdmin.PermissionLevel = 1 - - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(accountAdmin, nil) - - store.EXPECT(). - ListAccounts(gomock.Any(), gomock.Eq(arg)). - Times(1). - Return(accounts, nil) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - requireBodyMatchAccounts(t, recorder.Body, accounts) - }, - }, - { - name: "NoAuthorization", - query: Query{ - pageID: 1, - pageSize: n, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - ListAccounts(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "EmptyQuery", - query: Query{}, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - ListAccounts(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - { - name: "InvalidPageID", - query: Query{ - pageID: -1, - pageSize: n, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - ListAccounts(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - { - name: "InvalidPageSize", - query: Query{ - pageID: 1, - pageSize: 100000, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - ListAccounts(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - } - - for i := range testCases { - tc := testCases[i] - - t.Run(tc.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - store := mockdb.NewMockStore(ctrl) - tc.buildStubs(store) - - server, err := NewServer(config, store, nil) - require.NoError(t, err) - - recorder := httptest.NewRecorder() - - url := "/accounts" - request, err := http.NewRequest(http.MethodGet, url, nil) - require.NoError(t, err) - - // Add query parameters to request URL - q := request.URL.Query() - q.Add("page_id", fmt.Sprintf("%d", tc.query.pageID)) - q.Add("page_size", fmt.Sprintf("%d", tc.query.pageSize)) - request.URL.RawQuery = q.Encode() - - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) - tc.checkResponse(recorder) - }) - } -} - -func TestUpdateAccountPrivacyTxAPI(t *testing.T) { - account, _ := randomAccount() - - testCases := []struct { - name string - body gin.H - setupAuth func(t *testing.T, request *http.Request, tokenMaker token.Maker) - buildStubs func(store *mockdb.MockStore) - checkResponse func(recorder *httptest.ResponseRecorder) - }{ - { - name: "OK", - body: gin.H{ - "id": account.ID, - "privacy_accepted": true, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - trueBool := true - arg := db.UpdateAccountPrivacyTxParams{ - ID: account.ID, - PrivacyAccepted: &trueBool, - Changer: account.Email, - } - - account2 := account - - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) - - store.EXPECT(). - UpdateAccountPrivacyTx(gomock.Any(), gomock.Eq(arg)). - Times(1). - Return(account2, nil) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - data, err := io.ReadAll(recorder.Body) - require.NoError(t, err) - - var getAccount db.Account - err = json.Unmarshal(data, &getAccount) - require.NoError(t, err) - - require.Equal(t, account.ID, getAccount.ID) - }, - }, - { - name: "OK", - body: gin.H{ - "id": account.ID, - "privacy_accepted": true, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - trueBool := true - - arg := db.UpdateAccountPrivacyTxParams{ - ID: account.ID, - PrivacyAccepted: &trueBool, - Changer: account.Email, - } - - account2 := account - - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) - - store.EXPECT(). - UpdateAccountPrivacyTx(gomock.Any(), gomock.Eq(arg)). - Times(1). - Return(account2, nil) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - data, err := io.ReadAll(recorder.Body) - require.NoError(t, err) - - var getAccount db.Account - err = json.Unmarshal(data, &getAccount) - require.NoError(t, err) - - require.Equal(t, account.ID, getAccount.ID) - }, - }, - { - name: "Revoked", - body: gin.H{ - "id": account.ID, - "privacy_accepted": false, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - falseBool := false - - arg := db.UpdateAccountPrivacyTxParams{ - ID: account.ID, - PrivacyAccepted: &falseBool, - Changer: account.Email, - } - - account2 := account - - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) - - store.EXPECT(). - UpdateAccountPrivacyTx(gomock.Any(), gomock.Eq(arg)). - Times(1). - Return(account2, nil) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - data, err := io.ReadAll(recorder.Body) - require.NoError(t, err) - - var getAccount db.Account - err = json.Unmarshal(data, &getAccount) - require.NoError(t, err) - - require.Equal(t, account.ID, getAccount.ID) - - }, - }, { - name: "InvalidRequest", - body: gin.H{ - "id": account.ID, - }, - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, account.ID, time.Minute) - }, - buildStubs: func(store *mockdb.MockStore) { - store.EXPECT(). - GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(0) - - store.EXPECT(). - UpdateAccountPrivacyTx(gomock.Any(), gomock.Any()). - Times(0) - }, - checkResponse: func(recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusBadRequest, recorder.Code) - }, - }, - } - - for i := range testCases { - tc := testCases[i] - - t.Run(tc.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - store := mockdb.NewMockStore(ctrl) - tc.buildStubs(store) - - server, err := NewServer(config, store, nil) - require.NoError(t, err) - - recorder := httptest.NewRecorder() - - // Marshal body data to JSON - data, err := json.Marshal(tc.body) - require.NoError(t, err) - fmt.Println("privacy revoked", "body", string(data)) - - url := "/accounts/privacy" - request, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(data)) - require.NoError(t, err) - - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) - tc.checkResponse(recorder) - }) - } -} - -func randomAccount() (db.Account, string) { - password := util.RandomString(6) - hashedPassword, _ := util.HashPassword(password) - - email := util.RandomEmail() - acc := db.Account{ - ID: util.RandomInt(1, 1000), - Passwordhash: hashedPassword, - Email: email, - SecretKey: sql.NullString{ - String: util.RandomString(100), - Valid: true, - }, - } - - return acc, password -} - -func createRandomAccountInfo(t *testing.T) db.AccountInfo { - - creator := util.RandomName() - - arg := db.CreateAccountInfoParams{ - Firstname: util.RandomName(), - Lastname: util.RandomName(), - Birthday: time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC), - Phone: sql.NullString{ - Valid: true, - String: util.RandomPhone(), - }, - PrivacyAccepted: sql.NullBool{ - Valid: true, - Bool: true, - }, - PrivacyAcceptedDate: sql.NullTime{ - Valid: true, - Time: timestamp, - }, - City: util.RandomString(15), - Zip: util.RandomString(5), - Street: util.RandomString(20), - Country: util.RandomString(15), - Creator: creator, - } - - account_info, err := testQueries.CreateAccountInfo(context.Background(), arg) - require.NoError(t, err) - require.NotEmpty(t, account_info) - - require.Equal(t, arg.Firstname, account_info.Firstname) - require.Equal(t, arg.Lastname, account_info.Lastname) - require.Equal(t, arg.Birthday, account_info.Birthday) - require.Equal(t, arg.Phone, account_info.Phone) - require.Equal(t, arg.City, account_info.City) - require.Equal(t, arg.Zip, account_info.Zip) - require.Equal(t, arg.Street, account_info.Street) - require.Equal(t, arg.Country, account_info.Country) - require.Equal(t, arg.Creator, account_info.Creator) - require.Equal(t, arg.Creator, account_info.Changer) - - require.NotZero(t, account_info.ID) - require.NotZero(t, account_info.Created) - - return account_info -} - -func requireBodyMatchAccount(t *testing.T, body *bytes.Buffer, account db.Account) { - data, err := io.ReadAll(body) - require.NoError(t, err) - - var getAccount db.Account - err = json.Unmarshal(data, &getAccount) - require.NoError(t, err) - require.Equal(t, account.Passwordhash, getAccount.Passwordhash) - require.Equal(t, account.Email, getAccount.Email) - require.Equal(t, account.SecretKey, getAccount.SecretKey) - // require.WithinDuration(t, account.PrivacyAcceptedDate.Time, getAccount.PrivacyAcceptedDate.Time, time.Minute) -} - -func requireBodyMatchAccounts(t *testing.T, body *bytes.Buffer, accounts []db.Account) { - data, err := io.ReadAll(body) - require.NoError(t, err) - - var gotAccounts []db.Account - err = json.Unmarshal(data, &gotAccounts) - require.NoError(t, err) - - for i := range accounts { - a := accounts[i] - b := gotAccounts[i] - - require.Equal(t, a.Passwordhash, b.Passwordhash) - require.Equal(t, a.Email, b.Email) - require.Equal(t, a.SecretKey, b.SecretKey) - } - // require.Equal(t, accounts, gotAccounts) - -} diff --git a/bff/api/logger.go b/bff/api/logger.go deleted file mode 100644 index 05154e7..0000000 --- a/bff/api/logger.go +++ /dev/null @@ -1,74 +0,0 @@ -package api - -import ( - "bytes" - "fmt" - "io" - "log/slog" - "time" - - "github.com/gin-gonic/gin" -) - -type responseBodyWriter struct { - gin.ResponseWriter - body *bytes.Buffer -} - -func (r responseBodyWriter) Write(b []byte) (int, error) { - r.body.Write(b) - return r.ResponseWriter.Write(b) -} - -func Logger() gin.HandlerFunc { - return func(c *gin.Context) { - t := time.Now() - - var body []byte - var w *responseBodyWriter - - if c.Request.Method != "GET" { - body, _ = io.ReadAll(c.Request.Body) - w = &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer} - c.Writer = w - c.Request.Body = io.NopCloser(bytes.NewReader(body)) - } - c.Next() - - duration := time.Since(t).Milliseconds() - - if c.Request.Method != "GET" { - slog.LogAttrs( - c, - slog.LevelDebug, - "http", - slog.Group( - "request", - slog.Int("STATUS", c.Writer.Status()), - slog.String("METHOD", c.Request.Method), - slog.String("PATH", c.Request.RequestURI), - slog.String("DURATION", fmt.Sprintf("%d ms", duration)), - slog.String("BODY", string(body)), - ), - slog.Group( - "response", - slog.String("BODY", w.body.String()), - ), - ) - } else { - slog.LogAttrs( - c, - slog.LevelDebug, - "http", - slog.Group( - "request", - slog.Int("STATUS", c.Writer.Status()), - slog.String("METHOD", c.Request.Method), - slog.String("PATH", c.Request.RequestURI), - slog.String("DURATION", fmt.Sprintf("%d ms", duration)), - ), - ) - - } - } -} diff --git a/bff/api/main_test.go b/bff/api/main_test.go deleted file mode 100644 index 070f91c..0000000 --- a/bff/api/main_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package api - -import ( - "os" - "testing" - "time" - - "github.com/gin-gonic/gin" - "github.com/itsscb/df/bff/util" -) - -var config util.Config - -func TestMain(m *testing.M) { - config = util.Config{ - Environment: "production", - TokenPrivateKeyHex: "099c0b96725b99e95719c92aec580809ac58fc14be2105ed2656f1f6c464593d8cacd6c7bed924b9cf207ab3cff1c59be4e5865260c4dafa29699244bd4ea2de", - AccessTokenDuration: time.Minute * 1, - RefreshTokenDuration: time.Minute * 2, - } - - gin.SetMode(gin.TestMode) - - os.Exit(m.Run()) -} diff --git a/bff/api/middleware.go b/bff/api/middleware.go deleted file mode 100644 index 5f81445..0000000 --- a/bff/api/middleware.go +++ /dev/null @@ -1,54 +0,0 @@ -package api - -import ( - "errors" - "fmt" - "net/http" - "strings" - - "github.com/gin-gonic/gin" - "github.com/itsscb/df/bff/token" -) - -const ( - authorizationHeaderKey = "authorization" - authorizationTypeBearer = "bearer" - authorizationPayloadKey = "authorization_payload" -) - -// AuthMiddleware creates a gin middleware for authorization -func authMiddleware(tokenMaker token.Maker) gin.HandlerFunc { - return func(ctx *gin.Context) { - authorizationHeader := ctx.GetHeader(authorizationHeaderKey) - - if len(authorizationHeader) == 0 { - err := errors.New("authorization header is not provided") - ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - fields := strings.Fields(authorizationHeader) - if len(fields) < 2 { - err := errors.New("invalid authorization header format") - ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - authorizationType := strings.ToLower(fields[0]) - if authorizationType != authorizationTypeBearer { - err := fmt.Errorf("unsupported authorization type %s", authorizationType) - ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - accessToken := fields[1] - payload, err := tokenMaker.VerifyToken(accessToken) - if err != nil { - ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - ctx.Set(authorizationPayloadKey, payload) - ctx.Next() - } -} diff --git a/bff/api/middleware_test.go b/bff/api/middleware_test.go deleted file mode 100644 index f746c5a..0000000 --- a/bff/api/middleware_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package api - -import ( - "fmt" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/gin-gonic/gin" - mockdb "github.com/itsscb/df/bff/db/mock" - "github.com/itsscb/df/bff/token" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" -) - -func addAuthorization( - t *testing.T, - request *http.Request, - tokenMaker token.Maker, - authorizationType string, - account_id uint64, - duration time.Duration, -) { - id, err := tokenMaker.NewTokenID() - require.NoError(t, err) - - token, payload, err := tokenMaker.CreateToken(account_id, id, duration) - require.NoError(t, err) - require.NotEmpty(t, payload) - - authorizationHeader := fmt.Sprintf("%s %s", authorizationType, token) - request.Header.Set(authorizationHeaderKey, authorizationHeader) -} - -func TestAuthMiddleware(t *testing.T) { - testCases := []struct { - name string - setupAuth func(t *testing.T, request *http.Request, tokenMaker token.Maker) - checkResponse func(t *testing.T, recorder *httptest.ResponseRecorder) - }{ - { - name: "OK", - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, 1, time.Minute) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusOK, recorder.Code) - }, - }, - { - name: "NoAuthorization", - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "UnsupportedAuthorization", - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, "unsupported", 1, time.Minute) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "InvalidAuthorizationFormat", - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, "", 1, time.Minute) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - { - name: "ExpiredToken", - setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { - addAuthorization(t, request, tokenMaker, authorizationTypeBearer, 1, -time.Minute) - }, - checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { - require.Equal(t, http.StatusUnauthorized, recorder.Code) - }, - }, - } - - for i := range testCases { - tc := testCases[i] - - t.Run(tc.name, func(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - store := mockdb.NewMockStore(ctrl) - - server, err := NewServer(config, store, nil) - require.NoError(t, err) - authPath := "/auth" - server.router.GET( - authPath, - authMiddleware(server.tokenMaker), - func(ctx *gin.Context) { - ctx.JSON(http.StatusOK, gin.H{}) - }, - ) - - recorder := httptest.NewRecorder() - request, err := http.NewRequest(http.MethodGet, authPath, nil) - require.NoError(t, err) - - tc.setupAuth(t, request, server.tokenMaker) - server.router.ServeHTTP(recorder, request) - tc.checkResponse(t, recorder) - }) - } -} diff --git a/bff/api/server.go b/bff/api/server.go deleted file mode 100644 index 3b07df9..0000000 --- a/bff/api/server.go +++ /dev/null @@ -1,84 +0,0 @@ -package api - -import ( - "fmt" - "log/slog" - "net/http" - "os" - - "github.com/gin-gonic/gin" - db "github.com/itsscb/df/bff/db/sqlc" - "github.com/itsscb/df/bff/token" - "github.com/itsscb/df/bff/util" -) - -// Server serves HTTP requests for df service -type Server struct { - store db.Store - router *gin.Engine - config util.Config - tokenMaker token.Maker - swaggerFiles http.FileSystem -} - -// NewServer creates a new HTTP server and sets up routing -func NewServer(config util.Config, store db.Store, swaggerFS http.FileSystem) (*Server, error) { - tokenMaker, err := token.NewPasetoMaker(config.TokenPrivateKeyHex) - if err != nil { - return nil, fmt.Errorf("cannot create token maker: %w", err) - } - - server := &Server{ - store: store, - config: config, - tokenMaker: tokenMaker, - swaggerFiles: swaggerFS, - } - router := gin.New() - - router.Use(gin.Recovery()) - - logLevel := slog.LevelError - if config.Environment == "development" { - logLevel = slog.LevelDebug - } - - if swaggerFS != nil { - router.StaticFS("/swagger/", swaggerFS) - } - - opts := slog.HandlerOptions{ - Level: logLevel, - } - logger := slog.New(slog.NewTextHandler(os.Stdout, &opts)) - - if config.LogOutput == "json" { - logger = slog.New(slog.NewJSONHandler(os.Stdout, &opts)) - } - - slog.SetDefault(logger) - - router.Use(Logger()) - - router.POST("/login", server.loginAccount) - router.POST("/tokens/renew_access", server.renewAccessToken) - router.POST("/accounts", server.createAccount) - - authRoutes := router.Group("/").Use(authMiddleware(server.tokenMaker)) - authRoutes.PUT("/account", server.updateAccountInfo) - authRoutes.PUT("/account/privacy", server.updateAccountPrivacy) - authRoutes.GET("/accounts/:id", server.getAccount) - authRoutes.GET("/accounts", server.listAccounts) - authRoutes.POST("/sessions", server.blockSession) - - server.router = router - return server, nil -} - -func (server *Server) Start(address string) error { - return server.router.Run(address) -} - -func errorResponse(err error) gin.H { - return gin.H{"error": err.Error()} -} diff --git a/bff/api/session.go b/bff/api/session.go deleted file mode 100644 index ab7de2b..0000000 --- a/bff/api/session.go +++ /dev/null @@ -1,151 +0,0 @@ -package api - -import ( - "database/sql" - "errors" - "net/http" - "time" - - "github.com/gin-gonic/gin" - "github.com/google/uuid" - db "github.com/itsscb/df/bff/db/sqlc" - "github.com/itsscb/df/bff/token" - "github.com/itsscb/df/bff/util" -) - -type loginAccountRequest struct { - Email string `json:"email" binding:"required"` - Password string `json:"password" binding:"required,min=6"` -} - -type loginAccountResponse struct { - SessionID uuid.UUID `json:"session_id"` - AccessToken string `json:"access_token"` - AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` - RefreshToken string `json:"refresh_token"` - RefreshTokenExpiresAt time.Time `json:"refresh_token_expires_at"` - AccountID uint64 `json:"account_id"` -} - -func (server *Server) loginAccount(ctx *gin.Context) { - var req loginAccountRequest - if err := ctx.ShouldBindJSON(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - account, err := server.store.GetAccountByEmail(ctx, req.Email) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - err = util.CheckPassword(req.Password, account.Passwordhash) - if err != nil { - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - id, err := server.tokenMaker.NewTokenID() - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(errors.New("failed to create session token"))) - } - refreshToken, refreshPayload, err := server.tokenMaker.CreateToken( - account.ID, - id, - server.config.RefreshTokenDuration, - ) - - accessToken, accessPayload, err := server.tokenMaker.CreateToken( - account.ID, - id, - server.config.AccessTokenDuration, - ) - - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - session, err := server.store.CreateSession(ctx, db.CreateSessionParams{ - ID: refreshPayload.ID, - AccountID: refreshPayload.AccountID, - RefreshToken: refreshToken, - UserAgent: ctx.Request.UserAgent(), - ClientIp: ctx.ClientIP(), - IsBlocked: false, - ExpiresAt: refreshPayload.ExpiredAt, - }) - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - rsp := loginAccountResponse{ - SessionID: session.ID, - AccessToken: accessToken, - AccessTokenExpiresAt: accessPayload.ExpiredAt, - RefreshToken: refreshToken, - RefreshTokenExpiresAt: refreshPayload.ExpiredAt, - AccountID: refreshPayload.AccountID, - } - ctx.JSON(http.StatusOK, rsp) -} - -type blockSessionRequest struct { - ID uuid.UUID `json:"session_id"` -} - -func (server *Server) blockSession(ctx *gin.Context) { - var req blockSessionRequest - if err := ctx.ShouldBindJSON(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - authorizationPayload, ok := ctx.Get(authorizationPayloadKey) - if !ok { - ctx.JSON(http.StatusUnauthorized, nil) - return - } - - payload := authorizationPayload.(*token.Payload) - - session, err := server.store.GetSession(ctx, req.ID) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - ctx.JSON(http.StatusUnauthorized, errorResponse(errors.New("unauthorized"))) - return - } - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - if session.IsBlocked { - ctx.JSON(http.StatusAlreadyReported, errorResponse(errors.New("already blocked"))) - return - } - - if session.AccountID != payload.AccountID { - ctx.JSON(http.StatusUnauthorized, errorResponse(errors.New("unauthorized"))) - return - } - - err = server.store.BlockSession(ctx, session.ID) - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - rsp := struct { - Ok bool - }{ - Ok: true, - } - - ctx.JSON(http.StatusOK, rsp) -} diff --git a/bff/api/token.go b/bff/api/token.go deleted file mode 100644 index 21a8821..0000000 --- a/bff/api/token.go +++ /dev/null @@ -1,89 +0,0 @@ -package api - -import ( - "database/sql" - "errors" - "fmt" - "net/http" - "time" - - "github.com/gin-gonic/gin" -) - -type renewAccessTokenRequest struct { - RefreshToken string `json:"refresh_token" binding:"required"` -} - -type renewAccessTokenResponse struct { - AccessToken string `json:"access_token"` - AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` -} - -func (server *Server) renewAccessToken(ctx *gin.Context) { - var req renewAccessTokenRequest - if err := ctx.ShouldBindJSON(&req); err != nil { - ctx.JSON(http.StatusBadRequest, errorResponse(err)) - return - } - - refreshPayload, err := server.tokenMaker.VerifyToken(req.RefreshToken) - if err != nil { - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - session, err := server.store.GetSession(ctx, refreshPayload.ID) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - ctx.JSON(http.StatusNotFound, errorResponse(err)) - return - } - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - if session.IsBlocked { - err := fmt.Errorf("blocked session") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - if session.AccountID != refreshPayload.AccountID { - err := fmt.Errorf("incorrect session user") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - if session.RefreshToken != req.RefreshToken { - err := fmt.Errorf("mismatched session token") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - if time.Now().After(session.ExpiresAt) { - err := fmt.Errorf("expired session") - ctx.JSON(http.StatusUnauthorized, errorResponse(err)) - return - } - - id, err := server.tokenMaker.NewTokenID() - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(errors.New("failed to create session token"))) - } - accessToken, accessPayload, err := server.tokenMaker.CreateToken( - refreshPayload.AccountID, - id, - server.config.AccessTokenDuration, - ) - - if err != nil { - ctx.JSON(http.StatusInternalServerError, errorResponse(err)) - return - } - - rsp := renewAccessTokenResponse{ - AccessToken: accessToken, - AccessTokenExpiresAt: accessPayload.ExpiredAt, - } - ctx.JSON(http.StatusOK, rsp) -} diff --git a/bff/db/query/account.sql b/bff/db/query/account.sql index 85ec202..36a89a5 100644 --- a/bff/db/query/account.sql +++ b/bff/db/query/account.sql @@ -19,6 +19,15 @@ VALUES ( ) RETURNING *; +-- name: UpdateAccount :one +UPDATE accounts +SET + "email" = COALESCE(sqlc.narg(email), "email"), + "passwordhash" = COALESCE(sqlc.narg(passwordhash), "passwordhash"), + "secret_key" = COALESCE(sqlc.narg(secret_key), "secret_key") +WHERE "id" = sqlc.arg(id) +RETURNING *; + -- name: ListAccounts :many SELECT * FROM accounts ORDER BY "email" diff --git a/bff/db/sqlc/account.sql.go b/bff/db/sqlc/account.sql.go index abd1d8a..8f8bab1 100644 --- a/bff/db/sqlc/account.sql.go +++ b/bff/db/sqlc/account.sql.go @@ -138,6 +138,43 @@ func (q *Queries) ListAccounts(ctx context.Context, arg ListAccountsParams) ([]A return items, nil } +const updateAccount = `-- name: UpdateAccount :one +UPDATE accounts +SET + "email" = COALESCE($1, "email"), + "passwordhash" = COALESCE($2, "passwordhash"), + "secret_key" = COALESCE($3, "secret_key") +WHERE "id" = $4 +RETURNING id, permission_level, passwordhash, email, secret_key, email_verified, email_verified_time +` + +type UpdateAccountParams struct { + Email sql.NullString `json:"email"` + Passwordhash sql.NullString `json:"passwordhash"` + SecretKey sql.NullString `json:"secret_key"` + ID uint64 `json:"id"` +} + +func (q *Queries) UpdateAccount(ctx context.Context, arg UpdateAccountParams) (Account, error) { + row := q.db.QueryRowContext(ctx, updateAccount, + arg.Email, + arg.Passwordhash, + arg.SecretKey, + arg.ID, + ) + var i Account + err := row.Scan( + &i.ID, + &i.PermissionLevel, + &i.Passwordhash, + &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, + ) + return i, err +} + const verifyAccountEmail = `-- name: VerifyAccountEmail :exec UPDATE accounts SET diff --git a/bff/db/sqlc/querier.go b/bff/db/sqlc/querier.go index 0fcdfce..c165ec9 100644 --- a/bff/db/sqlc/querier.go +++ b/bff/db/sqlc/querier.go @@ -78,6 +78,7 @@ type Querier interface { ListReturnsLogs(ctx context.Context, arg ListReturnsLogsParams) ([]ReturnsLog, error) ListReturnsLogsByPersonID(ctx context.Context, personID uint64) ([]ReturnsLog, error) ListSessions(ctx context.Context, accountID uint64) ([]Session, error) + UpdateAccount(ctx context.Context, arg UpdateAccountParams) (Account, error) UpdateAccountInfo(ctx context.Context, arg UpdateAccountInfoParams) (AccountInfo, error) UpdateAccountPrivacy(ctx context.Context, arg UpdateAccountPrivacyParams) (AccountInfo, error) UpdateDocument(ctx context.Context, arg UpdateDocumentParams) (Document, error) diff --git a/bff/db/sqlc/store.go b/bff/db/sqlc/store.go index eaf0321..d7aa081 100644 --- a/bff/db/sqlc/store.go +++ b/bff/db/sqlc/store.go @@ -17,6 +17,7 @@ type Store interface { DeletePersonTx(ctx context.Context, id uint64) error CreateDocumentTx(ctx context.Context, arg CreateDocumentTxParams) (doc Document, code int, err error) DeleteDocumentTx(ctx context.Context, id uint64) (code codes.Code, err error) + UpdateAccountTx(ctx context.Context, arg UpdateAccountTxParams) (Account, error) } // Store provides all functions to execute db queries and transactions diff --git a/bff/db/sqlc/tx_update_accountt.go b/bff/db/sqlc/tx_update_accountt.go new file mode 100644 index 0000000..1803266 --- /dev/null +++ b/bff/db/sqlc/tx_update_accountt.go @@ -0,0 +1,42 @@ +package db + +import ( + "context" + "database/sql" + + "github.com/google/uuid" +) + +type UpdateAccountTxParams struct { + UpdateAccountParams + AfterUpdate func(Account) error +} + +type UpdateAccountTxResult struct { + Account Account `json:"account"` +} + +func (store *SQLStore) UpdateAccountTx(ctx context.Context, arg UpdateAccountTxParams) (Account, error) { + var result UpdateAccountTxResult + var err error + + uid, _ := uuid.NewUUID() + + arg.SecretKey = sql.NullString{ + Valid: uid.String() != "", + String: uid.String(), + } + + err = store.execTx(ctx, func(q *Queries) error { + var err error + + result.Account, err = q.UpdateAccount(ctx, arg.UpdateAccountParams) + if err != nil { + return err + } + + return arg.AfterUpdate(result.Account) + }) + + return result.Account, err +} diff --git a/bff/doc/swagger/df.swagger.json b/bff/doc/swagger/df.swagger.json index 3d0a522..123493c 100644 --- a/bff/doc/swagger/df.swagger.json +++ b/bff/doc/swagger/df.swagger.json @@ -67,40 +67,6 @@ } }, "/v1/accounts/create_account": { - "post": { - "summary": "Create AccountInfo", - "operationId": "df_CreateAccountInfo", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/pbCreateAccountInfoResponse" - } - }, - "default": { - "description": "An unexpected error response.", - "schema": { - "$ref": "#/definitions/rpcStatus" - } - } - }, - "parameters": [ - { - "name": "body", - "description": "Create an AccountInfo", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/pbCreateAccountInfoRequest" - } - } - ], - "tags": [ - "df" - ] - } - }, - "/v1/accounts/create_account_info": { "post": { "summary": "Create AccountInfo", "operationId": "df_CreateAccount", @@ -131,23 +97,18 @@ ], "tags": [ "df" - ], - "security": [ - { - "BearerAuth": [] - } ] } }, - "/v1/accounts/get_account/{accountId}": { - "get": { - "summary": "Get AccountInfo by account_id", - "operationId": "df_GetAccountInfo", + "/v1/accounts/create_account_info": { + "post": { + "summary": "Create AccountInfo", + "operationId": "df_CreateAccountInfo", "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/pbGetAccountInfoResponse" + "$ref": "#/definitions/pbCreateAccountInfoResponse" } }, "default": { @@ -159,11 +120,13 @@ }, "parameters": [ { - "name": "accountId", - "in": "path", + "name": "body", + "description": "Create an AccountInfo", + "in": "body", "required": true, - "type": "string", - "format": "uint64" + "schema": { + "$ref": "#/definitions/pbCreateAccountInfoRequest" + } } ], "tags": [ @@ -213,6 +176,43 @@ ] } }, + "/v1/accounts/get_account_info/{accountId}": { + "get": { + "summary": "Get AccountInfo by account_id", + "operationId": "df_GetAccountInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/pbGetAccountInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "accountId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + } + ], + "tags": [ + "df" + ], + "security": [ + { + "BearerAuth": [] + } + ] + } + }, "/v1/accounts/list_account_info": { "get": { "summary": "List AccountInfos [admin only]", @@ -302,6 +302,45 @@ } }, "/v1/accounts/update_account": { + "patch": { + "summary": "Update Account", + "operationId": "df_UpdateAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/pbUpdateAccountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "description": "Update an Account", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/pbUpdateAccountRequest" + } + } + ], + "tags": [ + "df" + ], + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/v1/accounts/update_account_info": { "patch": { "summary": "Update AccountInfo", "operationId": "df_UpdateAccountInfo", @@ -1197,6 +1236,10 @@ "birthday": "1990-10-05T00:00:00Z" }, "properties": { + "accountId": { + "type": "string", + "format": "uint64" + }, "firstname": { "type": "string" }, @@ -1231,7 +1274,7 @@ "description": "Create an AccountInfo", "title": "Create AccountInfo", "required": [ - "account_id", + "accountId", "firstname", "lastname", "street", @@ -2054,6 +2097,41 @@ }, "title": "Update Account Info Privacy Response" }, + "pbUpdateAccountRequest": { + "type": "object", + "example": { + "account_id": "1", + "email": "john.doe@example.com" + }, + "properties": { + "accountId": { + "type": "string", + "format": "uint64" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "description": "Update an Account", + "title": "Update Account", + "required": [ + "email", + "password" + ] + }, + "pbUpdateAccountResponse": { + "type": "object", + "properties": { + "account": { + "$ref": "#/definitions/pbAccount" + } + }, + "description": "Returns the updated Account", + "title": "Updated Account" + }, "pbUpdatePaymentRequest": { "type": "object", "example": { diff --git a/bff/gapi/converter.go b/bff/gapi/converter.go index ccf92bd..af2da8d 100644 --- a/bff/gapi/converter.go +++ b/bff/gapi/converter.go @@ -8,10 +8,12 @@ import ( func convertAccount(account db.Account) *pb.Account { return &pb.Account{ - Id: account.ID, - PermissionLevel: account.PermissionLevel, - Email: account.Email, - SecretKey: &account.SecretKey.String, + Id: account.ID, + PermissionLevel: account.PermissionLevel, + Email: account.Email, + EmailVerified: account.EmailVerified.Bool, + EmailVerifiedTime: timestamppb.New(account.EmailVerifiedTime.Time), + SecretKey: &account.SecretKey.String, } } diff --git a/bff/gapi/rpc_create_account_info.go b/bff/gapi/rpc_create_account_info.go new file mode 100644 index 0000000..36b556f --- /dev/null +++ b/bff/gapi/rpc_create_account_info.go @@ -0,0 +1,113 @@ +package gapi + +import ( + "context" + "database/sql" + "errors" + "fmt" + "log/slog" + "time" + + db "github.com/itsscb/df/bff/db/sqlc" + "github.com/itsscb/df/bff/pb" + "github.com/itsscb/df/bff/val" + "google.golang.org/genproto/googleapis/rpc/errdetails" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (server *Server) CreateAccountInfo(ctx context.Context, req *pb.CreateAccountInfoRequest) (*pb.CreateAccountInfoResponse, error) { + authPayload, err := server.authorizeUser(ctx) + if err != nil { + return nil, unauthenticatedError(err) + } + + violations := validateCreateAccountInfoRequest(req) + if violations != nil { + return nil, invalidArgumentError(violations) + } + + account, err := server.store.GetAccount(ctx, req.GetAccountId()) + if err != nil { + slog.Error("create_account_info (get account)", slog.Int64("invoked_by", int64(req.GetAccountId())), slog.String("error", err.Error())) + return nil, status.Error(codes.Internal, "failed to get account") + } + + admin := server.isAdmin(ctx, authPayload) + + if authPayload.AccountID != account.ID { + if !admin { + return nil, status.Error(codes.NotFound, "account not found") + } + } + + if !account.EmailVerified.Bool { + if !admin { + return nil, status.Error(codes.Unauthenticated, "account not verified") + } + } + + ai, err := server.store.GetAccountInfo(ctx, req.GetAccountId()) + if err == nil { + fmt.Printf("%#v", ai) + return nil, status.Error(codes.AlreadyExists, "account_info already exists for this account") + } + + arg := db.CreateAccountInfoParams{ + AccountID: req.GetAccountId(), + Firstname: req.GetFirstname(), + Lastname: req.GetLastname(), + Street: req.GetStreet(), + City: req.GetCity(), + Zip: req.GetZip(), + Country: req.GetCountry(), + Phone: sql.NullString{ + Valid: req.GetPhone() != "", + String: req.GetPhone(), + }, + Birthday: req.GetBirthday().AsTime(), + PrivacyAccepted: sql.NullBool{ + Valid: req.PrivacyAccepted != nil, + Bool: req.GetPrivacyAccepted(), + }, + PrivacyAcceptedDate: sql.NullTime{ + Valid: req.PrivacyAccepted != nil, + Time: time.Now(), + }, + } + + account_info, err := server.store.CreateAccountInfo(ctx, arg) + if err != nil { + slog.Error("create_account_info (db)", slog.Int64("invoked_by", int64(req.GetAccountId())), slog.String("error", err.Error())) + return nil, status.Error(codes.Internal, "failed to create account info") + } + + rsp := &pb.CreateAccountInfoResponse{ + AccountInfo: convertAccountInfo(account_info), + } + + return rsp, nil +} + +func validateCreateAccountInfoRequest(req *pb.CreateAccountInfoRequest) (violations []*errdetails.BadRequest_FieldViolation) { + if !val.IsValidName(req.GetFirstname()) { + violations = append(violations, fieldViolation("firstname", errors.New("invalid input"))) + } + if !val.IsValidName(req.GetLastname()) { + violations = append(violations, fieldViolation("lastname", errors.New("invalid input"))) + } + if !val.IsValidAlphaNumSpace(req.GetStreet()) { + violations = append(violations, fieldViolation("street", errors.New("invalid input"))) + } + if !val.IsValidAlphaNumSpace(req.GetZip()) { + violations = append(violations, fieldViolation("zip", errors.New("invalid input"))) + } + if !val.IsValidName(req.GetCity()) { + violations = append(violations, fieldViolation("city", errors.New("invalid input"))) + } + if !val.IsValidName(req.GetCountry()) { + violations = append(violations, fieldViolation("country", errors.New("invalid input"))) + } + + return violations +} diff --git a/bff/gapi/rpc_get_account_info.go b/bff/gapi/rpc_get_account_info.go new file mode 100644 index 0000000..d701b85 --- /dev/null +++ b/bff/gapi/rpc_get_account_info.go @@ -0,0 +1,54 @@ +package gapi + +import ( + "context" + "database/sql" + "errors" + "log/slog" + + "github.com/itsscb/df/bff/pb" + "google.golang.org/genproto/googleapis/rpc/errdetails" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (server *Server) GetAccountInfo(ctx context.Context, req *pb.GetAccountInfoRequest) (*pb.GetAccountInfoResponse, error) { + authPayload, err := server.authorizeUser(ctx) + if err != nil { + return nil, unauthenticatedError(err) + } + + violations := validateGetAccountInfoRequest(req) + if violations != nil { + return nil, invalidArgumentError(violations) + } + + account, err := server.store.GetAccountInfo(ctx, req.GetAccountId()) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, status.Errorf(codes.NotFound, "account not found") + } + slog.Error("get_account (db)", slog.Int64("invoked_by", int64(authPayload.AccountID)), slog.Int64("account_id", int64(req.GetAccountId())), slog.String("error", err.Error())) + return nil, status.Error(codes.Internal, "failed to get account") + } + + if authPayload.AccountID != account.AccountID { + if !server.isAdmin(ctx, authPayload) { + return nil, status.Error(codes.NotFound, "account not found") + } + } + + rsp := &pb.GetAccountInfoResponse{ + AccountInfo: convertAccountInfo(account), + } + + return rsp, nil +} + +func validateGetAccountInfoRequest(req *pb.GetAccountInfoRequest) (violations []*errdetails.BadRequest_FieldViolation) { + if req.GetAccountId() < 1 { + violations = append(violations, fieldViolation("id", errors.New("must be greater than 0"))) + } + + return violations +} diff --git a/bff/gapi/rpc_update_account.go b/bff/gapi/rpc_update_account.go index a2ec0a4..83bef20 100644 --- a/bff/gapi/rpc_update_account.go +++ b/bff/gapi/rpc_update_account.go @@ -4,17 +4,19 @@ import ( "context" "database/sql" "errors" + "fmt" "log/slog" db "github.com/itsscb/df/bff/db/sqlc" "github.com/itsscb/df/bff/pb" + "github.com/itsscb/df/bff/util" "github.com/itsscb/df/bff/val" "google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) -func (server *Server) UpdateAccount(ctx context.Context, req *pb.UpdateAccountInfoRequest) (*pb.UpdateAccountInfoResponse, error) { +func (server *Server) UpdateAccount(ctx context.Context, req *pb.UpdateAccountRequest) (*pb.UpdateAccountResponse, error) { authPayload, err := server.authorizeUser(ctx) if err != nil { return nil, unauthenticatedError(err) @@ -31,90 +33,63 @@ func (server *Server) UpdateAccount(ctx context.Context, req *pb.UpdateAccountIn } } - account, err := server.store.GetAccount(ctx, req.GetAccountId()) + _, err = server.store.GetAccount(ctx, req.GetAccountId()) if err != nil { return nil, status.Error(codes.NotFound, "account not found") } - arg := db.UpdateAccountInfoTxParams{ - AccountID: req.GetAccountId(), - Changer: account.Email, - Firstname: sql.NullString{ - Valid: req.GetFirstname() != "", - String: req.GetFirstname(), - }, - Lastname: sql.NullString{ - Valid: req.GetLastname() != "", - String: req.GetLastname(), - }, - City: sql.NullString{ - Valid: req.GetCity() != "", - String: req.GetCity(), - }, - Zip: sql.NullString{ - Valid: req.GetZip() != "", - String: req.GetZip(), - }, - Street: sql.NullString{ - Valid: req.GetStreet() != "", - String: req.GetStreet(), - }, - Country: sql.NullString{ - Valid: req.GetCountry() != "", - String: req.GetCountry(), - }, - Phone: sql.NullString{ - Valid: req.GetPhone() != "", - String: req.GetPhone(), - }, - Birthday: sql.NullTime{ - Valid: req.GetBirthday().IsValid(), - Time: req.GetBirthday().AsTime(), + var hashedPassword string + if req.Password != nil { + hashedPassword, err = util.HashPassword(req.GetPassword()) + if err != nil { + slog.Error("create_account (hash_password)", slog.String("invoked_by", req.GetEmail()), slog.String("error", err.Error())) + return nil, status.Errorf(codes.Internal, "failed to hash password: %s", err) + } + } + + arg := db.UpdateAccountTxParams{ + UpdateAccountParams: db.UpdateAccountParams{ + ID: req.GetAccountId(), + Email: sql.NullString{ + Valid: req.Email != nil, + String: req.GetEmail(), + }, + Passwordhash: sql.NullString{ + Valid: req.Password != nil, + String: hashedPassword, + }, }, } - account_info, err := server.store.UpdateAccountInfoTx(ctx, arg) + if req.Email != nil { + arg.AfterUpdate = func(a db.Account) error { + return server.mailSender.SendEmail("Verify your E-Mail Address", fmt.Sprintf("Hello %s,

please verify your E-Mail Addres by clicking on the following link:
Verification Link


Your Team of DF", req.GetEmail(), a.ID, a.SecretKey.String), []string{req.GetEmail()}, nil, nil, nil) + } + } + + account, err := server.store.UpdateAccountTx(ctx, arg) if err != nil { slog.Error("update_account (db)", slog.Int64("invoked_by", int64(authPayload.AccountID)), slog.Int64("account_id", int64(req.GetAccountId())), slog.String("error", err.Error())) return nil, status.Error(codes.Internal, "failed to update account") } - rsp := &pb.UpdateAccountInfoResponse{ - AccountInfo: convertAccountInfo(account_info), + rsp := &pb.UpdateAccountResponse{ + Account: convertAccount(account), } return rsp, nil } -func validateUpdateAccountRequest(req *pb.UpdateAccountInfoRequest) (violations []*errdetails.BadRequest_FieldViolation) { +func validateUpdateAccountRequest(req *pb.UpdateAccountRequest) (violations []*errdetails.BadRequest_FieldViolation) { if req.GetAccountId() < 1 { violations = append(violations, fieldViolation("id", errors.New("must be greater than 0"))) } + if err := val.ValidateEmail(req.GetEmail()); err != nil { + violations = append(violations, fieldViolation("email", err)) + } - if req.GetFirstname() != "" { - if err := val.ValidateName(req.GetFirstname()); err != nil { - violations = append(violations, fieldViolation("first_name", err)) - } - } - if req.GetLastname() != "" { - if err := val.ValidateName(req.GetLastname()); err != nil { - violations = append(violations, fieldViolation("last_name", err)) - } - } - if req.GetCity() != "" { - if err := val.ValidateName(req.GetCity()); err != nil { - violations = append(violations, fieldViolation("city", err)) - } - } - if req.GetZip() != "" { - if err := val.ValidateName(req.GetZip()); err != nil { - violations = append(violations, fieldViolation("zip", err)) - } - } - if req.GetStreet() != "" { - if err := val.ValidateStreet(req.GetStreet()); err != nil { - violations = append(violations, fieldViolation("street", err)) - } + if err := val.ValidatePassword(req.GetPassword()); err != nil { + violations = append(violations, fieldViolation("password", err)) } return violations diff --git a/bff/gapi/rpc_update_account_info.go b/bff/gapi/rpc_update_account_info.go new file mode 100644 index 0000000..64b0bfd --- /dev/null +++ b/bff/gapi/rpc_update_account_info.go @@ -0,0 +1,121 @@ +package gapi + +import ( + "context" + "database/sql" + "errors" + "log/slog" + + db "github.com/itsscb/df/bff/db/sqlc" + "github.com/itsscb/df/bff/pb" + "github.com/itsscb/df/bff/val" + "google.golang.org/genproto/googleapis/rpc/errdetails" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (server *Server) UpdateAccountInfo(ctx context.Context, req *pb.UpdateAccountInfoRequest) (*pb.UpdateAccountInfoResponse, error) { + authPayload, err := server.authorizeUser(ctx) + if err != nil { + return nil, unauthenticatedError(err) + } + + violations := validateUpdateAccountInfoRequest(req) + if violations != nil { + return nil, invalidArgumentError(violations) + } + + if authPayload.AccountID != req.GetAccountId() { + if !server.isAdmin(ctx, authPayload) { + return nil, status.Error(codes.NotFound, "account not found") + } + } + + changer, err := server.store.GetAccount(ctx, authPayload.AccountID) + if err != nil { + return nil, status.Error(codes.NotFound, "account not found") + } + + arg := db.UpdateAccountInfoTxParams{ + AccountID: req.GetAccountId(), + Changer: changer.Email, + Firstname: sql.NullString{ + Valid: req.GetFirstname() != "", + String: req.GetFirstname(), + }, + Lastname: sql.NullString{ + Valid: req.GetLastname() != "", + String: req.GetLastname(), + }, + City: sql.NullString{ + Valid: req.GetCity() != "", + String: req.GetCity(), + }, + Zip: sql.NullString{ + Valid: req.GetZip() != "", + String: req.GetZip(), + }, + Street: sql.NullString{ + Valid: req.GetStreet() != "", + String: req.GetStreet(), + }, + Country: sql.NullString{ + Valid: req.GetCountry() != "", + String: req.GetCountry(), + }, + Phone: sql.NullString{ + Valid: req.GetPhone() != "", + String: req.GetPhone(), + }, + Birthday: sql.NullTime{ + Valid: req.GetBirthday().IsValid(), + Time: req.GetBirthday().AsTime(), + }, + } + + account_info, err := server.store.UpdateAccountInfoTx(ctx, arg) + if err != nil { + slog.Error("update_account (db)", slog.Int64("invoked_by", int64(authPayload.AccountID)), slog.Int64("account_id", int64(req.GetAccountId())), slog.String("error", err.Error())) + return nil, status.Error(codes.Internal, "failed to update account") + } + + rsp := &pb.UpdateAccountInfoResponse{ + AccountInfo: convertAccountInfo(account_info), + } + + return rsp, nil +} + +func validateUpdateAccountInfoRequest(req *pb.UpdateAccountInfoRequest) (violations []*errdetails.BadRequest_FieldViolation) { + if req.GetAccountId() < 1 { + violations = append(violations, fieldViolation("id", errors.New("must be greater than 0"))) + } + + if req.GetFirstname() != "" { + if err := val.ValidateName(req.GetFirstname()); err != nil { + violations = append(violations, fieldViolation("first_name", err)) + } + } + if req.GetLastname() != "" { + if err := val.ValidateName(req.GetLastname()); err != nil { + violations = append(violations, fieldViolation("last_name", err)) + } + } + if req.GetCity() != "" { + if err := val.ValidateName(req.GetCity()); err != nil { + violations = append(violations, fieldViolation("city", err)) + } + } + if req.GetZip() != "" { + if err := val.ValidateName(req.GetZip()); err != nil { + violations = append(violations, fieldViolation("zip", err)) + } + } + if req.GetStreet() != "" { + if err := val.ValidateStreet(req.GetStreet()); err != nil { + violations = append(violations, fieldViolation("street", err)) + } + } + + return violations +} diff --git a/bff/main.go b/bff/main.go index bb672a2..e4233d3 100644 --- a/bff/main.go +++ b/bff/main.go @@ -13,7 +13,6 @@ import ( "github.com/gin-gonic/gin" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - "github.com/itsscb/df/bff/api" db "github.com/itsscb/df/bff/db/sqlc" "github.com/itsscb/df/bff/gapi" "github.com/itsscb/df/bff/gw" @@ -158,15 +157,3 @@ func runGatewayServer(config util.Config, store db.Store, swaggerFS http.FileSys log.Fatal("cannot start HTTP gateway server") } } - -func runHTTPServer(config util.Config, store db.Store, swaggerFS http.FileSystem) { - server, err := api.NewServer(config, store, swaggerFS) - if err != nil { - log.Fatalf("could not start server: %s", err) - } - - err = server.Start(config.HTTPServerAddress) - if err != nil { - log.Fatal("cannot start server:", err) - } -} diff --git a/bff/pb/rpc_create_account_info.pb.go b/bff/pb/rpc_create_account_info.pb.go index 78609a3..0ed4635 100644 --- a/bff/pb/rpc_create_account_info.pb.go +++ b/bff/pb/rpc_create_account_info.pb.go @@ -27,6 +27,7 @@ type CreateAccountInfoRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + AccountId uint64 `protobuf:"varint,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` Firstname string `protobuf:"bytes,3,opt,name=firstname,proto3" json:"firstname,omitempty"` Lastname string `protobuf:"bytes,4,opt,name=lastname,proto3" json:"lastname,omitempty"` Street string `protobuf:"bytes,5,opt,name=street,proto3" json:"street,omitempty"` @@ -70,6 +71,13 @@ func (*CreateAccountInfoRequest) Descriptor() ([]byte, []int) { return file_rpc_create_account_info_proto_rawDescGZIP(), []int{0} } +func (x *CreateAccountInfoRequest) GetAccountId() uint64 { + if x != nil { + return x.AccountId + } + return 0 +} + func (x *CreateAccountInfoRequest) GetFirstname() string { if x != nil { return x.Firstname @@ -191,60 +199,62 @@ var file_rpc_create_account_info_proto_rawDesc = []byte{ 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x05, 0x0a, 0x18, 0x43, 0x72, 0x65, + 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbb, 0x05, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x7a, - 0x69, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x12, 0x18, 0x0a, - 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x53, 0x0a, - 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x1b, 0x92, 0x41, 0x18, - 0x4a, 0x16, 0x22, 0x31, 0x39, 0x39, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x54, 0x30, 0x30, - 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x5a, 0x22, 0x52, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, - 0x61, 0x79, 0x12, 0x39, 0x0a, 0x10, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x09, 0x92, 0x41, - 0x06, 0x4a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x63, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x3a, 0xb2, 0x02, - 0x92, 0x41, 0xae, 0x02, 0x0a, 0x7a, 0x2a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0x15, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0xd2, 0x01, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0xd2, 0x01, - 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0xd2, 0x01, 0x08, 0x6c, 0x61, 0x73, - 0x74, 0x6e, 0x61, 0x6d, 0x65, 0xd2, 0x01, 0x06, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0xd2, 0x01, - 0x04, 0x63, 0x69, 0x74, 0x79, 0xd2, 0x01, 0x03, 0x7a, 0x69, 0x70, 0xd2, 0x01, 0x07, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x72, 0x79, 0xd2, 0x01, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, - 0x32, 0xaf, 0x01, 0x7b, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, - 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x20, 0x22, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x22, 0x3a, 0x20, 0x22, 0x4a, 0x6f, 0x68, 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x6c, 0x61, 0x73, - 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x44, 0x6f, 0x65, 0x22, 0x2c, 0x20, 0x22, - 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x53, - 0x74, 0x72, 0x65, 0x65, 0x74, 0x20, 0x31, 0x22, 0x2c, 0x20, 0x22, 0x7a, 0x69, 0x70, 0x22, 0x3a, - 0x20, 0x22, 0x30, 0x38, 0x31, 0x35, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x69, 0x74, 0x79, 0x22, 0x3a, - 0x20, 0x22, 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x55, 0x53, 0x41, 0x22, 0x2c, 0x20, 0x22, - 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x39, 0x30, - 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x54, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x5a, - 0x22, 0x7d, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, - 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x03, 0x92, 0x41, - 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x3b, - 0x92, 0x41, 0x38, 0x0a, 0x36, 0x2a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0x1f, 0x52, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x19, 0x5a, 0x17, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, - 0x2f, 0x64, 0x66, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x7a, 0x69, + 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x53, 0x0a, 0x08, + 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x1b, 0x92, 0x41, 0x18, 0x4a, + 0x16, 0x22, 0x31, 0x39, 0x39, 0x30, 0x2d, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x54, 0x30, 0x30, 0x3a, + 0x30, 0x30, 0x3a, 0x30, 0x30, 0x5a, 0x22, 0x52, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, + 0x79, 0x12, 0x39, 0x0a, 0x10, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x09, 0x92, 0x41, 0x06, + 0x4a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x3a, 0xb2, 0x02, 0x92, + 0x41, 0xae, 0x02, 0x0a, 0x7a, 0x2a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x20, 0x61, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0xd2, 0x01, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0xd2, 0x01, 0x09, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0xd2, 0x01, 0x08, 0x6c, 0x61, 0x73, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0xd2, 0x01, 0x06, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0xd2, 0x01, 0x04, + 0x63, 0x69, 0x74, 0x79, 0xd2, 0x01, 0x03, 0x7a, 0x69, 0x70, 0xd2, 0x01, 0x07, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0xd2, 0x01, 0x08, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x32, + 0xaf, 0x01, 0x7b, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x3a, + 0x20, 0x22, 0x31, 0x22, 0x2c, 0x20, 0x22, 0x66, 0x69, 0x72, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x4a, 0x6f, 0x68, 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x6c, 0x61, 0x73, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x44, 0x6f, 0x65, 0x22, 0x2c, 0x20, 0x22, 0x73, + 0x74, 0x72, 0x65, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x53, 0x74, + 0x72, 0x65, 0x65, 0x74, 0x20, 0x31, 0x22, 0x2c, 0x20, 0x22, 0x7a, 0x69, 0x70, 0x22, 0x3a, 0x20, + 0x22, 0x30, 0x38, 0x31, 0x35, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x69, 0x74, 0x79, 0x22, 0x3a, 0x20, + 0x22, 0x4e, 0x65, 0x77, 0x20, 0x59, 0x6f, 0x72, 0x6b, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x55, 0x53, 0x41, 0x22, 0x2c, 0x20, 0x22, 0x62, + 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x39, 0x39, 0x30, 0x2d, + 0x31, 0x30, 0x2d, 0x30, 0x35, 0x54, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x5a, 0x22, + 0x7d, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x03, 0x92, 0x41, 0x00, + 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x3b, 0x92, + 0x41, 0x38, 0x0a, 0x36, 0x2a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0x1f, 0x52, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x19, 0x5a, 0x17, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, 0x2f, + 0x64, 0x66, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/bff/pb/rpc_update_account.pb.go b/bff/pb/rpc_update_account.pb.go new file mode 100644 index 0000000..f5db072 --- /dev/null +++ b/bff/pb/rpc_update_account.pb.go @@ -0,0 +1,249 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.4 +// source: rpc_update_account.proto + +package pb + +import ( + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type UpdateAccountRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccountId uint64 `protobuf:"varint,1,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + Email *string `protobuf:"bytes,2,opt,name=email,proto3,oneof" json:"email,omitempty"` + Password *string `protobuf:"bytes,3,opt,name=password,proto3,oneof" json:"password,omitempty"` +} + +func (x *UpdateAccountRequest) Reset() { + *x = UpdateAccountRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_update_account_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAccountRequest) ProtoMessage() {} + +func (x *UpdateAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_update_account_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAccountRequest.ProtoReflect.Descriptor instead. +func (*UpdateAccountRequest) Descriptor() ([]byte, []int) { + return file_rpc_update_account_proto_rawDescGZIP(), []int{0} +} + +func (x *UpdateAccountRequest) GetAccountId() uint64 { + if x != nil { + return x.AccountId + } + return 0 +} + +func (x *UpdateAccountRequest) GetEmail() string { + if x != nil && x.Email != nil { + return *x.Email + } + return "" +} + +func (x *UpdateAccountRequest) GetPassword() string { + if x != nil && x.Password != nil { + return *x.Password + } + return "" +} + +type UpdateAccountResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Account *Account `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` +} + +func (x *UpdateAccountResponse) Reset() { + *x = UpdateAccountResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_update_account_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAccountResponse) ProtoMessage() {} + +func (x *UpdateAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_rpc_update_account_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAccountResponse.ProtoReflect.Descriptor instead. +func (*UpdateAccountResponse) Descriptor() ([]byte, []int) { + return file_rpc_update_account_proto_rawDescGZIP(), []int{1} +} + +func (x *UpdateAccountResponse) GetAccount() *Account { + if x != nil { + return x.Account + } + return nil +} + +var File_rpc_update_account_proto protoreflect.FileDescriptor + +var file_rpc_update_account_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, + 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0d, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfb, 0x01, + 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x88, 0x01, 0x01, + 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x01, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x88, 0x01, + 0x01, 0x3a, 0x71, 0x92, 0x41, 0x6e, 0x0a, 0x36, 0x2a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x20, 0x61, 0x6e, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0xd2, 0x01, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0xd2, 0x01, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x32, 0x34, + 0x7b, 0x22, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, + 0x31, 0x22, 0x2c, 0x20, 0x22, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x3a, 0x20, 0x22, 0x6a, 0x6f, + 0x68, 0x6e, 0x2e, 0x64, 0x6f, 0x65, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x22, 0x7d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x0b, + 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x78, 0x0a, 0x15, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x42, 0x03, 0x92, 0x41, 0x00, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x3a, 0x33, 0x92, 0x41, 0x30, 0x0a, 0x2e, 0x2a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x1b, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x19, 0x5a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, 0x2f, 0x64, 0x66, 0x2f, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_rpc_update_account_proto_rawDescOnce sync.Once + file_rpc_update_account_proto_rawDescData = file_rpc_update_account_proto_rawDesc +) + +func file_rpc_update_account_proto_rawDescGZIP() []byte { + file_rpc_update_account_proto_rawDescOnce.Do(func() { + file_rpc_update_account_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_update_account_proto_rawDescData) + }) + return file_rpc_update_account_proto_rawDescData +} + +var file_rpc_update_account_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_rpc_update_account_proto_goTypes = []interface{}{ + (*UpdateAccountRequest)(nil), // 0: pb.UpdateAccountRequest + (*UpdateAccountResponse)(nil), // 1: pb.UpdateAccountResponse + (*Account)(nil), // 2: pb.Account +} +var file_rpc_update_account_proto_depIdxs = []int32{ + 2, // 0: pb.UpdateAccountResponse.account:type_name -> pb.Account + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_rpc_update_account_proto_init() } +func file_rpc_update_account_proto_init() { + if File_rpc_update_account_proto != nil { + return + } + file_account_proto_init() + if !protoimpl.UnsafeEnabled { + file_rpc_update_account_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateAccountRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_update_account_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateAccountResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_rpc_update_account_proto_msgTypes[0].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_update_account_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_rpc_update_account_proto_goTypes, + DependencyIndexes: file_rpc_update_account_proto_depIdxs, + MessageInfos: file_rpc_update_account_proto_msgTypes, + }.Build() + File_rpc_update_account_proto = out.File + file_rpc_update_account_proto_rawDesc = nil + file_rpc_update_account_proto_goTypes = nil + file_rpc_update_account_proto_depIdxs = nil +} diff --git a/bff/pb/service_df.pb.go b/bff/pb/service_df.pb.go index 19dd61d..e1795e9 100644 --- a/bff/pb/service_df.pb.go +++ b/bff/pb/service_df.pb.go @@ -50,300 +50,312 @@ var file_service_df_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x72, 0x70, 0x63, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x72, 0x70, 0x63, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x72, 0x70, 0x63, 0x5f, 0x67, 0x65, 0x74, 0x5f, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1b, 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1d, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, - 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x17, 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x65, - 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x17, 0x72, 0x70, 0x63, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x72, 0x70, 0x63, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x5f, 0x6c, 0x6f, 0x67, - 0x5f, 0x62, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, - 0x72, 0x70, 0x63, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x72, 0x70, 0x63, 0x5f, 0x76, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x32, 0xaa, 0x20, 0x0a, 0x02, 0x64, 0x66, 0x12, 0x42, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x12, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x3a, 0x01, - 0x2a, 0x22, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x68, 0x0a, 0x0c, - 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x17, 0x2e, 0x70, - 0x62, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0xa4, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x92, 0x41, 0x2f, 0x12, - 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x62, - 0x79, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, - 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x92, 0x01, - 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, - 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x4f, 0x92, 0x41, 0x27, 0x12, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, - 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x32, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x92, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x55, 0x92, 0x41, 0x2d, 0x12, 0x19, 0x47, 0x65, 0x74, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, - 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, 0x92, 0x41, 0x2e, - 0x12, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, - 0x5b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x5d, 0x62, 0x10, 0x0a, 0x0e, - 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, - 0x12, 0x9a, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, - 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x92, 0x41, 0x26, 0x12, 0x12, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, - 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, - 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0xaa, 0x01, - 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x62, - 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x92, 0x41, 0x31, 0x12, 0x1d, 0x47, 0x65, - 0x74, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x20, 0x62, 0x79, - 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, - 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x73, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xa7, 0x01, 0x0a, 0x0f, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, - 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x92, 0x41, 0x32, 0x12, 0x1e, 0x4c, 0x69, - 0x73, 0x74, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x20, - 0x5b, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x5d, 0x62, 0x10, 0x0a, 0x0e, - 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x8f, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x92, 0x41, 0x14, 0x12, 0x12, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xa1, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x70, - 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x92, 0x41, 0x26, 0x12, 0x12, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, - 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, - 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xbf, 0x01, 0x0a, 0x14, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x63, 0x79, 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x92, 0x41, 0x33, 0x12, 0x1f, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x63, 0x79, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x62, 0x10, 0x0a, 0x0e, - 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x32, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x12, 0x8b, 0x01, 0x0a, - 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x2e, - 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x48, 0x92, 0x41, 0x21, 0x12, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x50, 0x65, - 0x72, 0x73, 0x6f, 0x6e, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, - 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, - 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x8b, 0x01, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x70, 0x62, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, - 0x92, 0x41, 0x21, 0x12, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, - 0x6f, 0x6e, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, - 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, - 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x84, 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, - 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x92, 0x41, 0x24, 0x12, 0x10, 0x47, 0x65, 0x74, 0x20, 0x50, 0x65, - 0x72, 0x73, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x20, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1d, 0x72, 0x70, 0x63, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1a, 0x72, 0x70, 0x63, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x72, 0x70, + 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x72, 0x70, 0x63, 0x5f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x6f, + 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x72, 0x70, 0x63, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x17, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x72, 0x70, 0x63, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x72, 0x70, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x62, 0x79, 0x5f, 0x70, 0x65, + 0x72, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x72, + 0x70, 0x63, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x72, 0x70, 0x63, 0x5f, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x72, 0x70, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xc8, 0x21, 0x0a, 0x02, + 0x64, 0x66, 0x12, 0x42, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x10, 0x2e, 0x70, 0x62, + 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, + 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x3a, 0x01, 0x2a, 0x22, 0x09, 0x2f, 0x76, 0x31, + 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x68, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x2f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0xa4, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x92, 0x41, 0x2f, 0x12, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x20, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, + 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x69, 0x73, + 0x74, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x92, 0x41, 0x27, + 0x12, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, + 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, + 0x32, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x92, 0x01, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x92, 0x41, 0x2d, 0x12, + 0x19, 0x47, 0x65, 0x74, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, - 0x67, 0x65, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, - 0x93, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, - 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x27, 0x12, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, - 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, - 0x6e, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, - 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, - 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, + 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, + 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, 0x92, 0x41, 0x2e, 0x12, 0x1a, 0x4c, 0x69, 0x73, 0x74, + 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x5b, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x5d, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, + 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, + 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, + 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x0d, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, + 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x3d, 0x92, 0x41, 0x14, 0x12, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, + 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x91, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, + 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, 0x41, 0x22, 0x12, 0x0e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x62, 0x10, 0x0a, 0x0e, + 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xaf, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, + 0x92, 0x41, 0x31, 0x12, 0x1d, 0x47, 0x65, 0x74, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, + 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x31, 0x2f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xa7, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x70, 0x62, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x5b, 0x92, 0x41, 0x32, 0x12, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x20, 0x5b, 0x61, 0x64, 0x6d, + 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x5d, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, + 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, + 0x12, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x6c, + 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x12, 0xa6, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x54, 0x92, 0x41, 0x26, 0x12, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x62, 0x10, 0x0a, 0x0e, + 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0xa6, 0x01, 0x0a, 0x11, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x92, 0x41, + 0x26, 0x12, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, + 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, + 0x32, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x12, 0xbf, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x12, 0x1f, 0x2e, 0x70, 0x62, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, + 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, + 0x92, 0x41, 0x33, 0x12, 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x20, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, + 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x32, + 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x63, 0x79, 0x12, 0x8b, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x92, 0x41, 0x21, 0x12, 0x0d, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x62, 0x10, 0x0a, 0x0e, + 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x12, 0x8b, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, + 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x92, 0x41, 0x21, 0x12, 0x0d, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, + 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, + 0x6e, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x12, 0x84, 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x14, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x92, 0x41, 0x24, + 0x12, 0x10, 0x47, 0x65, 0x74, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x20, 0x62, 0x79, 0x20, + 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, + 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x50, 0x92, 0x41, 0x27, + 0x12, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x20, + 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, + 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, + 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x92, 0x41, 0x2e, 0x12, 0x1a, 0x4c, 0x69, 0x73, - 0x74, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, - 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, - 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x69, 0x73, - 0x74, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, - 0x41, 0x22, 0x12, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, - 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, - 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x47, - 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, - 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x92, 0x41, 0x25, 0x12, 0x11, 0x47, - 0x65, 0x74, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, - 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, - 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x99, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, - 0x92, 0x41, 0x28, 0x12, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x50, 0x61, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, - 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x22, 0x2a, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x12, 0xa4, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, - 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x61, 0x92, 0x41, 0x2f, 0x12, 0x1b, 0x4c, 0x69, - 0x73, 0x74, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, - 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0d, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, - 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x4b, 0x92, 0x41, 0x22, 0x12, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, - 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, - 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0xb0, - 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x4c, 0x6f, - 0x67, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, - 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x4c, 0x6f, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x92, 0x41, 0x30, 0x12, 0x1c, 0x4c, - 0x69, 0x73, 0x74, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x20, 0x62, - 0x79, 0x20, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, - 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, - 0x5f, 0x6c, 0x6f, 0x67, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x2f, 0x7b, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x7d, 0x12, 0xca, 0x02, 0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x80, 0x02, 0x92, 0x41, - 0xe0, 0x01, 0x12, 0x1b, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x20, 0x5b, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x48, 0x54, 0x54, 0x50, 0x5d, 0x1a, - 0xae, 0x01, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x69, 0x61, 0x20, 0x73, 0x77, - 0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x70, 0x6f, 0x73, - 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2e, 0x20, 0x54, 0x72, 0x79, 0x20, 0x60, 0x60, 0x60, 0x63, 0x75, - 0x72, 0x6c, 0x20, 0x2d, 0x58, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x2d, 0x48, 0x20, 0x22, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x42, 0x65, - 0x61, 0x72, 0x65, 0x72, 0x20, 0x7b, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x7d, 0x22, 0x20, 0x2d, 0x46, - 0x20, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x3d, 0x40, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x2f, 0x74, 0x6f, - 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x20, 0x2d, 0x46, 0x20, 0x22, 0x70, 0x65, 0x72, 0x73, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x3d, 0x31, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x7b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x52, 0x49, 0x7d, 0x2f, 0x64, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x60, 0x60, 0x60, - 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, - 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x9f, - 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, - 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x29, 0x12, 0x15, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x62, - 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, - 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x76, - 0x31, 0x2f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xa2, 0x01, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, - 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x62, 0x92, 0x41, 0x2d, 0x12, 0x2b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x20, 0x45, - 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x69, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, - 0x6b, 0x65, 0x79, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x76, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2f, 0x7b, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x5f, 0x6b, 0x65, 0x79, 0x7d, 0x1a, 0x07, 0x92, 0x41, 0x04, 0x12, 0x02, 0x64, 0x66, 0x42, 0xb0, - 0x01, 0x92, 0x41, 0x93, 0x01, 0x12, 0x44, 0x0a, 0x06, 0x64, 0x66, 0x20, 0x41, 0x50, 0x49, 0x22, - 0x35, 0x0a, 0x06, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, 0x12, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, - 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, - 0x73, 0x73, 0x63, 0x62, 0x2f, 0x64, 0x66, 0x1a, 0x0d, 0x64, 0x65, 0x76, 0x40, 0x69, 0x74, 0x73, - 0x73, 0x63, 0x62, 0x2e, 0x64, 0x65, 0x32, 0x03, 0x31, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, - 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, - 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, - 0x73, 0x6f, 0x6e, 0x5a, 0x23, 0x0a, 0x21, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, - 0x75, 0x74, 0x68, 0x12, 0x13, 0x08, 0x02, 0x1a, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x02, 0x5a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, 0x2f, 0x64, 0x66, 0x2f, 0x70, - 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, + 0x92, 0x41, 0x2e, 0x12, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x62, + 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, + 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x91, + 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, 0x41, 0x22, 0x12, 0x0e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, + 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, + 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x4d, 0x92, 0x41, 0x25, 0x12, 0x11, 0x47, 0x65, 0x74, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, + 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, + 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x67, + 0x65, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, + 0x99, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x62, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, 0x92, 0x41, 0x28, 0x12, 0x14, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x49, + 0x44, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, + 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x2a, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa4, 0x01, 0x0a, 0x0c, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x17, 0x2e, 0x70, + 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x61, 0x92, 0x41, 0x2f, 0x12, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x62, 0x79, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, + 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, 0x41, 0x22, 0x12, 0x0e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x10, + 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0xb0, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x67, 0x92, 0x41, 0x30, 0x12, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x52, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x20, 0x62, 0x79, 0x20, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, + 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31, + 0x2f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x2f, 0x6c, 0x69, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x2f, 0x7b, 0x70, + 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xca, 0x02, 0x0a, 0x0e, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x2e, 0x70, + 0x62, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x80, 0x02, 0x92, 0x41, 0xe0, 0x01, 0x12, 0x1b, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x5b, 0x6f, 0x6e, 0x6c, + 0x79, 0x20, 0x48, 0x54, 0x54, 0x50, 0x5d, 0x1a, 0xae, 0x01, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x76, 0x69, 0x61, 0x20, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x20, 0x69, 0x73, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2e, 0x20, 0x54, + 0x72, 0x79, 0x20, 0x60, 0x60, 0x60, 0x63, 0x75, 0x72, 0x6c, 0x20, 0x2d, 0x58, 0x20, 0x50, 0x4f, + 0x53, 0x54, 0x20, 0x2d, 0x48, 0x20, 0x22, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x20, 0x7b, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x7d, 0x22, 0x20, 0x2d, 0x46, 0x20, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x3d, 0x40, + 0x2f, 0x70, 0x61, 0x74, 0x68, 0x2f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x20, 0x2d, + 0x46, 0x20, 0x22, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x3d, 0x31, 0x22, 0x20, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, + 0x52, 0x49, 0x7d, 0x2f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x60, 0x60, 0x60, 0x62, 0x10, 0x0a, 0x0e, 0x0a, 0x0a, 0x42, 0x65, + 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, + 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, + 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x9f, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x56, 0x92, 0x41, 0x29, 0x12, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x44, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x20, 0x49, 0x44, 0x62, 0x10, 0x0a, 0x0e, + 0x0a, 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x00, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa2, 0x01, 0x0a, 0x0b, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x62, 0x92, 0x41, 0x2d, 0x12, 0x2b, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x2c, 0x12, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x7b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x7d, 0x1a, 0x07, 0x92, + 0x41, 0x04, 0x12, 0x02, 0x64, 0x66, 0x42, 0xb0, 0x01, 0x92, 0x41, 0x93, 0x01, 0x12, 0x44, 0x0a, + 0x06, 0x64, 0x66, 0x20, 0x41, 0x50, 0x49, 0x22, 0x35, 0x0a, 0x06, 0x69, 0x74, 0x73, 0x73, 0x63, + 0x62, 0x12, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, 0x2f, 0x64, 0x66, 0x1a, + 0x0d, 0x64, 0x65, 0x76, 0x40, 0x69, 0x74, 0x73, 0x73, 0x63, 0x62, 0x2e, 0x64, 0x65, 0x32, 0x03, + 0x31, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x5a, 0x23, 0x0a, 0x21, 0x0a, + 0x0a, 0x42, 0x65, 0x61, 0x72, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12, 0x13, 0x08, 0x02, 0x1a, + 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x02, + 0x5a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x74, 0x73, + 0x73, 0x63, 0x62, 0x2f, 0x64, 0x66, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var file_service_df_proto_goTypes = []interface{}{ @@ -354,51 +366,53 @@ var file_service_df_proto_goTypes = []interface{}{ (*GetAccountRequest)(nil), // 4: pb.GetAccountRequest (*ListAccountsRequest)(nil), // 5: pb.ListAccountsRequest (*CreateAccountRequest)(nil), // 6: pb.CreateAccountRequest - (*GetAccountInfoRequest)(nil), // 7: pb.GetAccountInfoRequest - (*ListAccountInfoRequest)(nil), // 8: pb.ListAccountInfoRequest - (*CreateAccountInfoRequest)(nil), // 9: pb.CreateAccountInfoRequest - (*UpdateAccountInfoRequest)(nil), // 10: pb.UpdateAccountInfoRequest - (*UpdateAccountPrivacyRequest)(nil), // 11: pb.UpdateAccountPrivacyRequest - (*CreatePersonRequest)(nil), // 12: pb.CreatePersonRequest - (*UpdatePersonRequest)(nil), // 13: pb.UpdatePersonRequest - (*GetPersonRequest)(nil), // 14: pb.GetPersonRequest - (*DeletePersonRequest)(nil), // 15: pb.DeletePersonRequest - (*ListPersonsRequest)(nil), // 16: pb.ListPersonsRequest - (*CreatePaymentRequest)(nil), // 17: pb.CreatePaymentRequest - (*GetPaymentRequest)(nil), // 18: pb.GetPaymentRequest - (*DeletePaymentRequest)(nil), // 19: pb.DeletePaymentRequest - (*ListPaymentsRequest)(nil), // 20: pb.ListPaymentsRequest - (*UpdatePaymentRequest)(nil), // 21: pb.UpdatePaymentRequest - (*ListReturnsLogRequest)(nil), // 22: pb.ListReturnsLogRequest - (*UploadDocumentRequest)(nil), // 23: pb.UploadDocumentRequest - (*DeleteDocumentRequest)(nil), // 24: pb.DeleteDocumentRequest - (*VerifyEmailRequest)(nil), // 25: pb.VerifyEmailRequest - (*LoginResponse)(nil), // 26: pb.LoginResponse - (*RefreshTokenResponse)(nil), // 27: pb.RefreshTokenResponse - (*ListSessionsResponse)(nil), // 28: pb.ListSessionsResponse - (*BlockSessionResponse)(nil), // 29: pb.BlockSessionResponse - (*GetAccountResponse)(nil), // 30: pb.GetAccountResponse - (*ListAccountsResponse)(nil), // 31: pb.ListAccountsResponse - (*CreateAccountResponse)(nil), // 32: pb.CreateAccountResponse - (*GetAccountInfoResponse)(nil), // 33: pb.GetAccountInfoResponse - (*ListAccountInfoResponse)(nil), // 34: pb.ListAccountInfoResponse - (*CreateAccountInfoResponse)(nil), // 35: pb.CreateAccountInfoResponse - (*UpdateAccountInfoResponse)(nil), // 36: pb.UpdateAccountInfoResponse - (*UpdateAccountPrivacyResponse)(nil), // 37: pb.UpdateAccountPrivacyResponse - (*CreatePersonResponse)(nil), // 38: pb.CreatePersonResponse - (*UpdatePersonResponse)(nil), // 39: pb.UpdatePersonResponse - (*GetPersonResponse)(nil), // 40: pb.GetPersonResponse - (*DeletePersonResponse)(nil), // 41: pb.DeletePersonResponse - (*ListPersonsResponse)(nil), // 42: pb.ListPersonsResponse - (*CreatePaymentResponse)(nil), // 43: pb.CreatePaymentResponse - (*GetPaymentResponse)(nil), // 44: pb.GetPaymentResponse - (*DeletePaymentResponse)(nil), // 45: pb.DeletePaymentResponse - (*ListPaymentsResponse)(nil), // 46: pb.ListPaymentsResponse - (*UpdatePaymentResponse)(nil), // 47: pb.UpdatePaymentResponse - (*ListReturnsLogResponse)(nil), // 48: pb.ListReturnsLogResponse - (*UploadDocumentResponse)(nil), // 49: pb.UploadDocumentResponse - (*DeleteDocumentResponse)(nil), // 50: pb.DeleteDocumentResponse - (*VerifyEmailResponse)(nil), // 51: pb.VerifyEmailResponse + (*UpdateAccountRequest)(nil), // 7: pb.UpdateAccountRequest + (*GetAccountInfoRequest)(nil), // 8: pb.GetAccountInfoRequest + (*ListAccountInfoRequest)(nil), // 9: pb.ListAccountInfoRequest + (*CreateAccountInfoRequest)(nil), // 10: pb.CreateAccountInfoRequest + (*UpdateAccountInfoRequest)(nil), // 11: pb.UpdateAccountInfoRequest + (*UpdateAccountPrivacyRequest)(nil), // 12: pb.UpdateAccountPrivacyRequest + (*CreatePersonRequest)(nil), // 13: pb.CreatePersonRequest + (*UpdatePersonRequest)(nil), // 14: pb.UpdatePersonRequest + (*GetPersonRequest)(nil), // 15: pb.GetPersonRequest + (*DeletePersonRequest)(nil), // 16: pb.DeletePersonRequest + (*ListPersonsRequest)(nil), // 17: pb.ListPersonsRequest + (*CreatePaymentRequest)(nil), // 18: pb.CreatePaymentRequest + (*GetPaymentRequest)(nil), // 19: pb.GetPaymentRequest + (*DeletePaymentRequest)(nil), // 20: pb.DeletePaymentRequest + (*ListPaymentsRequest)(nil), // 21: pb.ListPaymentsRequest + (*UpdatePaymentRequest)(nil), // 22: pb.UpdatePaymentRequest + (*ListReturnsLogRequest)(nil), // 23: pb.ListReturnsLogRequest + (*UploadDocumentRequest)(nil), // 24: pb.UploadDocumentRequest + (*DeleteDocumentRequest)(nil), // 25: pb.DeleteDocumentRequest + (*VerifyEmailRequest)(nil), // 26: pb.VerifyEmailRequest + (*LoginResponse)(nil), // 27: pb.LoginResponse + (*RefreshTokenResponse)(nil), // 28: pb.RefreshTokenResponse + (*ListSessionsResponse)(nil), // 29: pb.ListSessionsResponse + (*BlockSessionResponse)(nil), // 30: pb.BlockSessionResponse + (*GetAccountResponse)(nil), // 31: pb.GetAccountResponse + (*ListAccountsResponse)(nil), // 32: pb.ListAccountsResponse + (*CreateAccountResponse)(nil), // 33: pb.CreateAccountResponse + (*UpdateAccountResponse)(nil), // 34: pb.UpdateAccountResponse + (*GetAccountInfoResponse)(nil), // 35: pb.GetAccountInfoResponse + (*ListAccountInfoResponse)(nil), // 36: pb.ListAccountInfoResponse + (*CreateAccountInfoResponse)(nil), // 37: pb.CreateAccountInfoResponse + (*UpdateAccountInfoResponse)(nil), // 38: pb.UpdateAccountInfoResponse + (*UpdateAccountPrivacyResponse)(nil), // 39: pb.UpdateAccountPrivacyResponse + (*CreatePersonResponse)(nil), // 40: pb.CreatePersonResponse + (*UpdatePersonResponse)(nil), // 41: pb.UpdatePersonResponse + (*GetPersonResponse)(nil), // 42: pb.GetPersonResponse + (*DeletePersonResponse)(nil), // 43: pb.DeletePersonResponse + (*ListPersonsResponse)(nil), // 44: pb.ListPersonsResponse + (*CreatePaymentResponse)(nil), // 45: pb.CreatePaymentResponse + (*GetPaymentResponse)(nil), // 46: pb.GetPaymentResponse + (*DeletePaymentResponse)(nil), // 47: pb.DeletePaymentResponse + (*ListPaymentsResponse)(nil), // 48: pb.ListPaymentsResponse + (*UpdatePaymentResponse)(nil), // 49: pb.UpdatePaymentResponse + (*ListReturnsLogResponse)(nil), // 50: pb.ListReturnsLogResponse + (*UploadDocumentResponse)(nil), // 51: pb.UploadDocumentResponse + (*DeleteDocumentResponse)(nil), // 52: pb.DeleteDocumentResponse + (*VerifyEmailResponse)(nil), // 53: pb.VerifyEmailResponse } var file_service_df_proto_depIdxs = []int32{ 0, // 0: pb.df.Login:input_type -> pb.LoginRequest @@ -408,53 +422,55 @@ var file_service_df_proto_depIdxs = []int32{ 4, // 4: pb.df.GetAccount:input_type -> pb.GetAccountRequest 5, // 5: pb.df.ListAccounts:input_type -> pb.ListAccountsRequest 6, // 6: pb.df.CreateAccount:input_type -> pb.CreateAccountRequest - 7, // 7: pb.df.GetAccountInfo:input_type -> pb.GetAccountInfoRequest - 8, // 8: pb.df.ListAccountInfo:input_type -> pb.ListAccountInfoRequest - 9, // 9: pb.df.CreateAccountInfo:input_type -> pb.CreateAccountInfoRequest - 10, // 10: pb.df.UpdateAccountInfo:input_type -> pb.UpdateAccountInfoRequest - 11, // 11: pb.df.UpdateAccountPrivacy:input_type -> pb.UpdateAccountPrivacyRequest - 12, // 12: pb.df.CreatePerson:input_type -> pb.CreatePersonRequest - 13, // 13: pb.df.UpdatePerson:input_type -> pb.UpdatePersonRequest - 14, // 14: pb.df.GetPerson:input_type -> pb.GetPersonRequest - 15, // 15: pb.df.DeletePerson:input_type -> pb.DeletePersonRequest - 16, // 16: pb.df.ListPersons:input_type -> pb.ListPersonsRequest - 17, // 17: pb.df.CreatePayment:input_type -> pb.CreatePaymentRequest - 18, // 18: pb.df.GetPayment:input_type -> pb.GetPaymentRequest - 19, // 19: pb.df.DeletePayment:input_type -> pb.DeletePaymentRequest - 20, // 20: pb.df.ListPayments:input_type -> pb.ListPaymentsRequest - 21, // 21: pb.df.UpdatePayment:input_type -> pb.UpdatePaymentRequest - 22, // 22: pb.df.ListReturnsLog:input_type -> pb.ListReturnsLogRequest - 23, // 23: pb.df.UploadDocument:input_type -> pb.UploadDocumentRequest - 24, // 24: pb.df.DeleteDocument:input_type -> pb.DeleteDocumentRequest - 25, // 25: pb.df.VerifyEmail:input_type -> pb.VerifyEmailRequest - 26, // 26: pb.df.Login:output_type -> pb.LoginResponse - 27, // 27: pb.df.RefreshToken:output_type -> pb.RefreshTokenResponse - 28, // 28: pb.df.ListSessions:output_type -> pb.ListSessionsResponse - 29, // 29: pb.df.BlockSession:output_type -> pb.BlockSessionResponse - 30, // 30: pb.df.GetAccount:output_type -> pb.GetAccountResponse - 31, // 31: pb.df.ListAccounts:output_type -> pb.ListAccountsResponse - 32, // 32: pb.df.CreateAccount:output_type -> pb.CreateAccountResponse - 33, // 33: pb.df.GetAccountInfo:output_type -> pb.GetAccountInfoResponse - 34, // 34: pb.df.ListAccountInfo:output_type -> pb.ListAccountInfoResponse - 35, // 35: pb.df.CreateAccountInfo:output_type -> pb.CreateAccountInfoResponse - 36, // 36: pb.df.UpdateAccountInfo:output_type -> pb.UpdateAccountInfoResponse - 37, // 37: pb.df.UpdateAccountPrivacy:output_type -> pb.UpdateAccountPrivacyResponse - 38, // 38: pb.df.CreatePerson:output_type -> pb.CreatePersonResponse - 39, // 39: pb.df.UpdatePerson:output_type -> pb.UpdatePersonResponse - 40, // 40: pb.df.GetPerson:output_type -> pb.GetPersonResponse - 41, // 41: pb.df.DeletePerson:output_type -> pb.DeletePersonResponse - 42, // 42: pb.df.ListPersons:output_type -> pb.ListPersonsResponse - 43, // 43: pb.df.CreatePayment:output_type -> pb.CreatePaymentResponse - 44, // 44: pb.df.GetPayment:output_type -> pb.GetPaymentResponse - 45, // 45: pb.df.DeletePayment:output_type -> pb.DeletePaymentResponse - 46, // 46: pb.df.ListPayments:output_type -> pb.ListPaymentsResponse - 47, // 47: pb.df.UpdatePayment:output_type -> pb.UpdatePaymentResponse - 48, // 48: pb.df.ListReturnsLog:output_type -> pb.ListReturnsLogResponse - 49, // 49: pb.df.UploadDocument:output_type -> pb.UploadDocumentResponse - 50, // 50: pb.df.DeleteDocument:output_type -> pb.DeleteDocumentResponse - 51, // 51: pb.df.VerifyEmail:output_type -> pb.VerifyEmailResponse - 26, // [26:52] is the sub-list for method output_type - 0, // [0:26] is the sub-list for method input_type + 7, // 7: pb.df.UpdateAccount:input_type -> pb.UpdateAccountRequest + 8, // 8: pb.df.GetAccountInfo:input_type -> pb.GetAccountInfoRequest + 9, // 9: pb.df.ListAccountInfo:input_type -> pb.ListAccountInfoRequest + 10, // 10: pb.df.CreateAccountInfo:input_type -> pb.CreateAccountInfoRequest + 11, // 11: pb.df.UpdateAccountInfo:input_type -> pb.UpdateAccountInfoRequest + 12, // 12: pb.df.UpdateAccountPrivacy:input_type -> pb.UpdateAccountPrivacyRequest + 13, // 13: pb.df.CreatePerson:input_type -> pb.CreatePersonRequest + 14, // 14: pb.df.UpdatePerson:input_type -> pb.UpdatePersonRequest + 15, // 15: pb.df.GetPerson:input_type -> pb.GetPersonRequest + 16, // 16: pb.df.DeletePerson:input_type -> pb.DeletePersonRequest + 17, // 17: pb.df.ListPersons:input_type -> pb.ListPersonsRequest + 18, // 18: pb.df.CreatePayment:input_type -> pb.CreatePaymentRequest + 19, // 19: pb.df.GetPayment:input_type -> pb.GetPaymentRequest + 20, // 20: pb.df.DeletePayment:input_type -> pb.DeletePaymentRequest + 21, // 21: pb.df.ListPayments:input_type -> pb.ListPaymentsRequest + 22, // 22: pb.df.UpdatePayment:input_type -> pb.UpdatePaymentRequest + 23, // 23: pb.df.ListReturnsLog:input_type -> pb.ListReturnsLogRequest + 24, // 24: pb.df.UploadDocument:input_type -> pb.UploadDocumentRequest + 25, // 25: pb.df.DeleteDocument:input_type -> pb.DeleteDocumentRequest + 26, // 26: pb.df.VerifyEmail:input_type -> pb.VerifyEmailRequest + 27, // 27: pb.df.Login:output_type -> pb.LoginResponse + 28, // 28: pb.df.RefreshToken:output_type -> pb.RefreshTokenResponse + 29, // 29: pb.df.ListSessions:output_type -> pb.ListSessionsResponse + 30, // 30: pb.df.BlockSession:output_type -> pb.BlockSessionResponse + 31, // 31: pb.df.GetAccount:output_type -> pb.GetAccountResponse + 32, // 32: pb.df.ListAccounts:output_type -> pb.ListAccountsResponse + 33, // 33: pb.df.CreateAccount:output_type -> pb.CreateAccountResponse + 34, // 34: pb.df.UpdateAccount:output_type -> pb.UpdateAccountResponse + 35, // 35: pb.df.GetAccountInfo:output_type -> pb.GetAccountInfoResponse + 36, // 36: pb.df.ListAccountInfo:output_type -> pb.ListAccountInfoResponse + 37, // 37: pb.df.CreateAccountInfo:output_type -> pb.CreateAccountInfoResponse + 38, // 38: pb.df.UpdateAccountInfo:output_type -> pb.UpdateAccountInfoResponse + 39, // 39: pb.df.UpdateAccountPrivacy:output_type -> pb.UpdateAccountPrivacyResponse + 40, // 40: pb.df.CreatePerson:output_type -> pb.CreatePersonResponse + 41, // 41: pb.df.UpdatePerson:output_type -> pb.UpdatePersonResponse + 42, // 42: pb.df.GetPerson:output_type -> pb.GetPersonResponse + 43, // 43: pb.df.DeletePerson:output_type -> pb.DeletePersonResponse + 44, // 44: pb.df.ListPersons:output_type -> pb.ListPersonsResponse + 45, // 45: pb.df.CreatePayment:output_type -> pb.CreatePaymentResponse + 46, // 46: pb.df.GetPayment:output_type -> pb.GetPaymentResponse + 47, // 47: pb.df.DeletePayment:output_type -> pb.DeletePaymentResponse + 48, // 48: pb.df.ListPayments:output_type -> pb.ListPaymentsResponse + 49, // 49: pb.df.UpdatePayment:output_type -> pb.UpdatePaymentResponse + 50, // 50: pb.df.ListReturnsLog:output_type -> pb.ListReturnsLogResponse + 51, // 51: pb.df.UploadDocument:output_type -> pb.UploadDocumentResponse + 52, // 52: pb.df.DeleteDocument:output_type -> pb.DeleteDocumentResponse + 53, // 53: pb.df.VerifyEmail:output_type -> pb.VerifyEmailResponse + 27, // [27:54] is the sub-list for method output_type + 0, // [0:27] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -478,6 +494,7 @@ func file_service_df_proto_init() { file_rpc_create_account_proto_init() file_rpc_get_account_proto_init() file_rpc_list_accounts_proto_init() + file_rpc_update_account_proto_init() file_rpc_update_account_privacy_proto_init() file_rpc_create_account_info_proto_init() file_rpc_get_account_info_proto_init() diff --git a/bff/pb/service_df.pb.gw.go b/bff/pb/service_df.pb.gw.go index 4711247..66e10e8 100644 --- a/bff/pb/service_df.pb.gw.go +++ b/bff/pb/service_df.pb.gw.go @@ -307,6 +307,40 @@ func local_request_Df_CreateAccount_0(ctx context.Context, marshaler runtime.Mar } +func request_Df_UpdateAccount_0(ctx context.Context, marshaler runtime.Marshaler, client DfClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateAccountRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Df_UpdateAccount_0(ctx context.Context, marshaler runtime.Marshaler, server DfServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateAccountRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateAccount(ctx, &protoReq) + return msg, metadata, err + +} + func request_Df_GetAccountInfo_0(ctx context.Context, marshaler runtime.Marshaler, client DfClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetAccountInfoRequest var metadata runtime.ServerMetadata @@ -1319,7 +1353,7 @@ func RegisterDfHandlerServer(ctx context.Context, mux *runtime.ServeMux, server inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/CreateAccount", runtime.WithHTTPPathPattern("/v1/accounts/create_account_info")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/CreateAccount", runtime.WithHTTPPathPattern("/v1/accounts/create_account")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -1336,6 +1370,31 @@ func RegisterDfHandlerServer(ctx context.Context, mux *runtime.ServeMux, server }) + mux.Handle("PATCH", pattern_Df_UpdateAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/UpdateAccount", runtime.WithHTTPPathPattern("/v1/accounts/update_account")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Df_UpdateAccount_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Df_UpdateAccount_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Df_GetAccountInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1344,7 +1403,7 @@ func RegisterDfHandlerServer(ctx context.Context, mux *runtime.ServeMux, server inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/GetAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/get_account/{account_id}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/GetAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/get_account_info/{account_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -1394,7 +1453,7 @@ func RegisterDfHandlerServer(ctx context.Context, mux *runtime.ServeMux, server inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/CreateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/create_account")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/CreateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/create_account_info")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -1419,7 +1478,7 @@ func RegisterDfHandlerServer(ctx context.Context, mux *runtime.ServeMux, server inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/UpdateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/update_account")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/pb.Df/UpdateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/update_account_info")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -1990,7 +2049,7 @@ func RegisterDfHandlerClient(ctx context.Context, mux *runtime.ServeMux, client inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/CreateAccount", runtime.WithHTTPPathPattern("/v1/accounts/create_account_info")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/CreateAccount", runtime.WithHTTPPathPattern("/v1/accounts/create_account")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -2006,13 +2065,35 @@ func RegisterDfHandlerClient(ctx context.Context, mux *runtime.ServeMux, client }) + mux.Handle("PATCH", pattern_Df_UpdateAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/UpdateAccount", runtime.WithHTTPPathPattern("/v1/accounts/update_account")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Df_UpdateAccount_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Df_UpdateAccount_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Df_GetAccountInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/GetAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/get_account/{account_id}")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/GetAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/get_account_info/{account_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -2056,7 +2137,7 @@ func RegisterDfHandlerClient(ctx context.Context, mux *runtime.ServeMux, client inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/CreateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/create_account")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/CreateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/create_account_info")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -2078,7 +2159,7 @@ func RegisterDfHandlerClient(ctx context.Context, mux *runtime.ServeMux, client inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/UpdateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/update_account")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/pb.Df/UpdateAccountInfo", runtime.WithHTTPPathPattern("/v1/accounts/update_account_info")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -2440,15 +2521,17 @@ var ( pattern_Df_ListAccounts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "list_accounts"}, "")) - pattern_Df_CreateAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "create_account_info"}, "")) + pattern_Df_CreateAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "create_account"}, "")) - pattern_Df_GetAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "accounts", "get_account", "account_id"}, "")) + pattern_Df_UpdateAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "update_account"}, "")) + + pattern_Df_GetAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "accounts", "get_account_info", "account_id"}, "")) pattern_Df_ListAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "list_account_info"}, "")) - pattern_Df_CreateAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "create_account"}, "")) + pattern_Df_CreateAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "create_account_info"}, "")) - pattern_Df_UpdateAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "update_account"}, "")) + pattern_Df_UpdateAccountInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "update_account_info"}, "")) pattern_Df_UpdateAccountPrivacy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "accounts", "update_account_privacy"}, "")) @@ -2496,6 +2579,8 @@ var ( forward_Df_CreateAccount_0 = runtime.ForwardResponseMessage + forward_Df_UpdateAccount_0 = runtime.ForwardResponseMessage + forward_Df_GetAccountInfo_0 = runtime.ForwardResponseMessage forward_Df_ListAccountInfo_0 = runtime.ForwardResponseMessage diff --git a/bff/pb/service_df_grpc.pb.go b/bff/pb/service_df_grpc.pb.go index 1dc311c..568a0c0 100644 --- a/bff/pb/service_df_grpc.pb.go +++ b/bff/pb/service_df_grpc.pb.go @@ -26,6 +26,7 @@ const ( Df_GetAccount_FullMethodName = "/pb.df/GetAccount" Df_ListAccounts_FullMethodName = "/pb.df/ListAccounts" Df_CreateAccount_FullMethodName = "/pb.df/CreateAccount" + Df_UpdateAccount_FullMethodName = "/pb.df/UpdateAccount" Df_GetAccountInfo_FullMethodName = "/pb.df/GetAccountInfo" Df_ListAccountInfo_FullMethodName = "/pb.df/ListAccountInfo" Df_CreateAccountInfo_FullMethodName = "/pb.df/CreateAccountInfo" @@ -58,21 +59,7 @@ type DfClient interface { GetAccount(ctx context.Context, in *GetAccountRequest, opts ...grpc.CallOption) (*GetAccountResponse, error) ListAccounts(ctx context.Context, in *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error) CreateAccount(ctx context.Context, in *CreateAccountRequest, opts ...grpc.CallOption) (*CreateAccountResponse, error) - // rpc UpdateAccount (UpdateAccountRequest) returns (UpdateAccountResponse) { - // option (google.api.http) = { - // patch: "/v1/accounts/update_account" - // body: "*" - // }; - // option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { - // summary: "Update Account" - // security: { - // security_requirement: { - // key: "BearerAuth"; - // value: {} - // } - // } - // }; - // }; + UpdateAccount(ctx context.Context, in *UpdateAccountRequest, opts ...grpc.CallOption) (*UpdateAccountResponse, error) GetAccountInfo(ctx context.Context, in *GetAccountInfoRequest, opts ...grpc.CallOption) (*GetAccountInfoResponse, error) ListAccountInfo(ctx context.Context, in *ListAccountInfoRequest, opts ...grpc.CallOption) (*ListAccountInfoResponse, error) CreateAccountInfo(ctx context.Context, in *CreateAccountInfoRequest, opts ...grpc.CallOption) (*CreateAccountInfoResponse, error) @@ -165,6 +152,15 @@ func (c *dfClient) CreateAccount(ctx context.Context, in *CreateAccountRequest, return out, nil } +func (c *dfClient) UpdateAccount(ctx context.Context, in *UpdateAccountRequest, opts ...grpc.CallOption) (*UpdateAccountResponse, error) { + out := new(UpdateAccountResponse) + err := c.cc.Invoke(ctx, Df_UpdateAccount_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *dfClient) GetAccountInfo(ctx context.Context, in *GetAccountInfoRequest, opts ...grpc.CallOption) (*GetAccountInfoResponse, error) { out := new(GetAccountInfoResponse) err := c.cc.Invoke(ctx, Df_GetAccountInfo_FullMethodName, in, out, opts...) @@ -347,21 +343,7 @@ type DfServer interface { GetAccount(context.Context, *GetAccountRequest) (*GetAccountResponse, error) ListAccounts(context.Context, *ListAccountsRequest) (*ListAccountsResponse, error) CreateAccount(context.Context, *CreateAccountRequest) (*CreateAccountResponse, error) - // rpc UpdateAccount (UpdateAccountRequest) returns (UpdateAccountResponse) { - // option (google.api.http) = { - // patch: "/v1/accounts/update_account" - // body: "*" - // }; - // option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { - // summary: "Update Account" - // security: { - // security_requirement: { - // key: "BearerAuth"; - // value: {} - // } - // } - // }; - // }; + UpdateAccount(context.Context, *UpdateAccountRequest) (*UpdateAccountResponse, error) GetAccountInfo(context.Context, *GetAccountInfoRequest) (*GetAccountInfoResponse, error) ListAccountInfo(context.Context, *ListAccountInfoRequest) (*ListAccountInfoResponse, error) CreateAccountInfo(context.Context, *CreateAccountInfoRequest) (*CreateAccountInfoResponse, error) @@ -409,6 +391,9 @@ func (UnimplementedDfServer) ListAccounts(context.Context, *ListAccountsRequest) func (UnimplementedDfServer) CreateAccount(context.Context, *CreateAccountRequest) (*CreateAccountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateAccount not implemented") } +func (UnimplementedDfServer) UpdateAccount(context.Context, *UpdateAccountRequest) (*UpdateAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateAccount not implemented") +} func (UnimplementedDfServer) GetAccountInfo(context.Context, *GetAccountInfoRequest) (*GetAccountInfoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetAccountInfo not implemented") } @@ -605,6 +590,24 @@ func _Df_CreateAccount_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Df_UpdateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DfServer).UpdateAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Df_UpdateAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DfServer).UpdateAccount(ctx, req.(*UpdateAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Df_GetAccountInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetAccountInfoRequest) if err := dec(in); err != nil { @@ -982,6 +985,10 @@ var Df_ServiceDesc = grpc.ServiceDesc{ MethodName: "CreateAccount", Handler: _Df_CreateAccount_Handler, }, + { + MethodName: "UpdateAccount", + Handler: _Df_UpdateAccount_Handler, + }, { MethodName: "GetAccountInfo", Handler: _Df_GetAccountInfo_Handler, diff --git a/bff/proto/rpc_create_account_info.proto b/bff/proto/rpc_create_account_info.proto index 2e4553c..9da3723 100644 --- a/bff/proto/rpc_create_account_info.proto +++ b/bff/proto/rpc_create_account_info.proto @@ -27,6 +27,7 @@ message CreateAccountInfoRequest { }; example: "{\"account_id\": \"1\", \"firstname\": \"John\", \"lastname\": \"Doe\", \"street\": \"Main Street 1\", \"zip\": \"0815\", \"city\": \"New York\", \"country\": \"USA\", \"birthday\": \"1990-10-05T00:00:00Z\"}"; }; + uint64 account_id = 1; string firstname = 3; string lastname = 4; string street = 5; diff --git a/bff/proto/rpc_update_account.proto b/bff/proto/rpc_update_account.proto new file mode 100644 index 0000000..ef0bd69 --- /dev/null +++ b/bff/proto/rpc_update_account.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package pb; + +import "protoc-gen-openapiv2/options/annotations.proto"; + +import "account.proto"; + +option go_package = "github.com/itsscb/df/pb"; + +message UpdateAccountRequest { + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + title: "Update Account"; + description: "Update an Account"; + required: [ + "email", + "password" + ]; + }; + example: "{\"account_id\": \"1\", \"email\": \"john.doe@example.com\"}"; + }; + uint64 account_id = 1; + optional string email = 2; + optional string password = 3; +} + +message UpdateAccountResponse { + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + title: "Updated Account"; + description: "Returns the updated Account"; + }; + }; + Account account = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + }]; +} \ No newline at end of file diff --git a/bff/proto/service_df.proto b/bff/proto/service_df.proto index 574e3fa..ba1cb27 100644 --- a/bff/proto/service_df.proto +++ b/bff/proto/service_df.proto @@ -20,7 +20,7 @@ import "rpc_delete_person.proto"; import "rpc_create_account.proto"; import "rpc_get_account.proto"; import "rpc_list_accounts.proto"; -// import "rpc_update_account.proto"; +import "rpc_update_account.proto"; import "rpc_update_account_privacy.proto"; import "rpc_create_account_info.proto"; @@ -146,11 +146,20 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { }; rpc CreateAccount (CreateAccountRequest) returns (CreateAccountResponse) { option (google.api.http) = { - post: "/v1/accounts/create_account_info" + post: "/v1/accounts/create_account" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { summary: "Create AccountInfo" + }; + }; + rpc UpdateAccount (UpdateAccountRequest) returns (UpdateAccountResponse) { + option (google.api.http) = { + patch: "/v1/accounts/update_account" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Update Account" security: { security_requirement: { key: "BearerAuth"; @@ -158,25 +167,10 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { } } }; - }; - // rpc UpdateAccount (UpdateAccountRequest) returns (UpdateAccountResponse) { - // option (google.api.http) = { - // patch: "/v1/accounts/update_account" - // body: "*" - // }; - // option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { - // summary: "Update Account" - // security: { - // security_requirement: { - // key: "BearerAuth"; - // value: {} - // } - // } - // }; - // }; + }; rpc GetAccountInfo (GetAccountInfoRequest) returns (GetAccountInfoResponse) { option (google.api.http) = { - get: "/v1/accounts/get_account/{account_id}" + get: "/v1/accounts/get_account_info/{account_id}" // get: "/v1/accounts/{id=id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { @@ -205,16 +199,22 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { }; rpc CreateAccountInfo (CreateAccountInfoRequest) returns (CreateAccountInfoResponse) { option (google.api.http) = { - post: "/v1/accounts/create_account" + post: "/v1/accounts/create_account_info" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { summary: "Create AccountInfo" + security: { + security_requirement: { + key: "BearerAuth"; + value: {} + } + } }; }; rpc UpdateAccountInfo (UpdateAccountInfoRequest) returns (UpdateAccountInfoResponse) { option (google.api.http) = { - patch: "/v1/accounts/update_account" + patch: "/v1/accounts/update_account_info" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { diff --git a/bff/val/validator.go b/bff/val/validator.go index 948061d..6246da1 100644 --- a/bff/val/validator.go +++ b/bff/val/validator.go @@ -7,9 +7,9 @@ import ( ) var ( - isValidName = regexp.MustCompile(`^[a-zA-Z\s]+$`).MatchString - isValidAlphaSpace = regexp.MustCompile(`^[a-zA-Z\s]+$`).MatchString - isValidAlphaNumSpace = regexp.MustCompile(`^[a-zA-Z0-9\s]+$`).MatchString + IsValidName = regexp.MustCompile(`^[a-zA-Z\s]+$`).MatchString + IsValidAlphaSpace = regexp.MustCompile(`^[a-zA-Z\s]+$`).MatchString + IsValidAlphaNumSpace = regexp.MustCompile(`^[a-zA-Z0-9\s]+$`).MatchString ) func ValidateString(value string, minLength int, maxLength int) error { @@ -24,7 +24,7 @@ func ValidateName(value string) error { if err := ValidateString(value, 2, 40); err != nil { return err } - if !isValidName(value) { + if !IsValidName(value) { return fmt.Errorf("must contain only letters or spaces") } return nil @@ -56,7 +56,7 @@ func ValidateStreet(value string) error { return err } - if !isValidAlphaNumSpace(value) { + if !IsValidAlphaNumSpace(value) { return fmt.Errorf("must contain only letters, numbers or spaces") } @@ -68,7 +68,7 @@ func ValidateAlphaSpace(value string) error { return err } - if !isValidAlphaSpace(value) { + if !IsValidAlphaSpace(value) { return fmt.Errorf("must contain only letters, numbers or spaces") }