UNPKG

@shopify/cli-kit

Version:

A set of utilities, interfaces, and models that are common across all the platform features

163 lines • 7.9 kB
import { normalizeStoreFqdn } from './context/fqdn.js'; import { BugError } from './error.js'; import { getPartnersToken } from './environment.js'; import { nonRandomUUID } from './crypto.js'; import * as secureStore from '../../private/node/session/store.js'; import { exchangeCustomPartnerToken, exchangeCliTokenForAppManagementAccessToken, exchangeCliTokenForBusinessPlatformAccessToken, } from '../../private/node/session/exchange.js'; import { outputContent, outputToken, outputDebug } from '../../public/node/output.js'; import { ensureAuthenticated, setLastSeenAuthMethod, setLastSeenUserIdAfterAuth, } from '../../private/node/session.js'; import { isThemeAccessSession } from '../../private/node/api/rest.js'; /** * Ensure that we have a valid session to access the Partners API. * If SHOPIFY_CLI_PARTNERS_TOKEN exists, that token will be used to obtain a valid Partners Token * If SHOPIFY_CLI_PARTNERS_TOKEN exists, scopes will be ignored. * * @param scopes - Optional array of extra scopes to authenticate with. * @param env - Optional environment variables to use. * @param options - Optional extra options to use. * @returns The access token for the Partners API. */ export async function ensureAuthenticatedPartners(scopes = [], env = process.env, options = {}) { outputDebug(outputContent `Ensuring that the user is authenticated with the Partners API with the following scopes: ${outputToken.json(scopes)} `); const envToken = getPartnersToken(); if (envToken) { const result = await exchangeCustomPartnerToken(envToken); return { token: result.accessToken, userId: result.userId }; } const tokens = await ensureAuthenticated({ partnersApi: { scopes } }, env, options); if (!tokens.partners) { throw new BugError('No partners token found after ensuring authenticated'); } return { token: tokens.partners, userId: tokens.userId }; } /** * Ensure that we have a valid session to access the App Management API. * * @param options - Optional extra options to use. * @param appManagementScopes - Optional array of extra scopes to authenticate with. * @param businessPlatformScopes - Optional array of extra scopes to authenticate with. * @param env - Optional environment variables to use. * @returns The access token for the App Management API. */ export async function ensureAuthenticatedAppManagementAndBusinessPlatform(options = {}, appManagementScopes = [], businessPlatformScopes = [], env = process.env) { outputDebug(outputContent `Ensuring that the user is authenticated with the App Management API with the following scopes: ${outputToken.json(appManagementScopes)} `); const envToken = getPartnersToken(); if (envToken) { const appManagmentToken = await exchangeCliTokenForAppManagementAccessToken(envToken); const businessPlatformToken = await exchangeCliTokenForBusinessPlatformAccessToken(envToken); return { appManagementToken: appManagmentToken.accessToken, userId: appManagmentToken.userId, businessPlatformToken: businessPlatformToken.accessToken, }; } const tokens = await ensureAuthenticated({ appManagementApi: { scopes: appManagementScopes }, businessPlatformApi: { scopes: businessPlatformScopes } }, env, options); if (!tokens.appManagement || !tokens.businessPlatform) { throw new BugError('No App Management or Business Platform token found after ensuring authenticated'); } return { appManagementToken: tokens.appManagement, userId: tokens.userId, businessPlatformToken: tokens.businessPlatform, }; } /** * Ensure that we have a valid session to access the Storefront API. * * @param scopes - Optional array of extra scopes to authenticate with. * @param password - Optional password to use. * @param forceRefresh - Optional flag to force a refresh of the token. * @returns The access token for the Storefront API. */ export async function ensureAuthenticatedStorefront(scopes = [], password = undefined, forceRefresh = false) { if (password) { const session = { token: password, storeFqdn: '' }; const authMethod = isThemeAccessSession(session) ? 'theme_access_token' : 'custom_app_token'; setLastSeenAuthMethod(authMethod); setLastSeenUserIdAfterAuth(nonRandomUUID(password)); return password; } outputDebug(outputContent `Ensuring that the user is authenticated with the Storefront API with the following scopes: ${outputToken.json(scopes)} `); const tokens = await ensureAuthenticated({ storefrontRendererApi: { scopes } }, process.env, { forceRefresh }); if (!tokens.storefront) { throw new BugError('No storefront token found after ensuring authenticated'); } return tokens.storefront; } /** * Ensure that we have a valid Admin session for the given store. * * @param store - Store fqdn to request auth for. * @param scopes - Optional array of extra scopes to authenticate with. * @param forceRefresh - Optional flag to force a refresh of the token. * @param options - Optional extra options to use. * @returns The access token for the Admin API. */ export async function ensureAuthenticatedAdmin(store, scopes = [], forceRefresh = false, options = {}) { outputDebug(outputContent `Ensuring that the user is authenticated with the Admin API with the following scopes for the store ${outputToken.raw(store)}: ${outputToken.json(scopes)} `); const tokens = await ensureAuthenticated({ adminApi: { scopes, storeFqdn: store } }, process.env, { forceRefresh, ...options, }); if (!tokens.admin) { throw new BugError('No admin token found after ensuring authenticated'); } return tokens.admin; } /** * Ensure that we have a valid session to access the Theme API. * If a password is provided, that token will be used against Theme Access API. * Otherwise, it will ensure that the user is authenticated with the Admin API. * * @param store - Store fqdn to request auth for. * @param password - Password generated from Theme Access app. * @param scopes - Optional array of extra scopes to authenticate with. * @param forceRefresh - Optional flag to force a refresh of the token. * @returns The access token and store. */ export async function ensureAuthenticatedThemes(store, password, scopes = [], forceRefresh = false) { outputDebug(outputContent `Ensuring that the user is authenticated with the Theme API with the following scopes: ${outputToken.json(scopes)} `); if (password) { const session = { token: password, storeFqdn: await normalizeStoreFqdn(store) }; const authMethod = isThemeAccessSession(session) ? 'theme_access_token' : 'custom_app_token'; setLastSeenAuthMethod(authMethod); setLastSeenUserIdAfterAuth(nonRandomUUID(password)); return session; } return ensureAuthenticatedAdmin(store, scopes, forceRefresh); } /** * Ensure that we have a valid session to access the Business Platform API. * * @param scopes - Optional array of extra scopes to authenticate with. * @returns The access token for the Business Platform API. */ export async function ensureAuthenticatedBusinessPlatform(scopes = []) { outputDebug(outputContent `Ensuring that the user is authenticated with the Business Platform API with the following scopes: ${outputToken.json(scopes)} `); const tokens = await ensureAuthenticated({ businessPlatformApi: { scopes } }, process.env); if (!tokens.businessPlatform) { throw new BugError('No business-platform token found after ensuring authenticated'); } return tokens.businessPlatform; } /** * Logout from Shopify. * * @returns A promise that resolves when the logout is complete. */ export function logout() { return secureStore.remove(); } //# sourceMappingURL=session.js.map