From a7878c9351d4b259d68818f3936c391c7e8666e1 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Tue, 12 Nov 2024 22:38:20 +0530 Subject: [PATCH 01/49] add users namespace in settings --- config/settings/common_settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/config/settings/common_settings.py b/config/settings/common_settings.py index 2fda29f914..bf7b9494aa 100644 --- a/config/settings/common_settings.py +++ b/config/settings/common_settings.py @@ -81,6 +81,7 @@ def pipe_delim(pipe_string): 'mathesar.rpc.tables', 'mathesar.rpc.tables.metadata', 'mathesar.rpc.tables.privileges', + 'mathesar.rpc.users' ] TEMPLATES = [ From f2da5f65700a5c0b4007589f0a173e0bafe219a9 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Wed, 13 Nov 2024 20:33:27 +0530 Subject: [PATCH 02/49] add utility functions for getting, listing, adding, updating and deleting users --- mathesar/utils/users.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 mathesar/utils/users.py diff --git a/mathesar/utils/users.py b/mathesar/utils/users.py new file mode 100644 index 0000000000..da5f750732 --- /dev/null +++ b/mathesar/utils/users.py @@ -0,0 +1,41 @@ +from django.db.models import F + +from mathesar.models import User + + +def get_user_info(user_id): + return User.objects.get(id=user_id) + + +def list_user_info(): + return User.objects.all() + + +def add_user(user_def): + return User.objects.create( + username=user_def["username"], + password=user_def["password"], + is_superuser=user_def["is_superuser"], + email=user_def.get("email", ""), + full_name=user_def.get("full_name", ""), + short_name=user_def.get("short_name", ""), + display_language=user_def.get("display_language", "en"), + ) + + +def update_user_info(user_id, user_info): + if not get_user_info(user_id).is_superuser: + user_info.pop("is_superuser") + User.objects.filter(id=user_id).update( + username=user_info.get("username", F("username")), + is_superuser=user_info.get("is_superuser", F("is_superuser")), + email=user_info.get("email", F("email")), + full_name=user_info.get("full_name", F("full_name")), + short_name=user_info.get("short_name", F("short_name")), + display_language=user_info.get("display_language", F("display_language")) + ) + return get_user_info(user_id) + + +def delete_user(user_id): + User.objects.get(id=user_id).delete() From cf013c1ad2bd720632024b3cdb7305018c44b17b Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Wed, 13 Nov 2024 20:33:55 +0530 Subject: [PATCH 03/49] add RPC functions for getting, listing, adding, updating and deleting users --- mathesar/rpc/users.py | 104 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 mathesar/rpc/users.py diff --git a/mathesar/rpc/users.py b/mathesar/rpc/users.py new file mode 100644 index 0000000000..a65e4d9250 --- /dev/null +++ b/mathesar/rpc/users.py @@ -0,0 +1,104 @@ +""" +Classes and functions exposed to the RPC endpoint for managing mathesar users. +""" +from typing import Optional, TypedDict +from modernrpc.core import rpc_method, REQUEST_KEY +from modernrpc.auth.basic import http_basic_auth_login_required, http_basic_auth_superuser_required + +from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions +from modernrpc.exceptions import AuthenticationFailed +from mathesar.utils.users import ( + get_user_info, + list_user_info, + add_user, + update_user_info, + delete_user +) + + +class UserInfo(TypedDict): + id: int + username: str + is_superuser: bool + email: str + full_name: str + short_name: str + display_language: str + + @classmethod + def from_model(cls, model): + return cls( + id=model.id, + username=model.username, + is_superuser=model.is_superuser, + email=model.email, + full_name=model.full_name, + short_name=model.short_name, + display_language=model.display_language + ) + + +class UserDef(TypedDict): + username: str + password: str + is_superuser: bool + email: Optional[str] + full_name: Optional[str] + short_name: Optional[str] + display_language: Optional[str] + + +class SettableUserInfo(TypedDict): + username: Optional[str] + is_superuser: Optional[bool] + email: Optional[str] + full_name: Optional[str] + short_name: Optional[str] + display_language: Optional[str] + + +@rpc_method(name="users.get") +@http_basic_auth_login_required +@handle_rpc_exceptions +def get(*, user_id: int) -> UserInfo: + user = get_user_info(user_id) + return UserInfo.from_model(user) + + +@rpc_method(name='users.list') +@http_basic_auth_login_required +@handle_rpc_exceptions +def list() -> list[UserInfo]: + users = list_user_info() + return [UserInfo.from_model(user) for user in users] + + +@rpc_method(name='users.add') +@http_basic_auth_superuser_required +@handle_rpc_exceptions +def add(*, user_def: UserDef) -> UserInfo: + user = add_user(user_def) + return UserInfo.from_model(user) + + +@rpc_method(name='users.patch') +@http_basic_auth_login_required +@handle_rpc_exceptions +def patch( + *, + user_id: int, + user_info: SettableUserInfo, + **kwargs +) -> UserInfo: + user = kwargs.get(REQUEST_KEY).user + if not (user.id == user_id or user.is_superuser): + raise AuthenticationFailed('users.patch') + updated_user_info = update_user_info(user_id, user_info) + return UserInfo.from_model(updated_user_info) + + +@rpc_method(name='users.delete') +@http_basic_auth_superuser_required +@handle_rpc_exceptions +def delete(*, user_id: int) -> None: + delete_user(user_id) From 9e0416d7e74dab676672596f303a6ea7c0c32e03 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Wed, 13 Nov 2024 20:41:25 +0530 Subject: [PATCH 04/49] reorganise endpoints --- mathesar/rpc/users.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/mathesar/rpc/users.py b/mathesar/rpc/users.py index a65e4d9250..2d44df2d00 100644 --- a/mathesar/rpc/users.py +++ b/mathesar/rpc/users.py @@ -57,6 +57,21 @@ class SettableUserInfo(TypedDict): display_language: Optional[str] +@rpc_method(name='users.add') +@http_basic_auth_superuser_required +@handle_rpc_exceptions +def add(*, user_def: UserDef) -> UserInfo: + user = add_user(user_def) + return UserInfo.from_model(user) + + +@rpc_method(name='users.delete') +@http_basic_auth_superuser_required +@handle_rpc_exceptions +def delete(*, user_id: int) -> None: + delete_user(user_id) + + @rpc_method(name="users.get") @http_basic_auth_login_required @handle_rpc_exceptions @@ -68,19 +83,11 @@ def get(*, user_id: int) -> UserInfo: @rpc_method(name='users.list') @http_basic_auth_login_required @handle_rpc_exceptions -def list() -> list[UserInfo]: +def list_() -> list[UserInfo]: users = list_user_info() return [UserInfo.from_model(user) for user in users] -@rpc_method(name='users.add') -@http_basic_auth_superuser_required -@handle_rpc_exceptions -def add(*, user_def: UserDef) -> UserInfo: - user = add_user(user_def) - return UserInfo.from_model(user) - - @rpc_method(name='users.patch') @http_basic_auth_login_required @handle_rpc_exceptions @@ -95,10 +102,3 @@ def patch( raise AuthenticationFailed('users.patch') updated_user_info = update_user_info(user_id, user_info) return UserInfo.from_model(updated_user_info) - - -@rpc_method(name='users.delete') -@http_basic_auth_superuser_required -@handle_rpc_exceptions -def delete(*, user_id: int) -> None: - delete_user(user_id) From ca3325cbf069caf5cbc94e3e9def88e0951a33c4 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Wed, 13 Nov 2024 20:41:40 +0530 Subject: [PATCH 05/49] add endpoint tests --- mathesar/tests/rpc/test_endpoints.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/mathesar/tests/rpc/test_endpoints.py b/mathesar/tests/rpc/test_endpoints.py index 183ed0de50..210a83472b 100644 --- a/mathesar/tests/rpc/test_endpoints.py +++ b/mathesar/tests/rpc/test_endpoints.py @@ -19,6 +19,7 @@ from mathesar.rpc import schemas from mathesar.rpc import servers from mathesar.rpc import tables +from mathesar.rpc import users METHODS = [ ( @@ -413,6 +414,32 @@ tables.metadata.set_, "tables.metadata.set", [user_is_authenticated] + ), + + ( + users.add, + "users.add", + [user_is_superuser] + ), + ( + users.delete, + "users.delete", + [user_is_superuser] + ), + ( + users.get, + "users.get", + [user_is_authenticated] + ), + ( + users.list_, + "users.list", + [user_is_authenticated] + ), + ( + users.patch, + "users.patch", + [user_is_authenticated] ) ] From e7e449e79d8fcbe651944713072730563ee31c95 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 02:16:28 +0530 Subject: [PATCH 06/49] manage imports in users.py --- mathesar/rpc/users.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mathesar/rpc/users.py b/mathesar/rpc/users.py index 2d44df2d00..a6d294d57e 100644 --- a/mathesar/rpc/users.py +++ b/mathesar/rpc/users.py @@ -3,7 +3,10 @@ """ from typing import Optional, TypedDict from modernrpc.core import rpc_method, REQUEST_KEY -from modernrpc.auth.basic import http_basic_auth_login_required, http_basic_auth_superuser_required +from modernrpc.auth.basic import ( + http_basic_auth_login_required, + http_basic_auth_superuser_required +) from mathesar.rpc.exceptions.handlers import handle_rpc_exceptions from modernrpc.exceptions import AuthenticationFailed From 78a8e8c777528a61dede8e9f5da8d0913b91ed52 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 02:18:32 +0530 Subject: [PATCH 07/49] create a users const for rpc methods --- mathesar_ui/src/api/rpc/users.ts | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 mathesar_ui/src/api/rpc/users.ts diff --git a/mathesar_ui/src/api/rpc/users.ts b/mathesar_ui/src/api/rpc/users.ts new file mode 100644 index 0000000000..940f223585 --- /dev/null +++ b/mathesar_ui/src/api/rpc/users.ts @@ -0,0 +1,33 @@ +import { rpcMethodTypeContainer } from '@mathesar/packages/json-rpc-client-builder'; +import type { Language } from '@mathesar/i18n/languages/utils'; + +export interface UnsavedUser { + full_name: string | null; + email: string | null; + username: string; + password: string; + display_language: Language; +} + +/* export interface User extends Omit { + readonly id: number; + readonly is_superuser: boolean; +} */ + +interface UserInfo {} + +export const users = { + list: rpcMethodTypeContainer< + {}, + UserInfo[] + >(), + get: rpcMethodTypeContainer<{ user_id: number }, UserInfo>(), + add: rpcMethodTypeContainer< + {}, + UserInfo + >(), + delete: rpcMethodTypeContainer<{ user_id: number }, void>(), + /* patch: rpcMethodTypeContainer< + { user_id: number, user_info: } + >(), */ +} From 5197017b7cc753c10902a5bfdeb9f93bbc29051c Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 02:21:39 +0530 Subject: [PATCH 08/49] add users import in buildRpcApi --- mathesar_ui/src/api/rpc/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mathesar_ui/src/api/rpc/index.ts b/mathesar_ui/src/api/rpc/index.ts index 16510638df..933e8b2d4c 100644 --- a/mathesar_ui/src/api/rpc/index.ts +++ b/mathesar_ui/src/api/rpc/index.ts @@ -13,6 +13,7 @@ import { roles } from './roles'; import { schemas } from './schemas'; import { servers } from './servers'; import { tables } from './tables'; +import { users } from './users'; /** Mathesar's JSON-RPC API */ export const api = buildRpcApi({ @@ -30,5 +31,6 @@ export const api = buildRpcApi({ schemas, servers, tables, + users, }, }); From 243cbab2f300a003148785293371fdffa03ec1d6 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 02:23:24 +0530 Subject: [PATCH 09/49] transition users delete endpoint to RPC in the frontend --- mathesar_ui/src/stores/users.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mathesar_ui/src/stores/users.ts b/mathesar_ui/src/stores/users.ts index 631eadbc22..fb07b4e9ab 100644 --- a/mathesar_ui/src/stores/users.ts +++ b/mathesar_ui/src/stores/users.ts @@ -3,6 +3,7 @@ import { getContext, setContext } from 'svelte'; import { type Writable, get, writable } from 'svelte/store'; +import { api } from '@mathesar/api/rpc'; import userApi, { type UnsavedUser, type User } from '@mathesar/api/rest/users'; import type { RequestStatus } from '@mathesar/api/rest/utils/requestUtils'; import { getErrorMessage } from '@mathesar/utils/errors'; @@ -128,7 +129,7 @@ class WritableUsersStore { this.requestStatus.set({ state: 'processing', }); - await userApi.delete(userId); + await api.users.delete({ user_id: userId }).run(); this.users.update((users) => users.filter((user) => user.id !== userId)); this.count.update((count) => count - 1); this.requestStatus.set({ From 171ac96a88c102049a6f15537b879e01e8a493dd Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 03:15:06 +0530 Subject: [PATCH 10/49] use users.add RPC endpoint on the frontend --- mathesar_ui/src/api/rpc/users.ts | 15 ++++++--------- .../src/systems/users/UserDetailsForm.svelte | 11 +++++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mathesar_ui/src/api/rpc/users.ts b/mathesar_ui/src/api/rpc/users.ts index 940f223585..5983355bb2 100644 --- a/mathesar_ui/src/api/rpc/users.ts +++ b/mathesar_ui/src/api/rpc/users.ts @@ -9,22 +9,19 @@ export interface UnsavedUser { display_language: Language; } -/* export interface User extends Omit { +export interface User extends Omit { readonly id: number; readonly is_superuser: boolean; -} */ - -interface UserInfo {} +} export const users = { list: rpcMethodTypeContainer< - {}, - UserInfo[] + void, User[] >(), - get: rpcMethodTypeContainer<{ user_id: number }, UserInfo>(), + get: rpcMethodTypeContainer<{ user_id: number }, User>(), add: rpcMethodTypeContainer< - {}, - UserInfo + {user_def: UnsavedUser}, + User >(), delete: rpcMethodTypeContainer<{ user_id: number }, void>(), /* patch: rpcMethodTypeContainer< diff --git a/mathesar_ui/src/systems/users/UserDetailsForm.svelte b/mathesar_ui/src/systems/users/UserDetailsForm.svelte index 71ae56620f..16a017e8b2 100644 --- a/mathesar_ui/src/systems/users/UserDetailsForm.svelte +++ b/mathesar_ui/src/systems/users/UserDetailsForm.svelte @@ -3,6 +3,7 @@ import { _ } from 'svelte-i18n'; import type { UnionToIntersection } from 'type-fest'; + import { api } from '@mathesar/api/rpc'; import userApi, { type User } from '@mathesar/api/rest/users'; import { extractDetailedFieldBasedErrors } from '@mathesar/api/rest/utils/errors'; import { @@ -75,10 +76,12 @@ }; if (isNewUser && hasProperty(formValues, 'password')) { - const newUser = await userApi.add({ - ...request, - password: formValues.password, - }); + const newUser = await api.users.add({ + user_def: { + ...request, + password: formValues.password, + }, + }).run(); dispatch('create', newUser); return; } From c5f64239ed401504fc62b65245ee0228d565ccab Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 23:39:19 +0530 Subject: [PATCH 11/49] fix a bug in patch logic --- mathesar/rpc/users.py | 6 +++++- mathesar/utils/users.py | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mathesar/rpc/users.py b/mathesar/rpc/users.py index a6d294d57e..fda41ce693 100644 --- a/mathesar/rpc/users.py +++ b/mathesar/rpc/users.py @@ -103,5 +103,9 @@ def patch( user = kwargs.get(REQUEST_KEY).user if not (user.id == user_id or user.is_superuser): raise AuthenticationFailed('users.patch') - updated_user_info = update_user_info(user_id, user_info) + updated_user_info = update_user_info( + user_id, + user_info, + requesting_user=user + ) return UserInfo.from_model(updated_user_info) diff --git a/mathesar/utils/users.py b/mathesar/utils/users.py index da5f750732..151fcbe00e 100644 --- a/mathesar/utils/users.py +++ b/mathesar/utils/users.py @@ -23,9 +23,9 @@ def add_user(user_def): ) -def update_user_info(user_id, user_info): - if not get_user_info(user_id).is_superuser: - user_info.pop("is_superuser") +def update_user_info(user_id, user_info, requesting_user): + if not requesting_user.is_superuser: + user_info.pop("is_superuser", None) User.objects.filter(id=user_id).update( username=user_info.get("username", F("username")), is_superuser=user_info.get("is_superuser", F("is_superuser")), From b36ca380f3300c164c0531b8a02b0ffda84c6cb4 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 23:41:06 +0530 Subject: [PATCH 12/49] define patch rpc in frontend --- mathesar_ui/src/api/rpc/users.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/mathesar_ui/src/api/rpc/users.ts b/mathesar_ui/src/api/rpc/users.ts index 5983355bb2..75fc3fc848 100644 --- a/mathesar_ui/src/api/rpc/users.ts +++ b/mathesar_ui/src/api/rpc/users.ts @@ -18,13 +18,14 @@ export const users = { list: rpcMethodTypeContainer< void, User[] >(), - get: rpcMethodTypeContainer<{ user_id: number }, User>(), + get: rpcMethodTypeContainer<{ user_id: User['id'] }, User>(), add: rpcMethodTypeContainer< - {user_def: UnsavedUser}, + { user_def: UnsavedUser }, User >(), - delete: rpcMethodTypeContainer<{ user_id: number }, void>(), - /* patch: rpcMethodTypeContainer< - { user_id: number, user_info: } - >(), */ -} + delete: rpcMethodTypeContainer<{ user_id: User['id'] }, void>(), + patch: rpcMethodTypeContainer< + { user_id: User['id'], user_info: Partial>}, + User + >(), +}; From 3cc4f5cf3a58c9492bb2b4e924467c90fd4c169c Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 23:43:27 +0530 Subject: [PATCH 13/49] implement users.list for users stores --- mathesar_ui/src/stores/users.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/mathesar_ui/src/stores/users.ts b/mathesar_ui/src/stores/users.ts index fb07b4e9ab..2c49f6a721 100644 --- a/mathesar_ui/src/stores/users.ts +++ b/mathesar_ui/src/stores/users.ts @@ -3,9 +3,9 @@ import { getContext, setContext } from 'svelte'; import { type Writable, get, writable } from 'svelte/store'; -import { api } from '@mathesar/api/rpc'; -import userApi, { type UnsavedUser, type User } from '@mathesar/api/rest/users'; import type { RequestStatus } from '@mathesar/api/rest/utils/requestUtils'; +import { api } from '@mathesar/api/rpc'; +import { type UnsavedUser, type User } from '@mathesar/api/rpc/users'; import { getErrorMessage } from '@mathesar/utils/errors'; import type { MakeWritablePropertiesReadable } from '@mathesar/utils/typeUtils'; @@ -76,7 +76,7 @@ class WritableUsersStore { readonly count = writable(0); - private request: ReturnType | undefined; + private request: ReturnType | undefined; constructor() { void this.fetchUsers(); @@ -86,11 +86,10 @@ class WritableUsersStore { * @throws Error */ private async fetchUsersSilently() { - this.request?.cancel(); - this.request = userApi.list(); - const response = await this.request; - this.users.set(response.results.map((user) => new UserModel(user))); - this.count.set(response.count); + this.request = api.users.list(); + const response = await this.request.run(); + this.users.set(response.map((user) => new UserModel(user))); + this.count.set(response.length); } async fetchUsers() { @@ -116,8 +115,8 @@ class WritableUsersStore { return get(this.users).find((user) => user.id === userId); } if (requestStatus?.state === 'processing') { - const result = await this.request; - const user = result?.results.find((entry) => entry.id === userId); + const result = await this.request?.run(); + const user = result?.find((entry) => entry.id === userId); if (user) { return new UserModel(user); } From c8c1cf9d02a2ecc70434c9a60658854d3aef2283 Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 23:46:57 +0530 Subject: [PATCH 14/49] add users.list rpc endpoint for db settings route --- mathesar_ui/src/contexts/DatabaseSettingsRouteContext.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mathesar_ui/src/contexts/DatabaseSettingsRouteContext.ts b/mathesar_ui/src/contexts/DatabaseSettingsRouteContext.ts index 810e4ed0d0..08621cd3bc 100644 --- a/mathesar_ui/src/contexts/DatabaseSettingsRouteContext.ts +++ b/mathesar_ui/src/contexts/DatabaseSettingsRouteContext.ts @@ -1,6 +1,7 @@ import { type Readable, derived } from 'svelte/store'; -import userApi, { type User } from '@mathesar/api/rest/users'; +import { api } from '@mathesar/api/rpc'; +import { type User } from '@mathesar/api/rpc/users'; import type { Collaborator } from '@mathesar/models/Collaborator'; import type { ConfiguredRole } from '@mathesar/models/ConfiguredRole'; import type { Database } from '@mathesar/models/Database'; @@ -21,14 +22,14 @@ export type CombinedLoginRole = { // TODO: Make CancellablePromise chainable const getUsersPromise = () => { - const promise = userApi.list(); + const promise = api.users.list().run(); return new CancellablePromise>( (resolve, reject) => { promise .then( (response) => resolve( - new ImmutableMap(response.results.map((user) => [user.id, user])), + new ImmutableMap(response.map((user) => [user.id, user])), ), (err) => reject(err), ) From c24c2f454b19bc7e7a1be577c7db1540d37dc3cc Mon Sep 17 00:00:00 2001 From: Anish Umale Date: Thu, 14 Nov 2024 23:47:33 +0530 Subject: [PATCH 15/49] update imports and reorder them --- mathesar_ui/src/pages/admin-users/NewUserPage.svelte | 2 +- .../settings/collaborators/AddCollaboratorModal.svelte | 2 +- .../collaborators/EditRoleForCollaboratorModal.svelte | 2 +- mathesar_ui/src/stores/userProfile.ts | 2 +- mathesar_ui/src/systems/users/UserDetailsForm.svelte | 6 +++--- mathesar_ui/src/utils/preloadData.ts | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mathesar_ui/src/pages/admin-users/NewUserPage.svelte b/mathesar_ui/src/pages/admin-users/NewUserPage.svelte index 9d17a8b589..778e02508c 100644 --- a/mathesar_ui/src/pages/admin-users/NewUserPage.svelte +++ b/mathesar_ui/src/pages/admin-users/NewUserPage.svelte @@ -2,7 +2,7 @@ import { _ } from 'svelte-i18n'; import { router } from 'tinro'; - import type { User } from '@mathesar/api/rest/users'; + import type { User } from '@mathesar/api/rpc/users'; import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte'; import FormBox from '@mathesar/components/form/FormBox.svelte'; import { iconAddUser } from '@mathesar/icons'; diff --git a/mathesar_ui/src/pages/database/settings/collaborators/AddCollaboratorModal.svelte b/mathesar_ui/src/pages/database/settings/collaborators/AddCollaboratorModal.svelte index 0be74c4447..df0f53275d 100644 --- a/mathesar_ui/src/pages/database/settings/collaborators/AddCollaboratorModal.svelte +++ b/mathesar_ui/src/pages/database/settings/collaborators/AddCollaboratorModal.svelte @@ -1,7 +1,7 @@