mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[Cloud] Fix sessions stitching across domains (#103964)
This commit is contained in:
parent
12e7fe50bb
commit
a3f86bda3e
3 changed files with 28 additions and 33 deletions
|
@ -12,7 +12,7 @@ export interface FullStoryDeps {
|
|||
basePath: IBasePath;
|
||||
orgId: string;
|
||||
packageInfo: PackageInfo;
|
||||
userIdPromise: Promise<string | undefined>;
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
interface FullStoryApi {
|
||||
|
@ -24,7 +24,7 @@ export const initializeFullStory = async ({
|
|||
basePath,
|
||||
orgId,
|
||||
packageInfo,
|
||||
userIdPromise,
|
||||
userId,
|
||||
}: FullStoryDeps) => {
|
||||
// @ts-expect-error
|
||||
window._fs_debug = false;
|
||||
|
@ -73,28 +73,23 @@ export const initializeFullStory = async ({
|
|||
/* eslint-enable */
|
||||
|
||||
// @ts-expect-error
|
||||
const fullstory: FullStoryApi = window.FSKibana;
|
||||
const fullStory: FullStoryApi = window.FSKibana;
|
||||
|
||||
try {
|
||||
// This needs to be called syncronously to be sure that we populate the user ID soon enough to make sessions merging
|
||||
// across domains work
|
||||
if (!userId) return;
|
||||
// Do the hashing here to keep it at clear as possible in our source code that we do not send literal user IDs
|
||||
const hashedId = sha256(userId.toString());
|
||||
fullStory.identify(hashedId);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`[cloud.full_story] Could not call FS.identify due to error: ${e.toString()}`, e);
|
||||
}
|
||||
|
||||
// Record an event that Kibana was opened so we can easily search for sessions that use Kibana
|
||||
// @ts-expect-error
|
||||
window.FSKibana.event('Loaded Kibana', {
|
||||
fullStory.event('Loaded Kibana', {
|
||||
// `str` suffix is required, see docs: https://help.fullstory.com/hc/en-us/articles/360020623234
|
||||
kibana_version_str: packageInfo.version,
|
||||
});
|
||||
|
||||
// Use a promise here so we don't have to wait to retrieve the user to start recording the session
|
||||
userIdPromise
|
||||
.then((userId) => {
|
||||
if (!userId) return;
|
||||
// Do the hashing here to keep it at clear as possible in our source code that we do not send literal user IDs
|
||||
const hashedId = sha256(userId.toString());
|
||||
// @ts-expect-error
|
||||
window.FSKibana.identify(hashedId);
|
||||
})
|
||||
.catch((e) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`[cloud.full_story] Could not call FS.identify due to error: ${e.toString()}`,
|
||||
e
|
||||
);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -63,16 +63,11 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
expect(initializeFullStoryMock).toHaveBeenCalled();
|
||||
const {
|
||||
basePath,
|
||||
orgId,
|
||||
packageInfo,
|
||||
userIdPromise,
|
||||
} = initializeFullStoryMock.mock.calls[0][0];
|
||||
const { basePath, orgId, packageInfo, userId } = initializeFullStoryMock.mock.calls[0][0];
|
||||
expect(basePath.prepend).toBeDefined();
|
||||
expect(orgId).toEqual('foo');
|
||||
expect(packageInfo).toEqual(initContext.env.packageInfo);
|
||||
expect(await userIdPromise).toEqual('1234');
|
||||
expect(userId).toEqual('1234');
|
||||
});
|
||||
|
||||
it('passes undefined user ID when security is not available', async () => {
|
||||
|
@ -82,9 +77,9 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
expect(initializeFullStoryMock).toHaveBeenCalled();
|
||||
const { orgId, userIdPromise } = initializeFullStoryMock.mock.calls[0][0];
|
||||
const { orgId, userId } = initializeFullStoryMock.mock.calls[0][0];
|
||||
expect(orgId).toEqual('foo');
|
||||
expect(await userIdPromise).toEqual(undefined);
|
||||
expect(userId).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('does not call initializeFullStory when enabled=false', async () => {
|
||||
|
|
|
@ -166,16 +166,21 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
}
|
||||
|
||||
// Keep this import async so that we do not load any FullStory code into the browser when it is disabled.
|
||||
const { initializeFullStory } = await import('./fullstory');
|
||||
const fullStoryChunkPromise = import('./fullstory');
|
||||
const userIdPromise: Promise<string | undefined> = security
|
||||
? loadFullStoryUserId({ getCurrentUser: security.authc.getCurrentUser })
|
||||
: Promise.resolve(undefined);
|
||||
|
||||
const [{ initializeFullStory }, userId] = await Promise.all([
|
||||
fullStoryChunkPromise,
|
||||
userIdPromise,
|
||||
]);
|
||||
|
||||
initializeFullStory({
|
||||
basePath,
|
||||
orgId,
|
||||
packageInfo: this.initializerContext.env.packageInfo,
|
||||
userIdPromise,
|
||||
userId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue