From a7fb9265c3174dc2958cd5e9a3d8501e709ba853 Mon Sep 17 00:00:00 2001 From: itsscb Date: Thu, 19 Oct 2023 00:28:53 +0200 Subject: [PATCH] Add email verification Fixes #47 --- Makefile | 4 +- bff/api/account.go | 37 +- bff/api/account_test.go | 85 +++- bff/app.env | 5 +- bff/db/migration/000001_init_schema.up.sql | 3 + bff/db/mock/store.go | 14 + bff/db/query/account.sql | 10 + bff/db/sqlc/account.sql.go | 61 ++- bff/db/sqlc/models.go | 3 + bff/db/sqlc/querier.go | 1 + bff/db/sqlc/tx_create_account.go | 31 +- bff/doc/swagger/df.swagger.json | 47 ++ bff/gapi/rpc_create_account.go | 38 +- bff/gapi/rpc_verify_email.go | 53 ++ bff/gapi/server.go | 5 + bff/go.mod | 1 + bff/go.sum | 2 + bff/mail/sender.go | 65 +++ bff/pb/rpc_verify_email.pb.go | 229 +++++++++ bff/pb/service_df.pb.go | 559 +++++++++++---------- bff/pb/service_df.pb.gw.go | 123 +++++ bff/pb/service_df_grpc.pb.go | 37 ++ bff/proto/rpc_verify_email.proto | 32 ++ bff/proto/service_df.proto | 10 + bff/util/config.go | 5 +- 25 files changed, 1109 insertions(+), 351 deletions(-) create mode 100644 bff/gapi/rpc_verify_email.go create mode 100644 bff/mail/sender.go create mode 100644 bff/pb/rpc_verify_email.pb.go create mode 100644 bff/proto/rpc_verify_email.proto diff --git a/Makefile b/Makefile index 16af16f..6efea5a 100644 --- a/Makefile +++ b/Makefile @@ -52,10 +52,10 @@ migratedown: docker run --name migratedown --privileged=true --rm -v $(PWD)/bff/db/migration:/migrations --network host migrate/migrate -path=/migrations/ -database $(DB_URL) down createdb: - docker exec -it postgres createdb --username=root --owner=root df + docker exec -it df-bff_postgres_1 createdb --username=root --owner=root df dropdb: - docker exec -it postgres dropdb df + docker exec -it df-bff_postgres_1 dropdb df sqlc: cd bff && \ diff --git a/bff/api/account.go b/bff/api/account.go index aa6a30d..2d95c35 100644 --- a/bff/api/account.go +++ b/bff/api/account.go @@ -33,24 +33,27 @@ func (server *Server) createAccount(ctx *gin.Context) { } arg := db.CreateAccountTxParams{ - Passwordhash: req.Passwordhash, - PrivacyAccepted: sql.NullBool{ - Valid: true, - Bool: req.PrivacyAccepted, - }, - Firstname: req.Firstname, - Lastname: req.Lastname, - Birthday: req.Birthday, - Email: req.Email, - City: req.City, - Zip: req.Zip, - Street: req.Street, - Country: req.Country, - Creator: req.Email, - Phone: sql.NullString{ - Valid: req.Phone != "", - String: req.Phone, + CreateAccountParams: db.CreateAccountParams{ + Passwordhash: req.Passwordhash, + PrivacyAccepted: sql.NullBool{ + Valid: true, + Bool: req.PrivacyAccepted, + }, + Firstname: req.Firstname, + Lastname: req.Lastname, + Birthday: req.Birthday, + Email: req.Email, + City: req.City, + Zip: req.Zip, + Street: req.Street, + Country: req.Country, + Creator: req.Email, + Phone: sql.NullString{ + Valid: req.Phone != "", + String: req.Phone, + }, }, + AfterCreate: func(a db.Account) error { return nil }, } account, err := server.store.CreateAccountTx(ctx, arg) diff --git a/bff/api/account_test.go b/bff/api/account_test.go index b53a931..f62868c 100644 --- a/bff/api/account_test.go +++ b/bff/api/account_test.go @@ -8,6 +8,7 @@ import ( "io" "net/http" "net/http/httptest" + "reflect" "testing" "time" @@ -22,8 +23,44 @@ import ( 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 := randomAccount() + account, password := randomAccount() + + // fn := func(db.Account) error { return nil} testCases := []struct { name string @@ -53,24 +90,32 @@ func TestCreateAccountAPI(t *testing.T) { }, buildStubs: func(store *mockdb.MockStore) { arg := db.CreateAccountTxParams{ - Passwordhash: account.Passwordhash, - PrivacyAccepted: account.PrivacyAccepted, - 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, - Creator: account.Email, + CreateAccountParams: db.CreateAccountParams{ + Passwordhash: account.Passwordhash, + PrivacyAccepted: account.PrivacyAccepted, + 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, + Creator: account.Email, + }, + AfterCreate: func(a db.Account) error { return nil }, } store.EXPECT(). - CreateAccountTx(gomock.Any(), gomock.Eq(arg)). + 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) @@ -184,7 +229,7 @@ func TestCreateAccountAPI(t *testing.T) { } func TestGetAccountAPI(t *testing.T) { - account := randomAccount() + account, _ := randomAccount() testCases := []struct { name string @@ -315,7 +360,7 @@ func TestGetAccountAPI(t *testing.T) { } func TestUpdateAccountTxAPI(t *testing.T) { - account := randomAccount() + account, _ := randomAccount() newLastname := util.RandomName() testCases := []struct { @@ -472,7 +517,7 @@ func TestListAccountsAPI(t *testing.T) { n := 5 accounts := make([]db.Account, n) for i := 0; i < n; i++ { - accounts[i] = randomAccount() + accounts[i], _ = randomAccount() } account := accounts[1] @@ -624,7 +669,7 @@ func TestListAccountsAPI(t *testing.T) { } func TestUpdateAccountPrivacyTxAPI(t *testing.T) { - account := randomAccount() + account, _ := randomAccount() testCases := []struct { name string @@ -832,7 +877,7 @@ func TestUpdateAccountPrivacyTxAPI(t *testing.T) { } } -func randomAccount() db.Account { +func randomAccount() (db.Account, string) { password := util.RandomString(6) hashedPassword, _ := util.HashPassword(password) @@ -866,7 +911,7 @@ func randomAccount() db.Account { Birthday: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC), } - return acc + return acc, password } func requireBodyMatchAccount(t *testing.T, body *bytes.Buffer, account db.Account) { diff --git a/bff/app.env b/bff/app.env index 1abc2ca..caafd50 100644 --- a/bff/app.env +++ b/bff/app.env @@ -8,4 +8,7 @@ ACCESS_TOKEN_DURATION=15m MIGRATION_URL=file://db/migration MIGRATION_RETRIES=5 REFRESH_TOKEN_DURATION=24h -TOKEN_PRIVATEKEY_HEX=099c0b96725b99e95719c92aec580809ac58fc14be2105ed2656f1f6c464593d8cacd6c7bed924b9cf207ab3cff1c59be4e5865260c4dafa29699244bd4ea2de \ No newline at end of file +TOKEN_PRIVATEKEY_HEX=099c0b96725b99e95719c92aec580809ac58fc14be2105ed2656f1f6c464593d8cacd6c7bed924b9cf207ab3cff1c59be4e5865260c4dafa29699244bd4ea2de +SMTP_ADDRESS=smtp.gmail.com:587 +SMTP_PASSWORD=P@$$w0Rd +SMTP_MAIL=dev.itsscb@gmail.com \ No newline at end of file diff --git a/bff/db/migration/000001_init_schema.up.sql b/bff/db/migration/000001_init_schema.up.sql index 1a21371..5a083d0 100644 --- a/bff/db/migration/000001_init_schema.up.sql +++ b/bff/db/migration/000001_init_schema.up.sql @@ -22,6 +22,9 @@ CREATE TABLE "accounts" ( "privacy_accepted" boolean DEFAULT false, "privacy_accepted_date" timestamptz, "email" varchar UNIQUE NOT NULL, + "secret_key" varchar, + "email_verified" boolean DEFAULT false, + "email_verified_time" timestamptz, "phone" varchar, "city" varchar NOT NULL, "zip" varchar NOT NULL, diff --git a/bff/db/mock/store.go b/bff/db/mock/store.go index bd8e1b8..1748e6a 100644 --- a/bff/db/mock/store.go +++ b/bff/db/mock/store.go @@ -1018,3 +1018,17 @@ func (mr *MockStoreMockRecorder) ValidateDocument(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateDocument", reflect.TypeOf((*MockStore)(nil).ValidateDocument), arg0, arg1) } + +// VerifyAccountEmail mocks base method. +func (m *MockStore) VerifyAccountEmail(arg0 context.Context, arg1 db.VerifyAccountEmailParams) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifyAccountEmail", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// VerifyAccountEmail indicates an expected call of VerifyAccountEmail. +func (mr *MockStoreMockRecorder) VerifyAccountEmail(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyAccountEmail", reflect.TypeOf((*MockStore)(nil).VerifyAccountEmail), arg0, arg1) +} diff --git a/bff/db/query/account.sql b/bff/db/query/account.sql index 58780f7..4fe1c0a 100644 --- a/bff/db/query/account.sql +++ b/bff/db/query/account.sql @@ -20,6 +20,7 @@ INSERT INTO accounts ( "lastname", "birthday", "email", + "secret_key", "phone", "city", "zip", @@ -35,6 +36,7 @@ INSERT INTO accounts ( sqlc.arg(lastname), sqlc.arg(birthday), sqlc.arg(email), + sqlc.arg(secret_key), sqlc.arg(phone), sqlc.arg(city), sqlc.arg(zip), @@ -78,6 +80,14 @@ SET WHERE "id" = sqlc.arg(id) RETURNING *; +-- name: VerifyAccountEmail :exec +UPDATE accounts +SET + "email_verified" = sqlc.arg(email_verified), + "email_verified_time" = sqlc.arg(email_verified_time), + "secret_key" = '' +WHERE "id" = sqlc.arg(id); + -- name: DeleteAccount :exec DELETE FROM accounts WHERE "id" = $1; \ No newline at end of file diff --git a/bff/db/sqlc/account.sql.go b/bff/db/sqlc/account.sql.go index 779da37..634eca4 100644 --- a/bff/db/sqlc/account.sql.go +++ b/bff/db/sqlc/account.sql.go @@ -20,6 +20,7 @@ INSERT INTO accounts ( "lastname", "birthday", "email", + "secret_key", "phone", "city", "zip", @@ -41,8 +42,9 @@ INSERT INTO accounts ( $11, $12, $13, - $13 -) RETURNING id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed + $14, + $14 +) RETURNING id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed ` type CreateAccountParams struct { @@ -53,6 +55,7 @@ type CreateAccountParams struct { Lastname string `json:"lastname"` Birthday time.Time `json:"birthday"` Email string `json:"email"` + SecretKey sql.NullString `json:"secret_key"` Phone sql.NullString `json:"phone"` City string `json:"city"` Zip string `json:"zip"` @@ -70,6 +73,7 @@ func (q *Queries) CreateAccount(ctx context.Context, arg CreateAccountParams) (A arg.Lastname, arg.Birthday, arg.Email, + arg.SecretKey, arg.Phone, arg.City, arg.Zip, @@ -88,6 +92,9 @@ func (q *Queries) CreateAccount(ctx context.Context, arg CreateAccountParams) (A &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -112,7 +119,7 @@ func (q *Queries) DeleteAccount(ctx context.Context, id uint64) error { } const getAccount = `-- name: GetAccount :one -SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed FROM accounts +SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed FROM accounts WHERE "id" = $1 LIMIT 1 ` @@ -129,6 +136,9 @@ func (q *Queries) GetAccount(ctx context.Context, id uint64) (Account, error) { &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -143,7 +153,7 @@ func (q *Queries) GetAccount(ctx context.Context, id uint64) (Account, error) { } const getAccountByEmail = `-- name: GetAccountByEmail :one -SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed FROM accounts +SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed FROM accounts WHERE "email" = $1 LIMIT 1 ` @@ -160,6 +170,9 @@ func (q *Queries) GetAccountByEmail(ctx context.Context, email string) (Account, &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -174,7 +187,7 @@ func (q *Queries) GetAccountByEmail(ctx context.Context, email string) (Account, } const getAccountForUpdate = `-- name: GetAccountForUpdate :one -SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed FROM accounts +SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed FROM accounts WHERE "id" = $1 LIMIT 1 FOR NO KEY UPDATE ` @@ -192,6 +205,9 @@ func (q *Queries) GetAccountForUpdate(ctx context.Context, id uint64) (Account, &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -206,7 +222,7 @@ func (q *Queries) GetAccountForUpdate(ctx context.Context, id uint64) (Account, } const listAccounts = `-- name: ListAccounts :many -SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed FROM accounts +SELECT id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed FROM accounts ORDER BY "lastname", "firstname" LIMIT $1 OFFSET $2 @@ -236,6 +252,9 @@ func (q *Queries) ListAccounts(ctx context.Context, arg ListAccountsParams) ([]A &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -275,7 +294,7 @@ SET "changer" = $2, "changed" = now() WHERE "id" = $1 -RETURNING id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed +RETURNING id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed ` type UpdateAccountParams struct { @@ -319,6 +338,9 @@ func (q *Queries) UpdateAccount(ctx context.Context, arg UpdateAccountParams) (A &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -340,7 +362,7 @@ SET "changer" = $3, "changed" = now() WHERE "id" = $4 -RETURNING id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, phone, city, zip, street, country, creator, created, changer, changed +RETURNING id, permission_level, passwordhash, firstname, lastname, birthday, privacy_accepted, privacy_accepted_date, email, secret_key, email_verified, email_verified_time, phone, city, zip, street, country, creator, created, changer, changed ` type UpdateAccountPrivacyParams struct { @@ -368,6 +390,9 @@ func (q *Queries) UpdateAccountPrivacy(ctx context.Context, arg UpdateAccountPri &i.PrivacyAccepted, &i.PrivacyAcceptedDate, &i.Email, + &i.SecretKey, + &i.EmailVerified, + &i.EmailVerifiedTime, &i.Phone, &i.City, &i.Zip, @@ -380,3 +405,23 @@ func (q *Queries) UpdateAccountPrivacy(ctx context.Context, arg UpdateAccountPri ) return i, err } + +const verifyAccountEmail = `-- name: VerifyAccountEmail :exec +UPDATE accounts +SET + "email_verified" = $1, + "email_verified_time" = $2, + "secret_key" = '' +WHERE "id" = $3 +` + +type VerifyAccountEmailParams struct { + EmailVerified sql.NullBool `json:"email_verified"` + EmailVerifiedTime sql.NullTime `json:"email_verified_time"` + ID uint64 `json:"id"` +} + +func (q *Queries) VerifyAccountEmail(ctx context.Context, arg VerifyAccountEmailParams) error { + _, err := q.db.ExecContext(ctx, verifyAccountEmail, arg.EmailVerified, arg.EmailVerifiedTime, arg.ID) + return err +} diff --git a/bff/db/sqlc/models.go b/bff/db/sqlc/models.go index 20920aa..9451cea 100644 --- a/bff/db/sqlc/models.go +++ b/bff/db/sqlc/models.go @@ -21,6 +21,9 @@ type Account struct { PrivacyAccepted sql.NullBool `json:"privacy_accepted"` PrivacyAcceptedDate sql.NullTime `json:"privacy_accepted_date"` Email string `json:"email"` + SecretKey sql.NullString `json:"secret_key"` + EmailVerified sql.NullBool `json:"email_verified"` + EmailVerifiedTime sql.NullTime `json:"email_verified_time"` Phone sql.NullString `json:"phone"` City string `json:"city"` Zip string `json:"zip"` diff --git a/bff/db/sqlc/querier.go b/bff/db/sqlc/querier.go index 0c8fb83..30bd3b8 100644 --- a/bff/db/sqlc/querier.go +++ b/bff/db/sqlc/querier.go @@ -84,6 +84,7 @@ type Querier interface { UpdateReturn(ctx context.Context, arg UpdateReturnParams) (Return, error) UpdateReturnsLog(ctx context.Context, arg UpdateReturnsLogParams) (ReturnsLog, error) ValidateDocument(ctx context.Context, arg ValidateDocumentParams) (Document, error) + VerifyAccountEmail(ctx context.Context, arg VerifyAccountEmailParams) error } var _ Querier = (*Queries)(nil) diff --git a/bff/db/sqlc/tx_create_account.go b/bff/db/sqlc/tx_create_account.go index 11b996b..5dff46c 100644 --- a/bff/db/sqlc/tx_create_account.go +++ b/bff/db/sqlc/tx_create_account.go @@ -4,22 +4,13 @@ import ( "context" "database/sql" "time" + + "github.com/google/uuid" ) type CreateAccountTxParams struct { - Passwordhash string `json:"passwordhash"` - PrivacyAccepted sql.NullBool `json:"privacy_accepted"` - PrivacyAcceptedDate sql.NullTime `json:"privacy_accepted_date"` - Firstname string `json:"firstname"` - Lastname string `json:"lastname"` - Birthday time.Time `json:"birthday"` - Email string `json:"email"` - Phone sql.NullString `json:"phone"` - City string `json:"city"` - Zip string `json:"zip"` - Street string `json:"street"` - Country string `json:"country"` - Creator string `json:"creator"` + CreateAccountParams + AfterCreate func(Account) error } type CreateAccountTxResult struct { @@ -30,6 +21,13 @@ func (store *SQLStore) CreateAccountTx(ctx context.Context, arg CreateAccountTxP var result CreateAccountTxResult var err error + uid, _ := uuid.NewUUID() + + arg.SecretKey = sql.NullString{ + Valid: uid.String() != "", + String: uid.String(), + } + if arg.PrivacyAccepted.Bool && arg.PrivacyAccepted.Valid && !arg.PrivacyAcceptedDate.Valid { arg.PrivacyAcceptedDate = sql.NullTime{ Valid: true, @@ -45,9 +43,12 @@ func (store *SQLStore) CreateAccountTx(ctx context.Context, arg CreateAccountTxP err = store.execTx(ctx, func(q *Queries) error { var err error - result.Account, err = q.CreateAccount(ctx, CreateAccountParams(arg)) + result.Account, err = q.CreateAccount(ctx, arg.CreateAccountParams) + if err != nil { + return err + } - return err + return arg.AfterCreate(result.Account) }) return result.Account, err diff --git a/bff/doc/swagger/df.swagger.json b/bff/doc/swagger/df.swagger.json index d774dc5..ab00d82 100644 --- a/bff/doc/swagger/df.swagger.json +++ b/bff/doc/swagger/df.swagger.json @@ -852,6 +852,44 @@ "df" ] } + }, + "/v1/verify_email/{accountId}/{secretKey}": { + "get": { + "summary": "Verify Email with account_id and secret_key", + "operationId": "df_VerifyEmail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/pbVerifyEmailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "accountId", + "in": "path", + "required": true, + "type": "string", + "format": "uint64" + }, + { + "name": "secretKey", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "df" + ] + } } }, "definitions": { @@ -1955,6 +1993,15 @@ }, "title": "UploadDocument Response" }, + "pbVerifyEmailResponse": { + "type": "object", + "properties": { + "verified": { + "type": "boolean" + } + }, + "title": "VerifyEmail Response" + }, "protobufAny": { "type": "object", "properties": { diff --git a/bff/gapi/rpc_create_account.go b/bff/gapi/rpc_create_account.go index 1f65fe3..f7cc281 100644 --- a/bff/gapi/rpc_create_account.go +++ b/bff/gapi/rpc_create_account.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "errors" + "fmt" "log/slog" db "github.com/itsscb/df/bff/db/sqlc" @@ -28,23 +29,28 @@ func (server *Server) CreateAccount(ctx context.Context, req *pb.CreateAccountRe } arg := db.CreateAccountTxParams{ - Passwordhash: hashedPassword, - PrivacyAccepted: sql.NullBool{ - Valid: true, - Bool: req.GetPrivacyAccepted(), + CreateAccountParams: db.CreateAccountParams{ + Passwordhash: hashedPassword, + PrivacyAccepted: sql.NullBool{ + Valid: true, + Bool: req.GetPrivacyAccepted(), + }, + Firstname: req.GetFirstname(), + Lastname: req.GetLastname(), + Birthday: req.GetBirthday().AsTime(), + Email: req.GetEmail(), + City: req.GetCity(), + Zip: req.GetZip(), + Street: req.GetStreet(), + Country: req.GetCountry(), + Creator: req.GetEmail(), + Phone: sql.NullString{ + Valid: req.GetPhone() != "", + String: req.GetPhone(), + }, }, - Firstname: req.GetFirstname(), - Lastname: req.GetLastname(), - Birthday: req.GetBirthday().AsTime(), - Email: req.GetEmail(), - City: req.GetCity(), - Zip: req.GetZip(), - Street: req.GetStreet(), - Country: req.GetCountry(), - Creator: req.GetEmail(), - Phone: sql.NullString{ - Valid: req.GetPhone() != "", - String: req.GetPhone(), + AfterCreate: func(a db.Account) error { + return server.mailSender.SendEmail("Verify your E-Mail Address", fmt.Sprintf("Hello %s %s,

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


Your Team of DF", req.GetFirstname(), req.GetLastname(), a.ID, a.SecretKey.String), []string{req.GetEmail()}, nil, nil, nil) }, } diff --git a/bff/gapi/rpc_verify_email.go b/bff/gapi/rpc_verify_email.go new file mode 100644 index 0000000..53c48c2 --- /dev/null +++ b/bff/gapi/rpc_verify_email.go @@ -0,0 +1,53 @@ +package gapi + +import ( + "context" + "database/sql" + "errors" + "log/slog" + "time" + + db "github.com/itsscb/df/bff/db/sqlc" + "github.com/itsscb/df/bff/pb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (server *Server) VerifyEmail(ctx context.Context, req *pb.VerifyEmailRequest) (*pb.VerifyEmailResponse, error) { + + account, err := server.store.GetAccount(ctx, req.GetAccountId()) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, status.Errorf(codes.NotFound, "account not found") + } + slog.Error("verify_email (get_account)", slog.Int64("account_id", int64(req.GetAccountId())), slog.String("error", err.Error())) + return nil, status.Error(codes.Internal, "failed to get account") + } + + if account.ID != req.GetAccountId() { + return nil, status.Error(codes.NotFound, "account not found") + } + + if account.SecretKey.String != req.GetSecretKey() { + return nil, status.Error(codes.NotFound, "unknown secret_key: "+req.GetSecretKey()) + } + + arg := db.VerifyAccountEmailParams{ + ID: account.ID, + EmailVerified: sql.NullBool{ + Valid: true, + Bool: true, + }, + EmailVerifiedTime: sql.NullTime{ + Valid: true, + Time: time.Now(), + }, + } + + err = server.store.VerifyAccountEmail(ctx, arg) + + rsp := &pb.VerifyEmailResponse{ + Verified: err == nil, + } + return rsp, err +} diff --git a/bff/gapi/server.go b/bff/gapi/server.go index 9be8219..893a91e 100644 --- a/bff/gapi/server.go +++ b/bff/gapi/server.go @@ -6,6 +6,7 @@ import ( "os" db "github.com/itsscb/df/bff/db/sqlc" + "github.com/itsscb/df/bff/mail" "github.com/itsscb/df/bff/pb" "github.com/itsscb/df/bff/token" "github.com/itsscb/df/bff/util" @@ -17,6 +18,7 @@ type Server struct { store db.Store config util.Config tokenMaker token.Maker + mailSender mail.EmailSender } func NewServer(config util.Config, store db.Store) (*Server, error) { @@ -25,10 +27,13 @@ func NewServer(config util.Config, store db.Store) (*Server, error) { return nil, fmt.Errorf("cannot create token maker: %w", err) } + mailSender := mail.NewGmailSender("df", config.SMTPMail, config.SMTPPassword) + server := &Server{ store: store, config: config, tokenMaker: tokenMaker, + mailSender: mailSender, } logLevel := slog.LevelError diff --git a/bff/go.mod b/bff/go.mod index 37723a0..3211926 100644 --- a/bff/go.mod +++ b/bff/go.mod @@ -10,6 +10,7 @@ require ( github.com/golang-migrate/migrate/v4 v4.16.2 github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 + github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/lib/pq v1.10.9 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 diff --git a/bff/go.sum b/bff/go.sum index f9b3e1f..4413dff 100644 --- a/bff/go.sum +++ b/bff/go.sum @@ -188,6 +188,8 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA= +github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= diff --git a/bff/mail/sender.go b/bff/mail/sender.go new file mode 100644 index 0000000..e383406 --- /dev/null +++ b/bff/mail/sender.go @@ -0,0 +1,65 @@ +package mail + +import ( + "fmt" + "net/smtp" + + "github.com/jordan-wright/email" +) + +const ( + smtpAuthAddress = "smtp.gmail.com" + smtpServerAddress = "smtp.gmail.com:587" +) + +type EmailSender interface { + SendEmail( + subject string, + content string, + to []string, + cc []string, + bcc []string, + attachFiles []string, + ) error +} + +type GmailSender struct { + displayName string + fromEmailAddress string + fromEmailPassword string +} + +func NewGmailSender(displayName string, fromEmailAddress string, fromEmailPassword string) EmailSender { + return &GmailSender{ + displayName: displayName, + fromEmailAddress: fromEmailAddress, + fromEmailPassword: fromEmailPassword, + } +} + +func (sender *GmailSender) SendEmail( + subject string, + content string, + to []string, + cc []string, + bcc []string, + attachFiles []string, +) error { + e := email.NewEmail() + e.From = fmt.Sprintf("%s <%s>", sender.displayName, sender.fromEmailAddress) + e.Subject = subject + e.HTML = []byte(content) + e.To = to + e.Cc = cc + e.Bcc = bcc + + for _, f := range attachFiles { + _, err := e.AttachFile(f) + if err != nil { + return fmt.Errorf("failed to attach file %s: %w", f, err) + } + } + + smtpAuth := smtp.PlainAuth("", sender.fromEmailAddress, sender.fromEmailPassword, smtpAuthAddress) + return e.Send(smtpServerAddress, smtpAuth) +} diff --git a/bff/pb/rpc_verify_email.pb.go b/bff/pb/rpc_verify_email.pb.go new file mode 100644 index 0000000..3adf7b1 --- /dev/null +++ b/bff/pb/rpc_verify_email.pb.go @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.4 +// source: rpc_verify_email.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 VerifyEmailRequest 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"` + SecretKey string `protobuf:"bytes,2,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` +} + +func (x *VerifyEmailRequest) Reset() { + *x = VerifyEmailRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_verify_email_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VerifyEmailRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyEmailRequest) ProtoMessage() {} + +func (x *VerifyEmailRequest) ProtoReflect() protoreflect.Message { + mi := &file_rpc_verify_email_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 VerifyEmailRequest.ProtoReflect.Descriptor instead. +func (*VerifyEmailRequest) Descriptor() ([]byte, []int) { + return file_rpc_verify_email_proto_rawDescGZIP(), []int{0} +} + +func (x *VerifyEmailRequest) GetAccountId() uint64 { + if x != nil { + return x.AccountId + } + return 0 +} + +func (x *VerifyEmailRequest) GetSecretKey() string { + if x != nil { + return x.SecretKey + } + return "" +} + +type VerifyEmailResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Verified bool `protobuf:"varint,1,opt,name=verified,proto3" json:"verified,omitempty"` +} + +func (x *VerifyEmailResponse) Reset() { + *x = VerifyEmailResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_verify_email_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VerifyEmailResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VerifyEmailResponse) ProtoMessage() {} + +func (x *VerifyEmailResponse) ProtoReflect() protoreflect.Message { + mi := &file_rpc_verify_email_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 VerifyEmailResponse.ProtoReflect.Descriptor instead. +func (*VerifyEmailResponse) Descriptor() ([]byte, []int) { + return file_rpc_verify_email_proto_rawDescGZIP(), []int{1} +} + +func (x *VerifyEmailResponse) GetVerified() bool { + if x != nil { + return x.Verified + } + return false +} + +var File_rpc_verify_email_proto protoreflect.FileDescriptor + +var file_rpc_verify_email_proto_rawDesc = []byte{ + 0x0a, 0x16, 0x72, 0x70, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 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, 0x22, 0xb0, 0x01, 0x0a, + 0x12, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 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, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x3a, 0x5c, 0x92, 0x41, 0x59, 0x0a, 0x27, 0x2a, 0x0b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x45, 0x6d, 0x61, 0x69, 0x6c, 0xd2, 0x01, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0xd2, 0x01, 0x0a, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x32, + 0x2e, 0x7b, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x20, 0x22, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x68, 0x69, 0x73, + 0x69, 0x73, 0x61, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x6b, 0x65, 0x79, 0x22, 0x20, 0x7d, 0x22, + 0x53, 0x0a, 0x13, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0x92, 0x41, 0x00, 0x52, 0x08, 0x76, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, 0x1b, 0x92, 0x41, 0x18, 0x0a, 0x16, 0x2a, 0x14, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 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_verify_email_proto_rawDescOnce sync.Once + file_rpc_verify_email_proto_rawDescData = file_rpc_verify_email_proto_rawDesc +) + +func file_rpc_verify_email_proto_rawDescGZIP() []byte { + file_rpc_verify_email_proto_rawDescOnce.Do(func() { + file_rpc_verify_email_proto_rawDescData = protoimpl.X.CompressGZIP(file_rpc_verify_email_proto_rawDescData) + }) + return file_rpc_verify_email_proto_rawDescData +} + +var file_rpc_verify_email_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_rpc_verify_email_proto_goTypes = []interface{}{ + (*VerifyEmailRequest)(nil), // 0: pb.VerifyEmailRequest + (*VerifyEmailResponse)(nil), // 1: pb.VerifyEmailResponse +} +var file_rpc_verify_email_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] 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 +} + +func init() { file_rpc_verify_email_proto_init() } +func file_rpc_verify_email_proto_init() { + if File_rpc_verify_email_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_rpc_verify_email_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyEmailRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_verify_email_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VerifyEmailResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_rpc_verify_email_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_rpc_verify_email_proto_goTypes, + DependencyIndexes: file_rpc_verify_email_proto_depIdxs, + MessageInfos: file_rpc_verify_email_proto_msgTypes, + }.Build() + File_rpc_verify_email_proto = out.File + file_rpc_verify_email_proto_rawDesc = nil + file_rpc_verify_email_proto_goTypes = nil + file_rpc_verify_email_proto_depIdxs = nil +} diff --git a/bff/pb/service_df.pb.go b/bff/pb/service_df.pb.go index 79d811e..b7d9e1a 100644 --- a/bff/pb/service_df.pb.go +++ b/bff/pb/service_df.pb.go @@ -65,234 +65,246 @@ var file_service_df_proto_rawDesc = []byte{ 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, 0x32, 0xf0, 0x1a, 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, 0x7f, 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, 0x39, 0x92, 0x41, 0x10, 0x12, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 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, 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, 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, + 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, 0x95, 0x1c, 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, 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, + 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, 0x7f, 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, 0x39, 0x92, 0x41, 0x10, 0x12, 0x0e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 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, 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, 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, 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, + 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, 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{}{ @@ -318,28 +330,30 @@ var file_service_df_proto_goTypes = []interface{}{ (*ListReturnsLogRequest)(nil), // 19: pb.ListReturnsLogRequest (*UploadDocumentRequest)(nil), // 20: pb.UploadDocumentRequest (*DeleteDocumentRequest)(nil), // 21: pb.DeleteDocumentRequest - (*LoginResponse)(nil), // 22: pb.LoginResponse - (*RefreshTokenResponse)(nil), // 23: pb.RefreshTokenResponse - (*ListSessionsResponse)(nil), // 24: pb.ListSessionsResponse - (*BlockSessionResponse)(nil), // 25: pb.BlockSessionResponse - (*GetAccountResponse)(nil), // 26: pb.GetAccountResponse - (*ListAccountsResponse)(nil), // 27: pb.ListAccountsResponse - (*CreateAccountResponse)(nil), // 28: pb.CreateAccountResponse - (*UpdateAccountResponse)(nil), // 29: pb.UpdateAccountResponse - (*UpdateAccountPrivacyResponse)(nil), // 30: pb.UpdateAccountPrivacyResponse - (*CreatePersonResponse)(nil), // 31: pb.CreatePersonResponse - (*UpdatePersonResponse)(nil), // 32: pb.UpdatePersonResponse - (*GetPersonResponse)(nil), // 33: pb.GetPersonResponse - (*DeletePersonResponse)(nil), // 34: pb.DeletePersonResponse - (*ListPersonsResponse)(nil), // 35: pb.ListPersonsResponse - (*CreatePaymentResponse)(nil), // 36: pb.CreatePaymentResponse - (*GetPaymentResponse)(nil), // 37: pb.GetPaymentResponse - (*DeletePaymentResponse)(nil), // 38: pb.DeletePaymentResponse - (*ListPaymentsResponse)(nil), // 39: pb.ListPaymentsResponse - (*UpdatePaymentResponse)(nil), // 40: pb.UpdatePaymentResponse - (*ListReturnsLogResponse)(nil), // 41: pb.ListReturnsLogResponse - (*UploadDocumentResponse)(nil), // 42: pb.UploadDocumentResponse - (*DeleteDocumentResponse)(nil), // 43: pb.DeleteDocumentResponse + (*VerifyEmailRequest)(nil), // 22: pb.VerifyEmailRequest + (*LoginResponse)(nil), // 23: pb.LoginResponse + (*RefreshTokenResponse)(nil), // 24: pb.RefreshTokenResponse + (*ListSessionsResponse)(nil), // 25: pb.ListSessionsResponse + (*BlockSessionResponse)(nil), // 26: pb.BlockSessionResponse + (*GetAccountResponse)(nil), // 27: pb.GetAccountResponse + (*ListAccountsResponse)(nil), // 28: pb.ListAccountsResponse + (*CreateAccountResponse)(nil), // 29: pb.CreateAccountResponse + (*UpdateAccountResponse)(nil), // 30: pb.UpdateAccountResponse + (*UpdateAccountPrivacyResponse)(nil), // 31: pb.UpdateAccountPrivacyResponse + (*CreatePersonResponse)(nil), // 32: pb.CreatePersonResponse + (*UpdatePersonResponse)(nil), // 33: pb.UpdatePersonResponse + (*GetPersonResponse)(nil), // 34: pb.GetPersonResponse + (*DeletePersonResponse)(nil), // 35: pb.DeletePersonResponse + (*ListPersonsResponse)(nil), // 36: pb.ListPersonsResponse + (*CreatePaymentResponse)(nil), // 37: pb.CreatePaymentResponse + (*GetPaymentResponse)(nil), // 38: pb.GetPaymentResponse + (*DeletePaymentResponse)(nil), // 39: pb.DeletePaymentResponse + (*ListPaymentsResponse)(nil), // 40: pb.ListPaymentsResponse + (*UpdatePaymentResponse)(nil), // 41: pb.UpdatePaymentResponse + (*ListReturnsLogResponse)(nil), // 42: pb.ListReturnsLogResponse + (*UploadDocumentResponse)(nil), // 43: pb.UploadDocumentResponse + (*DeleteDocumentResponse)(nil), // 44: pb.DeleteDocumentResponse + (*VerifyEmailResponse)(nil), // 45: pb.VerifyEmailResponse } var file_service_df_proto_depIdxs = []int32{ 0, // 0: pb.df.Login:input_type -> pb.LoginRequest @@ -364,30 +378,32 @@ var file_service_df_proto_depIdxs = []int32{ 19, // 19: pb.df.ListReturnsLog:input_type -> pb.ListReturnsLogRequest 20, // 20: pb.df.UploadDocument:input_type -> pb.UploadDocumentRequest 21, // 21: pb.df.DeleteDocument:input_type -> pb.DeleteDocumentRequest - 22, // 22: pb.df.Login:output_type -> pb.LoginResponse - 23, // 23: pb.df.RefreshToken:output_type -> pb.RefreshTokenResponse - 24, // 24: pb.df.ListSessions:output_type -> pb.ListSessionsResponse - 25, // 25: pb.df.BlockSession:output_type -> pb.BlockSessionResponse - 26, // 26: pb.df.GetAccount:output_type -> pb.GetAccountResponse - 27, // 27: pb.df.ListAccounts:output_type -> pb.ListAccountsResponse - 28, // 28: pb.df.CreateAccount:output_type -> pb.CreateAccountResponse - 29, // 29: pb.df.UpdateAccount:output_type -> pb.UpdateAccountResponse - 30, // 30: pb.df.UpdateAccountPrivacy:output_type -> pb.UpdateAccountPrivacyResponse - 31, // 31: pb.df.CreatePerson:output_type -> pb.CreatePersonResponse - 32, // 32: pb.df.UpdatePerson:output_type -> pb.UpdatePersonResponse - 33, // 33: pb.df.GetPerson:output_type -> pb.GetPersonResponse - 34, // 34: pb.df.DeletePerson:output_type -> pb.DeletePersonResponse - 35, // 35: pb.df.ListPersons:output_type -> pb.ListPersonsResponse - 36, // 36: pb.df.CreatePayment:output_type -> pb.CreatePaymentResponse - 37, // 37: pb.df.GetPayment:output_type -> pb.GetPaymentResponse - 38, // 38: pb.df.DeletePayment:output_type -> pb.DeletePaymentResponse - 39, // 39: pb.df.ListPayments:output_type -> pb.ListPaymentsResponse - 40, // 40: pb.df.UpdatePayment:output_type -> pb.UpdatePaymentResponse - 41, // 41: pb.df.ListReturnsLog:output_type -> pb.ListReturnsLogResponse - 42, // 42: pb.df.UploadDocument:output_type -> pb.UploadDocumentResponse - 43, // 43: pb.df.DeleteDocument:output_type -> pb.DeleteDocumentResponse - 22, // [22:44] is the sub-list for method output_type - 0, // [0:22] is the sub-list for method input_type + 22, // 22: pb.df.VerifyEmail:input_type -> pb.VerifyEmailRequest + 23, // 23: pb.df.Login:output_type -> pb.LoginResponse + 24, // 24: pb.df.RefreshToken:output_type -> pb.RefreshTokenResponse + 25, // 25: pb.df.ListSessions:output_type -> pb.ListSessionsResponse + 26, // 26: pb.df.BlockSession:output_type -> pb.BlockSessionResponse + 27, // 27: pb.df.GetAccount:output_type -> pb.GetAccountResponse + 28, // 28: pb.df.ListAccounts:output_type -> pb.ListAccountsResponse + 29, // 29: pb.df.CreateAccount:output_type -> pb.CreateAccountResponse + 30, // 30: pb.df.UpdateAccount:output_type -> pb.UpdateAccountResponse + 31, // 31: pb.df.UpdateAccountPrivacy:output_type -> pb.UpdateAccountPrivacyResponse + 32, // 32: pb.df.CreatePerson:output_type -> pb.CreatePersonResponse + 33, // 33: pb.df.UpdatePerson:output_type -> pb.UpdatePersonResponse + 34, // 34: pb.df.GetPerson:output_type -> pb.GetPersonResponse + 35, // 35: pb.df.DeletePerson:output_type -> pb.DeletePersonResponse + 36, // 36: pb.df.ListPersons:output_type -> pb.ListPersonsResponse + 37, // 37: pb.df.CreatePayment:output_type -> pb.CreatePaymentResponse + 38, // 38: pb.df.GetPayment:output_type -> pb.GetPaymentResponse + 39, // 39: pb.df.DeletePayment:output_type -> pb.DeletePaymentResponse + 40, // 40: pb.df.ListPayments:output_type -> pb.ListPaymentsResponse + 41, // 41: pb.df.UpdatePayment:output_type -> pb.UpdatePaymentResponse + 42, // 42: pb.df.ListReturnsLog:output_type -> pb.ListReturnsLogResponse + 43, // 43: pb.df.UploadDocument:output_type -> pb.UploadDocumentResponse + 44, // 44: pb.df.DeleteDocument:output_type -> pb.DeleteDocumentResponse + 45, // 45: pb.df.VerifyEmail:output_type -> pb.VerifyEmailResponse + 23, // [23:46] is the sub-list for method output_type + 0, // [0:23] 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 @@ -420,6 +436,7 @@ func file_service_df_proto_init() { file_rpc_list_returns_log_by_person_id_proto_init() file_rpc_upload_document_proto_init() file_rpc_delete_document_proto_init() + file_rpc_verify_email_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/bff/pb/service_df.pb.gw.go b/bff/pb/service_df.pb.gw.go index 3fe5b8e..ef95b50 100644 --- a/bff/pb/service_df.pb.gw.go +++ b/bff/pb/service_df.pb.gw.go @@ -961,6 +961,78 @@ func local_request_Df_DeleteDocument_0(ctx context.Context, marshaler runtime.Ma } +func request_Df_VerifyEmail_0(ctx context.Context, marshaler runtime.Marshaler, client DfClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VerifyEmailRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["account_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "account_id") + } + + protoReq.AccountId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "account_id", err) + } + + val, ok = pathParams["secret_key"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "secret_key") + } + + protoReq.SecretKey, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "secret_key", err) + } + + msg, err := client.VerifyEmail(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Df_VerifyEmail_0(ctx context.Context, marshaler runtime.Marshaler, server DfServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VerifyEmailRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["account_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "account_id") + } + + protoReq.AccountId, err = runtime.Uint64(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "account_id", err) + } + + val, ok = pathParams["secret_key"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "secret_key") + } + + protoReq.SecretKey, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "secret_key", err) + } + + msg, err := server.VerifyEmail(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterDfHandlerServer registers the http handlers for service Df to "mux". // UnaryRPC :call DfServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1517,6 +1589,31 @@ func RegisterDfHandlerServer(ctx context.Context, mux *runtime.ServeMux, server }) + mux.Handle("GET", pattern_Df_VerifyEmail_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/VerifyEmail", runtime.WithHTTPPathPattern("/v1/verify_email/{account_id}/{secret_key}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Df_VerifyEmail_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_VerifyEmail_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2042,6 +2139,28 @@ func RegisterDfHandlerClient(ctx context.Context, mux *runtime.ServeMux, client }) + mux.Handle("GET", pattern_Df_VerifyEmail_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/VerifyEmail", runtime.WithHTTPPathPattern("/v1/verify_email/{account_id}/{secret_key}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Df_VerifyEmail_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_VerifyEmail_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2089,6 +2208,8 @@ var ( pattern_Df_UploadDocument_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"documents", "upload"}, "")) pattern_Df_DeleteDocument_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "documents", "delete_document", "id"}, "")) + + pattern_Df_VerifyEmail_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "verify_email", "account_id", "secret_key"}, "")) ) var ( @@ -2135,4 +2256,6 @@ var ( forward_Df_UploadDocument_0 = runtime.ForwardResponseMessage forward_Df_DeleteDocument_0 = runtime.ForwardResponseMessage + + forward_Df_VerifyEmail_0 = runtime.ForwardResponseMessage ) diff --git a/bff/pb/service_df_grpc.pb.go b/bff/pb/service_df_grpc.pb.go index c89183f..89bf273 100644 --- a/bff/pb/service_df_grpc.pb.go +++ b/bff/pb/service_df_grpc.pb.go @@ -41,6 +41,7 @@ const ( Df_ListReturnsLog_FullMethodName = "/pb.df/ListReturnsLog" Df_UploadDocument_FullMethodName = "/pb.df/UploadDocument" Df_DeleteDocument_FullMethodName = "/pb.df/DeleteDocument" + Df_VerifyEmail_FullMethodName = "/pb.df/VerifyEmail" ) // DfClient is the client API for Df service. @@ -69,6 +70,7 @@ type DfClient interface { ListReturnsLog(ctx context.Context, in *ListReturnsLogRequest, opts ...grpc.CallOption) (*ListReturnsLogResponse, error) UploadDocument(ctx context.Context, in *UploadDocumentRequest, opts ...grpc.CallOption) (*UploadDocumentResponse, error) DeleteDocument(ctx context.Context, in *DeleteDocumentRequest, opts ...grpc.CallOption) (*DeleteDocumentResponse, error) + VerifyEmail(ctx context.Context, in *VerifyEmailRequest, opts ...grpc.CallOption) (*VerifyEmailResponse, error) } type dfClient struct { @@ -277,6 +279,15 @@ func (c *dfClient) DeleteDocument(ctx context.Context, in *DeleteDocumentRequest return out, nil } +func (c *dfClient) VerifyEmail(ctx context.Context, in *VerifyEmailRequest, opts ...grpc.CallOption) (*VerifyEmailResponse, error) { + out := new(VerifyEmailResponse) + err := c.cc.Invoke(ctx, Df_VerifyEmail_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // DfServer is the server API for Df service. // All implementations must embed UnimplementedDfServer // for forward compatibility @@ -303,6 +314,7 @@ type DfServer interface { ListReturnsLog(context.Context, *ListReturnsLogRequest) (*ListReturnsLogResponse, error) UploadDocument(context.Context, *UploadDocumentRequest) (*UploadDocumentResponse, error) DeleteDocument(context.Context, *DeleteDocumentRequest) (*DeleteDocumentResponse, error) + VerifyEmail(context.Context, *VerifyEmailRequest) (*VerifyEmailResponse, error) mustEmbedUnimplementedDfServer() } @@ -376,6 +388,9 @@ func (UnimplementedDfServer) UploadDocument(context.Context, *UploadDocumentRequ func (UnimplementedDfServer) DeleteDocument(context.Context, *DeleteDocumentRequest) (*DeleteDocumentResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteDocument not implemented") } +func (UnimplementedDfServer) VerifyEmail(context.Context, *VerifyEmailRequest) (*VerifyEmailResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VerifyEmail not implemented") +} func (UnimplementedDfServer) mustEmbedUnimplementedDfServer() {} // UnsafeDfServer may be embedded to opt out of forward compatibility for this service. @@ -785,6 +800,24 @@ func _Df_DeleteDocument_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Df_VerifyEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyEmailRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DfServer).VerifyEmail(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Df_VerifyEmail_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DfServer).VerifyEmail(ctx, req.(*VerifyEmailRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Df_ServiceDesc is the grpc.ServiceDesc for Df service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -880,6 +913,10 @@ var Df_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteDocument", Handler: _Df_DeleteDocument_Handler, }, + { + MethodName: "VerifyEmail", + Handler: _Df_VerifyEmail_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "service_df.proto", diff --git a/bff/proto/rpc_verify_email.proto b/bff/proto/rpc_verify_email.proto new file mode 100644 index 0000000..1e0c345 --- /dev/null +++ b/bff/proto/rpc_verify_email.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package pb; + +import "protoc-gen-openapiv2/options/annotations.proto"; + +option go_package = "github.com/itsscb/df/pb"; + +message VerifyEmailRequest { + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + title: "VerifyEmail"; + required: [ + "account_id", + "secret_key" + ]; + }; + example: "{\"id\": \"1\", \"secret_key\": \"thisisasecretkey\" }"; + }; + uint64 account_id = 1; + string secret_key = 2; +} + +message VerifyEmailResponse { + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + title: "VerifyEmail Response"; + }; + }; + bool verified = 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 46de630..9504b0f 100644 --- a/bff/proto/service_df.proto +++ b/bff/proto/service_df.proto @@ -33,6 +33,8 @@ import "rpc_list_returns_log_by_person_id.proto"; import "rpc_upload_document.proto"; import "rpc_delete_document.proto"; +import "rpc_verify_email.proto"; + option go_package = "github.com/itsscb/df/pb"; @@ -364,4 +366,12 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { } }; }; + rpc VerifyEmail (VerifyEmailRequest) returns (VerifyEmailResponse) { + option (google.api.http) = { + get: "/v1/verify_email/{account_id}/{secret_key}" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Verify Email with account_id and secret_key" + }; + }; }; \ No newline at end of file diff --git a/bff/util/config.go b/bff/util/config.go index cefd65a..69a1168 100644 --- a/bff/util/config.go +++ b/bff/util/config.go @@ -15,7 +15,10 @@ type Config struct { LogOutput string `mapstructure:"LOG_OUTPUT"` TokenPrivateKeyHex string `mapstructure:"TOKEN_PRIVATEKEY_HEX"` MigrationURL string `mapstructure:"MIGRATION_URL"` - MigrationRetries int `mapstructure:"MIGRATION_RETRIES"` + SMTPAddress string `mapstructure:"SMTP_ADDRESS"` + SMTPPassword string `mapstructure:"SMTP_PASSWORD"` + SMTPMail string `mapstructure:"SMTP_MAIL"` + MigrationRetries int `mapstructure:"MIGRATION_RETRIES"` AccessTokenDuration time.Duration `mapstructure:"ACCESS_TOKEN_DURATION"` RefreshTokenDuration time.Duration `mapstructure:"REFRESH_TOKEN_DURATION"` }