diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7d3359b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +dist: trusty +language: node_js +sudo: required +branches: + only: + - master + - develop +notifications: + email: + recipients: + - ci.report@ost.com + on_success: always + on_failure: always +node_js: + - "9" + - "8" + - "7" +before_install: + - sudo apt-get update + - sudo apt-get install nodejs + - sudo apt-get install npm +install: + - npm install + - npm install -g mocha +before_script: +script: + - mocha --timeout 120000 test.js --exit +after_script: diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..7df7c61 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2018 OST.com Ltd. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index b223989..b72a281 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ ## KYC Javascript SDK -The official [KYC JavaScript SDK](https://dev.ost.com/docs/kyc/index.html). +The official [OST KYC JavaScript SDK](https://dev.ost.com/docs/kyc/index.html). ## Requirements + To use this node module, developers will need to: -1. Be a client of OST KYC -2. Obtain an API Key and API Secret from OST KYC. +1. Login on [https://kyc.ost.com/admin/login](https://kyc.ost.com/admin/login). +2. Obtain an API Key and API Secret from [https://kyc.ost.com/admin/settings/developer-integrations](https://kyc.ost.com/admin/settings/developer-integrations). ## Documentation @@ -17,7 +18,7 @@ To use this node module, developers will need to: Install OST KYC JavaScript SDK ```bash -> npm install @ostdotcom/kyc-sdk-js +> npm install @ostdotcom/ost-kyc-sdk-js ``` ## Example Usage @@ -25,14 +26,16 @@ Install OST KYC JavaScript SDK Require the SDK: ```node.js -const KYCSDK = require('@ostdotcom/kyc-sdk-js'); +const KYCSDK = require('@ostdotcom/ost-kyc-sdk-js'); ``` Initialize the SDK object: ```node.js // the latest valid API endpoint is "https://kyc.sandboxost.com", this may change in the future -const kycObj = new KYCSDK({apiKey: , apiSecret: , apiEndpoint: }); +// timeout can be passed in config object. This is http request timeout.(In seconds) +const kycObj = new KYCSDK({apiKey: , apiSecret: , apiEndpoint: , +config: {timeout: }}); ``` ### Users Module @@ -63,13 +66,13 @@ userService.list({}).then(function(res) { console.log(JSON.stringify(res)); }).c ### Users KYC module ```node.js -const usersKYCService = kycSdk.services.usersKyc; +const usersKYCService = kycObj.services.usersKyc; ``` Submit KYC: ```node.js -usersKYCService.submitKyc({user_id:11003, first_name:'YOGESH', last_name:'SAWANT', birthdate:'29/07/1992', country:'INDIA', nationality:'INDIAN', document_id_number:'DMDPS9634C', document_id_file_path:'10/i/4ae058629d4b384edcda8decdfbf0dd1', selfie_file_path:'10/i/4ae058629d4b384edcda8decdfbf0dd2', ethereum_address:'0x04d39e0b112c20917868ffd5c42372ecc5df577b',estimated_participation_amount:'1.2',residence_proof_file_path:'10/i/4ae058629d4b384edcda8decdfbf0dd3',investor_proof_files_path: ['10/i/4ae058629d4b384edcda8decdfbf0da1', '10/i/4ae058629d4b384edcda8decdfbf0da2'], city:'pune',street_address:'hadapsar',postal_code:'411028',state:'maharashtra'}).then(function(res) { console.log(JSON.stringify(res)); }).catch(function(err) { console.log(JSON.stringify(err)); }); +usersKYCService.submitKyc({user_id:11003, first_name:'RAJESH', last_name:'KUMAR', birthdate:'29/07/1992', country:'INDIA', nationality:'INDIAN', document_id_number:'ADDHBDHBSH', document_id_file_path:'10/i/4ae058629d4b384edcda8decdfbf0dd1', selfie_file_path:'10/i/4ae058629d4b384edcda8decdfbf0dd2', ethereum_address:'0x04d39e0b112c20917868ffd5c42372ecc5df577b',estimated_participation_amount:'1.2',residence_proof_file_path:'10/i/4ae058629d4b384edcda8decdfbf0dd3',investor_proof_files_path: ['10/i/4ae058629d4b384edcda8decdfbf0da1', '10/i/4ae058629d4b384edcda8decdfbf0da2'], city:'pune',street_address:'hadapsar',postal_code:'411028',state:'maharashtra'}).then(function(res) { console.log(JSON.stringify(res)); }).catch(function(err) { console.log(JSON.stringify(err)); }); ``` List Users KYC: @@ -81,7 +84,7 @@ usersKYCService.list().then(function(res) { console.log(JSON.stringify(res)); }) Get Users KYC ```node.js -usersKYCService.get({id:11003}).then(function(res) { console.log(JSON.stringify(res)); }).catch(function(err) { console.log(JSON.stringify(err)); }); +usersKYCService.get({user_id:11003}).then(function(res) { console.log(JSON.stringify(res)); }).catch(function(err) { console.log(JSON.stringify(err)); }); ``` @@ -123,7 +126,7 @@ usersKYCService.getPresignedUrlPost({ ### Users KYC details Module ```node.js -const usersKYCDetailsService = kycSdk.services.usersKycDetails, +const usersKYCDetailsService = kycObj.services.usersKycDetails; ``` Get user's kyc details @@ -136,7 +139,7 @@ usersKYCDetailsService.get({user_id:11003}).then(function(res) { console.log(JSO ```node.js -const validatorService = kycSdk.services.validators; +const validatorService = kycObj.services.validators; ``` Verify ethereum address diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..359a5b9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.0.0 \ No newline at end of file diff --git a/configuration.json b/configuration.json index 494f2d2..7ccd7fa 100644 --- a/configuration.json +++ b/configuration.json @@ -16,7 +16,17 @@ "email": "mayur+67@ost.com" }, "testResource": "/api/v2/users", - "signatureExpected": "c42188c53bfdf84e542a0a9c0a78d19c9f497c61e816f169e1907bc98477eb82" + "signatureExpected": "c42188c53bfdf84e542a0a9c0a78d19c9f497c61e816f169e1907bc98477eb82", + "getPreSignedUrlObj": {"files": { + "residence_proof": "application/pdf", + "investor_proof_file1": "application/pdf", + "investor_proof_file2": "application/pdf", + "document_id": "image/jpeg", + "selfie": "image/jpeg" + }}, + "api_secret_for_testing_signature":"35f346e5ef825ed4499da98a6ac6b401" + + } \ No newline at end of file diff --git a/lib/request.js b/lib/request.js index b224d45..e58459a 100644 --- a/lib/request.js +++ b/lib/request.js @@ -15,10 +15,10 @@ const queryString = require('qs') const rootPrefix = ".." , validate = require(rootPrefix + '/lib/validate') , version = require(rootPrefix + '/package.json').version - , httpUserAgent = "ost-sdk-js " + version + , httpUserAgent = "ost-kyc-sdk-js " + version ; -let DEBUG = ( "true" === process.env.OST_SDK_DEBUG ); +let DEBUG = ( "true" === process.env.OST_KYC_SDK_DEBUG ); /** * Generate query signature @@ -48,6 +48,7 @@ function alphabeticalSort(a, b) { * @param {string} params.apiKey - api key * @param {string} params.apiSecret - api secret * @param {string} params.apiEndpoint - version specific api endpoint + * @param {obj} params.config - configularions like timeout * * @constructor */ @@ -71,6 +72,8 @@ const RequestKlass = function(params) { } oThis.apiEndpoint = params.apiEndpoint.replace(/\/$/, ""); + var config = params.config || {}; + oThis.timeOut = config.timeout * 1000 || 15000; oThis._formatQueryParams = function (resource, queryParams) { const oThis = this; @@ -206,9 +209,16 @@ RequestKlass.prototype = { }); + request.on('socket', function (socket) { + socket.setTimeout(oThis.timeOut); + socket.on('timeout', function(e) { + onReject({"success":false,"err":{"code":"GATEWAY_TIMEOUT","internal_id":"TIMEOUT_ERROR","msg":"","error_data":[]}}); + }); + }); + request.on('error', function (e) { - console.error('OST-SDK: Request error'); + console.error('KYC-SDK: Request error'); console.error(e); var parsedResponse = oThis._parseResponse(e); if (parsedResponse.success) { @@ -231,17 +241,14 @@ RequestKlass.prototype = { * Parse response * * @param {string} responseData - Response data - * @param {object} response - Response object + * @param { object} response - Response object * * @private */ _parseResponse: function(responseData, response) { - var statusesHandledAtServers = [200, 400, 422, 500]; + var statusesHandledAtServers = [200, 400, 401, 403, 404, 422, 429, 500]; if (!validate.isPresent(responseData) || statusesHandledAtServers.indexOf((response || {}).statusCode) < 0 ) { switch ((response || {}).statusCode) { - case 429: - responseData = responseData || '{"success": false, "err": {"code": "TOO_MANY_REQUESTS", "internal_id": "SDK(TOO_MANY_REQUESTS)", "msg": "", "error_data":[]}}'; - break; case 502: responseData = responseData || '{"success": false, "err": {"code": "BAD_GATEWAY", "internal_id": "SDK(BAD_GATEWAY)", "msg": "", "error_data":[]}}'; break; @@ -259,7 +266,7 @@ RequestKlass.prototype = { try { var parsedResponse = JSON.parse(responseData); } catch(e) { - //console.error('OST-SDK: Response parsing error'); + //console.error('KYC-SDK: Response parsing error'); //console.error(e); var parsedResponse = {"success": false, "err": {"code": "SOMETHING_WENT_WRONG", "internal_id": "SDK(SOMETHING_WENT_WRONG)", "msg": "Response parsing error", "error_data":[]}}; } diff --git a/lib/validate.js b/lib/validate.js index 0cdce17..c640e90 100644 --- a/lib/validate.js +++ b/lib/validate.js @@ -17,6 +17,8 @@ const ValidateKlass = function() {}; ValidateKlass.prototype = { + pattern: /^[a-z\d\-\.]+$/i, + /** * Check if parameter is present * @@ -25,7 +27,7 @@ ValidateKlass.prototype = { * @public */ isPresent: function (param) { - return (typeof param !== 'undefined' && param !== null); + return (typeof param !== 'undefined' && param !== null && String(param).trim() !== ''); }, /** @@ -35,10 +37,10 @@ ValidateKlass.prototype = { */ getId: function (params) { const oThis = this; - if (oThis.isPresent(params.id)) { + if (oThis.isPresent(params.id) && oThis.pattern.test(params.id)) { return params.id; } else { - throw new Error('id missing in request params'); + throw new Error('missing or invalid id in request params'); } }, @@ -49,10 +51,10 @@ ValidateKlass.prototype = { */ getUserId: function (params) { const oThis = this; - if(oThis.isPresent(params.user_id)){ + if(oThis.isPresent(params.user_id)&& oThis.pattern.test(params.user_id)){ return params.user_id } else{ - throw new Error('user id missing in request params'); + throw new Error('missing or invalid user id in request params'); } } diff --git a/package.json b/package.json index 0271e18..d166039 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,20 @@ { "name": "@ostdotcom/ost-kyc-sdk-js", - "version": "1.0.0", - "description": "KYC sdk", + "version": "2.0.0", + "description": "OST KYC sdk", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, + "keywords": [ + "OST", + "KYC", + "Javascript", + "Node.js", + "SDK" + ], "dependencies": { - "qs": "^6.5.2", - "query-string": "6.0.0" + "qs": "^6.5.2" }, "devDependencies": { "chai": "4.1.2", @@ -16,12 +22,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/OpenSTFoundation/kyc-sdk-js.git" + "url": "git+https://github.com/OpenSTFoundation/ost-kyc-sdk-js.git" }, "author": "", - "license": "ISC", + "license": "MIT", "bugs": { - "url": "https://github.com/OpenSTFoundation/kyc-sdk-js/issues" + "url": "https://github.com/OpenSTFoundation/ost-kyc-sdk-js/issues" }, - "homepage": "https://github.com/OpenSTFoundation/kyc-sdk-js#readme" + "homepage": "https://github.com/OpenSTFoundation/ost-kyc-sdk-js#readme" } diff --git a/test.js b/test.js index bdf170f..3986879 100644 --- a/test.js +++ b/test.js @@ -15,50 +15,286 @@ const rootPrefix = ".", testObjForSignature = configObj["testObjForSignature"], credentialObject = { - apiKey: process.env.API_KEY, - secret: process.env.API_SECRET + apiKey: process.env.OST_KYC_API_KEY, + secret: process.env.OST_KYC_API_SECRET }, - apiEndpont = process.env.API_BASE_URL, + credentialObjectForSignatureTest = { + secret: configObj['api_secret_for_testing_signature'] + }, + apiEndpont = process.env.OST_KYC_API_ENDPOINT, KYCSDK = require(rootPrefix + "/index"), - kycSdk = new KYCSDK({apiKey: credentialObject.apiKey, apiSecret: credentialObject.secret, apiEndpoint: apiEndpont}), + //config is optional param, timeout should be given in seconds + kycSdk = new KYCSDK({apiKey: credentialObject.apiKey, apiSecret: credentialObject.secret, apiEndpoint: apiEndpont, config:{timeout:15}}), userService = kycSdk.services.users, - usersKycService = kycSdk.services.usersKyc + usersKycService = kycSdk.services.usersKyc, + usersKycDetailsService = kycSdk.services.usersKycDetails, + validateService = kycSdk.services.validators + ; -function checkSignature() { - it ("Signature should match with given one", function () { - const requestObj = new RequestKlass({apiKey: '12121', apiSecret:'dsdsd', apiEndpoint: "endpoint" }), +function testSignature() { + it("Signature should match with given one", function () { + const requestObj = new RequestKlass({apiKey: '12121', apiSecret: 'dsdsd', apiEndpoint: "endpoint"}), queryString = requestObj.formatQueryParams(testObjForSignature); - console.log("queryString", queryString ); - var fullQueryString = requestObj.signQueryParamsTest(configObj["testResource"], queryString, credentialObject), + var fullQueryString = requestObj.signQueryParamsTest(configObj["testResource"], queryString, credentialObjectForSignatureTest), queryStringObj = qs.parse(fullQueryString); - assert.equal(queryStringObj.signature, configObj["signatureExpected"] ); + assert.equal(queryStringObj.signature, configObj["signatureExpected"]); }); } -function checkGetRequest(){ - it('response.success should be true for testing get request', async function () { - var email = 'alice+' + Date.now() + '@ost.com'; - const response = await userService.list().catch(function(err) { assert.fail('GET request testcase is failed'); }); +function testGetUsers() { + it('Testing get user', + async function () { + var userId = process.env.USER_ID + const response = await + userService.get({id: userId}).catch(function (err) { + assert.fail('GET User testcase is failed'); + }); assert.equal(response.success, true); - }); + } + +) + ; +} + +function testGetUsersIdZero() { + it('Testing get user with 0 id', + async function () { + var userId = process.env.USER_ID + const response = await + userService.get({id: 0}).then(function(res){ + assert.fail('Resource is not present. This should fail'); + }).catch(function (err) { + //console.log(err) + }); + } +); +} + + +function testGetUsersGarbageId() { + it('Testing get user with garbage id', + async function () { + try{ + const response = await + userService.get({id: "&#@%#@#^#6"}).then(function(res){ + assert.fail('Id is garbage. This should fail'); + }); + assert.fail('Id is garbage. This should fail'); + } + catch (error){ + const message = "missing or invalid id in request params"; + if (error.message != message) + assert.fail('Id is garbage or invalid'); + } + } +); +} + + +function testGetUsersBlanckId() { + it('Testing get user with blank id', + async function () { + try{ + const response = await + userService.get({id: ""}).then(function(res){ + assert.fail('Id is garbage. This should fail'); + }); + assert.fail('Id is garbage. This should fail'); + } + catch (error){ + const message = "missing or invalid id in request params"; + if (error.message != message) + assert.fail('Id is garbage or invalid'); + } + } +); +} + + +function testGetUsersList() { + it('Testing list user', + async function () { + var userId = process.env.USER_ID + const response = await + userService.list({id: userId}).catch(function (err) { + assert.fail('GET User list testcase is failed'); + }); + } + +) + ; +} + +function testCreateUser() { + it('response.success should be true for testing create request', + async function () { + var email = 'alice+' + Date.now() + '_' + process.version + '@ost.com'; + const response = await + userService.create({email: email}).catch(function (err) { + assert.fail('Create User testcase is failed'); + }); + assert.equal(response.success, true); + } + ) + ; } -function checkPostRequest() { - var email = 'alice+' + Date.now() + '@ost.com'; - it('response.success should be true for post request', async function () { - var email = 'alice+' + Date.now() + '@ost.com'; - const response = await userService.create({email: email, test_params: testObjForSignature }).catch(function(err) { assert.fail('POST request testcase is failed'); }); +function testGetUserKyc() { + it("Get user's KYC", + async function () { + var userId = process.env.USER_ID + const response = await + usersKycService.get({user_id: userId}).catch(function (err) { + assert.fail('Get Users KYC testcase is failed'); + }); assert.equal(response.success, true); - }); + } + +) + ; + +} + + +function testGetUserKycList() { + it("Get user's KYC", + async function () { + var userId = process.env.USER_ID + const response = await + usersKycService.get({user_id: userId}).catch(function (err) { + assert.fail('Get Users KYC testcase is failed'); + }); + assert.equal(response.success, true); + } + +) + ; + +} + +function testSubmitKyc() { + it("Submit KYC", + async function () { + var obj = { + 'user_id': 11035, + 'first_name': 'aniket', + 'last_name': 'ayachit', + 'birthdate': '21/12/1991', + 'country': 'india', + 'nationality': 'indian', + 'document_id_number': 'arqpa7659a', + 'document_id_file_path': '2/i/016be96da275031de2787b57c99f1471', + 'selfie_file_path': '2/i/9e8d3a5a7a58f0f1be50b7876521aebc', + 'residence_proof_file_path': '2/i/4ed790b2d525f4c7b30fbff5cb7bbbdb', + 'ethereum_address': '0xdfbc84ccac430f2c0455c437adf417095d7ad68e', + 'estimated_participation_amount': '2', + 'street_address': 'afawfveav ', + 'city': 'afawfveav', + 'state': 'afawfveav', + 'postal_code': 'afawfveav', + 'investor_proof_files_path': ['2/i/9ff6374909897ca507ba3077ee8587da', '2/i/4872730399670c6d554ab3821d63ebce'] + } + const response = await + usersKycService.submitKyc(obj).then(function (res) { + assert.fail('Get Users KYC testcase should pass error in response'); + }).catch(function (err) { + }); + + } + +) + ; + +} + +function testGetPresignedUrlForPut() { + it("Get PresignedUrl for PUT", + async function () { + var userId = process.env.USER_ID + const response = await + usersKycService.getPresignedUrlPut(configObj["getPreSignedUrlObj"]).catch(function (err) { + assert.fail('Get Presigned Url For Put testcase is failed'); + }); + assert.equal(response.success, true); + } + +) + ; + +} + + +function testGetPresignedUrlForPost() { + it("Get PresignedUrl for POST", + async function () { + var userId = process.env.USER_ID + const response = await + usersKycService.getPresignedUrlPost(configObj["getPreSignedUrlObj"]).catch(function (err) { + assert.fail('Get Presigned Url For POST testcase is failed'); + }); + assert.equal(response.success, true); + } + +) + ; + +} + + +function testGetUserKycDetails() { + + it("Get PresignedUrl for POST", + async function () { + var userId = process.env.USER_ID + const response = await + usersKycDetailsService.get({user_id: process.env.USER_ID}).catch(function (err) { + console.log("this is error", err['success']); + assert.fail('Get User KYC details testcase is failed'); + }); + } + +) + ; + + +} + +function testValidateEthereumAddress() { + it('Verify Ethereum address', + async function () { + const response = await + validateService.verifyEthereumAddress({ethereum_address: '0x32be343b94f860124dc4fee278fdcbd38c102d88'}).then(function (r) { + console.log('response', r); + }).catch(function (err) { + console.log(err); + assert.fail('Verify eth adress failed'); + }); + } + +) + ; + + } function main() { - checkSignature(); - checkGetRequest(); - checkPostRequest(); + testSignature(); + testGetUsers(); + testGetUsersList(); + testCreateUser(); + testGetUserKyc(); + testGetUserKycList(); + testSubmitKyc(); + testGetPresignedUrlForPut(); + testGetPresignedUrlForPost(); + testGetUserKycDetails(); + testValidateEthereumAddress(); + testGetUsersIdZero(); + testGetUsersGarbageId(); + testGetUsersBlanckId(); } main();