|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"><head><title></title><script> |
| 3 | +/** |
| 4 | + * Factory method to create and load a BotGuardClient instance. |
| 5 | + * @param options - Configuration options for the BotGuardClient. |
| 6 | + * @returns A promise that resolves to a loaded BotGuardClient instance. |
| 7 | + */ |
| 8 | +function loadBotGuard(challengeData) { |
| 9 | + this.vm = this[challengeData.globalName]; |
| 10 | + this.program = challengeData.program; |
| 11 | + this.vmFunctions = {}; |
| 12 | + this.syncSnapshotFunction = null; |
| 13 | + |
| 14 | + if (!this.vm) |
| 15 | + throw new Error('[BotGuardClient]: VM not found in the global object'); |
| 16 | + |
| 17 | + if (!this.vm.a) |
| 18 | + throw new Error('[BotGuardClient]: Could not load program'); |
| 19 | + |
| 20 | + const vmFunctionsCallback = function ( |
| 21 | + asyncSnapshotFunction, |
| 22 | + shutdownFunction, |
| 23 | + passEventFunction, |
| 24 | + checkCameraFunction |
| 25 | + ) { |
| 26 | + this.vmFunctions = { |
| 27 | + asyncSnapshotFunction: asyncSnapshotFunction, |
| 28 | + shutdownFunction: shutdownFunction, |
| 29 | + passEventFunction: passEventFunction, |
| 30 | + checkCameraFunction: checkCameraFunction |
| 31 | + }; |
| 32 | + }; |
| 33 | + |
| 34 | + this.syncSnapshotFunction = this.vm.a(this.program, vmFunctionsCallback, true, this.userInteractionElement, function () {/** no-op */ }, [ [], [] ])[0] |
| 35 | + |
| 36 | + // an asynchronous function runs in the background and it will eventually call |
| 37 | + // `vmFunctionsCallback`, however we need to manually tell JavaScript to pass |
| 38 | + // control to the things running in the background by interrupting this async |
| 39 | + // function in any way, e.g. with a delay of 1ms. The loop is most probably not |
| 40 | + // needed but is there just because. |
| 41 | + return new Promise(function (resolve, reject) { |
| 42 | + i = 0 |
| 43 | + refreshIntervalId = setInterval(function () { |
| 44 | + if (!!this.vmFunctions.asyncSnapshotFunction) { |
| 45 | + resolve(this) |
| 46 | + clearInterval(refreshIntervalId); |
| 47 | + } |
| 48 | + if (i >= 10000) { |
| 49 | + reject("asyncSnapshotFunction is null even after 10 seconds") |
| 50 | + clearInterval(refreshIntervalId); |
| 51 | + } |
| 52 | + i += 1; |
| 53 | + }, 1); |
| 54 | + }) |
| 55 | +} |
| 56 | + |
| 57 | +/** |
| 58 | + * Takes a snapshot asynchronously. |
| 59 | + * @returns The snapshot result. |
| 60 | + * @example |
| 61 | + * ```ts |
| 62 | + * const result = await botguard.snapshot({ |
| 63 | + * contentBinding: { |
| 64 | + * c: "a=6&a2=10&b=SZWDwKVIuixOp7Y4euGTgwckbJA&c=1729143849&d=1&t=7200&c1a=1&c6a=1&c6b=1&hh=HrMb5mRWTyxGJphDr0nW2Oxonh0_wl2BDqWuLHyeKLo", |
| 65 | + * e: "ENGAGEMENT_TYPE_VIDEO_LIKE", |
| 66 | + * encryptedVideoId: "P-vC09ZJcnM" |
| 67 | + * } |
| 68 | + * }); |
| 69 | + * |
| 70 | + * console.log(result); |
| 71 | + * ``` |
| 72 | + */ |
| 73 | +function snapshot(args) { |
| 74 | + return new Promise(function (resolve, reject) { |
| 75 | + if (!this.vmFunctions.asyncSnapshotFunction) |
| 76 | + return reject(new Error('[BotGuardClient]: Async snapshot function not found')); |
| 77 | + |
| 78 | + this.vmFunctions.asyncSnapshotFunction(function (response) { resolve(response) }, [ |
| 79 | + args.contentBinding, |
| 80 | + args.signedTimestamp, |
| 81 | + args.webPoSignalOutput, |
| 82 | + args.skipPrivacyBuffer |
| 83 | + ]); |
| 84 | + }); |
| 85 | +} |
| 86 | + |
| 87 | +function runBotGuard(challengeData) { |
| 88 | + const interpreterJavascript = challengeData.interpreterJavascript.privateDoNotAccessOrElseSafeScriptWrappedValue; |
| 89 | + |
| 90 | + if (interpreterJavascript) { |
| 91 | + new Function(interpreterJavascript)(); |
| 92 | + } else throw new Error('Could not load VM'); |
| 93 | + |
| 94 | + const webPoSignalOutput = []; |
| 95 | + return loadBotGuard({ |
| 96 | + globalName: challengeData.globalName, |
| 97 | + globalObj: this, |
| 98 | + program: challengeData.program |
| 99 | + }).then(function (botguard) { |
| 100 | + return botguard.snapshot({ webPoSignalOutput: webPoSignalOutput }) |
| 101 | + }).then(function (botguardResponse) { |
| 102 | + return { webPoSignalOutput: webPoSignalOutput, botguardResponse: botguardResponse } |
| 103 | + }) |
| 104 | +} |
| 105 | + |
| 106 | +function obtainPoToken(webPoSignalOutput, integrityToken, identifier) { |
| 107 | + const getMinter = webPoSignalOutput[0]; |
| 108 | + |
| 109 | + if (!getMinter) |
| 110 | + throw new Error('PMD:Undefined'); |
| 111 | + |
| 112 | + const mintCallback = getMinter(integrityToken); |
| 113 | + |
| 114 | + if (!(mintCallback instanceof Function)) |
| 115 | + throw new Error('APF:Failed'); |
| 116 | + |
| 117 | + const result = mintCallback(identifier); |
| 118 | + |
| 119 | + if (!result) |
| 120 | + throw new Error('YNJ:Undefined'); |
| 121 | + |
| 122 | + if (!(result instanceof Uint8Array)) |
| 123 | + throw new Error('ODM:Invalid'); |
| 124 | + |
| 125 | + return result; |
| 126 | +} |
| 127 | +</script></head><body></body></html> |
0 commit comments