@@ -10,6 +10,8 @@ import {
1010} from "./definitions" ;
1111import * as crypto from "crypto" ;
1212
13+ import { GSASRPAuthenticator } from "./srp/srp-wrapper" ;
14+
1315export class ApplePortalSessionService implements IApplePortalSessionService {
1416 private loginConfigEndpoint =
1517 "https://appstoreconnect.apple.com/olympus/v1/app/config?hostname=itunesconnect.apple.com" ;
@@ -174,29 +176,53 @@ For more details how to set up your environment, please execute "ns publish ios
174176 }
175177
176178 private async loginCore ( credentials : ICredentials ) : Promise < void > {
179+ const wrapper = new GSASRPAuthenticator ( credentials . username ) ;
180+ const initData = await wrapper . getInit ( ) ;
181+
177182 const loginConfig = await this . getLoginConfig ( ) ;
178- const loginUrl = `${ loginConfig . authServiceUrl } /auth/signin` ;
183+ const loginUrl = `${ loginConfig . authServiceUrl } /auth/signin/init ` ;
179184 const headers = {
180185 "Content-Type" : "application/json" ,
181186 "X-Requested-With" : "XMLHttpRequest" ,
182187 "X-Apple-Widget-Key" : loginConfig . authServiceKey ,
183188 Accept : "application/json, text/javascript" ,
184189 } ;
185- const body = {
186- accountName : credentials . username ,
187- password : credentials . password ,
188- rememberMe : true ,
189- } ;
190190
191- const loginResponse = await this . $httpClient . httpRequest ( {
191+ const initResponse = await this . $httpClient . httpRequest ( {
192192 url : loginUrl ,
193193 method : "POST" ,
194- body,
194+ body : initData ,
195195 headers,
196196 } ) ;
197197
198+ const body = JSON . parse ( initResponse . response . body ) ;
199+
200+ const completeData = await wrapper . getComplete ( credentials . password , body ) ;
201+
202+ const hashcash = await this . fetchHashcash (
203+ loginConfig . authServiceUrl ,
204+ loginConfig . authServiceKey
205+ ) ;
206+
207+ const completeUrl = `${ loginConfig . authServiceUrl } /auth/signin/complete?isRememberMeEnabled=false` ;
208+ const completeHeaders = {
209+ "Content-Type" : "application/json" ,
210+ "X-Requested-With" : "XMLHttpRequest" ,
211+ "X-Apple-Widget-Key" : loginConfig . authServiceKey ,
212+ Accept : "application/json, text/javascript" ,
213+ "X-Apple-HC" : hashcash || "" ,
214+ } ;
215+
216+ const completeResponse = await this . $httpClient . httpRequest ( {
217+ url : completeUrl ,
218+ method : "POST" ,
219+ completeHeaders,
220+ body : completeData ,
221+ headers : completeHeaders ,
222+ } ) ;
223+
198224 this . $applePortalCookieService . updateUserSessionCookie (
199- loginResponse . headers [ "set-cookie" ]
225+ completeResponse . headers [ "set-cookie" ]
200226 ) ;
201227 }
202228
@@ -221,6 +247,23 @@ For more details how to set up your environment, please execute "ns publish ios
221247 return config || this . defaultLoginConfig ;
222248 }
223249
250+ private async fetchHashcash (
251+ authServiceUrl : string ,
252+ authServiceKey : string
253+ ) : Promise < string > {
254+ const loginUrl = `${ authServiceUrl } /auth/signin?widgetKey=${ authServiceKey } ` ;
255+ const response = await this . $httpClient . httpRequest ( {
256+ url : loginUrl ,
257+ method : "GET" ,
258+ } ) ;
259+
260+ const headers = response . headers ;
261+
262+ const bits = headers [ "X-Apple-HC-Bits" ] ;
263+ const challenge = headers [ "X-Apple-HC-Challenge" ] ;
264+ return makeHashCash ( bits , challenge ) ;
265+ }
266+
224267 private async handleTwoFactorAuthentication (
225268 scnt : string ,
226269 xAppleIdSessionId : string ,
0 commit comments