@@ -10,7 +10,104 @@ export async function getLiveStreamKey(datasourceUid: string, topic?: string): P
1010
1111 const orgId = config . bootData . user . orgId ;
1212 const msgUint8 = new TextEncoder ( ) . encode ( str ) ; // encode as (utf-8) Uint8Array
13- const hashBuffer = await crypto . subtle . digest ( 'SHA-1' , msgUint8 ) ; // hash the message
13+ let hashBuffer ;
14+ if ( crypto . subtle === undefined ) {
15+ // Fall back to our own sha1 if we don't have crypto.subtle (e.g. not on localhost or over https)
16+ hashBuffer = sha1 ( msgUint8 ) ;
17+ }
18+ else {
19+ hashBuffer = await crypto . subtle . digest ( 'SHA-1' , msgUint8 ) ; // hash the message
20+ }
1421 const hashArray = Array . from ( new Uint8Array ( hashBuffer . slice ( 0 , 8 ) ) ) ; // first 8 bytes
1522 return `${ datasourceUid } /${ hashArray . map ( ( b ) => b . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) } /${ orgId } ` ;
1623}
24+
25+ function sha1 ( message : Uint8Array ) : ArrayBuffer {
26+ let h0 = 0x67452301 ;
27+ let h1 = 0xEFCDAB89 ;
28+ let h2 = 0x98BADCFE ;
29+ let h3 = 0x10325476 ;
30+ let h4 = 0xC3D2E1F0 ;
31+
32+ const message_length = message . length * 8 ;
33+
34+ // We need to pad with 0x80, zeroes, and then the message length as a 64-bit integer, to take us up
35+ // to a multiple of 64 bytes.
36+ let buf = new Uint8Array ( 64 * Math . ceil ( ( message . length + 9 ) / 64 ) ) ;
37+ buf . set ( message ) ;
38+ buf [ message . length ] = 0x80 ;
39+
40+
41+ // Bitwise operators truncate to 32 bits, we need to explicitly take the high bits
42+ const message_length_high = Math . floor ( message_length / 0x100000000 ) ;
43+ buf [ buf . length - 8 ] = ( message_length_high & 0xff000000 ) >>> 24 ;
44+ buf [ buf . length - 7 ] = ( message_length_high & 0x00ff0000 ) >>> 16 ;
45+ buf [ buf . length - 6 ] = ( message_length_high & 0x0000ff00 ) >>> 8 ;
46+ buf [ buf . length - 5 ] = ( message_length_high & 0x000000ff ) ;
47+
48+ buf [ buf . length - 4 ] = ( message_length & 0xff000000 ) >>> 24 ;
49+ buf [ buf . length - 3 ] = ( message_length & 0x00ff0000 ) >>> 16 ;
50+ buf [ buf . length - 2 ] = ( message_length & 0x0000ff00 ) >>> 8 ;
51+ buf [ buf . length - 1 ] = ( message_length & 0x000000ff ) ;
52+
53+ for ( let chunkIdx = 0 ; chunkIdx < buf . length ; chunkIdx += 64 ) {
54+ let words = [ ]
55+ for ( let wordIdx = 0 ; wordIdx < 80 ; wordIdx += 1 ) {
56+ if ( wordIdx < 16 ) {
57+ words [ wordIdx ] = buf [ chunkIdx + ( wordIdx * 4 ) ] << 24 |
58+ buf [ chunkIdx + ( wordIdx * 4 ) + 1 ] << 16 |
59+ buf [ chunkIdx + ( wordIdx * 4 ) + 2 ] << 8 |
60+ buf [ chunkIdx + ( wordIdx * 4 ) + 3 ] ;
61+ } else {
62+ const withoutRotation : number = words [ wordIdx - 3 ] ^ words [ wordIdx - 8 ] ^ words [ wordIdx - 14 ] ^ words [ wordIdx - 16 ] ;
63+ words [ wordIdx ] = ( withoutRotation << 1 ) | ( withoutRotation >>> 31 ) ;
64+ }
65+ }
66+
67+ let a = h0 ;
68+ let b = h1 ;
69+ let c = h2 ;
70+ let d = h3 ;
71+ let e = h4 ;
72+
73+ for ( let i = 0 ; i < 80 ; i += 1 ) {
74+ let f ;
75+ let k ;
76+ if ( i < 20 ) {
77+ f = ( b & c ) | ( ( ~ b ) & d ) ;
78+ k = 0x5A827999 ;
79+ } else if ( i < 40 ) {
80+ f = b ^ c ^ d ;
81+ k = 0x6ED9EBA1 ;
82+ } else if ( i < 60 ) {
83+ f = ( b & c ) | ( b & d ) | ( c & d ) ;
84+ k = 0x8F1BBCDC ;
85+ } else {
86+ f = b ^ c ^ d ;
87+ k = 0xCA62C1D6 ;
88+ }
89+
90+ const temp = ( ( a << 5 ) | ( a >>> 27 ) ) + f + e + k + words [ i ] ;
91+ e = d ;
92+ d = c ;
93+ c = ( b << 30 ) | ( b >>> 2 ) ;
94+ b = a ;
95+ a = temp ;
96+ }
97+
98+ h0 += a
99+ h1 += b
100+ h2 += c
101+ h3 += d
102+ h4 += e
103+ }
104+
105+ const retBuffer = new ArrayBuffer ( 20 ) ;
106+ const view = new DataView ( retBuffer ) ;
107+ view . setUint32 ( 0 , h0 , false ) ;
108+ view . setUint32 ( 4 , h1 , false ) ;
109+ view . setUint32 ( 8 , h2 , false ) ;
110+ view . setUint32 ( 12 , h3 , false ) ;
111+ view . setUint32 ( 16 , h4 , false ) ;
112+ return retBuffer ;
113+ }
0 commit comments