alexa-cookie2 4.0.1 → 4.0.2
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/.eslintrc.json +40 -0
- package/.releaseconfig.json +3 -0
- package/LICENSE +1 -1
- package/README.md +8 -1
- package/alexa-cookie.js +65 -72
- package/lib/proxy.js +32 -32
- package/package.json +7 -5
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": true,
|
|
3
|
+
"env": {
|
|
4
|
+
"es6": true,
|
|
5
|
+
"node": true,
|
|
6
|
+
"mocha": true
|
|
7
|
+
},
|
|
8
|
+
"extends": [
|
|
9
|
+
"eslint:recommended"
|
|
10
|
+
],
|
|
11
|
+
"plugins": [],
|
|
12
|
+
"rules": {
|
|
13
|
+
"indent": [
|
|
14
|
+
"error",
|
|
15
|
+
4,
|
|
16
|
+
{
|
|
17
|
+
"SwitchCase": 1
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"no-console": "off",
|
|
21
|
+
"no-var": "error",
|
|
22
|
+
"no-trailing-spaces": "error",
|
|
23
|
+
"prefer-const": "error",
|
|
24
|
+
"quotes": [
|
|
25
|
+
"error",
|
|
26
|
+
"single",
|
|
27
|
+
{
|
|
28
|
+
"avoidEscape": true,
|
|
29
|
+
"allowTemplateLiterals": true
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"semi": [
|
|
33
|
+
"error",
|
|
34
|
+
"always"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"parserOptions": {
|
|
38
|
+
"ecmaVersion": 2018
|
|
39
|
+
}
|
|
40
|
+
}
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2018-
|
|
3
|
+
Copyright (c) 2018-2022 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
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
Library to generate/retrieve a cookie including a csrf for alexa remote
|
|
8
8
|
|
|
9
|
+
## Disclaimer
|
|
10
|
+
**All product and company names or logos are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them or any associated subsidiaries! This personal project is maintained in spare time and has no business goal.**
|
|
11
|
+
**ALEXA is a trademark of AMAZON TECHNOLOGIES, INC.**
|
|
12
|
+
|
|
9
13
|
## Description
|
|
10
14
|
This library can be used to get the cookies needed to access Amazon Alexa services from outside. It authenticates with Amazon and gathers all needed details. These details are returned in the callback.
|
|
11
15
|
If the automatic authentication fails (which is more common case in the meantime because of security checks from amazon like a needed Captcha or because you enabled two factor authentication) the library can also setup a proxy server to allow the manual login and will catch the cookie by itself. Using this proxy you can enter needed 2FA codes or solve captchas and still do not need to trick around to get the cookie.
|
|
@@ -45,6 +49,9 @@ Partly based on [Amazon Alexa Remote Control](http://blog.loetzimmer.de/2017/10/
|
|
|
45
49
|
Thank you for that work.
|
|
46
50
|
|
|
47
51
|
## Changelog:
|
|
52
|
+
### 4.0.2 (2022-06-30)
|
|
53
|
+
* (Apollon77) Prevent potential crash cases
|
|
54
|
+
|
|
48
55
|
### 4.0.1 (2021-10-11)
|
|
49
56
|
* (Apollon77) Adjust call headers
|
|
50
57
|
|
|
@@ -140,4 +147,4 @@ Thank you for that work.
|
|
|
140
147
|
* (Apollon77) 0.1.1: update to get it working again and sync to [alexa-remote-control](https://github.com/thorsten-gehrig/alexa-remote-control)
|
|
141
148
|
|
|
142
149
|
### 0.0.x
|
|
143
|
-
* Versions by soef
|
|
150
|
+
* Versions by soef
|
package/alexa-cookie.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/* jshint -W097 */
|
|
2
|
-
/* jshint -W030 */
|
|
3
|
-
/* jshint strict: false */
|
|
4
|
-
/* jslint node: true */
|
|
5
|
-
/* jslint esversion: 6 */
|
|
6
|
-
"use strict";
|
|
7
|
-
|
|
8
1
|
/**
|
|
9
2
|
* partly based on Amazon Alexa Remote Control (PLAIN shell)
|
|
10
3
|
* http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html AND on
|
|
@@ -57,7 +50,7 @@ function AlexaCookie() {
|
|
|
57
50
|
}
|
|
58
51
|
}
|
|
59
52
|
Cookie = '';
|
|
60
|
-
for (
|
|
53
|
+
for (const name in cookies) {
|
|
61
54
|
if (!cookies.hasOwnProperty(name)) continue;
|
|
62
55
|
Cookie += name + '=' + cookies[name] + '; ';
|
|
63
56
|
}
|
|
@@ -83,14 +76,14 @@ function AlexaCookie() {
|
|
|
83
76
|
removeContentLength = true;
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
|
|
87
|
-
let body =
|
|
79
|
+
const req = https.request(options, (res) => {
|
|
80
|
+
let body = '';
|
|
88
81
|
info.requests.push({options: options, response: res});
|
|
89
82
|
|
|
90
83
|
if (options.followRedirects !== false && res.statusCode >= 300 && res.statusCode < 400) {
|
|
91
84
|
_options.logger && _options.logger('Alexa-Cookie: Response (' + res.statusCode + ')' + (res.headers.location ? ' - Redirect to ' + res.headers.location : ''));
|
|
92
85
|
//options.url = res.headers.location;
|
|
93
|
-
|
|
86
|
+
const u = url.parse(res.headers.location);
|
|
94
87
|
if (u.host) options.host = u.host;
|
|
95
88
|
options.path = u.path;
|
|
96
89
|
options.method = 'GET';
|
|
@@ -127,11 +120,11 @@ function AlexaCookie() {
|
|
|
127
120
|
const getFields = body => {
|
|
128
121
|
body = body.replace(/[\n\r]/g, ' ');
|
|
129
122
|
let re = /^.*?("hidden"\s*name=".*$)/;
|
|
130
|
-
|
|
123
|
+
const ar = re.exec(body);
|
|
131
124
|
if (!ar || ar.length < 2) return {};
|
|
132
125
|
let h;
|
|
133
126
|
re = /.*?name="([^"]+)"[\s^\s]*value="([^"]+).*?"/g;
|
|
134
|
-
|
|
127
|
+
const data = {};
|
|
135
128
|
while ((h = re.exec(ar[1])) !== null) {
|
|
136
129
|
if (h[1] !== 'rememberMe') {
|
|
137
130
|
data[h[1]] = h[2];
|
|
@@ -164,7 +157,7 @@ function AlexaCookie() {
|
|
|
164
157
|
}
|
|
165
158
|
|
|
166
159
|
if (!_options.userAgent) {
|
|
167
|
-
|
|
160
|
+
const platform = os.platform();
|
|
168
161
|
if (platform === 'win32') {
|
|
169
162
|
_options.userAgent = defaultUserAgent;
|
|
170
163
|
}
|
|
@@ -205,7 +198,7 @@ function AlexaCookie() {
|
|
|
205
198
|
|
|
206
199
|
function csrfTry() {
|
|
207
200
|
const path = csrfUrls.shift();
|
|
208
|
-
|
|
201
|
+
const options = {
|
|
209
202
|
'host': 'alexa.' + _options.amazonPage,
|
|
210
203
|
'path': path,
|
|
211
204
|
'method': 'GET',
|
|
@@ -223,8 +216,8 @@ function AlexaCookie() {
|
|
|
223
216
|
_options.logger && _options.logger('Alexa-Cookie: Step 4: get CSRF via ' + path);
|
|
224
217
|
request(options, (error, response) => {
|
|
225
218
|
cookie = addCookies(cookie, response ? response.headers : null);
|
|
226
|
-
|
|
227
|
-
|
|
219
|
+
const ar = /csrf=([^;]+)/.exec(cookie);
|
|
220
|
+
const csrf = ar ? ar[1] : undefined;
|
|
228
221
|
_options.logger && _options.logger('Alexa-Cookie: Result: csrf=' + csrf + ', Cookie=' + cookie);
|
|
229
222
|
if (!csrf && csrfUrls.length) {
|
|
230
223
|
csrfTry();
|
|
@@ -268,7 +261,7 @@ function AlexaCookie() {
|
|
|
268
261
|
|
|
269
262
|
if (!_options.proxyOnly) {
|
|
270
263
|
// get first cookie and write redirection target into referer
|
|
271
|
-
|
|
264
|
+
const options = {
|
|
272
265
|
host: 'alexa.' + _options.amazonPage,
|
|
273
266
|
path: '',
|
|
274
267
|
method: 'GET',
|
|
@@ -288,10 +281,10 @@ function AlexaCookie() {
|
|
|
288
281
|
return;
|
|
289
282
|
}
|
|
290
283
|
|
|
291
|
-
|
|
284
|
+
const lastRequestOptions = info.requests[info.requests.length - 1].options;
|
|
292
285
|
// login empty to generate session
|
|
293
286
|
Cookie = addCookies(Cookie, response.headers);
|
|
294
|
-
|
|
287
|
+
const options = {
|
|
295
288
|
host: 'www.' + _options.amazonPage,
|
|
296
289
|
path: '/ap/signin',
|
|
297
290
|
method: 'POST',
|
|
@@ -322,7 +315,7 @@ function AlexaCookie() {
|
|
|
322
315
|
options.path = '/ap/signin';
|
|
323
316
|
options.method = 'POST';
|
|
324
317
|
options.headers.Cookie = Cookie = addCookies(Cookie, response.headers);
|
|
325
|
-
|
|
318
|
+
const ar = options.headers.Cookie.match(/session-id=([^;]+)/);
|
|
326
319
|
options.headers.Referer = `https://www.${_options.amazonPage}/ap/signin/${ar[1]}`;
|
|
327
320
|
options.body = getFields(body);
|
|
328
321
|
options.body.email = email || '';
|
|
@@ -336,7 +329,7 @@ function AlexaCookie() {
|
|
|
336
329
|
return;
|
|
337
330
|
}
|
|
338
331
|
|
|
339
|
-
|
|
332
|
+
const lastRequestOptions = info.requests[info.requests.length - 1].options;
|
|
340
333
|
|
|
341
334
|
// check whether the login has been successful or exit otherwise
|
|
342
335
|
if (!lastRequestOptions.host.startsWith('alexa') || !lastRequestOptions.path.endsWith('.html')) {
|
|
@@ -422,64 +415,64 @@ function AlexaCookie() {
|
|
|
422
415
|
*/
|
|
423
416
|
|
|
424
417
|
const registerData = {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
418
|
+
'requested_extensions': [
|
|
419
|
+
'device_info',
|
|
420
|
+
'customer_info'
|
|
428
421
|
],
|
|
429
|
-
|
|
430
|
-
|
|
422
|
+
'cookies': {
|
|
423
|
+
'website_cookies': [
|
|
431
424
|
/*{
|
|
432
425
|
"Value": cookies["session-id-time"],
|
|
433
426
|
"Name": "session-id-time"
|
|
434
427
|
}*/
|
|
435
428
|
],
|
|
436
|
-
|
|
429
|
+
'domain': '.' + _options.baseAmazonPage
|
|
437
430
|
},
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
431
|
+
'registration_data': {
|
|
432
|
+
'domain': 'Device',
|
|
433
|
+
'app_version': '2.2.443692.0',
|
|
434
|
+
'device_type': 'A2IVLV5VM2W81',
|
|
435
|
+
'device_name': '%FIRST_NAME%\u0027s%DUPE_STRATEGY_1ST%ioBroker Alexa2',
|
|
436
|
+
'os_version': '14.8',
|
|
437
|
+
'device_serial': deviceSerial,
|
|
438
|
+
'device_model': 'iPhone',
|
|
439
|
+
'app_name': 'ioBroker Alexa2',
|
|
440
|
+
'software_version': '1'
|
|
448
441
|
},
|
|
449
|
-
|
|
442
|
+
'auth_data': {
|
|
450
443
|
// Filled below
|
|
451
444
|
},
|
|
452
|
-
|
|
453
|
-
|
|
445
|
+
'user_context_map': {
|
|
446
|
+
'frc': cookies.frc
|
|
454
447
|
},
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
448
|
+
'requested_token_type': [
|
|
449
|
+
'bearer',
|
|
450
|
+
'mac_dms',
|
|
451
|
+
'website_cookies'
|
|
459
452
|
]
|
|
460
453
|
};
|
|
461
454
|
if (loginData.accessToken) {
|
|
462
455
|
registerData.auth_data = {
|
|
463
|
-
|
|
456
|
+
'access_token': loginData.accessToken
|
|
464
457
|
};
|
|
465
458
|
} else if (loginData.authorization_code && loginData.verifier) {
|
|
466
459
|
registerData.auth_data = {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
460
|
+
'client_id' : loginData.deviceId,
|
|
461
|
+
'authorization_code' : loginData.authorization_code,
|
|
462
|
+
'code_verifier' : loginData.verifier,
|
|
463
|
+
'code_algorithm' : 'SHA-256',
|
|
464
|
+
'client_domain' : 'DeviceLegacy'
|
|
472
465
|
};
|
|
473
466
|
}
|
|
474
|
-
for (
|
|
467
|
+
for (const key in cookies) {
|
|
475
468
|
if (!cookies.hasOwnProperty(key)) continue;
|
|
476
469
|
registerData.cookies.website_cookies.push({
|
|
477
|
-
|
|
478
|
-
|
|
470
|
+
'Value': cookies[key],
|
|
471
|
+
'Name': key
|
|
479
472
|
});
|
|
480
473
|
}
|
|
481
474
|
|
|
482
|
-
|
|
475
|
+
const options = {
|
|
483
476
|
host: 'api.' + _options.baseAmazonPage,
|
|
484
477
|
path: '/auth/register',
|
|
485
478
|
method: 'POST',
|
|
@@ -524,7 +517,7 @@ function AlexaCookie() {
|
|
|
524
517
|
Get Amazon Marketplace Country
|
|
525
518
|
*/
|
|
526
519
|
|
|
527
|
-
|
|
520
|
+
const options = {
|
|
528
521
|
host: 'alexa.' + _options.baseAmazonPage,
|
|
529
522
|
path: '/api/users/me?platform=ios&version=2.2.443692.0',
|
|
530
523
|
method: 'GET',
|
|
@@ -560,7 +553,7 @@ function AlexaCookie() {
|
|
|
560
553
|
} else if (error && (!_options || !_options.amazonPage)) {
|
|
561
554
|
callback && callback(error, null);
|
|
562
555
|
return;
|
|
563
|
-
} else if (error && !_options.formerRegistrationData.amazonPage && _options.amazonPage) {
|
|
556
|
+
} else if (error && (!_options.formerRegistrationData || !_options.formerRegistrationData.amazonPage) && _options.amazonPage) {
|
|
564
557
|
_options.logger && _options.logger('Continue with externally set amazonPage: ' + _options.amazonPage);
|
|
565
558
|
} else if (error) {
|
|
566
559
|
_options.logger && _options.logger('Ignore error while getting user data and amazonPage because previously set amazonPage is available');
|
|
@@ -611,7 +604,7 @@ function AlexaCookie() {
|
|
|
611
604
|
'app_name': 'Amazon Alexa',
|
|
612
605
|
'di.os.version': '11.4.1'
|
|
613
606
|
};
|
|
614
|
-
|
|
607
|
+
const options = {
|
|
615
608
|
host: 'www.' + amazonPage,
|
|
616
609
|
path: '/ap/exchangetoken',
|
|
617
610
|
method: 'POST',
|
|
@@ -665,7 +658,7 @@ function AlexaCookie() {
|
|
|
665
658
|
|
|
666
659
|
});
|
|
667
660
|
let localCookie = '';
|
|
668
|
-
for (
|
|
661
|
+
for (const name in cookies) {
|
|
669
662
|
if (!cookies.hasOwnProperty(name)) continue;
|
|
670
663
|
localCookie += name + '=' + cookies[name] + '; ';
|
|
671
664
|
}
|
|
@@ -693,21 +686,21 @@ function AlexaCookie() {
|
|
|
693
686
|
initConfig();
|
|
694
687
|
|
|
695
688
|
const refreshData = {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
689
|
+
'app_name': 'ioBroker Alexa2',
|
|
690
|
+
'app_version': '2.2.443692.0',
|
|
691
|
+
'di.sdk.version': '6.10.0',
|
|
692
|
+
'source_token': _options.formerRegistrationData.refreshToken,
|
|
693
|
+
'package_name': 'com.amazon.echo',
|
|
694
|
+
'di.hw.version': 'iPhone',
|
|
695
|
+
'platform': 'iOS',
|
|
696
|
+
'requested_token_type': 'access_token',
|
|
697
|
+
'source_token_type': 'refresh_token',
|
|
698
|
+
'di.os.name': 'iOS',
|
|
699
|
+
'di.os.version': '14.8',
|
|
700
|
+
'current_version': '6.10.0'
|
|
708
701
|
};
|
|
709
702
|
|
|
710
|
-
|
|
703
|
+
const options = {
|
|
711
704
|
host: 'api.' + _options.baseAmazonPage,
|
|
712
705
|
path: '/auth/token',
|
|
713
706
|
method: 'POST',
|
package/lib/proxy.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/* jshint strict: false */
|
|
4
4
|
/* jslint node: true */
|
|
5
5
|
/* jslint esversion: 6 */
|
|
6
|
-
|
|
6
|
+
'use strict';
|
|
7
7
|
|
|
8
8
|
const modifyResponse = require('http-proxy-response-rewrite');
|
|
9
9
|
const express = require('express');
|
|
@@ -27,7 +27,7 @@ function addCookies(Cookie, headers) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
Cookie = '';
|
|
30
|
-
for (
|
|
30
|
+
for (const name in cookies) {
|
|
31
31
|
if (!cookies.hasOwnProperty(name)) continue;
|
|
32
32
|
Cookie += name + '=' + cookies[name] + '; ';
|
|
33
33
|
}
|
|
@@ -90,7 +90,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
90
90
|
initialCookies.frc = _options.formerRegistrationData.frc;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
if (!_options.formerRegistrationData || !_options.formerRegistrationData[
|
|
93
|
+
if (!_options.formerRegistrationData || !_options.formerRegistrationData['map-md']) {
|
|
94
94
|
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');
|
|
95
95
|
}
|
|
96
96
|
else {
|
|
@@ -123,19 +123,19 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
123
123
|
// ignore
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
126
|
+
function base64URLEncode(str) {
|
|
127
|
+
return str.toString('base64')
|
|
128
|
+
.replace(/\+/g, '-')
|
|
129
|
+
.replace(/\//g, '_')
|
|
130
|
+
.replace(/=/g, '');
|
|
131
|
+
}
|
|
132
|
+
function sha256(buffer) {
|
|
133
|
+
return crypto.createHash('sha256').update(buffer).digest();
|
|
134
|
+
}
|
|
135
|
+
const code_verifier = base64URLEncode(crypto.randomBytes(32));
|
|
136
|
+
const code_challenge = base64URLEncode(sha256(code_verifier));
|
|
137
137
|
|
|
138
|
-
let proxyCookies =
|
|
138
|
+
let proxyCookies = '';
|
|
139
139
|
|
|
140
140
|
// proxy middleware options
|
|
141
141
|
const optionsAlexa = {
|
|
@@ -151,12 +151,12 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
151
151
|
onProxyRes: onProxyRes,
|
|
152
152
|
onProxyReq: onProxyReq,
|
|
153
153
|
headers: {
|
|
154
|
-
'user-agent':
|
|
154
|
+
'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]',
|
|
155
155
|
'accept-language': _options.acceptLanguage,
|
|
156
156
|
'authority': `www.${_options.baseAmazonPage}`
|
|
157
157
|
},
|
|
158
158
|
cookieDomainRewrite: { // enhanced below
|
|
159
|
-
|
|
159
|
+
'*': ''
|
|
160
160
|
}
|
|
161
161
|
};
|
|
162
162
|
optionsAlexa.pathRewrite[`^/www.${_options.baseAmazonPage}`] = '';
|
|
@@ -190,7 +190,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
if (url === '/') { // initial redirect
|
|
193
|
-
|
|
193
|
+
returnedInitUrl = `https://www.${_options.baseAmazonPage}/ap/signin?openid.return_to=https%3A%2F%2Fwww.${_options.baseAmazonPage}%2Fap%2Fmaplanding&openid.assoc_handle=amzn_dp_project_dee_ios${_options.baseAmazonPageHandle}&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&pageId=amzn_dp_project_dee_ios${_options.baseAmazonPageHandle}&accountStatusPolicy=P1&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns.oa2=http%3A%2F%2Fwww.${_options.baseAmazonPage}%2Fap%2Fext%2Foauth%2F2&openid.oa2.client_id=device%3A${deviceId}&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.oa2.response_type=code&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.pape.max_auth_age=0&openid.oa2.scope=device_auth_access&openid.oa2.code_challenge_method=S256&openid.oa2.code_challenge=${code_challenge}&language=${_options.amazonPageProxyLanguage}`;
|
|
194
194
|
_options.logger && _options.logger('Alexa-Cookie: Initial Page Request: ' + returnedInitUrl);
|
|
195
195
|
return returnedInitUrl;
|
|
196
196
|
}
|
|
@@ -215,8 +215,8 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
215
215
|
|
|
216
216
|
function replaceHosts(data) {
|
|
217
217
|
//const dataOrig = data;
|
|
218
|
-
const amazonRegex = new RegExp(`https?://www.${_options.baseAmazonPage}:?[0-9]*/`.replace(/\./g,
|
|
219
|
-
const alexaRegex = new RegExp(`https?://alexa.${_options.baseAmazonPage}:?[0-9]*/`.replace(/\./g,
|
|
218
|
+
const amazonRegex = new RegExp(`https?://www.${_options.baseAmazonPage}:?[0-9]*/`.replace(/\./g, '\\.'), 'g');
|
|
219
|
+
const alexaRegex = new RegExp(`https?://alexa.${_options.baseAmazonPage}:?[0-9]*/`.replace(/\./g, '\\.'), 'g');
|
|
220
220
|
data = data.replace(///g, '/');
|
|
221
221
|
data = data.replace(amazonRegex, `http://${_options.proxyOwnIp}:${_options.proxyPort}/www.${_options.baseAmazonPage}/`);
|
|
222
222
|
data = data.replace(alexaRegex, `http://${_options.proxyOwnIp}:${_options.proxyPort}/alexa.${_options.baseAmazonPage}/`);
|
|
@@ -225,8 +225,8 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
function replaceHostsBack(data) {
|
|
228
|
-
const amazonRegex = new RegExp(`http://${_options.proxyOwnIp}:${_options.proxyPort}/www.${_options.baseAmazonPage}/`.replace(/\./g,
|
|
229
|
-
const alexaRegex = new RegExp(`http://${_options.proxyOwnIp}:${_options.proxyPort}/alexa.${_options.baseAmazonPage}/`.replace(/\./g,
|
|
228
|
+
const amazonRegex = new RegExp(`http://${_options.proxyOwnIp}:${_options.proxyPort}/www.${_options.baseAmazonPage}/`.replace(/\./g, '\\.'), 'g');
|
|
229
|
+
const alexaRegex = new RegExp(`http://${_options.proxyOwnIp}:${_options.proxyPort}/alexa.${_options.baseAmazonPage}/`.replace(/\./g, '\\.'), 'g');
|
|
230
230
|
data = data.replace(amazonRegex, `https://www.${_options.baseAmazonPage}/`);
|
|
231
231
|
data = data.replace(alexaRegex, `https://alexa.${_options.baseAmazonPage}/`);
|
|
232
232
|
if (data === `http://${_options.proxyOwnIp}:${_options.proxyPort}/`) {
|
|
@@ -247,9 +247,9 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
247
247
|
_options.logger && _options.logger('Alexa-Cookie: Headers: ' + JSON.stringify(proxyReq.getHeaders()));
|
|
248
248
|
let reqCookie = proxyReq.getHeader('cookie');
|
|
249
249
|
if (reqCookie === undefined) {
|
|
250
|
-
reqCookie =
|
|
250
|
+
reqCookie = '';
|
|
251
251
|
}
|
|
252
|
-
for (
|
|
252
|
+
for (const cookie in initialCookies) {
|
|
253
253
|
if (!initialCookies.hasOwnProperty(cookie)) continue;
|
|
254
254
|
if (!reqCookie.includes(cookie + '=')) {
|
|
255
255
|
reqCookie += '; ' + cookie + '=' + initialCookies[cookie];
|
|
@@ -270,7 +270,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
270
270
|
let modified = false;
|
|
271
271
|
if (req.method === 'POST') {
|
|
272
272
|
if (typeof proxyReq.getHeader === 'function' && proxyReq.getHeader('referer')) {
|
|
273
|
-
|
|
273
|
+
const fixedReferer = replaceHostsBack(proxyReq.getHeader('referer'));
|
|
274
274
|
if (fixedReferer ) {
|
|
275
275
|
proxyReq.setHeader('referer', fixedReferer);
|
|
276
276
|
_options.logger && _options.logger('Alexa-Cookie: Modify headers: Changed Referer: ' + fixedReferer);
|
|
@@ -330,12 +330,12 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
330
330
|
_options.logger && _options.logger('Alexa-Cookie: Proxy catched parameters: ' + JSON.stringify(queryParams));
|
|
331
331
|
|
|
332
332
|
callbackCookie && callbackCookie(null, {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
333
|
+
'loginCookie': proxyCookies,
|
|
334
|
+
'authorization_code': queryParams['openid.oa2.authorization_code'],
|
|
335
|
+
'frc': initialCookies.frc,
|
|
336
|
+
'map-md': initialCookies['map-md'],
|
|
337
|
+
'deviceId': deviceId,
|
|
338
|
+
'verifier': code_verifier
|
|
339
339
|
});
|
|
340
340
|
return;
|
|
341
341
|
}
|
|
@@ -376,7 +376,7 @@ function initAmazonProxy(_options, callbackCookie, callbackListening) {
|
|
|
376
376
|
app.get('/cookie-success', function(req, res) {
|
|
377
377
|
res.send('<b>Amazon Alexa Cookie successfully retrieved. You can close the browser.</b>');
|
|
378
378
|
});
|
|
379
|
-
|
|
379
|
+
const server = app.listen(_options.proxyPort, _options.proxyListenBind, function() {
|
|
380
380
|
_options.logger && _options.logger('Alexa-Cookie: Proxy-Server listening on port ' + server.address().port);
|
|
381
381
|
callbackListening && callbackListening(server);
|
|
382
382
|
callbackListening = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alexa-cookie2",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Generate Cookie and CSRF for Alexa Remote",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Apollon77",
|
|
@@ -21,15 +21,17 @@
|
|
|
21
21
|
"layla.amazon.de"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"cookie": "^0.
|
|
25
|
-
"express": "^4.
|
|
26
|
-
"http-proxy-middleware": "^2.0.
|
|
24
|
+
"cookie": "^0.5.0",
|
|
25
|
+
"express": "^4.18.1",
|
|
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.
|
|
32
|
+
"@alcalzone/release-script": "^3.5.9",
|
|
33
|
+
"@alcalzone/release-script-plugin-license": "^3.5.9",
|
|
34
|
+
"eslint": "^8.18.0"
|
|
33
35
|
},
|
|
34
36
|
"repository": {
|
|
35
37
|
"type": "git",
|