mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
- Add GetAccountByRefreshToken to amazon.Service — the speaker sends the bare Atzr| refresh token (extracted from AmazonSecret JSON), not a surrogate, so lookup must match against Account.RefreshToken - Add amazonService field, SetAmazonService and IsAmazonConfigured to Server (step 5 essentials required by the handler) - Replace HandleBoseAmazonToken 501 stub with full implementation: lookup by refresh token → RefreshAccessToken; fallback to GetFreshToken; fallback to HandleBoseProxy if no service configured; scope intentionally omitted from response - Add handler tests covering the by-refresh-token path (mock LWA server), the default-account path, and the no-service fallback - Unlock assertions in post_oauth_token_amazon.http integration test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
40 lines
1.8 KiB
HTTP
40 lines
1.8 KiB
HTTP
### POST /oauth/device/{{deviceId}}/music/musicprovider/20/token/cs1
|
|
# Mirrors the exact request the SoundTouch firmware makes when it needs a fresh Amazon access token.
|
|
# The speaker extracts the bare refresh_token from its stored AmazonSecret JSON and sends it here.
|
|
# Log reference: STSOAuth2::ConstructPostDataString — grant_type=refresh_token, code and redirect_uri are always empty.
|
|
POST {{host}}/oauth/device/{{deviceId}}/music/musicprovider/20/token/cs1
|
|
Authorization: Bearer {{token}}
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"code": "",
|
|
"grant_type": "refresh_token",
|
|
"redirect_uri": "",
|
|
"refresh_token": "{{amazonRefreshToken}}"
|
|
}
|
|
|
|
> {%
|
|
client.test("Request executed successfully", function() {
|
|
client.assert(response.status === 200, "Response status is not 200");
|
|
});
|
|
|
|
client.test("Response content type is JSON", function() {
|
|
var type = response.contentType.mimeType;
|
|
client.assert(type === "application/json", "Expected 'application/json' but received '" + type + "'");
|
|
});
|
|
|
|
client.test("Response body has expected structure", function() {
|
|
client.assert(response.body.hasOwnProperty("access_token"), "Response body missing 'access_token'");
|
|
client.assert(response.body.access_token.length > 0, "access_token is empty");
|
|
|
|
client.assert(response.body.hasOwnProperty("expires_in"), "Response body missing 'expires_in'");
|
|
client.assert(typeof response.body.expires_in === "number", "expires_in is not a number");
|
|
|
|
client.assert(response.body.hasOwnProperty("token_type"), "Response body missing 'token_type'");
|
|
client.assert(response.body.token_type === "Bearer", "token_type is not 'Bearer'");
|
|
|
|
// Amazon omits 'scope' — do not assert its presence.
|
|
client.assert(!response.body.hasOwnProperty("scope"), "Response must NOT include 'scope' for Amazon");
|
|
});
|
|
%}
|