├── .drone.yml ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── code-of-conduct.md ├── docs ├── .nojekyll ├── assets │ ├── css │ │ ├── main.css │ │ └── main.css.map │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ ├── main.js │ │ └── search.js ├── classes │ ├── _apiservices_analysesservice_.analysesservice.html │ ├── _apiservices_authservice_.authservice.html │ └── _apiservices_clientservice_.clientservice.html ├── globals.html ├── index.html ├── interfaces │ ├── _index_.analysisgroups.html │ ├── _index_.analyzeoptions.html │ ├── _index_.group.html │ ├── _index_.jwttokensinterface.html │ ├── _index_.loginresponse.html │ ├── _index_.statsresponse.html │ ├── _index_.users.html │ ├── _index_.usersresponse.html │ └── _util_validatetoken_.jwtinterface.html └── modules │ ├── _apiservices_analysesservice_.html │ ├── _apiservices_authservice_.html │ ├── _apiservices_clientservice_.html │ ├── _auth_loginuser_.html │ ├── _auth_loginuser_spec_.html │ ├── _http_getrequest_.html │ ├── _http_index_.html │ ├── _http_postrequest_.html │ ├── _index_.html │ ├── _test_analysesclass_analyze_spec_.html │ ├── _test_analysesclass_creategroup_spec_.html │ ├── _test_analysesclass_getanalyseslist_spec_.html │ ├── _test_analysesclass_getanalysisstatus_spec_.html │ ├── _test_analysesclass_getdetectedissues_spec_.html │ ├── _test_analysesclass_getgroupbyid_spec_.html │ ├── _test_analysesclass_getpdf_spec_.html │ ├── _test_analysesclass_groupoperation_spec_.html │ ├── _test_analysesclass_listgroups_spec_.html │ ├── _test_analysesclass_submitbytecode_spec_.html │ ├── _test_analysesclass_submitsourcecode_spec_.html │ ├── _test_authclass_getchallenge_spec_.html │ ├── _test_authclass_getopenapihtml_spec_.html │ ├── _test_authclass_getopenapiyaml_spec_.html │ ├── _test_authclass_getstats_spec_.html │ ├── _test_authclass_getusers_spec_.html │ ├── _test_authclass_getversion_spec_.html │ ├── _test_authclass_loginwithsignature_spec_.html │ ├── _test_authservice_login_spec_.html │ ├── _test_authservice_logout_spec_.html │ ├── _types_index_.html │ ├── _util_errorhandler_.html │ ├── _util_generatecontractsrequests_.html │ ├── _util_getheaders_.html │ ├── _util_mock_.html │ ├── _util_refreshtoken_.html │ └── _util_validatetoken_.html ├── index.ts ├── package-lock.json ├── package.json ├── src ├── apiServices │ ├── AnalysesService.ts │ ├── AuthService.ts │ └── ClientService.ts ├── auth │ ├── loginUser.spec.ts │ └── loginUser.ts ├── external.d.ts ├── http │ ├── getRequest.ts │ ├── index.ts │ └── postRequest.ts ├── index.ts ├── model │ └── response │ │ ├── analysis-list.json │ │ ├── analysis-submission.json │ │ ├── detected-issues.json │ │ ├── openapi.json │ │ └── version.json ├── test │ ├── analysesClass.analyze.spec.ts │ ├── analysesClass.createGroup.spec.ts │ ├── analysesClass.getAnalysesList.spec.ts │ ├── analysesClass.getAnalysisStatus.spec.ts │ ├── analysesClass.getDetectedIssues.spec.ts │ ├── analysesClass.getGroupById.spec.ts │ ├── analysesClass.getPdf.spec.ts │ ├── analysesClass.groupOperation.spec.ts │ ├── analysesClass.listGroups.spec.ts │ ├── analysesClass.submitBytecode.spec.ts │ ├── analysesClass.submitSourcecode.spec.ts │ ├── authClass.getChallenge.spec.ts │ ├── authClass.getOpenApiHTML.spec.ts │ ├── authClass.getOpenApiYAML.spec.ts │ ├── authClass.getStats.spec.ts │ ├── authClass.getUsers.spec.ts │ ├── authClass.getVersion.spec.ts │ ├── authClass.loginWithSignature.spec.ts │ ├── authService.login.spec.ts │ └── authService.logout.spec.ts ├── types │ ├── analysis-list.d.ts │ ├── analysis-submission.d.ts │ ├── detected-issues.d.ts │ ├── index.ts │ ├── openapi.d.ts │ └── version.d.ts └── util │ ├── errorHandler.ts │ ├── generateContractsRequests.ts │ ├── getHeaders.ts │ ├── mock.ts │ ├── refreshToken.ts │ └── validateToken.ts └── tsconfig.json /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | name: default 3 | 4 | platform: 5 | os: linux 6 | arch: amd64 7 | 8 | steps: 9 | 10 | - name: build 11 | image: node:10.15.1 12 | commands: 13 | - npm ci 14 | - npm run test 15 | - npm run build 16 | 17 | - name: npm_publish 18 | image: node:10.15.1 19 | environment: 20 | NPM_TOKEN: 21 | from_secret: NPM_TOKEN 22 | commands: 23 | - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc 24 | - npm publish 25 | when: 26 | event: 27 | - tag 28 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | #root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | max_line_length = 100 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true 6 | }, 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { 9 | "ecmaVersion": "2018", 10 | "sourceType": "module" 11 | }, 12 | "rules": { 13 | "quotes": [ "error", "single" ] 14 | } 15 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .nyc_output 4 | .DS_Store 5 | *.log 6 | .vscode 7 | .idea 8 | dist 9 | compiled 10 | .awcache 11 | .rpt2_cache 12 | .env 13 | tokens.json 14 | __contracts 15 | coverage 16 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | trailingComma: 'all', 4 | singleQuote: true, 5 | printWidth: 120, 6 | tabWidth: 4, 7 | }; 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Instructions 2 | 3 | These steps will guide you through contributing to this project: 4 | 5 | - Fork the repo 6 | - Clone it and install dependencies 7 | 8 | git clone https://github.com/ConsenSys/mythxjs.git 9 | npm install 10 | 11 | Make and commit your changes. Make sure the commands `npm run build` and `npm run test:prod` are working. 12 | 13 | Finally send a [GitHub Pull Request](https://github.com/ConsenSys/mythxjs/compare?expand=1) with a clear list of what you've done (read more [about pull requests](https://help.github.com/articles/about-pull-requests/)). Make sure all of your commits are atomic (one feature per commit). 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-present, ConsenSys 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | npm run build 3 | 4 | test: 5 | npm run test 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MythX JS Library 2 | 3 | [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) 4 | 5 | MythXJS is a Javascript based library for the [Mythx](https://mythx.io/) smart contract security analysis platform. 6 | 7 | The library works out of the box on Node and modern browsers. 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install mythxjs 13 | ``` 14 | 15 | ## Example 16 | 17 | Creating a new instance of the library using ES6 modules and pass in a config object 18 | 19 | ```typescript 20 | import { Client } from 'mythxjs' 21 | 22 | const mythx = new Client({ 23 | username: '', 24 | apiKey: '' 25 | }); 26 | ``` 27 | 28 | Submitting an analysis using bytecode only 29 | 30 | ```typescript 31 | const bytecode = '0xfe' 32 | await mythx.submitBytecode(bytecode) 33 | ``` 34 | 35 | Getting a list of detected issues 36 | 37 | ```typescript 38 | await mythx.getDetectedIssues('1111-2222-3333-4444') 39 | ``` 40 | 41 | ### Logging in with MetaMask 42 | In order to keep MythXJS as lean as possible we do not handle MetaMask integration ourself. Instead we provide two methods: getChallenge() and loginWithSignature() and leave the user handle the MetaMask integration the way they better prefer on their front end. This also lets the user work with their preffered version of `web3`. 43 | 44 | Example using react app and `web3@1.0.0-beta.37`: 45 | ```typescript 46 | const handleSignMessage = (account, data) => { 47 | try { 48 | return new Promise((resolve) => { 49 | const {value} = data.message 50 | if (!account) { 51 | console.error('no-account') 52 | } 53 | const params = [account, JSON.stringify(data)] 54 | web3.currentProvider.send( 55 | { method: 'eth_signTypedData_v3', params, from: account }, 56 | (err, result) => { 57 | if (err || result.error) { 58 | console.error('Error with handling signature.', err) 59 | } 60 | resolve(value + '.' + result.result) 61 | } 62 | ) 63 | }).catch((error) => { 64 | console.error(error) 65 | }) 66 | } catch(err) { 67 | console.error(err) 68 | } 69 | } 70 | 71 | const loginWithMM = async () => { 72 | const accounts = await web3.eth.getAccounts(); 73 | const account = accounts[0] 74 | 75 | const data = await mythx.getChallenge(account.toLowerCase()) 76 | 77 | handleSignMessage(account, data).then( 78 | async (message) => { 79 | // Returns set of tokens 80 | const result = await mythx.loginWithSignature(message) 81 | } 82 | ).catch(err => console.error(err)) 83 | } 84 | ``` 85 | 86 | 87 | ## Documentation 88 | For a complete list of functionality available on the library please check our [docs](https://consensys.github.io/mythxjs/classes/_apiservices_clientservice_.clientservice.html) 89 | 90 | ## Contributing 91 | 92 | Please read [CONTRIBUTING.md](https://github.com/ConsenSys/mythxjs/blob/master/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. 93 | 94 | ## Versioning 95 | 96 | For the versions available, see [the tags on this repository](https://github.com/ConsenSys/mythxjs/tags). 97 | 98 | ## Projects using MythxJS 99 | 100 | - [MythX for VSCode](https://marketplace.visualstudio.com/items?itemName=mirkogarozzo.mythxvsc) 101 | - [truffle security](https://github.com/ConsenSys/truffle-security) 102 | - [remix-mythx-plugin](https://github.com/aquiladev/remix-mythx-plugin) 103 | 104 | ## See also 105 | 106 | - [openapi spec](https://api.mythx.io/v1/openapi) for details of the MythX API. 107 | - [MythX Developer and User Guide](https://docs.mythx.io/) for more information 108 | - [MythX Discord channel](https://discord.gg/kktn8Wt) to join the MythX community. 109 | -------------------------------------------------------------------------------- /code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at alexjovermorales@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConsenSysDiligence/mythxjs/cc04411f2f6dbdc5e521160da7b47a445121ea5d/docs/.nojekyll -------------------------------------------------------------------------------- /docs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConsenSysDiligence/mythxjs/cc04411f2f6dbdc5e521160da7b47a445121ea5d/docs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConsenSysDiligence/mythxjs/cc04411f2f6dbdc5e521160da7b47a445121ea5d/docs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConsenSysDiligence/mythxjs/cc04411f2f6dbdc5e521160da7b47a445121ea5d/docs/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConsenSysDiligence/mythxjs/cc04411f2f6dbdc5e521160da7b47a445121ea5d/docs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/modules/_apiservices_analysesservice_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "apiServices/AnalysesService" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "apiServices/AnalysesService"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 102 |
103 |
104 |
105 |
106 |

Legend

107 |
108 |
    109 |
  • Module
  • 110 |
  • Object literal
  • 111 |
  • Variable
  • 112 |
  • Function
  • 113 |
  • Function with type parameter
  • 114 |
  • Index signature
  • 115 |
  • Type alias
  • 116 |
117 |
    118 |
  • Enumeration
  • 119 |
  • Enumeration member
  • 120 |
  • Property
  • 121 |
  • Method
  • 122 |
123 |
    124 |
  • Interface
  • 125 |
  • Interface with type parameter
  • 126 |
  • Constructor
  • 127 |
  • Property
  • 128 |
  • Method
  • 129 |
  • Index signature
  • 130 |
131 |
    132 |
  • Class
  • 133 |
  • Class with type parameter
  • 134 |
  • Constructor
  • 135 |
  • Property
  • 136 |
  • Method
  • 137 |
  • Accessor
  • 138 |
  • Index signature
  • 139 |
140 |
    141 |
  • Inherited constructor
  • 142 |
  • Inherited property
  • 143 |
  • Inherited method
  • 144 |
  • Inherited accessor
  • 145 |
146 |
    147 |
  • Protected property
  • 148 |
  • Protected method
  • 149 |
  • Protected accessor
  • 150 |
151 |
    152 |
  • Private property
  • 153 |
  • Private method
  • 154 |
  • Private accessor
  • 155 |
156 |
    157 |
  • Static property
  • 158 |
  • Static method
  • 159 |
160 |
161 |
162 |
163 |
164 |

Generated using TypeDoc

165 |
166 |
167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /docs/modules/_apiservices_authservice_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "apiServices/AuthService" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "apiServices/AuthService"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 102 |
103 |
104 |
105 |
106 |

Legend

107 |
108 |
    109 |
  • Module
  • 110 |
  • Object literal
  • 111 |
  • Variable
  • 112 |
  • Function
  • 113 |
  • Function with type parameter
  • 114 |
  • Index signature
  • 115 |
  • Type alias
  • 116 |
117 |
    118 |
  • Enumeration
  • 119 |
  • Enumeration member
  • 120 |
  • Property
  • 121 |
  • Method
  • 122 |
123 |
    124 |
  • Interface
  • 125 |
  • Interface with type parameter
  • 126 |
  • Constructor
  • 127 |
  • Property
  • 128 |
  • Method
  • 129 |
  • Index signature
  • 130 |
131 |
    132 |
  • Class
  • 133 |
  • Class with type parameter
  • 134 |
  • Constructor
  • 135 |
  • Property
  • 136 |
  • Method
  • 137 |
  • Accessor
  • 138 |
  • Index signature
  • 139 |
140 |
    141 |
  • Inherited constructor
  • 142 |
  • Inherited property
  • 143 |
  • Inherited method
  • 144 |
  • Inherited accessor
  • 145 |
146 |
    147 |
  • Protected property
  • 148 |
  • Protected method
  • 149 |
  • Protected accessor
  • 150 |
151 |
    152 |
  • Private property
  • 153 |
  • Private method
  • 154 |
  • Private accessor
  • 155 |
156 |
    157 |
  • Static property
  • 158 |
  • Static method
  • 159 |
160 |
161 |
162 |
163 |
164 |

Generated using TypeDoc

165 |
166 |
167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /docs/modules/_apiservices_clientservice_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "apiServices/ClientService" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "apiServices/ClientService"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 102 |
103 |
104 |
105 |
106 |

Legend

107 |
108 |
    109 |
  • Module
  • 110 |
  • Object literal
  • 111 |
  • Variable
  • 112 |
  • Function
  • 113 |
  • Function with type parameter
  • 114 |
  • Index signature
  • 115 |
  • Type alias
  • 116 |
117 |
    118 |
  • Enumeration
  • 119 |
  • Enumeration member
  • 120 |
  • Property
  • 121 |
  • Method
  • 122 |
123 |
    124 |
  • Interface
  • 125 |
  • Interface with type parameter
  • 126 |
  • Constructor
  • 127 |
  • Property
  • 128 |
  • Method
  • 129 |
  • Index signature
  • 130 |
131 |
    132 |
  • Class
  • 133 |
  • Class with type parameter
  • 134 |
  • Constructor
  • 135 |
  • Property
  • 136 |
  • Method
  • 137 |
  • Accessor
  • 138 |
  • Index signature
  • 139 |
140 |
    141 |
  • Inherited constructor
  • 142 |
  • Inherited property
  • 143 |
  • Inherited method
  • 144 |
  • Inherited accessor
  • 145 |
146 |
    147 |
  • Protected property
  • 148 |
  • Protected method
  • 149 |
  • Protected accessor
  • 150 |
151 |
    152 |
  • Private property
  • 153 |
  • Private method
  • 154 |
  • Private accessor
  • 155 |
156 |
    157 |
  • Static property
  • 158 |
  • Static method
  • 159 |
160 |
161 |
162 |
163 |
164 |

Generated using TypeDoc

165 |
166 |
167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /docs/modules/_auth_loginuser_spec_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "auth/loginUser.spec" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "auth/loginUser.spec"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 86 |
87 |
88 |
89 |
90 |

Legend

91 |
92 |
    93 |
  • Module
  • 94 |
  • Object literal
  • 95 |
  • Variable
  • 96 |
  • Function
  • 97 |
  • Function with type parameter
  • 98 |
  • Index signature
  • 99 |
  • Type alias
  • 100 |
101 |
    102 |
  • Enumeration
  • 103 |
  • Enumeration member
  • 104 |
  • Property
  • 105 |
  • Method
  • 106 |
107 |
    108 |
  • Interface
  • 109 |
  • Interface with type parameter
  • 110 |
  • Constructor
  • 111 |
  • Property
  • 112 |
  • Method
  • 113 |
  • Index signature
  • 114 |
115 |
    116 |
  • Class
  • 117 |
  • Class with type parameter
  • 118 |
  • Constructor
  • 119 |
  • Property
  • 120 |
  • Method
  • 121 |
  • Accessor
  • 122 |
  • Index signature
  • 123 |
124 |
    125 |
  • Inherited constructor
  • 126 |
  • Inherited property
  • 127 |
  • Inherited method
  • 128 |
  • Inherited accessor
  • 129 |
130 |
    131 |
  • Protected property
  • 132 |
  • Protected method
  • 133 |
  • Protected accessor
  • 134 |
135 |
    136 |
  • Private property
  • 137 |
  • Private method
  • 138 |
  • Private accessor
  • 139 |
140 |
    141 |
  • Static property
  • 142 |
  • Static method
  • 143 |
144 |
145 |
146 |
147 |
148 |

Generated using TypeDoc

149 |
150 |
151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/modules/_http_index_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "http/index" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "http/index"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 86 |
87 |
88 |
89 |
90 |

Legend

91 |
92 |
    93 |
  • Module
  • 94 |
  • Object literal
  • 95 |
  • Variable
  • 96 |
  • Function
  • 97 |
  • Function with type parameter
  • 98 |
  • Index signature
  • 99 |
  • Type alias
  • 100 |
101 |
    102 |
  • Enumeration
  • 103 |
  • Enumeration member
  • 104 |
  • Property
  • 105 |
  • Method
  • 106 |
107 |
    108 |
  • Interface
  • 109 |
  • Interface with type parameter
  • 110 |
  • Constructor
  • 111 |
  • Property
  • 112 |
  • Method
  • 113 |
  • Index signature
  • 114 |
115 |
    116 |
  • Class
  • 117 |
  • Class with type parameter
  • 118 |
  • Constructor
  • 119 |
  • Property
  • 120 |
  • Method
  • 121 |
  • Accessor
  • 122 |
  • Index signature
  • 123 |
124 |
    125 |
  • Inherited constructor
  • 126 |
  • Inherited property
  • 127 |
  • Inherited method
  • 128 |
  • Inherited accessor
  • 129 |
130 |
    131 |
  • Protected property
  • 132 |
  • Protected method
  • 133 |
  • Protected accessor
  • 134 |
135 |
    136 |
  • Private property
  • 137 |
  • Private method
  • 138 |
  • Private accessor
  • 139 |
140 |
    141 |
  • Static property
  • 142 |
  • Static method
  • 143 |
144 |
145 |
146 |
147 |
148 |

Generated using TypeDoc

149 |
150 |
151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/modules/_test_analysesclass_getpdf_spec_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "test/analysesClass.getPdf.spec" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "test/analysesClass.getPdf.spec"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Variables

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Variables

84 |
85 | 86 |

Const getRequest

87 |
getRequest: any = require('../http/index')
88 | 93 |
94 |
95 |
96 | 115 |
116 |
117 |
118 |
119 |

Legend

120 |
121 |
    122 |
  • Module
  • 123 |
  • Object literal
  • 124 |
  • Variable
  • 125 |
  • Function
  • 126 |
  • Function with type parameter
  • 127 |
  • Index signature
  • 128 |
  • Type alias
  • 129 |
130 |
    131 |
  • Enumeration
  • 132 |
  • Enumeration member
  • 133 |
  • Property
  • 134 |
  • Method
  • 135 |
136 |
    137 |
  • Interface
  • 138 |
  • Interface with type parameter
  • 139 |
  • Constructor
  • 140 |
  • Property
  • 141 |
  • Method
  • 142 |
  • Index signature
  • 143 |
144 |
    145 |
  • Class
  • 146 |
  • Class with type parameter
  • 147 |
  • Constructor
  • 148 |
  • Property
  • 149 |
  • Method
  • 150 |
  • Accessor
  • 151 |
  • Index signature
  • 152 |
153 |
    154 |
  • Inherited constructor
  • 155 |
  • Inherited property
  • 156 |
  • Inherited method
  • 157 |
  • Inherited accessor
  • 158 |
159 |
    160 |
  • Protected property
  • 161 |
  • Protected method
  • 162 |
  • Protected accessor
  • 163 |
164 |
    165 |
  • Private property
  • 166 |
  • Private method
  • 167 |
  • Private accessor
  • 168 |
169 |
    170 |
  • Static property
  • 171 |
  • Static method
  • 172 |
173 |
174 |
175 |
176 |
177 |

Generated using TypeDoc

178 |
179 |
180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /docs/modules/_test_authclass_getstats_spec_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "test/authClass.getStats.spec" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "test/authClass.getStats.spec"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Variables

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Variables

84 |
85 | 86 |

Const getRequest

87 |
getRequest: any = require('../http/index')
88 | 93 |
94 |
95 |
96 | 115 |
116 |
117 |
118 |
119 |

Legend

120 |
121 |
    122 |
  • Module
  • 123 |
  • Object literal
  • 124 |
  • Variable
  • 125 |
  • Function
  • 126 |
  • Function with type parameter
  • 127 |
  • Index signature
  • 128 |
  • Type alias
  • 129 |
130 |
    131 |
  • Enumeration
  • 132 |
  • Enumeration member
  • 133 |
  • Property
  • 134 |
  • Method
  • 135 |
136 |
    137 |
  • Interface
  • 138 |
  • Interface with type parameter
  • 139 |
  • Constructor
  • 140 |
  • Property
  • 141 |
  • Method
  • 142 |
  • Index signature
  • 143 |
144 |
    145 |
  • Class
  • 146 |
  • Class with type parameter
  • 147 |
  • Constructor
  • 148 |
  • Property
  • 149 |
  • Method
  • 150 |
  • Accessor
  • 151 |
  • Index signature
  • 152 |
153 |
    154 |
  • Inherited constructor
  • 155 |
  • Inherited property
  • 156 |
  • Inherited method
  • 157 |
  • Inherited accessor
  • 158 |
159 |
    160 |
  • Protected property
  • 161 |
  • Protected method
  • 162 |
  • Protected accessor
  • 163 |
164 |
    165 |
  • Private property
  • 166 |
  • Private method
  • 167 |
  • Private accessor
  • 168 |
169 |
    170 |
  • Static property
  • 171 |
  • Static method
  • 172 |
173 |
174 |
175 |
176 |
177 |

Generated using TypeDoc

178 |
179 |
180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /docs/modules/_test_authclass_getusers_spec_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "test/authClass.getUsers.spec" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "test/authClass.getUsers.spec"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Variables

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Variables

84 |
85 | 86 |

Const getRequest

87 |
getRequest: any = require('../http/index')
88 | 93 |
94 |
95 |
96 | 115 |
116 |
117 |
118 |
119 |

Legend

120 |
121 |
    122 |
  • Module
  • 123 |
  • Object literal
  • 124 |
  • Variable
  • 125 |
  • Function
  • 126 |
  • Function with type parameter
  • 127 |
  • Index signature
  • 128 |
  • Type alias
  • 129 |
130 |
    131 |
  • Enumeration
  • 132 |
  • Enumeration member
  • 133 |
  • Property
  • 134 |
  • Method
  • 135 |
136 |
    137 |
  • Interface
  • 138 |
  • Interface with type parameter
  • 139 |
  • Constructor
  • 140 |
  • Property
  • 141 |
  • Method
  • 142 |
  • Index signature
  • 143 |
144 |
    145 |
  • Class
  • 146 |
  • Class with type parameter
  • 147 |
  • Constructor
  • 148 |
  • Property
  • 149 |
  • Method
  • 150 |
  • Accessor
  • 151 |
  • Index signature
  • 152 |
153 |
    154 |
  • Inherited constructor
  • 155 |
  • Inherited property
  • 156 |
  • Inherited method
  • 157 |
  • Inherited accessor
  • 158 |
159 |
    160 |
  • Protected property
  • 161 |
  • Protected method
  • 162 |
  • Protected accessor
  • 163 |
164 |
    165 |
  • Private property
  • 166 |
  • Private method
  • 167 |
  • Private accessor
  • 168 |
169 |
    170 |
  • Static property
  • 171 |
  • Static method
  • 172 |
173 |
174 |
175 |
176 |
177 |

Generated using TypeDoc

178 |
179 |
180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /docs/modules/_test_authclass_getversion_spec_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "test/authClass.getVersion.spec" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "test/authClass.getVersion.spec"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Variables

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Variables

84 |
85 | 86 |

Const getRequest

87 |
getRequest: any = require('../http/index')
88 | 93 |
94 |
95 |
96 | 115 |
116 |
117 |
118 |
119 |

Legend

120 |
121 |
    122 |
  • Module
  • 123 |
  • Object literal
  • 124 |
  • Variable
  • 125 |
  • Function
  • 126 |
  • Function with type parameter
  • 127 |
  • Index signature
  • 128 |
  • Type alias
  • 129 |
130 |
    131 |
  • Enumeration
  • 132 |
  • Enumeration member
  • 133 |
  • Property
  • 134 |
  • Method
  • 135 |
136 |
    137 |
  • Interface
  • 138 |
  • Interface with type parameter
  • 139 |
  • Constructor
  • 140 |
  • Property
  • 141 |
  • Method
  • 142 |
  • Index signature
  • 143 |
144 |
    145 |
  • Class
  • 146 |
  • Class with type parameter
  • 147 |
  • Constructor
  • 148 |
  • Property
  • 149 |
  • Method
  • 150 |
  • Accessor
  • 151 |
  • Index signature
  • 152 |
153 |
    154 |
  • Inherited constructor
  • 155 |
  • Inherited property
  • 156 |
  • Inherited method
  • 157 |
  • Inherited accessor
  • 158 |
159 |
    160 |
  • Protected property
  • 161 |
  • Protected method
  • 162 |
  • Protected accessor
  • 163 |
164 |
    165 |
  • Private property
  • 166 |
  • Private method
  • 167 |
  • Private accessor
  • 168 |
169 |
    170 |
  • Static property
  • 171 |
  • Static method
  • 172 |
173 |
174 |
175 |
176 |
177 |

Generated using TypeDoc

178 |
179 |
180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /docs/modules/_test_authservice_logout_spec_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "test/authService.logout.spec" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "test/authService.logout.spec"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Variables

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Variables

84 |
85 | 86 |

Const postRequest

87 |
postRequest: any = require('../http/index')
88 | 93 |
94 |
95 |
96 | 115 |
116 |
117 |
118 |
119 |

Legend

120 |
121 |
    122 |
  • Module
  • 123 |
  • Object literal
  • 124 |
  • Variable
  • 125 |
  • Function
  • 126 |
  • Function with type parameter
  • 127 |
  • Index signature
  • 128 |
  • Type alias
  • 129 |
130 |
    131 |
  • Enumeration
  • 132 |
  • Enumeration member
  • 133 |
  • Property
  • 134 |
  • Method
  • 135 |
136 |
    137 |
  • Interface
  • 138 |
  • Interface with type parameter
  • 139 |
  • Constructor
  • 140 |
  • Property
  • 141 |
  • Method
  • 142 |
  • Index signature
  • 143 |
144 |
    145 |
  • Class
  • 146 |
  • Class with type parameter
  • 147 |
  • Constructor
  • 148 |
  • Property
  • 149 |
  • Method
  • 150 |
  • Accessor
  • 151 |
  • Index signature
  • 152 |
153 |
    154 |
  • Inherited constructor
  • 155 |
  • Inherited property
  • 156 |
  • Inherited method
  • 157 |
  • Inherited accessor
  • 158 |
159 |
    160 |
  • Protected property
  • 161 |
  • Protected method
  • 162 |
  • Protected accessor
  • 163 |
164 |
    165 |
  • Private property
  • 166 |
  • Private method
  • 167 |
  • Private accessor
  • 168 |
169 |
    170 |
  • Static property
  • 171 |
  • Static method
  • 172 |
173 |
174 |
175 |
176 |
177 |

Generated using TypeDoc

178 |
179 |
180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /docs/modules/_types_index_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "types/index" | mythxjs 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "types/index"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 86 |
87 |
88 |
89 |
90 |

Legend

91 |
92 |
    93 |
  • Module
  • 94 |
  • Object literal
  • 95 |
  • Variable
  • 96 |
  • Function
  • 97 |
  • Function with type parameter
  • 98 |
  • Index signature
  • 99 |
  • Type alias
  • 100 |
101 |
    102 |
  • Enumeration
  • 103 |
  • Enumeration member
  • 104 |
  • Property
  • 105 |
  • Method
  • 106 |
107 |
    108 |
  • Interface
  • 109 |
  • Interface with type parameter
  • 110 |
  • Constructor
  • 111 |
  • Property
  • 112 |
  • Method
  • 113 |
  • Index signature
  • 114 |
115 |
    116 |
  • Class
  • 117 |
  • Class with type parameter
  • 118 |
  • Constructor
  • 119 |
  • Property
  • 120 |
  • Method
  • 121 |
  • Accessor
  • 122 |
  • Index signature
  • 123 |
124 |
    125 |
  • Inherited constructor
  • 126 |
  • Inherited property
  • 127 |
  • Inherited method
  • 128 |
  • Inherited accessor
  • 129 |
130 |
    131 |
  • Protected property
  • 132 |
  • Protected method
  • 133 |
  • Protected accessor
  • 134 |
135 |
    136 |
  • Private property
  • 137 |
  • Private method
  • 138 |
  • Private accessor
  • 139 |
140 |
    141 |
  • Static property
  • 142 |
  • Static method
  • 143 |
144 |
145 |
146 |
147 |
148 |

Generated using TypeDoc

149 |
150 |
151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export { ClientService as Client } from './src/apiServices/ClientService' 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mythxjs", 3 | "version": "1.3.13", 4 | "description": "Mythxjs is a library for the MythX smart contract security analysis platform.", 5 | "//": [ 6 | " ## ## ## ## ######## ## ## ## ## ## ###### ", 7 | " ### ### ## ## ## ## ## ## ## ## ## ## ", 8 | " #### #### #### ## ## ## ## ## ## ## ", 9 | " ## ### ## ## ## ######### ### ## ###### ", 10 | " ## ## ## ## ## ## ## ## ## ## ## ", 11 | " ## ## ## ## ## ## ## ## ## ## ## ## ", 12 | " ## ## ## ## ## ## ## ## ###### ###### " 13 | ], 14 | "keywords": [ 15 | "MythX", 16 | "Smart Contract", 17 | "Ethereum", 18 | "Blockchain", 19 | "Security" 20 | ], 21 | "author": "Mirko Garozzo", 22 | "homepage": "https://github.com/ConsenSys/mythxjs", 23 | "repository": "https://github.com/ConsenSys/mythxjs.git", 24 | "bugs": "https://github.com/ConsenSys/mythxjs/issues", 25 | "license": "MIT", 26 | "main": "dist/index.js", 27 | "types": "dist/index.d.ts", 28 | "scripts": { 29 | "build": "tsc", 30 | "test": "nyc mocha -r ts-node/register src/**/*.spec.ts", 31 | "precommit": "lint-staged", 32 | "docs": "typedoc --out docs src" 33 | }, 34 | "lint-staged": { 35 | "*.ts": [ 36 | "prettier --write", 37 | "eslint --fix", 38 | "git add" 39 | ], 40 | "*.js": [ 41 | "eslint --fix", 42 | "git add" 43 | ] 44 | }, 45 | "nyc": { 46 | "include": [ 47 | "src/*.ts", 48 | "src/**/*.ts" 49 | ], 50 | "exclude": [ 51 | "src/**/*.spec.ts" 52 | ], 53 | "extension": [ 54 | ".ts" 55 | ], 56 | "require": [ 57 | "ts-node/register" 58 | ], 59 | "reporter": [ 60 | "text-summary", 61 | "html" 62 | ] 63 | }, 64 | "devDependencies": { 65 | "@types/chai": "^4.1.7", 66 | "@types/es6-promise": "^3.3.0", 67 | "@types/mocha": "^5.2.7", 68 | "@types/node": "^12.0.2", 69 | "@types/sinon": "^7.0.11", 70 | "@types/sinon-chai": "^3.2.2", 71 | "@typescript-eslint/eslint-plugin": "^1.9.0", 72 | "@typescript-eslint/parser": "^1.9.0", 73 | "chai": "^4.2.0", 74 | "eslint": "^5.16.0", 75 | "eslint-config-prettier": "^4.3.0", 76 | "eslint-plugin-prettier": "^3.1.0", 77 | "husky": "^2.3.0", 78 | "lint-staged": "^8.1.7", 79 | "mocha": "^6.1.4", 80 | "nyc": "^14.1.1", 81 | "prettier": "^1.17.1", 82 | "sinon": "^7.3.2", 83 | "sinon-chai": "^3.3.0", 84 | "ts-loader": "^5.4.3", 85 | "ts-node": "^8.1.0", 86 | "typedoc": "^0.14.2", 87 | "typescript": "^3.4.4" 88 | }, 89 | "dependencies": { 90 | "axios": "^0.25.0", 91 | "chai-as-promised": "^7.1.1", 92 | "jsonwebtoken": "^8.5.1" 93 | }, 94 | "husky": { 95 | "hooks": { 96 | "pre-commit": "npm run build && npm test && lint-staged" 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/apiServices/AnalysesService.ts: -------------------------------------------------------------------------------- 1 | import { AnalysisGroups, AnalyzeOptions, Group, JwtTokensInterface } from '..' 2 | import { AnalysisList, AnalysisSubmission, DetectedIssues } from '../types' 3 | import { 4 | generateAnalysisRequest, 5 | generateBytecodeRequest, 6 | generateSourceCodeRequest, 7 | } from '../util/generateContractsRequests' 8 | import { getRequest, postRequest } from '../http' 9 | 10 | import { ClientService } from './ClientService' 11 | import { errorHandler } from '../util/errorHandler' 12 | import { getHeaders } from '../util/getHeaders' 13 | import { isTokenValid } from '../util/validateToken' 14 | 15 | export class AnalysesService { 16 | private API_URL: string = ClientService.MYTHX_API_ENVIRONMENT 17 | private toolName: string 18 | 19 | constructor(jwtTokens: JwtTokensInterface, toolName: string = 'MythXJS') { 20 | if (isTokenValid(jwtTokens.access)) { 21 | ClientService.jwtTokens = jwtTokens as JwtTokensInterface 22 | } else { 23 | throw new Error('Access token has expired or is invalid! Please login again.') 24 | } 25 | this.toolName = toolName 26 | } 27 | 28 | public async getAnalysesList(): Promise { 29 | try { 30 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 31 | this.setCredentials(tokens) 32 | 33 | const result = await getRequest(`${this.API_URL}/analyses`, headers) 34 | const analysisList: AnalysisList = result.data 35 | 36 | return analysisList 37 | } catch (err) { 38 | errorHandler(err) 39 | throw err 40 | } 41 | } 42 | 43 | public async getAnalysisStatus(uuid: string): Promise { 44 | try { 45 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 46 | this.setCredentials(tokens) 47 | 48 | const result = await getRequest(`${this.API_URL}/analyses/${uuid}`, headers) 49 | const analysisRes: AnalysisSubmission = result.data 50 | 51 | return analysisRes 52 | } catch (err) { 53 | errorHandler(err) 54 | throw err 55 | } 56 | } 57 | 58 | public async getDetectedIssues(uuid: string): Promise { 59 | try { 60 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 61 | this.setCredentials(tokens) 62 | 63 | const getStatus = await this.getAnalysisStatus(uuid) 64 | if (getStatus.status === 'Queued' || getStatus.status === 'In progress') { 65 | await new Promise(resolve => { 66 | const timer = setInterval(async () => { 67 | const analysisReq = await this.getAnalysisStatus(uuid) 68 | if (analysisReq.status === 'Finished' || analysisReq.status === 'Error') { 69 | clearInterval(timer) 70 | resolve('done') 71 | } 72 | }, 5000) 73 | }) 74 | } 75 | 76 | const result = await getRequest(`${this.API_URL}/analyses/${uuid}/issues`, headers) 77 | const detectedIssues: DetectedIssues = result.data 78 | 79 | return detectedIssues 80 | } catch (err) { 81 | errorHandler(err) 82 | throw err 83 | } 84 | } 85 | 86 | public async submitBytecode(bytecode: string): Promise { 87 | try { 88 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 89 | this.setCredentials(tokens) 90 | 91 | const request = generateBytecodeRequest(bytecode, this.toolName) 92 | 93 | const result = await postRequest(`${this.API_URL}/analyses`, request, headers) 94 | const analysisRes: AnalysisSubmission = result.data 95 | 96 | return analysisRes 97 | } catch (err) { 98 | errorHandler(err) 99 | throw err 100 | } 101 | } 102 | 103 | public async submitSourceCode( 104 | sourceCode: string, 105 | contractName: string, 106 | propertyChecking: boolean = false, 107 | ): Promise { 108 | try { 109 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 110 | this.setCredentials(tokens) 111 | 112 | const request = generateSourceCodeRequest(sourceCode, contractName, this.toolName, propertyChecking) 113 | 114 | const result = await postRequest(`${this.API_URL}/analyses`, request, headers) 115 | const analysisRes: AnalysisSubmission = result.data 116 | 117 | return analysisRes 118 | } catch (err) { 119 | errorHandler(err) 120 | throw err 121 | } 122 | } 123 | 124 | public async analyze(options: AnalyzeOptions, propertyChecking?: boolean): Promise { 125 | try { 126 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 127 | this.setCredentials(tokens) 128 | 129 | const request = generateAnalysisRequest(options, this.toolName, propertyChecking) 130 | 131 | const result = await postRequest(`${this.API_URL}/analyses`, request, headers) 132 | const analysisRes: AnalysisSubmission = result.data 133 | 134 | return analysisRes 135 | } catch (err) { 136 | errorHandler(err) 137 | throw err 138 | } 139 | } 140 | 141 | public async getPdf(uuid: string): Promise { 142 | try { 143 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 144 | this.setCredentials(tokens) 145 | 146 | const result = await getRequest(`${this.API_URL}/analyses/${uuid}/pdf-report`, headers) 147 | const pdfRes: any = result.data 148 | 149 | return pdfRes 150 | } catch (err) { 151 | errorHandler(err) 152 | throw err 153 | } 154 | } 155 | 156 | public async listGroups(queryString?): Promise { 157 | try { 158 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 159 | this.setCredentials(tokens) 160 | 161 | const result = await getRequest(`${this.API_URL}/analysis-groups?${queryString}`, headers) 162 | const groupsRes: AnalysisGroups = result.data 163 | 164 | return groupsRes 165 | } catch (err) { 166 | errorHandler(err) 167 | throw err 168 | } 169 | } 170 | 171 | public async getGroupById(groupId: string) { 172 | try { 173 | if (!groupId) { 174 | throw new Error('MythXJS: Group ID is required to perform this operation') 175 | } 176 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 177 | this.setCredentials(tokens) 178 | 179 | const result = await getRequest(`${this.API_URL}/analysis-groups/${groupId}`, headers) 180 | const groupRes: Group = result.data 181 | 182 | return groupRes 183 | } catch (err) { 184 | errorHandler(err) 185 | throw err 186 | } 187 | } 188 | 189 | public async createGroup(groupName?: string): Promise { 190 | try { 191 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 192 | this.setCredentials(tokens) 193 | 194 | const body = groupName ? { groupName: groupName } : null 195 | 196 | const result = await postRequest(`${this.API_URL}/analysis-groups`, body, headers) 197 | const groupRes: Group = result.data 198 | 199 | return groupRes 200 | } catch (err) { 201 | errorHandler(err) 202 | throw err 203 | } 204 | } 205 | 206 | public async groupOperation(groupId: string, operationType?: string): Promise { 207 | try { 208 | if (!groupId) { 209 | throw new Error('MythXJS: Group ID is required to perform this operation') 210 | } 211 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 212 | this.setCredentials(tokens) 213 | 214 | const body = operationType ? { type: operationType } : 'seal_group' 215 | 216 | const result = await postRequest(`${this.API_URL}/analysis-groups/${groupId}`, body, headers) 217 | const groupRes: Group = result.data 218 | 219 | return groupRes 220 | } catch (err) { 221 | errorHandler(err) 222 | throw err 223 | } 224 | } 225 | 226 | private setCredentials(tokens: JwtTokensInterface) { 227 | ClientService.jwtTokens.access = tokens.access 228 | ClientService.jwtTokens.refresh = tokens.refresh 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/apiServices/AuthService.ts: -------------------------------------------------------------------------------- 1 | import { ClientService } from './ClientService' 2 | 3 | import { postRequest, getRequest } from '../http' 4 | 5 | import { loginUser } from '../auth/loginUser' 6 | 7 | import { getHeaders } from '../util/getHeaders' 8 | import { errorHandler } from '../util/errorHandler' 9 | 10 | import { JwtTokensInterface, StatsResponse, UsersResponse } from '..' 11 | 12 | import { Openapi, Version } from '../types' 13 | 14 | export class AuthService { 15 | public ethAddress: string 16 | public password: string 17 | private API_URL = ClientService.MYTHX_API_ENVIRONMENT 18 | 19 | constructor(ethAddress?: string, password?: string) { 20 | this.ethAddress = ethAddress as string 21 | this.password = password as string 22 | } 23 | 24 | public async login(ethAddress?: string, password?: string): Promise { 25 | try { 26 | if (ethAddress && password) { 27 | this.ethAddress = ethAddress 28 | this.password = password 29 | } 30 | const result = await loginUser(this.ethAddress, this.password, `${this.API_URL}/auth/login`) 31 | const tokens: JwtTokensInterface = result.data.jwtTokens 32 | this.setCredentials(tokens) 33 | 34 | return tokens 35 | } catch (err) { 36 | errorHandler(err) 37 | throw err 38 | } 39 | } 40 | 41 | /** 42 | * Login to the API using metamask challenge result message. 43 | * In order to get the object containing the message, use `getChallenge` and handle Metamask login in the frontend. 44 | * @param signature message.value property contained in object returned from `getChallenge`. 45 | * @param provider pass a provider value for the HTTP headers. If nothing is passed defaults to MetaMask 46 | * @return {Promise} Returns an object containing two tokens (access+refresh) that can be saved in storage. 47 | */ 48 | public async loginWithSignature(signature: string, provider: string = 'MetaMask'): Promise { 49 | try { 50 | const headers = { 51 | Authorization: `${provider} ${signature}`, 52 | } 53 | const result = await postRequest(`${this.API_URL}/auth/login`, null, headers) 54 | const tokens: JwtTokensInterface = result.data.jwtTokens 55 | this.setCredentials(tokens) 56 | 57 | return tokens 58 | } catch (err) { 59 | errorHandler(err) 60 | throw err 61 | } 62 | } 63 | 64 | public async logout(): Promise<{}> { 65 | if (this.isUserLoggedIn()) { 66 | try { 67 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 68 | this.setCredentials(tokens) 69 | 70 | const result = await postRequest(`${this.API_URL}/auth/logout`, {}, headers) 71 | ClientService.jwtTokens.access = ClientService.jwtTokens.refresh = '' 72 | 73 | return result.data 74 | } catch (err) { 75 | errorHandler(err) 76 | throw err 77 | } 78 | } else { 79 | throw new Error('MythxJS no valid token found. Please login') 80 | } 81 | } 82 | 83 | public async getVersion(): Promise { 84 | try { 85 | const result = await getRequest(`${this.API_URL}/version`, null) 86 | const version: Version = result.data 87 | 88 | return version 89 | } catch (err) { 90 | errorHandler(err) 91 | throw err 92 | } 93 | } 94 | 95 | public async getOpenApiHTML(): Promise { 96 | try { 97 | const result = await getRequest(`${this.API_URL}/openapi`, null) 98 | const openApi: Openapi = result.data 99 | 100 | return openApi 101 | } catch (err) { 102 | errorHandler(err) 103 | throw err 104 | } 105 | } 106 | 107 | public async getOpenApiYAML(): Promise { 108 | try { 109 | const result = await getRequest(`${this.API_URL}/openapi.yaml`, null) 110 | 111 | return result.data 112 | } catch (err) { 113 | errorHandler(err) 114 | } 115 | } 116 | 117 | public async getStats(queryString?: string): Promise | void> { 118 | if (this.isUserLoggedIn()) { 119 | try { 120 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 121 | this.setCredentials(tokens) 122 | 123 | const result = await getRequest(`${this.API_URL}/stats/users-analyses?${queryString}`, headers) 124 | const stats: Array = result.data 125 | 126 | return stats 127 | } catch (err) { 128 | errorHandler(err) 129 | } 130 | } else { 131 | throw new Error('MythxJS no valid token found. Please login.') 132 | } 133 | } 134 | 135 | /** 136 | * Generates authentication challenge (Metamask only for now). 137 | * The Metamask flow needs to be handled on the front end since MythXJS does not have Web3 dependencies. 138 | * @param ethAddress Ethereum address for Mythx account 139 | * @returns Resolves with API response or throw error 140 | */ 141 | public async getChallenge(ethAddress?: string): Promise { 142 | try { 143 | const address = ethAddress ? ethAddress : this.ethAddress 144 | const result = await getRequest(`${this.API_URL}/auth/challenge?ethAddress=${address}`, {}) 145 | 146 | return result.data 147 | } catch (err) { 148 | errorHandler(err) 149 | } 150 | } 151 | 152 | /** 153 | * Retrieve list of registred API users or just caller user object if no required permission. 154 | * @param queryString Query string for detailed list (query parameters: offset, orderBy, email, ethAddress) 155 | * @returns Resolves with API response or throw error 156 | */ 157 | 158 | public async getUsers(queryString: string = ''): Promise { 159 | if (this.isUserLoggedIn()) { 160 | try { 161 | const { headers, tokens } = await getHeaders(ClientService.jwtTokens) 162 | this.setCredentials(tokens) 163 | 164 | const result = await getRequest(`${this.API_URL}/users?${queryString}`, headers) 165 | const users: UsersResponse = result.data 166 | 167 | return users 168 | } catch (err) { 169 | errorHandler(err) 170 | throw err 171 | } 172 | } else { 173 | throw new Error('MythxJS no valid token found. Please login.') 174 | } 175 | } 176 | 177 | private isUserLoggedIn() { 178 | return !!ClientService.jwtTokens.access 179 | } 180 | 181 | private setCredentials(tokens: JwtTokensInterface) { 182 | ClientService.jwtTokens.access = tokens.access 183 | ClientService.jwtTokens.refresh = tokens.refresh 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/auth/loginUser.spec.ts: -------------------------------------------------------------------------------- 1 | // import { expect } from 'chai' 2 | // export { stub } from 'sinon' 3 | 4 | // import { loginUser } from './loginUser' 5 | 6 | // describe('loginUser', () => { 7 | // it('is a function', () => { 8 | // expect(loginUser).to.be.a('function') 9 | // }) 10 | // }) -------------------------------------------------------------------------------- /src/auth/loginUser.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | export async function loginUser(ethAddress: string, password: string, url: string) { 4 | return axios.post(url, { ethAddress, password }) 5 | } -------------------------------------------------------------------------------- /src/external.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'axios' 2 | -------------------------------------------------------------------------------- /src/http/getRequest.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | async function getRequest(url: string, headers: any) { 4 | return axios.get(url, { headers: headers }) 5 | } 6 | 7 | export default getRequest -------------------------------------------------------------------------------- /src/http/index.ts: -------------------------------------------------------------------------------- 1 | export { default as postRequest } from './postRequest' 2 | export { default as getRequest } from './getRequest' 3 | -------------------------------------------------------------------------------- /src/http/postRequest.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | async function postRequest(url: string, body, headers: any) { 4 | return axios.post(url, body, { headers: headers, timeout: 10000 }) 5 | } 6 | 7 | export default postRequest 8 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // BUSINESS OBJECTS 2 | 3 | export interface JwtTokensInterface { 4 | access: string 5 | refresh: string 6 | } 7 | 8 | export interface loginResponse { 9 | jwtTokens: JwtTokensInterface 10 | access: string 11 | refresh: string 12 | } 13 | 14 | export interface StatsResponse { 15 | from: string 16 | interval: string 17 | createdAt: string 18 | type: string 19 | revision: number 20 | data: any 21 | } 22 | 23 | export interface UsersResponse { 24 | total: number 25 | users: Array 26 | } 27 | 28 | interface Users { 29 | id: string 30 | createdAt: string 31 | email: any 32 | ethAddress: string 33 | roles: Array 34 | preferences: any 35 | termsId: string 36 | } 37 | 38 | export interface AnalyzeOptions { 39 | groupId?: string 40 | toolName?: string 41 | noCacheLookup?: boolean 42 | contractName?: string 43 | bytecode?: string 44 | sourceMap?: string 45 | deployedBytecode?: string 46 | deployedSourceMap?: string 47 | mainSource?: string 48 | sources?: any 49 | sourceList?: Array 50 | solcVersion?: string 51 | analysisMode?: string 52 | propertyChecking?: boolean 53 | } 54 | 55 | export interface AnalysisGroups { 56 | groups: Array 57 | total: number 58 | } 59 | 60 | export interface Group { 61 | id: string 62 | name: string 63 | createdAt: string 64 | createdBy: string 65 | completedAt: string 66 | progress: number 67 | status: string 68 | mainSourceFiles: Array 69 | numAnalyses: {} 70 | numVulnerabilities: {} 71 | } 72 | 73 | export interface ClientConfig { 74 | username: string 75 | apiKey: string 76 | environment?: string 77 | toolName?: string 78 | } 79 | -------------------------------------------------------------------------------- /src/model/response/analysis-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "required": [ 4 | "total", 5 | "analyses" 6 | ], 7 | "properties": { 8 | "total": { 9 | "type": "integer" 10 | }, 11 | "analyses": { 12 | "type": "array", 13 | "items": { 14 | "type": "object", 15 | "required": [ 16 | "apiVersion", 17 | "harveyVersion", 18 | "maruVersion", 19 | "mythrilVersion", 20 | "queueTime", 21 | "runTime", 22 | "status", 23 | "submittedAt", 24 | "submittedBy", 25 | "uuid" 26 | ], 27 | "properties": { 28 | "apiVersion": { 29 | "type": "string" 30 | }, 31 | "harveyVersion": { 32 | "type": "string" 33 | }, 34 | "maruVersion": { 35 | "type": "string" 36 | }, 37 | "mythrilVersion": { 38 | "type": "string" 39 | }, 40 | "queueTime": { 41 | "type": "integer" 42 | }, 43 | "runTime": { 44 | "type": "integer" 45 | }, 46 | "status": { 47 | "type": "string" 48 | }, 49 | "submittedAt": { 50 | "type": "string" 51 | }, 52 | "submittedBy": { 53 | "type": "string" 54 | }, 55 | "uuid": { 56 | "type": "string" 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/model/response/analysis-submission.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "required": [ 4 | "apiVersion", 5 | "queueTime", 6 | "status", 7 | "submittedAt", 8 | "submittedBy", 9 | "uuid" 10 | ], 11 | "properties": { 12 | "apiVersion": { 13 | "type": "string" 14 | }, 15 | "harveyVersion": { 16 | "type": "string" 17 | }, 18 | "maruVersion": { 19 | "type": "string" 20 | }, 21 | "mythrilVersion": { 22 | "type": "string" 23 | }, 24 | "queueTime": { 25 | "type": "integer" 26 | }, 27 | "status": { 28 | "type": "string" 29 | }, 30 | "submittedAt": { 31 | "type": "string" 32 | }, 33 | "submittedBy": { 34 | "type": "string" 35 | }, 36 | "uuid": { 37 | "type": "string" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/model/response/detected-issues.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "array", 4 | "items": { 5 | "type": "object", 6 | "required": [ 7 | "issues", 8 | "sourceType", 9 | "sourceFormat", 10 | "sourceList", 11 | "meta" 12 | ], 13 | "properties": { 14 | "issues": { 15 | "type": "array", 16 | "items": { 17 | "type": "object", 18 | "required": [ 19 | "swcID", 20 | "swcTitle", 21 | "description", 22 | "severity", 23 | "locations", 24 | "extra" 25 | ], 26 | "properties": { 27 | "decodedLocations": { 28 | "type": [ 29 | "null", 30 | "array" 31 | ], 32 | "items": { 33 | "type": "array", 34 | "items": { 35 | "type": "object", 36 | "required": [ 37 | "column", 38 | "line" 39 | ], 40 | "properties": { 41 | "column": { 42 | "type": "integer" 43 | }, 44 | "line": { 45 | "type": "integer" 46 | } 47 | } 48 | } 49 | } 50 | }, 51 | "swcID": { 52 | "type": "string", 53 | "default": "" 54 | }, 55 | "swcTitle": { 56 | "type": "string" 57 | }, 58 | "description": { 59 | "type": "object", 60 | "required": [ 61 | "head", 62 | "tail" 63 | ], 64 | "properties": { 65 | "head": { 66 | "type": "string" 67 | }, 68 | "tail": { 69 | "type": "string" 70 | } 71 | } 72 | }, 73 | "severity": { 74 | "type": [ 75 | "string", 76 | "null" 77 | ] 78 | }, 79 | "locations": { 80 | "type": [ 81 | "array", 82 | "null" 83 | ], 84 | "items": { 85 | "type": "object", 86 | "properties": { 87 | "sourceMap": { 88 | "type": [ 89 | "string", 90 | "null" 91 | ] 92 | }, 93 | "sourceType": { 94 | "type": [ 95 | "string", 96 | "null" 97 | ] 98 | }, 99 | "sourceFormat": { 100 | "type": [ 101 | "string", 102 | "null" 103 | ] 104 | }, 105 | "sourceList": { 106 | "type": [ 107 | "array", 108 | "null" 109 | ], 110 | "items": { 111 | "type": "string" 112 | } 113 | } 114 | } 115 | } 116 | }, 117 | "extra": { 118 | "type": "object" 119 | } 120 | } 121 | } 122 | }, 123 | "sourceType": { 124 | "type": [ 125 | "string", 126 | "null" 127 | ] 128 | }, 129 | "sourceFormat": { 130 | "type": [ 131 | "string", 132 | "null" 133 | ] 134 | }, 135 | "sourceList": { 136 | "type": [ 137 | "array", 138 | "null" 139 | ], 140 | "items": { 141 | "type": "string" 142 | } 143 | }, 144 | "meta": { 145 | "type": "object" 146 | } 147 | } 148 | }, 149 | "definitions": { 150 | "issue": { 151 | "type": "object", 152 | "required": [ 153 | "swcID", 154 | "swcTitle", 155 | "description", 156 | "severity", 157 | "locations", 158 | "extra" 159 | ], 160 | "properties": { 161 | "swcID": { 162 | "type": [ 163 | "null", 164 | "string" 165 | ], 166 | "default": "" 167 | }, 168 | "swcTitle": { 169 | "type": [ 170 | "null", 171 | "string" 172 | ] 173 | }, 174 | "description": { 175 | "type": [ 176 | "null", 177 | "object" 178 | ], 179 | "required": [ 180 | "head", 181 | "tail" 182 | ], 183 | "properties": { 184 | "head": { 185 | "type": "string" 186 | }, 187 | "tail": { 188 | "type": "string" 189 | } 190 | } 191 | }, 192 | "severity": { 193 | "type": [ 194 | "string", 195 | "null" 196 | ] 197 | }, 198 | "locations": { 199 | "type": [ 200 | "array", 201 | "null" 202 | ], 203 | "items": { 204 | "type": "object", 205 | "properties": { 206 | "sourceMap": { 207 | "type": [ 208 | "string", 209 | "null" 210 | ] 211 | }, 212 | "sourceType": { 213 | "type": [ 214 | "string", 215 | "null" 216 | ] 217 | }, 218 | "sourceFormat": { 219 | "type": [ 220 | "string", 221 | "null" 222 | ] 223 | }, 224 | "sourceList": { 225 | "type": [ 226 | "array", 227 | "null" 228 | ], 229 | "items": { 230 | "type": "string" 231 | } 232 | } 233 | } 234 | } 235 | }, 236 | "extra": { 237 | "type": "object" 238 | } 239 | } 240 | } 241 | } 242 | } -------------------------------------------------------------------------------- /src/model/response/openapi.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "required": ["data"], 5 | "properties": { 6 | "data": { 7 | "type": "string" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/model/response/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "required": [ 5 | "api", 6 | "hash", 7 | "harvey", 8 | "maru", 9 | "mythril" 10 | ], 11 | "properties": { 12 | "api": { 13 | "type": "string" 14 | }, 15 | "hash": { 16 | "type": "string" 17 | }, 18 | "harvey": { 19 | "type": "string" 20 | }, 21 | "maru": { 22 | "type": "string" 23 | }, 24 | "mythril": { 25 | "type": "string" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/analysesClass.analyze.spec.ts: -------------------------------------------------------------------------------- 1 | import * as jwt from 'jsonwebtoken' 2 | import * as sinon from 'sinon' 3 | 4 | import { AnalyzeOptions, JwtTokensInterface } from '..' 5 | 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { ClientService } from '../apiServices/ClientService' 8 | import { expect } from 'chai' 9 | 10 | const postRequest = require('../http/index') 11 | 12 | describe('analyze', () => { 13 | const accessToken = { 14 | jti: '', 15 | iss: '', 16 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 17 | userId: '', 18 | iat: 0, 19 | } 20 | const tokens: JwtTokensInterface = { 21 | access: jwt.sign(accessToken, 'secret'), 22 | refresh: 'refresh', 23 | } 24 | 25 | let postRequestStub: any 26 | 27 | let ANALYSES 28 | 29 | beforeEach(() => { 30 | postRequestStub = sinon.stub(postRequest, 'postRequest') 31 | 32 | ANALYSES = new AnalysesService(tokens, 'MythXJTest') 33 | }) 34 | 35 | afterEach(() => { 36 | postRequestStub.restore() 37 | }) 38 | 39 | it('is a function', () => { 40 | expect(ANALYSES.analyze).to.be.a('function') 41 | }) 42 | 43 | it('should return an object with info about submitted analysis', async () => { 44 | const options: AnalyzeOptions = { 45 | groupId: '1111-2222-3333-4444', 46 | contractName: 'contractName', 47 | bytecode: 'bytecode', 48 | sourceMap: 'sourceMap', 49 | deployedBytecode: 'deployedBytecode', 50 | deployedSourceMap: 'deployedSourceMap', 51 | mainSource: 'mainSource', 52 | sources: 'sources', 53 | } 54 | 55 | const expected = { 56 | clientToolName: 'MythXJTest', 57 | noCacheLookup: false, 58 | groupId: '1111-2222-3333-4444', 59 | propertyChecking: false, 60 | data: { 61 | contractName: 'contractName', 62 | bytecode: 'bytecode', 63 | sourceMap: 'sourceMap', 64 | deployedBytecode: 'deployedBytecode', 65 | deployedSourceMap: 'deployedSourceMap', 66 | mainSource: 'mainSource', 67 | sources: 'sources', 68 | }, 69 | } 70 | 71 | const response = { 72 | apiVersion: 'v1.4.14', 73 | harveyVersion: '0.0.22', 74 | maestroVersion: '1.2.11', 75 | maruVersion: '0.4.6', 76 | mythrilVersion: '0.20.4', 77 | queueTime: 10, 78 | runTime: 0, 79 | status: 'Queued', 80 | submittedAt: '2019-05-29T17:41:46.902Z', 81 | submittedBy: '123456789012345678901234', 82 | uuid: '1111-2222-3333-4444', 83 | propertyChecking: false, 84 | } 85 | 86 | postRequestStub.resolves({ 87 | data: response, 88 | }) 89 | 90 | const result = await ANALYSES.analyze(options) 91 | 92 | expect(result).to.equal(response) 93 | expect(postRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses`, expected)).to.be.true 94 | }) 95 | 96 | it('should fail if there is something wrong with the request', async () => { 97 | const options: AnalyzeOptions = { 98 | groupId: '1111-2222-3333-4444', 99 | toolName: 'test', 100 | noCacheLookup: false, 101 | contractName: 'contractName', 102 | bytecode: 'bytecode', 103 | sourceMap: 'sourceMap', 104 | deployedBytecode: 'deployedBytecode', 105 | deployedSourceMap: 'deployedSourceMap', 106 | mainSource: 'mainSource', 107 | sources: 'sources', 108 | } 109 | 110 | postRequestStub.throws('400') 111 | 112 | try { 113 | await ANALYSES.analyze(options) 114 | expect.fail('analyze should be rejected') 115 | } catch (err) { 116 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 117 | } 118 | }) 119 | }) 120 | -------------------------------------------------------------------------------- /src/test/analysesClass.createGroup.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface } from '..' 8 | 9 | const postRequest = require('../http/index') 10 | 11 | describe('createGroup', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let postRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | postRequestStub = sinon.stub(postRequest, 'postRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJTest') 32 | }) 33 | 34 | afterEach(() => { 35 | postRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.createGroup).to.be.a('function') 40 | }) 41 | 42 | it('should return an object with a groupName property', async () => { 43 | const groupName = 'foo' 44 | 45 | const response = { 46 | groupName: 'foo', 47 | } 48 | 49 | postRequestStub.resolves({ 50 | data: response, 51 | }) 52 | 53 | const result = await ANALYSES.createGroup(groupName) 54 | expect(result).to.equal(response) 55 | expect( 56 | postRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analysis-groups`, { 57 | groupName: groupName, 58 | }), 59 | ).to.be.true 60 | }) 61 | 62 | it('should fail if there is something wrong with the request', async () => { 63 | const groupName = 'foo' 64 | 65 | postRequestStub.throws('400') 66 | 67 | try { 68 | await ANALYSES.createGroup(groupName) 69 | expect.fail('createGroup should be rejected') 70 | } catch (err) { 71 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 72 | } 73 | }) 74 | }) 75 | -------------------------------------------------------------------------------- /src/test/analysesClass.getAnalysesList.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface } from '..' 8 | 9 | const getRequest = require('../http/index') 10 | 11 | describe('getAnalysesList', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let getRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | getRequestStub = sinon.stub(getRequest, 'getRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythxJTest') 32 | }) 33 | 34 | afterEach(() => { 35 | getRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.getAnalysesList).to.be.a('function') 40 | }) 41 | 42 | it('should return a list of analysis', async () => { 43 | const response = { 44 | total: 3, 45 | analyses: [], 46 | } 47 | 48 | getRequestStub.resolves({ 49 | data: response, 50 | }) 51 | 52 | const result = await ANALYSES.getAnalysesList() 53 | expect(result).to.deep.equal(response) 54 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses`)).to.be.true 55 | }) 56 | 57 | it('should fail if there is something wrong with the request', async () => { 58 | getRequestStub.throws('400') 59 | 60 | try { 61 | await ANALYSES.getAnalysesList() 62 | expect.fail('getAnalysesList should be rejected') 63 | } catch (err) { 64 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 65 | } 66 | }) 67 | }) 68 | -------------------------------------------------------------------------------- /src/test/analysesClass.getAnalysisStatus.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface } from '..' 8 | 9 | const getRequest = require('../http/index') 10 | 11 | describe('getAnalysisStatus', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let getRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | getRequestStub = sinon.stub(getRequest, 'getRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJSTest') 32 | }) 33 | 34 | afterEach(() => { 35 | getRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.getAnalysisStatus).to.be.a('function') 40 | }) 41 | 42 | it('returns an object containing the analyis status', async () => { 43 | const uuid = '123-456-789' 44 | 45 | const value = { 46 | apiVersion: 'v1.4.14-30-g66a01cd', 47 | harveyVersion: '0.0.21', 48 | maestroVersion: '1.2.10-12-gea51d0b', 49 | maruVersion: '0.4.6', 50 | mythrilVersion: '0.20.4', 51 | queueTime: 88, 52 | runTime: 5358, 53 | status: 'Finished', 54 | submittedAt: '2019-05-10T15:25:44.637Z', 55 | submittedBy: '123456789012345678901234', 56 | uuid: '4ac074eb-fe26-4dc9-bb0c-061da1f00862', 57 | } 58 | 59 | getRequestStub.resolves({ 60 | data: value, 61 | }) 62 | 63 | const result = await ANALYSES.getAnalysisStatus(uuid) 64 | expect(result).to.deep.equal(value) 65 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses/123-456-789`)).to.be.true 66 | }) 67 | 68 | it('should fail if there is something wrong with the request', async () => { 69 | const uuid = '123-456-789' 70 | 71 | getRequestStub.throws('400') 72 | 73 | try { 74 | await ANALYSES.getAnalysisStatus(uuid) 75 | expect.fail('getAnalysisStatus should be rejected') 76 | } catch (err) { 77 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 78 | } 79 | }) 80 | }) 81 | -------------------------------------------------------------------------------- /src/test/analysesClass.getDetectedIssues.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface } from '..' 8 | 9 | const getRequest = require('../http/index') 10 | 11 | describe('getDetectedIssues', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let getRequestStub: any 25 | let getAnalysesStatusStub: any 26 | 27 | let ANALYSES 28 | 29 | beforeEach(() => { 30 | getRequestStub = sinon.stub(getRequest, 'getRequest') 31 | 32 | ANALYSES = new AnalysesService(tokens, 'MythXJS test') 33 | 34 | getAnalysesStatusStub = sinon.stub(ANALYSES, 'getAnalysisStatus') 35 | }) 36 | 37 | afterEach(() => { 38 | getRequestStub.restore() 39 | getAnalysesStatusStub.restore() 40 | }) 41 | 42 | it('is a function', () => { 43 | expect(ANALYSES.getDetectedIssues).to.be.a('function') 44 | }) 45 | 46 | it('returns an object containing the detected issues', async () => { 47 | const uuid = '123-456-789' 48 | 49 | const response = { 50 | issues: [], 51 | } 52 | 53 | getAnalysesStatusStub.resolves({ 54 | status: 'Finished', 55 | }) 56 | 57 | getRequestStub.resolves({ 58 | data: response, 59 | }) 60 | 61 | const result = await ANALYSES.getDetectedIssues(uuid) 62 | expect(result).to.deep.equal(response) 63 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses/123-456-789/issues`)).to.be 64 | .true 65 | }) 66 | 67 | it('should fail if there is something wrong with the request', async () => { 68 | const uuid = '123-456-789' 69 | 70 | getAnalysesStatusStub.resolves({ 71 | status: 'Finished', 72 | }) 73 | 74 | getRequestStub.throws('400') 75 | 76 | try { 77 | await ANALYSES.getDetectedIssues(uuid) 78 | expect.fail('getDetectedIssues should be rejected') 79 | } catch (err) { 80 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 81 | } 82 | }) 83 | }) 84 | -------------------------------------------------------------------------------- /src/test/analysesClass.getGroupById.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface, Group } from '..' 8 | 9 | const getRequest = require('../http/index') 10 | 11 | describe('getGroupById', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let getRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | getRequestStub = sinon.stub(getRequest, 'getRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJS test') 32 | }) 33 | 34 | afterEach(() => { 35 | getRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.getGroupById).to.be.a('function') 40 | }) 41 | 42 | it('should return a group given an ID', async () => { 43 | const groupId = '1111-2222-3333-4444' 44 | 45 | const response: Group = { 46 | id: 'string', 47 | name: 'string', 48 | createdAt: '2019-11-19T15:40:12Z', 49 | createdBy: 'string', 50 | completedAt: '2019-11-19T15:40:12Z', 51 | progress: 0, 52 | status: 'opened', 53 | mainSourceFiles: ['string'], 54 | numAnalyses: { 55 | total: 0, 56 | queued: 0, 57 | running: 0, 58 | failed: 0, 59 | finished: 0, 60 | }, 61 | numVulnerabilities: { 62 | high: 0, 63 | medium: 0, 64 | low: 0, 65 | none: 0, 66 | }, 67 | } 68 | 69 | getRequestStub.resolves({ 70 | data: response, 71 | }) 72 | 73 | const result = await ANALYSES.getGroupById(groupId) 74 | expect(result).to.deep.equal(response) 75 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analysis-groups/${groupId}`)).to.be 76 | .true 77 | }) 78 | 79 | it('should fail if there is something wrong with the request', async () => { 80 | const groupId = '1111-2222-3333-4444' 81 | 82 | getRequestStub.throws('400') 83 | 84 | try { 85 | await ANALYSES.getGroupById(groupId) 86 | expect.fail('gretGroupById should be rejected') 87 | } catch (err) { 88 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 89 | } 90 | }) 91 | }) 92 | -------------------------------------------------------------------------------- /src/test/analysesClass.getPdf.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface } from '..' 8 | 9 | const getRequest = require('../http/index') 10 | 11 | describe('getPdf', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let getRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | getRequestStub = sinon.stub(getRequest, 'getRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJS test') 32 | }) 33 | 34 | afterEach(() => { 35 | getRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.getPdf).to.be.a('function') 40 | }) 41 | 42 | it('should return a request with a blob of pdf', async () => { 43 | const uuid = '1111-2222-3333-4444' 44 | 45 | const response = [ 46 | { 47 | foo: 'foo', 48 | }, 49 | ] 50 | 51 | getRequestStub.resolves({ 52 | data: response, 53 | }) 54 | 55 | const result = await ANALYSES.getPdf(uuid) 56 | expect(result).to.deep.equal(response) 57 | expect( 58 | getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses/1111-2222-3333-4444/pdf-report`), 59 | ).to.be.true 60 | }) 61 | 62 | it('should fail if there is something wrong with the request', async () => { 63 | const uuid = '123-456-789' 64 | 65 | getRequestStub.throws('400') 66 | 67 | try { 68 | await ANALYSES.getPdf(uuid) 69 | expect.fail('getPdf should be rejected') 70 | } catch (err) { 71 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 72 | } 73 | }) 74 | }) 75 | -------------------------------------------------------------------------------- /src/test/analysesClass.groupOperation.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface, Group } from '..' 8 | 9 | const postRequest = require('../http/index') 10 | 11 | describe('groupOperation', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let postRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | postRequestStub = sinon.stub(postRequest, 'postRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJTest') 32 | }) 33 | 34 | afterEach(() => { 35 | postRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.groupOperation).to.be.a('function') 40 | }) 41 | 42 | it('should return an object with a group info if request worked', async () => { 43 | const groupId = '1111-2222-3333-4444' 44 | const operationType = 'seal_group' 45 | 46 | const response: Group = { 47 | id: 'string', 48 | name: 'string', 49 | createdAt: '2019-11-19T15:40:12Z', 50 | createdBy: 'string', 51 | completedAt: '2019-11-19T15:40:12Z', 52 | progress: 0, 53 | status: 'opened', 54 | mainSourceFiles: ['string'], 55 | numAnalyses: { 56 | total: 0, 57 | queued: 0, 58 | running: 0, 59 | failed: 0, 60 | finished: 0, 61 | }, 62 | numVulnerabilities: { 63 | high: 0, 64 | medium: 0, 65 | low: 0, 66 | none: 0, 67 | }, 68 | } 69 | 70 | postRequestStub.resolves({ 71 | data: response, 72 | }) 73 | 74 | const result = await ANALYSES.groupOperation(groupId, operationType) 75 | expect(result).to.equal(response) 76 | expect( 77 | postRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analysis-groups/${groupId}`, { 78 | type: operationType, 79 | }), 80 | ).to.be.true 81 | }) 82 | 83 | it('should fail if there is something wrong with the request', async () => { 84 | const groupId = '1111-2222-3333-4444' 85 | const operationType = 'seal_group' 86 | 87 | postRequestStub.throws('400') 88 | 89 | try { 90 | await ANALYSES.groupOperation(groupId, operationType) 91 | expect.fail('groupOperation should be rejected') 92 | } catch (err) { 93 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 94 | } 95 | }) 96 | }) 97 | -------------------------------------------------------------------------------- /src/test/analysesClass.listGroups.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface, AnalysisGroups } from '..' 8 | 9 | const getRequest = require('../http/index') 10 | 11 | describe('listGroups', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let getRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | getRequestStub = sinon.stub(getRequest, 'getRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJS test') 32 | }) 33 | 34 | afterEach(() => { 35 | getRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.listGroups).to.be.a('function') 40 | }) 41 | 42 | it('should return a request a list of Groups', async () => { 43 | const query = 'offset=5' 44 | 45 | const response: AnalysisGroups = { 46 | groups: [], 47 | total: 3, 48 | } 49 | 50 | getRequestStub.resolves({ 51 | data: response, 52 | }) 53 | 54 | const result = await ANALYSES.listGroups(query) 55 | expect(result).to.deep.equal(response) 56 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analysis-groups?offset=5`)).to.be.true 57 | }) 58 | 59 | it('should fail if there is something wrong with the request', async () => { 60 | const query = 'offset=5' 61 | 62 | getRequestStub.throws('400') 63 | 64 | try { 65 | await ANALYSES.listGroups(query) 66 | expect.fail('listGroups should be rejected') 67 | } catch (err) { 68 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 69 | } 70 | }) 71 | }) 72 | -------------------------------------------------------------------------------- /src/test/analysesClass.submitBytecode.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { AnalysesService } from '../apiServices/AnalysesService' 7 | import { JwtTokensInterface } from '..' 8 | 9 | const postRequest = require('../http/index') 10 | 11 | describe('submitBytecode', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let postRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | postRequestStub = sinon.stub(postRequest, 'postRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythxJTest') 32 | }) 33 | 34 | afterEach(() => { 35 | postRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.submitBytecode).to.be.a('function') 40 | }) 41 | 42 | it('should return an object with info about submitted analysis using bytecode only', async () => { 43 | const bytecode = '1111111' 44 | 45 | const expected = { 46 | clientToolName: 'MythxJTest', 47 | data: { 48 | bytecode: `${bytecode}`, 49 | }, 50 | } 51 | 52 | const response = { 53 | apiVersion: 'v1.4.14', 54 | harveyVersion: '0.0.22', 55 | maestroVersion: '1.2.11', 56 | maruVersion: '0.4.6', 57 | mythrilVersion: '0.20.4', 58 | queueTime: 10, 59 | runTime: 0, 60 | status: 'Queued', 61 | submittedAt: '2019-05-29T17:41:46.902Z', 62 | submittedBy: '123456789012345678901234', 63 | uuid: '1111-2222-3333-4444', 64 | } 65 | 66 | postRequestStub.resolves({ 67 | data: response, 68 | }) 69 | 70 | const result = await ANALYSES.submitBytecode(bytecode) 71 | expect(result).to.equal(response) 72 | expect(postRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses`, expected)).to.be.true 73 | }) 74 | 75 | it('should fail if there is something wrong with the request', async () => { 76 | const bytecode = '1111111' 77 | 78 | postRequestStub.throws('400') 79 | 80 | try { 81 | await ANALYSES.submitBytecode(bytecode) 82 | expect.fail('submitBytecode should be rejected') 83 | } catch (err) { 84 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 85 | } 86 | }) 87 | }) 88 | -------------------------------------------------------------------------------- /src/test/analysesClass.submitSourcecode.spec.ts: -------------------------------------------------------------------------------- 1 | import * as jwt from 'jsonwebtoken' 2 | import * as sinon from 'sinon' 3 | 4 | import { AnalysesService } from '../apiServices/AnalysesService' 5 | import { ClientService } from '../apiServices/ClientService' 6 | import { JwtTokensInterface } from '..' 7 | import { expect } from 'chai' 8 | 9 | const postRequest = require('../http/index') 10 | 11 | describe('submitSourceCode', () => { 12 | const accessToken = { 13 | jti: '', 14 | iss: '', 15 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 16 | userId: '', 17 | iat: 0, 18 | } 19 | const tokens: JwtTokensInterface = { 20 | access: jwt.sign(accessToken, 'secret'), 21 | refresh: 'refresh', 22 | } 23 | 24 | let postRequestStub: any 25 | 26 | let ANALYSES 27 | 28 | beforeEach(() => { 29 | postRequestStub = sinon.stub(postRequest, 'postRequest') 30 | 31 | ANALYSES = new AnalysesService(tokens, 'MythXJTest') 32 | }) 33 | 34 | afterEach(() => { 35 | postRequestStub.restore() 36 | }) 37 | 38 | it('is a function', () => { 39 | expect(ANALYSES.submitSourceCode).to.be.a('function') 40 | }) 41 | 42 | it('should return an object with info about submitted analysis using source code only', async () => { 43 | const sourceCode = 'solidity code' 44 | 45 | const response = { 46 | apiVersion: 'v1.4.14', 47 | harveyVersion: '0.0.22', 48 | maestroVersion: '1.2.11', 49 | maruVersion: '0.4.6', 50 | mythrilVersion: '0.20.4', 51 | queueTime: 10, 52 | runTime: 0, 53 | status: 'Queued', 54 | submittedAt: '2019-05-29T17:41:46.902Z', 55 | submittedBy: '123456789012345678901234', 56 | uuid: '1111-2222-3333-4444', 57 | } 58 | 59 | const expected = { 60 | clientToolName: 'MythXJTest', 61 | propertyChecking: false, 62 | data: { 63 | contractName: 'contractName', 64 | sources: { 65 | [`${'contractName'}.sol`]: { 66 | source: sourceCode, 67 | }, 68 | }, 69 | mainSource: `${'contractName'}.sol`, 70 | }, 71 | } 72 | 73 | postRequestStub.resolves({ 74 | data: response, 75 | }) 76 | 77 | const result = await ANALYSES.submitSourceCode(sourceCode, 'contractName') 78 | expect(result).to.equal(response) 79 | expect(postRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses`, expected)).to.be.true 80 | }) 81 | 82 | it('should return an object with info about submitted analysis when property check is triggered', async () => { 83 | const sourceCode = 'solidity code' 84 | 85 | const response = { 86 | apiVersion: 'v1.4.14', 87 | harveyVersion: '0.0.22', 88 | maestroVersion: '1.2.11', 89 | maruVersion: '0.4.6', 90 | mythrilVersion: '0.20.4', 91 | queueTime: 10, 92 | runTime: 0, 93 | status: 'Queued', 94 | submittedAt: '2019-05-29T17:41:46.902Z', 95 | submittedBy: '123456789012345678901234', 96 | uuid: '1111-2222-3333-4444', 97 | } 98 | 99 | const expected = { 100 | clientToolName: 'MythXJTest', 101 | propertyChecking: true, 102 | data: { 103 | contractName: 'contractName', 104 | sources: { 105 | [`${'contractName'}.sol`]: { 106 | source: sourceCode, 107 | }, 108 | }, 109 | mainSource: `${'contractName'}.sol`, 110 | }, 111 | } 112 | 113 | postRequestStub.resolves({ 114 | data: response, 115 | }) 116 | 117 | const result = await ANALYSES.submitSourceCode(sourceCode, 'contractName', true) 118 | expect(result).to.equal(response) 119 | expect(postRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/analyses`, expected)).to.be.true 120 | }) 121 | 122 | it('should fail if there is something wrong with the request', async () => { 123 | const sourceCode = 'source code' 124 | 125 | postRequestStub.throws('400') 126 | 127 | try { 128 | await ANALYSES.submitSourceCode(sourceCode, 'contractName') 129 | expect.fail('submitSourceCode should be rejected') 130 | } catch (err) { 131 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 132 | } 133 | }) 134 | }) 135 | -------------------------------------------------------------------------------- /src/test/authClass.getChallenge.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | 4 | import { AuthService } from '../apiServices/AuthService' 5 | 6 | const getRequest = require('../http/index') 7 | 8 | describe('getChallenge', () => { 9 | let getRequestStub: any 10 | 11 | let AUTH 12 | beforeEach(() => { 13 | getRequestStub = sinon.stub(getRequest, 'getRequest') 14 | 15 | AUTH = new AuthService('user', 'password') 16 | }) 17 | 18 | afterEach(() => { 19 | getRequestStub.restore() 20 | }) 21 | 22 | it('is a function', () => { 23 | expect(AUTH.getChallenge).to.be.a('function') 24 | }) 25 | 26 | it('returns a object', async () => { 27 | const value = { 28 | domain: { name: 'MythX API Platform' }, 29 | message: { value: 'message' }, 30 | primaryType: 'Challenge', 31 | types: {}, 32 | } 33 | 34 | getRequestStub.resolves({ data: value }) 35 | 36 | const result = await AUTH.getChallenge() 37 | console.error(result) 38 | expect(result).to.deep.equal(value) 39 | }) 40 | 41 | it('should fail if there is something wrong with the request', async () => { 42 | getRequestStub.throws('400') 43 | 44 | try { 45 | await AUTH.getChallenge() 46 | expect.fail('getChallenge should be rejected') 47 | } catch (err) { 48 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 49 | } 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /src/test/authClass.getOpenApiHTML.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | 4 | import { ClientService } from '../apiServices/ClientService' 5 | import { AuthService } from '../apiServices/AuthService' 6 | 7 | const getRequest = require('../http/index') 8 | 9 | describe('getOpenApiHTML', () => { 10 | let getRequestStub: any 11 | 12 | let AUTH 13 | beforeEach(() => { 14 | getRequestStub = sinon.stub(getRequest, 'getRequest') 15 | 16 | AUTH = new AuthService('user', 'password') 17 | }) 18 | 19 | afterEach(() => { 20 | getRequestStub.restore() 21 | }) 22 | 23 | it('is a function', () => { 24 | expect(AUTH.getOpenApiHTML).to.be.a('function') 25 | }) 26 | 27 | it('returns an object', async () => { 28 | const value = { 29 | html: 'html', 30 | } 31 | 32 | getRequestStub.resolves({ 33 | data: value, 34 | }) 35 | 36 | const result = await AUTH.getOpenApiHTML() 37 | expect(result).to.deep.equal(value) 38 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/openapi`)).to.be.true 39 | }) 40 | 41 | it('should fail if there is something wrong with the request', async () => { 42 | getRequestStub.throws('400') 43 | 44 | try { 45 | await AUTH.getOpenApiHTML() 46 | expect.fail('openApiHTML should be rejected') 47 | } catch (err) { 48 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 49 | } 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /src/test/authClass.getOpenApiYAML.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | 4 | import { ClientService } from '../apiServices/ClientService' 5 | import { AuthService } from '../apiServices/AuthService' 6 | 7 | const getRequest = require('../http/index') 8 | 9 | describe('getOpenApiYAML', () => { 10 | let getRequestStub: any 11 | 12 | let AUTH 13 | beforeEach(() => { 14 | getRequestStub = sinon.stub(getRequest, 'getRequest') 15 | 16 | AUTH = new AuthService('user', 'password') 17 | }) 18 | 19 | afterEach(() => { 20 | getRequestStub.restore() 21 | }) 22 | 23 | it('is a function', () => { 24 | expect(AUTH.getOpenApiYAML).to.be.a('function') 25 | }) 26 | 27 | it('returns an object', async () => { 28 | const value = { 29 | yaml: 'yaml', 30 | } 31 | 32 | getRequestStub.resolves({ 33 | data: value, 34 | }) 35 | 36 | const result = await AUTH.getOpenApiYAML() 37 | expect(result).to.deep.equal(value) 38 | expect(getRequestStub.calledWith(`${ClientService.MYTHX_API_ENVIRONMENT}/openapi.yaml`)).to.be.true 39 | }) 40 | 41 | it('should fail if there is something wrong with the request', async () => { 42 | getRequestStub.throws('400') 43 | 44 | try { 45 | await AUTH.getOpenApiYAML() 46 | expect.fail('openApiYAML should be rejected') 47 | } catch (err) { 48 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 49 | } 50 | }) 51 | }) 52 | -------------------------------------------------------------------------------- /src/test/authClass.getStats.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { AuthService } from '../apiServices/AuthService' 6 | 7 | const getRequest = require('../http/index') 8 | 9 | describe('getStats', () => { 10 | const accessToken = { 11 | jti: '', 12 | iss: '', 13 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 14 | userId: '', 15 | iat: 0, 16 | } 17 | let getRequestStub: any 18 | 19 | let AUTH 20 | let isUserLoggedInStub: any 21 | beforeEach(() => { 22 | getRequestStub = sinon.stub(getRequest, 'getRequest') 23 | 24 | AUTH = new AuthService('user', 'password') 25 | AUTH.jwtTokens = { 26 | access: jwt.sign(accessToken, 'secret'), 27 | refresh: 'refresh', 28 | } 29 | 30 | isUserLoggedInStub = sinon.stub(AUTH, 'isUserLoggedIn') 31 | }) 32 | 33 | afterEach(() => { 34 | getRequestStub.restore() 35 | isUserLoggedInStub.restore() 36 | 37 | delete AUTH.jwtTokens 38 | }) 39 | 40 | it('is a function', () => { 41 | expect(AUTH.getStats).to.be.a('function') 42 | }) 43 | 44 | it('returns an object containg stats', async () => { 45 | const response = [ 46 | { 47 | from: '2018-01-01T00:00:00.000Z', 48 | interval: 'LIFE_TIME', 49 | createdAt: '2019-06-14T12:32:59.794Z', 50 | type: 'USERS_ANALYSES', 51 | revision: 14, 52 | data: { numUsers: [], numAnalyses: [], analysis: [] }, 53 | }, 54 | ] 55 | isUserLoggedInStub.returns(true) 56 | 57 | getRequestStub.resolves({ 58 | data: response, 59 | }) 60 | 61 | const result = await AUTH.getStats() 62 | expect(result).to.deep.equal(response) 63 | }) 64 | 65 | it('should fail if there is something wrong with the request', async () => { 66 | isUserLoggedInStub.returns(true) 67 | 68 | getRequestStub.throws('400') 69 | 70 | try { 71 | await AUTH.getStats() 72 | expect.fail('getStats should be rejected') 73 | } catch (err) { 74 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 75 | } 76 | }) 77 | }) 78 | -------------------------------------------------------------------------------- /src/test/authClass.getUsers.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { AuthService } from '../apiServices/AuthService' 6 | 7 | const getRequest = require('../http/index') 8 | 9 | describe('getUsers', () => { 10 | const accessToken = { 11 | jti: '', 12 | iss: '', 13 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 14 | userId: '', 15 | iat: 0, 16 | } 17 | let getRequestStub: any 18 | 19 | let AUTH 20 | let isUserLoggedInStub: any 21 | beforeEach(() => { 22 | getRequestStub = sinon.stub(getRequest, 'getRequest') 23 | 24 | AUTH = new AuthService('user', 'password') 25 | AUTH.jwtTokens = { 26 | access: jwt.sign(accessToken, 'secret'), 27 | refresh: 'refresh', 28 | } 29 | 30 | isUserLoggedInStub = sinon.stub(AUTH, 'isUserLoggedIn') 31 | }) 32 | 33 | afterEach(() => { 34 | getRequestStub.restore() 35 | isUserLoggedInStub.restore() 36 | 37 | delete AUTH.jwtTokens 38 | }) 39 | 40 | it('is a function', () => { 41 | expect(AUTH.getUsers).to.be.a('function') 42 | }) 43 | 44 | it('returns an object containg user object', async () => { 45 | const response = { 46 | total: 1, 47 | users: [ 48 | { 49 | id: '5c18ee88eba3190015f7bc02', 50 | createdAt: '2018-12-18T12:56:40.000Z', 51 | email: {}, 52 | ethAddress: '0x79b483371e87d664cd39491b5f06250165e4b184', 53 | roles: ['trusted_user', 'Free'], 54 | preferences: { 55 | newsletter: false, 56 | }, 57 | termsId: 'no_terms', 58 | }, 59 | ], 60 | } 61 | 62 | isUserLoggedInStub.returns(true) 63 | 64 | getRequestStub.resolves({ 65 | data: response, 66 | }) 67 | 68 | const result = await AUTH.getUsers() 69 | expect(result).to.deep.equal(response) 70 | }) 71 | 72 | it('should fail if there is something wrong with the request', async () => { 73 | isUserLoggedInStub.returns(true) 74 | 75 | getRequestStub.throws('400') 76 | 77 | try { 78 | await AUTH.getUsers() 79 | expect.fail('getUsers should be rejected') 80 | } catch (err) { 81 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 82 | } 83 | }) 84 | }) 85 | -------------------------------------------------------------------------------- /src/test/authClass.getVersion.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | 4 | import { AuthService } from '../apiServices/AuthService' 5 | 6 | const getRequest = require('../http/index') 7 | 8 | describe('getVersion', () => { 9 | let getRequestStub: any 10 | 11 | let AUTH 12 | beforeEach(() => { 13 | getRequestStub = sinon.stub(getRequest, 'getRequest') 14 | 15 | AUTH = new AuthService('user', 'password') 16 | }) 17 | 18 | afterEach(() => { 19 | getRequestStub.restore() 20 | }) 21 | 22 | it('is a function', () => { 23 | expect(AUTH.getVersion).to.be.a('function') 24 | }) 25 | 26 | it('returns an object', async () => { 27 | const value = { 28 | api: 'v1.2.5', 29 | hash: 'c0d8ccbf9ba2623cc147da2860f20093', 30 | harvey: 'v0.1.0', 31 | maestro: '1.1.4', 32 | maru: '0.1.0', 33 | mythril: 'v1.2.3', 34 | } 35 | 36 | getRequestStub.resolves({ 37 | data: value, 38 | }) 39 | 40 | const result = await AUTH.getVersion() 41 | expect(result).to.deep.equal(value) 42 | }) 43 | 44 | it('should fail if there is something wrong with the request', async () => { 45 | getRequestStub.throws('400') 46 | 47 | try { 48 | await AUTH.getVersion() 49 | expect.fail('getVersion should be rejected') 50 | } catch (err) { 51 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 52 | } 53 | }) 54 | }) 55 | -------------------------------------------------------------------------------- /src/test/authClass.loginWithSignature.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | 4 | import { AuthService } from '../apiServices/AuthService' 5 | import { JwtTokensInterface } from '..' 6 | 7 | const postRequest = require('../http/index') 8 | 9 | describe('loginWithSignature', () => { 10 | const tokens: JwtTokensInterface = { 11 | access: 'access', 12 | refresh: 'refresh', 13 | } 14 | 15 | let postRequestStub: any 16 | 17 | let AUTH 18 | beforeEach(() => { 19 | postRequestStub = sinon.stub(postRequest, 'postRequest') 20 | 21 | AUTH = new AuthService('user', 'password') 22 | }) 23 | 24 | afterEach(() => { 25 | postRequestStub.restore() 26 | 27 | delete AUTH.jwtTokens 28 | }) 29 | 30 | it('is a function', () => { 31 | expect(AUTH.loginWithSignature).to.be.a('function') 32 | }) 33 | 34 | it('should return and set access and refresh tokens', async () => { 35 | postRequestStub.resolves({ 36 | data: { jwtTokens: tokens }, 37 | }) 38 | 39 | const result = await AUTH.loginWithSignature() 40 | 41 | expect(result).to.equal(tokens) 42 | }) 43 | 44 | it('should fail if there is something wrong with the request', async () => { 45 | postRequestStub.throws('400') 46 | 47 | try { 48 | await AUTH.loginWithSignature() 49 | expect.fail('loginWithSignature should be rejected') 50 | } catch (err) { 51 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 52 | } 53 | }) 54 | }) 55 | -------------------------------------------------------------------------------- /src/test/authService.login.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | 4 | import { AuthService } from '../apiServices/AuthService' 5 | import { JwtTokensInterface } from '..' 6 | 7 | const loginUser = require('../auth/loginUser') 8 | const errorHandler = require('../util/errorHandler') 9 | 10 | describe('loginUser', () => { 11 | const tokens: JwtTokensInterface = { 12 | access: 'access', 13 | refresh: 'refresh', 14 | } 15 | 16 | let loginUserStub: any 17 | let errorHandlerStub: any 18 | let setCredentialsStub: any 19 | let AUTH 20 | beforeEach(() => { 21 | loginUserStub = sinon.stub(loginUser, 'loginUser') 22 | errorHandlerStub = sinon.stub(errorHandler, 'errorHandler') 23 | 24 | AUTH = new AuthService('user', 'password') 25 | setCredentialsStub = sinon.stub(AUTH, 'setCredentials') 26 | }) 27 | 28 | afterEach(() => { 29 | loginUserStub.restore() 30 | errorHandlerStub.restore() 31 | setCredentialsStub.restore() 32 | }) 33 | 34 | it('is a function', () => { 35 | expect(AUTH.login).to.be.a('function') 36 | }) 37 | 38 | it('should return and set access and refresh tokens', async () => { 39 | loginUserStub.resolves({ 40 | data: { jwtTokens: tokens }, 41 | }) 42 | 43 | const result = await AUTH.login() 44 | 45 | expect(loginUserStub.calledWith('user', 'password', sinon.match.string)).to.be.true 46 | expect(setCredentialsStub.calledWith(tokens)).to.be.true 47 | expect(result).to.equal(tokens) 48 | }) 49 | 50 | it('should fail with error', async () => { 51 | const errMsg = 'MythxJS. Error with your request.' 52 | 53 | loginUserStub.throws(errMsg) 54 | errorHandlerStub.throws() 55 | 56 | try { 57 | await AUTH.login() 58 | expect.fail('login should be rejected') 59 | } catch (err) { 60 | expect(errorHandlerStub.getCall(0).args[0].name).to.equal(errMsg) 61 | } 62 | }) 63 | }) 64 | -------------------------------------------------------------------------------- /src/test/authService.logout.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai' 2 | import * as sinon from 'sinon' 3 | import * as jwt from 'jsonwebtoken' 4 | 5 | import { AuthService } from '../apiServices/AuthService' 6 | import { ClientService } from '../apiServices/ClientService' 7 | 8 | const postRequest = require('../http/index') 9 | 10 | describe('logout', () => { 11 | const accessToken = { 12 | jti: '', 13 | iss: '', 14 | exp: Math.floor(new Date().getTime() / 1000) + 60 * 20, 15 | userId: '', 16 | iat: 0, 17 | } 18 | let postRequestStub: any 19 | 20 | let AUTH 21 | let isUserLoggedInStub: any 22 | let CLIENT 23 | beforeEach(() => { 24 | postRequestStub = sinon.stub(postRequest, 'postRequest') 25 | 26 | AUTH = new AuthService('user', 'password') 27 | ClientService.jwtTokens = { 28 | access: jwt.sign(accessToken, 'secret'), 29 | refresh: 'refresh', 30 | } 31 | 32 | isUserLoggedInStub = sinon.stub(AUTH, 'isUserLoggedIn') 33 | }) 34 | 35 | afterEach(() => { 36 | postRequestStub.restore() 37 | isUserLoggedInStub.restore() 38 | 39 | delete ClientService.jwtTokens 40 | }) 41 | 42 | it('is a function', () => { 43 | expect(AUTH.logout).to.be.a('function') 44 | }) 45 | 46 | it('returns an empty object', async () => { 47 | isUserLoggedInStub.returns(true) 48 | 49 | postRequestStub.resolves({ 50 | data: {}, 51 | }) 52 | 53 | const result = await AUTH.logout() 54 | expect(result).to.deep.equal({}) 55 | }) 56 | 57 | it('should fail if user is not logged in', async () => { 58 | isUserLoggedInStub.returns(false) 59 | 60 | try { 61 | await AUTH.logout() 62 | expect.fail('logout should be rejected') 63 | } catch (err) { 64 | expect(err.message).to.equal('MythxJS no valid token found. Please login') 65 | } 66 | }) 67 | 68 | it('should fail if there is something wrong with the request', async () => { 69 | isUserLoggedInStub.returns(true) 70 | postRequestStub.throws('400') 71 | 72 | try { 73 | await AUTH.logout() 74 | expect.fail('logout should be rejected') 75 | } catch (err) { 76 | expect(err.message).to.equal('MythxJS. Error with your request. 400') 77 | } 78 | }) 79 | }) 80 | -------------------------------------------------------------------------------- /src/types/analysis-list.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /** 3 | * This file was automatically generated by json-schema-to-typescript. 4 | * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, 5 | * and run json-schema-to-typescript to regenerate this file. 6 | */ 7 | 8 | export interface AnalysisList { 9 | total: number 10 | analyses: { 11 | apiVersion: string 12 | harveyVersion: string 13 | maruVersion: string 14 | mythrilVersion: string 15 | queueTime: number 16 | runTime: number 17 | status: string 18 | submittedAt: string 19 | submittedBy: string 20 | uuid: string 21 | [k: string]: any 22 | }[] 23 | [k: string]: any 24 | } 25 | -------------------------------------------------------------------------------- /src/types/analysis-submission.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /** 3 | * This file was automatically generated by json-schema-to-typescript. 4 | * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, 5 | * and run json-schema-to-typescript to regenerate this file. 6 | */ 7 | 8 | export interface AnalysisSubmission { 9 | apiVersion: string 10 | harveyVersion?: string 11 | maruVersion?: string 12 | mythrilVersion?: string 13 | queueTime: number 14 | status: string 15 | submittedAt: string 16 | submittedBy: string 17 | uuid: string 18 | [k: string]: any 19 | } 20 | -------------------------------------------------------------------------------- /src/types/detected-issues.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /** 3 | * This file was automatically generated by json-schema-to-typescript. 4 | * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, 5 | * and run json-schema-to-typescript to regenerate this file. 6 | */ 7 | 8 | export type DetectedIssues = { 9 | issues: { 10 | decodedLocations?: { 11 | column: number 12 | line: number 13 | [k: string]: any 14 | }[][] 15 | swcID: string 16 | swcTitle: string 17 | description: { 18 | head: string 19 | tail: string 20 | [k: string]: any 21 | } 22 | severity: string | null 23 | locations: { 24 | sourceMap?: string | null 25 | sourceType?: string | null 26 | sourceFormat?: string | null 27 | sourceList?: string[] 28 | [k: string]: any 29 | }[] 30 | extra: { 31 | [k: string]: any 32 | } 33 | [k: string]: any 34 | }[] 35 | sourceType: string | null 36 | sourceFormat: string | null 37 | sourceList: string[] 38 | meta: { 39 | [k: string]: any 40 | } 41 | [k: string]: any 42 | }[] 43 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export { AnalysisList } from './analysis-list' 2 | export { AnalysisSubmission } from './analysis-submission' 3 | export { DetectedIssues } from './detected-issues' 4 | export { Openapi } from './openapi' 5 | export { Version } from './version' 6 | -------------------------------------------------------------------------------- /src/types/openapi.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /** 3 | * This file was automatically generated by json-schema-to-typescript. 4 | * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, 5 | * and run json-schema-to-typescript to regenerate this file. 6 | */ 7 | 8 | export interface Openapi { 9 | data: string 10 | [k: string]: any 11 | } 12 | -------------------------------------------------------------------------------- /src/types/version.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /** 3 | * This file was automatically generated by json-schema-to-typescript. 4 | * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, 5 | * and run json-schema-to-typescript to regenerate this file. 6 | */ 7 | 8 | export interface Version { 9 | api: string 10 | hash: string 11 | harvey: string 12 | maru: string 13 | mythril: string 14 | [k: string]: any 15 | } 16 | -------------------------------------------------------------------------------- /src/util/errorHandler.ts: -------------------------------------------------------------------------------- 1 | export function errorHandler(err) { 2 | let status 3 | let error 4 | if (err.response && err.response.data) { 5 | status = err.response.data.status 6 | error = err.response.data.error 7 | } 8 | 9 | if (status && error) { 10 | throw new Error(`${status} ${error}`) 11 | } else { 12 | throw new Error(`MythxJS. Error with your request. ${err}`) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/util/generateContractsRequests.ts: -------------------------------------------------------------------------------- 1 | import { AnalyzeOptions } from '..' 2 | 3 | export function generateBytecodeRequest(bytecode: string, toolName: string = 'MythxJS') { 4 | return { 5 | clientToolName: toolName, 6 | data: { 7 | bytecode: `${bytecode}`, 8 | }, 9 | } 10 | } 11 | 12 | export function generateSourceCodeRequest( 13 | sourceCode: string, 14 | contractName: string, 15 | toolName: string = 'MythxJS', 16 | propertyChecking: boolean = false, 17 | ) { 18 | return { 19 | clientToolName: toolName, 20 | propertyChecking, 21 | data: { 22 | contractName: contractName, 23 | sources: { 24 | [`${contractName}.sol`]: { 25 | source: sourceCode, 26 | }, 27 | }, 28 | mainSource: `${contractName}.sol`, 29 | }, 30 | } 31 | } 32 | 33 | export function generateAnalysisRequest( 34 | options: AnalyzeOptions, 35 | toolName: string = 'MythXJS', 36 | propertyChecking: boolean = false, 37 | ) { 38 | if (options.toolName) { 39 | toolName = options.toolName 40 | } 41 | let result: { [k: string]: any } = { 42 | clientToolName: toolName, 43 | noCacheLookup: options.noCacheLookup === undefined ? false : options.noCacheLookup, 44 | propertyChecking, 45 | data: {}, 46 | } 47 | if (typeof options.contractName !== 'undefined') result.data['contractName'] = options.contractName 48 | if (typeof options.bytecode !== 'undefined') result.data['bytecode'] = options.bytecode 49 | if (typeof options.sourceMap !== 'undefined') result.data['sourceMap'] = options.sourceMap 50 | if (typeof options.deployedBytecode !== 'undefined') result.data['deployedBytecode'] = options.deployedBytecode 51 | if (typeof options.deployedSourceMap !== 'undefined') result.data['deployedSourceMap'] = options.deployedSourceMap 52 | if (typeof options.mainSource !== 'undefined') result.data['mainSource'] = options.mainSource 53 | if (typeof options.sources !== 'undefined') result.data['sources'] = options.sources 54 | if (typeof options.sourceList !== 'undefined') result.data['sourceList'] = options.sourceList 55 | if (typeof options.solcVersion !== 'undefined') result.data['version'] = options.solcVersion 56 | if (typeof options.analysisMode !== 'undefined') result.data['analysisMode'] = options.analysisMode 57 | if (typeof options.groupId !== 'undefined') result['groupId'] = options.groupId 58 | return result 59 | } 60 | -------------------------------------------------------------------------------- /src/util/getHeaders.ts: -------------------------------------------------------------------------------- 1 | import { validateToken } from './validateToken' 2 | import { JwtTokensInterface } from '..' 3 | 4 | export async function getHeaders(jwtTokens: JwtTokensInterface) { 5 | const tokens = await validateToken(jwtTokens) 6 | const headers = { 7 | Authorization: `Bearer ${tokens.access}`, 8 | 'Content-Type': 'application/json', 9 | } 10 | 11 | return { tokens, headers } 12 | } 13 | -------------------------------------------------------------------------------- /src/util/mock.ts: -------------------------------------------------------------------------------- 1 | export const ANALYSIS_MOCK = { 2 | 'clientToolName': 'mythxjs-api-curl', 3 | 'data': 4 | { 5 | 'contractName': 'UsesExample', 6 | 'bytecode': '60806040526040518060400160405280600b81526020017f557365734578616d706c650000000000000000000000000000000000000000008152506000908051906020019061004f9291906100d4565b5034801561005c57600080fd5b506040516020806103808339810180604052602081101561007c57600080fd5b810190808051906020019092919050505080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610179565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061011557805160ff1916838001178555610143565b82800160010185558215610143579182015b82811115610142578251825591602001919060010190610127565b5b5090506101509190610154565b5090565b61017691905b8082111561017257600081600090555060010161015a565b5090565b90565b6101f8806101886000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063852958771461003b578063af640d0f14610085575b600080fd5b610043610108565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61008d61012e565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100cd5780820151818401526020810190506100b2565b50505050905090810190601f1680156100fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101c45780601f10610199576101008083540402835291602001916101c4565b820191906000526020600020905b8154815290600101906020018083116101a757829003601f168201915b50505050508156fea165627a7a723058201d03acbedb47e67190be7805476a9573db831184464773ecbe2ab76dd92ef1a00029', 7 | 'analysisMode': 'quick', 8 | 'sourceList': [ 9 | 'UsesExample.sol' 10 | ], 11 | 'sources': { 12 | 'UsesExample.sol': { 13 | 'source': 'pragma solidity ^0.5.0;\r\n\r\n\r\ncontract UsesExample {\r\n string public id = \'UsesExample\';\r\n address public other;\r\n constructor(address _other) public {\r\n other = _other;\r\n }\r\n}\r\n' 14 | } 15 | }, 16 | 'mainSource': 'UsesExample.sol' 17 | } 18 | } 19 | 20 | 21 | export const ANALYSIS_MOCK_VULNERABLE = { 22 | 'data': { 'contractName': 'Vulnerable', 'bytecode': '608060405260f960005534801561001557600080fd5b5060a7806100246000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80630dbe671f14604157806326121ff01460495780632e52d60614604f575b600080fd5b60476067565b005b60476072565b60556075565b60408051918252519081900360200190f35b600080546002029055565b33ff5b6000548156fea165627a7a72305820354a0ccc1504fa2943f1b286225b3cb12c4078eb2d9bc1b757cc8fddf700bf570029', 'sourceMap': '26:172:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26:172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;150:46;;;:::i;:::-;;83:61;;;:::i;52:24::-;;;:::i;:::-;;;;;;;;;;;;;;;;150:46;184:1;;;188;184:5;180:9;;150:46::o;83:61::-;126:10;113:24;52;;;;:::o', 'deployedBytecode': '6080604052348015600f57600080fd5b5060043610603c5760003560e01c80630dbe671f14604157806326121ff01460495780632e52d60614604f575b600080fd5b60476067565b005b60476072565b60556075565b60408051918252519081900360200190f35b600080546002029055565b33ff5b6000548156fea165627a7a72305820354a0ccc1504fa2943f1b286225b3cb12c4078eb2d9bc1b757cc8fddf700bf570029', 'deployedSourceMap': '26:172:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26:172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;150:46;;;:::i;:::-;;83:61;;;:::i;52:24::-;;;:::i;:::-;;;;;;;;;;;;;;;;150:46;184:1;;;188;184:5;180:9;;150:46::o;83:61::-;126:10;113:24;52;;;;:::o', 'sourceList': ['vulnerable.sol'], 'analysisMode': 'quick', 'sources': { 'vulnerable.sol': { 'source': '\npragma solidity ^0.5.5;\n\ncontract Vulnerable {\n uint256 public n = 2^251;\n\n function f() public {\n selfdestruct(msg.sender);\n }\n\n function a() public {\n n = n * 2;\n }\n}' } }, 'mainSource': 'vulnerable.sol' } 23 | } 24 | 25 | export const ANALYSIS_MOCK_TOKEN = 26 | { 'data': { 'contractName': 'Token', 'bytecode': '608060405234801561001057600080fd5b5060405160208061019c8339810180604052602081101561003057600080fd5b5051600181905533600090815260208190526040902055610146806100566000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806318160ddd1461004657806370a0823114610060578063a9059cbb14610086575b600080fd5b61004e6100c6565b60408051918252519081900360200190f35b61004e6004803603602081101561007657600080fd5b50356001600160a01b03166100cc565b6100b26004803603604081101561009c57600080fd5b506001600160a01b0381351690602001356100e7565b604080519115158252519081900360200190f35b60015481565b6001600160a01b031660009081526020819052604090205490565b33600090815260208190526040808220805484900390556001600160a01b0384168252902080548201905560019291505056fea165627a7a72305820812708d93099d7ca1cc78a250793999174dcea2913f0567544733ddbb149807d0029', 'sourceMap': '2:454:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2:454:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59:23;;;:::i;:::-;;;;;;;;;;;;;;;;350:104;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;350:104:0;-1:-1:-1;;;;;350:104:0;;:::i;193:153::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;193:153:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59:23;;;;:::o;350:104::-;-1:-1:-1;;;;;433:16:0;406:12;433:16;;;;;;;;;;;;350:104::o;193:153::-;274:10;253:4;265:20;;;;;;;;;;;:30;;;;;;;-1:-1:-1;;;;;301:13:0;;;;;;:23;;;;;;-1:-1:-1;193:153:0;;;;:::o', 'deployedBytecode': '608060405234801561001057600080fd5b50600436106100415760003560e01c806318160ddd1461004657806370a0823114610060578063a9059cbb14610086575b600080fd5b61004e6100c6565b60408051918252519081900360200190f35b61004e6004803603602081101561007657600080fd5b50356001600160a01b03166100cc565b6100b26004803603604081101561009c57600080fd5b506001600160a01b0381351690602001356100e7565b604080519115158252519081900360200190f35b60015481565b6001600160a01b031660009081526020819052604090205490565b33600090815260208190526040808220805484900390556001600160a01b0384168252902080548201905560019291505056fea165627a7a72305820812708d93099d7ca1cc78a250793999174dcea2913f0567544733ddbb149807d0029', 'deployedSourceMap': '2:454:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2:454:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59:23;;;:::i;:::-;;;;;;;;;;;;;;;;350:104;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;350:104:0;-1:-1:-1;;;;;350:104:0;;:::i;193:153::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;193:153:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59:23;;;;:::o;350:104::-;-1:-1:-1;;;;;433:16:0;406:12;433:16;;;;;;;;;;;;350:104::o;193:153::-;274:10;253:4;265:20;;;;;;;;;;;:30;;;;;;;-1:-1:-1;;;;;301:13:0;;;;;;:23;;;;;;-1:-1:-1;193:153:0;;;;:::o', 'sourceList': ['token.sol'], 'analysisMode': 'quick', 'sources': { 'token.sol': { 'source': '\n\ncontract Token {\n\n mapping(address => uint) balances;\n uint public totalSupply;\n\n constructor(uint _initialSupply) public {\n balances[msg.sender] = totalSupply = _initialSupply;\n }\n\n function transfer(address _to, uint _value) public returns (bool) {\n balances[msg.sender] -= _value;\n balances[_to] += _value;\n return true;\n }\n\n function balanceOf(address _owner) public view returns (uint balance) {\n return balances[_owner];\n }\n}\n' } }, 'mainSource': 'token.sol' } } 27 | -------------------------------------------------------------------------------- /src/util/refreshToken.ts: -------------------------------------------------------------------------------- 1 | import { ClientService } from '../apiServices/ClientService' 2 | 3 | import { postRequest } from '../http' 4 | import { JwtTokensInterface } from '..' 5 | import { errorHandler } from './errorHandler' 6 | 7 | export async function refreshToken(jwtTokens: JwtTokensInterface): Promise { 8 | try { 9 | const reqBody = { 10 | jwtTokens: jwtTokens, 11 | } 12 | 13 | const result = await postRequest(`${ClientService.MYTHX_API_ENVIRONMENT}/auth/refresh`, reqBody, {}) 14 | const tokens: JwtTokensInterface = result.data.jwtTokens 15 | 16 | return tokens 17 | } catch (err) { 18 | errorHandler(err) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/util/validateToken.ts: -------------------------------------------------------------------------------- 1 | import * as jwt from 'jsonwebtoken' 2 | 3 | import { refreshToken } from './refreshToken' 4 | import { JwtTokensInterface } from '..' 5 | 6 | interface jwtInterface { 7 | jti: string 8 | iss: string 9 | exp: number 10 | userId: string 11 | iat: number 12 | } 13 | 14 | export async function validateToken(tokens: JwtTokensInterface): Promise { 15 | if (isTokenValid(tokens.access)) { 16 | return tokens 17 | } else { 18 | // else return refreshed token 19 | const returnT = (await refreshToken(tokens)) as JwtTokensInterface 20 | return returnT 21 | } 22 | } 23 | 24 | // Returns a boolean on whatever the token has expired or not 25 | export function isTokenValid(token: string): boolean { 26 | try { 27 | // decode token 28 | const tokenDecoded: jwtInterface = jwt.decode(token) 29 | const { exp } = tokenDecoded 30 | 31 | // returns true if token is still valid 32 | const now = new Date() 33 | return now.getTime() < exp * 1000 34 | } catch (err) { 35 | throw new Error(`Error with checking if token is still valid. ${err}`) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./dist", 7 | "strict": true, 8 | "noImplicitAny": false, 9 | "skipLibCheck": true, 10 | "lib": [ "es2015" ], 11 | "types": ["node", "mocha"], 12 | "typeRoots": ["node_modules/@types"] 13 | }, 14 | "exclude":[ 15 | "node_modules", 16 | "./dist", 17 | "./**/*.spec.ts", 18 | "./test/**/*.ts", 19 | ] 20 | } --------------------------------------------------------------------------------