@@ -21,9 +21,10 @@ const parseURL = url => {
2121/**
2222 * Sets up the global.Scratch API for an unsandboxed extension.
2323 * @param {VirtualMachine } vm
24+ * @param {{bypassSecurity?: boolean} } [options]
2425 * @returns {Promise<object[]> } Resolves with a list of extension objects when Scratch.extensions.register is called.
2526 */
26- const setupUnsandboxedExtensionAPI = vm => new Promise ( resolve => {
27+ const setupUnsandboxedExtensionAPI = ( vm , options = { } ) => new Promise ( resolve => {
2728 const extensionObjects = [ ] ;
2829 const register = extensionObject => {
2930 extensionObjects . push ( extensionObject ) ;
@@ -39,7 +40,10 @@ const setupUnsandboxedExtensionAPI = vm => new Promise(resolve => {
3940 Scratch . vm = vm ;
4041 Scratch . renderer = vm . runtime . renderer ;
4142
43+ const bypass = options . bypassSecurity === true ;
44+
4245 Scratch . canFetch = async url => {
46+ if ( bypass ) return true ;
4347 const parsed = parseURL ( url ) ;
4448 if ( ! parsed ) {
4549 return false ;
@@ -52,6 +56,7 @@ const setupUnsandboxedExtensionAPI = vm => new Promise(resolve => {
5256 } ;
5357
5458 Scratch . canOpenWindow = async url => {
59+ if ( bypass ) return true ;
5560 const parsed = parseURL ( url ) ;
5661 if ( ! parsed ) {
5762 return false ;
@@ -65,6 +70,7 @@ const setupUnsandboxedExtensionAPI = vm => new Promise(resolve => {
6570 } ;
6671
6772 Scratch . canRedirect = async url => {
73+ if ( bypass ) return true ;
6874 const parsed = parseURL ( url ) ;
6975 if ( ! parsed ) {
7076 return false ;
@@ -77,17 +83,33 @@ const setupUnsandboxedExtensionAPI = vm => new Promise(resolve => {
7783 return vm . securityManager . canRedirect ( parsed . href ) ;
7884 } ;
7985
80- Scratch . canRecordAudio = async ( ) => vm . securityManager . canRecordAudio ( ) ;
86+ Scratch . canRecordAudio = async ( ) => {
87+ if ( bypass ) return true ;
88+ return vm . securityManager . canRecordAudio ( ) ;
89+ } ;
8190
82- Scratch . canRecordVideo = async ( ) => vm . securityManager . canRecordVideo ( ) ;
91+ Scratch . canRecordVideo = async ( ) => {
92+ if ( bypass ) return true ;
93+ return vm . securityManager . canRecordVideo ( ) ;
94+ } ;
8395
84- Scratch . canReadClipboard = async ( ) => vm . securityManager . canReadClipboard ( ) ;
96+ Scratch . canReadClipboard = async ( ) => {
97+ if ( bypass ) return true ;
98+ return vm . securityManager . canReadClipboard ( ) ;
99+ } ;
85100
86- Scratch . canNotify = async ( ) => vm . securityManager . canNotify ( ) ;
101+ Scratch . canNotify = async ( ) => {
102+ if ( bypass ) return true ;
103+ return vm . securityManager . canNotify ( ) ;
104+ } ;
87105
88- Scratch . canGeolocate = async ( ) => vm . securityManager . canGeolocate ( ) ;
106+ Scratch . canGeolocate = async ( ) => {
107+ if ( bypass ) return true ;
108+ return vm . securityManager . canGeolocate ( ) ;
109+ } ;
89110
90111 Scratch . canEmbed = async url => {
112+ if ( bypass ) return true ;
91113 const parsed = parseURL ( url ) ;
92114 if ( ! parsed ) {
93115 return false ;
@@ -96,6 +118,7 @@ const setupUnsandboxedExtensionAPI = vm => new Promise(resolve => {
96118 } ;
97119
98120 Scratch . canDownload = async ( url , name ) => {
121+ if ( bypass ) return true ;
99122 const parsed = parseURL ( url ) ;
100123 if ( ! parsed ) {
101124 return false ;
@@ -200,9 +223,10 @@ const teardownUnsandboxedExtensionAPI = () => {
200223 * Load an unsandboxed extension from an arbitrary URL. This is dangerous.
201224 * @param {string } extensionURL
202225 * @param {Virtualmachine } vm
226+ * @param {{bypassSecurity?: boolean} } [options]
203227 * @returns {Promise<object[]> } Resolves with a list of extension objects if the extension was loaded successfully.
204228 */
205- const loadUnsandboxedExtension = ( extensionURL , vm ) => new Promise ( ( resolve , reject ) => {
229+ const loadUnsandboxedExtension = ( extensionURL , vm , options = { } ) => new Promise ( ( resolve , reject ) => {
206230 let isResolved = false ;
207231 let registrationTimeout = null ;
208232 let overallTimeout = null ;
@@ -215,7 +239,7 @@ const loadUnsandboxedExtension = (extensionURL, vm) => new Promise((resolve, rej
215239 fn ( arg ) ;
216240 } ;
217241
218- setupUnsandboxedExtensionAPI ( vm )
242+ setupUnsandboxedExtensionAPI ( vm , options )
219243 . then ( extensionObjects => settle ( resolve , extensionObjects ) )
220244 . catch ( error => {
221245 error . url = extensionURL ;
@@ -293,9 +317,9 @@ const prefetchExtensionScript = extensionURL => {
293317// only let one extension register at a time. The script download is started up front (in
294318// parallel across extensions) so only the registration step is serialized.
295319const limiter = new AsyncLimiter ( loadUnsandboxedExtension , 1 ) ;
296- const load = ( extensionURL , vm ) => {
320+ const load = ( extensionURL , vm , options = { } ) => {
297321 prefetchExtensionScript ( extensionURL ) ;
298- return limiter . do ( extensionURL , vm ) ;
322+ return limiter . do ( extensionURL , vm , options ) ;
299323} ;
300324
301325module . exports = {
0 commit comments