From 7b77c9bf19281c892f3133ee7c8764f53434183e Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:30:57 +0000 Subject: [PATCH 1/7] associating api key with user record --- backend/gen/go/db/api-keys.sql.go | 15 ++++-- backend/gen/go/db/models.go | 2 + backend/gen/go/db/users.sql.go | 54 ++++++++++++++----- backend/internal/authmw/auth.go | 4 +- .../20231113155315_machine-user.down.sql | 7 +++ .../schema/20231113155315_machine-user.up.sql | 8 +++ 6 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 backend/sql/postgresql/schema/20231113155315_machine-user.down.sql create mode 100644 backend/sql/postgresql/schema/20231113155315_machine-user.up.sql diff --git a/backend/gen/go/db/api-keys.sql.go b/backend/gen/go/db/api-keys.sql.go index 65ab027221..f0d678a0ae 100644 --- a/backend/gen/go/db/api-keys.sql.go +++ b/backend/gen/go/db/api-keys.sql.go @@ -17,7 +17,7 @@ INSERT INTO neosync_api.account_api_keys ( ) VALUES ( $1, $2, $3, $4, $5, $6 ) -RETURNING id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name +RETURNING id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name, user_id ` type CreateAccountApiKeyParams struct { @@ -49,12 +49,13 @@ func (q *Queries) CreateAccountApiKey(ctx context.Context, db DBTX, arg CreateAc &i.UpdatedAt, &i.ExpiresAt, &i.KeyName, + &i.UserID, ) return i, err } const getAccountApiKeyById = `-- name: GetAccountApiKeyById :one -SELECT id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name from neosync_api.account_api_keys WHERE id = $1 +SELECT id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name, user_id from neosync_api.account_api_keys WHERE id = $1 ` func (q *Queries) GetAccountApiKeyById(ctx context.Context, db DBTX, id pgtype.UUID) (NeosyncApiAccountApiKey, error) { @@ -70,12 +71,13 @@ func (q *Queries) GetAccountApiKeyById(ctx context.Context, db DBTX, id pgtype.U &i.UpdatedAt, &i.ExpiresAt, &i.KeyName, + &i.UserID, ) return i, err } const getAccountApiKeyByKeyValue = `-- name: GetAccountApiKeyByKeyValue :one -SELECT id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name from neosync_api.account_api_keys WHERE key_value = $1 +SELECT id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name, user_id from neosync_api.account_api_keys WHERE key_value = $1 ` func (q *Queries) GetAccountApiKeyByKeyValue(ctx context.Context, db DBTX, keyValue string) (NeosyncApiAccountApiKey, error) { @@ -91,12 +93,13 @@ func (q *Queries) GetAccountApiKeyByKeyValue(ctx context.Context, db DBTX, keyVa &i.UpdatedAt, &i.ExpiresAt, &i.KeyName, + &i.UserID, ) return i, err } const getAccountApiKeys = `-- name: GetAccountApiKeys :many -SELECT aak.id, aak.account_id, aak.key_value, aak.created_by_id, aak.updated_by_id, aak.created_at, aak.updated_at, aak.expires_at, aak.key_name from neosync_api.account_api_keys aak +SELECT aak.id, aak.account_id, aak.key_value, aak.created_by_id, aak.updated_by_id, aak.created_at, aak.updated_at, aak.expires_at, aak.key_name, aak.user_id from neosync_api.account_api_keys aak INNER JOIN neosync_api.accounts a on a.id = aak.account_id WHERE a.id = $1 ` @@ -120,6 +123,7 @@ func (q *Queries) GetAccountApiKeys(ctx context.Context, db DBTX, accountid pgty &i.UpdatedAt, &i.ExpiresAt, &i.KeyName, + &i.UserID, ); err != nil { return nil, err } @@ -146,7 +150,7 @@ SET key_value = $1, expires_at = $2, updated_by_id = $3 WHERE id = $4 -RETURNING id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name +RETURNING id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name, user_id ` type UpdateAccountApiKeyValueParams struct { @@ -174,6 +178,7 @@ func (q *Queries) UpdateAccountApiKeyValue(ctx context.Context, db DBTX, arg Upd &i.UpdatedAt, &i.ExpiresAt, &i.KeyName, + &i.UserID, ) return i, err } diff --git a/backend/gen/go/db/models.go b/backend/gen/go/db/models.go index ea80f6bc40..7fd96a4220 100644 --- a/backend/gen/go/db/models.go +++ b/backend/gen/go/db/models.go @@ -28,6 +28,7 @@ type NeosyncApiAccountApiKey struct { UpdatedAt pgtype.Timestamp ExpiresAt pgtype.Timestamp KeyName string + UserID pgtype.UUID } type NeosyncApiAccountInvite struct { @@ -103,6 +104,7 @@ type NeosyncApiUser struct { ID pgtype.UUID CreatedAt pgtype.Timestamp UpdatedAt pgtype.Timestamp + UserType int16 } type NeosyncApiUserIdentityProviderAssociation struct { diff --git a/backend/gen/go/db/users.sql.go b/backend/gen/go/db/users.sql.go index fd8d7f343d..c8b982c427 100644 --- a/backend/gen/go/db/users.sql.go +++ b/backend/gen/go/db/users.sql.go @@ -156,13 +156,18 @@ INSERT INTO neosync_api.users ( ) VALUES ( DEFAULT, DEFAULT, DEFAULT ) -RETURNING id, created_at, updated_at +RETURNING id, created_at, updated_at, user_type ` func (q *Queries) CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { row := db.QueryRow(ctx, createUser) var i NeosyncApiUser - err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) return i, err } @@ -302,14 +307,19 @@ func (q *Queries) GetActiveAccountInvites(ctx context.Context, db DBTX, accounti } const getAnonymousUser = `-- name: GetAnonymousUser :one -SELECT id, created_at, updated_at from neosync_api.users +SELECT id, created_at, updated_at, user_type from neosync_api.users WHERE id = '00000000-0000-0000-0000-000000000000' ` func (q *Queries) GetAnonymousUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { row := db.QueryRow(ctx, getAnonymousUser) var i NeosyncApiUser - err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) return i, err } @@ -402,14 +412,19 @@ func (q *Queries) GetTemporalConfigByUserAccount(ctx context.Context, db DBTX, a } const getUser = `-- name: GetUser :one -SELECT id, created_at, updated_at FROM neosync_api.users +SELECT id, created_at, updated_at, user_type FROM neosync_api.users WHERE id = $1 ` func (q *Queries) GetUser(ctx context.Context, db DBTX, id pgtype.UUID) (NeosyncApiUser, error) { row := db.QueryRow(ctx, getUser, id) var i NeosyncApiUser - err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) return i, err } @@ -432,7 +447,7 @@ func (q *Queries) GetUserAssociationByAuth0Id(ctx context.Context, db DBTX, auth } const getUserByAuth0Id = `-- name: GetUserByAuth0Id :one -SELECT u.id, u.created_at, u.updated_at from neosync_api.users u +SELECT u.id, u.created_at, u.updated_at, u.user_type from neosync_api.users u INNER JOIN neosync_api.user_identity_provider_associations uipa ON uipa.user_id = u.id WHERE uipa.auth0_provider_id = $1 ` @@ -440,12 +455,17 @@ WHERE uipa.auth0_provider_id = $1 func (q *Queries) GetUserByAuth0Id(ctx context.Context, db DBTX, auth0ProviderID string) (NeosyncApiUser, error) { row := db.QueryRow(ctx, getUserByAuth0Id, auth0ProviderID) var i NeosyncApiUser - err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) return i, err } const getUsersByTeamAccount = `-- name: GetUsersByTeamAccount :many -SELECT u.id, u.created_at, u.updated_at from neosync_api.users u +SELECT u.id, u.created_at, u.updated_at, u.user_type from neosync_api.users u INNER JOIN neosync_api.account_user_associations aua ON aua.user_id = u.id INNER JOIN neosync_api.accounts a ON a.id = aua.account_id WHERE a.id = $1 AND a.account_type = 1 @@ -460,7 +480,12 @@ func (q *Queries) GetUsersByTeamAccount(ctx context.Context, db DBTX, accountid var items []NeosyncApiUser for rows.Next() { var i NeosyncApiUser - if err := rows.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt); err != nil { + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ); err != nil { return nil, err } items = append(items, i) @@ -524,13 +549,18 @@ INSERT INTO neosync_api.users ( ON CONFLICT (id) DO UPDATE SET updated_at = current_timestamp -RETURNING id, created_at, updated_at +RETURNING id, created_at, updated_at, user_type ` func (q *Queries) SetAnonymousUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { row := db.QueryRow(ctx, setAnonymousUser) var i NeosyncApiUser - err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt) + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) return i, err } diff --git a/backend/internal/authmw/auth.go b/backend/internal/authmw/auth.go index b25d9bd46f..7b70083851 100644 --- a/backend/internal/authmw/auth.go +++ b/backend/internal/authmw/auth.go @@ -23,14 +23,14 @@ func New( } func (n *AuthMiddleware) ValidateAndInjectAll(ctx context.Context, header http.Header) (context.Context, error) { - ctx, err := n.ValidateAndInjectToken(ctx, header) + ctx, err := n.ValidateAndInjectJwtToken(ctx, header) if err != nil { return nil, err } return ctx, nil } -func (n *AuthMiddleware) ValidateAndInjectToken(ctx context.Context, header http.Header) (context.Context, error) { +func (n *AuthMiddleware) ValidateAndInjectJwtToken(ctx context.Context, header http.Header) (context.Context, error) { ctx, err := n.jwtClient.InjectTokenCtx(ctx, header) if err != nil { return nil, err diff --git a/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql b/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql new file mode 100644 index 0000000000..91edda7bfe --- /dev/null +++ b/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql @@ -0,0 +1,7 @@ +ALTER TABLE neosync_api.users +DROP COLUMN user_type; + +-- ALTER TABLE neosync_api.account_api_keys +-- DROP CONSTRAINT IF EXISTS fk_account_api_keys_user_id_users_id; +ALTER TABLE neosync_api.account_api_keys +DROP COLUMN user_id; diff --git a/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql b/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql new file mode 100644 index 0000000000..cb60fe9f73 --- /dev/null +++ b/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql @@ -0,0 +1,8 @@ +ALTER TABLE neosync_api.users +ADD COLUMN user_type smallint not null default 0; + +ALTER TABLE neosync_api.account_api_keys +ADD COLUMN user_id uuid null; + +ALTER TABLE neosync_api.account_api_keys +ADD CONSTRAINT fk_account_api_keys_user_id_users_id FOREIGN KEY (user_id) REFERENCES neosync_api.users(id); From edd44530b1dc9631b5a1a8b568d9d25178dd4dc4 Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:32:42 +0000 Subject: [PATCH 2/7] remove commented code from new down migration --- .../sql/postgresql/schema/20231113155315_machine-user.down.sql | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql b/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql index 91edda7bfe..7567f4ef66 100644 --- a/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql +++ b/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql @@ -1,7 +1,5 @@ ALTER TABLE neosync_api.users DROP COLUMN user_type; --- ALTER TABLE neosync_api.account_api_keys --- DROP CONSTRAINT IF EXISTS fk_account_api_keys_user_id_users_id; ALTER TABLE neosync_api.account_api_keys DROP COLUMN user_id; From 60d0460501f207eeba8276d86b00a89744f04f96 Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:38:01 +0000 Subject: [PATCH 3/7] make migrations more idempotent --- .../postgresql/schema/20231113155315_machine-user.down.sql | 4 ++-- .../sql/postgresql/schema/20231113155315_machine-user.up.sql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql b/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql index 7567f4ef66..e9bdfe4580 100644 --- a/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql +++ b/backend/sql/postgresql/schema/20231113155315_machine-user.down.sql @@ -1,5 +1,5 @@ ALTER TABLE neosync_api.users -DROP COLUMN user_type; +DROP COLUMN IF EXISTS user_type; ALTER TABLE neosync_api.account_api_keys -DROP COLUMN user_id; +DROP COLUMN IF EXISTS user_id; diff --git a/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql b/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql index cb60fe9f73..ead68be901 100644 --- a/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql +++ b/backend/sql/postgresql/schema/20231113155315_machine-user.up.sql @@ -1,8 +1,8 @@ ALTER TABLE neosync_api.users -ADD COLUMN user_type smallint not null default 0; +ADD COLUMN IF NOT EXISTS user_type smallint not null default 0; ALTER TABLE neosync_api.account_api_keys -ADD COLUMN user_id uuid null; +ADD COLUMN IF NOT EXISTS user_id uuid null; ALTER TABLE neosync_api.account_api_keys ADD CONSTRAINT fk_account_api_keys_user_id_users_id FOREIGN KEY (user_id) REFERENCES neosync_api.users(id); From a0375ca3acab4fbe02360ab8e06391b8e0533960 Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:10:38 +0000 Subject: [PATCH 4/7] refactoring api key to include machine user --- backend/gen/go/db/api-keys.sql.go | 6 +- backend/gen/go/db/mock_Querier.go | 155 ++++++++++++------ backend/gen/go/db/querier.go | 3 +- backend/gen/go/db/users.sql.go | 69 +++++--- backend/internal/nucleusdb/api-keys.go | 52 ++++++ backend/internal/nucleusdb/users.go | 4 +- backend/internal/nucleusdb/users_test.go | 6 +- .../mgmt/v1alpha1/api-key-service/api-keys.go | 15 +- backend/sql/postgresql/queries/api-keys.sql | 4 +- backend/sql/postgresql/queries/users.sql | 22 ++- 10 files changed, 236 insertions(+), 100 deletions(-) create mode 100644 backend/internal/nucleusdb/api-keys.go diff --git a/backend/gen/go/db/api-keys.sql.go b/backend/gen/go/db/api-keys.sql.go index f0d678a0ae..7810329538 100644 --- a/backend/gen/go/db/api-keys.sql.go +++ b/backend/gen/go/db/api-keys.sql.go @@ -13,9 +13,9 @@ import ( const createAccountApiKey = `-- name: CreateAccountApiKey :one INSERT INTO neosync_api.account_api_keys ( - key_name, key_value, account_id, expires_at, created_by_id, updated_by_id + key_name, key_value, account_id, expires_at, created_by_id, updated_by_id, user_id ) VALUES ( - $1, $2, $3, $4, $5, $6 + $1, $2, $3, $4, $5, $6, $7 ) RETURNING id, account_id, key_value, created_by_id, updated_by_id, created_at, updated_at, expires_at, key_name, user_id ` @@ -27,6 +27,7 @@ type CreateAccountApiKeyParams struct { ExpiresAt pgtype.Timestamp CreatedByID pgtype.UUID UpdatedByID pgtype.UUID + UserID pgtype.UUID } func (q *Queries) CreateAccountApiKey(ctx context.Context, db DBTX, arg CreateAccountApiKeyParams) (NeosyncApiAccountApiKey, error) { @@ -37,6 +38,7 @@ func (q *Queries) CreateAccountApiKey(ctx context.Context, db DBTX, arg CreateAc arg.ExpiresAt, arg.CreatedByID, arg.UpdatedByID, + arg.UserID, ) var i NeosyncApiAccountApiKey err := row.Scan( diff --git a/backend/gen/go/db/mock_Querier.go b/backend/gen/go/db/mock_Querier.go index 6d48f14091..80b4e6aac7 100644 --- a/backend/gen/go/db/mock_Querier.go +++ b/backend/gen/go/db/mock_Querier.go @@ -510,23 +510,23 @@ func (_c *MockQuerier_CreateJobConnectionDestinations_Call) RunAndReturn(run fun return _c } -// CreatePersonalAccount provides a mock function with given fields: ctx, db, accountSlug -func (_m *MockQuerier) CreatePersonalAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) { - ret := _m.Called(ctx, db, accountSlug) +// CreateMachineUser provides a mock function with given fields: ctx, db +func (_m *MockQuerier) CreateMachineUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { + ret := _m.Called(ctx, db) - var r0 NeosyncApiAccount + var r0 NeosyncApiUser var r1 error - if rf, ok := ret.Get(0).(func(context.Context, DBTX, string) (NeosyncApiAccount, error)); ok { - return rf(ctx, db, accountSlug) + if rf, ok := ret.Get(0).(func(context.Context, DBTX) (NeosyncApiUser, error)); ok { + return rf(ctx, db) } - if rf, ok := ret.Get(0).(func(context.Context, DBTX, string) NeosyncApiAccount); ok { - r0 = rf(ctx, db, accountSlug) + if rf, ok := ret.Get(0).(func(context.Context, DBTX) NeosyncApiUser); ok { + r0 = rf(ctx, db) } else { - r0 = ret.Get(0).(NeosyncApiAccount) + r0 = ret.Get(0).(NeosyncApiUser) } - if rf, ok := ret.Get(1).(func(context.Context, DBTX, string) error); ok { - r1 = rf(ctx, db, accountSlug) + if rf, ok := ret.Get(1).(func(context.Context, DBTX) error); ok { + r1 = rf(ctx, db) } else { r1 = ret.Error(1) } @@ -534,38 +534,90 @@ func (_m *MockQuerier) CreatePersonalAccount(ctx context.Context, db DBTX, accou return r0, r1 } -// MockQuerier_CreatePersonalAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePersonalAccount' -type MockQuerier_CreatePersonalAccount_Call struct { +// MockQuerier_CreateMachineUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateMachineUser' +type MockQuerier_CreateMachineUser_Call struct { *mock.Call } -// CreatePersonalAccount is a helper method to define mock.On call +// CreateMachineUser is a helper method to define mock.On call // - ctx context.Context // - db DBTX -// - accountSlug string -func (_e *MockQuerier_Expecter) CreatePersonalAccount(ctx interface{}, db interface{}, accountSlug interface{}) *MockQuerier_CreatePersonalAccount_Call { - return &MockQuerier_CreatePersonalAccount_Call{Call: _e.mock.On("CreatePersonalAccount", ctx, db, accountSlug)} +func (_e *MockQuerier_Expecter) CreateMachineUser(ctx interface{}, db interface{}) *MockQuerier_CreateMachineUser_Call { + return &MockQuerier_CreateMachineUser_Call{Call: _e.mock.On("CreateMachineUser", ctx, db)} } -func (_c *MockQuerier_CreatePersonalAccount_Call) Run(run func(ctx context.Context, db DBTX, accountSlug string)) *MockQuerier_CreatePersonalAccount_Call { +func (_c *MockQuerier_CreateMachineUser_Call) Run(run func(ctx context.Context, db DBTX)) *MockQuerier_CreateMachineUser_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(DBTX), args[2].(string)) + run(args[0].(context.Context), args[1].(DBTX)) }) return _c } -func (_c *MockQuerier_CreatePersonalAccount_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_CreatePersonalAccount_Call { +func (_c *MockQuerier_CreateMachineUser_Call) Return(_a0 NeosyncApiUser, _a1 error) *MockQuerier_CreateMachineUser_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockQuerier_CreatePersonalAccount_Call) RunAndReturn(run func(context.Context, DBTX, string) (NeosyncApiAccount, error)) *MockQuerier_CreatePersonalAccount_Call { +func (_c *MockQuerier_CreateMachineUser_Call) RunAndReturn(run func(context.Context, DBTX) (NeosyncApiUser, error)) *MockQuerier_CreateMachineUser_Call { _c.Call.Return(run) return _c } -// CreateTeamAccount provides a mock function with given fields: ctx, db, accountSlug -func (_m *MockQuerier) CreateTeamAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) { +// CreateNonMachineUser provides a mock function with given fields: ctx, db +func (_m *MockQuerier) CreateNonMachineUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { + ret := _m.Called(ctx, db) + + var r0 NeosyncApiUser + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, DBTX) (NeosyncApiUser, error)); ok { + return rf(ctx, db) + } + if rf, ok := ret.Get(0).(func(context.Context, DBTX) NeosyncApiUser); ok { + r0 = rf(ctx, db) + } else { + r0 = ret.Get(0).(NeosyncApiUser) + } + + if rf, ok := ret.Get(1).(func(context.Context, DBTX) error); ok { + r1 = rf(ctx, db) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockQuerier_CreateNonMachineUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateNonMachineUser' +type MockQuerier_CreateNonMachineUser_Call struct { + *mock.Call +} + +// CreateNonMachineUser is a helper method to define mock.On call +// - ctx context.Context +// - db DBTX +func (_e *MockQuerier_Expecter) CreateNonMachineUser(ctx interface{}, db interface{}) *MockQuerier_CreateNonMachineUser_Call { + return &MockQuerier_CreateNonMachineUser_Call{Call: _e.mock.On("CreateNonMachineUser", ctx, db)} +} + +func (_c *MockQuerier_CreateNonMachineUser_Call) Run(run func(ctx context.Context, db DBTX)) *MockQuerier_CreateNonMachineUser_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(DBTX)) + }) + return _c +} + +func (_c *MockQuerier_CreateNonMachineUser_Call) Return(_a0 NeosyncApiUser, _a1 error) *MockQuerier_CreateNonMachineUser_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockQuerier_CreateNonMachineUser_Call) RunAndReturn(run func(context.Context, DBTX) (NeosyncApiUser, error)) *MockQuerier_CreateNonMachineUser_Call { + _c.Call.Return(run) + return _c +} + +// CreatePersonalAccount provides a mock function with given fields: ctx, db, accountSlug +func (_m *MockQuerier) CreatePersonalAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) { ret := _m.Called(ctx, db, accountSlug) var r0 NeosyncApiAccount @@ -588,53 +640,53 @@ func (_m *MockQuerier) CreateTeamAccount(ctx context.Context, db DBTX, accountSl return r0, r1 } -// MockQuerier_CreateTeamAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateTeamAccount' -type MockQuerier_CreateTeamAccount_Call struct { +// MockQuerier_CreatePersonalAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePersonalAccount' +type MockQuerier_CreatePersonalAccount_Call struct { *mock.Call } -// CreateTeamAccount is a helper method to define mock.On call +// CreatePersonalAccount is a helper method to define mock.On call // - ctx context.Context // - db DBTX // - accountSlug string -func (_e *MockQuerier_Expecter) CreateTeamAccount(ctx interface{}, db interface{}, accountSlug interface{}) *MockQuerier_CreateTeamAccount_Call { - return &MockQuerier_CreateTeamAccount_Call{Call: _e.mock.On("CreateTeamAccount", ctx, db, accountSlug)} +func (_e *MockQuerier_Expecter) CreatePersonalAccount(ctx interface{}, db interface{}, accountSlug interface{}) *MockQuerier_CreatePersonalAccount_Call { + return &MockQuerier_CreatePersonalAccount_Call{Call: _e.mock.On("CreatePersonalAccount", ctx, db, accountSlug)} } -func (_c *MockQuerier_CreateTeamAccount_Call) Run(run func(ctx context.Context, db DBTX, accountSlug string)) *MockQuerier_CreateTeamAccount_Call { +func (_c *MockQuerier_CreatePersonalAccount_Call) Run(run func(ctx context.Context, db DBTX, accountSlug string)) *MockQuerier_CreatePersonalAccount_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(DBTX), args[2].(string)) }) return _c } -func (_c *MockQuerier_CreateTeamAccount_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_CreateTeamAccount_Call { +func (_c *MockQuerier_CreatePersonalAccount_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_CreatePersonalAccount_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockQuerier_CreateTeamAccount_Call) RunAndReturn(run func(context.Context, DBTX, string) (NeosyncApiAccount, error)) *MockQuerier_CreateTeamAccount_Call { +func (_c *MockQuerier_CreatePersonalAccount_Call) RunAndReturn(run func(context.Context, DBTX, string) (NeosyncApiAccount, error)) *MockQuerier_CreatePersonalAccount_Call { _c.Call.Return(run) return _c } -// CreateUser provides a mock function with given fields: ctx, db -func (_m *MockQuerier) CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { - ret := _m.Called(ctx, db) +// CreateTeamAccount provides a mock function with given fields: ctx, db, accountSlug +func (_m *MockQuerier) CreateTeamAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) { + ret := _m.Called(ctx, db, accountSlug) - var r0 NeosyncApiUser + var r0 NeosyncApiAccount var r1 error - if rf, ok := ret.Get(0).(func(context.Context, DBTX) (NeosyncApiUser, error)); ok { - return rf(ctx, db) + if rf, ok := ret.Get(0).(func(context.Context, DBTX, string) (NeosyncApiAccount, error)); ok { + return rf(ctx, db, accountSlug) } - if rf, ok := ret.Get(0).(func(context.Context, DBTX) NeosyncApiUser); ok { - r0 = rf(ctx, db) + if rf, ok := ret.Get(0).(func(context.Context, DBTX, string) NeosyncApiAccount); ok { + r0 = rf(ctx, db, accountSlug) } else { - r0 = ret.Get(0).(NeosyncApiUser) + r0 = ret.Get(0).(NeosyncApiAccount) } - if rf, ok := ret.Get(1).(func(context.Context, DBTX) error); ok { - r1 = rf(ctx, db) + if rf, ok := ret.Get(1).(func(context.Context, DBTX, string) error); ok { + r1 = rf(ctx, db, accountSlug) } else { r1 = ret.Error(1) } @@ -642,31 +694,32 @@ func (_m *MockQuerier) CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, return r0, r1 } -// MockQuerier_CreateUser_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateUser' -type MockQuerier_CreateUser_Call struct { +// MockQuerier_CreateTeamAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateTeamAccount' +type MockQuerier_CreateTeamAccount_Call struct { *mock.Call } -// CreateUser is a helper method to define mock.On call +// CreateTeamAccount is a helper method to define mock.On call // - ctx context.Context // - db DBTX -func (_e *MockQuerier_Expecter) CreateUser(ctx interface{}, db interface{}) *MockQuerier_CreateUser_Call { - return &MockQuerier_CreateUser_Call{Call: _e.mock.On("CreateUser", ctx, db)} +// - accountSlug string +func (_e *MockQuerier_Expecter) CreateTeamAccount(ctx interface{}, db interface{}, accountSlug interface{}) *MockQuerier_CreateTeamAccount_Call { + return &MockQuerier_CreateTeamAccount_Call{Call: _e.mock.On("CreateTeamAccount", ctx, db, accountSlug)} } -func (_c *MockQuerier_CreateUser_Call) Run(run func(ctx context.Context, db DBTX)) *MockQuerier_CreateUser_Call { +func (_c *MockQuerier_CreateTeamAccount_Call) Run(run func(ctx context.Context, db DBTX, accountSlug string)) *MockQuerier_CreateTeamAccount_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(DBTX)) + run(args[0].(context.Context), args[1].(DBTX), args[2].(string)) }) return _c } -func (_c *MockQuerier_CreateUser_Call) Return(_a0 NeosyncApiUser, _a1 error) *MockQuerier_CreateUser_Call { +func (_c *MockQuerier_CreateTeamAccount_Call) Return(_a0 NeosyncApiAccount, _a1 error) *MockQuerier_CreateTeamAccount_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockQuerier_CreateUser_Call) RunAndReturn(run func(context.Context, DBTX) (NeosyncApiUser, error)) *MockQuerier_CreateUser_Call { +func (_c *MockQuerier_CreateTeamAccount_Call) RunAndReturn(run func(context.Context, DBTX, string) (NeosyncApiAccount, error)) *MockQuerier_CreateTeamAccount_Call { _c.Call.Return(run) return _c } diff --git a/backend/gen/go/db/querier.go b/backend/gen/go/db/querier.go index 1d76e59308..2f566b8636 100644 --- a/backend/gen/go/db/querier.go +++ b/backend/gen/go/db/querier.go @@ -21,9 +21,10 @@ type Querier interface { CreateJob(ctx context.Context, db DBTX, arg CreateJobParams) (NeosyncApiJob, error) CreateJobConnectionDestination(ctx context.Context, db DBTX, arg CreateJobConnectionDestinationParams) (NeosyncApiJobDestinationConnectionAssociation, error) CreateJobConnectionDestinations(ctx context.Context, db DBTX, arg []CreateJobConnectionDestinationsParams) (int64, error) + CreateMachineUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) + CreateNonMachineUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) CreatePersonalAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) CreateTeamAccount(ctx context.Context, db DBTX, accountSlug string) (NeosyncApiAccount, error) - CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) DeleteCustomTransformerById(ctx context.Context, db DBTX, id pgtype.UUID) error DeleteJob(ctx context.Context, db DBTX, id pgtype.UUID) error GetAccount(ctx context.Context, db DBTX, id pgtype.UUID) (NeosyncApiAccount, error) diff --git a/backend/gen/go/db/users.sql.go b/backend/gen/go/db/users.sql.go index c8b982c427..73bd51a58a 100644 --- a/backend/gen/go/db/users.sql.go +++ b/backend/gen/go/db/users.sql.go @@ -104,6 +104,48 @@ func (q *Queries) CreateAuth0IdentityProviderAssociation(ctx context.Context, db return i, err } +const createMachineUser = `-- name: CreateMachineUser :one +INSERT INTO neosync_api.users ( + id, created_at, updated_at, user_type +) VALUES ( + DEFAULT, DEFAULT, DEFAULT, 1 +) +RETURNING id, created_at, updated_at, user_type +` + +func (q *Queries) CreateMachineUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { + row := db.QueryRow(ctx, createMachineUser) + var i NeosyncApiUser + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) + return i, err +} + +const createNonMachineUser = `-- name: CreateNonMachineUser :one +INSERT INTO neosync_api.users ( + id, created_at, updated_at, user_type +) VALUES ( + DEFAULT, DEFAULT, DEFAULT, 0 +) +RETURNING id, created_at, updated_at, user_type +` + +func (q *Queries) CreateNonMachineUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { + row := db.QueryRow(ctx, createNonMachineUser) + var i NeosyncApiUser + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.UserType, + ) + return i, err +} + const createPersonalAccount = `-- name: CreatePersonalAccount :one INSERT INTO neosync_api.accounts ( account_type, account_slug @@ -150,27 +192,6 @@ func (q *Queries) CreateTeamAccount(ctx context.Context, db DBTX, accountSlug st return i, err } -const createUser = `-- name: CreateUser :one -INSERT INTO neosync_api.users ( - id, created_at, updated_at -) VALUES ( - DEFAULT, DEFAULT, DEFAULT -) -RETURNING id, created_at, updated_at, user_type -` - -func (q *Queries) CreateUser(ctx context.Context, db DBTX) (NeosyncApiUser, error) { - row := db.QueryRow(ctx, createUser) - var i NeosyncApiUser - err := row.Scan( - &i.ID, - &i.CreatedAt, - &i.UpdatedAt, - &i.UserType, - ) - return i, err -} - const getAccount = `-- name: GetAccount :one SELECT id, created_at, updated_at, account_type, account_slug, temporal_config from neosync_api.accounts WHERE id = $1 @@ -449,7 +470,7 @@ func (q *Queries) GetUserAssociationByAuth0Id(ctx context.Context, db DBTX, auth const getUserByAuth0Id = `-- name: GetUserByAuth0Id :one SELECT u.id, u.created_at, u.updated_at, u.user_type from neosync_api.users u INNER JOIN neosync_api.user_identity_provider_associations uipa ON uipa.user_id = u.id -WHERE uipa.auth0_provider_id = $1 +WHERE uipa.auth0_provider_id = $1 and u.user_type = 0 ` func (q *Queries) GetUserByAuth0Id(ctx context.Context, db DBTX, auth0ProviderID string) (NeosyncApiUser, error) { @@ -516,7 +537,7 @@ func (q *Queries) IsUserInAccount(ctx context.Context, db DBTX, arg IsUserInAcco } const removeAccountInvite = `-- name: RemoveAccountInvite :exec -DELETE FROM neosync_api.account_invites +DELETE FROM neosync_api.account_invites WHERE id = $1 ` @@ -526,7 +547,7 @@ func (q *Queries) RemoveAccountInvite(ctx context.Context, db DBTX, id pgtype.UU } const removeAccountUser = `-- name: RemoveAccountUser :exec -DELETE FROM neosync_api.account_user_associations +DELETE FROM neosync_api.account_user_associations WHERE account_id = $1 AND user_id = $2 ` diff --git a/backend/internal/nucleusdb/api-keys.go b/backend/internal/nucleusdb/api-keys.go new file mode 100644 index 0000000000..a3487a0174 --- /dev/null +++ b/backend/internal/nucleusdb/api-keys.go @@ -0,0 +1,52 @@ +package nucleusdb + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" + db_queries "github.com/nucleuscloud/neosync/backend/gen/go/db" +) + +type CreateAccountApiKeyRequest struct { + KeyName string + KeyValue string + AccountUuid pgtype.UUID + CreatedByUserUuid pgtype.UUID + ExpiresAt pgtype.Timestamp +} + +func (d *NucleusDb) CreateAccountApikey( + ctx context.Context, + req *CreateAccountApiKeyRequest, +) (*db_queries.NeosyncApiAccountApiKey, error) { + var createdApiKey *db_queries.NeosyncApiAccountApiKey + if err := d.WithTx(ctx, nil, func(tx BaseDBTX) error { + // create machine user + user, err := d.Q.CreateMachineUser(ctx, tx) + if err != nil { + return err + } + newApiKey, err := d.Q.CreateAccountApiKey( + ctx, + tx, + db_queries.CreateAccountApiKeyParams{ + KeyName: req.KeyName, + KeyValue: req.KeyValue, + AccountID: req.AccountUuid, + ExpiresAt: req.ExpiresAt, + CreatedByID: req.CreatedByUserUuid, + UpdatedByID: req.CreatedByUserUuid, + UserID: user.ID, + }, + ) + if err != nil { + return err + } + createdApiKey = &newApiKey + return nil + }); err != nil { + return nil, err + } + + return createdApiKey, nil +} diff --git a/backend/internal/nucleusdb/users.go b/backend/internal/nucleusdb/users.go index db034aa9a0..854654a840 100644 --- a/backend/internal/nucleusdb/users.go +++ b/backend/internal/nucleusdb/users.go @@ -25,7 +25,7 @@ func (d *NucleusDb) SetUserByAuth0Id( return err } else if err != nil && IsNoRows(err) { // create user, create association - user, err = d.Q.CreateUser(ctx, dbtx) + user, err = d.Q.CreateNonMachineUser(ctx, dbtx) if err != nil { return err } @@ -44,7 +44,7 @@ func (d *NucleusDb) SetUserByAuth0Id( return err } } else if err != nil && IsNoRows(err) { - user, err = d.Q.CreateUser(ctx, dbtx) + user, err = d.Q.CreateNonMachineUser(ctx, dbtx) if err != nil { return err } diff --git a/backend/internal/nucleusdb/users_test.go b/backend/internal/nucleusdb/users_test.go index 68a4fe6511..479823268d 100644 --- a/backend/internal/nucleusdb/users_test.go +++ b/backend/internal/nucleusdb/users_test.go @@ -85,7 +85,7 @@ func Test_SetUserByAuth0Id_NoAssociation(t *testing.T) { dbtxMock.On("Begin", ctx).Return(mockTx, nil) querierMock.On("GetUserByAuth0Id", ctx, mockTx, mockAuth0Id).Return(nilUser, sql.ErrNoRows) querierMock.On("GetUserAssociationByAuth0Id", ctx, mockTx, mockAuth0Id).Return(nilAssociation, sql.ErrNoRows) - querierMock.On("CreateUser", ctx, mockTx).Return(db_queries.NeosyncApiUser{ID: userUuid}, nil) + querierMock.On("CreateNonMachineUser", ctx, mockTx).Return(db_queries.NeosyncApiUser{ID: userUuid}, nil) querierMock.On("CreateAuth0IdentityProviderAssociation", ctx, mockTx, db_queries.CreateAuth0IdentityProviderAssociationParams{ UserID: userUuid, Auth0ProviderID: mockAuth0Id, @@ -117,7 +117,7 @@ func Test_SetUserByAuth0Id_Association_NoUser(t *testing.T) { querierMock.On("GetUserByAuth0Id", ctx, mockTx, mockAuth0Id).Return(nilUser, sql.ErrNoRows) querierMock.On("GetUserAssociationByAuth0Id", ctx, mockTx, mockAuth0Id).Return(db_queries.NeosyncApiUserIdentityProviderAssociation{UserID: userUuid}, nil) querierMock.On("GetUser", ctx, mockTx, userUuid).Return(nilUser, sql.ErrNoRows) - querierMock.On("CreateUser", ctx, mockTx).Return(db_queries.NeosyncApiUser{ID: userUuid}, nil) + querierMock.On("CreateNonMachineUser", ctx, mockTx).Return(db_queries.NeosyncApiUser{ID: userUuid}, nil) mockTx.On("Commit", ctx).Return(nil) mockTx.On("Rollback", ctx).Return(nil) @@ -144,7 +144,7 @@ func Test_SetUserByAuth0Id_CreateAuth0IdentityProviderAssociation_Error(t *testi dbtxMock.On("Begin", ctx).Return(mockTx, nil) querierMock.On("GetUserByAuth0Id", ctx, mockTx, mockAuth0Id).Return(nilUser, sql.ErrNoRows) querierMock.On("GetUserAssociationByAuth0Id", ctx, mockTx, mockAuth0Id).Return(nilAssociation, sql.ErrNoRows) - querierMock.On("CreateUser", ctx, mockTx).Return(db_queries.NeosyncApiUser{ID: userUuid}, nil) + querierMock.On("CreateNonMachineUser", ctx, mockTx).Return(db_queries.NeosyncApiUser{ID: userUuid}, nil) querierMock.On("CreateAuth0IdentityProviderAssociation", ctx, mockTx, db_queries.CreateAuth0IdentityProviderAssociationParams{ UserID: userUuid, Auth0ProviderID: mockAuth0Id, diff --git a/backend/services/mgmt/v1alpha1/api-key-service/api-keys.go b/backend/services/mgmt/v1alpha1/api-key-service/api-keys.go index ae49530c06..5d208e3d95 100644 --- a/backend/services/mgmt/v1alpha1/api-key-service/api-keys.go +++ b/backend/services/mgmt/v1alpha1/api-key-service/api-keys.go @@ -88,19 +88,18 @@ func (s *Service) CreateAccountApiKey( clearKeyValue, ) - newApiKey, err := s.db.Q.CreateAccountApiKey(ctx, s.db.Db, db_queries.CreateAccountApiKeyParams{ - KeyName: req.Msg.Name, - KeyValue: hashedKeyValue, - AccountID: *accountUuid, - ExpiresAt: expiresAt, - CreatedByID: *userUuid, - UpdatedByID: *userUuid, + newApiKey, err := s.db.CreateAccountApikey(ctx, &nucleusdb.CreateAccountApiKeyRequest{ + KeyName: req.Msg.Name, + KeyValue: hashedKeyValue, + AccountUuid: *accountUuid, + CreatedByUserUuid: *userUuid, + ExpiresAt: expiresAt, }) if err != nil { return nil, err } return connect.NewResponse(&mgmtv1alpha1.CreateAccountApiKeyResponse{ - ApiKey: dtomaps.ToAccountApiKeyDto(&newApiKey, &clearKeyValue), + ApiKey: dtomaps.ToAccountApiKeyDto(newApiKey, &clearKeyValue), }), nil } diff --git a/backend/sql/postgresql/queries/api-keys.sql b/backend/sql/postgresql/queries/api-keys.sql index e332c298ad..eefac5e0eb 100644 --- a/backend/sql/postgresql/queries/api-keys.sql +++ b/backend/sql/postgresql/queries/api-keys.sql @@ -14,9 +14,9 @@ SELECT * from neosync_api.account_api_keys WHERE key_value = $1; -- name: CreateAccountApiKey :one INSERT INTO neosync_api.account_api_keys ( - key_name, key_value, account_id, expires_at, created_by_id, updated_by_id + key_name, key_value, account_id, expires_at, created_by_id, updated_by_id, user_id ) VALUES ( - $1, $2, $3, $4, $5, $6 + $1, $2, $3, $4, $5, $6, $7 ) RETURNING *; diff --git a/backend/sql/postgresql/queries/users.sql b/backend/sql/postgresql/queries/users.sql index a0e6dbd869..edaf69ab0b 100644 --- a/backend/sql/postgresql/queries/users.sql +++ b/backend/sql/postgresql/queries/users.sql @@ -9,13 +9,21 @@ WHERE auth0_provider_id = $1; -- name: GetUserByAuth0Id :one SELECT u.* from neosync_api.users u INNER JOIN neosync_api.user_identity_provider_associations uipa ON uipa.user_id = u.id -WHERE uipa.auth0_provider_id = $1; +WHERE uipa.auth0_provider_id = $1 and u.user_type = 0; --- name: CreateUser :one +-- name: CreateNonMachineUser :one INSERT INTO neosync_api.users ( - id, created_at, updated_at + id, created_at, updated_at, user_type +) VALUES ( + DEFAULT, DEFAULT, DEFAULT, 0 +) +RETURNING *; + +-- name: CreateMachineUser :one +INSERT INTO neosync_api.users ( + id, created_at, updated_at, user_type ) VALUES ( - DEFAULT, DEFAULT, DEFAULT + DEFAULT, DEFAULT, DEFAULT, 1 ) RETURNING *; @@ -125,7 +133,7 @@ INNER JOIN neosync_api.users u ON u.id = aua.user_id WHERE a.id = sqlc.arg('accountId') AND u.id = sqlc.arg('userId'); -- name: RemoveAccountUser :exec -DELETE FROM neosync_api.account_user_associations +DELETE FROM neosync_api.account_user_associations WHERE account_id = sqlc.arg('accountId') AND user_id = sqlc.arg('userId'); -- name: CreateAccountInvite :one @@ -138,7 +146,7 @@ RETURNING *; -- name: GetActiveAccountInvites :many SELECT * FROM neosync_api.account_invites -WHERE account_id = sqlc.arg('accountId') AND expires_at > CURRENT_TIMESTAMP; +WHERE account_id = sqlc.arg('accountId') AND expires_at > CURRENT_TIMESTAMP; -- name: UpdateActiveAccountInvitesToExpired :one UPDATE neosync_api.account_invites @@ -151,5 +159,5 @@ SELECT * FROM neosync_api.account_invites WHERE id = $1; -- name: RemoveAccountInvite :exec -DELETE FROM neosync_api.account_invites +DELETE FROM neosync_api.account_invites WHERE id = $1; From 21a93e48d075d26bcdca346c7bc56e814219c050 Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:17:20 +0000 Subject: [PATCH 5/7] fix api key service tests --- .../mgmt/v1alpha1/api-key-service/api-keys_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/services/mgmt/v1alpha1/api-key-service/api-keys_test.go b/backend/services/mgmt/v1alpha1/api-key-service/api-keys_test.go index 14fe449821..01e42ae574 100644 --- a/backend/services/mgmt/v1alpha1/api-key-service/api-keys_test.go +++ b/backend/services/mgmt/v1alpha1/api-key-service/api-keys_test.go @@ -168,12 +168,22 @@ func Test_Service_GetAccountApiKey_Found_ForbiddenAccount(t *testing.T) { func Test_Service_CreateAccountApiKey(t *testing.T) { mockDbtx := nucleusdb.NewMockDBTX(t) mockQuerier := db_queries.NewMockQuerier(t) + mockTx := new(nucleusdb.MockTx) mockUserAccountService := mgmtv1alpha1connect.NewMockUserAccountServiceClient(t) svc := New(&Config{}, nucleusdb.New(mockDbtx, mockQuerier), mockUserAccountService) mockIsUserInAccount(mockUserAccountService, true) mockUserAccountCalls(mockUserAccountService, true, uuid.NewString()) + mockDbtx.On("Begin", mock.Anything).Return(mockTx, nil) + mockTx.On("Commit", mock.Anything).Return(nil) + mockTx.On("Rollback", mock.Anything).Return(nil) + user := db_queries.NeosyncApiUser{ + ID: newPgUuid(t), + UserType: 1, + } + mockQuerier.On("CreateMachineUser", mock.Anything, mock.Anything, mock.Anything). + Return(user, nil) rawData := db_queries.NeosyncApiAccountApiKey{ ID: newPgUuid(t), AccountID: newPgUuid(t), @@ -184,6 +194,7 @@ func Test_Service_CreateAccountApiKey(t *testing.T) { UpdatedAt: pgtype.Timestamp{Time: time.Now(), Valid: true}, ExpiresAt: pgtype.Timestamp{Time: time.Now().Add(24 * time.Hour), Valid: true}, KeyName: "foo", + UserID: user.ID, } mockQuerier.On("CreateAccountApiKey", mock.Anything, mock.Anything, mock.Anything). Return(rawData, nil) From efc37fe67c783a7677444c822d36eeb6c9c8d4aa Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:23:43 +0000 Subject: [PATCH 6/7] adds basic nucleus db api key test --- backend/internal/nucleusdb/api-keys_test.go | 50 +++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 backend/internal/nucleusdb/api-keys_test.go diff --git a/backend/internal/nucleusdb/api-keys_test.go b/backend/internal/nucleusdb/api-keys_test.go new file mode 100644 index 0000000000..1e19d135e7 --- /dev/null +++ b/backend/internal/nucleusdb/api-keys_test.go @@ -0,0 +1,50 @@ +package nucleusdb + +import ( + "context" + "testing" + + "github.com/google/uuid" + "github.com/jackc/pgx/v5/pgtype" + db_queries "github.com/nucleuscloud/neosync/backend/gen/go/db" + "github.com/stretchr/testify/mock" + "github.com/zeebo/assert" +) + +func Test_CreateAccountApiKey(t *testing.T) { + dbtxMock := NewMockDBTX(t) + querierMock := db_queries.NewMockQuerier(t) + mockTx := new(MockTx) + + service := New(dbtxMock, querierMock) + dbtxMock.On("Begin", mock.Anything).Return(mockTx, nil) + mockTx.On("Commit", mock.Anything).Return(nil) + mockTx.On("Rollback", mock.Anything).Return(nil) + user := db_queries.NeosyncApiUser{ + ID: newPgUuid(t), + UserType: 1, + } + querierMock.On("CreateMachineUser", mock.Anything, mock.Anything). + Return(user, nil) + apiKeyUuid := newPgUuid(t) + querierMock.On("CreateAccountApiKey", mock.Anything, mock.Anything, mock.Anything). + Return(db_queries.NeosyncApiAccountApiKey{ + ID: apiKeyUuid, + }, nil) + + newApiKey, err := service.CreateAccountApikey( + context.Background(), + &CreateAccountApiKeyRequest{}, + ) + assert.NoError(t, err) + assert.NotNil(t, newApiKey) + assert.Equal(t, newApiKey.ID, apiKeyUuid) +} + +func newPgUuid(t *testing.T) pgtype.UUID { + t.Helper() + newuuid := uuid.NewString() + val, err := ToUuid(newuuid) + assert.NoError(t, err) + return val +} From 85d5d1f68d3006da4bf4a0669ea4830e13916873 Mon Sep 17 00:00:00 2001 From: Nick Z <2420177+nickzelei@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:36:17 +0000 Subject: [PATCH 7/7] wires up user id to api keys --- .../gen/go/protos/mgmt/v1alpha1/api_key.pb.go | 181 +++++++++--------- .../mgmt/v1alpha1/api_key.pb.validate.go | 2 + .../internal/cmds/mgmt/serve/connect/cmd.go | 47 ++++- backend/internal/dtomaps/api-keys.go | 1 + backend/protos/mgmt/v1alpha1/api_key.proto | 1 + .../mgmt/v1alpha1/api_key_pb.ts | 6 + frontend/package.json | 2 +- 7 files changed, 152 insertions(+), 88 deletions(-) diff --git a/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.go b/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.go index d17c289840..c6a4b31ee5 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.go @@ -147,6 +147,7 @@ type AccountApiKey struct { UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // key_value is only returned on initial creation or when it is regenerated KeyValue *string `protobuf:"bytes,8,opt,name=key_value,json=keyValue,proto3,oneof" json:"key_value,omitempty"` + UserId string `protobuf:"bytes,9,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` } func (x *AccountApiKey) Reset() { @@ -237,6 +238,13 @@ func (x *AccountApiKey) GetKeyValue() string { return "" } +func (x *AccountApiKey) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + type GetAccountApiKeysRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -639,7 +647,7 @@ var file_mgmt_v1alpha1_api_key_proto_rawDesc = []byte{ 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x61, 0x70, 0x69, 0x4b, 0x65, - 0x79, 0x22, 0xc0, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, + 0x79, 0x22, 0xd9, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, @@ -658,95 +666,96 @@ var file_mgmt_v1alpha1_api_key_proto_rawDesc = []byte{ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x22, 0x43, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x09, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x54, 0x0a, 0x19, 0x47, 0x65, 0x74, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, - 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x22, - 0x33, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, - 0x52, 0x02, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x35, 0x0a, 0x07, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, + 0x0c, 0x0a, 0x0a, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x43, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, + 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0a, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x49, 0x64, 0x22, 0x54, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x37, 0x0a, 0x08, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, - 0x06, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x22, 0x86, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x4a, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, - 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0f, 0xba, 0x48, 0x0c, 0xb2, 0x01, 0x09, 0x4a, 0x05, 0x08, 0x80, - 0xe7, 0x84, 0x0f, 0x40, 0x01, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, - 0x22, 0x58, 0x0a, 0x1f, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, - 0x65, 0x79, 0x52, 0x06, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x22, 0x36, 0x0a, 0x1a, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, - 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xbc, 0x04, 0x0a, 0x0d, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x27, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, - 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, - 0x10, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, - 0x79, 0x12, 0x26, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x07, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x33, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x51, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x07, 0x61, 0x70, 0x69, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, + 0x22, 0x86, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4a, 0x0a, + 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0f, 0xba, + 0x48, 0x0c, 0xb2, 0x01, 0x09, 0x4a, 0x05, 0x08, 0x80, 0xe7, 0x84, 0x0f, 0x40, 0x01, 0x52, 0x09, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x58, 0x0a, 0x1f, 0x52, 0x65, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, + 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x07, + 0x61, 0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x61, 0x70, 0x69, + 0x4b, 0x65, 0x79, 0x22, 0x36, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xbc, 0x04, 0x0a, 0x0d, 0x41, + 0x70, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x11, + 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, + 0x73, 0x12, 0x27, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x67, 0x6d, 0x74, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x2e, 0x6d, 0x67, - 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x17, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, - 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x6e, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, + 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x65, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0xc7, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0b, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6e, 0x75, 0x63, 0x6c, 0x65, 0x75, 0x73, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6e, - 0x65, 0x6f, 0x73, 0x79, 0x6e, 0x63, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x67, - 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d, 0x67, 0x6d, - 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x67, 0x6d, 0x74, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0d, - 0x4d, 0x67, 0x6d, 0x74, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x0d, - 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x19, - 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x67, 0x6d, 0x74, - 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, + 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, + 0x69, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, + 0x17, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x12, 0x2d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x13, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, + 0x12, 0x29, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, + 0x69, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x67, + 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xc7, 0x01, 0x0a, 0x11, 0x63, 0x6f, + 0x6d, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, + 0x0b, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x75, 0x63, 0x6c, 0x65, + 0x75, 0x73, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6e, 0x65, 0x6f, 0x73, 0x79, 0x6e, 0x63, 0x2f, + 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x67, 0x6d, 0x74, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0xa2, 0x02, 0x03, 0x4d, 0x58, 0x58, 0xaa, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x2e, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x0d, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x19, 0x4d, 0x67, 0x6d, 0x74, 0x5c, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x67, 0x6d, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.validate.go b/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.validate.go index 7b787018b5..dcb7f4b936 100644 --- a/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.validate.go +++ b/backend/gen/go/protos/mgmt/v1alpha1/api_key.pb.validate.go @@ -392,6 +392,8 @@ func (m *AccountApiKey) validate(all bool) error { } } + // no validation rules for UserId + if m.KeyValue != nil { // no validation rules for KeyValue } diff --git a/backend/internal/cmds/mgmt/serve/connect/cmd.go b/backend/internal/cmds/mgmt/serve/connect/cmd.go index 3b57beb40c..544e509e26 100644 --- a/backend/internal/cmds/mgmt/serve/connect/cmd.go +++ b/backend/internal/cmds/mgmt/serve/connect/cmd.go @@ -103,9 +103,13 @@ func serve(ctx context.Context) error { if schemaDir == "" { return errors.New("must provide DB_SCHEMA_DIR env var to run auto db migrations") } + dbMigConfig, err := getDbMigrationConfig() + if err != nil { + return err + } if err := up_cmd.Up( ctx, - nucleusdb.GetDbUrl(dbconfig), + nucleusdb.GetDbUrl(dbMigConfig), schemaDir, logger, ); err != nil { @@ -283,6 +287,47 @@ func getDbConfig() (*nucleusdb.ConnectConfig, error) { sslMode = "disable" } + return &nucleusdb.ConnectConfig{ + Host: dbHost, + Port: dbPort, + Database: dbName, + User: dbUser, + Pass: dbPass, + SslMode: &sslMode, + }, nil +} + +func getDbMigrationConfig() (*nucleusdb.ConnectConfig, error) { + dbHost := viper.GetString("DB_HOST") + if dbHost == "" { + return nil, fmt.Errorf("must provide DB_HOST in environment") + } + + dbPort := viper.GetInt("DB_PORT") + if dbPort == 0 { + return nil, fmt.Errorf("must provide DB_PORT in environment") + } + + dbName := viper.GetString("DB_NAME") + if dbName == "" { + return nil, fmt.Errorf("must provide DB_NAME in environment") + } + + dbUser := viper.GetString("DB_USER") + if dbUser == "" { + return nil, fmt.Errorf("must provide DB_USER in environment") + } + + dbPass := viper.GetString("DB_PASS") + if dbPass == "" { + return nil, fmt.Errorf("must provide DB_PASS in environment") + } + + sslMode := "require" + if viper.IsSet("DB_SSL_DISABLE") && viper.GetBool("DB_SSL_DISABLE") { + sslMode = "disable" + } + var migrationsTable *string if viper.IsSet("DB_MIGRATIONS_TABLE") { table := viper.GetString("DB_MIGRATIONS_TABLE") diff --git a/backend/internal/dtomaps/api-keys.go b/backend/internal/dtomaps/api-keys.go index 948a86a047..f7e2ebd61f 100644 --- a/backend/internal/dtomaps/api-keys.go +++ b/backend/internal/dtomaps/api-keys.go @@ -20,5 +20,6 @@ func ToAccountApiKeyDto( UpdatedById: nucleusdb.UUIDString(input.UpdatedByID), UpdatedAt: timestamppb.New(input.UpdatedAt.Time), KeyValue: cleartextKeyValue, + UserId: nucleusdb.UUIDString(input.UserID), } } diff --git a/backend/protos/mgmt/v1alpha1/api_key.proto b/backend/protos/mgmt/v1alpha1/api_key.proto index 639195f50b..21118d4036 100644 --- a/backend/protos/mgmt/v1alpha1/api_key.proto +++ b/backend/protos/mgmt/v1alpha1/api_key.proto @@ -28,6 +28,7 @@ message AccountApiKey { google.protobuf.Timestamp updated_at = 7; /* key_value is only returned on initial creation or when it is regenerated */ optional string key_value = 8; + string user_id = 9; } message GetAccountApiKeysRequest { diff --git a/frontend/neosync-api-client/mgmt/v1alpha1/api_key_pb.ts b/frontend/neosync-api-client/mgmt/v1alpha1/api_key_pb.ts index 70c924f5d6..11d07f3006 100644 --- a/frontend/neosync-api-client/mgmt/v1alpha1/api_key_pb.ts +++ b/frontend/neosync-api-client/mgmt/v1alpha1/api_key_pb.ts @@ -140,6 +140,11 @@ export class AccountApiKey extends Message { */ keyValue?: string; + /** + * @generated from field: string user_id = 9; + */ + userId = ""; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -156,6 +161,7 @@ export class AccountApiKey extends Message { { no: 6, name: "updated_by_id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 7, name: "updated_at", kind: "message", T: Timestamp }, { no: 8, name: "key_value", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 9, name: "user_id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): AccountApiKey { diff --git a/frontend/package.json b/frontend/package.json index 250b0ee4d6..ea35d4afdd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "next dev -p 3001", + "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint",