2022-10-19 17:10:34 +00:00
const tabIDs = { } ;
const textDecoder = new TextDecoder ( ) ;
function requestToClipboard ( tabId ) {
chrome . tabs . get ( tabId , ( details ) => {
const lic _headers = tabIDs [ details . id ] . license _request [ 0 ] ? . license _headers ;
const lic _url = tabIDs [ details . id ] . license _url ;
const lic _data _json = tabIDs [ details . id ] . license _data ;
const mpd _link = tabIDs [ details . id ] . mpd _url ;
if ( ! lic _headers )
return ;
// Fetching the user's ip for setting the header X-Forwarded-For.
// This might help to bypass regional restrictions when performing the license request in some cases.
const ip _retrieve _link = "https://ipinfo.io/ip" ;
var get _ip = new XMLHttpRequest ( ) ;
get _ip . open ( 'GET' , ip _retrieve _link , true ) ;
get _ip . onload = function ( ) {
var ip _resposnse = this . responseText ;
console . log ( ip _resposnse ) ;
var i = 0 ;
let curl _license _data = "curl " ;
curl _license _data += ` ' ${ lic _url } ' \\ ` ;
for ( ; i < lic _headers . length ; ++ i )
curl _license _data += ` \n -H ' ${ lic _headers [ i ] . name . toLowerCase ( ) } : ${ lic _headers [ i ] . value } ' \\ ` ;
curl _license _data += ` \n -H 'x-forwarded-for: ${ ip _resposnse } ' \\ ` ;
curl _license _data += "\n --data-raw " ;
if ( lic _data _json . includes ( "u0008" ) ) {
curl _license _data += ` ${ lic _data _json } \\ ` ;
} else {
curl _license _data += ` ' ${ lic _data _json } ' \\ ` ; /* It is not the same as above line. Note the additional ' symbol at the start and end! */
}
curl _license _data += "\n --compressed" ;
// Generating the curl license text link for https://t.me/drm_downloader_robot
const license _gen _link = "https://drm-bot.herokuapp.com/gen.php" ;
var data = new FormData ( ) ;
data . append ( 'playlist' , curl _license _data ) ;
data . append ( 'api' , 'api' ) ;
var gen _link = new XMLHttpRequest ( ) ;
gen _link . open ( 'POST' , license _gen _link , true ) ;
gen _link . onload = function ( ) {
var gen _link _resposnse = this . responseText ;
let json _resp = JSON . parse ( gen _link _resposnse ) ;
console . log ( json _resp ) ;
let generated _license _link = json _resp . data ;
const final = ` ${ mpd _link } * ${ generated _license _link } ` ;
console . log ( final ) ;
const copyText = document . createElement ( "textarea" ) ;
copyText . style . position = "absolute" ;
copyText . style . left = "-5454px" ;
copyText . style . top = "-5454px" ;
copyText . style . opacity = 0 ;
document . body . appendChild ( copyText ) ;
copyText . value = final ;
copyText . select ( ) ;
document . execCommand ( "copy" ) ;
document . body . removeChild ( copyText ) ;
chrome . browserAction . setBadgeBackgroundColor ( { color : "#FF0000" , tabId : details . id } ) ;
chrome . browserAction . setBadgeText ( { text : "📋" , tabId : details . id } ) ;
console . log ( "The mpd link and the generated link of widevine license curl data has been copied to your clipboard successfully!\n\nNow go to https://t.me/drm_downloader_robot and paste it and send it to the bot." ) ;
}
gen _link . send ( data ) ;
}
get _ip . send ( ) ;
} ) ;
}
function getLicenseRequestData ( details ) {
tabIDs [ details . tabId ] = tabIDs [ details . tabId ] || { } ;
2022-10-23 02:34:55 +00:00
if ( details . url . includes ( ".mpd" ) || details . url . includes ( ".ism" ) || details . url . includes ( "manifest" ) ) {
2022-10-19 17:10:34 +00:00
console . log ( details . url ) ;
tabIDs [ details . tabId ] . mpd _url = details . url ;
} else if ( details . requestBody && details . requestBody . raw && details . method == "POST" ) {
for ( var j = 0 ; j < details . requestBody . raw . length ; ++ j ) {
try {
const decodedString = textDecoder . decode ( details . requestBody . raw [ j ] . bytes ) ;
const encodedString = btoa ( unescape ( encodeURIComponent ( decodedString ) ) ) ;
// If the license request does not uses json payloads the data has been sent in raw format.
// But the base64 encoded format of it will have the characters "CAES".
if ( encodedString . includes ( "CAES" ) ) {
tabIDs [ details . tabId ] = { license _data : ` $ ' \\ u0008 \\ u0004' ` , license _request : [ ] , license _url : details . url , req _id : details . requestId , mpd _url : tabIDs [ details . tabId ] . mpd _url ? ? "" } ;
// If the license request uses json payloads the charcters "CAES" will be there in almost all cases.
} else if ( decodedString . includes ( "CAES" ) || details . url . includes ( "license" ) && decodedString . includes ( "token" ) && decodedString . length > 4000 || decodedString . includes ( "8,1,18" ) ) {
tabIDs [ details . tabId ] = { license _data : decodedString , license _request : [ ] , license _url : details . url , req _id : details . requestId , mpd _url : tabIDs [ details . tabId ] . mpd _url ? ? "" } ;
} else {
return ;
}
} catch ( e ) {
console . error ( e ) ;
}
}
} else if ( details . requestBody && details . requestBody . formData && details . method == "POST" ) {
try {
if ( details . requestBody . formData . widevine2Challenge ) {
const challenge = String ( details . requestBody . formData . widevine2Challenge )
if ( challenge . includes ( "CAES" ) ) {
const decodedString = ` widevine2Challenge= ${ challenge } &includeHdcpTestKeyInLicense=true ` ;
tabIDs [ details . tabId ] = { license _data : decodedString , license _request : [ ] , license _url : details . url , req _id : details . requestId , mpd _url : tabIDs [ details . tabId ] . mpd _url ? ? "" } ;
}
} else {
return ;
}
} catch ( e ) {
console . error ( e ) ;
}
}
}
chrome . webRequest . onBeforeRequest . addListener (
getLicenseRequestData ,
{ urls : [ "<all_urls>" ] , types : [ "xmlhttprequest" ] } ,
[ "requestBody" ]
) ;
function getLicenseRequestHeaders ( details ) {
if ( details . method == "POST" && tabIDs [ details . tabId ] && tabIDs [ details . tabId ] . license _url === details . url && tabIDs [ details . tabId ] . req _id === details . requestId ) {
console . log ( details . url ) ;
tabIDs [ details . tabId ] . license _request . push ( { license _headers : details . requestHeaders } ) ;
requestToClipboard ( details . tabId ) ;
// Some license requests can hold one time token values in their headers or payload. So blocking such requests before they are sent to the server and capturing them!
// If your license request also holds one time values add them in the below line, seprating by an || operator. Remember to disable the extension if you actually need to play the video of these services!
2022-10-22 06:16:01 +00:00
if ( details . url . includes ( "api2.hbogoasia.com/onwards-widevine" ) || details . requestHeaders . includes ( "prepladder.com" ) || details . url . includes ( "scvm1sc0.anycast.nagra.com" ) || details . url . includes ( "wvls/contentlicenseservice/v1/licenses" ) || details . url . includes ( "license.vdocipher.com/auth" ) ) {
2022-10-19 17:10:34 +00:00
return { cancel : true } ;
}
}
}
chrome . webRequest . onBeforeSendHeaders . addListener (
getLicenseRequestHeaders ,
{ urls : [ "<all_urls>" ] , types : [ "xmlhttprequest" ] } ,
[ "requestHeaders" , "blocking" ]
2022-10-22 06:16:01 +00:00
) ;