@scrypted/server 0.114.0 → 0.115.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/fetch/http-fetch.js +6 -27
  2. package/dist/fetch/http-fetch.js.map +1 -1
  3. package/dist/fetch/index.d.ts +5 -2
  4. package/dist/fetch/index.js +6 -26
  5. package/dist/fetch/index.js.map +1 -1
  6. package/dist/listen-zero.d.ts +2 -2
  7. package/dist/listen-zero.js +1 -1
  8. package/dist/listen-zero.js.map +1 -1
  9. package/dist/plugin/plugin-console.js +2 -2
  10. package/dist/plugin/plugin-console.js.map +1 -1
  11. package/dist/plugin/plugin-npm-dependencies.js +5 -1
  12. package/dist/plugin/plugin-npm-dependencies.js.map +1 -1
  13. package/dist/plugin/plugin-remote-worker.js +22 -17
  14. package/dist/plugin/plugin-remote-worker.js.map +1 -1
  15. package/dist/plugin/plugin-remote.js +0 -1
  16. package/dist/plugin/plugin-remote.js.map +1 -1
  17. package/dist/plugin/plugin-repl.js +1 -1
  18. package/dist/plugin/plugin-repl.js.map +1 -1
  19. package/dist/rpc-peer-eval.d.ts +4 -0
  20. package/dist/rpc-peer-eval.js +25 -0
  21. package/dist/rpc-peer-eval.js.map +1 -0
  22. package/dist/rpc-serializer.js.map +1 -1
  23. package/dist/rpc.d.ts +4 -4
  24. package/dist/rpc.js +6 -23
  25. package/dist/rpc.js.map +1 -1
  26. package/dist/runtime.js +7 -5
  27. package/dist/runtime.js.map +1 -1
  28. package/dist/scrypted-server-main.js +14 -0
  29. package/dist/scrypted-server-main.js.map +1 -1
  30. package/package.json +12 -12
  31. package/python/plugin_remote.py +39 -11
  32. package/python/rpc.py +10 -10
  33. package/src/fetch/http-fetch.ts +7 -32
  34. package/src/fetch/index.ts +10 -33
  35. package/src/listen-zero.ts +3 -3
  36. package/src/plugin/plugin-console.ts +2 -2
  37. package/src/plugin/plugin-npm-dependencies.ts +5 -1
  38. package/src/plugin/plugin-remote-worker.ts +25 -17
  39. package/src/plugin/plugin-remote.ts +1 -2
  40. package/src/plugin/plugin-repl.ts +1 -1
  41. package/src/rpc-peer-eval.ts +27 -0
  42. package/src/rpc-serializer.ts +2 -2
  43. package/src/rpc.ts +16 -32
  44. package/src/runtime.ts +9 -5
  45. package/src/scrypted-server-main.ts +16 -0
package/src/rpc.ts CHANGED
@@ -1,6 +1,3 @@
1
- import type { CompileFunctionOptions } from 'vm';
2
- type CompileFunction = (code: string, params?: ReadonlyArray<string>, options?: CompileFunctionOptions) => Function;
3
-
4
1
  export function startPeriodicGarbageCollection() {
5
2
  if (!global.gc) {
6
3
  console.warn('rpc peer garbage collection not available: global.gc is not exposed.');
@@ -253,12 +250,6 @@ export class RPCResultError extends Error {
253
250
  }
254
251
  }
255
252
 
256
- function compileFunction(code: string, params?: ReadonlyArray<string>, options?: CompileFunctionOptions): any {
257
- params = params || [];
258
- const f = `(function(${params.join(',')}) {;${code};})`;
259
- return eval(f);
260
- }
261
-
262
253
  declare class WeakRef<T> {
263
254
  target: T;
264
255
  constructor(target: any);
@@ -313,7 +304,10 @@ export class RpcPeer {
313
304
  finalizers = new FinalizationRegistry(entry => this.finalize(entry as LocalProxiedEntry));
314
305
  nameDeserializerMap = new Map<string, RpcSerializer>();
315
306
  onProxyTypeSerialization = new Map<string, (value: any) => void>();
316
- onProxySerialization: (value: any, proxyId: string) => any;
307
+ onProxySerialization: (value: any) => {
308
+ proxyId: string;
309
+ properties: any;
310
+ };
317
311
  constructorSerializerMap = new Map<any, string>();
318
312
  transportSafeArgumentTypes = RpcPeer.getDefaultTransportSafeArgumentTypes();
319
313
  killed: Promise<string>;
@@ -499,23 +493,6 @@ export class RpcPeer {
499
493
  });
500
494
  }
501
495
 
502
- evalLocal<T>(script: string, filename?: string, coercedParams?: { [name: string]: any }): T {
503
- const params = Object.assign({}, this.params, coercedParams);
504
- let compile: CompileFunction;
505
- try {
506
- // prevent bundlers from trying to include non-existent vm module.
507
- compile = module[`require`]('vm').compileFunction;
508
- }
509
- catch (e) {
510
- compile = compileFunction;
511
- }
512
- const f = compile(script, Object.keys(params), {
513
- filename,
514
- });
515
- const value = f(...Object.values(params));
516
- return value;
517
- }
518
-
519
496
  /**
520
497
  * @deprecated
521
498
  * @param result
@@ -656,7 +633,16 @@ export class RpcPeer {
656
633
 
657
634
  this.onProxyTypeSerialization.get(__remote_constructor_name)?.(value);
658
635
 
659
- const __remote_proxy_id = RpcPeer.generateId();
636
+ const {
637
+ proxyId: __remote_proxy_id,
638
+ properties: __remote_proxy_props,
639
+ } = this.onProxySerialization
640
+ ? this.onProxySerialization(value)
641
+ : {
642
+ proxyId: RpcPeer.generateId(),
643
+ properties: RpcPeer.prepareProxyProperties(value),
644
+ };
645
+
660
646
  proxiedEntry = {
661
647
  id: __remote_proxy_id,
662
648
  finalizerId: __remote_proxy_id,
@@ -664,8 +650,6 @@ export class RpcPeer {
664
650
  this.localProxied.set(value, proxiedEntry);
665
651
  this.localProxyMap.set(__remote_proxy_id, value);
666
652
 
667
- const __remote_proxy_props = this.onProxySerialization ? this.onProxySerialization(value, __remote_proxy_id) : RpcPeer.prepareProxyProperties(value);
668
-
669
653
  const ret: RpcRemoteProxyValue = {
670
654
  __remote_proxy_id,
671
655
  __remote_proxy_finalizer_id: __remote_proxy_id,
@@ -723,7 +707,7 @@ export class RpcPeer {
723
707
  }
724
708
  catch (e) {
725
709
  // console.error('failure', rpcApply.method, e);
726
- this.createErrorResult(result, e);
710
+ this.createErrorResult(result, e as Error);
727
711
  }
728
712
 
729
713
  this.send(result, undefined, serializationContext);
@@ -785,7 +769,7 @@ export class RpcPeer {
785
769
  }
786
770
  catch (e) {
787
771
  // console.error('failure', rpcApply.method, e);
788
- this.createErrorResult(result, e);
772
+ this.createErrorResult(result, e as Error);
789
773
  }
790
774
 
791
775
  if (!rpcApply.oneway)
package/src/runtime.ts CHANGED
@@ -275,10 +275,11 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
275
275
  return;
276
276
  }
277
277
 
278
+ const reqany = req as any;
278
279
  if ((req as any).upgradeHead)
279
- this.connectRPCObjectIO.handleUpgrade(req, res.socket, (req as any).upgradeHead)
280
+ this.connectRPCObjectIO.handleUpgrade(reqany, res.socket, reqany.upgradeHead)
280
281
  else
281
- this.connectRPCObjectIO.handleRequest(req, res);
282
+ this.connectRPCObjectIO.handleRequest(reqany, res);
282
283
  }
283
284
 
284
285
  async getEndpointPluginData(req: Request, endpoint: string, isUpgrade: boolean, isEngineIOEndpoint: boolean): Promise<HttpPluginData> {
@@ -422,15 +423,18 @@ export class ScryptedRuntime extends PluginHttp<HttpPluginData> {
422
423
  return;
423
424
  }
424
425
 
425
- (req as any).scrypted = {
426
+ const reqany = req as any;
427
+
428
+ reqany.scrypted = {
426
429
  endpointRequest,
427
430
  pluginDevice,
428
431
  accessControls,
429
432
  };
433
+
430
434
  if ((req as any).upgradeHead)
431
- pluginHost.io.handleUpgrade(req, res.socket, (req as any).upgradeHead)
435
+ pluginHost.io.handleUpgrade(reqany, res.socket, reqany.upgradeHead)
432
436
  else
433
- pluginHost.io.handleRequest(req, res);
437
+ pluginHost.io.handleRequest(reqany, res);
434
438
  }
435
439
 
436
440
  handleRequestEndpoint(req: Request, res: Response, endpointRequest: HttpRequest, pluginData: HttpPluginData) {
@@ -161,6 +161,16 @@ async function start(mainFilename: string, options?: {
161
161
  callback(sha === user.passwordHash || password === user.token);
162
162
  });
163
163
 
164
+ // the default http-auth will returns a WWW-Authenticate header if login fails.
165
+ // this causes the Safari to prompt for login.
166
+ // https://github.com/gevorg/http-auth/blob/4158fa75f58de70fd44aa68876a8674725e0556e/src/auth/base.js#L81
167
+ // override the ask function to return a bare 401 instead.
168
+ // @ts-expect-error
169
+ basicAuth.ask = (res) => {
170
+ res.statusCode = 401;
171
+ res.end();
172
+ };
173
+
164
174
  const httpsServerOptions = process.env.SCRYPTED_HTTPS_OPTIONS_FILE
165
175
  ? JSON.parse(fs.readFileSync(process.env.SCRYPTED_HTTPS_OPTIONS_FILE).toString())
166
176
  : {};
@@ -219,6 +229,12 @@ async function start(mainFilename: string, options?: {
219
229
  }
220
230
 
221
231
  app.use(async (req, res, next) => {
232
+ // /web/component requires basic auth admin access.
233
+ if (req.url.startsWith('/web/component/')) {
234
+ next();
235
+ return;
236
+ }
237
+
222
238
  // the remote address may be ipv6 prefixed so use a fuzzy match.
223
239
  // eg ::ffff:192.168.2.124
224
240
  if (process.env.SCRYPTED_ADMIN_USERNAME