diff --git a/README.md b/README.md index 2e5d6d8..4e18c43 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,19 @@ protocol://[username:password@]host:port The `username` and `password` components are optional, with these you can set the authentication credentials to the message queue server. +> Note: if you would like to use special characters in username or password, then you have to `encodeURIComponent()` these values, because +> the library will decode the values right before connection creation. If you don't encode these values, then you will get a URL parse +> error. +> +> If you use environment variables to connection username or password, then use the env values with `encodeURIComponent()` as well. +> +> Example: +> ``` +> const username = encodeURIComponent('Jörg'); +> const password = encodeURIComponent('Gt|N#R=6$5(TE@rH"Pvc$7a'); +> const connectionUri = `amqps://${username}:${password}@localhost:5672`; +> ``` + You can set custom protocol what will set the connection transport automatically, so you don't have to add the `transport` to the connection options object. The protocol can be: * **amqp**: in this case the `transport` will be `tcp` diff --git a/src/service/amqp/amqp.service.spec.ts b/src/service/amqp/amqp.service.spec.ts index f535526..726cb2a 100644 --- a/src/service/amqp/amqp.service.spec.ts +++ b/src/service/amqp/amqp.service.spec.ts @@ -96,6 +96,16 @@ describe('AMQPService', () => { expect((connection as any).open).toHaveBeenCalled(); }); + it('should create connection with special chars in username and password', async () => { + const username = 'Jörg'; + const password = 'Gt|N#R=6$5(TE@rH"Pvc$7a'; + const connectionUri = `amqps://${encodeURIComponent(username)}:${encodeURIComponent(password)}@localhost:5672`; + + await AMQPService.createConnection({ connectionUri }); + + expect(getLastMockCall(Connection as any)[0]).toEqual(expect.objectContaining({ username, password })); + }); + it('should create throw error if connection options is not a valid object', async () => { await expect(AMQPService.createConnection(null)).rejects.toThrow(/connection options must an object/); }); diff --git a/src/service/amqp/amqp.service.ts b/src/service/amqp/amqp.service.ts index 6f4c8f9..58e216b 100644 --- a/src/service/amqp/amqp.service.ts +++ b/src/service/amqp/amqp.service.ts @@ -54,7 +54,10 @@ export class AMQPService { logger.log('creating AMQP client'); const { throwExceptionOnConnectionError, connectionUri, ...rheaConnectionOptions } = options; - const { protocol, username, password, hostname, port } = new URL(connectionUri); + const parsedConnectionUri = new URL(connectionUri); + const { protocol, hostname, port } = parsedConnectionUri; + const username = decodeURIComponent(parsedConnectionUri.username); + const password = decodeURIComponent(parsedConnectionUri.password); logger.log( `initializing client connection to ${JSON.stringify({