@@ -12,8 +12,10 @@ import {
12
12
PluginInitializerContext ,
13
13
HttpStart ,
14
14
IBasePath ,
15
+ ApplicationStart ,
15
16
} from 'src/core/public' ;
16
17
import { i18n } from '@kbn/i18n' ;
18
+ import { Subscription } from 'rxjs' ;
17
19
import type {
18
20
AuthenticatedUser ,
19
21
SecurityPluginSetup ,
@@ -57,17 +59,26 @@ export interface CloudSetup {
57
59
isCloudEnabled : boolean ;
58
60
}
59
61
62
+ interface SetupFullstoryDeps extends CloudSetupDependencies {
63
+ application ?: Promise < ApplicationStart > ;
64
+ basePath : IBasePath ;
65
+ }
66
+
60
67
export class CloudPlugin implements Plugin < CloudSetup > {
61
68
private config ! : CloudConfigType ;
62
69
private isCloudEnabled : boolean ;
70
+ private appSubscription ?: Subscription ;
63
71
64
72
constructor ( private readonly initializerContext : PluginInitializerContext ) {
65
73
this . config = this . initializerContext . config . get < CloudConfigType > ( ) ;
66
74
this . isCloudEnabled = false ;
67
75
}
68
76
69
77
public setup ( core : CoreSetup , { home, security } : CloudSetupDependencies ) {
70
- this . setupFullstory ( { basePath : core . http . basePath , security } ) . catch ( ( e ) =>
78
+ const application = core . getStartServices ( ) . then ( ( [ coreStart ] ) => {
79
+ return coreStart . application ;
80
+ } ) ;
81
+ this . setupFullstory ( { basePath : core . http . basePath , security, application } ) . catch ( ( e ) =>
71
82
// eslint-disable-next-line no-console
72
83
console . debug ( `Error setting up FullStory: ${ e . toString ( ) } ` )
73
84
) ;
@@ -130,6 +141,10 @@ export class CloudPlugin implements Plugin<CloudSetup> {
130
141
. catch ( ( ) => setLinks ( true ) ) ;
131
142
}
132
143
144
+ public stop ( ) {
145
+ this . appSubscription ?. unsubscribe ( ) ;
146
+ }
147
+
133
148
/**
134
149
* Determines if the current user should see links back to Cloud.
135
150
* This isn't a true authorization check, but rather a heuristic to
@@ -156,10 +171,7 @@ export class CloudPlugin implements Plugin<CloudSetup> {
156
171
return user ?. roles . includes ( 'superuser' ) ?? true ;
157
172
}
158
173
159
- private async setupFullstory ( {
160
- basePath,
161
- security,
162
- } : CloudSetupDependencies & { basePath : IBasePath } ) {
174
+ private async setupFullstory ( { basePath, security, application } : SetupFullstoryDeps ) {
163
175
const { enabled, org_id : orgId } = this . config . full_story ;
164
176
if ( ! enabled || ! orgId ) {
165
177
return ; // do not load any fullstory code in the browser if not enabled
@@ -190,7 +202,35 @@ export class CloudPlugin implements Plugin<CloudSetup> {
190
202
if ( userId ) {
191
203
// Do the hashing here to keep it at clear as possible in our source code that we do not send literal user IDs
192
204
const hashedId = sha256 ( userId . toString ( ) ) ;
193
- fullStory . identify ( hashedId ) ;
205
+ application
206
+ ?. then ( async ( ) => {
207
+ const appStart = await application ;
208
+ this . appSubscription = appStart . currentAppId$ . subscribe ( ( appId ) => {
209
+ // Update the current application every time it changes
210
+ fullStory . setUserVars ( {
211
+ app_id_str : appId ?? 'unknown' ,
212
+ } ) ;
213
+ } ) ;
214
+ } )
215
+ . catch ( ( e ) => {
216
+ // eslint-disable-next-line no-console
217
+ console . error (
218
+ `[cloud.full_story] Could not retrieve application service due to error: ${ e . toString ( ) } ` ,
219
+ e
220
+ ) ;
221
+ } ) ;
222
+ const kibanaVer = this . initializerContext . env . packageInfo . version ;
223
+ // TODO: use semver instead
224
+ const parsedVer = ( kibanaVer . indexOf ( '.' ) > - 1 ? kibanaVer . split ( '.' ) : [ ] ) . map ( ( s ) =>
225
+ parseInt ( s , 10 )
226
+ ) ;
227
+ // `str` suffix is required for evn vars, see docs: https://help.fullstory.com/hc/en-us/articles/360020623234
228
+ fullStory . identify ( hashedId , {
229
+ version_str : kibanaVer ,
230
+ version_major_int : parsedVer [ 0 ] ?? - 1 ,
231
+ version_minor_int : parsedVer [ 1 ] ?? - 1 ,
232
+ version_patch_int : parsedVer [ 2 ] ?? - 1 ,
233
+ } ) ;
194
234
}
195
235
} catch ( e ) {
196
236
// eslint-disable-next-line no-console
0 commit comments