alexa-cookie2 5.0.4 → 5.0.5

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
@@ -55,6 +55,9 @@ Partly based on [Amazon Alexa Remote Control](http://blog.loetzimmer.de/2017/10/
55
55
  Thank you for that work.
56
56
 
57
57
  ## Changelog:
58
+ ### 5.0.5 (2026-07-06)
59
+ * (@Apollon77) Fix Proxy URL when no static port is provided
60
+
58
61
  ### 5.0.4 (2026-07-05)
59
62
  * (@fkhr79, @blabond) Fix Amazon login proxy auth flow
60
63
 
package/lib/proxy.js CHANGED
@@ -72,7 +72,7 @@ function customStringify(v, func, intent) {
72
72
 
73
73
  function initAmazonProxy(_options, callbackCookie, callbackListening) {
74
74
  const initialCookies = {};
75
- const proxyBase = `http://${_options.proxyOwnIp}:${_options.proxyPort}/`;
75
+ const proxyBase = () => `http://${_options.proxyOwnIp}:${_options.proxyPort}/`;
76
76
  const defaultAmazonHost = `www.${_options.baseAmazonPage}`;
77
77
  const amazonProxyHosts = [];
78
78
 
@@ -106,7 +106,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
106
106
  function amazonHostFromProxyUrl(url) {
107
107
  if (!url) return null;
108
108
  for (const host of amazonProxyHosts) {
109
- if (url === `${proxyBase}${host}` || url.startsWith(`${proxyBase}${host}/`)) {
109
+ if (url === `${proxyBase()}${host}` || url.startsWith(`${proxyBase()}${host}/`)) {
110
110
  return host;
111
111
  }
112
112
  }
@@ -286,22 +286,23 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
286
286
  data = data.replace(///g, '/');
287
287
  for (const host of amazonProxyHosts) {
288
288
  const hostRegex = new RegExp(`https?://${escapeRegex(host)}:?[0-9]*/`, 'g');
289
- data = data.replace(hostRegex, `${proxyBase}${host}/`);
289
+ data = data.replace(hostRegex, `${proxyBase()}${host}/`);
290
290
  }
291
291
  //_options.logger && _options.logger('REPLACEHOSTS: ' + dataOrig + ' --> ' + data);
292
292
  return data;
293
293
  }
294
294
 
295
295
  function replaceHostsBack(data) {
296
+ const base = proxyBase();
296
297
  for (const host of amazonProxyHosts) {
297
- const hostRegex = new RegExp(`${escapeRegex(proxyBase)}${escapeRegex(host)}/`, 'g');
298
+ const hostRegex = new RegExp(`${escapeRegex(base)}${escapeRegex(host)}/`, 'g');
298
299
  data = data.replace(hostRegex, `https://${host}/`);
299
300
  }
300
- if (data === proxyBase) {
301
+ if (data === base) {
301
302
  data = returnedInitUrl;
302
303
  }
303
- else if (data.startsWith(proxyBase)) {
304
- data = `https://${defaultAmazonHost}/${data.slice(proxyBase.length)}`;
304
+ else if (data.startsWith(base)) {
305
+ data = `https://${defaultAmazonHost}/${data.slice(base.length)}`;
305
306
  }
306
307
  return data;
307
308
  }
@@ -466,7 +467,8 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
466
467
  _options.proxyPort = undefined;
467
468
  }
468
469
  const server = app.listen(_options.proxyPort, _options.proxyListenBind, function() {
469
- _options.logger && _options.logger(`Alexa-Cookie: Proxy-Server listening on port ${server.address().port}`);
470
+ _options.proxyPort = this.address().port;
471
+ _options.logger && _options.logger(`Alexa-Cookie: Proxy-Server listening on port ${_options.proxyPort}`);
470
472
  callbackListening && callbackListening(server);
471
473
  callbackListening = null;
472
474
  }).on('error', err => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alexa-cookie2",
3
- "version": "5.0.4",
3
+ "version": "5.0.5",
4
4
  "description": "Generate Cookie and CSRF for Alexa Remote",
5
5
  "author": {
6
6
  "name": "Apollon77",
@@ -0,0 +1,147 @@
1
+ const assert = require('assert');
2
+ const fs = require('fs');
3
+ const os = require('os');
4
+ const path = require('path');
5
+ const vm = require('vm');
6
+
7
+ const testName = 'proxy-random-port';
8
+ const outputDir = process.env.ALEXA_COOKIE_TEST_OUTPUT_DIR || path.join(__dirname, '..', 'test-output');
9
+ const outputFile = path.join(outputDir, `${testName}.txt`);
10
+ const lines = [];
11
+
12
+ function line(value = '') {
13
+ lines.push(value);
14
+ }
15
+
16
+ function writeOutput() {
17
+ fs.mkdirSync(outputDir, { recursive: true });
18
+ fs.writeFileSync(outputFile, `${lines.join('\n')}\n`);
19
+ }
20
+
21
+ function recordAssertion(description, fn) {
22
+ try {
23
+ fn();
24
+ line(`${description}: PASS`);
25
+ } catch (err) {
26
+ line(`${description}: FAIL`);
27
+ writeOutput();
28
+ throw err;
29
+ }
30
+ }
31
+
32
+ const proxyFile = path.join(__dirname, '..', 'lib', 'proxy.js');
33
+ const source = fs.readFileSync(proxyFile, 'utf8');
34
+
35
+ const ASSIGNED_PORT = 3456;
36
+ let capturedProxyOptions;
37
+
38
+ function createExpressStub() {
39
+ return {
40
+ use() {},
41
+ get() {},
42
+ listen(port, bind, callback) {
43
+ const server = {
44
+ address: () => ({ port: ASSIGNED_PORT }),
45
+ on: () => server
46
+ };
47
+ callback && callback.call(server);
48
+ return server;
49
+ }
50
+ };
51
+ }
52
+
53
+ function loadProxyModule() {
54
+ capturedProxyOptions = undefined;
55
+ const module = { exports: {} };
56
+ const sandbox = {
57
+ Buffer,
58
+ URL,
59
+ __dirname: path.dirname(proxyFile),
60
+ console,
61
+ module,
62
+ exports: module.exports,
63
+ require(name) {
64
+ if (name === 'express') return createExpressStub;
65
+ if (name === 'http-proxy-response-rewrite') return () => {};
66
+ if (name === 'http-proxy-middleware') {
67
+ return {
68
+ createProxyMiddleware(_context, options) {
69
+ capturedProxyOptions = options;
70
+ return function proxyMiddleware() {};
71
+ }
72
+ };
73
+ }
74
+ if (name === 'cookie') {
75
+ return { parse: () => ({}) };
76
+ }
77
+ return require(name);
78
+ }
79
+ };
80
+ vm.runInNewContext(source, sandbox, { filename: proxyFile });
81
+ return module.exports;
82
+ }
83
+
84
+ const proxyModule = loadProxyModule();
85
+ const formerDataStorePath = path.join(os.tmpdir(), `alexa-cookie-proxy-random-port-test-${Date.now()}.json`);
86
+
87
+ try {
88
+ const input = {
89
+ proxyOwnIp: '127.0.0.1',
90
+ proxyPort: 0,
91
+ proxyListenBind: '0.0.0.0',
92
+ baseAmazonPage: 'amazon.de',
93
+ baseAmazonPageHandle: '_de',
94
+ amazonPageProxyLanguage: 'de_DE',
95
+ acceptLanguage: 'de-DE',
96
+ proxyLogLevel: 'silent',
97
+ formerDataStorePath
98
+ };
99
+ proxyModule.initAmazonProxy(input);
100
+
101
+ const refererReq = {
102
+ method: 'POST',
103
+ url: '/ap/cvf/verify',
104
+ headers: {
105
+ host: `127.0.0.1:${ASSIGNED_PORT}`,
106
+ referer: `http://127.0.0.1:${ASSIGNED_PORT}/www.amazon.com/ap/signin`
107
+ }
108
+ };
109
+
110
+ const refererTarget = capturedProxyOptions.router(refererReq);
111
+
112
+ line('TEST: proxy random port (proxyPort 0)');
113
+ line('');
114
+ line('CODE UNDER TEST:');
115
+ line('- lib/proxy.js: proxyBase() lazy resolution');
116
+ line('- lib/proxy.js: listen callback writes assigned port to _options.proxyPort');
117
+ line('- lib/proxy.js: router()/amazonHostFromProxyUrl()');
118
+ line('');
119
+ line('INPUT:');
120
+ line(`proxyPort: ${input.proxyPort}`);
121
+ line(`assigned listen port: ${ASSIGNED_PORT}`);
122
+ line(`referer header: ${refererReq.headers.referer}`);
123
+ line('');
124
+ line('OBSERVED:');
125
+ line(`_options.proxyPort after init: ${input.proxyPort}`);
126
+ line(`referer router target: ${refererTarget}`);
127
+ line('');
128
+ line('ASSERTIONS:');
129
+ recordAssertion(`_options.proxyPort updated to ${ASSIGNED_PORT}`, () => {
130
+ assert.strictEqual(input.proxyPort, ASSIGNED_PORT);
131
+ });
132
+ recordAssertion('referer router target === "https://www.amazon.com"', () => {
133
+ assert.strictEqual(refererTarget, 'https://www.amazon.com');
134
+ });
135
+ line('');
136
+ line('RESULT: PASS');
137
+ writeOutput();
138
+ } catch (err) {
139
+ if (!lines.includes('RESULT: PASS')) {
140
+ line('');
141
+ line('RESULT: FAIL');
142
+ writeOutput();
143
+ }
144
+ throw err;
145
+ } finally {
146
+ fs.rmSync(formerDataStorePath, { force: true });
147
+ }