@shopify/cli-kit 3.16.3 → 3.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +1 -1
- package/assets/success.html +1 -1
- package/dist/analytics.d.ts +5 -5
- package/dist/analytics.js +5 -5
- package/dist/analytics.js.map +1 -1
- package/dist/api/common.d.ts +2 -2
- package/dist/api/common.js +2 -2
- package/dist/api/common.js.map +1 -1
- package/dist/api/graphql/index.d.ts +0 -2
- package/dist/api/graphql/index.js +0 -2
- package/dist/api/graphql/index.js.map +1 -1
- package/dist/api/oxygen.d.ts +5 -0
- package/dist/api/oxygen.js +30 -0
- package/dist/api/oxygen.js.map +1 -0
- package/dist/api/partners.d.ts +7 -7
- package/dist/api/partners.js +7 -7
- package/dist/api/partners.js.map +1 -1
- package/dist/api.d.ts +2 -2
- package/dist/api.js +2 -2
- package/dist/api.js.map +1 -1
- package/dist/common/object.d.ts +3 -3
- package/dist/common/object.js +3 -3
- package/dist/common/object.js.map +1 -1
- package/dist/content-tokens.js.map +1 -1
- package/dist/environment/fqdn.d.ts +3 -3
- package/dist/environment/fqdn.js +3 -3
- package/dist/environment/fqdn.js.map +1 -1
- package/dist/environment/local.d.ts +13 -13
- package/dist/environment/local.js +16 -16
- package/dist/environment/local.js.map +1 -1
- package/dist/environment/service.d.ts +1 -0
- package/dist/environment/service.js +3 -0
- package/dist/environment/service.js.map +1 -1
- package/dist/environment/spin.d.ts +12 -12
- package/dist/environment/spin.js +12 -12
- package/dist/environment/spin.js.map +1 -1
- package/dist/environment/utilities.d.ts +0 -2
- package/dist/environment/utilities.js +0 -2
- package/dist/environment/utilities.js.map +1 -1
- package/dist/environment.d.ts +3 -1
- package/dist/environment.js +3 -1
- package/dist/environment.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.js +4 -3
- package/dist/error.js.map +1 -1
- package/dist/file.d.ts +17 -18
- package/dist/file.js +17 -18
- package/dist/file.js.map +1 -1
- package/dist/git.d.ts +1 -1
- package/dist/git.js +5 -2
- package/dist/git.js.map +1 -1
- package/dist/http/fetch.d.ts +2 -2
- package/dist/http/fetch.js +2 -2
- package/dist/http/fetch.js.map +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/http.js +1 -1
- package/dist/http.js.map +1 -1
- package/dist/id.d.ts +1 -1
- package/dist/id.js +1 -1
- package/dist/id.js.map +1 -1
- package/dist/network/service.d.ts +0 -2
- package/dist/network/service.js +0 -1
- package/dist/network/service.js.map +1 -1
- package/dist/node/archiver.d.ts +2 -2
- package/dist/node/archiver.js +2 -2
- package/dist/node/archiver.js.map +1 -1
- package/dist/node/checksum.d.ts +2 -2
- package/dist/node/checksum.js +2 -2
- package/dist/node/checksum.js.map +1 -1
- package/dist/node/cli.d.ts +1 -2
- package/dist/node/cli.js +2 -8
- package/dist/node/cli.js.map +1 -1
- package/dist/node/colors.d.ts +2 -1
- package/dist/node/colors.js +2 -7
- package/dist/node/colors.js.map +1 -1
- package/dist/node/dot-env.d.ts +7 -7
- package/dist/node/dot-env.js +7 -7
- package/dist/node/dot-env.js.map +1 -1
- package/dist/node/framework.d.ts +2 -2
- package/dist/node/framework.js +2 -2
- package/dist/node/framework.js.map +1 -1
- package/dist/node/hooks/prerun.js +6 -6
- package/dist/node/hooks/prerun.js.map +1 -1
- package/dist/node/node-package-manager.d.ts +32 -28
- package/dist/node/node-package-manager.js +29 -29
- package/dist/node/node-package-manager.js.map +1 -1
- package/dist/node/ruby.d.ts +4 -4
- package/dist/node/ruby.js +5 -5
- package/dist/node/ruby.js.map +1 -1
- package/dist/os.d.ts +1 -1
- package/dist/os.js +1 -1
- package/dist/os.js.map +1 -1
- package/dist/output.d.ts +26 -34
- package/dist/output.js +23 -143
- package/dist/output.js.map +1 -1
- package/dist/path.d.ts +4 -4
- package/dist/path.js +4 -4
- package/dist/path.js.map +1 -1
- package/dist/plugins.d.ts +4 -4
- package/dist/plugins.js +4 -4
- package/dist/plugins.js.map +1 -1
- package/dist/port.d.ts +1 -1
- package/dist/port.js +1 -1
- package/dist/port.js.map +1 -1
- package/dist/private/node/ui/alert.d.ts +2 -0
- package/dist/private/node/ui/alert.js +18 -0
- package/dist/private/node/ui/alert.js.map +1 -0
- package/dist/private/node/ui/components/Alert.d.ts +17 -0
- package/dist/private/node/ui/components/Alert.js +21 -0
- package/dist/private/node/ui/components/Alert.js.map +1 -0
- package/dist/private/node/ui/components/Banner.d.ts +7 -0
- package/dist/private/node/ui/components/Banner.js +35 -0
- package/dist/private/node/ui/components/Banner.js.map +1 -0
- package/dist/private/node/ui/components/Command.d.ts +9 -0
- package/dist/private/node/ui/components/Command.js +10 -0
- package/dist/private/node/ui/components/Command.js.map +1 -0
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +48 -0
- package/dist/private/node/ui/components/ConcurrentOutput.js +98 -0
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -0
- package/dist/private/node/ui/components/Error.d.ts +8 -0
- package/dist/private/node/ui/components/Error.js +13 -0
- package/dist/private/node/ui/components/Error.js.map +1 -0
- package/dist/private/node/ui/components/FatalError.d.ts +7 -0
- package/dist/private/node/ui/components/FatalError.js +42 -0
- package/dist/private/node/ui/components/FatalError.js.map +1 -0
- package/dist/private/node/ui/components/FullScreen.d.ts +8 -0
- package/dist/private/node/ui/components/FullScreen.js +32 -0
- package/dist/private/node/ui/components/FullScreen.js.map +1 -0
- package/dist/private/node/ui/components/Link.d.ts +10 -0
- package/dist/private/node/ui/components/Link.js +14 -0
- package/dist/private/node/ui/components/Link.js.map +1 -0
- package/dist/private/node/ui/components/List.d.ts +13 -0
- package/dist/private/node/ui/components/List.js +19 -0
- package/dist/private/node/ui/components/List.js.map +1 -0
- package/dist/private/node/ui/components/TextAnimation.d.ts +11 -0
- package/dist/private/node/ui/components/TextAnimation.js +46 -0
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -0
- package/dist/private/node/ui/components/TokenizedText.d.ts +21 -0
- package/dist/private/node/ui/components/TokenizedText.js +26 -0
- package/dist/private/node/ui/components/TokenizedText.js.map +1 -0
- package/dist/private/node/ui/error.d.ts +4 -0
- package/dist/private/node/ui/error.js +12 -0
- package/dist/private/node/ui/error.js.map +1 -0
- package/dist/private/node/ui.d.ts +10 -0
- package/dist/private/node/ui.js +47 -0
- package/dist/private/node/ui.js.map +1 -0
- package/dist/public/common/array.d.ts +4 -4
- package/dist/public/common/array.js +4 -4
- package/dist/public/common/array.js.map +1 -1
- package/dist/public/node/ui.d.ts +155 -0
- package/dist/public/node/ui.js +163 -0
- package/dist/public/node/ui.js.map +1 -0
- package/dist/secure-store.d.ts +4 -4
- package/dist/secure-store.js +4 -4
- package/dist/secure-store.js.map +1 -1
- package/dist/session/device-authorization.d.ts +5 -5
- package/dist/session/device-authorization.js +5 -5
- package/dist/session/device-authorization.js.map +1 -1
- package/dist/session/exchange.d.ts +10 -16
- package/dist/session/exchange.js +10 -16
- package/dist/session/exchange.js.map +1 -1
- package/dist/session/post-auth.js +2 -2
- package/dist/session/post-auth.js.map +1 -1
- package/dist/session/redirect-listener.js +1 -1
- package/dist/session/redirect-listener.js.map +1 -1
- package/dist/session/schema.d.ts +3 -2
- package/dist/session/schema.js +3 -2
- package/dist/session/schema.js.map +1 -1
- package/dist/session/scopes.d.ts +3 -3
- package/dist/session/scopes.js +3 -3
- package/dist/session/scopes.js.map +1 -1
- package/dist/session/store.d.ts +2 -2
- package/dist/session/store.js +2 -2
- package/dist/session/store.js.map +1 -1
- package/dist/session/token.d.ts +1 -1
- package/dist/session/token.js +1 -1
- package/dist/session/token.js.map +1 -1
- package/dist/session/validate.d.ts +4 -4
- package/dist/session/validate.js +4 -7
- package/dist/session/validate.js.map +1 -1
- package/dist/session.d.ts +10 -10
- package/dist/session.js +12 -12
- package/dist/session.js.map +1 -1
- package/dist/string.d.ts +2 -2
- package/dist/string.js +2 -2
- package/dist/string.js.map +1 -1
- package/dist/system.d.ts +6 -9
- package/dist/system.js +23 -23
- package/dist/system.js.map +1 -1
- package/dist/template.d.ts +3 -3
- package/dist/template.js +3 -3
- package/dist/template.js.map +1 -1
- package/dist/testing/fixtures/render-concurrent.d.ts +1 -0
- package/dist/testing/fixtures/render-concurrent.js +28 -0
- package/dist/testing/fixtures/render-concurrent.js.map +1 -0
- package/dist/testing/output.d.ts +1 -0
- package/dist/testing/output.js +1 -0
- package/dist/testing/output.js.map +1 -1
- package/dist/testing/store.d.ts +2 -2
- package/dist/testing/store.js +2 -2
- package/dist/testing/store.js.map +1 -1
- package/dist/testing/ui.d.ts +8 -0
- package/dist/testing/ui.js +17 -0
- package/dist/testing/ui.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/inquirer/input.d.ts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +17 -8
- package/dist/ui.js.map +1 -1
- package/dist/version.d.ts +3 -3
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +9 -2
- package/dist/api/graphql/functions/compile_module.d.ts +0 -15
- package/dist/api/graphql/functions/compile_module.js +0 -13
- package/dist/api/graphql/functions/compile_module.js.map +0 -1
- package/dist/api/graphql/functions/module_compilation_status.d.ts +0 -15
- package/dist/api/graphql/functions/module_compilation_status.js +0 -13
- package/dist/api/graphql/functions/module_compilation_status.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../../src/session/device-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import {clientId} from './identity.js'\nimport {exchangeDeviceCodeForAccessToken} from './exchange.js'\nimport {IdentityToken} from './schema.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {content, debug, info, token} from '../output.js'\nimport {Bug} from '../error.js'\n\nexport interface DeviceAuthorizationResponse {\n deviceCode: string\n userCode: string\n verificationUri: string\n expiresIn: number\n verificationUriComplete?: string\n interval?: number\n}\n\nconst DeviceAuthError = () => {\n return new Bug('Failed to start authorization process')\n}\n\n/**\n * Initiate a device authorization flow.\n * This will return a DeviceAuthorizationResponse containing the URL where user\n * should go to authorize the device without the need of a callback to the CLI.\n *\n * Also returns a `deviceCode` used for polling the token endpoint in the next step.\n *\n * @param scopes The scopes to request\n * @returns
|
|
1
|
+
{"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../../src/session/device-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import {clientId} from './identity.js'\nimport {exchangeDeviceCodeForAccessToken} from './exchange.js'\nimport {IdentityToken} from './schema.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {content, debug, info, token} from '../output.js'\nimport {Bug} from '../error.js'\n\nexport interface DeviceAuthorizationResponse {\n deviceCode: string\n userCode: string\n verificationUri: string\n expiresIn: number\n verificationUriComplete?: string\n interval?: number\n}\n\nconst DeviceAuthError = () => {\n return new Bug('Failed to start authorization process')\n}\n\n/**\n * Initiate a device authorization flow.\n * This will return a DeviceAuthorizationResponse containing the URL where user\n * should go to authorize the device without the need of a callback to the CLI.\n *\n * Also returns a `deviceCode` used for polling the token endpoint in the next step.\n *\n * @param scopes - The scopes to request\n * @returns An object with the device authorization response.\n */\nexport async function requestDeviceAuthorization(scopes: string[]): Promise<DeviceAuthorizationResponse> {\n const fqdn = await identityFqdn()\n const identityClientId = await clientId()\n const queryParams = {client_id: identityClientId, scope: scopes.join(' ')}\n const url = `https://${fqdn}/oauth/device_authorization`\n\n const response = await shopifyFetch(url, {\n method: 'POST',\n headers: {'Content-type': 'application/x-www-form-urlencoded'},\n body: convertRequestToParams(queryParams),\n })\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonResult: any = await response.json()\n\n debug(content`Received device authorization code: ${token.json(jsonResult)}`)\n if (!jsonResult.device_code || !jsonResult.verification_uri_complete) throw DeviceAuthError()\n\n info('\\nTo run this command, log in to Shopify Partners.')\n info(content`User verification code: ${jsonResult.user_code}`)\n info(content`👉 Open this link to start the auth process: ${token.green(jsonResult.verification_uri_complete)}`)\n\n return {\n deviceCode: jsonResult.device_code,\n userCode: jsonResult.user_code,\n verificationUri: jsonResult.verification_uri,\n expiresIn: jsonResult.expires_in,\n verificationUriComplete: jsonResult.verification_uri_complete,\n interval: jsonResult.interval,\n }\n}\n\n/**\n * Poll the Oauth token endpoint with the device code obtained from a DeviceAuthorizationResponse.\n * The endpoint will return `authorization_pending` until the user completes the auth flow in the browser.\n * Once the user completes the auth flow, the endpoint will return the identity token.\n *\n * Timeout for the polling is defined by the server and is around 600 seconds.\n *\n * @param code - The device code obtained after starting a device identity flow\n * @param interval - The interval to poll the token endpoint\n * @returns The identity token\n */\nexport async function pollForDeviceAuthorization(code: string, interval = 5): Promise<IdentityToken> {\n let currentIntervalInSeconds = interval\n\n return new Promise<IdentityToken>((resolve, reject) => {\n const onPoll = async () => {\n const result = await exchangeDeviceCodeForAccessToken(code)\n if (!result.isErr()) return resolve(result.value)\n\n const error = result.error ?? 'unknown_failure'\n\n debug(content`Polling for device authorization... status: ${error}`)\n switch (error) {\n case 'authorization_pending':\n return startPolling()\n case 'slow_down':\n currentIntervalInSeconds += 5\n return startPolling()\n case 'access_denied':\n case 'expired_token':\n case 'unknown_failure':\n return reject(result)\n }\n }\n\n const startPolling = () => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n setTimeout(onPoll, currentIntervalInSeconds * 1000)\n }\n\n startPolling()\n })\n}\n\nfunction convertRequestToParams(queryParams: {client_id: string; scope: string}): string {\n return Object.entries(queryParams)\n .map(([key, value]) => value && `${key}=${value}`)\n .filter((hasValue) => Boolean(hasValue))\n .join('&')\n}\n"]}
|
|
@@ -11,41 +11,35 @@ export interface ExchangeScopes {
|
|
|
11
11
|
/**
|
|
12
12
|
* Given a valid authorization code, request an identity access token.
|
|
13
13
|
* This token can then be used to get API specific tokens.
|
|
14
|
-
* @param codeData code and codeVerifier from the authorize endpoint
|
|
15
|
-
* @
|
|
16
|
-
* @param identityFqdn
|
|
17
|
-
* @returns {Promise<IdentityToken>} An instance with the identity access tokens.
|
|
14
|
+
* @param codeData - code and codeVerifier from the authorize endpoint
|
|
15
|
+
* @returns An instance with the identity access tokens.
|
|
18
16
|
*/
|
|
19
17
|
export declare function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken>;
|
|
20
18
|
/**
|
|
21
19
|
* Given an identity token, request an application token.
|
|
22
|
-
* @param
|
|
23
|
-
* @param store the store to use, only needed for admin API
|
|
24
|
-
* @
|
|
25
|
-
* @param identityFqdn
|
|
26
|
-
* @returns {Promise<ApplicationSchema>} An array with the application access tokens.
|
|
20
|
+
* @param identityToken - access token obtained in a previous step
|
|
21
|
+
* @param store - the store to use, only needed for admin API
|
|
22
|
+
* @returns An array with the application access tokens.
|
|
27
23
|
*/
|
|
28
24
|
export declare function exchangeAccessForApplicationTokens(identityToken: IdentityToken, scopes: ExchangeScopes, store?: string): Promise<{
|
|
29
25
|
[x: string]: ApplicationToken;
|
|
30
26
|
}>;
|
|
31
27
|
/**
|
|
32
28
|
* Given an expired access token, refresh it to get a new one.
|
|
33
|
-
* @param currentToken
|
|
34
|
-
* @returns
|
|
35
29
|
*/
|
|
36
30
|
export declare function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken>;
|
|
37
31
|
/**
|
|
38
32
|
* Given a custom CLI token passed as ENV variable, request a valid partners API token
|
|
39
33
|
* This token does not accept extra scopes, just the cli one.
|
|
40
|
-
* @param token
|
|
41
|
-
* @returns
|
|
34
|
+
* @param token - The CLI token passed as ENV variable
|
|
35
|
+
* @returns An instance with the application access tokens.
|
|
42
36
|
*/
|
|
43
37
|
export declare function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken>;
|
|
44
38
|
export declare type IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'expired_token' | 'slow_down' | 'unknown_failure';
|
|
45
39
|
/**
|
|
46
40
|
* Given a deviceCode obtained after starting a device identity flow, request an identity token.
|
|
47
|
-
* @param deviceCode The device code obtained after starting a device identity flow
|
|
48
|
-
* @param scopes The scopes to request
|
|
49
|
-
* @returns
|
|
41
|
+
* @param deviceCode - The device code obtained after starting a device identity flow
|
|
42
|
+
* @param scopes - The scopes to request
|
|
43
|
+
* @returns An instance with the identity access tokens.
|
|
50
44
|
*/
|
|
51
45
|
export declare function exchangeDeviceCodeForAccessToken(deviceCode: string): Promise<Result<IdentityToken, IdentityDeviceError>>;
|
package/dist/session/exchange.js
CHANGED
|
@@ -10,10 +10,8 @@ const InvalidIdentityError = () => new Abort('\nError validating auth session',
|
|
|
10
10
|
/**
|
|
11
11
|
* Given a valid authorization code, request an identity access token.
|
|
12
12
|
* This token can then be used to get API specific tokens.
|
|
13
|
-
* @param codeData code and codeVerifier from the authorize endpoint
|
|
14
|
-
* @
|
|
15
|
-
* @param identityFqdn
|
|
16
|
-
* @returns {Promise<IdentityToken>} An instance with the identity access tokens.
|
|
13
|
+
* @param codeData - code and codeVerifier from the authorize endpoint
|
|
14
|
+
* @returns An instance with the identity access tokens.
|
|
17
15
|
*/
|
|
18
16
|
export async function exchangeCodeForAccessToken(codeData) {
|
|
19
17
|
const clientId = await getIdentityClientId();
|
|
@@ -30,11 +28,9 @@ export async function exchangeCodeForAccessToken(codeData) {
|
|
|
30
28
|
}
|
|
31
29
|
/**
|
|
32
30
|
* Given an identity token, request an application token.
|
|
33
|
-
* @param
|
|
34
|
-
* @param store the store to use, only needed for admin API
|
|
35
|
-
* @
|
|
36
|
-
* @param identityFqdn
|
|
37
|
-
* @returns {Promise<ApplicationSchema>} An array with the application access tokens.
|
|
31
|
+
* @param identityToken - access token obtained in a previous step
|
|
32
|
+
* @param store - the store to use, only needed for admin API
|
|
33
|
+
* @returns An array with the application access tokens.
|
|
38
34
|
*/
|
|
39
35
|
export async function exchangeAccessForApplicationTokens(identityToken, scopes, store) {
|
|
40
36
|
const token = identityToken.accessToken;
|
|
@@ -52,8 +48,6 @@ export async function exchangeAccessForApplicationTokens(identityToken, scopes,
|
|
|
52
48
|
}
|
|
53
49
|
/**
|
|
54
50
|
* Given an expired access token, refresh it to get a new one.
|
|
55
|
-
* @param currentToken
|
|
56
|
-
* @returns
|
|
57
51
|
*/
|
|
58
52
|
export async function refreshAccessToken(currentToken) {
|
|
59
53
|
const clientId = await getIdentityClientId();
|
|
@@ -70,8 +64,8 @@ export async function refreshAccessToken(currentToken) {
|
|
|
70
64
|
/**
|
|
71
65
|
* Given a custom CLI token passed as ENV variable, request a valid partners API token
|
|
72
66
|
* This token does not accept extra scopes, just the cli one.
|
|
73
|
-
* @param token
|
|
74
|
-
* @returns
|
|
67
|
+
* @param token - The CLI token passed as ENV variable
|
|
68
|
+
* @returns An instance with the application access tokens.
|
|
75
69
|
*/
|
|
76
70
|
export async function exchangeCustomPartnerToken(token) {
|
|
77
71
|
const appId = applicationId('partners');
|
|
@@ -80,9 +74,9 @@ export async function exchangeCustomPartnerToken(token) {
|
|
|
80
74
|
}
|
|
81
75
|
/**
|
|
82
76
|
* Given a deviceCode obtained after starting a device identity flow, request an identity token.
|
|
83
|
-
* @param deviceCode The device code obtained after starting a device identity flow
|
|
84
|
-
* @param scopes The scopes to request
|
|
85
|
-
* @returns
|
|
77
|
+
* @param deviceCode - The device code obtained after starting a device identity flow
|
|
78
|
+
* @param scopes - The scopes to request
|
|
79
|
+
* @returns An instance with the identity access tokens.
|
|
86
80
|
*/
|
|
87
81
|
export async function exchangeDeviceCodeForAccessToken(deviceCode) {
|
|
88
82
|
const clientId = await getIdentityClientId();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/session/exchange.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAE,QAAQ,IAAI,mBAAmB,EAAC,MAAM,eAAe,CAAA;AAE5E,OAAO,KAAK,WAAW,MAAM,YAAY,CAAA;AACzC,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAC,QAAQ,IAAI,YAAY,EAAC,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,EAAC,GAAG,EAAE,EAAE,EAAS,MAAM,qBAAqB,CAAA;AAEnD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;CAAG;AAE/C,MAAM,oBAAoB,GAAG,GAAG,EAAE,CAChC,IAAI,KAAK,CAAC,iCAAiC,EAAE,qDAAqD,CAAC,CAAA;AAOrG;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,QAAwB;IACvE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,oBAAoB;QAChC,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,YAAY,EAAE,uBAAuB;QACrC,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE,QAAQ,CAAC,YAAY;KACrC,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,YAAY,EAAE,CAAA;IAC3E,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAA;AAClC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,aAA4B,EAC5B,MAAsB,EACtB,KAAc;IAEd,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,CAAA;IAEvC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC1E,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,qBAAqB,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;IAEzF,MAAM,MAAM,GAAG;QACb,GAAG,QAAQ;QACX,GAAG,UAAU;KACd,CAAA;IAED,IAAI,KAAK,EAAE;QACT,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QACxE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;KAC7B;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,YAA2B;IAClE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,YAAY,CAAC,WAAW;QACtC,aAAa,EAAE,YAAY,CAAC,YAAY;QACxC,SAAS,EAAE,QAAQ;KACpB,CAAA;IACD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,YAAY,EAAE,CAAA;IAC3E,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAA;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAa;IAC5D,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,sDAAsD,CAAC,CAAC,CAAA;IACnH,OAAO,QAAQ,CAAC,KAAK,CAAE,CAAA;AACzB,CAAC;AASD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,UAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAE5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,8CAA8C;QAC1D,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,QAAQ;KACpB,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE;QACvB,OAAO,GAAG,CAAC,WAAW,CAAC,KAA4B,CAAC,CAAA;KACrD;IACD,MAAM,aAAa,GAAG,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC3D,OAAO,EAAE,CAAC,aAAa,CAAC,CAAA;AAC1B,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,GAAQ,EACR,KAAa,EACb,SAAmB,EAAE,EACrB,KAAc;IAEd,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAE5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,iDAAiD;QAC7D,oBAAoB,EAAE,+CAA+C;QACrE,kBAAkB,EAAE,+CAA+C;QACnE,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,aAAa,EAAE,KAAK;QACpB,GAAG,CAAC,GAAG,KAAK,OAAO,IAAI,EAAC,WAAW,EAAE,WAAW,KAAK,QAAQ,EAAC,CAAC;KAChE,CAAA;IAED,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,GAAG,KAAK,OAAO,IAAI,KAAK,EAAE;QAC5B,UAAU,GAAG,GAAG,KAAK,IAAI,KAAK,EAAE,CAAA;KACjC;IACD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,YAAY,EAAE,CAAA;IAC3E,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAA;IACnD,OAAO,EAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAC,CAAA;AACjC,CAAC;AASD,KAAK,UAAU,wBAAwB,CAAC,KAAa;IACnD,IAAI,KAAK,KAAK,eAAe,EAAE;QAC7B,6FAA6F;QAC7F,oGAAoG;QACpG,OAAO,IAAI,iBAAiB,EAAE,CAAA;KAC/B;IACD,IAAI,KAAK,KAAK,iBAAiB,EAAE;QAC/B,iGAAiG;QACjG,mGAAmG;QACnG,MAAM,WAAW,CAAC,MAAM,EAAE,CAAA;QAC1B,OAAO,oBAAoB,EAAE,CAAA;KAC9B;IACD,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,MAA+B;IACzD,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,IAAI,cAAc,CAAC,CAAA;IAClD,GAAG,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACnE,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC,CAAA;IAC1D,8DAA8D;IAC9D,MAAM,OAAO,GAAQ,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;IAErC,IAAI,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC;AAED,SAAS,kBAAkB,CAAC,MAA0B;IACpD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,YAAY,EAAE,MAAM,CAAC,aAAa;QAClC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;KAChC,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAA0B;IACvD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;KAChC,CAAA;AACH,CAAC","sourcesContent":["import {ApplicationToken, IdentityToken} from './schema.js'\nimport {applicationId, clientId as getIdentityClientId} from './identity.js'\nimport {CodeAuthResult} from './authorize.js'\nimport * as secureStore from './store.js'\nimport {Abort} from '../error.js'\nimport {API} from '../network/api.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {err, ok, Result} from '../common/result.js'\n\nexport class InvalidGrantError extends Error {}\n\nconst InvalidIdentityError = () =>\n new Abort('\\nError validating auth session', \"We've cleared the current session, please try again\")\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n}\n/**\n * Given a valid authorization code, request an identity access token.\n * This token can then be used to get API specific tokens.\n * @param codeData code and codeVerifier from the authorize endpoint\n * @param clientId\n * @param identityFqdn\n * @returns {Promise<IdentityToken>} An instance with the identity access tokens.\n */\nexport async function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'authorization_code',\n code: codeData.code,\n redirect_uri: 'http://127.0.0.1:3456',\n client_id: clientId,\n code_verifier: codeData.codeVerifier,\n }\n\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrThrow()\n return buildIdentityToken(value)\n}\n\n/**\n * Given an identity token, request an application token.\n * @param token access token obtained in a previous step\n * @param store the store to use, only needed for admin API\n * @param clientId\n * @param identityFqdn\n * @returns {Promise<ApplicationSchema>} An array with the application access tokens.\n */\nexport async function exchangeAccessForApplicationTokens(\n identityToken: IdentityToken,\n scopes: ExchangeScopes,\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const token = identityToken.accessToken\n\n const partners = await requestAppToken('partners', token, scopes.partners)\n const storefront = await requestAppToken('storefront-renderer', token, scopes.storefront)\n\n const result = {\n ...partners,\n ...storefront,\n }\n\n if (store) {\n const admin = await requestAppToken('admin', token, scopes.admin, store)\n Object.assign(result, admin)\n }\n return result\n}\n\n/**\n * Given an expired access token, refresh it to get a new one.\n * @param currentToken\n * @returns\n */\nexport async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'refresh_token',\n access_token: currentToken.accessToken,\n refresh_token: currentToken.refreshToken,\n client_id: clientId,\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrThrow()\n return buildIdentityToken(value)\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid partners API token\n * This token does not accept extra scopes, just the cli one.\n * @param token {string} The CLI token passed as ENV variable\n * @returns {Promise<ApplicationToken>} An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken> {\n const appId = applicationId('partners')\n const newToken = await requestAppToken('partners', token, ['https://api.shopify.com/auth/partners.app.cli.access'])\n return newToken[appId]!\n}\n\nexport type IdentityDeviceError =\n | 'authorization_pending'\n | 'access_denied'\n | 'expired_token'\n | 'slow_down'\n | 'unknown_failure'\n\n/**\n * Given a deviceCode obtained after starting a device identity flow, request an identity token.\n * @param deviceCode The device code obtained after starting a device identity flow\n * @param scopes The scopes to request\n * @returns {Promise<IdentityToken>} An instance with the identity access tokens.\n */\nexport async function exchangeDeviceCodeForAccessToken(\n deviceCode: string,\n): Promise<Result<IdentityToken, IdentityDeviceError>> {\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }\n\n const tokenResult = await tokenRequest(params)\n if (tokenResult.isErr()) {\n return err(tokenResult.error as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nasync function requestAppToken(\n api: API,\n token: string,\n scopes: string[] = [],\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const appId = applicationId(api)\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n client_id: clientId,\n audience: appId,\n scope: scopes.join(' '),\n subject_token: token,\n ...(api === 'admin' && {destination: `https://${store}/admin`}),\n }\n\n let identifier = appId\n if (api === 'admin' && store) {\n identifier = `${store}-${appId}`\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrThrow()\n const appToken = await buildApplicationToken(value)\n return {[identifier]: appToken}\n}\n\ninterface TokenRequestResult {\n access_token: string\n expires_in: number\n refresh_token: string\n scope: string\n}\n\nasync function tokenRequestErrorHandler(error: string) {\n if (error === 'invalid_grant') {\n // There's an scenario when Identity returns \"invalid_grant\" when trying to refresh the token\n // using a valid refresh token. When that happens, we take the user through the authentication flow.\n return new InvalidGrantError()\n }\n if (error === 'invalid_request') {\n // There's an scenario when Identity returns \"invalid_request\" when exchanging an identity token.\n // This means the token is invalid. We clear the session and throw an error to let the caller know.\n await secureStore.remove()\n return InvalidIdentityError()\n }\n return new Abort(error)\n}\n\nasync function tokenRequest(params: {[key: string]: string}): Promise<Result<TokenRequestResult, string>> {\n const fqdn = await identityFqdn()\n const url = new URL(`https://${fqdn}/oauth/token`)\n url.search = new URLSearchParams(Object.entries(params)).toString()\n const res = await shopifyFetch(url.href, {method: 'POST'})\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const payload: any = await res.json()\n\n if (res.ok) return ok(payload)\n return err(payload.error)\n}\n\nfunction buildIdentityToken(result: TokenRequestResult): IdentityToken {\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n\nfunction buildApplicationToken(result: TokenRequestResult): ApplicationToken {\n return {\n accessToken: result.access_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../src/session/exchange.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApplicationToken, IdentityToken} from './schema.js'\nimport {applicationId, clientId as getIdentityClientId} from './identity.js'\nimport {CodeAuthResult} from './authorize.js'\nimport * as secureStore from './store.js'\nimport {Abort} from '../error.js'\nimport {API} from '../network/api.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {err, ok, Result} from '../common/result.js'\n\nexport class InvalidGrantError extends Error {}\n\nconst InvalidIdentityError = () =>\n new Abort('\\nError validating auth session', \"We've cleared the current session, please try again\")\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n}\n/**\n * Given a valid authorization code, request an identity access token.\n * This token can then be used to get API specific tokens.\n * @param codeData - code and codeVerifier from the authorize endpoint\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'authorization_code',\n code: codeData.code,\n redirect_uri: 'http://127.0.0.1:3456',\n client_id: clientId,\n code_verifier: codeData.codeVerifier,\n }\n\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrThrow()\n return buildIdentityToken(value)\n}\n\n/**\n * Given an identity token, request an application token.\n * @param identityToken - access token obtained in a previous step\n * @param store - the store to use, only needed for admin API\n * @returns An array with the application access tokens.\n */\nexport async function exchangeAccessForApplicationTokens(\n identityToken: IdentityToken,\n scopes: ExchangeScopes,\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const token = identityToken.accessToken\n\n const partners = await requestAppToken('partners', token, scopes.partners)\n const storefront = await requestAppToken('storefront-renderer', token, scopes.storefront)\n\n const result = {\n ...partners,\n ...storefront,\n }\n\n if (store) {\n const admin = await requestAppToken('admin', token, scopes.admin, store)\n Object.assign(result, admin)\n }\n return result\n}\n\n/**\n * Given an expired access token, refresh it to get a new one.\n */\nexport async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'refresh_token',\n access_token: currentToken.accessToken,\n refresh_token: currentToken.refreshToken,\n client_id: clientId,\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrThrow()\n return buildIdentityToken(value)\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid partners API token\n * This token does not accept extra scopes, just the cli one.\n * @param token - The CLI token passed as ENV variable\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken> {\n const appId = applicationId('partners')\n const newToken = await requestAppToken('partners', token, ['https://api.shopify.com/auth/partners.app.cli.access'])\n return newToken[appId]!\n}\n\nexport type IdentityDeviceError =\n | 'authorization_pending'\n | 'access_denied'\n | 'expired_token'\n | 'slow_down'\n | 'unknown_failure'\n\n/**\n * Given a deviceCode obtained after starting a device identity flow, request an identity token.\n * @param deviceCode - The device code obtained after starting a device identity flow\n * @param scopes - The scopes to request\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeDeviceCodeForAccessToken(\n deviceCode: string,\n): Promise<Result<IdentityToken, IdentityDeviceError>> {\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }\n\n const tokenResult = await tokenRequest(params)\n if (tokenResult.isErr()) {\n return err(tokenResult.error as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nasync function requestAppToken(\n api: API,\n token: string,\n scopes: string[] = [],\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const appId = applicationId(api)\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n client_id: clientId,\n audience: appId,\n scope: scopes.join(' '),\n subject_token: token,\n ...(api === 'admin' && {destination: `https://${store}/admin`}),\n }\n\n let identifier = appId\n if (api === 'admin' && store) {\n identifier = `${store}-${appId}`\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrThrow()\n const appToken = await buildApplicationToken(value)\n return {[identifier]: appToken}\n}\n\ninterface TokenRequestResult {\n access_token: string\n expires_in: number\n refresh_token: string\n scope: string\n}\n\nasync function tokenRequestErrorHandler(error: string) {\n if (error === 'invalid_grant') {\n // There's an scenario when Identity returns \"invalid_grant\" when trying to refresh the token\n // using a valid refresh token. When that happens, we take the user through the authentication flow.\n return new InvalidGrantError()\n }\n if (error === 'invalid_request') {\n // There's an scenario when Identity returns \"invalid_request\" when exchanging an identity token.\n // This means the token is invalid. We clear the session and throw an error to let the caller know.\n await secureStore.remove()\n return InvalidIdentityError()\n }\n return new Abort(error)\n}\n\nasync function tokenRequest(params: {[key: string]: string}): Promise<Result<TokenRequestResult, string>> {\n const fqdn = await identityFqdn()\n const url = new URL(`https://${fqdn}/oauth/token`)\n url.search = new URLSearchParams(Object.entries(params)).toString()\n const res = await shopifyFetch(url.href, {method: 'POST'})\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const payload: any = await res.json()\n\n if (res.ok) return ok(payload)\n return err(payload.error)\n}\n\nfunction buildIdentityToken(result: TokenRequestResult): IdentityToken {\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n\nfunction buildApplicationToken(result: TokenRequestResult): ApplicationToken {\n return {\n accessToken: result.access_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n"]}
|
|
@@ -13,8 +13,8 @@ const FaviconFileName = 'favicon.svg';
|
|
|
13
13
|
/**
|
|
14
14
|
* Finds the full path of the given file-name from the assets folder.
|
|
15
15
|
*
|
|
16
|
-
* @param
|
|
17
|
-
* @returns
|
|
16
|
+
* @param fileName - The name of the file to look for.
|
|
17
|
+
* @returns The full path of the file, or null if not found.
|
|
18
18
|
*/
|
|
19
19
|
const getFilePath = async (fileName) => {
|
|
20
20
|
const filePath = await findUp(`assets/${fileName}`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-auth.js","sourceRoot":"","sources":["../../src/session/post-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,eAAe,EAAC,MAAM,YAAY,CAAA;AAClD,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAA;AAC/B,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA;AAE/B,MAAM,aAAa,GAAG;IACpB,gBAAgB;IAChB,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;IACpB,cAAc;CACN,CAAA;AACV,MAAM,kBAAkB,GAAG,WAAW,CAAA;AACtC,MAAM,eAAe,GAAG,aAAa,CAAA;AAErC;;;;;GAKG;AACH,MAAM,WAAW,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;IAC9D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,QAAQ,EAAE,EAAE;QAClD,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KACtC,CAAC,CAAA;IACF,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,8BAA8B,EAAE,CAAA;KACvC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,IAAqB,EAAE;IACzD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAqB,EAAE;IAC1D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAqB,EAAE;IAC5D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,IAAqB,EAAE;IAC7D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,IAAqB,EAAE;IACxD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAqB,EAAE;IACvD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,CAAA;IACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,IAAqB,EAAE;IACpD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,CAAA;IACnD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,+DAA+D,CAAA;AAE7F,MAAM,CAAC,MAAM,eAAe,GAAG,kDAAkD,CAAA;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAAG,kFAAkF,CAAA;AAEnH,MAAM,CAAC,MAAM,kBAAkB,GAAG,mFAAmF,CAAA;AAErH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,+BAA+B,CAAC,CAAA","sourcesContent":["import {findUp, moduleDirectory} from '../path.js'\nimport {read} from '../file.js'\nimport {Bug} from '../error.js'\n\nconst HTMLFileNames = [\n 'empty-url.html',\n 'auth-error.html',\n 'missing-code.html',\n 'missing-state.html',\n 'success.html',\n] as const\nconst StylesheetFilename = 'style.css'\nconst FaviconFileName = 'favicon.svg'\n\n/**\n * Finds the full path of the given file-name from the assets folder.\n *\n * @param
|
|
1
|
+
{"version":3,"file":"post-auth.js","sourceRoot":"","sources":["../../src/session/post-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,eAAe,EAAC,MAAM,YAAY,CAAA;AAClD,OAAO,EAAC,IAAI,EAAC,MAAM,YAAY,CAAA;AAC/B,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA;AAE/B,MAAM,aAAa,GAAG;IACpB,gBAAgB;IAChB,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;IACpB,cAAc;CACN,CAAA;AACV,MAAM,kBAAkB,GAAG,WAAW,CAAA;AACtC,MAAM,eAAe,GAAG,aAAa,CAAA;AAErC;;;;;GAKG;AACH,MAAM,WAAW,GAAG,KAAK,EAAE,QAAgB,EAAmB,EAAE;IAC9D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,QAAQ,EAAE,EAAE;QAClD,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KACtC,CAAC,CAAA;IACF,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,8BAA8B,EAAE,CAAA;KACvC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,IAAqB,EAAE;IACzD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAqB,EAAE;IAC1D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAqB,EAAE;IAC5D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,IAAqB,EAAE;IAC7D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,IAAqB,EAAE;IACxD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAqB,EAAE;IACvD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,CAAA;IACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,IAAqB,EAAE;IACpD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,CAAA;IACnD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,+DAA+D,CAAA;AAE7F,MAAM,CAAC,MAAM,eAAe,GAAG,kDAAkD,CAAA;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAAG,kFAAkF,CAAA;AAEnH,MAAM,CAAC,MAAM,kBAAkB,GAAG,mFAAmF,CAAA;AAErH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,+BAA+B,CAAC,CAAA","sourcesContent":["import {findUp, moduleDirectory} from '../path.js'\nimport {read} from '../file.js'\nimport {Bug} from '../error.js'\n\nconst HTMLFileNames = [\n 'empty-url.html',\n 'auth-error.html',\n 'missing-code.html',\n 'missing-state.html',\n 'success.html',\n] as const\nconst StylesheetFilename = 'style.css'\nconst FaviconFileName = 'favicon.svg'\n\n/**\n * Finds the full path of the given file-name from the assets folder.\n *\n * @param fileName - The name of the file to look for.\n * @returns The full path of the file, or null if not found.\n */\nconst getFilePath = async (fileName: string): Promise<string> => {\n const filePath = await findUp(`assets/${fileName}`, {\n type: 'file',\n cwd: moduleDirectory(import.meta.url),\n })\n if (!filePath) {\n throw RedirectPageAssetNotFoundError()\n }\n return filePath\n}\n\nexport const getEmptyUrlHTML = async (): Promise<string> => {\n const filePath = await getFilePath(HTMLFileNames[0])\n return read(filePath)\n}\n\nexport const getAuthErrorHTML = async (): Promise<string> => {\n const filePath = await getFilePath(HTMLFileNames[1])\n return read(filePath)\n}\n\nexport const getMissingCodeHTML = async (): Promise<string> => {\n const filePath = await getFilePath(HTMLFileNames[2])\n return read(filePath)\n}\n\nexport const getMissingStateHTML = async (): Promise<string> => {\n const filePath = await getFilePath(HTMLFileNames[3])\n return read(filePath)\n}\n\nexport const getSuccessHTML = async (): Promise<string> => {\n const filePath = await getFilePath(HTMLFileNames[4])\n return read(filePath)\n}\n\nexport const getStylesheet = async (): Promise<string> => {\n const filePath = await getFilePath(StylesheetFilename)\n return read(filePath)\n}\n\nexport const getFavicon = async (): Promise<string> => {\n const filePath = await getFilePath(FaviconFileName)\n return read(filePath)\n}\n\nexport const EmptyUrlString = 'We received the authentication redirect but the URL is empty.'\n\nexport const AuthErrorString = 'There was an issue while trying to authenticate.'\n\nexport const MissingCodeString = \"The authentication can't continue because the redirect doesn't include the code.\"\n\nexport const MissingStateString = \"The authentication can't continue because the redirect doesn't include the state.\"\n\nexport const RedirectPageAssetNotFoundError = () => new Bug(`Redirect page asset not found`)\n"]}
|
|
@@ -22,7 +22,7 @@ export class RedirectListener {
|
|
|
22
22
|
static createServer(callback) {
|
|
23
23
|
const app = createApp().use('*', async (request, response) => {
|
|
24
24
|
const requestUrl = request.url;
|
|
25
|
-
if (requestUrl
|
|
25
|
+
if (requestUrl?.includes('favicon')) {
|
|
26
26
|
const faviconFile = await getFavicon();
|
|
27
27
|
response.setHeader('Content-Type', 'image/svg+xml').write(faviconFile);
|
|
28
28
|
response.end();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redirect-listener.js","sourceRoot":"","sources":["../../src/session/redirect-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAC,KAAK,EAAE,GAAG,EAAC,MAAM,aAAa,CAAA;AACtC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AACjD,OAAO,EAAC,SAAS,EAAkC,MAAM,IAAI,CAAA;AAC7D,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAC,YAAY,EAAS,MAAM,MAAM,CAAA;AAEzC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AACjC,MAAM,sBAAsB,GAAG,GAAG,CAAA;AAgBlC;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IAgE3B,YAAY,OAAgC;QAC1C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/D,CAAC;IAnEO,MAAM,CAAC,YAAY,CAAC,QAA0B;QACpD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAwB,EAAE,QAAwB,EAAE,EAAE;YAC5F,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAA;YAC9B,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"redirect-listener.js","sourceRoot":"","sources":["../../src/session/redirect-listener.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getFavicon,\n getStylesheet,\n getEmptyUrlHTML,\n getAuthErrorHTML,\n getMissingCodeHTML,\n getMissingStateHTML,\n getSuccessHTML,\n EmptyUrlString,\n MissingCodeString,\n MissingStateString,\n} from './post-auth.js'\nimport {Abort, Bug} from '../error.js'\nimport {content, info, token} from '../output.js'\nimport {createApp, IncomingMessage, ServerResponse} from 'h3'\nimport url from 'url'\nimport {createServer, Server} from 'http'\n\nconst ResponseTimeoutSeconds = 10\nconst ServerStopDelaySeconds = 0.5\n\n/**\n * It represents the result of a redirect.\n */\ntype RedirectCallback = (error: Error | undefined, state: string | undefined, code: string | undefined) => void\n\n/**\n * Defines the interface of the options that\n * are used to instantiate a redirect listener.\n */\ninterface RedirectListenerOptions {\n host: string\n port: number\n callback: RedirectCallback\n}\n/**\n * When the authentication completes, Identity redirects\n * the user to a URL. In the case of the CLI, the redirect\n * is to localhost passing some parameters that are necessary\n * to continue the authentication. Because of that, we need\n * an HTTP server that runs and listens to the request.\n */\nexport class RedirectListener {\n private static createServer(callback: RedirectCallback): Server {\n const app = createApp().use('*', async (request: IncomingMessage, response: ServerResponse) => {\n const requestUrl = request.url\n if (requestUrl?.includes('favicon')) {\n const faviconFile = await getFavicon()\n response.setHeader('Content-Type', 'image/svg+xml').write(faviconFile)\n response.end()\n return {}\n } else if (requestUrl === '/style.css') {\n const stylesheetFile = await getStylesheet()\n response.setHeader('Content-Type', 'text/css').write(stylesheetFile)\n response.end()\n return {}\n }\n\n const respond = async (contents: string, error?: Error, state?: string, code?: string) => {\n response.setHeader('Content-Type', 'text/html').write(contents)\n response.end()\n callback(error, state, code)\n return {}\n }\n\n // If there was an empty/malformed URL sent back.\n if (!requestUrl) {\n const file = await getEmptyUrlHTML()\n const err = new Bug(EmptyUrlString)\n return respond(file, err, undefined, undefined)\n }\n\n // If an error was returned by the Identity server.\n const queryObject = url.parse(requestUrl, true).query\n if (queryObject.error && queryObject.error_description) {\n const file = await getAuthErrorHTML()\n const err = new Abort(`${queryObject.error_description}`)\n return respond(file, err, undefined, undefined)\n }\n\n // If the code isn't present in the URL.\n if (!queryObject.code) {\n const file = await getMissingCodeHTML()\n const err = new Bug(MissingCodeString)\n return respond(file, err, undefined, undefined)\n }\n\n // If the state isn't present in the URL.\n if (!queryObject.state) {\n const file = await getMissingStateHTML()\n const err = new Bug(MissingStateString)\n return respond(file, err, undefined, undefined)\n }\n\n const file = await getSuccessHTML()\n return respond(file, undefined, `${queryObject.code}`, `${queryObject.state}`)\n })\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n return createServer(app)\n }\n\n port: number\n host: string\n server: ReturnType<typeof RedirectListener.createServer>\n\n constructor(options: RedirectListenerOptions) {\n this.port = options.port\n this.host = options.host\n this.server = RedirectListener.createServer(options.callback)\n }\n\n start(): void {\n this.server.listen({port: this.port, host: this.host}, () => {})\n }\n\n async stop(): Promise<void> {\n await this.server.close()\n }\n}\n\nexport async function listenRedirect(host: string, port: number, url: string): Promise<{code: string; state: string}> {\n const result = await new Promise<{code: string; state: string}>((resolve, reject) => {\n const timeout = setTimeout(() => {\n const message = '\\nAuto-open timed out. Open the login page: '\n info(content`${message}${token.link('Log in to Shopify Partners', url)}\\n`)\n }, ResponseTimeoutSeconds * 1000)\n\n const callback: RedirectCallback = (error, code, state) => {\n clearTimeout(timeout)\n setTimeout(() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n redirectListener.stop()\n if (error) reject(error)\n else resolve({code: code as string, state: state as string})\n }, ServerStopDelaySeconds * 1000)\n }\n\n const redirectListener = new RedirectListener({host, port, callback})\n redirectListener.start()\n })\n return result\n}\n"]}
|
package/dist/session/schema.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ declare const ApplicationTokenSchema: define.ZodObject<{
|
|
|
40
40
|
* token exchanges.
|
|
41
41
|
*
|
|
42
42
|
* @example
|
|
43
|
+
* ```
|
|
43
44
|
* {
|
|
44
45
|
* "accounts.shopify.com": {
|
|
45
46
|
* "identity": {...} // IdentityTokenSchema
|
|
@@ -53,8 +54,8 @@ declare const ApplicationTokenSchema: define.ZodObject<{
|
|
|
53
54
|
* }
|
|
54
55
|
* },
|
|
55
56
|
* "identity.spin.com": {...}
|
|
56
|
-
*}
|
|
57
|
-
*
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
58
59
|
*/
|
|
59
60
|
export declare const SessionSchema: define.ZodObject<{}, "strip", define.ZodObject<{
|
|
60
61
|
/**
|
package/dist/session/schema.js
CHANGED
|
@@ -27,6 +27,7 @@ const ApplicationTokenSchema = define.object({
|
|
|
27
27
|
* token exchanges.
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
|
+
* ```
|
|
30
31
|
* {
|
|
31
32
|
* "accounts.shopify.com": {
|
|
32
33
|
* "identity": {...} // IdentityTokenSchema
|
|
@@ -40,8 +41,8 @@ const ApplicationTokenSchema = define.object({
|
|
|
40
41
|
* }
|
|
41
42
|
* },
|
|
42
43
|
* "identity.spin.com": {...}
|
|
43
|
-
*}
|
|
44
|
-
*
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
45
46
|
*/
|
|
46
47
|
export const SessionSchema = define.object({}).catchall(define.object({
|
|
47
48
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/session/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAA;AAEnC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE;IAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,YAAY,IAAI;QAAE,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;IACxE,OAAO,IAAI,CAAA;AACb,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;AAEjB;;GAEG;AACH,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;IAC7B,SAAS,EAAE,UAAU;IACrB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;CACtC,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5B,SAAS,EAAE,UAAU;IACrB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;CACtC,CAAC,CAAA;AAEF
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/session/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAA;AAEnC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE;IAC3C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,YAAY,IAAI;QAAE,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;IACxE,OAAO,IAAI,CAAA;AACb,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;AAEjB;;GAEG;AACH,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;IAC7B,SAAS,EAAE,UAAU;IACrB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;CACtC,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5B,SAAS,EAAE,UAAU;IACrB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;CACtC,CAAC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CACrD,MAAM,CAAC,MAAM,CAAC;IACZ;;;;OAIG;IACH,QAAQ,EAAE,mBAAmB;IAC7B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;CACjE,CAAC,CACH,CAAA","sourcesContent":["import {define} from '../schema.js'\n\nconst DateSchema = define.preprocess((arg) => {\n if (typeof arg === 'string' || arg instanceof Date) return new Date(arg)\n return null\n}, define.date())\n\n/**\n * The schema represents an Identity token.\n */\nconst IdentityTokenSchema = define.object({\n accessToken: define.string(),\n refreshToken: define.string(),\n expiresAt: DateSchema,\n scopes: define.array(define.string()),\n})\n\n/**\n * The schema represents an application token.\n */\nconst ApplicationTokenSchema = define.object({\n accessToken: define.string(),\n expiresAt: DateSchema,\n scopes: define.array(define.string()),\n})\n\n/**\n * This schema represents the format of the session\n * that we cache in the system to avoid unnecessary\n * token exchanges.\n *\n * @example\n * ```\n * {\n * \"accounts.shopify.com\": {\n * \"identity\": {...} // IdentityTokenSchema\n * \"applications\": {\n * \"${domain}-application-id\": { // Admin APIs includes domain in the key\n * \"accessToken\": \"...\",\n * },\n * \"$application-id\": { // ApplicationTokenSchema\n * \"accessToken\": \"...\",\n * },\n * }\n * },\n * \"identity.spin.com\": {...}\n * }\n * ```\n */\nexport const SessionSchema = define.object({}).catchall(\n define.object({\n /**\n * It contains the identity token. Before usint it, we exchange it\n * to get a token that we can use with different applications. The exchanged\n * tokens for the applications are stored under applications.\n */\n identity: IdentityTokenSchema,\n /**\n * It contains exchanged tokens for the applications the CLI\n * authenticates with. Tokens are scoped under the fqdn of the applications.\n */\n applications: define.object({}).catchall(ApplicationTokenSchema),\n }),\n)\n\nexport type Session = define.infer<typeof SessionSchema>\nexport type IdentityToken = define.infer<typeof IdentityTokenSchema>\nexport type ApplicationToken = define.infer<typeof ApplicationTokenSchema>\n"]}
|
package/dist/session/scopes.d.ts
CHANGED
|
@@ -2,15 +2,15 @@ import { API } from '../network/api.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Generate a flat array with all the default scopes for all the APIs plus
|
|
4
4
|
* any custom scope defined by the user.
|
|
5
|
-
* @param extraScopes custom user-defined scopes
|
|
5
|
+
* @param extraScopes - custom user-defined scopes
|
|
6
6
|
* @returns Array of scopes
|
|
7
7
|
*/
|
|
8
8
|
export declare function allDefaultScopes(extraScopes?: string[]): string[];
|
|
9
9
|
/**
|
|
10
10
|
* Generate a flat array with the default scopes for the given API plus
|
|
11
11
|
* any custom scope defined by the user
|
|
12
|
-
* @param api API to get the scopes for
|
|
13
|
-
* @param extraScopes custom user-defined scopes
|
|
12
|
+
* @param api - API to get the scopes for
|
|
13
|
+
* @param extraScopes - custom user-defined scopes
|
|
14
14
|
* @returns Array of scopes
|
|
15
15
|
*/
|
|
16
16
|
export declare function apiScopes(api: API, extraScopes?: string[]): string[];
|
package/dist/session/scopes.js
CHANGED
|
@@ -3,7 +3,7 @@ import { allAPIs } from '../network/api.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Generate a flat array with all the default scopes for all the APIs plus
|
|
5
5
|
* any custom scope defined by the user.
|
|
6
|
-
* @param extraScopes custom user-defined scopes
|
|
6
|
+
* @param extraScopes - custom user-defined scopes
|
|
7
7
|
* @returns Array of scopes
|
|
8
8
|
*/
|
|
9
9
|
export function allDefaultScopes(extraScopes = []) {
|
|
@@ -14,8 +14,8 @@ export function allDefaultScopes(extraScopes = []) {
|
|
|
14
14
|
/**
|
|
15
15
|
* Generate a flat array with the default scopes for the given API plus
|
|
16
16
|
* any custom scope defined by the user
|
|
17
|
-
* @param api API to get the scopes for
|
|
18
|
-
* @param extraScopes custom user-defined scopes
|
|
17
|
+
* @param api - API to get the scopes for
|
|
18
|
+
* @param extraScopes - custom user-defined scopes
|
|
19
19
|
* @returns Array of scopes
|
|
20
20
|
*/
|
|
21
21
|
export function apiScopes(api, extraScopes = []) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/session/scopes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA;AAC/B,OAAO,EAAC,OAAO,EAAM,MAAM,mBAAmB,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,cAAwB,EAAE;IACzD,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAA;IACjD,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAClE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAQ,EAAE,cAAwB,EAAE;IAC5D,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAC3G,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAQ;IAChC,QAAQ,GAAG,EAAE;QACX,KAAK,OAAO;YACV,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC9C,KAAK,qBAAqB;YACxB,OAAO,CAAC,UAAU,CAAC,CAAA;QACrB,KAAK,UAAU;YACb,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB;YACE,MAAM,IAAI,GAAG,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAA;KACvC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,QAAQ,KAAK,EAAE;QACb,KAAK,SAAS;YACZ,OAAO,iDAAiD,CAAA;QAC1D,KAAK,QAAQ;YACX,OAAO,gDAAgD,CAAA;QACzD,KAAK,cAAc;YACjB,OAAO,2EAA2E,CAAA;QACpF,KAAK,KAAK;YACR,OAAO,sDAAsD,CAAA;QAC/D,KAAK,UAAU;YACb,OAAO,gEAAgE,CAAA;QACzE;YACE,OAAO,KAAK,CAAA;KACf;AACH,CAAC","sourcesContent":["import {Bug} from '../error.js'\nimport {allAPIs, API} from '../network/api.js'\n\n/**\n * Generate a flat array with all the default scopes for all the APIs plus\n * any custom scope defined by the user.\n * @param extraScopes custom user-defined scopes\n * @returns Array of scopes\n */\nexport function allDefaultScopes(extraScopes: string[] = []): string[] {\n let scopes = allAPIs.map(defaultApiScopes).flat()\n scopes = ['openid', ...scopes, ...extraScopes].map(scopeTransform)\n return Array.from(new Set(scopes))\n}\n\n/**\n * Generate a flat array with the default scopes for the given API plus\n * any custom scope defined by the user\n * @param api API to get the scopes for\n * @param extraScopes custom user-defined scopes\n * @returns Array of scopes\n */\nexport function apiScopes(api: API, extraScopes: string[] = []): string[] {\n const scopes = ['openid', ...defaultApiScopes(api), ...extraScopes.map(scopeTransform)].map(scopeTransform)\n return Array.from(new Set(scopes))\n}\n\nfunction defaultApiScopes(api: API): string[] {\n switch (api) {\n case 'admin':\n return ['graphql', 'themes', 'collaborator']\n case 'storefront-renderer':\n return ['devtools']\n case 'partners':\n return ['cli']\n default:\n throw new Bug(`Unknown API: ${api}`)\n }\n}\n\nfunction scopeTransform(scope: string): string {\n switch (scope) {\n case 'graphql':\n return 'https://api.shopify.com/auth/shop.admin.graphql'\n case 'themes':\n return 'https://api.shopify.com/auth/shop.admin.themes'\n case 'collaborator':\n return 'https://api.shopify.com/auth/partners.collaborator-relationships.readonly'\n case 'cli':\n return 'https://api.shopify.com/auth/partners.app.cli.access'\n case 'devtools':\n return 'https://api.shopify.com/auth/shop.storefront-renderer.devtools'\n default:\n return scope\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/session/scopes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA;AAC/B,OAAO,EAAC,OAAO,EAAM,MAAM,mBAAmB,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,cAAwB,EAAE;IACzD,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAA;IACjD,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAClE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAQ,EAAE,cAAwB,EAAE;IAC5D,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAC3G,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAQ;IAChC,QAAQ,GAAG,EAAE;QACX,KAAK,OAAO;YACV,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC9C,KAAK,qBAAqB;YACxB,OAAO,CAAC,UAAU,CAAC,CAAA;QACrB,KAAK,UAAU;YACb,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB;YACE,MAAM,IAAI,GAAG,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAA;KACvC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,QAAQ,KAAK,EAAE;QACb,KAAK,SAAS;YACZ,OAAO,iDAAiD,CAAA;QAC1D,KAAK,QAAQ;YACX,OAAO,gDAAgD,CAAA;QACzD,KAAK,cAAc;YACjB,OAAO,2EAA2E,CAAA;QACpF,KAAK,KAAK;YACR,OAAO,sDAAsD,CAAA;QAC/D,KAAK,UAAU;YACb,OAAO,gEAAgE,CAAA;QACzE;YACE,OAAO,KAAK,CAAA;KACf;AACH,CAAC","sourcesContent":["import {Bug} from '../error.js'\nimport {allAPIs, API} from '../network/api.js'\n\n/**\n * Generate a flat array with all the default scopes for all the APIs plus\n * any custom scope defined by the user.\n * @param extraScopes - custom user-defined scopes\n * @returns Array of scopes\n */\nexport function allDefaultScopes(extraScopes: string[] = []): string[] {\n let scopes = allAPIs.map(defaultApiScopes).flat()\n scopes = ['openid', ...scopes, ...extraScopes].map(scopeTransform)\n return Array.from(new Set(scopes))\n}\n\n/**\n * Generate a flat array with the default scopes for the given API plus\n * any custom scope defined by the user\n * @param api - API to get the scopes for\n * @param extraScopes - custom user-defined scopes\n * @returns Array of scopes\n */\nexport function apiScopes(api: API, extraScopes: string[] = []): string[] {\n const scopes = ['openid', ...defaultApiScopes(api), ...extraScopes.map(scopeTransform)].map(scopeTransform)\n return Array.from(new Set(scopes))\n}\n\nfunction defaultApiScopes(api: API): string[] {\n switch (api) {\n case 'admin':\n return ['graphql', 'themes', 'collaborator']\n case 'storefront-renderer':\n return ['devtools']\n case 'partners':\n return ['cli']\n default:\n throw new Bug(`Unknown API: ${api}`)\n }\n}\n\nfunction scopeTransform(scope: string): string {\n switch (scope) {\n case 'graphql':\n return 'https://api.shopify.com/auth/shop.admin.graphql'\n case 'themes':\n return 'https://api.shopify.com/auth/shop.admin.themes'\n case 'collaborator':\n return 'https://api.shopify.com/auth/partners.collaborator-relationships.readonly'\n case 'cli':\n return 'https://api.shopify.com/auth/partners.app.cli.access'\n case 'devtools':\n return 'https://api.shopify.com/auth/shop.storefront-renderer.devtools'\n default:\n return scope\n }\n}\n"]}
|
package/dist/session/store.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const identifier = "session";
|
|
|
6
6
|
/**
|
|
7
7
|
* Serializes the session as a JSON and stores it securely in the system.
|
|
8
8
|
* If the secure store is not available, the session is stored in the local config.
|
|
9
|
-
* @param session
|
|
9
|
+
* @param session - the session to store.
|
|
10
10
|
*/
|
|
11
11
|
export declare function store(session: Session): Promise<void>;
|
|
12
12
|
/**
|
|
@@ -15,7 +15,7 @@ export declare function store(session: Session): Promise<void>;
|
|
|
15
15
|
* If the format of the session is invalid, the method will discard it.
|
|
16
16
|
* In the future might add some logic for supporting migrating the schema
|
|
17
17
|
* of already-persisted sessions.
|
|
18
|
-
* @returns
|
|
18
|
+
* @returns Returns a promise that resolves with the session if it exists and is valid.
|
|
19
19
|
*/
|
|
20
20
|
export declare function fetch(): Promise<Session | undefined>;
|
|
21
21
|
/**
|
package/dist/session/store.js
CHANGED
|
@@ -11,7 +11,7 @@ export const identifier = 'session';
|
|
|
11
11
|
/**
|
|
12
12
|
* Serializes the session as a JSON and stores it securely in the system.
|
|
13
13
|
* If the secure store is not available, the session is stored in the local config.
|
|
14
|
-
* @param session
|
|
14
|
+
* @param session - the session to store.
|
|
15
15
|
*/
|
|
16
16
|
export async function store(session) {
|
|
17
17
|
const jsonSession = JSON.stringify(session);
|
|
@@ -28,7 +28,7 @@ export async function store(session) {
|
|
|
28
28
|
* If the format of the session is invalid, the method will discard it.
|
|
29
29
|
* In the future might add some logic for supporting migrating the schema
|
|
30
30
|
* of already-persisted sessions.
|
|
31
|
-
* @returns
|
|
31
|
+
* @returns Returns a promise that resolves with the session if it exists and is valid.
|
|
32
32
|
*/
|
|
33
33
|
export async function fetch() {
|
|
34
34
|
let content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AACxC,OAAO,EAAC,KAAK,IAAI,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAA;AACrG,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAC,MAAM,aAAa,CAAA;AAGlF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAA;AAEnC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAgB;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAC3C,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC3C;SAAM;QACL,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;KAC9B;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,IAAI,OAAO,CAAA;IACX,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,OAAO,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAA;KACxC;SAAM;QACL,OAAO,GAAG,MAAM,UAAU,EAAE,CAAA;KAC7B;IAED,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAA;KACjB;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,aAAa,CAAC,OAAO,EAAE;QACzB,OAAO,aAAa,CAAC,IAAI,CAAA;KAC1B;SAAM;QACL,MAAM,MAAM,EAAE,CAAA;QACd,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;KAC/B;SAAM;QACL,MAAM,aAAa,EAAE,CAAA;KACtB;IAED,MAAM,eAAe,EAAE,CAAA;AACzB,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,oBAAoB;IACjC,IAAI;QACF,IAAI,eAAe,EAAE,CAAC,QAAQ,KAAK,SAAS,EAAE;YAC5C,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;YACrD,OAAO,KAAK,CAAA;SACb;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;QACrC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAChE,KAAK,CAAC,OAAO,CAAA,2BAA2B,CAAC,CAAA;QACzC,OAAO,IAAI,CAAA;QACX,qDAAqD;KACtD;IAAC,OAAO,MAAM,EAAE;QACf,KAAK,CAAC,OAAO,CAAA,6BAA6B,CAAC,CAAA;QAC3C,OAAO,KAAK,CAAA;KACb;AACH,CAAC","sourcesContent":["import {SessionSchema} from './schema.js'\nimport constants from '../constants.js'\nimport {platformAndArch} from '../os.js'\nimport {store as secureStore, fetch as secureFetch, remove as secureRemove} from '../secure-store.js'\nimport {content, debug} from '../output.js'\nimport {getSession, removeSession, setSession, clearAllAppInfo} from '../store.js'\nimport type {Session} from './schema.js'\n\n/**\n * The identifier of the session in the secure store.\n */\nexport const identifier = 'session'\n\n/**\n * Serializes the session as a JSON and stores it securely in the system.\n * If the secure store is not available, the session is stored in the local config.\n * @param session
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AACxC,OAAO,EAAC,KAAK,IAAI,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAA;AACrG,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAC,MAAM,aAAa,CAAA;AAGlF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAA;AAEnC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAgB;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAC3C,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC3C;SAAM;QACL,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;KAC9B;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,IAAI,OAAO,CAAA;IACX,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,OAAO,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAA;KACxC;SAAM;QACL,OAAO,GAAG,MAAM,UAAU,EAAE,CAAA;KAC7B;IAED,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAA;KACjB;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,aAAa,CAAC,OAAO,EAAE;QACzB,OAAO,aAAa,CAAC,IAAI,CAAA;KAC1B;SAAM;QACL,MAAM,MAAM,EAAE,CAAA;QACd,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;KAC/B;SAAM;QACL,MAAM,aAAa,EAAE,CAAA;KACtB;IAED,MAAM,eAAe,EAAE,CAAA;AACzB,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,oBAAoB;IACjC,IAAI;QACF,IAAI,eAAe,EAAE,CAAC,QAAQ,KAAK,SAAS,EAAE;YAC5C,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;YACrD,OAAO,KAAK,CAAA;SACb;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;QACrC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAChE,KAAK,CAAC,OAAO,CAAA,2BAA2B,CAAC,CAAA;QACzC,OAAO,IAAI,CAAA;QACX,qDAAqD;KACtD;IAAC,OAAO,MAAM,EAAE;QACf,KAAK,CAAC,OAAO,CAAA,6BAA6B,CAAC,CAAA;QAC3C,OAAO,KAAK,CAAA;KACb;AACH,CAAC","sourcesContent":["import {SessionSchema} from './schema.js'\nimport constants from '../constants.js'\nimport {platformAndArch} from '../os.js'\nimport {store as secureStore, fetch as secureFetch, remove as secureRemove} from '../secure-store.js'\nimport {content, debug} from '../output.js'\nimport {getSession, removeSession, setSession, clearAllAppInfo} from '../store.js'\nimport type {Session} from './schema.js'\n\n/**\n * The identifier of the session in the secure store.\n */\nexport const identifier = 'session'\n\n/**\n * Serializes the session as a JSON and stores it securely in the system.\n * If the secure store is not available, the session is stored in the local config.\n * @param session - the session to store.\n */\nexport async function store(session: Session) {\n const jsonSession = JSON.stringify(session)\n if (await secureStoreAvailable()) {\n await secureStore(identifier, jsonSession)\n } else {\n await setSession(jsonSession)\n }\n}\n\n/**\n * Fetches the session from the secure store and returns it.\n * If the secure store is not available, the session is fetched from the local config.\n * If the format of the session is invalid, the method will discard it.\n * In the future might add some logic for supporting migrating the schema\n * of already-persisted sessions.\n * @returns Returns a promise that resolves with the session if it exists and is valid.\n */\nexport async function fetch(): Promise<Session | undefined> {\n let content\n if (await secureStoreAvailable()) {\n content = await secureFetch(identifier)\n } else {\n content = await getSession()\n }\n\n if (!content) {\n return undefined\n }\n const contentJson = JSON.parse(content)\n const parsedSession = await SessionSchema.safeParseAsync(contentJson)\n if (parsedSession.success) {\n return parsedSession.data\n } else {\n await remove()\n return undefined\n }\n}\n\n/**\n * Removes a session from the system.\n */\nexport async function remove() {\n if (await secureStoreAvailable()) {\n await secureRemove(identifier)\n } else {\n await removeSession()\n }\n\n await clearAllAppInfo()\n}\n\n/**\n * Returns true if the secure store is available on the system.\n * Keytar it's not supported on some Linux environments or Windows.\n * More details: https://github.com/Shopify/shopify-cli-planning/issues/261\n * @returns a boolean indicating if the secure store is available.\n */\nasync function secureStoreAvailable(): Promise<boolean> {\n try {\n if (platformAndArch().platform === 'windows') {\n debug(content`Secure store not supported on Windows`)\n return false\n }\n const keytar = await import('keytar')\n await keytar.default.findCredentials(constants.keychain.service)\n debug(content`Secure store is available`)\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_error) {\n debug(content`Failed to load secure store`)\n return false\n }\n}\n"]}
|
package/dist/session/token.d.ts
CHANGED
package/dist/session/token.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/session/token.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,KAAK;IA2BT,YAAY,OAAsG;QAChH,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;QACtC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;QACxC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;QAClC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;IAC9B,CAAC;IAED;;;OAGG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAA;IACpC,CAAC;CACF;AAED,eAAe,KAAK,CAAA","sourcesContent":["/**\n * It represents a temporary token that can be\n * used to send authenticated HTTP requests.\n */\nclass Token {\n /**\n * A fully-qualified domain name of the service\n * this token is for.\n */\n fqdn: string\n\n /**\n * Access token\n */\n accessToken: string\n\n /**\n * Token to refresh the access token if it has expired.\n */\n refreshToken?: string\n\n /**\n * The expiration date of the session\n */\n expiresAt: Date\n\n /**\n * The list of scopes the token has access to.\n */\n scopes: string[]\n\n constructor(options: {fqdn: string; accessToken: string; refreshToken?: string; expiresAt: Date; scopes: string[]}) {\n this.fqdn = options.fqdn\n this.accessToken = options.accessToken\n this.refreshToken = options.refreshToken\n this.expiresAt = options.expiresAt\n this.scopes = options.scopes\n }\n\n /**\n * Returns true if the session is expired.\n * @returns
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/session/token.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,KAAK;IA2BT,YAAY,OAAsG;QAChH,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;QACtC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;QACxC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;QAClC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;IAC9B,CAAC;IAED;;;OAGG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAA;IACpC,CAAC;CACF;AAED,eAAe,KAAK,CAAA","sourcesContent":["/**\n * It represents a temporary token that can be\n * used to send authenticated HTTP requests.\n */\nclass Token {\n /**\n * A fully-qualified domain name of the service\n * this token is for.\n */\n fqdn: string\n\n /**\n * Access token\n */\n accessToken: string\n\n /**\n * Token to refresh the access token if it has expired.\n */\n refreshToken?: string\n\n /**\n * The expiration date of the session\n */\n expiresAt: Date\n\n /**\n * The list of scopes the token has access to.\n */\n scopes: string[]\n\n constructor(options: {fqdn: string; accessToken: string; refreshToken?: string; expiresAt: Date; scopes: string[]}) {\n this.fqdn = options.fqdn\n this.accessToken = options.accessToken\n this.refreshToken = options.refreshToken\n this.expiresAt = options.expiresAt\n this.scopes = options.scopes\n }\n\n /**\n * Returns true if the session is expired.\n * @returns True if the session is expired.\n */\n get isExpired(): boolean {\n return new Date() > this.expiresAt\n }\n}\n\nexport default Token\n"]}
|
|
@@ -3,10 +3,10 @@ import { OAuthApplications } from '../session.js';
|
|
|
3
3
|
declare type ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok';
|
|
4
4
|
/**
|
|
5
5
|
* Validate if the current session is valid or we need to refresh/re-authenticate
|
|
6
|
-
* @param scopes
|
|
7
|
-
* @param applications
|
|
8
|
-
* @param session current session with identity and application tokens
|
|
9
|
-
* @returns
|
|
6
|
+
* @param scopes - requested scopes to validate
|
|
7
|
+
* @param applications - requested applications
|
|
8
|
+
* @param session - current session with identity and application tokens
|
|
9
|
+
* @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session
|
|
10
10
|
*/
|
|
11
11
|
export declare function validateSession(scopes: string[], applications: OAuthApplications, session: {
|
|
12
12
|
identity: IdentityToken;
|
package/dist/session/validate.js
CHANGED
|
@@ -5,9 +5,6 @@ import { debug } from '../output.js';
|
|
|
5
5
|
import { firstPartyDev } from '../environment/local.js';
|
|
6
6
|
/**
|
|
7
7
|
* Validate if an identity token is valid for the requested scopes
|
|
8
|
-
* @param requestedScopes scopes
|
|
9
|
-
* @param identity
|
|
10
|
-
* @returns
|
|
11
8
|
*/
|
|
12
9
|
function validateScopes(requestedScopes, identity) {
|
|
13
10
|
const currentScopes = identity.scopes;
|
|
@@ -17,10 +14,10 @@ function validateScopes(requestedScopes, identity) {
|
|
|
17
14
|
}
|
|
18
15
|
/**
|
|
19
16
|
* Validate if the current session is valid or we need to refresh/re-authenticate
|
|
20
|
-
* @param scopes
|
|
21
|
-
* @param applications
|
|
22
|
-
* @param session current session with identity and application tokens
|
|
23
|
-
* @returns
|
|
17
|
+
* @param scopes - requested scopes to validate
|
|
18
|
+
* @param applications - requested applications
|
|
19
|
+
* @param session - current session with identity and application tokens
|
|
20
|
+
* @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session
|
|
24
21
|
*/
|
|
25
22
|
export async function validateSession(scopes, applications, session) {
|
|
26
23
|
if (!session)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAE3C,OAAO,SAAS,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAA;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAIrD
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"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","sourcesContent":["import {applicationId} from './identity.js'\nimport {ApplicationToken, IdentityToken} from './schema.js'\nimport constants from '../constants.js'\nimport {OAuthApplications} from '../session.js'\nimport {identity, partners} from '../api.js'\nimport {debug} from '../output.js'\nimport {firstPartyDev} from '../environment/local.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (firstPartyDev() !== currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes - requested scopes to validate\n * @param applications - requested applications\n * @param session - current session with identity and application tokens\n * @returns 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: {\n identity: IdentityToken\n applications: {[x: string]: ApplicationToken}\n },\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n const identityIsValid = await identity.validateIdentityToken(session.identity.accessToken)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n let tokensAreRevoked = false\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreRevoked = tokensAreRevoked || (await isPartnersTokenRevoked(token))\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n debug(`\nThe validation of the token for application/identity completed with the following results:\n- It's expired: ${tokensAreExpired}\n- It's been revoked: ${tokensAreRevoked}\n- It's invalid in identity: ${!identityIsValid}\n `)\n\n if (tokensAreRevoked) return 'needs_full_auth'\n if (!identityIsValid) return 'needs_full_auth'\n if (tokensAreExpired) return 'needs_refresh'\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nasync function isPartnersTokenRevoked(token: ApplicationToken) {\n if (!token) return false\n return partners.checkIfTokenIsRevoked(token.accessToken)\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + constants.session.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}
|