Display warning for unsupported origins

remixd
ioedeveloper 4 years ago
parent 4da76d599a
commit 9a5c0c9f7e
  1. 127
      bin/remixd.ts
  2. 33
      package-lock.json
  3. 4
      package.json
  4. 14
      src/utils.ts
  5. 5
      src/websocket.ts

@ -2,54 +2,93 @@
import WebSocket from '../src/websocket'
import * as servicesList from '../src/serviceList'
import { WS } from '../types/index'
import { getDomain } from '../src/utils'
import Axios from 'axios'
import * as fs from 'fs-extra'
import * as path from 'path'
const program = require('commander')
program
.usage('-s <shared folder>')
.description('Provide a two-way connection between the local computer and Remix IDE')
.option('--remix-ide <url>', 'URL of remix instance allowed to connect to this web sockect connection')
.option('-s, --shared-folder <path>', 'Folder to share with Remix IDE')
.option('--read-only', 'Treat shared folder as read-only (experimental)')
.on('--help', function(){
console.log('\nExample:\n\n remixd -s ./ --remix-ide http://localhost:8080')
}).parse(process.argv)
const killCallBack: Array<Function> = []
if (!program.remixIde) {
console.log('\x1b[31m%s\x1b[0m', '[ERR] URL Remix IDE instance has to be provided.')
}
console.log('\x1b[33m%s\x1b[0m', '[WARN] You may now only use IDE at ' + program.remixIde + ' to connect to that instance')
if (program.sharedFolder) {
console.log('\x1b[33m%s\x1b[0m', '[WARN] Any application that runs on your computer can potentially read from and write to all files in the directory.')
console.log('\x1b[33m%s\x1b[0m', '[WARN] Symbolic links are not forwarded to Remix IDE\n')
try {
const sharedFolderClient = new servicesList['sharedfolder']()
const websocketHandler = new WebSocket(65520, { remixIdeUrl: program.remixIde }, sharedFolderClient)
websocketHandler.start((ws: WS) => {
sharedFolderClient.setWebSocket(ws)
sharedFolderClient.setupNotifications(program.sharedFolder)
sharedFolderClient.sharedFolder(program.sharedFolder, program.readOnly || false)
})
killCallBack.push(websocketHandler.close.bind(websocketHandler))
} catch(error) {
throw new Error(error)
(async () => {
const program = require('commander')
program
.usage('-s <shared folder>')
.description('Provide a two-way connection between the local computer and Remix IDE')
.option('--remix-ide <url>', 'URL of remix instance allowed to connect to this web sockect connection')
.option('-s, --shared-folder <path>', 'Folder to share with Remix IDE')
.option('--read-only', 'Treat shared folder as read-only (experimental)')
.on('--help', function(){
console.log('\nExample:\n\n remixd -s ./ --remix-ide http://localhost:8080')
}).parse(process.argv)
const killCallBack: Array<Function> = []
if (!program.remixIde) {
console.log('\x1b[31m%s\x1b[0m', '[ERR] URL Remix IDE instance has to be provided.')
}
const isValid = await isValidOrigin(program.remixIde)
if (!isValid) {
console.log('\x1b[33m%s\x1b[0m', '[WARN] You are using IDE from an unsupported origin.')
console.log('\x1b[33m%s\x1b[0m', 'Check https://gist.github.com/EthereumRemix/091ccc57986452bbb33f57abfb13d173 for list of all supported origins.\n')
}
console.log('\x1b[33m%s\x1b[0m', '[WARN] You may now only use IDE at ' + program.remixIde + ' to connect to that instance')
if (program.sharedFolder) {
console.log('\x1b[33m%s\x1b[0m', '[WARN] Any application that runs on your computer can potentially read from and write to all files in the directory.')
console.log('\x1b[33m%s\x1b[0m', '[WARN] Symbolic links are not forwarded to Remix IDE\n')
try {
const sharedFolderClient = new servicesList['sharedfolder']()
const websocketHandler = new WebSocket(65520, { remixIdeUrl: program.remixIde }, sharedFolderClient)
websocketHandler.start((ws: WS) => {
sharedFolderClient.setWebSocket(ws)
sharedFolderClient.setupNotifications(program.sharedFolder)
sharedFolderClient.sharedFolder(program.sharedFolder, program.readOnly || false)
})
killCallBack.push(websocketHandler.close.bind(websocketHandler))
} catch(error) {
throw new Error(error)
}
}
// kill
function kill () {
for (const k in killCallBack) {
try {
killCallBack[k]()
} catch (e) {
console.log(e)
}
}
}
}
process.on('SIGINT', kill) // catch ctrl-c
process.on('SIGTERM', kill) // catch kill
process.on('exit', kill)
// kill
function kill () {
for (const k in killCallBack) {
async function isValidOrigin (origin: string): Promise<any> {
const domain = getDomain(origin)
if (!domain) return
try {
killCallBack[k]()
const { data } = await Axios.get('https://gist.githubusercontent.com/EthereumRemix/091ccc57986452bbb33f57abfb13d173/raw/3367e019335746b73288e3710af2922d4c8ef5a3/origins.json') as { data: string[] }
try {
await fs.writeJSON(path.resolve(__dirname + '/origins.json'), { data })
} catch (e) {
console.error(e)
}
return data.includes(origin) ? data.includes(origin) : data.includes(domain)
} catch (e) {
console.log(e)
try {
const origins = require('./origins.json')
const { data } = origins
return data.includes(origin) ? data.includes(origin) : data.includes(domain)
} catch (e) {
return false
}
}
}
}
process.on('SIGINT', kill) // catch ctrl-c
process.on('SIGTERM', kill) // catch kill
process.on('exit', kill)
})()

33
package-lock.json generated

@ -110,6 +110,15 @@
"defer-to-connect": "^1.0.1"
}
},
"@types/axios": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz",
"integrity": "sha1-7CMA++fX3d1+udOr+HmZlkyvzkY=",
"dev": true,
"requires": {
"axios": "*"
}
},
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
@ -143,6 +152,12 @@
"integrity": "sha512-aYNbO+FZ/3KGeQCEkNhHFRIzBOUgc7QvcVNKXbfnhDkSfwUv91JsQQa10rDgKSTSLkXZ1UIyPe4FJJNVgw1xWQ==",
"dev": true
},
"@types/psl": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@types/psl/-/psl-1.1.0.tgz",
"integrity": "sha512-HhZnoLAvI2koev3czVPzBNRYvdrzJGLjQbWZhqFmS9Q6a0yumc5qtfSahBGb5g+6qWvA8iiQktqGkwoIXa/BNQ==",
"dev": true
},
"@types/ws": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.2.6.tgz",
@ -449,6 +464,14 @@
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
"axios": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
"integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -1584,6 +1607,11 @@
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
"dev": true
},
"follow-redirects": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -2926,6 +2954,11 @@
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
"pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",

@ -9,7 +9,7 @@
},
"scripts": {
"test": "echo \"Error: no test specified\"",
"start": "./lib/bin/remixd.js",
"start": "./lib/bin/remixd.js -s ./shared --remix-ide https://remix.ethereum.org/",
"npip": "npip",
"lint": "eslint ./src ./bin --ext .ts",
"build": "tsc -p ./ && chmod +x ./lib/bin/remixd.js",
@ -36,6 +36,7 @@
"@remixproject/plugin-api": "0.3.0-beta.5",
"@remixproject/plugin-utils": "0.3.0-beta.5",
"@remixproject/plugin-ws": "^0.3.0-beta.8",
"axios": "^0.20.0",
"chokidar": "^2.1.8",
"commander": "^2.20.3",
"fs-extra": "^3.0.1",
@ -49,6 +50,7 @@
}
},
"devDependencies": {
"@types/axios": "^0.14.0",
"@types/fs-extra": "^9.0.1",
"@types/node": "^14.0.5",
"@types/ws": "^7.2.4",

@ -76,4 +76,16 @@ function resolveDirectory (dir: string, sharedFolder: string): ResolveDirectory
return ret
}
export { absolutePath, relativePath, walkSync, resolveDirectory }
/**
* returns the absolute path of the given @arg url
*
* @param {String} url - Remix-IDE URL instance
* @return {String} extracted domain name from url
*/
function getDomain(url: string) {
const domainMatch = url.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)/img)
return domainMatch ? domainMatch[0] : null
}
export { absolutePath, relativePath, walkSync, resolveDirectory, getDomain }

@ -1,6 +1,7 @@
import * as WS from 'ws'
import * as http from 'http'
import { WebsocketOpt, SharedFolderClient } from '../types'
import { getDomain } from './utils'
const { createClient } = require('@remixproject/plugin-ws')
@ -52,5 +53,7 @@ export default class WebSocket {
}
function originIsAllowed (origin: string, self: WebSocket): boolean {
return origin === self.opt.remixIdeUrl
console.log('origin: ', origin)
console.log('self.opt.remixIdeUrl: ', self.opt.remixIdeUrl)
return origin === self.opt.remixIdeUrl || origin === getDomain(self.opt.remixIdeUrl)
}

Loading…
Cancel
Save