You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+33-14Lines changed: 33 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -307,7 +307,7 @@ The callback function is called with the following three arguments:
307
307
*`handshake` {Object} - A handshake object
308
308
*`protocols` {Set} - A set of subprotocols purportedly supported by the client.
309
309
*`identity` {String} - The identity portion of the connection URL, decoded.
310
-
*`password` {String} - If HTTP Basic auth was used in the connection, and the username correctly matches the identity, this field will contain the password (otherwise `undefined`). Read [Security Profile 1](#security-profile-1) for more details of how this works.
310
+
*`password` {Buffer} - If HTTP Basic auth was used in the connection, and the username correctly matches the identity, this field will contain the password (otherwise `undefined`). Typically this password would be a string, but the OCPP specs allow for this to be binary, so it is provided as a `Buffer` for you to interpret as you wish. Read [Security Profile 1](#security-profile-1) for more details of how this works.
311
311
*`endpoint` {String} - The endpoint path portion of the connection URL. This is the part of the path before the identity.
312
312
*`query` {URLSearchParams} - The query string parsed as [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams).
313
313
*`remoteAddress` {String} - The remote IP address of the socket.
@@ -384,7 +384,7 @@ Returns a `Promise` which resolves when the server has completed closing.
384
384
-`endpoint` {String} - The RPC server's endpoint (a websocket URL). **Required**.
385
385
-`identity` {String} - The RPC client's identity. Will be automatically encoded. **Required**.
386
386
-`protocols` {Array<String>} - Array of subprotocols supported by this client. Defaults to `[]`.
387
-
-`password` {String} - Optional password to use in [HTTP Basic auth](#security-profile-1). (The username will always be the identity).
387
+
-`password` {String|Buffer} - Optional password to use in [HTTP Basic auth](#security-profile-1). This can be a Buffer to allow for binary auth keys as recommended in the OCPP security whitepaper. If provided as a string, it will be encoded as UTF-8. (The corresponding username will always be the identity).
388
388
-`headers` {Object} - Additional HTTP headers to send along with the websocket upgrade request. Defaults to `{}`.
389
389
-`query` {Object|String} - An optional query string or object to append as the query string of the connection URL. Defaults to `''`.
390
390
-`callTimeoutMs` {Number} - Milliseconds to wait before unanswered outbound calls are rejected automatically. Defaults to `60000`.
@@ -415,7 +415,14 @@ If too many bad messages are received in succession, the client will be closed w
415
415
416
416
#### Event: 'strictValidationFailure'
417
417
418
-
*`error`[{RPCError}](#rpcerror)
418
+
*`event` {Object}
419
+
*`error` {Error} - The validation error that triggered the `strictValidationFailure` event.
420
+
*`messageId` {String} - The RPC message ID
421
+
*`method` {String} - The RPC method being invoked.
422
+
*`params` {Object} - The RPC parameters.
423
+
*`result` {Object} - If this error relates to a **CALLRESULT** validation failure, then this contains the invalid result, otherwise `null`.
424
+
*`outbound` {Boolean} - This will be `true` if the invalid message originated locally.
425
+
*`isCall` {Boolean} - This will be `true` if the invalid message is a **CALL** type. `false` indicates a **CALLRESULT** type.
419
426
420
427
This event is emitted in [strict mode](#strict-validation) when an inbound call or outbound response does not satisfy the subprotocol schema validator. See [Effects of `strictMode`](#effects-of-strictmode) to understand what happens in response to the invalid message.
421
428
@@ -668,7 +675,7 @@ The RPCServerClient is a subclass of RPCClient. This represents an RPCClient fro
668
675
* {Object}
669
676
*`protocols` {Set} - A set of subprotocols purportedly supported by the client.
670
677
*`identity` {String} - The identity portion of the connection URL, decoded.
671
-
*`password` {String} - If HTTP Basic auth was used in the connection, and the username correctly matches the identity, this field will contain the password (otherwise `undefined`). Read [Security Profile 1](#security-profile-1) for more details of how this works.
678
+
*`password` {Buffer} - If HTTP Basic auth was used in the connection, and the username correctly matches the identity, this field will contain the password (otherwise `undefined`). Typically this password would be a string, but the OCPP specs allow for this to be binary, so it is provided as a `Buffer` for you to interpret as you wish. Read [Security Profile 1](#security-profile-1) for more details of how this works.
672
679
*`endpoint` {String} - The endpoint path portion of the connection URL. This is the part of the path before the identity.
673
680
*`query` {URLSearchParams} - The query string parsed as [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams).
674
681
*`remoteAddress` {String} - The remote IP address of the socket.
@@ -717,7 +724,7 @@ An object containing additional error details.
717
724
718
725
This is a utility function to create a special type of RPC Error to be thrown from a call handler to return a non-generic error response.
719
726
720
-
Returns an [`RPCError`](#rpcerror) which corresponds to the specified type:
727
+
Returns an [`RPCError`](#class-rpcerror--error) which corresponds to the specified type:
@@ -763,12 +770,14 @@ const server = new RPCServer({
763
770
### Effects of `strictMode`
764
771
765
772
As a caller, `strictMode` has the following effects:
766
-
* If your method or params fail validation, your call will reject immediately with an [`RPCError`](#rpcerror). The call will not be sent.
767
-
* If a response to your call fails validation, the call will reject with an [`RPCError`](#rpcerror).
773
+
* If your method or params fail validation, your call will reject immediately with an [`RPCError`](#class-rpcerror--error). The call will not be sent.
774
+
* If a response to your call fails validation, the call will reject with an [`RPCError`](#class-rpcerror--error) and you will not receive the actual response that was sent.
768
775
769
776
As a callee, `strictMode` has the following effects:
770
-
* If an inbound call's params fail validation, the call will not be passed to a handler. Instead, an error response will be automatically issued to the caller with an appropriate RPC error. A [`'strictValidationFailure'`](#event-strictvalidationfailure) event will be emitted with an [`RPCError`](#rpcerror).
771
-
* If your response to a call fails validation, the response will be discarded and an `"InternalError"` RPC error will be sent instead. A [`'strictValidationFailure'`](#event-strictvalidationfailure) event will be emitted with an [`RPCError`](#rpcerror).
777
+
* If an inbound call's params fail validation, the call will not be passed to a handler. Instead, an error response will be automatically issued to the caller with an appropriate RPC error.
778
+
* If your response to a call fails validation, then your response will be discarded and an `"InternalError"` RPC error will be sent instead.
779
+
780
+
In all cases, a [`'strictValidationFailure'`](#event-strictvalidationfailure) event will be emitted, detailing the circumstances of the failure.
772
781
773
782
**Important:** If you are using `strictMode`, you are strongly encouraged to listen for [`'strictValidationFailure'`](#event-strictvalidationfailure) events, otherwise you may not know if your responses or inbound calls are being dropped for failing validation.
774
783
@@ -846,7 +855,7 @@ const cli = new RPCClient({
846
855
847
856
constserver=newRPCServer();
848
857
server.auth((accept, reject, handshake) => {
849
-
if (handshake.identity==="AzureDiamond"&&handshake.password==="hunter2") {
858
+
if (handshake.identity==="AzureDiamond"&&handshake.password.toString('utf8')==="hunter2") {
850
859
accept();
851
860
} else {
852
861
reject(401);
@@ -867,6 +876,8 @@ In practice, it's not uncommon to see violations of RFC7617 in the wild. All maj
867
876
868
877
However, in OCPP, since we have the luxury of knowing that the username must always be equal to the client's identity, it is no longer necessary to rely upon a colon to delineate the username from the password. This module makes use of this guarantee to enable identities and passwords to contain as many or as few colons as you wish.
869
878
879
+
Additionally, the OCPP security whitepaper recommends passwords consist purely of random bytes (for maximum entropy), although this violates the Basic Auth RFC which requires all passwords to be TEXT (US-ASCII compatible with no control characters). For this reason, this library will not make any presumptions about the character encoding (or otherwise) of the password provided, and present the password as a `Buffer`.
* The `RPCClient` event [`'strictValidationFailure'`](#event-strictvalidationfailure) now fires for both inbound & outbound requests & responses.
1092
+
* The `RPCClient` event [`'strictValidationFailure'`](#event-strictvalidationfailure) emits an object containing more information than was previously available. The Error which was previously emitted is now a member of this object.
1093
+
* The `password` option in the `RPCClient`[constructor](#new-rpcclientoptions) can now be supplied as a `Buffer`. If a string is provided, it will be encoded as utf8.
1094
+
* The `password` field of `RPCServerClient`'s [`handshake`](#clienthandshake) object is now always provided as a Buffer instead of a string. Use `password.toString('utf8')` to convert back to a string as per previous versions.
0 commit comments