mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(editor): Include n8n version in user identify call (no-changelog) (#19306)
Co-authored-by: Michael Kret <michael.k@radency.com>
This commit is contained in:
@@ -1,23 +1,25 @@
|
|||||||
import { useUsersStore } from '@/stores/users.store';
|
import { mockedStore, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils';
|
||||||
|
import { EnterpriseEditionFeature } from '@/constants';
|
||||||
|
import { initializeAuthenticatedFeatures, initializeCore, state } from '@/init';
|
||||||
|
import { UserManagementAuthenticationMethod } from '@/Interface';
|
||||||
import { useCloudPlanStore } from '@/stores/cloudPlan.store';
|
import { useCloudPlanStore } from '@/stores/cloudPlan.store';
|
||||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
|
||||||
import { state, initializeAuthenticatedFeatures, initializeCore } from '@/init';
|
|
||||||
import { createTestingPinia } from '@pinia/testing';
|
|
||||||
import { setActivePinia } from 'pinia';
|
|
||||||
import { useSettingsStore } from '@/stores/settings.store';
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
|
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||||
|
import { useSSOStore } from '@/stores/sso.store';
|
||||||
|
import { useUIStore } from '@/stores/ui.store';
|
||||||
|
import { useUsersStore } from '@/stores/users.store';
|
||||||
import { useVersionsStore } from '@/stores/versions.store';
|
import { useVersionsStore } from '@/stores/versions.store';
|
||||||
|
import type { Cloud, CurrentUserResponse } from '@n8n/rest-api-client';
|
||||||
|
import type { IUser } from '@n8n/rest-api-client/api/users';
|
||||||
|
import { STORES } from '@n8n/stores';
|
||||||
|
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||||
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import { mockedStore, SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils';
|
import { setActivePinia } from 'pinia';
|
||||||
import { STORES } from '@n8n/stores';
|
import { mock } from 'vitest-mock-extended';
|
||||||
import { useSSOStore } from '@/stores/sso.store';
|
import { telemetry } from './plugins/telemetry';
|
||||||
import { UserManagementAuthenticationMethod } from '@/Interface';
|
|
||||||
import type { IUser } from '@n8n/rest-api-client/api/users';
|
|
||||||
import { EnterpriseEditionFeature } from '@/constants';
|
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
|
||||||
import type { Cloud } from '@n8n/rest-api-client';
|
|
||||||
|
|
||||||
const showMessage = vi.fn();
|
const showMessage = vi.fn();
|
||||||
const showToast = vi.fn();
|
const showToast = vi.fn();
|
||||||
@@ -34,19 +36,16 @@ vi.mock('@/stores/users.store', () => ({
|
|||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('@n8n/stores/useRootStore', () => ({
|
|
||||||
useRootStore: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('Init', () => {
|
describe('Init', () => {
|
||||||
let settingsStore: ReturnType<typeof useSettingsStore>;
|
let settingsStore: ReturnType<typeof mockedStore<typeof useSettingsStore>>;
|
||||||
let cloudPlanStore: ReturnType<typeof mockedStore<typeof useCloudPlanStore>>;
|
let cloudPlanStore: ReturnType<typeof mockedStore<typeof useCloudPlanStore>>;
|
||||||
let sourceControlStore: ReturnType<typeof useSourceControlStore>;
|
let sourceControlStore: ReturnType<typeof mockedStore<typeof useSourceControlStore>>;
|
||||||
let usersStore: ReturnType<typeof useUsersStore>;
|
let usersStore: ReturnType<typeof mockedStore<typeof useUsersStore>>;
|
||||||
let nodeTypesStore: ReturnType<typeof useNodeTypesStore>;
|
let nodeTypesStore: ReturnType<typeof mockedStore<typeof useNodeTypesStore>>;
|
||||||
let versionsStore: ReturnType<typeof useVersionsStore>;
|
let versionsStore: ReturnType<typeof mockedStore<typeof useVersionsStore>>;
|
||||||
let ssoStore: ReturnType<typeof useSSOStore>;
|
let ssoStore: ReturnType<typeof mockedStore<typeof useSSOStore>>;
|
||||||
let uiStore: ReturnType<typeof useUIStore>;
|
let uiStore: ReturnType<typeof mockedStore<typeof useUIStore>>;
|
||||||
|
let rootStore: ReturnType<typeof mockedStore<typeof useRootStore>>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
setActivePinia(
|
setActivePinia(
|
||||||
@@ -57,15 +56,16 @@ describe('Init', () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
settingsStore = useSettingsStore();
|
settingsStore = mockedStore(useSettingsStore);
|
||||||
cloudPlanStore = mockedStore(useCloudPlanStore);
|
cloudPlanStore = mockedStore(useCloudPlanStore);
|
||||||
sourceControlStore = useSourceControlStore();
|
sourceControlStore = mockedStore(useSourceControlStore);
|
||||||
nodeTypesStore = useNodeTypesStore();
|
nodeTypesStore = mockedStore(useNodeTypesStore);
|
||||||
usersStore = useUsersStore();
|
usersStore = mockedStore(useUsersStore);
|
||||||
versionsStore = useVersionsStore();
|
versionsStore = mockedStore(useVersionsStore);
|
||||||
versionsStore = useVersionsStore();
|
versionsStore = mockedStore(useVersionsStore);
|
||||||
ssoStore = useSSOStore();
|
ssoStore = mockedStore(useSSOStore);
|
||||||
uiStore = useUIStore();
|
uiStore = mockedStore(useUIStore);
|
||||||
|
rootStore = mockedStore(useRootStore);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('initializeCore()', () => {
|
describe('initializeCore()', () => {
|
||||||
@@ -118,6 +118,19 @@ describe('Init', () => {
|
|||||||
expect(registerLogoutHookSpy).toHaveBeenCalled();
|
expect(registerLogoutHookSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should correctly identify the user for telemetry', async () => {
|
||||||
|
const telemetryIdentifySpy = vi.spyOn(telemetry, 'identify');
|
||||||
|
usersStore.registerLoginHook.mockImplementation((hook) =>
|
||||||
|
hook(mock<CurrentUserResponse>({ id: 'userId' })),
|
||||||
|
);
|
||||||
|
rootStore.instanceId = 'testInstanceId';
|
||||||
|
rootStore.versionCli = '1.102.0';
|
||||||
|
|
||||||
|
await initializeCore();
|
||||||
|
|
||||||
|
expect(telemetryIdentifySpy).toHaveBeenCalledWith('testInstanceId', 'userId', '1.102.0');
|
||||||
|
});
|
||||||
|
|
||||||
it('should initialize ssoStore with settings SSO configuration', async () => {
|
it('should initialize ssoStore with settings SSO configuration', async () => {
|
||||||
const saml = { loginEnabled: true, loginLabel: '' };
|
const saml = { loginEnabled: true, loginLabel: '' };
|
||||||
const ldap = { loginEnabled: false, loginLabel: '' };
|
const ldap = { loginEnabled: false, loginLabel: '' };
|
||||||
@@ -155,12 +168,10 @@ describe('Init', () => {
|
|||||||
|
|
||||||
describe('initializeAuthenticatedFeatures()', () => {
|
describe('initializeAuthenticatedFeatures()', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.spyOn(settingsStore, 'isCloudDeployment', 'get').mockReturnValue(true);
|
settingsStore.isCloudDeployment = true;
|
||||||
vi.spyOn(settingsStore, 'isTemplatesEnabled', 'get').mockReturnValue(true);
|
settingsStore.isTemplatesEnabled = true;
|
||||||
vi.spyOn(sourceControlStore, 'isEnterpriseSourceControlEnabled', 'get').mockReturnValue(true);
|
sourceControlStore.isEnterpriseSourceControlEnabled = true;
|
||||||
vi.mocked(useRootStore).mockReturnValue({ defaultLocale: 'es' } as ReturnType<
|
rootStore.defaultLocale = 'es';
|
||||||
typeof useRootStore
|
|
||||||
>);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -172,9 +183,7 @@ describe('Init', () => {
|
|||||||
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
||||||
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
||||||
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
||||||
vi.mocked(useUsersStore).mockReturnValue({ currentUser: null } as ReturnType<
|
usersStore.currentUser = null;
|
||||||
typeof useUsersStore
|
|
||||||
>);
|
|
||||||
|
|
||||||
await initializeAuthenticatedFeatures(false);
|
await initializeAuthenticatedFeatures(false);
|
||||||
expect(cloudStoreSpy).not.toHaveBeenCalled();
|
expect(cloudStoreSpy).not.toHaveBeenCalled();
|
||||||
@@ -188,9 +197,7 @@ describe('Init', () => {
|
|||||||
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
||||||
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
||||||
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
||||||
vi.mocked(useUsersStore).mockReturnValue({ currentUser: { id: '123' } } as ReturnType<
|
usersStore.currentUser = mock<IUser>({ id: '123', globalScopes: ['*'] });
|
||||||
typeof useUsersStore
|
|
||||||
>);
|
|
||||||
|
|
||||||
await initializeAuthenticatedFeatures(false);
|
await initializeAuthenticatedFeatures(false);
|
||||||
|
|
||||||
@@ -211,9 +218,7 @@ describe('Init', () => {
|
|||||||
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
||||||
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
||||||
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
||||||
vi.mocked(useUsersStore).mockReturnValue({ currentUser: { id: '123' } } as ReturnType<
|
usersStore.currentUser = mock<IUser>({ id: '123', globalScopes: ['*'] });
|
||||||
typeof useUsersStore
|
|
||||||
>);
|
|
||||||
|
|
||||||
await initializeAuthenticatedFeatures(false);
|
await initializeAuthenticatedFeatures(false);
|
||||||
|
|
||||||
@@ -230,9 +235,7 @@ describe('Init', () => {
|
|||||||
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
const sourceControlSpy = vi.spyOn(sourceControlStore, 'getPreferences');
|
||||||
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
const nodeTranslationSpy = vi.spyOn(nodeTypesStore, 'getNodeTranslationHeaders');
|
||||||
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
const versionsSpy = vi.spyOn(versionsStore, 'checkForNewVersions');
|
||||||
vi.mocked(useUsersStore).mockReturnValue({ currentUser: { id: '123' } } as ReturnType<
|
usersStore.currentUser = mock<IUser>({ id: '123', globalScopes: ['*'] });
|
||||||
typeof useUsersStore
|
|
||||||
>);
|
|
||||||
|
|
||||||
await initializeAuthenticatedFeatures(false);
|
await initializeAuthenticatedFeatures(false);
|
||||||
|
|
||||||
@@ -244,9 +247,7 @@ describe('Init', () => {
|
|||||||
|
|
||||||
it('should handle source control initialization error', async () => {
|
it('should handle source control initialization error', async () => {
|
||||||
vi.spyOn(cloudPlanStore, 'initialize').mockResolvedValue();
|
vi.spyOn(cloudPlanStore, 'initialize').mockResolvedValue();
|
||||||
vi.mocked(useUsersStore).mockReturnValue({ currentUser: { id: '123' } } as ReturnType<
|
usersStore.currentUser = mock<IUser>({ id: '123', globalScopes: ['*'] });
|
||||||
typeof useUsersStore
|
|
||||||
>);
|
|
||||||
vi.spyOn(sourceControlStore, 'getPreferences').mockRejectedValueOnce(
|
vi.spyOn(sourceControlStore, 'getPreferences').mockRejectedValueOnce(
|
||||||
new AxiosError('Something went wrong', '404'),
|
new AxiosError('Something went wrong', '404'),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
import { h } from 'vue';
|
|
||||||
import { useCloudPlanStore } from '@/stores/cloudPlan.store';
|
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
|
||||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
|
||||||
import { useSettingsStore } from '@/stores/settings.store';
|
|
||||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
|
||||||
import { useUsersStore } from '@/stores/users.store';
|
|
||||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
|
||||||
import { useVersionsStore } from '@/stores/versions.store';
|
|
||||||
import { useProjectsStore } from '@/stores/projects.store';
|
|
||||||
import { useRolesStore } from './stores/roles.store';
|
|
||||||
import { useInsightsStore } from '@/features/insights/insights.store';
|
|
||||||
import { useToast } from '@/composables/useToast';
|
|
||||||
import { useI18n } from '@n8n/i18n';
|
|
||||||
import SourceControlInitializationErrorMessage from '@/components/SourceControlInitializationErrorMessage.vue';
|
import SourceControlInitializationErrorMessage from '@/components/SourceControlInitializationErrorMessage.vue';
|
||||||
import { useSSOStore } from '@/stores/sso.store';
|
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||||
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
|
|
||||||
import type { UserManagementAuthenticationMethod } from '@/Interface';
|
|
||||||
import { useUIStore } from '@/stores/ui.store';
|
|
||||||
import type { BannerName } from '@n8n/api-types';
|
|
||||||
import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
|
|
||||||
import { usePostHog } from '@/stores/posthog.store';
|
|
||||||
import { useTelemetry } from '@/composables/useTelemetry';
|
import { useTelemetry } from '@/composables/useTelemetry';
|
||||||
import { useRBACStore } from '@/stores/rbac.store';
|
import { useToast } from '@/composables/useToast';
|
||||||
|
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
|
||||||
|
import { useInsightsStore } from '@/features/insights/insights.store';
|
||||||
|
import type { UserManagementAuthenticationMethod } from '@/Interface';
|
||||||
import {
|
import {
|
||||||
|
registerModuleModals,
|
||||||
registerModuleProjectTabs,
|
registerModuleProjectTabs,
|
||||||
registerModuleResources,
|
registerModuleResources,
|
||||||
registerModuleModals,
|
|
||||||
} from '@/moduleInitializer/moduleInitializer';
|
} from '@/moduleInitializer/moduleInitializer';
|
||||||
|
import { useCloudPlanStore } from '@/stores/cloudPlan.store';
|
||||||
|
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||||
|
import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
|
||||||
|
import { usePostHog } from '@/stores/posthog.store';
|
||||||
|
import { useProjectsStore } from '@/stores/projects.store';
|
||||||
|
import { useRBACStore } from '@/stores/rbac.store';
|
||||||
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
|
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||||
|
import { useSSOStore } from '@/stores/sso.store';
|
||||||
|
import { useUIStore } from '@/stores/ui.store';
|
||||||
|
import { useUsersStore } from '@/stores/users.store';
|
||||||
|
import { useVersionsStore } from '@/stores/versions.store';
|
||||||
|
import type { BannerName } from '@n8n/api-types';
|
||||||
|
import { useI18n } from '@n8n/i18n';
|
||||||
|
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||||
|
import { h } from 'vue';
|
||||||
|
import { useRolesStore } from './stores/roles.store';
|
||||||
|
|
||||||
export const state = {
|
export const state = {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
@@ -209,7 +209,7 @@ function registerAuthenticationHooks() {
|
|||||||
|
|
||||||
usersStore.registerLoginHook((user) => {
|
usersStore.registerLoginHook((user) => {
|
||||||
RBACStore.setGlobalScopes(user.globalScopes ?? []);
|
RBACStore.setGlobalScopes(user.globalScopes ?? []);
|
||||||
telemetry.identify(rootStore.instanceId, user.id);
|
telemetry.identify(rootStore.instanceId, user.id, rootStore.versionCli);
|
||||||
postHogStore.init(user.featureFlags);
|
postHogStore.init(user.featureFlags);
|
||||||
npsSurveyStore.setupNpsSurveyOnLogin(user.id, user.settings);
|
npsSurveyStore.setupNpsSurveyOnLogin(user.id, user.settings);
|
||||||
void settingsStore.getModuleSettings();
|
void settingsStore.getModuleSettings();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { usePostHog } from './posthog.store';
|
|||||||
import { useSettingsStore } from '@/stores/settings.store';
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
import { defaultSettings } from '../__tests__/defaults';
|
import { defaultSettings } from '../__tests__/defaults';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import { DEFAULT_POSTHOG_SETTINGS } from './posthog.test';
|
import { DEFAULT_POSTHOG_SETTINGS } from './posthog.store.test';
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
import * as chatAPI from '@/api/ai';
|
import * as chatAPI from '@/api/ai';
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { usePostHog } from './posthog.store';
|
|||||||
import { useSettingsStore } from '@/stores/settings.store';
|
import { useSettingsStore } from '@/stores/settings.store';
|
||||||
import { defaultSettings } from '../__tests__/defaults';
|
import { defaultSettings } from '../__tests__/defaults';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import { DEFAULT_POSTHOG_SETTINGS } from './posthog.test';
|
import { DEFAULT_POSTHOG_SETTINGS } from './posthog.store.test';
|
||||||
import { WORKFLOW_BUILDER_EXPERIMENT, DEFAULT_NEW_WORKFLOW_NAME } from '@/constants';
|
import { WORKFLOW_BUILDER_EXPERIMENT, DEFAULT_NEW_WORKFLOW_NAME } from '@/constants';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
import * as chatAPI from '@/api/ai';
|
import * as chatAPI from '@/api/ai';
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export const DEFAULT_POSTHOG_SETTINGS: FrontendSettings['posthog'] = {
|
|||||||
};
|
};
|
||||||
const CURRENT_USER_ID = '1';
|
const CURRENT_USER_ID = '1';
|
||||||
const CURRENT_INSTANCE_ID = '456';
|
const CURRENT_INSTANCE_ID = '456';
|
||||||
|
const CURRENT_VERSION_CLI = '1.100.0';
|
||||||
|
|
||||||
function setSettings(overrides?: Partial<FrontendSettings>) {
|
function setSettings(overrides?: Partial<FrontendSettings>) {
|
||||||
useSettingsStore().setSettings({
|
useSettingsStore().setSettings({
|
||||||
@@ -30,6 +31,7 @@ function setSettings(overrides?: Partial<FrontendSettings>) {
|
|||||||
} as FrontendSettings);
|
} as FrontendSettings);
|
||||||
|
|
||||||
useRootStore().setInstanceId(CURRENT_INSTANCE_ID);
|
useRootStore().setInstanceId(CURRENT_INSTANCE_ID);
|
||||||
|
useRootStore().setVersionCli(CURRENT_VERSION_CLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCurrentUser() {
|
function setCurrentUser() {
|
||||||
@@ -123,6 +125,7 @@ describe('Posthog store', () => {
|
|||||||
const userId = `${CURRENT_INSTANCE_ID}#${CURRENT_USER_ID}`;
|
const userId = `${CURRENT_INSTANCE_ID}#${CURRENT_USER_ID}`;
|
||||||
expect(window.posthog?.identify).toHaveBeenCalledWith(userId, {
|
expect(window.posthog?.identify).toHaveBeenCalledWith(userId, {
|
||||||
instance_id: CURRENT_INSTANCE_ID,
|
instance_id: CURRENT_INSTANCE_ID,
|
||||||
|
version_cli: CURRENT_VERSION_CLI,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -81,7 +81,11 @@ export const usePostHog = defineStore('posthog', () => {
|
|||||||
const identify = () => {
|
const identify = () => {
|
||||||
const instanceId = rootStore.instanceId;
|
const instanceId = rootStore.instanceId;
|
||||||
const user = usersStore.currentUser;
|
const user = usersStore.currentUser;
|
||||||
const traits: Record<string, string | number> = { instance_id: instanceId };
|
const versionCli = rootStore.versionCli;
|
||||||
|
const traits: Record<string, string | number> = {
|
||||||
|
instance_id: instanceId,
|
||||||
|
version_cli: versionCli,
|
||||||
|
};
|
||||||
|
|
||||||
if (user && typeof user.createdAt === 'string') {
|
if (user && typeof user.createdAt === 'string') {
|
||||||
traits.created_at_timestamp = new Date(user.createdAt).getTime();
|
traits.created_at_timestamp = new Date(user.createdAt).getTime();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const _isInstanceOwner = (user: IUserResponse | null) => user?.role === ROLE.Own
|
|||||||
const _isDefaultUser = (user: IUserResponse | null) =>
|
const _isDefaultUser = (user: IUserResponse | null) =>
|
||||||
_isInstanceOwner(user) && _isPendingUser(user);
|
_isInstanceOwner(user) && _isPendingUser(user);
|
||||||
|
|
||||||
type LoginHook = (user: CurrentUserResponse) => void;
|
export type LoginHook = (user: CurrentUserResponse) => void;
|
||||||
type LogoutHook = () => void;
|
type LogoutHook = () => void;
|
||||||
|
|
||||||
export const useUsersStore = defineStore(STORES.USERS, () => {
|
export const useUsersStore = defineStore(STORES.USERS, () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user