@xiboplayer/xmr 0.3.0 → 0.3.3

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.
package/README.md CHANGED
@@ -45,4 +45,4 @@ xmr.connect();
45
45
 
46
46
  ---
47
47
 
48
- **Part of the [XiboPlayer SDK](https://github.com/linuxnow/xiboplayer)**
48
+ **Part of the [XiboPlayer SDK](https://github.com/xibo-players/xiboplayer)** | [MCP Server](https://github.com/xibo-players/xiboplayer/tree/main/mcp-server) for AI-assisted development
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiboplayer/xmr",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "XMR WebSocket client for real-time Xibo CMS commands",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@xibosignage/xibo-communication-framework": "^0.0.6",
12
- "@xiboplayer/utils": "0.3.0"
12
+ "@xiboplayer/utils": "0.3.3"
13
13
  },
14
14
  "devDependencies": {
15
15
  "vitest": "^2.0.0"
package/src/test-utils.js CHANGED
@@ -101,6 +101,14 @@ export function createMockConfig(overrides = {}) {
101
101
  hardwareKey: 'test-hw-key',
102
102
  serverKey: 'test-server-key',
103
103
  xmrChannel: 'test-channel',
104
+ data: {
105
+ xmrPubKey: '',
106
+ xmrPrivKey: '',
107
+ },
108
+ ensureXmrKeyPair: vi.fn(async function () {
109
+ this.data.xmrPubKey = '-----BEGIN PUBLIC KEY-----\nMOCK\n-----END PUBLIC KEY-----';
110
+ this.data.xmrPrivKey = '-----BEGIN PRIVATE KEY-----\nMOCK\n-----END PRIVATE KEY-----';
111
+ }),
104
112
  ...overrides
105
113
  };
106
114
  }
@@ -232,10 +232,18 @@ export class XmrWrapper {
232
232
  }
233
233
  });
234
234
 
235
- // CMS command: Rekey
236
- this.xmr.on('rekey', () => {
237
- log.debug('Received rekey command (pubKey rotation)');
238
- // TODO: Implement RSA key pair rotation if XMR encryption is needed
235
+ // CMS command: Rekey (RSA key pair rotation)
236
+ this.xmr.on('rekey', async () => {
237
+ log.info('Received rekey command - rotating RSA key pair');
238
+ try {
239
+ this.config.data.xmrPubKey = '';
240
+ this.config.data.xmrPrivKey = '';
241
+ await this.config.ensureXmrKeyPair();
242
+ await this.player.collect();
243
+ log.info('RSA key pair rotated successfully');
244
+ } catch (error) {
245
+ log.error('Key rotation failed:', error);
246
+ }
239
247
  });
240
248
 
241
249
  // CMS command: Screen Shot (alternative event name)
@@ -305,11 +305,36 @@ describe('XmrWrapper', () => {
305
305
  consoleErrorSpy.mockRestore();
306
306
  });
307
307
 
308
- it('should handle rekey command', () => {
309
- // rekey is a debug-level log — just verify it doesn't throw
310
- expect(() => {
311
- xmrInstance.simulateCommand('rekey');
312
- }).not.toThrow();
308
+ it('should handle rekey command — rotates RSA keys and triggers collect', async () => {
309
+ // Set existing keys
310
+ mockConfig.data.xmrPubKey = 'old-pub-key';
311
+ mockConfig.data.xmrPrivKey = 'old-priv-key';
312
+
313
+ xmrInstance.simulateCommand('rekey');
314
+ await vi.runAllTimersAsync();
315
+
316
+ // Should clear old keys before regenerating
317
+ expect(mockConfig.ensureXmrKeyPair).toHaveBeenCalled();
318
+ // After ensureXmrKeyPair, new keys should be set
319
+ expect(mockConfig.data.xmrPubKey).toMatch(/^-----BEGIN PUBLIC KEY-----/);
320
+ expect(mockConfig.data.xmrPrivKey).toMatch(/^-----BEGIN PRIVATE KEY-----/);
321
+ // Should trigger collect to re-register with new key
322
+ expect(mockPlayer.collect).toHaveBeenCalled();
323
+ });
324
+
325
+ it('should handle rekey failure gracefully', async () => {
326
+ mockConfig.ensureXmrKeyPair.mockRejectedValue(new Error('Key generation failed'));
327
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
328
+
329
+ xmrInstance.simulateCommand('rekey');
330
+ await vi.runAllTimersAsync();
331
+
332
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
333
+ '[XMR]',
334
+ 'Key rotation failed:',
335
+ expect.any(Error)
336
+ );
337
+ consoleErrorSpy.mockRestore();
313
338
  });
314
339
 
315
340
  it('should handle criteriaUpdate command', async () => {