@@ -9,6 +9,7 @@ import { IScheduler } from 'rxjs/Scheduler';
99import { Subscriber } from 'rxjs/Subscriber' ;
1010import { Subscription } from 'rxjs/Subscription' ;
1111import { async as AsyncScheduler } from 'rxjs/scheduler/async' ;
12+ import jwtDecode , { JwtPayload , InvalidTokenError } from 'jwt-decode' ;
1213
1314import 'rxjs/add/operator/catch' ;
1415import 'rxjs/add/operator/combineLatest' ;
@@ -471,6 +472,7 @@ export class DirectLine implements IBotConnection {
471472 private retries : number ;
472473
473474 private localeOnStartConversation : string ;
475+ private userIdOnStartConversation : string ;
474476
475477 private pollingInterval : number = 1000 ; //ms
476478
@@ -630,6 +632,9 @@ export class DirectLine implements IBotConnection {
630632 const body = this . conversationId
631633 ? undefined
632634 : {
635+ user : {
636+ id : this . userIdOnStartConversation
637+ } ,
633638 locale : this . localeOnStartConversation
634639 } ;
635640 return this . services . ajax ( {
@@ -749,6 +754,11 @@ export class DirectLine implements IBotConnection {
749754 }
750755
751756 postActivity ( activity : Activity ) {
757+ // If user id is set, check if it match activity.from.id and always override it in activity
758+ if ( this . userIdOnStartConversation && activity . from && activity . from . id !== this . userIdOnStartConversation ) {
759+ console . warn ( 'DirectLineJS: Activity.from.id does not match with user id, ignoring activity.from.id' ) ;
760+ activity . from . id = this . userIdOnStartConversation ;
761+ }
752762 // Use postMessageWithAttachments for messages with attachments that are local files (e.g. an image to upload)
753763 // Technically we could use it for *all* activities, but postActivity is much lighter weight
754764 // So, since WebChat is partially a reference implementation of Direct Line, we implement both.
@@ -1032,5 +1042,32 @@ export class DirectLine implements IBotConnection {
10321042 return `${ DIRECT_LINE_VERSION } (${ clientAgent } ${ process . env . npm_package_version } )` ;
10331043 }
10341044
1045+ setUserId ( userId : string ) {
1046+ if ( this . connectionStatus$ . getValue ( ) === ConnectionStatus . Online ) {
1047+ throw new Error ( 'DirectLineJS: It is connected, we cannot set user id.' ) ;
1048+ }
1049+
1050+ const userIdFromToken = this . parseToken ( this . token ) ;
1051+ if ( userIdFromToken ) {
1052+ return console . warn ( 'DirectLineJS: user id is already set in token, will ignore this user id.' ) ;
1053+ }
1054+
1055+ if ( / ^ d l _ / u. test ( userId ) ) {
1056+ return console . warn ( 'DirectLineJS: user id prefixed with "dl_" is reserved and must be embedded into the Direct Line token to prevent forgery.' ) ;
1057+ }
1058+
1059+ this . userIdOnStartConversation = userId ;
1060+ }
1061+
1062+ private parseToken ( token : string ) {
1063+ try {
1064+ const { user } = jwtDecode < JwtPayload > ( token ) as { [ key : string ] : any ; } ;
1065+ return user ;
1066+ } catch ( e ) {
1067+ if ( e instanceof InvalidTokenError ) {
1068+ return undefined ;
1069+ }
1070+ }
1071+ }
10351072
10361073}
0 commit comments