@n8n/stores 2.35.2 → 2.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,34 +1,34 @@
1
1
  import { t as IInviteResponse } from "./invitation2.api.cjs";
2
2
  import { t as ModalOpeners } from "./modalOpeners2.cjs";
3
- import * as vue395 from "vue";
4
- import * as pinia6 from "pinia";
3
+ import * as vue32 from "vue";
4
+ import * as pinia2 from "pinia";
5
5
  import { LoginRequestDto, PasswordUpdateRequestDto, SettingsUpdateRequestDto, User, UserSelfSettingsUpdateRequestDto, UserUpdateRequestDto, UsersListFilterDto } from "@n8n/api-types";
6
6
  import { AssignableGlobalRole } from "@n8n/permissions";
7
7
  import { CurrentUserResponse, IPersonalizationLatestVersion, IUser, IUserResponse, UpdateGlobalRolePayload } from "@n8n/rest-api-client/api/users";
8
- import * as _vueuse_core2 from "@vueuse/core";
8
+ import * as _vueuse_core0 from "@vueuse/core";
9
9
  import * as zod0 from "zod";
10
10
  import * as mfaApi from "@n8n/rest-api-client/api/mfa";
11
11
 
12
12
  //#region src/users.store.d.ts
13
13
  type LoginHook = (user: CurrentUserResponse) => void | Promise<void>;
14
14
  type LogoutHook = () => void | Promise<void>;
15
- declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
16
- initialized: vue395.Ref<boolean, boolean>;
17
- currentUserId: vue395.Ref<string | null, string | null>;
18
- usersById: vue395.Ref<Record<string, IUser>, Record<string, IUser>>;
19
- allUsers: vue395.ComputedRef<IUser[]>;
20
- currentUser: vue395.ComputedRef<IUser | null>;
21
- userActivated: vue395.ComputedRef<boolean>;
22
- isDefaultUser: vue395.ComputedRef<boolean>;
23
- isInstanceOwner: vue395.ComputedRef<boolean>;
24
- isAdmin: vue395.ComputedRef<boolean>;
25
- isAdminOrOwner: vue395.ComputedRef<boolean>;
26
- mfaEnabled: vue395.ComputedRef<boolean>;
27
- globalRoleName: vue395.ComputedRef<string>;
28
- userClaimedAiCredits: vue395.ComputedRef<boolean | undefined>;
29
- isEasyAIWorkflowOnboardingDone: vue395.ComputedRef<boolean>;
30
- canUserUpdateVersion: vue395.ComputedRef<boolean>;
31
- usersLimitNotReached: vue395.ComputedRef<boolean>;
15
+ declare const useUsersStore: pinia2.StoreDefinition<"users", Pick<{
16
+ initialized: vue32.Ref<boolean, boolean>;
17
+ currentUserId: vue32.Ref<string | null, string | null>;
18
+ usersById: vue32.Ref<Record<string, IUser>, Record<string, IUser>>;
19
+ allUsers: vue32.ComputedRef<IUser[]>;
20
+ currentUser: vue32.ComputedRef<IUser | null>;
21
+ userActivated: vue32.ComputedRef<boolean>;
22
+ isDefaultUser: vue32.ComputedRef<boolean>;
23
+ isInstanceOwner: vue32.ComputedRef<boolean>;
24
+ isAdmin: vue32.ComputedRef<boolean>;
25
+ isAdminOrOwner: vue32.ComputedRef<boolean>;
26
+ mfaEnabled: vue32.ComputedRef<boolean>;
27
+ globalRoleName: vue32.ComputedRef<string>;
28
+ userClaimedAiCredits: vue32.ComputedRef<boolean | undefined>;
29
+ isEasyAIWorkflowOnboardingDone: vue32.ComputedRef<boolean>;
30
+ canUserUpdateVersion: vue32.ComputedRef<boolean>;
31
+ usersLimitNotReached: vue32.ComputedRef<boolean>;
32
32
  addUsers: (newUsers: User[]) => void;
33
33
  loginWithCookie: () => Promise<void>;
34
34
  initialize: () => Promise<void>;
@@ -144,7 +144,7 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
144
144
  setCalloutDismissed: (callout: string) => void;
145
145
  submitContactEmail: (email: string, agree: boolean) => Promise<string | null>;
146
146
  setUserQuota: (quota?: number) => void;
147
- usersList: _vueuse_core2.UseAsyncStateReturn<{
147
+ usersList: _vueuse_core0.UseAsyncStateReturn<{
148
148
  count: number;
149
149
  items: {
150
150
  id: string;
@@ -191,22 +191,22 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
191
191
  }[];
192
192
  }, [filter?: UsersListFilterDto | undefined], true>;
193
193
  }, "initialized" | "currentUserId" | "usersById" | "usersList">, Pick<{
194
- initialized: vue395.Ref<boolean, boolean>;
195
- currentUserId: vue395.Ref<string | null, string | null>;
196
- usersById: vue395.Ref<Record<string, IUser>, Record<string, IUser>>;
197
- allUsers: vue395.ComputedRef<IUser[]>;
198
- currentUser: vue395.ComputedRef<IUser | null>;
199
- userActivated: vue395.ComputedRef<boolean>;
200
- isDefaultUser: vue395.ComputedRef<boolean>;
201
- isInstanceOwner: vue395.ComputedRef<boolean>;
202
- isAdmin: vue395.ComputedRef<boolean>;
203
- isAdminOrOwner: vue395.ComputedRef<boolean>;
204
- mfaEnabled: vue395.ComputedRef<boolean>;
205
- globalRoleName: vue395.ComputedRef<string>;
206
- userClaimedAiCredits: vue395.ComputedRef<boolean | undefined>;
207
- isEasyAIWorkflowOnboardingDone: vue395.ComputedRef<boolean>;
208
- canUserUpdateVersion: vue395.ComputedRef<boolean>;
209
- usersLimitNotReached: vue395.ComputedRef<boolean>;
194
+ initialized: vue32.Ref<boolean, boolean>;
195
+ currentUserId: vue32.Ref<string | null, string | null>;
196
+ usersById: vue32.Ref<Record<string, IUser>, Record<string, IUser>>;
197
+ allUsers: vue32.ComputedRef<IUser[]>;
198
+ currentUser: vue32.ComputedRef<IUser | null>;
199
+ userActivated: vue32.ComputedRef<boolean>;
200
+ isDefaultUser: vue32.ComputedRef<boolean>;
201
+ isInstanceOwner: vue32.ComputedRef<boolean>;
202
+ isAdmin: vue32.ComputedRef<boolean>;
203
+ isAdminOrOwner: vue32.ComputedRef<boolean>;
204
+ mfaEnabled: vue32.ComputedRef<boolean>;
205
+ globalRoleName: vue32.ComputedRef<string>;
206
+ userClaimedAiCredits: vue32.ComputedRef<boolean | undefined>;
207
+ isEasyAIWorkflowOnboardingDone: vue32.ComputedRef<boolean>;
208
+ canUserUpdateVersion: vue32.ComputedRef<boolean>;
209
+ usersLimitNotReached: vue32.ComputedRef<boolean>;
210
210
  addUsers: (newUsers: User[]) => void;
211
211
  loginWithCookie: () => Promise<void>;
212
212
  initialize: () => Promise<void>;
@@ -322,7 +322,7 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
322
322
  setCalloutDismissed: (callout: string) => void;
323
323
  submitContactEmail: (email: string, agree: boolean) => Promise<string | null>;
324
324
  setUserQuota: (quota?: number) => void;
325
- usersList: _vueuse_core2.UseAsyncStateReturn<{
325
+ usersList: _vueuse_core0.UseAsyncStateReturn<{
326
326
  count: number;
327
327
  items: {
328
328
  id: string;
@@ -369,22 +369,22 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
369
369
  }[];
370
370
  }, [filter?: UsersListFilterDto | undefined], true>;
371
371
  }, "allUsers" | "currentUser" | "userActivated" | "isDefaultUser" | "isInstanceOwner" | "isAdmin" | "isAdminOrOwner" | "mfaEnabled" | "globalRoleName" | "userClaimedAiCredits" | "isEasyAIWorkflowOnboardingDone" | "canUserUpdateVersion" | "usersLimitNotReached">, Pick<{
372
- initialized: vue395.Ref<boolean, boolean>;
373
- currentUserId: vue395.Ref<string | null, string | null>;
374
- usersById: vue395.Ref<Record<string, IUser>, Record<string, IUser>>;
375
- allUsers: vue395.ComputedRef<IUser[]>;
376
- currentUser: vue395.ComputedRef<IUser | null>;
377
- userActivated: vue395.ComputedRef<boolean>;
378
- isDefaultUser: vue395.ComputedRef<boolean>;
379
- isInstanceOwner: vue395.ComputedRef<boolean>;
380
- isAdmin: vue395.ComputedRef<boolean>;
381
- isAdminOrOwner: vue395.ComputedRef<boolean>;
382
- mfaEnabled: vue395.ComputedRef<boolean>;
383
- globalRoleName: vue395.ComputedRef<string>;
384
- userClaimedAiCredits: vue395.ComputedRef<boolean | undefined>;
385
- isEasyAIWorkflowOnboardingDone: vue395.ComputedRef<boolean>;
386
- canUserUpdateVersion: vue395.ComputedRef<boolean>;
387
- usersLimitNotReached: vue395.ComputedRef<boolean>;
372
+ initialized: vue32.Ref<boolean, boolean>;
373
+ currentUserId: vue32.Ref<string | null, string | null>;
374
+ usersById: vue32.Ref<Record<string, IUser>, Record<string, IUser>>;
375
+ allUsers: vue32.ComputedRef<IUser[]>;
376
+ currentUser: vue32.ComputedRef<IUser | null>;
377
+ userActivated: vue32.ComputedRef<boolean>;
378
+ isDefaultUser: vue32.ComputedRef<boolean>;
379
+ isInstanceOwner: vue32.ComputedRef<boolean>;
380
+ isAdmin: vue32.ComputedRef<boolean>;
381
+ isAdminOrOwner: vue32.ComputedRef<boolean>;
382
+ mfaEnabled: vue32.ComputedRef<boolean>;
383
+ globalRoleName: vue32.ComputedRef<string>;
384
+ userClaimedAiCredits: vue32.ComputedRef<boolean | undefined>;
385
+ isEasyAIWorkflowOnboardingDone: vue32.ComputedRef<boolean>;
386
+ canUserUpdateVersion: vue32.ComputedRef<boolean>;
387
+ usersLimitNotReached: vue32.ComputedRef<boolean>;
388
388
  addUsers: (newUsers: User[]) => void;
389
389
  loginWithCookie: () => Promise<void>;
390
390
  initialize: () => Promise<void>;
@@ -500,7 +500,7 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
500
500
  setCalloutDismissed: (callout: string) => void;
501
501
  submitContactEmail: (email: string, agree: boolean) => Promise<string | null>;
502
502
  setUserQuota: (quota?: number) => void;
503
- usersList: _vueuse_core2.UseAsyncStateReturn<{
503
+ usersList: _vueuse_core0.UseAsyncStateReturn<{
504
504
  count: number;
505
505
  items: {
506
506
  id: string;
@@ -1,7 +1,7 @@
1
1
  import { t as IInviteResponse } from "./invitation2.api.mjs";
2
2
  import { t as ModalOpeners } from "./modalOpeners2.mjs";
3
3
  import * as pinia6 from "pinia";
4
- import * as vue395 from "vue";
4
+ import * as vue401 from "vue";
5
5
  import { LoginRequestDto, PasswordUpdateRequestDto, SettingsUpdateRequestDto, User, UserSelfSettingsUpdateRequestDto, UserUpdateRequestDto, UsersListFilterDto } from "@n8n/api-types";
6
6
  import { AssignableGlobalRole } from "@n8n/permissions";
7
7
  import * as _vueuse_core2 from "@vueuse/core";
@@ -13,22 +13,22 @@ import * as zod0 from "zod";
13
13
  type LoginHook = (user: CurrentUserResponse) => void | Promise<void>;
14
14
  type LogoutHook = () => void | Promise<void>;
15
15
  declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
16
- initialized: vue395.Ref<boolean, boolean>;
17
- currentUserId: vue395.Ref<string | null, string | null>;
18
- usersById: vue395.Ref<Record<string, IUser>, Record<string, IUser>>;
19
- allUsers: vue395.ComputedRef<IUser[]>;
20
- currentUser: vue395.ComputedRef<IUser | null>;
21
- userActivated: vue395.ComputedRef<boolean>;
22
- isDefaultUser: vue395.ComputedRef<boolean>;
23
- isInstanceOwner: vue395.ComputedRef<boolean>;
24
- isAdmin: vue395.ComputedRef<boolean>;
25
- isAdminOrOwner: vue395.ComputedRef<boolean>;
26
- mfaEnabled: vue395.ComputedRef<boolean>;
27
- globalRoleName: vue395.ComputedRef<string>;
28
- userClaimedAiCredits: vue395.ComputedRef<boolean | undefined>;
29
- isEasyAIWorkflowOnboardingDone: vue395.ComputedRef<boolean>;
30
- canUserUpdateVersion: vue395.ComputedRef<boolean>;
31
- usersLimitNotReached: vue395.ComputedRef<boolean>;
16
+ initialized: vue401.Ref<boolean, boolean>;
17
+ currentUserId: vue401.Ref<string | null, string | null>;
18
+ usersById: vue401.Ref<Record<string, IUser>, Record<string, IUser>>;
19
+ allUsers: vue401.ComputedRef<IUser[]>;
20
+ currentUser: vue401.ComputedRef<IUser | null>;
21
+ userActivated: vue401.ComputedRef<boolean>;
22
+ isDefaultUser: vue401.ComputedRef<boolean>;
23
+ isInstanceOwner: vue401.ComputedRef<boolean>;
24
+ isAdmin: vue401.ComputedRef<boolean>;
25
+ isAdminOrOwner: vue401.ComputedRef<boolean>;
26
+ mfaEnabled: vue401.ComputedRef<boolean>;
27
+ globalRoleName: vue401.ComputedRef<string>;
28
+ userClaimedAiCredits: vue401.ComputedRef<boolean | undefined>;
29
+ isEasyAIWorkflowOnboardingDone: vue401.ComputedRef<boolean>;
30
+ canUserUpdateVersion: vue401.ComputedRef<boolean>;
31
+ usersLimitNotReached: vue401.ComputedRef<boolean>;
32
32
  addUsers: (newUsers: User[]) => void;
33
33
  loginWithCookie: () => Promise<void>;
34
34
  initialize: () => Promise<void>;
@@ -191,22 +191,22 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
191
191
  }[];
192
192
  }, [filter?: UsersListFilterDto | undefined], true>;
193
193
  }, "initialized" | "currentUserId" | "usersById" | "usersList">, Pick<{
194
- initialized: vue395.Ref<boolean, boolean>;
195
- currentUserId: vue395.Ref<string | null, string | null>;
196
- usersById: vue395.Ref<Record<string, IUser>, Record<string, IUser>>;
197
- allUsers: vue395.ComputedRef<IUser[]>;
198
- currentUser: vue395.ComputedRef<IUser | null>;
199
- userActivated: vue395.ComputedRef<boolean>;
200
- isDefaultUser: vue395.ComputedRef<boolean>;
201
- isInstanceOwner: vue395.ComputedRef<boolean>;
202
- isAdmin: vue395.ComputedRef<boolean>;
203
- isAdminOrOwner: vue395.ComputedRef<boolean>;
204
- mfaEnabled: vue395.ComputedRef<boolean>;
205
- globalRoleName: vue395.ComputedRef<string>;
206
- userClaimedAiCredits: vue395.ComputedRef<boolean | undefined>;
207
- isEasyAIWorkflowOnboardingDone: vue395.ComputedRef<boolean>;
208
- canUserUpdateVersion: vue395.ComputedRef<boolean>;
209
- usersLimitNotReached: vue395.ComputedRef<boolean>;
194
+ initialized: vue401.Ref<boolean, boolean>;
195
+ currentUserId: vue401.Ref<string | null, string | null>;
196
+ usersById: vue401.Ref<Record<string, IUser>, Record<string, IUser>>;
197
+ allUsers: vue401.ComputedRef<IUser[]>;
198
+ currentUser: vue401.ComputedRef<IUser | null>;
199
+ userActivated: vue401.ComputedRef<boolean>;
200
+ isDefaultUser: vue401.ComputedRef<boolean>;
201
+ isInstanceOwner: vue401.ComputedRef<boolean>;
202
+ isAdmin: vue401.ComputedRef<boolean>;
203
+ isAdminOrOwner: vue401.ComputedRef<boolean>;
204
+ mfaEnabled: vue401.ComputedRef<boolean>;
205
+ globalRoleName: vue401.ComputedRef<string>;
206
+ userClaimedAiCredits: vue401.ComputedRef<boolean | undefined>;
207
+ isEasyAIWorkflowOnboardingDone: vue401.ComputedRef<boolean>;
208
+ canUserUpdateVersion: vue401.ComputedRef<boolean>;
209
+ usersLimitNotReached: vue401.ComputedRef<boolean>;
210
210
  addUsers: (newUsers: User[]) => void;
211
211
  loginWithCookie: () => Promise<void>;
212
212
  initialize: () => Promise<void>;
@@ -369,22 +369,22 @@ declare const useUsersStore: pinia6.StoreDefinition<"users", Pick<{
369
369
  }[];
370
370
  }, [filter?: UsersListFilterDto | undefined], true>;
371
371
  }, "allUsers" | "currentUser" | "userActivated" | "isDefaultUser" | "isInstanceOwner" | "isAdmin" | "isAdminOrOwner" | "mfaEnabled" | "globalRoleName" | "userClaimedAiCredits" | "isEasyAIWorkflowOnboardingDone" | "canUserUpdateVersion" | "usersLimitNotReached">, Pick<{
372
- initialized: vue395.Ref<boolean, boolean>;
373
- currentUserId: vue395.Ref<string | null, string | null>;
374
- usersById: vue395.Ref<Record<string, IUser>, Record<string, IUser>>;
375
- allUsers: vue395.ComputedRef<IUser[]>;
376
- currentUser: vue395.ComputedRef<IUser | null>;
377
- userActivated: vue395.ComputedRef<boolean>;
378
- isDefaultUser: vue395.ComputedRef<boolean>;
379
- isInstanceOwner: vue395.ComputedRef<boolean>;
380
- isAdmin: vue395.ComputedRef<boolean>;
381
- isAdminOrOwner: vue395.ComputedRef<boolean>;
382
- mfaEnabled: vue395.ComputedRef<boolean>;
383
- globalRoleName: vue395.ComputedRef<string>;
384
- userClaimedAiCredits: vue395.ComputedRef<boolean | undefined>;
385
- isEasyAIWorkflowOnboardingDone: vue395.ComputedRef<boolean>;
386
- canUserUpdateVersion: vue395.ComputedRef<boolean>;
387
- usersLimitNotReached: vue395.ComputedRef<boolean>;
372
+ initialized: vue401.Ref<boolean, boolean>;
373
+ currentUserId: vue401.Ref<string | null, string | null>;
374
+ usersById: vue401.Ref<Record<string, IUser>, Record<string, IUser>>;
375
+ allUsers: vue401.ComputedRef<IUser[]>;
376
+ currentUser: vue401.ComputedRef<IUser | null>;
377
+ userActivated: vue401.ComputedRef<boolean>;
378
+ isDefaultUser: vue401.ComputedRef<boolean>;
379
+ isInstanceOwner: vue401.ComputedRef<boolean>;
380
+ isAdmin: vue401.ComputedRef<boolean>;
381
+ isAdminOrOwner: vue401.ComputedRef<boolean>;
382
+ mfaEnabled: vue401.ComputedRef<boolean>;
383
+ globalRoleName: vue401.ComputedRef<string>;
384
+ userClaimedAiCredits: vue401.ComputedRef<boolean | undefined>;
385
+ isEasyAIWorkflowOnboardingDone: vue401.ComputedRef<boolean>;
386
+ canUserUpdateVersion: vue401.ComputedRef<boolean>;
387
+ usersLimitNotReached: vue401.ComputedRef<boolean>;
388
388
  addUsers: (newUsers: User[]) => void;
389
389
  loginWithCookie: () => Promise<void>;
390
390
  initialize: () => Promise<void>;
@@ -8,6 +8,7 @@ __n8n_rest_api_client_api_cloudPlans = require_settings_store.__toESM(__n8n_rest
8
8
  let pinia = require("pinia");
9
9
  let vue = require("vue");
10
10
  let __n8n_api_types = require("@n8n/api-types");
11
+ let __n8n_rest_api_client = require("@n8n/rest-api-client");
11
12
  let __vueuse_core = require("@vueuse/core");
12
13
  let __n8n_constants = require("@n8n/constants");
13
14
  let __n8n_frontend_constants_users = require("@n8n/frontend-constants/users");
@@ -23,6 +24,7 @@ const _isPendingUser = (user) => !!user?.isPending;
23
24
  const _isInstanceOwner = (user) => user?.role === __n8n_api_types.ROLE.Owner;
24
25
  const _isDefaultUser = (user) => _isInstanceOwner(user) && _isPendingUser(user);
25
26
  const _isAdmin = (user) => user?.role === __n8n_api_types.ROLE.Admin;
27
+ const _isSessionAlreadyInvalid = (error) => error instanceof __n8n_rest_api_client.ResponseError && error.httpStatusCode === 401;
26
28
  const useUsersStore = (0, pinia.defineStore)(require_constants.STORES.USERS, () => {
27
29
  const initialized = (0, vue.ref)(false);
28
30
  const currentUserId = (0, vue.ref)(null);
@@ -138,14 +140,21 @@ const useUsersStore = (0, pinia.defineStore)(require_constants.STORES.USERS, ()
138
140
  const registerLogoutHook = (hook) => {
139
141
  logoutHooks.value.push(hook);
140
142
  };
143
+ const standardLogout = async () => {
144
+ try {
145
+ await __n8n_rest_api_client_api_users.logout(rootStore.restApiContext);
146
+ } catch (error) {
147
+ if (!_isSessionAlreadyInvalid(error)) throw error;
148
+ }
149
+ };
141
150
  const logout = async (options) => {
142
151
  let redirectUrl = null;
143
152
  if (options?.viaOidc) try {
144
153
  ({redirectUrl} = await __n8n_rest_api_client_api_sso.oidcLogout(rootStore.restApiContext));
145
154
  } catch {
146
- await __n8n_rest_api_client_api_users.logout(rootStore.restApiContext);
155
+ await standardLogout();
147
156
  }
148
- else await __n8n_rest_api_client_api_users.logout(rootStore.restApiContext);
157
+ else await standardLogout();
149
158
  unsetCurrentUser();
150
159
  for (const hook of logoutHooks.value) try {
151
160
  await hook();
@@ -1 +1 @@
1
- {"version":3,"file":"users2.store.cjs","names":["ROLE","STORES","useRootStore","useSettingsStore","user: IUser","usersApi","redirectUrl: string | null","ssoApi","BROWSER_ID_STORAGE_KEY","acceptInvitation","inviteUsers","PERSONALIZATION_MODAL_KEY","mfaApi","cloudApi"],"sources":["../src/users.store.ts"],"sourcesContent":["import {\n\ttype LoginRequestDto,\n\ttype PasswordUpdateRequestDto,\n\ttype SettingsUpdateRequestDto,\n\ttype UserSelfSettingsUpdateRequestDto,\n\ttype UserUpdateRequestDto,\n\ttype User,\n\tROLE,\n\ttype UsersListFilterDto,\n} from '@n8n/api-types';\nimport { BROWSER_ID_STORAGE_KEY } from '@n8n/constants';\nimport { PERSONALIZATION_MODAL_KEY } from '@n8n/frontend-constants/users';\nimport type { AssignableGlobalRole } from '@n8n/permissions';\nimport * as cloudApi from '@n8n/rest-api-client/api/cloudPlans';\nimport * as mfaApi from '@n8n/rest-api-client/api/mfa';\nimport * as ssoApi from '@n8n/rest-api-client/api/sso';\nimport type {\n\tUpdateGlobalRolePayload,\n\tIUserResponse,\n\tIUser,\n\tCurrentUserResponse,\n\tIPersonalizationLatestVersion,\n} from '@n8n/rest-api-client/api/users';\nimport * as usersApi from '@n8n/rest-api-client/api/users';\nimport { useAsyncState } from '@vueuse/core';\nimport { defineStore } from 'pinia';\nimport { computed, ref } from 'vue';\n\nimport { STORES } from './constants';\nimport * as invitationsApi from './invitation.api';\nimport type { ModalOpeners } from './modalOpeners';\nimport * as onboardingApi from './onboarding.api';\nimport { useSettingsStore } from './settings.store';\nimport { useRootStore } from './useRootStore';\n\nconst _isPendingUser = (user: IUserResponse | null) => !!user?.isPending;\nconst _isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Owner;\nconst _isDefaultUser = (user: IUserResponse | null) =>\n\t_isInstanceOwner(user) && _isPendingUser(user);\nconst _isAdmin = (user: IUserResponse | null) => user?.role === ROLE.Admin;\n\nexport type LoginHook = (user: CurrentUserResponse) => void | Promise<void>;\ntype LogoutHook = () => void | Promise<void>;\n\nexport const useUsersStore = defineStore(STORES.USERS, () => {\n\tconst initialized = ref(false);\n\tconst currentUserId = ref<string | null>(null);\n\tconst usersById = ref<Record<string, IUser>>({});\n\tconst userQuota = ref<number>(-1);\n\n\tconst loginHooks = ref<LoginHook[]>([]);\n\tconst logoutHooks = ref<LogoutHook[]>([]);\n\n\t// Modal-open actions, registered at app bootstrap (see app/init.ts). Until then\n\t// they no-op — warning in dev — so the store never reaches into `ui.store`. Shares\n\t// the `ModalOpeners` contract with the other decoupled stores; this store currently\n\t// uses only `openModal`.\n\tconst warnModalOpenerMissing = (action: string) => {\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.warn(\n\t\t\t\t`[users.store] ${action} called before modal openers were registered; ignoring. Call registerModalOpeners() at app bootstrap.`,\n\t\t\t);\n\t\t}\n\t};\n\tconst modalOpeners = ref<ModalOpeners>({\n\t\topenModal: (name) => warnModalOpenerMissing(`openModal(${String(name)})`),\n\t\topenModalWithData: (payload) =>\n\t\t\twarnModalOpenerMissing(`openModalWithData(${String(payload.name)})`),\n\t});\n\tconst registerModalOpeners = (openers: ModalOpeners) => {\n\t\tmodalOpeners.value = openers;\n\t};\n\n\t// App-provided capabilities, registered at bootstrap (see app/init.ts) so the store\n\t// carries no `@/app` dependency. Both fall back to safe no-ops before registration.\n\n\t// Permission checks, keyed by capability (app RBAC checks; extend the object as\n\t// more permissions need resolving). `listUsers` gates the `user:list` scope.\n\tconst canListUsers = ref<() => boolean>(() => false);\n\tconst setPermissionsResolvers = (resolvers: { listUsers: () => boolean }) => {\n\t\tcanListUsers.value = resolvers.listUsers;\n\t};\n\n\t// Stores\n\n\tconst rootStore = useRootStore();\n\tconst settingsStore = useSettingsStore();\n\n\t// Computed\n\n\tconst allUsers = computed(() => Object.values(usersById.value));\n\n\tconst currentUser = computed(() =>\n\t\tcurrentUserId.value ? usersById.value[currentUserId.value] : null,\n\t);\n\n\tconst userActivated = computed(() => Boolean(currentUser.value?.settings?.userActivated));\n\n\tconst isDefaultUser = computed(() => _isDefaultUser(currentUser.value));\n\n\tconst isInstanceOwner = computed(() => _isInstanceOwner(currentUser.value));\n\n\tconst isAdmin = computed(() => _isAdmin(currentUser.value));\n\n\tconst isAdminOrOwner = computed(() => isInstanceOwner.value || isAdmin.value);\n\n\tconst mfaEnabled = computed(() => currentUser.value?.mfaEnabled ?? false);\n\n\tconst globalRoleName = computed(() => currentUser.value?.role ?? 'default');\n\n\tconst userClaimedAiCredits = computed(() => currentUser.value?.settings?.userClaimedAiCredits);\n\n\tconst isEasyAIWorkflowOnboardingDone = computed(() =>\n\t\tBoolean(currentUser.value?.settings?.easyAIWorkflowOnboarded),\n\t);\n\n\tconst canUserUpdateVersion = computed(() => {\n\t\treturn isInstanceOwner.value;\n\t});\n\n\tconst setEasyAIWorkflowOnboardingDone = () => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.easyAIWorkflowOnboarded = true;\n\t\t}\n\t};\n\n\tconst isCalloutDismissed = (callout: string) =>\n\t\tBoolean(currentUser.value?.settings?.dismissedCallouts?.[callout]);\n\n\tconst setCalloutDismissed = (callout: string) => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.dismissedCallouts ??= {};\n\n\t\t\tcurrentUser.value.settings.dismissedCallouts[callout] = true;\n\t\t}\n\t};\n\n\tconst usersLimitNotReached = computed(\n\t\t(): boolean => userQuota.value === -1 || userQuota.value > allUsers.value.length,\n\t);\n\n\t// Methods\n\n\tconst addUsers = (newUsers: User[]) => {\n\t\tnewUsers.forEach((userResponse) => {\n\t\t\tconst prevUser = usersById.value[userResponse.id] || {};\n\t\t\tconst updatedUser = {\n\t\t\t\t...prevUser,\n\t\t\t\t...userResponse,\n\t\t\t};\n\t\t\tconst user: IUser = {\n\t\t\t\t...updatedUser,\n\t\t\t\tfullName: userResponse.firstName\n\t\t\t\t\t? `${updatedUser.firstName} ${updatedUser.lastName ?? ''}`\n\t\t\t\t\t: undefined,\n\t\t\t\tisDefaultUser: _isDefaultUser(updatedUser),\n\t\t\t\tisPendingUser: _isPendingUser(updatedUser),\n\t\t\t};\n\n\t\t\tusersById.value = {\n\t\t\t\t...usersById.value,\n\t\t\t\t[user.id]: user,\n\t\t\t};\n\t\t});\n\t};\n\n\tconst setCurrentUser = async (user: CurrentUserResponse) => {\n\t\taddUsers([user]);\n\t\tcurrentUserId.value = user.id;\n\n\t\tfor (const hook of loginHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook(user);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing login hook:', error);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst loginWithCookie = async () => {\n\t\tconst user = await usersApi.loginCurrentUser(rootStore.restApiContext);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst initialize = async () => {\n\t\tif (initialized.value) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait loginWithCookie();\n\t\t\tinitialized.value = true;\n\t\t} catch {\n\t\t\t// A missing or expired auth cookie before setup is expected; leave the store\n\t\t\t// uninitialized and let the caller proceed to the login/setup flow.\n\t\t}\n\t};\n\n\tconst unsetCurrentUser = () => {\n\t\tcurrentUserId.value = null;\n\t};\n\n\tconst deleteUserById = (userId: string) => {\n\t\tconst { [userId]: _, ...rest } = usersById.value;\n\t\tusersById.value = rest;\n\t};\n\n\tconst setPersonalizationAnswers = (answers: IPersonalizationLatestVersion) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\tusersById.value = {\n\t\t\t...usersById.value,\n\t\t\t[currentUser.value.id]: {\n\t\t\t\t...currentUser.value,\n\t\t\t\tpersonalizationAnswers: answers,\n\t\t\t},\n\t\t};\n\t};\n\n\tconst loginWithCreds = async (params: LoginRequestDto) => {\n\t\tconst user = await usersApi.login(rootStore.restApiContext, params);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst registerLoginHook = (hook: LoginHook) => {\n\t\tloginHooks.value.push(hook);\n\t};\n\n\tconst registerLogoutHook = (hook: LogoutHook) => {\n\t\tlogoutHooks.value.push(hook);\n\t};\n\n\tconst logout = async (options?: { viaOidc?: boolean }) => {\n\t\tlet redirectUrl: string | null = null;\n\n\t\tif (options?.viaOidc) {\n\t\t\ttry {\n\t\t\t\t({ redirectUrl } = await ssoApi.oidcLogout(rootStore.restApiContext));\n\t\t\t} catch {\n\t\t\t\t// The OIDC logout endpoint may be unavailable (e.g. the license\n\t\t\t\t// lapsed since login). Fall back to the standard logout so the\n\t\t\t\t// n8n session is terminated in any case.\n\t\t\t\tawait usersApi.logout(rootStore.restApiContext);\n\t\t\t}\n\t\t} else {\n\t\t\tawait usersApi.logout(rootStore.restApiContext);\n\t\t}\n\n\t\tunsetCurrentUser();\n\n\t\tfor (const hook of logoutHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing logout hook:', error);\n\t\t\t}\n\t\t}\n\n\t\tlocalStorage.removeItem(BROWSER_ID_STORAGE_KEY);\n\n\t\treturn { redirectUrl };\n\t};\n\n\tconst createOwner = async (params: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\temail: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await usersApi.setupOwner(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t\tsettingsStore.stopShowingSetupPage();\n\t\t}\n\t};\n\n\tconst validateSignupToken = async (params: { token: string }) => {\n\t\treturn await usersApi.validateSignupToken(rootStore.restApiContext, params);\n\t};\n\n\tconst acceptInvitation = async (params: {\n\t\ttoken: string;\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await invitationsApi.acceptInvitation(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t}\n\t};\n\n\tconst sendForgotPasswordEmail = async (params: { email: string }) => {\n\t\tawait usersApi.sendForgotPasswordEmail(rootStore.restApiContext, params);\n\t};\n\n\tconst validatePasswordToken = async (params: { token: string }) => {\n\t\tawait usersApi.validatePasswordToken(rootStore.restApiContext, params);\n\t};\n\n\tconst changePassword = async (params: { token: string; password: string; mfaCode?: string }) => {\n\t\tawait usersApi.changePassword(rootStore.restApiContext, params);\n\t};\n\n\tconst updateUser = async (params: UserUpdateRequestDto) => {\n\t\tconst user = await usersApi.updateCurrentUser(rootStore.restApiContext, params);\n\t\taddUsers([user]);\n\t\treturn user;\n\t};\n\n\tconst updateUserName = async (params: { firstName: string; lastName: string }) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn await updateUser({\n\t\t\temail: currentUser.value.email as string,\n\t\t\t...params,\n\t\t});\n\t};\n\n\tconst updateUserSettings = async (settings: UserSelfSettingsUpdateRequestDto) => {\n\t\tconst updatedSettings = await usersApi.updateCurrentUserSettings(\n\t\t\trootStore.restApiContext,\n\t\t\tsettings,\n\t\t);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.settings = updatedSettings;\n\t\t\taddUsers([currentUser.value]);\n\t\t}\n\t};\n\n\tconst updateOtherUserSettings = async (userId: string, settings: SettingsUpdateRequestDto) => {\n\t\tawait usersApi.updateOtherUserSettings(rootStore.restApiContext, userId, settings);\n\t};\n\n\tconst updateCurrentUserPassword = async (params: PasswordUpdateRequestDto) => {\n\t\tawait usersApi.updateCurrentUserPassword(rootStore.restApiContext, params);\n\t};\n\n\tconst deleteUser = async (params: { id: string; transferId?: string }) => {\n\t\tawait usersApi.deleteUser(rootStore.restApiContext, params);\n\t\tdeleteUserById(params.id);\n\t};\n\n\tconst fetchUsers = async ({\n\t\ttake,\n\t\tskip,\n\t\tfilter,\n\t}: { take?: number; skip?: number; filter?: UsersListFilterDto['filter'] } = {}) => {\n\t\tif (!canListUsers.value()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { items } = await usersApi.getUsers(rootStore.restApiContext, {\n\t\t\ttake: take ?? 50,\n\t\t\tskip: skip ?? 0,\n\t\t\tfilter,\n\t\t});\n\t\taddUsers(items);\n\t};\n\n\tconst inviteUsers = async (params: Array<{ email: string; role: AssignableGlobalRole }>) => {\n\t\tconst invitedUsers = await invitationsApi.inviteUsers(rootStore.restApiContext, params);\n\t\taddUsers(\n\t\t\tinvitedUsers.map(({ user }) => ({\n\t\t\t\tisPending: true,\n\t\t\t\t...user,\n\t\t\t})),\n\t\t);\n\t\treturn invitedUsers;\n\t};\n\n\tconst reinviteUser = async ({ email, role }: { email: string; role: AssignableGlobalRole }) => {\n\t\tconst invitationResponse = await invitationsApi.inviteUsers(rootStore.restApiContext, [\n\t\t\t{ email, role },\n\t\t]);\n\t\tif (!invitationResponse[0].user.emailSent) {\n\t\t\tthrow Error(invitationResponse[0].error);\n\t\t}\n\t};\n\n\tconst getUserPasswordResetLink = async (params: { id: string }) => {\n\t\treturn await usersApi.getPasswordResetLink(rootStore.restApiContext, params);\n\t};\n\n\tconst generateInviteLink = async (params: { id: string }) => {\n\t\treturn await usersApi.generateInviteLink(rootStore.restApiContext, params);\n\t};\n\n\tconst submitPersonalizationSurvey = async (results: IPersonalizationLatestVersion) => {\n\t\tawait usersApi.submitPersonalizationSurvey(rootStore.restApiContext, results);\n\t\tsetPersonalizationAnswers(results);\n\t};\n\n\t// Synchronous: after the `ui.store` modal decoupling this only fires the injected\n\t// opener. All call sites invoke it fire-and-forget (`void ...`).\n\tconst showPersonalizationSurvey = () => {\n\t\tconst surveyEnabled = settingsStore.isPersonalizationSurveyEnabled;\n\t\tif (surveyEnabled && currentUser.value && !currentUser.value.personalizationAnswers) {\n\t\t\tmodalOpeners.value.openModal(PERSONALIZATION_MODAL_KEY);\n\t\t}\n\t};\n\n\tconst fetchMfaQR = async () => {\n\t\treturn await mfaApi.getMfaQR(rootStore.restApiContext);\n\t};\n\n\tconst verifyMfaCode = async (data: { mfaCode: string }) => {\n\t\treturn await mfaApi.verifyMfaCode(rootStore.restApiContext, data);\n\t};\n\n\tconst canEnableMFA = async () => {\n\t\treturn await mfaApi.canEnableMFA(rootStore.restApiContext);\n\t};\n\n\tconst enableMfa = async (data: { mfaCode: string }) => {\n\t\tawait mfaApi.enableMfa(rootStore.restApiContext, data);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = true;\n\t\t}\n\t};\n\n\tconst disableMfa = async (data: mfaApi.DisableMfaParams) => {\n\t\tawait mfaApi.disableMfa(rootStore.restApiContext, data);\n\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = false;\n\t\t}\n\t};\n\n\tconst updateEnforceMfa = async (enforce: boolean) => {\n\t\tawait mfaApi.updateEnforceMfa(rootStore.restApiContext, enforce);\n\t\tsettingsStore.isMFAEnforced = enforce;\n\t};\n\n\tconst sendConfirmationEmail = async () => {\n\t\tawait cloudApi.sendConfirmationEmail(rootStore.restApiContext);\n\t};\n\n\tconst updateGlobalRole = async ({ id, newRoleName }: UpdateGlobalRolePayload) => {\n\t\tawait usersApi.updateGlobalRole(rootStore.restApiContext, { id, newRoleName });\n\t\tawait fetchUsers({ filter: { ids: [id] } });\n\t};\n\n\tconst submitContactEmail = async (email: string, agree: boolean) => {\n\t\tif (currentUser.value) {\n\t\t\treturn await onboardingApi.submitEmailOnSignup(\n\t\t\t\trootStore.instanceId,\n\t\t\t\tcurrentUser.value,\n\t\t\t\temail ?? currentUser.value.email,\n\t\t\t\tagree,\n\t\t\t);\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst usersList = useAsyncState(\n\t\tasync (filter?: UsersListFilterDto) =>\n\t\t\tawait usersApi.getUsers(rootStore.restApiContext, filter),\n\t\t{\n\t\t\tcount: 0,\n\t\t\titems: [],\n\t\t},\n\t\t{ immediate: false, resetOnExecute: false },\n\t);\n\n\tconst setUserQuota = (quota?: number) => {\n\t\tif (typeof quota !== 'undefined') {\n\t\t\tuserQuota.value = quota;\n\t\t}\n\t};\n\n\treturn {\n\t\tinitialized,\n\t\tcurrentUserId,\n\t\tusersById,\n\t\tallUsers,\n\t\tcurrentUser,\n\t\tuserActivated,\n\t\tisDefaultUser,\n\t\tisInstanceOwner,\n\t\tisAdmin,\n\t\tisAdminOrOwner,\n\t\tmfaEnabled,\n\t\tglobalRoleName,\n\t\tuserClaimedAiCredits,\n\t\tisEasyAIWorkflowOnboardingDone,\n\t\tcanUserUpdateVersion,\n\t\tusersLimitNotReached,\n\t\taddUsers,\n\t\tloginWithCookie,\n\t\tinitialize,\n\t\tsetPersonalizationAnswers,\n\t\tloginWithCreds,\n\t\tlogout,\n\t\tregisterLoginHook,\n\t\tregisterLogoutHook,\n\t\tregisterModalOpeners,\n\t\tsetPermissionsResolvers,\n\t\tcreateOwner,\n\t\tvalidateSignupToken,\n\t\tacceptInvitation,\n\t\tsendForgotPasswordEmail,\n\t\tvalidatePasswordToken,\n\t\tchangePassword,\n\t\tupdateUser,\n\t\tupdateUserName,\n\t\tupdateUserSettings,\n\t\tupdateOtherUserSettings,\n\t\tupdateCurrentUserPassword,\n\t\tdeleteUser,\n\t\tfetchUsers,\n\t\tinviteUsers,\n\t\treinviteUser,\n\t\tgetUserPasswordResetLink,\n\t\tgenerateInviteLink,\n\t\tsubmitPersonalizationSurvey,\n\t\tshowPersonalizationSurvey,\n\t\tfetchMfaQR,\n\t\tverifyMfaCode,\n\t\tenableMfa,\n\t\tdisableMfa,\n\t\tupdateEnforceMfa,\n\t\tcanEnableMFA,\n\t\tsendConfirmationEmail,\n\t\tupdateGlobalRole,\n\t\tsetEasyAIWorkflowOnboardingDone,\n\t\tisCalloutDismissed,\n\t\tsetCalloutDismissed,\n\t\tsubmitContactEmail,\n\t\tsetUserQuota,\n\t\tusersList,\n\t};\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"users2.store.cjs","names":["ROLE","ResponseError","STORES","useRootStore","useSettingsStore","user: IUser","usersApi","redirectUrl: string | null","ssoApi","BROWSER_ID_STORAGE_KEY","acceptInvitation","inviteUsers","PERSONALIZATION_MODAL_KEY","mfaApi","cloudApi"],"sources":["../src/users.store.ts"],"sourcesContent":["import {\n\ttype LoginRequestDto,\n\ttype PasswordUpdateRequestDto,\n\ttype SettingsUpdateRequestDto,\n\ttype UserSelfSettingsUpdateRequestDto,\n\ttype UserUpdateRequestDto,\n\ttype User,\n\tROLE,\n\ttype UsersListFilterDto,\n} from '@n8n/api-types';\nimport { BROWSER_ID_STORAGE_KEY } from '@n8n/constants';\nimport { PERSONALIZATION_MODAL_KEY } from '@n8n/frontend-constants/users';\nimport type { AssignableGlobalRole } from '@n8n/permissions';\nimport { ResponseError } from '@n8n/rest-api-client';\nimport * as cloudApi from '@n8n/rest-api-client/api/cloudPlans';\nimport * as mfaApi from '@n8n/rest-api-client/api/mfa';\nimport * as ssoApi from '@n8n/rest-api-client/api/sso';\nimport type {\n\tUpdateGlobalRolePayload,\n\tIUserResponse,\n\tIUser,\n\tCurrentUserResponse,\n\tIPersonalizationLatestVersion,\n} from '@n8n/rest-api-client/api/users';\nimport * as usersApi from '@n8n/rest-api-client/api/users';\nimport { useAsyncState } from '@vueuse/core';\nimport { defineStore } from 'pinia';\nimport { computed, ref } from 'vue';\n\nimport { STORES } from './constants';\nimport * as invitationsApi from './invitation.api';\nimport type { ModalOpeners } from './modalOpeners';\nimport * as onboardingApi from './onboarding.api';\nimport { useSettingsStore } from './settings.store';\nimport { useRootStore } from './useRootStore';\n\nconst _isPendingUser = (user: IUserResponse | null) => !!user?.isPending;\nconst _isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Owner;\nconst _isDefaultUser = (user: IUserResponse | null) =>\n\t_isInstanceOwner(user) && _isPendingUser(user);\nconst _isAdmin = (user: IUserResponse | null) => user?.role === ROLE.Admin;\n\n// A 401 means the session was already dead server-side; any other error must still propagate.\nconst _isSessionAlreadyInvalid = (error: unknown) =>\n\terror instanceof ResponseError && error.httpStatusCode === 401;\n\nexport type LoginHook = (user: CurrentUserResponse) => void | Promise<void>;\ntype LogoutHook = () => void | Promise<void>;\n\nexport const useUsersStore = defineStore(STORES.USERS, () => {\n\tconst initialized = ref(false);\n\tconst currentUserId = ref<string | null>(null);\n\tconst usersById = ref<Record<string, IUser>>({});\n\tconst userQuota = ref<number>(-1);\n\n\tconst loginHooks = ref<LoginHook[]>([]);\n\tconst logoutHooks = ref<LogoutHook[]>([]);\n\n\t// Modal-open actions, registered at app bootstrap (see app/init.ts). Until then\n\t// they no-op — warning in dev — so the store never reaches into `ui.store`. Shares\n\t// the `ModalOpeners` contract with the other decoupled stores; this store currently\n\t// uses only `openModal`.\n\tconst warnModalOpenerMissing = (action: string) => {\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.warn(\n\t\t\t\t`[users.store] ${action} called before modal openers were registered; ignoring. Call registerModalOpeners() at app bootstrap.`,\n\t\t\t);\n\t\t}\n\t};\n\tconst modalOpeners = ref<ModalOpeners>({\n\t\topenModal: (name) => warnModalOpenerMissing(`openModal(${String(name)})`),\n\t\topenModalWithData: (payload) =>\n\t\t\twarnModalOpenerMissing(`openModalWithData(${String(payload.name)})`),\n\t});\n\tconst registerModalOpeners = (openers: ModalOpeners) => {\n\t\tmodalOpeners.value = openers;\n\t};\n\n\t// App-provided capabilities, registered at bootstrap (see app/init.ts) so the store\n\t// carries no `@/app` dependency. Both fall back to safe no-ops before registration.\n\n\t// Permission checks, keyed by capability (app RBAC checks; extend the object as\n\t// more permissions need resolving). `listUsers` gates the `user:list` scope.\n\tconst canListUsers = ref<() => boolean>(() => false);\n\tconst setPermissionsResolvers = (resolvers: { listUsers: () => boolean }) => {\n\t\tcanListUsers.value = resolvers.listUsers;\n\t};\n\n\t// Stores\n\n\tconst rootStore = useRootStore();\n\tconst settingsStore = useSettingsStore();\n\n\t// Computed\n\n\tconst allUsers = computed(() => Object.values(usersById.value));\n\n\tconst currentUser = computed(() =>\n\t\tcurrentUserId.value ? usersById.value[currentUserId.value] : null,\n\t);\n\n\tconst userActivated = computed(() => Boolean(currentUser.value?.settings?.userActivated));\n\n\tconst isDefaultUser = computed(() => _isDefaultUser(currentUser.value));\n\n\tconst isInstanceOwner = computed(() => _isInstanceOwner(currentUser.value));\n\n\tconst isAdmin = computed(() => _isAdmin(currentUser.value));\n\n\tconst isAdminOrOwner = computed(() => isInstanceOwner.value || isAdmin.value);\n\n\tconst mfaEnabled = computed(() => currentUser.value?.mfaEnabled ?? false);\n\n\tconst globalRoleName = computed(() => currentUser.value?.role ?? 'default');\n\n\tconst userClaimedAiCredits = computed(() => currentUser.value?.settings?.userClaimedAiCredits);\n\n\tconst isEasyAIWorkflowOnboardingDone = computed(() =>\n\t\tBoolean(currentUser.value?.settings?.easyAIWorkflowOnboarded),\n\t);\n\n\tconst canUserUpdateVersion = computed(() => {\n\t\treturn isInstanceOwner.value;\n\t});\n\n\tconst setEasyAIWorkflowOnboardingDone = () => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.easyAIWorkflowOnboarded = true;\n\t\t}\n\t};\n\n\tconst isCalloutDismissed = (callout: string) =>\n\t\tBoolean(currentUser.value?.settings?.dismissedCallouts?.[callout]);\n\n\tconst setCalloutDismissed = (callout: string) => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.dismissedCallouts ??= {};\n\n\t\t\tcurrentUser.value.settings.dismissedCallouts[callout] = true;\n\t\t}\n\t};\n\n\tconst usersLimitNotReached = computed(\n\t\t(): boolean => userQuota.value === -1 || userQuota.value > allUsers.value.length,\n\t);\n\n\t// Methods\n\n\tconst addUsers = (newUsers: User[]) => {\n\t\tnewUsers.forEach((userResponse) => {\n\t\t\tconst prevUser = usersById.value[userResponse.id] || {};\n\t\t\tconst updatedUser = {\n\t\t\t\t...prevUser,\n\t\t\t\t...userResponse,\n\t\t\t};\n\t\t\tconst user: IUser = {\n\t\t\t\t...updatedUser,\n\t\t\t\tfullName: userResponse.firstName\n\t\t\t\t\t? `${updatedUser.firstName} ${updatedUser.lastName ?? ''}`\n\t\t\t\t\t: undefined,\n\t\t\t\tisDefaultUser: _isDefaultUser(updatedUser),\n\t\t\t\tisPendingUser: _isPendingUser(updatedUser),\n\t\t\t};\n\n\t\t\tusersById.value = {\n\t\t\t\t...usersById.value,\n\t\t\t\t[user.id]: user,\n\t\t\t};\n\t\t});\n\t};\n\n\tconst setCurrentUser = async (user: CurrentUserResponse) => {\n\t\taddUsers([user]);\n\t\tcurrentUserId.value = user.id;\n\n\t\tfor (const hook of loginHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook(user);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing login hook:', error);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst loginWithCookie = async () => {\n\t\tconst user = await usersApi.loginCurrentUser(rootStore.restApiContext);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst initialize = async () => {\n\t\tif (initialized.value) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait loginWithCookie();\n\t\t\tinitialized.value = true;\n\t\t} catch {\n\t\t\t// A missing or expired auth cookie before setup is expected; leave the store\n\t\t\t// uninitialized and let the caller proceed to the login/setup flow.\n\t\t}\n\t};\n\n\tconst unsetCurrentUser = () => {\n\t\tcurrentUserId.value = null;\n\t};\n\n\tconst deleteUserById = (userId: string) => {\n\t\tconst { [userId]: _, ...rest } = usersById.value;\n\t\tusersById.value = rest;\n\t};\n\n\tconst setPersonalizationAnswers = (answers: IPersonalizationLatestVersion) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\tusersById.value = {\n\t\t\t...usersById.value,\n\t\t\t[currentUser.value.id]: {\n\t\t\t\t...currentUser.value,\n\t\t\t\tpersonalizationAnswers: answers,\n\t\t\t},\n\t\t};\n\t};\n\n\tconst loginWithCreds = async (params: LoginRequestDto) => {\n\t\tconst user = await usersApi.login(rootStore.restApiContext, params);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst registerLoginHook = (hook: LoginHook) => {\n\t\tloginHooks.value.push(hook);\n\t};\n\n\tconst registerLogoutHook = (hook: LogoutHook) => {\n\t\tlogoutHooks.value.push(hook);\n\t};\n\n\tconst standardLogout = async () => {\n\t\ttry {\n\t\t\tawait usersApi.logout(rootStore.restApiContext);\n\t\t} catch (error) {\n\t\t\tif (!_isSessionAlreadyInvalid(error)) throw error;\n\t\t}\n\t};\n\n\tconst logout = async (options?: { viaOidc?: boolean }) => {\n\t\tlet redirectUrl: string | null = null;\n\n\t\tif (options?.viaOidc) {\n\t\t\ttry {\n\t\t\t\t({ redirectUrl } = await ssoApi.oidcLogout(rootStore.restApiContext));\n\t\t\t} catch {\n\t\t\t\t// The OIDC logout endpoint may be unavailable (e.g. the license\n\t\t\t\t// lapsed since login). Fall back to the standard logout so the\n\t\t\t\t// n8n session is terminated in any case.\n\t\t\t\tawait standardLogout();\n\t\t\t}\n\t\t} else {\n\t\t\tawait standardLogout();\n\t\t}\n\n\t\tunsetCurrentUser();\n\n\t\tfor (const hook of logoutHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing logout hook:', error);\n\t\t\t}\n\t\t}\n\n\t\tlocalStorage.removeItem(BROWSER_ID_STORAGE_KEY);\n\n\t\treturn { redirectUrl };\n\t};\n\n\tconst createOwner = async (params: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\temail: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await usersApi.setupOwner(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t\tsettingsStore.stopShowingSetupPage();\n\t\t}\n\t};\n\n\tconst validateSignupToken = async (params: { token: string }) => {\n\t\treturn await usersApi.validateSignupToken(rootStore.restApiContext, params);\n\t};\n\n\tconst acceptInvitation = async (params: {\n\t\ttoken: string;\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await invitationsApi.acceptInvitation(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t}\n\t};\n\n\tconst sendForgotPasswordEmail = async (params: { email: string }) => {\n\t\tawait usersApi.sendForgotPasswordEmail(rootStore.restApiContext, params);\n\t};\n\n\tconst validatePasswordToken = async (params: { token: string }) => {\n\t\tawait usersApi.validatePasswordToken(rootStore.restApiContext, params);\n\t};\n\n\tconst changePassword = async (params: { token: string; password: string; mfaCode?: string }) => {\n\t\tawait usersApi.changePassword(rootStore.restApiContext, params);\n\t};\n\n\tconst updateUser = async (params: UserUpdateRequestDto) => {\n\t\tconst user = await usersApi.updateCurrentUser(rootStore.restApiContext, params);\n\t\taddUsers([user]);\n\t\treturn user;\n\t};\n\n\tconst updateUserName = async (params: { firstName: string; lastName: string }) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn await updateUser({\n\t\t\temail: currentUser.value.email as string,\n\t\t\t...params,\n\t\t});\n\t};\n\n\tconst updateUserSettings = async (settings: UserSelfSettingsUpdateRequestDto) => {\n\t\tconst updatedSettings = await usersApi.updateCurrentUserSettings(\n\t\t\trootStore.restApiContext,\n\t\t\tsettings,\n\t\t);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.settings = updatedSettings;\n\t\t\taddUsers([currentUser.value]);\n\t\t}\n\t};\n\n\tconst updateOtherUserSettings = async (userId: string, settings: SettingsUpdateRequestDto) => {\n\t\tawait usersApi.updateOtherUserSettings(rootStore.restApiContext, userId, settings);\n\t};\n\n\tconst updateCurrentUserPassword = async (params: PasswordUpdateRequestDto) => {\n\t\tawait usersApi.updateCurrentUserPassword(rootStore.restApiContext, params);\n\t};\n\n\tconst deleteUser = async (params: { id: string; transferId?: string }) => {\n\t\tawait usersApi.deleteUser(rootStore.restApiContext, params);\n\t\tdeleteUserById(params.id);\n\t};\n\n\tconst fetchUsers = async ({\n\t\ttake,\n\t\tskip,\n\t\tfilter,\n\t}: { take?: number; skip?: number; filter?: UsersListFilterDto['filter'] } = {}) => {\n\t\tif (!canListUsers.value()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { items } = await usersApi.getUsers(rootStore.restApiContext, {\n\t\t\ttake: take ?? 50,\n\t\t\tskip: skip ?? 0,\n\t\t\tfilter,\n\t\t});\n\t\taddUsers(items);\n\t};\n\n\tconst inviteUsers = async (params: Array<{ email: string; role: AssignableGlobalRole }>) => {\n\t\tconst invitedUsers = await invitationsApi.inviteUsers(rootStore.restApiContext, params);\n\t\taddUsers(\n\t\t\tinvitedUsers.map(({ user }) => ({\n\t\t\t\tisPending: true,\n\t\t\t\t...user,\n\t\t\t})),\n\t\t);\n\t\treturn invitedUsers;\n\t};\n\n\tconst reinviteUser = async ({ email, role }: { email: string; role: AssignableGlobalRole }) => {\n\t\tconst invitationResponse = await invitationsApi.inviteUsers(rootStore.restApiContext, [\n\t\t\t{ email, role },\n\t\t]);\n\t\tif (!invitationResponse[0].user.emailSent) {\n\t\t\tthrow Error(invitationResponse[0].error);\n\t\t}\n\t};\n\n\tconst getUserPasswordResetLink = async (params: { id: string }) => {\n\t\treturn await usersApi.getPasswordResetLink(rootStore.restApiContext, params);\n\t};\n\n\tconst generateInviteLink = async (params: { id: string }) => {\n\t\treturn await usersApi.generateInviteLink(rootStore.restApiContext, params);\n\t};\n\n\tconst submitPersonalizationSurvey = async (results: IPersonalizationLatestVersion) => {\n\t\tawait usersApi.submitPersonalizationSurvey(rootStore.restApiContext, results);\n\t\tsetPersonalizationAnswers(results);\n\t};\n\n\t// Synchronous: after the `ui.store` modal decoupling this only fires the injected\n\t// opener. All call sites invoke it fire-and-forget (`void ...`).\n\tconst showPersonalizationSurvey = () => {\n\t\tconst surveyEnabled = settingsStore.isPersonalizationSurveyEnabled;\n\t\tif (surveyEnabled && currentUser.value && !currentUser.value.personalizationAnswers) {\n\t\t\tmodalOpeners.value.openModal(PERSONALIZATION_MODAL_KEY);\n\t\t}\n\t};\n\n\tconst fetchMfaQR = async () => {\n\t\treturn await mfaApi.getMfaQR(rootStore.restApiContext);\n\t};\n\n\tconst verifyMfaCode = async (data: { mfaCode: string }) => {\n\t\treturn await mfaApi.verifyMfaCode(rootStore.restApiContext, data);\n\t};\n\n\tconst canEnableMFA = async () => {\n\t\treturn await mfaApi.canEnableMFA(rootStore.restApiContext);\n\t};\n\n\tconst enableMfa = async (data: { mfaCode: string }) => {\n\t\tawait mfaApi.enableMfa(rootStore.restApiContext, data);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = true;\n\t\t}\n\t};\n\n\tconst disableMfa = async (data: mfaApi.DisableMfaParams) => {\n\t\tawait mfaApi.disableMfa(rootStore.restApiContext, data);\n\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = false;\n\t\t}\n\t};\n\n\tconst updateEnforceMfa = async (enforce: boolean) => {\n\t\tawait mfaApi.updateEnforceMfa(rootStore.restApiContext, enforce);\n\t\tsettingsStore.isMFAEnforced = enforce;\n\t};\n\n\tconst sendConfirmationEmail = async () => {\n\t\tawait cloudApi.sendConfirmationEmail(rootStore.restApiContext);\n\t};\n\n\tconst updateGlobalRole = async ({ id, newRoleName }: UpdateGlobalRolePayload) => {\n\t\tawait usersApi.updateGlobalRole(rootStore.restApiContext, { id, newRoleName });\n\t\tawait fetchUsers({ filter: { ids: [id] } });\n\t};\n\n\tconst submitContactEmail = async (email: string, agree: boolean) => {\n\t\tif (currentUser.value) {\n\t\t\treturn await onboardingApi.submitEmailOnSignup(\n\t\t\t\trootStore.instanceId,\n\t\t\t\tcurrentUser.value,\n\t\t\t\temail ?? currentUser.value.email,\n\t\t\t\tagree,\n\t\t\t);\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst usersList = useAsyncState(\n\t\tasync (filter?: UsersListFilterDto) =>\n\t\t\tawait usersApi.getUsers(rootStore.restApiContext, filter),\n\t\t{\n\t\t\tcount: 0,\n\t\t\titems: [],\n\t\t},\n\t\t{ immediate: false, resetOnExecute: false },\n\t);\n\n\tconst setUserQuota = (quota?: number) => {\n\t\tif (typeof quota !== 'undefined') {\n\t\t\tuserQuota.value = quota;\n\t\t}\n\t};\n\n\treturn {\n\t\tinitialized,\n\t\tcurrentUserId,\n\t\tusersById,\n\t\tallUsers,\n\t\tcurrentUser,\n\t\tuserActivated,\n\t\tisDefaultUser,\n\t\tisInstanceOwner,\n\t\tisAdmin,\n\t\tisAdminOrOwner,\n\t\tmfaEnabled,\n\t\tglobalRoleName,\n\t\tuserClaimedAiCredits,\n\t\tisEasyAIWorkflowOnboardingDone,\n\t\tcanUserUpdateVersion,\n\t\tusersLimitNotReached,\n\t\taddUsers,\n\t\tloginWithCookie,\n\t\tinitialize,\n\t\tsetPersonalizationAnswers,\n\t\tloginWithCreds,\n\t\tlogout,\n\t\tregisterLoginHook,\n\t\tregisterLogoutHook,\n\t\tregisterModalOpeners,\n\t\tsetPermissionsResolvers,\n\t\tcreateOwner,\n\t\tvalidateSignupToken,\n\t\tacceptInvitation,\n\t\tsendForgotPasswordEmail,\n\t\tvalidatePasswordToken,\n\t\tchangePassword,\n\t\tupdateUser,\n\t\tupdateUserName,\n\t\tupdateUserSettings,\n\t\tupdateOtherUserSettings,\n\t\tupdateCurrentUserPassword,\n\t\tdeleteUser,\n\t\tfetchUsers,\n\t\tinviteUsers,\n\t\treinviteUser,\n\t\tgetUserPasswordResetLink,\n\t\tgenerateInviteLink,\n\t\tsubmitPersonalizationSurvey,\n\t\tshowPersonalizationSurvey,\n\t\tfetchMfaQR,\n\t\tverifyMfaCode,\n\t\tenableMfa,\n\t\tdisableMfa,\n\t\tupdateEnforceMfa,\n\t\tcanEnableMFA,\n\t\tsendConfirmationEmail,\n\t\tupdateGlobalRole,\n\t\tsetEasyAIWorkflowOnboardingDone,\n\t\tisCalloutDismissed,\n\t\tsetCalloutDismissed,\n\t\tsubmitContactEmail,\n\t\tsetUserQuota,\n\t\tusersList,\n\t};\n});\n"],"mappings":"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"}
@@ -7,6 +7,7 @@ import * as cloudApi from "@n8n/rest-api-client/api/cloudPlans";
7
7
  import { defineStore } from "pinia";
8
8
  import { computed, ref } from "vue";
9
9
  import { ROLE } from "@n8n/api-types";
10
+ import { ResponseError } from "@n8n/rest-api-client";
10
11
  import { useAsyncState } from "@vueuse/core";
11
12
  import { BROWSER_ID_STORAGE_KEY } from "@n8n/constants";
12
13
  import { PERSONALIZATION_MODAL_KEY } from "@n8n/frontend-constants/users";
@@ -19,6 +20,7 @@ const _isPendingUser = (user) => !!user?.isPending;
19
20
  const _isInstanceOwner = (user) => user?.role === ROLE.Owner;
20
21
  const _isDefaultUser = (user) => _isInstanceOwner(user) && _isPendingUser(user);
21
22
  const _isAdmin = (user) => user?.role === ROLE.Admin;
23
+ const _isSessionAlreadyInvalid = (error) => error instanceof ResponseError && error.httpStatusCode === 401;
22
24
  const useUsersStore = defineStore(STORES.USERS, () => {
23
25
  const initialized = ref(false);
24
26
  const currentUserId = ref(null);
@@ -134,14 +136,21 @@ const useUsersStore = defineStore(STORES.USERS, () => {
134
136
  const registerLogoutHook = (hook) => {
135
137
  logoutHooks.value.push(hook);
136
138
  };
139
+ const standardLogout = async () => {
140
+ try {
141
+ await usersApi.logout(rootStore.restApiContext);
142
+ } catch (error) {
143
+ if (!_isSessionAlreadyInvalid(error)) throw error;
144
+ }
145
+ };
137
146
  const logout = async (options) => {
138
147
  let redirectUrl = null;
139
148
  if (options?.viaOidc) try {
140
149
  ({redirectUrl} = await ssoApi.oidcLogout(rootStore.restApiContext));
141
150
  } catch {
142
- await usersApi.logout(rootStore.restApiContext);
151
+ await standardLogout();
143
152
  }
144
- else await usersApi.logout(rootStore.restApiContext);
153
+ else await standardLogout();
145
154
  unsetCurrentUser();
146
155
  for (const hook of logoutHooks.value) try {
147
156
  await hook();
@@ -1 +1 @@
1
- {"version":3,"file":"users2.store.mjs","names":["user: IUser","redirectUrl: string | null","acceptInvitation","invitationsApi.acceptInvitation","inviteUsers","invitationsApi.inviteUsers","onboardingApi.submitEmailOnSignup"],"sources":["../src/users.store.ts"],"sourcesContent":["import {\n\ttype LoginRequestDto,\n\ttype PasswordUpdateRequestDto,\n\ttype SettingsUpdateRequestDto,\n\ttype UserSelfSettingsUpdateRequestDto,\n\ttype UserUpdateRequestDto,\n\ttype User,\n\tROLE,\n\ttype UsersListFilterDto,\n} from '@n8n/api-types';\nimport { BROWSER_ID_STORAGE_KEY } from '@n8n/constants';\nimport { PERSONALIZATION_MODAL_KEY } from '@n8n/frontend-constants/users';\nimport type { AssignableGlobalRole } from '@n8n/permissions';\nimport * as cloudApi from '@n8n/rest-api-client/api/cloudPlans';\nimport * as mfaApi from '@n8n/rest-api-client/api/mfa';\nimport * as ssoApi from '@n8n/rest-api-client/api/sso';\nimport type {\n\tUpdateGlobalRolePayload,\n\tIUserResponse,\n\tIUser,\n\tCurrentUserResponse,\n\tIPersonalizationLatestVersion,\n} from '@n8n/rest-api-client/api/users';\nimport * as usersApi from '@n8n/rest-api-client/api/users';\nimport { useAsyncState } from '@vueuse/core';\nimport { defineStore } from 'pinia';\nimport { computed, ref } from 'vue';\n\nimport { STORES } from './constants';\nimport * as invitationsApi from './invitation.api';\nimport type { ModalOpeners } from './modalOpeners';\nimport * as onboardingApi from './onboarding.api';\nimport { useSettingsStore } from './settings.store';\nimport { useRootStore } from './useRootStore';\n\nconst _isPendingUser = (user: IUserResponse | null) => !!user?.isPending;\nconst _isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Owner;\nconst _isDefaultUser = (user: IUserResponse | null) =>\n\t_isInstanceOwner(user) && _isPendingUser(user);\nconst _isAdmin = (user: IUserResponse | null) => user?.role === ROLE.Admin;\n\nexport type LoginHook = (user: CurrentUserResponse) => void | Promise<void>;\ntype LogoutHook = () => void | Promise<void>;\n\nexport const useUsersStore = defineStore(STORES.USERS, () => {\n\tconst initialized = ref(false);\n\tconst currentUserId = ref<string | null>(null);\n\tconst usersById = ref<Record<string, IUser>>({});\n\tconst userQuota = ref<number>(-1);\n\n\tconst loginHooks = ref<LoginHook[]>([]);\n\tconst logoutHooks = ref<LogoutHook[]>([]);\n\n\t// Modal-open actions, registered at app bootstrap (see app/init.ts). Until then\n\t// they no-op — warning in dev — so the store never reaches into `ui.store`. Shares\n\t// the `ModalOpeners` contract with the other decoupled stores; this store currently\n\t// uses only `openModal`.\n\tconst warnModalOpenerMissing = (action: string) => {\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.warn(\n\t\t\t\t`[users.store] ${action} called before modal openers were registered; ignoring. Call registerModalOpeners() at app bootstrap.`,\n\t\t\t);\n\t\t}\n\t};\n\tconst modalOpeners = ref<ModalOpeners>({\n\t\topenModal: (name) => warnModalOpenerMissing(`openModal(${String(name)})`),\n\t\topenModalWithData: (payload) =>\n\t\t\twarnModalOpenerMissing(`openModalWithData(${String(payload.name)})`),\n\t});\n\tconst registerModalOpeners = (openers: ModalOpeners) => {\n\t\tmodalOpeners.value = openers;\n\t};\n\n\t// App-provided capabilities, registered at bootstrap (see app/init.ts) so the store\n\t// carries no `@/app` dependency. Both fall back to safe no-ops before registration.\n\n\t// Permission checks, keyed by capability (app RBAC checks; extend the object as\n\t// more permissions need resolving). `listUsers` gates the `user:list` scope.\n\tconst canListUsers = ref<() => boolean>(() => false);\n\tconst setPermissionsResolvers = (resolvers: { listUsers: () => boolean }) => {\n\t\tcanListUsers.value = resolvers.listUsers;\n\t};\n\n\t// Stores\n\n\tconst rootStore = useRootStore();\n\tconst settingsStore = useSettingsStore();\n\n\t// Computed\n\n\tconst allUsers = computed(() => Object.values(usersById.value));\n\n\tconst currentUser = computed(() =>\n\t\tcurrentUserId.value ? usersById.value[currentUserId.value] : null,\n\t);\n\n\tconst userActivated = computed(() => Boolean(currentUser.value?.settings?.userActivated));\n\n\tconst isDefaultUser = computed(() => _isDefaultUser(currentUser.value));\n\n\tconst isInstanceOwner = computed(() => _isInstanceOwner(currentUser.value));\n\n\tconst isAdmin = computed(() => _isAdmin(currentUser.value));\n\n\tconst isAdminOrOwner = computed(() => isInstanceOwner.value || isAdmin.value);\n\n\tconst mfaEnabled = computed(() => currentUser.value?.mfaEnabled ?? false);\n\n\tconst globalRoleName = computed(() => currentUser.value?.role ?? 'default');\n\n\tconst userClaimedAiCredits = computed(() => currentUser.value?.settings?.userClaimedAiCredits);\n\n\tconst isEasyAIWorkflowOnboardingDone = computed(() =>\n\t\tBoolean(currentUser.value?.settings?.easyAIWorkflowOnboarded),\n\t);\n\n\tconst canUserUpdateVersion = computed(() => {\n\t\treturn isInstanceOwner.value;\n\t});\n\n\tconst setEasyAIWorkflowOnboardingDone = () => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.easyAIWorkflowOnboarded = true;\n\t\t}\n\t};\n\n\tconst isCalloutDismissed = (callout: string) =>\n\t\tBoolean(currentUser.value?.settings?.dismissedCallouts?.[callout]);\n\n\tconst setCalloutDismissed = (callout: string) => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.dismissedCallouts ??= {};\n\n\t\t\tcurrentUser.value.settings.dismissedCallouts[callout] = true;\n\t\t}\n\t};\n\n\tconst usersLimitNotReached = computed(\n\t\t(): boolean => userQuota.value === -1 || userQuota.value > allUsers.value.length,\n\t);\n\n\t// Methods\n\n\tconst addUsers = (newUsers: User[]) => {\n\t\tnewUsers.forEach((userResponse) => {\n\t\t\tconst prevUser = usersById.value[userResponse.id] || {};\n\t\t\tconst updatedUser = {\n\t\t\t\t...prevUser,\n\t\t\t\t...userResponse,\n\t\t\t};\n\t\t\tconst user: IUser = {\n\t\t\t\t...updatedUser,\n\t\t\t\tfullName: userResponse.firstName\n\t\t\t\t\t? `${updatedUser.firstName} ${updatedUser.lastName ?? ''}`\n\t\t\t\t\t: undefined,\n\t\t\t\tisDefaultUser: _isDefaultUser(updatedUser),\n\t\t\t\tisPendingUser: _isPendingUser(updatedUser),\n\t\t\t};\n\n\t\t\tusersById.value = {\n\t\t\t\t...usersById.value,\n\t\t\t\t[user.id]: user,\n\t\t\t};\n\t\t});\n\t};\n\n\tconst setCurrentUser = async (user: CurrentUserResponse) => {\n\t\taddUsers([user]);\n\t\tcurrentUserId.value = user.id;\n\n\t\tfor (const hook of loginHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook(user);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing login hook:', error);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst loginWithCookie = async () => {\n\t\tconst user = await usersApi.loginCurrentUser(rootStore.restApiContext);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst initialize = async () => {\n\t\tif (initialized.value) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait loginWithCookie();\n\t\t\tinitialized.value = true;\n\t\t} catch {\n\t\t\t// A missing or expired auth cookie before setup is expected; leave the store\n\t\t\t// uninitialized and let the caller proceed to the login/setup flow.\n\t\t}\n\t};\n\n\tconst unsetCurrentUser = () => {\n\t\tcurrentUserId.value = null;\n\t};\n\n\tconst deleteUserById = (userId: string) => {\n\t\tconst { [userId]: _, ...rest } = usersById.value;\n\t\tusersById.value = rest;\n\t};\n\n\tconst setPersonalizationAnswers = (answers: IPersonalizationLatestVersion) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\tusersById.value = {\n\t\t\t...usersById.value,\n\t\t\t[currentUser.value.id]: {\n\t\t\t\t...currentUser.value,\n\t\t\t\tpersonalizationAnswers: answers,\n\t\t\t},\n\t\t};\n\t};\n\n\tconst loginWithCreds = async (params: LoginRequestDto) => {\n\t\tconst user = await usersApi.login(rootStore.restApiContext, params);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst registerLoginHook = (hook: LoginHook) => {\n\t\tloginHooks.value.push(hook);\n\t};\n\n\tconst registerLogoutHook = (hook: LogoutHook) => {\n\t\tlogoutHooks.value.push(hook);\n\t};\n\n\tconst logout = async (options?: { viaOidc?: boolean }) => {\n\t\tlet redirectUrl: string | null = null;\n\n\t\tif (options?.viaOidc) {\n\t\t\ttry {\n\t\t\t\t({ redirectUrl } = await ssoApi.oidcLogout(rootStore.restApiContext));\n\t\t\t} catch {\n\t\t\t\t// The OIDC logout endpoint may be unavailable (e.g. the license\n\t\t\t\t// lapsed since login). Fall back to the standard logout so the\n\t\t\t\t// n8n session is terminated in any case.\n\t\t\t\tawait usersApi.logout(rootStore.restApiContext);\n\t\t\t}\n\t\t} else {\n\t\t\tawait usersApi.logout(rootStore.restApiContext);\n\t\t}\n\n\t\tunsetCurrentUser();\n\n\t\tfor (const hook of logoutHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing logout hook:', error);\n\t\t\t}\n\t\t}\n\n\t\tlocalStorage.removeItem(BROWSER_ID_STORAGE_KEY);\n\n\t\treturn { redirectUrl };\n\t};\n\n\tconst createOwner = async (params: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\temail: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await usersApi.setupOwner(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t\tsettingsStore.stopShowingSetupPage();\n\t\t}\n\t};\n\n\tconst validateSignupToken = async (params: { token: string }) => {\n\t\treturn await usersApi.validateSignupToken(rootStore.restApiContext, params);\n\t};\n\n\tconst acceptInvitation = async (params: {\n\t\ttoken: string;\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await invitationsApi.acceptInvitation(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t}\n\t};\n\n\tconst sendForgotPasswordEmail = async (params: { email: string }) => {\n\t\tawait usersApi.sendForgotPasswordEmail(rootStore.restApiContext, params);\n\t};\n\n\tconst validatePasswordToken = async (params: { token: string }) => {\n\t\tawait usersApi.validatePasswordToken(rootStore.restApiContext, params);\n\t};\n\n\tconst changePassword = async (params: { token: string; password: string; mfaCode?: string }) => {\n\t\tawait usersApi.changePassword(rootStore.restApiContext, params);\n\t};\n\n\tconst updateUser = async (params: UserUpdateRequestDto) => {\n\t\tconst user = await usersApi.updateCurrentUser(rootStore.restApiContext, params);\n\t\taddUsers([user]);\n\t\treturn user;\n\t};\n\n\tconst updateUserName = async (params: { firstName: string; lastName: string }) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn await updateUser({\n\t\t\temail: currentUser.value.email as string,\n\t\t\t...params,\n\t\t});\n\t};\n\n\tconst updateUserSettings = async (settings: UserSelfSettingsUpdateRequestDto) => {\n\t\tconst updatedSettings = await usersApi.updateCurrentUserSettings(\n\t\t\trootStore.restApiContext,\n\t\t\tsettings,\n\t\t);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.settings = updatedSettings;\n\t\t\taddUsers([currentUser.value]);\n\t\t}\n\t};\n\n\tconst updateOtherUserSettings = async (userId: string, settings: SettingsUpdateRequestDto) => {\n\t\tawait usersApi.updateOtherUserSettings(rootStore.restApiContext, userId, settings);\n\t};\n\n\tconst updateCurrentUserPassword = async (params: PasswordUpdateRequestDto) => {\n\t\tawait usersApi.updateCurrentUserPassword(rootStore.restApiContext, params);\n\t};\n\n\tconst deleteUser = async (params: { id: string; transferId?: string }) => {\n\t\tawait usersApi.deleteUser(rootStore.restApiContext, params);\n\t\tdeleteUserById(params.id);\n\t};\n\n\tconst fetchUsers = async ({\n\t\ttake,\n\t\tskip,\n\t\tfilter,\n\t}: { take?: number; skip?: number; filter?: UsersListFilterDto['filter'] } = {}) => {\n\t\tif (!canListUsers.value()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { items } = await usersApi.getUsers(rootStore.restApiContext, {\n\t\t\ttake: take ?? 50,\n\t\t\tskip: skip ?? 0,\n\t\t\tfilter,\n\t\t});\n\t\taddUsers(items);\n\t};\n\n\tconst inviteUsers = async (params: Array<{ email: string; role: AssignableGlobalRole }>) => {\n\t\tconst invitedUsers = await invitationsApi.inviteUsers(rootStore.restApiContext, params);\n\t\taddUsers(\n\t\t\tinvitedUsers.map(({ user }) => ({\n\t\t\t\tisPending: true,\n\t\t\t\t...user,\n\t\t\t})),\n\t\t);\n\t\treturn invitedUsers;\n\t};\n\n\tconst reinviteUser = async ({ email, role }: { email: string; role: AssignableGlobalRole }) => {\n\t\tconst invitationResponse = await invitationsApi.inviteUsers(rootStore.restApiContext, [\n\t\t\t{ email, role },\n\t\t]);\n\t\tif (!invitationResponse[0].user.emailSent) {\n\t\t\tthrow Error(invitationResponse[0].error);\n\t\t}\n\t};\n\n\tconst getUserPasswordResetLink = async (params: { id: string }) => {\n\t\treturn await usersApi.getPasswordResetLink(rootStore.restApiContext, params);\n\t};\n\n\tconst generateInviteLink = async (params: { id: string }) => {\n\t\treturn await usersApi.generateInviteLink(rootStore.restApiContext, params);\n\t};\n\n\tconst submitPersonalizationSurvey = async (results: IPersonalizationLatestVersion) => {\n\t\tawait usersApi.submitPersonalizationSurvey(rootStore.restApiContext, results);\n\t\tsetPersonalizationAnswers(results);\n\t};\n\n\t// Synchronous: after the `ui.store` modal decoupling this only fires the injected\n\t// opener. All call sites invoke it fire-and-forget (`void ...`).\n\tconst showPersonalizationSurvey = () => {\n\t\tconst surveyEnabled = settingsStore.isPersonalizationSurveyEnabled;\n\t\tif (surveyEnabled && currentUser.value && !currentUser.value.personalizationAnswers) {\n\t\t\tmodalOpeners.value.openModal(PERSONALIZATION_MODAL_KEY);\n\t\t}\n\t};\n\n\tconst fetchMfaQR = async () => {\n\t\treturn await mfaApi.getMfaQR(rootStore.restApiContext);\n\t};\n\n\tconst verifyMfaCode = async (data: { mfaCode: string }) => {\n\t\treturn await mfaApi.verifyMfaCode(rootStore.restApiContext, data);\n\t};\n\n\tconst canEnableMFA = async () => {\n\t\treturn await mfaApi.canEnableMFA(rootStore.restApiContext);\n\t};\n\n\tconst enableMfa = async (data: { mfaCode: string }) => {\n\t\tawait mfaApi.enableMfa(rootStore.restApiContext, data);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = true;\n\t\t}\n\t};\n\n\tconst disableMfa = async (data: mfaApi.DisableMfaParams) => {\n\t\tawait mfaApi.disableMfa(rootStore.restApiContext, data);\n\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = false;\n\t\t}\n\t};\n\n\tconst updateEnforceMfa = async (enforce: boolean) => {\n\t\tawait mfaApi.updateEnforceMfa(rootStore.restApiContext, enforce);\n\t\tsettingsStore.isMFAEnforced = enforce;\n\t};\n\n\tconst sendConfirmationEmail = async () => {\n\t\tawait cloudApi.sendConfirmationEmail(rootStore.restApiContext);\n\t};\n\n\tconst updateGlobalRole = async ({ id, newRoleName }: UpdateGlobalRolePayload) => {\n\t\tawait usersApi.updateGlobalRole(rootStore.restApiContext, { id, newRoleName });\n\t\tawait fetchUsers({ filter: { ids: [id] } });\n\t};\n\n\tconst submitContactEmail = async (email: string, agree: boolean) => {\n\t\tif (currentUser.value) {\n\t\t\treturn await onboardingApi.submitEmailOnSignup(\n\t\t\t\trootStore.instanceId,\n\t\t\t\tcurrentUser.value,\n\t\t\t\temail ?? currentUser.value.email,\n\t\t\t\tagree,\n\t\t\t);\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst usersList = useAsyncState(\n\t\tasync (filter?: UsersListFilterDto) =>\n\t\t\tawait usersApi.getUsers(rootStore.restApiContext, filter),\n\t\t{\n\t\t\tcount: 0,\n\t\t\titems: [],\n\t\t},\n\t\t{ immediate: false, resetOnExecute: false },\n\t);\n\n\tconst setUserQuota = (quota?: number) => {\n\t\tif (typeof quota !== 'undefined') {\n\t\t\tuserQuota.value = quota;\n\t\t}\n\t};\n\n\treturn {\n\t\tinitialized,\n\t\tcurrentUserId,\n\t\tusersById,\n\t\tallUsers,\n\t\tcurrentUser,\n\t\tuserActivated,\n\t\tisDefaultUser,\n\t\tisInstanceOwner,\n\t\tisAdmin,\n\t\tisAdminOrOwner,\n\t\tmfaEnabled,\n\t\tglobalRoleName,\n\t\tuserClaimedAiCredits,\n\t\tisEasyAIWorkflowOnboardingDone,\n\t\tcanUserUpdateVersion,\n\t\tusersLimitNotReached,\n\t\taddUsers,\n\t\tloginWithCookie,\n\t\tinitialize,\n\t\tsetPersonalizationAnswers,\n\t\tloginWithCreds,\n\t\tlogout,\n\t\tregisterLoginHook,\n\t\tregisterLogoutHook,\n\t\tregisterModalOpeners,\n\t\tsetPermissionsResolvers,\n\t\tcreateOwner,\n\t\tvalidateSignupToken,\n\t\tacceptInvitation,\n\t\tsendForgotPasswordEmail,\n\t\tvalidatePasswordToken,\n\t\tchangePassword,\n\t\tupdateUser,\n\t\tupdateUserName,\n\t\tupdateUserSettings,\n\t\tupdateOtherUserSettings,\n\t\tupdateCurrentUserPassword,\n\t\tdeleteUser,\n\t\tfetchUsers,\n\t\tinviteUsers,\n\t\treinviteUser,\n\t\tgetUserPasswordResetLink,\n\t\tgenerateInviteLink,\n\t\tsubmitPersonalizationSurvey,\n\t\tshowPersonalizationSurvey,\n\t\tfetchMfaQR,\n\t\tverifyMfaCode,\n\t\tenableMfa,\n\t\tdisableMfa,\n\t\tupdateEnforceMfa,\n\t\tcanEnableMFA,\n\t\tsendConfirmationEmail,\n\t\tupdateGlobalRole,\n\t\tsetEasyAIWorkflowOnboardingDone,\n\t\tisCalloutDismissed,\n\t\tsetCalloutDismissed,\n\t\tsubmitContactEmail,\n\t\tsetUserQuota,\n\t\tusersList,\n\t};\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"users2.store.mjs","names":["user: IUser","redirectUrl: string | null","acceptInvitation","invitationsApi.acceptInvitation","inviteUsers","invitationsApi.inviteUsers","onboardingApi.submitEmailOnSignup"],"sources":["../src/users.store.ts"],"sourcesContent":["import {\n\ttype LoginRequestDto,\n\ttype PasswordUpdateRequestDto,\n\ttype SettingsUpdateRequestDto,\n\ttype UserSelfSettingsUpdateRequestDto,\n\ttype UserUpdateRequestDto,\n\ttype User,\n\tROLE,\n\ttype UsersListFilterDto,\n} from '@n8n/api-types';\nimport { BROWSER_ID_STORAGE_KEY } from '@n8n/constants';\nimport { PERSONALIZATION_MODAL_KEY } from '@n8n/frontend-constants/users';\nimport type { AssignableGlobalRole } from '@n8n/permissions';\nimport { ResponseError } from '@n8n/rest-api-client';\nimport * as cloudApi from '@n8n/rest-api-client/api/cloudPlans';\nimport * as mfaApi from '@n8n/rest-api-client/api/mfa';\nimport * as ssoApi from '@n8n/rest-api-client/api/sso';\nimport type {\n\tUpdateGlobalRolePayload,\n\tIUserResponse,\n\tIUser,\n\tCurrentUserResponse,\n\tIPersonalizationLatestVersion,\n} from '@n8n/rest-api-client/api/users';\nimport * as usersApi from '@n8n/rest-api-client/api/users';\nimport { useAsyncState } from '@vueuse/core';\nimport { defineStore } from 'pinia';\nimport { computed, ref } from 'vue';\n\nimport { STORES } from './constants';\nimport * as invitationsApi from './invitation.api';\nimport type { ModalOpeners } from './modalOpeners';\nimport * as onboardingApi from './onboarding.api';\nimport { useSettingsStore } from './settings.store';\nimport { useRootStore } from './useRootStore';\n\nconst _isPendingUser = (user: IUserResponse | null) => !!user?.isPending;\nconst _isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Owner;\nconst _isDefaultUser = (user: IUserResponse | null) =>\n\t_isInstanceOwner(user) && _isPendingUser(user);\nconst _isAdmin = (user: IUserResponse | null) => user?.role === ROLE.Admin;\n\n// A 401 means the session was already dead server-side; any other error must still propagate.\nconst _isSessionAlreadyInvalid = (error: unknown) =>\n\terror instanceof ResponseError && error.httpStatusCode === 401;\n\nexport type LoginHook = (user: CurrentUserResponse) => void | Promise<void>;\ntype LogoutHook = () => void | Promise<void>;\n\nexport const useUsersStore = defineStore(STORES.USERS, () => {\n\tconst initialized = ref(false);\n\tconst currentUserId = ref<string | null>(null);\n\tconst usersById = ref<Record<string, IUser>>({});\n\tconst userQuota = ref<number>(-1);\n\n\tconst loginHooks = ref<LoginHook[]>([]);\n\tconst logoutHooks = ref<LogoutHook[]>([]);\n\n\t// Modal-open actions, registered at app bootstrap (see app/init.ts). Until then\n\t// they no-op — warning in dev — so the store never reaches into `ui.store`. Shares\n\t// the `ModalOpeners` contract with the other decoupled stores; this store currently\n\t// uses only `openModal`.\n\tconst warnModalOpenerMissing = (action: string) => {\n\t\tif (import.meta.env.DEV) {\n\t\t\tconsole.warn(\n\t\t\t\t`[users.store] ${action} called before modal openers were registered; ignoring. Call registerModalOpeners() at app bootstrap.`,\n\t\t\t);\n\t\t}\n\t};\n\tconst modalOpeners = ref<ModalOpeners>({\n\t\topenModal: (name) => warnModalOpenerMissing(`openModal(${String(name)})`),\n\t\topenModalWithData: (payload) =>\n\t\t\twarnModalOpenerMissing(`openModalWithData(${String(payload.name)})`),\n\t});\n\tconst registerModalOpeners = (openers: ModalOpeners) => {\n\t\tmodalOpeners.value = openers;\n\t};\n\n\t// App-provided capabilities, registered at bootstrap (see app/init.ts) so the store\n\t// carries no `@/app` dependency. Both fall back to safe no-ops before registration.\n\n\t// Permission checks, keyed by capability (app RBAC checks; extend the object as\n\t// more permissions need resolving). `listUsers` gates the `user:list` scope.\n\tconst canListUsers = ref<() => boolean>(() => false);\n\tconst setPermissionsResolvers = (resolvers: { listUsers: () => boolean }) => {\n\t\tcanListUsers.value = resolvers.listUsers;\n\t};\n\n\t// Stores\n\n\tconst rootStore = useRootStore();\n\tconst settingsStore = useSettingsStore();\n\n\t// Computed\n\n\tconst allUsers = computed(() => Object.values(usersById.value));\n\n\tconst currentUser = computed(() =>\n\t\tcurrentUserId.value ? usersById.value[currentUserId.value] : null,\n\t);\n\n\tconst userActivated = computed(() => Boolean(currentUser.value?.settings?.userActivated));\n\n\tconst isDefaultUser = computed(() => _isDefaultUser(currentUser.value));\n\n\tconst isInstanceOwner = computed(() => _isInstanceOwner(currentUser.value));\n\n\tconst isAdmin = computed(() => _isAdmin(currentUser.value));\n\n\tconst isAdminOrOwner = computed(() => isInstanceOwner.value || isAdmin.value);\n\n\tconst mfaEnabled = computed(() => currentUser.value?.mfaEnabled ?? false);\n\n\tconst globalRoleName = computed(() => currentUser.value?.role ?? 'default');\n\n\tconst userClaimedAiCredits = computed(() => currentUser.value?.settings?.userClaimedAiCredits);\n\n\tconst isEasyAIWorkflowOnboardingDone = computed(() =>\n\t\tBoolean(currentUser.value?.settings?.easyAIWorkflowOnboarded),\n\t);\n\n\tconst canUserUpdateVersion = computed(() => {\n\t\treturn isInstanceOwner.value;\n\t});\n\n\tconst setEasyAIWorkflowOnboardingDone = () => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.easyAIWorkflowOnboarded = true;\n\t\t}\n\t};\n\n\tconst isCalloutDismissed = (callout: string) =>\n\t\tBoolean(currentUser.value?.settings?.dismissedCallouts?.[callout]);\n\n\tconst setCalloutDismissed = (callout: string) => {\n\t\tif (currentUser.value?.settings) {\n\t\t\tcurrentUser.value.settings.dismissedCallouts ??= {};\n\n\t\t\tcurrentUser.value.settings.dismissedCallouts[callout] = true;\n\t\t}\n\t};\n\n\tconst usersLimitNotReached = computed(\n\t\t(): boolean => userQuota.value === -1 || userQuota.value > allUsers.value.length,\n\t);\n\n\t// Methods\n\n\tconst addUsers = (newUsers: User[]) => {\n\t\tnewUsers.forEach((userResponse) => {\n\t\t\tconst prevUser = usersById.value[userResponse.id] || {};\n\t\t\tconst updatedUser = {\n\t\t\t\t...prevUser,\n\t\t\t\t...userResponse,\n\t\t\t};\n\t\t\tconst user: IUser = {\n\t\t\t\t...updatedUser,\n\t\t\t\tfullName: userResponse.firstName\n\t\t\t\t\t? `${updatedUser.firstName} ${updatedUser.lastName ?? ''}`\n\t\t\t\t\t: undefined,\n\t\t\t\tisDefaultUser: _isDefaultUser(updatedUser),\n\t\t\t\tisPendingUser: _isPendingUser(updatedUser),\n\t\t\t};\n\n\t\t\tusersById.value = {\n\t\t\t\t...usersById.value,\n\t\t\t\t[user.id]: user,\n\t\t\t};\n\t\t});\n\t};\n\n\tconst setCurrentUser = async (user: CurrentUserResponse) => {\n\t\taddUsers([user]);\n\t\tcurrentUserId.value = user.id;\n\n\t\tfor (const hook of loginHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook(user);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing login hook:', error);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst loginWithCookie = async () => {\n\t\tconst user = await usersApi.loginCurrentUser(rootStore.restApiContext);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst initialize = async () => {\n\t\tif (initialized.value) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait loginWithCookie();\n\t\t\tinitialized.value = true;\n\t\t} catch {\n\t\t\t// A missing or expired auth cookie before setup is expected; leave the store\n\t\t\t// uninitialized and let the caller proceed to the login/setup flow.\n\t\t}\n\t};\n\n\tconst unsetCurrentUser = () => {\n\t\tcurrentUserId.value = null;\n\t};\n\n\tconst deleteUserById = (userId: string) => {\n\t\tconst { [userId]: _, ...rest } = usersById.value;\n\t\tusersById.value = rest;\n\t};\n\n\tconst setPersonalizationAnswers = (answers: IPersonalizationLatestVersion) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\tusersById.value = {\n\t\t\t...usersById.value,\n\t\t\t[currentUser.value.id]: {\n\t\t\t\t...currentUser.value,\n\t\t\t\tpersonalizationAnswers: answers,\n\t\t\t},\n\t\t};\n\t};\n\n\tconst loginWithCreds = async (params: LoginRequestDto) => {\n\t\tconst user = await usersApi.login(rootStore.restApiContext, params);\n\t\tif (!user) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait setCurrentUser(user);\n\t};\n\n\tconst registerLoginHook = (hook: LoginHook) => {\n\t\tloginHooks.value.push(hook);\n\t};\n\n\tconst registerLogoutHook = (hook: LogoutHook) => {\n\t\tlogoutHooks.value.push(hook);\n\t};\n\n\tconst standardLogout = async () => {\n\t\ttry {\n\t\t\tawait usersApi.logout(rootStore.restApiContext);\n\t\t} catch (error) {\n\t\t\tif (!_isSessionAlreadyInvalid(error)) throw error;\n\t\t}\n\t};\n\n\tconst logout = async (options?: { viaOidc?: boolean }) => {\n\t\tlet redirectUrl: string | null = null;\n\n\t\tif (options?.viaOidc) {\n\t\t\ttry {\n\t\t\t\t({ redirectUrl } = await ssoApi.oidcLogout(rootStore.restApiContext));\n\t\t\t} catch {\n\t\t\t\t// The OIDC logout endpoint may be unavailable (e.g. the license\n\t\t\t\t// lapsed since login). Fall back to the standard logout so the\n\t\t\t\t// n8n session is terminated in any case.\n\t\t\t\tawait standardLogout();\n\t\t\t}\n\t\t} else {\n\t\t\tawait standardLogout();\n\t\t}\n\n\t\tunsetCurrentUser();\n\n\t\tfor (const hook of logoutHooks.value) {\n\t\t\ttry {\n\t\t\t\tawait hook();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('Error executing logout hook:', error);\n\t\t\t}\n\t\t}\n\n\t\tlocalStorage.removeItem(BROWSER_ID_STORAGE_KEY);\n\n\t\treturn { redirectUrl };\n\t};\n\n\tconst createOwner = async (params: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\temail: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await usersApi.setupOwner(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t\tsettingsStore.stopShowingSetupPage();\n\t\t}\n\t};\n\n\tconst validateSignupToken = async (params: { token: string }) => {\n\t\treturn await usersApi.validateSignupToken(rootStore.restApiContext, params);\n\t};\n\n\tconst acceptInvitation = async (params: {\n\t\ttoken: string;\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tpassword: string;\n\t}) => {\n\t\tconst user = await invitationsApi.acceptInvitation(rootStore.restApiContext, params);\n\t\tif (user) {\n\t\t\tawait setCurrentUser(user);\n\t\t}\n\t};\n\n\tconst sendForgotPasswordEmail = async (params: { email: string }) => {\n\t\tawait usersApi.sendForgotPasswordEmail(rootStore.restApiContext, params);\n\t};\n\n\tconst validatePasswordToken = async (params: { token: string }) => {\n\t\tawait usersApi.validatePasswordToken(rootStore.restApiContext, params);\n\t};\n\n\tconst changePassword = async (params: { token: string; password: string; mfaCode?: string }) => {\n\t\tawait usersApi.changePassword(rootStore.restApiContext, params);\n\t};\n\n\tconst updateUser = async (params: UserUpdateRequestDto) => {\n\t\tconst user = await usersApi.updateCurrentUser(rootStore.restApiContext, params);\n\t\taddUsers([user]);\n\t\treturn user;\n\t};\n\n\tconst updateUserName = async (params: { firstName: string; lastName: string }) => {\n\t\tif (!currentUser.value) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn await updateUser({\n\t\t\temail: currentUser.value.email as string,\n\t\t\t...params,\n\t\t});\n\t};\n\n\tconst updateUserSettings = async (settings: UserSelfSettingsUpdateRequestDto) => {\n\t\tconst updatedSettings = await usersApi.updateCurrentUserSettings(\n\t\t\trootStore.restApiContext,\n\t\t\tsettings,\n\t\t);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.settings = updatedSettings;\n\t\t\taddUsers([currentUser.value]);\n\t\t}\n\t};\n\n\tconst updateOtherUserSettings = async (userId: string, settings: SettingsUpdateRequestDto) => {\n\t\tawait usersApi.updateOtherUserSettings(rootStore.restApiContext, userId, settings);\n\t};\n\n\tconst updateCurrentUserPassword = async (params: PasswordUpdateRequestDto) => {\n\t\tawait usersApi.updateCurrentUserPassword(rootStore.restApiContext, params);\n\t};\n\n\tconst deleteUser = async (params: { id: string; transferId?: string }) => {\n\t\tawait usersApi.deleteUser(rootStore.restApiContext, params);\n\t\tdeleteUserById(params.id);\n\t};\n\n\tconst fetchUsers = async ({\n\t\ttake,\n\t\tskip,\n\t\tfilter,\n\t}: { take?: number; skip?: number; filter?: UsersListFilterDto['filter'] } = {}) => {\n\t\tif (!canListUsers.value()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { items } = await usersApi.getUsers(rootStore.restApiContext, {\n\t\t\ttake: take ?? 50,\n\t\t\tskip: skip ?? 0,\n\t\t\tfilter,\n\t\t});\n\t\taddUsers(items);\n\t};\n\n\tconst inviteUsers = async (params: Array<{ email: string; role: AssignableGlobalRole }>) => {\n\t\tconst invitedUsers = await invitationsApi.inviteUsers(rootStore.restApiContext, params);\n\t\taddUsers(\n\t\t\tinvitedUsers.map(({ user }) => ({\n\t\t\t\tisPending: true,\n\t\t\t\t...user,\n\t\t\t})),\n\t\t);\n\t\treturn invitedUsers;\n\t};\n\n\tconst reinviteUser = async ({ email, role }: { email: string; role: AssignableGlobalRole }) => {\n\t\tconst invitationResponse = await invitationsApi.inviteUsers(rootStore.restApiContext, [\n\t\t\t{ email, role },\n\t\t]);\n\t\tif (!invitationResponse[0].user.emailSent) {\n\t\t\tthrow Error(invitationResponse[0].error);\n\t\t}\n\t};\n\n\tconst getUserPasswordResetLink = async (params: { id: string }) => {\n\t\treturn await usersApi.getPasswordResetLink(rootStore.restApiContext, params);\n\t};\n\n\tconst generateInviteLink = async (params: { id: string }) => {\n\t\treturn await usersApi.generateInviteLink(rootStore.restApiContext, params);\n\t};\n\n\tconst submitPersonalizationSurvey = async (results: IPersonalizationLatestVersion) => {\n\t\tawait usersApi.submitPersonalizationSurvey(rootStore.restApiContext, results);\n\t\tsetPersonalizationAnswers(results);\n\t};\n\n\t// Synchronous: after the `ui.store` modal decoupling this only fires the injected\n\t// opener. All call sites invoke it fire-and-forget (`void ...`).\n\tconst showPersonalizationSurvey = () => {\n\t\tconst surveyEnabled = settingsStore.isPersonalizationSurveyEnabled;\n\t\tif (surveyEnabled && currentUser.value && !currentUser.value.personalizationAnswers) {\n\t\t\tmodalOpeners.value.openModal(PERSONALIZATION_MODAL_KEY);\n\t\t}\n\t};\n\n\tconst fetchMfaQR = async () => {\n\t\treturn await mfaApi.getMfaQR(rootStore.restApiContext);\n\t};\n\n\tconst verifyMfaCode = async (data: { mfaCode: string }) => {\n\t\treturn await mfaApi.verifyMfaCode(rootStore.restApiContext, data);\n\t};\n\n\tconst canEnableMFA = async () => {\n\t\treturn await mfaApi.canEnableMFA(rootStore.restApiContext);\n\t};\n\n\tconst enableMfa = async (data: { mfaCode: string }) => {\n\t\tawait mfaApi.enableMfa(rootStore.restApiContext, data);\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = true;\n\t\t}\n\t};\n\n\tconst disableMfa = async (data: mfaApi.DisableMfaParams) => {\n\t\tawait mfaApi.disableMfa(rootStore.restApiContext, data);\n\n\t\tif (currentUser.value) {\n\t\t\tcurrentUser.value.mfaEnabled = false;\n\t\t}\n\t};\n\n\tconst updateEnforceMfa = async (enforce: boolean) => {\n\t\tawait mfaApi.updateEnforceMfa(rootStore.restApiContext, enforce);\n\t\tsettingsStore.isMFAEnforced = enforce;\n\t};\n\n\tconst sendConfirmationEmail = async () => {\n\t\tawait cloudApi.sendConfirmationEmail(rootStore.restApiContext);\n\t};\n\n\tconst updateGlobalRole = async ({ id, newRoleName }: UpdateGlobalRolePayload) => {\n\t\tawait usersApi.updateGlobalRole(rootStore.restApiContext, { id, newRoleName });\n\t\tawait fetchUsers({ filter: { ids: [id] } });\n\t};\n\n\tconst submitContactEmail = async (email: string, agree: boolean) => {\n\t\tif (currentUser.value) {\n\t\t\treturn await onboardingApi.submitEmailOnSignup(\n\t\t\t\trootStore.instanceId,\n\t\t\t\tcurrentUser.value,\n\t\t\t\temail ?? currentUser.value.email,\n\t\t\t\tagree,\n\t\t\t);\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst usersList = useAsyncState(\n\t\tasync (filter?: UsersListFilterDto) =>\n\t\t\tawait usersApi.getUsers(rootStore.restApiContext, filter),\n\t\t{\n\t\t\tcount: 0,\n\t\t\titems: [],\n\t\t},\n\t\t{ immediate: false, resetOnExecute: false },\n\t);\n\n\tconst setUserQuota = (quota?: number) => {\n\t\tif (typeof quota !== 'undefined') {\n\t\t\tuserQuota.value = quota;\n\t\t}\n\t};\n\n\treturn {\n\t\tinitialized,\n\t\tcurrentUserId,\n\t\tusersById,\n\t\tallUsers,\n\t\tcurrentUser,\n\t\tuserActivated,\n\t\tisDefaultUser,\n\t\tisInstanceOwner,\n\t\tisAdmin,\n\t\tisAdminOrOwner,\n\t\tmfaEnabled,\n\t\tglobalRoleName,\n\t\tuserClaimedAiCredits,\n\t\tisEasyAIWorkflowOnboardingDone,\n\t\tcanUserUpdateVersion,\n\t\tusersLimitNotReached,\n\t\taddUsers,\n\t\tloginWithCookie,\n\t\tinitialize,\n\t\tsetPersonalizationAnswers,\n\t\tloginWithCreds,\n\t\tlogout,\n\t\tregisterLoginHook,\n\t\tregisterLogoutHook,\n\t\tregisterModalOpeners,\n\t\tsetPermissionsResolvers,\n\t\tcreateOwner,\n\t\tvalidateSignupToken,\n\t\tacceptInvitation,\n\t\tsendForgotPasswordEmail,\n\t\tvalidatePasswordToken,\n\t\tchangePassword,\n\t\tupdateUser,\n\t\tupdateUserName,\n\t\tupdateUserSettings,\n\t\tupdateOtherUserSettings,\n\t\tupdateCurrentUserPassword,\n\t\tdeleteUser,\n\t\tfetchUsers,\n\t\tinviteUsers,\n\t\treinviteUser,\n\t\tgetUserPasswordResetLink,\n\t\tgenerateInviteLink,\n\t\tsubmitPersonalizationSurvey,\n\t\tshowPersonalizationSurvey,\n\t\tfetchMfaQR,\n\t\tverifyMfaCode,\n\t\tenableMfa,\n\t\tdisableMfa,\n\t\tupdateEnforceMfa,\n\t\tcanEnableMFA,\n\t\tsendConfirmationEmail,\n\t\tupdateGlobalRole,\n\t\tsetEasyAIWorkflowOnboardingDone,\n\t\tisCalloutDismissed,\n\t\tsetCalloutDismissed,\n\t\tsubmitContactEmail,\n\t\tsetUserQuota,\n\t\tusersList,\n\t};\n});\n"],"mappings":"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nE,MAAI,YAAY,MACf,QAAO,MAAMC,oBACZ,UAAU,YACV,YAAY,OACZ,SAAS,YAAY,MAAM,OAC3B,MACA;AAEF,SAAO;;CAGR,MAAM,YAAY,cACjB,OAAO,WACN,MAAM,SAAS,SAAS,UAAU,gBAAgB,OAAO,EAC1D;EACC,OAAO;EACP,OAAO,EAAE;EACT,EACD;EAAE,WAAW;EAAO,gBAAgB;EAAO,CAC3C;CAED,MAAM,gBAAgB,UAAmB;AACxC,MAAI,OAAO,UAAU,YACpB,WAAU,QAAQ;;AAIpB,QAAO;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA"}