diff --git a/games/handlers/flashcards.py b/games/handlers/flashcards.py index 6a58cbf..e2c187b 100644 --- a/games/handlers/flashcards.py +++ b/games/handlers/flashcards.py @@ -62,14 +62,18 @@ def student_view(xblock, context=None): # Obfuscated decoder with unique function name obf_decoder = ( - f"function {init_function_name}({var_names['runtime']},{var_names['elem']}){{" # function header - f"var {var_names['tag']}=$('#{data_element_id}',{var_names['elem']});" # locate script tag - f"if(!{var_names['tag']}.length)return;try{{" # guard - f"var {var_names['payload']}=JSON.parse(atob({var_names['tag']}.text()));" # decode - f"{var_names['tag']}.remove();" # remove script - f"if({var_names['payload']}&&{var_names['payload']}.cards)" # validate - f"GamesXBlockFlashcardsInit({var_names['runtime']},{var_names['elem']},{var_names['payload']}.cards);" # init - f"}}catch({var_names['err']}){{console.warn('Decode failed');}}}}" + f"function {init_function_name}({var_names['runtime']},{var_names['elem']}){{" + f"try{{" + f"var {var_names['tag']}=$('#{data_element_id}',{var_names['elem']});" + f"if(!{var_names['tag']}.length){{console.error('Flashcards: Data element not found');return;}}" + f"var {var_names['payload']}=JSON.parse(atob({var_names['tag']}.text()));" + f"{var_names['tag']}.remove();" + f"if({var_names['payload']}&&{var_names['payload']}.cards){{" + f"if(typeof GamesXBlockFlashcardsInit==='function'){{" + f"GamesXBlockFlashcardsInit({var_names['runtime']},{var_names['elem']},{var_names['payload']}.cards);" + f"}}else{{console.error('Flashcards: GamesXBlockFlashcardsInit not defined');}}" + f"}}else{{console.error('Flashcards: Invalid payload');}}" + f"}}catch({var_names['err']}){{console.error('Flashcards decode failed:',{var_names['err']});}}}}" ) template_context = { @@ -97,5 +101,6 @@ def student_view(xblock, context=None): __name__, "../static/js/src/flashcards.js" ).decode("utf8") ) + frag.add_javascript(obf_decoder) frag.initialize_js(init_function_name) return frag diff --git a/games/handlers/matching.py b/games/handlers/matching.py index b5791ff..053efd5 100644 --- a/games/handlers/matching.py +++ b/games/handlers/matching.py @@ -124,13 +124,18 @@ def student_view(xblock, context=None): # Build obfuscated decoder function; initializes JS via payload obf_decoder = ( f"function {init_function_name}({var_names['runtime']},{var_names['elem']}){{" + f"try{{" f"var {var_names['tag']}=$('#{data_element_id}',{var_names['elem']});" - f"if(!{var_names['tag']}.length)return;try{{" + f"if(!{var_names['tag']}.length){{console.error('Matching: Data element not found');return;}}" f"var {var_names['payload']}=JSON.parse(atob({var_names['tag']}.text()));" - f"{var_names['tag']}.remove();if({var_names['payload']}&&{var_names['payload']}.pages)" + f"{var_names['tag']}.remove();" + f"if({var_names['payload']}&&{var_names['payload']}.pages){{" + f"if(typeof GamesXBlockMatchingInit==='function'){{" f"GamesXBlockMatchingInit({runtime},{elem},{payload}.pages,{payload}.key);" + f"}}else{{console.error('Matching: GamesXBlockMatchingInit not defined');}}" + f"}}else{{console.error('Matching: Invalid payload');}}" f"$('#obf_decoder_script',{var_names['elem']}).remove();" - f"}}catch({var_names['err']}){{console.warn('Decode failed');}}}}" + f"}}catch({var_names['err']}){{console.error('Matching decode failed:',{var_names['err']});}}}}" ) template_context["encoded_mapping"] = encoded_mapping @@ -165,6 +170,8 @@ def student_view(xblock, context=None): __name__, "../static/js/src/confetti.js" ).decode("utf8") ) + # Add decoder function AFTER main JS files so GamesXBlockMatchingInit is defined + frag.add_javascript(obf_decoder) frag.initialize_js(init_function_name) return frag diff --git a/games/static/html/flashcards.html b/games/static/html/flashcards.html index 47ef59d..484306d 100644 --- a/games/static/html/flashcards.html +++ b/games/static/html/flashcards.html @@ -3,7 +3,7 @@ - +
diff --git a/games/static/html/matching.html b/games/static/html/matching.html index 25e33a9..5a6ba29 100644 --- a/games/static/html/matching.html +++ b/games/static/html/matching.html @@ -2,7 +2,7 @@ - +
diff --git a/games/static/js/src/matching.js b/games/static/js/src/matching.js index 3cbd2a0..eb606ff 100644 --- a/games/static/js/src/matching.js +++ b/games/static/js/src/matching.js @@ -63,7 +63,7 @@ function GamesXBlockMatchingInit(runtime, element, pages, matching_key) { var match = scriptContent.match(/function\s+(\w+)\s*\(/); if (match) { var initFuncName = match[1]; - eval(scriptContent); + (1, eval)(scriptContent); if (typeof window[initFuncName] === 'function') { window[initFuncName](runtime, element); setTimeout(function() { diff --git a/setup.py b/setup.py index 8707ca4..c691456 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ def package_data(pkg, roots): setup( name="edx-games", - version="1.0.10", + version="1.0.11", description="Interactive games XBlock for Open edX - Create flashcards and matching games with image support", author="edX", author_email="edx@edx.org",