77/* eslint-disable camelcase */
88/* eslint-disable @typescript-eslint/ban-types */
99
10- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
11- // @ts -ignore
12- import * as Transport from 'jsforce/lib/transport' ;
10+ import { URLSearchParams } from 'url' ;
11+ import Transport from 'jsforce/lib/transport' ;
1312import { AsyncCreatable , Duration , parseJsonMap } from '@salesforce/kit' ;
14- import { OAuth2Options } from 'jsforce' ;
13+ import { OAuth2Config } from 'jsforce/lib/oauth2' ;
14+ import { HttpRequest } from 'jsforce' ;
1515import { Nullable , ensureString , JsonMap } from '@salesforce/ts-types' ;
1616import { Logger } from './logger' ;
1717import { AuthInfo , DEFAULT_CONNECTED_APP_INFO } from './org/authInfo' ;
@@ -40,35 +40,13 @@ export interface DeviceCodePollingResponse extends JsonMap {
4040 issued_at : string ;
4141}
4242
43- interface DeviceLoginOptions {
44- url : string ;
45- headers : object ;
46- method : string ;
47- form : {
48- client_id : string ;
49- response_type : string ;
50- scope : string ;
51- } ;
52- }
53-
54- interface DevicePollingOptions {
55- url : string ;
56- headers : object ;
57- method : string ;
58- form : {
59- client_id : string ;
60- grant_type : string ;
61- code : string ;
62- } ;
63- }
64-
6543async function wait ( ms = 1000 ) : Promise < void > {
6644 return new Promise ( ( resolve ) => {
6745 setTimeout ( resolve , ms ) ;
6846 } ) ;
6947}
7048
71- async function makeRequest < T extends JsonMap > ( options : DeviceLoginOptions | DevicePollingOptions ) : Promise < T > {
49+ async function makeRequest < T extends JsonMap > ( options : HttpRequest ) : Promise < T > {
7250 const rawResponse = await new Transport ( ) . httpRequest ( options ) ;
7351 const response = parseJsonMap < T > ( rawResponse . body ) ;
7452 if ( response . error ) {
@@ -96,17 +74,17 @@ async function makeRequest<T extends JsonMap>(options: DeviceLoginOptions | Devi
9674 * const authInfo = await deviceOauthService.authorizeAndSave(approval);
9775 * ```
9876 */
99- export class DeviceOauthService extends AsyncCreatable < OAuth2Options > {
77+ export class DeviceOauthService extends AsyncCreatable < OAuth2Config > {
10078 public static RESPONSE_TYPE = 'device_code' ;
10179 public static GRANT_TYPE = 'device' ;
10280 public static SCOPE = 'refresh_token web api' ;
10381 private static POLLING_COUNT_MAX = 100 ;
10482
10583 private logger ! : Logger ;
106- private options : OAuth2Options ;
84+ private options : OAuth2Config ;
10785 private pollingCount = 0 ;
10886
109- public constructor ( options : OAuth2Options ) {
87+ public constructor ( options : OAuth2Config ) {
11088 super ( options ) ;
11189 this . options = options ;
11290 if ( ! this . options . clientId ) this . options . clientId = DEFAULT_CONNECTED_APP_INFO . clientId ;
@@ -161,42 +139,42 @@ export class DeviceOauthService extends AsyncCreatable<OAuth2Options> {
161139 this . logger . debug ( `this.options.loginUrl: ${ this . options . loginUrl } ` ) ;
162140 }
163141
164- private getLoginOptions ( url : string ) : DeviceLoginOptions {
142+ private getLoginOptions ( url : string ) : HttpRequest {
143+ const body = new URLSearchParams ( ) ;
144+ body . append ( 'client_id' , ensureString ( this . options . clientId ) ) ;
145+ body . append ( 'response_type' , DeviceOauthService . RESPONSE_TYPE ) ;
146+ body . append ( 'scope' , DeviceOauthService . SCOPE ) ;
165147 return {
166148 url,
167149 headers : SFDX_HTTP_HEADERS ,
168150 method : 'POST' ,
169- form : {
170- client_id : ensureString ( this . options . clientId ) ,
171- response_type : DeviceOauthService . RESPONSE_TYPE ,
172- scope : DeviceOauthService . SCOPE ,
173- } ,
151+ body,
174152 } ;
175153 }
176154
177- private getPollingOptions ( url : string , code : string ) : DevicePollingOptions {
155+ private getPollingOptions ( url : string , code : string ) : HttpRequest {
156+ const body = new URLSearchParams ( ) ;
157+ body . append ( 'client_id' , ensureString ( this . options . clientId ) ) ;
158+ body . append ( 'grant_type' , DeviceOauthService . GRANT_TYPE ) ;
159+ body . append ( 'code' , code ) ;
178160 return {
179161 url,
180162 headers : SFDX_HTTP_HEADERS ,
181163 method : 'POST' ,
182- form : {
183- code,
184- grant_type : DeviceOauthService . GRANT_TYPE ,
185- client_id : ensureString ( this . options . clientId ) ,
186- } ,
164+ body,
187165 } ;
188166 }
189167
190168 private getDeviceFlowRequestUrl ( ) : string {
191169 return `${ ensureString ( this . options . loginUrl ) } /services/oauth2/token` ;
192170 }
193171
194- private async poll ( pollingOptions : DevicePollingOptions ) : Promise < Nullable < DeviceCodePollingResponse > > {
172+ private async poll ( httpRequest : HttpRequest ) : Promise < Nullable < DeviceCodePollingResponse > > {
195173 this . logger . debug (
196174 `polling for device approval (attempt ${ this . pollingCount } of ${ DeviceOauthService . POLLING_COUNT_MAX } )`
197175 ) ;
198176 try {
199- return await makeRequest < DeviceCodePollingResponse > ( pollingOptions ) ;
177+ return await makeRequest < DeviceCodePollingResponse > ( httpRequest ) ;
200178 } catch ( e ) {
201179 const err = e . data ;
202180 if ( err . error && err . status === 400 && err . error === 'authorization_pending' ) {
@@ -218,13 +196,13 @@ export class DeviceOauthService extends AsyncCreatable<OAuth2Options> {
218196 }
219197
220198 private async pollForDeviceApproval (
221- pollingOptions : DevicePollingOptions ,
199+ httpRequest : HttpRequest ,
222200 interval : number
223201 ) : Promise < Nullable < DeviceCodePollingResponse > > {
224202 this . logger . debug ( 'BEGIN POLLING FOR DEVICE APPROVAL' ) ;
225203 let result : Nullable < DeviceCodePollingResponse > ;
226204 while ( this . shouldContinuePolling ( ) ) {
227- result = await this . poll ( pollingOptions ) ;
205+ result = await this . poll ( httpRequest ) ;
228206 if ( result ) {
229207 this . logger . debug ( 'POLLING FOR DEVICE APPROVAL SUCCESS' ) ;
230208 break ;
0 commit comments