@@ -19,6 +19,7 @@ interface State {
1919 decryptor : DecryptionService | null ,
2020 rows : Row [ ] ,
2121 raw : boolean ,
22+ highlightRow : string ,
2223}
2324
2425export class Monitor extends Component < { } , State > {
@@ -30,13 +31,29 @@ export class Monitor extends Component<{}, State> {
3031 constructor ( props : any ) {
3132 super ( props ) ;
3233
34+ // Redirect due to backward compatibility with old client which set the
35+ // key as a query parameter(?key=) and not as a hash parameter (#key=)
36+ let params = new URLSearchParams ( new URL ( window . location . href ) . search ) ;
37+ if ( params . has ( "key" ) ) {
38+ const password = params . get ( "key" ) ;
39+ if ( password !== null ) {
40+ this . addToHashParam ( "key" , password ) ;
41+ }
42+ params . delete ( "key" ) ;
43+ window . location . search = params . toString ( )
44+ }
45+
46+ let password = this . extractFromHash ( window . location . hash , "key" ) ;
47+ let highlightRowId = this . extractFromHash ( window . location . hash , "row" ) ;
48+
3349 this . state = {
3450 encrypted : false ,
35- enterPwdFirstTime : ! ( new URLSearchParams ( new URL ( window . location . href ) . search ) . has ( "key" ) ) ,
36- password : new URLSearchParams ( new URL ( window . location . href ) . search ) . get ( "key" ) ,
51+ enterPwdFirstTime : password === null ,
52+ password : password ,
3753 decryptor : null ,
3854 rows : [ ] ,
39- raw : new URLSearchParams ( new URL ( window . location . href ) . search ) . has ( "raw" ) ,
55+ raw : params . has ( "raw" ) ,
56+ highlightRow : highlightRowId === null ? "" : highlightRowId ,
4057 } ;
4158
4259 this . numLines = 1 ;
@@ -60,25 +77,67 @@ export class Monitor extends Component<{}, State> {
6077 this . client . then ( ( client ) => { this . setState ( { encrypted : client . getEncrypted ( ) } ) } ) ;
6178
6279 if ( ! this . state . enterPwdFirstTime ) {
63- this . createDecryptor ( ) ;
80+ this . createDecryptor ( this . state . password ) ;
6481 }
6582
6683 this . loadContent ( ) ;
6784 }
6885
86+ private extractFromHash ( hash : string , key : string ) : string | null {
87+ const params : string = hash . substring ( 1 , hash . length ) ;
88+ let value : string | null = null ;
89+
90+ params . split ( "&" ) . forEach ( ( parts , _ ) => {
91+ let kv = parts . split ( "=" ) ;
92+ if ( kv !== [ ] && kv [ 0 ] === key ) {
93+ value = kv [ 1 ] ;
94+ }
95+ } ) ;
96+ return value ;
97+ }
98+
99+ private addToHashParam ( key : string , value : string , remove : boolean = false ) {
100+ const newParamPair = key + "=" + value ;
101+ const currHash = window . location . hash . substring ( 1 , window . location . hash . length ) ;
102+ let newHash = "" ;
103+ let exists : boolean = false ;
104+
105+ currHash . split ( "&" ) . forEach ( ( parts , _ ) => {
106+ let kv = parts . split ( "=" ) ;
107+ if ( kv . length !== 0 && kv [ 0 ] !== '' ) {
108+ if ( kv [ 0 ] === key ) {
109+ exists = true ;
110+ if ( remove ) {
111+ return ;
112+ }
113+ newHash += newParamPair ;
114+ } else {
115+ newHash += parts ;
116+ }
117+ newHash += '&' ;
118+ }
119+ } ) ;
120+
121+ if ( ! exists ) {
122+ newHash += newParamPair ;
123+ }
124+
125+ window . location . hash = newHash ;
126+ }
127+
69128 private updatePassword ( newPassword : string ) {
70- this . setURLParams ( "key" , newPassword ) ;
129+ this . addToHashParam ( "key" , newPassword ) ;
71130 this . setState ( { password : newPassword } ) ;
72- this . createDecryptor ( ) ;
131+ this . createDecryptor ( newPassword ) ;
73132 }
74133
75- private createDecryptor ( ) {
76- if ( this . state . password === null ) {
134+ private createDecryptor ( password : string | null ) {
135+ if ( password === null ) {
77136 console . log ( "Can't create decryptor" ) ;
78137 return ;
79138 }
80139 this . client . then ( ( client : Client ) => {
81- this . setState ( { decryptor : new DecryptionService ( this . state . password ! , client . getSalt ( ) , client . getIv ( ) ) } ) ;
140+ this . setState ( { decryptor : new DecryptionService ( password ! , client . getSalt ( ) , client . getIv ( ) ) } ) ;
82141 } ) ;
83142 }
84143
@@ -92,6 +151,8 @@ export class Monitor extends Component<{}, State> {
92151 stream . on ( "error" , ( error : Error ) : void => {
93152 console . error ( error ) ;
94153 } ) ;
154+
155+
95156 }
96157
97158 private addNewContent ( content : string ) {
@@ -106,7 +167,14 @@ export class Monitor extends Component<{}, State> {
106167 }
107168
108169 private highlightRow ( line : number ) {
109- window . location . hash = line . toString ( ) ;
170+ if ( this . state . highlightRow === line . toString ( ) ) {
171+ this . setState ( { highlightRow : "" } ) ;
172+ // delete the hash parameter again if set
173+ this . addToHashParam ( "row" , "" , true ) ;
174+ } else {
175+ this . addToHashParam ( "row" , line . toString ( ) ) ;
176+ this . setState ( { highlightRow : line . toString ( ) } ) ;
177+ }
110178 }
111179
112180 private decryptRowIfEncrypted ( content : string ) : string {
@@ -132,16 +200,18 @@ export class Monitor extends Component<{}, State> {
132200 }
133201
134202 this . createNewDecryptorIfEncrypted ( )
135- return this . state . rows . map ( ( row : Row ) =>
136- < div className = { styles . row } id = { row . line . toString ( ) } key = { row . line } >
203+ return this . state . rows . map ( ( row : Row ) => {
204+ let rowStyle = row . line . toString ( ) === this . state . highlightRow ? styles . selectedRow : styles . row ;
205+
206+ return < div className = { rowStyle } id = { row . line . toString ( ) } key = { row . line } >
137207 < span className = { styles . line } onClick = { ( ) => this . highlightRow ( row . line ) } >
138208 { row . line }
139209 </ span >
140210 < span className = { styles . content } >
141211 { this . decryptRowIfEncrypted ( row . content ) }
142212 </ span >
143213 </ div >
144- ) ;
214+ } ) ;
145215 }
146216
147217 private createDivsForRawOutput ( ) : JSX . Element [ ] | JSX . Element {
0 commit comments