diff --git a/config/config.json b/config/config.json index 8f3679f4c2..9906ca1803 100644 --- a/config/config.json +++ b/config/config.json @@ -131,7 +131,7 @@ "config": { "networkId": "otp::testnet", "hubContractAddress": "0x707233a55bD035C6Bc732196CA4dbffa63CbA169", - "rpcEndpoints": ["wss://lofar.origin-trail.network"], + "rpcEndpoints": ["https://lofar-tm-rpc.origin-trail.network"], "initialStakeAmount": 50000, "initialAskAmount": 2 } @@ -413,8 +413,7 @@ "hubContractAddress": "0xBbfF7Ea6b2Addc1f38A0798329e12C08f03750A6", "rpcEndpoints": [ "https://lofar-testnet.origin-trail.network", - "https://lofar-testnet.origintrail.network", - "wss://parachain-testnet-rpc.origin-trail.network" + "https://lofar-testnet.origintrail.network" ] } } @@ -562,8 +561,7 @@ "hubContractAddress": "0x5fA7916c48Fe6D5F1738d12Ad234b78c90B4cAdA", "rpcEndpoints": [ "https://astrosat-parachain-rpc.origin-trail.network", - "https://astrosat.origintrail.network/", - "wss://parachain-rpc.origin-trail.network" + "https://astrosat.origintrail.network/" ] } } diff --git a/ot-node.js b/ot-node.js index 5e89a6b99f..fa68cfc2af 100644 --- a/ot-node.js +++ b/ot-node.js @@ -63,13 +63,14 @@ class OTNode { await this.createProfiles(); + await this.initializeCommandExecutor(); await this.initializeShardingTableService(); await this.initializeTelemetryInjectionService(); await this.initializeBlockchainEventListenerService(); - await this.initializeCommandExecutor(); await this.initializeRouters(); await this.startNetworkModule(); + this.resumeCommandExecutor(); this.logger.info('Node is up and running!'); } @@ -244,9 +245,11 @@ class OTNode { async initializeCommandExecutor() { try { const commandExecutor = this.container.resolve('commandExecutor'); - await commandExecutor.init(); - commandExecutor.replay(); - await commandExecutor.start(); + commandExecutor.pauseQueue(); + await commandExecutor.addDefaultCommands(); + commandExecutor + .replayOldCommands() + .then(() => this.logger.info('Finished replaying old commands')); } catch (e) { this.logger.error( `Command executor initialization failed. Error message: ${e.message}`, @@ -255,6 +258,18 @@ class OTNode { } } + resumeCommandExecutor() { + try { + const commandExecutor = this.container.resolve('commandExecutor'); + commandExecutor.resumeQueue(); + } catch (e) { + this.logger.error( + `Unable to resume command executor queue. Error message: ${e.message}`, + ); + this.stop(1); + } + } + async startNetworkModule() { const networkModuleManager = this.container.resolve('networkModuleManager'); await networkModuleManager.start(); diff --git a/package-lock.json b/package-lock.json index 28d3231823..4fdac68a57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "origintrail_node", - "version": "6.0.15", + "version": "6.0.16", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "origintrail_node", - "version": "6.0.15", + "version": "6.0.16", "license": "ISC", "dependencies": { "@comunica/query-sparql": "^2.4.3", @@ -54,7 +54,7 @@ "pino-pretty": "^9.1.0", "rc": "^1.2.8", "rolling-rate-limiter": "^0.2.13", - "semver": "^7.3.7", + "semver": "^7.5.2", "sequelize": "^6.29.0", "timeout-abort-controller": "^3.0.0", "toobusy-js": "^0.5.1", @@ -2707,6 +2707,39 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@cucumber/cucumber/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@cucumber/cucumber/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@cucumber/cucumber/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@cucumber/gherkin": { "version": "26.0.3", "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-26.0.3.tgz", @@ -16553,9 +16586,9 @@ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -21869,6 +21902,30 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -32600,9 +32657,9 @@ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "requires": { "lru-cache": "^6.0.0" }, diff --git a/package.json b/package.json index 2c8c7ec700..307fadd425 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "origintrail_node", - "version": "6.0.15", + "version": "6.0.16", "description": "OTNode V6", "main": "index.js", "type": "module", @@ -104,7 +104,7 @@ "pino-pretty": "^9.1.0", "rc": "^1.2.8", "rolling-rate-limiter": "^0.2.13", - "semver": "^7.3.7", + "semver": "^7.5.2", "sequelize": "^6.29.0", "timeout-abort-controller": "^3.0.0", "toobusy-js": "^0.5.1", diff --git a/src/commands/command-executor.js b/src/commands/command-executor.js index e62e042acb..9f2a85933a 100644 --- a/src/commands/command-executor.js +++ b/src/commands/command-executor.js @@ -16,7 +16,6 @@ class CommandExecutor { constructor(ctx) { this.logger = ctx.logger; this.commandResolver = ctx.commandResolver; - this.started = false; this.repositoryModuleManager = ctx.repositoryModuleManager; this.verboseLoggingEnabled = ctx.config.commandExecutorVerboseLoggingEnabled; @@ -39,8 +38,8 @@ class CommandExecutor { * Initialize executor * @returns {Promise} */ - async init() { - await Promise.all(PERMANENT_COMMANDS.map((command) => this._startDefaultCommand(command))); + async addDefaultCommands() { + await Promise.all(PERMANENT_COMMANDS.map((command) => this._addDefaultCommand(command))); if (this.verboseLoggingEnabled) { this.logger.trace('Command executor has been initialized...'); @@ -48,14 +47,23 @@ class CommandExecutor { } /** - * Starts the command executor - * @return {Promise} + * Resumes the command executor queue + */ + resumeQueue() { + if (this.verboseLoggingEnabled) { + this.logger.trace('Command executor queue has been resumed...'); + } + this.queue.resume(); + } + + /** + * Pause the command executor queue */ - async start() { - this.started = true; + pauseQueue() { if (this.verboseLoggingEnabled) { - this.logger.trace('Command executor has been started...'); + this.logger.trace('Command executor queue has been paused...'); } + this.queue.pause(); } /** @@ -224,7 +232,7 @@ class CommandExecutor { * @return {Promise} * @private */ - async _startDefaultCommand(name) { + async _addDefaultCommand(name) { await this._delete(name); const handler = this.commandResolver.resolve(name); if (!handler) { @@ -398,7 +406,7 @@ class CommandExecutor { * Replays pending commands from the database * @returns {Promise} */ - async replay() { + async replayOldCommands() { this.logger.info('Replay pending/started commands from the database...'); const pendingCommands = await this.repositoryModuleManager.getCommandsWithStatus( [COMMAND_STATUS.PENDING, COMMAND_STATUS.STARTED, COMMAND_STATUS.REPEATING], diff --git a/src/commands/protocols/update/receiver/submit-update-commit-command.js b/src/commands/protocols/update/receiver/submit-update-commit-command.js index 7c40eb0f56..bf5289600a 100644 --- a/src/commands/protocols/update/receiver/submit-update-commit-command.js +++ b/src/commands/protocols/update/receiver/submit-update-commit-command.js @@ -108,8 +108,8 @@ class SubmitUpdateCommitCommand extends Command { this.logger.trace( `Scheduled submit update commit transaction for agreement id: ${agreementId} ` + `blockchain: ${blockchain} contract: ${contract}, token id: ${tokenId}, ` + - `keyword: ${keyword}, hash function id: ${hashFunctionId}, operationId ${operationId}` + - `transaction queue length: ${transactionQueueLength}.`, + `keyword: ${keyword}, hash function id: ${hashFunctionId}, operationId ${operationId}. ` + + `Transaction queue length: ${transactionQueueLength}.`, ); return Command.empty(); diff --git a/src/constants/constants.js b/src/constants/constants.js index 9458748ae7..3fff5854e4 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -8,6 +8,8 @@ export const STAKE_UINT256_MULTIPLIER_BN = UINT256_MAX_BN.div(500000000); export const UINT256_UINT32_DIVISOR_BN = UINT256_MAX_BN.div(UINT32_MAX_BN); +export const ZERO_PREFIX = '0x'; + export const ZERO_BYTES32 = `0x${'0'.repeat(64)}`; export const SCHEMA_CONTEXT = 'http://schema.org/'; @@ -21,6 +23,22 @@ export const COMMITS_DELAY_BETWEEN_NODES_IN_BLOCKS = 2; export const TRANSACTION_POLLING_TIMEOUT_MILLIS = 50 * 1000; +export const SOLIDITY_ERROR_STRING_PREFIX = '0x08c379a0'; + +export const SOLIDITY_PANIC_CODE_PREFIX = '0x4e487b71'; + +export const SOLIDITY_PANIC_REASONS = { + 0x1: 'Assertion error', + 0x11: 'Arithmetic operation underflowed or overflowed outside of an unchecked block', + 0x12: 'Division or modulo division by zero', + 0x21: 'Tried to convert a value into an enum, but the value was too big or negative', + 0x22: 'Incorrectly encoded storage byte array', + 0x31: '.pop() was called on an empty array', + 0x32: 'Array accessed at an out-of-bounds or negative index', + 0x41: 'Too much memory was allocated, or an array was created that is too large', + 0x51: 'Called a zero-initialized variable of internal function type', +}; + export const LIBP2P_KEY_DIRECTORY = 'libp2p'; export const LIBP2P_KEY_FILENAME = 'privateKey'; @@ -38,6 +56,7 @@ export const TRIPLE_STORE_CONNECT_RETRY_FREQUENCY = 10; export const MAX_FILE_SIZE = 2621440; export const GET_STATES = { LATEST: 'LATEST', FINALIZED: 'LATEST_FINALIZED' }; + export const BYTES_IN_KILOBYTE = 1024; export const BYTES_IN_MEGABYTE = BYTES_IN_KILOBYTE * BYTES_IN_KILOBYTE; diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 5759b4d1bf..49632f426f 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -1,10 +1,14 @@ -import { ethers } from 'ethers'; +import { ethers, BigNumber } from 'ethers'; import axios from 'axios'; import async from 'async'; import { setTimeout as sleep } from 'timers/promises'; import { createRequire } from 'module'; import { + SOLIDITY_ERROR_STRING_PREFIX, + SOLIDITY_PANIC_CODE_PREFIX, + SOLIDITY_PANIC_REASONS, + ZERO_PREFIX, DEFAULT_BLOCKCHAIN_EVENT_SYNC_PERIOD_IN_MILLS, MAXIMUM_NUMBERS_OF_BLOCKS_TO_FETCH, TRANSACTION_QUEUE_CONCURRENCY, @@ -344,31 +348,47 @@ class Web3Service { let result; let gasPrice = (await this.getGasPrice()) ?? this.convertToWei(20, 'gwei'); let transactionRetried = false; + while (result === undefined) { + let gasLimit; + try { /* eslint-disable no-await-in-loop */ - const gasLimit = await contractInstance.estimateGas[functionName](...args); - const gas = gasLimit ?? this.convertToWei(900, 'kwei'); - - this.logger.info( - 'Sending signed transaction to blockchain, calling method: ' + - `${functionName} with gas limit: ${gas.toString()} and gasPrice ${gasPrice.toString()}. Transaction queue length: ${this.getTransactionQueueLength()}`, + gasLimit = await contractInstance.estimateGas[functionName](...args); + } catch (error) { + const decodedReturnData = this._decodeReturnData(error, contractInstance.interface); + await this.handleError( + Error(`gas estimation failed, reason: ${decodedReturnData}`), + functionName, ); + } + + gasLimit = gasLimit ?? this.convertToWei(900, 'kwei'); + + this.logger.info( + 'Sending signed transaction to blockchain, calling method: ' + + `${functionName} with gas limit: ${gasLimit.toString()} and gasPrice ${gasPrice.toString()}. ` + + `Transaction queue length: ${this.getTransactionQueueLength()}`, + ); + + try { const tx = await contractInstance[functionName](...args, { gasPrice, - gasLimit: gas, + gasLimit, }); result = await this.provider.waitForTransaction( tx.hash, TRANSACTION_CONFIRMATIONS, TRANSACTION_POLLING_TIMEOUT_MILLIS, ); - if (result?.status === 0) { - throw Error(); + + if (result.status === 0) { + await this.provider.call(tx, tx.blockNumber); } } catch (error) { + const decodedReturnData = this._decodeReturnData(error, contractInstance.interface); this.logger.warn( - `Failed executing smart contract function ${functionName}. Error: ${error.message}`, + `Failed executing smart contract function ${functionName}. Error: ${decodedReturnData}`, ); if ( !transactionRetried && @@ -381,13 +401,120 @@ class Web3Service { ); transactionRetried = true; } else { - await this.handleError(error, functionName); + await this.handleError( + Error(`transaction reverted, reason: ${decodedReturnData}`), + functionName, + ); } } } return result; } + _getReturnData(error) { + let nestedError = error; + while (nestedError && nestedError.error) { + nestedError = nestedError.error; + } + const errorData = nestedError.data; + + if (errorData === undefined) { + throw error; + } + + let returnData = typeof errorData === 'string' ? errorData : errorData.data; + + if (typeof returnData === 'object' && returnData.data) { + returnData = returnData.data; + } + + if (returnData === undefined || typeof returnData !== 'string') { + throw error; + } + + return returnData; + } + + _decodeReturnData(evmError, contractInterface) { + let returnData; + + try { + returnData = this._getReturnData(evmError); + } catch (error) { + return error.message; + } + + // Handle empty error data + if (returnData === ZERO_PREFIX) { + return 'Empty error data.'; + } + + // Handle standard solidity string error + if (returnData.startsWith(SOLIDITY_ERROR_STRING_PREFIX)) { + const encodedReason = returnData.slice(SOLIDITY_ERROR_STRING_PREFIX.length); + try { + return ethers.utils.defaultAbiCoder.decode(['string'], `0x${encodedReason}`)[0]; + } catch (error) { + return error.message; + } + } + + // Handle solidity panic code + if (returnData.startsWith(SOLIDITY_PANIC_CODE_PREFIX)) { + const encodedReason = returnData.slice(SOLIDITY_PANIC_CODE_PREFIX.length); + let code; + try { + [code] = ethers.utils.defaultAbiCoder.decode(['uint256'], `0x${encodedReason}`); + } catch (error) { + return error.message; + } + + return SOLIDITY_PANIC_REASONS[code] ?? 'Unknown Solidity panic code.'; + } + + // Try parsing a custom error using the contract ABI + try { + const decodedCustomError = contractInterface.parseError(returnData); + const formattedArgs = decodedCustomError.errorFragment.inputs + .map((input, i) => { + const argName = input.name; + const argValue = this._formatCustomErrorArgument(decodedCustomError.args[i]); + return `${argName}=${argValue}`; + }) + .join(', '); + return `custom error ${decodedCustomError.name}(${formattedArgs})`; + } catch (error) { + return `Failed to decode custom error data. Error: ${error}`; + } + } + + _formatCustomErrorArgument(value) { + if (value === null || value === undefined) { + return 'null'; + } + + if (typeof value === 'string') { + return value; + } + + if (typeof value === 'number' || BigNumber.isBigNumber(value)) { + return value.toString(); + } + + if (Array.isArray(value)) { + return `[${value.map((v) => this._formatCustomErrorArgument(v)).join(', ')}]`; + } + + if (typeof value === 'object') { + const formattedEntries = Object.entries(value).map( + ([k, v]) => `${k}: ${this._formatCustomErrorArgument(v)}`, + ); + return `{${formattedEntries.join(', ')}}`; + } + + return value.toString(); + } + async getAllPastEvents( blockchainId, contractName, diff --git a/src/modules/http-client/implementation/middleware/authentication-middleware.js b/src/modules/http-client/implementation/middleware/authentication-middleware.js index 87bdf99454..bb3ce98246 100644 --- a/src/modules/http-client/implementation/middleware/authentication-middleware.js +++ b/src/modules/http-client/implementation/middleware/authentication-middleware.js @@ -14,7 +14,11 @@ const parseIp = (req) => { }; export default (authService) => async (req, res, next) => { - const operation = req.url.split('/')[1].split('?')[0].toUpperCase(); + // eslint-disable-next-line no-useless-escape + const match = req.path.match(/^\/(?:v[0-9]+\/)?([^\/\?]+)/); + if (!match) return res.status(404).send('Not found.'); + + const operation = match[0].substring(1); if (authService.isPublicOperation(operation)) { return next(); diff --git a/src/modules/http-client/implementation/middleware/authorization-middleware.js b/src/modules/http-client/implementation/middleware/authorization-middleware.js index 3c9c03ca58..5c92020f15 100644 --- a/src/modules/http-client/implementation/middleware/authorization-middleware.js +++ b/src/modules/http-client/implementation/middleware/authorization-middleware.js @@ -5,7 +5,11 @@ const getToken = (req) => { }; export default (authService) => async (req, res, next) => { - const operation = req.url.split('/')[1].split('?')[0].toUpperCase(); + // eslint-disable-next-line no-useless-escape + const match = req.path.match(/^\/(?:v[0-9]+\/)?([^\/\?]+)/); + if (!match) return res.status(404).send('Not found.'); + + const operation = match[0].substring(1); if (authService.isPublicOperation(operation)) { return next(); diff --git a/src/service/auth-service.js b/src/service/auth-service.js index 729923934c..05c6c3093e 100644 --- a/src/service/auth-service.js +++ b/src/service/auth-service.js @@ -62,7 +62,15 @@ class AuthService { return false; } - return this._authConfig.publicOperations.includes(operationName); + const lowerCaseOperationName = operationName.toLowerCase(); + + return this._authConfig.publicOperations.some((publicOperation) => { + const lowerCasePublicOperation = publicOperation.toLowerCase(); + return ( + lowerCasePublicOperation === `v0/${lowerCaseOperationName}` || + lowerCasePublicOperation === lowerCaseOperationName + ); + }); } /** diff --git a/test/bdd/features/get.feature b/test/bdd/features/get.feature index d11fcf2f30..88c3af8c01 100644 --- a/test/bdd/features/get.feature +++ b/test/bdd/features/get.feature @@ -59,6 +59,8 @@ Feature: Get asset states test And I wait for latest Update to finalize Then Latest Update operation finished with status: COMPLETED + And I wait for 30 seconds + When I call Update on the node 4 for the latest published UAL with validUpdate_2 And I wait for latest Update to finalize Then Latest Update operation finished with status: COMPLETED diff --git a/test/unit/middleware/authentication-middleware.test.js b/test/unit/middleware/authentication-middleware.test.js index cd67d9b888..287af08f03 100644 --- a/test/unit/middleware/authentication-middleware.test.js +++ b/test/unit/middleware/authentication-middleware.test.js @@ -25,7 +25,7 @@ describe('authentication middleware test', async () => { }), ); - const req = { headers: { authorization: 'Bearer token' }, url: '/publish' }; + const req = { headers: { authorization: 'Bearer token' }, path: '/publish' }; const spySend = sandbox.spy(); const spyStatus = sandbox.spy(() => ({ send: spySend })); @@ -46,7 +46,7 @@ describe('authentication middleware test', async () => { }), ); - const req = { headers: { authorization: 'Bearer token' }, url: '/publish' }; + const req = { headers: { authorization: 'Bearer token' }, path: '/publish' }; const spySend = sandbox.spy(); const spyStatus = sandbox.spy(() => ({ send: spySend })); @@ -67,7 +67,7 @@ describe('authentication middleware test', async () => { }), ); - const req = { headers: { authorization: 'Bearer token' }, url: '/publish' }; + const req = { headers: { authorization: 'Bearer token' }, path: '/publish' }; const spySend = sandbox.spy(); const spyStatus = sandbox.spy(() => ({ send: spySend })); diff --git a/test/unit/middleware/authorization-middleware.test.js b/test/unit/middleware/authorization-middleware.test.js index 6d254394f8..6e0dd30714 100644 --- a/test/unit/middleware/authorization-middleware.test.js +++ b/test/unit/middleware/authorization-middleware.test.js @@ -26,7 +26,7 @@ describe('authentication middleware test', async () => { }), ); - const req = { headers: { authorization: 'Bearer token' }, url: '/publish' }; + const req = { headers: { authorization: 'Bearer token' }, path: '/publish' }; const spySend = sandbox.spy(); const spyStatus = sandbox.spy(() => ({ send: spySend })); @@ -46,7 +46,7 @@ describe('authentication middleware test', async () => { }), ); - const req = { headers: { authorization: 'Bearer token' }, url: '/publish' }; + const req = { headers: { authorization: 'Bearer token' }, path: '/publish' }; const spySend = sandbox.spy(); const spyStatus = sandbox.spy(() => ({ send: spySend })); @@ -67,7 +67,7 @@ describe('authentication middleware test', async () => { }), ); - const req = { headers: { authorization: 'Bearer token' }, url: '/publish' }; + const req = { headers: { authorization: 'Bearer token' }, path: '/publish' }; const spySend = sandbox.spy(); const spyStatus = sandbox.spy(() => ({ send: spySend }));