diff --git a/packages/composer-cli/lib/cmds/card/lib/schema/ccpschema.json b/packages/composer-cli/lib/cmds/card/lib/schema/ccpschema.json index d4de0ba16b..02fc59b212 100644 --- a/packages/composer-cli/lib/cmds/card/lib/schema/ccpschema.json +++ b/packages/composer-cli/lib/cmds/card/lib/schema/ccpschema.json @@ -1,10 +1,10 @@ -{ +{ "$schema" : "http://json-schema.org/schema#", "definitions" : { "client" : { "type" : "object", "properties" : { - "organization" : { "type" : "string" } + "organization" : { "type" : "string" } }, "required" : [ "organization" ] }, @@ -57,20 +57,20 @@ "channel-peer" : { "type" : "object", "patternProperties": { - "^.*$" : { + "^.*$" : { "endorsingPeer" : { "type" : "boolean" }, "chaincodeQuery" : { "type" : "boolean" }, "ledgerQuery" : { "type" : "boolean" }, "eventSource" : { "type" : "boolean" } }, - "additionalProperties": false + "additionalProperties": false }, "minimum" : 1 }, "orderers" : { "type" : "object", "patternProperties": { - "^.*$" : { "$ref": "#/definitions/orderer" } + "^.*$" : { "$ref": "#/definitions/orderer" } }, "minimum": 1 }, @@ -112,7 +112,7 @@ "^.*$" : { "$ref": "#/definitions/organization" } }, "minimum": 1 - }, + }, "organization" : { "type" : "object", "properties": { @@ -127,34 +127,51 @@ "adminPrivateKey" : { "type" : "object", "properties": { - "oneOf" : { - "pem" : { "type" : "string" }, - "path" : { "type" : "string" } + "pem" : { "type" : "string" }, + "path": { + "type": "string" } }, - "required" : [ "pem" ] + "oneOf" : [{ + "anyOf" : [{ + "required" : ["path"] + }, { + "required" : ["pem"] + } + ] + }] }, "signedCert" : { "type" : "object", "properties": { - "path" : { "type" : "string" } + "pem" : { "type" : "string" }, + "path": { + "type": "string" + } }, - "required" : [ "path" ] + "oneOf" : [{ + "anyOf" : [{ + "required" : ["path"] + }, { + "required" : ["pem"] + } + ] + }] }, "peers" : { "type" : "object", "patternProperties": { - "^.*$" : { "$ref": "#/definitions/peer" } + "^.*$" : { "$ref": "#/definitions/peer" } }, "minimum": 1 }, "peer" : { - "type" : "object", + "type" : "object", "properties": { "url" : { "format" : "uri" }, "eventUrl" : { "format" : "uri" }, "grpcOptions" : { "$ref": "#/definitions/grpcOptions" }, - "tlsCACerts" : { "$ref": "#/definitions/tlsCACerts" } + "tlsCACerts" : { "$ref": "#/definitions/tlsCACerts" } }, "required": [ "url", "eventUrl"] } @@ -173,5 +190,5 @@ "organizations" : { "$ref" : "#/definitions/organizations" }, "peers" : { "$ref": "#/definitions/peers" } }, - "required" : ["name", "x-type", "client", "certificateAuthorities", "channels", "orderers", "peers"] -} \ No newline at end of file + "required" : ["name", "x-type", "client", "certificateAuthorities", "channels", "orderers", "peers"] +} diff --git a/packages/composer-common/lib/cardstore/businessnetworkcardstore.js b/packages/composer-common/lib/cardstore/businessnetworkcardstore.js index 7b83a5273a..dd48d7f234 100644 --- a/packages/composer-common/lib/cardstore/businessnetworkcardstore.js +++ b/packages/composer-common/lib/cardstore/businessnetworkcardstore.js @@ -30,7 +30,17 @@ class BusinessNetworkCardStore { * @returns {String} A card name */ static getDefaultCardName(card) { - const locationName = card.getBusinessNetworkName() || card.getConnectionProfile().name; + let locationName; + if(card.getBusinessNetworkName()) { + locationName = card.getBusinessNetworkName(); + } else { + locationName = card.getConnectionProfile().name; + // take out all invalid characters + locationName = locationName.replace(/[^a-zA-Z0-9-_\s]/g, ''); + // swap spaces for - + locationName = locationName.replace(/\s/gi, '-'); + } + return card.getUserName() + '@' + locationName; } diff --git a/packages/composer-common/test/cardstore/businessnetworkcardstore.js b/packages/composer-common/test/cardstore/businessnetworkcardstore.js index b65cecd6b3..788d3e11aa 100644 --- a/packages/composer-common/test/cardstore/businessnetworkcardstore.js +++ b/packages/composer-common/test/cardstore/businessnetworkcardstore.js @@ -39,6 +39,14 @@ describe('BusinessNetworkCardStore', function() { const result = BusinessNetworkCardStore.getDefaultCardName(card); result.should.include(metadata.userName).and.include(connectionProfile.name); }); + + it('should update the name given in the connection profile if invalid', () => { + const metadata = { userName: 'PeerAdmin', roles: [ 'PeerAdmin', 'ChannelAdmin' ] }; + const connectionProfile = { name: 'profile-name_that\'s got spaces and &^%$# characters' }; + const card = new IdCard(metadata, connectionProfile); + const result = BusinessNetworkCardStore.getDefaultCardName(card); + result.should.include(metadata.userName).and.include('profile-name_thats-got-spaces-and--characters'); + }); }); describe('#get', function() {