woocommerce/plugins/woocommerce-blocks/assets/js/middleware/store-api-nonce.js

123 lines
3.3 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import apiFetch from '@wordpress/api-fetch';
// Stores the current nonce for the middleware.
let currentNonce = '';
let currentTimestamp = 0;
try {
const storedNonceValue = window.localStorage.getItem( 'storeApiNonce' );
const storedNonce = storedNonceValue ? JSON.parse( storedNonceValue ) : {};
currentNonce = storedNonce?.nonce || '';
currentTimestamp = storedNonce?.timestamp || 0;
} catch {
// We can ignore an error from JSON parse.
}
/**
* Returns whether or not this is a wc/store API request.
*
* @param {Object} options Fetch options.
*
* @return {boolean} Returns true if this is a store request.
*/
const isStoreApiRequest = ( options ) => {
const url = options.url || options.path;
if ( ! url || ! options.method || options.method === 'GET' ) {
return false;
}
return /wc\/store\//.exec( url ) !== null;
};
/**
* Set the current nonce from a header object.
*
* @param {Object} headers Headers object.
*/
const setNonce = ( headers ) => {
const nonce =
typeof headers?.get === 'function'
? headers.get( 'X-WC-Store-API-Nonce' )
: headers[ 'X-WC-Store-API-Nonce' ];
const timestamp =
typeof headers?.get === 'function'
? headers.get( 'X-WC-Store-API-Nonce-Timestamp' )
: headers[ 'X-WC-Store-API-Nonce-Timestamp' ];
if ( nonce ) {
updateNonce( nonce, timestamp );
}
};
/**
* Updates the stored nonce within localStorage so it is persisted between page loads.
*
* @param {string} nonce Incoming nonce string.
* @param {number} timestamp Timestamp from server of nonce.
*/
const updateNonce = ( nonce, timestamp ) => {
// If the "new" nonce matches the current nonce, we don't need to update.
if ( nonce === currentNonce ) {
return;
}
// Only update the nonce if newer. It might be coming from cache.
if ( currentTimestamp && timestamp < currentTimestamp ) {
return;
}
currentNonce = nonce;
currentTimestamp = timestamp || Date.now() / 1000; // Convert ms to seconds to match php time()
// Update the persisted values.
window.localStorage.setItem(
'storeApiNonce',
JSON.stringify( {
nonce: currentNonce,
timestamp: currentTimestamp,
} )
);
};
const appendNonceHeader = ( request ) => {
const headers = request.headers || {};
request.headers = {
...headers,
'X-WC-Store-API-Nonce': currentNonce,
};
return request;
};
/**
* Nonce middleware which appends the current nonce to store API requests.
*
* @param {Object} options Fetch options.
* @param {Function} next The next middleware or fetchHandler to call.
* @return {*} The evaluated result of the remaining middleware chain.
*/
const storeNonceMiddleware = ( options, next ) => {
if ( isStoreApiRequest( options ) ) {
options = appendNonceHeader( options );
// Add nonce to sub-requests
if ( Array.isArray( options?.data?.requests ) ) {
options.data.requests = options.data.requests.map(
appendNonceHeader
);
}
}
return next( options, next );
};
apiFetch.use( storeNonceMiddleware );
apiFetch.setNonce = setNonce;
Move Block Type Settings into Block Type Classes (https://github.com/woocommerce/woocommerce-blocks/pull/4059) * BLOCK SETTINGS: Remove unused constants/settings * AssetDataRegistry: Helpers to check for settings that exist, and registering page ID/permalinks * Move checkout and cart block settings to checkout and cart blocktypes * Move isShippingCalculatorEnabled to cart block * Remove HAS_DARK_EDITOR_STYLE_SUPPORT and IS_SHIPPING_CALCULATOR_ENABLED in favour of getSetting * Move displayCartPricesIncludingTax to blocktypes, and implement getSetting * Move block settings to core settings and blocktypes * Fix namespace usage * Move review settings * move tag settings * Keep productCount in core data * Move min and default height * Improve storePages code * Move attributes to attribute filter block type * Move $word_count_type outside of settings array * Remove unneeded setting in preview data (shippingCostRequiresAddress) * Move min/max settings dependency from GridLayoutControl to Blocks themselves and use getSettings * DEFAULT_COLUMNS and ROWS to settings * Move product columns/rows to block types * Add grid settings to AllProducts block * Correct default rows * correct min rows default * Move hasDarkEditorStyleSupport * Move hideOutOfStockItems to block type settings * Move build settings to inline script dependency * Pass data through asset api and move restApiRoutes * Export all core settings as constants * Remove WORD_COUNT_TYPE from core settings * Move some other core settings to assets * Update constants * Make settings use TypeScript * Update CURRENT_USER_IS_ADMIN usage * WORD_COUNT_TYPE * REST_API_ROUTES * REVIEW_RATINGS_ENABLED and SHOW_AVATARS * Remove REVIEW_RATINGS_ENABLED and SHOW_AVATARS constants * Remove MIN_HEIGHT * Remove DEFAULT_HEIGHT * PLACEHOLDER_IMG_SRC * LIMIT_TAGS * HAS_PRODUCTS * HOME_URL * HAS_TAGS * COUPONS_ENABLED * SHIPPING_ENABLED * TAXES_ENABLED * DISPLAY_ITEMIZED_TAXES * SHIPPING_COST_REQUIRES_ADDRESS * SHIPPING_STATES and SHIPPING_COUNTRIES * STORE_PAGES * ALLOWED_COUNTRIES * ALLOWED_STATES * SHIPPING_METHODS_EXIST * PAYMENT_GATEWAY_SORT_ORDER * CHECKOUT_SHOW_LOGIN_REMINDER * CHECKOUT_ALLOWS_GUEST and CHECKOUT_ALLOWS_SIGNUP * ATTRIBUTES * DISPLAY_CART_PRICES_INCLUDING_TAX * DISPLAY_CART_PRICES_INCLUDING_TAX * update build for TS files * fix build dir * Move blocks build config params * Move placeholderImgSrc to core settings * Move rest api hydration hoc to shared hocs and provide it restApiRoutes directly to avoid asset data registration * Move wordCountType to abstract block * Remove WORD_COUNT_TYPE in favour of getSetting * Move IS_LARGE_CATALOG and PRODUCT_COUNT to abstract block type and use getSetting inline * Add wcBlocksConfig * fix tests * Remove unused $asset_data_registry * remove console.log * Move build settings to abstract block * Trigger build again * Move hydration back to regular hocs for compatibility with trunk (merge conflict) * Removed wcSharedHocsConfig * esc home url * Update search fixture * Update search snap * 40000 timeout * hasProducts -> productCount * Product Count is part of blocks config * update mocks * Use version comparison to determine if batching is enabled * Change isWpVersion * scrollTo button
2021-04-22 11:37:27 +00:00
updateNonce(
// @ts-ignore wcBlocksMiddlewareConfig is window global cache for the initial nonce initialized from hydration.
wcBlocksMiddlewareConfig.storeApiNonce,
// @ts-ignore wcBlocksMiddlewareConfig is window global cache for the initial nonce initialized from hydration.
wcBlocksMiddlewareConfig.storeApiNonceTimestamp
);