refactor(editor): Migrate users.store to composition API (no-changelog) (#9960)

This commit is contained in:
Ricardo Espinoza
2024-07-08 10:21:03 -04:00
committed by GitHub
parent 4ff4534454
commit f40f9b0287
11 changed files with 407 additions and 370 deletions

View File

@@ -1376,13 +1376,6 @@ export interface IVersionsState {
currentVersion: IVersion | undefined; currentVersion: IVersion | undefined;
} }
export interface IUsersState {
initialized: boolean;
currentUserId: null | string;
users: { [userId: string]: IUser };
currentUserCloudInfo: Cloud.UserAccount | null;
}
export interface IWorkflowsState { export interface IWorkflowsState {
currentWorkflowExecutions: ExecutionSummary[]; currentWorkflowExecutions: ExecutionSummary[];
activeWorkflowExecution: ExecutionSummary | null; activeWorkflowExecution: ExecutionSummary | null;

View File

@@ -119,7 +119,7 @@ export default defineComponent({
...mapStores(useUsersStore, useProjectsStore), ...mapStores(useUsersStore, useProjectsStore),
userToDelete(): IUser | null { userToDelete(): IUser | null {
if (!this.activeId) return null; if (!this.activeId) return null;
return this.usersStore.getUserById(this.activeId); return this.usersStore.usersById[this.activeId];
}, },
isPending(): boolean { isPending(): boolean {
return this.userToDelete ? this.userToDelete && !this.userToDelete.firstName : false; return this.userToDelete ? this.userToDelete && !this.userToDelete.firstName : false;

View File

@@ -254,7 +254,7 @@ const onSetupClick = async () => {
const getMfaQR = async () => { const getMfaQR = async () => {
try { try {
const response = await userStore.getMfaQR(); const response = await userStore.fetchMfaQR();
qrCode.value = response.qrCode; qrCode.value = response.qrCode;
secret.value = response.secret; secret.value = response.secret;
recoveryCodes.value = response.recoveryCodes; recoveryCodes.value = response.recoveryCodes;

View File

@@ -69,7 +69,7 @@ const firstLicensedRole = computed(() => projectRoles.value.find((role) => role.
const onAddMember = (userId: string) => { const onAddMember = (userId: string) => {
isDirty.value = true; isDirty.value = true;
const user = usersStore.getUserById(userId); const user = usersStore.usersById[userId];
if (!user) return; if (!user) return;
const { id, firstName, lastName, email } = user; const { id, firstName, lastName, email } = user;

View File

@@ -23,7 +23,7 @@ const initialState = {
}, },
[STORES.USERS]: { [STORES.USERS]: {
currentUserId: 'aaa-bbb', currentUserId: 'aaa-bbb',
users: { usersById: {
'aaa-bbb': { 'aaa-bbb': {
id: 'aaa-bbb', id: 'aaa-bbb',
role: ROLE.Owner, role: ROLE.Owner,

View File

@@ -23,7 +23,7 @@ const pinia = createTestingPinia({
}, },
}, },
[STORES.USERS]: { [STORES.USERS]: {
users: { usersById: {
123: { 123: {
email: 'john@doe.com', email: 'john@doe.com',
firstName: 'John', firstName: 'John',

View File

@@ -23,9 +23,8 @@ describe('V1 Banner', () => {
}); });
it('should render banner with dismiss call if user is owner', () => { it('should render banner with dismiss call if user is owner', () => {
vi.spyOn(usersStore, 'currentUser', 'get').mockReturnValue({ usersStore.usersById = { '1': { role: ROLE.Owner } as IUser };
role: ROLE.Owner, usersStore.currentUserId = '1';
} as IUser);
const { container } = render(V1Banner); const { container } = render(V1Banner);
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();

View File

@@ -45,7 +45,7 @@ function setCurrentUser() {
function resetStores() { function resetStores() {
useSettingsStore().$reset(); useSettingsStore().$reset();
useUsersStore().$reset(); useUsersStore().reset();
} }
function setup() { function setup() {

View File

@@ -1,32 +1,11 @@
import type { IUpdateUserSettingsReqPayload, UpdateGlobalRolePayload } from '@/api/users'; import type { IUpdateUserSettingsReqPayload, UpdateGlobalRolePayload } from '@/api/users';
import { import * as usersApi from '@/api/users';
changePassword,
deleteUser,
getPasswordResetLink,
getUsers,
login,
loginCurrentUser,
logout,
sendForgotPasswordEmail,
setupOwner,
submitPersonalizationSurvey,
updateCurrentUser,
updateCurrentUserPassword,
updateCurrentUserSettings,
updateOtherUserSettings,
validatePasswordToken,
validateSignupToken,
updateGlobalRole,
} from '@/api/users';
import { PERSONALIZATION_MODAL_KEY, STORES, ROLE } from '@/constants'; import { PERSONALIZATION_MODAL_KEY, STORES, ROLE } from '@/constants';
import type { import type {
Cloud, Cloud,
IInviteResponse,
IPersonalizationLatestVersion, IPersonalizationLatestVersion,
IRole,
IUser, IUser,
IUserResponse, IUserResponse,
IUsersState,
CurrentUserResponse, CurrentUserResponse,
InvitableRoleName, InvitableRoleName,
} from '@/Interface'; } from '@/Interface';
@@ -37,344 +16,410 @@ import { usePostHog } from './posthog.store';
import { useSettingsStore } from './settings.store'; import { useSettingsStore } from './settings.store';
import { useUIStore } from './ui.store'; import { useUIStore } from './ui.store';
import { useCloudPlanStore } from './cloudPlan.store'; import { useCloudPlanStore } from './cloudPlan.store';
import { disableMfa, enableMfa, getMfaQR, verifyMfaToken } from '@/api/mfa'; import * as mfaApi from '@/api/mfa';
import { confirmEmail, getCloudUserInfo } from '@/api/cloudPlans'; import * as cloudApi from '@/api/cloudPlans';
import { useRBACStore } from '@/stores/rbac.store'; import { useRBACStore } from '@/stores/rbac.store';
import type { Scope } from '@n8n/permissions'; import type { Scope } from '@n8n/permissions';
import { inviteUsers, acceptInvitation } from '@/api/invitation'; import * as invitationsApi from '@/api/invitation';
import { useNpsSurveyStore } from './npsSurvey.store'; import { useNpsSurveyStore } from './npsSurvey.store';
import { computed, ref } from 'vue';
const isPendingUser = (user: IUserResponse | null) => !!user?.isPending; const _isPendingUser = (user: IUserResponse | null) => !!user?.isPending;
const isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Owner; const _isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Owner;
const isDefaultUser = (user: IUserResponse | null) => isInstanceOwner(user) && isPendingUser(user); const _isDefaultUser = (user: IUserResponse | null) =>
_isInstanceOwner(user) && _isPendingUser(user);
export const useUsersStore = defineStore(STORES.USERS, { export const useUsersStore = defineStore(STORES.USERS, () => {
state: (): IUsersState => ({ const initialized = ref(false);
initialized: false, const currentUserId = ref<string | null>(null);
currentUserId: null, const usersById = ref<Record<string, IUser>>({});
users: {}, const currentUserCloudInfo = ref<Cloud.UserAccount | null>(null);
currentUserCloudInfo: null,
}),
getters: {
allUsers(): IUser[] {
return Object.values(this.users);
},
userActivated(): boolean {
return Boolean(this.currentUser?.settings?.userActivated);
},
currentUser(): IUser | null {
return this.currentUserId ? this.users[this.currentUserId] : null;
},
isDefaultUser(): boolean {
return isDefaultUser(this.currentUser);
},
isInstanceOwner(): boolean {
return isInstanceOwner(this.currentUser);
},
mfaEnabled(): boolean {
return this.currentUser?.mfaEnabled ?? false;
},
getUserById(state) {
return (userId: string): IUser | null => state.users[userId];
},
globalRoleName(): IRole {
return this.currentUser?.role ?? 'default';
},
personalizedNodeTypes(): string[] {
const user = this.currentUser;
if (!user) {
return [];
}
const answers = user.personalizationAnswers; // Stores
if (!answers) {
return [];
}
return getPersonalizedNodeTypes(answers);
},
},
actions: {
async initialize() {
if (this.initialized) {
return;
}
try { const RBACStore = useRBACStore();
await this.loginWithCookie(); const npsSurveyStore = useNpsSurveyStore();
this.initialized = true; const uiStore = useUIStore();
} catch (e) {} const rootStore = useRootStore();
}, const settingsStore = useSettingsStore();
setCurrentUser(user: CurrentUserResponse) { const cloudPlanStore = useCloudPlanStore();
this.addUsers([user]);
this.currentUserId = user.id;
const defaultScopes: Scope[] = []; // Composables
useRBACStore().setGlobalScopes(user.globalScopes || defaultScopes);
usePostHog().init(user.featureFlags);
useNpsSurveyStore().setupNpsSurveyOnLogin(user.id, user.settings);
},
unsetCurrentUser() {
this.currentUserId = null;
this.currentUserCloudInfo = null;
useRBACStore().setGlobalScopes([]);
},
addUsers(users: IUserResponse[]) {
users.forEach((userResponse: IUserResponse) => {
const prevUser = this.users[userResponse.id] || {};
const updatedUser = {
...prevUser,
...userResponse,
};
const user: IUser = {
...updatedUser,
fullName: userResponse.firstName
? `${updatedUser.firstName} ${updatedUser.lastName || ''}`
: undefined,
isDefaultUser: isDefaultUser(updatedUser),
isPendingUser: isPendingUser(updatedUser),
};
this.users = { const postHogStore = usePostHog();
...this.users,
[user.id]: user,
};
});
},
deleteUserById(userId: string): void {
const { [userId]: _, ...users } = this.users;
this.users = users;
},
setPersonalizationAnswers(answers: IPersonalizationLatestVersion): void {
if (!this.currentUser) {
return;
}
this.users = { // Computed
...this.users,
[this.currentUser.id]: { const allUsers = computed(() => Object.values(usersById.value));
...this.currentUser,
personalizationAnswers: answers, const currentUser = computed(() =>
}, currentUserId.value ? usersById.value[currentUserId.value] : null,
);
const userActivated = computed(() => Boolean(currentUser.value?.settings?.userActivated));
const isDefaultUser = computed(() => _isDefaultUser(currentUser.value));
const isInstanceOwner = computed(() => _isInstanceOwner(currentUser.value));
const mfaEnabled = computed(() => currentUser.value?.mfaEnabled ?? false);
const globalRoleName = computed(() => currentUser.value?.role ?? 'default');
const personalizedNodeTypes = computed(() => {
const user = currentUser.value;
if (!user) {
return [];
}
const answers = user.personalizationAnswers;
if (!answers) {
return [];
}
return getPersonalizedNodeTypes(answers);
});
// Methods
const addUsers = (newUsers: IUserResponse[]) => {
newUsers.forEach((userResponse: IUserResponse) => {
const prevUser = usersById.value[userResponse.id] || {};
const updatedUser = {
...prevUser,
...userResponse,
};
const user: IUser = {
...updatedUser,
fullName: userResponse.firstName
? `${updatedUser.firstName} ${updatedUser.lastName || ''}`
: undefined,
isDefaultUser: _isDefaultUser(updatedUser),
isPendingUser: _isPendingUser(updatedUser),
}; };
},
async loginWithCookie(): Promise<void> {
const rootStore = useRootStore();
const user = await loginCurrentUser(rootStore.restApiContext);
if (!user) {
return;
}
this.setCurrentUser(user); usersById.value = {
}, ...usersById.value,
async loginWithCreds(params: { [user.id]: user,
email: string; };
password: string; });
mfaToken?: string; };
mfaRecoveryCode?: string;
}): Promise<void> {
const rootStore = useRootStore();
const user = await login(rootStore.restApiContext, params);
if (!user) {
return;
}
this.setCurrentUser(user); const setCurrentUser = (user: CurrentUserResponse) => {
}, addUsers([user]);
async logout(): Promise<void> { currentUserId.value = user.id;
const rootStore = useRootStore();
await logout(rootStore.restApiContext); const defaultScopes: Scope[] = [];
this.unsetCurrentUser(); RBACStore.setGlobalScopes(user.globalScopes || defaultScopes);
useCloudPlanStore().reset(); postHogStore.init(user.featureFlags);
usePostHog().reset(); npsSurveyStore.setupNpsSurveyOnLogin(user.id, user.settings);
useUIStore().clearBannerStack(); };
useNpsSurveyStore().resetNpsSurveyOnLogOut();
}, const loginWithCookie = async () => {
async createOwner(params: { const user = await usersApi.loginCurrentUser(rootStore.restApiContext);
firstName: string; if (!user) {
lastName: string; return;
email: string; }
password: string;
}): Promise<void> { setCurrentUser(user);
const rootStore = useRootStore(); };
const user = await setupOwner(rootStore.restApiContext, params);
const settingsStore = useSettingsStore(); const initialize = async () => {
if (user) { if (initialized.value) {
this.setCurrentUser(user); return;
settingsStore.stopShowingSetupPage(); }
}
}, try {
async validateSignupToken(params: { await loginWithCookie();
inviteeId: string; initialized.value = true;
inviterId: string; } catch (e) {}
}): Promise<{ inviter: { firstName: string; lastName: string } }> { };
const rootStore = useRootStore();
return await validateSignupToken(rootStore.restApiContext, params); const unsetCurrentUser = () => {
}, currentUserId.value = null;
async acceptInvitation(params: { currentUserCloudInfo.value = null;
inviteeId: string; RBACStore.setGlobalScopes([]);
inviterId: string; };
firstName: string;
lastName: string; const deleteUserById = (userId: string) => {
password: string; const { [userId]: _, ...rest } = usersById.value;
}): Promise<void> { usersById.value = rest;
const rootStore = useRootStore(); };
const user = await acceptInvitation(rootStore.restApiContext, params);
if (user) { const setPersonalizationAnswers = (answers: IPersonalizationLatestVersion) => {
this.setCurrentUser(user); if (!currentUser.value) {
} return;
}, }
async sendForgotPasswordEmail(params: { email: string }): Promise<void> {
const rootStore = useRootStore(); usersById.value = {
await sendForgotPasswordEmail(rootStore.restApiContext, params); ...usersById.value,
}, [currentUser.value.id]: {
async validatePasswordToken(params: { token: string }): Promise<void> { ...currentUser.value,
const rootStore = useRootStore(); personalizationAnswers: answers,
await validatePasswordToken(rootStore.restApiContext, params); },
}, };
async changePassword(params: { };
token: string;
password: string; const loginWithCreds = async (params: {
mfaToken?: string; email: string;
}): Promise<void> { password: string;
const rootStore = useRootStore(); mfaToken?: string;
await changePassword(rootStore.restApiContext, params); mfaRecoveryCode?: string;
}, }) => {
async updateUser(params: { const user = await usersApi.login(rootStore.restApiContext, params);
id: string; if (!user) {
firstName: string; return;
lastName: string; }
email: string;
}): Promise<void> { setCurrentUser(user);
const rootStore = useRootStore(); };
const user = await updateCurrentUser(rootStore.restApiContext, params);
this.addUsers([user]); const logout = async () => {
}, await usersApi.logout(rootStore.restApiContext);
async updateUserSettings(settings: IUpdateUserSettingsReqPayload): Promise<void> { unsetCurrentUser();
const rootStore = useRootStore(); cloudPlanStore.reset();
const updatedSettings = await updateCurrentUserSettings(rootStore.restApiContext, settings); postHogStore.reset();
if (this.currentUser) { uiStore.clearBannerStack();
this.currentUser.settings = updatedSettings; npsSurveyStore.resetNpsSurveyOnLogOut();
this.addUsers([this.currentUser]); };
}
}, const createOwner = async (params: {
async updateOtherUserSettings( firstName: string;
userId: string, lastName: string;
settings: IUpdateUserSettingsReqPayload, email: string;
): Promise<void> { password: string;
const rootStore = useRootStore(); }) => {
const updatedSettings = await updateOtherUserSettings( const user = await usersApi.setupOwner(rootStore.restApiContext, params);
rootStore.restApiContext, if (user) {
userId, setCurrentUser(user);
settings, settingsStore.stopShowingSetupPage();
); }
this.users[userId].settings = updatedSettings; };
this.addUsers([this.users[userId]]);
}, const validateSignupToken = async (params: { inviteeId: string; inviterId: string }) => {
async updateCurrentUserPassword({ return await usersApi.validateSignupToken(rootStore.restApiContext, params);
password, };
const acceptInvitation = async (params: {
inviteeId: string;
inviterId: string;
firstName: string;
lastName: string;
password: string;
}) => {
const user = await invitationsApi.acceptInvitation(rootStore.restApiContext, params);
if (user) {
setCurrentUser(user);
}
};
const sendForgotPasswordEmail = async (params: { email: string }) => {
await usersApi.sendForgotPasswordEmail(rootStore.restApiContext, params);
};
const validatePasswordToken = async (params: { token: string }) => {
await usersApi.validatePasswordToken(rootStore.restApiContext, params);
};
const changePassword = async (params: { token: string; password: string; mfaToken?: string }) => {
await usersApi.changePassword(rootStore.restApiContext, params);
};
const updateUser = async (params: {
id: string;
firstName: string;
lastName: string;
email: string;
}) => {
const user = await usersApi.updateCurrentUser(rootStore.restApiContext, params);
addUsers([user]);
};
const updateUserSettings = async (settings: IUpdateUserSettingsReqPayload) => {
const updatedSettings = await usersApi.updateCurrentUserSettings(
rootStore.restApiContext,
settings,
);
if (currentUser.value) {
currentUser.value.settings = updatedSettings;
addUsers([currentUser.value]);
}
};
const updateOtherUserSettings = async (
userId: string,
settings: IUpdateUserSettingsReqPayload,
) => {
const updatedSettings = await usersApi.updateOtherUserSettings(
rootStore.restApiContext,
userId,
settings,
);
usersById.value[userId].settings = updatedSettings;
addUsers([usersById.value[userId]]);
};
const updateCurrentUserPassword = async ({
password,
currentPassword,
}: {
password: string;
currentPassword: string;
}) => {
await usersApi.updateCurrentUserPassword(rootStore.restApiContext, {
newPassword: password,
currentPassword, currentPassword,
}: { });
password: string; };
currentPassword: string;
}): Promise<void> {
const rootStore = useRootStore();
await updateCurrentUserPassword(rootStore.restApiContext, {
newPassword: password,
currentPassword,
});
},
async deleteUser(params: { id: string; transferId?: string }): Promise<void> {
const rootStore = useRootStore();
await deleteUser(rootStore.restApiContext, params);
this.deleteUserById(params.id);
},
async fetchUsers(): Promise<void> {
const rootStore = useRootStore();
const users = await getUsers(rootStore.restApiContext);
this.addUsers(users);
},
async inviteUsers(
params: Array<{ email: string; role: InvitableRoleName }>,
): Promise<IInviteResponse[]> {
const rootStore = useRootStore();
const users = await inviteUsers(rootStore.restApiContext, params);
this.addUsers(
users.map(({ user }, index) => ({
isPending: true,
globalRole: { name: params[index].role },
...user,
})),
);
return users;
},
async reinviteUser({ email, role }: { email: string; role: InvitableRoleName }): Promise<void> {
const rootStore = useRootStore();
const invitationResponse = await inviteUsers(rootStore.restApiContext, [{ email, role }]);
if (!invitationResponse[0].user.emailSent) {
throw Error(invitationResponse[0].error);
}
},
async getUserPasswordResetLink(params: { id: string }): Promise<{ link: string }> {
const rootStore = useRootStore();
return await getPasswordResetLink(rootStore.restApiContext, params);
},
async submitPersonalizationSurvey(results: IPersonalizationLatestVersion): Promise<void> {
const rootStore = useRootStore();
await submitPersonalizationSurvey(rootStore.restApiContext, results);
this.setPersonalizationAnswers(results);
},
async showPersonalizationSurvey(): Promise<void> {
const settingsStore = useSettingsStore();
const surveyEnabled = settingsStore.isPersonalizationSurveyEnabled;
const currentUser = this.currentUser;
if (surveyEnabled && currentUser && !currentUser.personalizationAnswers) {
const uiStore = useUIStore();
uiStore.openModal(PERSONALIZATION_MODAL_KEY);
}
},
async getMfaQR(): Promise<{ qrCode: string; secret: string; recoveryCodes: string[] }> {
const rootStore = useRootStore();
return await getMfaQR(rootStore.restApiContext);
},
async verifyMfaToken(data: { token: string }): Promise<void> {
const rootStore = useRootStore();
return await verifyMfaToken(rootStore.restApiContext, data);
},
async enableMfa(data: { token: string }) {
const rootStore = useRootStore();
const usersStore = useUsersStore();
await enableMfa(rootStore.restApiContext, data);
const currentUser = usersStore.currentUser;
if (currentUser) {
currentUser.mfaEnabled = true;
}
},
async disabledMfa() {
const rootStore = useRootStore();
const usersStore = useUsersStore();
await disableMfa(rootStore.restApiContext);
const currentUser = usersStore.currentUser;
if (currentUser) {
currentUser.mfaEnabled = false;
}
},
async fetchUserCloudAccount() {
let cloudUser: Cloud.UserAccount | null = null;
try {
cloudUser = await getCloudUserInfo(useRootStore().restApiContext);
this.currentUserCloudInfo = cloudUser;
} catch (error) {
throw new Error(error);
}
},
async confirmEmail() {
await confirmEmail(useRootStore().restApiContext);
},
async updateGlobalRole({ id, newRoleName }: UpdateGlobalRolePayload) { const deleteUser = async (params: { id: string; transferId?: string }) => {
const rootStore = useRootStore(); await usersApi.deleteUser(rootStore.restApiContext, params);
await updateGlobalRole(rootStore.restApiContext, { id, newRoleName }); deleteUserById(params.id);
await this.fetchUsers(); };
},
}, const fetchUsers = async () => {
const users = await usersApi.getUsers(rootStore.restApiContext);
addUsers(users);
};
const inviteUsers = async (params: Array<{ email: string; role: InvitableRoleName }>) => {
const invitedUsers = await invitationsApi.inviteUsers(rootStore.restApiContext, params);
addUsers(
invitedUsers.map(({ user }, index) => ({
isPending: true,
globalRole: { name: params[index].role },
...user,
})),
);
return invitedUsers;
};
const reinviteUser = async ({ email, role }: { email: string; role: InvitableRoleName }) => {
const invitationResponse = await invitationsApi.inviteUsers(rootStore.restApiContext, [
{ email, role },
]);
if (!invitationResponse[0].user.emailSent) {
throw Error(invitationResponse[0].error);
}
};
const getUserPasswordResetLink = async (params: { id: string }) => {
return await usersApi.getPasswordResetLink(rootStore.restApiContext, params);
};
const submitPersonalizationSurvey = async (results: IPersonalizationLatestVersion) => {
await usersApi.submitPersonalizationSurvey(rootStore.restApiContext, results);
setPersonalizationAnswers(results);
};
const showPersonalizationSurvey = async () => {
const surveyEnabled = settingsStore.isPersonalizationSurveyEnabled;
if (surveyEnabled && currentUser.value && !currentUser.value.personalizationAnswers) {
uiStore.openModal(PERSONALIZATION_MODAL_KEY);
}
};
const fetchMfaQR = async () => {
return await mfaApi.getMfaQR(rootStore.restApiContext);
};
const verifyMfaToken = async (data: { token: string }) => {
return await mfaApi.verifyMfaToken(rootStore.restApiContext, data);
};
const enableMfa = async (data: { token: string }) => {
await mfaApi.enableMfa(rootStore.restApiContext, data);
if (currentUser.value) {
currentUser.value.mfaEnabled = true;
}
};
const disableMfa = async () => {
await mfaApi.disableMfa(rootStore.restApiContext);
if (currentUser.value) {
currentUser.value.mfaEnabled = false;
}
};
const disabledMfa = async () => {
await mfaApi.disableMfa(rootStore.restApiContext);
if (currentUser.value) {
currentUser.value.mfaEnabled = false;
}
};
const fetchUserCloudAccount = async () => {
let cloudUser: Cloud.UserAccount | null = null;
try {
cloudUser = await cloudApi.getCloudUserInfo(rootStore.restApiContext);
currentUserCloudInfo.value = cloudUser;
} catch (error) {
throw new Error(error);
}
};
const confirmEmail = async () => {
await cloudApi.confirmEmail(rootStore.restApiContext);
};
const updateGlobalRole = async ({ id, newRoleName }: UpdateGlobalRolePayload) => {
await usersApi.updateGlobalRole(rootStore.restApiContext, { id, newRoleName });
await fetchUsers();
};
const reset = () => {
initialized.value = false;
currentUserId.value = null;
usersById.value = {};
currentUserCloudInfo.value = null;
};
return {
initialized,
currentUserId,
usersById,
currentUserCloudInfo,
allUsers,
currentUser,
userActivated,
isDefaultUser,
isInstanceOwner,
mfaEnabled,
globalRoleName,
personalizedNodeTypes,
addUsers,
setCurrentUser,
loginWithCookie,
initialize,
unsetCurrentUser,
deleteUserById,
setPersonalizationAnswers,
loginWithCreds,
logout,
createOwner,
validateSignupToken,
acceptInvitation,
sendForgotPasswordEmail,
validatePasswordToken,
changePassword,
updateUser,
updateUserSettings,
updateOtherUserSettings,
updateCurrentUserPassword,
deleteUser,
fetchUsers,
inviteUsers,
reinviteUser,
getUserPasswordResetLink,
submitPersonalizationSurvey,
showPersonalizationSurvey,
fetchMfaQR,
verifyMfaToken,
enableMfa,
disableMfa,
fetchUserCloudAccount,
confirmEmail,
updateGlobalRole,
disabledMfa,
reset,
};
}); });

View File

@@ -216,13 +216,13 @@ export default defineComponent({
this.uiStore.openModal(INVITE_USER_MODAL_KEY); this.uiStore.openModal(INVITE_USER_MODAL_KEY);
}, },
async onDelete(userId: string) { async onDelete(userId: string) {
const user = this.usersStore.getUserById(userId); const user = this.usersStore.usersById[userId];
if (user) { if (user) {
this.uiStore.openDeleteUserModal(userId); this.uiStore.openDeleteUserModal(userId);
} }
}, },
async onReinvite(userId: string) { async onReinvite(userId: string) {
const user = this.usersStore.getUserById(userId); const user = this.usersStore.usersById[userId];
if (user?.email && user?.role) { if (user?.email && user?.role) {
if (!['global:admin', 'global:member'].includes(user.role)) { if (!['global:admin', 'global:member'].includes(user.role)) {
throw new Error('Invalid role name on reinvite'); throw new Error('Invalid role name on reinvite');
@@ -245,7 +245,7 @@ export default defineComponent({
} }
}, },
async onCopyInviteLink(userId: string) { async onCopyInviteLink(userId: string) {
const user = this.usersStore.getUserById(userId); const user = this.usersStore.usersById[userId];
if (user?.inviteAcceptUrl) { if (user?.inviteAcceptUrl) {
void this.clipboard.copy(user.inviteAcceptUrl); void this.clipboard.copy(user.inviteAcceptUrl);
@@ -257,7 +257,7 @@ export default defineComponent({
} }
}, },
async onCopyPasswordResetLink(userId: string) { async onCopyPasswordResetLink(userId: string) {
const user = this.usersStore.getUserById(userId); const user = this.usersStore.usersById[userId];
if (user) { if (user) {
const url = await this.usersStore.getUserPasswordResetLink(user); const url = await this.usersStore.getUserPasswordResetLink(user);
void this.clipboard.copy(url.link); void this.clipboard.copy(url.link);
@@ -270,7 +270,7 @@ export default defineComponent({
} }
}, },
async onAllowSSOManualLogin(userId: string) { async onAllowSSOManualLogin(userId: string) {
const user = this.usersStore.getUserById(userId); const user = this.usersStore.usersById[userId];
if (user) { if (user) {
if (!user.settings) { if (!user.settings) {
user.settings = {}; user.settings = {};
@@ -286,7 +286,7 @@ export default defineComponent({
} }
}, },
async onDisallowSSOManualLogin(userId: string) { async onDisallowSSOManualLogin(userId: string) {
const user = this.usersStore.getUserById(userId); const user = this.usersStore.usersById[userId];
if (user?.settings) { if (user?.settings) {
user.settings.allowSSOManualLogin = false; user.settings.allowSSOManualLogin = false;
await this.usersStore.updateOtherUserSettings(userId, user.settings); await this.usersStore.updateOtherUserSettings(userId, user.settings);

View File

@@ -41,7 +41,7 @@ describe('SettingsPersonalView', () => {
usersStore = useUsersStore(pinia); usersStore = useUsersStore(pinia);
uiStore = useUIStore(pinia); uiStore = useUIStore(pinia);
usersStore.users[currentUser.id] = currentUser; usersStore.usersById[currentUser.id] = currentUser;
usersStore.currentUserId = currentUser.id; usersStore.currentUserId = currentUser.id;
await settingsStore.getSettings(); await settingsStore.getSettings();