alexa-cookie2 4.1.2 → 4.2.0

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018-2022 Apollon77 <ingo@fischer-ka.de>
3
+ Copyright (c) 2018-2023 Apollon77 <ingo@fischer-ka.de>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -49,6 +49,14 @@ Partly based on [Amazon Alexa Remote Control](http://blog.loetzimmer.de/2017/10/
49
49
  Thank you for that work.
50
50
 
51
51
  ## Changelog:
52
+ ### 4.2.0 (2023-08-08)
53
+ * (Hive) Adds the ability to alter the close proxy message
54
+
55
+ ### 4.1.3 (2022-08-03)
56
+ * (Apollon77) Fix device registration and token exchange in other regions
57
+ * (Apollon77) Use the chosen App name also for refreshing of tokens
58
+ * (Apollon77) General updates
59
+
52
60
  ### 4.1.2 (2022-07-19)
53
61
  * (Apollon77) Prevent crash case
54
62
 
package/alexa-cookie.js CHANGED
@@ -16,10 +16,11 @@ const defaultAmazonPage = 'amazon.de';
16
16
  const defaultUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36';
17
17
  const defaultUserAgentLinux = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36';
18
18
  //const defaultUserAgentMacOs = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36';
19
+ const defaultProxyCloseWindowHTML = '<b>Amazon Alexa Cookie successfully retrieved. You can close the browser.</b>';
19
20
  const defaultAcceptLanguage = 'de-DE';
20
21
 
21
- const apiCallVersion = '2.2.483723.0';
22
- const apiCallUserAgent = 'AmazonWebView/Amazon Alexa/2.2.483723.0/iOS/15.5/iPhone';
22
+ const apiCallVersion = '2.2.485407.0';
23
+ const apiCallUserAgent = 'AmazonWebView/Amazon Alexa/2.2.485407.0/iOS/15.5/iPhone';
23
24
  const defaultAppName = 'ioBroker Alexa2';
24
25
 
25
26
  const csrfOptions = [
@@ -46,23 +47,23 @@ function AlexaCookie() {
46
47
  if (cookie && cookie.length === 3) {
47
48
  if (cookie[1] === 'ap-fid' && cookie[2] === '""') continue;
48
49
  if (cookies[cookie[1]] && cookies[cookie[1]] !== cookie[2]) {
49
- _options.logger && _options.logger('Alexa-Cookie: Update Cookie ' + cookie[1] + ' = ' + cookie[2]);
50
+ _options.logger && _options.logger(`Alexa-Cookie: Update Cookie ${cookie[1]} = ${cookie[2]}`);
50
51
  } else if (!cookies[cookie[1]]) {
51
- _options.logger && _options.logger('Alexa-Cookie: Add Cookie ' + cookie[1] + ' = ' + cookie[2]);
52
+ _options.logger && _options.logger(`Alexa-Cookie: Add Cookie ${cookie[1]} = ${cookie[2]}`);
52
53
  }
53
54
  cookies[cookie[1]] = cookie[2];
54
55
  }
55
56
  }
56
57
  Cookie = '';
57
58
  for (const name of Object.keys(cookies)) {
58
- Cookie += name + '=' + cookies[name] + '; ';
59
+ Cookie += `${name}=${cookies[name]}; `;
59
60
  }
60
61
  Cookie = Cookie.replace(/[; ]*$/, '');
61
62
  return Cookie;
62
63
  };
63
64
 
64
65
  const request = (options, info, callback) => {
65
- _options.logger && _options.logger('Alexa-Cookie: Sending Request with ' + JSON.stringify(options));
66
+ _options.logger && _options.logger(`Alexa-Cookie: Sending Request with ${JSON.stringify(options)}`);
66
67
  if (typeof info === 'function') {
67
68
  callback = info;
68
69
  info = {
@@ -84,7 +85,7 @@ function AlexaCookie() {
84
85
  info.requests.push({options: options, response: res});
85
86
 
86
87
  if (options.followRedirects !== false && res.statusCode >= 300 && res.statusCode < 400) {
87
- _options.logger && _options.logger('Alexa-Cookie: Response (' + res.statusCode + ')' + (res.headers.location ? ' - Redirect to ' + res.headers.location : ''));
88
+ _options.logger && _options.logger(`Alexa-Cookie: Response (${res.statusCode})${res.headers.location ? ` - Redirect to ${res.headers.location}` : ''}`);
88
89
  //options.url = res.headers.location;
89
90
  const u = url.parse(res.headers.location);
90
91
  if (u.host) options.host = u.host;
@@ -96,7 +97,7 @@ function AlexaCookie() {
96
97
  res.socket && res.socket.end();
97
98
  return request(options, info, callback);
98
99
  } else {
99
- _options.logger && _options.logger('Alexa-Cookie: Response (' + res.statusCode + ')');
100
+ _options.logger && _options.logger(`Alexa-Cookie: Response (${res.statusCode})`);
100
101
  res.on('data', (chunk) => {
101
102
  body += chunk;
102
103
  });
@@ -140,18 +141,18 @@ function AlexaCookie() {
140
141
  _options.amazonPage = _options.amazonPage || defaultAmazonPage;
141
142
  if (_options.formerRegistrationData && _options.formerRegistrationData.amazonPage) _options.amazonPage = _options.formerRegistrationData.amazonPage;
142
143
 
143
- _options.logger && _options.logger('Alexa-Cookie: Use as Login-Amazon-URL: ' + _options.amazonPage);
144
+ _options.logger && _options.logger(`Alexa-Cookie: Use as Login-Amazon-URL: ${_options.amazonPage}`);
144
145
 
145
146
  _options.baseAmazonPage = _options.baseAmazonPage || 'amazon.com';
146
- _options.logger && _options.logger('Alexa-Cookie: Use as Base-Amazon-URL: ' + _options.baseAmazonPage);
147
+ _options.logger && _options.logger(`Alexa-Cookie: Use as Base-Amazon-URL: ${_options.baseAmazonPage}`);
147
148
 
148
149
  _options.deviceAppName = _options.deviceAppName || defaultAppName;
149
- _options.logger && _options.logger('Alexa-Cookie: Use as Device-App-Name: ' + _options.deviceAppName);
150
+ _options.logger && _options.logger(`Alexa-Cookie: Use as Device-App-Name: ${_options.deviceAppName}`);
150
151
 
151
152
  if (!_options.baseAmazonPageHandle && _options.baseAmazonPageHandle !== '') {
152
153
  const amazonDomain = _options.baseAmazonPage.substr(_options.baseAmazonPage.lastIndexOf('.') + 1);
153
154
  if (amazonDomain === 'jp') {
154
- _options.baseAmazonPageHandle = '_' + amazonDomain;
155
+ _options.baseAmazonPageHandle = `_${amazonDomain}`;
155
156
  }
156
157
  else if (amazonDomain !== 'com') {
157
158
  //_options.baseAmazonPageHandle = '_' + amazonDomain;
@@ -174,11 +175,14 @@ function AlexaCookie() {
174
175
  _options.userAgent = defaultUserAgentLinux;
175
176
  }
176
177
  }
177
- _options.logger && _options.logger('Alexa-Cookie: Use as User-Agent: ' + _options.userAgent);
178
+ _options.logger && _options.logger(`Alexa-Cookie: Use as User-Agent: ${_options.userAgent}`);
178
179
 
179
180
  _options.acceptLanguage = _options.acceptLanguage || defaultAcceptLanguage;
180
- _options.logger && _options.logger('Alexa-Cookie: Use as Accept-Language: ' + _options.acceptLanguage);
181
181
 
182
+ _options.logger && _options.logger(`Alexa-Cookie: Use as Accept-Language: ${_options.acceptLanguage}`);
183
+
184
+ _options.proxyCloseWindowHTML = _options.proxyCloseWindowHTML || defaultProxyCloseWindowHTML;
185
+
182
186
  if (_options.setupProxy && !_options.proxyOwnIp) {
183
187
  _options.logger && _options.logger('Alexa-Cookie: Own-IP Setting missing for Proxy. Disabling!');
184
188
  _options.setupProxy = false;
@@ -187,7 +191,7 @@ function AlexaCookie() {
187
191
  _options.setupProxy = true;
188
192
  _options.proxyPort = _options.proxyPort || 0;
189
193
  _options.proxyListenBind = _options.proxyListenBind || '0.0.0.0';
190
- _options.logger && _options.logger('Alexa-Cookie: Proxy-Mode enabled if needed: ' + _options.proxyOwnIp + ':' + _options.proxyPort + ' to listen on ' + _options.proxyListenBind);
194
+ _options.logger && _options.logger(`Alexa-Cookie: Proxy-Mode enabled if needed: ${_options.proxyOwnIp}:${_options.proxyPort} to listen on ${_options.proxyListenBind}`);
191
195
  } else {
192
196
  _options.setupProxy = false;
193
197
  _options.logger && _options.logger('Alexa-Cookie: Proxy mode disabled');
@@ -205,26 +209,26 @@ function AlexaCookie() {
205
209
  function csrfTry() {
206
210
  const path = csrfUrls.shift();
207
211
  const options = {
208
- 'host': 'alexa.' + _options.amazonPage,
212
+ 'host': `alexa.${_options.amazonPage}`,
209
213
  'path': path,
210
214
  'method': 'GET',
211
215
  'headers': {
212
216
  'DNT': '1',
213
217
  'User-Agent': _options.userAgent,
214
218
  'Connection': 'keep-alive',
215
- 'Referer': 'https://alexa.' + _options.amazonPage + '/spa/index.html',
219
+ 'Referer': `https://alexa.${_options.amazonPage}/spa/index.html`,
216
220
  'Cookie': cookie,
217
221
  'Accept': '*/*',
218
- 'Origin': 'https://alexa.' + _options.amazonPage
222
+ 'Origin': `https://alexa.${_options.amazonPage}`
219
223
  }
220
224
  };
221
225
 
222
- _options.logger && _options.logger('Alexa-Cookie: Step 4: get CSRF via ' + path);
226
+ _options.logger && _options.logger(`Alexa-Cookie: Step 4: get CSRF via ${path}`);
223
227
  request(options, (error, response) => {
224
228
  cookie = addCookies(cookie, response ? response.headers : null);
225
229
  const ar = /csrf=([^;]+)/.exec(cookie);
226
230
  const csrf = ar ? ar[1] : undefined;
227
- _options.logger && _options.logger('Alexa-Cookie: Result: csrf=' + csrf + ', Cookie=' + cookie);
231
+ _options.logger && _options.logger(`Alexa-Cookie: Result: csrf=${csrf}, Cookie=${cookie}`);
228
232
  if (!csrf && csrfUrls.length) {
229
233
  csrfTry();
230
234
  return;
@@ -268,7 +272,7 @@ function AlexaCookie() {
268
272
  if (!_options.proxyOnly) {
269
273
  // get first cookie and write redirection target into referer
270
274
  const options = {
271
- host: 'alexa.' + _options.amazonPage,
275
+ host: `alexa.${_options.amazonPage}`,
272
276
  path: '',
273
277
  method: 'GET',
274
278
  headers: {
@@ -291,7 +295,7 @@ function AlexaCookie() {
291
295
  // login empty to generate session
292
296
  Cookie = addCookies(Cookie, response.headers);
293
297
  const options = {
294
- host: 'www.' + _options.amazonPage,
298
+ host: `www.${_options.amazonPage}`,
295
299
  path: '/ap/signin',
296
300
  method: 'POST',
297
301
  headers: {
@@ -301,7 +305,7 @@ function AlexaCookie() {
301
305
  'Accept-Language': _options.acceptLanguage,
302
306
  'Connection': 'keep-alive',
303
307
  'Content-Type': 'application/x-www-form-urlencoded',
304
- 'Referer': 'https://' + lastRequestOptions.host + lastRequestOptions.path,
308
+ 'Referer': `https://${lastRequestOptions.host}${lastRequestOptions.path}`,
305
309
  'Cookie': Cookie,
306
310
  'Accept': '*/*'
307
311
  },
@@ -317,7 +321,7 @@ function AlexaCookie() {
317
321
 
318
322
  // login with filled out form
319
323
  // !!! referer now contains session in URL
320
- options.host = 'www.' + _options.amazonPage;
324
+ options.host = `www.${_options.amazonPage}`;
321
325
  options.path = '/ap/signin';
322
326
  options.method = 'POST';
323
327
  options.headers.Cookie = Cookie = addCookies(Cookie, response.headers);
@@ -401,7 +405,7 @@ function AlexaCookie() {
401
405
  };
402
406
 
403
407
  const handleTokenRegistration = (_options, loginData, callback) => {
404
- _options.logger && _options.logger('Handle token registration Start: ' + JSON.stringify(loginData));
408
+ _options.logger && _options.logger(`Handle token registration Start: ${JSON.stringify(loginData)}`);
405
409
 
406
410
  loginData.deviceAppName = _options.deviceAppName;
407
411
 
@@ -437,7 +441,7 @@ function AlexaCookie() {
437
441
  "Name": "session-id-time"
438
442
  }*/
439
443
  ],
440
- 'domain': '.' + _options.baseAmazonPage
444
+ 'domain': `.${_options.baseAmazonPage}`
441
445
  },
442
446
  'registration_data': {
443
447
  'domain': 'Device',
@@ -483,7 +487,7 @@ function AlexaCookie() {
483
487
  }
484
488
 
485
489
  const options = {
486
- host: 'api.' + _options.baseAmazonPage,
490
+ host: `api.${_options.baseAmazonPage}`,
487
491
  path: '/auth/register',
488
492
  method: 'POST',
489
493
  headers: {
@@ -494,7 +498,7 @@ function AlexaCookie() {
494
498
  'Content-Type': 'application/json',
495
499
  'Cookie': loginData.loginCookie,
496
500
  'Accept': 'application/json',
497
- 'x-amzn-identity-auth-domain': 'api.' + _options.baseAmazonPage
501
+ 'x-amzn-identity-auth-domain': `api.${_options.baseAmazonPage}`
498
502
  },
499
503
  body: JSON.stringify(registerData)
500
504
  };
@@ -508,11 +512,11 @@ function AlexaCookie() {
508
512
  try {
509
513
  if (typeof body !== 'object') body = JSON.parse(body);
510
514
  } catch (err) {
511
- _options.logger && _options.logger('Register App Response: ' + JSON.stringify(body));
515
+ _options.logger && _options.logger(`Register App Response: ${JSON.stringify(body)}`);
512
516
  callback && callback(err, null);
513
517
  return;
514
518
  }
515
- _options.logger && _options.logger('Register App Response: ' + JSON.stringify(body));
519
+ _options.logger && _options.logger(`Register App Response: ${JSON.stringify(body)}`);
516
520
 
517
521
  if (!body.response || !body.response.success || !body.response.success.tokens || !body.response.success.tokens.bearer) {
518
522
  callback && callback(new Error('No tokens in Register response'), null);
@@ -523,13 +527,21 @@ function AlexaCookie() {
523
527
  loginData.tokenDate = Date.now();
524
528
  loginData.macDms = body.response.success.tokens.mac_dms;
525
529
 
530
+ if (body.response.success.tokens.website_cookies && Array.isArray(body.response.success.tokens.website_cookies)) {
531
+ const newCookies = [];
532
+ body.response.success.tokens.website_cookies.forEach(cookie => {
533
+ newCookies.push(`${cookie.Name}=${cookie.Value};`);
534
+ });
535
+ Cookie = addCookies(Cookie, {'set-cookie': newCookies});
536
+ }
537
+
526
538
  /*
527
539
  Get Amazon Marketplace Country
528
540
  */
529
541
 
530
542
  const options = {
531
- host: 'alexa.' + _options.baseAmazonPage,
532
- path: '/api/users/me?platform=ios&version=' + apiCallVersion,
543
+ host: `alexa.${_options.baseAmazonPage}`,
544
+ path: `/api/users/me?platform=ios&version=${apiCallVersion}`,
533
545
  method: 'GET',
534
546
  headers: {
535
547
  'User-Agent': apiCallUserAgent,
@@ -547,11 +559,11 @@ function AlexaCookie() {
547
559
  try {
548
560
  if (typeof body !== 'object') body = JSON.parse(body);
549
561
  } catch (err) {
550
- _options.logger && _options.logger('Get User data Response: ' + JSON.stringify(body));
562
+ _options.logger && _options.logger(`Get User data Response: ${JSON.stringify(body)}`);
551
563
  callback && callback(err, null);
552
564
  return;
553
565
  }
554
- _options.logger && _options.logger('Get User data Response: ' + JSON.stringify(body));
566
+ _options.logger && _options.logger(`Get User data Response: ${JSON.stringify(body)}`);
555
567
 
556
568
  Cookie = addCookies(Cookie, response.headers);
557
569
 
@@ -564,7 +576,7 @@ function AlexaCookie() {
564
576
  callback && callback(error, null);
565
577
  return;
566
578
  } else if (error && (!_options.formerRegistrationData || !_options.formerRegistrationData.amazonPage) && _options.amazonPage) {
567
- _options.logger && _options.logger('Continue with externally set amazonPage: ' + _options.amazonPage);
579
+ _options.logger && _options.logger(`Continue with externally set amazonPage: ${_options.amazonPage}`);
568
580
  } else if (error) {
569
581
  _options.logger && _options.logger('Ignore error while getting user data and amazonPage because previously set amazonPage is available');
570
582
  }
@@ -579,7 +591,7 @@ function AlexaCookie() {
579
591
  loginData.localCookie = localCookie;
580
592
  getCSRFFromCookies(loginData.localCookie, _options, (err, resData) => {
581
593
  if (err) {
582
- callback && callback(new Error('Error getting csrf for ' + loginData.amazonPage), null);
594
+ callback && callback(new Error(`Error getting csrf for ${loginData.amazonPage}`), null);
583
595
  return;
584
596
  }
585
597
  loginData.localCookie = resData.cookie;
@@ -587,7 +599,7 @@ function AlexaCookie() {
587
599
  delete loginData.accessToken;
588
600
  delete loginData.authorization_code;
589
601
  delete loginData.verifier;
590
- _options.logger && _options.logger('Final Registration Result: ' + JSON.stringify(loginData));
602
+ _options.logger && _options.logger(`Final Registration Result: ${JSON.stringify(loginData)}`);
591
603
  callback && callback(null, loginData);
592
604
  });
593
605
  });
@@ -604,19 +616,19 @@ function AlexaCookie() {
604
616
  const exchangeParams = {
605
617
  'di.os.name': 'iOS',
606
618
  'app_version': apiCallVersion,
607
- 'domain': '.' + amazonPage,
619
+ 'domain': `.${amazonPage}`,
608
620
  'source_token': refreshToken,
609
621
  'requested_token_type': 'auth_cookies',
610
622
  'source_token_type': 'refresh_token',
611
623
  'di.hw.version': 'iPhone',
612
- 'di.sdk.version': '6.10.0',
613
- 'cookies': Buffer.from('{„cookies“:{".' + amazonPage + '":[]}}').toString('base64'),
614
- 'app_name': 'Amazon Alexa',
615
- 'di.os.version': '11.4.1'
624
+ 'di.sdk.version': '6.12.3',
625
+ 'cookies': Buffer.from(`{„cookies“:{".${amazonPage}":[]}}`).toString('base64'),
626
+ 'app_name': _options.deviceAppName || defaultAppName,
627
+ 'di.os.version': '15.5'
616
628
  };
617
629
  const options = {
618
- host: 'www.' + amazonPage,
619
- path: '/ap/exchangetoken',
630
+ host: `www.${amazonPage}`,
631
+ path: '/ap/exchangetoken/cookies',
620
632
  method: 'POST',
621
633
  headers: {
622
634
  'User-Agent': apiCallUserAgent,
@@ -630,7 +642,7 @@ function AlexaCookie() {
630
642
  encodeURIComponent: encodeURIComponent
631
643
  })
632
644
  };
633
- _options.logger && _options.logger('Alexa-Cookie: Exchange tokens for ' + amazonPage);
645
+ _options.logger && _options.logger(`Alexa-Cookie: Exchange tokens for ${amazonPage}`);
634
646
  _options.logger && _options.logger(JSON.stringify(options));
635
647
 
636
648
  request(options, (error, response, body) => {
@@ -641,35 +653,35 @@ function AlexaCookie() {
641
653
  try {
642
654
  if (typeof body !== 'object') body = JSON.parse(body);
643
655
  } catch (err) {
644
- _options.logger && _options.logger('Exchange Token Response: ' + JSON.stringify(body));
656
+ _options.logger && _options.logger(`Exchange Token Response: ${JSON.stringify(body)}`);
645
657
  callback && callback(err, null);
646
658
  return;
647
659
  }
648
- _options.logger && _options.logger('Exchange Token Response: ' + JSON.stringify(body));
660
+ _options.logger && _options.logger(`Exchange Token Response: ${JSON.stringify(body)}`);
649
661
 
650
662
  if (!body.response || !body.response.tokens || !body.response.tokens.cookies) {
651
663
  callback && callback(new Error('No cookies in Exchange response'), null);
652
664
  return;
653
665
  }
654
- if (!body.response.tokens.cookies['.' + amazonPage]) {
655
- callback && callback(new Error('No cookies for ' + amazonPage + ' in Exchange response'), null);
666
+ if (!body.response.tokens.cookies[`.${amazonPage}`]) {
667
+ callback && callback(new Error(`No cookies for ${amazonPage} in Exchange response`), null);
656
668
  return;
657
669
  }
658
670
 
659
671
  Cookie = addCookies(Cookie, response.headers);
660
672
  const cookies = cookieTools.parse(Cookie);
661
- body.response.tokens.cookies['.' + amazonPage].forEach((cookie) => {
673
+ body.response.tokens.cookies[`.${amazonPage}`].forEach((cookie) => {
662
674
  if (cookies[cookie.Name] && cookies[cookie.Name] !== cookie.Value) {
663
- _options.logger && _options.logger('Alexa-Cookie: Update Cookie ' + cookie.Name + ' = ' + cookie.Value);
675
+ _options.logger && _options.logger(`Alexa-Cookie: Update Cookie ${cookie.Name} = ${cookie.Value}`);
664
676
  } else if (!cookies[cookie.Name]) {
665
- _options.logger && _options.logger('Alexa-Cookie: Add Cookie ' + cookie.Name + ' = ' + cookie.Value);
677
+ _options.logger && _options.logger(`Alexa-Cookie: Add Cookie ${cookie.Name} = ${cookie.Value}`);
666
678
  }
667
679
  cookies[cookie.Name] = cookie.Value;
668
680
 
669
681
  });
670
682
  let localCookie = '';
671
683
  for (const name of Object.keys(cookies)) {
672
- localCookie += name + '=' + cookies[name] + '; ';
684
+ localCookie += `${name}=${cookies[name]}; `;
673
685
  }
674
686
  localCookie = localCookie.replace(/[; ]*$/, '');
675
687
 
@@ -695,9 +707,9 @@ function AlexaCookie() {
695
707
  initConfig();
696
708
 
697
709
  const refreshData = {
698
- 'app_name': 'ioBroker Alexa2',
710
+ 'app_name': _options.deviceAppName || defaultAppName,
699
711
  'app_version': apiCallVersion,
700
- 'di.sdk.version': '6.10.0',
712
+ 'di.sdk.version': '6.12.3',
701
713
  'source_token': _options.formerRegistrationData.refreshToken,
702
714
  'package_name': 'com.amazon.echo',
703
715
  'di.hw.version': 'iPhone',
@@ -705,12 +717,12 @@ function AlexaCookie() {
705
717
  'requested_token_type': 'access_token',
706
718
  'source_token_type': 'refresh_token',
707
719
  'di.os.name': 'iOS',
708
- 'di.os.version': '14.8',
709
- 'current_version': '6.10.0'
720
+ 'di.os.version': '15.5',
721
+ 'current_version': '6.12.3'
710
722
  };
711
723
 
712
724
  const options = {
713
- host: 'api.' + _options.baseAmazonPage,
725
+ host: `api.${_options.baseAmazonPage}`,
714
726
  path: '/auth/token',
715
727
  method: 'POST',
716
728
  headers: {
@@ -721,7 +733,7 @@ function AlexaCookie() {
721
733
  'Content-Type': 'application/x-www-form-urlencoded',
722
734
  'Cookie': _options.formerRegistrationData.loginCookie,
723
735
  'Accept': 'application/json',
724
- 'x-amzn-identity-auth-domain': 'api.' + _options.baseAmazonPage
736
+ 'x-amzn-identity-auth-domain': `api.${_options.baseAmazonPage}`
725
737
  },
726
738
  body: querystring.stringify(refreshData)
727
739
  };
@@ -736,11 +748,11 @@ function AlexaCookie() {
736
748
  try {
737
749
  if (typeof body !== 'object') body = JSON.parse(body);
738
750
  } catch (err) {
739
- _options.logger && _options.logger('Refresh Token Response: ' + JSON.stringify(body));
751
+ _options.logger && _options.logger(`Refresh Token Response: ${JSON.stringify(body)}`);
740
752
  callback && callback(err, null);
741
753
  return;
742
754
  }
743
- _options.logger && _options.logger('Refresh Token Response: ' + JSON.stringify(body));
755
+ _options.logger && _options.logger(`Refresh Token Response: ${JSON.stringify(body)}`);
744
756
 
745
757
  _options.formerRegistrationData.loginCookie = addCookies(_options.formerRegistrationData.loginCookie, response.headers);
746
758
 
@@ -758,8 +770,8 @@ function AlexaCookie() {
758
770
 
759
771
  // Restore frc and map-md
760
772
  const initCookies = cookieTools.parse(_options.formerRegistrationData.loginCookie);
761
- let newCookie = 'frc=' + initCookies.frc + '; ';
762
- newCookie += 'map-md=' + initCookies['map-md'] + '; ';
773
+ let newCookie = `frc=${initCookies.frc}; `;
774
+ newCookie += `map-md=${initCookies['map-md']}; `;
763
775
  newCookie += comCookie;
764
776
 
765
777
  _options.formerRegistrationData.loginCookie = newCookie;
@@ -17,11 +17,12 @@ const config = {
17
17
  proxyPort: 3456, // optional: use this port for the proxy, default is 0 means random port is selected
18
18
  proxyListenBind: '0.0.0.0',// optional: set this to bind the proxy to a special IP, default is '0.0.0.0'
19
19
  proxyLogLevel: 'info', // optional: Loglevel of Proxy, default 'warn'
20
- baseAmazonPage: 'amazon.com', // optional: Change the Proxy Amazon Page - all "western countries" directly use amazon.com! Change to amazon.co.jp for Japan
20
+ baseAmazonPage: 'amazon.com', // optional: Change the Proxy Amazon Page - all "western countries" directly use amazon.com including australia! Change to amazon.co.jp for Japan
21
21
  amazonPageProxyLanguage: 'de_DE', // optional: language to be used for the Amazon Sign-in page the proxy calls. default is "de_DE")
22
22
  deviceAppName: '...', // optional: name of the device app name which will be registered with Amazon, leave empty to use a default one
23
23
  formerDataStorePath: '...', // optional: overwrite path where some of the formerRegistrationData are persisted to optimize against Amazon security measures
24
- formerRegistrationData: { ... } // optional/preferred: provide the result object from subsequent proxy usages here and some generated data will be reused for next proxy call too
24
+ formerRegistrationData: { ... }, // optional/preferred: provide the result object from subsequent proxy usages here and some generated data will be reused for next proxy call too
25
+ proxyCloseWindowHTML: '...' // optional: use in order to override the default html displayed when the proxy window can be closed, default is '<b>Amazon Alexa Cookie successfully retrieved. You can close the browser.</b>'
25
26
  };
26
27
 
27
28
 
package/lib/proxy.js CHANGED
@@ -90,7 +90,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
90
90
  }
91
91
 
92
92
  if (!_options.formerRegistrationData || !_options.formerRegistrationData['map-md']) {
93
- initialCookies['map-md'] = Buffer.from('{"device_user_dictionary":[],"device_registration_data":{"software_version":"1"},"app_identifier":{"app_version":"2.2.223830","bundle_id":"com.amazon.echo"}}').toString('base64');
93
+ initialCookies['map-md'] = Buffer.from('{"device_user_dictionary":[],"device_registration_data":{"software_version":"1"},"app_identifier":{"app_version":"2.2.485407","bundle_id":"com.amazon.echo"}}').toString('base64');
94
94
  }
95
95
  else {
96
96
  _options.logger && _options.logger('Proxy Init: reuse map-md from former data');
@@ -150,7 +150,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
150
150
  onProxyRes: onProxyRes,
151
151
  onProxyReq: onProxyReq,
152
152
  headers: {
153
- 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 PitanguiBridge/2.2.345247.0-[HARDWARE=iPhone10_4][SOFTWARE=13.5.1]',
153
+ 'user-agent': 'AppleWebKit PitanguiBridge/2.2.485407.0-[HARDWARE=iPhone10_4][SOFTWARE=15.5][DEVICE=iPhone]',
154
154
  'accept-language': _options.acceptLanguage,
155
155
  'authority': `www.${_options.baseAmazonPage}`
156
156
  },
@@ -372,7 +372,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
372
372
 
373
373
  app.use(myProxy);
374
374
  app.get('/cookie-success', function(req, res) {
375
- res.send('<b>Amazon Alexa Cookie successfully retrieved. You can close the browser.</b>');
375
+ res.send(_options.proxyCloseWindowHTML);
376
376
  });
377
377
  const server = app.listen(_options.proxyPort, _options.proxyListenBind, function() {
378
378
  _options.logger && _options.logger('Alexa-Cookie: Proxy-Server listening on port ' + server.address().port);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alexa-cookie2",
3
- "version": "4.1.2",
3
+ "version": "4.2.0",
4
4
  "description": "Generate Cookie and CSRF for Alexa Remote",
5
5
  "author": {
6
6
  "name": "Apollon77",
@@ -22,16 +22,16 @@
22
22
  ],
23
23
  "dependencies": {
24
24
  "cookie": "^0.5.0",
25
- "express": "^4.18.1",
25
+ "express": "^4.18.2",
26
26
  "http-proxy-middleware": "^2.0.6",
27
27
  "http-proxy-response-rewrite": "^0.0.1",
28
28
  "https": "^1.0.0",
29
29
  "querystring": "^0.2.1"
30
30
  },
31
31
  "devDependencies": {
32
- "@alcalzone/release-script": "^3.5.9",
32
+ "@alcalzone/release-script": "^3.6.0",
33
33
  "@alcalzone/release-script-plugin-license": "^3.5.9",
34
- "eslint": "^8.20.0"
34
+ "eslint": "^8.46.0"
35
35
  },
36
36
  "repository": {
37
37
  "type": "git",