@@ -5,7 +5,6 @@ import {identityFqdn} from '../../../public/node/context/fqdn.js'
5
5
import { shopifyFetch } from '../../../public/node/http.js'
6
6
import { err , ok , Result } from '../../../public/node/result.js'
7
7
import { AbortError , BugError , ExtendableError } from '../../../public/node/error.js'
8
- import { isAppManagementDisabled } from '../../../public/node/context/local.js'
9
8
import { setLastSeenAuthMethod , setLastSeenUserIdAfterAuth } from '../session.js'
10
9
import * as jose from 'jose'
11
10
import { nonRandomUUID } from '@shopify/cli-kit/node/crypto'
@@ -40,7 +39,7 @@ export async function exchangeAccessForApplicationTokens(
40
39
requestAppToken ( 'storefront-renderer' , token , scopes . storefront ) ,
41
40
requestAppToken ( 'business-platform' , token , scopes . businessPlatform ) ,
42
41
store ? requestAppToken ( 'admin' , token , scopes . admin , store ) : { } ,
43
- isAppManagementDisabled ( ) ? { } : requestAppToken ( 'app-management' , token , scopes . appManagement ) ,
42
+ requestAppToken ( 'app-management' , token , scopes . appManagement ) ,
44
43
] )
45
44
46
45
return {
@@ -69,26 +68,55 @@ export async function refreshAccessToken(currentToken: IdentityToken): Promise<I
69
68
}
70
69
71
70
/**
72
- * Given a custom CLI token passed as ENV variable, request a valid partners API token
73
- * This token does not accept extra scopes, just the cli one.
71
+ * Given a custom CLI token passed as ENV variable (`SHOPIFY_CLI_PARTNERS_TOKEN`), request a valid API access token
74
72
* @param token - The CLI token passed as ENV variable
75
73
* @returns An instance with the application access tokens.
76
74
*/
77
- export async function exchangeCustomPartnerToken ( token : string ) : Promise < { accessToken : string ; userId : string } > {
78
- const appId = applicationId ( 'partners' )
75
+ export async function exchangeCliTokenForAccessToken (
76
+ apiName : API ,
77
+ token : string ,
78
+ scopes : string [ ] ,
79
+ ) : Promise < { accessToken : string ; userId : string } > {
80
+ const appId = applicationId ( apiName )
79
81
try {
80
- const newToken = await requestAppToken ( 'partners' , token , [ 'https://api.shopify.com/auth/partners.app.cli.access' ] )
82
+ const newToken = await requestAppToken ( apiName , token , scopes )
81
83
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
82
84
const accessToken = newToken [ appId ] ! . accessToken
83
85
const userId = nonRandomUUID ( token )
84
86
setLastSeenUserIdAfterAuth ( userId )
85
87
setLastSeenAuthMethod ( 'partners_token' )
86
88
return { accessToken, userId}
87
89
} catch ( error ) {
88
- throw new AbortError ( 'The custom token provided is invalid.' , 'Ensure the token is correct and not expired.' )
90
+ const prettyName = apiName . replace ( / - / g, ' ' ) . replace ( / \b \w / g, ( char ) => char . toUpperCase ( ) )
91
+
92
+ throw new AbortError (
93
+ `The custom token provided can't be used for the ${ prettyName } API.` ,
94
+ 'Ensure the token is correct and not expired.' ,
95
+ )
89
96
}
90
97
}
91
98
99
+ export async function exchangeCustomPartnerToken ( token : string ) : Promise < { accessToken : string ; userId : string } > {
100
+ return exchangeCliTokenForAccessToken ( 'partners' , token , [ 'https://api.shopify.com/auth/partners.app.cli.access' ] )
101
+ }
102
+
103
+ export async function exchangeCliTokenForAppManagementAccessToken (
104
+ token : string ,
105
+ ) : Promise < { accessToken : string ; userId : string } > {
106
+ return exchangeCliTokenForAccessToken ( 'app-management' , token , [
107
+ 'https://api.shopify.com/auth/organization.apps.manage' ,
108
+ ] )
109
+ }
110
+
111
+ export async function exchangeCliTokenForBusinessPlatformAccessToken (
112
+ token : string ,
113
+ ) : Promise < { accessToken : string ; userId : string } > {
114
+ return exchangeCliTokenForAccessToken ( 'business-platform' , token , [
115
+ 'https://api.shopify.com/auth/destinations.readonly' ,
116
+ 'https://api.shopify.com/auth/organization.store-management' ,
117
+ ] )
118
+ }
119
+
92
120
type IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'expired_token' | 'slow_down' | 'unknown_failure'
93
121
94
122
/**
0 commit comments