@@ -63,7 +63,7 @@ public class ApiBridge {
63
63
private static final String BASE_PATH_AUTH = "https://authglb.digital.panasonic.com" ;
64
64
private static final String BASE_PATH_ACC = "https://accsmart.panasonic.com" ;
65
65
private static final String APPBRAIN_URL = "https://www.appbrain.com/app/panasonic-comfort-cloud/com.panasonic.ACCsmart" ;
66
- private static final String DEFAULT_APP_VERSION = "1.21.1 " ;
66
+ private static final String DEFAULT_APP_VERSION = "1.22.0 " ;
67
67
68
68
private static final String ACCESS_TOKEN_KEY = "accessToken" ;
69
69
private static final String REFRESH_TOKEN_KEY = "refreshToken" ;
@@ -74,6 +74,7 @@ public class ApiBridge {
74
74
private static final int ERROR_CODE_UPDATE_VERSION = 4106 ;
75
75
76
76
private final Logger logger = LoggerFactory .getLogger (ApiBridge .class );
77
+ private MessageDigest digest = null ;
77
78
78
79
private String clientId ;
79
80
private String username ;
@@ -82,11 +83,19 @@ public class ApiBridge {
82
83
private Gson gson ;
83
84
private OkHttpClient client ;
84
85
private Storage <String > storage ;
86
+ private DateTimeFormatter dateTimeFormatter ;
85
87
86
88
public ApiBridge (Storage <String > storage ) {
87
89
this .storage = storage ;
88
90
HttpLoggingInterceptor logging = new HttpLoggingInterceptor (message -> logger .debug (message ));
89
91
logging .setLevel (HttpLoggingInterceptor .Level .BODY );
92
+ dateTimeFormatter = DateTimeFormatter .ofPattern ("yyyy-MM-dd HH:mm:ss" ).withZone (ZoneId .of ("UTC" ));
93
+
94
+ try {
95
+ digest = MessageDigest .getInstance ("SHA-256" );
96
+ } catch (NoSuchAlgorithmException e ) {
97
+ throw new RuntimeException (e );
98
+ }
90
99
91
100
CookieJar cookieJar = new CookieJar () {
92
101
@@ -122,13 +131,29 @@ public List<Cookie> loadForRequest(HttpUrl httpUrl) {
122
131
return cookies ;
123
132
}
124
133
125
- public static String generateRandomStringHex ( int bitLength ) {
134
+ public String generateAPIKey ( Instant timestamp , String accessToken ) {
126
135
StringBuilder b = new StringBuilder ();
127
- for (int i = 0 ; i < bitLength ; i ++) {
128
- b .append (Integer .toHexString ((int ) (Math .random () * 16 )));
129
- }
136
+ b .append ("Comfort Cloud" );
137
+ b .append ("521325fb2dd486bf4831b47644317fca" );
138
+ b .append (timestamp .getEpochSecond () * 1000 );
139
+ b .append ("Bearer " );
140
+ b .append (accessToken );
141
+
142
+ byte [] hash = digest .digest (b .toString ().getBytes (StandardCharsets .UTF_8 ));
143
+ String hex = bytesToHex (hash );
144
+ return hex .substring (0 , 9 ) + "cfc" + hex .substring (9 );
145
+ }
130
146
131
- return b .toString ();
147
+ private static String bytesToHex (byte [] hash ) {
148
+ StringBuilder hexString = new StringBuilder (2 * hash .length );
149
+ for (int i = 0 ; i < hash .length ; i ++) {
150
+ String hex = Integer .toHexString (0xff & hash [i ]);
151
+ if (hex .length () == 1 ) {
152
+ hexString .append ('0' );
153
+ }
154
+ hexString .append (hex );
155
+ }
156
+ return hexString .toString ();
132
157
}
133
158
134
159
public static String generateHash (String codeVerifier ) throws NoSuchAlgorithmException {
@@ -175,14 +200,14 @@ private Request buildRequest(Token token, final AbstractRequest req) {
175
200
request = request .post (RequestBody .create (JSON , reqJson ));
176
201
}
177
202
203
+ Instant timestamp = Instant .now ();
204
+
178
205
request .addHeader ("Accept-Encoding" , "gzip, deflate" ).addHeader ("Accept" , "*/*" )
179
206
.addHeader ("User-Agent" , "G-RAC" ).addHeader ("Content-Type" , "application/json;charset=utf-8" )
180
207
.addHeader ("x-app-name" , "Comfort Cloud" )
181
- .addHeader ("x-app-timestamp" ,
182
- DateTimeFormatter .ofPattern ("yyyy-MM-dd HH:mm:ss" ).withZone (ZoneId .systemDefault ())
183
- .format (Instant .now ()))
184
- .addHeader ("x-app-type" , "1" ).addHeader ("x-app-version" , appVersion )
185
- .addHeader ("x-cfc-api-key" , generateRandomStringHex (128 ))
208
+ .addHeader ("x-app-timestamp" , dateTimeFormatter .format (timestamp )).addHeader ("x-app-type" , "1" )
209
+ .addHeader ("x-app-version" , appVersion )
210
+ .addHeader ("x-cfc-api-key" , generateAPIKey (timestamp , token .getAccessToken ()))
186
211
.addHeader ("x-user-authorization-v2" , "Bearer " + token .getAccessToken ())
187
212
.addHeader ("x-client-id" , token .getClientId ()).build ();
188
213
@@ -375,14 +400,13 @@ private Token doV2AuthorizationFlow() throws IOException, NoSuchAlgorithmExcepti
375
400
376
401
RequestBody body = RequestBody .create (MediaType .parse ("application/json;charset=utf-8" ),
377
402
gson .toJson (new GetAccClientIdDTO ()));
403
+
378
404
Request getAccClientIdRequest = new Request .Builder ().post (body ).url (BASE_PATH_ACC + "/auth/v2/login" )
379
405
.addHeader ("Accept-Encoding" , "gzip, deflate" ).addHeader ("Accept" , "*/*" )
380
406
.addHeader ("User-Agent" , "G-RAC" ).addHeader ("Content-Type" , "application/json;charset=utf-8" )
381
- .addHeader ("x-app-name" , "Comfort Cloud" )
382
- .addHeader ("x-app-timestamp" ,
383
- DateTimeFormatter .ofPattern ("yyyy-MM-dd HH:mm:ss" ).withZone (ZoneId .systemDefault ()).format (now ))
407
+ .addHeader ("x-app-name" , "Comfort Cloud" ).addHeader ("x-app-timestamp" , dateTimeFormatter .format (now ))
384
408
.addHeader ("x-app-type" , "1" ).addHeader ("x-app-version" , appVersion )
385
- .addHeader ("x-cfc-api-key" , generateRandomStringHex ( 128 ))
409
+ .addHeader ("x-cfc-api-key" , generateAPIKey ( now , accessToken ))
386
410
.addHeader ("x-user-authorization-v2" , "Bearer " + accessToken ).build ();
387
411
388
412
Response getAccClientResponse = client .newCall (getAccClientIdRequest ).execute ();
0 commit comments