Skip to content

Commit a22cfed

Browse files
wire up identity client to current identity callsites
1 parent 78b33dc commit a22cfed

File tree

5 files changed

+17
-31
lines changed

5 files changed

+17
-31
lines changed

packages/cli-kit/src/private/node/session.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ import {
55
exchangeAccessForApplicationTokens,
66
exchangeCustomPartnerToken,
77
ExchangeScopes,
8-
refreshAccessToken,
98
InvalidGrantError,
109
InvalidRequestError,
1110
} from './session/exchange.js'
1211
import {IdentityToken, Session, Sessions} from './session/schema.js'
1312
import * as sessionStore from './session/store.js'
14-
import {pollForDeviceAuthorization, requestDeviceAuthorization} from './session/device-authorization.js'
1513
import {isThemeAccessSession} from './api/rest.js'
1614
import {getCurrentSessionId, setCurrentSessionId} from './conf-store.js'
1715
import {UserEmailQueryString, UserEmailQuery} from './api/graphql/business-platform-destinations/user-email.js'
16+
import {getIdentityClient} from './clients/identity/instance.js'
1817
import {outputContent, outputToken, outputDebug, outputCompleted} from '../../public/node/output.js'
1918
import {firstPartyDev, themeToken} from '../../public/node/context/local.js'
2019
import {AbortError} from '../../public/node/error.js'
@@ -306,13 +305,7 @@ async function executeCompleteFlow(applications: OAuthApplications): Promise<Ses
306305
if (identityTokenInformation) {
307306
identityToken = buildIdentityTokenFromEnv(scopes, identityTokenInformation)
308307
} else {
309-
// Request a device code to authorize without a browser redirect.
310-
outputDebug(outputContent`Requesting device authorization code...`)
311-
const deviceAuth = await requestDeviceAuthorization(scopes)
312-
313-
// Poll for the identity token
314-
outputDebug(outputContent`Starting polling for the identity token...`)
315-
identityToken = await pollForDeviceAuthorization(deviceAuth.deviceCode, deviceAuth.interval)
308+
identityToken = await getIdentityClient().requestAccessToken(scopes)
316309
}
317310

318311
// Exchange identity token for application tokens
@@ -343,7 +336,7 @@ async function executeCompleteFlow(applications: OAuthApplications): Promise<Ses
343336
*/
344337
async function refreshTokens(session: Session, applications: OAuthApplications): Promise<Session> {
345338
// Refresh Identity Token
346-
const identityToken = await refreshAccessToken(session.identity)
339+
const identityToken = await getIdentityClient().refreshAccessToken(session.identity)
347340
// Exchange new identity token for application tokens
348341
const exchangeScopes = getExchangeScopes(applications)
349342
const applicationTokens = await exchangeAccessForApplicationTokens(

packages/cli-kit/src/private/node/session/device-authorization.test.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
pollForDeviceAuthorization,
44
requestDeviceAuthorization,
55
} from './device-authorization.js'
6-
import {clientId} from './identity.js'
76
import {IdentityToken} from './schema.js'
87
import {exchangeDeviceCodeForAccessToken} from './exchange.js'
98
import {identityFqdn} from '../../../public/node/context/fqdn.js'
@@ -50,7 +49,6 @@ describe('requestDeviceAuthorization', () => {
5049
const response = new Response(JSON.stringify(data))
5150
vi.mocked(shopifyFetch).mockResolvedValue(response)
5251
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
53-
vi.mocked(clientId).mockReturnValue('clientId')
5452

5553
// When
5654
const got = await requestDeviceAuthorization(['scope1', 'scope2'])
@@ -59,7 +57,7 @@ describe('requestDeviceAuthorization', () => {
5957
expect(shopifyFetch).toBeCalledWith('https://fqdn.com/oauth/device_authorization', {
6058
method: 'POST',
6159
headers: {'Content-type': 'application/x-www-form-urlencoded'},
62-
body: 'client_id=clientId&scope=scope1 scope2',
60+
body: 'client_id=fbdb2649-e327-4907-8f67-908d24cfd7e3&scope=scope1 scope2',
6361
})
6462
expect(got).toEqual(dataExpected)
6563
})
@@ -71,7 +69,6 @@ describe('requestDeviceAuthorization', () => {
7169
Object.defineProperty(response, 'statusText', {value: 'OK'})
7270
vi.mocked(shopifyFetch).mockResolvedValue(response)
7371
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
74-
vi.mocked(clientId).mockReturnValue('clientId')
7572

7673
// When/Then
7774
await expect(requestDeviceAuthorization(['scope1', 'scope2'])).rejects.toThrowError(
@@ -86,7 +83,6 @@ describe('requestDeviceAuthorization', () => {
8683
Object.defineProperty(response, 'statusText', {value: 'OK'})
8784
vi.mocked(shopifyFetch).mockResolvedValue(response)
8885
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
89-
vi.mocked(clientId).mockReturnValue('clientId')
9086

9187
// When/Then
9288
await expect(requestDeviceAuthorization(['scope1', 'scope2'])).rejects.toThrowError(
@@ -102,7 +98,6 @@ describe('requestDeviceAuthorization', () => {
10298
Object.defineProperty(response, 'statusText', {value: 'Not Found'})
10399
vi.mocked(shopifyFetch).mockResolvedValue(response)
104100
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
105-
vi.mocked(clientId).mockReturnValue('clientId')
106101

107102
// When/Then
108103
await expect(requestDeviceAuthorization(['scope1', 'scope2'])).rejects.toThrowError(
@@ -117,7 +112,6 @@ describe('requestDeviceAuthorization', () => {
117112
Object.defineProperty(response, 'statusText', {value: 'Internal Server Error'})
118113
vi.mocked(shopifyFetch).mockResolvedValue(response)
119114
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
120-
vi.mocked(clientId).mockReturnValue('clientId')
121115

122116
// When/Then
123117
await expect(requestDeviceAuthorization(['scope1', 'scope2'])).rejects.toThrowError(
@@ -134,7 +128,6 @@ describe('requestDeviceAuthorization', () => {
134128
response.text = vi.fn().mockRejectedValue(new Error('Network error'))
135129
vi.mocked(shopifyFetch).mockResolvedValue(response)
136130
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
137-
vi.mocked(clientId).mockReturnValue('clientId')
138131

139132
// When/Then
140133
await expect(requestDeviceAuthorization(['scope1', 'scope2'])).rejects.toThrowError(

packages/cli-kit/src/private/node/session/device-authorization.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import {clientId} from './identity.js'
21
import {exchangeDeviceCodeForAccessToken} from './exchange.js'
32
import {IdentityToken} from './schema.js'
43
import {identityFqdn} from '../../../public/node/context/fqdn.js'
@@ -8,6 +7,7 @@ import {AbortError, BugError} from '../../../public/node/error.js'
87
import {isCloudEnvironment} from '../../../public/node/context/local.js'
98
import {isCI, openURL} from '../../../public/node/system.js'
109
import {isTTY, keypress} from '../../../public/node/ui.js'
10+
import {getIdentityClient} from '../clients/identity/instance.js'
1111
import {Response} from 'node-fetch'
1212

1313
export interface DeviceAuthorizationResponse {
@@ -31,7 +31,7 @@ export interface DeviceAuthorizationResponse {
3131
*/
3232
export async function requestDeviceAuthorization(scopes: string[]): Promise<DeviceAuthorizationResponse> {
3333
const fqdn = await identityFqdn()
34-
const identityClientId = clientId()
34+
const identityClientId = getIdentityClient().clientId()
3535
const queryParams = {client_id: identityClientId, scope: scopes.join(' ')}
3636
const url = `https://${fqdn}/oauth/device_authorization`
3737

packages/cli-kit/src/private/node/session/exchange.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
refreshAccessToken,
99
requestAppToken,
1010
} from './exchange.js'
11-
import {applicationId, clientId} from './identity.js'
11+
import {applicationId} from './identity.js'
1212
import {IdentityToken} from './schema.js'
1313
import {shopifyFetch} from '../../../public/node/http.js'
1414
import {identityFqdn} from '../../../public/node/context/fqdn.js'
@@ -43,7 +43,6 @@ vi.mock('../../../public/node/context/fqdn.js')
4343
vi.mock('./identity')
4444

4545
beforeEach(() => {
46-
vi.mocked(clientId).mockReturnValue('clientId')
4746
vi.setSystemTime(currentDate)
4847
vi.mocked(applicationId).mockImplementation((api) => api)
4948
vi.mocked(identityFqdn).mockResolvedValue('fqdn.com')
@@ -301,7 +300,7 @@ describe.each(tokenExchangeMethods)(
301300
expect(params.get('grant_type')).toBe(grantType)
302301
expect(params.get('requested_token_type')).toBe(accessTokenType)
303302
expect(params.get('subject_token_type')).toBe(accessTokenType)
304-
expect(params.get('client_id')).toBe('clientId')
303+
expect(params.get('client_id')).toBe('fbdb2649-e327-4907-8f67-908d24cfd7e3')
305304
expect(params.get('audience')).toBe(expectedApi)
306305
expect(params.get('scope')).toBe(expectedScopes.join(' '))
307306
expect(params.get('subject_token')).toBe(cliToken)

packages/cli-kit/src/private/node/session/exchange.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {ApplicationToken, IdentityToken} from './schema.js'
2-
import {applicationId, clientId as getIdentityClientId} from './identity.js'
2+
import {applicationId} from './identity.js'
33
import {tokenExchangeScopes} from './scopes.js'
44
import {API} from '../api.js'
55
import {identityFqdn} from '../../../public/node/context/fqdn.js'
@@ -8,6 +8,7 @@ import {err, ok, Result} from '../../../public/node/result.js'
88
import {AbortError, BugError, ExtendableError} from '../../../public/node/error.js'
99
import {setLastSeenAuthMethod, setLastSeenUserIdAfterAuth} from '../session.js'
1010
import {nonRandomUUID} from '../../../public/node/crypto.js'
11+
import {getIdentityClient} from '../clients/identity/instance.js'
1112
import * as jose from 'jose'
1213

1314
export class InvalidGrantError extends ExtendableError {}
@@ -56,14 +57,14 @@ export async function exchangeAccessForApplicationTokens(
5657
* Given an expired access token, refresh it to get a new one.
5758
*/
5859
export async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {
59-
const clientId = getIdentityClientId()
60+
const clientId = getIdentityClient().clientId()
6061
const params = {
6162
grant_type: 'refresh_token',
6263
access_token: currentToken.accessToken,
6364
refresh_token: currentToken.refreshToken,
6465
client_id: clientId,
6566
}
66-
const tokenResult = await tokenRequest(params)
67+
const tokenResult = await getIdentityClient().tokenRequest(params)
6768
const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()
6869
return buildIdentityToken(value, currentToken.userId, currentToken.alias)
6970
}
@@ -141,15 +142,15 @@ type IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'expired_
141142
export async function exchangeDeviceCodeForAccessToken(
142143
deviceCode: string,
143144
): Promise<Result<IdentityToken, IdentityDeviceError>> {
144-
const clientId = await getIdentityClientId()
145+
const clientId = getIdentityClient().clientId()
145146

146147
const params = {
147148
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
148149
device_code: deviceCode,
149150
client_id: clientId,
150151
}
151152

152-
const tokenResult = await tokenRequest(params)
153+
const tokenResult = await getIdentityClient().tokenRequest(params)
153154
if (tokenResult.isErr()) {
154155
return err(tokenResult.error.error as IdentityDeviceError)
155156
}
@@ -164,7 +165,7 @@ export async function requestAppToken(
164165
store?: string,
165166
): Promise<{[x: string]: ApplicationToken}> {
166167
const appId = applicationId(api)
167-
const clientId = await getIdentityClientId()
168+
const clientId = getIdentityClient().clientId()
168169

169170
const params = {
170171
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
@@ -181,7 +182,7 @@ export async function requestAppToken(
181182
if (api === 'admin' && store) {
182183
identifier = `${store}-${appId}`
183184
}
184-
const tokenResult = await tokenRequest(params)
185+
const tokenResult = await getIdentityClient().tokenRequest(params)
185186
const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()
186187
const appToken = buildApplicationToken(value)
187188
return {[identifier]: appToken}
@@ -221,7 +222,7 @@ export function tokenRequestErrorHandler({error, store}: {error: string; store?:
221222
return new AbortError(error)
222223
}
223224

224-
async function tokenRequest(params: {
225+
async function _tokenRequest(params: {
225226
[key: string]: string
226227
}): Promise<Result<TokenRequestResult, {error: string; store?: string}>> {
227228
const fqdn = await identityFqdn()

0 commit comments

Comments
 (0)