diff --git a/src/LAND/LAND.router.spec.ts b/src/LAND/LAND.router.spec.ts index bdff9fcf..9cfff308 100644 --- a/src/LAND/LAND.router.spec.ts +++ b/src/LAND/LAND.router.spec.ts @@ -2,12 +2,30 @@ import supertest from 'supertest' import { buildURL } from '../../spec/utils' import { app } from '../server' import { MAX_COORDS } from './LAND.router' +import { getLandRouterEnvs } from './utils' + +jest.mock('./utils') + +const mockGetLandRouterEnvs = getLandRouterEnvs as jest.MockedFunction< + typeof getLandRouterEnvs +> const server = supertest(app.getApp()) describe('LAND router', () => { let url: string + beforeEach(() => { + jest.clearAllMocks() + + mockGetLandRouterEnvs.mockImplementation(() => ({ + ipfsUrl: 'https://ipfs.xyz', + ipfsProjectId: 'ipfsProjectId', + ipfsApiKey: 'ipfsApiKey', + explorerUrl: 'https://explorer.xyz', + })) + }) + describe('when fetching the redirection file hashes', () => { beforeEach(() => { url = '/lands/redirectionHashes?' @@ -57,8 +75,8 @@ describe('LAND router', () => { expect(body).toEqual({ data: new Array(MAX_COORDS).fill({ contentHash: - 'e30101701220166b6b4d93ece408525081ade3c0258c6e992180d9b4ceb469d08192589095d7', - ipfsHash: 'QmPrAgSua8WLPZ4CNL6tGMSdN45Kte3WjPJTPjfQSfv1kJ', + 'e301017012205453e784584c205c23a771c67af071129721f0e21b0472e3061361005393a908', + ipfsHash: 'QmU1qAKrZKEUinZ7j7gbPcJ7dKSkJ6diHLk9YrB4PbLr7q', x: 100, y: 100, }), @@ -99,15 +117,15 @@ describe('LAND router', () => { data: [ { contentHash: - 'e30101701220166b6b4d93ece408525081ade3c0258c6e992180d9b4ceb469d08192589095d7', - ipfsHash: 'QmPrAgSua8WLPZ4CNL6tGMSdN45Kte3WjPJTPjfQSfv1kJ', + 'e301017012205453e784584c205c23a771c67af071129721f0e21b0472e3061361005393a908', + ipfsHash: 'QmU1qAKrZKEUinZ7j7gbPcJ7dKSkJ6diHLk9YrB4PbLr7q', x: 100, y: 100, }, { contentHash: - 'e301017012207a05747aa476fe4f72b0316b99b6f5af96be152288d9a840aba5d2bc17bd88b7', - ipfsHash: 'QmWYyGnw1QRSZDZKaXppu9GW37JtFGdhgADLVSagguXgjg', + 'e301017012204d02b4fe9cee2f8e4ab0a88adbf2338faa903355a0280d725f72f0f79929c079', + ipfsHash: 'QmTXGVk1DtCP6km25iNUmEmV2Wf7dCFAziwiTzZNeQKM9z', x: 200, y: 200, }, @@ -149,8 +167,8 @@ describe('LAND router', () => { data: [ { contentHash: - 'e30101701220166b6b4d93ece408525081ade3c0258c6e992180d9b4ceb469d08192589095d7', - ipfsHash: 'QmPrAgSua8WLPZ4CNL6tGMSdN45Kte3WjPJTPjfQSfv1kJ', + 'e301017012205453e784584c205c23a771c67af071129721f0e21b0472e3061361005393a908', + ipfsHash: 'QmU1qAKrZKEUinZ7j7gbPcJ7dKSkJ6diHLk9YrB4PbLr7q', x: 100, y: 100, }, diff --git a/src/LAND/LAND.router.ts b/src/LAND/LAND.router.ts index 111cada6..c7a03627 100644 --- a/src/LAND/LAND.router.ts +++ b/src/LAND/LAND.router.ts @@ -1,4 +1,3 @@ -import { env } from 'decentraland-commons' import { server } from 'decentraland-server' import FormData from 'form-data' import { Request } from 'express' @@ -12,19 +11,13 @@ import { GetRedirectionHashesResponse, UploadRedirectionResponse, } from './LAND.types' +import { getLandRouterEnvs } from './utils' export const MAX_COORDS = 150 const INDEX_FILE = 'index.html' export class LANDRouter extends Router { - private ipfsUrl = env.get('IPFS_URL') - private ipfsProjectId = env.get('IPFS_PROJECT_ID') - private ipfsApiKey = env.get('IPFS_API_KEY') - private explorerUrl = env.get('EXPLORER_URL') - mount() { - this.verifyEnvs() - this.router.get( '/lands/redirectionHashes', server.handleRequest(this.getRedirectionHashes) @@ -39,13 +32,24 @@ export class LANDRouter extends Router { private uploadRedirection = async ( req: Request ): Promise => { + const { + ipfsUrl, + ipfsProjectId, + ipfsApiKey, + explorerUrl, + } = getLandRouterEnvs() + const coords = server.extractFromReq(req, 'coords') this.validateCoords(coords) const locale = req.headers['accept-language'] - const redirectionFile = this.generateRedirectionFile(coords, locale) + const redirectionFile = this.generateRedirectionFile( + coords, + explorerUrl, + locale + ) const formData = new FormData() @@ -54,12 +58,12 @@ export class LANDRouter extends Router { let result: FetchResponse try { - result = await fetch(this.ipfsUrl + '/api/v0/add?pin=false', { + result = await fetch(ipfsUrl + '/api/v0/add?pin=false', { method: 'post', body: formData, headers: { Authorization: `Basic ${Buffer.from( - `${this.ipfsProjectId}:${this.ipfsApiKey}` + `${ipfsProjectId}:${ipfsApiKey}` ).toString('base64')}`, }, }) @@ -90,11 +94,13 @@ export class LANDRouter extends Router { private getRedirectionHashes = async ( req: Request ): Promise => { + const { explorerUrl } = getLandRouterEnvs() + let coordsListQP: string | string[] try { coordsListQP = server.extractFromReq(req, 'coords') - } catch (e) { + } catch (e: any) { throw new HTTPError(e.message, {}, STATUS_CODES.badRequest) } @@ -116,7 +122,11 @@ export class LANDRouter extends Router { for (const coords of coordsList) { this.validateCoords(coords) - const redirectionFile = this.generateRedirectionFile(coords, locale) + const redirectionFile = this.generateRedirectionFile( + coords, + explorerUrl, + locale + ) const ipfsHash = await getCID({ path: INDEX_FILE, @@ -137,24 +147,6 @@ export class LANDRouter extends Router { return output } - private verifyEnvs = () => { - if (!this.ipfsUrl) { - throw new Error('IPFS_URL not defined') - } - - if (!this.ipfsProjectId) { - throw new Error('IPFS_PROJECT_ID not defined') - } - - if (!this.ipfsApiKey) { - throw new Error('IPFS_API_KEY not defined') - } - - if (!this.explorerUrl) { - throw new Error('EXPLORER_URL not defined') - } - } - private validateCoords = (coords: string): void => { if (!/^-?[1-9]\d*,-?[1-9]\d*$/.test(coords)) { throw new HTTPError( @@ -167,6 +159,7 @@ export class LANDRouter extends Router { private generateRedirectionFile = ( coords: string, + explorerUrl: string, locale?: string ): Buffer => { let messages: [string, string] @@ -186,13 +179,13 @@ export class LANDRouter extends Router {

${messages[0]} - + ${messages[1]} .

diff --git a/src/LAND/utils.ts b/src/LAND/utils.ts new file mode 100644 index 00000000..0e6be4f0 --- /dev/null +++ b/src/LAND/utils.ts @@ -0,0 +1,31 @@ +import { env } from 'decentraland-commons' + +export const getLandRouterEnvs = () => { + const ipfsUrl: string | undefined = env.get('IPFS_URL') + const ipfsProjectId: string | undefined = env.get('IPFS_PROJECT_ID') + const ipfsApiKey: string | undefined = env.get('IPFS_API_KEY') + const explorerUrl: string | undefined = env.get('EXPLORER_URL') + + if (!ipfsUrl) { + throw new Error('IPFS_URL not defined') + } + + if (!ipfsProjectId) { + throw new Error('IPFS_PROJECT_ID not defined') + } + + if (!ipfsApiKey) { + throw new Error('IPFS_API_KEY not defined') + } + + if (!explorerUrl) { + throw new Error('EXPLORER_URL not defined') + } + + return { + ipfsUrl, + ipfsProjectId, + ipfsApiKey, + explorerUrl, + } +}